Something went wrong. Try again.
(I'm so sorry!) Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665/* 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 <linux/types.h>#include <linux/bitfield.h>#include <linux/if_ether.h>#include "ieee80211-eht.h"
#define IEEE80211_UHR_OPER_PARAMS_DPS_ENA 0x0001#define IEEE80211_UHR_OPER_PARAMS_NPCA_ENA 0x0002#define IEEE80211_UHR_OPER_PARAMS_PEDCA_ENA 0x0004#define IEEE80211_UHR_OPER_PARAMS_DBE_ENA 0x0008#define IEEE80211_UHR_OPER_PARAMS_DBE_BW 0x0070#define IEEE80211_UHR_OPER_PARAMS_ELR_RX 0x0080#define IEEE80211_UHR_OPER_PARAMS_DUO_PRES 0x0100#define IEEE80211_UHR_OPER_PARAMS_DPS_PRES 0x0200#define IEEE80211_UHR_OPER_PARAMS_NPCA_PRES 0x0400#define IEEE80211_UHR_OPER_PARAMS_PEDCA_PRES 0x0800#define IEEE80211_UHR_OPER_PARAMS_DBE_PRES 0x1000
struct ieee80211_uhr_operation { __le16 params; u8 variable[];} __packed;
#define IEEE80211_UHR_NPCA_PARAMS_PRIMARY_CHAN 0x000000FF#define IEEE80211_UHR_NPCA_PARAMS_MIN_DUR_THRESH 0x00000F00#define IEEE80211_UHR_NPCA_PARAMS_SWITCH_DELAY 0x0003F000#define IEEE80211_UHR_NPCA_PARAMS_SWITCH_BACK_DELAY 0x00FC0000#define IEEE80211_UHR_NPCA_PARAMS_INIT_QSRC 0x03000000#define IEEE80211_UHR_NPCA_PARAMS_MOPLEN 0x04000000#define IEEE80211_UHR_NPCA_PARAMS_DIS_SUBCH_BMAP_PRES 0x08000000
/** * struct ieee80211_uhr_npca_info - npca operation information * * This structure is the "NPCA Operation Parameters field format" of "UHR * Operation Element" fields as described in P802.11bn_D1.5 * subclause 9.4.2.355.2, see Figure 9-aa6. * * Refer to IEEE80211_UHR_NPCA* * @params: * NPCA Primary Channel - NPCA primary channel * NPCA_Min Duration Threshold - Minimum duration of inter-BSS activity * NPCA Switching Delay - * Time needed by an NPCA AP to switch from the * BSS primary channel to the NPCA primary channel * in the unit of 4 µs. * NPCA Switching Back Delay - * Time to switch from the NPCA primary channel * to the BSS primary channel in the unit of 4 µs. * NPCA Initial QSRC - * Initialize the EDCAF QSRC[AC] variables * when an NPCA STA in the BSS * switches to NPCA operation. * NPCA MOPLEN - * Indicates which conditions can be used to * initiate an NPCA operation, * 1 -> both PHYLEN NPCA operation and MOPLEN * NPCA operation are * permitted in the BSS * 0 -> only PHYLEN NPCA operation is allowed in the BSS. * NPCA Disabled Subchannel Bitmap Present - * Indicates whether the NPCA Disabled Subchannel * Bitmap field is present. A 1 in this field indicates that * the NPCA Disabled Subchannel Bitmap field is present * @dis_subch_bmap: * A bit in the bitmap that lies within the BSS bandwidth is set * to 1 to indicate that the corresponding 20 MHz subchannel is * punctured and is set to 0 to indicate that the corresponding * 20 MHz subchannel is not punctured. A bit in the bitmap that * falls outside of the BSS bandwidth is reserved. This field is * present when the value of the NPCA Disabled Subchannel Bitmap * Field Present field is equal to 1, and not present, otherwise */struct ieee80211_uhr_npca_info { __le32 params; __le16 dis_subch_bmap[];} __packed;
#define IEEE80211_UHR_DPS_PADDING_DELAY 0x0000003F#define IEEE80211_UHR_DPS_TRANSITION_DELAY 0x00003F00#define IEEE80211_UHR_DPS_ICF_REQUIRED 0x00010000#define IEEE80211_UHR_DPS_PARAMETERIZED_FLAG 0x00020000#define IEEE80211_UHR_DPS_LC_MODE_BW 0x001C0000#define IEEE80211_UHR_DPS_LC_MODE_NSS 0x01E00000#define IEEE80211_UHR_DPS_LC_MODE_MCS 0x1E000000#define IEEE80211_UHR_DPS_MOBILE_AP_DPS_STATIC_HCM 0x20000000
/** * struct ieee80211_uhr_dps_info - DPS operation information * * This structure is the "DPS Operation Parameter field" of "UHR * Operation Element" fields as described in P802.11bn_D1.5 * subclause 9.4.1.87. See Figure 9-207u. * * Refer to IEEE80211_UHR_DPS* * @params: * DPS Padding Delay - * Indicates the minimum MAC padding * duration that is required by a DPS STA * in an ICF to cause the STA to transition * from the lower capability mode to the * higher capability mode. The DPS Padding * Delay field is in units of 4 µs. * DPS Transition Delay - * Indicates the amount of time required by a * DPS STA to transition from the higher * capability mode to the lower capability * mode. The DPS Transition Delay field is in * units of 4 µs. * ICF Required - * Indicates when the DPS assisting STA needs * to transmit an ICF frame to the peer DPS STA * before performing the frame exchanges with * the peer DPS STA in a TXOP. * 1 -> indicates that the transmission of the * ICF frame to the peer DPS STA prior to * any frame exchange is needed. * 0 -> ICF transmission before the frame * exchanges with the peer DPS STA is only * needed if the frame exchange is performed * in the HC mode. * Parameterized Flag - * 0 -> indicates that only 20 MHz, 1 SS, * non-HT PPDU format with the data * rate of 6, 12, and 24 Mb/s as the * default mode are supported by the * DPS STA in the LC mode * 1 -> indicates that a bandwidth up to the * bandwidth indicated in the LC Mode * Bandwidth field, a number of spatial * streams up to the NSS indicated in * the LC Mode Nss field, and an MCS up * to the MCS indicated in the LC Mode * MCS fields are supported by the DPS * STA in the LC mode as the * parameterized mode. * LC Mode Bandwidth - * Indicates the maximum bandwidth supported * by the STA in the LC mode. * LC Mode NSS - * Indicates the maximum number of the spatial * streams supported by the STA in the LC mode. * LC Mode MCS - * Indicates the highest MCS supported by the STA * in the LC mode. * Mobile AP DPS Static HCM - * 1 -> indicates that it will remain in the DPS high * capability mode until the next TBTT on that * link. * 0 -> otherwise. */struct ieee80211_uhr_dps_info { __le32 params;} __packed;
#define IEEE80211_UHR_DBE_OPER_BANDWIDTH 0x07#define IEEE80211_UHR_DBE_OPER_DIS_SUBCHANNEL_BITMAP_PRES 0x08
/** * enum ieee80211_uhr_dbe_oper_bw - DBE Operational Bandwidth * * Encoding for the DBE Operational Bandwidth field in the UHR Operation * element (DBE Operation Parameters). * * @IEEE80211_UHR_DBE_OPER_BW_40: 40 MHz operational DBE bandwidth * @IEEE80211_UHR_DBE_OPER_BW_80: 80 MHz operational DBE bandwidth * @IEEE80211_UHR_DBE_OPER_BW_160: 160 MHz operational DBE bandwidth * @IEEE80211_UHR_DBE_OPER_BW_320_1: 320-1 MHz operational DBE bandwidth * @IEEE80211_UHR_DBE_OPER_BW_320_2: 320-2 MHz operational DBE bandwidth */enum ieee80211_uhr_dbe_oper_bw { IEEE80211_UHR_DBE_OPER_BW_40 = 1, IEEE80211_UHR_DBE_OPER_BW_80 = 2, IEEE80211_UHR_DBE_OPER_BW_160 = 3, IEEE80211_UHR_DBE_OPER_BW_320_1 = 4, IEEE80211_UHR_DBE_OPER_BW_320_2 = 5,};
/** * ieee80211_uhr_dbe_bw_mhz - get bandwidth in MHz from UHR DBE bandwidth * @bw: UHR DBE bandwidth * * Return: the bandwidth in MHz, or -1 for invalid values */static inline int ieee80211_uhr_dbe_bw_mhz(enum ieee80211_uhr_dbe_oper_bw bw){ switch (bw) { case IEEE80211_UHR_DBE_OPER_BW_40: return 40; case IEEE80211_UHR_DBE_OPER_BW_80: return 80; case IEEE80211_UHR_DBE_OPER_BW_160: return 160; case IEEE80211_UHR_DBE_OPER_BW_320_1: case IEEE80211_UHR_DBE_OPER_BW_320_2: return 320; default: return -1; }}
/** * struct ieee80211_uhr_dbe_info - DBE operation information * * This structure is the "DBE Operation Parameters field" of * "UHR Operation Element" fields as described in P802.11bn_D1.5 * subclause 9.4.2.355.4, see Figure 9-aa9. * * Refer to IEEE80211_UHR_DBE_OPER* * @params: * B0-B2 - DBE Operational Bandwidth field, see * "enum ieee80211_uhr_dbe_oper_bw" for values. * Value 0 is reserved. * Value 1 indicates 40 MHz operational DBE bandwidth. * Value 2 indicates 80 MHz operational DBE bandwidth. * Value 3 indicates 160 MHz operational DBE bandwidth. * Value 4 indicates 320-1 MHz operational DBE bandwidth. * Value 5 indicates 320-2 MHz operational DBE bandwidth. * Values 6 to 7 are reserved. * B3 - DBE Disabled Subchannel Bitmap Present. * @dis_subch_bmap: DBE Disabled Subchannel Bitmap field is set to indicate * disabled 20 MHz subchannels within the DBE Bandwidth. */struct ieee80211_uhr_dbe_info { u8 params; __le16 dis_subch_bmap[];} __packed;
#define IEEE80211_UHR_P_EDCA_ECWMIN 0x0007#define IEEE80211_UHR_P_EDCA_ECWMAX 0x0038#define IEEE80211_UHR_P_EDCA_AIFSN 0x01C0#define IEEE80211_UHR_P_EDCA_CW_DS 0x0600#define IEEE80211_UHR_P_EDCA_PSRC_THRESHOLD 0x3800#define IEEE80211_UHR_P_EDCA_QSRC_THRESHOLD 0xC000
/** * struct ieee80211_uhr_p_edca_info - P-EDCA operation information * * This structure is the "P-EDCA Operation Parameters field" of * "UHR Operation Element" fields as described in P802.11bn_D1.5 * subclause 9.4.2.355.3, see Figure 9-aa8. * * Refer to IEEE80211_UHR_P_EDCA* * @params: ECWmin, ECWmax, AIFSN, CW DS, PSRC threshold, and QSRC threshold. * - CWmin/CWmax values used by a P-EDCA STA during P-EDCA contention. * - The AIFSN field indicates the AIFSN value used by a P-EDCA STA * during P-EDCA contention. * - The CW DS field indicates the value used for randomization of the * transmission slot of the DS-CTS frame. The value 3 is reserved. * The value 0 indicates that randomization is not enabled. * - The P-EDCA PSRC threshold field indicates the maximum number of * allowed consecutive DS-CTS transmissions. The value 0 and values * greater than 4 are reserved. * - The P-EDCA QSRC threshold field indicates the value of the * QSRC[AC_VO] counter required to start P-EDCA contention. The * value 0 is reserved. */struct ieee80211_uhr_p_edca_info { __le16 params;} __packed;
static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len){ const struct ieee80211_uhr_operation *oper = (const void *)data; u8 needed = sizeof(*oper);
if (len < needed) return false;
/* DPS Operation Parameters (fixed 4 bytes) */ if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_PRES)) { needed += sizeof(struct ieee80211_uhr_dps_info); if (len < needed) return false; }
/* NPCA Operation Parameters (fixed 4 bytes + optional 2 bytes) */ if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_PRES)) { const struct ieee80211_uhr_npca_info *npca = (const void *)(data + needed);
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]); if (len < needed) return false; } }
/* P-EDCA Operation Parameters */ if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_PEDCA_PRES)) { needed += sizeof(struct ieee80211_uhr_p_edca_info); if (len < needed) return false; }
/* DBE Operation Parameters (fixed 1 byte + optional 2 bytes) */ if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DBE_PRES)) { const struct ieee80211_uhr_dbe_info *dbe = (const void *)(data + needed);
needed += sizeof(*dbe); if (len < needed) return false;
if (dbe->params & IEEE80211_UHR_DBE_OPER_DIS_SUBCHANNEL_BITMAP_PRES) { needed += sizeof(dbe->dis_subch_bmap[0]); if (len < needed) return false; } }
return len >= needed;}
/* Note: must ensure ieee80211_uhr_oper_size_ok(...) first */static inline const struct ieee80211_uhr_npca_info *ieee80211_uhr_npca_info(const struct ieee80211_uhr_operation *oper){ const u8 *pos = oper->variable;
if (!(oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_PRES))) return NULL;
if (!(oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_ENA))) return NULL;
if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DUO_PRES)) pos += 1;
if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_PRES)) pos += sizeof(struct ieee80211_uhr_dps_info);
return (const void *)pos;}
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;}
/* Note: must ensure ieee80211_uhr_oper_size_ok(...) first */static inline const struct ieee80211_uhr_dbe_info *ieee80211_uhr_oper_dbe_info(const struct ieee80211_uhr_operation *oper){ const u8 *pos = oper->variable;
if (!(oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DBE_PRES))) return NULL;
if (!(oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DBE_ENA))) return NULL;
if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DUO_PRES)) pos += 1;
if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_PRES)) pos += sizeof(struct ieee80211_uhr_dps_info);
if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_PRES)) { const struct ieee80211_uhr_npca_info *npca = (const void *)pos;
pos += sizeof(*npca); if (npca->params & cpu_to_le32(IEEE80211_UHR_NPCA_PARAMS_DIS_SUBCH_BMAP_PRES)) pos += sizeof(npca->dis_subch_bmap[0]); }
if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_PEDCA_PRES)) pos += sizeof(struct ieee80211_uhr_p_edca_info);
return (const void *)pos;}
#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 0x7C#define IEEE80211_UHR_MAC_CAP3_UPD_IND_TIM_INTV_LOW 0x80
#define IEEE80211_UHR_MAC_CAP4_UPD_IND_TIM_INTV_HIGH 0x0F#define IEEE80211_UHR_MAC_CAP4_BOUNDED_ESS 0x10#define IEEE80211_UHR_MAC_CAP4_BTM_ASSURANCE 0x20#define IEEE80211_UHR_MAC_CAP4_CO_BF_SUPP 0x40#define IEEE80211_UHR_MAC_CAP4_CO_SR_SUPP 0x80
#define IEEE80211_UHR_MAC_CAP5_MAPC_ENH_MSRMT_SUPP 0x01
#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_dbe::bwcap[].cap */#define IEEE80211_UHR_MAC_CAP_DBE_CAP_NUM_SND_DIMS 0x07#define IEEE80211_UHR_MAC_CAP_DBE_CAP_NON_OFDMA_UL_MUMIMO 0x08#define IEEE80211_UHR_MAC_CAP_DBE_CAP_MU_BEAMFORMER 0x10#define IEEE80211_UHR_MAC_CAP_DBE_CAP_BEAMFORMEE_SS 0xe0
struct ieee80211_uhr_cap_dbe { u8 cap; u8 max_switch_time_period; u8 mode_change_intvl; /* present 0, 1 or 2 times depending on _PRES bits */ struct { struct ieee80211_eht_mcs_nss_supp_bw eht_mcs_map; u8 cap; } __packed bwcap[];} __packed;
/** * enum ieee80211_uhr_dbe_max_supported_bw - DBE Maximum Supported Bandwidth * * As per spec P802.11bn_D1.5 Table 9-bb8 "Encoding of the DBE Maximum * Supported Bandwidth field". * * @IEEE80211_UHR_DBE_MAX_BW_40: Indicates 40 MHz DBE max supported bw * @IEEE80211_UHR_DBE_MAX_BW_80: Indicates 80 MHz DBE max supported bw * @IEEE80211_UHR_DBE_MAX_BW_160: Indicates 160 MHz DBE max supported bw * @IEEE80211_UHR_DBE_MAX_BW_320: Indicates 320 MHz DBE max supported bw */enum ieee80211_uhr_dbe_max_supported_bw { IEEE80211_UHR_DBE_MAX_BW_40 = 1, IEEE80211_UHR_DBE_MAX_BW_80 = 2, IEEE80211_UHR_DBE_MAX_BW_160 = 3, IEEE80211_UHR_DBE_MAX_BW_320 = 4,};
struct ieee80211_uhr_cap_mac { u8 mac_cap[6];} __packed;
#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_LE80 0x00000001#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_LE80 0x00000002#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_160 0x00000004#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_160 0x00000008#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_320 0x00000010#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_320 0x00000020#define IEEE80211_UHR_PHY_CAP_ELR_TX 0x00000040#define IEEE80211_UHR_PHY_CAP_ELR_RX 0x00000080#define IEEE80211_UHR_PHY_CAP_PART_BW_DL_MUMIMO 0x00000100#define IEEE80211_UHR_PHY_CAP_PART_BW_UL_MUMIMO 0x00000200#define IEEE80211_UHR_PHY_CAP_MCS15 0x00000400#define IEEE80211_UHR_PHY_CAP_2XLDPC_TX 0x00000800#define IEEE80211_UHR_PHY_CAP_2XLDPC_RX 0x00001000#define IEEE80211_UHR_PHY_CAP_UEQM_TX_MAX_NSS 0x00006000#define IEEE80211_UHR_PHY_CAP_UEQM_RX_MAX_NSS 0x00018000#define IEEE80211_UHR_PHY_CAP_CO_BF_JOINT_SOUNDING 0x00040000#define IEEE80211_UHR_PHY_CAP_IM_TX 0x00080000#define IEEE80211_UHR_PHY_CAP_IM_RX 0x00100000#define IEEE80211_UHR_PHY_CAP_CO_SR_MODE_1 0x00200000#define IEEE80211_UHR_PHY_CAP_CO_SR_MODE_2 0x00400000#define IEEE80211_UHR_PHY_CAP_DRU_DBW_20_IN_PBW_20 0x00800000#define IEEE80211_UHR_PHY_CAP_DRU_DBW_40_IN_PBW_40 0x01000000#define IEEE80211_UHR_PHY_CAP_DRU_DBW_80_IN_PBW_80 0x02000000#define IEEE80211_UHR_PHY_CAP_DRU_DBW_80_IN_PBW_160 0x04000000#define IEEE80211_UHR_PHY_CAP_DRU_DBW_80_IN_PBW_320 0x08000000#define IEEE80211_UHR_PHY_CAP_DRU_DBW_20_IN_PBW_GE80 0x10000000#define IEEE80211_UHR_PHY_CAP_DRU_DBW_40_IN_PBW_GE80 0x20000000#define IEEE80211_UHR_PHY_CAP_DRU_DBW_60_IN_PBW_GE80 0x40000000#define IEEE80211_UHR_PHY_CAP_DRU_RRU_HYBRID_MODE 0x80000000
struct ieee80211_uhr_cap_phy { __le32 cap; u8 reserved;} __packed;
struct ieee80211_uhr_cap { struct ieee80211_uhr_cap_mac mac; struct ieee80211_uhr_cap_phy phy; /* optional DBE capabilities */ u8 variable[];} __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);
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) { const struct ieee80211_uhr_cap_dbe *dbe;
needed += sizeof(struct ieee80211_uhr_cap_dbe); if (len < needed) return false;
dbe = (const void *)cap->variable;
if (dbe->cap & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_160_PRES) needed += sizeof(dbe->bwcap[0]);
if (dbe->cap & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_320_PRES) needed += sizeof(dbe->bwcap[0]); }
return len >= needed;}
#define IEEE80211_UHR_OM_PU_TO_128TU 11
/** * ieee80211_uhr_capa_get_om_pu_to_us - get OM parameter update timeout in usec * @cap: the UHR capability element, size must be validated * * Return: the OM parameter update timeout in usec, or -1 if it's not valid */static inline intieee80211_uhr_capa_get_om_pu_to_us(const struct ieee80211_uhr_cap *cap){ u8 timeout;
timeout = u8_get_bits(cap->mac.mac_cap[3], IEEE80211_UHR_MAC_CAP3_UHR_OM_PU_TO_HIGH); timeout <<= 2; timeout |= u8_get_bits(cap->mac.mac_cap[2], IEEE80211_UHR_MAC_CAP2_UHR_OM_PU_TO_LOW);
if (timeout > IEEE80211_UHR_OM_PU_TO_128TU) return -1;
if (!timeout) return 0;
return 128 << (timeout - 1);}
/* only valid from AP, must check ieee80211_uhr_capa_size_ok(..., true) */static inline const struct ieee80211_uhr_cap_dbe *ieee80211_uhr_dbe_cap(const struct ieee80211_uhr_cap *cap){ if (!(cap->mac.mac_cap[1] & IEEE80211_UHR_MAC_CAP1_DBE_SUPP)) return NULL;
return (const void *)cap->variable;}
#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;
enum ieee80211_protected_uhr_action { IEEE80211_PROTECTED_UHR_ACTION_LINK_RECONFIG_REQUEST = 0, IEEE80211_PROTECTED_UHR_ACTION_LINK_RECONFIG_RESPONSE = 1, IEEE80211_PROTECTED_UHR_ACTION_LINK_RECONFIG_NOTIFY = 2,};
enum ieee80211_uhr_link_reconfig_request_type { IEEE80211_UHR_LINK_RECONFIG_REQUEST_ST_PREP = 0, IEEE80211_UHR_LINK_RECONFIG_REQUEST_ST_EXEC = 1, IEEE80211_UHR_LINK_RECONFIG_REQUEST_OMP_REQUEST = 3,};
enum ieee80211_uhr_link_reconfig_response_type { IEEE80211_UHR_LINK_RECONFIG_RESPONSE_ST_PREP = 0, IEEE80211_UHR_LINK_RECONFIG_RESPONSE_ST_EXEC = 1,};
enum ieee80211_uhr_link_reconfig_notify_type { IEEE80211_UHR_LINK_RECONFIG_NOTIFY_DL_DRAINED = 2, IEEE80211_UHR_LINK_RECONFIG_NOTIFY_OMP_RESPONSE = 3,};
enum ieee80211_uhr_mode_change_control { IEEE80211_UHR_MODE_CHANGE_CONTROL_MODE_ID = 0x003f, IEEE80211_UHR_MODE_CHANGE_CONTROL_MODE_ENABLE = 0x0040, IEEE80211_UHR_MODE_CHANGE_CONTROL_MODE_UPDATE = 0x0080, IEEE80211_UHR_MODE_CHANGE_CONTROL_MODE_LENGTH = 0x0f00, IEEE80211_UHR_MODE_CHANGE_CONTROL_MODE_SPECIFIC = 0xf000,};
enum ieee80211_uhr_mode_change_mode_id { IEEE80211_UHR_MODE_CHANGE_MODE_ID_DPS = 0, IEEE80211_UHR_MODE_CHANGE_MODE_ID_NPCA = 1, IEEE80211_UHR_MODE_CHANGE_MODE_ID_DUO = 2, IEEE80211_UHR_MODE_CHANGE_MODE_ID_DSO = 3, IEEE80211_UHR_MODE_CHANGE_MODE_ID_P_EDCA = 4, IEEE80211_UHR_MODE_CHANGE_MODE_ID_ELR_RX = 5, IEEE80211_UHR_MODE_CHANGE_MODE_ID_AOM = 6, IEEE80211_UHR_MODE_CHANGE_MODE_ID_LLI = 7, IEEE80211_UHR_MODE_CHANGE_MODE_ID_CO_BF = 8, IEEE80211_UHR_MODE_CHANGE_MODE_ID_CO_SR = 9, IEEE80211_UHR_MODE_CHANGE_MODE_ID_EMLSR = 10, IEEE80211_UHR_MODE_CHANGE_MODE_ID_DBE = 11,};
struct ieee80211_uhr_mode_change_tuple { __le16 control; u8 variable[];} __packed;
static inline intieee80211_uhr_mode_change_tuple_size(const struct ieee80211_uhr_mode_change_tuple *tuple){ return sizeof(*tuple) + le16_get_bits(tuple->control, IEEE80211_UHR_MODE_CHANGE_CONTROL_MODE_LENGTH);}
#define for_each_uhr_mode_change_tuple(data, len, tuple) \ for (tuple = (const void *)(data); \ (len) - ((const u8 *)tuple - (data)) >= sizeof(*tuple) && \ (len) - ((const u8 *)tuple - (data)) >= \ ieee80211_uhr_mode_change_tuple_size(tuple); \ tuple = (const void *)((const u8 *)tuple + \ ieee80211_uhr_mode_change_tuple_size(tuple)))
#endif /* LINUX_IEEE80211_UHR_H */