diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c index f27d43acca..6223e64fe4 100644 --- a/components/mlme/core/src/wlan_mlme_main.c +++ b/components/mlme/core/src/wlan_mlme_main.c @@ -2312,6 +2312,8 @@ static void mlme_init_reg_cfg(struct wlan_objmgr_psoc *psoc, reg->enable_11d_in_world_mode = cfg_get(psoc, CFG_ENABLE_11D_IN_WORLD_MODE); reg->scan_11d_interval = cfg_get(psoc, CFG_SCAN_11D_INTERVAL); + reg->enable_pending_chan_list_req = cfg_get(psoc, + CFG_ENABLE_PENDING_CHAN_LIST_REQ); reg->ignore_fw_reg_offload_ind = cfg_get( psoc, CFG_IGNORE_FW_REG_OFFLOAD_IND); diff --git a/components/mlme/dispatcher/inc/cfg_mlme_reg.h b/components/mlme/dispatcher/inc/cfg_mlme_reg.h index bc06bc034d..7f435eda8d 100644 --- a/components/mlme/dispatcher/inc/cfg_mlme_reg.h +++ b/components/mlme/dispatcher/inc/cfg_mlme_reg.h @@ -274,8 +274,32 @@ 0, \ "Ignore Regulatory offloads Indication from FW") +/* + * + * enable_pending_list_req - Sets Pending channel List Req. + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This option enables/disables SCAN_CHAN_LIST_CMDID channel list command to FW + * till the current scan is complete. + * + * Related: None + * + * Supported Feature: STA + * + * Usage: External + * + * + */ +#define CFG_ENABLE_PENDING_CHAN_LIST_REQ CFG_INI_BOOL( \ + "enable_pending_list_req", \ + 0, \ + "Enable Pending list req") + #define CFG_REG_ALL \ CFG(CFG_SELF_GEN_FRM_PWR) \ + CFG(CFG_ENABLE_PENDING_CHAN_LIST_REQ) \ CFG(CFG_ENABLE_11D_IN_WORLD_MODE) \ CFG(CFG_ETSI13_SRD_CHAN_IN_MASTER_MODE) \ CFG(CFG_RESTART_BEACONING_ON_CH_AVOID) \ diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index 1b704fa324..698ecadc06 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -2149,6 +2149,8 @@ struct wlan_mlme_mwc { * during acs * @avoid_acs_freq_list_num: Number of the frequencies to be avoided during acs * @ignore_fw_reg_offload_ind: Ignore fw regulatory offload indication + * @enable_pending_chan_list_req: enables/disables scan channel + * list command to FW till the current scan is complete. */ struct wlan_mlme_reg { uint32_t self_gen_frm_pwr; @@ -2167,6 +2169,7 @@ struct wlan_mlme_reg { uint8_t avoid_acs_freq_list_num; #endif bool ignore_fw_reg_offload_ind; + bool enable_pending_chan_list_req; }; /** diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h index 2b70259f0f..5dc4aae536 100644 --- a/core/sme/inc/csr_internal.h +++ b/core/sme/inc/csr_internal.h @@ -446,6 +446,7 @@ struct csr_scanstruct { int8_t roam_candidate_count[WLAN_MAX_VDEVS]; int8_t inScanResultBestAPRssi; bool fcc_constraint; + bool pending_channel_list_req; wlan_scan_requester requester_id; }; diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index cf117afc6a..6e35086a46 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -64,6 +64,7 @@ #include "wlan_qct_sys.h" #include "wlan_blm_api.h" #include "wlan_policy_mgr_i.h" +#include "wlan_scan_utils_api.h" #include @@ -1375,6 +1376,37 @@ static void csr_add_social_channels(struct mac_context *mac, } #endif +/** + * csr_scan_event_handler() - callback for scan event + * @vdev: wlan objmgr vdev pointer + * @event: scan event + * @arg: global mac context pointer + * + * Return: void + */ +static void csr_scan_event_handler(struct wlan_objmgr_vdev *vdev, + struct scan_event *event, + void *arg) +{ + bool success = false; + QDF_STATUS lock_status; + struct mac_context *mac = arg; + + if (!mac) + return; + + if (!util_is_scan_completed(event, &success)) + return; + + lock_status = sme_acquire_global_lock(&mac->sme); + if (QDF_IS_STATUS_ERROR(lock_status)) + return; + + if (mac->scan.pending_channel_list_req) + csr_update_channel_list(mac); + sme_release_global_lock(&mac->sme); +} + QDF_STATUS csr_update_channel_list(struct mac_context *mac) { tSirUpdateChanList *pChanList; @@ -1391,6 +1423,8 @@ QDF_STATUS csr_update_channel_list(struct mac_context *mac) uint32_t channel_freq; bool is_unsafe_chan; bool is_same_band; + enum scm_scan_status scan_status; + QDF_STATUS lock_status; qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); @@ -1399,6 +1433,23 @@ QDF_STATUS csr_update_channel_list(struct mac_context *mac) return QDF_STATUS_E_FAILURE; } + lock_status = sme_acquire_global_lock(&mac->sme); + if (QDF_IS_STATUS_ERROR(lock_status)) + return lock_status; + + if (mac->mlme_cfg->reg.enable_pending_chan_list_req) { + scan_status = ucfg_scan_get_pdev_status(mac->pdev); + if (scan_status == SCAN_IS_ACTIVE || + scan_status == SCAN_IS_ACTIVE_AND_PENDING) { + mac->scan.pending_channel_list_req = true; + sme_release_global_lock(&mac->sme); + sme_debug("scan in progress postpone channel list req "); + return QDF_STATUS_SUCCESS; + } + mac->scan.pending_channel_list_req = false; + } + sme_release_global_lock(&mac->sme); + pld_get_wlan_unsafe_channel(qdf_ctx->dev, unsafe_chan, &unsafe_chan_cnt, sizeof(unsafe_chan)); @@ -1591,6 +1642,14 @@ QDF_STATUS csr_start(struct mac_context *mac) mac->scan.requester_id = ucfg_scan_register_requester( mac->psoc, "CSR", csr_scan_callback, mac); + + if (mac->mlme_cfg->reg.enable_pending_chan_list_req) { + status = ucfg_scan_register_event_handler(mac->pdev, + csr_scan_event_handler, mac); + + if (QDF_IS_STATUS_ERROR(status)) + sme_err("scan event registration failed "); + } } while (0); return status; } @@ -1599,6 +1658,10 @@ QDF_STATUS csr_stop(struct mac_context *mac) { uint32_t sessionId; + if (mac->mlme_cfg->reg.enable_pending_chan_list_req) + ucfg_scan_unregister_event_handler(mac->pdev, + csr_scan_event_handler, + mac); ucfg_scan_psoc_set_disable(mac->psoc, REASON_SYSTEM_DOWN); ucfg_scan_unregister_requester(mac->psoc, mac->scan.requester_id);