From patchwork Thu Aug 4 18:51:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Prestwood X-Patchwork-Id: 12936603 Received: from mail-pg1-f175.google.com (mail-pg1-f175.google.com [209.85.215.175]) (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 3E1DE28F9 for ; Thu, 4 Aug 2022 18:51:16 +0000 (UTC) Received: by mail-pg1-f175.google.com with SMTP id 73so649652pgb.9 for ; Thu, 04 Aug 2022 11:51:16 -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=Zk4Gb2yzPjGHSmFkTzbrJdoEFExhA3Rvdlbad4oek8A=; b=JAFvsqdPrQNyt4ClUPIb2vxb0k61Tkl5SPCSpJZ7vFslvzSoyVrJC8VSUYHitzMo90 7isTbsb76JGZWKgPxYmAsbcN2e+KRRFgVU02gpnA4mMamYO+efGTc0p2PjGLugE5xoFe Lovt24fp34CF6rohNYCpJ6jD02BvujB+W7xVQaN9+0+YT8lQGapr00lkhUy/1G+D/8Mk g8RQw7l53K/PiFGDQpznjIk3E20ppB1wXkrAUuYVxy61EefntXLyDUtemmY3Uc275KMo zVwCaAMzk3vjqfLcC7MGqGywa+f7+sLBRSphkJ7knpPyNMXYSEpoSe5aVXOhRDyIXzhD DZ+g== 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=Zk4Gb2yzPjGHSmFkTzbrJdoEFExhA3Rvdlbad4oek8A=; b=0Vn02Luq+SYt4IRRzk3ud0X+GeQKQR63dNF5hDD5Q2jQ59hDy2PKi3g1HzNZ0vX2H+ yhp8KM9tfYRLo8jDkNrx+Q0xYLv3SmsxEj9GU5f4GSm8Th3iGUE0v94yFObE+ichmGZN NAsAZ7HmYyzE0G4LuPEyJ6SH096S5lG4M2SV/YmqzfdgHr3Iiw2L5ElaKZI+oZ0XKxj+ XEZ4UT/9zyXMZsmFpzJWlHlg4B0jZDI7szAgmN5Ta8QfMxMdN5Jvie8l2vXK1oGtmOs1 yRgVNqY0Da0A4HFid5jPHf19ieMu0pbuyXvoTvOXuKvDVgF0vp5e9F4HFEV6/a4t9PgE H9Zg== X-Gm-Message-State: ACgBeo3wUEIEWJIqYtDFaqh7uBVwQZKen87/fipY/3kDg+pz4t5OBjjp k1hbW3b0vuhETqbee9/SXOBpDLUlYXY= X-Google-Smtp-Source: AA6agR7P49edvbF+wGIk8nm4AviG7+JHE6nHAl87ekX+oo9X7yGWYM3RCHxVfCu8hnnySh9giXBwCA== X-Received: by 2002:aa7:8e91:0:b0:52d:8ebf:29a4 with SMTP id a17-20020aa78e91000000b0052d8ebf29a4mr3204355pfr.1.1659639075439; Thu, 04 Aug 2022 11:51:15 -0700 (PDT) Received: from jprestwo-xps.none ([50.45.187.22]) by smtp.gmail.com with ESMTPSA id c7-20020a634e07000000b0041b3c112b1esm219954pgb.29.2022.08.04.11.51.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Aug 2022 11:51:15 -0700 (PDT) From: James Prestwood To: iwd@lists.linux.dev Cc: James Prestwood Subject: [PATCH v3 1/7] wiphy: track GET_REG ID Date: Thu, 4 Aug 2022 11:51:06 -0700 Message-Id: <20220804185112.457670-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 Keep track of the GET_REG call so it can be canceled if the wiphy goes down. --- src/wiphy.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) v3: * Moved this out into its own patch diff --git a/src/wiphy.c b/src/wiphy.c index 8cb9eb39..30b860da 100644 --- a/src/wiphy.c +++ b/src/wiphy.c @@ -121,6 +121,7 @@ struct wiphy { /* Work queue for this radio */ struct l_queue *work; bool work_in_callback; + unsigned int get_reg_id; bool support_scheduled_scan:1; bool support_rekey_offload:1; @@ -341,6 +342,9 @@ static void wiphy_free(void *data) l_debug("Freeing wiphy %s[%u]", wiphy->name, wiphy->id); + if (wiphy->get_reg_id) + l_genl_family_cancel(nl80211, wiphy->get_reg_id); + for (i = 0; i < NUM_NL80211_IFTYPES; i++) l_free(wiphy->iftype_extended_capabilities[i]); @@ -1875,6 +1879,8 @@ static void wiphy_get_reg_cb(struct l_genl_msg *msg, void *user_data) uint32_t tmp; bool global; + wiphy->get_reg_id = 0; + /* * NL80211_CMD_GET_REG contains an NL80211_ATTR_WIPHY iff the wiphy * uses a self-managed regulatory domain. @@ -1892,8 +1898,9 @@ static void wiphy_get_reg_domain(struct wiphy *wiphy) msg = l_genl_msg_new(NL80211_CMD_GET_REG); l_genl_msg_append_attr(msg, NL80211_ATTR_WIPHY, 4, &wiphy->id); - if (!l_genl_family_send(wiphy->nl80211, msg, wiphy_get_reg_cb, wiphy, - NULL)) { + wiphy->get_reg_id = l_genl_family_send(wiphy->nl80211, msg, + wiphy_get_reg_cb, wiphy, NULL); + if (!wiphy->get_reg_id) { l_error("Error sending NL80211_CMD_GET_REG for %s", wiphy->name); l_genl_msg_unref(msg); } From patchwork Thu Aug 4 18:51:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Prestwood X-Patchwork-Id: 12936604 Received: from mail-pj1-f47.google.com (mail-pj1-f47.google.com [209.85.216.47]) (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 048115380 for ; Thu, 4 Aug 2022 18:51:16 +0000 (UTC) Received: by mail-pj1-f47.google.com with SMTP id a8so583915pjg.5 for ; Thu, 04 Aug 2022 11:51:16 -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=64iFZ5d0cTUCU7ewULKck6X5mJo5Bk5AG9qkKfeS31U=; b=eb9ZTpC8T1oWgHV1a1I3aI5i28L7DFxbdF/LK3Sc0LLEadwbX2Cb53csiy+gh9KmuR DCC4h2PfEkBHxSWuFO5cISK7g5azUWYwdaMjJSzrZjjkq+i4bQj2FGAK8OTdx+WYM2zh j8u+DmXe1CRGF2PTnKSNvQJ5QPzBUO/Qxo0fpTy/IaYfYYvO+F+K3vxDTaljwtHdIgZE c485I4Fqd48TfNNit4dMvkE22zNlvT6bZtzGh2e22GW+taDBOwDuQsFx1fSU+jyTf4fm nm2Ax1XvWfATTmXefIh/2a5+j+8bWvp6vqa0BNEncfILPdrtf916bLNAe+q1KTx2FnNS fO8Q== 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=64iFZ5d0cTUCU7ewULKck6X5mJo5Bk5AG9qkKfeS31U=; b=ByDma5aEsvBgKDIa2h7Vyc83PhTgB9BWqe8f8fVEt7EozcTs9tDVxTcmNAdmNB64Ra wNkHrecI2ATah/fUSdSJ8BN8ZCTOgF2RvB6wKJKx9+rHMvsT6/8iK8mD8nzDCehxzb14 Y0EP43mEFCbVHPE9qaxm/bi6D2WYtuJq5eMeowN7oHApnAeK92c8nKcFUhtRq84O/wFC ORD0lJrgj/QCEckCvvc1/oyfvl44WkKhRb7l9U2pI9mMQlCIsqiuxVPNroMxuIuQvhGM sBtYCo47en3eibKMskQCuOQXgMBqSTNbMNorXRI24Mp32Cw6XpFKP8j1JQbCQbn2nVf7 eing== X-Gm-Message-State: ACgBeo3JAbe0MAUV1THNDRwEGsmYZ2LWe6EUWIhFrKkadvBUJxXwXO/Z p6kGmUamHeGj7HV1PMpCuddCOitj2b0= X-Google-Smtp-Source: AA6agR6aHALN4Kov32H5KjWd0yktiPLKD95oP6Q0xY7+pgm+40Qyw3hsbyMKxrjCV+MfgJa0iX9zug== X-Received: by 2002:a17:90b:1bc7:b0:1f5:37a6:e473 with SMTP id oa7-20020a17090b1bc700b001f537a6e473mr3410924pjb.87.1659639076142; Thu, 04 Aug 2022 11:51:16 -0700 (PDT) Received: from jprestwo-xps.none ([50.45.187.22]) by smtp.gmail.com with ESMTPSA id c7-20020a634e07000000b0041b3c112b1esm219954pgb.29.2022.08.04.11.51.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Aug 2022 11:51:15 -0700 (PDT) From: James Prestwood To: iwd@lists.linux.dev Cc: James Prestwood Subject: [PATCH v3 2/7] wiphy: dump wiphy's on regulatory domain change Date: Thu, 4 Aug 2022 11:51:07 -0700 Message-Id: <20220804185112.457670-2-prestwoj@gmail.com> X-Mailer: git-send-email 2.34.3 In-Reply-To: <20220804185112.457670-1-prestwoj@gmail.com> References: <20220804185112.457670-1-prestwoj@gmail.com> Precedence: bulk X-Mailing-List: iwd@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 A change in regulatory domain can result in frequencies being enabled or disabled depending on the domain. This effects the frequencies stored in wiphy which other modules depend on such as scanning, offchannel work etc. When the regulatory domain changes re-dump the wiphy in order to update any frequency restrictions. --- src/wiphy.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 195 insertions(+), 7 deletions(-) v3: * Removed the GET_REG handling and instead only dump wiphy from the notify callback directly diff --git a/src/wiphy.c b/src/wiphy.c index 30b860da..dfdca989 100644 --- a/src/wiphy.c +++ b/src/wiphy.c @@ -66,6 +66,7 @@ static char **blacklist_filter; static int mac_randomize_bytes = 6; static char regdom_country[2]; static uint32_t work_ids; +static unsigned int wiphy_dump_id; enum driver_flag { DEFAULT_IF = 0x1, @@ -105,6 +106,7 @@ struct wiphy { uint16_t supported_ciphers; struct scan_freq_set *supported_freqs; struct scan_freq_set *disabled_freqs; + struct scan_freq_set *pending_freqs; struct band *band_2g; struct band *band_5g; struct band *band_6g; @@ -122,6 +124,7 @@ struct wiphy { struct l_queue *work; bool work_in_callback; unsigned int get_reg_id; + unsigned int dump_id; bool support_scheduled_scan:1; bool support_rekey_offload:1; @@ -342,6 +345,9 @@ static void wiphy_free(void *data) l_debug("Freeing wiphy %s[%u]", wiphy->name, wiphy->id); + if (wiphy->dump_id) + l_genl_family_cancel(nl80211, wiphy->dump_id); + if (wiphy->get_reg_id) l_genl_family_cancel(nl80211, wiphy->get_reg_id); @@ -1839,6 +1845,182 @@ static void wiphy_setup_rm_enabled_capabilities(struct wiphy *wiphy) */ } +static void wiphy_dump_done(void *user_data) +{ + struct wiphy *wiphy = user_data; + const struct l_queue_entry *e; + + /* This dump was canceled due to another dump */ + if ((wiphy && !wiphy->dump_id) || (!wiphy && !wiphy_dump_id)) + return; + + if (wiphy) { + wiphy->dump_id = 0; + scan_freq_set_free(wiphy->disabled_freqs); + wiphy->disabled_freqs = wiphy->pending_freqs; + wiphy->pending_freqs = NULL; + + WATCHLIST_NOTIFY(&wiphy->state_watches, + wiphy_state_watch_func_t, wiphy, + WIPHY_STATE_WATCH_EVENT_REGDOM_DONE); + + return; + } + + wiphy_dump_id = 0; + + for (e = l_queue_get_entries(wiphy_list); e; e = e->next) { + wiphy = e->data; + + if (!wiphy->pending_freqs || wiphy->self_managed) + continue; + + scan_freq_set_free(wiphy->disabled_freqs); + wiphy->disabled_freqs = wiphy->pending_freqs; + wiphy->pending_freqs = NULL; + + WATCHLIST_NOTIFY(&wiphy->state_watches, + wiphy_state_watch_func_t, wiphy, + WIPHY_STATE_WATCH_EVENT_REGDOM_DONE); + } +} + +/* We are dumping wiphy(s) due to a regulatory change */ +static void wiphy_dump_callback(struct l_genl_msg *msg, + void *user_data) +{ + struct wiphy *wiphy; + uint32_t id; + struct l_genl_attr bands; + struct l_genl_attr attr; + uint16_t type; + + if (nl80211_parse_attrs(msg, NL80211_ATTR_WIPHY, &id, + NL80211_ATTR_WIPHY_BANDS, &bands, + NL80211_ATTR_UNSPEC) < 0) + return; + + wiphy = wiphy_find(id); + if (L_WARN_ON(!wiphy)) + return; + + while (l_genl_attr_next(&bands, NULL, NULL, NULL)) { + if (!l_genl_attr_recurse(&bands, &attr)) + return; + + while (l_genl_attr_next(&attr, &type, NULL, NULL)) { + if (type != NL80211_BAND_ATTR_FREQS) + continue; + + nl80211_parse_supported_frequencies(&attr, NULL, + wiphy->pending_freqs); + } + } +} + +static bool wiphy_cancel_last_dump(struct wiphy *wiphy) +{ + const struct l_queue_entry *e; + unsigned int id = 0; + + /* + * Zero command ID to signal that wiphy_dump_done doesn't need to do + * anything. For a self-managed wiphy just free/NULL pending_freqs. For + * a global dump each wiphy needs to be checked and dealt with. + */ + if (wiphy && wiphy->dump_id) { + id = wiphy->dump_id; + wiphy->dump_id = 0; + + scan_freq_set_free(wiphy->pending_freqs); + wiphy->pending_freqs = NULL; + } else if (!wiphy && wiphy_dump_id) { + id = wiphy_dump_id; + wiphy_dump_id = 0; + + for (e = l_queue_get_entries(wiphy_list); e; e = e->next) { + struct wiphy *w = e->data; + + if (!w->pending_freqs || w->self_managed) + continue; + + scan_freq_set_free(w->pending_freqs); + w->pending_freqs = NULL; + } + } + + if (id) { + l_debug("Canceling pending regdom wiphy dump (%s)", + wiphy ? wiphy->name : "global"); + + l_genl_family_cancel(nl80211, id); + } + + return id != 0; +} + +static void wiphy_dump_after_regdom(struct wiphy *wiphy) +{ + const struct l_queue_entry *e; + struct l_genl_msg *msg; + unsigned int id; + bool no_start_event; + + msg = l_genl_msg_new_sized(NL80211_CMD_GET_WIPHY, 128); + + if (wiphy) + l_genl_msg_append_attr(msg, NL80211_ATTR_WIPHY, 4, &wiphy->id); + + l_genl_msg_append_attr(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP, 0, NULL); + id = l_genl_family_dump(nl80211, msg, wiphy_dump_callback, + wiphy, wiphy_dump_done); + if (!id) { + l_error("Wiphy information dump failed"); + l_genl_msg_unref(msg); + return; + } + + /* + * Another update while dumping wiphy. This next dump should supercede + * the first and not result in a DONE event until this new dump is + * finished. This is because the disabled frequencies are in an unknown + * state and could cause incorrect behavior by any watchers. + */ + no_start_event = wiphy_cancel_last_dump(wiphy); + + /* Limited dump so just emit the event for this wiphy */ + if (wiphy) { + wiphy->dump_id = id; + wiphy->pending_freqs = scan_freq_set_new(); + + if (no_start_event) + return; + + WATCHLIST_NOTIFY(&wiphy->state_watches, + wiphy_state_watch_func_t, wiphy, + WIPHY_STATE_WATCH_EVENT_REGDOM_STARTED); + return; + } + + wiphy_dump_id = id; + + /* Otherwise for a global regdom change notify for all wiphy's */ + for (e = l_queue_get_entries(wiphy_list); e; e = e->next) { + struct wiphy *w = e->data; + + if (w->self_managed) + continue; + + w->pending_freqs = scan_freq_set_new(); + + if (no_start_event) + continue; + + WATCHLIST_NOTIFY(&w->state_watches, wiphy_state_watch_func_t, + w, WIPHY_STATE_WATCH_EVENT_REGDOM_STARTED); + } +} + static void wiphy_update_reg_domain(struct wiphy *wiphy, bool global, struct l_genl_msg *msg) { @@ -2110,6 +2292,8 @@ static void setup_wiphy_interface(struct l_dbus_interface *interface) static void wiphy_reg_notify(struct l_genl_msg *msg, void *user_data) { uint8_t cmd = l_genl_msg_get_command(msg); + struct wiphy *wiphy = NULL; + uint32_t wiphy_id; l_debug("Notification of command %s(%u)", nl80211cmd_to_string(cmd), cmd); @@ -2119,22 +2303,21 @@ static void wiphy_reg_notify(struct l_genl_msg *msg, void *user_data) wiphy_update_reg_domain(NULL, true, msg); break; case NL80211_CMD_WIPHY_REG_CHANGE: - { - uint32_t wiphy_id; - struct wiphy *wiphy; - if (nl80211_parse_attrs(msg, NL80211_ATTR_WIPHY, &wiphy_id, NL80211_ATTR_UNSPEC) < 0) - break; + return; wiphy = wiphy_find(wiphy_id); if (!wiphy) - break; + return; wiphy_update_reg_domain(wiphy, false, msg); break; + default: + return; } - } + + wiphy_dump_after_regdom(wiphy); } static void wiphy_radio_work_next(struct wiphy *wiphy) @@ -2313,6 +2496,11 @@ static void wiphy_exit(void) l_strfreev(whitelist_filter); l_strfreev(blacklist_filter); + if (wiphy_dump_id) { + l_genl_family_cancel(nl80211, wiphy_dump_id); + wiphy_dump_id = 0; + } + l_queue_destroy(wiphy_list, wiphy_free); wiphy_list = NULL; From patchwork Thu Aug 4 18:51:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Prestwood X-Patchwork-Id: 12936605 Received: from mail-pl1-f174.google.com (mail-pl1-f174.google.com [209.85.214.174]) (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 A000B5381 for ; Thu, 4 Aug 2022 18:51:17 +0000 (UTC) Received: by mail-pl1-f174.google.com with SMTP id p18so630376plr.8 for ; Thu, 04 Aug 2022 11:51:17 -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=YKsn5N8WM2TITn5H+mBaX48uKeeMhXvkmYo3teNknnk=; b=n/2mZyYy35hmGVef7Lm8XWS+kP7RMSnb/QQbH1LJeGAGUgjXQWTbhPW8/KgWqSvZxM N5g8bNHtoHstJf6aw9CYItRYKXQqW1Q2W4OFt+SsD1oYJJMAC3DUHf4AZLw2BHXPGJkE l7EakuTp9o1+s4T/ivChDVA/tzPFPPn8rr9oIuKutXwPKsxMBRi+jZCnjdYN0QyAVl5F Z5MimlrH+ETEYkRhVfN11atVGSw/Jj1Ke+wxSYiBBmwuCIXJco5fNM4JucvBNt1/bEq1 YDMU2DeVWoaE5fW6cQFUqtlQl2SjI+q2ubBKKcWIMeADC+KQDerKrsM61pizbzAymLLw RI8Q== 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=YKsn5N8WM2TITn5H+mBaX48uKeeMhXvkmYo3teNknnk=; b=C7HeET2S3QIJS5WrktAEem7r5uPk5Wbahkgih8bJSsiLH/Zr+CN0tl8G7BAGWsEFXk JW+hNj9awSSEE+Wqpazw18scUYaG0KQOOdP/kkbCmYOYeMx40VG2YSV+OuyMMFTdF7xW XOEHUNt6nZBgdoxsPPwb0nqVZ2odQHnzLMAccLTJzHMYLgKjxhzAONtJ3u5TQnCDxEq/ iMJDAAuI3gsmeL9+KYvKZE7LXoIcZI4fdtZZIqPNAXEeZ+tHPGWJu30RiUCvJYO496eg 6m3Rd/6SR/2SfslUB/FLfth8mAl1STZshmQR+Y1KmeEfdpsoTfadD73UhhuY1zlKRn/j jFUw== X-Gm-Message-State: ACgBeo2pJYh6x3UIMz5DEFa2F2dCtGDeh7WMi3wsB7L3NEcHSo7wfo4i En/7FHD+Iq0XW8YDU89oNuhwfg4CbqA= X-Google-Smtp-Source: AA6agR4FnjVJM8ntUN+KLsoxHZeoE32QG2FXlLVLwomGMYgVHA5RrIAI6c27n5pc68AHWsC+BAroPw== X-Received: by 2002:a17:902:b786:b0:16d:a8f3:b2c2 with SMTP id e6-20020a170902b78600b0016da8f3b2c2mr3161657pls.91.1659639076921; Thu, 04 Aug 2022 11:51:16 -0700 (PDT) Received: from jprestwo-xps.none ([50.45.187.22]) by smtp.gmail.com with ESMTPSA id c7-20020a634e07000000b0041b3c112b1esm219954pgb.29.2022.08.04.11.51.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Aug 2022 11:51:16 -0700 (PDT) From: James Prestwood To: iwd@lists.linux.dev Cc: James Prestwood Subject: [PATCH v3 3/7] wiphy: add wiphy_regdom_is_updating Date: Thu, 4 Aug 2022 11:51:08 -0700 Message-Id: <20220804185112.457670-3-prestwoj@gmail.com> X-Mailer: git-send-email 2.34.3 In-Reply-To: <20220804185112.457670-1-prestwoj@gmail.com> References: <20220804185112.457670-1-prestwoj@gmail.com> Precedence: bulk X-Mailing-List: iwd@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This allows a module to check the current status of the regdom in case it misses the wiphy event (e.g. registers after the STARTED event). --- src/wiphy.c | 5 +++++ src/wiphy.h | 1 + 2 files changed, 6 insertions(+) diff --git a/src/wiphy.c b/src/wiphy.c index dfdca989..3beb351c 100644 --- a/src/wiphy.c +++ b/src/wiphy.c @@ -921,6 +921,11 @@ int wiphy_estimate_data_rate(struct wiphy *wiphy, out_data_rate); } +bool wiphy_regdom_is_updating(struct wiphy *wiphy) +{ + return wiphy->pending_freqs != NULL; +} + uint32_t wiphy_state_watch_add(struct wiphy *wiphy, wiphy_state_watch_func_t func, void *user_data, wiphy_destroy_func_t destroy) diff --git a/src/wiphy.h b/src/wiphy.h index da2eca20..2159fc00 100644 --- a/src/wiphy.h +++ b/src/wiphy.h @@ -134,6 +134,7 @@ int wiphy_estimate_data_rate(struct wiphy *wiphy, const void *ies, uint16_t ies_len, const struct scan_bss *bss, uint64_t *out_data_rate); +bool wiphy_regdom_is_updating(struct wiphy *wiphy); uint32_t wiphy_state_watch_add(struct wiphy *wiphy, wiphy_state_watch_func_t func, void *user_data, From patchwork Thu Aug 4 18:51:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Prestwood X-Patchwork-Id: 12936606 Received: from mail-pg1-f180.google.com (mail-pg1-f180.google.com [209.85.215.180]) (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 7A72C28F9 for ; Thu, 4 Aug 2022 18:51:18 +0000 (UTC) Received: by mail-pg1-f180.google.com with SMTP id d7so630366pgc.13 for ; Thu, 04 Aug 2022 11:51:18 -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=VUGZsRjXnvMMiol65M/eC5toD4JAQnOrf4VlNwDGoWM=; b=Wc71uQs/PS1NcQtl2vKQv7cWA1mTHmf37enmyfjh08D6mdL6yHUrwSafKFQfrR+Auj 5fTNl1GPxoPF0uyk0AcQ4/VBebHCw8gulYCNZqxTKciBFTLwOOIA9KBGVrOdEPSU26DC C0YlR5cQT/d0QXhNZKEoZXO6VqgldPEhpitKZzwe8HKoLi9HTqF2WLXthdVBgfli5MXx DWJfv5eUWj7uERqRcF2ezHmNC7/gFQ3/IgIHAloHabV3cWu2b3lZAEHjtafrNkQIPySY WfsPakNztcA7OGcrLSgl6ZxSbUsrZB+w4iXZVDdOqRW5amzBf/M2Jn89z9sKirJnRHgp KZ3A== 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=VUGZsRjXnvMMiol65M/eC5toD4JAQnOrf4VlNwDGoWM=; b=zqWNPvrOordQxhpZLnj2SV+V65uyTni5lrVAame8jmHQqGqZZMOpkZtW9J+QoeDae7 FDW5Obrwevnup07lHkpZ2mY8wT1GBgbTdc+O5hbr4YQaaMq2MwfgKDLc6+aar8uid7Jj uFpR8lYIZUzyfUhYk84KAPw66t3NNCF7ONGqYYsiTHQZFnbcJMtOq1HsiVG24UdnZYB6 KrEWDzbhz7bFkp1L3yIBluyUp40vVezm9CnP3ZAWufGNdEIzn5AVyzcIYggiIHloqajC 85eZUchFUWqfthoYfxqBuGB/JPrVXf0Nh0HZU/MeXQC1gmmxmcaPAHtThFvzJGeMY5EW I+Sw== X-Gm-Message-State: ACgBeo1Uuvk9nrOalSOZPpkutAGe2N1XtdYWLc/eMSCbQ6mjPnH2QDC+ 0ESVaV3xWoIc+oGl5lSoeZb76bKLmC8= X-Google-Smtp-Source: AA6agR7MHtSHNMr/EEdDaPLgQsKnAzykpBBMCPfSl9XEP1oc0TLHJ2vRPKl1eElDlSB1k3Xm3VPlPw== X-Received: by 2002:a05:6a00:b55:b0:52a:db7b:2880 with SMTP id p21-20020a056a000b5500b0052adb7b2880mr3020087pfo.22.1659639077566; Thu, 04 Aug 2022 11:51:17 -0700 (PDT) Received: from jprestwo-xps.none ([50.45.187.22]) by smtp.gmail.com with ESMTPSA id c7-20020a634e07000000b0041b3c112b1esm219954pgb.29.2022.08.04.11.51.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Aug 2022 11:51:17 -0700 (PDT) From: James Prestwood To: iwd@lists.linux.dev Cc: James Prestwood Subject: [PATCH v3 4/7] station: do full passive scan if 6GHz is supported but disabled. Date: Thu, 4 Aug 2022 11:51:09 -0700 Message-Id: <20220804185112.457670-4-prestwoj@gmail.com> X-Mailer: git-send-email 2.34.3 In-Reply-To: <20220804185112.457670-1-prestwoj@gmail.com> References: <20220804185112.457670-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 handles setting the regulatory domain by receiving beacons which set the country IE. Presumably since most regulatory domains disallow 6GHz the default (world) domain also disables it. This means until the country is set, 6GHz is disabled. This poses a problem for IWD's quick scanning since it only scans a few frequencies and this likely isn't enough beacons for the firmware to update the country, leaving 6Ghz inaccessable to the user without manual intervention (e.g. iw scan passive, or periodic scans by IWD). To try and work around this limitation the quick scan logic has been updated to check if a 6GHz AP has been connected to before and if that frequency is disabled (but supported). If this is the case IWD will opt for a full passive scan rather than scanning a limited set of frequencies. --- src/station.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) v3: * Return -EAGAIN in the case of a regdom update rather than 0. Check this along with 0 in both calls. * Re-worked the wiphy state event to focus only on the DONE event, and set regdom_updated based on wiphy_regdom_is_updating. This avoids a switch statement when its mainly the DONE event we care about. * Check quick_scan_id if regdom update so we aren't accidentally re-triggering a quick scan. diff --git a/src/station.c b/src/station.c index e39e9d4b..e3a36f46 100644 --- a/src/station.c +++ b/src/station.c @@ -112,6 +112,8 @@ struct station { struct scan_freq_set *scan_freqs_order[3]; unsigned int dbus_scan_subset_idx; + uint32_t wiphy_watch; + bool preparing_roam : 1; bool roam_scan_full : 1; bool signal_low : 1; @@ -119,6 +121,7 @@ struct station { bool scanning : 1; bool autoconnect : 1; bool autoconnect_can_start : 1; + bool regdom_updating : 1; }; struct anqp_entry { @@ -1353,11 +1356,36 @@ static void station_quick_scan_destroy(void *userdata) static int station_quick_scan_trigger(struct station *station) { struct scan_freq_set *known_freq_set; + bool known_6ghz; + const struct scan_freq_set *disabled = wiphy_get_disabled_freqs( + station->wiphy); + + if (station->regdom_updating) { + l_debug("regdom is updating, delaying quick scan"); + + return -EAGAIN; + } known_freq_set = known_networks_get_recent_frequencies(5); if (!known_freq_set) return -ENODATA; + known_6ghz = scan_freq_set_get_bands(known_freq_set) & BAND_FREQ_6_GHZ; + + /* + * This means IWD has previously connected to a 6GHz AP before, but now + * the regulatory domain disallows 6GHz likely caused by a reboot, the + * firmware going down, or a regulatory update. The only way to + * re-enable 6GHz is to get enough beacons via scanning for the firmware + * to set the regulatory domain. A quick scan is very unlikely to do + * this since its so limited, so return an error which will fall back to + * full autoconnect. + */ + if ((scan_freq_set_get_bands(disabled) & BAND_FREQ_6_GHZ) && + wiphy_country_is_unknown(station->wiphy) && + known_6ghz) + return -ENOTSUP; + if (!wiphy_constrain_freq_set(station->wiphy, known_freq_set)) { scan_freq_set_free(known_freq_set); return -ENOTSUP; @@ -1446,6 +1474,7 @@ static void station_enter_state(struct station *station, uint64_t id = netdev_get_wdev_id(station->netdev); struct l_dbus *dbus = dbus_get_bus(); bool disconnected; + int ret; l_debug("Old State: %s, new state: %s", station_state_to_string(station->state), @@ -1462,7 +1491,8 @@ static void station_enter_state(struct station *station, switch (state) { case STATION_STATE_AUTOCONNECT_QUICK: - if (!station_quick_scan_trigger(station)) + ret = station_quick_scan_trigger(station); + if (ret == 0 || ret == -EAGAIN) break; station->state = STATION_STATE_AUTOCONNECT_FULL; @@ -3988,6 +4018,36 @@ static void station_fill_scan_freq_subsets(struct station *station) } } +static void station_wiphy_watch(struct wiphy *wiphy, + enum wiphy_state_watch_event event, + void *user_data) +{ + struct station *station = user_data; + int ret; + + station->regdom_updating = wiphy_regdom_is_updating(wiphy); + + if (event != WIPHY_STATE_WATCH_EVENT_REGDOM_DONE) + return; + + /* + * The only state that requires special handling is for + * quick scans since the previous quick scan was delayed until + * the regulatory domain updated. Try again in case 6Ghz is now + * unlocked (unlikely), or advance to full autoconnect. Just in + * case this update came during a quick scan, ignore it. + */ + if (station->state != STATION_STATE_AUTOCONNECT_QUICK || + station->quick_scan_id) + return; + + ret = station_quick_scan_trigger(station); + if (ret == 0 || ret == -EAGAIN) + return; + + station_enter_state(station, STATION_STATE_AUTOCONNECT_FULL); +} + static struct station *station_create(struct netdev *netdev) { struct station *station; @@ -4008,6 +4068,11 @@ static struct station *station_create(struct netdev *netdev) station->wiphy = netdev_get_wiphy(netdev); station->netdev = netdev; + station->wiphy_watch = wiphy_state_watch_add(station->wiphy, + station_wiphy_watch, + station, NULL); + station->regdom_updating = wiphy_regdom_is_updating(station->wiphy); + l_queue_push_head(station_list, station); l_dbus_object_add_interface(dbus, netdev_get_path(netdev), @@ -4117,6 +4182,8 @@ static void station_free(struct station *station) if (station->scan_freqs_order[2]) scan_freq_set_free(station->scan_freqs_order[2]); + wiphy_state_watch_remove(station->wiphy, station->wiphy_watch); + l_free(station); } From patchwork Thu Aug 4 18:51:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Prestwood X-Patchwork-Id: 12936607 Received: from mail-pf1-f173.google.com (mail-pf1-f173.google.com [209.85.210.173]) (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 40AD35381 for ; Thu, 4 Aug 2022 18:51:19 +0000 (UTC) Received: by mail-pf1-f173.google.com with SMTP id w185so299067pfb.4 for ; Thu, 04 Aug 2022 11:51:19 -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=X11Al+otvb1mqCp6xZM1E1PKL9zxEt5ibnsXp3lZgns=; b=QvGjurhSIcauuBhVqxfHyLlTDwaHoEqAEalm40RTJM/2iewcUDo/qWfLyZHcDwa70G hiy/sGSX3li8GkWsgq+VY6RXxMZYaQRQ38rqz8R8TBBwQmjMqrvL4gJEbkV0lQUqNRFH D7BzQQ4OVprr2Uc2dQdg6DLxhF+SQkX9mfmkTYKIczFU8q2GaLpCggoKKqzCFZNhSMXH ahLXs54nYB6qKIy8C60HHXJgnNqTqMO1ror5RGC7jQLG2rnoUJlLw+dw0sfceR47QfmR 7K60bLaxIp6z04i5JWKo2Yr6DR5GnojEbW5u6MXhEcoCt6V5ecIeyzgWaFQJKGkpBVcB yxNQ== 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=X11Al+otvb1mqCp6xZM1E1PKL9zxEt5ibnsXp3lZgns=; b=BGYuYHqhSy8BycHsmE8tnjxYtvso5dltrpTawz3Z8Pd5wR34/tHKfhhMtPvld31Q9x nQnbE0KMfl4OSDSRpOZb5IQF55OM80IZTU2ZCCN/TchBZWoSrdroBEH43iNolKNjyw/q il3RbIrCQjT19C/WaHIPQSR8bQeglSTKp8pgCfcSFXy1yGs3FeK1ZYY7xOChXeVKytpl l6edE2IHJygqHz5xRqb8m0rOJ0s6Y3WSaZoow4H5gSJhSj6dnPvTNpNz1D4O9pwe55mp ia9vsDBSz1nX0/i4q3c4Enwi7NQ+oQBbnDVTqUq12Ofc3br/MUtFiRdaUDjZFVSrfof/ MGHQ== X-Gm-Message-State: ACgBeo2AN7byvwYQaYNlB0//WB90jf/F8v44d/Rv/adzh4sOAfUyL2Pt Az3WZcQolXth3QhjQM/A92/Bhv51gZQ= X-Google-Smtp-Source: AA6agR5tn8zaXlsqOKR/7jokIQgzFet0NwZzv6QH3lBhYBUvkYqa2SmpqkmC7n1KUDej+HmwjvFLZA== X-Received: by 2002:a63:4c4c:0:b0:41c:b81a:a16f with SMTP id m12-20020a634c4c000000b0041cb81aa16fmr2600429pgl.584.1659639078443; Thu, 04 Aug 2022 11:51:18 -0700 (PDT) Received: from jprestwo-xps.none ([50.45.187.22]) by smtp.gmail.com with ESMTPSA id c7-20020a634e07000000b0041b3c112b1esm219954pgb.29.2022.08.04.11.51.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Aug 2022 11:51:18 -0700 (PDT) From: James Prestwood To: iwd@lists.linux.dev Cc: James Prestwood Subject: [PATCH v3 5/7] scan: split full scans by band to enable 6GHz Date: Thu, 4 Aug 2022 11:51:10 -0700 Message-Id: <20220804185112.457670-5-prestwoj@gmail.com> X-Mailer: git-send-email 2.34.3 In-Reply-To: <20220804185112.457670-1-prestwoj@gmail.com> References: <20220804185112.457670-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 | 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, ¶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 18:51:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Prestwood X-Patchwork-Id: 12936608 Received: from mail-pg1-f179.google.com (mail-pg1-f179.google.com [209.85.215.179]) (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 C34F25385 for ; Thu, 4 Aug 2022 18:51:19 +0000 (UTC) Received: by mail-pg1-f179.google.com with SMTP id h132so646785pgc.10 for ; Thu, 04 Aug 2022 11:51:19 -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=qe39BLq4IBDTBxHdRyJt9ZBbv1zb2MsXCAL9qTwxMkA=; b=QGgeig/5c92II35Mfql4FGT5lvMvgFkKYRH3C2gSI3L17xUxHXCXeMxoX9qRwQ8maC bvAoIzgTHEV2MfC9ZrOJwfjuqRprKzFAlgiuwn4zHE1B4dgSVFopP6l5BBay3rhvsd6/ lMCCG+xaEL96Nhe97l8eqNqE7zo3Vv9zJRtTmmcgVIKXbdMKZ+76v2SEqPGnY7z3/JyY /wpyhsEMjbScfGXl9PZwyGOMHdUvSNpBuH0mHojBQgUqncv3KhHfSJKKiiNQ9URuAcpb 1j0K9umTGCiaDXLD3VoX+Gt93kdjArIFsLqRTTC+UvWyO3jM0loiyPvYEdiIGrbeOY9t V5HQ== 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=qe39BLq4IBDTBxHdRyJt9ZBbv1zb2MsXCAL9qTwxMkA=; b=eSp/bFsC0F1iWei5gjZNx+5XurCikNket3ciNZqMQ/57px1X7YZfmsRUaiVwrkv8Vh T1FPE8sSegohYldT7uh6c/U78eqhE39jaweTLwpTPDK6A+LwvjaDmskmS0R0dRI7Jycg AzisroP5zIJkP17ZvVKK3vEpH4jon7Sx9KRYUSkttH3xNwRo2CiPcc6WTblpIoA/iO4n zWwgj+2sWZE8zXkdGeRVCz1ua/zOWtLdTTvXoPcYV1UKGys6ljxQ18k3QlAXTXvPwWvT OVcdU0ID5Lj2PfmmaLa6o9/VqLVeuLtvLhTN9POEgiUGGlorcq5pEcBJ/p7/pFVs8nQe EMDQ== X-Gm-Message-State: ACgBeo1KcyogrgRP+kFRoUPR0vJDyiRhiezsijrBnnlbXtozyS6Kek6K tJxsmt3KeaMqvKqubTRx6uoIWvlVKAE= X-Google-Smtp-Source: AA6agR4tw95mKtK0uo/viQorqEzwbQszxnZhM+0G0Ja1O6P2eSJyQTCYj12kg+MSBzG+KRC+r/ofDQ== X-Received: by 2002:a05:6a00:1a14:b0:52d:5fee:d46b with SMTP id g20-20020a056a001a1400b0052d5feed46bmr2961431pfv.82.1659639078931; Thu, 04 Aug 2022 11:51:18 -0700 (PDT) Received: from jprestwo-xps.none ([50.45.187.22]) by smtp.gmail.com with ESMTPSA id c7-20020a634e07000000b0041b3c112b1esm219954pgb.29.2022.08.04.11.51.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Aug 2022 11:51:18 -0700 (PDT) From: James Prestwood To: iwd@lists.linux.dev Cc: James Prestwood Subject: [PATCH v3 6/7] scan: watch for regdom updates to enable 6GHz Date: Thu, 4 Aug 2022 11:51:11 -0700 Message-Id: <20220804185112.457670-6-prestwoj@gmail.com> X-Mailer: git-send-email 2.34.3 In-Reply-To: <20220804185112.457670-1-prestwoj@gmail.com> References: <20220804185112.457670-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 | 165 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 147 insertions(+), 18 deletions(-) diff --git a/src/scan.c b/src/scan.c index e016bd4d..40e527d9 100644 --- a/src/scan.c +++ b/src/scan.c @@ -71,6 +71,8 @@ struct scan_periodic { void *userdata; uint32_t id; bool needs_active_scan:1; + /* Delay periodic scan results until regulatory domain updates */ + bool wait_on_regdom:1; }; struct scan_request { @@ -108,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 @@ -126,6 +129,8 @@ struct scan_context { */ unsigned int get_fw_scan_cmd_id; struct wiphy *wiphy; + /* 6GHz may become available after a regdom update */ + bool expect_6ghz : 1; }; struct scan_results { @@ -184,24 +189,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; @@ -227,6 +214,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); } @@ -477,6 +466,142 @@ done: return msg; } +static void scan_add_6ghz(uint32_t freq, void *user_data) +{ + struct scan_freq_set *freqs = user_data; + + if (freq < 6000) + return; + + scan_freq_set_add(freqs, freq); +} + +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; + 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_STARTED && + event != WIPHY_STATE_WATCH_EVENT_REGDOM_DONE) || + !(scan_freq_set_get_bands(supported) & BAND_FREQ_6_GHZ)) + return; + + allowed = scan_get_allowed_freqs(sc); + allow_6g = scan_freq_set_get_bands(allowed) & BAND_FREQ_6_GHZ; + + switch (event) { + case WIPHY_STATE_WATCH_EVENT_REGDOM_STARTED: + if (allow_6g) + goto done; + + sc->expect_6ghz = true; + + /* + * If there is a running/queued periodic scan we may need to + * delay the results if 6GHz becomes available. + */ + if (sc->sp.id) + sc->sp.wait_on_regdom = true; + + goto done; + case WIPHY_STATE_WATCH_EVENT_REGDOM_DONE: + if (!sc->expect_6ghz) + goto done; + + sc->expect_6ghz = false; + + if (!sc->sp.id) + goto done; + + sr = l_queue_find(sc->requests, scan_request_match, + L_UINT_TO_PTR(sc->sp.id)); + if (!sr) + goto done; + + /* This update did not allow 6GHz */ + if (!allow_6g) + goto check_periodic; + + /* + * 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_new(); + + scan_freq_set_foreach(allowed, scan_add_6ghz, freqs_6ghz); + + msg = scan_build_cmd(sc, false, true, ¶ms, freqs_6ghz); + l_queue_push_tail(sr->cmds, msg); + + scan_freq_set_free(freqs_6ghz); + +check_periodic: + if (sc->sp.wait_on_regdom) { + /* Periodic scan results delayed until this update */ + if (sr && l_queue_peek_head(sc->requests) == sr) + start_next_scan_request(&sr->work); + + sc->sp.wait_on_regdom = false; + } + + break; + default: + return; + } + +done: + scan_freq_set_free(allowed); +} + +/* + * Should only used to initialize 'expect_6ghz'. This is only to cover the case + * of a scan context being created during a regulatory update, which means it + * would miss the START event. If a DONE event comes, and expect_6ghz is false, + * no further action would be taken which may be incorrect. + */ +static bool scan_expect_6ghz(struct wiphy *wiphy) +{ + const struct scan_freq_set *supported = + wiphy_get_supported_freqs(wiphy); + + if (!(scan_freq_set_get_bands(supported) & BAND_FREQ_6_GHZ)) + return false; + + return wiphy_regdom_is_updating(wiphy); +} + +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->expect_6ghz = scan_expect_6ghz(wiphy); + sc->wiphy_watch_id = wiphy_state_watch_add(wiphy, scan_wiphy_watch, + sc, NULL); + + return sc; +} + struct l_genl_msg *scan_build_trigger_scan_bss(uint32_t ifindex, struct wiphy *wiphy, uint32_t frequency, @@ -2120,6 +2245,10 @@ 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 && sc->sp.wait_on_regdom) + return; + if (!sr->callback) { scan_finished(sc, -ECANCELED, NULL, NULL, sr); break; From patchwork Thu Aug 4 18:51:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Prestwood X-Patchwork-Id: 12936609 Received: from mail-pj1-f47.google.com (mail-pj1-f47.google.com [209.85.216.47]) (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 19B6228F9 for ; Thu, 4 Aug 2022 18:51:20 +0000 (UTC) Received: by mail-pj1-f47.google.com with SMTP id o5-20020a17090a3d4500b001ef76490983so660275pjf.2 for ; Thu, 04 Aug 2022 11:51:20 -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=wsQ59p4psmTzZ/XOUqXYraFK9AD2nSA95AN9KOpoD2g=; b=MjorjsfaF5/25DptJy8qt3PWMwGlT7fC7yTwrH+qilOJgRgc4vRbX+74NvFBtDf2te bIXtFitUcjbH/xix+E+hGlifd2N3Jqn3lhGzYDd3sBW3XuvGXcNezNwbPEEBjc8HP8LI v2fUdDF6IVZU7Ol4kfs4KLqRRkerPgBCKvgiGBpW5PouKjNV89wQFpBQztiHCluzYqIC tWXaBEfvaYJrwLZVWSzPcDbyRMnYGDR0ygVdgDprq7QEF/3TpUXVBmmi42iDMEjLlSP9 CVNpU1zFMg3RKUS030/Nujf1wvCcd9AvesAdpyXEFduqXbB2CUV3Kn0sn5bePE52vKHL fAuQ== 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=wsQ59p4psmTzZ/XOUqXYraFK9AD2nSA95AN9KOpoD2g=; b=YNI9f3IFWXCUmvmb4nawbQ1INSmV4Tk7nutRtpI3RlUuu7/ndhpXYgy+lLg7WTIGoS 3TbY2Uru6dewqE1ESJmGJlPTehbjSjBWXxtzqnDDcUZpSkyW58uvk/zlT4Mb8zEl2Tyw FaZDK2lLSpTsGN6wla8+dv053aNnhBAjtF3imwwEr+3HS9oYlFcQqUbvbRPRvwbUDMNU xteOXn+3MhYX9O7+/yIeWyCZL7i5bLZ6B4RVVsmZXucmUiVUJl1cVvIXW1LVblZbSAXP i3m4JzxqGwkszPMUtnBw4xwszZ5bMCwYWl//otBQdNWkkZcg4Z2Bmpmgs969ECax1yCf 6kHw== X-Gm-Message-State: ACgBeo2rrYD5j02ecbkOIsRdZARpHSwa7LbzhTUWUxdlWbV8vKoVpWWS GMDTNL4g/2Q0R9aMHxc64Yv3+e7G8eE= X-Google-Smtp-Source: AA6agR5AuEdxfij2QfBW89h50cVGP9iRH5oy48u1FFKBcqZ1lRLxIhx8iKyVfDA5jHDxaIxr9oRAZA== X-Received: by 2002:a17:90a:f490:b0:1f3:139e:a487 with SMTP id bx16-20020a17090af49000b001f3139ea487mr11989641pjb.91.1659639079444; Thu, 04 Aug 2022 11:51:19 -0700 (PDT) Received: from jprestwo-xps.none ([50.45.187.22]) by smtp.gmail.com with ESMTPSA id c7-20020a634e07000000b0041b3c112b1esm219954pgb.29.2022.08.04.11.51.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Aug 2022 11:51:19 -0700 (PDT) From: James Prestwood To: iwd@lists.linux.dev Cc: James Prestwood Subject: [PATCH v3 7/7] wiphy: don't re-dump wiphy if the regdom didn't change Date: Thu, 4 Aug 2022 11:51:12 -0700 Message-Id: <20220804185112.457670-7-prestwoj@gmail.com> X-Mailer: git-send-email 2.34.3 In-Reply-To: <20220804185112.457670-1-prestwoj@gmail.com> References: <20220804185112.457670-1-prestwoj@gmail.com> Precedence: bulk X-Mailing-List: iwd@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 For whatever reason the kernel will send regdom updates even if the regdom didn't change. This ends up causing wiphy to dump which isn't needed since there should be no changes in disabled frequencies. Now the previous country is checked against the new one, and if they match the wiphy is not dumped again. --- src/wiphy.c | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/src/wiphy.c b/src/wiphy.c index 3beb351c..28d4b66e 100644 --- a/src/wiphy.c +++ b/src/wiphy.c @@ -2026,10 +2026,19 @@ static void wiphy_dump_after_regdom(struct wiphy *wiphy) } } -static void wiphy_update_reg_domain(struct wiphy *wiphy, bool global, +static bool wiphy_update_reg_domain(struct wiphy *wiphy, bool global, struct l_genl_msg *msg) { - char *out_country; + char out_country[2]; + char *orig; + + /* + * Write the new country code or XX if the reg domain is not a + * country domain. + */ + if (nl80211_parse_attrs(msg, NL80211_ATTR_REG_ALPHA2, out_country, + NL80211_ATTR_UNSPEC) < 0) + out_country[0] = out_country[1] = 'X'; if (global) /* @@ -2043,21 +2052,26 @@ static void wiphy_update_reg_domain(struct wiphy *wiphy, bool global, * wiphy created (that is not self-managed anyway) and we * haven't received any REG_CHANGE events yet. */ - out_country = regdom_country; + orig = regdom_country; + else - out_country = wiphy->regdom_country; + orig = wiphy->regdom_country; /* - * Write the new country code or XX if the reg domain is not a - * country domain. + * The kernel seems to send regdom updates even if the country didn't + * change. Skip these as there is no reason to re-dump. */ - if (nl80211_parse_attrs(msg, NL80211_ATTR_REG_ALPHA2, out_country, - NL80211_ATTR_UNSPEC) < 0) - out_country[0] = out_country[1] = 'X'; + if (orig[0] == out_country[0] && orig[1] == out_country[1]) + return false; l_debug("New reg domain country code for %s is %c%c", global ? "(global)" : wiphy->name, out_country[0], out_country[1]); + + orig[0] = out_country[0]; + orig[1] = out_country[1]; + + return true; } static void wiphy_get_reg_cb(struct l_genl_msg *msg, void *user_data) @@ -2305,7 +2319,8 @@ static void wiphy_reg_notify(struct l_genl_msg *msg, void *user_data) switch (cmd) { case NL80211_CMD_REG_CHANGE: - wiphy_update_reg_domain(NULL, true, msg); + if (!wiphy_update_reg_domain(NULL, true, msg)) + return; break; case NL80211_CMD_WIPHY_REG_CHANGE: if (nl80211_parse_attrs(msg, NL80211_ATTR_WIPHY, &wiphy_id, @@ -2316,7 +2331,9 @@ static void wiphy_reg_notify(struct l_genl_msg *msg, void *user_data) if (!wiphy) return; - wiphy_update_reg_domain(wiphy, false, msg); + if (!wiphy_update_reg_domain(wiphy, false, msg)) + return; + break; default: return;