diff options
author | Vasanthakumar Thiagarajan <vasanth@atheros.com> | 2010-07-22 02:24:11 -0700 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-07-26 15:32:41 -0400 |
commit | 68e8f2fae03cde0ba841325e2660b55fe49bf4b9 (patch) | |
tree | 011191db1afaa3933d1d83f5fcbee1af0f8904fe /drivers/net | |
parent | 2189d13f6cfc58627a01d6a91591e59a2fa62902 (diff) |
ath9k: Fix inconsistency between txq->stopped and the actual queue state
Sometimes txq state(txq->stopped) can be marked as started but the actual
queue may not be started (in ATH_WIPHY_SCAN state, for example). Fix this.
Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/virtual.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 4 |
3 files changed, 8 insertions, 4 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 6e486a508ed..998ae2c49ed 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -687,7 +687,7 @@ bool ath9k_all_wiphys_idle(struct ath_softc *sc); void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle); void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue); -void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue); +bool ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue); void ath_start_rfkill_poll(struct ath_softc *sc); extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c index 89423ca23d2..fd20241f57d 100644 --- a/drivers/net/wireless/ath/ath9k/virtual.c +++ b/drivers/net/wireless/ath/ath9k/virtual.c @@ -695,16 +695,18 @@ void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle) idle ? "idle" : "not-idle"); } /* Only bother starting a queue on an active virtual wiphy */ -void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue) +bool ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue) { struct ieee80211_hw *hw = sc->pri_wiphy->hw; unsigned int i; + bool txq_started = false; spin_lock_bh(&sc->wiphy_lock); /* Start the primary wiphy */ if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE) { ieee80211_wake_queue(hw, skb_queue); + txq_started = true; goto unlock; } @@ -718,11 +720,13 @@ void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue) hw = aphy->hw; ieee80211_wake_queue(hw, skb_queue); + txq_started = true; break; } unlock: spin_unlock_bh(&sc->wiphy_lock); + return txq_started; } /* Go ahead and propagate information to all virtual wiphys, it won't hurt */ diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 0644f1e9188..21aa5bdb259 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -2077,8 +2077,8 @@ static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq) spin_lock_bh(&txq->axq_lock); if (txq->stopped && sc->tx.pending_frames[qnum] < ATH_MAX_QDEPTH) { - ath_mac80211_start_queue(sc, qnum); - txq->stopped = 0; + if (ath_mac80211_start_queue(sc, qnum)) + txq->stopped = 0; } spin_unlock_bh(&txq->axq_lock); } |