Bläddra i källkod

qcacmn: Add mode based flags to channels in PNO request

Currently 6 GHz channel flags are not set for channels
present in the list from PNO scan request but are set for
all other 6 GHz channels which are added when either of the
two below conditions are satisfied
1. Userspace sets NL80211_SCAN_FLAG_COLOCATED_6GHZ flag
in PNO scan request.
2. At least one 6 GHz channel is present in the PNO scan req.

Add flags for channels in the PNO scan request based on the
scan_mode_6g ini configured similar to active scan request.

Add changes to remove the RNR flag for the channel if the
corresponding short SSID entry is present in the RNR db
Cache since if colocated SSID is different userspace doesn't
include corresponding 2.4/5 GHz channel information in PNO
request.

Change-Id: I22c4f7ecf65d4ab09dfbbe126aefe02f9145de42
CRs-Fixed: 3119113
Sai Pavan Akhil Remella 3 år sedan
förälder
incheckning
aabe3575e9

+ 25 - 19
os_if/linux/scan/src/wlan_cfg80211_scan.c

@@ -529,36 +529,42 @@ int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_vdev *vdev,
 
 	/* Filling per profile  params */
 	for (i = 0; i < req->networks_cnt; i++) {
-		req->networks_list[i].ssid.length =
-			request->match_sets[i].ssid.ssid_len;
+		struct cfg80211_match_set *user_req = &request->match_sets[i];
+		struct pno_nw_type *tgt_req = &req->networks_list[i];
 
-		if ((!req->networks_list[i].ssid.length) ||
-		    (req->networks_list[i].ssid.length > WLAN_SSID_MAX_LEN)) {
+		tgt_req->ssid.length = user_req->ssid.ssid_len;
+
+		if (!tgt_req->ssid.length ||
+		    tgt_req->ssid.length > WLAN_SSID_MAX_LEN) {
 			osif_err(" SSID Len %d is not correct for network %d",
-				 req->networks_list[i].ssid.length, i);
+				 tgt_req->ssid.length, i);
 			ret = -EINVAL;
 			goto error;
 		}
 
-		qdf_mem_copy(req->networks_list[i].ssid.ssid,
-			request->match_sets[i].ssid.ssid,
-			req->networks_list[i].ssid.length);
-		req->networks_list[i].authentication = 0;   /*eAUTH_TYPE_ANY */
-		req->networks_list[i].encryption = 0;       /*eED_ANY */
-		req->networks_list[i].bc_new_type = 0;    /*eBCAST_UNKNOWN */
+		qdf_mem_copy(tgt_req->ssid.ssid, user_req->ssid.ssid,
+			     tgt_req->ssid.length);
+		tgt_req->authentication = 0;   /*eAUTH_TYPE_ANY */
+		tgt_req->encryption = 0;       /*eED_ANY */
+		tgt_req->bc_new_type = 0;    /*eBCAST_UNKNOWN */
+
 
 		/*Copying list of valid channel into request */
 		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;
+			tgt_req->pno_chan_list.chan[j].freq = valid_ch[j];
+		tgt_req->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);
+		if (ucfg_is_6ghz_pno_scan_optimization_supported(psoc)) {
+			uint32_t short_ssid =
+				wlan_construct_shortssid(tgt_req->ssid.ssid,
+							 tgt_req->ssid.length);
+
+			ucfg_scan_add_flags_to_pno_chan_list(vdev, req,
+							     &num_chan,
+							     short_ssid, i);
+		}
 
-		req->networks_list[i].rssi_thresh =
-			request->match_sets[i].rssi_thold;
+		tgt_req->rssi_thresh = user_req->rssi_thold;
 	}
 
 	/* set scan to passive if no SSIDs are specified in the request */

+ 55 - 0
umac/scan/core/src/wlan_scan_cache_db.c

@@ -156,6 +156,8 @@ static void scm_add_rnr_channel_db(struct wlan_objmgr_psoc *psoc,
 				     QDF_MAC_ADDR_SIZE);
 		if (rnr_bss->short_ssid)
 			rnr_node->entry.short_ssid = rnr_bss->short_ssid;
+		if (rnr_bss->bss_params)
+			rnr_node->entry.bss_params = rnr_bss->bss_params;
 		scm_debug("Add freq %d: "QDF_MAC_ADDR_FMT" short ssid %x", chan_freq,
 			  QDF_MAC_ADDR_REF(rnr_bss->bssid.bytes),
 			  rnr_bss->short_ssid);
@@ -163,6 +165,59 @@ static void scm_add_rnr_channel_db(struct wlan_objmgr_psoc *psoc,
 				     &rnr_node->node);
 	}
 }
+
+void scm_filter_rnr_flag_pno(struct wlan_objmgr_vdev *vdev,
+			     uint32_t short_ssid,
+			     struct chan_list *pno_chan_list)
+{
+	uint8_t i;
+	uint32_t freq;
+	struct meta_rnr_channel *chan;
+	struct scan_rnr_node *rnr_node;
+	enum scan_mode_6ghz scan_mode;
+	struct wlan_scan_obj *scan_obj;
+	struct wlan_objmgr_psoc *psoc;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc)
+		return;
+
+	scan_obj = wlan_vdev_get_scan_obj(vdev);
+	if (!scan_obj) {
+		scm_err("scan_obj is NULL");
+		return;
+	}
+
+	scan_mode = scan_obj->scan_def.scan_mode_6g;
+	/* No Filteration required for below scan modes since
+	 * no RNR flag marked.
+	 */
+	if (scan_mode == SCAN_MODE_6G_NO_CHANNEL ||
+	    scan_mode == SCAN_MODE_6G_ALL_CHANNEL ||
+	    scan_mode == SCAN_MODE_6G_ALL_DUTY_CYCLE)
+		return;
+
+	for (i = 0; i < pno_chan_list->num_chan; i++) {
+		freq = pno_chan_list->chan[i].freq;
+
+		chan = scm_get_chan_meta(psoc, freq);
+		if (!chan || qdf_list_empty(&chan->rnr_list))
+			continue;
+
+		qdf_list_for_each(&chan->rnr_list, rnr_node, node) {
+			if (rnr_node->entry.short_ssid) {
+				if (rnr_node->entry.short_ssid == short_ssid) {
+			/* If short ssid entry present in RNR db cache, remove
+			 * FLAG_SCAN_ONLY_IF_RNR_FOUND flag from the channel.
+			 */
+					pno_chan_list->chan[i].flags &=
+						~FLAG_SCAN_ONLY_IF_RNR_FOUND;
+					break;
+				}
+			}
+		}
+	}
+}
 #endif
 
 /**

+ 26 - 0
umac/scan/core/src/wlan_scan_cache_db.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
@@ -248,6 +249,24 @@ QDF_STATUS scm_rnr_db_flush(struct wlan_objmgr_psoc *psoc);
  */
 void scm_update_rnr_from_scan_cache(struct wlan_objmgr_pdev *pdev);
 
+/**
+ * scm_filter_rnr_flag_pno() - Remove FLAG_SCAN_ONLY_IF_RNR_FOUND flag
+ *                             in channel if ssid is different for colocated AP,
+ *                             during pno scan request
+ * @vdev: vdev
+ * @short_ssid: short ssid
+ * @pno_chan_list: channel list
+ *
+ * Remove FLAG_SCAN_ONLY_IF_RNR_FOUND flag in channel if ssid is different for
+ * colocated AP, in pno scan request
+ *
+ * Return: None
+ */
+void
+scm_filter_rnr_flag_pno(struct wlan_objmgr_vdev *vdev,
+			uint32_t short_ssid,
+			struct chan_list *chan_list);
+
 #else
 static inline QDF_STATUS scm_channel_list_db_init(struct wlan_objmgr_psoc *psoc)
 {
@@ -259,6 +278,13 @@ QDF_STATUS scm_channel_list_db_deinit(struct wlan_objmgr_psoc *psoc)
 {
 	return QDF_STATUS_SUCCESS;
 }
+
+static inline void
+scm_filter_rnr_flag_pno(struct wlan_objmgr_vdev *vdev,
+			uint32_t short_ssid,
+			struct chan_list *chan_list)
+{
+}
 #endif
 
 /**

+ 72 - 54
umac/scan/core/src/wlan_scan_manager_6ghz.c

@@ -331,18 +331,6 @@ 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,
@@ -444,6 +432,76 @@ scm_is_6ghz_scan_optimization_supported(struct wlan_objmgr_psoc *psoc)
 					    WLAN_SOC_CEXT_SCAN_PER_CH_CONFIG);
 }
 
+void scm_add_channel_flags(struct wlan_objmgr_vdev *vdev,
+			   struct chan_list *chan_list,
+			   uint8_t *num_chan,
+			   bool is_colocated_6ghz_scan_enabled,
+			   bool is_pno_scan)
+{
+	struct wlan_scan_obj *scan_obj;
+	enum scan_mode_6ghz scan_mode;
+	struct wlan_objmgr_pdev *pdev;
+	uint8_t num_scan_chan = *num_chan;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev)
+		return;
+	scan_obj = wlan_vdev_get_scan_obj(vdev);
+	if (!scan_obj) {
+		scm_err("scan_obj is NULL");
+		return;
+	}
+
+	scan_mode = scan_obj->scan_def.scan_mode_6g;
+
+	switch (scan_mode) {
+	case SCAN_MODE_6G_RNR_ONLY:
+		/*
+		 * When the ini is set to SCAN_MODE_6G_RNR_ONLY
+		 * always set RNR flag for all(PSC and non-PSC) channels.
+		 */
+		scm_set_rnr_flag_all_6g_ch(&chan_list->chan[0], num_scan_chan);
+		break;
+	case SCAN_MODE_6G_PSC_CHANNEL:
+		/*
+		 * When the ini is set to SCAN_MODE_6G_PSC_CHANNEL,
+		 * always set RNR flag for non-PSC channels.
+		 */
+		scm_set_rnr_flag_non_psc_6g_ch(&chan_list->chan[0],
+					       num_scan_chan);
+		break;
+	case SCAN_MODE_6G_PSC_DUTY_CYCLE:
+	case SCAN_MODE_6G_ALL_DUTY_CYCLE:
+		if (!is_pno_scan && !scm_is_duty_cycle_scan(scan_obj))
+			scm_set_rnr_flag_all_6g_ch(&chan_list->chan[0],
+						   num_scan_chan);
+		else if (scan_mode == SCAN_MODE_6G_PSC_DUTY_CYCLE) {
+			if (is_pno_scan)
+				scm_debug("Duty cycle scan not supported in pno");
+			scm_set_rnr_flag_non_psc_6g_ch(&chan_list->chan[0],
+						       num_scan_chan);
+		}
+		break;
+	case SCAN_MODE_6G_ALL_CHANNEL:
+		/*
+		 * When the ini is set to SCAN_MODE_6G_ALL_CHANNEL,
+		 * Host fills all remaining (other than channel(s) present in
+		 * host scan req) valid 6 GHz channel(s) to scan requests and
+		 * set the flag FLAG_SCAN_ONLY_IF_RNR_FOUND for each remaining
+		 * channels.
+		 */
+		scm_add_all_valid_6g_channels(pdev, chan_list, num_chan,
+					      is_colocated_6ghz_scan_enabled);
+		break;
+	default:
+		/*
+		 * Don't set the RNR flag for SCAN_MODE_6G_NO_CHANNEL/
+		 * SCAN_MODE_6G_RNR_ONLY
+		 */
+		break;
+	}
+}
+
 void
 scm_update_6ghz_channel_list(struct scan_start_request *req,
 			     struct wlan_scan_obj *scan_obj)
@@ -492,48 +550,8 @@ scm_update_6ghz_channel_list(struct scan_start_request *req,
 	    scm_is_scan_type_exempted_from_optimization(req))
 		goto end;
 
-	switch (scan_mode) {
-	case SCAN_MODE_6G_RNR_ONLY:
-		/*
-		 * When the ini is set to SCAN_MODE_6G_RNR_ONLY,
-		 * always set RNR flag for all(PSC and non-PSC) channels.
-		 */
-		scm_set_rnr_flag_all_6g_ch(&chan_list->chan[0], num_scan_ch);
-		break;
-	case SCAN_MODE_6G_PSC_CHANNEL:
-		/*
-		 * When the ini is set to SCAN_MODE_6G_PSC_CHANNEL,
-		 * always set RNR flag for non-PSC channels.
-		 */
-		scm_set_rnr_flag_non_psc_6g_ch(&chan_list->chan[0],
-					       num_scan_ch);
-		break;
-	case SCAN_MODE_6G_PSC_DUTY_CYCLE:
-	case SCAN_MODE_6G_ALL_DUTY_CYCLE:
-		if (!scm_is_duty_cycle_scan(scan_obj))
-			scm_set_rnr_flag_all_6g_ch(&chan_list->chan[0],
-						   num_scan_ch);
-		else if (scan_mode == SCAN_MODE_6G_PSC_DUTY_CYCLE)
-			scm_set_rnr_flag_non_psc_6g_ch(&chan_list->chan[0],
-						       num_scan_ch);
-		break;
-	case SCAN_MODE_6G_ALL_CHANNEL:
-		/*
-		 * When the ini is set to SCAN_MODE_6G_ALL_CHANNEL,
-		 * Host fills all remaining (other than channel(s) present in
-		 * host scan req) valid 6 GHz channel(s) to scan requests and
-		 * set the flag FLAG_SCAN_ONLY_IF_RNR_FOUND for each remaining
-		 * channels.
-		 */
-		scm_scan_add_all_valid_6g_channels(pdev, req, &num_scan_ch);
-		break;
-	default:
-		/*
-		 * Don't set the RNR flag for SCAN_MODE_6G_NO_CHANNEL/
-		 * SCAN_MODE_6G_RNR_ONLY
-		 */
-		break;
-	}
+	scm_add_channel_flags(vdev, chan_list, &num_scan_ch,
+			      req->scan_req.scan_policy_colocated_6ghz, false);
 
 end:
 	chan_list->num_chan = num_scan_ch;

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

@@ -47,6 +47,25 @@
 #define SET_RNR_FLAG_TO_NON_PSC_CHANNEL 0x2
 #define SET_RNR_FLAG_TO_ALL_6G_CHANNELS 0x3
 
+/**
+ * scm_add_channel_flags() - Update 6ghz channel flags in active/pno scan req
+ * @vdev: vdev
+ * @pno_chan_list: channel list
+ * @num_chan: number channels
+ * @is_colocated_6ghz_scan_enabled: Colacated 6ghz flag
+ * @is_pno_scan: is pno scan
+ *
+ * Add channel flags for 6ghz channels from active/pno scan request based on ini
+ *
+ * Return: None
+ */
+void
+scm_add_channel_flags(struct wlan_objmgr_vdev *vdev,
+		      struct chan_list *chan_list,
+		      uint8_t *num_chan,
+		      bool is_colocated_6ghz_scan_enabled,
+		      bool is_pno_scan);
+
 /**
  * scm_update_6ghz_channel_list() - Update 6ghz channel list in the scan req
  * @req: scan start request
@@ -93,6 +112,15 @@ void scm_add_all_valid_6g_channels(struct wlan_objmgr_pdev *pdev,
 				   bool is_colocated_6ghz);
 
 #else
+static inline void
+scm_add_channel_flags(struct wlan_objmgr_vdev *vdev,
+		      struct chan_list *pno_chan_list,
+		      uint8_t *num_chan,
+		      bool is_colocated_6ghz,
+		      bool is_pno_scan)
+{
+}
+
 static inline void
 scm_update_6ghz_channel_list(struct scan_start_request *req,
 			     struct wlan_scan_obj *scan_obj)

+ 2 - 0
umac/scan/dispatcher/inc/wlan_scan_public_structs.h

@@ -1554,11 +1554,13 @@ enum ext_cap_bit_field {
  * @timestamp: time stamp of beacon/probe
  * @short_ssid: Short SSID
  * @bssid: BSSID
+ * @bss_params: bss params present in RNR IE
  */
 struct scan_rnr_info {
 	qdf_time_t timestamp;
 	uint32_t short_ssid;
 	struct qdf_mac_addr bssid;
+	uint8_t bss_params;
 };
 
 /**

+ 10 - 6
umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h

@@ -109,17 +109,21 @@ QDF_STATUS ucfg_scan_pno_start(struct wlan_objmgr_vdev *vdev,
 			       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
+ * ucfg_scan_add_flags_to_pno_chan_list() - This API to update flags for all 6g
+ * channels in pno scan request
  * @vdev: vdev pointer
  * @req: pno req params
- * @num_scan_ch: total number of channels present in pno scan request
+ * @num_chan: number of channels
+ * @short_ssid: short ssid
+ * @list_idx: index of network_list in pno 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);
+void ucfg_scan_add_flags_to_pno_chan_list(struct wlan_objmgr_vdev *vdev,
+					  struct pno_scan_req_params *req,
+					  uint8_t *num_chan,
+					  uint32_t short_ssid,
+					  int list_idx);
 
 /**
  * ucfg_is_6ghz_pno_scan_optimization_supported() - Public API to check

+ 17 - 14
umac/scan/dispatcher/src/wlan_scan_ucfg_api.c

@@ -185,20 +185,23 @@ 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);
+void ucfg_scan_add_flags_to_pno_chan_list(struct wlan_objmgr_vdev *vdev,
+					  struct pno_scan_req_params *req,
+					  uint8_t *num_chan,
+					  uint32_t short_ssid,
+					  int list_idx)
+{
+	struct chan_list *pno_chan_list =
+				    &req->networks_list[list_idx].pno_chan_list;
+
+	/* Add RNR flags to channels based on scan_mode_6g ini */
+	scm_add_channel_flags(vdev, pno_chan_list, num_chan,
+			      req->scan_policy_colocated_6ghz, true);
+	/* Filter RNR flags in pno channel list based on short ssid entry in
+	 * RNR db cache.
+	 */
+	scm_filter_rnr_flag_pno(vdev, short_ssid,
+				&req->networks_list[0].pno_chan_list);
 }
 
 QDF_STATUS ucfg_scan_pno_stop(struct wlan_objmgr_vdev *vdev)