diff options
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_main.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_tx.c | 28 |
3 files changed, 22 insertions, 21 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h index cc974eae009..7f03f899b2b 100644 --- a/drivers/net/wireless/wl12xx/wl1271.h +++ b/drivers/net/wireless/wl12xx/wl1271.h | |||
@@ -491,7 +491,8 @@ int wl1271_plt_stop(struct wl1271 *wl); | |||
491 | 491 | ||
492 | #define WL1271_DEFAULT_POWER_LEVEL 0 | 492 | #define WL1271_DEFAULT_POWER_LEVEL 0 |
493 | 493 | ||
494 | #define WL1271_TX_QUEUE_MAX_LENGTH 20 | 494 | #define WL1271_TX_QUEUE_LOW_WATERMARK 10 |
495 | #define WL1271_TX_QUEUE_HIGH_WATERMARK 25 | ||
495 | 496 | ||
496 | /* WL1271 needs a 200ms sleep after power on, and a 20ms sleep before power | 497 | /* WL1271 needs a 200ms sleep after power on, and a 20ms sleep before power |
497 | on in case is has been shut down shortly before */ | 498 | on in case is has been shut down shortly before */ |
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 81fb02e8292..184264a53b2 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c | |||
@@ -791,15 +791,13 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
791 | * The workqueue is slow to process the tx_queue and we need stop | 791 | * The workqueue is slow to process the tx_queue and we need stop |
792 | * the queue here, otherwise the queue will get too long. | 792 | * the queue here, otherwise the queue will get too long. |
793 | */ | 793 | */ |
794 | if (skb_queue_len(&wl->tx_queue) >= WL1271_TX_QUEUE_MAX_LENGTH) { | 794 | if (skb_queue_len(&wl->tx_queue) >= WL1271_TX_QUEUE_HIGH_WATERMARK) { |
795 | ieee80211_stop_queues(wl->hw); | 795 | wl1271_debug(DEBUG_TX, "op_tx: stopping queues"); |
796 | 796 | ||
797 | /* | 797 | spin_lock_irqsave(&wl->wl_lock, flags); |
798 | * FIXME: this is racy, the variable is not properly | 798 | ieee80211_stop_queues(wl->hw); |
799 | * protected. Maybe fix this by removing the stupid | ||
800 | * variable altogether and checking the real queue state? | ||
801 | */ | ||
802 | set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); | 799 | set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); |
800 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
803 | } | 801 | } |
804 | 802 | ||
805 | return NETDEV_TX_OK; | 803 | return NETDEV_TX_OK; |
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c index 2e057b0e325..7926471cd09 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.c +++ b/drivers/net/wireless/wl12xx/wl1271_tx.c | |||
@@ -278,22 +278,12 @@ void wl1271_tx_work(struct work_struct *work) | |||
278 | 278 | ||
279 | ret = wl1271_tx_frame(wl, skb); | 279 | ret = wl1271_tx_frame(wl, skb); |
280 | if (ret == -EBUSY) { | 280 | if (ret == -EBUSY) { |
281 | /* firmware buffer is full, stop queues */ | 281 | /* firmware buffer is full, lets stop transmitting. */ |
282 | wl1271_debug(DEBUG_TX, "tx_work: fw buffer full, " | ||
283 | "stop queues"); | ||
284 | ieee80211_stop_queues(wl->hw); | ||
285 | set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); | ||
286 | skb_queue_head(&wl->tx_queue, skb); | 282 | skb_queue_head(&wl->tx_queue, skb); |
287 | goto out_ack; | 283 | goto out_ack; |
288 | } else if (ret < 0) { | 284 | } else if (ret < 0) { |
289 | dev_kfree_skb(skb); | 285 | dev_kfree_skb(skb); |
290 | goto out_ack; | 286 | goto out_ack; |
291 | } else if (test_and_clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED, | ||
292 | &wl->flags)) { | ||
293 | /* firmware buffer has space, restart queues */ | ||
294 | wl1271_debug(DEBUG_TX, | ||
295 | "complete_packet: waking queues"); | ||
296 | ieee80211_wake_queues(wl->hw); | ||
297 | } | 287 | } |
298 | } | 288 | } |
299 | 289 | ||
@@ -380,8 +370,6 @@ void wl1271_tx_complete(struct wl1271 *wl) | |||
380 | u32 count, fw_counter; | 370 | u32 count, fw_counter; |
381 | u32 i; | 371 | u32 i; |
382 | 372 | ||
383 | wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count); | ||
384 | |||
385 | /* read the tx results from the chipset */ | 373 | /* read the tx results from the chipset */ |
386 | wl1271_read(wl, le32_to_cpu(memmap->tx_result), | 374 | wl1271_read(wl, le32_to_cpu(memmap->tx_result), |
387 | wl->tx_res_if, sizeof(*wl->tx_res_if), false); | 375 | wl->tx_res_if, sizeof(*wl->tx_res_if), false); |
@@ -393,6 +381,7 @@ void wl1271_tx_complete(struct wl1271 *wl) | |||
393 | tx_result_host_counter), fw_counter); | 381 | tx_result_host_counter), fw_counter); |
394 | 382 | ||
395 | count = fw_counter - wl->tx_results_count; | 383 | count = fw_counter - wl->tx_results_count; |
384 | wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count); | ||
396 | 385 | ||
397 | /* verify that the result buffer is not getting overrun */ | 386 | /* verify that the result buffer is not getting overrun */ |
398 | if (unlikely(count > TX_HW_RESULT_QUEUE_LEN)) | 387 | if (unlikely(count > TX_HW_RESULT_QUEUE_LEN)) |
@@ -409,6 +398,19 @@ void wl1271_tx_complete(struct wl1271 *wl) | |||
409 | 398 | ||
410 | wl->tx_results_count++; | 399 | wl->tx_results_count++; |
411 | } | 400 | } |
401 | |||
402 | if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) && | ||
403 | skb_queue_len(&wl->tx_queue) <= WL1271_TX_QUEUE_LOW_WATERMARK) { | ||
404 | unsigned long flags; | ||
405 | |||
406 | /* firmware buffer has space, restart queues */ | ||
407 | wl1271_debug(DEBUG_TX, "tx_complete: waking queues"); | ||
408 | spin_lock_irqsave(&wl->wl_lock, flags); | ||
409 | ieee80211_wake_queues(wl->hw); | ||
410 | clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); | ||
411 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
412 | ieee80211_queue_work(wl->hw, &wl->tx_work); | ||
413 | } | ||
412 | } | 414 | } |
413 | 415 | ||
414 | /* caller must hold wl->mutex */ | 416 | /* caller must hold wl->mutex */ |