From: Mordechay Goodstein <mordechay.goodstein@xxxxxxxxx> We calculate based on chandef the place of the control channel inside the wide band, this is used for understanding the N value in 11be D.5 table 9-53a for column PHY MU/MRU index. To avoid the need to calculate every frame the value, do it once monitor vif is added. Signed-off-by: Mordechay Goodstein <mordechay.goodstein@xxxxxxxxx> Signed-off-by: Gregory Greenman <gregory.greenman@xxxxxxxxx> --- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 26 ++++++++++++++++++- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 ++ drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 6 +++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 565522466eba..c9911750d8af 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1362,6 +1362,28 @@ static void iwl_mvm_channel_switch_disconnect_wk(struct work_struct *wk) ieee80211_chswitch_done(vif, false); } +static u8 +iwl_mvm_chandef_get_primary_80(struct cfg80211_chan_def *chandef) +{ + int data_start; + int control_start; + int bw; + + if (chandef->width == NL80211_CHAN_WIDTH_320) + bw = 320; + else if (chandef->width == NL80211_CHAN_WIDTH_160) + bw = 160; + else + return 0; + + /* data is bw wide so the start is half the width */ + data_start = chandef->center_freq1 - bw / 2; + /* control is 20Mhz width */ + control_start = chandef->chan->center_freq - 10; + + return (control_start - data_start) / 80; +} + static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { @@ -1478,8 +1500,10 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, INIT_DELAYED_WORK(&mvmvif->csa_work, iwl_mvm_channel_switch_disconnect_wk); - if (vif->type == NL80211_IFTYPE_MONITOR) + if (vif->type == NL80211_IFTYPE_MONITOR) { mvm->monitor_on = true; + mvm->monitor_p80 = iwl_mvm_chandef_get_primary_80(&vif->bss_conf.chandef); + } iwl_mvm_vif_dbgfs_register(mvm, vif); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index ce6b701f3f4c..6862896c561e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1096,6 +1096,8 @@ struct iwl_mvm { /* does a monitor vif exist (only one can exist hence bool) */ bool monitor_on; + /* primary channel place relative the whole bandwidth in gaps of 80Mhz */ + u8 monitor_p80; /* sniffer data to include in radiotap */ __le16 cur_aid; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index c8b4d751f5f0..d866fa534be5 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -1694,6 +1694,12 @@ static void iwl_mvm_decode_eht_phy_data(struct iwl_mvm *mvm, iwl_mvm_decode_eht_ru(mvm, rx_status, eht); + /* We only get here in case of IWL_RX_MPDU_PHY_TSF_OVERLOAD is set + * which is on only in case of monitor mode so no need to check monitor mode */ + eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_PRIMARY_80); + eht->data[1] |= le32_encode_bits(mvm->monitor_p80, + IEEE80211_RADIOTAP_EHT_DATA1_PRIMARY_80); + usig->common |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP_KNOWN); if (phy_data->with_data) usig->common |= LE32_DEC_ENC(data0, IWL_RX_PHY_DATA0_EHT_TXOP_DUR_MASK, -- 2.38.1