Commit da118544 authored by Johannes Berg's avatar Johannes Berg
Browse files

wifi: iwlwifi: mvm: fix EOF bit reporting



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: f1490546 ("wifi: iwlwifi: mvm: rxmq: refactor mac80211 rx_status setting")
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarGregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230305124407.e273aa0d3fdc.I77db4cc247898eae8a98b80659386d6737052b95@changeid


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent b55c1f4e
Loading
Loading
Loading
Loading
+10 −18
Original line number Diff line number Diff line
@@ -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,16 +1886,11 @@ 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) {
	    (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)
		iwl_mvm_decode_eht_phy_data(mvm, phy_data, rx_status, eht, usig);
@@ -2036,16 +2032,11 @@ 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) {
	    (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_HE_DELIM_EOF))
		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 &&
	    rate_n_flags & RATE_MCS_HE_106T_MSK) {
@@ -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;
	}