From patchwork Thu Aug 4 22:02:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Prestwood X-Patchwork-Id: 12936699 Received: from mail-pf1-f176.google.com (mail-pf1-f176.google.com [209.85.210.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B77DB6AA4 for ; Thu, 4 Aug 2022 22:02:52 +0000 (UTC) Received: by mail-pf1-f176.google.com with SMTP id y141so676149pfb.7 for ; Thu, 04 Aug 2022 15:02:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc; bh=KrG7oocmPw8aTDDnqc+23rxGgN3aKuqTzl2qrU7VpfA=; b=ACL+H4BrXUlQ1bOhf8hUJdyyWgF23C5sRmA6Vd6vTkyZIdegrEr45yRYWTft2CGZtV yxQW0YgAqBGdXbtnj5gaJfCJ3MwMfbjegJTyuzOmXVor3gfs2Xa5Hvt9qcV96Fp7CCE5 Z9w7ijrFVz5ee9SWfTxiH5AVMHw33bne279+DteI8EALvxFnZZd7HCsI8ISpKfXHxOZX dEF+w7dsUB/vVwT5rvlO6amCLziPVuKWQrAuAtdnpjaoF99weaRaIdpHQbBLxibu4qgs sdLOWKAwVCXFM6RkhvLNKGXZFqrE7l2ueUpRWihwhNg7ew2qdDjmDvJspmcrVZ8ZrZBb o8MQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc; bh=KrG7oocmPw8aTDDnqc+23rxGgN3aKuqTzl2qrU7VpfA=; b=gpKSRRfKOvEP4KNTGDKvesuWb50HCNy50fZvNMfn3MAF49RuFkzyBwPuZaIbBR7PpR RhOgisZEckjT/TdyMh4JidsPr+6kiQRYBojxoPFN53CvXZzv/H1YIWfvclnCgJT22KGj ah8ojJJeTELrUAss95qGNAIkeoBwbEK7zDygUDaUGvBwR3ELHtOJeE4xP6cE5wxqWG+4 sopcZu814V/zNmNEjNtGCDvd3Pg6ERXaVA3AWrsBxdcXcLl7slt5mmHLJAfZ4o6VDjmt WoEXtjdaaoTS0+A+c/u4DXCY2V59OAKtNACSsU1xlZKiQ7EIQ6WFW/4Y+JsVg38RFD87 fwiQ== X-Gm-Message-State: ACgBeo1Dq3RQJ2v7K1m37EskRyHA9p3QJDPBsA1szzHNmi3ig+d77mL3 UjJOn1nY2sBAnV92OuAuNPNFEvhSUa0= X-Google-Smtp-Source: AA6agR50TFpnoFIpm4GoO/6kdtGDIxs73gJWhg4CpvCWP0TEVEVCHUHfY+qYLWOGT9DEX5Bz7Ps0jw== X-Received: by 2002:a63:7e4c:0:b0:412:f7e:9ab6 with SMTP id o12-20020a637e4c000000b004120f7e9ab6mr3163297pgn.494.1659650571709; Thu, 04 Aug 2022 15:02:51 -0700 (PDT) Received: from jprestwo-xps.none ([50.45.187.22]) by smtp.gmail.com with ESMTPSA id p3-20020a170902ebc300b0016dbdf7b97bsm1376886plg.266.2022.08.04.15.02.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Aug 2022 15:02:51 -0700 (PDT) From: James Prestwood To: iwd@lists.linux.dev Cc: James Prestwood Subject: [PATCH v4 1/3] util: add scan_freq_set_copy_bands Date: Thu, 4 Aug 2022 15:02:47 -0700 Message-Id: <20220804220249.508207-1-prestwoj@gmail.com> X-Mailer: git-send-email 2.34.3 Precedence: bulk X-Mailing-List: iwd@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This creates a new scan_freq_set from an input set which only contains frequencies from bands included in the mask. --- src/util.c | 21 +++++++++++++++++++++ src/util.h | 2 ++ 2 files changed, 23 insertions(+) diff --git a/src/util.c b/src/util.c index ebaff6a0..64d85cbc 100644 --- a/src/util.c +++ b/src/util.c @@ -554,3 +554,24 @@ uint32_t *scan_freq_set_to_fixed_array(const struct scan_freq_set *set, return freqs; } + +struct scan_freq_set *scan_freq_set_copy_bands(const struct scan_freq_set *set, + uint32_t band_mask) +{ + struct scan_freq_set *new = l_new(struct scan_freq_set, 1); + + if (band_mask & BAND_FREQ_2_4_GHZ) + new->channels_2ghz = set->channels_2ghz; + + if (band_mask & BAND_FREQ_5_GHZ) + new->channels_5ghz = l_uintset_clone(set->channels_5ghz); + else + new->channels_5ghz = l_uintset_new_from_range(1, 200); + + if (band_mask & BAND_FREQ_6_GHZ) + new->channels_6ghz = l_uintset_clone(set->channels_6ghz); + else + new->channels_6ghz = l_uintset_new_from_range(1, 233); + + return new; +} diff --git a/src/util.h b/src/util.h index 0b7832fb..9d3ec604 100644 --- a/src/util.h +++ b/src/util.h @@ -123,5 +123,7 @@ void scan_freq_set_subtract(struct scan_freq_set *set, bool scan_freq_set_isempty(const struct scan_freq_set *set); uint32_t *scan_freq_set_to_fixed_array(const struct scan_freq_set *set, size_t *len_out); +struct scan_freq_set *scan_freq_set_copy_bands(const struct scan_freq_set *set, + uint32_t band_mask); #endif /* __UTIL_H */ From patchwork Thu Aug 4 22:02:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Prestwood X-Patchwork-Id: 12936700 Received: from mail-pf1-f171.google.com (mail-pf1-f171.google.com [209.85.210.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 24BF66AAC for ; Thu, 4 Aug 2022 22:02:53 +0000 (UTC) Received: by mail-pf1-f171.google.com with SMTP id b133so680968pfb.6 for ; Thu, 04 Aug 2022 15:02:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc; bh=LgfYiM82pqVKPoeFQ7deB7V4HpJJkCf1GoVxPhKOlTw=; b=bl4oufDuz8iKNnnXAVevHWtcPzXWYn9ASaxxO/loLHa1H6m1qI24n2bw7/ImOQjyGI 5uEuHf/Q3hBG+TtvBPJabGidaQ84gXV8igaBGP9sYbNvkiN4GwH8//zjFuMLrsyAlPX/ 3tkpmKj6E/bwe3Y0vq/Y2L3F4ZgyXMgqoIkYdC1ASPj5Q+uo39MsPKxk6tsOA987pMsC nfPQoz7qhxCt8aoDR9iH8cOymtLSthyy/MOSX6VpH9XLvxmBC9wunmZFdiMnrTwu1+of AgTL+SFx5uwlUZ2FvcB0QLobqU5K7dp6Z+2zy1j4iIdUaS1IAVFksmnKvFLkmbfw4q2O 9UsQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc; bh=LgfYiM82pqVKPoeFQ7deB7V4HpJJkCf1GoVxPhKOlTw=; b=By0YyTlqVDJAGaqF0bISninD45+NtLUWthZ9Pyr4EZviinr0/wgIDklel0WKWZsYMa rQme1CbEWQtU4BKaGMhsBt94eaAdzrs7/nqWxImEJKMkS56LojmPVK+vUZ1ROfrnkGrw KXYQ557HMrzZ7yZhAelsZxe4v6dhlqCiaMSuPBngZlmkyMxw0Eag1vu9CbhL/OGcp+nK xz5F2TXKzvBvjIRUgI1khaxUKz3gRDlwlPxUHXBUNmMpmBXE8q9ntqW5iYz9A2JboZ5K YKP4/kcZ4J9UpE//Xdqs+pM9HoT6/atVfg3n7dYBJSZObXCdFtXJfc33ledojVdV4mcY PdKQ== X-Gm-Message-State: ACgBeo3VVDeWDeF7t42yRHgyrjS1F2SXGdVfERcKdHupcSBp8YAdTENu +5URlhgvlbqZ1Fq2D1eqsS/0Z5Mnbgg= X-Google-Smtp-Source: AA6agR686b0D3k70+B1rONKaX3HoQNm9LDd37iJWto3lsvIIi5u/G6ZSeSogpPtOjSO2gyMk6XE9NQ== X-Received: by 2002:a63:5364:0:b0:41a:529b:c1af with SMTP id t36-20020a635364000000b0041a529bc1afmr3299128pgl.98.1659650572320; Thu, 04 Aug 2022 15:02:52 -0700 (PDT) Received: from jprestwo-xps.none ([50.45.187.22]) by smtp.gmail.com with ESMTPSA id p3-20020a170902ebc300b0016dbdf7b97bsm1376886plg.266.2022.08.04.15.02.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Aug 2022 15:02:52 -0700 (PDT) From: James Prestwood To: iwd@lists.linux.dev Cc: James Prestwood Subject: [PATCH v4 2/3] scan: split full scans by band to enable 6GHz Date: Thu, 4 Aug 2022 15:02:48 -0700 Message-Id: <20220804220249.508207-2-prestwoj@gmail.com> X-Mailer: git-send-email 2.34.3 In-Reply-To: <20220804220249.508207-1-prestwoj@gmail.com> References: <20220804220249.508207-1-prestwoj@gmail.com> Precedence: bulk X-Mailing-List: iwd@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 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 | 85 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 76 insertions(+), 9 deletions(-) v4: * Use scan_freq_set_copy_bands diff --git a/src/scan.c b/src/scan.c index b666ba2e..12c970a7 100644 --- a/src/scan.c +++ b/src/scan.c @@ -94,6 +94,8 @@ struct scan_request { */ bool triggered : 1; bool in_callback : 1; /* Scan request complete, re-entrancy guard */ + /* The request was split anticipating 6GHz will become available */ + bool split : 1; struct l_queue *cmds; /* The time the current scan was started. Reported in TRIGGER_SCAN */ uint64_t start_time_tsf; @@ -352,9 +354,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 +383,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 +541,18 @@ 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_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 +563,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 +591,54 @@ 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 scan_request *sr, struct scan_context *sc, + bool passive, + const struct scan_parameters *params) +{ + unsigned int i; + struct scan_freq_set *subsets[2] = { 0 }; + struct scan_freq_set *allowed = scan_get_allowed_freqs(sc); + const struct scan_freq_set *supported = + wiphy_get_supported_freqs(sc->wiphy); + + /* + * If 6GHz is not possible, or already allowed, or the frequencies are + * explicit don't break up the request. + */ + if (!(scan_freq_set_get_bands(supported) & BAND_FREQ_6_GHZ) || + (scan_freq_set_get_bands(allowed) & BAND_FREQ_6_GHZ) || + params->freqs) { + scan_freq_set_free(allowed); + scan_build_next_cmd(sr->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. + */ + subsets[0] = scan_freq_set_copy_bands(allowed, BAND_FREQ_2_4_GHZ); + subsets[1] = scan_freq_set_copy_bands(allowed, BAND_FREQ_5_GHZ); + + scan_freq_set_free(allowed); + + for(i = 0; i < L_ARRAY_SIZE(subsets); i++) { + scan_build_next_cmd(sr->cmds, sc, passive, params, + subsets[i]); + scan_freq_set_free(subsets[i]); + } + + sr->split = true; +} + static int scan_request_send_trigger(struct scan_context *sc, struct scan_request *sr) { @@ -649,7 +716,7 @@ static uint32_t scan_common(uint64_t wdev_id, bool passive, sr = scan_request_new(sc, passive, trigger, notify, userdata, destroy); - scan_cmds_add(sr->cmds, sc, passive, params); + scan_cmds_add(sr, sc, passive, params); /* * sr->work isn't initialized yet, it will be done by @@ -743,7 +810,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, ¶ms); + cmd = scan_build_cmd(sc, ignore_flush, false, ¶ms, params.freqs); l_genl_msg_enter_nested(cmd, NL80211_ATTR_SCAN_SSIDS); l_genl_msg_append_attr(cmd, 0, params.ssid_len, params.ssid); From patchwork Thu Aug 4 22:02:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Prestwood X-Patchwork-Id: 12936701 Received: from mail-pl1-f182.google.com (mail-pl1-f182.google.com [209.85.214.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E93656AAD for ; Thu, 4 Aug 2022 22:02:53 +0000 (UTC) Received: by mail-pl1-f182.google.com with SMTP id iw1so1032835plb.6 for ; Thu, 04 Aug 2022 15:02:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc; bh=wfLBRlYqB6Hhy3IEaoMJSS9tQKJKoI49aX+f7vXHaWU=; b=ZsHj5gL9H/JNWNoEP/KRIMSNOKWQc71MZArEA0ykDQDyWcYCTRpgbLcaS7TQknhSYl 357j9818IhPHW6u+avvOCMUpzgbCJ/B0vfDzPblA3S0m9rU6cmy0N1zx/DLRIR54xWrk d/OYkozhrLJhziYzDCWNXg9xU3IfbkOuZKoFQuHVVfD+g4miIetHJDGdzZ5X8/xkdLhK 9PY+ET2Ei2gFXAH7ouGO0L5kCCDx83QZIC0sH67B6y5DaULnqYv6am8meG2yneil6WUI 6QiUZtsRydJ5Fi7VEmjx39pj44Hpt3MRNGc8SfyxWzpUBKoANUmPyA5541ux26jDt7q1 wytw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc; bh=wfLBRlYqB6Hhy3IEaoMJSS9tQKJKoI49aX+f7vXHaWU=; b=32UBS8jLa1Od+mwgSrJCng0B1DFJ1JhXvyQ1gJEkyDscQtugH30ayRgb0h/tbgyZ1M 58fb6ApSh2h/fmoKcc8zox37IrEs933VgdDPqVRpo8kDNJMUYMu0k+aYC81YUhgtStXR ErbBeg7IO93+8CZ4gSa2OsEj+4/sn6QEq60IC4U8IWkt1LjEzv9bIOiWmU5BSSz00fmL RqTtx/8upNMIuYZEZL7RTHVArx1MfvA0fVY1LFaDPRHy1beJwyFXJE1CCeCEFe8CgouT YojDuzbttMoxCnEDwYrAqeWTHS8hPe9YYuVseLrVyxPyTiHhbtw/1NPyORQ58WiXjTgY kuug== X-Gm-Message-State: ACgBeo2ZVXDJjgbTaO3S2Wj7bU99bIQeFHBNzhw3qeFO8tEni+k/VeUy dyYWLd/e3hC6htqfWVrU1ubcTTY1ngQ= X-Google-Smtp-Source: AA6agR6PgwSrMSNdKZlK3/hKcZmERhUvtxX7Emiw3yAnzHrxj6/W/1Re8pJbayxiBAnqkOnYF0hpxQ== X-Received: by 2002:a17:902:c713:b0:16e:cbe3:29da with SMTP id p19-20020a170902c71300b0016ecbe329damr3642167plp.61.1659650573057; Thu, 04 Aug 2022 15:02:53 -0700 (PDT) Received: from jprestwo-xps.none ([50.45.187.22]) by smtp.gmail.com with ESMTPSA id p3-20020a170902ebc300b0016dbdf7b97bsm1376886plg.266.2022.08.04.15.02.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Aug 2022 15:02:52 -0700 (PDT) From: James Prestwood To: iwd@lists.linux.dev Cc: James Prestwood Subject: [PATCH v4 3/3] scan: watch for regdom updates to enable 6GHz Date: Thu, 4 Aug 2022 15:02:49 -0700 Message-Id: <20220804220249.508207-3-prestwoj@gmail.com> X-Mailer: git-send-email 2.34.3 In-Reply-To: <20220804220249.508207-1-prestwoj@gmail.com> References: <20220804220249.508207-1-prestwoj@gmail.com> Precedence: bulk X-Mailing-List: iwd@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This functionality works around the kernel's behavior of allowing 6GHz only after a regulatory domain update. If the regdom updates scan.c needs to be aware in order to split up periodic scans, or insert 6GHz frequencies into an ongoing periodic scan. Doing this allows any 6GHz BSS's to show up in the scan results rather than needing to issue an entirely new scan to see these BSS's. --- src/scan.c | 146 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 114 insertions(+), 32 deletions(-) v4: * Remove wait_for_regdom/expect_6ghz flags. This reduced the complexity and avoided the need to even check for the STARTED regdom event. * Fixed issue where a periodic scan waiting on the regdom wasn't parsing the NEW_SCAN_RESULT frequencies before bailing out of the notify callback * Fixed issue where a periodic scan was not finished if a new scan command was not appended. diff --git a/src/scan.c b/src/scan.c index 12c970a7..d044e80c 100644 --- a/src/scan.c +++ b/src/scan.c @@ -110,6 +110,7 @@ struct scan_request { struct scan_context { uint64_t wdev_id; + uint32_t wiphy_watch_id; /* * Tells us whether a scan, our own or external, is running. * Set when scan gets triggered, cleared when scan done and @@ -186,24 +187,6 @@ static void scan_request_failed(struct scan_context *sc, wiphy_radio_work_done(sc->wiphy, sr->work.id); } -static struct scan_context *scan_context_new(uint64_t wdev_id) -{ - struct wiphy *wiphy = wiphy_find_by_wdev(wdev_id); - struct scan_context *sc; - - if (!wiphy) - return NULL; - - sc = l_new(struct scan_context, 1); - - sc->wdev_id = wdev_id; - sc->wiphy = wiphy; - sc->state = SCAN_STATE_NOT_RUNNING; - sc->requests = l_queue_new(); - - return sc; -} - static void scan_request_cancel(void *data) { struct scan_request *sr = data; @@ -229,6 +212,8 @@ static void scan_context_free(struct scan_context *sc) if (sc->get_fw_scan_cmd_id && nl80211) l_genl_family_cancel(nl80211, sc->get_fw_scan_cmd_id); + wiphy_state_watch_remove(sc->wiphy, sc->wiphy_watch_id); + l_free(sc); } @@ -2006,6 +1991,108 @@ static void get_scan_done(void *user) l_free(results); } +static void scan_get_results(struct scan_context *sc, struct scan_request *sr) +{ + struct scan_results *results; + struct l_genl_msg *scan_msg; + + results = l_new(struct scan_results, 1); + results->sc = sc; + results->time_stamp = l_time_now(); + results->sr = sr; + results->bss_list = l_queue_new(); + + scan_msg = l_genl_msg_new_sized(NL80211_CMD_GET_SCAN, 8); + + l_genl_msg_append_attr(scan_msg, NL80211_ATTR_WDEV, 8, + &sc->wdev_id); + sc->get_scan_cmd_id = l_genl_family_dump(nl80211, scan_msg, + get_scan_callback, + results, get_scan_done); +} + +static void scan_wiphy_watch(struct wiphy *wiphy, + enum wiphy_state_watch_event event, + void *user_data) +{ + struct scan_context *sc = user_data; + struct scan_request *sr = NULL; + struct l_genl_msg *msg = NULL; + struct scan_parameters params = { 0 }; + struct scan_freq_set *freqs_6ghz; + struct scan_freq_set *allowed; + bool allow_6g; + const struct scan_freq_set *supported = + wiphy_get_supported_freqs(wiphy); + + /* Only care about regulatory events, and if 6GHz capable */ + if (event != WIPHY_STATE_WATCH_EVENT_REGDOM_DONE || + !(scan_freq_set_get_bands(supported) & BAND_FREQ_6_GHZ)) + return; + + if (!sc->sp.id) + return; + + sr = l_queue_find(sc->requests, scan_request_match, + L_UINT_TO_PTR(sc->sp.id)); + if (!sr) + return; + + allowed = scan_get_allowed_freqs(sc); + allow_6g = scan_freq_set_get_bands(allowed) & BAND_FREQ_6_GHZ; + + /* + * This update did not allow 6GHz, or the original request was + * not expecting 6GHz. The periodic scan should now be ended. + */ + if (!allow_6g || !sr->split) { + scan_get_results(sc, sr); + goto free_allowed; + } + + /* + * At this point we know there is an ongoing periodic scan. + * Create a new 6GHz passive scan request and append to the + * command list + */ + freqs_6ghz = scan_freq_set_copy_bands(allowed, BAND_FREQ_6_GHZ); + + msg = scan_build_cmd(sc, false, true, ¶ms, freqs_6ghz); + l_queue_push_tail(sr->cmds, msg); + + scan_freq_set_free(freqs_6ghz); + + /* + * If this periodic scan is at the top of the queue, continue + * running it. + */ + if (l_queue_peek_head(sc->requests) == sr) + start_next_scan_request(&sr->work); + +free_allowed: + scan_freq_set_free(allowed); +} + +static struct scan_context *scan_context_new(uint64_t wdev_id) +{ + struct wiphy *wiphy = wiphy_find_by_wdev(wdev_id); + struct scan_context *sc; + + if (!wiphy) + return NULL; + + sc = l_new(struct scan_context, 1); + + sc->wdev_id = wdev_id; + sc->wiphy = wiphy; + sc->state = SCAN_STATE_NOT_RUNNING; + sc->requests = l_queue_new(); + sc->wiphy_watch_id = wiphy_state_watch_add(wiphy, scan_wiphy_watch, + sc, NULL); + + return sc; +} + static bool scan_parse_flush_flag_from_msg(struct l_genl_msg *msg) { struct l_genl_attr attr; @@ -2094,8 +2181,6 @@ static void scan_notify(struct l_genl_msg *msg, void *user_data) switch (cmd) { case NL80211_CMD_NEW_SCAN_RESULTS: { - struct l_genl_msg *scan_msg; - struct scan_results *results; bool send_next = false; bool retry = false; bool get_results = false; @@ -2106,6 +2191,14 @@ static void scan_notify(struct l_genl_msg *msg, void *user_data) if (sr && sr->triggered) { sr->triggered = false; + /* Regdom changed during a periodic scan */ + if (sc->sp.id == sr->work.id && + wiphy_regdom_is_updating(sc->wiphy)) { + scan_parse_result_frequencies(msg, + sr->freqs_scanned); + return; + } + if (!sr->callback) { scan_finished(sc, -ECANCELED, NULL, NULL, sr); break; @@ -2162,20 +2255,9 @@ static void scan_notify(struct l_genl_msg *msg, void *user_data) if (!get_results) break; - results = l_new(struct scan_results, 1); - results->sc = sc; - results->time_stamp = l_time_now(); - results->sr = sr; - results->bss_list = l_queue_new(); - scan_parse_result_frequencies(msg, sr->freqs_scanned); - scan_msg = l_genl_msg_new_sized(NL80211_CMD_GET_SCAN, 8); - l_genl_msg_append_attr(scan_msg, NL80211_ATTR_WDEV, 8, - &sc->wdev_id); - sc->get_scan_cmd_id = l_genl_family_dump(nl80211, scan_msg, - get_scan_callback, - results, get_scan_done); + scan_get_results(sc, sr); break; }