diff mbox series

[v2,01/19] wil6210: Rx multicast packets duplicate detection

Message ID 1532418280-5849-2-git-send-email-merez@codeaurora.org (mailing list archive)
State Accepted
Commit 1bd82ee09aeae74c9f68e6f4147132a3e30e721e
Delegated to: Kalle Valo
Headers show
Series wil6210 patches | expand

Commit Message

Maya Erez July 24, 2018, 7:44 a.m. UTC
From: Dedy Lansky <dlansky@codeaurora.org>

Store the last received multicast sequence number (SN) part of the TID
info. Drop Rx multicast packets with retry bit set which their SN
is equal to the last received.

Signed-off-by: Dedy Lansky <dlansky@codeaurora.org>
Signed-off-by: Maya Erez <merez@codeaurora.org>
---
 drivers/net/wireless/ath/wil6210/debugfs.c    |  7 ++++---
 drivers/net/wireless/ath/wil6210/rx_reorder.c | 23 ++++++++++++++++-------
 drivers/net/wireless/ath/wil6210/txrx.c       |  3 ++-
 drivers/net/wireless/ath/wil6210/txrx.h       |  5 +++++
 drivers/net/wireless/ath/wil6210/txrx_edma.c  |  3 ++-
 drivers/net/wireless/ath/wil6210/txrx_edma.h  |  6 ++++++
 drivers/net/wireless/ath/wil6210/wil6210.h    |  6 +++++-
 7 files changed, 40 insertions(+), 13 deletions(-)

Comments

Kalle Valo July 31, 2018, 8:05 a.m. UTC | #1
Maya Erez <merez@codeaurora.org> wrote:

> Store the last received multicast sequence number (SN) part of the TID
> info. Drop Rx multicast packets with retry bit set which their SN
> is equal to the last received.
> 
> Signed-off-by: Dedy Lansky <dlansky@codeaurora.org>
> Signed-off-by: Maya Erez <merez@codeaurora.org>
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>

19 patches applied to ath-next branch of ath.git, thanks.

1bd82ee09aea wil6210: Rx multicast packets duplicate detection
e15af41c05ed wil6210: drop Rx packets with L2 error indication from HW
a24a3d6abb97 wil6210: add TX latency statistics
6d9eb7ebae3d wil6210: fix temperature debugfs
0b8532102293 wil6210: fix RX checksum report to network stack
1c0dd5f5f3ad wil6210: support Talyn specific FW file
b5aeff16b20f wil6210: align to latest auto generated wmi.h
aea2f8b781b2 wil6210: add 3-MSI support
65e6ffdcc450 wil6210: fix min() compilation errors
0c936b3c9633 wil6210: add support for link statistics
af2cd85e8dbd wil6210: allow scan on AP interface
1b99197dc00c wil6210: support max aggregation window size 64
6ccae584014e wil6210: increase firmware ready timeout
631d3b4f7eeb wil6210: support Talyn specific board file
7f10f8ba0220 wil6210: set default 3-MSI
6a363e8aa382 wil6210: align to latest auto generated wmi.h
b698e2dfc24c wil6210: off channel transmit management frames in AP mode
d554edcd972d wil6210: prevent FW download if HW is configured for secured boot
1bb38e8bb81e wil6210: fix eDMA RX chaining
diff mbox series

Patch

diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index 58ce044..7d62126 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -1640,6 +1640,7 @@  static void wil_print_rxtid(struct seq_file *s, struct wil_tid_ampdu_rx *r)
 	int i;
 	u16 index = ((r->head_seq_num - r->ssn) & 0xfff) % r->buf_size;
 	unsigned long long drop_dup = r->drop_dup, drop_old = r->drop_old;
+	unsigned long long drop_dup_mcast = r->drop_dup_mcast;
 
 	seq_printf(s, "([%2d]) 0x%03x [", r->buf_size, r->head_seq_num);
 	for (i = 0; i < r->buf_size; i++) {
@@ -1649,9 +1650,9 @@  static void wil_print_rxtid(struct seq_file *s, struct wil_tid_ampdu_rx *r)
 			seq_printf(s, "%c", r->reorder_buf[i] ? '*' : '_');
 	}
 	seq_printf(s,
-		   "] total %llu drop %llu (dup %llu + old %llu) last 0x%03x\n",
-		   r->total, drop_dup + drop_old, drop_dup, drop_old,
-		   r->ssn_last_drop);
+		   "] total %llu drop %llu (dup %llu + old %llu + dup mcast %llu) last 0x%03x\n",
+		   r->total, drop_dup + drop_old + drop_dup_mcast, drop_dup,
+		   drop_old, drop_dup_mcast, r->ssn_last_drop);
 }
 
 static void wil_print_rxtid_crypto(struct seq_file *s, int tid,
diff --git a/drivers/net/wireless/ath/wil6210/rx_reorder.c b/drivers/net/wireless/ath/wil6210/rx_reorder.c
index 22475a1..ba4e93f 100644
--- a/drivers/net/wireless/ath/wil6210/rx_reorder.c
+++ b/drivers/net/wireless/ath/wil6210/rx_reorder.c
@@ -95,7 +95,7 @@  void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb)
 {
 	struct wil6210_vif *vif;
 	struct net_device *ndev;
-	int tid, cid, mid, mcast;
+	int tid, cid, mid, mcast, retry;
 	u16 seq;
 	struct wil_sta_info *sta;
 	struct wil_tid_ampdu_rx *r;
@@ -103,7 +103,7 @@  void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb)
 	int index;
 
 	wil->txrx_ops.get_reorder_params(wil, skb, &tid, &cid, &mid, &seq,
-					 &mcast);
+					 &mcast, &retry);
 	sta = &wil->sta[cid];
 
 	wil_dbg_txrx(wil, "MID %d CID %d TID %d Seq 0x%03x mcast %01x\n",
@@ -117,11 +117,6 @@  void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb)
 	}
 	ndev = vif_to_ndev(vif);
 
-	if (unlikely(mcast)) {
-		wil_netif_rx_any(skb, ndev);
-		return;
-	}
-
 	spin_lock(&sta->tid_rx_lock);
 
 	r = sta->tid_rx[tid];
@@ -130,6 +125,19 @@  void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb)
 		goto out;
 	}
 
+	if (unlikely(mcast)) {
+		if (retry && seq == r->mcast_last_seq) {
+			r->drop_dup_mcast++;
+			wil_dbg_txrx(wil, "Rx drop: dup mcast seq 0x%03x\n",
+				     seq);
+			dev_kfree_skb(skb);
+			goto out;
+		}
+		r->mcast_last_seq = seq;
+		wil_netif_rx_any(skb, ndev);
+		goto out;
+	}
+
 	r->total++;
 	hseq = r->head_seq_num;
 
@@ -262,6 +270,7 @@  struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil,
 	r->buf_size = size;
 	r->stored_mpdu_num = 0;
 	r->first_time = true;
+	r->mcast_last_seq = U16_MAX;
 	return r;
 }
 
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 2098f3c..ad40a96 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -2180,7 +2180,7 @@  static inline void wil_tx_fini(struct wil6210_priv *wil) {}
 
 static void wil_get_reorder_params(struct wil6210_priv *wil,
 				   struct sk_buff *skb, int *tid, int *cid,
-				   int *mid, u16 *seq, int *mcast)
+				   int *mid, u16 *seq, int *mcast, int *retry)
 {
 	struct vring_rx_desc *d = wil_skb_rxdesc(skb);
 
@@ -2189,6 +2189,7 @@  static void wil_get_reorder_params(struct wil6210_priv *wil,
 	*mid = wil_rxdesc_mid(d);
 	*seq = wil_rxdesc_seq(d);
 	*mcast = wil_rxdesc_mcast(d);
+	*retry = wil_rxdesc_retry(d);
 }
 
 void wil_init_txrx_ops_legacy_dma(struct wil6210_priv *wil)
diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h
index f361423..3dfd7f9 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.h
+++ b/drivers/net/wireless/ath/wil6210/txrx.h
@@ -500,6 +500,11 @@  static inline int wil_rxdesc_ext_subtype(struct vring_rx_desc *d)
 	return WIL_GET_BITS(d->mac.d0, 28, 31);
 }
 
+static inline int wil_rxdesc_retry(struct vring_rx_desc *d)
+{
+	return WIL_GET_BITS(d->mac.d0, 31, 31);
+}
+
 static inline int wil_rxdesc_key_id(struct vring_rx_desc *d)
 {
 	return WIL_GET_BITS(d->mac.d1, 4, 5);
diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.c b/drivers/net/wireless/ath/wil6210/txrx_edma.c
index 95f38e6..1940347 100644
--- a/drivers/net/wireless/ath/wil6210/txrx_edma.c
+++ b/drivers/net/wireless/ath/wil6210/txrx_edma.c
@@ -503,7 +503,7 @@  static int wil_init_rx_desc_ring(struct wil6210_priv *wil, u16 desc_ring_size,
 static void wil_get_reorder_params_edma(struct wil6210_priv *wil,
 					struct sk_buff *skb, int *tid,
 					int *cid, int *mid, u16 *seq,
-					int *mcast)
+					int *mcast, int *retry)
 {
 	struct wil_rx_status_extended *s = wil_skb_rxstatus(skb);
 
@@ -512,6 +512,7 @@  static void wil_get_reorder_params_edma(struct wil6210_priv *wil,
 	*mid = wil_rx_status_get_mid(s);
 	*seq = le16_to_cpu(wil_rx_status_get_seq(wil, s));
 	*mcast = wil_rx_status_get_mcast(s);
+	*retry = wil_rx_status_get_retry(s);
 }
 
 static void wil_get_netif_rx_params_edma(struct sk_buff *skb, int *cid,
diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.h b/drivers/net/wireless/ath/wil6210/txrx_edma.h
index e86fc2d..a7fe929 100644
--- a/drivers/net/wireless/ath/wil6210/txrx_edma.h
+++ b/drivers/net/wireless/ath/wil6210/txrx_edma.h
@@ -471,6 +471,12 @@  static inline __le16 wil_rx_status_get_seq(struct wil6210_priv *wil, void *msg)
 	return ((struct wil_rx_status_extended *)msg)->ext.seq_num;
 }
 
+static inline u8 wil_rx_status_get_retry(void *msg)
+{
+	/* retry bit is missing in EDMA HW. return 1 to be on the safe side */
+	return 1;
+}
+
 static inline int wil_rx_status_get_mid(void *msg)
 {
 	if (!(((struct wil_rx_status_compressed *)msg)->d0 &
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index d963c76..9b1467c 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -572,7 +572,7 @@  struct wil_txrx_ops {
 				 u16 agg_wsize, u16 timeout);
 	void (*get_reorder_params)(struct wil6210_priv *wil,
 				   struct sk_buff *skb, int *tid, int *cid,
-				   int *mid, u16 *seq, int *mcast);
+				   int *mid, u16 *seq, int *mcast, int *retry);
 	void (*get_netif_rx_params)(struct sk_buff *skb,
 				    int *cid, int *security);
 	int (*rx_crypto_check)(struct wil6210_priv *wil, struct sk_buff *skb);
@@ -625,6 +625,8 @@  enum { /* for wil6210_priv.status */
  * @drop_dup: duplicate frames dropped for this reorder buffer
  * @drop_old: old frames dropped for this reorder buffer
  * @first_time: true when this buffer used 1-st time
+ * @mcast_last_seq: sequence number (SN) of last received multicast packet
+ * @drop_dup_mcast: duplicate multicast frames dropped for this reorder buffer
  */
 struct wil_tid_ampdu_rx {
 	struct sk_buff **reorder_buf;
@@ -638,6 +640,8 @@  struct wil_tid_ampdu_rx {
 	unsigned long long drop_dup;
 	unsigned long long drop_old;
 	bool first_time; /* is it 1-st time this buffer used? */
+	u16 mcast_last_seq; /* multicast dup detection */
+	unsigned long long drop_dup_mcast;
 };
 
 /**