Commit 764f9de5 authored by Johannes Berg's avatar Johannes Berg Committed by Luca Coelho

iwlwifi: mvm: decode HE TB PPDU data

Decode the HE TB PPDU data that we get in sniffer mode
and use it to populate the HE radiotap information.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent 423584dd
...@@ -362,22 +362,27 @@ enum iwl_rx_he_phy { ...@@ -362,22 +362,27 @@ enum iwl_rx_he_phy {
/* 6 bits reserved */ /* 6 bits reserved */
IWL_RX_HE_PHY_DELIM_EOF = BIT(31), IWL_RX_HE_PHY_DELIM_EOF = BIT(31),
/* second dword - MU data */ /* second dword - common data */
IWL_RX_HE_PHY_SIGB_COMPRESSION = BIT_ULL(32 + 0),
IWL_RX_HE_PHY_SIBG_SYM_OR_USER_NUM_MASK = 0x1e00000000ULL,
IWL_RX_HE_PHY_HE_LTF_NUM_MASK = 0xe000000000ULL, IWL_RX_HE_PHY_HE_LTF_NUM_MASK = 0xe000000000ULL,
IWL_RX_HE_PHY_RU_ALLOC_SEC80 = BIT_ULL(32 + 8), IWL_RX_HE_PHY_RU_ALLOC_SEC80 = BIT_ULL(32 + 8),
/* trigger encoded */ /* trigger encoded */
IWL_RX_HE_PHY_RU_ALLOC_MASK = 0xfe0000000000ULL, IWL_RX_HE_PHY_RU_ALLOC_MASK = 0xfe0000000000ULL,
IWL_RX_HE_PHY_SIGB_MCS_MASK = 0xf000000000000ULL,
/* 1 bit reserved */
IWL_RX_HE_PHY_SIGB_DCM = BIT_ULL(32 + 21),
IWL_RX_HE_PHY_PREAMBLE_PUNC_TYPE_MASK = 0xc0000000000000ULL,
/* 4 bits reserved */
IWL_RX_HE_PHY_INFO_TYPE_MASK = 0xf000000000000000ULL, IWL_RX_HE_PHY_INFO_TYPE_MASK = 0xf000000000000000ULL,
IWL_RX_HE_PHY_INFO_TYPE_SU = 0x0, IWL_RX_HE_PHY_INFO_TYPE_SU = 0x0,
IWL_RX_HE_PHY_INFO_TYPE_MU = 0x1, IWL_RX_HE_PHY_INFO_TYPE_MU = 0x1,
IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO = 0x2, IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO = 0x2,
IWL_RX_HE_PHY_INFO_TYPE_TB_EXT_INFO = 0x3,
/* 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
}; };
enum iwl_rx_he_sigb_common0 { enum iwl_rx_he_sigb_common0 {
......
...@@ -988,23 +988,23 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, ...@@ -988,23 +988,23 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb,
} }
} else if (overload && he_mu && he_phy_data != HE_PHY_DATA_INVAL) { } else if (overload && he_mu && he_phy_data != HE_PHY_DATA_INVAL) {
he_mu->flags1 |= he_mu->flags1 |=
le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIBG_SYM_OR_USER_NUM_MASK, le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIBG_SYM_OR_USER_NUM_MASK,
he_phy_data), he_phy_data),
IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS); IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS);
he_mu->flags1 |= he_mu->flags1 |=
le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIGB_DCM, le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIGB_DCM,
he_phy_data), he_phy_data),
IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM); IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM);
he_mu->flags1 |= he_mu->flags1 |=
le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIGB_MCS_MASK, le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIGB_MCS_MASK,
he_phy_data), he_phy_data),
IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS); IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS);
he_mu->flags2 |= he_mu->flags2 |=
le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIGB_COMPRESSION, le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIGB_COMPRESSION,
he_phy_data), he_phy_data),
IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP); IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP);
he_mu->flags2 |= he_mu->flags2 |=
le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_PREAMBLE_PUNC_TYPE_MASK, le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_PREAMBLE_PUNC_TYPE_MASK,
he_phy_data), he_phy_data),
IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW); IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW);
...@@ -1049,15 +1049,18 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, ...@@ -1049,15 +1049,18 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb,
rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106; rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106;
} }
if (he_mu) { if (he_phy_data != HE_PHY_DATA_INVAL &&
(FIELD_GET(IWL_RX_HE_PHY_INFO_TYPE_MASK, he_phy_data) ==
IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO ||
FIELD_GET(IWL_RX_HE_PHY_INFO_TYPE_MASK, he_phy_data) ==
IWL_RX_HE_PHY_INFO_TYPE_TB_EXT_INFO)) {
/* /*
* Unfortunately, we have to leave the mac80211 data * Unfortunately, we have to leave the mac80211 data
* incorrect for the case that we receive an HE-MU * incorrect for the case that we receive an HE-MU
* transmission and *don't* have the he_mu pointer, * transmission and *don't* have the HE phy data (due
* i.e. we don't have the phy data (due to the bits * to the bits being used for TSF). This shouldn't
* being used for TSF). This shouldn't happen though * happen though as management frames where we need
* as management frames where we need the TSF/timers * the TSF/timers are not be transmitted in HE-MU.
* are not be transmitted in HE-MU, I think.
*/ */
u8 ru = FIELD_GET(IWL_RX_HE_PHY_RU_ALLOC_MASK, he_phy_data); u8 ru = FIELD_GET(IWL_RX_HE_PHY_RU_ALLOC_MASK, he_phy_data);
u8 offs = 0; u8 offs = 0;
...@@ -1100,10 +1103,11 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, ...@@ -1100,10 +1103,11 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb,
IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET); IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET);
he->data2 |= he->data2 |=
cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_KNOWN); cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_KNOWN);
if (he_phy_data & IWL_RX_HE_PHY_RU_ALLOC_SEC80) { if (he_phy_data & IWL_RX_HE_PHY_RU_ALLOC_SEC80)
he->data2 |= he->data2 |=
cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_SEC); cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_SEC);
if (he_mu) {
#define CHECK_BW(bw) \ #define CHECK_BW(bw) \
BUILD_BUG_ON(IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_ ## bw ## MHZ != \ BUILD_BUG_ON(IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_ ## bw ## MHZ != \
RATE_MCS_CHAN_WIDTH_##bw >> RATE_MCS_CHAN_WIDTH_POS) RATE_MCS_CHAN_WIDTH_##bw >> RATE_MCS_CHAN_WIDTH_POS)
...@@ -1111,7 +1115,7 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, ...@@ -1111,7 +1115,7 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb,
CHECK_BW(40); CHECK_BW(40);
CHECK_BW(80); CHECK_BW(80);
CHECK_BW(160); CHECK_BW(160);
he_mu->flags2 |= he->data2 |=
le16_encode_bits(FIELD_GET(RATE_MCS_CHAN_WIDTH_MSK, le16_encode_bits(FIELD_GET(RATE_MCS_CHAN_WIDTH_MSK,
rate_n_flags), rate_n_flags),
IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW); IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment