فهرست منبع

qcacmn: Allow FW to pno scan 6G chan based on RNR flag only

First host checks below two things in PNO scan request:
1. Userspace sets NL80211_SCAN_FLAG_COLOCATED_6GHZ flag
in pno scan request.
2. At least one 6G channel is present in the pno scan req.

If any of above conditions satisfy, Host fills all remaining
(other than channel(s) present in pno scan req) valid 6 GHz
channel(s) to pno scan requests and set the flag
FLAG_SCAN_ONLY_IF_RNR_FOUND for each remaining channel(s).
Host sends this updated channel list via WMI command
WMI_START_SCAN_CMDID_param_tlvs->channel_list for pno scan
to firmware.

By this driver allows Firmware to scan 6G channels based on
RNR IEs only (for colocated APs reported by 2.4/5 GHz APs).

Change-Id: Ib6118c4525e9fbe233eb6a7e07a4a3345d486e8a
CRs-Fixed: 3103923
abhinav kumar 3 سال پیش
والد
کامیت
3b1731aa70

+ 33 - 24
os_if/linux/scan/src/wlan_cfg80211_scan.c

@@ -52,6 +52,27 @@ const struct nla_policy cfg80211_scan_policy[
 	[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE] = {.type = NLA_U64},
 };
 
+/**
+ * wlan_cfg80211_is_colocated_6ghz_scan_supported() - Check whether colocated
+ * 6ghz scan flag present in scan request or not
+ * @scan_flag: Flags bitmap comming from kernel
+ *
+ * Return: True if colocated 6ghz scan flag present in scan req
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0))
+static bool
+wlan_cfg80211_is_colocated_6ghz_scan_supported(uint32_t scan_flag)
+{
+	return !!(scan_flag & NL80211_SCAN_FLAG_COLOCATED_6GHZ);
+}
+#else
+static inline bool
+wlan_cfg80211_is_colocated_6ghz_scan_supported(uint32_t scan_flag)
+{
+	return false;
+}
+#endif
+
 #if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \
 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
 /**
@@ -430,6 +451,9 @@ int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_vdev *vdev,
 
 	req->networks_cnt = request->n_match_sets;
 	req->vdev_id = wlan_vdev_get_id(vdev);
+	req->vdev = vdev;
+	req->scan_policy_colocated_6ghz =
+		wlan_cfg80211_is_colocated_6ghz_scan_supported(request->flags);
 
 	if ((!req->networks_cnt) ||
 	    (req->networks_cnt > SCAN_PNO_MAX_SUPP_NETWORKS)) {
@@ -524,9 +548,15 @@ int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_vdev *vdev,
 		req->networks_list[i].bc_new_type = 0;    /*eBCAST_UNKNOWN */
 
 		/*Copying list of valid channel into request */
-		qdf_mem_copy(req->networks_list[i].channels, valid_ch,
-			num_chan * sizeof(uint32_t));
-		req->networks_list[i].channel_cnt = num_chan;
+		for (j = 0; j < num_chan; j++)
+			req->networks_list[i].pno_chan_list.chan[j].freq =
+								valid_ch[j];
+		req->networks_list[i].pno_chan_list.num_chan = num_chan;
+
+		if (ucfg_is_6ghz_pno_scan_optimization_supported(psoc))
+			ucfg_scan_pno_add_all_valid_6g_channels(vdev, req,
+								&num_chan);
+
 		req->networks_list[i].rssi_thresh =
 			request->match_sets[i].rssi_thold;
 	}
@@ -1316,27 +1346,6 @@ void wlan_cfg80211_cleanup_scan_queue(struct wlan_objmgr_pdev *pdev,
 	return;
 }
 
-/**
- * wlan_cfg80211_is_colocated_6ghz_scan_supported() - Check whether colocated
- * 6ghz scan flag present in scan request or not
- * @scan_flag: Flags bitmap coming from kernel
- *
- * Return: True if colocated 6ghz scan flag present in scan req
- */
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0))
-static bool
-wlan_cfg80211_is_colocated_6ghz_scan_supported(uint32_t scan_flag)
-{
-	return !!(scan_flag & NL80211_SCAN_FLAG_COLOCATED_6GHZ);
-}
-#else
-static inline bool
-wlan_cfg80211_is_colocated_6ghz_scan_supported(uint32_t scan_flag)
-{
-	return false;
-}
-#endif
-
 /**
  * wlan_cfg80211_update_scan_policy_type_flags() - Set scan flags according to
  * scan request

+ 19 - 7
umac/scan/core/src/wlan_scan_manager_6ghz.c

@@ -250,6 +250,7 @@ scm_is_scan_type_exempted_from_optimization(struct scan_start_request *req)
  * @vdev: vdev on which scan request is issued
  * @req: Scan start request
  * @num_scan_ch: Total number of scan channels
+ * @is_colocated_6ghz_scan_enabled: colocated 6ghz scan flag enabled in scan req
  *
  * If colocated 6ghz scan flag present in host scan request or at least one 6G
  * channel is present in the host scan request, then this API
@@ -260,13 +261,13 @@ scm_is_scan_type_exempted_from_optimization(struct scan_start_request *req)
  *
  * Return: None
  */
-static void scm_add_all_valid_6g_channels(struct wlan_objmgr_pdev *pdev,
-					  struct scan_start_request *req,
-					  uint8_t *num_scan_ch)
+void scm_add_all_valid_6g_channels(struct wlan_objmgr_pdev *pdev,
+				   struct chan_list *chan_list,
+				   uint8_t *num_scan_ch,
+				   bool is_colocated_6ghz_scan_enabled)
 {
 	uint8_t i, j;
 	enum channel_enum freq_idx;
-	struct chan_list *chan_list = &req->scan_req.chan_list;
 	struct regulatory_channel *cur_chan_list;
 	bool is_6g_ch_present = false, found;
 	QDF_STATUS status;
@@ -281,8 +282,7 @@ static void scm_add_all_valid_6g_channels(struct wlan_objmgr_pdev *pdev,
 		}
 	}
 
-	if (!is_6g_ch_present &&
-	    !req->scan_req.scan_policy_colocated_6ghz) {
+	if (!is_6g_ch_present && !is_colocated_6ghz_scan_enabled) {
 		scm_debug("Neither 6G chan present nor flag set in scan req");
 		return;
 	}
@@ -331,6 +331,18 @@ static void scm_add_all_valid_6g_channels(struct wlan_objmgr_pdev *pdev,
 	qdf_mem_free(cur_chan_list);
 }
 
+static void scm_scan_add_all_valid_6g_channels(struct wlan_objmgr_pdev *pdev,
+					       struct scan_start_request *req,
+					       uint8_t *num_scan_ch)
+{
+	bool is_colocated_6ghz_scan_enabled =
+		req->scan_req.scan_policy_colocated_6ghz;
+
+	scm_add_all_valid_6g_channels(pdev, &req->scan_req.chan_list,
+				      num_scan_ch,
+				      is_colocated_6ghz_scan_enabled);
+}
+
 static void
 scm_copy_valid_channels(struct wlan_objmgr_psoc *psoc,
 			enum scan_mode_6ghz scan_mode,
@@ -513,7 +525,7 @@ scm_update_6ghz_channel_list(struct scan_start_request *req,
 		 * set the flag FLAG_SCAN_ONLY_IF_RNR_FOUND for each remaining
 		 * channels.
 		 */
-		scm_add_all_valid_6g_channels(pdev, req, &num_scan_ch);
+		scm_scan_add_all_valid_6g_channels(pdev, req, &num_scan_ch);
 		break;
 	default:
 		/*

+ 29 - 0
umac/scan/core/src/wlan_scan_manager_6ghz.h

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -70,6 +71,27 @@ scm_update_6ghz_channel_list(struct scan_start_request *req,
  */
 bool
 scm_is_6ghz_scan_optimization_supported(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * scm_add_all_valid_6g_channels() - Add all valid 6g channels to scan request
+ * @vdev: vdev on which scan request is issued
+ * @req: Scan start request
+ * @num_scan_ch: Total number of scan channels
+ *
+ * If colocated 6ghz scan flag present in host scan request or at least one 6G
+ * channel is present in the host scan request, then this API
+ * fills all remaining (other than channel(s) resent in host scan req) valid
+ * 6 GHz channel(s) to scan requests channel list and set the flag
+ * FLAG_SCAN_ONLY_IF_RNR_FOUND for each of those added channels.
+ * By this driver allows Firmware to scan 6G channels based on RNR IEs only.
+ *
+ * Return: None
+ */
+void scm_add_all_valid_6g_channels(struct wlan_objmgr_pdev *pdev,
+				   struct chan_list *chan_list,
+				   uint8_t *num_scan_ch,
+				   bool is_colocated_6ghz);
+
 #else
 static inline void
 scm_update_6ghz_channel_list(struct scan_start_request *req,
@@ -82,6 +104,13 @@ scm_is_6ghz_scan_optimization_supported(struct wlan_objmgr_psoc *psoc)
 {
 	return false;
 }
+
+static inline void scm_add_all_valid_6g_channels(struct wlan_objmgr_pdev *pdev,
+						 struct chan_list *chan_list,
+						 uint8_t *num_scan_ch,
+						 bool is_colocated_6ghz)
+{
+}
 #endif
 
 #endif

+ 8 - 6
umac/scan/dispatcher/inc/wlan_scan_public_structs.h

@@ -1389,18 +1389,16 @@ enum ssid_bc_type {
  * @ssid: ssid
  * @authentication: authentication type
  * @encryption: encryption type
- * @bcastNetwType: broadcast nw type
- * @ucChannelCount: uc channel count
- * @aChannels: pno channel
- * @rssiThreshold: rssi threshold
+ * @bc_new_type: broadcast nw type
+ * @pno_chan_list: pno channel list info
+ * @rssi_thresh: rssi threshold
  */
 struct pno_nw_type {
 	struct wlan_ssid ssid;
 	uint32_t authentication;
 	uint32_t encryption;
 	uint32_t bc_new_type;
-	uint8_t channel_cnt;
-	uint32_t channels[SCAN_PNO_MAX_NETW_CHANNELS_EX];
+	struct chan_list pno_chan_list;
 	int32_t rssi_thresh;
 };
 
@@ -1434,6 +1432,7 @@ struct nlo_mawc_params {
 
 /**
  * struct pno_scan_req_params - PNO Scan request structure
+ * @vdev: vdev object
  * @networks_cnt: Number of networks
  * @do_passive_scan: Flag to request passive scan to fw
  * @vdev_id: vdev id
@@ -1464,8 +1463,10 @@ struct nlo_mawc_params {
  *	  slow_scan_period=1800, scan_backoff_multiplier=2 }
  *	Result: 120s x2, 240s x2, 480s x2, 960s x2, 1800s xN
  * @mawc_params: Configuration parameters for NLO MAWC.
+ * @scan_policy_colocated_6ghz: colocated_6ghz flag is set in pno scan req
  */
 struct pno_scan_req_params {
+	struct wlan_objmgr_vdev *vdev;
 	uint32_t networks_cnt;
 	bool     do_passive_scan;
 	uint32_t vdev_id;
@@ -1488,6 +1489,7 @@ struct pno_scan_req_params {
 	int8_t relative_rssi;
 	struct cpno_band_rssi_pref band_rssi_pref;
 	struct nlo_mawc_params mawc_params;
+	bool scan_policy_colocated_6ghz;
 };
 
 /**

+ 25 - 1
umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -105,7 +106,30 @@ wlan_scan_id ucfg_scan_get_scan_id(struct wlan_objmgr_psoc *psoc)
  * Return: 0 for success or error code.
  */
 QDF_STATUS ucfg_scan_pno_start(struct wlan_objmgr_vdev *vdev,
-struct pno_scan_req_params *req);
+			       struct pno_scan_req_params *req);
+
+/**
+ * ucfg_scan_pno_add_all_valid_6g_channels() - This API to update all valid 6g
+ * channels to pno scan request
+ * @vdev: vdev pointer
+ * @req: pno req params
+ * @num_scan_ch: total number of channels present in pno scan request
+ *
+ * Return: None
+ */
+void ucfg_scan_pno_add_all_valid_6g_channels(struct wlan_objmgr_vdev *vdev,
+					     struct pno_scan_req_params *req,
+					     uint8_t *num_scan_ch);
+
+/**
+ * ucfg_is_6ghz_pno_scan_optimization_supported() - Public API to check
+ * 6ghz pno scan optimization supported in fw
+ * @psoc: psoc object
+ *
+ * Return: 0 for success.
+ */
+bool
+ucfg_is_6ghz_pno_scan_optimization_supported(struct wlan_objmgr_psoc *psoc);
 
 /**
  * ucfg_scan_pno_stop() - Public API to stop PNO

+ 23 - 1
umac/scan/dispatcher/src/wlan_scan_ucfg_api.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -153,6 +153,12 @@ QDF_STATUS ucfg_scan_deinit(void)
 }
 
 #ifdef FEATURE_WLAN_SCAN_PNO
+bool
+ucfg_is_6ghz_pno_scan_optimization_supported(struct wlan_objmgr_psoc *psoc)
+{
+	return wlan_psoc_nif_fw_ext_cap_get(psoc,
+					WLAN_SOC_PNO_SCAN_CONFIG_PER_CHANNEL);
+}
 
 QDF_STATUS ucfg_scan_pno_start(struct wlan_objmgr_vdev *vdev,
 	struct pno_scan_req_params *req)
@@ -179,6 +185,22 @@ QDF_STATUS ucfg_scan_pno_start(struct wlan_objmgr_vdev *vdev,
 	return status;
 }
 
+void ucfg_scan_pno_add_all_valid_6g_channels(struct wlan_objmgr_vdev *vdev,
+					     struct pno_scan_req_params *req,
+					     uint8_t *num_scan_ch)
+{
+	struct wlan_objmgr_pdev *pdev;
+	struct chan_list *pno_chan_list = &req->networks_list[0].pno_chan_list;
+	bool is_colocated_6ghz = req->scan_policy_colocated_6ghz;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev)
+		return;
+
+	scm_add_all_valid_6g_channels(pdev, pno_chan_list, num_scan_ch,
+				      is_colocated_6ghz);
+}
+
 QDF_STATUS ucfg_scan_pno_stop(struct wlan_objmgr_vdev *vdev)
 {
 	struct scan_vdev_obj *scan_vdev_obj;

+ 50 - 7
wmi/src/wmi_unified_tlv.c

@@ -5225,6 +5225,40 @@ static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle,
 	return QDF_STATUS_SUCCESS;
 }
 
+/**
+ * wmi_dump_pno_scan_freq_list() - dump frequency list associated with pno
+ * scan
+ * @scan_freq_list: frequency list for pno scan
+ *
+ * Return: void
+ */
+static void wmi_dump_pno_scan_freq_list(struct chan_list *scan_freq_list)
+{
+	uint32_t i;
+	uint8_t info[WMI_MAX_CHAN_INFO_LOG];
+	uint32_t len = 0;
+	struct chan_info *chan_info;
+	int ret;
+
+	wmi_debug("[PNO_SCAN] Total freq %d", scan_freq_list->num_chan);
+	for (i = 0; i < scan_freq_list->num_chan; i++) {
+		chan_info = &scan_freq_list->chan[i];
+		ret = qdf_scnprintf(info + len, sizeof(info) - len,
+				    " %d[%d]", chan_info->freq,
+				    chan_info->flags);
+		if (ret <= 0)
+			break;
+		len += ret;
+		if (len >= (sizeof(info) - 20)) {
+			wmi_nofl_debug("Freq[flag]:%s",
+				       info);
+			len = 0;
+		}
+	}
+	if (len)
+		wmi_nofl_debug("Freq[flag]:%s", info);
+}
+
 /**
  * send_pno_start_cmd_tlv() - PNO start request
  * @wmi_handle: wmi handle
@@ -5240,6 +5274,7 @@ static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle,
 	nlo_configured_parameters *nlo_list;
 	uint32_t *channel_list;
 	int32_t len;
+	qdf_freq_t freq;
 	wmi_buf_t buf;
 	uint8_t *buf_ptr;
 	uint8_t i;
@@ -5259,7 +5294,7 @@ static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle,
 		WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE +
 		WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE;
 
-	len += sizeof(uint32_t) * pno->networks_list[0].channel_cnt;
+	len += sizeof(uint32_t) * pno->networks_list[0].pno_chan_list.num_chan;
 	len += sizeof(nlo_configured_parameters) *
 	       QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS);
 	len += sizeof(nlo_channel_prediction_cfg);
@@ -5346,20 +5381,28 @@ static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle,
 	buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters);
 
 	/* Copy channel info */
-	cmd->num_of_channels = pno->networks_list[0].channel_cnt;
+	cmd->num_of_channels = pno->networks_list[0].pno_chan_list.num_chan;
 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
 		       (cmd->num_of_channels * sizeof(uint32_t)));
 	buf_ptr += WMI_TLV_HDR_SIZE;
 
 	channel_list = (uint32_t *) buf_ptr;
 	for (i = 0; i < cmd->num_of_channels; i++) {
-		channel_list[i] = pno->networks_list[0].channels[i];
+		TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i],
+			pno->networks_list[0].pno_chan_list.chan[i].freq);
+
+		if (channel_list[i] < WMI_NLO_FREQ_THRESH) {
+			freq = pno->networks_list[0].pno_chan_list.chan[i].freq;
+			TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i],
+						     wlan_chan_to_freq(freq));
+		}
 
-		if (channel_list[i] < WMI_NLO_FREQ_THRESH)
-			channel_list[i] =
-				wlan_chan_to_freq(pno->
-					networks_list[0].channels[i]);
+		TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(channel_list[i],
+		     pno->networks_list[0].pno_chan_list.chan[i].flags);
 	}
+
+	wmi_dump_pno_scan_freq_list(&pno->networks_list[0].pno_chan_list);
+
 	buf_ptr += cmd->num_of_channels * sizeof(uint32_t);
 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
 			sizeof(nlo_channel_prediction_cfg));