wil6210: Rx multicast packets duplicate detection

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>
This commit is contained in:
Dedy Lansky
2018-07-24 10:44:22 +03:00
committed by Kalle Valo
parent 52d7e0e533
commit 1bd82ee09a
7 changed files with 40 additions and 13 deletions

View File

@@ -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,

View File

@@ -95,7 +95,7 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
{
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 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
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 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
}
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 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
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;
}

View File

@@ -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)

View File

@@ -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);

View File

@@ -503,7 +503,7 @@ out_free:
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,

View File

@@ -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 &

View File

@@ -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 @@ struct pci_dev;
* @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;
};
/**