]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: nl80211: split out UHR operation information
authorJohannes Berg <johannes.berg@intel.com>
Tue, 3 Mar 2026 21:17:09 +0000 (22:17 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 13 Mar 2026 06:10:36 +0000 (07:10 +0100)
The beacon doesn't contain the full UHR operation, a number
of fields (such as NPCA) are only partially there. Add a new
attribute to contain the full information, so it's available
to the driver/mac80211.

Link: https://patch.msgid.link/20260303221710.866bacf82639.Iafdf37fb0f4304bdcdb824977d61e17b38c47685@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/uapi/linux/nl80211.h
net/wireless/nl80211.c

index 0b7a06c2b9f78668decd322b1601cf470b88923a..67d7640239883bdd6e4db66e1fb4a1efb5f7d279 100644 (file)
@@ -3001,6 +3001,10 @@ enum nl80211_commands {
  *     interference detection is not performed on these sub-channels, their
  *     corresponding bits are consistently set to zero.
  *
+ * @NL80211_ATTR_UHR_OPERATION: Full UHR Operation element, as it appears in
+ *     association response etc., since it's abridged in the beacon. Used
+ *     for START_AP etc.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3576,6 +3580,8 @@ enum nl80211_attrs {
 
        NL80211_ATTR_INCUMBENT_SIGNAL_INTERFERENCE_BITMAP,
 
+       NL80211_ATTR_UHR_OPERATION,
+
        /* add attributes here, update the policy in nl80211.c */
 
        __NL80211_ATTR_AFTER_LAST,
index 699687a0caa9f665d150b4e56fd3987c43911326..3e867930e253c229911bd02b106d1dfe654c7f9b 100644 (file)
@@ -344,6 +344,17 @@ static int validate_uhr_capa(const struct nlattr *attr,
        return 0;
 }
 
+static int validate_uhr_operation(const struct nlattr *attr,
+                                 struct netlink_ext_ack *extack)
+{
+       const u8 *data = nla_data(attr);
+       unsigned int len = nla_len(attr);
+
+       if (!ieee80211_uhr_oper_size_ok(data, len, false))
+               return -EINVAL;
+       return 0;
+}
+
 /* policy for the attributes */
 static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR];
 
@@ -949,6 +960,8 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
        [NL80211_ATTR_UHR_CAPABILITY] =
                NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_uhr_capa, 255),
        [NL80211_ATTR_DISABLE_UHR] = { .type = NLA_FLAG },
+       [NL80211_ATTR_UHR_OPERATION] =
+               NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_uhr_operation),
 };
 
 /* policy for the key attributes */
@@ -6501,16 +6514,6 @@ static int nl80211_calculate_ap_params(struct cfg80211_ap_settings *params)
                        return -EINVAL;
        }
 
-       cap = cfg80211_find_ext_elem(WLAN_EID_EXT_UHR_OPER, ies, ies_len);
-       if (cap) {
-               if (!cap->datalen)
-                       return -EINVAL;
-               params->uhr_oper = (void *)(cap->data + 1);
-               if (!ieee80211_uhr_oper_size_ok((const u8 *)params->uhr_oper,
-                                               cap->datalen - 1, true))
-                       return -EINVAL;
-       }
-
        return 0;
 }
 
@@ -6952,6 +6955,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
        if (err)
                goto out;
 
+       if (info->attrs[NL80211_ATTR_UHR_OPERATION])
+               params->uhr_oper = nla_data(info->attrs[NL80211_ATTR_UHR_OPERATION]);
+
        err = nl80211_validate_ap_phy_operation(params);
        if (err)
                goto out;