summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ti
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2012-11-28 10:42:44 +0100
committerLuciano Coelho <coelho@ti.com>2012-12-11 11:37:22 +0100
commitd6037d22f30738e942ddfd29e3fef17deb075420 (patch)
treeb2eb73c6cf0c538f1523f5c5119b365db8e6c591 /drivers/net/wireless/ti
parentwlcore: use separate HW queue for each AC in each vif (diff)
downloadlinux-d6037d22f30738e942ddfd29e3fef17deb075420.tar.xz
linux-d6037d22f30738e942ddfd29e3fef17deb075420.zip
wlcore: don't take mutex before stopping queues
Protect all functions touching queue_stop_reasons by spin-lock, since they are accessed by op_tx. Now there's no need to take the mutex before caling wlcore_queue_xxx functions. Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless/ti')
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c9
-rw-r--r--drivers/net/wireless/ti/wlcore/tx.c23
-rw-r--r--drivers/net/wireless/ti/wlcore/tx.h9
3 files changed, 31 insertions, 10 deletions
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 89f69d949443..56a5308b5b03 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -1200,8 +1200,8 @@ static void wl1271_op_tx(struct ieee80211_hw *hw,
*/
if (hlid == WL12XX_INVALID_LINK_ID ||
(!test_bit(hlid, wlvif->links_map)) ||
- (wlcore_is_queue_stopped(wl, wlvif, q) &&
- !wlcore_is_queue_stopped_by_reason(wl, wlvif, q,
+ (wlcore_is_queue_stopped_locked(wl, wlvif, q) &&
+ !wlcore_is_queue_stopped_by_reason_locked(wl, wlvif, q,
WLCORE_QUEUE_STOP_REASON_WATERMARK))) {
wl1271_debug(DEBUG_TX, "DROP skb hlid %d q %d", hlid, q);
ieee80211_free_txskb(hw, skb);
@@ -1220,7 +1220,7 @@ static void wl1271_op_tx(struct ieee80211_hw *hw,
* the queue here, otherwise the queue will get too long.
*/
if (wlvif->tx_queue_count[q] >= WL1271_TX_QUEUE_HIGH_WATERMARK &&
- !wlcore_is_queue_stopped_by_reason(wl, wlvif, q,
+ !wlcore_is_queue_stopped_by_reason_locked(wl, wlvif, q,
WLCORE_QUEUE_STOP_REASON_WATERMARK)) {
wl1271_debug(DEBUG_TX, "op_tx: stopping queues for q %d", q);
wlcore_stop_queue_locked(wl, wlvif, q,
@@ -3229,10 +3229,7 @@ static int wlcore_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
* stop the queues and flush to ensure the next packets are
* in sync with FW spare block accounting
*/
- mutex_lock(&wl->mutex);
wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_SPARE_BLK);
- mutex_unlock(&wl->mutex);
-
wl1271_tx_flush(wl);
}
diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c
index d464a8eba7b0..894ddc73a890 100644
--- a/drivers/net/wireless/ti/wlcore/tx.c
+++ b/drivers/net/wireless/ti/wlcore/tx.c
@@ -1288,13 +1288,32 @@ bool wlcore_is_queue_stopped_by_reason(struct wl1271 *wl,
struct wl12xx_vif *wlvif, u8 queue,
enum wlcore_queue_stop_reason reason)
{
+ unsigned long flags;
+ bool stopped;
+
+ spin_lock_irqsave(&wl->wl_lock, flags);
+ stopped = wlcore_is_queue_stopped_by_reason_locked(wl, wlvif, queue,
+ reason);
+ spin_unlock_irqrestore(&wl->wl_lock, flags);
+
+ return stopped;
+}
+
+bool wlcore_is_queue_stopped_by_reason_locked(struct wl1271 *wl,
+ struct wl12xx_vif *wlvif, u8 queue,
+ enum wlcore_queue_stop_reason reason)
+{
int hwq = wlcore_tx_get_mac80211_queue(wlvif, queue);
+
+ WARN_ON_ONCE(!spin_is_locked(&wl->wl_lock));
return test_bit(reason, &wl->queue_stop_reasons[hwq]);
}
-bool wlcore_is_queue_stopped(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u8 queue)
+bool wlcore_is_queue_stopped_locked(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+ u8 queue)
{
int hwq = wlcore_tx_get_mac80211_queue(wlvif, queue);
+
+ WARN_ON_ONCE(!spin_is_locked(&wl->wl_lock));
return !!wl->queue_stop_reasons[hwq];
}
diff --git a/drivers/net/wireless/ti/wlcore/tx.h b/drivers/net/wireless/ti/wlcore/tx.h
index 751bb6f46cbf..55aa4acf9105 100644
--- a/drivers/net/wireless/ti/wlcore/tx.h
+++ b/drivers/net/wireless/ti/wlcore/tx.h
@@ -268,8 +268,13 @@ void wlcore_wake_queues(struct wl1271 *wl,
bool wlcore_is_queue_stopped_by_reason(struct wl1271 *wl,
struct wl12xx_vif *wlvif, u8 queue,
enum wlcore_queue_stop_reason reason);
-bool wlcore_is_queue_stopped(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u8 queue);
+bool
+wlcore_is_queue_stopped_by_reason_locked(struct wl1271 *wl,
+ struct wl12xx_vif *wlvif,
+ u8 queue,
+ enum wlcore_queue_stop_reason reason);
+bool wlcore_is_queue_stopped_locked(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+ u8 queue);
/* from main.c */
void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid);