]> www.infradead.org Git - users/hch/misc.git/commitdiff
wifi: nl80211: allow drivers to support subset of NL80211_CMD_SET_BSS
authorArend van Spriel <arend.vanspriel@broadcom.com>
Sun, 17 Aug 2025 19:04:32 +0000 (21:04 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Thu, 4 Sep 2025 09:19:02 +0000 (11:19 +0200)
The so-called fullmac devices rely on firmware functionality and/or API to
change BSS parameters. Today there are limited drivers supporting the
nl80211 primitive, but they only handle a subset of the bss parameters
passed if any. The mac80211 driver does handle all parameters and stores
their configured values. Some of the BSS parameters were already conditional
by wiphy->features. For these the wiphy->bss_param_support and wiphy->features
fields are silently aligned in wiphy_register(). Maybe better to issue a warning
instead when they are misaligned.

Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Link: https://patch.msgid.link/20250817190435.1495094-2-arend.vanspriel@broadcom.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/cfg80211.h
include/uapi/linux/nl80211.h
net/wireless/core.c
net/wireless/nl80211.c

index 7d881aa7e48b2095bcb35c4d31b1b50f46b6eb18..4072a67c9cc9b64942a46188c4eaf7d9e7f7ddbb 100644 (file)
@@ -2459,6 +2459,29 @@ struct mpath_info {
        int generation;
 };
 
+/**
+ * enum wiphy_bss_param_flags - bit positions for supported bss parameters.
+ *
+ * @WIPHY_BSS_PARAM_CTS_PROT: support changing CTS protection.
+ * @WIPHY_BSS_PARAM_SHORT_PREAMBLE: support changing short preamble usage.
+ * @WIPHY_BSS_PARAM_SHORT_SLOT_TIME: support changing short slot time usage.
+ * @WIPHY_BSS_PARAM_BASIC_RATES: support reconfiguring basic rates.
+ * @WIPHY_BSS_PARAM_AP_ISOLATE: support changing AP isolation.
+ * @WIPHY_BSS_PARAM_HT_OPMODE: support changing HT operating mode.
+ * @WIPHY_BSS_PARAM_P2P_CTWINDOW: support reconfiguring ctwindow.
+ * @WIPHY_BSS_PARAM_P2P_OPPPS: support changing P2P opportunistic power-save.
+ */
+enum wiphy_bss_param_flags {
+       WIPHY_BSS_PARAM_CTS_PROT = BIT(0),
+       WIPHY_BSS_PARAM_SHORT_PREAMBLE = BIT(1),
+       WIPHY_BSS_PARAM_SHORT_SLOT_TIME = BIT(2),
+       WIPHY_BSS_PARAM_BASIC_RATES = BIT(3),
+       WIPHY_BSS_PARAM_AP_ISOLATE = BIT(4),
+       WIPHY_BSS_PARAM_HT_OPMODE = BIT(5),
+       WIPHY_BSS_PARAM_P2P_CTWINDOW = BIT(6),
+       WIPHY_BSS_PARAM_P2P_OPPPS = BIT(7),
+};
+
 /**
  * struct bss_parameters - BSS parameters
  *
@@ -5785,6 +5808,11 @@ struct wiphy_radio {
  *     and probe responses.  This value should be set if the driver
  *     wishes to limit the number of csa counters. Default (0) means
  *     infinite.
+ * @bss_param_support: bitmask indicating which bss_parameters as defined in
+ *     &struct bss_parameters the driver can actually handle in the
+ *     .change_bss() callback. The bit positions are defined in &enum
+ *     wiphy_bss_param_flags.
+ *
  * @bss_select_support: bitmask indicating the BSS selection criteria supported
  *     by the driver in the .connect() callback. The bit position maps to the
  *     attribute indices defined in &enum nl80211_bss_select_attr.
@@ -5970,6 +5998,7 @@ struct wiphy {
 
        u8 max_num_csa_counters;
 
+       u32 bss_param_support;
        u32 bss_select_support;
 
        u8 nan_supported_bands;
index 4f08264bbc8eafe3debb661d87d959ef8c359f05..6c07100fc01f48a0317fb1b5fbf92eee44540122 100644 (file)
@@ -2930,6 +2930,9 @@ enum nl80211_commands {
  *     required alongside this attribute. Refer to
  *     @enum nl80211_s1g_short_beacon_attrs for the attribute definitions.
  *
+ * @NL80211_ATTR_BSS_PARAM: nested attribute used with %NL80211_CMD_GET_WIPHY
+ *     which indicates which BSS parameters can be modified.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3491,6 +3494,7 @@ enum nl80211_attrs {
 
        NL80211_ATTR_S1G_LONG_BEACON_PERIOD,
        NL80211_ATTR_S1G_SHORT_BEACON,
+       NL80211_ATTR_BSS_PARAM,
 
        /* add attributes here, update the policy in nl80211.c */
 
index a7e2931ffb2ef5fb3b14dee39c96d4c6d21a488b..797f9f2004a6948afb0ac617018b5404faba2322 100644 (file)
@@ -1018,6 +1018,15 @@ int wiphy_register(struct wiphy *wiphy)
 
        rdev->wiphy.features |= NL80211_FEATURE_SCAN_FLUSH;
 
+       if (rdev->wiphy.bss_param_support & WIPHY_BSS_PARAM_P2P_CTWINDOW)
+               rdev->wiphy.features |= NL80211_FEATURE_P2P_GO_CTWIN;
+       else if (rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN)
+               rdev->wiphy.bss_param_support |= WIPHY_BSS_PARAM_P2P_CTWINDOW;
+       if (rdev->wiphy.bss_param_support & WIPHY_BSS_PARAM_P2P_OPPPS)
+               rdev->wiphy.features |= NL80211_FEATURE_P2P_GO_OPPPS;
+       else if (rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS)
+               rdev->wiphy.bss_param_support |= WIPHY_BSS_PARAM_P2P_OPPPS;
+
        rtnl_lock();
        wiphy_lock(&rdev->wiphy);
        res = device_add(&rdev->wiphy.dev);
index 364d83fb99924432f927ba7d4ee99b01fe2fab29..153644a040723af474fb29121a9f930fffc3f9b4 100644 (file)
@@ -3027,6 +3027,40 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
                            rdev->wiphy.ext_features))
                        goto nla_put_failure;
 
+               if (rdev->wiphy.bss_param_support) {
+                       struct nlattr *nested;
+                       u32 parsup = rdev->wiphy.bss_param_support;
+
+                       nested = nla_nest_start(msg, NL80211_ATTR_BSS_PARAM);
+                       if (!nested)
+                               goto nla_put_failure;
+
+                       if ((parsup & WIPHY_BSS_PARAM_CTS_PROT) &&
+                           nla_put_flag(msg, NL80211_ATTR_BSS_CTS_PROT))
+                               goto nla_put_failure;
+                       if ((parsup & WIPHY_BSS_PARAM_SHORT_PREAMBLE) &&
+                           nla_put_flag(msg, NL80211_ATTR_BSS_SHORT_PREAMBLE))
+                               goto nla_put_failure;
+                       if ((parsup & WIPHY_BSS_PARAM_SHORT_SLOT_TIME) &&
+                           nla_put_flag(msg, NL80211_ATTR_BSS_SHORT_SLOT_TIME))
+                               goto nla_put_failure;
+                       if ((parsup & WIPHY_BSS_PARAM_BASIC_RATES) &&
+                           nla_put_flag(msg, NL80211_ATTR_BSS_BASIC_RATES))
+                               goto nla_put_failure;
+                       if ((parsup & WIPHY_BSS_PARAM_AP_ISOLATE) &&
+                           nla_put_flag(msg, NL80211_ATTR_AP_ISOLATE))
+                               goto nla_put_failure;
+                       if ((parsup & WIPHY_BSS_PARAM_HT_OPMODE) &&
+                           nla_put_flag(msg, NL80211_ATTR_BSS_HT_OPMODE))
+                               goto nla_put_failure;
+                       if ((parsup & WIPHY_BSS_PARAM_P2P_CTWINDOW) &&
+                           nla_put_flag(msg, NL80211_ATTR_P2P_CTWINDOW))
+                               goto nla_put_failure;
+                       if ((parsup & WIPHY_BSS_PARAM_P2P_OPPPS) &&
+                           nla_put_flag(msg, NL80211_ATTR_P2P_OPPPS))
+                               goto nla_put_failure;
+                       nla_nest_end(msg, nested);
+               }
                if (rdev->wiphy.bss_select_support) {
                        struct nlattr *nested;
                        u32 bss_select_support = rdev->wiphy.bss_select_support;
@@ -9048,6 +9082,7 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
        struct cfg80211_registered_device *rdev = info->user_ptr[0];
        struct net_device *dev = info->user_ptr[1];
        struct bss_parameters params;
+       u32 bss_param_support = rdev->wiphy.bss_param_support;
 
        memset(&params, 0, sizeof(params));
        params.link_id = nl80211_link_id_or_invalid(info->attrs);
@@ -9087,7 +9122,7 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
                params.p2p_ctwindow =
                        nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
                if (params.p2p_ctwindow != 0 &&
-                   !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
+                   !(bss_param_support & WIPHY_BSS_PARAM_P2P_CTWINDOW))
                        return -EINVAL;
        }
 
@@ -9099,7 +9134,7 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
                tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
                params.p2p_opp_ps = tmp;
                if (params.p2p_opp_ps &&
-                   !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
+                   !(bss_param_support & WIPHY_BSS_PARAM_P2P_OPPPS))
                        return -EINVAL;
        }