wlan: Add diag event for TDLS teardown

Add diag event for TDLS teardown. Event contains reason for
teardown and peer mac address.

Change-Id: Ib04deac6cf7d61fae1a7bb0d0fb8f4dc652b3217
CRs-Fixed: 934448
diff --git a/CORE/HDD/inc/wlan_hdd_tdls.h b/CORE/HDD/inc/wlan_hdd_tdls.h
index 1a1e1bc..532b5ec 100644
--- a/CORE/HDD/inc/wlan_hdd_tdls.h
+++ b/CORE/HDD/inc/wlan_hdd_tdls.h
@@ -117,6 +117,28 @@
     eTDLS_LINK_TEARING,
 } tTDLSLinkStatus;
 
+/**
+ * enum tdls_teardown_reason - Reason for TDLS teardown
+ * @eTDLS_TEARDOWN_EXT_CTRL: Reason ext ctrl.
+ * @eTDLS_TEARDOWN_CONCURRENCY: Reason concurrency.
+ * @eTDLS_TEARDOWN_RSSI_THRESHOLD: Reason rssi threashold.
+ * @eTDLS_TEARDOWN_TXRX_THRESHOLD: Reason txrx threashold.
+ * @eTDLS_TEARDOWN_BTCOEX: Reason BTCOEX.
+ * @eTDLS_TEARDOWN_SCAN: Reason scan.
+ * @eTDLS_TEARDOWN_BSS_DISCONNECT: Reason bss disconnected.
+ *
+ * Reason to indicate in diag event of tdls teardown.
+ */
+
+enum tdls_teardown_reason {
+    eTDLS_TEARDOWN_EXT_CTRL,
+    eTDLS_TEARDOWN_CONCURRENCY,
+    eTDLS_TEARDOWN_RSSI_THRESHOLD,
+    eTDLS_TEARDOWN_TXRX_THRESHOLD,
+    eTDLS_TEARDOWN_BTCOEX,
+    eTDLS_TEARDOWN_SCAN,
+    eTDLS_TEARDOWN_BSS_DISCONNECT,
+};
 
 typedef enum {
     eTDLS_LINK_SUCCESS,                              /* Success */
@@ -393,6 +415,17 @@
 void wlan_hdd_tdls_indicate_teardown(hdd_adapter_t *pAdapter,
                                      hddTdlsPeer_t *curr_peer,
                                      tANI_U16 reason);
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+void hdd_send_wlan_tdls_teardown_event(uint32_t reason,
+                                      uint8_t *peer_mac);
+#else
+static inline
+void hdd_send_wlan_tdls_teardown_event(uint32_t reason,
+                                      uint8_t *peer_mac)
+{
+    return;
+}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
 
 int wlan_hdd_tdls_set_force_peer(hdd_adapter_t *pAdapter,
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c
index fe53ce9..32828ca 100644
--- a/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/CORE/HDD/src/wlan_hdd_assoc.c
@@ -3141,6 +3141,8 @@
             curr_peer = wlan_hdd_tdls_find_peer(pAdapter, pRoamInfo->peerMac,
                                                 FALSE);
             wlan_hdd_tdls_indicate_teardown(pAdapter, curr_peer, pRoamInfo->reasonCode);
+            hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_BSS_DISCONNECT,
+                                                          curr_peer->peerMac);
             mutex_unlock(&pHddCtx->tdls_lock);
 #endif
             status = eHAL_STATUS_SUCCESS ;
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 9437055..99c7774 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -17717,6 +17717,7 @@
 
     hddTdlsPeer_t *pTdlsPeer;
     hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+
     VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
               " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
               __func__, MAC_ADDR_ARRAY(peer));
@@ -17749,6 +17750,8 @@
     else {
         wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
                            eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
+        hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
+                                                 pTdlsPeer->peerMac);
         /* if channel switch is configured, reset
            the channel for this peer */
         if (TRUE == pTdlsPeer->isOffChannelConfigured)
diff --git a/CORE/HDD/src/wlan_hdd_tdls.c b/CORE/HDD/src/wlan_hdd_tdls.c
index 5ec5a73..a6c3469 100644
--- a/CORE/HDD/src/wlan_hdd_tdls.c
+++ b/CORE/HDD/src/wlan_hdd_tdls.c
@@ -67,6 +67,33 @@
     return key;
 }
 
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+/**
+ * hdd_send_wlan_tdls_teardown_event()- send TDLS teardown event
+ *
+ * @reason: reason for tear down.
+ * @peer_mac: peer mac
+ *
+ * This Function send TDLS teardown diag event
+ *
+ * Return: void.
+ */
+void hdd_send_wlan_tdls_teardown_event(uint32_t reason,
+                                      uint8_t *peer_mac)
+{
+   WLAN_VOS_DIAG_EVENT_DEF(tdls_tear_down,
+                      struct vos_event_tdls_teardown);
+   vos_mem_zero(&tdls_tear_down,
+                    sizeof(tdls_tear_down));
+
+   tdls_tear_down.reason = reason;
+   vos_mem_copy(tdls_tear_down.peer_mac,
+        peer_mac, HDD_MAC_ADDR_LEN);
+   WLAN_VOS_DIAG_EVENT_REPORT(&tdls_tear_down,
+       EVENT_WLAN_TDLS_TEARDOWN);
+}
+#endif
+
 /**
  * wlan_hdd_tdls_disable_offchan_and_teardown_links - Disable offchannel
  * and teardown TDLS links
@@ -160,7 +187,8 @@
                 curr_peer->pHddTdlsCtx->pAdapter,
                 curr_peer,
                 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
-
+        hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_CONCURRENCY,
+                                            curr_peer->peerMac);
         mutex_unlock(&hddctx->tdls_lock);
 
         /* Del Sta happened already as part of sme_DeleteAllTDLSPeers
@@ -175,7 +203,6 @@
         vos_mem_zero(&hddctx->tdlsConnInfo[staIdx].peerMac,
                  sizeof(v_MACADDR_t)) ;
         wlan_hdd_tdls_check_bmps(adapter);
-
     }
 
 done:
@@ -414,6 +441,9 @@
       wlan_hdd_tdls_indicate_teardown(curr_peer->pHddTdlsCtx->pAdapter,
                                       curr_peer,
                                       eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
+      hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_TXRX_THRESHOLD,
+                                           curr_peer->peerMac);
+
     }
     mutex_unlock(&pHddCtx->tdls_lock);
     EXIT();
@@ -533,6 +563,10 @@
                         wlan_hdd_tdls_indicate_teardown(pHddTdlsCtx->pAdapter,
                                                         curr_peer,
                                                         eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
+                        hdd_send_wlan_tdls_teardown_event(
+                               eTDLS_TEARDOWN_RSSI_THRESHOLD,
+                               curr_peer->peerMac);
+
 #endif
                         goto next_peer;
                     }
@@ -879,15 +913,18 @@
                                   ("%s: indicate TDLS teardown (staId %d)"),
                                   __func__,pHddCtx->tdlsConnInfo[staIdx].staId);
 
-                        #ifdef CONFIG_TDLS_IMPLICIT
+#ifdef CONFIG_TDLS_IMPLICIT
                         curr_peer = wlan_hdd_tdls_find_all_peer(pHddCtx,
                                    pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes);
                         if(curr_peer) {
                            wlan_hdd_tdls_indicate_teardown(
                                    curr_peer->pHddTdlsCtx->pAdapter, curr_peer,
                                    eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
+                           hdd_send_wlan_tdls_teardown_event(
+                                                eTDLS_TEARDOWN_BTCOEX,
+                                                curr_peer->peerMac);
                         }
-                        #endif
+#endif
                     }
                }
                mutex_unlock(&pHddCtx->tdls_lock);
@@ -3086,10 +3123,14 @@
 #ifdef CONFIG_TDLS_IMPLICIT
                     curr_peer = wlan_hdd_tdls_find_all_peer(pHddCtx,
                             pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes);
-                    if(curr_peer)
+                    if(curr_peer) {
                         wlan_hdd_tdls_indicate_teardown(
                                 curr_peer->pHddTdlsCtx->pAdapter, curr_peer,
                                 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
+                        hdd_send_wlan_tdls_teardown_event(
+                                               eTDLS_TEARDOWN_SCAN,
+                                               curr_peer->peerMac);
+                    }
 #endif
                 }
             }
diff --git a/CORE/VOSS/inc/event_defs.h b/CORE/VOSS/inc/event_defs.h
index c076cfe..0721a74 100644
--- a/CORE/VOSS/inc/event_defs.h
+++ b/CORE/VOSS/inc/event_defs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -1904,6 +1904,7 @@
   EVENT_WLAN_EAPOL = 0xA8D,/* 18 bytes payload */
   EVENT_WLAN_WAKE_LOCK = 0xAA2, /* 96 bytes payload */
   EVENT_WLAN_LOG_COMPLETE = 0xAA7, /* 16 bytes payload */
+  EVENT_WLAN_TDLS_TEARDOWN = 0xAB5,
   EVENT_NEXT_UNUSED_EVENT,
   EVENT_RSVD_START = 0x0800,
   EVENT_RSVD_END   = 0x083F,
diff --git a/CORE/VOSS/inc/vos_diag_core_event.h b/CORE/VOSS/inc/vos_diag_core_event.h
index 596711d..547efc0 100644
--- a/CORE/VOSS/inc/vos_diag_core_event.h
+++ b/CORE/VOSS/inc/vos_diag_core_event.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -282,6 +282,18 @@
        char     name[WAKE_LOCK_NAME_LEN];
 };
 
+/**
+ * struct vos_event_tdls_teardown - tdls teardown diag event
+ * @reason: reason for tear down
+ * @peer_mac: peer mac
+ *
+ * This structure contain tdls teardown diag event info
+ */
+
+struct vos_event_tdls_teardown {
+   uint32_t reason;
+   uint8_t peer_mac[6];
+};
 
 /*-------------------------------------------------------------------------
   Event ID: EVENT_WLAN_LOG_COMPLETE