summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorAmitkumar Karwar <akarwar@marvell.com>2014-07-12 07:53:13 +0400
committerJohn W. Linville <linville@tuxdriver.com>2014-07-16 00:00:04 +0400
commit2d702830e004f17e62980869e72f79775140201a (patch)
tree740087abdf4eb11e596c817681aca36aab046422 /drivers
parent6a06e554daef86c4e8d290284927b081fedb249e (diff)
downloadlinux-2d702830e004f17e62980869e72f79775140201a.tar.xz
mwifiex: access rx_reorder_tbl_ptr only while holding lock
This patch fixes a bug in which rx_reorder_tbl_ptr is accessed without holding spinlock at few places. Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> Signed-off-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index b22bae3d1205..06a2c215ef5e 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -249,13 +249,22 @@ void mwifiex_11n_del_rx_reorder_tbl_by_ta(struct mwifiex_private *priv, u8 *ta)
* buffered in Rx reordering table.
*/
static int
-mwifiex_11n_find_last_seq_num(struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr)
+mwifiex_11n_find_last_seq_num(struct reorder_tmr_cnxt *ctx)
{
+ struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr = ctx->ptr;
+ struct mwifiex_private *priv = ctx->priv;
+ unsigned long flags;
int i;
- for (i = (rx_reorder_tbl_ptr->win_size - 1); i >= 0; --i)
- if (rx_reorder_tbl_ptr->rx_reorder_ptr[i])
+ spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+ for (i = rx_reorder_tbl_ptr->win_size - 1; i >= 0; --i) {
+ if (rx_reorder_tbl_ptr->rx_reorder_ptr[i]) {
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
+ flags);
return i;
+ }
+ }
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
return -1;
}
@@ -274,7 +283,7 @@ mwifiex_flush_data(unsigned long context)
(struct reorder_tmr_cnxt *) context;
int start_win, seq_num;
- seq_num = mwifiex_11n_find_last_seq_num(ctx->ptr);
+ seq_num = mwifiex_11n_find_last_seq_num(ctx);
if (seq_num < 0)
return;
@@ -729,9 +738,9 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv)
mwifiex_del_rx_reorder_entry(priv, del_tbl_ptr);
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
}
+ INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
- INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
mwifiex_reset_11n_rx_seq_num(priv);
}
@@ -749,10 +758,14 @@ void mwifiex_update_rxreor_flags(struct mwifiex_adapter *adapter, u8 flags)
priv = adapter->priv[i];
if (!priv)
continue;
- if (list_empty(&priv->rx_reorder_tbl_ptr))
- continue;
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, lock_flags);
+ if (list_empty(&priv->rx_reorder_tbl_ptr)) {
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
+ lock_flags);
+ continue;
+ }
+
list_for_each_entry(tbl, &priv->rx_reorder_tbl_ptr, list)
tbl->flags = flags;
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, lock_flags);