Ping stalls from TDLS discovery to enable link

Initiator to postpone TX direct packet until either receiving
direct packet or TDLS_WAIT_TIME_INITIATOR (300 msec)
Reponder to exit BMPS before sending TDLS setup or discovery
response.
Do not allow BMPS if TDLS is ongoing.
Rewrite TL suspend/resume routine to handle up to 41 STA.

Change-Id: Iae353d6bef0c225e357fe9e9153625bafff15a6c
CRs-Fixed: 466258
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 736d560..62aa33b 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -6949,12 +6949,6 @@
         return -ENOTSUPP;
     }
 
-    if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
-        (SIR_MAC_TDLS_DIS_RSP == action_code))
-    {
-        wlan_hdd_tdls_set_cap (pAdapter, peer, eTDLS_CAP_SUPPORTED);
-    }
-
     /* other than teardown frame, other mgmt frames are not sent if disabled */
     if (SIR_MAC_TDLS_TEARDOWN != action_code)
     {
@@ -7055,6 +7049,18 @@
        }
     }
 
+    if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
+        (SIR_MAC_TDLS_DIS_RSP == action_code))
+    {
+        if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
+        {
+            VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
+                       "%s: Sending Disc/Setup Rsp Frame.Disable BMPS", __func__);
+            hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
+        }
+        wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
+    }
+
     INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
 
     status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
@@ -7064,7 +7070,8 @@
     {
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
-        return -EPERM;
+        wlan_hdd_tdls_check_bmps(pAdapter);
+        goto error;
     }
 
     /* not block discovery request, as it is called from timer callback */
@@ -7080,12 +7087,16 @@
             VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                       "%s: Mgmt Tx Completion failed status %ld TxCompletion %lu",
                       __func__, rc, pAdapter->mgmtTxCompletionStatus);
+            wlan_hdd_tdls_check_bmps(pAdapter);
             goto error;
         }
     }
 
     if (max_sta_failed)
+    {
+      wlan_hdd_tdls_check_bmps(pAdapter);
       return max_sta_failed;
+    }
 
     if (SIR_MAC_TDLS_SETUP_RSP == action_code)
     {
@@ -7183,6 +7194,18 @@
                     status = hdd_roamRegisterTDLSSTA( pAdapter, peer, pTdlsPeer->staId, pTdlsPeer->signature);
                     if (VOS_STATUS_SUCCESS == status)
                     {
+                        if (pTdlsPeer->is_responder == 0)
+                        {
+                            v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
+
+                            wlan_hdd_tdls_timer_restart(pAdapter,
+                                                        &pTdlsPeer->initiatorWaitTimeoutTimer,
+                                                       WAIT_TIME_TDLS_INITIATOR);
+                            /* suspend initiator TX until it receives direct packet from the
+                            reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
+                            WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
+                                                   &staId, NULL);
+                        }
                         wlan_hdd_tdls_increment_peer_count(pAdapter);
                     }
                     wlan_hdd_tdls_check_bmps(pAdapter);