aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvinash Patil <patila@marvell.com>2014-12-05 12:53:41 -0500
committerJohn W. Linville <linville@tuxdriver.com>2014-12-05 14:15:25 -0500
commitc11fb9857f8c7951e30509c5af72ada8e121be8b (patch)
tree60cea5b4884ea221e936e1a29444678ffe508596
parent9817fffbf04caae2843bc09321561afdea8c8d89 (diff)
mwifiex: guard station nodes access by station list lock
Station node entries should be guarded for whole of their reference instead of just while getting node entry from station list. It may happen that station node is retrieved may be deleted by deauthentication event while it is still in use. Reported by: Tim Shepard <shep@xplot.org> Signed-off-by: Avinash Patil <patila@marvell.com> Signed-off-by: Cathy Luo <cluo@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/mwifiex/11n.c4
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.c6
-rw-r--r--drivers/net/wireless/mwifiex/uap_txrx.c3
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c6
4 files changed, 16 insertions, 3 deletions
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index 62f5dbe602d3..9d4786e7ddff 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -544,6 +544,7 @@ int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac)
544 u32 tx_win_size = priv->add_ba_param.tx_win_size; 544 u32 tx_win_size = priv->add_ba_param.tx_win_size;
545 static u8 dialog_tok; 545 static u8 dialog_tok;
546 int ret; 546 int ret;
547 unsigned long flags;
547 u16 block_ack_param_set; 548 u16 block_ack_param_set;
548 549
549 dev_dbg(priv->adapter->dev, "cmd: %s: tid %d\n", __func__, tid); 550 dev_dbg(priv->adapter->dev, "cmd: %s: tid %d\n", __func__, tid);
@@ -554,15 +555,18 @@ int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac)
554 memcmp(priv->cfg_bssid, peer_mac, ETH_ALEN)) { 555 memcmp(priv->cfg_bssid, peer_mac, ETH_ALEN)) {
555 struct mwifiex_sta_node *sta_ptr; 556 struct mwifiex_sta_node *sta_ptr;
556 557
558 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
557 sta_ptr = mwifiex_get_sta_entry(priv, peer_mac); 559 sta_ptr = mwifiex_get_sta_entry(priv, peer_mac);
558 if (!sta_ptr) { 560 if (!sta_ptr) {
559 dev_warn(priv->adapter->dev, 561 dev_warn(priv->adapter->dev,
560 "BA setup with unknown TDLS peer %pM!\n", 562 "BA setup with unknown TDLS peer %pM!\n",
561 peer_mac); 563 peer_mac);
564 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
562 return -1; 565 return -1;
563 } 566 }
564 if (sta_ptr->is_11ac_enabled) 567 if (sta_ptr->is_11ac_enabled)
565 tx_win_size = MWIFIEX_11AC_STA_AMPDU_DEF_TXWINSIZE; 568 tx_win_size = MWIFIEX_11AC_STA_AMPDU_DEF_TXWINSIZE;
569 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
566 } 570 }
567 571
568 block_ack_param_set = (u16)((tid << BLOCKACKPARAM_TID_POS) | 572 block_ack_param_set = (u16)((tid << BLOCKACKPARAM_TID_POS) |
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index 5ef5a0eeba50..d73fda312c87 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -351,6 +351,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
351 new_node->init_win = seq_num; 351 new_node->init_win = seq_num;
352 new_node->flags = 0; 352 new_node->flags = 0;
353 353
354 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
354 if (mwifiex_queuing_ra_based(priv)) { 355 if (mwifiex_queuing_ra_based(priv)) {
355 dev_dbg(priv->adapter->dev, 356 dev_dbg(priv->adapter->dev,
356 "info: AP/ADHOC:last_seq=%d start_win=%d\n", 357 "info: AP/ADHOC:last_seq=%d start_win=%d\n",
@@ -367,6 +368,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
367 else 368 else
368 last_seq = priv->rx_seq[tid]; 369 last_seq = priv->rx_seq[tid];
369 } 370 }
371 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
370 372
371 if (last_seq != MWIFIEX_DEF_11N_RX_SEQ_NUM && 373 if (last_seq != MWIFIEX_DEF_11N_RX_SEQ_NUM &&
372 last_seq >= new_node->start_win) { 374 last_seq >= new_node->start_win) {
@@ -455,22 +457,26 @@ int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv,
455 u32 rx_win_size = priv->add_ba_param.rx_win_size; 457 u32 rx_win_size = priv->add_ba_param.rx_win_size;
456 u8 tid; 458 u8 tid;
457 int win_size; 459 int win_size;
460 unsigned long flags;
458 uint16_t block_ack_param_set; 461 uint16_t block_ack_param_set;
459 462
460 if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && 463 if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
461 ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) && 464 ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) &&
462 priv->adapter->is_hw_11ac_capable && 465 priv->adapter->is_hw_11ac_capable &&
463 memcmp(priv->cfg_bssid, cmd_addba_req->peer_mac_addr, ETH_ALEN)) { 466 memcmp(priv->cfg_bssid, cmd_addba_req->peer_mac_addr, ETH_ALEN)) {
467 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
464 sta_ptr = mwifiex_get_sta_entry(priv, 468 sta_ptr = mwifiex_get_sta_entry(priv,
465 cmd_addba_req->peer_mac_addr); 469 cmd_addba_req->peer_mac_addr);
466 if (!sta_ptr) { 470 if (!sta_ptr) {
467 dev_warn(priv->adapter->dev, 471 dev_warn(priv->adapter->dev,
468 "BA setup with unknown TDLS peer %pM!\n", 472 "BA setup with unknown TDLS peer %pM!\n",
469 cmd_addba_req->peer_mac_addr); 473 cmd_addba_req->peer_mac_addr);
474 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
470 return -1; 475 return -1;
471 } 476 }
472 if (sta_ptr->is_11ac_enabled) 477 if (sta_ptr->is_11ac_enabled)
473 rx_win_size = MWIFIEX_11AC_STA_AMPDU_DEF_RXWINSIZE; 478 rx_win_size = MWIFIEX_11AC_STA_AMPDU_DEF_RXWINSIZE;
479 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
474 } 480 }
475 481
476 cmd->command = cpu_to_le16(HostCmd_CMD_11N_ADDBA_RSP); 482 cmd->command = cpu_to_le16(HostCmd_CMD_11N_ADDBA_RSP);
diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c
index e7d326f5b96e..be3a203a529b 100644
--- a/drivers/net/wireless/mwifiex/uap_txrx.c
+++ b/drivers/net/wireless/mwifiex/uap_txrx.c
@@ -266,6 +266,7 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv,
266 struct rx_packet_hdr *rx_pkt_hdr; 266 struct rx_packet_hdr *rx_pkt_hdr;
267 u16 rx_pkt_type; 267 u16 rx_pkt_type;
268 u8 ta[ETH_ALEN], pkt_type; 268 u8 ta[ETH_ALEN], pkt_type;
269 unsigned long flags;
269 struct mwifiex_sta_node *node; 270 struct mwifiex_sta_node *node;
270 271
271 uap_rx_pd = (struct uap_rxpd *)(skb->data); 272 uap_rx_pd = (struct uap_rxpd *)(skb->data);
@@ -294,10 +295,12 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv,
294 memcpy(ta, rx_pkt_hdr->eth803_hdr.h_source, ETH_ALEN); 295 memcpy(ta, rx_pkt_hdr->eth803_hdr.h_source, ETH_ALEN);
295 296
296 if (rx_pkt_type != PKT_TYPE_BAR && uap_rx_pd->priority < MAX_NUM_TID) { 297 if (rx_pkt_type != PKT_TYPE_BAR && uap_rx_pd->priority < MAX_NUM_TID) {
298 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
297 node = mwifiex_get_sta_entry(priv, ta); 299 node = mwifiex_get_sta_entry(priv, ta);
298 if (node) 300 if (node)
299 node->rx_seq[uap_rx_pd->priority] = 301 node->rx_seq[uap_rx_pd->priority] =
300 le16_to_cpu(uap_rx_pd->seq_num); 302 le16_to_cpu(uap_rx_pd->seq_num);
303 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
301 } 304 }
302 305
303 if (!priv->ap_11n_enabled || 306 if (!priv->ap_11n_enabled ||
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 0dafcb0d7eb1..ffffd2c5a76e 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -147,9 +147,6 @@ void mwifiex_ralist_add(struct mwifiex_private *priv, const u8 *ra)
147 struct mwifiex_sta_node *node; 147 struct mwifiex_sta_node *node;
148 unsigned long flags; 148 unsigned long flags;
149 149
150 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
151 node = mwifiex_get_sta_entry(priv, ra);
152 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
153 150
154 for (i = 0; i < MAX_NUM_TID; ++i) { 151 for (i = 0; i < MAX_NUM_TID; ++i) {
155 ra_list = mwifiex_wmm_allocate_ralist_node(adapter, ra); 152 ra_list = mwifiex_wmm_allocate_ralist_node(adapter, ra);
@@ -170,10 +167,13 @@ void mwifiex_ralist_add(struct mwifiex_private *priv, const u8 *ra)
170 ra_list->is_11n_enabled = IS_11N_ENABLED(priv); 167 ra_list->is_11n_enabled = IS_11N_ENABLED(priv);
171 } 168 }
172 } else { 169 } else {
170 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
171 node = mwifiex_get_sta_entry(priv, ra);
173 ra_list->is_11n_enabled = 172 ra_list->is_11n_enabled =
174 mwifiex_is_sta_11n_enabled(priv, node); 173 mwifiex_is_sta_11n_enabled(priv, node);
175 if (ra_list->is_11n_enabled) 174 if (ra_list->is_11n_enabled)
176 ra_list->max_amsdu = node->max_amsdu; 175 ra_list->max_amsdu = node->max_amsdu;
176 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
177 } 177 }
178 178
179 dev_dbg(adapter->dev, "data: ralist %p: is_11n_enabled=%d\n", 179 dev_dbg(adapter->dev, "data: ralist %p: is_11n_enabled=%d\n",