qcacld-3.0: Use Reassociation during BSS Transition

This is qcacld-2.0 to qcacld-3.0 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.

Change-Id: Idf1a7058009a8d2082bc1742dca1364cf59c405b
CRs-Fixed: 1010596
This commit is contained in:
Varun Reddy Yeturu 2016-07-18 15:58:47 -07:00 • committed by Anjaneedevi Kapparapu
commit 3e91dad283
7 changed files with 97 additions and 18 deletions

View file

@ -1737,4 +1737,7 @@ static inline int wlan_hdd_nl_init(hdd_context_t *hdd_ctx)
#endif
QDF_STATUS hdd_sme_close_session_callback(void *pContext);
int hdd_reassoc(hdd_adapter_t *adapter, const uint8_t *bssid,
const uint8_t channel, const handoff_src src);
#endif /* end #if !defined(WLAN_HDD_MAIN_H) */

View file

@ -10409,6 +10409,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
/**
* __wlan_hdd_cfg80211_connect() - cfg80211 connect api
* @wiphy: Pointer to wiphy
@ -10464,6 +10499,11 @@ static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy,
status = wlan_hdd_validate_context(pHddCtx);
if (0 != status)
return status;
status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
if (0 == status)
return status;
if (req->channel) {
if (!cds_allow_concurrency(
cds_convert_device_mode_to_qdf_type(
@ -10480,6 +10520,7 @@ static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy,
return -ECONNREFUSED;
}
}
wlan_hdd_disable_roaming(pAdapter);
/*Try disconnecting if already in connected state */

View file

@ -842,14 +842,14 @@ static int hdd_parse_reassoc_command_v1_data(const uint8_t *pValue,
* @adapter: 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
*
* This function performs a userspace-directed reassoc operation
*
* Return: 0 for success non-zero for failure
*/
static int
hdd_reassoc(hdd_adapter_t *adapter, const uint8_t *bssid,
const uint8_t channel)
int hdd_reassoc(hdd_adapter_t *adapter, const uint8_t *bssid,
const uint8_t channel, const handoff_src src)
{
hdd_station_ctx_t *pHddStaCtx;
int ret = 0;
@ -895,7 +895,7 @@ hdd_reassoc(hdd_adapter_t *adapter, const uint8_t *bssid,
hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
handoffInfo.channel = channel;
handoffInfo.src = REASSOC;
handoffInfo.src = src;
qdf_mem_copy(handoffInfo.bssid.bytes, bssid, QDF_MAC_ADDR_SIZE);
sme_handoff_request(hdd_ctx->hHal, adapter->sessionId,
&handoffInfo);
@ -931,7 +931,7 @@ static int hdd_parse_reassoc_v1(hdd_adapter_t *adapter, const char *command)
if (ret) {
hdd_err("Failed to parse reassoc command data");
} else {
ret = hdd_reassoc(adapter, bssid, channel);
ret = hdd_reassoc(adapter, bssid, channel, REASSOC);
}
return ret;
}
@ -961,7 +961,7 @@ static int hdd_parse_reassoc_v2(hdd_adapter_t *adapter, const char *command)
hdd_err("MAC address parsing failed");
ret = -EINVAL;
} else {
ret = hdd_reassoc(adapter, bssid, params.channel);
ret = hdd_reassoc(adapter, bssid, params.channel, REASSOC);
}
return ret;
}

View file

@ -1570,7 +1570,8 @@ typedef void *tScanResultHandle;
typedef enum {
REASSOC = 0,
FASTREASSOC = 1
FASTREASSOC = 1,
CONNECT_CMD_USERSPACE = 2,
} handoff_src;
typedef struct tagCsrHandoffRequest {

View file

@ -1422,4 +1422,9 @@ enum tQDF_ADAPTER_MODE csr_get_session_persona(tpAniSirGlobal pmac,
void csr_roam_substate_change(tpAniSirGlobal pMac, eCsrRoamSubState NewSubstate,
uint32_t sessionId);
void csr_neighbor_roam_process_scan_results(tpAniSirGlobal mac_ctx,
uint8_t sessionid, tScanResultHandle *scan_results_list);
void csr_neighbor_roam_trigger_handoff(tpAniSirGlobal mac_ctx,
uint8_t session_id);
#endif

View file

@ -142,10 +142,8 @@ QDF_STATUS csr_roam_issue_reassociate_cmd(tpAniSirGlobal pMac,
* Return: void
*/
static void
csr_neighbor_roam_process_scan_results(tpAniSirGlobal mac_ctx,
uint8_t sessionid,
tScanResultHandle *scan_results_list)
void csr_neighbor_roam_process_scan_results(tpAniSirGlobal mac_ctx,
uint8_t sessionid, tScanResultHandle *scan_results_list)
{
tCsrScanResultInfo *scan_result;
tpCsrNeighborRoamControlInfo n_roam_info =
@ -356,8 +354,8 @@ csr_neighbor_roam_process_scan_results(tpAniSirGlobal mac_ctx,
*
* Return: None
*/
static void csr_neighbor_roam_trigger_handoff(tpAniSirGlobal mac_ctx,
uint8_t session_id)
void csr_neighbor_roam_trigger_handoff(tpAniSirGlobal mac_ctx,
uint8_t session_id)
{
if (csr_roam_is_fast_roam_enabled(mac_ctx, session_id))
csr_neighbor_roam_issue_preauth_req(mac_ctx, session_id);

View file

@ -371,6 +371,8 @@ csr_neighbor_roam_prepare_scan_profile_filter(tpAniSirGlobal pMac,
pScanFilter->scan_filter_for_roam = 1;
/* only for HDD requested handoff fill in the BSSID in the filter */
if (nbr_roam_info->uOsRequestedHandoff) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
FL("OS Requested Handoff"));
pScanFilter->BSSIDs.numOfBSSIDs = 1;
pScanFilter->BSSIDs.bssid =
qdf_mem_malloc(sizeof(tSirMacAddr) *
@ -1494,6 +1496,10 @@ QDF_STATUS csr_neighbor_roam_process_handoff_req(
tCsrRoamProfile *profile = NULL;
tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
uint8_t i = 0;
uint8_t roam_now = 0;
uint8_t roamable_ap_count = 0;
tCsrScanResultFilter scan_filter;
tScanResultHandle scan_result;
if (NULL == session) {
sms_log(mac_ctx, LOGE, FL("session is NULL "));
@ -1553,11 +1559,36 @@ QDF_STATUS csr_neighbor_roam_process_handoff_req(
profile->ChannelInfo.ChannelList[0] =
roam_ctrl_info->handoffReqInfo.channel;
/* do a SSID scan */
status =
csr_scan_for_ssid(mac_ctx, session_id, profile, roam_id, false);
if (!QDF_IS_STATUS_SUCCESS(status)) {
sms_log(mac_ctx, 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 (roam_ctrl_info->handoffReqInfo.src == CONNECT_CMD_USERSPACE) {
sms_log(mac_ctx, LOG1,
FL("Connect cmd with bssid within same ESS"));
status = csr_neighbor_roam_prepare_scan_profile_filter(mac_ctx,
&scan_filter,
session_id);
sms_log(mac_ctx, LOG1, FL("Filter creation status = %d"),
status);
status = csr_scan_get_result(mac_ctx, &scan_filter,
&scan_result);
csr_neighbor_roam_process_scan_results(mac_ctx, session_id,
&scan_result);
roamable_ap_count = csr_ll_count(
&roam_ctrl_info->roamableAPList);
csr_free_scan_filter(mac_ctx, &scan_filter);
sms_log(mac_ctx, LOG1, FL("roam_now=%d, roamable_ap_count=%d"),
roam_now, roamable_ap_count);
}
if (roam_now && roamable_ap_count) {
csr_neighbor_roam_trigger_handoff(mac_ctx, session_id);
} else {
status = csr_scan_for_ssid(mac_ctx, session_id, profile,
roam_id, false);
if (status != QDF_STATUS_SUCCESS)
sms_log(mac_ctx, LOGE, FL("SSID scan failed"));
}
end: