aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.c2
-rw-r--r--drivers/net/wireless/wl12xx/main.c12
-rw-r--r--drivers/net/wireless/wl12xx/tx.c60
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h3
4 files changed, 60 insertions, 17 deletions
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index c2cd58074372..ec6077760157 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -225,7 +225,7 @@ static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
225 char buf[20]; 225 char buf[20];
226 int res; 226 int res;
227 227
228 queue_len = skb_queue_len(&wl->tx_queue); 228 queue_len = wl->tx_queue_count;
229 229
230 res = scnprintf(buf, sizeof(buf), "%u\n", queue_len); 230 res = scnprintf(buf, sizeof(buf), "%u\n", queue_len);
231 return simple_read_from_buffer(userbuf, count, ppos, buf, res); 231 return simple_read_from_buffer(userbuf, count, ppos, buf, res);
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 8c50d3b3fabb..062247ef3ad2 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -570,7 +570,7 @@ static void wl1271_irq_work(struct work_struct *work)
570 570
571 /* Check if any tx blocks were freed */ 571 /* Check if any tx blocks were freed */
572 if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && 572 if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) &&
573 !skb_queue_empty(&wl->tx_queue)) { 573 wl->tx_queue_count) {
574 /* 574 /*
575 * In order to avoid starvation of the TX path, 575 * In order to avoid starvation of the TX path,
576 * call the work function directly. 576 * call the work function directly.
@@ -891,6 +891,7 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
891 struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); 891 struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
892 struct ieee80211_sta *sta = txinfo->control.sta; 892 struct ieee80211_sta *sta = txinfo->control.sta;
893 unsigned long flags; 893 unsigned long flags;
894 int q;
894 895
895 /* 896 /*
896 * peek into the rates configured in the STA entry. 897 * peek into the rates configured in the STA entry.
@@ -918,10 +919,12 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
918 set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags); 919 set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
919 } 920 }
920#endif 921#endif
922 wl->tx_queue_count++;
921 spin_unlock_irqrestore(&wl->wl_lock, flags); 923 spin_unlock_irqrestore(&wl->wl_lock, flags);
922 924
923 /* queue the packet */ 925 /* queue the packet */
924 skb_queue_tail(&wl->tx_queue, skb); 926 q = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
927 skb_queue_tail(&wl->tx_queue[q], skb);
925 928
926 /* 929 /*
927 * The chip specific setup must run before the first TX packet - 930 * The chip specific setup must run before the first TX packet -
@@ -935,7 +938,7 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
935 * The workqueue is slow to process the tx_queue and we need stop 938 * The workqueue is slow to process the tx_queue and we need stop
936 * the queue here, otherwise the queue will get too long. 939 * the queue here, otherwise the queue will get too long.
937 */ 940 */
938 if (skb_queue_len(&wl->tx_queue) >= WL1271_TX_QUEUE_HIGH_WATERMARK) { 941 if (wl->tx_queue_count >= WL1271_TX_QUEUE_HIGH_WATERMARK) {
939 wl1271_debug(DEBUG_TX, "op_tx: stopping queues"); 942 wl1271_debug(DEBUG_TX, "op_tx: stopping queues");
940 943
941 spin_lock_irqsave(&wl->wl_lock, flags); 944 spin_lock_irqsave(&wl->wl_lock, flags);
@@ -2719,7 +2722,8 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
2719 wl->hw = hw; 2722 wl->hw = hw;
2720 wl->plat_dev = plat_dev; 2723 wl->plat_dev = plat_dev;
2721 2724
2722 skb_queue_head_init(&wl->tx_queue); 2725 for (i = 0; i < NUM_TX_QUEUES; i++)
2726 skb_queue_head_init(&wl->tx_queue[i]);
2723 2727
2724 INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work); 2728 INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work);
2725 INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work); 2729 INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work);
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index d332b3f6d0fa..b44c75cd8c1e 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -125,7 +125,6 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
125 /* queue (we use same identifiers for tid's and ac's */ 125 /* queue (we use same identifiers for tid's and ac's */
126 ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); 126 ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
127 desc->tid = ac; 127 desc->tid = ac;
128
129 desc->aid = TX_HW_DEFAULT_AID; 128 desc->aid = TX_HW_DEFAULT_AID;
130 desc->reserved = 0; 129 desc->reserved = 0;
131 130
@@ -228,7 +227,7 @@ static void handle_tx_low_watermark(struct wl1271 *wl)
228 unsigned long flags; 227 unsigned long flags;
229 228
230 if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) && 229 if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) &&
231 skb_queue_len(&wl->tx_queue) <= WL1271_TX_QUEUE_LOW_WATERMARK) { 230 wl->tx_queue_count <= WL1271_TX_QUEUE_LOW_WATERMARK) {
232 /* firmware buffer has space, restart queues */ 231 /* firmware buffer has space, restart queues */
233 spin_lock_irqsave(&wl->wl_lock, flags); 232 spin_lock_irqsave(&wl->wl_lock, flags);
234 ieee80211_wake_queues(wl->hw); 233 ieee80211_wake_queues(wl->hw);
@@ -237,6 +236,43 @@ static void handle_tx_low_watermark(struct wl1271 *wl)
237 } 236 }
238} 237}
239 238
239static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl)
240{
241 struct sk_buff *skb = NULL;
242 unsigned long flags;
243
244 skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_VO]);
245 if (skb)
246 goto out;
247 skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_VI]);
248 if (skb)
249 goto out;
250 skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_BE]);
251 if (skb)
252 goto out;
253 skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_BK]);
254
255out:
256 if (skb) {
257 spin_lock_irqsave(&wl->wl_lock, flags);
258 wl->tx_queue_count--;
259 spin_unlock_irqrestore(&wl->wl_lock, flags);
260 }
261
262 return skb;
263}
264
265static void wl1271_skb_queue_head(struct wl1271 *wl, struct sk_buff *skb)
266{
267 unsigned long flags;
268 int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
269
270 skb_queue_head(&wl->tx_queue[q], skb);
271 spin_lock_irqsave(&wl->wl_lock, flags);
272 wl->tx_queue_count++;
273 spin_unlock_irqrestore(&wl->wl_lock, flags);
274}
275
240void wl1271_tx_work_locked(struct wl1271 *wl) 276void wl1271_tx_work_locked(struct wl1271 *wl)
241{ 277{
242 struct sk_buff *skb; 278 struct sk_buff *skb;
@@ -270,7 +306,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
270 wl1271_acx_rate_policies(wl); 306 wl1271_acx_rate_policies(wl);
271 } 307 }
272 308
273 while ((skb = skb_dequeue(&wl->tx_queue))) { 309 while ((skb = wl1271_skb_dequeue(wl))) {
274 if (!woken_up) { 310 if (!woken_up) {
275 ret = wl1271_ps_elp_wakeup(wl, false); 311 ret = wl1271_ps_elp_wakeup(wl, false);
276 if (ret < 0) 312 if (ret < 0)
@@ -284,9 +320,9 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
284 * Aggregation buffer is full. 320 * Aggregation buffer is full.
285 * Flush buffer and try again. 321 * Flush buffer and try again.
286 */ 322 */
287 skb_queue_head(&wl->tx_queue, skb); 323 wl1271_skb_queue_head(wl, skb);
288 wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, 324 wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf,
289 buf_offset, true); 325 buf_offset, true);
290 sent_packets = true; 326 sent_packets = true;
291 buf_offset = 0; 327 buf_offset = 0;
292 continue; 328 continue;
@@ -295,7 +331,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
295 * Firmware buffer is full. 331 * Firmware buffer is full.
296 * Queue back last skb, and stop aggregating. 332 * Queue back last skb, and stop aggregating.
297 */ 333 */
298 skb_queue_head(&wl->tx_queue, skb); 334 wl1271_skb_queue_head(wl, skb);
299 /* No work left, avoid scheduling redundant tx work */ 335 /* No work left, avoid scheduling redundant tx work */
300 set_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags); 336 set_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
301 goto out_ack; 337 goto out_ack;
@@ -440,10 +476,13 @@ void wl1271_tx_reset(struct wl1271 *wl)
440 struct sk_buff *skb; 476 struct sk_buff *skb;
441 477
442 /* TX failure */ 478 /* TX failure */
443 while ((skb = skb_dequeue(&wl->tx_queue))) { 479 for (i = 0; i < NUM_TX_QUEUES; i++) {
444 wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); 480 while ((skb = skb_dequeue(&wl->tx_queue[i]))) {
445 ieee80211_tx_status(wl->hw, skb); 481 wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb);
482 ieee80211_tx_status(wl->hw, skb);
483 }
446 } 484 }
485 wl->tx_queue_count = 0;
447 486
448 /* 487 /*
449 * Make sure the driver is at a consistent state, in case this 488 * Make sure the driver is at a consistent state, in case this
@@ -472,8 +511,7 @@ void wl1271_tx_flush(struct wl1271 *wl)
472 mutex_lock(&wl->mutex); 511 mutex_lock(&wl->mutex);
473 wl1271_debug(DEBUG_TX, "flushing tx buffer: %d", 512 wl1271_debug(DEBUG_TX, "flushing tx buffer: %d",
474 wl->tx_frames_cnt); 513 wl->tx_frames_cnt);
475 if ((wl->tx_frames_cnt == 0) && 514 if ((wl->tx_frames_cnt == 0) && (wl->tx_queue_count == 0)) {
476 skb_queue_empty(&wl->tx_queue)) {
477 mutex_unlock(&wl->mutex); 515 mutex_unlock(&wl->mutex);
478 return; 516 return;
479 } 517 }
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 07c2297b89a2..ce3d31f98c55 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -292,7 +292,8 @@ struct wl1271 {
292 int session_counter; 292 int session_counter;
293 293
294 /* Frames scheduled for transmission, not handled yet */ 294 /* Frames scheduled for transmission, not handled yet */
295 struct sk_buff_head tx_queue; 295 struct sk_buff_head tx_queue[NUM_TX_QUEUES];
296 int tx_queue_count;
296 297
297 struct work_struct tx_work; 298 struct work_struct tx_work;
298 299