diff options
-rw-r--r-- | drivers/net/wireless/mwifiex/main.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/wmm.c | 29 |
2 files changed, 28 insertions, 3 deletions
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 537b40dc016e..ea3184d15674 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -215,6 +215,8 @@ struct mwifiex_wmm_desc { | |||
215 | u32 user_pri_pkt_tx_ctrl[WMM_HIGHEST_PRIORITY + 1]; /* UP: 0 to 7 */ | 215 | u32 user_pri_pkt_tx_ctrl[WMM_HIGHEST_PRIORITY + 1]; /* UP: 0 to 7 */ |
216 | /* Number of transmit packets queued */ | 216 | /* Number of transmit packets queued */ |
217 | atomic_t tx_pkts_queued; | 217 | atomic_t tx_pkts_queued; |
218 | /* Tracks highest priority with a packet queued */ | ||
219 | atomic_t highest_queued_prio; | ||
218 | }; | 220 | }; |
219 | 221 | ||
220 | struct mwifiex_802_11_security { | 222 | struct mwifiex_802_11_security { |
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 52d218512c1e..f3d5f23c91d1 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c | |||
@@ -177,14 +177,20 @@ static void mwifiex_wmm_default_queue_priorities(struct mwifiex_private *priv) | |||
177 | * This function map ACs to TIDs. | 177 | * This function map ACs to TIDs. |
178 | */ | 178 | */ |
179 | static void | 179 | static void |
180 | mwifiex_wmm_queue_priorities_tid(u8 queue_priority[]) | 180 | mwifiex_wmm_queue_priorities_tid(struct mwifiex_wmm_desc *wmm) |
181 | { | 181 | { |
182 | u8 *queue_priority = wmm->queue_priority; | ||
182 | int i; | 183 | int i; |
183 | 184 | ||
184 | for (i = 0; i < 4; ++i) { | 185 | for (i = 0; i < 4; ++i) { |
185 | tos_to_tid[7 - (i * 2)] = ac_to_tid[queue_priority[i]][1]; | 186 | tos_to_tid[7 - (i * 2)] = ac_to_tid[queue_priority[i]][1]; |
186 | tos_to_tid[6 - (i * 2)] = ac_to_tid[queue_priority[i]][0]; | 187 | tos_to_tid[6 - (i * 2)] = ac_to_tid[queue_priority[i]][0]; |
187 | } | 188 | } |
189 | |||
190 | for (i = 0; i < MAX_NUM_TID; ++i) | ||
191 | tos_to_tid_inv[tos_to_tid[i]] = (u8)i; | ||
192 | |||
193 | atomic_set(&wmm->highest_queued_prio, HIGH_PRIO_TID); | ||
188 | } | 194 | } |
189 | 195 | ||
190 | /* | 196 | /* |
@@ -246,7 +252,7 @@ mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv, | |||
246 | } | 252 | } |
247 | } | 253 | } |
248 | 254 | ||
249 | mwifiex_wmm_queue_priorities_tid(priv->wmm.queue_priority); | 255 | mwifiex_wmm_queue_priorities_tid(&priv->wmm); |
250 | } | 256 | } |
251 | 257 | ||
252 | /* | 258 | /* |
@@ -401,6 +407,7 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter) | |||
401 | priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE; | 407 | priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE; |
402 | 408 | ||
403 | atomic_set(&priv->wmm.tx_pkts_queued, 0); | 409 | atomic_set(&priv->wmm.tx_pkts_queued, 0); |
410 | atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID); | ||
404 | } | 411 | } |
405 | } | 412 | } |
406 | 413 | ||
@@ -468,6 +475,7 @@ static void mwifiex_wmm_cleanup_queues(struct mwifiex_private *priv) | |||
468 | ra_list); | 475 | ra_list); |
469 | 476 | ||
470 | atomic_set(&priv->wmm.tx_pkts_queued, 0); | 477 | atomic_set(&priv->wmm.tx_pkts_queued, 0); |
478 | atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID); | ||
471 | } | 479 | } |
472 | 480 | ||
473 | /* | 481 | /* |
@@ -640,6 +648,11 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter, | |||
640 | 648 | ||
641 | atomic_inc(&priv->wmm.tx_pkts_queued); | 649 | atomic_inc(&priv->wmm.tx_pkts_queued); |
642 | 650 | ||
651 | if (atomic_read(&priv->wmm.highest_queued_prio) < | ||
652 | tos_to_tid_inv[tid_down]) | ||
653 | atomic_set(&priv->wmm.highest_queued_prio, | ||
654 | tos_to_tid_inv[tid_down]); | ||
655 | |||
643 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); | 656 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); |
644 | } | 657 | } |
645 | 658 | ||
@@ -865,9 +878,14 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, | |||
865 | } | 878 | } |
866 | 879 | ||
867 | do { | 880 | do { |
881 | atomic_t *hqp; | ||
882 | spinlock_t *lock; | ||
883 | |||
868 | priv_tmp = bssprio_node->priv; | 884 | priv_tmp = bssprio_node->priv; |
885 | hqp = &priv_tmp->wmm.highest_queued_prio; | ||
886 | lock = &priv_tmp->wmm.ra_list_spinlock; | ||
869 | 887 | ||
870 | for (i = HIGH_PRIO_TID; i >= LOW_PRIO_TID; --i) { | 888 | for (i = atomic_read(hqp); i >= LOW_PRIO_TID; --i) { |
871 | 889 | ||
872 | tid_ptr = &(priv_tmp)->wmm. | 890 | tid_ptr = &(priv_tmp)->wmm. |
873 | tid_tbl_ptr[tos_to_tid[i]]; | 891 | tid_tbl_ptr[tos_to_tid[i]]; |
@@ -905,6 +923,11 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, | |||
905 | is_list_empty = | 923 | is_list_empty = |
906 | skb_queue_empty(&ptr->skb_head); | 924 | skb_queue_empty(&ptr->skb_head); |
907 | if (!is_list_empty) { | 925 | if (!is_list_empty) { |
926 | spin_lock_irqsave(lock, flags); | ||
927 | if (atomic_read(hqp) > i) | ||
928 | atomic_set(hqp, i); | ||
929 | spin_unlock_irqrestore(lock, | ||
930 | flags); | ||
908 | *priv = priv_tmp; | 931 | *priv = priv_tmp; |
909 | *tid = tos_to_tid[i]; | 932 | *tid = tos_to_tid[i]; |
910 | return ptr; | 933 | return ptr; |