From ca5977a93f42553da18a4e6638637bb577f706f7 Mon Sep 17 00:00:00 2001 From: "Selvaraj, Sridhar" Date: Tue, 3 May 2016 17:31:57 +0530 Subject: 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 --- CORE/HDD/inc/wlan_hdd_main.h | 3 +++ CORE/HDD/src/wlan_hdd_cfg80211.c | 39 ++++++++++++++++++++++++++++++++++++++ CORE/HDD/src/wlan_hdd_main.c | 29 ++++++++++++++-------------- CORE/SME/inc/csrApi.h | 13 +++++++------ CORE/SME/src/csr/csrNeighborRoam.c | 36 ++++++++++++++++++++++++++++++----- 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); -- cgit v1.2.3