aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMarc Yang <yangyang@marvell.com>2011-05-16 22:17:50 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-05-19 13:53:55 -0400
commit49729ff616547d7abcb96924d14aa860320e7352 (patch)
tree9f07fc3f7cad6d11fe00adeb8f177f1d1536539f /drivers
parentf699254c7126d7df94491dfd4c3648f8ec0c0d51 (diff)
mwifiex: reduce CPU usage by tracking highest_queued_prio
This patch adds highest_queued_prio to track priority of packets as they are enqueued so that mwifiex_wmm_get_highest_priolist_ptr() starts checking at the first level where we have packets, instead of the highest. The function also lowers priority value to the level where first packet is found. Signed-off-by: Marc Yang <yangyang@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/main.h2
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c29
2 files changed, 28 insertions, 3 deletions
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 537b40dc016..ea3184d1567 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
220struct mwifiex_802_11_security { 222struct mwifiex_802_11_security {
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 52d218512c1..f3d5f23c91d 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 */
179static void 179static void
180mwifiex_wmm_queue_priorities_tid(u8 queue_priority[]) 180mwifiex_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;