From 743c052c1979560d3ddca312ef084715120e17c8 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 30 Sep 2026 12:02:56 +0300 Subject: [PATCH] wifi: cfg80211: add protected TWT assoc flag Protected TWT support is indicated in RSNX, but RSNX may be used from security profile now, and not be present in the association response frame, so the logic in mac80211 to determine it doesn't/won't really work. Add a flag for wpa_supplicant to indicate if protected TWT is supported in the association, it can easily check this based on the RSNX data that was used. Signed-off-by: Johannes Berg Reviewed-by: Ilan Peer Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260930120021.1eb6760356f2.Ie4962eaca97be29c7f08043d615534c7aeb3f370@changeid Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 2 ++ include/uapi/linux/nl80211.h | 5 +++++ net/wireless/nl80211.c | 8 ++++++++ 3 files changed, 15 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 2e3dfee85019..3154f12fbd89 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -3407,6 +3407,7 @@ struct cfg80211_ml_reconf_req { * @ASSOC_REQ_SPP_AMSDU: SPP A-MSDUs will be used on this connection (if any) * @ASSOC_REQ_DISABLE_UHR: Disable UHR * @ASSOC_REQ_CIP: Enable Control Integrity Protocol + * @ASSOC_REQ_PROTECTED_TWT: Enable protected TWT */ enum cfg80211_assoc_req_flags { ASSOC_REQ_DISABLE_HT = BIT(0), @@ -3419,6 +3420,7 @@ enum cfg80211_assoc_req_flags { ASSOC_REQ_SPP_AMSDU = BIT(7), ASSOC_REQ_DISABLE_UHR = BIT(8), ASSOC_REQ_CIP = BIT(9), + ASSOC_REQ_PROTECTED_TWT = BIT(10), }; /** diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 75d4c5d6a7a3..7dae0860a1b8 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -3228,6 +3228,9 @@ enum nl80211_commands { * @NL80211_ATTR_CIP_CAPABILITIES: The Control Integrity Protocol for the * station. * + * @NL80211_ATTR_ASSOC_PROTECTED_TWT: Enable protected TWT for the association, + * requires protected TWT support (flag attribute) + * * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use @@ -3833,6 +3836,8 @@ enum nl80211_attrs { NL80211_ATTR_ASSOC_CIP, NL80211_ATTR_CIP_CAPABILITIES, + NL80211_ATTR_ASSOC_PROTECTED_TWT, + /* 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 572da1d8f3d9..cbd51de57b6e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1100,6 +1100,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { [NL80211_ATTR_FRAME_NO_STA] = { .type = NLA_FLAG }, [NL80211_ATTR_ASSOC_CIP] = { .type = NLA_FLAG }, [NL80211_ATTR_CIP_CAPABILITIES] = { .type = NLA_U8 }, + [NL80211_ATTR_ASSOC_PROTECTED_TWT] = { .type = NLA_FLAG }, }; /* policy for the key attributes */ @@ -13422,6 +13423,13 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) req.flags |= ASSOC_REQ_CIP; } + if (nla_get_flag(info->attrs[NL80211_ATTR_ASSOC_PROTECTED_TWT])) { + if (!wiphy_ext_feature_isset(&rdev->wiphy, + NL80211_EXT_FEATURE_PROTECTED_TWT)) + return -EINVAL; + req.flags |= ASSOC_REQ_PROTECTED_TWT; + } + req.link_id = nl80211_link_id_or_invalid(info->attrs); if (info->attrs[NL80211_ATTR_MLO_LINKS]) {