linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/4] ath9k: always issue a full hw reset after waking up from full-sleep mode
@ 2011-11-16 12:08 Felix Fietkau
  2011-11-16 12:08 ` [PATCH 2/4] ath9k: rework power state handling Felix Fietkau
  0 siblings, 1 reply; 11+ messages in thread
From: Felix Fietkau @ 2011-11-16 12:08 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, mcgrof

After waking up from full sleep, registers are accessible, but rx/tx
typically fails. A fast channel change will not recover from this, so
ensure that a full-sleep -> wake transition is always followed by a full
reset.

The reason why this hasn't created any serious problems yet is that it's
hidden by the (wrong) behavior of enabling/disabling the radio when the
wiphy idle state changes.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/main.c |   12 ++++++++++--
 drivers/net/wireless/ath/ath9k/xmit.c |    2 +-
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index e43c41c..734e854 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -118,7 +118,7 @@ void ath9k_ps_restore(struct ath_softc *sc)
 	if (--sc->ps_usecount != 0)
 		goto unlock;
 
-	if (sc->ps_idle)
+	if (sc->ps_idle && (sc->ps_flags & PS_WAIT_FOR_TX_ACK))
 		mode = ATH9K_PM_FULL_SLEEP;
 	else if (sc->ps_enabled &&
 		 !(sc->ps_flags & (PS_WAIT_FOR_BEACON |
@@ -332,7 +332,8 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,
 		hchan = ah->curchan;
 	}
 
-	if (fastcc && !ath9k_hw_check_alive(ah))
+	if (fastcc && (ah->chip_fullsleep ||
+	    !ath9k_hw_check_alive(ah)))
 		fastcc = false;
 
 	if (!ath_prepare_reset(sc, retry_tx, flush))
@@ -1176,6 +1177,13 @@ static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 		}
 	}
 
+	/*
+	 * Cannot tx while the hardware is in full sleep, it first needs a full
+	 * chip reset to recover from that
+	 */
+	if (unlikely(sc->sc_ah->power_mode == ATH9K_PM_FULL_SLEEP))
+		goto exit;
+
 	if (unlikely(sc->sc_ah->power_mode != ATH9K_PM_AWAKE)) {
 		/*
 		 * We are using PS-Poll and mac80211 can request TX while in
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 55d077e..363bf33 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1955,7 +1955,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
 		skb_pull(skb, padsize);
 	}
 
-	if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) {
+	if ((sc->ps_flags & PS_WAIT_FOR_TX_ACK) && !txq->axq_depth) {
 		sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK;
 		ath_dbg(common, ATH_DBG_PS,
 			"Going back to sleep after having received TX status (0x%lx)\n",
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2011-12-06 20:20 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-16 12:08 [PATCH 1/4] ath9k: always issue a full hw reset after waking up from full-sleep mode Felix Fietkau
2011-11-16 12:08 ` [PATCH 2/4] ath9k: rework power state handling Felix Fietkau
2011-11-16 12:08   ` [PATCH 3/4] ath9k: only drop packets in drv_flush when asked to Felix Fietkau
2011-11-16 12:08     ` [PATCH 4/4] ath9k: cancel all workqueue activity when going idle Felix Fietkau
2011-11-16 17:42   ` [PATCH 2/4] ath9k: rework power state handling Luis R. Rodriguez
2011-11-16 18:16     ` Felix Fietkau
2011-11-16 18:23       ` Luis R. Rodriguez
2011-11-16 18:40         ` Paul Stewart
2011-11-16 23:52           ` Felix Fietkau
2011-12-06 20:04             ` John W. Linville
2011-12-06 20:20               ` Paul Stewart

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).