diff options
-rw-r--r-- | drivers/net/wireless/ti/wlcore/main.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wlcore/tx.c | 11 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wlcore/tx.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wlcore/wlcore.h | 3 |
4 files changed, 15 insertions, 1 deletions
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index bbab19a..d81c86c 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -5148,6 +5148,7 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size) wl->state = WL1271_STATE_OFF; wl->fw_type = WL12XX_FW_TYPE_NONE; mutex_init(&wl->mutex); + mutex_init(&wl->flush_mutex); order = get_order(WL1271_AGGR_BUFFER_SIZE); wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order); diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index f68567b..78bf1b9 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) diff --git a/drivers/net/wireless/ti/wlcore/tx.h b/drivers/net/wireless/ti/wlcore/tx.h index 6bf6956..e058a55 100644 --- a/drivers/net/wireless/ti/wlcore/tx.h +++ b/drivers/net/wireless/ti/wlcore/tx.h @@ -187,6 +187,7 @@ struct wl1271_tx_hw_res_if { enum wlcore_queue_stop_reason { WLCORE_QUEUE_STOP_REASON_WATERMARK, WLCORE_QUEUE_STOP_REASON_FW_RESTART, + WLCORE_QUEUE_STOP_REASON_FLUSH, }; static inline int wl1271_tx_get_queue(int queue) diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 6810543..99a0619 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -378,6 +378,9 @@ struct wl1271 { /* the current channel type */ enum nl80211_channel_type channel_type; + + /* mutex for protecting the tx_flush function */ + struct mutex flush_mutex; }; int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev); |