]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: iwlwifi: mvm: fix EOF bit reporting
authorJohannes Berg <johannes.berg@intel.com>
Sun, 5 Mar 2023 12:16:35 +0000 (14:16 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 7 Mar 2023 21:14:15 +0000 (22:14 +0100)
In monitor mode, we try to report the EOF bit on the
first MPDU of an A-MPDU (hardware duplicates this bit
over all MPDUs, so it's only trustable on the first).

However, due to reshuffling in an ealier commit, the
toggle_bit != mvm->ampdu_toggle logic can no longer
work since mvm->ampdu_toggle is now set before this
code runs.

Fix this by tracking the first_subframe status in the
phy data struct and using that instead of checking.

Fixes: f1490546bec9 ("wifi: iwlwifi: mvm: rxmq: refactor mac80211 rx_status setting")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230305124407.e273aa0d3fdc.I77db4cc247898eae8a98b80659386d6737052b95@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c

index 2ea1fbf81d3b661db93966f14ef50efc16f582cf..91556d43735a7cf7546d12e4e4d2e419e9988d9b 100644 (file)
@@ -1180,6 +1180,7 @@ struct iwl_mvm_rx_phy_data {
        __le32 d0, d1, d2, d3, eht_d4, d5;
        __le16 d4;
        bool with_data;
+       bool first_subframe;
        __le32 rx_vec[4];
 
        u32 rate_n_flags;
@@ -1885,15 +1886,10 @@ static void iwl_mvm_rx_eht(struct iwl_mvm *mvm, struct sk_buff *skb,
 
        /* 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)) {
-               bool toggle_bit = phy_info & IWL_RX_MPDU_PHY_AMPDU_TOGGLE;
-
-               /* toggle is switched whenever new aggregation starts */
-               if (toggle_bit != mvm->ampdu_toggle) {
-                       rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN;
-                       if (phy_data->d0 & cpu_to_le32(IWL_RX_PHY_DATA0_EHT_DELIM_EOF))
-                               rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT;
-               }
+           (phy_info & IWL_RX_MPDU_PHY_AMPDU) && phy_data->first_subframe) {
+               rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN;
+               if (phy_data->d0 & cpu_to_le32(IWL_RX_PHY_DATA0_EHT_DELIM_EOF))
+                       rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT;
        }
 
        if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD)
@@ -2036,15 +2032,10 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb,
 
        /* 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)) {
-               bool toggle_bit = phy_info & IWL_RX_MPDU_PHY_AMPDU_TOGGLE;
-
-               /* toggle is switched whenever new aggregation starts */
-               if (toggle_bit != mvm->ampdu_toggle) {
-                       rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN;
-                       if (phy_data->d0 & cpu_to_le32(IWL_RX_PHY_DATA0_HE_DELIM_EOF))
-                               rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT;
-               }
+           (phy_info & IWL_RX_MPDU_PHY_AMPDU) && phy_data->first_subframe) {
+               rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN;
+               if (phy_data->d0 & cpu_to_le32(IWL_RX_PHY_DATA0_EHT_DELIM_EOF))
+                       rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT;
        }
 
        if (he_type == RATE_MCS_HE_TYPE_EXT_SU &&
@@ -2447,6 +2438,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
                        if (mvm->ampdu_ref == 0)
                                mvm->ampdu_ref++;
                        mvm->ampdu_toggle = toggle_bit;
+                       phy_data.first_subframe = true;
                }
                rx_status->ampdu_reference = mvm->ampdu_ref;
        }