prima: Enable/Disable TDLS only for p2p interfaces

Currently, Disable and Teardown functionality invoked for
TDLS during concurrency only if device mode is other than
WLAN_HDD_INFRA_STATION and during p2p disconnection since the
device mode will be either WLAN_HDD_P2P_CLIENT/WLAN_HDD_P2P_GO
which would invoke Disable and teardown functionality again and
thus disabling TDLS and connection attempt was not made.

To mitigate:
Include check for device mode and invoke Disable and
Teardown TDLS functionality only if device mode is
WLAN_HDD_P2P_DEVICE and interface type is
NL80211_IFTYPE_P2P_CLIENT/NL80211_IFTYPE_P2P_GO.

Change-Id: Ia2c272a2975c83aebff147ceb6b2fb57a90182b2
CRs-Fixed: 891225
diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c
index a522c7d..2fe4999 100644
--- a/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/CORE/HDD/src/wlan_hdd_assoc.c
@@ -61,9 +61,7 @@
 #include "csrInsideApi.h"
 #include "wlan_hdd_p2p.h"
 #include <vos_sched.h>
-#ifdef FEATURE_WLAN_TDLS
 #include "wlan_hdd_tdls.h"
-#endif
 #include "sme_Api.h"
 #include "wlan_hdd_hostapd.h"
 #include "vos_utils.h"
@@ -1087,18 +1085,14 @@
                    cfg80211_disconnected(dev, WLAN_REASON_UNSPECIFIED, NULL, 0, GFP_KERNEL);
                }
             }
-            if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
-                          (TRUE == sme_IsFeatureSupportedByFW(TDLS)) &&
-                          (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode_last ||
-                           eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY ==
-                                           pHddCtx->tdls_mode_last)) {
-                if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
-                    /* Enable TDLS support Once P2P session ends since
-                     * upond detection of concurrency TDLS would be disabled
-                     */
-                    wlan_hdd_tdls_set_mode(pHddCtx, pHddCtx->tdls_mode_last,
-                                           FALSE);
+
+            if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
+            {
+                hddLog(LOG1,
+                       FL("P2P client is getting removed and we are tryig to re-enable TDLS"));
+                wlan_hdd_tdls_reenable(pHddCtx);
             }
+
             //If the Device Mode is Station
             // and the P2P Client is Connected
             //Enable BMPS
@@ -1960,6 +1954,14 @@
          * completed operation - with a ASSOCIATION_FAILURE status.*/
         if ( eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus &&  !hddDisconInProgress )
         {
+
+            if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
+            {
+                hddLog(LOG1,
+                       FL("Assoication Failure for P2P client and we are trying to re-enable TDLS"));
+                wlan_hdd_tdls_reenable(pHddCtx);
+            }
+
             if (pRoamInfo)
                 hddLog(VOS_TRACE_LEVEL_ERROR,
                      "%s: send connect failure to nl80211:"
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index ab23e73..6869885 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -8232,12 +8232,20 @@
     /* Reset the current device mode bit mask*/
     wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
 
-    /* Notify Mode change in case of concurrency.
-     * Below function invokes TDLS teardown Functionality Since TDLS is
-     * not Supported in case of concurrency i.e Once P2P session
-     * is detected disable offchannel and teardown TDLS links
-     */
-    hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
+    if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
+        ((type == NL80211_IFTYPE_P2P_CLIENT) ||
+         (type == NL80211_IFTYPE_P2P_GO)))
+    {
+        /* Notify Mode change in case of concurrency.
+         * Below function invokes TDLS teardown Functionality Since TDLS is
+         * not Supported in case of concurrency i.e Once P2P session
+         * is detected disable offchannel and teardown TDLS links
+         */
+        hddLog(LOG1,
+               FL("Device mode = %d Interface type = %d"),
+               pAdapter->device_mode, type);
+        hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
+    }
 
     if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
       || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index 53fdc29..26cec89 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -75,6 +75,7 @@
 #include "wlan_nlink_common.h"
 #include "wlan_btc_svc.h"
 #include <bap_hdd_main.h>
+#include "wlan_hdd_tdls.h"
 #include "wlan_hdd_p2p.h"
 #include "cfgApi.h"
 #include "wniCfg.h"
@@ -924,21 +925,11 @@
 
             pHddApCtx->operatingChannel = 0; //Invalidate the channel info.
 
-            if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
-                    (TRUE == sme_IsFeatureSupportedByFW(TDLS)) &&
-                    (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode_last ||
-                     eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY ==
-                                                pHddCtx->tdls_mode_last))
+            if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
             {
-                if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
-                {
-                    /* Enable TDLS support Once P2P session ends since
-                     * upond detection of concurrency TDLS would be disabled
-                     */
-                    hddLog(LOG1, FL("Enable TDLS support"));
-                    wlan_hdd_tdls_set_mode(pHddCtx, pHddCtx->tdls_mode_last,
-                                           FALSE);
-                }
+                hddLog(LOG1,
+                       FL("P2P Go is getting removed and we are trying to re-enable TDLS"));
+                wlan_hdd_tdls_reenable(pHddCtx);
             }
 
             goto stopbss;
diff --git a/CORE/HDD/src/wlan_hdd_p2p.c b/CORE/HDD/src/wlan_hdd_p2p.c
index 6838547..d421e81 100644
--- a/CORE/HDD/src/wlan_hdd_p2p.c
+++ b/CORE/HDD/src/wlan_hdd_p2p.c
@@ -2032,12 +2032,17 @@
 #endif
     }
 
-    /* Below function Notifies Mode change and
-     * If p2p session is detected then invokes functionality to
-     * Teardown TDLS links and disable offchannel if any. Since
-     * TDLS is not supported in case of concurrency.
-     */
-    hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
+    if ((type == NL80211_IFTYPE_P2P_CLIENT) ||
+          (type == NL80211_IFTYPE_P2P_GO))
+    {
+        /* Below function Notifies Mode change and
+         * If p2p session is detected then invokes functionality to
+         * Teardown TDLS links and disable offchannel if any. Since
+         * TDLS is not supported in case of concurrency.
+         */
+        hddLog(LOG1, FL("Interface type = %d"), type);
+        hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
+    }
 
     EXIT();
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
diff --git a/CORE/HDD/src/wlan_hdd_tdls.c b/CORE/HDD/src/wlan_hdd_tdls.c
index 636cfaf..3ab746a 100644
--- a/CORE/HDD/src/wlan_hdd_tdls.c
+++ b/CORE/HDD/src/wlan_hdd_tdls.c
@@ -178,7 +178,6 @@
  */
 void hdd_tdls_notify_mode_change(hdd_adapter_t *adapter, hdd_context_t *hddctx)
 {
-    if (adapter->device_mode != WLAN_HDD_INFRA_STATION)
         wlan_hdd_tdls_disable_offchan_and_teardown_links(hddctx);
 }
 
@@ -3271,5 +3270,43 @@
             "mac : " MAC_ADDRESS_STR "rssi is %d",
             MAC_ADDR_ARRAY(mac), rssiAvg);
 }
-/*EXT TDLS*/
 
+/**
+ * wlan_hdd_tdls_reenable() - Re-Enable TDLS
+ * @hddctx: pointer to hdd context
+ *
+ * Function re-enable's TDLS which might be disabled during concurrency
+ *
+ * Return: None
+ */
+void wlan_hdd_tdls_reenable(hdd_context_t *pHddCtx)
+{
+
+    if ((TRUE != pHddCtx->cfg_ini->fEnableTDLSSupport) ||
+        (TRUE != sme_IsFeatureSupportedByFW(TDLS))) {
+        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                  FL("tdls support not enabled"));
+        return;
+    }
+
+    /* if tdls is not enabled or BtCoex is on then don't revert tdls mode */
+    if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
+        (pHddCtx->is_tdls_btc_enabled == FALSE)) {
+        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                  FL("btc disable tdls so no need to enable: Mode=%d, BTC enabled=%d"),
+                  pHddCtx->tdls_mode, pHddCtx->is_tdls_btc_enabled);
+            return;
+    }
+
+    if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode_last ||
+         eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY ==
+                               pHddCtx->tdls_mode_last) {
+            /* Enable TDLS support Once P2P session ends since
+             * upond detection of concurrency TDLS might be disabled
+             */
+             hddLog(LOG1, FL("TDLS mode set to %d"), pHddCtx->tdls_mode_last);
+             wlan_hdd_tdls_set_mode(pHddCtx, pHddCtx->tdls_mode_last,
+                                    FALSE);
+    }
+}
+/*EXT TDLS*/