TDLS: Remember initiator/reponder role and use this for teardown.

Passing tdls requestor type i.e. initiator/responder correctly to fill
the teardown frame with proper LinkIdentifier element.

CRs-Fixed: 448441
Change-Id: I29e96a1da50e94447c568fb7095217ff2718c1e6
diff --git a/CORE/HDD/inc/wlan_hdd_tdls.h b/CORE/HDD/inc/wlan_hdd_tdls.h
index b6901cb..21d74b1 100644
--- a/CORE/HDD/inc/wlan_hdd_tdls.h
+++ b/CORE/HDD/inc/wlan_hdd_tdls.h
@@ -88,6 +88,7 @@
     tANI_S8     rssi;
     tANI_S8     tdls_support;
     tANI_S8     link_status;
+    tANI_U8     is_responder;
     tANI_U16    discovery_attempt;
     tANI_U16    tx_pkt;
     tANI_U16    rx_pkt;
@@ -127,6 +128,10 @@
 
 int wlan_hdd_tdls_set_rssi(u8 *mac, tANI_S8 rxRssi);
 
+int wlan_hdd_tdls_set_responder(u8 *mac, tANI_U8 responder);
+
+int wlan_hdd_tdls_get_responder(u8 *mac);
+
 int wlan_hdd_tdls_set_params(tdls_config_params_t *config);
 
 int wlan_hdd_tdls_reset_peer(u8 *mac);
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 868f312..d48a98d 100755
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -6512,10 +6512,9 @@
 
     hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
     hdd_context_t *pHddCtx = wiphy_priv(wiphy);
-    u8 *buf_1;
-    size_t len_1 = len;
     u8 peerMac[6];
     VOS_STATUS status;
+    int responder;
 
     if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
     {
@@ -6567,23 +6566,37 @@
                       action_code, dialog_token, status_code, len);
 #endif
 
-    buf_1 = vos_mem_malloc(len);
-    if(buf_1 == NULL) {
-        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
-                "%s: malloc failed!", __func__);
-        return -ENOMEM;
+    /*Except teardown responder will not be used so just make 0*/
+    responder = 0;
+    if(SIR_MAC_TDLS_TEARDOWN == action_code)
+    {
+       responder = wlan_hdd_tdls_get_responder(peerMac);
+       if(-1 == responder)
+       {
+            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                     "%s: %02x:%02x:%02x:%02x:%02x:%02x) peer doesn't exist dialog_token %d status %d, len = %d",
+                     "tdls_mgmt", peer[0], peer[1], peer[2], peer[3], peer[4], peer[5],
+                      dialog_token, status_code, len);
+            return -EPERM;
+       }
     }
-    vos_mem_copy(buf_1, buf, len);
 
     status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
-            peerMac, action_code, dialog_token, status_code, buf_1, len_1);
+            peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
 
     if (VOS_STATUS_SUCCESS != status) {
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
     }
 
-    vos_mem_free(buf_1);
+    if (SIR_MAC_TDLS_SETUP_RSP == action_code)
+    {
+        wlan_hdd_tdls_set_responder(peerMac, TRUE);
+    }
+    else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
+    {
+        wlan_hdd_tdls_set_responder(peerMac, FALSE);
+    }
 
     return 0;
 }
diff --git a/CORE/HDD/src/wlan_hdd_tdls.c b/CORE/HDD/src/wlan_hdd_tdls.c
index 431768e..77e70e8 100644
--- a/CORE/HDD/src/wlan_hdd_tdls.c
+++ b/CORE/HDD/src/wlan_hdd_tdls.c
@@ -255,7 +255,8 @@
 
     cfg80211_tdls_oper_request(pHddTdlsCtx->dev,
                                curr_peer->peerMac,
-                               NL80211_TDLS_TEARDOWN, FALSE,
+                               NL80211_TDLS_TEARDOWN,
+                               eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON,
                                GFP_KERNEL);
 #endif
 }
@@ -440,6 +441,35 @@
     return 0;
 }
 
+int wlan_hdd_tdls_set_responder(u8 *mac, tANI_U8 responder)
+{
+    hddTdlsPeer_t *curr_peer;
+
+    if (NULL == pHddTdlsCtx) return -1;
+
+    curr_peer = wlan_hdd_tdls_get_peer(mac);
+    if(curr_peer == NULL)
+        return -1;
+
+    curr_peer->is_responder = responder;
+
+    return 0;
+}
+
+int wlan_hdd_tdls_get_responder(u8 *mac)
+{
+    hddTdlsPeer_t *curr_peer;
+
+    if (NULL == pHddTdlsCtx) return -1;
+
+    curr_peer = wlan_hdd_tdls_find_peer(mac);
+    if(curr_peer == NULL)
+        return -1;
+
+    return (curr_peer->is_responder);
+}
+
+
 void wlan_hdd_tdls_extract_da(struct sk_buff *skb, u8 *mac)
 {
     memcpy(mac, skb->data, 6);