summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>2011-11-15 14:53:21 +0000
committernbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>2011-11-15 14:53:21 +0000
commitccd11de0ba26fb0f2f95e5936820a382c30ab43a (patch)
tree4a5f777fa4e1a7b8eac129da51325763ecf42438
parente512826d645cf8610454a41755b9671aeb42c827 (diff)
ath9k: reorganize patches, reset hardware after full sleep (fixes #10349)
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@29155 3c298f89-4303-0410-b956-a3cf2f4a3e73
-rw-r--r--package/mac80211/patches/560-ath9k_reset_after_full_sleep.patch68
-rw-r--r--package/mac80211/patches/561-ath9k_fix_ps_idle_handling.patch (renamed from package/mac80211/patches/560-ath9k_fix_radio_stop.patch)40
-rw-r--r--package/mac80211/patches/562-ath9k_fix_flush.patch (renamed from package/mac80211/patches/561-ath9k_fix_flush.patch)4
-rw-r--r--package/mac80211/patches/562-ath9k_fix_led.patch30
-rw-r--r--package/mac80211/patches/563-ath9k_fix_full_sleep_tx.patch22
5 files changed, 98 insertions, 66 deletions
diff --git a/package/mac80211/patches/560-ath9k_reset_after_full_sleep.patch b/package/mac80211/patches/560-ath9k_reset_after_full_sleep.patch
new file mode 100644
index 000000000..9a5b58001
--- /dev/null
+++ b/package/mac80211/patches/560-ath9k_reset_after_full_sleep.patch
@@ -0,0 +1,68 @@
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -619,6 +619,7 @@ struct ath_softc {
+ u16 curtxpow;
+ bool ps_enabled;
+ bool ps_idle;
++ bool ps_fullsleep;
+ short nbcnvifs;
+ short nvifs;
+ unsigned long ps_usecount;
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -118,9 +118,10 @@ void ath9k_ps_restore(struct ath_softc *
+ 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_fullsleep = true;
++ } else if (sc->ps_enabled &&
+ !(sc->ps_flags & (PS_WAIT_FOR_BEACON |
+ PS_WAIT_FOR_CAB |
+ PS_WAIT_FOR_PSPOLL_DATA |
+@@ -275,6 +276,7 @@ static bool ath_complete_reset(struct at
+ sc->config.txpowlimit, &sc->curtxpow);
+ ath9k_hw_set_interrupts(ah);
+ ath9k_hw_enable_interrupts(ah);
++ sc->ps_fullsleep = false;
+
+ if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) && start) {
+ if (sc->sc_flags & SC_OP_BEACONS)
+@@ -332,7 +334,8 @@ static int ath_reset_internal(struct ath
+ hchan = ah->curchan;
+ }
+
+- if (fastcc && !ath9k_hw_check_alive(ah))
++ if (fastcc && (sc->ps_fullsleep ||
++ !ath9k_hw_check_alive(ah)))
+ fastcc = false;
+
+ if (!ath_prepare_reset(sc, retry_tx, flush))
+@@ -1173,6 +1176,13 @@ static void ath9k_tx(struct ieee80211_hw
+ }
+ }
+
++ /*
++ * 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
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -1983,7 +1983,7 @@ static void ath_tx_complete(struct ath_s
+ 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",
diff --git a/package/mac80211/patches/560-ath9k_fix_radio_stop.patch b/package/mac80211/patches/561-ath9k_fix_ps_idle_handling.patch
index 2367ffa6a..40f24e1ec 100644
--- a/package/mac80211/patches/560-ath9k_fix_radio_stop.patch
+++ b/package/mac80211/patches/561-ath9k_fix_ps_idle_handling.patch
@@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -880,82 +880,6 @@ chip_reset:
+@@ -883,82 +883,6 @@ chip_reset:
#undef SCHED_INTR
}
@@ -83,7 +83,7 @@
static int ath_reset(struct ath_softc *sc, bool retry_tx)
{
int r;
-@@ -1091,6 +1015,9 @@ static int ath9k_start(struct ieee80211_
+@@ -1094,6 +1018,9 @@ static int ath9k_start(struct ieee80211_
* and then setup of the interrupt mask.
*/
spin_lock_bh(&sc->sc_pcu_lock);
@@ -93,13 +93,15 @@
r = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
if (r) {
ath_err(common,
-@@ -1129,6 +1056,16 @@ static int ath9k_start(struct ieee80211_
+@@ -1132,6 +1059,18 @@ static int ath9k_start(struct ieee80211_
goto mutex_unlock;
}
-+ ath9k_hw_cfg_output(ah, ah->led_pin,
-+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
-+ ath9k_hw_set_gpio(ah, ah->led_pin, 0);
++ if (ah->led_pin >= 0) {
++ ath9k_hw_cfg_output(ah, ah->led_pin,
++ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
++ ath9k_hw_set_gpio(ah, ah->led_pin, 0);
++ }
+
+ /*
+ * Reset key cache to sane defaults (all entries cleared) instead of
@@ -110,7 +112,15 @@
spin_unlock_bh(&sc->sc_pcu_lock);
if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) &&
-@@ -1248,33 +1185,39 @@ static void ath9k_stop(struct ieee80211_
+@@ -1229,6 +1168,7 @@ static void ath9k_stop(struct ieee80211_
+ struct ath_softc *sc = hw->priv;
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_common *common = ath9k_hw_common(ah);
++ bool prev_idle;
+
+ mutex_lock(&sc->mutex);
+
+@@ -1258,35 +1198,45 @@ static void ath9k_stop(struct ieee80211_
* before setting the invalid flag. */
ath9k_hw_disable_interrupts(ah);
@@ -128,12 +138,15 @@
+ tasklet_kill(&sc->intr_tq);
+ tasklet_kill(&sc->bcon_tasklet);
+
++ prev_idle = sc->ps_idle;
+ sc->ps_idle = true;
+
+ spin_lock_bh(&sc->sc_pcu_lock);
+
-+ ath9k_hw_set_gpio(ah, ah->led_pin, 1);
-+ ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
++ if (ah->led_pin >= 0) {
++ ath9k_hw_set_gpio(ah, ah->led_pin, 1);
++ ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
++ }
+
+ ath_prepare_reset(sc, false, true);
@@ -166,8 +179,11 @@
+ ath9k_ps_restore(sc);
sc->sc_flags |= SC_OP_INVALID;
++ sc->ps_idle = prev_idle;
+
+ mutex_unlock(&sc->mutex);
-@@ -1598,8 +1541,8 @@ static int ath9k_config(struct ieee80211
+@@ -1608,8 +1558,8 @@ static int ath9k_config(struct ieee80211
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_conf *conf = &hw->conf;
@@ -177,7 +193,7 @@
mutex_lock(&sc->mutex);
/*
-@@ -1608,16 +1551,8 @@ static int ath9k_config(struct ieee80211
+@@ -1618,16 +1568,8 @@ static int ath9k_config(struct ieee80211
* of the changes. Likewise we must only disable the radio towards
* the end.
*/
@@ -195,7 +211,7 @@
/*
* We just prepare to enable PS. We have to wait until our AP has
-@@ -1742,19 +1677,13 @@ static int ath9k_config(struct ieee80211
+@@ -1752,19 +1694,13 @@ static int ath9k_config(struct ieee80211
ath_dbg(common, ATH_DBG_CONFIG,
"Set power: %d\n", conf->power_level);
sc->config.txpowlimit = 2 * conf->power_level;
diff --git a/package/mac80211/patches/561-ath9k_fix_flush.patch b/package/mac80211/patches/562-ath9k_fix_flush.patch
index df2089060..a5329adc9 100644
--- a/package/mac80211/patches/561-ath9k_fix_flush.patch
+++ b/package/mac80211/patches/562-ath9k_fix_flush.patch
@@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -2251,9 +2251,6 @@ static void ath9k_flush(struct ieee80211
+@@ -2268,9 +2268,6 @@ static void ath9k_flush(struct ieee80211
return;
}
@@ -10,7 +10,7 @@
for (j = 0; j < timeout; j++) {
bool npend = false;
-@@ -2271,21 +2268,22 @@ static void ath9k_flush(struct ieee80211
+@@ -2288,21 +2285,22 @@ static void ath9k_flush(struct ieee80211
}
if (!npend)
diff --git a/package/mac80211/patches/562-ath9k_fix_led.patch b/package/mac80211/patches/562-ath9k_fix_led.patch
deleted file mode 100644
index 0ef16684b..000000000
--- a/package/mac80211/patches/562-ath9k_fix_led.patch
+++ /dev/null
@@ -1,30 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1056,9 +1056,11 @@ static int ath9k_start(struct ieee80211_
- goto mutex_unlock;
- }
-
-- ath9k_hw_cfg_output(ah, ah->led_pin,
-- AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
-- ath9k_hw_set_gpio(ah, ah->led_pin, 0);
-+ if (ah->led_pin >= 0) {
-+ ath9k_hw_cfg_output(ah, ah->led_pin,
-+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
-+ ath9k_hw_set_gpio(ah, ah->led_pin, 0);
-+ }
-
- /*
- * Reset key cache to sane defaults (all entries cleared) instead of
-@@ -1197,8 +1199,10 @@ static void ath9k_stop(struct ieee80211_
-
- spin_lock_bh(&sc->sc_pcu_lock);
-
-- ath9k_hw_set_gpio(ah, ah->led_pin, 1);
-- ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
-+ if (ah->led_pin >= 0) {
-+ ath9k_hw_set_gpio(ah, ah->led_pin, 1);
-+ ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
-+ }
-
- ath_prepare_reset(sc, false, true);
-
diff --git a/package/mac80211/patches/563-ath9k_fix_full_sleep_tx.patch b/package/mac80211/patches/563-ath9k_fix_full_sleep_tx.patch
deleted file mode 100644
index 17575b9e4..000000000
--- a/package/mac80211/patches/563-ath9k_fix_full_sleep_tx.patch
+++ /dev/null
@@ -1,22 +0,0 @@
---- 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 *
- 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 |
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -1983,7 +1983,7 @@ static void ath_tx_complete(struct ath_s
- 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",