wlan: Stop connection in progress STA when SAP comes up

Propagation from qcacld-3.0 to prima.

For STA+SAP concurrency support from GUI, first STA connection gets
triggered and while it is in progress, SAP start also comes up. Once
STA association is successful, STA connect event is sent to kernel which
gets queued in kernel workqueue and supplicant won't process M1 received
from AP and send M2 until this NL80211_CONNECT event is received. Workqueue
is not scheduled as RTNL lock is already taken by hostapd thread which has
issued start_bss command to driver. Driver cannot complete start_bss as the
pending command at the head of the SME command pending list is
hw_mode_update for STA session which cannot be processed as SME is in
WAITforKey state for STA interface. The start_bss command for SAP interface
is queued behind the hw_mode_update command and so it cannot be processed
until hw_mode_update command is processed. This causes a deadlock.

Disconnect STA interface first if connection or key exchange is in progress
and then start SAP interface to prevent this deadlock condition.

Change-Id: I2ef5fe0e3bc84e721e6a2baa0dae81c6106c5a8f
CRs-Fixed: 2260683
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 8e991a9..10a69e1 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -10632,10 +10632,6 @@
     EXIT();
 }
 
-/*
- * FUNCTION: wlan_hdd_disconnect
- * This function is used to issue a disconnect request to SME
- */
 int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
 {
     int status, result = 0;
@@ -10988,6 +10984,7 @@
     hdd_config_t *iniConfig;
     v_SINT_t i;
     hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
+    hdd_adapter_t *sta_adapter;
     tSmeConfigParams *psmeConfig;
     v_BOOL_t MFPCapable = VOS_FALSE;
     v_BOOL_t MFPRequired = VOS_FALSE;
@@ -10998,6 +10995,31 @@
     ENTER();
 
     wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
+
+    /*
+     * For STA+SAP concurrency support from GUI, first STA connection gets
+     * triggered and while it is in progress, SAP start also comes up.
+     * Once STA association is successful, STA connect event is sent to
+     * kernel which gets queued in kernel workqueue and supplicant won't
+     * process M1 received from AP and send M2 until this NL80211_CONNECT
+     * event is received. Workqueue is not scheduled as RTNL lock is already
+     * taken by hostapd thread which has issued start_bss command to driver.
+     * Driver cannot complete start_bss as the pending command at the head
+     * of the SME command pending list is hw_mode_update for STA session
+     * which cannot be processed as SME is in WAITforKey state for STA
+     * interface. The start_bss command for SAP interface is queued behind
+     * the hw_mode_update command and so it cannot be processed until
+     * hw_mode_update command is processed. This is causing a deadlock so
+     * disconnect the STA interface first if connection or key exchange is
+     * in progress and then start SAP interface.
+     */
+    sta_adapter = hdd_get_sta_connection_in_progress(pHddCtx);
+    if (sta_adapter) {
+        hddLog(LOG1, FL("Disconnecting STA with session id: %d"),
+               sta_adapter->sessionId);
+        wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
+    }
+
     iniConfig = pHddCtx->cfg_ini;
 
     /* Mark the indoor channel (passive) to disable */