#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 {
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 {
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 {
__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 {
__le32 he_oper_params;
__le16 he_mcs_nss_set;
u8 optional[];
} __packed;
struct ieee80211_he_spr {
u8 he_sr_control;
u8 optional[];
} __packed;
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 {
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;
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
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,
};
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;
}
#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)
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));
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;
}
#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 {
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 {
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),
};
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,
};
enum ieee80211_tx_power_category_6ghz {
IEEE80211_TPE_CAT_6GHZ_DEFAULT = 0,
IEEE80211_TPE_CAT_6GHZ_SUBORDINATE = 1,
};
#define IEEE80211_TPE_MAX_TX_PWR_NO_CONSTRAINT 127
#define IEEE80211_TPE_PSD_NO_LIMIT 127
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;
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;
needed += count + 1;
if (len < needed)
return false;
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;
}
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;
if (!he_oper_ie)
return 0;
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);
oper_len++;
return oper_len;
}
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;
}
#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)
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;
if (!he_spr_ie)
return 0;
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;
spr_len++;
return spr_len;
}
struct ieee80211_he_6ghz_capa {
__le16 capa;
} __packed;
#define IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START 0x0007
#define IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP 0x0038
#define IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN 0x00c0
#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