ath9k: add some more pending fixes / optimizations
authorFelix Fietkau <nbd@openwrt.org>
Mon, 14 Oct 2013 19:38:42 +0000 (19:38 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Mon, 14 Oct 2013 19:38:42 +0000 (19:38 +0000)
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
SVN-Revision: 38398

package/kernel/mac80211/patches/300-pending_work.patch
package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
package/kernel/mac80211/patches/501-ath9k-eeprom_endianess.patch
package/kernel/mac80211/patches/502-ath9k_ahb_init.patch
package/kernel/mac80211/patches/521-ath9k_cur_txpower.patch
package/kernel/mac80211/patches/524-ath9k_use_configured_antenna_gain.patch
package/kernel/mac80211/patches/530-ath9k_extra_leds.patch
package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch
package/kernel/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch

index 91781f92fd6b33905fd89e69c6d560b4d6aa1ad3..81f03c532efe2c745e5d188cc6fcae7e049bc7f3 100644 (file)
 +
 +      if (!ath_tid_has_buffered(tid))
 +              return false;
-+
-+      INIT_LIST_HEAD(&bf_q);
  
 -              ath_tx_fill_desc(sc, bf, txq, aggr_len);
 -              ath_tx_txqaddbuf(sc, txq, &bf_q, false);
 -      } while (txq->axq_ampdu_depth < ATH_AGGR_MIN_QDEPTH &&
 -               status != ATH_AGGR_BAW_CLOSED);
++      INIT_LIST_HEAD(&bf_q);
++
 +      bf = ath_tx_get_tid_subframe(sc, txq, tid, &tid_q);
 +      if (!bf)
 +              return false;
                        list_del(&bf->list);
  
                        ath_tx_return_buffer(sc, bf);
-@@ -1665,25 +1820,27 @@ void ath_tx_cleanupq(struct ath_softc *s
+@@ -1630,6 +1785,9 @@ bool ath_drain_all_txq(struct ath_softc 
+               if (!ATH_TXQ_SETUP(sc, i))
+                       continue;
++              if (!sc->tx.txq[i].axq_depth)
++                      continue;
++
+               if (ath9k_hw_numtxpending(ah, sc->tx.txq[i].axq_qnum))
+                       npend |= BIT(i);
+       }
+@@ -1665,25 +1823,27 @@ void ath_tx_cleanupq(struct ath_softc *s
   */
  void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
  {
                        tid = list_first_entry(&ac->tid_q, struct ath_atx_tid,
                                               list);
                        list_del(&tid->list);
-@@ -1692,17 +1849,17 @@ void ath_txq_schedule(struct ath_softc *
+@@ -1692,17 +1852,17 @@ void ath_txq_schedule(struct ath_softc *
                        if (tid->paused)
                                continue;
  
                                break;
                }
  
-@@ -1711,9 +1868,17 @@ void ath_txq_schedule(struct ath_softc *
+@@ -1711,9 +1871,17 @@ void ath_txq_schedule(struct ath_softc *
                        list_add_tail(&ac->list, &txq->axq_acq);
                }
  
        }
  
        rcu_read_unlock();
-@@ -1787,74 +1952,28 @@ static void ath_tx_txqaddbuf(struct ath_
+@@ -1787,74 +1955,28 @@ static void ath_tx_txqaddbuf(struct ath_
                        if (bf_is_ampdu_not_probing(bf))
                                txq->axq_ampdu_depth++;
  
  
        bf->bf_next = NULL;
        bf->bf_lastbf = bf;
-@@ -1911,8 +2030,7 @@ u8 ath_txchainmask_reduction(struct ath_
+@@ -1911,8 +2033,7 @@ u8 ath_txchainmask_reduction(struct ath_
        struct ath_hw *ah = sc->sc_ah;
        struct ath9k_channel *curchan = ah->curchan;
  
            (chainmask == 0x7) && (rate < 0x90))
                return 0x3;
        else if (AR_SREV_9462(ah) && ath9k_hw_btcoex_is_enabled(ah) &&
-@@ -1985,6 +2103,7 @@ static int ath_tx_prepare(struct ieee802
+@@ -1985,6 +2106,7 @@ static int ath_tx_prepare(struct ieee802
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct ieee80211_sta *sta = txctl->sta;
        struct ieee80211_vif *vif = info->control.vif;
        struct ath_softc *sc = hw->priv;
        int frmlen = skb->len + FCS_LEN;
        int padpos, padsize;
-@@ -1992,6 +2111,10 @@ static int ath_tx_prepare(struct ieee802
+@@ -1992,6 +2114,10 @@ static int ath_tx_prepare(struct ieee802
        /* NOTE:  sta can be NULL according to net/mac80211.h */
        if (sta)
                txctl->an = (struct ath_node *)sta->drv_priv;
  
        if (info->control.hw_key)
                frmlen += info->control.hw_key->icv_len;
-@@ -2041,7 +2164,6 @@ int ath_tx_start(struct ieee80211_hw *hw
+@@ -2041,7 +2167,6 @@ int ath_tx_start(struct ieee80211_hw *hw
        struct ath_txq *txq = txctl->txq;
        struct ath_atx_tid *tid = NULL;
        struct ath_buf *bf;
        int q;
        int ret;
  
-@@ -2069,27 +2191,31 @@ int ath_tx_start(struct ieee80211_hw *hw
+@@ -2069,27 +2194,31 @@ int ath_tx_start(struct ieee80211_hw *hw
                ath_txq_unlock(sc, txq);
                txq = sc->tx.uapsdq;
                ath_txq_lock(sc, txq);
                if (txctl->paprd)
                        dev_kfree_skb_any(skb);
                else
-@@ -2142,7 +2268,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw
+@@ -2142,7 +2271,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw
  
                bf->bf_lastbf = bf;
                ath_set_rates(vif, NULL, bf);
                duration += info.rates[0].PktDuration;
                if (bf_tail)
                        bf_tail->bf_next = bf;
-@@ -2189,7 +2315,7 @@ static void ath_tx_complete(struct ath_s
+@@ -2189,7 +2318,7 @@ static void ath_tx_complete(struct ath_s
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data;
        unsigned long flags;
  
        ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb);
-@@ -2225,21 +2351,7 @@ static void ath_tx_complete(struct ath_s
+@@ -2225,21 +2354,7 @@ static void ath_tx_complete(struct ath_s
        spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
  
        __skb_queue_tail(&txq->complete_q, skb);
  }
  
  static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
-@@ -2360,8 +2472,7 @@ static void ath_tx_processq(struct ath_s
+@@ -2360,8 +2475,7 @@ static void ath_tx_processq(struct ath_s
  
                if (list_empty(&txq->axq_q)) {
                        txq->axq_link = NULL;
                        break;
                }
                bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
-@@ -2375,7 +2486,7 @@ static void ath_tx_processq(struct ath_s
+@@ -2375,7 +2489,7 @@ static void ath_tx_processq(struct ath_s
                 * it with the STALE flag.
                 */
                bf_held = NULL;
                        bf_held = bf;
                        if (list_is_last(&bf_held->list, &txq->axq_q))
                                break;
-@@ -2399,7 +2510,7 @@ static void ath_tx_processq(struct ath_s
+@@ -2399,7 +2513,7 @@ static void ath_tx_processq(struct ath_s
                 * however leave the last descriptor back as the holding
                 * descriptor for hw.
                 */
                INIT_LIST_HEAD(&bf_head);
                if (!list_is_singular(&lastbf->list))
                        list_cut_position(&bf_head,
-@@ -2470,7 +2581,7 @@ void ath_tx_edma_tasklet(struct ath_soft
+@@ -2470,7 +2584,7 @@ void ath_tx_edma_tasklet(struct ath_soft
                }
  
                bf = list_first_entry(fifo_list, struct ath_buf, list);
                        list_del(&bf->list);
                        ath_tx_return_buffer(sc, bf);
                        bf = list_first_entry(fifo_list, struct ath_buf, list);
-@@ -2492,7 +2603,7 @@ void ath_tx_edma_tasklet(struct ath_soft
+@@ -2492,7 +2606,7 @@ void ath_tx_edma_tasklet(struct ath_soft
                                ath_tx_txqaddbuf(sc, txq, &bf_q, true);
                        }
                } else {
                        if (bf != lastbf)
                                list_cut_position(&bf_head, fifo_list,
                                                  lastbf->list.prev);
-@@ -2583,6 +2694,7 @@ void ath_tx_node_init(struct ath_softc *
+@@ -2583,6 +2697,7 @@ void ath_tx_node_init(struct ath_softc *
                tid->paused    = false;
                tid->active        = false;
                __skb_queue_head_init(&tid->buf_q);
                acno = TID_TO_WME_AC(tidno);
                tid->ac = &an->ac[acno];
        }
-@@ -2590,6 +2702,7 @@ void ath_tx_node_init(struct ath_softc *
+@@ -2590,6 +2705,7 @@ void ath_tx_node_init(struct ath_softc *
        for (acno = 0, ac = &an->ac[acno];
             acno < IEEE80211_NUM_ACS; acno++, ac++) {
                ac->sched    = false;
        }
 --- a/drivers/net/wireless/ath/ath9k/main.c
 +++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -173,8 +173,7 @@ static void ath_restart_work(struct ath_
+@@ -82,6 +82,22 @@ static bool ath9k_setpower(struct ath_so
+       return ret;
+ }
++void ath_ps_full_sleep(unsigned long data)
++{
++      struct ath_softc *sc = (struct ath_softc *) data;
++      struct ath_common *common = ath9k_hw_common(sc->sc_ah);
++      bool reset;
++
++      spin_lock(&common->cc_lock);
++      ath_hw_cycle_counters_update(common);
++      spin_unlock(&common->cc_lock);
++
++      ath9k_hw_setrxabort(sc->sc_ah, 1);
++      ath9k_hw_stopdmarecv(sc->sc_ah, &reset);
++
++      ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
++}
++
+ void ath9k_ps_wakeup(struct ath_softc *sc)
+ {
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+@@ -92,6 +108,7 @@ void ath9k_ps_wakeup(struct ath_softc *s
+       if (++sc->ps_usecount != 1)
+               goto unlock;
++      del_timer_sync(&sc->sleep_timer);
+       power_mode = sc->sc_ah->power_mode;
+       ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
+@@ -117,17 +134,17 @@ void ath9k_ps_restore(struct ath_softc *
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+       enum ath9k_power_mode mode;
+       unsigned long flags;
+-      bool reset;
+       spin_lock_irqsave(&sc->sc_pm_lock, flags);
+       if (--sc->ps_usecount != 0)
+               goto unlock;
+       if (sc->ps_idle) {
+-              ath9k_hw_setrxabort(sc->sc_ah, 1);
+-              ath9k_hw_stopdmarecv(sc->sc_ah, &reset);
+-              mode = ATH9K_PM_FULL_SLEEP;
+-      } else if (sc->ps_enabled &&
++              mod_timer(&sc->sleep_timer, jiffies + HZ / 10);
++              goto unlock;
++      }
++
++      if (sc->ps_enabled &&
+                  !(sc->ps_flags & (PS_WAIT_FOR_BEACON |
+                                    PS_WAIT_FOR_CAB |
+                                    PS_WAIT_FOR_PSPOLL_DATA |
+@@ -173,8 +190,7 @@ static void ath_restart_work(struct ath_
  {
        ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
  
                ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work,
                                     msecs_to_jiffies(ATH_PLL_WORK_INTERVAL));
  
-@@ -209,6 +208,7 @@ static bool ath_complete_reset(struct at
+@@ -209,6 +225,7 @@ static bool ath_complete_reset(struct at
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
        unsigned long flags;
  
        if (ath_startrecv(sc) != 0) {
                ath_err(common, "Unable to restart recv logic\n");
-@@ -236,10 +236,16 @@ static bool ath_complete_reset(struct at
+@@ -236,10 +253,16 @@ static bool ath_complete_reset(struct at
                }
        work:
                ath_restart_work(sc);
  
        ieee80211_wake_queues(sc->hw);
  
-@@ -306,17 +312,91 @@ out:
+@@ -306,17 +329,91 @@ out:
   * by reseting the chip.  To accomplish this we must first cleanup any pending
   * DMA, then restart stuff.
  */
  }
  
  static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
-@@ -543,21 +623,10 @@ chip_reset:
+@@ -400,6 +497,8 @@ void ath9k_tasklet(unsigned long data)
+                       ath_tx_edma_tasklet(sc);
+               else
+                       ath_tx_tasklet(sc);
++
++              wake_up(&sc->tx_wait);
+       }
+       ath9k_btcoex_handle_interrupt(sc, status);
+@@ -543,21 +642,10 @@ chip_reset:
  
  static int ath_reset(struct ath_softc *sc)
  {
        ath9k_ps_restore(sc);
  
        return r;
-@@ -599,7 +668,7 @@ static int ath9k_start(struct ieee80211_
+@@ -599,7 +687,7 @@ static int ath9k_start(struct ieee80211_
        ath9k_ps_wakeup(sc);
        mutex_lock(&sc->mutex);
  
  
        /* Reset SERDES registers */
        ath9k_hw_configpcipowersave(ah, false);
-@@ -802,7 +871,7 @@ static void ath9k_stop(struct ieee80211_
+@@ -802,7 +890,7 @@ static void ath9k_stop(struct ieee80211_
        }
  
        if (!ah->curchan)
  
        ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
        ath9k_hw_phy_disable(ah);
-@@ -821,7 +890,7 @@ static void ath9k_stop(struct ieee80211_
+@@ -821,7 +909,7 @@ static void ath9k_stop(struct ieee80211_
        ath_dbg(common, CONFIG, "Driver halt\n");
  }
  
  {
        switch (type) {
        case NL80211_IFTYPE_AP:
-@@ -966,6 +1035,8 @@ static int ath9k_add_interface(struct ie
+@@ -966,6 +1054,8 @@ static int ath9k_add_interface(struct ie
        struct ath_softc *sc = hw->priv;
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
  
        mutex_lock(&sc->mutex);
  
-@@ -979,6 +1050,12 @@ static int ath9k_add_interface(struct ie
+@@ -979,6 +1069,12 @@ static int ath9k_add_interface(struct ie
        if (ath9k_uses_beacons(vif->type))
                ath9k_beacon_assign_slot(sc, vif);
  
        mutex_unlock(&sc->mutex);
        return 0;
  }
-@@ -1016,6 +1093,7 @@ static void ath9k_remove_interface(struc
+@@ -1016,6 +1112,7 @@ static void ath9k_remove_interface(struc
  {
        struct ath_softc *sc = hw->priv;
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
  
        ath_dbg(common, CONFIG, "Detach Interface\n");
  
-@@ -1030,6 +1108,8 @@ static void ath9k_remove_interface(struc
+@@ -1030,6 +1127,8 @@ static void ath9k_remove_interface(struc
        ath9k_calculate_summary_state(hw, NULL);
        ath9k_ps_restore(sc);
  
        mutex_unlock(&sc->mutex);
  }
  
-@@ -1192,83 +1272,12 @@ static int ath9k_config(struct ieee80211
+@@ -1192,83 +1291,12 @@ static int ath9k_config(struct ieee80211
        }
  
        if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) {
        }
  
        if (changed & IEEE80211_CONF_CHANGE_POWER) {
-@@ -1374,9 +1383,6 @@ static void ath9k_sta_notify(struct ieee
+@@ -1374,9 +1402,6 @@ static void ath9k_sta_notify(struct ieee
        struct ath_softc *sc = hw->priv;
        struct ath_node *an = (struct ath_node *) sta->drv_priv;
  
        switch (cmd) {
        case STA_NOTIFY_SLEEP:
                an->sleeping = true;
-@@ -2094,7 +2100,7 @@ static void ath9k_wow_add_pattern(struct
+@@ -1772,13 +1797,31 @@ static void ath9k_set_coverage_class(str
+       mutex_unlock(&sc->mutex);
+ }
++static bool ath9k_has_tx_pending(struct ath_softc *sc)
++{
++      int i, npend;
++
++      for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
++              if (!ATH_TXQ_SETUP(sc, i))
++                      continue;
++
++              if (!sc->tx.txq[i].axq_depth)
++                      continue;
++
++              npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
++              if (npend)
++                      break;
++      }
++
++      return !!npend;
++}
++
+ static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
+ {
+       struct ath_softc *sc = hw->priv;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+-      int timeout = 200; /* ms */
+-      int i, j;
++      int timeout = HZ / 5; /* 200 ms */
+       bool drain_txq;
+       mutex_lock(&sc->mutex);
+@@ -1796,25 +1839,9 @@ static void ath9k_flush(struct ieee80211
+               return;
+       }
+-      for (j = 0; j < timeout; j++) {
+-              bool npend = false;
+-
+-              if (j)
+-                      usleep_range(1000, 2000);
+-
+-              for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+-                      if (!ATH_TXQ_SETUP(sc, i))
+-                              continue;
+-
+-                      npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
+-
+-                      if (npend)
+-                              break;
+-              }
+-
+-              if (!npend)
+-                  break;
+-      }
++      if (wait_event_timeout(sc->tx_wait, !ath9k_has_tx_pending(sc),
++                             timeout) > 0)
++              drop = false;
+       if (drop) {
+               ath9k_ps_wakeup(sc);
+@@ -2094,7 +2121,7 @@ static void ath9k_wow_add_pattern(struct
  {
        struct ath_hw *ah = sc->sc_ah;
        struct ath9k_wow_pattern *wow_pattern = NULL;
        int av_bslot;
        bool primary_sta_vif;
        __le64 tsf_adjust; /* TSF adjustment for staggered beacons */
-@@ -585,19 +588,14 @@ static inline void ath_fill_led_pin(stru
+@@ -459,6 +462,7 @@ void ath_check_ani(struct ath_softc *sc)
+ int ath_update_survey_stats(struct ath_softc *sc);
+ void ath_update_survey_nf(struct ath_softc *sc, int channel);
+ void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type);
++void ath_ps_full_sleep(unsigned long data);
+ /**********/
+ /* BTCOEX */
+@@ -585,19 +589,14 @@ static inline void ath_fill_led_pin(stru
  #define ATH_ANT_DIV_COMB_MAX_COUNT 100
  #define ATH_ANT_DIV_COMB_ALT_ANT_RATIO 30
  #define ATH_ANT_DIV_COMB_ALT_ANT_RATIO2 20
  struct ath_ant_comb {
        u16 count;
        u16 total_pkt_count;
-@@ -614,27 +612,36 @@ struct ath_ant_comb {
+@@ -614,27 +613,36 @@ struct ath_ant_comb {
        int rssi_first;
        int rssi_second;
        int rssi_third;
  
  /*
   * Default cache line size, in bytes.
-@@ -926,7 +933,6 @@ void ath9k_deinit_device(struct ath_soft
+@@ -717,6 +725,7 @@ struct ath_softc {
+       struct work_struct hw_check_work;
+       struct work_struct hw_reset_work;
+       struct completion paprd_complete;
++      wait_queue_head_t tx_wait;
+       unsigned int hw_busy_count;
+       unsigned long sc_flags;
+@@ -753,6 +762,7 @@ struct ath_softc {
+       struct delayed_work tx_complete_work;
+       struct delayed_work hw_pll_work;
+       struct timer_list rx_poll_timer;
++      struct timer_list sleep_timer;
+ #ifdef CPTCFG_ATH9K_BTCOEX_SUPPORT
+       struct ath_btcoex btcoex;
+@@ -926,7 +936,6 @@ void ath9k_deinit_device(struct ath_soft
  void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
  void ath9k_reload_chainmask_settings(struct ath_softc *sc);
  
        struct ath_common *common;
        int ret = 0, i;
        int csz = 0;
-@@ -600,6 +650,7 @@ static int ath9k_init_softc(u16 devid, s
+@@ -600,8 +650,10 @@ static int ath9k_init_softc(u16 devid, s
        ah->reg_ops.rmw = ath9k_reg_rmw;
        atomic_set(&ah->intr_ref_cnt, -1);
        sc->sc_ah = ah;
 +      pCap = &ah->caps;
  
        sc->dfs_detector = dfs_pattern_detector_init(ah, NL80211_DFS_UNSET);
++      init_waitqueue_head(&sc->tx_wait);
  
-@@ -631,11 +682,15 @@ static int ath9k_init_softc(u16 devid, s
+       if (!pdata) {
+               ah->ah_flags |= AH_USE_EEPROM;
+@@ -631,11 +683,15 @@ static int ath9k_init_softc(u16 devid, s
        ath9k_init_platform(sc);
  
        /*
  
        spin_lock_init(&common->cc_lock);
  
-@@ -710,13 +765,15 @@ static void ath9k_init_band_txpower(stru
+@@ -646,6 +702,7 @@ static int ath9k_init_softc(u16 devid, s
+       tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
+                    (unsigned long)sc);
++      setup_timer(&sc->sleep_timer, ath_ps_full_sleep, (unsigned long)sc);
+       INIT_WORK(&sc->hw_reset_work, ath_reset_work);
+       INIT_WORK(&sc->hw_check_work, ath_hw_check);
+       INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
+@@ -710,13 +767,15 @@ static void ath9k_init_band_txpower(stru
        struct ieee80211_supported_band *sband;
        struct ieee80211_channel *chan;
        struct ath_hw *ah = sc->sc_ah;
                ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true);
        }
  }
-@@ -802,7 +859,8 @@ void ath9k_set_hw_capab(struct ath_softc
+@@ -802,7 +861,8 @@ void ath9k_set_hw_capab(struct ath_softc
                IEEE80211_HW_PS_NULLFUNC_STACK |
                IEEE80211_HW_SPECTRUM_MGMT |
                IEEE80211_HW_REPORTS_TX_ACK_STATUS |
  
        if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
                hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
+@@ -968,6 +1028,7 @@ static void ath9k_deinit_softc(struct at
+               if (ATH_TXQ_SETUP(sc, i))
+                       ath_tx_cleanupq(sc, &sc->tx.txq[i]);
++      del_timer_sync(&sc->sleep_timer);
+       ath9k_hw_deinit(sc->sc_ah);
+       if (sc->dfs_detector != NULL)
+               sc->dfs_detector->exit(sc->dfs_detector);
 --- a/drivers/net/wireless/ath/carl9170/main.c
 +++ b/drivers/net/wireless/ath/carl9170/main.c
 @@ -1878,7 +1878,8 @@ void *carl9170_alloc(size_t priv_size)
index e65292b34046c70dfc9a77647fca3c58ca71c0c3..7d69ced99b1474369f63565ec36a522d5880f684 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -812,6 +812,7 @@ static const struct ieee80211_iface_limi
+@@ -814,6 +814,7 @@ static const struct ieee80211_iface_limi
  #endif
                                 BIT(NL80211_IFTYPE_AP) |
                                 BIT(NL80211_IFTYPE_P2P_GO) },
index 9588649457c44cb3b532645ef6cac6dd66307ae7..284a82a273be0c485d4b95e0bef1e7d2645345d6 100644 (file)
@@ -81,7 +81,7 @@
        struct ath_ops reg_ops;
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -664,6 +664,8 @@ static int ath9k_init_softc(u16 devid, s
+@@ -665,6 +665,8 @@ static int ath9k_init_softc(u16 devid, s
                ah->is_clk_25mhz = pdata->is_clk_25mhz;
                ah->get_mac_revision = pdata->get_mac_revision;
                ah->external_reset = pdata->external_reset;
index e951ec76f6ce699c32444fee727675b45ebb34c1..0a031392bc2764f88e7e298bc798f52b2b5837d8 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -1069,23 +1069,23 @@ static int __init ath9k_init(void)
+@@ -1072,23 +1072,23 @@ static int __init ath9k_init(void)
                goto err_out;
        }
  
index e101b249a345a2585c2b387df09ec16d77c88fdc..9d5acb9a0ffb1aeae088017720ba61a37436a163 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/main.c
 +++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -296,8 +296,12 @@ static int ath_reset_internal(struct ath
+@@ -313,8 +313,12 @@ static int ath_reset_internal(struct ath
            (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))
                ath9k_mci_set_txpower(sc, true, false);
  
@@ -14,7 +14,7 @@
  
  out:
        spin_unlock_bh(&sc->sc_pcu_lock);
-@@ -1285,6 +1289,7 @@ static int ath9k_config(struct ieee80211
+@@ -1304,6 +1308,7 @@ static int ath9k_config(struct ieee80211
                sc->config.txpowlimit = 2 * conf->power_level;
                ath9k_cmn_update_txpow(ah, sc->curtxpow,
                                       sc->config.txpowlimit, &sc->curtxpow);
index bc5bc0d4f806e8b2c0273f859d8bb48a03643568..20f94b6bc745c2ed1fc7f36f411ccb1b1ca9c72c 100644 (file)
@@ -21,7 +21,7 @@
        if (ant_gain > max_gain)
 --- a/drivers/net/wireless/ath/ath9k/main.c
 +++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1285,7 +1285,10 @@ static int ath9k_config(struct ieee80211
+@@ -1304,7 +1304,10 @@ static int ath9k_config(struct ieee80211
        }
  
        if (changed & IEEE80211_CONF_CHANGE_POWER) {
index 78b6cd79d4984cd0f83c5a42d1b40b245fe1590f..2d548492756d8d56fc4f040b157b6152f4502d80 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -560,6 +560,9 @@ struct ath9k_wow_pattern {
+@@ -561,6 +561,9 @@ struct ath9k_wow_pattern {
  void ath_init_leds(struct ath_softc *sc);
  void ath_deinit_leds(struct ath_softc *sc);
  void ath_fill_led_pin(struct ath_softc *sc);
@@ -10,7 +10,7 @@
  #else
  static inline void ath_init_leds(struct ath_softc *sc)
  {
-@@ -704,6 +707,13 @@ enum spectral_mode {
+@@ -705,6 +708,13 @@ enum spectral_mode {
        SPECTRAL_CHANSCAN,
  };
  
@@ -24,7 +24,7 @@
  struct ath_softc {
        struct ieee80211_hw *hw;
        struct device *dev;
-@@ -745,9 +755,8 @@ struct ath_softc {
+@@ -747,9 +757,8 @@ struct ath_softc {
        struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
  
  #ifdef CPTCFG_MAC80211_LEDS
  void ath_fill_led_pin(struct ath_softc *sc)
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -976,7 +976,7 @@ int ath9k_init_device(u16 devid, struct 
+@@ -978,7 +978,7 @@ int ath9k_init_device(u16 devid, struct 
  
  #ifdef CPTCFG_MAC80211_LEDS
        /* must be initialized before ieee80211_register_hw */
index 8cbe6638928c7cf28fda56c6bb39c781f61434da..e3125bf8be8db7cc7ada9c86c45aabb25bbfed9e 100644 (file)
                REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
 --- a/drivers/net/wireless/ath/ath9k/main.c
 +++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -546,6 +546,11 @@ irqreturn_t ath_isr(int irq, void *dev)
+@@ -565,6 +565,11 @@ irqreturn_t ath_isr(int irq, void *dev)
        ath9k_hw_getisr(ah, &status);   /* NB: clears ISR too */
        status &= ah->imask;    /* discard unasked-for bits */
  
index 621caf71c28c8d97bd2e7b97950d3339f8db97b7..779ed6498d11654cf6439c70ae5be8149ddf921c 100644 (file)
@@ -59,7 +59,7 @@
  };
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -664,6 +664,8 @@ static int ath9k_init_softc(u16 devid, s
+@@ -665,6 +665,8 @@ static int ath9k_init_softc(u16 devid, s
                ah->is_clk_25mhz = pdata->is_clk_25mhz;
                ah->get_mac_revision = pdata->get_mac_revision;
                ah->external_reset = pdata->external_reset;