From: Emmanuel Grumbach iwl_mvm_rx_rx_mpdu() and iwl_mvm_rx_handle_tcm() parse the rate_n_flags they get from struct iwl_rx_phy_info, which is in the version 1 format. There, the number of spatial streams minus one is encoded in bits 4-5, i.e. RATE_VHT_MCS_NSS_MSK, but both of them used RATE_MCS_NSS_MSK. This used to work by accident: RATE_MCS_NSS_MSK was BIT(4), which overlaps the low bit of the version 1 field, and that is enough for our 2x2 devices. Since the version 3 rate format was introduced, RATE_MCS_NSS_MSK is BIT(5), which is always 0 in a version 1 rate, so every received VHT frame is now reported as single stream. On an 8260 this shows up as half the actual rate being reported: rx bitrate: 390.0 MBit/s VHT-MCS 8 80MHz short GI VHT-NSS 1 instead of 780.0 MBit/s with VHT-NSS 2. Devices using the multi-queue RX path are not affected, they convert the rate to the version 3 format before parsing it. Fixes: 3592c0083fb2 ("wifi: iwlwifi: mvm: fix beacon template/fixed rate") Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221685 Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Emmanuel Grumbach Reviewed-by: Johannes Berg Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/mvm/rx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c index ab1eb2eb0c3c..59dbbdd4aa35 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c @@ -257,7 +257,7 @@ static void iwl_mvm_rx_handle_tcm(struct iwl_mvm *mvm, ARRAY_SIZE(thresh_tpt))) return; thr = thresh_tpt[rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK]; - thr *= 1 + FIELD_GET(RATE_MCS_NSS_MSK, rate_n_flags); + thr *= 1 + FIELD_GET(RATE_VHT_MCS_NSS_MSK, rate_n_flags); } thr <<= ((rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK_V1) >> @@ -502,7 +502,7 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi, u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >> RATE_MCS_STBC_POS; rx_status->nss = - FIELD_GET(RATE_MCS_NSS_MSK, rate_n_flags) + 1; + FIELD_GET(RATE_VHT_MCS_NSS_MSK, rate_n_flags) + 1; rx_status->rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK; rx_status->encoding = RX_ENC_VHT; rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; -- 2.34.1