Wireless Daemon for Linux
 help / color / mirror / Atom feed
From: James Prestwood <prestwoj@gmail.com>
To: iwd@lists.linux.dev
Cc: James Prestwood <prestwoj@gmail.com>
Subject: [PATCH v2 11/13] scan: split full scans by band to enable 6GHz
Date: Wed,  3 Aug 2022 14:36:42 -0700	[thread overview]
Message-ID: <20220803213644.277534-11-prestwoj@gmail.com> (raw)
In-Reply-To: <20220803213644.277534-1-prestwoj@gmail.com>

The kernel's regulatory domain updates after some number of beacons
are processed. This triggers a regulatory domain update (and wiphy
dump) but only after a scan request. This means a full scan started
prior to the regdom being set will not include any 6Ghz BSS's even
if the regdom was unlocked during the scan.

This can be worked around by splitting up a large scan request into
multiple requests allowing one of the first commands to trigger a
regdom update. Once the regdom updates (and wiphy dumps) we are
hopefully still scanning and could append an additional request to
scan 6GHz.
---
 src/scan.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 89 insertions(+), 8 deletions(-)

diff --git a/src/scan.c b/src/scan.c
index b666ba2e..e016bd4d 100644
--- a/src/scan.c
+++ b/src/scan.c
@@ -352,9 +352,24 @@ static bool scan_mac_address_randomization_is_disabled(void)
 	return disabled;
 }
 
+static struct scan_freq_set *scan_get_allowed_freqs(struct scan_context *sc)
+{
+	struct scan_freq_set *allowed = scan_freq_set_new();
+
+	scan_freq_set_merge(allowed, wiphy_get_supported_freqs(sc->wiphy));
+
+	if (!wiphy_constrain_freq_set(sc->wiphy, allowed)) {
+		scan_freq_set_free(allowed);
+		allowed = NULL;
+	}
+
+	return allowed;
+}
+
 static struct l_genl_msg *scan_build_cmd(struct scan_context *sc,
 					bool ignore_flush_flag, bool is_passive,
-					const struct scan_parameters *params)
+					const struct scan_parameters *params,
+					const struct scan_freq_set *freqs)
 {
 	struct l_genl_msg *msg;
 	uint32_t flags = 0;
@@ -366,8 +381,8 @@ static struct l_genl_msg *scan_build_cmd(struct scan_context *sc,
 	if (wiphy_get_max_scan_ie_len(sc->wiphy))
 		scan_build_attr_ie(msg, sc, params);
 
-	if (params->freqs)
-		scan_build_attr_scan_frequencies(msg, params->freqs);
+	if (freqs)
+		scan_build_attr_scan_frequencies(msg, freqs);
 
 	if (params->flush && !ignore_flush_flag && wiphy_has_feature(sc->wiphy,
 						NL80211_FEATURE_SCAN_FLUSH))
@@ -524,16 +539,36 @@ static bool scan_cmds_add_hidden(const struct network_info *network,
 		 * of all scans in the batch after the last scan is finished.
 		 */
 		*data->cmd = scan_build_cmd(data->sc, true, false,
-								data->params);
+							data->params,
+							data->params->freqs);
 		l_genl_msg_enter_nested(*data->cmd, NL80211_ATTR_SCAN_SSIDS);
 	}
 
 	return true;
 }
 
-static void scan_cmds_add(struct l_queue *cmds, struct scan_context *sc,
+static void scan_foreach_freq_split_bands(uint32_t freq, void *user_data)
+{
+	struct scan_freq_set **subsets = user_data;
+	int idx;
+
+	if (freq < 3000)
+		idx = 0;
+	else if (freq < 6000)
+		idx = 1;
+	else
+		idx = 2;
+
+	if (!subsets[idx])
+		subsets[idx] = scan_freq_set_new();
+
+	scan_freq_set_add(subsets[idx], freq);
+}
+
+static void scan_build_next_cmd(struct l_queue *cmds, struct scan_context *sc,
 				bool passive,
-				const struct scan_parameters *params)
+				const struct scan_parameters *params,
+				const struct scan_freq_set *freqs)
 {
 	struct l_genl_msg *cmd;
 	struct scan_cmds_add_data data = {
@@ -544,7 +579,7 @@ static void scan_cmds_add(struct l_queue *cmds, struct scan_context *sc,
 		wiphy_get_max_num_ssids_per_scan(sc->wiphy),
 	};
 
-	cmd = scan_build_cmd(sc, false, passive, params);
+	cmd = scan_build_cmd(sc, false, passive, params, freqs);
 
 	if (passive) {
 		/* passive scan */
@@ -572,6 +607,52 @@ static void scan_cmds_add(struct l_queue *cmds, struct scan_context *sc,
 	l_queue_push_tail(cmds, cmd);
 }
 
+static void scan_cmds_add(struct l_queue *cmds, struct scan_context *sc,
+				bool passive,
+				const struct scan_parameters *params)
+{
+	unsigned int i;
+	struct scan_freq_set *subsets[3] = { 0 };
+	struct scan_freq_set *allowed;
+
+	/*
+	 * If the frequencies are explicit don't break up the request
+	 */
+	if (params->freqs) {
+		scan_build_next_cmd(cmds, sc, passive, params, params->freqs);
+		return;
+	}
+
+	/*
+	 * Otherwise a full spectrum scan will likely open up the 6GHz
+	 * band. The problem is the regdom update occurs after an
+	 * individual scan request so a single request isn't going to
+	 * include potential 6GHz results.
+	 *
+	 * Instead we can break this full scan up into individual bands
+	 * and increase our chances of the regdom updating after one of
+	 * the earlier requests. If it does update to allow 6GHz an
+	 * extra 6GHz-only passive scan can be appended to this request
+	 * at that time.
+	 */
+
+	allowed = scan_get_allowed_freqs(sc);
+	if (L_WARN_ON(!allowed))
+		return;
+
+	scan_freq_set_foreach(allowed, scan_foreach_freq_split_bands, subsets);
+	scan_freq_set_free(allowed);
+
+	for(i = 0; i < L_ARRAY_SIZE(subsets); i++) {
+		if (!subsets[i])
+			continue;
+
+		scan_build_next_cmd(cmds, sc, passive, params,
+					subsets[i]);
+		scan_freq_set_free(subsets[i]);
+	}
+}
+
 static int scan_request_send_trigger(struct scan_context *sc,
 					struct scan_request *sr)
 {
@@ -743,7 +824,7 @@ static void add_owe_scan_cmd(struct scan_context *sc, struct scan_request *sr,
 	params.ssid_len = bss->owe_trans->ssid_len;
 	params.flush = true;
 
-	cmd = scan_build_cmd(sc, ignore_flush, false, &params);
+	cmd = scan_build_cmd(sc, ignore_flush, false, &params, params.freqs);
 
 	l_genl_msg_enter_nested(cmd, NL80211_ATTR_SCAN_SSIDS);
 	l_genl_msg_append_attr(cmd, 0, params.ssid_len, params.ssid);
-- 
2.34.3


  parent reply	other threads:[~2022-08-03 21:36 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-03 21:36 [PATCH v2 01/13] wiphy: fix runtime error from bit shift James Prestwood
2022-08-03 21:36 ` [PATCH v2 02/13] scan: track scanned frequencies for entire request James Prestwood
2022-08-03 21:36 ` [PATCH v2 03/13] nl80211util: add nl80211_parse_supported_frequencies James Prestwood
2022-08-04 15:27   ` Denis Kenzior
2022-08-03 21:36 ` [PATCH v2 04/13] wiphy: track self-managed flag James Prestwood
2022-08-03 21:36 ` [PATCH v2 05/13] wiphy: use nl80211_parse_supported_frequencies James Prestwood
2022-08-03 21:36 ` [PATCH v2 06/13] wiphy: add two regulatory domain state events James Prestwood
2022-08-04 15:31   ` Denis Kenzior
2022-08-03 21:36 ` [PATCH v2 07/13] wiphy: dump wiphy's on regulatory domain change James Prestwood
2022-08-03 21:36 ` [PATCH v2 08/13] wiphy: add wiphy_regdom_is_updating James Prestwood
2022-08-03 21:36 ` [PATCH v2 09/13] wiphy: add wiphy_country_is_unknown James Prestwood
2022-08-04 16:48   ` Denis Kenzior
2022-08-03 21:36 ` [PATCH v2 10/13] station: do full passive scan if 6GHz is supported but disabled James Prestwood
2022-08-03 21:36 ` James Prestwood [this message]
2022-08-03 21:36 ` [PATCH v2 12/13] scan: watch for regdom updates to enable 6GHz James Prestwood
2022-08-03 21:36 ` [PATCH v2 13/13] wiphy: don't re-dump wiphy if the regdom didn't change James Prestwood

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220803213644.277534-11-prestwoj@gmail.com \
    --to=prestwoj@gmail.com \
    --cc=iwd@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox