aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/wl12xx/tx.c')
-rw-r--r--drivers/net/wireless/wl12xx/tx.c60
1 files changed, 49 insertions, 11 deletions
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 }