summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSelvaraj, Sridhar <sselvara@qti.qualcomm.com>2016-05-03 17:31:57 +0530
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2016-05-04 19:27:01 +0530
commitca5977a93f42553da18a4e6638637bb577f706f7 (patch)
treed35cdad112f59073f8d83e2dcf4a671ce45bdb3f
parent5ad6cc46eda9e6d7195c353730a22427b9937283 (diff)
qcacld-2.0: Use Reassociation during BSS Transition
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. Change-Id: Idf1a7058009a8d2082bc1742dca1364cf59c405b CRs-Fixed: 1010596
-rw-r--r--CORE/HDD/inc/wlan_hdd_main.h3
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg80211.c39
-rw-r--r--CORE/HDD/src/wlan_hdd_main.c29
-rw-r--r--CORE/SME/inc/csrApi.h13
-rw-r--r--CORE/SME/src/csr/csrNeighborRoam.c36
5 files changed, 94 insertions, 26 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 0fd2ed9ed98e..1d63c2ea397e 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -2216,4 +2216,7 @@ static inline void wlan_hdd_restart_sap(hdd_adapter_t *ap_adapter)
{
}
#endif
+
+int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
+ const tANI_U8 channel, const handoff_src src);
#endif // end #if !defined( WLAN_HDD_MAIN_H )
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index c8427d1adae5..3967a606bc8b 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -18566,6 +18566,41 @@ disconnected:
return result;
}
+/**
+ * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
+ * @adapter: Pointer to the HDD adapter
+ * @req: Pointer to the structure cfg_connect_params receieved from user space
+ *
+ * This function will start reassociation if bssid hint, channel hint and
+ * previous bssid parameters are present in the connect request
+ *
+ * Return: success if reassociation is happening
+ * Error code if reassociation is not permitted or not happening
+ */
+#ifdef CFG80211_CONNECT_PREV_BSSID
+static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
+ struct cfg80211_connect_params *req)
+{
+ int status = -EPERM;
+ if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
+ hddLog(VOS_TRACE_LEVEL_INFO,
+ FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
+ req->channel_hint->hw_value,
+ MAC_ADDR_ARRAY(req->bssid_hint));
+ status = hdd_reassoc(adapter, req->bssid_hint,
+ req->channel_hint->hw_value,
+ CONNECT_CMD_USERSPACE);
+ }
+ return status;
+}
+#else
+static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
+ struct cfg80211_connect_params *req)
+{
+ return -EPERM;
+}
+#endif
+
/*
* FUNCTION: __wlan_hdd_cfg80211_connect
* This function is used to start the association process
@@ -18614,6 +18649,10 @@ static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
if (0 != status)
return status;
+ status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
+ if (0 == status)
+ return status;
+
#if defined(FEATURE_WLAN_LFR) && defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD)
wlan_hdd_disable_roaming(pAdapter);
#endif
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 7b04621644db..0df86d6bd6ab 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -1850,18 +1850,17 @@ static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
return VOS_STATUS_SUCCESS;
}
-/*
- \brief hdd_reassoc() - perform a user space-directed reassoc
-
- \param - pAdapter - Adapter upon which the command was received
- \param - bssid - BSSID with which to reassociate
- \param - channel - channel upon which to reassociate
-
- \return - 0 for success non-zero for failure
-
- --------------------------------------------------------------------------*/
-static int
-hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid, const tANI_U8 channel)
+/**
+ * hdd_reassoc() - perform a user space directed reassoc
+ * @pAdapter: Adapter upon which the command was received
+ * @bssid: BSSID with which to reassociate
+ * @channel: channel upon which to reassociate
+ * @src: The source for the trigger of this action
+ *
+ * Return: 0 for success non-zero for failure
+ */
+int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
+ const tANI_U8 channel, const handoff_src src)
{
hdd_station_ctx_t *pHddStaCtx;
int ret = 0;
@@ -1901,7 +1900,7 @@ hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid, const tANI_U8 channel
hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
handoffInfo.channel = channel;
- handoffInfo.src = REASSOC;
+ handoffInfo.src = src;
memcpy(handoffInfo.bssid, bssid, sizeof(tSirMacAddr));
sme_HandoffRequest(pHddCtx->hHal, pAdapter->sessionId, &handoffInfo);
}
@@ -1942,7 +1941,7 @@ hdd_parse_reassoc_v1(hdd_adapter_t *pAdapter, const char *command)
hddLog(VOS_TRACE_LEVEL_ERROR,
"%s: Failed to parse reassoc command data", __func__);
} else {
- ret = hdd_reassoc(pAdapter, bssid, channel);
+ ret = hdd_reassoc(pAdapter, bssid, channel, REASSOC);
}
return ret;
}
@@ -1976,7 +1975,7 @@ hdd_parse_reassoc_v2(hdd_adapter_t *pAdapter,
hddLog(LOGE, "%s: MAC address parsing failed", __func__);
ret = -EINVAL;
} else {
- ret = hdd_reassoc(pAdapter, bssid, params.channel);
+ ret = hdd_reassoc(pAdapter, bssid, params.channel, REASSOC);
}
return ret;
}
diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h
index 18e13f1a23bb..36d9e7dc0832 100644
--- a/CORE/SME/inc/csrApi.h
+++ b/CORE/SME/inc/csrApi.h
@@ -1672,12 +1672,6 @@ typedef void * tScanResultHandle;
#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;
@@ -1686,6 +1680,13 @@ typedef struct tagCsrHandoffRequest
}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 5354b8c6c1a6..b48575d592a8 100644
--- a/CORE/SME/src/csr/csrNeighborRoam.c
+++ b/CORE/SME/src/csr/csrNeighborRoam.c
@@ -1818,6 +1818,9 @@ csrNeighborRoamPrepareScanProfileFilter(tpAniSirGlobal pMac,
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
if (pNeighborRoamInfo->uOsRequestedHandoff)
{
+
+ VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
+ FL("OS Requested Handoff"));
pScanFilter->BSSIDs.numOfBSSIDs = 1;
pScanFilter->BSSIDs.bssid = vos_mem_malloc(sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs);
if (NULL == pScanFilter->BSSIDs.bssid)
@@ -6071,6 +6074,10 @@ eHalStatus csrNeighborRoamProcessHandoffReq(tpAniSirGlobal pMac,
tCsrRoamProfile *pProfile = NULL;
tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
tANI_U8 i = 0;
+ uint8_t roam_now = 0;
+ uint8_t roamable_ap_count = 0;
+ tCsrScanResultFilter scan_filter;
+ tScanResultHandle scan_result;
if (NULL == pSession)
{
@@ -6134,11 +6141,30 @@ eHalStatus csrNeighborRoamProcessHandoffReq(tpAniSirGlobal pMac,
}
pProfile->ChannelInfo.ChannelList[0] = pNeighborRoamInfo->handoffReqInfo.channel;
- //do a SSID scan
- status = csrScanForSSID(pMac, sessionId, 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, sessionId);
+ smsLog(pMac, LOG1, FL("Filter creation status = %d"), status);
+ status = csrScanGetResult(pMac, &scan_filter, &scan_result);
+ roam_now = csrNeighborRoamProcessScanResults(pMac, sessionId,
+ &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, sessionId);
+ } else {
+ status = csrScanForSSID(pMac, sessionId, pProfile, roamId, FALSE);
+ if(!HAL_STATUS_SUCCESS(status))
+ smsLog(pMac, LOGE, FL("SSID scan failed"));
}
}while(0);