]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
ath9k: reorganize patches, reset hardware after full sleep (fixes #10349)
authorFelix Fietkau <nbd@openwrt.org>
Tue, 15 Nov 2011 14:53:21 +0000 (14:53 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Tue, 15 Nov 2011 14:53:21 +0000 (14:53 +0000)
SVN-Revision: 29155

package/mac80211/patches/560-ath9k_reset_after_full_sleep.patch [new file with mode: 0644]
package/mac80211/patches/561-ath9k_fix_ps_idle_handling.patch [moved from package/mac80211/patches/560-ath9k_fix_radio_stop.patch with 86% similarity]
package/mac80211/patches/562-ath9k_fix_flush.patch [moved from package/mac80211/patches/561-ath9k_fix_flush.patch with 87% similarity]
package/mac80211/patches/562-ath9k_fix_led.patch [deleted file]
package/mac80211/patches/563-ath9k_fix_full_sleep_tx.patch [deleted file]

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 (file)
index 0000000..9a5b580
--- /dev/null
@@ -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",
similarity index 86%
rename from package/mac80211/patches/560-ath9k_fix_radio_stop.patch
rename to package/mac80211/patches/561-ath9k_fix_ps_idle_handling.patch
index 2367ffa6abce3374e8738f43766950c162aefe0d..40f24e1ecadbd11f62dfb32f72fa164f20a93f28 100644 (file)
@@ -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);
        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
        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);
  
 +      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);
  
 +      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;
        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.
         */
  
        /*
         * 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;
similarity index 87%
rename from package/mac80211/patches/561-ath9k_fix_flush.patch
rename to package/mac80211/patches/562-ath9k_fix_flush.patch
index df208906036d8a935e835e4a580fb4db5af1b261..a5329adc968534ed0bb8689b0a40fa9a10bc7728 100644 (file)
@@ -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 (file)
index 0ef1668..0000000
+++ /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 (file)
index 17575b9..0000000
+++ /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",