linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Luca Coelho <luca@coelho.fi>
To: kvalo@codeaurora.org
Cc: linux-wireless@vger.kernel.org
Subject: [PATCH 12/21] iwlwifi: mvm: drop BA sessions on too many old-SN frames
Date: Tue,  3 Sep 2019 10:37:05 +0300	[thread overview]
Message-ID: <20190903073714.32278-13-luca@coelho.fi> (raw)
In-Reply-To: <20190903073714.32278-1-luca@coelho.fi>

From: Johannes Berg <johannes.berg@intel.com>

Certain APs (I think a certain Broadcom model) interact badly with our
full state BA bitmap handling, and if triggered badly with many powersave
transitions they keep sending frames from before the window, which our
hardware then doesn't appear to ACK (to them) since it has moved on and
is sending ACKs for higher SNs now.

Try to detect this situation and if this keeps happening, disable the
aggregation session.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 .../wireless/intel/iwlwifi/mvm/constants.h    |  1 +
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  |  9 ++++
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 53 +++++++++++++++++++
 3 files changed, 63 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h
index 915b172da57a..60aff2ecec12 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h
@@ -153,5 +153,6 @@
 #define IWL_MVM_FTM_INITIATOR_DYNACK		true
 #define IWL_MVM_D3_DEBUG			false
 #define IWL_MVM_USE_TWT				false
+#define IWL_MVM_AMPDU_CONSEC_DROPS_DELBA	10
 
 #endif /* __MVM_CONSTANTS_H */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 2540d7ffbbc1..b8a8369457b9 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -661,6 +661,12 @@ struct iwl_mvm_tcm {
  * @valid: reordering is valid for this queue
  * @lock: protect reorder buffer internal state
  * @mvm: mvm pointer, needed for frame timer context
+ * @consec_oldsn_drops: consecutive drops due to old SN
+ * @consec_oldsn_ampdu_gp2: A-MPDU GP2 timestamp to track
+ *	when to apply old SN consecutive drop workaround
+ * @consec_oldsn_prev_drop: track whether or not an MPDU
+ *	that was single/part of the previous A-MPDU was
+ *	dropped due to old SN
  */
 struct iwl_mvm_reorder_buffer {
 	u16 head_sn;
@@ -674,6 +680,9 @@ struct iwl_mvm_reorder_buffer {
 	bool valid;
 	spinlock_t lock;
 	struct iwl_mvm *mvm;
+	unsigned int consec_oldsn_drops;
+	u32 consec_oldsn_ampdu_gp2;
+	unsigned int consec_oldsn_prev_drop:1;
 } ____cacheline_aligned_in_smp;
 
 /**
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index 25d038092eec..f3f9e641ae70 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -781,6 +781,55 @@ void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct napi_struct *napi,
 		wake_up(&mvm->rx_sync_waitq);
 }
 
+static void iwl_mvm_oldsn_workaround(struct iwl_mvm *mvm,
+				     struct ieee80211_sta *sta, int tid,
+				     struct iwl_mvm_reorder_buffer *buffer,
+				     u32 reorder, u32 gp2, int queue)
+{
+	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
+
+	if (gp2 != buffer->consec_oldsn_ampdu_gp2) {
+		/* we have a new (A-)MPDU ... */
+
+		/*
+		 * reset counter to 0 if we didn't have any oldsn in
+		 * the last A-MPDU (as detected by GP2 being identical)
+		 */
+		if (!buffer->consec_oldsn_prev_drop)
+			buffer->consec_oldsn_drops = 0;
+
+		/* either way, update our tracking state */
+		buffer->consec_oldsn_ampdu_gp2 = gp2;
+	} else if (buffer->consec_oldsn_prev_drop) {
+		/*
+		 * tracking state didn't change, and we had an old SN
+		 * indication before - do nothing in this case, we
+		 * already noted this one down and are waiting for the
+		 * next A-MPDU (by GP2)
+		 */
+		return;
+	}
+
+	/* return unless this MPDU has old SN */
+	if (!(reorder & IWL_RX_MPDU_REORDER_BA_OLD_SN))
+		return;
+
+	/* update state */
+	buffer->consec_oldsn_prev_drop = 1;
+	buffer->consec_oldsn_drops++;
+
+	/* if limit is reached, send del BA and reset state */
+	if (buffer->consec_oldsn_drops == IWL_MVM_AMPDU_CONSEC_DROPS_DELBA) {
+		IWL_WARN(mvm,
+			 "reached %d old SN frames from %pM on queue %d, stopping BA session on TID %d\n",
+			 IWL_MVM_AMPDU_CONSEC_DROPS_DELBA,
+			 sta->addr, queue, tid);
+		ieee80211_stop_rx_ba_session(mvmsta->vif, BIT(tid), sta->addr);
+		buffer->consec_oldsn_prev_drop = 0;
+		buffer->consec_oldsn_drops = 0;
+	}
+}
+
 /*
  * Returns true if the MPDU was buffered\dropped, false if it should be passed
  * to upper layer.
@@ -792,6 +841,7 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
 			    struct sk_buff *skb,
 			    struct iwl_rx_mpdu_desc *desc)
 {
+	struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
 	struct ieee80211_hdr *hdr = iwl_mvm_skb_get_hdr(skb);
 	struct iwl_mvm_sta *mvm_sta;
 	struct iwl_mvm_baid_data *baid_data;
@@ -894,6 +944,9 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
 				       min_sn, IWL_MVM_RELEASE_SEND_RSS_SYNC);
 	}
 
+	iwl_mvm_oldsn_workaround(mvm, sta, tid, buffer, reorder,
+				 rx_status->device_timestamp, queue);
+
 	/* drop any oudated packets */
 	if (ieee80211_sn_less(sn, buffer->head_sn))
 		goto drop;
-- 
2.23.0.rc1


  parent reply	other threads:[~2019-09-03  7:37 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-03  7:36 [PATCH 00/21] iwlwifi: updates intended for v5.4 2019-09-03 Luca Coelho
2019-09-03  7:36 ` [PATCH 01/21] iwlwifi: separate elements from cfg that are needed by trans_alloc Luca Coelho
2019-09-03  7:36 ` [PATCH 02/21] iwlwifi: pcie: use the cfg we passed to iwl_trans_pcie_alloc() Luca Coelho
2019-09-03  7:36 ` [PATCH 03/21] iwlwifi: pcie: move some cfg mangling from trans_pcie_alloc to probe Luca Coelho
2019-09-03  7:36 ` [PATCH 04/21] iwlwifi: pcie: set iwl_trans->cfg later in the probe function Luca Coelho
2019-09-03  7:36 ` [PATCH 05/21] iwlwifi: pass the iwl_config_trans_params when needed Luca Coelho
2019-09-03  7:36 ` [PATCH 06/21] iwlwifi: add a pointer to the trans_cfg directly in trans Luca Coelho
2019-09-03  7:37 ` [PATCH 07/21] iwlwifi: pass the iwl_trans instead of cfg to some functions Luca Coelho
2019-09-03  7:37 ` [PATCH 08/21] iwlwifi: always access the trans configuration via trans Luca Coelho
2019-09-03  7:37 ` [PATCH 09/21] iwlwifi: fix warning iwl-trans.h is included more than once Luca Coelho
2019-09-03  7:37 ` [PATCH 10/21] iwlwifi: add support for suspend-resume flow for new device generation Luca Coelho
2019-09-03  7:37 ` [PATCH 11/21] iwlwifi: add sta_id to WOWLAN_CONFIG_CMD Luca Coelho
2019-09-03  7:37 ` Luca Coelho [this message]
2019-09-03  7:37 ` [PATCH 13/21] iwlwifi: mvm: handle BAR_FRAME_RELEASE (0xc2) notification Luca Coelho
2019-09-03  7:37 ` [PATCH 14/21] iwlwifi: mvm: add support for single antenna diversity Luca Coelho
2019-09-03  7:37 ` [PATCH 15/21] iwlwifi: mvm: don't log un-decrypted frames Luca Coelho
2019-09-03  7:37 ` [PATCH 16/21] iwlwifi: add iwl_tlv_array_len() Luca Coelho
2019-09-03  7:37 ` [PATCH 17/21] iwlwifi: dbg_ini: remove apply point, switch to time point API Luca Coelho
2019-09-03  7:37 ` [PATCH 18/21] iwlwifi: fw api: add DRAM buffer allocation command Luca Coelho
2019-09-03  7:37 ` [PATCH 19/21] iwlwifi: dbg_ini: fix dump structs doc Luca Coelho
2019-09-03  7:37 ` [PATCH 20/21] iwlwifi: dbg_ini: remove periodic trigger Luca Coelho
2019-09-03  7:37 ` [PATCH 21/21] iwlwifi: dbg: remove iwl_fw_cancel_dumps function Luca Coelho

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190903073714.32278-13-luca@coelho.fi \
    --to=luca@coelho.fi \
    --cc=kvalo@codeaurora.org \
    --cc=linux-wireless@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).