| /* SPDX-License-Identifier: GPL-2.0-only */ | |
| /* | |
| * IEEE 802.11 HE definitions | |
| * | |
| * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen | |
| * <jkmaline@cc.hut.fi> | |
| * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> | |
| * Copyright (c) 2005, Devicescape Software, Inc. | |
| * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net> | |
| * Copyright (c) 2013 - 2014 Intel Mobile Communications GmbH | |
| * Copyright (c) 2016 - 2017 Intel Deutschland GmbH | |
| * Copyright (c) 2018 - 2025 Intel Corporation | |
| */ | |
| #ifndef LINUX_IEEE80211_HE_H | |
| #define LINUX_IEEE80211_HE_H | |
| #include <linux/types.h> | |
| #include <linux/if_ether.h> | |
| #define IEEE80211_TWT_CONTROL_NDP BIT(0) | |
| #define IEEE80211_TWT_CONTROL_RESP_MODE BIT(1) | |
| #define IEEE80211_TWT_CONTROL_NEG_TYPE_BROADCAST BIT(3) | |
| #define IEEE80211_TWT_CONTROL_RX_DISABLED BIT(4) | |
| #define IEEE80211_TWT_CONTROL_WAKE_DUR_UNIT BIT(5) | |
| #define IEEE80211_TWT_REQTYPE_REQUEST BIT(0) | |
| #define IEEE80211_TWT_REQTYPE_SETUP_CMD GENMASK(3, 1) | |
| #define IEEE80211_TWT_REQTYPE_TRIGGER BIT(4) | |
| #define IEEE80211_TWT_REQTYPE_IMPLICIT BIT(5) | |
| #define IEEE80211_TWT_REQTYPE_FLOWTYPE BIT(6) | |
| #define IEEE80211_TWT_REQTYPE_FLOWID GENMASK(9, 7) | |
| #define IEEE80211_TWT_REQTYPE_WAKE_INT_EXP GENMASK(14, 10) | |
| #define IEEE80211_TWT_REQTYPE_PROTECTION BIT(15) | |
| enum ieee80211_twt_setup_cmd { | |
| TWT_SETUP_CMD_REQUEST, | |
| TWT_SETUP_CMD_SUGGEST, | |
| TWT_SETUP_CMD_DEMAND, | |
| TWT_SETUP_CMD_GROUPING, | |
| TWT_SETUP_CMD_ACCEPT, | |
| TWT_SETUP_CMD_ALTERNATE, | |
| TWT_SETUP_CMD_DICTATE, | |
| TWT_SETUP_CMD_REJECT, | |
| }; | |
| struct ieee80211_twt_params { | |
| __le16 req_type; | |
| __le64 twt; | |
| u8 min_twt_dur; | |
| __le16 mantissa; | |
| u8 channel; | |
| } __packed; | |
| struct ieee80211_twt_setup { | |
| u8 dialog_token; | |
| u8 element_id; | |
| u8 length; | |
| u8 control; | |
| u8 params[]; | |
| } __packed; | |
| /** | |
| * struct ieee80211_he_cap_elem - HE capabilities element | |
| * @mac_cap_info: HE MAC Capabilities Information | |
| * @phy_cap_info: HE PHY Capabilities Information | |
| * | |
| * This structure represents the fixed fields of the payload of the | |
| * "HE capabilities element" as described in IEEE Std 802.11ax-2021 | |
| * sections 9.4.2.248.2 and 9.4.2.248.3. | |
| */ | |
| struct ieee80211_he_cap_elem { | |
| u8 mac_cap_info[6]; | |
| u8 phy_cap_info[11]; | |
| } __packed; | |
| #define IEEE80211_TX_RX_MCS_NSS_DESC_MAX_LEN 5 | |
| /** | |
| * enum ieee80211_he_mcs_support - HE MCS support definitions | |
| * @IEEE80211_HE_MCS_SUPPORT_0_7: MCSes 0-7 are supported for the | |
| * number of streams | |
| * @IEEE80211_HE_MCS_SUPPORT_0_9: MCSes 0-9 are supported | |
| * @IEEE80211_HE_MCS_SUPPORT_0_11: MCSes 0-11 are supported | |
| * @IEEE80211_HE_MCS_NOT_SUPPORTED: This number of streams isn't supported | |
| * | |
| * These definitions are used in each 2-bit subfield of the rx_mcs_* | |
| * and tx_mcs_* fields of &struct ieee80211_he_mcs_nss_supp, which are | |
| * both split into 8 subfields by number of streams. These values indicate | |
| * which MCSes are supported for the number of streams the value appears | |
| * for. | |
| */ | |
| enum ieee80211_he_mcs_support { | |
| IEEE80211_HE_MCS_SUPPORT_0_7 = 0, | |
| IEEE80211_HE_MCS_SUPPORT_0_9 = 1, | |
| IEEE80211_HE_MCS_SUPPORT_0_11 = 2, | |
| IEEE80211_HE_MCS_NOT_SUPPORTED = 3, | |
| }; | |
| /** | |
| * struct ieee80211_he_mcs_nss_supp - HE Tx/Rx HE MCS NSS Support Field | |
| * | |
| * This structure holds the data required for the Tx/Rx HE MCS NSS Support Field | |
| * described in P802.11ax_D2.0 section 9.4.2.237.4 | |
| * | |
| * @rx_mcs_80: Rx MCS map 2 bits for each stream, total 8 streams, for channel | |
| * widths less than 80MHz. | |
| * @tx_mcs_80: Tx MCS map 2 bits for each stream, total 8 streams, for channel | |
| * widths less than 80MHz. | |
| * @rx_mcs_160: Rx MCS map 2 bits for each stream, total 8 streams, for channel | |
| * width 160MHz. | |
| * @tx_mcs_160: Tx MCS map 2 bits for each stream, total 8 streams, for channel | |
| * width 160MHz. | |
| * @rx_mcs_80p80: Rx MCS map 2 bits for each stream, total 8 streams, for | |
| * channel width 80p80MHz. | |
| * @tx_mcs_80p80: Tx MCS map 2 bits for each stream, total 8 streams, for | |
| * channel width 80p80MHz. | |
| */ | |
| struct ieee80211_he_mcs_nss_supp { | |
| __le16 rx_mcs_80; | |
| __le16 tx_mcs_80; | |
| __le16 rx_mcs_160; | |
| __le16 tx_mcs_160; | |
| __le16 rx_mcs_80p80; | |
| __le16 tx_mcs_80p80; | |
| } __packed; | |
| /** | |
| * struct ieee80211_he_operation - HE Operation element | |
| * @he_oper_params: HE Operation Parameters + BSS Color Information | |
| * @he_mcs_nss_set: Basic HE-MCS And NSS Set | |
| * @optional: Optional fields VHT Operation Information, Max Co-Hosted | |
| * BSSID Indicator, and 6 GHz Operation Information | |
| * | |
| * This structure represents the payload of the "HE Operation | |
| * element" as described in IEEE Std 802.11ax-2021 section 9.4.2.249. | |
| */ | |
| struct ieee80211_he_operation { | |
| __le32 he_oper_params; | |
| __le16 he_mcs_nss_set; | |
| u8 optional[]; | |
| } __packed; | |
| /** | |
| * struct ieee80211_he_spr - Spatial Reuse Parameter Set element | |
| * @he_sr_control: SR Control | |
| * @optional: Optional fields Non-SRG OBSS PD Max Offset, SRG OBSS PD | |
| * Min Offset, SRG OBSS PD Max Offset, SRG BSS Color | |
| * Bitmap, and SRG Partial BSSID Bitmap | |
| * | |
| * This structure represents the payload of the "Spatial Reuse | |
| * Parameter Set element" as described in IEEE Std 802.11ax-2021 | |
| * section 9.4.2.252. | |
| */ | |
| struct ieee80211_he_spr { | |
| u8 he_sr_control; | |
| u8 optional[]; | |
| } __packed; | |
| /** | |
| * struct ieee80211_he_mu_edca_param_ac_rec - MU AC Parameter Record field | |
| * @aifsn: ACI/AIFSN | |
| * @ecw_min_max: ECWmin/ECWmax | |
| * @mu_edca_timer: MU EDCA Timer | |
| * | |
| * This structure represents the "MU AC Parameter Record" as described | |
| * in IEEE Std 802.11ax-2021 section 9.4.2.251, Figure 9-788p. | |
| */ | |
| struct ieee80211_he_mu_edca_param_ac_rec { | |
| u8 aifsn; | |
| u8 ecw_min_max; | |
| u8 mu_edca_timer; | |
| } __packed; | |
| /** | |
| * struct ieee80211_mu_edca_param_set - MU EDCA Parameter Set element | |
| * @mu_qos_info: QoS Info | |
| * @ac_be: MU AC_BE Parameter Record | |
| * @ac_bk: MU AC_BK Parameter Record | |
| * @ac_vi: MU AC_VI Parameter Record | |
| * @ac_vo: MU AC_VO Parameter Record | |
| * | |
| * This structure represents the payload of the "MU EDCA Parameter Set | |
| * element" as described in IEEE Std 802.11ax-2021 section 9.4.2.251. | |
| */ | |
| struct ieee80211_mu_edca_param_set { | |
| u8 mu_qos_info; | |
| struct ieee80211_he_mu_edca_param_ac_rec ac_be; | |
| struct ieee80211_he_mu_edca_param_ac_rec ac_bk; | |
| struct ieee80211_he_mu_edca_param_ac_rec ac_vi; | |
| struct ieee80211_he_mu_edca_param_ac_rec ac_vo; | |
| } __packed; | |
| /* 802.11ax HE MAC capabilities */ | |
| #define IEEE80211_HE_MAC_CAP0_HTC_HE 0x01 | |
| #define IEEE80211_HE_MAC_CAP0_TWT_REQ 0x02 | |
| #define IEEE80211_HE_MAC_CAP0_TWT_RES 0x04 | |
| #define IEEE80211_HE_MAC_CAP0_DYNAMIC_FRAG_NOT_SUPP 0x00 | |
| #define IEEE80211_HE_MAC_CAP0_DYNAMIC_FRAG_LEVEL_1 0x08 | |
| #define IEEE80211_HE_MAC_CAP0_DYNAMIC_FRAG_LEVEL_2 0x10 | |
| #define IEEE80211_HE_MAC_CAP0_DYNAMIC_FRAG_LEVEL_3 0x18 | |
| #define IEEE80211_HE_MAC_CAP0_DYNAMIC_FRAG_MASK 0x18 | |
| #define IEEE80211_HE_MAC_CAP0_MAX_NUM_FRAG_MSDU_1 0x00 | |
| #define IEEE80211_HE_MAC_CAP0_MAX_NUM_FRAG_MSDU_2 0x20 | |
| #define IEEE80211_HE_MAC_CAP0_MAX_NUM_FRAG_MSDU_4 0x40 | |
| #define IEEE80211_HE_MAC_CAP0_MAX_NUM_FRAG_MSDU_8 0x60 | |
| #define IEEE80211_HE_MAC_CAP0_MAX_NUM_FRAG_MSDU_16 0x80 | |
| #define IEEE80211_HE_MAC_CAP0_MAX_NUM_FRAG_MSDU_32 0xa0 | |
| #define IEEE80211_HE_MAC_CAP0_MAX_NUM_FRAG_MSDU_64 0xc0 | |
| #define IEEE80211_HE_MAC_CAP0_MAX_NUM_FRAG_MSDU_UNLIMITED 0xe0 | |
| #define IEEE80211_HE_MAC_CAP0_MAX_NUM_FRAG_MSDU_MASK 0xe0 | |
| #define IEEE80211_HE_MAC_CAP1_MIN_FRAG_SIZE_UNLIMITED 0x00 | |
| #define IEEE80211_HE_MAC_CAP1_MIN_FRAG_SIZE_128 0x01 | |
| #define IEEE80211_HE_MAC_CAP1_MIN_FRAG_SIZE_256 0x02 | |
| #define IEEE80211_HE_MAC_CAP1_MIN_FRAG_SIZE_512 0x03 | |
| #define IEEE80211_HE_MAC_CAP1_MIN_FRAG_SIZE_MASK 0x03 | |
| #define IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_0US 0x00 | |
| #define IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_8US 0x04 | |
| #define IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US 0x08 | |
| #define IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_MASK 0x0c | |
| #define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_1 0x00 | |
| #define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_2 0x10 | |
| #define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_3 0x20 | |
| #define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_4 0x30 | |
| #define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_5 0x40 | |
| #define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_6 0x50 | |
| #define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_7 0x60 | |
| #define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8 0x70 | |
| #define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_MASK 0x70 | |
| /* Link adaptation is split between byte HE_MAC_CAP1 and | |
| * HE_MAC_CAP2. It should be set only if IEEE80211_HE_MAC_CAP0_HTC_HE | |
| * in which case the following values apply: | |
| * 0 = No feedback. | |
| * 1 = reserved. | |
| * 2 = Unsolicited feedback. | |
| * 3 = both | |
| */ | |
| #define IEEE80211_HE_MAC_CAP1_LINK_ADAPTATION 0x80 | |
| #define IEEE80211_HE_MAC_CAP2_LINK_ADAPTATION 0x01 | |
| #define IEEE80211_HE_MAC_CAP2_ALL_ACK 0x02 | |
| #define IEEE80211_HE_MAC_CAP2_TRS 0x04 | |
| #define IEEE80211_HE_MAC_CAP2_BSR 0x08 | |
| #define IEEE80211_HE_MAC_CAP2_BCAST_TWT 0x10 | |
| #define IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP 0x20 | |
| #define IEEE80211_HE_MAC_CAP2_MU_CASCADING 0x40 | |
| #define IEEE80211_HE_MAC_CAP2_ACK_EN 0x80 | |
| #define IEEE80211_HE_MAC_CAP3_OMI_CONTROL 0x02 | |
| #define IEEE80211_HE_MAC_CAP3_OFDMA_RA 0x04 | |
| /* The maximum length of an A-MDPU is defined by the combination of the Maximum | |
| * A-MDPU Length Exponent field in the HT capabilities, VHT capabilities and the | |
| * same field in the HE capabilities. | |
| */ | |
| #define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_0 0x00 | |
| #define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_1 0x08 | |
| #define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2 0x10 | |
| #define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3 0x18 | |
| #define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK 0x18 | |
| #define IEEE80211_HE_MAC_CAP3_AMSDU_FRAG 0x20 | |
| #define IEEE80211_HE_MAC_CAP3_FLEX_TWT_SCHED 0x40 | |
| #define IEEE80211_HE_MAC_CAP3_RX_CTRL_FRAME_TO_MULTIBSS 0x80 | |
| #define IEEE80211_HE_MAC_CAP4_BSRP_BQRP_A_MPDU_AGG 0x01 | |
| #define IEEE80211_HE_MAC_CAP4_QTP 0x02 | |
| #define IEEE80211_HE_MAC_CAP4_BQR 0x04 | |
| #define IEEE80211_HE_MAC_CAP4_PSR_RESP 0x08 | |
| #define IEEE80211_HE_MAC_CAP4_NDP_FB_REP 0x10 | |
| #define IEEE80211_HE_MAC_CAP4_OPS 0x20 | |
| #define IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU 0x40 | |
| /* Multi TID agg TX is split between byte #4 and #5 | |
| * The value is a combination of B39,B40,B41 | |
| */ | |
| #define IEEE80211_HE_MAC_CAP4_MULTI_TID_AGG_TX_QOS_B39 0x80 | |
| #define IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B40 0x01 | |
| #define IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B41 0x02 | |
| #define IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECTIVE_TRANSMISSION 0x04 | |
| #define IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU 0x08 | |
| #define IEEE80211_HE_MAC_CAP5_OM_CTRL_UL_MU_DATA_DIS_RX 0x10 | |
| #define IEEE80211_HE_MAC_CAP5_HE_DYNAMIC_SM_PS 0x20 | |
| #define IEEE80211_HE_MAC_CAP5_PUNCTURED_SOUNDING 0x40 | |
| #define IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX 0x80 | |
| #define IEEE80211_HE_VHT_MAX_AMPDU_FACTOR 20 | |
| #define IEEE80211_HE_HT_MAX_AMPDU_FACTOR 16 | |
| #define IEEE80211_HE_6GHZ_MAX_AMPDU_FACTOR 13 | |
| /* 802.11ax HE PHY capabilities */ | |
| #define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G 0x02 | |
| #define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G 0x04 | |
| #define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G 0x08 | |
| #define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G 0x10 | |
| #define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_MASK_ALL 0x1e | |
| #define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_2G 0x20 | |
| #define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_5G 0x40 | |
| #define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_MASK 0xfe | |
| #define IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_80MHZ_ONLY_SECOND_20MHZ 0x01 | |
| #define IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_80MHZ_ONLY_SECOND_40MHZ 0x02 | |
| #define IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_160MHZ_ONLY_SECOND_20MHZ 0x04 | |
| #define IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_160MHZ_ONLY_SECOND_40MHZ 0x08 | |
| #define IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK 0x0f | |
| #define IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A 0x10 | |
| #define IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD 0x20 | |
| #define IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US 0x40 | |
| /* Midamble RX/TX Max NSTS is split between byte #2 and byte #3 */ | |
| #define IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS 0x80 | |
| #define IEEE80211_HE_PHY_CAP2_MIDAMBLE_RX_TX_MAX_NSTS 0x01 | |
| #define IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US 0x02 | |
| #define IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ 0x04 | |
| #define IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ 0x08 | |
| #define IEEE80211_HE_PHY_CAP2_DOPPLER_TX 0x10 | |
| #define IEEE80211_HE_PHY_CAP2_DOPPLER_RX 0x20 | |
| /* Note that the meaning of UL MU below is different between an AP and a non-AP | |
| * sta, where in the AP case it indicates support for Rx and in the non-AP sta | |
| * case it indicates support for Tx. | |
| */ | |
| #define IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO 0x40 | |
| #define IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO 0x80 | |
| #define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_NO_DCM 0x00 | |
| #define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_BPSK 0x01 | |
| #define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_QPSK 0x02 | |
| #define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_16_QAM 0x03 | |
| #define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_MASK 0x03 | |
| #define IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_1 0x00 | |
| #define IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_2 0x04 | |
| #define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_NO_DCM 0x00 | |
| #define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_BPSK 0x08 | |
| #define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_QPSK 0x10 | |
| #define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM 0x18 | |
| #define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_MASK 0x18 | |
| #define IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1 0x00 | |
| #define IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_2 0x20 | |
| #define IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU 0x40 | |
| #define IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER 0x80 | |
| #define IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE 0x01 | |
| #define IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER 0x02 | |
| /* Minimal allowed value of Max STS under 80MHz is 3 */ | |
| #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4 0x0c | |
| #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_5 0x10 | |
| #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_6 0x14 | |
| #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_7 0x18 | |
| #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_8 0x1c | |
| #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_MASK 0x1c | |
| /* Minimal allowed value of Max STS above 80MHz is 3 */ | |
| #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_4 0x60 | |
| #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_5 0x80 | |
| #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_6 0xa0 | |
| #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_7 0xc0 | |
| #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_8 0xe0 | |
| #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_MASK 0xe0 | |
| #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_1 0x00 | |
| #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_2 0x01 | |
| #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_3 0x02 | |
| #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_4 0x03 | |
| #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_5 0x04 | |
| #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_6 0x05 | |
| #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_7 0x06 | |
| #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_8 0x07 | |
| #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK 0x07 | |
| #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_1 0x00 | |
| #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_2 0x08 | |
| #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_3 0x10 | |
| #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_4 0x18 | |
| #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_5 0x20 | |
| #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_6 0x28 | |
| #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_7 0x30 | |
| #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_8 0x38 | |
| #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK 0x38 | |
| #define IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK 0x40 | |
| #define IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK 0x80 | |
| #define IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU 0x01 | |
| #define IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU 0x02 | |
| #define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB 0x04 | |
| #define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB 0x08 | |
| #define IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB 0x10 | |
| #define IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE 0x20 | |
| #define IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO 0x40 | |
| #define IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT 0x80 | |
| #define IEEE80211_HE_PHY_CAP7_PSR_BASED_SR 0x01 | |
| #define IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP 0x02 | |
| #define IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI 0x04 | |
| #define IEEE80211_HE_PHY_CAP7_MAX_NC_1 0x08 | |
| #define IEEE80211_HE_PHY_CAP7_MAX_NC_2 0x10 | |
| #define IEEE80211_HE_PHY_CAP7_MAX_NC_3 0x18 | |
| #define IEEE80211_HE_PHY_CAP7_MAX_NC_4 0x20 | |
| #define IEEE80211_HE_PHY_CAP7_MAX_NC_5 0x28 | |
| #define IEEE80211_HE_PHY_CAP7_MAX_NC_6 0x30 | |
| #define IEEE80211_HE_PHY_CAP7_MAX_NC_7 0x38 | |
| #define IEEE80211_HE_PHY_CAP7_MAX_NC_MASK 0x38 | |
| #define IEEE80211_HE_PHY_CAP7_STBC_TX_ABOVE_80MHZ 0x40 | |
| #define IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ 0x80 | |
| #define IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI 0x01 | |
| #define IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G 0x02 | |
| #define IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU 0x04 | |
| #define IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU 0x08 | |
| #define IEEE80211_HE_PHY_CAP8_HE_ER_SU_1XLTF_AND_08_US_GI 0x10 | |
| #define IEEE80211_HE_PHY_CAP8_MIDAMBLE_RX_TX_2X_AND_1XLTF 0x20 | |
| #define IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_242 0x00 | |
| #define IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_484 0x40 | |
| #define IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_996 0x80 | |
| #define IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_2x996 0xc0 | |
| #define IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_MASK 0xc0 | |
| #define IEEE80211_HE_PHY_CAP9_LONGER_THAN_16_SIGB_OFDM_SYM 0x01 | |
| #define IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK 0x02 | |
| #define IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU 0x04 | |
| #define IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU 0x08 | |
| #define IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB 0x10 | |
| #define IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB 0x20 | |
| #define IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_0US 0x0 | |
| #define IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_8US 0x1 | |
| #define IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US 0x2 | |
| #define IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_RESERVED 0x3 | |
| #define IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_POS 6 | |
| #define IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK 0xc0 | |
| #define IEEE80211_HE_PHY_CAP10_HE_MU_M1RU_MAX_LTF 0x01 | |
| /* 802.11ax HE TX/RX MCS NSS Support */ | |
| #define IEEE80211_TX_RX_MCS_NSS_SUPP_HIGHEST_MCS_POS (3) | |
| #define IEEE80211_TX_RX_MCS_NSS_SUPP_TX_BITMAP_POS (6) | |
| #define IEEE80211_TX_RX_MCS_NSS_SUPP_RX_BITMAP_POS (11) | |
| #define IEEE80211_TX_RX_MCS_NSS_SUPP_TX_BITMAP_MASK 0x07c0 | |
| #define IEEE80211_TX_RX_MCS_NSS_SUPP_RX_BITMAP_MASK 0xf800 | |
| /* TX/RX HE MCS Support field Highest MCS subfield encoding */ | |
| enum ieee80211_he_highest_mcs_supported_subfield_enc { | |
| HIGHEST_MCS_SUPPORTED_MCS7 = 0, | |
| HIGHEST_MCS_SUPPORTED_MCS8, | |
| HIGHEST_MCS_SUPPORTED_MCS9, | |
| HIGHEST_MCS_SUPPORTED_MCS10, | |
| HIGHEST_MCS_SUPPORTED_MCS11, | |
| }; | |
| /* Calculate 802.11ax HE capabilities IE Tx/Rx HE MCS NSS Support Field size */ | |
| static inline u8 | |
| ieee80211_he_mcs_nss_size(const struct ieee80211_he_cap_elem *he_cap) | |
| { | |
| u8 count = 4; | |
| if (he_cap->phy_cap_info[0] & | |
| IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G) | |
| count += 4; | |
| if (he_cap->phy_cap_info[0] & | |
| IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) | |
| count += 4; | |
| return count; | |
| } | |
| /* 802.11ax HE PPE Thresholds */ | |
| #define IEEE80211_PPE_THRES_NSS_SUPPORT_2NSS (1) | |
| #define IEEE80211_PPE_THRES_NSS_POS (0) | |
| #define IEEE80211_PPE_THRES_NSS_MASK (7) | |
| #define IEEE80211_PPE_THRES_RU_INDEX_BITMASK_2x966_AND_966_RU \ | |
| (BIT(5) | BIT(6)) | |
| #define IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK 0x78 | |
| #define IEEE80211_PPE_THRES_RU_INDEX_BITMASK_POS (3) | |
| #define IEEE80211_PPE_THRES_INFO_PPET_SIZE (3) | |
| #define IEEE80211_HE_PPE_THRES_INFO_HEADER_SIZE (7) | |
| /* | |
| * Calculate 802.11ax HE capabilities IE PPE field size | |
| * Input: Header byte of ppe_thres (first byte), and HE capa IE's PHY cap u8* | |
| */ | |
| static inline u8 | |
| ieee80211_he_ppe_size(u8 ppe_thres_hdr, const u8 *phy_cap_info) | |
| { | |
| u8 n; | |
| if ((phy_cap_info[6] & | |
| IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) == 0) | |
| return 0; | |
| n = hweight8(ppe_thres_hdr & | |
| IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK); | |
| n *= (1 + ((ppe_thres_hdr & IEEE80211_PPE_THRES_NSS_MASK) >> | |
| IEEE80211_PPE_THRES_NSS_POS)); | |
| /* | |
| * Each pair is 6 bits, and we need to add the 7 "header" bits to the | |
| * total size. | |
| */ | |
| n = (n * IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2) + 7; | |
| n = DIV_ROUND_UP(n, 8); | |
| return n; | |
| } | |
| static inline bool ieee80211_he_capa_size_ok(const u8 *data, u8 len) | |
| { | |
| const struct ieee80211_he_cap_elem *he_cap_ie_elem = (const void *)data; | |
| u8 needed = sizeof(*he_cap_ie_elem); | |
| if (len < needed) | |
| return false; | |
| needed += ieee80211_he_mcs_nss_size(he_cap_ie_elem); | |
| if (len < needed) | |
| return false; | |
| if (he_cap_ie_elem->phy_cap_info[6] & | |
| IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) { | |
| if (len < needed + 1) | |
| return false; | |
| needed += ieee80211_he_ppe_size(data[needed], | |
| he_cap_ie_elem->phy_cap_info); | |
| } | |
| return len >= needed; | |
| } | |
| /* HE Operation defines */ | |
| #define IEEE80211_HE_OPERATION_DFLT_PE_DURATION_MASK 0x00000007 | |
| #define IEEE80211_HE_OPERATION_TWT_REQUIRED 0x00000008 | |
| #define IEEE80211_HE_OPERATION_RTS_THRESHOLD_MASK 0x00003ff0 | |
| #define IEEE80211_HE_OPERATION_RTS_THRESHOLD_OFFSET 4 | |
| #define IEEE80211_HE_OPERATION_VHT_OPER_INFO 0x00004000 | |
| #define IEEE80211_HE_OPERATION_CO_HOSTED_BSS 0x00008000 | |
| #define IEEE80211_HE_OPERATION_ER_SU_DISABLE 0x00010000 | |
| #define IEEE80211_HE_OPERATION_6GHZ_OP_INFO 0x00020000 | |
| #define IEEE80211_HE_OPERATION_BSS_COLOR_MASK 0x3f000000 | |
| #define IEEE80211_HE_OPERATION_BSS_COLOR_OFFSET 24 | |
| #define IEEE80211_HE_OPERATION_PARTIAL_BSS_COLOR 0x40000000 | |
| #define IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED 0x80000000 | |
| #define IEEE80211_6GHZ_CTRL_REG_LPI_AP 0 | |
| #define IEEE80211_6GHZ_CTRL_REG_SP_AP 1 | |
| #define IEEE80211_6GHZ_CTRL_REG_VLP_AP 2 | |
| #define IEEE80211_6GHZ_CTRL_REG_INDOOR_LPI_AP 3 | |
| #define IEEE80211_6GHZ_CTRL_REG_INDOOR_SP_AP_OLD 4 | |
| #define IEEE80211_6GHZ_CTRL_REG_AP_ROLE_NOT_RELEVANT 7 | |
| #define IEEE80211_6GHZ_CTRL_REG_INDOOR_SP_AP 8 | |
| /** | |
| * struct ieee80211_he_6ghz_oper - HE 6 GHz operation Information field | |
| * @primary: primary channel | |
| * @control: control flags | |
| * @ccfs0: channel center frequency segment 0 | |
| * @ccfs1: channel center frequency segment 1 | |
| * @minrate: minimum rate (in 1 Mbps units) | |
| */ | |
| struct ieee80211_he_6ghz_oper { | |
| u8 primary; | |
| #define IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH 0x3 | |
| #define IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_20MHZ 0 | |
| #define IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_40MHZ 1 | |
| #define IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_80MHZ 2 | |
| #define IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ 3 | |
| #define IEEE80211_HE_6GHZ_OPER_CTRL_DUP_BEACON 0x4 | |
| #define IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO 0x78 | |
| u8 control; | |
| u8 ccfs0; | |
| u8 ccfs1; | |
| u8 minrate; | |
| } __packed; | |
| /** | |
| * enum ieee80211_reg_conn_bits - represents Regulatory connectivity field bits. | |
| * | |
| * This enumeration defines bit flags used to represent regulatory connectivity | |
| * field bits. | |
| * | |
| * @IEEE80211_REG_CONN_LPI_VALID: Indicates whether the LPI bit is valid. | |
| * @IEEE80211_REG_CONN_LPI_VALUE: Represents the value of the LPI bit. | |
| * @IEEE80211_REG_CONN_SP_VALID: Indicates whether the SP bit is valid. | |
| * @IEEE80211_REG_CONN_SP_VALUE: Represents the value of the SP bit. | |
| */ | |
| enum ieee80211_reg_conn_bits { | |
| IEEE80211_REG_CONN_LPI_VALID = BIT(0), | |
| IEEE80211_REG_CONN_LPI_VALUE = BIT(1), | |
| IEEE80211_REG_CONN_SP_VALID = BIT(2), | |
| IEEE80211_REG_CONN_SP_VALUE = BIT(3), | |
| }; | |
| /* transmit power interpretation type of transmit power envelope element */ | |
| enum ieee80211_tx_power_intrpt_type { | |
| IEEE80211_TPE_LOCAL_EIRP, | |
| IEEE80211_TPE_LOCAL_EIRP_PSD, | |
| IEEE80211_TPE_REG_CLIENT_EIRP, | |
| IEEE80211_TPE_REG_CLIENT_EIRP_PSD, | |
| }; | |
| /* category type of transmit power envelope element */ | |
| enum ieee80211_tx_power_category_6ghz { | |
| IEEE80211_TPE_CAT_6GHZ_DEFAULT = 0, | |
| IEEE80211_TPE_CAT_6GHZ_SUBORDINATE = 1, | |
| }; | |
| /* | |
| * For IEEE80211_TPE_LOCAL_EIRP / IEEE80211_TPE_REG_CLIENT_EIRP, | |
| * setting to 63.5 dBm means no constraint. | |
| */ | |
| #define IEEE80211_TPE_MAX_TX_PWR_NO_CONSTRAINT 127 | |
| /* | |
| * For IEEE80211_TPE_LOCAL_EIRP_PSD / IEEE80211_TPE_REG_CLIENT_EIRP_PSD, | |
| * setting to 127 indicates no PSD limit for the 20 MHz channel. | |
| */ | |
| #define IEEE80211_TPE_PSD_NO_LIMIT 127 | |
| /** | |
| * struct ieee80211_tx_pwr_env - Transmit Power Envelope | |
| * @info: Transmit Power Information field | |
| * @variable: Maximum Transmit Power field | |
| * | |
| * This structure represents the payload of the "Transmit Power | |
| * Envelope element" as described in IEEE Std 802.11ax-2021 section | |
| * 9.4.2.161 | |
| */ | |
| struct ieee80211_tx_pwr_env { | |
| u8 info; | |
| u8 variable[]; | |
| } __packed; | |
| #define IEEE80211_TX_PWR_ENV_INFO_COUNT 0x7 | |
| #define IEEE80211_TX_PWR_ENV_INFO_INTERPRET 0x38 | |
| #define IEEE80211_TX_PWR_ENV_INFO_CATEGORY 0xC0 | |
| #define IEEE80211_TX_PWR_ENV_EXT_COUNT 0xF | |
| static inline bool ieee80211_valid_tpe_element(const u8 *data, u8 len) | |
| { | |
| const struct ieee80211_tx_pwr_env *env = (const void *)data; | |
| u8 count, interpret, category; | |
| u8 needed = sizeof(*env); | |
| u8 N; /* also called N in the spec */ | |
| if (len < needed) | |
| return false; | |
| count = u8_get_bits(env->info, IEEE80211_TX_PWR_ENV_INFO_COUNT); | |
| interpret = u8_get_bits(env->info, IEEE80211_TX_PWR_ENV_INFO_INTERPRET); | |
| category = u8_get_bits(env->info, IEEE80211_TX_PWR_ENV_INFO_CATEGORY); | |
| switch (category) { | |
| case IEEE80211_TPE_CAT_6GHZ_DEFAULT: | |
| case IEEE80211_TPE_CAT_6GHZ_SUBORDINATE: | |
| break; | |
| default: | |
| return false; | |
| } | |
| switch (interpret) { | |
| case IEEE80211_TPE_LOCAL_EIRP: | |
| case IEEE80211_TPE_REG_CLIENT_EIRP: | |
| if (count > 3) | |
| return false; | |
| /* count == 0 encodes 1 value for 20 MHz, etc. */ | |
| needed += count + 1; | |
| if (len < needed) | |
| return false; | |
| /* there can be extension fields not accounted for in 'count' */ | |
| return true; | |
| case IEEE80211_TPE_LOCAL_EIRP_PSD: | |
| case IEEE80211_TPE_REG_CLIENT_EIRP_PSD: | |
| if (count > 4) | |
| return false; | |
| N = count ? 1 << (count - 1) : 1; | |
| needed += N; | |
| if (len < needed) | |
| return false; | |
| if (len > needed) { | |
| u8 K = u8_get_bits(env->variable[N], | |
| IEEE80211_TX_PWR_ENV_EXT_COUNT); | |
| needed += 1 + K; | |
| if (len < needed) | |
| return false; | |
| } | |
| return true; | |
| } | |
| return false; | |
| } | |
| /* | |
| * ieee80211_he_oper_size - calculate 802.11ax HE Operations IE size | |
| * @he_oper_ie: byte data of the He Operations IE, stating from the byte | |
| * after the ext ID byte. It is assumed that he_oper_ie has at least | |
| * sizeof(struct ieee80211_he_operation) bytes, the caller must have | |
| * validated this. | |
| * @return the actual size of the IE data (not including header), or 0 on error | |
| */ | |
| static inline u8 | |
| ieee80211_he_oper_size(const u8 *he_oper_ie) | |
| { | |
| const struct ieee80211_he_operation *he_oper = (const void *)he_oper_ie; | |
| u8 oper_len = sizeof(struct ieee80211_he_operation); | |
| u32 he_oper_params; | |
| /* Make sure the input is not NULL */ | |
| if (!he_oper_ie) | |
| return 0; | |
| /* Calc required length */ | |
| he_oper_params = le32_to_cpu(he_oper->he_oper_params); | |
| if (he_oper_params & IEEE80211_HE_OPERATION_VHT_OPER_INFO) | |
| oper_len += 3; | |
| if (he_oper_params & IEEE80211_HE_OPERATION_CO_HOSTED_BSS) | |
| oper_len++; | |
| if (he_oper_params & IEEE80211_HE_OPERATION_6GHZ_OP_INFO) | |
| oper_len += sizeof(struct ieee80211_he_6ghz_oper); | |
| /* Add the first byte (extension ID) to the total length */ | |
| oper_len++; | |
| return oper_len; | |
| } | |
| /** | |
| * ieee80211_he_6ghz_oper - obtain 6 GHz operation field | |
| * @he_oper: HE operation element (must be pre-validated for size) | |
| * but may be %NULL | |
| * | |
| * Return: a pointer to the 6 GHz operation field, or %NULL | |
| */ | |
| static inline const struct ieee80211_he_6ghz_oper * | |
| ieee80211_he_6ghz_oper(const struct ieee80211_he_operation *he_oper) | |
| { | |
| const u8 *ret; | |
| u32 he_oper_params; | |
| if (!he_oper) | |
| return NULL; | |
| ret = (const void *)&he_oper->optional; | |
| he_oper_params = le32_to_cpu(he_oper->he_oper_params); | |
| if (!(he_oper_params & IEEE80211_HE_OPERATION_6GHZ_OP_INFO)) | |
| return NULL; | |
| if (he_oper_params & IEEE80211_HE_OPERATION_VHT_OPER_INFO) | |
| ret += 3; | |
| if (he_oper_params & IEEE80211_HE_OPERATION_CO_HOSTED_BSS) | |
| ret++; | |
| return (const void *)ret; | |
| } | |
| /* HE Spatial Reuse defines */ | |
| #define IEEE80211_HE_SPR_PSR_DISALLOWED BIT(0) | |
| #define IEEE80211_HE_SPR_NON_SRG_OBSS_PD_SR_DISALLOWED BIT(1) | |
| #define IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT BIT(2) | |
| #define IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT BIT(3) | |
| #define IEEE80211_HE_SPR_HESIGA_SR_VAL15_ALLOWED BIT(4) | |
| /* | |
| * ieee80211_he_spr_size - calculate 802.11ax HE Spatial Reuse IE size | |
| * @he_spr_ie: byte data of the He Spatial Reuse IE, stating from the byte | |
| * after the ext ID byte. It is assumed that he_spr_ie has at least | |
| * sizeof(struct ieee80211_he_spr) bytes, the caller must have validated | |
| * this | |
| * @return the actual size of the IE data (not including header), or 0 on error | |
| */ | |
| static inline u8 | |
| ieee80211_he_spr_size(const u8 *he_spr_ie) | |
| { | |
| const struct ieee80211_he_spr *he_spr = (const void *)he_spr_ie; | |
| u8 spr_len = sizeof(struct ieee80211_he_spr); | |
| u8 he_spr_params; | |
| /* Make sure the input is not NULL */ | |
| if (!he_spr_ie) | |
| return 0; | |
| /* Calc required length */ | |
| he_spr_params = he_spr->he_sr_control; | |
| if (he_spr_params & IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT) | |
| spr_len++; | |
| if (he_spr_params & IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT) | |
| spr_len += 18; | |
| /* Add the first byte (extension ID) to the total length */ | |
| spr_len++; | |
| return spr_len; | |
| } | |
| struct ieee80211_he_6ghz_capa { | |
| /* uses IEEE80211_HE_6GHZ_CAP_* below */ | |
| __le16 capa; | |
| } __packed; | |
| /* HE 6 GHz band capabilities */ | |
| /* uses enum ieee80211_min_mpdu_spacing values */ | |
| #define IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START 0x0007 | |
| /* uses enum ieee80211_vht_max_ampdu_length_exp values */ | |
| #define IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP 0x0038 | |
| /* uses IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_* values */ | |
| #define IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN 0x00c0 | |
| /* WLAN_HT_CAP_SM_PS_* values */ | |
| #define IEEE80211_HE_6GHZ_CAP_SM_PS 0x0600 | |
| #define IEEE80211_HE_6GHZ_CAP_RD_RESPONDER 0x0800 | |
| #define IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS 0x1000 | |
| #define IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS 0x2000 | |
| #endif /* LINUX_IEEE80211_HE_H */ |