diff options
author | Arik Nemtsov <arik@wizery.com> | 2012-05-18 07:46:39 +0300 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2012-06-06 19:28:05 +0300 |
commit | 2c38849f4a247673c8203a569444042e32d82410 (patch) | |
tree | 86b41dd4670f9d1ffa9997cc43ca4565a5050c2b /drivers/net/wireless/ti/wlcore/tx.c | |
parent | wlcore: add stop reason bitmap for waking/starting queues (diff) | |
download | linux-dev-2c38849f4a247673c8203a569444042e32d82410.tar.xz linux-dev-2c38849f4a247673c8203a569444042e32d82410.zip |
wlcore: stop queues on Tx flush
Stop network queues during Tx flush, and also drop other internal
mac80211 packets (mgmt) that may arrive when the queues are stopped.
When flush is done all driver queues are clear, forcefully if needed.
Protect the Tx flush operation with a new mutex, to prevent concurrency
that can mess us queue state.
Based on a patch by Eliad Peller <eliad@wizery.com>
Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless/ti/wlcore/tx.c')
-rw-r--r-- | drivers/net/wireless/ti/wlcore/tx.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index f68567b1524c..78bf1b9208a9 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c @@ -1024,6 +1024,11 @@ void wl1271_tx_flush(struct wl1271 *wl) int i; timeout = jiffies + usecs_to_jiffies(WL1271_TX_FLUSH_TIMEOUT); + /* only one flush should be in progress, for consistent queue state */ + mutex_lock(&wl->flush_mutex); + + wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_FLUSH); + while (!time_after(jiffies, timeout)) { mutex_lock(&wl->mutex); wl1271_debug(DEBUG_TX, "flushing tx buffer: %d %d", @@ -1032,7 +1037,7 @@ void wl1271_tx_flush(struct wl1271 *wl) if ((wl->tx_frames_cnt == 0) && (wl1271_tx_total_queue_count(wl) == 0)) { mutex_unlock(&wl->mutex); - return; + goto out; } mutex_unlock(&wl->mutex); msleep(1); @@ -1045,6 +1050,10 @@ void wl1271_tx_flush(struct wl1271 *wl) for (i = 0; i < WL12XX_MAX_LINKS; i++) wl1271_tx_reset_link_queues(wl, i); mutex_unlock(&wl->mutex); + +out: + wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_FLUSH); + mutex_unlock(&wl->flush_mutex); } u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set) |