Commit 92583924 authored by Stone Piao's avatar Stone Piao Committed by John W. Linville

mwifiex: fix 11n rx packet drop issue

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.

Cc: "3.0.y, 3.1.y, 3.2.y, 3.3.y, 3.4.y" <stable@vger.kernel.org>
Signed-off-by: default avatarStone Piao <piaoyun@marvell.com>
Signed-off-by: default avatarAvinash Patil <patila@marvell.com>
Signed-off-by: default avatarKiran Divekar <dkiran@marvell.com>
Signed-off-by: default avatarBing Zhao <bzhao@marvell.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 8d6fcbdb
...@@ -256,7 +256,8 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, ...@@ -256,7 +256,8 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
else else
last_seq = priv->rx_seq[tid]; last_seq = priv->rx_seq[tid];
if (last_seq >= new_node->start_win) if (last_seq != MWIFIEX_DEF_11N_RX_SEQ_NUM &&
last_seq >= new_node->start_win)
new_node->start_win = last_seq + 1; new_node->start_win = last_seq + 1;
new_node->win_size = win_size; new_node->win_size = win_size;
...@@ -596,5 +597,5 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv) ...@@ -596,5 +597,5 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv)
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr); INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
memset(priv->rx_seq, 0, sizeof(priv->rx_seq)); mwifiex_reset_11n_rx_seq_num(priv);
} }
...@@ -37,6 +37,13 @@ ...@@ -37,6 +37,13 @@
#define ADDBA_RSP_STATUS_ACCEPT 0 #define ADDBA_RSP_STATUS_ACCEPT 0
#define MWIFIEX_DEF_11N_RX_SEQ_NUM 0xffff
static inline void mwifiex_reset_11n_rx_seq_num(struct mwifiex_private *priv)
{
memset(priv->rx_seq, 0xff, sizeof(priv->rx_seq));
}
int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *, int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *,
u16 seqNum, u16 seqNum,
u16 tid, u8 *ta, u16 tid, u8 *ta,
......
...@@ -404,6 +404,8 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter) ...@@ -404,6 +404,8 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter)
priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE; priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE;
priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE; priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE;
mwifiex_reset_11n_rx_seq_num(priv);
atomic_set(&priv->wmm.tx_pkts_queued, 0); atomic_set(&priv->wmm.tx_pkts_queued, 0);
atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID); atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment