Wlan: Drop connect after scan for ssid if stop adaptor is issued

During connection if AP is not found in scan list, driver tries
to scan for the ssid (eCsrScanForSsid) and if AP is found,
the connect cmd is queued in sme queue.

During this scan if stop adaptor is called as part of unload,
it will try to issue disconnect, but as there is no ongoing
connect command and sme is not in connected state,
the disconnect command is dropped in sme.

In this case driver tries to abort the scan for ssid to stop
the connect command. But a condition arise when scan for ssid
is already completed before abort was issued and thus connect
command is issued.

If this connect command is successful, it will send ADD BSS to
firmware.

Now as stop adapter failed to send disconnect, stop request
will be sent to firmware without DEL BSS. This leads to crash.

To avoid this don't issue connect after scan for ssid, if stop
adapter has called disconnect.

Change-Id: I5d61bf3d6831674e3241b10bded04fc025fd2181
CRs-Fixed: 975008
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index adc346b..adeeba3 100755
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -7398,13 +7398,17 @@
                 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
                                             pAdapter->sessionId, 
                                             eCSR_DISCONNECT_REASON_UNSPECIFIED);
-            //success implies disconnect command got queued up successfully
-            if(halStatus == eHAL_STATUS_SUCCESS)
+            /* Success implies disconnect command got queued up successfully
+             * Or cmd not queued as scan for SSID is in progress
+             */
+            if((eHAL_STATUS_SUCCESS == halStatus) ||
+               (eHAL_STATUS_CMD_NOT_QUEUED == halStatus))
             {
                ret = wait_for_completion_interruptible_timeout(
                           &pAdapter->disconnect_comp_var,
                            msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
-               if (ret <= 0)
+               if (ret <= 0 &&
+                   (eHAL_STATUS_CMD_NOT_QUEUED != halStatus))
                {
                    hddLog(VOS_TRACE_LEVEL_ERROR,
                           "%s: wait on disconnect_comp_var failed %ld",
diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h
index 9d7338e..0d2d51b 100644
--- a/CORE/SME/inc/csrApi.h
+++ b/CORE/SME/inc/csrApi.h
@@ -651,6 +651,8 @@
     eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED,
     // Participating in a Infra network and connected to a peer
     eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED,
+    /* Disconnecting with AP or stop connecting process */
+    eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTING,
 
 }eCsrConnectState;
 
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index 1e78c64..befe4c2 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -6861,6 +6861,19 @@
 #ifdef FEATURE_WLAN_BTAMP_UT_RF
     pSession->maxRetryCount = CSR_JOIN_MAX_RETRY_COUNT; 
 #endif
+    /*
+     * If roamSession.connectState is disconnecting that mean
+     * disconnect/stop adapter was received with scan for ssid
+     * in progress and dropped. This state will ensure that
+     * connect will not be issued from scan for ssid completion.
+     * Thus if this fresh connect also issue scan for ssid the connect
+     * command will be dropped assuming disconnect is in progress.
+     * Thus reset connectState here
+     */
+    if (eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTING ==
+         pMac->roam.roamSession[sessionId].connectState)
+        pMac->roam.roamSession[sessionId].connectState =
+                       eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
     if(CSR_INVALID_SCANRESULT_HANDLE != hBssListIn)
     {
         smsLog(pMac, LOG1, FL("is called with BSSList"));
@@ -7452,6 +7465,8 @@
     }
     else
     {
+        pMac->roam.roamSession[sessionId].connectState =
+            eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTING;
         csrScanAbortScanForSSID(pMac, sessionId);
         status = eHAL_STATUS_CMD_NOT_QUEUED;
         smsLog(pMac, LOGE,
diff --git a/CORE/SME/src/csr/csrApiScan.c b/CORE/SME/src/csr/csrApiScan.c
index 1b7111b..c247f48 100644
--- a/CORE/SME/src/csr/csrApiScan.c
+++ b/CORE/SME/src/csr/csrApiScan.c
@@ -1699,8 +1699,13 @@
             smsLog(pMac, LOGE, FL("session %d not found"), sessionId);
             break;
         }
-        /* If Disconnect is already issued from HDD no need to issue connect */
-        if (pSession->abortConnection)
+        /* If Disconnect is already issued from HDD no need to issue connect
+         * pSession->abortConnection will not be set in case of try
+         * disconnect or hdd stop adaptor use connectState for these cases.
+         */
+        if (pSession->abortConnection ||
+            (pMac->roam.roamSession[sessionId].connectState ==
+            eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTING))
         {
            smsLog(pMac, LOGE,
               FL("Disconnect in progress, no need to issue connect"));