diff options
author | Avinash Patil <patila@marvell.com> | 2012-09-27 22:00:10 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-09-28 13:54:10 -0400 |
commit | 2db96c3d0a1f716fc90451cc2ed13842471f4658 (patch) | |
tree | 2228789e8ed71fd30e0d39ff04c2aa89354af2ad /drivers/net/wireless | |
parent | ff9bd2d8d95aedb661714536cb919281540f9772 (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.c | 49 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/11n_rxreorder.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/cmdevt.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/main.h | 1 |
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 | */ | ||
651 | void 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 | ||
44 | enum mwifiex_rxreor_flags { | ||
45 | RXREOR_FORCE_NO_DROP = 1<<0, | ||
46 | }; | ||
47 | |||
44 | static inline void mwifiex_reset_11n_rx_seq_num(struct mwifiex_private *priv) | 48 | static 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 | |||
73 | struct mwifiex_rx_reorder_tbl * | 77 | struct mwifiex_rx_reorder_tbl * |
74 | mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta); | 78 | mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta); |
75 | void mwifiex_11n_del_rx_reorder_tbl_by_ta(struct mwifiex_private *priv, u8 *ta); | 79 | void mwifiex_11n_del_rx_reorder_tbl_by_ta(struct mwifiex_private *priv, u8 *ta); |
80 | void 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 | ||
540 | struct mwifiex_bss_prio_node { | 541 | struct mwifiex_bss_prio_node { |