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);