From 1ba994826c20a5251759f45c105f8a551e19ac56 Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Fri, 19 Oct 2018 02:57:29 -0400 Subject: [PATCH] qcacld-3.0: Get proper channel after scan for SSID If there is no scan cache available, csr_roam_connect will trigger a scan and after scan complete csr will call csr_roam_issue_connect to connect one of candidate BSS. And driver only checks the first candidate BSS's channel for HW mode change after scan complete. The issue is if connect first candidate failed, the next or other candidate BSS may require DBS in concurrency condition and the check policy_mgr_is_hwmode_set_for_given_chnl will be failed. To avoid such the hw mode check failed, we need to change hw mode early if any of BSS requires DBS mode before try to connect the BSS candidate in list one by one. Add API csr_scan_get_channel_for_hw_mode_change which returns DBS required candidate channel in BSS list if available, otherwise returns the first candidate's channel. Change-Id: I42862f100ee56ada41d6397346937219d0e688df CRs-Fixed: 2335075 --- core/sme/inc/sme_api.h | 3 ++- core/sme/inc/sme_inside.h | 2 ++ core/sme/src/common/sme_api.c | 11 +++++--- core/sme/src/csr/csr_api_scan.c | 43 +++++++++++++++++++++++++++++-- core/sme/src/csr/csr_inside_api.h | 23 +++++++++++++++++ 5 files changed, 76 insertions(+), 6 deletions(-) diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index af1b6666dff9..80be7deb2ed7 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -1343,7 +1343,8 @@ void sme_register_hw_mode_trans_cb(tHalHandle hal, QDF_STATUS sme_nss_update_request(uint32_t vdev_id, uint8_t new_nss, policy_mgr_nss_update_cback cback, uint8_t next_action, struct wlan_objmgr_psoc *psoc, - enum policy_mgr_conn_update_reason reason); + enum policy_mgr_conn_update_reason reason, + uint32_t original_vdev_id); typedef void (*sme_peer_authorized_fp) (uint32_t vdev_id); QDF_STATUS sme_set_peer_authorized(uint8_t *peer_addr, diff --git a/core/sme/inc/sme_inside.h b/core/sme/inc/sme_inside.h index 4d1db471895d..34875e657734 100644 --- a/core/sme/inc/sme_inside.h +++ b/core/sme/inc/sme_inside.h @@ -136,6 +136,7 @@ typedef struct s_tdls_cmd { * @context: Adapter context * @next_action: Action to be taken after nss update * @reason: reason for nss update + * @original_vdev_id: original request hwmode change vdev id */ struct s_nss_update_cmd { uint32_t new_nss; @@ -144,6 +145,7 @@ struct s_nss_update_cmd { void *context; uint8_t next_action; enum policy_mgr_conn_update_reason reason; + uint32_t original_vdev_id; }; typedef struct tagSmeCmd { diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index afe5358c56a7..8a0ae5b58096 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -2455,7 +2455,8 @@ static QDF_STATUS sme_process_nss_update_resp(tpAniSirGlobal mac, uint8_t *msg) param->tx_status, param->session_id, command->u.nss_update_cmd.next_action, - command->u.nss_update_cmd.reason); + command->u.nss_update_cmd.reason, + command->u.nss_update_cmd.original_vdev_id); } else { sme_err("Callback does not exisit"); } @@ -13179,6 +13180,7 @@ void sme_register_hw_mode_trans_cb(tHalHandle hal, * @new_nss: the new nss value * @cback: hdd callback * @next_action: next action to happen at policy mgr after beacon update + * @original_vdev_id: original request hwmode change vdev id * * Sends the command to CSR to send to PE * Return: QDF_STATUS_SUCCESS on successful posting @@ -13186,7 +13188,8 @@ void sme_register_hw_mode_trans_cb(tHalHandle hal, QDF_STATUS sme_nss_update_request(uint32_t vdev_id, uint8_t new_nss, policy_mgr_nss_update_cback cback, uint8_t next_action, struct wlan_objmgr_psoc *psoc, - enum policy_mgr_conn_update_reason reason) + enum policy_mgr_conn_update_reason reason, + uint32_t original_vdev_id) { QDF_STATUS status = QDF_STATUS_E_FAILURE; tpAniSirGlobal mac = sme_get_mac_context(); @@ -13213,8 +13216,10 @@ QDF_STATUS sme_nss_update_request(uint32_t vdev_id, cmd->u.nss_update_cmd.context = psoc; cmd->u.nss_update_cmd.next_action = next_action; cmd->u.nss_update_cmd.reason = reason; + cmd->u.nss_update_cmd.original_vdev_id = original_vdev_id; - sme_debug("Queuing e_sme_command_nss_update to CSR"); + sme_debug("Queuing e_sme_command_nss_update to CSR:vdev (%d %d) ss %d r %d", + vdev_id, original_vdev_id, new_nss, reason); csr_queue_sme_command(mac, cmd, false); sme_release_global_lock(&mac->sme); } diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c index 9ae178a1bbec..0eddcff44860 100644 --- a/core/sme/src/csr/csr_api_scan.c +++ b/core/sme/src/csr/csr_api_scan.c @@ -1034,8 +1034,8 @@ static enum csr_scancomplete_nextcommand csr_scan_get_next_command_state( switch (session->scan_info.scan_reason) { case eCsrScanForSsid: sme_debug("Resp for Scan For Ssid"); - channel = policy_mgr_search_and_check_for_session_conc( - mac_ctx->psoc, + channel = csr_scan_get_channel_for_hw_mode_change( + mac_ctx, session_id, session->scan_info.profile); if ((!channel) || scan_status) { @@ -2175,6 +2175,45 @@ end: return channel_id; } +uint8_t +csr_scan_get_channel_for_hw_mode_change( + tpAniSirGlobal mac_ctx, uint32_t session_id, + struct csr_roam_profile *profile) +{ + tScanResultHandle result_handle = NULL; + QDF_STATUS status; + uint8_t first_ap_ch = 0; + uint8_t candidate_chan; + + status = sme_get_ap_channel_from_scan_cache(profile, &result_handle, + &first_ap_ch); + if (status != QDF_STATUS_SUCCESS || !result_handle || !first_ap_ch) { + if (result_handle) + sme_scan_result_purge(result_handle); + sme_err("fail get scan result: status %d first ap ch %d", + status, first_ap_ch); + return 0; + } + if (!policy_mgr_check_for_session_conc(mac_ctx->psoc, session_id, + first_ap_ch)) { + sme_scan_result_purge(result_handle); + sme_err("Conc not allowed for the session %d ch %d", + session_id, first_ap_ch); + return 0; + } + + candidate_chan = csr_get_channel_for_hw_mode_change(mac_ctx, + result_handle, + session_id); + sme_scan_result_purge(result_handle); + if (!candidate_chan) + candidate_chan = first_ap_ch; + sme_debug("session %d hw mode check candidate_chan %d", session_id, + candidate_chan); + + return candidate_chan; +} + static enum wlan_auth_type csr_covert_auth_type_new(eCsrAuthType auth) { switch (auth) { diff --git a/core/sme/src/csr/csr_inside_api.h b/core/sme/src/csr/csr_inside_api.h index 49433802f9f7..fc558a2c2e56 100644 --- a/core/sme/src/csr/csr_inside_api.h +++ b/core/sme/src/csr/csr_inside_api.h @@ -1123,4 +1123,27 @@ uint8_t csr_get_channel_for_hw_mode_change(tpAniSirGlobal mac_ctx, tScanResultHandle result_handle, uint32_t session_id); + +/** + * csr_scan_get_channel_for_hw_mode_change() - This function to find + * out if HW mode change + * is needed for any of + * the candidate AP which + * STA could join + * @mac_ctx: mac context + * @session_id: STA session ID + * @profile: profile + * + * This function is written to find out for any bss from scan + * handle a HW mode change to DBS will be needed or not. + * If there is no candidate AP which requires DBS, this function will return + * the first Candidate AP's chan. + * + * Return: AP channel for which HW mode change will be needed. 0 + * means no candidate AP to connect. + */ +uint8_t +csr_scan_get_channel_for_hw_mode_change( + tpAniSirGlobal mac_ctx, uint32_t session_id, + struct csr_roam_profile *profile); #endif /* CSR_INSIDE_API_H__ */