From 31fdae686b7a84c5e47e9ab298dfdbaec1ccaeb9 Mon Sep 17 00:00:00 2001 From: Eugene Syromiatnikov Date: Thu, 5 Sep 2019 18:45:30 +0200 Subject: [PATCH 14/43] Revert "iwlwifi: mvm: change PHY data RX for HE radiotap" This reverts commit bdf180c8d375ee75493d79ae384dd1f9686fc974. --- drivers/net/wireless/intel/iwlwifi/fw/api/rx.h | 190 +++++-------- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 367 +++++++++++++------------ 2 files changed, 261 insertions(+), 296 deletions(-) Index: src/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h =================================================================== --- src.orig/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h 2019-06-27 14:54:04.122678470 +0200 +++ src/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h 2019-09-06 01:25:42.865325621 +0200 @@ -343,98 +343,66 @@ IWL_RX_MPDU_PHY_PHY_INDEX_MASK = 0xf0, }; -/* TSF overload low dword */ -enum iwl_rx_phy_data0 { - /* info type: HE any */ - IWL_RX_PHY_DATA0_HE_BEAM_CHNG = 0x00000001, - IWL_RX_PHY_DATA0_HE_UPLINK = 0x00000002, - IWL_RX_PHY_DATA0_HE_BSS_COLOR_MASK = 0x000000fc, - IWL_RX_PHY_DATA0_HE_SPATIAL_REUSE_MASK = 0x00000f00, - /* 1 bit reserved */ - IWL_RX_PHY_DATA0_HE_TXOP_DUR_MASK = 0x000fe000, - IWL_RX_PHY_DATA0_HE_LDPC_EXT_SYM = 0x00100000, - IWL_RX_PHY_DATA0_HE_PRE_FEC_PAD_MASK = 0x00600000, - IWL_RX_PHY_DATA0_HE_PE_DISAMBIG = 0x00800000, - IWL_RX_PHY_DATA0_HE_DOPPLER = 0x01000000, +/* + * enum iwl_rx_he_phy - HE PHY data + */ +enum iwl_rx_he_phy { + IWL_RX_HE_PHY_BEAM_CHNG = BIT(0), + IWL_RX_HE_PHY_UPLINK = BIT(1), + IWL_RX_HE_PHY_BSS_COLOR_MASK = 0xfc, + IWL_RX_HE_PHY_SPATIAL_REUSE_MASK = 0xf00, + IWL_RX_HE_PHY_SU_EXT_BW10 = BIT(12), + IWL_RX_HE_PHY_TXOP_DUR_MASK = 0xfe000, + IWL_RX_HE_PHY_LDPC_EXT_SYM = BIT(20), + IWL_RX_HE_PHY_PRE_FEC_PAD_MASK = 0x600000, + IWL_RX_HE_PHY_PE_DISAMBIG = BIT(23), + IWL_RX_HE_PHY_DOPPLER = BIT(24), /* 6 bits reserved */ - IWL_RX_PHY_DATA0_HE_DELIM_EOF = 0x80000000, -}; - -enum iwl_rx_phy_info_type { - IWL_RX_PHY_INFO_TYPE_NONE = 0, - IWL_RX_PHY_INFO_TYPE_CCK = 1, - IWL_RX_PHY_INFO_TYPE_OFDM_LGCY = 2, - IWL_RX_PHY_INFO_TYPE_HT = 3, - IWL_RX_PHY_INFO_TYPE_VHT_SU = 4, - IWL_RX_PHY_INFO_TYPE_VHT_MU = 5, - IWL_RX_PHY_INFO_TYPE_HE_SU = 6, - IWL_RX_PHY_INFO_TYPE_HE_MU = 7, - IWL_RX_PHY_INFO_TYPE_HE_TB = 8, - IWL_RX_PHY_INFO_TYPE_HE_MU_EXT = 9, - IWL_RX_PHY_INFO_TYPE_HE_TB_EXT = 10, -}; + IWL_RX_HE_PHY_DELIM_EOF = BIT(31), -/* TSF overload high dword */ -enum iwl_rx_phy_data1 { - /* - * check this first - if TSF overload is set, - * see &enum iwl_rx_phy_info_type - */ - IWL_RX_PHY_DATA1_INFO_TYPE_MASK = 0xf0000000, - - /* info type: HT/VHT/HE any */ - IWL_RX_PHY_DATA1_LSIG_LEN_MASK = 0x0fff0000, - - /* info type: HE MU/MU-EXT */ - IWL_RX_PHY_DATA1_HE_MU_SIGB_COMPRESSION = 0x00000001, - IWL_RX_PHY_DATA1_HE_MU_SIBG_SYM_OR_USER_NUM_MASK = 0x0000001e, - - /* info type: HE any */ - IWL_RX_PHY_DATA1_HE_LTF_NUM_MASK = 0x000000e0, - IWL_RX_PHY_DATA1_HE_RU_ALLOC_SEC80 = 0x00000100, + /* second dword - common data */ + IWL_RX_HE_PHY_HE_LTF_NUM_MASK = 0xe000000000ULL, + IWL_RX_HE_PHY_RU_ALLOC_SEC80 = BIT_ULL(32 + 8), /* trigger encoded */ - IWL_RX_PHY_DATA1_HE_RU_ALLOC_MASK = 0x0000fe00, - - /* info type: HE TB/TX-EXT */ - IWL_RX_PHY_DATA1_HE_TB_PILOT_TYPE = 0x00000001, - IWL_RX_PHY_DATA1_HE_TB_LOW_SS_MASK = 0x0000000e, + IWL_RX_HE_PHY_RU_ALLOC_MASK = 0xfe0000000000ULL, + IWL_RX_HE_PHY_INFO_TYPE_MASK = 0xf000000000000000ULL, + IWL_RX_HE_PHY_INFO_TYPE_SU = 0x0, /* TSF low valid (first DW) */ + IWL_RX_HE_PHY_INFO_TYPE_MU = 0x1, /* TSF low/high valid (both DWs) */ + IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO = 0x2, /* same + SIGB-common0/1/2 valid */ + IWL_RX_HE_PHY_INFO_TYPE_TB = 0x3, /* TSF low/high valid (both DWs) */ + + /* second dword - MU data */ + IWL_RX_HE_PHY_MU_SIGB_COMPRESSION = BIT_ULL(32 + 0), + IWL_RX_HE_PHY_MU_SIBG_SYM_OR_USER_NUM_MASK = 0x1e00000000ULL, + IWL_RX_HE_PHY_MU_SIGB_MCS_MASK = 0xf000000000000ULL, + IWL_RX_HE_PHY_MU_SIGB_DCM = BIT_ULL(32 + 21), + IWL_RX_HE_PHY_MU_PREAMBLE_PUNC_TYPE_MASK = 0xc0000000000000ULL, + + /* second dword - TB data */ + IWL_RX_HE_PHY_TB_PILOT_TYPE = BIT_ULL(32 + 0), + IWL_RX_HE_PHY_TB_LOW_SS_MASK = 0xe00000000ULL }; -/* goes into Metadata DW 7 */ -enum iwl_rx_phy_data2 { - /* info type: HE MU-EXT */ +enum iwl_rx_he_sigb_common0 { /* the a1/a2/... is what the PHY/firmware calls the values */ - IWL_RX_PHY_DATA2_HE_MU_EXT_CH1_RU0 = 0x000000ff, /* a1 */ - IWL_RX_PHY_DATA2_HE_MU_EXT_CH1_RU2 = 0x0000ff00, /* a2 */ - IWL_RX_PHY_DATA2_HE_MU_EXT_CH2_RU0 = 0x00ff0000, /* b1 */ - IWL_RX_PHY_DATA2_HE_MU_EXT_CH2_RU2 = 0xff000000, /* b2 */ - - /* info type: HE TB-EXT */ - IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE1 = 0x0000000f, - IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE2 = 0x000000f0, - IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE3 = 0x00000f00, - IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE4 = 0x0000f000, + IWL_RX_HE_SIGB_COMMON0_CH1_RU0 = 0x000000ff, /* a1 */ + IWL_RX_HE_SIGB_COMMON0_CH1_RU2 = 0x0000ff00, /* a2 */ + IWL_RX_HE_SIGB_COMMON0_CH2_RU0 = 0x00ff0000, /* b1 */ + IWL_RX_HE_SIGB_COMMON0_CH2_RU2 = 0xff000000, /* b2 */ }; -/* goes into Metadata DW 8 */ -enum iwl_rx_phy_data3 { - /* info type: HE MU-EXT */ - IWL_RX_PHY_DATA3_HE_MU_EXT_CH1_RU1 = 0x000000ff, /* c1 */ - IWL_RX_PHY_DATA3_HE_MU_EXT_CH1_RU3 = 0x0000ff00, /* c2 */ - IWL_RX_PHY_DATA3_HE_MU_EXT_CH2_RU1 = 0x00ff0000, /* d1 */ - IWL_RX_PHY_DATA3_HE_MU_EXT_CH2_RU3 = 0xff000000, /* d2 */ +enum iwl_rx_he_sigb_common1 { + IWL_RX_HE_SIGB_COMMON1_CH1_RU1 = 0x000000ff, /* c1 */ + IWL_RX_HE_SIGB_COMMON1_CH1_RU3 = 0x0000ff00, /* c2 */ + IWL_RX_HE_SIGB_COMMON1_CH2_RU1 = 0x00ff0000, /* d1 */ + IWL_RX_HE_SIGB_COMMON1_CH2_RU3 = 0xff000000, /* d2 */ }; -/* goes into Metadata DW 4 high 16 bits */ -enum iwl_rx_phy_data4 { - /* info type: HE MU-EXT */ - IWL_RX_PHY_DATA4_HE_MU_EXT_CH1_CTR_RU = 0x0001, - IWL_RX_PHY_DATA4_HE_MU_EXT_CH2_CTR_RU = 0x0002, - IWL_RX_PHY_DATA4_HE_MU_EXT_CH1_CRC_OK = 0x0004, - IWL_RX_PHY_DATA4_HE_MU_EXT_CH2_CRC_OK = 0x0008, - IWL_RX_PHY_DATA4_HE_MU_EXT_SIGB_MCS_MASK = 0x00f0, - IWL_RX_PHY_DATA4_HE_MU_EXT_SIGB_DCM = 0x0100, - IWL_RX_PHY_DATA4_HE_MU_EXT_PREAMBLE_PUNC_TYPE_MASK = 0x0600, +enum iwl_rx_he_sigb_common2 { + IWL_RX_HE_SIGB_COMMON2_CH1_CTR_RU = 0x0001, + IWL_RX_HE_SIGB_COMMON2_CH2_CTR_RU = 0x0002, + IWL_RX_HE_SIGB_COMMON2_CH1_CRC_OK = 0x0004, + IWL_RX_HE_SIGB_COMMON2_CH2_CRC_OK = 0x0008, }; /** @@ -449,9 +417,9 @@ __le32 rss_hash; /** - * @phy_data2: depends on info type (see @phy_data1) + * @sigb_common0: for HE sniffer, HE-SIG-B common part 0 */ - __le32 phy_data2; + __le32 sigb_common0; }; /* DW8 - carries filter_match only when rpa_en == 1 */ @@ -462,9 +430,9 @@ __le32 filter_match; /** - * @phy_data3: depends on info type (see @phy_data1) + * @sigb_common1: for HE sniffer, HE-SIG-B common part 1 */ - __le32 phy_data3; + __le32 sigb_common1; }; /* DW9 */ @@ -502,19 +470,12 @@ * %IWL_RX_MPDU_PHY_TSF_OVERLOAD isn't set */ __le64 tsf_on_air_rise; - - struct { - /** - * @phy_data0: depends on info_type, see @phy_data1 - */ - __le32 phy_data0; - /** - * @phy_data1: valid only if - * %IWL_RX_MPDU_PHY_TSF_OVERLOAD is set, - * see &enum iwl_rx_phy_data1. - */ - __le32 phy_data1; - }; + /** + * @he_phy_data: + * HE PHY data, see &enum iwl_rx_he_phy, valid + * only if %IWL_RX_MPDU_PHY_TSF_OVERLOAD is set + */ + __le64 he_phy_data; }; } __packed; @@ -530,9 +491,9 @@ __le32 filter_match; /** - * @phy_data2: depends on info type (see @phy_data1) + * @sigb_common0: for HE sniffer, HE-SIG-B common part 0 */ - __le32 phy_data2; + __le32 sigb_common0; }; /* DW8 - carries rss_hash only when rpa_en == 1 */ @@ -543,9 +504,9 @@ __le32 rss_hash; /** - * @phy_data3: depends on info type (see @phy_data1) + * @sigb_common1: for HE sniffer, HE-SIG-B common part 1 */ - __le32 phy_data3; + __le32 sigb_common1; }; /* DW9 */ /** @@ -593,19 +554,12 @@ * %IWL_RX_MPDU_PHY_TSF_OVERLOAD isn't set */ __le64 tsf_on_air_rise; - - struct { - /** - * @phy_data0: depends on info_type, see @phy_data1 - */ - __le32 phy_data0; - /** - * @phy_data1: valid only if - * %IWL_RX_MPDU_PHY_TSF_OVERLOAD is set, - * see &enum iwl_rx_phy_data1. - */ - __le32 phy_data1; - }; + /** + * @he_phy_data: + * HE PHY data, see &enum iwl_rx_he_phy, valid + * only if %IWL_RX_MPDU_PHY_TSF_OVERLOAD is set + */ + __le64 he_phy_data; }; /* DW16 & DW17 */ /** @@ -657,9 +611,9 @@ __le16 l3l4_flags; /** - * @phy_data4: depends on info type, see phy_data1 + * @sigb_common2: for HE sniffer, HE-SIG-B common part 2 */ - __le16 phy_data4; + __le16 sigb_common2; }; /* DW5 */ /** Index: src/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c =================================================================== --- src.orig/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c 2019-09-06 01:25:42.700327726 +0200 +++ src/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c 2019-09-06 01:25:42.865325621 +0200 @@ -903,65 +903,68 @@ ether_addr_copy(addr, mac_addr); } -struct iwl_mvm_rx_phy_data { - __le32 d0, d1, d2, d3; - __le16 d4; -}; - -static void iwl_mvm_decode_he_mu_ext(struct iwl_mvm *mvm, - struct iwl_mvm_rx_phy_data *phy_data, - u32 rate_n_flags, - struct ieee80211_radiotap_he_mu *he_mu) +static void iwl_mvm_decode_he_sigb(struct iwl_mvm *mvm, + struct iwl_rx_mpdu_desc *desc, + u32 rate_n_flags, + struct ieee80211_radiotap_he_mu *he_mu) { - u32 phy_data2 = le32_to_cpu(phy_data->d2); - u32 phy_data3 = le32_to_cpu(phy_data->d3); - u16 phy_data4 = le16_to_cpu(phy_data->d4); + u32 sigb0, sigb1; + u16 sigb2; - if (FIELD_GET(IWL_RX_PHY_DATA4_HE_MU_EXT_CH1_CRC_OK, phy_data4)) { + if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) { + sigb0 = le32_to_cpu(desc->v3.sigb_common0); + sigb1 = le32_to_cpu(desc->v3.sigb_common1); + } else { + sigb0 = le32_to_cpu(desc->v1.sigb_common0); + sigb1 = le32_to_cpu(desc->v1.sigb_common1); + } + + sigb2 = le16_to_cpu(desc->sigb_common2); + + if (FIELD_GET(IWL_RX_HE_SIGB_COMMON2_CH1_CRC_OK, sigb2)) { he_mu->flags1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_RU_KNOWN | IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_CTR_26T_RU_KNOWN); he_mu->flags1 |= - le16_encode_bits(FIELD_GET(IWL_RX_PHY_DATA4_HE_MU_EXT_CH1_CTR_RU, - phy_data4), + le16_encode_bits(FIELD_GET(IWL_RX_HE_SIGB_COMMON2_CH1_CTR_RU, + sigb2), IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_CTR_26T_RU); - he_mu->ru_ch1[0] = FIELD_GET(IWL_RX_PHY_DATA2_HE_MU_EXT_CH1_RU0, - phy_data2); - he_mu->ru_ch1[1] = FIELD_GET(IWL_RX_PHY_DATA3_HE_MU_EXT_CH1_RU1, - phy_data3); - he_mu->ru_ch1[2] = FIELD_GET(IWL_RX_PHY_DATA2_HE_MU_EXT_CH1_RU2, - phy_data2); - he_mu->ru_ch1[3] = FIELD_GET(IWL_RX_PHY_DATA3_HE_MU_EXT_CH1_RU3, - phy_data3); + he_mu->ru_ch1[0] = FIELD_GET(IWL_RX_HE_SIGB_COMMON0_CH1_RU0, + sigb0); + he_mu->ru_ch1[1] = FIELD_GET(IWL_RX_HE_SIGB_COMMON1_CH1_RU1, + sigb1); + he_mu->ru_ch1[2] = FIELD_GET(IWL_RX_HE_SIGB_COMMON0_CH1_RU2, + sigb0); + he_mu->ru_ch1[3] = FIELD_GET(IWL_RX_HE_SIGB_COMMON1_CH1_RU3, + sigb1); } - if (FIELD_GET(IWL_RX_PHY_DATA4_HE_MU_EXT_CH2_CRC_OK, phy_data4) && + if (FIELD_GET(IWL_RX_HE_SIGB_COMMON2_CH2_CRC_OK, sigb2) && (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) != RATE_MCS_CHAN_WIDTH_20) { he_mu->flags1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_RU_KNOWN | IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_CTR_26T_RU_KNOWN); he_mu->flags2 |= - le16_encode_bits(FIELD_GET(IWL_RX_PHY_DATA4_HE_MU_EXT_CH2_CTR_RU, - phy_data4), + le16_encode_bits(FIELD_GET(IWL_RX_HE_SIGB_COMMON2_CH2_CTR_RU, + sigb2), IEEE80211_RADIOTAP_HE_MU_FLAGS2_CH2_CTR_26T_RU); - he_mu->ru_ch2[0] = FIELD_GET(IWL_RX_PHY_DATA2_HE_MU_EXT_CH2_RU0, - phy_data2); - he_mu->ru_ch2[1] = FIELD_GET(IWL_RX_PHY_DATA3_HE_MU_EXT_CH2_RU1, - phy_data3); - he_mu->ru_ch2[2] = FIELD_GET(IWL_RX_PHY_DATA2_HE_MU_EXT_CH2_RU2, - phy_data2); - he_mu->ru_ch2[3] = FIELD_GET(IWL_RX_PHY_DATA3_HE_MU_EXT_CH2_RU3, - phy_data3); + he_mu->ru_ch2[0] = FIELD_GET(IWL_RX_HE_SIGB_COMMON0_CH2_RU0, + sigb0); + he_mu->ru_ch2[1] = FIELD_GET(IWL_RX_HE_SIGB_COMMON1_CH2_RU1, + sigb1); + he_mu->ru_ch2[2] = FIELD_GET(IWL_RX_HE_SIGB_COMMON0_CH2_RU2, + sigb0); + he_mu->ru_ch2[3] = FIELD_GET(IWL_RX_HE_SIGB_COMMON1_CH2_RU3, + sigb1); } } static void -iwl_mvm_decode_he_phy_ru_alloc(struct iwl_mvm_rx_phy_data *phy_data, - u32 rate_n_flags, +iwl_mvm_decode_he_phy_ru_alloc(u64 he_phy_data, u32 rate_n_flags, struct ieee80211_radiotap_he *he, struct ieee80211_radiotap_he_mu *he_mu, struct ieee80211_rx_status *rx_status) @@ -974,7 +977,7 @@ * happen though as management frames where we need * the TSF/timers are not be transmitted in HE-MU. */ - u8 ru = le32_get_bits(phy_data->d1, IWL_RX_PHY_DATA1_HE_RU_ALLOC_MASK); + u8 ru = FIELD_GET(IWL_RX_HE_PHY_RU_ALLOC_MASK, he_phy_data); u8 offs = 0; rx_status->bw = RATE_INFO_BW_HE_RU; @@ -1013,7 +1016,7 @@ IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET); he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_KNOWN | IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET_KNOWN); - if (phy_data->d1 & cpu_to_le32(IWL_RX_PHY_DATA1_HE_RU_ALLOC_SEC80)) + if (he_phy_data & IWL_RX_HE_PHY_RU_ALLOC_SEC80) he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_SEC); @@ -1033,124 +1036,105 @@ } static void iwl_mvm_decode_he_phy_data(struct iwl_mvm *mvm, - struct iwl_mvm_rx_phy_data *phy_data, + struct iwl_rx_mpdu_desc *desc, struct ieee80211_radiotap_he *he, struct ieee80211_radiotap_he_mu *he_mu, struct ieee80211_rx_status *rx_status, - u32 rate_n_flags, int queue) + u64 he_phy_data, u32 rate_n_flags, + int queue) { - enum iwl_rx_phy_info_type info_type; - - info_type = le32_get_bits(phy_data->d1, IWL_RX_PHY_DATA1_INFO_TYPE_MASK); - - switch (info_type) { - case IWL_RX_PHY_INFO_TYPE_NONE: - case IWL_RX_PHY_INFO_TYPE_CCK: - case IWL_RX_PHY_INFO_TYPE_OFDM_LGCY: - return; - case IWL_RX_PHY_INFO_TYPE_HT: - case IWL_RX_PHY_INFO_TYPE_VHT_SU: - case IWL_RX_PHY_INFO_TYPE_VHT_MU: - /* TODO: we have LSIG-LEN, where do we put it? */ - return; - case IWL_RX_PHY_INFO_TYPE_HE_TB_EXT: - he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN | - IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE2_KNOWN | - IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE3_KNOWN | - IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE4_KNOWN); - he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0, - IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE1), - IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE1); - he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0, - IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE2), - IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE2); - he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0, - IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE3), - IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE3); - he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0, - IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE4), - IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE4); - /* fall through */ - case IWL_RX_PHY_INFO_TYPE_HE_SU: - case IWL_RX_PHY_INFO_TYPE_HE_MU: - case IWL_RX_PHY_INFO_TYPE_HE_MU_EXT: - case IWL_RX_PHY_INFO_TYPE_HE_TB: - /* HE common */ - he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN | - IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN | - IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN | - IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN | - IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN); - he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN | - IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN | - IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN | - IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN); - he->data3 |= le16_encode_bits(le32_get_bits(phy_data->d0, - IWL_RX_PHY_DATA0_HE_BSS_COLOR_MASK), - IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR); - he->data3 |= le16_encode_bits(le32_get_bits(phy_data->d0, - IWL_RX_PHY_DATA0_HE_UPLINK), - IEEE80211_RADIOTAP_HE_DATA3_UL_DL); - he->data3 |= le16_encode_bits(le32_get_bits(phy_data->d0, - IWL_RX_PHY_DATA0_HE_LDPC_EXT_SYM), - IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG); - he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0, - IWL_RX_PHY_DATA0_HE_SPATIAL_REUSE_MASK), - IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE); - he->data5 |= le16_encode_bits(le32_get_bits(phy_data->d0, - IWL_RX_PHY_DATA0_HE_PRE_FEC_PAD_MASK), - IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD); - he->data5 |= le16_encode_bits(le32_get_bits(phy_data->d0, - IWL_RX_PHY_DATA0_HE_PE_DISAMBIG), - IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG); - he->data5 |= le16_encode_bits(le32_get_bits(phy_data->d1, - IWL_RX_PHY_DATA1_HE_LTF_NUM_MASK), - IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS); - he->data6 |= le16_encode_bits(le32_get_bits(phy_data->d0, - IWL_RX_PHY_DATA0_HE_TXOP_DUR_MASK), - IEEE80211_RADIOTAP_HE_DATA6_TXOP); - he->data6 |= le16_encode_bits(le32_get_bits(phy_data->d0, - IWL_RX_PHY_DATA0_HE_DOPPLER), - IEEE80211_RADIOTAP_HE_DATA6_DOPPLER); - break; - } + u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK; + bool sigb_data; + u16 d1known = IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN | + IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN | + IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN | + IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN | + IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN; + u16 d2known = IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN | + IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN | + IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN; + + he->data1 |= cpu_to_le16(d1known); + he->data2 |= cpu_to_le16(d2known); + he->data3 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_BSS_COLOR_MASK, + he_phy_data), + IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR); + he->data3 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_UPLINK, + he_phy_data), + IEEE80211_RADIOTAP_HE_DATA3_UL_DL); + he->data3 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_LDPC_EXT_SYM, + he_phy_data), + IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG); + he->data4 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SPATIAL_REUSE_MASK, + he_phy_data), + IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE); + he->data5 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_PRE_FEC_PAD_MASK, + he_phy_data), + IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD); + he->data5 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_PE_DISAMBIG, + he_phy_data), + IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG); + he->data6 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_TXOP_DUR_MASK, + he_phy_data), + IEEE80211_RADIOTAP_HE_DATA6_TXOP); + he->data6 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_DOPPLER, + he_phy_data), + IEEE80211_RADIOTAP_HE_DATA6_DOPPLER); - switch (info_type) { - case IWL_RX_PHY_INFO_TYPE_HE_MU_EXT: + switch (he_type) { + case RATE_MCS_HE_TYPE_MU: he_mu->flags1 |= - le16_encode_bits(le16_get_bits(phy_data->d4, - IWL_RX_PHY_DATA4_HE_MU_EXT_SIGB_DCM), + le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIGB_DCM, + he_phy_data), IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM); he_mu->flags1 |= - le16_encode_bits(le16_get_bits(phy_data->d4, - IWL_RX_PHY_DATA4_HE_MU_EXT_SIGB_MCS_MASK), + le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIGB_MCS_MASK, + he_phy_data), IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS); he_mu->flags2 |= - le16_encode_bits(le16_get_bits(phy_data->d4, - IWL_RX_PHY_DATA4_HE_MU_EXT_PREAMBLE_PUNC_TYPE_MASK), - IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW); - iwl_mvm_decode_he_mu_ext(mvm, phy_data, rate_n_flags, he_mu); - /* fall through */ - case IWL_RX_PHY_INFO_TYPE_HE_MU: + le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIBG_SYM_OR_USER_NUM_MASK, + he_phy_data), + IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS); he_mu->flags2 |= - le16_encode_bits(le32_get_bits(phy_data->d1, - IWL_RX_PHY_DATA1_HE_MU_SIBG_SYM_OR_USER_NUM_MASK), - IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS); - he_mu->flags2 |= - le16_encode_bits(le32_get_bits(phy_data->d1, - IWL_RX_PHY_DATA1_HE_MU_SIGB_COMPRESSION), + le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIGB_COMPRESSION, + he_phy_data), IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP); + he_mu->flags2 |= + le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_PREAMBLE_PUNC_TYPE_MASK, + he_phy_data), + IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW); + + sigb_data = FIELD_GET(IWL_RX_HE_PHY_INFO_TYPE_MASK, + he_phy_data) == + IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO; + if (sigb_data) + iwl_mvm_decode_he_sigb(mvm, desc, rate_n_flags, he_mu); /* fall through */ - case IWL_RX_PHY_INFO_TYPE_HE_TB: - case IWL_RX_PHY_INFO_TYPE_HE_TB_EXT: - iwl_mvm_decode_he_phy_ru_alloc(phy_data, rate_n_flags, - he, he_mu, rx_status); + case RATE_MCS_HE_TYPE_TRIG: + he->data2 |= + cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN); + he->data5 |= + le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_HE_LTF_NUM_MASK, + he_phy_data), + IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS); + break; + case RATE_MCS_HE_TYPE_SU: + case RATE_MCS_HE_TYPE_EXT_SU: + he->data1 |= + cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BEAM_CHANGE_KNOWN); + he->data3 |= + le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_BEAM_CHNG, + he_phy_data), + IEEE80211_RADIOTAP_HE_DATA3_BEAM_CHANGE); break; - case IWL_RX_PHY_INFO_TYPE_HE_SU: - he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BEAM_CHANGE_KNOWN); - he->data3 |= le16_encode_bits(le32_get_bits(phy_data->d0, - IWL_RX_PHY_DATA0_HE_BEAM_CHNG), - IEEE80211_RADIOTAP_HE_DATA3_BEAM_CHANGE); + } + + switch (FIELD_GET(IWL_RX_HE_PHY_INFO_TYPE_MASK, he_phy_data)) { + case IWL_RX_HE_PHY_INFO_TYPE_MU: + case IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO: + case IWL_RX_HE_PHY_INFO_TYPE_TB: + iwl_mvm_decode_he_phy_ru_alloc(he_phy_data, rate_n_flags, + he, he_mu, rx_status); break; default: /* nothing */ @@ -1163,6 +1147,9 @@ u32 rate_n_flags, u16 phy_info, int queue) { struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); + /* this is invalid e.g. because puncture type doesn't allow 0b11 */ +#define HE_PHY_DATA_INVAL ((u64)-1) + u64 he_phy_data = HE_PHY_DATA_INVAL; struct ieee80211_radiotap_he *he = NULL; struct ieee80211_radiotap_he_mu *he_mu = NULL; u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK; @@ -1184,66 +1171,54 @@ IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN), }; unsigned int radiotap_len = 0; - struct iwl_mvm_rx_phy_data phy_data = { - .d4 = desc->phy_data4, - }; - enum iwl_rx_phy_info_type info_type = IWL_RX_PHY_INFO_TYPE_NONE; - - if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) { - phy_data.d0 = desc->v3.phy_data0; - phy_data.d1 = desc->v3.phy_data1; - phy_data.d2 = desc->v3.phy_data2; - phy_data.d3 = desc->v3.phy_data3; - } else { - phy_data.d0 = desc->v1.phy_data0; - phy_data.d1 = desc->v1.phy_data1; - phy_data.d2 = desc->v1.phy_data2; - phy_data.d3 = desc->v1.phy_data3; - } - - if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) - info_type = le32_get_bits(phy_data.d1, - IWL_RX_PHY_DATA1_INFO_TYPE_MASK); he = skb_put_data(skb, &known, sizeof(known)); radiotap_len += sizeof(known); rx_status->flag |= RX_FLAG_RADIOTAP_HE; - if (info_type == IWL_RX_PHY_INFO_TYPE_HE_MU || - info_type == IWL_RX_PHY_INFO_TYPE_HE_MU_EXT) { - he_mu = skb_put_data(skb, &mu_known, sizeof(mu_known)); - radiotap_len += sizeof(mu_known); - rx_status->flag |= RX_FLAG_RADIOTAP_HE_MU; + if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) { + if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) + he_phy_data = le64_to_cpu(desc->v3.he_phy_data); + else + he_phy_data = le64_to_cpu(desc->v1.he_phy_data); + + if (he_type == RATE_MCS_HE_TYPE_MU) { + he_mu = skb_put_data(skb, &mu_known, sizeof(mu_known)); + radiotap_len += sizeof(mu_known); + rx_status->flag |= RX_FLAG_RADIOTAP_HE_MU; + } } /* temporarily hide the radiotap data */ __skb_pull(skb, radiotap_len); - if (info_type == IWL_RX_PHY_INFO_TYPE_HE_SU) { + if (he_phy_data != HE_PHY_DATA_INVAL && + he_type == RATE_MCS_HE_TYPE_SU) { /* report the AMPDU-EOF bit on single frames */ if (!queue && !(phy_info & IWL_RX_MPDU_PHY_AMPDU)) { rx_status->flag |= RX_FLAG_AMPDU_DETAILS; rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN; - if (phy_data.d0 & cpu_to_le32(IWL_RX_PHY_DATA0_HE_DELIM_EOF)) + if (FIELD_GET(IWL_RX_HE_PHY_DELIM_EOF, he_phy_data)) rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT; } } - if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) - iwl_mvm_decode_he_phy_data(mvm, &phy_data, he, he_mu, rx_status, - rate_n_flags, queue); + if (he_phy_data != HE_PHY_DATA_INVAL) + iwl_mvm_decode_he_phy_data(mvm, desc, he, he_mu, rx_status, + he_phy_data, rate_n_flags, queue); /* update aggregation data for monitor sake on default queue */ - if (!queue && (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) && - (phy_info & IWL_RX_MPDU_PHY_AMPDU)) { + if (!queue && (phy_info & IWL_RX_MPDU_PHY_AMPDU)) { bool toggle_bit = phy_info & IWL_RX_MPDU_PHY_AMPDU_TOGGLE; /* toggle is switched whenever new aggregation starts */ if (toggle_bit != mvm->ampdu_toggle && + he_phy_data != HE_PHY_DATA_INVAL && (he_type == RATE_MCS_HE_TYPE_MU || he_type == RATE_MCS_HE_TYPE_SU)) { rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN; - if (phy_data.d0 & cpu_to_le32(IWL_RX_PHY_DATA0_HE_DELIM_EOF)) + if (FIELD_GET(IWL_RX_HE_PHY_DELIM_EOF, + he_phy_data)) rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT; } } @@ -1326,8 +1301,44 @@ break; } - he->data5 |= le16_encode_bits(ltf, - IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE); + he->data5 |= le16_encode_bits(ltf, IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE); + + if (he_type == RATE_MCS_HE_TYPE_SU || + he_type == RATE_MCS_HE_TYPE_EXT_SU) { + u16 val; + + /* LTF syms correspond to streams */ + he->data2 |= + cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN); + switch (rx_status->nss) { + case 1: + val = 0; + break; + case 2: + val = 1; + break; + case 3: + case 4: + val = 2; + break; + case 5: + case 6: + val = 3; + break; + case 7: + case 8: + val = 4; + break; + default: + WARN_ONCE(1, "invalid nss: %d\n", + rx_status->nss); + val = 0; + } + + he->data5 |= + le16_encode_bits(val, + IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS); + } } void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,