diff options
author | Stone Piao <piaoyun@marvell.com> | 2012-06-20 23:21:10 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-07-16 11:47:49 -0400 |
commit | c148a3eb63d97d2956a906ebed2def889d07eb21 (patch) | |
tree | 468adfce10bb3f0daae932101e02847413ed0a26 | |
parent | 1dc1e5ad5a05da69c51446f9c8a2c097884fece7 (diff) |
mwifiex: fix 11n rx packet drop issue
commit 925839243dc9aa4ef25305f5afd10ed18258a4ac upstream.
Currently we check the sequence number of last packet received
against start_win. If a sequence hole is detected, start_win is
updated to next sequence number.
Since the rx sequence number is initialized to 0, a corner case
exists when BA setup happens immediately after association. As
0 is a valid sequence number, start_win gets increased to 1
incorrectly. This causes the first packet with sequence number 0
being dropped.
Initialize rx sequence number as 0xffff and skip adjusting
start_win if the sequence number remains 0xffff. The sequence
number will be updated once the first packet is received.
Signed-off-by: Stone Piao <piaoyun@marvell.com>
Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Kiran Divekar <dkiran@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/net/wireless/mwifiex/11n_rxreorder.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/11n_rxreorder.h | 7 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/wmm.c | 2 |
3 files changed, 12 insertions, 2 deletions
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index e5dfdc39a92..d2358cfcbe9 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c | |||
@@ -267,7 +267,8 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, | |||
267 | else | 267 | else |
268 | last_seq = priv->rx_seq[tid]; | 268 | last_seq = priv->rx_seq[tid]; |
269 | 269 | ||
270 | if (last_seq >= new_node->start_win) | 270 | if (last_seq != MWIFIEX_DEF_11N_RX_SEQ_NUM && |
271 | last_seq >= new_node->start_win) | ||
271 | new_node->start_win = last_seq + 1; | 272 | new_node->start_win = last_seq + 1; |
272 | 273 | ||
273 | new_node->win_size = win_size; | 274 | new_node->win_size = win_size; |
@@ -612,5 +613,5 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv) | |||
612 | spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); | 613 | spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); |
613 | 614 | ||
614 | INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr); | 615 | INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr); |
615 | memset(priv->rx_seq, 0, sizeof(priv->rx_seq)); | 616 | mwifiex_reset_11n_rx_seq_num(priv); |
616 | } | 617 | } |
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h index f3ca8c8c18f..7576c2ab93b 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.h +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h | |||
@@ -37,6 +37,13 @@ | |||
37 | 37 | ||
38 | #define ADDBA_RSP_STATUS_ACCEPT 0 | 38 | #define ADDBA_RSP_STATUS_ACCEPT 0 |
39 | 39 | ||
40 | #define MWIFIEX_DEF_11N_RX_SEQ_NUM 0xffff | ||
41 | |||
42 | static inline void mwifiex_reset_11n_rx_seq_num(struct mwifiex_private *priv) | ||
43 | { | ||
44 | memset(priv->rx_seq, 0xff, sizeof(priv->rx_seq)); | ||
45 | } | ||
46 | |||
40 | int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *, | 47 | int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *, |
41 | u16 seqNum, | 48 | u16 seqNum, |
42 | u16 tid, u8 *ta, | 49 | u16 tid, u8 *ta, |
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 91634daec30..2cdb41ac743 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c | |||
@@ -406,6 +406,8 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter) | |||
406 | priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE; | 406 | priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE; |
407 | priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE; | 407 | priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE; |
408 | 408 | ||
409 | mwifiex_reset_11n_rx_seq_num(priv); | ||
410 | |||
409 | atomic_set(&priv->wmm.tx_pkts_queued, 0); | 411 | atomic_set(&priv->wmm.tx_pkts_queued, 0); |
410 | atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID); | 412 | atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID); |
411 | } | 413 | } |