wlan: Use Reassociation during BSS Transition

qcacld-2.0 to prima propagation

The BSS transition request is handled by the supplicant.
The supplicant upon receiving the request will issue a
connect request to the driver with a hint of prev_bssid
telling the driver to perform a re-association.
Use this hint in the driver and initiate a re-association.
While doing the re-association, there is no need to do a
scan if the target AP is already present in the scan cache.
Optimize the re-association code to not do a scan if not
necessary in this particular case.

Git-commit:ca5977a93f42553da18a4e6638637bb577f706f7
Change-Id: Idf1a7058009a8d2082bc1742dca1364cf59c405b
CRs-Fixed: 1010596
diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h
index caa69c8..0a93a95 100644
--- a/CORE/SME/inc/csrApi.h
+++ b/CORE/SME/inc/csrApi.h
@@ -1497,22 +1497,21 @@
 #define CSR_INVALID_SCANRESULT_HANDLE       (NULL)
 
 #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
-typedef enum {
-    REASSOC     = 0,
-    FASTREASSOC = 1
-} handoff_src;
-
 typedef struct tagCsrHandoffRequest
 {
     tCsrBssid bssid;
     tANI_U8 channel;
-#ifndef QCA_WIFI_ISOC
     /* To check if its a REASSOC or a FASTREASSOC IOCTL */
     tANI_U8 src;
-#endif
 }tCsrHandoffRequest;
 #endif
 
+typedef enum {
+    REASSOC     = 0,
+    FASTREASSOC = 1,
+    CONNECT_CMD_USERSPACE = 2,
+} handoff_src;
+
 #if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
 typedef struct tagCsrEseBeaconReqParams
 {
diff --git a/CORE/SME/src/csr/csrNeighborRoam.c b/CORE/SME/src/csr/csrNeighborRoam.c
index cb9c4eb..b889aa6 100644
--- a/CORE/SME/src/csr/csrNeighborRoam.c
+++ b/CORE/SME/src/csr/csrNeighborRoam.c
@@ -1307,6 +1307,8 @@
 #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
     if (pNeighborRoamInfo->uOsRequestedHandoff)
     {
+
+        smsLog(pMac, LOG1, FL("OS Requested Handoff"));
         pScanFilter->BSSIDs.numOfBSSIDs = 1;
         pScanFilter->BSSIDs.bssid = vos_mem_malloc(sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs);
         if (NULL == pScanFilter->BSSIDs.bssid)
@@ -5340,6 +5342,10 @@
     tCsrRoamProfile *pProfile = NULL;
     tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, pNeighborRoamInfo->csrSessionId );
     tANI_U8 i = 0;
+    uint8_t roam_now = 0;
+    uint8_t roamable_ap_count = 0;
+    tCsrScanResultFilter    scan_filter;
+    tScanResultHandle       scan_result;
 
     if (NULL == pSession)
     {
@@ -5395,13 +5401,30 @@
         }
         pProfile->ChannelInfo.ChannelList[0] = pNeighborRoamInfo->handoffReqInfo.channel;
 
-        //clean up csr cache first
-        //csrScanFlushSelectiveResult(pMac, VOS_FALSE);
-        //do a SSID scan
-        status = csrScanForSSID(pMac, pNeighborRoamInfo->csrSessionId, pProfile, roamId, FALSE);
-        if(!HAL_STATUS_SUCCESS(status))
-        {
-            smsLog(pMac, LOGE, FL("SSID scan failed"));
+        /*
+         * For User space connect requests, the scan has already been done.
+         * So, check if the BSS descriptor exists in the scan cache and
+         * proceed with the handoff instead of a redundant scan again.
+         */
+        if (pNeighborRoamInfo->handoffReqInfo.src == CONNECT_CMD_USERSPACE) {
+            smsLog(pMac, LOG1, FL("Connect cmd with bssid within same ESS"));
+            status = csrNeighborRoamPrepareScanProfileFilter(
+                                               pMac, &scan_filter);
+            smsLog(pMac, LOG1, FL("Filter creation status = %d"), status);
+            status = csrScanGetResult(pMac, &scan_filter, &scan_result);
+            roam_now = csrNeighborRoamProcessScanResults(pMac, &scan_result);
+            roamable_ap_count = csrLLCount(&pNeighborRoamInfo->roamableAPList);
+            csrFreeScanFilter(pMac, &scan_filter);
+            smsLog(pMac, LOG1, FL("roam_now=%d, roamable_ap_count=%d"),
+                   roam_now, roamable_ap_count);
+        }
+        if (roam_now && roamable_ap_count) {
+            csrNeighborRoamTriggerHandoff(pMac, pNeighborRoamInfo);
+        } else {
+            status = csrScanForSSID(pMac, pSession->sessionId,
+                                           pProfile, roamId, FALSE);
+            if(!HAL_STATUS_SUCCESS(status))
+               smsLog(pMac, LOGE, FL("SSID scan failed"));
         }
     }while(0);