aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/tx.c
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2011-04-18 07:15:28 -0400
committerLuciano Coelho <coelho@ti.com>2011-05-02 03:31:28 -0400
commit7dece1c8e1044287287d44ac183a946333b55fc3 (patch)
tree82330386e96e8292bdea78301af98c047eb8a51c /drivers/net/wireless/wl12xx/tx.c
parent2dc5a5c2c656b9029a0e635bb3a1cbcfbcb4ca5c (diff)
wl12xx: fix race condition during recovery in AP mode
When operating as AP, the TX queues are not stopped when we start recovery. mac80211 is notified only after the fact. When there is pending TX, it will be queued even after the FW is down. This leads to situations where the TX queues are stopped (because of the TX-watermark mechanism), and are never woken up when we return from recovery. Fix this by explicitly stopping the TX queues when before initiating recovery. Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx/tx.c')
-rw-r--r--drivers/net/wireless/wl12xx/tx.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index cc837bba5468..ca3ab1c1acef 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -769,8 +769,8 @@ void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid)
769 wl1271_handle_tx_low_watermark(wl); 769 wl1271_handle_tx_low_watermark(wl);
770} 770}
771 771
772/* caller must hold wl->mutex */ 772/* caller must hold wl->mutex and TX must be stopped */
773void wl1271_tx_reset(struct wl1271 *wl) 773void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues)
774{ 774{
775 int i; 775 int i;
776 struct sk_buff *skb; 776 struct sk_buff *skb;
@@ -806,8 +806,10 @@ void wl1271_tx_reset(struct wl1271 *wl)
806 /* 806 /*
807 * Make sure the driver is at a consistent state, in case this 807 * Make sure the driver is at a consistent state, in case this
808 * function is called from a context other than interface removal. 808 * function is called from a context other than interface removal.
809 * This call will always wake the TX queues.
809 */ 810 */
810 wl1271_handle_tx_low_watermark(wl); 811 if (reset_tx_queues)
812 wl1271_handle_tx_low_watermark(wl);
811 813
812 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) { 814 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) {
813 if (wl->tx_frames[i] == NULL) 815 if (wl->tx_frames[i] == NULL)