From: Johannes Berg Date: Tue, 3 Mar 2026 21:17:09 +0000 (+0100) Subject: wifi: nl80211: split out UHR operation information X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e4b993f2bca78357b430170574f8de7bc7874088;p=thirdparty%2Flinux.git wifi: nl80211: split out UHR operation information 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 --- diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 0b7a06c2b9f78..67d7640239883 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -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, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 699687a0caa9f..3e867930e253c 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -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;