From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7B48019D8BC; Sat, 12 Sep 2026 10:37:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789209434; cv=none; b=PApK5CVceuaLPiOeKZna1J7nbsgWt5gKsF3zAD5YIT8zOg/+0vOX/9luNJaksixvqrDi6/MuQIQGpFYfAfwqUg5jiyAFvoUir8yv/xBTGWrV2XkblM2lRJr2AzODlP1v64cY76EgJ4W2mCmieZ9BHnnB7rjY3tm21wZL0JPDefI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789209434; c=relaxed/simple; bh=0ivNucUTJN3WxtO37G3kfXqzcBEybRyB/ADG6UCYtvg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NRMzVDF1Z7g3jx0tdXnXqkWAosJzA0CkbRF8ozMxNBq2b2U/bviX9hOEJ6t4eGCgt7jnn7Y4VpSCyuEnultUz/9ipP6xvFwneAvy8ZjSRzDhIV2WjOO/7vZ4kD7ggbpEUEJq1H7g8QVvpXRD32yfSErt46WPlNCoptF/w0PHz5Y= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=NawR5eWW; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="NawR5eWW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1898F1F000FF; Sat, 12 Sep 2026 10:37:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1789209433; bh=eZrmIfXYhdHt8pBELOoZgeSPWreSkdKgmIDxvqTgYgc=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=NawR5eWWNkeruHQcu0CFN1ZBDgFf+QcnIopeCFvr2RH28XTgGw1NPezIXsNh5AxYz VovYP+Q25ZXHij7M0jQvZqo9GHzJ6cqk9gNLDiopRs7cGlQbiOnDjRdq/aJI6lWPkA lh/Ep+/u3ODb3oJl0aWLUhc1fWHSpDsIfx/YBh5c= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Johannes Berg , Sasha Levin Subject: [PATCH 6.18 0819/1518] wifi: ieee80211: add some initial UHR definitions Date: Sat, 12 Sep 2026 08:49:48 +0200 Message-ID: <20260912065641.964126346@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260912065623.398859879@linuxfoundation.org> References: <20260912065623.398859879@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Johannes Berg [ Upstream commit a7cb50156e8206562b001b3bb625045a0ee0f651 ] This is based on Draft P802.11bn_D1.2, but that's still very incomplete, so don't handle a number of things and make some local decisions such as using 40 bits for MAC capabilities and 8 bits for PHY capabilities. Link: https://patch.msgid.link/20260130164259.b28c9456ff94.I5b11fb0345a933bf497fd802aecc72932d58dd68@changeid Signed-off-by: Johannes Berg Stable-dep-of: 6c5fc504d0d6 ("wifi: cfg80211: stop PMSR before P2P and NAN teardown") Signed-off-by: Sasha Levin --- include/linux/ieee80211-uhr.h | 220 ++++++++++++++++++++++++++++++++++ include/linux/ieee80211.h | 33 ++++- 2 files changed, 251 insertions(+), 2 deletions(-) create mode 100644 include/linux/ieee80211-uhr.h diff --git a/include/linux/ieee80211-uhr.h b/include/linux/ieee80211-uhr.h new file mode 100644 index 0000000000000..132acced7d798 --- /dev/null +++ b/include/linux/ieee80211-uhr.h @@ -0,0 +1,220 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * IEEE 802.11 UHR definitions + * + * Copyright (c) 2025-2026 Intel Corporation + */ +#ifndef LINUX_IEEE80211_UHR_H +#define LINUX_IEEE80211_UHR_H + +#include +#include + +#define IEEE80211_UHR_OPER_PARAMS_DPS_ENA 0x0001 +#define IEEE80211_UHR_OPER_PARAMS_NPCA_ENA 0x0002 +#define IEEE80211_UHR_OPER_PARAMS_DBE_ENA 0x0004 +#define IEEE80211_UHR_OPER_PARAMS_PEDCA_ENA 0x0008 + +struct ieee80211_uhr_operation { + __le16 params; + u8 basic_mcs_nss_set[4]; + u8 variable[]; +} __packed; + +#define IEEE80211_UHR_NPCA_PARAMS_PRIMARY_CHAN_OFFS 0x0000000F +#define IEEE80211_UHR_NPCA_PARAMS_MIN_DUR_THRESH 0x000000F0 +#define IEEE80211_UHR_NPCA_PARAMS_SWITCH_DELAY 0x00003F00 +#define IEEE80211_UHR_NPCA_PARAMS_SWITCH_BACK_DELAY 0x000FC000 +#define IEEE80211_UHR_NPCA_PARAMS_INIT_QSRC 0x00300000 +#define IEEE80211_UHR_NPCA_PARAMS_MOPLEN 0x00400000 +#define IEEE80211_UHR_NPCA_PARAMS_DIS_SUBCH_BMAP_PRES 0x00800000 + +struct ieee80211_uhr_npca_info { + __le32 params; + __le16 dis_subch_bmap[]; +} __packed; + +static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len, + bool beacon) +{ + const struct ieee80211_uhr_operation *oper = (const void *)data; + u8 needed = sizeof(*oper); + + if (len < needed) + return false; + + /* nothing else present in beacons */ + if (beacon) + return true; + + /* FIXME: DPS, DBE, P-EDCA (consider order, also relative to NPCA) */ + + if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_ENA)) { + const struct ieee80211_uhr_npca_info *npca = + (const void *)oper->variable; + + needed += sizeof(*npca); + + if (len < needed) + return false; + + if (npca->params & cpu_to_le32(IEEE80211_UHR_NPCA_PARAMS_DIS_SUBCH_BMAP_PRES)) + needed += sizeof(npca->dis_subch_bmap[0]); + } + + return len >= needed; +} + +/* + * Note: cannot call this on the element coming from a beacon, + * must ensure ieee80211_uhr_oper_size_ok(..., false) first + */ +static inline const struct ieee80211_uhr_npca_info * +ieee80211_uhr_npca_info(const struct ieee80211_uhr_operation *oper) +{ + if (!(oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_ENA))) + return NULL; + + /* FIXME: DPS */ + + return (const void *)oper->variable; +} + +static inline const __le16 * +ieee80211_uhr_npca_dis_subch_bitmap(const struct ieee80211_uhr_operation *oper) +{ + const struct ieee80211_uhr_npca_info *npca; + + npca = ieee80211_uhr_npca_info(oper); + if (!npca) + return NULL; + if (!(npca->params & cpu_to_le32(IEEE80211_UHR_NPCA_PARAMS_DIS_SUBCH_BMAP_PRES))) + return NULL; + return npca->dis_subch_bmap; +} + +#define IEEE80211_UHR_MAC_CAP0_DPS_SUPP 0x01 +#define IEEE80211_UHR_MAC_CAP0_DPS_ASSIST_SUPP 0x02 +#define IEEE80211_UHR_MAC_CAP0_DPS_AP_STATIC_HCM_SUPP 0x04 +#define IEEE80211_UHR_MAC_CAP0_NPCA_SUPP 0x10 +#define IEEE80211_UHR_MAC_CAP0_ENH_BSR_SUPP 0x20 +#define IEEE80211_UHR_MAC_CAP0_ADD_MAP_TID_SUPP 0x40 +#define IEEE80211_UHR_MAC_CAP0_EOTSP_SUPP 0x80 + +#define IEEE80211_UHR_MAC_CAP1_DSO_SUPP 0x01 +#define IEEE80211_UHR_MAC_CAP1_PEDCA_SUPP 0x02 +#define IEEE80211_UHR_MAC_CAP1_DBE_SUPP 0x04 +#define IEEE80211_UHR_MAC_CAP1_UL_LLI_SUPP 0x08 +#define IEEE80211_UHR_MAC_CAP1_P2P_LLI_SUPP 0x10 +#define IEEE80211_UHR_MAC_CAP1_PUO_SUPP 0x20 +#define IEEE80211_UHR_MAC_CAP1_AP_PUO_SUPP 0x40 +#define IEEE80211_UHR_MAC_CAP1_DUO_SUPP 0x80 + +#define IEEE80211_UHR_MAC_CAP2_OMC_UL_MU_DIS_RX_SUPP 0x01 +#define IEEE80211_UHR_MAC_CAP2_AOM_SUPP 0x02 +#define IEEE80211_UHR_MAC_CAP2_IFCS_LOC_SUPP 0x04 +#define IEEE80211_UHR_MAC_CAP2_UHR_TRS_SUPP 0x08 +#define IEEE80211_UHR_MAC_CAP2_TXSPG_SUPP 0x10 +#define IEEE80211_UHR_MAC_CAP2_TXOP_RET_IN_TXSPG 0x20 +#define IEEE80211_UHR_MAC_CAP2_UHR_OM_PU_TO_LOW 0xC0 + +#define IEEE80211_UHR_MAC_CAP3_UHR_OM_PU_TO_HIGH 0x03 +#define IEEE80211_UHR_MAC_CAP3_PARAM_UPD_ADV_NOTIF_INTV 0x1C +#define IEEE80211_UHR_MAC_CAP3_UPD_IND_TIM_INTV_LOW 0xE0 + +#define IEEE80211_UHR_MAC_CAP4_UPD_IND_TIM_INTV_HIGH 0x03 +#define IEEE80211_UHR_MAC_CAP4_BOUNDED_ESS 0x04 +#define IEEE80211_UHR_MAC_CAP4_BTM_ASSURANCE 0x08 +#define IEEE80211_UHR_MAC_CAP4_CO_BF_SUPP 0x10 + +#define IEEE80211_UHR_MAC_CAP_DBE_MAX_BW 0x07 +#define IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_160_PRES 0x08 +#define IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_320_PRES 0x10 + +struct ieee80211_uhr_cap_mac { + u8 mac_cap[5]; +} __packed; + +struct ieee80211_uhr_cap { + struct ieee80211_uhr_cap_mac mac; + /* DBE, PHY capabilities */ + u8 variable[]; +} __packed; + +#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_LE80 0x01 +#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_LE80 0x02 +#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_160 0x04 +#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_160 0x08 +#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_320 0x10 +#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_320 0x20 +#define IEEE80211_UHR_PHY_CAP_ELR_RX 0x40 +#define IEEE80211_UHR_PHY_CAP_ELR_TX 0x80 + +struct ieee80211_uhr_cap_phy { + u8 cap; +} __packed; + +static inline bool ieee80211_uhr_capa_size_ok(const u8 *data, u8 len, + bool from_ap) +{ + const struct ieee80211_uhr_cap *cap = (const void *)data; + size_t needed = sizeof(*cap) + sizeof(struct ieee80211_uhr_cap_phy); + + if (len < needed) + return false; + + /* + * A non-AP STA does not include the DBE Capability Parameters field + * in the UHR MAC Capabilities Information field. + */ + if (from_ap && cap->mac.mac_cap[1] & IEEE80211_UHR_MAC_CAP1_DBE_SUPP) { + u8 dbe; + + needed += 1; + if (len < needed) + return false; + + dbe = cap->variable[0]; + + if (dbe & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_160_PRES) + needed += 3; + + if (dbe & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_320_PRES) + needed += 3; + } + + return len >= needed; +} + +static inline const struct ieee80211_uhr_cap_phy * +ieee80211_uhr_phy_cap(const struct ieee80211_uhr_cap *cap, bool from_ap) +{ + u8 offs = 0; + + if (from_ap && cap->mac.mac_cap[1] & IEEE80211_UHR_MAC_CAP1_DBE_SUPP) { + u8 dbe = cap->variable[0]; + + offs += 1; + + if (dbe & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_160_PRES) + offs += 3; + + if (dbe & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_320_PRES) + offs += 3; + } + + return (const void *)&cap->variable[offs]; +} + +#define IEEE80211_SMD_INFO_CAPA_DL_DATA_FWD 0x01 +#define IEEE80211_SMD_INFO_CAPA_MAX_NUM_PREP 0x0E +#define IEEE80211_SMD_INFO_CAPA_TYPE 0x10 +#define IEEE80211_SMD_INFO_CAPA_PTK_PER_AP_MLD 0x20 + +struct ieee80211_smd_info { + u8 id[ETH_ALEN]; + u8 capa; + __le16 timeout; +} __packed; + +#endif /* LINUX_IEEE80211_UHR_H */ diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 992a0c09c1e53..2526ccd8a4a06 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -9,7 +9,7 @@ * Copyright (c) 2006, Michael Wu * Copyright (c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright (c) 2016 - 2017 Intel Deutschland GmbH - * Copyright (c) 2018 - 2025 Intel Corporation + * Copyright (c) 2018 - 2026 Intel Corporation */ #ifndef LINUX_IEEE80211_H @@ -1381,8 +1381,9 @@ struct ieee80211_mgmt { #define BSS_MEMBERSHIP_SELECTOR_SAE_H2E 123 #define BSS_MEMBERSHIP_SELECTOR_HE_PHY 122 #define BSS_MEMBERSHIP_SELECTOR_EHT_PHY 121 +#define BSS_MEMBERSHIP_SELECTOR_UHR_PHY 120 -#define BSS_MEMBERSHIP_SELECTOR_MIN BSS_MEMBERSHIP_SELECTOR_EHT_PHY +#define BSS_MEMBERSHIP_SELECTOR_MIN BSS_MEMBERSHIP_SELECTOR_UHR_PHY /* mgmt header + 1 byte category code */ #define IEEE80211_MIN_ACTION_SIZE offsetof(struct ieee80211_mgmt, u.action.u) @@ -2117,6 +2118,15 @@ enum ieee80211_eid_ext { WLAN_EID_EXT_BANDWIDTH_INDICATION = 135, WLAN_EID_EXT_KNOWN_STA_IDENTIFCATION = 136, WLAN_EID_EXT_NON_AP_STA_REG_CON = 137, + WLAN_EID_EXT_UHR_OPER = 151, + WLAN_EID_EXT_UHR_CAPA = 152, + WLAN_EID_EXT_MACP = 153, + WLAN_EID_EXT_SMD = 154, + WLAN_EID_EXT_BSS_SMD_TRANS_PARAMS = 155, + WLAN_EID_EXT_CHAN_USAGE = 156, + WLAN_EID_EXT_UHR_MODE_CHG = 157, + WLAN_EID_EXT_UHR_PARAM_UPD = 158, + WLAN_EID_EXT_TXPI = 159, }; /* Action category code */ @@ -3352,6 +3362,22 @@ static inline bool for_each_element_completed(const struct element *element, #define WLAN_RSNX_CAPA_PROTECTED_TWT BIT(4) #define WLAN_RSNX_CAPA_SAE_H2E BIT(5) +/* EBPCC = Enhanced BSS Parameter Change Count */ +#define IEEE80211_ENH_CRIT_UPD_EBPCC 0x0F +#define IEEE80211_ENH_CRIT_UPD_TYPE 0x70 +#define IEEE80211_ENH_CRIT_UPD_TYPE_NO_UHR 0 +#define IEEE80211_ENH_CRIT_UPD_TYPE_UHR 1 +#define IEEE80211_ENH_CRIT_UPD_ALL 0x80 + +/** + * struct ieee80211_enh_crit_upd - enhanced critical update (UHR) + * @v: value of the enhanced critical update data, + * see %IEEE80211_ENH_CRIT_UPD_* to parse the bits + */ +struct ieee80211_enh_crit_upd { + u8 v; +} __packed; + /* * reduced neighbor report, based on Draft P802.11ax_D6.1, * section 9.4.2.170 and accepted contributions. @@ -3370,6 +3396,7 @@ static inline bool for_each_element_completed(const struct element *element, #define IEEE80211_RNR_TBTT_PARAMS_COLOC_ESS 0x10 #define IEEE80211_RNR_TBTT_PARAMS_PROBE_ACTIVE 0x20 #define IEEE80211_RNR_TBTT_PARAMS_COLOC_AP 0x40 +#define IEEE80211_RNR_TBTT_PARAMS_SAME_SMD 0x80 #define IEEE80211_RNR_TBTT_PARAMS_PSD_NO_LIMIT 127 #define IEEE80211_RNR_TBTT_PARAMS_PSD_RESERVED -128 @@ -3422,6 +3449,7 @@ struct ieee80211_tbtt_info_ge_11 { u8 bss_params; s8 psd_20; struct ieee80211_rnr_mld_params mld_params; + struct ieee80211_enh_crit_upd enh_crit_upd; } __packed; /* NAN operation mode, as defined in Wi-Fi Aware (TM) specification Table 81 */ @@ -3445,6 +3473,7 @@ struct ieee80211_tbtt_info_ge_11 { #include "ieee80211-vht.h" #include "ieee80211-he.h" #include "ieee80211-eht.h" +#include "ieee80211-uhr.h" #include "ieee80211-mesh.h" #endif /* LINUX_IEEE80211_H */ -- 2.53.0