diff options
Diffstat (limited to 'drivers/net/wireless/wl12xx/tx.c')
-rw-r--r-- | drivers/net/wireless/wl12xx/tx.c | 60 |
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 | ||
239 | static 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 | |||
255 | out: | ||
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 | |||
265 | static 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 | |||
240 | void wl1271_tx_work_locked(struct wl1271 *wl) | 276 | void 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 | } |