aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorAvinash Patil <patila@marvell.com>2012-09-27 22:00:10 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-09-28 13:54:10 -0400
commit2db96c3d0a1f716fc90451cc2ed13842471f4658 (patch)
tree2228789e8ed71fd30e0d39ff04c2aa89354af2ad /drivers/net/wireless
parentff9bd2d8d95aedb661714536cb919281540f9772 (diff)
mwifiex: enhance RX reordering to avoid packet drop during host sleep
Once hostsleep is activated, this patch takes care of not dropping packets in RX reorder table. Signed-off-by: Avinash Patil <patila@marvell.com> Signed-off-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.c49
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.h5
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c2
-rw-r--r--drivers/net/wireless/mwifiex/main.h1
4 files changed, 49 insertions, 8 deletions
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index 24e2582b467c..9402b93b9a36 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -302,6 +302,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
302 new_node->start_win = last_seq + 1; 302 new_node->start_win = last_seq + 1;
303 303
304 new_node->win_size = win_size; 304 new_node->win_size = win_size;
305 new_node->flags = 0;
305 306
306 new_node->rx_reorder_ptr = kzalloc(sizeof(void *) * win_size, 307 new_node->rx_reorder_ptr = kzalloc(sizeof(void *) * win_size,
307 GFP_KERNEL); 308 GFP_KERNEL);
@@ -457,13 +458,20 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
457 * If seq_num is less then starting win then ignore and drop the 458 * If seq_num is less then starting win then ignore and drop the
458 * packet 459 * packet
459 */ 460 */
460 if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) {/* Wrap */ 461 if (tbl->flags & RXREOR_FORCE_NO_DROP) {
461 if (seq_num >= ((start_win + TWOPOW11) & 462 dev_dbg(priv->adapter->dev,
462 (MAX_TID_VALUE - 1)) && (seq_num < start_win)) 463 "RXREOR_FORCE_NO_DROP when HS is activated\n");
464 tbl->flags &= ~RXREOR_FORCE_NO_DROP;
465 } else {
466 if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) {
467 if (seq_num >= ((start_win + TWOPOW11) &
468 (MAX_TID_VALUE - 1)) &&
469 seq_num < start_win)
470 return -1;
471 } else if ((seq_num < start_win) ||
472 (seq_num > (start_win + TWOPOW11))) {
463 return -1; 473 return -1;
464 } else if ((seq_num < start_win) || 474 }
465 (seq_num > (start_win + TWOPOW11))) {
466 return -1;
467 } 475 }
468 476
469 /* 477 /*
@@ -474,8 +482,7 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
474 seq_num = ((seq_num + win_size) - 1) & (MAX_TID_VALUE - 1); 482 seq_num = ((seq_num + win_size) - 1) & (MAX_TID_VALUE - 1);
475 483
476 if (((end_win < start_win) && 484 if (((end_win < start_win) &&
477 (seq_num < (TWOPOW11 - (MAX_TID_VALUE - start_win))) && 485 (seq_num < start_win) && (seq_num > end_win)) ||
478 (seq_num > end_win)) ||
479 ((end_win > start_win) && ((seq_num > end_win) || 486 ((end_win > start_win) && ((seq_num > end_win) ||
480 (seq_num < start_win)))) { 487 (seq_num < start_win)))) {
481 end_win = seq_num; 488 end_win = seq_num;
@@ -637,3 +644,29 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv)
637 INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr); 644 INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
638 mwifiex_reset_11n_rx_seq_num(priv); 645 mwifiex_reset_11n_rx_seq_num(priv);
639} 646}
647
648/*
649 * This function updates all rx_reorder_tbl's flags.
650 */
651void mwifiex_update_rxreor_flags(struct mwifiex_adapter *adapter, u8 flags)
652{
653 struct mwifiex_private *priv;
654 struct mwifiex_rx_reorder_tbl *tbl;
655 unsigned long lock_flags;
656 int i;
657
658 for (i = 0; i < adapter->priv_num; i++) {
659 priv = adapter->priv[i];
660 if (!priv)
661 continue;
662 if (list_empty(&priv->rx_reorder_tbl_ptr))
663 continue;
664
665 spin_lock_irqsave(&priv->rx_reorder_tbl_lock, lock_flags);
666 list_for_each_entry(tbl, &priv->rx_reorder_tbl_ptr, list)
667 tbl->flags = flags;
668 spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, lock_flags);
669 }
670
671 return;
672}
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h
index 72848591691a..4064041ac852 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.h
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h
@@ -41,6 +41,10 @@
41#define BA_SETUP_MAX_PACKET_THRESHOLD 16 41#define BA_SETUP_MAX_PACKET_THRESHOLD 16
42#define BA_SETUP_PACKET_OFFSET 16 42#define BA_SETUP_PACKET_OFFSET 16
43 43
44enum mwifiex_rxreor_flags {
45 RXREOR_FORCE_NO_DROP = 1<<0,
46};
47
44static inline void mwifiex_reset_11n_rx_seq_num(struct mwifiex_private *priv) 48static inline void mwifiex_reset_11n_rx_seq_num(struct mwifiex_private *priv)
45{ 49{
46 memset(priv->rx_seq, 0xff, sizeof(priv->rx_seq)); 50 memset(priv->rx_seq, 0xff, sizeof(priv->rx_seq));
@@ -73,5 +77,6 @@ struct mwifiex_rx_reorder_tbl *mwifiex_11n_get_rxreorder_tbl(struct
73struct mwifiex_rx_reorder_tbl * 77struct mwifiex_rx_reorder_tbl *
74mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta); 78mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta);
75void mwifiex_11n_del_rx_reorder_tbl_by_ta(struct mwifiex_private *priv, u8 *ta); 79void mwifiex_11n_del_rx_reorder_tbl_by_ta(struct mwifiex_private *priv, u8 *ta);
80void mwifiex_update_rxreor_flags(struct mwifiex_adapter *adapter, u8 flags);
76 81
77#endif /* _MWIFIEX_11N_RXREORDER_H_ */ 82#endif /* _MWIFIEX_11N_RXREORDER_H_ */
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 225c1a4feeba..8d465107f52b 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -1088,6 +1088,8 @@ mwifiex_hs_activated_event(struct mwifiex_private *priv, u8 activated)
1088 if (activated) { 1088 if (activated) {
1089 if (priv->adapter->is_hs_configured) { 1089 if (priv->adapter->is_hs_configured) {
1090 priv->adapter->hs_activated = true; 1090 priv->adapter->hs_activated = true;
1091 mwifiex_update_rxreor_flags(priv->adapter,
1092 RXREOR_FORCE_NO_DROP);
1091 dev_dbg(priv->adapter->dev, "event: hs_activated\n"); 1093 dev_dbg(priv->adapter->dev, "event: hs_activated\n");
1092 priv->adapter->hs_activate_wait_q_woken = true; 1094 priv->adapter->hs_activate_wait_q_woken = true;
1093 wake_up_interruptible( 1095 wake_up_interruptible(
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 956312f45e60..bfb3fa69805c 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -535,6 +535,7 @@ struct mwifiex_rx_reorder_tbl {
535 int win_size; 535 int win_size;
536 void **rx_reorder_ptr; 536 void **rx_reorder_ptr;
537 struct reorder_tmr_cnxt timer_context; 537 struct reorder_tmr_cnxt timer_context;
538 u8 flags;
538}; 539};
539 540
540struct mwifiex_bss_prio_node { 541struct mwifiex_bss_prio_node {