Prechádzať zdrojové kódy

qcacld-3.0: Fix connection latency situation in driver

In 11D scan procedure if WMI_11D_NEW_COUNTRY_EVENTID event is
received, host processes 11d new country code event.
Host driver as a response sends WMI_SCAN_CHAN_LIST_CMDID
new channel list cmd to firmware.

As a result the ongoing scan procedure is aborted by firmware,
and if the scan was a first scan for connection, then it would
lead to connection latency as the supplicant then have to
scan again.

Fix is to check if any scan is in progress, then delay
WMI_SCAN_CHAN_LIST_CMDID channel list command to FW till
the current scan is complete.

Change-Id: I4e747bb747c32430b5d8024823aa0df4928a8c71
CRs-Fixed: 2569741
Pankaj Singh 5 rokov pred
rodič
commit
f84a5dd718

+ 2 - 0
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);

+ 24 - 0
components/mlme/dispatcher/inc/cfg_mlme_reg.h

@@ -274,8 +274,32 @@
 		0, \
 		"Ignore Regulatory offloads Indication from FW")
 
+/*
+ * <ini>
+ * 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
+ *
+ * </ini>
+ */
+#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) \

+ 3 - 0
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;
 };
 
 /**

+ 1 - 0
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;
 };
 

+ 63 - 0
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 <ol_defines.h>
 
@@ -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);