cfg80211: Add support for HE
Add support for the HE in cfg80211 and also add userspace API to nl80211 to send rate information out, conforming with P802.11ax_D2.0. Signed-off-by: Liad Kaufman <liad.kaufman@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Ilan Peer <ilan.peer@intel.com> Signed-off-by: Ido Yariv <idox.yariv@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
This commit is contained in:
parent
446faa15c6
commit
c4cbaf7973
|
@ -1539,6 +1539,106 @@ struct ieee80211_vht_operation {
|
|||
__le16 basic_mcs_set;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct ieee80211_he_cap_elem - HE capabilities element
|
||||
*
|
||||
* This structure is the "HE capabilities element" fixed fields as
|
||||
* described in P802.11ax_D2.0 section 9.4.2.237.2 and 9.4.2.237.3
|
||||
*/
|
||||
struct ieee80211_he_cap_elem {
|
||||
u8 mac_cap_info[5];
|
||||
u8 phy_cap_info[9];
|
||||
} __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 capabilities element
|
||||
*
|
||||
* This structure is the "HE operation element" fields as
|
||||
* described in P802.11ax_D2.0 section 9.4.2.238
|
||||
*/
|
||||
struct ieee80211_he_operation {
|
||||
__le32 he_oper_params;
|
||||
__le16 he_mcs_nss_set;
|
||||
/* Optional 0,1,3 or 4 bytes: depends on @he_oper_params */
|
||||
u8 optional[0];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct ieee80211_he_mu_edca_param_ac_rec - MU AC Parameter Record field
|
||||
*
|
||||
* This structure is the "MU AC Parameter Record" fields as
|
||||
* described in P802.11ax_D2.0 section 9.4.2.240
|
||||
*/
|
||||
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
|
||||
*
|
||||
* This structure is the "MU EDCA Parameter Set element" fields as
|
||||
* described in P802.11ax_D2.0 section 9.4.2.240
|
||||
*/
|
||||
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.11ac VHT Capabilities */
|
||||
#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 0x00000000
|
||||
|
@ -1577,6 +1677,328 @@ struct ieee80211_vht_operation {
|
|||
#define IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN 0x10000000
|
||||
#define IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN 0x20000000
|
||||
|
||||
/* 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_QOS_1 0x00
|
||||
#define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_QOS_2 0x10
|
||||
#define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_QOS_3 0x20
|
||||
#define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_QOS_4 0x30
|
||||
#define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_QOS_5 0x40
|
||||
#define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_QOS_6 0x50
|
||||
#define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_QOS_7 0x60
|
||||
#define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_QOS_8 0x70
|
||||
#define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_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_UL_MU_RESP_SCHED 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_GRP_ADDR_MULTI_STA_BA_DL_MU 0x01
|
||||
#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_A_AMPDU_LEN_EXP_USE_VHT 0x00
|
||||
#define IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_VHT_1 0x08
|
||||
#define IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_VHT_2 0x10
|
||||
#define IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_RESERVED 0x18
|
||||
#define IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_MASK 0x18
|
||||
#define IEEE80211_HE_MAC_CAP3_A_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_SR_RESP 0x08
|
||||
#define IEEE80211_HE_MAC_CAP4_NDP_FB_REP 0x10
|
||||
#define IEEE80211_HE_MAC_CAP4_OPS 0x20
|
||||
#define IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU 0x40
|
||||
|
||||
/* 802.11ax HE PHY capabilities */
|
||||
#define IEEE80211_HE_PHY_CAP0_DUAL_BAND 0x01
|
||||
#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_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 Max NSTS is split between byte #2 and byte #3 */
|
||||
#define IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_MAX_NSTS 0x80
|
||||
|
||||
#define IEEE80211_HE_PHY_CAP2_MIDAMBLE_RX_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_HE_MU_PPDU_FROM_NON_AP_STA 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_BEAMFORMER_FB 0x04
|
||||
#define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_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_SRP_BASED_SR 0x01
|
||||
#define IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR 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_2X_AND_1XLTF 0x20
|
||||
|
||||
/* 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)
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
/* HE Operation defines */
|
||||
#define IEEE80211_HE_OPERATION_BSS_COLOR_MASK 0x0000003f
|
||||
#define IEEE80211_HE_OPERATION_DFLT_PE_DURATION_MASK 0x000001c0
|
||||
#define IEEE80211_HE_OPERATION_DFLT_PE_DURATION_OFFSET 6
|
||||
#define IEEE80211_HE_OPERATION_TWT_REQUIRED 0x00000200
|
||||
#define IEEE80211_HE_OPERATION_RTS_THRESHOLD_MASK 0x000ffc00
|
||||
#define IEEE80211_HE_OPERATION_RTS_THRESHOLD_OFFSET 10
|
||||
#define IEEE80211_HE_OPERATION_PARTIAL_BSS_COLOR 0x000100000
|
||||
#define IEEE80211_HE_OPERATION_VHT_OPER_INFO 0x000200000
|
||||
#define IEEE80211_HE_OPERATION_MULTI_BSSID_AP 0x10000000
|
||||
#define IEEE80211_HE_OPERATION_TX_BSSID_INDICATOR 0x20000000
|
||||
#define IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED 0x40000000
|
||||
|
||||
/*
|
||||
* ieee80211_he_oper_size - calculate 802.11ax HE Operations IE size
|
||||
* @he_oper_ie: byte data of the He Operations IE, stating from the the byte
|
||||
* after the ext ID byte. It is assumed that he_oper_ie has at least
|
||||
* sizeof(struct ieee80211_he_operation) bytes, checked already in
|
||||
* ieee802_11_parse_elems_crc()
|
||||
* @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)
|
||||
{
|
||||
struct ieee80211_he_operation *he_oper = (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_MULTI_BSSID_AP)
|
||||
oper_len++;
|
||||
|
||||
/* Add the first byte (extension ID) to the total length */
|
||||
oper_len++;
|
||||
|
||||
return oper_len;
|
||||
}
|
||||
|
||||
/* Authentication algorithms */
|
||||
#define WLAN_AUTH_OPEN 0
|
||||
#define WLAN_AUTH_SHARED_KEY 1
|
||||
|
@ -1992,6 +2414,11 @@ enum ieee80211_eid_ext {
|
|||
WLAN_EID_EXT_FILS_WRAPPED_DATA = 8,
|
||||
WLAN_EID_EXT_FILS_PUBLIC_KEY = 12,
|
||||
WLAN_EID_EXT_FILS_NONCE = 13,
|
||||
WLAN_EID_EXT_FUTURE_CHAN_GUIDANCE = 14,
|
||||
WLAN_EID_EXT_HE_CAPABILITY = 35,
|
||||
WLAN_EID_EXT_HE_OPERATION = 36,
|
||||
WLAN_EID_EXT_UORA = 37,
|
||||
WLAN_EID_EXT_HE_MU_EDCA = 38,
|
||||
};
|
||||
|
||||
/* Action category code */
|
||||
|
|
|
@ -285,6 +285,41 @@ struct ieee80211_sta_vht_cap {
|
|||
struct ieee80211_vht_mcs_info vht_mcs;
|
||||
};
|
||||
|
||||
#define IEEE80211_HE_PPE_THRES_MAX_LEN 25
|
||||
|
||||
/**
|
||||
* struct ieee80211_sta_he_cap - STA's HE capabilities
|
||||
*
|
||||
* This structure describes most essential parameters needed
|
||||
* to describe 802.11ax HE capabilities for a STA.
|
||||
*
|
||||
* @has_he: true iff HE data is valid.
|
||||
* @he_cap_elem: Fixed portion of the HE capabilities element.
|
||||
* @he_mcs_nss_supp: The supported NSS/MCS combinations.
|
||||
* @ppe_thres: Holds the PPE Thresholds data.
|
||||
*/
|
||||
struct ieee80211_sta_he_cap {
|
||||
bool has_he;
|
||||
struct ieee80211_he_cap_elem he_cap_elem;
|
||||
struct ieee80211_he_mcs_nss_supp he_mcs_nss_supp;
|
||||
u8 ppe_thres[IEEE80211_HE_PPE_THRES_MAX_LEN];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ieee80211_sband_iftype_data
|
||||
*
|
||||
* This structure encapsulates sband data that is relevant for the
|
||||
* interface types defined in @types_mask. Each type in the
|
||||
* @types_mask must be unique across all instances of iftype_data.
|
||||
*
|
||||
* @types_mask: interface types mask
|
||||
* @he_cap: holds the HE capabilities
|
||||
*/
|
||||
struct ieee80211_sband_iftype_data {
|
||||
u16 types_mask;
|
||||
struct ieee80211_sta_he_cap he_cap;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ieee80211_supported_band - frequency band definition
|
||||
*
|
||||
|
@ -301,6 +336,11 @@ struct ieee80211_sta_vht_cap {
|
|||
* @n_bitrates: Number of bitrates in @bitrates
|
||||
* @ht_cap: HT capabilities in this band
|
||||
* @vht_cap: VHT capabilities in this band
|
||||
* @n_iftype_data: number of iftype data entries
|
||||
* @iftype_data: interface type data entries. Note that the bits in
|
||||
* @types_mask inside this structure cannot overlap (i.e. only
|
||||
* one occurrence of each type is allowed across all instances of
|
||||
* iftype_data).
|
||||
*/
|
||||
struct ieee80211_supported_band {
|
||||
struct ieee80211_channel *channels;
|
||||
|
@ -310,8 +350,55 @@ struct ieee80211_supported_band {
|
|||
int n_bitrates;
|
||||
struct ieee80211_sta_ht_cap ht_cap;
|
||||
struct ieee80211_sta_vht_cap vht_cap;
|
||||
u16 n_iftype_data;
|
||||
const struct ieee80211_sband_iftype_data *iftype_data;
|
||||
};
|
||||
|
||||
/**
|
||||
* ieee80211_get_sband_iftype_data - return sband data for a given iftype
|
||||
* @sband: the sband to search for the STA on
|
||||
* @iftype: enum nl80211_iftype
|
||||
*
|
||||
* Return: pointer to struct ieee80211_sband_iftype_data, or NULL is none found
|
||||
*/
|
||||
static inline const struct ieee80211_sband_iftype_data *
|
||||
ieee80211_get_sband_iftype_data(const struct ieee80211_supported_band *sband,
|
||||
u8 iftype)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (WARN_ON(iftype >= NL80211_IFTYPE_MAX))
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < sband->n_iftype_data; i++) {
|
||||
const struct ieee80211_sband_iftype_data *data =
|
||||
&sband->iftype_data[i];
|
||||
|
||||
if (data->types_mask & BIT(iftype))
|
||||
return data;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* ieee80211_get_he_sta_cap - return HE capabilities for an sband's STA
|
||||
* @sband: the sband to search for the STA on
|
||||
*
|
||||
* Return: pointer to the struct ieee80211_sta_he_cap, or NULL is none found
|
||||
*/
|
||||
static inline const struct ieee80211_sta_he_cap *
|
||||
ieee80211_get_he_sta_cap(const struct ieee80211_supported_band *sband)
|
||||
{
|
||||
const struct ieee80211_sband_iftype_data *data =
|
||||
ieee80211_get_sband_iftype_data(sband, NL80211_IFTYPE_STATION);
|
||||
|
||||
if (data && data->he_cap.has_he)
|
||||
return &data->he_cap;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* wiphy_read_of_freq_limits - read frequency limits from device tree
|
||||
*
|
||||
|
@ -899,6 +986,8 @@ enum station_parameters_apply_mask {
|
|||
* @opmode_notif: operating mode field from Operating Mode Notification
|
||||
* @opmode_notif_used: information if operating mode field is used
|
||||
* @support_p2p_ps: information if station supports P2P PS mechanism
|
||||
* @he_capa: HE capabilities of station
|
||||
* @he_capa_len: the length of the HE capabilities
|
||||
*/
|
||||
struct station_parameters {
|
||||
const u8 *supported_rates;
|
||||
|
@ -926,6 +1015,8 @@ struct station_parameters {
|
|||
u8 opmode_notif;
|
||||
bool opmode_notif_used;
|
||||
int support_p2p_ps;
|
||||
const struct ieee80211_he_cap_elem *he_capa;
|
||||
u8 he_capa_len;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1000,12 +1091,14 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
|
|||
* @RATE_INFO_FLAGS_VHT_MCS: mcs field filled with VHT MCS
|
||||
* @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval
|
||||
* @RATE_INFO_FLAGS_60G: 60GHz MCS
|
||||
* @RATE_INFO_FLAGS_HE_MCS: HE MCS information
|
||||
*/
|
||||
enum rate_info_flags {
|
||||
RATE_INFO_FLAGS_MCS = BIT(0),
|
||||
RATE_INFO_FLAGS_VHT_MCS = BIT(1),
|
||||
RATE_INFO_FLAGS_SHORT_GI = BIT(2),
|
||||
RATE_INFO_FLAGS_60G = BIT(3),
|
||||
RATE_INFO_FLAGS_HE_MCS = BIT(4),
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1019,6 +1112,7 @@ enum rate_info_flags {
|
|||
* @RATE_INFO_BW_40: 40 MHz bandwidth
|
||||
* @RATE_INFO_BW_80: 80 MHz bandwidth
|
||||
* @RATE_INFO_BW_160: 160 MHz bandwidth
|
||||
* @RATE_INFO_BW_HE_RU: bandwidth determined by HE RU allocation
|
||||
*/
|
||||
enum rate_info_bw {
|
||||
RATE_INFO_BW_20 = 0,
|
||||
|
@ -1027,6 +1121,7 @@ enum rate_info_bw {
|
|||
RATE_INFO_BW_40,
|
||||
RATE_INFO_BW_80,
|
||||
RATE_INFO_BW_160,
|
||||
RATE_INFO_BW_HE_RU,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1035,10 +1130,14 @@ enum rate_info_bw {
|
|||
* Information about a receiving or transmitting bitrate
|
||||
*
|
||||
* @flags: bitflag of flags from &enum rate_info_flags
|
||||
* @mcs: mcs index if struct describes a 802.11n bitrate
|
||||
* @mcs: mcs index if struct describes an HT/VHT/HE rate
|
||||
* @legacy: bitrate in 100kbit/s for 802.11abg
|
||||
* @nss: number of streams (VHT only)
|
||||
* @nss: number of streams (VHT & HE only)
|
||||
* @bw: bandwidth (from &enum rate_info_bw)
|
||||
* @he_gi: HE guard interval (from &enum nl80211_he_gi)
|
||||
* @he_dcm: HE DCM value
|
||||
* @he_ru_alloc: HE RU allocation (from &enum nl80211_he_ru_alloc,
|
||||
* only valid if bw is %RATE_INFO_BW_HE_RU)
|
||||
*/
|
||||
struct rate_info {
|
||||
u8 flags;
|
||||
|
@ -1046,6 +1145,9 @@ struct rate_info {
|
|||
u16 legacy;
|
||||
u8 nss;
|
||||
u8 bw;
|
||||
u8 he_gi;
|
||||
u8 he_dcm;
|
||||
u8 he_ru_alloc;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -2237,6 +2237,9 @@ enum nl80211_commands {
|
|||
* enforced.
|
||||
* @NL80211_ATTR_TXQ_QUANTUM: TXQ scheduler quantum (bytes). Number of bytes
|
||||
* a flow is assigned on each round of the DRR scheduler.
|
||||
* @NL80211_ATTR_HE_CAPABILITY: HE Capability information element (from
|
||||
* association request when used with NL80211_CMD_NEW_STATION). Can be set
|
||||
* only if %NL80211_STA_FLAG_WME is set.
|
||||
*
|
||||
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
|
||||
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
||||
|
@ -2677,6 +2680,8 @@ enum nl80211_attrs {
|
|||
NL80211_ATTR_TXQ_MEMORY_LIMIT,
|
||||
NL80211_ATTR_TXQ_QUANTUM,
|
||||
|
||||
NL80211_ATTR_HE_CAPABILITY,
|
||||
|
||||
/* add attributes here, update the policy in nl80211.c */
|
||||
|
||||
__NL80211_ATTR_AFTER_LAST,
|
||||
|
@ -2726,7 +2731,8 @@ enum nl80211_attrs {
|
|||
#define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24
|
||||
#define NL80211_HT_CAPABILITY_LEN 26
|
||||
#define NL80211_VHT_CAPABILITY_LEN 12
|
||||
|
||||
#define NL80211_HE_MIN_CAPABILITY_LEN 16
|
||||
#define NL80211_HE_MAX_CAPABILITY_LEN 51
|
||||
#define NL80211_MAX_NR_CIPHER_SUITES 5
|
||||
#define NL80211_MAX_NR_AKM_SUITES 2
|
||||
|
||||
|
@ -2853,6 +2859,38 @@ struct nl80211_sta_flag_update {
|
|||
__u32 set;
|
||||
} __attribute__((packed));
|
||||
|
||||
/**
|
||||
* enum nl80211_he_gi - HE guard interval
|
||||
* @NL80211_RATE_INFO_HE_GI_0_8: 0.8 usec
|
||||
* @NL80211_RATE_INFO_HE_GI_1_6: 1.6 usec
|
||||
* @NL80211_RATE_INFO_HE_GI_3_2: 3.2 usec
|
||||
*/
|
||||
enum nl80211_he_gi {
|
||||
NL80211_RATE_INFO_HE_GI_0_8,
|
||||
NL80211_RATE_INFO_HE_GI_1_6,
|
||||
NL80211_RATE_INFO_HE_GI_3_2,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum nl80211_he_ru_alloc - HE RU allocation values
|
||||
* @NL80211_RATE_INFO_HE_RU_ALLOC_26: 26-tone RU allocation
|
||||
* @NL80211_RATE_INFO_HE_RU_ALLOC_52: 52-tone RU allocation
|
||||
* @NL80211_RATE_INFO_HE_RU_ALLOC_106: 106-tone RU allocation
|
||||
* @NL80211_RATE_INFO_HE_RU_ALLOC_242: 242-tone RU allocation
|
||||
* @NL80211_RATE_INFO_HE_RU_ALLOC_484: 484-tone RU allocation
|
||||
* @NL80211_RATE_INFO_HE_RU_ALLOC_996: 996-tone RU allocation
|
||||
* @NL80211_RATE_INFO_HE_RU_ALLOC_2x996: 2x996-tone RU allocation
|
||||
*/
|
||||
enum nl80211_he_ru_alloc {
|
||||
NL80211_RATE_INFO_HE_RU_ALLOC_26,
|
||||
NL80211_RATE_INFO_HE_RU_ALLOC_52,
|
||||
NL80211_RATE_INFO_HE_RU_ALLOC_106,
|
||||
NL80211_RATE_INFO_HE_RU_ALLOC_242,
|
||||
NL80211_RATE_INFO_HE_RU_ALLOC_484,
|
||||
NL80211_RATE_INFO_HE_RU_ALLOC_996,
|
||||
NL80211_RATE_INFO_HE_RU_ALLOC_2x996,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum nl80211_rate_info - bitrate information
|
||||
*
|
||||
|
@ -2885,6 +2923,13 @@ struct nl80211_sta_flag_update {
|
|||
* @NL80211_RATE_INFO_5_MHZ_WIDTH: 5 MHz width - note that this is
|
||||
* a legacy rate and will be reported as the actual bitrate, i.e.
|
||||
* a quarter of the base (20 MHz) rate
|
||||
* @NL80211_RATE_INFO_HE_MCS: HE MCS index (u8, 0-11)
|
||||
* @NL80211_RATE_INFO_HE_NSS: HE NSS value (u8, 1-8)
|
||||
* @NL80211_RATE_INFO_HE_GI: HE guard interval identifier
|
||||
* (u8, see &enum nl80211_he_gi)
|
||||
* @NL80211_RATE_INFO_HE_DCM: HE DCM value (u8, 0/1)
|
||||
* @NL80211_RATE_INFO_RU_ALLOC: HE RU allocation, if not present then
|
||||
* non-OFDMA was used (u8, see &enum nl80211_he_ru_alloc)
|
||||
* @__NL80211_RATE_INFO_AFTER_LAST: internal use
|
||||
*/
|
||||
enum nl80211_rate_info {
|
||||
|
@ -2901,6 +2946,11 @@ enum nl80211_rate_info {
|
|||
NL80211_RATE_INFO_160_MHZ_WIDTH,
|
||||
NL80211_RATE_INFO_10_MHZ_WIDTH,
|
||||
NL80211_RATE_INFO_5_MHZ_WIDTH,
|
||||
NL80211_RATE_INFO_HE_MCS,
|
||||
NL80211_RATE_INFO_HE_NSS,
|
||||
NL80211_RATE_INFO_HE_GI,
|
||||
NL80211_RATE_INFO_HE_DCM,
|
||||
NL80211_RATE_INFO_HE_RU_ALLOC,
|
||||
|
||||
/* keep last */
|
||||
__NL80211_RATE_INFO_AFTER_LAST,
|
||||
|
@ -3166,6 +3216,38 @@ enum nl80211_mpath_info {
|
|||
NL80211_MPATH_INFO_MAX = __NL80211_MPATH_INFO_AFTER_LAST - 1
|
||||
};
|
||||
|
||||
/**
|
||||
* enum nl80211_band_iftype_attr - Interface type data attributes
|
||||
*
|
||||
* @__NL80211_BAND_IFTYPE_ATTR_INVALID: attribute number 0 is reserved
|
||||
* @NL80211_BAND_IFTYPE_ATTR_IFTYPES: nested attribute containing a flag attribute
|
||||
* for each interface type that supports the band data
|
||||
* @NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC: HE MAC capabilities as in HE
|
||||
* capabilities IE
|
||||
* @NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY: HE PHY capabilities as in HE
|
||||
* capabilities IE
|
||||
* @NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET: HE supported NSS/MCS as in HE
|
||||
* capabilities IE
|
||||
* @NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE: HE PPE thresholds information as
|
||||
* defined in HE capabilities IE
|
||||
* @NL80211_BAND_IFTYPE_ATTR_MAX: highest band HE capability attribute currently
|
||||
* defined
|
||||
* @__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST: internal use
|
||||
*/
|
||||
enum nl80211_band_iftype_attr {
|
||||
__NL80211_BAND_IFTYPE_ATTR_INVALID,
|
||||
|
||||
NL80211_BAND_IFTYPE_ATTR_IFTYPES,
|
||||
NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC,
|
||||
NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY,
|
||||
NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET,
|
||||
NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE,
|
||||
|
||||
/* keep last */
|
||||
__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST,
|
||||
NL80211_BAND_IFTYPE_ATTR_MAX = __NL80211_BAND_IFTYPE_ATTR_AFTER_LAST - 1
|
||||
};
|
||||
|
||||
/**
|
||||
* enum nl80211_band_attr - band attributes
|
||||
* @__NL80211_BAND_ATTR_INVALID: attribute number 0 is reserved
|
||||
|
@ -3181,6 +3263,8 @@ enum nl80211_mpath_info {
|
|||
* @NL80211_BAND_ATTR_VHT_MCS_SET: 32-byte attribute containing the MCS set as
|
||||
* defined in 802.11ac
|
||||
* @NL80211_BAND_ATTR_VHT_CAPA: VHT capabilities, as in the HT information IE
|
||||
* @NL80211_BAND_ATTR_IFTYPE_DATA: nested array attribute, with each entry using
|
||||
* attributes from &enum nl80211_band_iftype_attr
|
||||
* @NL80211_BAND_ATTR_MAX: highest band attribute currently defined
|
||||
* @__NL80211_BAND_ATTR_AFTER_LAST: internal use
|
||||
*/
|
||||
|
@ -3196,6 +3280,7 @@ enum nl80211_band_attr {
|
|||
|
||||
NL80211_BAND_ATTR_VHT_MCS_SET,
|
||||
NL80211_BAND_ATTR_VHT_CAPA,
|
||||
NL80211_BAND_ATTR_IFTYPE_DATA,
|
||||
|
||||
/* keep last */
|
||||
__NL80211_BAND_ATTR_AFTER_LAST,
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright 2015 Intel Deutschland GmbH
|
||||
* Copyright 2015-2017 Intel Deutschland GmbH
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
@ -744,6 +744,8 @@ int wiphy_register(struct wiphy *wiphy)
|
|||
|
||||
/* sanity check supported bands/channels */
|
||||
for (band = 0; band < NUM_NL80211_BANDS; band++) {
|
||||
u16 types = 0;
|
||||
|
||||
sband = wiphy->bands[band];
|
||||
if (!sband)
|
||||
continue;
|
||||
|
@ -788,6 +790,23 @@ int wiphy_register(struct wiphy *wiphy)
|
|||
sband->channels[i].band = band;
|
||||
}
|
||||
|
||||
for (i = 0; i < sband->n_iftype_data; i++) {
|
||||
const struct ieee80211_sband_iftype_data *iftd;
|
||||
|
||||
iftd = &sband->iftype_data[i];
|
||||
|
||||
if (WARN_ON(!iftd->types_mask))
|
||||
return -EINVAL;
|
||||
if (WARN_ON(types & iftd->types_mask))
|
||||
return -EINVAL;
|
||||
|
||||
/* at least one piece of information must be present */
|
||||
if (WARN_ON(!iftd->he_cap.has_he))
|
||||
return -EINVAL;
|
||||
|
||||
types |= iftd->types_mask;
|
||||
}
|
||||
|
||||
have_band = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -428,6 +428,8 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
|||
[NL80211_ATTR_TXQ_LIMIT] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_TXQ_MEMORY_LIMIT] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_TXQ_QUANTUM] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_HE_CAPABILITY] = { .type = NLA_BINARY,
|
||||
.len = NL80211_HE_MAX_CAPABILITY_LEN },
|
||||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
|
@ -1324,6 +1326,34 @@ static int nl80211_send_coalesce(struct sk_buff *msg,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nl80211_send_iftype_data(struct sk_buff *msg,
|
||||
const struct ieee80211_sband_iftype_data *iftdata)
|
||||
{
|
||||
const struct ieee80211_sta_he_cap *he_cap = &iftdata->he_cap;
|
||||
|
||||
if (nl80211_put_iftypes(msg, NL80211_BAND_IFTYPE_ATTR_IFTYPES,
|
||||
iftdata->types_mask))
|
||||
return -ENOBUFS;
|
||||
|
||||
if (he_cap->has_he) {
|
||||
if (nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC,
|
||||
sizeof(he_cap->he_cap_elem.mac_cap_info),
|
||||
he_cap->he_cap_elem.mac_cap_info) ||
|
||||
nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY,
|
||||
sizeof(he_cap->he_cap_elem.phy_cap_info),
|
||||
he_cap->he_cap_elem.phy_cap_info) ||
|
||||
nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET,
|
||||
sizeof(he_cap->he_mcs_nss_supp),
|
||||
&he_cap->he_mcs_nss_supp) ||
|
||||
nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE,
|
||||
sizeof(he_cap->ppe_thres), he_cap->ppe_thres))
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nl80211_send_band_rateinfo(struct sk_buff *msg,
|
||||
struct ieee80211_supported_band *sband)
|
||||
{
|
||||
|
@ -1353,6 +1383,32 @@ static int nl80211_send_band_rateinfo(struct sk_buff *msg,
|
|||
sband->vht_cap.cap)))
|
||||
return -ENOBUFS;
|
||||
|
||||
if (sband->n_iftype_data) {
|
||||
struct nlattr *nl_iftype_data =
|
||||
nla_nest_start(msg, NL80211_BAND_ATTR_IFTYPE_DATA);
|
||||
int err;
|
||||
|
||||
if (!nl_iftype_data)
|
||||
return -ENOBUFS;
|
||||
|
||||
for (i = 0; i < sband->n_iftype_data; i++) {
|
||||
struct nlattr *iftdata;
|
||||
|
||||
iftdata = nla_nest_start(msg, i + 1);
|
||||
if (!iftdata)
|
||||
return -ENOBUFS;
|
||||
|
||||
err = nl80211_send_iftype_data(msg,
|
||||
&sband->iftype_data[i]);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
nla_nest_end(msg, iftdata);
|
||||
}
|
||||
|
||||
nla_nest_end(msg, nl_iftype_data);
|
||||
}
|
||||
|
||||
/* add bitrates */
|
||||
nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES);
|
||||
if (!nl_rates)
|
||||
|
@ -4472,6 +4528,9 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
|
|||
case RATE_INFO_BW_160:
|
||||
rate_flg = NL80211_RATE_INFO_160_MHZ_WIDTH;
|
||||
break;
|
||||
case RATE_INFO_BW_HE_RU:
|
||||
rate_flg = 0;
|
||||
WARN_ON(!(info->flags & RATE_INFO_FLAGS_HE_MCS));
|
||||
}
|
||||
|
||||
if (rate_flg && nla_put_flag(msg, rate_flg))
|
||||
|
@ -4491,6 +4550,19 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
|
|||
if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
|
||||
nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
|
||||
return false;
|
||||
} else if (info->flags & RATE_INFO_FLAGS_HE_MCS) {
|
||||
if (nla_put_u8(msg, NL80211_RATE_INFO_HE_MCS, info->mcs))
|
||||
return false;
|
||||
if (nla_put_u8(msg, NL80211_RATE_INFO_HE_NSS, info->nss))
|
||||
return false;
|
||||
if (nla_put_u8(msg, NL80211_RATE_INFO_HE_GI, info->he_gi))
|
||||
return false;
|
||||
if (nla_put_u8(msg, NL80211_RATE_INFO_HE_DCM, info->he_dcm))
|
||||
return false;
|
||||
if (info->bw == RATE_INFO_BW_HE_RU &&
|
||||
nla_put_u8(msg, NL80211_RATE_INFO_HE_RU_ALLOC,
|
||||
info->he_ru_alloc))
|
||||
return false;
|
||||
}
|
||||
|
||||
nla_nest_end(msg, rate);
|
||||
|
@ -4887,7 +4959,8 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
|
|||
return -EINVAL;
|
||||
if (params->supported_rates)
|
||||
return -EINVAL;
|
||||
if (params->ext_capab || params->ht_capa || params->vht_capa)
|
||||
if (params->ext_capab || params->ht_capa || params->vht_capa ||
|
||||
params->he_capa)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -5093,6 +5166,15 @@ static int nl80211_set_station_tdls(struct genl_info *info,
|
|||
if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
|
||||
params->vht_capa =
|
||||
nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
|
||||
if (info->attrs[NL80211_ATTR_HE_CAPABILITY]) {
|
||||
params->he_capa =
|
||||
nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
|
||||
params->he_capa_len =
|
||||
nla_len(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
|
||||
|
||||
if (params->he_capa_len < NL80211_HE_MIN_CAPABILITY_LEN)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = nl80211_parse_sta_channel_info(info, params);
|
||||
if (err)
|
||||
|
@ -5320,6 +5402,17 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
|
|||
params.vht_capa =
|
||||
nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
|
||||
|
||||
if (info->attrs[NL80211_ATTR_HE_CAPABILITY]) {
|
||||
params.he_capa =
|
||||
nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
|
||||
params.he_capa_len =
|
||||
nla_len(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
|
||||
|
||||
/* max len is validated in nla policy */
|
||||
if (params.he_capa_len < NL80211_HE_MIN_CAPABILITY_LEN)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
|
||||
params.opmode_notif_used = true;
|
||||
params.opmode_notif =
|
||||
|
@ -5352,6 +5445,10 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
|
|||
if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME))) {
|
||||
params.ht_capa = NULL;
|
||||
params.vht_capa = NULL;
|
||||
|
||||
/* HE requires WME */
|
||||
if (params.he_capa_len)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* When you run into this, adjust the code below for the new flag */
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*
|
||||
* Copyright 2007-2009 Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright 2017 Intel Deutschland GmbH
|
||||
*/
|
||||
#include <linux/export.h>
|
||||
#include <linux/bitops.h>
|
||||
|
@ -1142,6 +1143,85 @@ static u32 cfg80211_calculate_bitrate_vht(struct rate_info *rate)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static u32 cfg80211_calculate_bitrate_he(struct rate_info *rate)
|
||||
{
|
||||
#define SCALE 2048
|
||||
u16 mcs_divisors[12] = {
|
||||
34133, /* 16.666666... */
|
||||
17067, /* 8.333333... */
|
||||
11378, /* 5.555555... */
|
||||
8533, /* 4.166666... */
|
||||
5689, /* 2.777777... */
|
||||
4267, /* 2.083333... */
|
||||
3923, /* 1.851851... */
|
||||
3413, /* 1.666666... */
|
||||
2844, /* 1.388888... */
|
||||
2560, /* 1.250000... */
|
||||
2276, /* 1.111111... */
|
||||
2048, /* 1.000000... */
|
||||
};
|
||||
u32 rates_160M[3] = { 960777777, 907400000, 816666666 };
|
||||
u32 rates_969[3] = { 480388888, 453700000, 408333333 };
|
||||
u32 rates_484[3] = { 229411111, 216666666, 195000000 };
|
||||
u32 rates_242[3] = { 114711111, 108333333, 97500000 };
|
||||
u32 rates_106[3] = { 40000000, 37777777, 34000000 };
|
||||
u32 rates_52[3] = { 18820000, 17777777, 16000000 };
|
||||
u32 rates_26[3] = { 9411111, 8888888, 8000000 };
|
||||
u64 tmp;
|
||||
u32 result;
|
||||
|
||||
if (WARN_ON_ONCE(rate->mcs > 11))
|
||||
return 0;
|
||||
|
||||
if (WARN_ON_ONCE(rate->he_gi > NL80211_RATE_INFO_HE_GI_3_2))
|
||||
return 0;
|
||||
if (WARN_ON_ONCE(rate->he_ru_alloc >
|
||||
NL80211_RATE_INFO_HE_RU_ALLOC_2x996))
|
||||
return 0;
|
||||
if (WARN_ON_ONCE(rate->nss < 1 || rate->nss > 8))
|
||||
return 0;
|
||||
|
||||
if (rate->bw == RATE_INFO_BW_160)
|
||||
result = rates_160M[rate->he_gi];
|
||||
else if (rate->bw == RATE_INFO_BW_80 ||
|
||||
(rate->bw == RATE_INFO_BW_HE_RU &&
|
||||
rate->he_ru_alloc == NL80211_RATE_INFO_HE_RU_ALLOC_996))
|
||||
result = rates_969[rate->he_gi];
|
||||
else if (rate->bw == RATE_INFO_BW_40 ||
|
||||
(rate->bw == RATE_INFO_BW_HE_RU &&
|
||||
rate->he_ru_alloc == NL80211_RATE_INFO_HE_RU_ALLOC_484))
|
||||
result = rates_484[rate->he_gi];
|
||||
else if (rate->bw == RATE_INFO_BW_20 ||
|
||||
(rate->bw == RATE_INFO_BW_HE_RU &&
|
||||
rate->he_ru_alloc == NL80211_RATE_INFO_HE_RU_ALLOC_242))
|
||||
result = rates_242[rate->he_gi];
|
||||
else if (rate->bw == RATE_INFO_BW_HE_RU &&
|
||||
rate->he_ru_alloc == NL80211_RATE_INFO_HE_RU_ALLOC_106)
|
||||
result = rates_106[rate->he_gi];
|
||||
else if (rate->bw == RATE_INFO_BW_HE_RU &&
|
||||
rate->he_ru_alloc == NL80211_RATE_INFO_HE_RU_ALLOC_52)
|
||||
result = rates_52[rate->he_gi];
|
||||
else if (rate->bw == RATE_INFO_BW_HE_RU &&
|
||||
rate->he_ru_alloc == NL80211_RATE_INFO_HE_RU_ALLOC_26)
|
||||
result = rates_26[rate->he_gi];
|
||||
else if (WARN(1, "invalid HE MCS: bw:%d, ru:%d\n",
|
||||
rate->bw, rate->he_ru_alloc))
|
||||
return 0;
|
||||
|
||||
/* now scale to the appropriate MCS */
|
||||
tmp = result;
|
||||
tmp *= SCALE;
|
||||
do_div(tmp, mcs_divisors[rate->mcs]);
|
||||
result = tmp;
|
||||
|
||||
/* and take NSS, DCM into account */
|
||||
result = (result * rate->nss) / 8;
|
||||
if (rate->he_dcm)
|
||||
result /= 2;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
u32 cfg80211_calculate_bitrate(struct rate_info *rate)
|
||||
{
|
||||
if (rate->flags & RATE_INFO_FLAGS_MCS)
|
||||
|
@ -1150,6 +1230,8 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate)
|
|||
return cfg80211_calculate_bitrate_60g(rate);
|
||||
if (rate->flags & RATE_INFO_FLAGS_VHT_MCS)
|
||||
return cfg80211_calculate_bitrate_vht(rate);
|
||||
if (rate->flags & RATE_INFO_FLAGS_HE_MCS)
|
||||
return cfg80211_calculate_bitrate_he(rate);
|
||||
|
||||
return rate->legacy;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue