From f1ea6d3c2dc2b222abcf607d12f8889295718c54 Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@openwrt.org>
Date: Mon, 14 Oct 2013 19:38:42 +0000
Subject: ath9k: add some more pending fixes / optimizations

Signed-off-by: Felix Fietkau <nbd@openwrt.org>

SVN-Revision: 38398
---
 .../kernel/mac80211/patches/300-pending_work.patch | 265 +++++++++++++++++----
 .../patches/410-ath9k_allow_adhoc_and_ap.patch     |   2 +-
 .../patches/501-ath9k-eeprom_endianess.patch       |   2 +-
 .../mac80211/patches/502-ath9k_ahb_init.patch      |   2 +-
 .../mac80211/patches/521-ath9k_cur_txpower.patch   |   4 +-
 .../524-ath9k_use_configured_antenna_gain.patch    |   2 +-
 .../mac80211/patches/530-ath9k_extra_leds.patch    |   8 +-
 .../mac80211/patches/542-ath9k_debugfs_diag.patch  |   2 +-
 ...-allow-to-disable-bands-via-platform-data.patch |   2 +-
 9 files changed, 234 insertions(+), 55 deletions(-)

(limited to 'package/kernel/mac80211/patches')

diff --git a/package/kernel/mac80211/patches/300-pending_work.patch b/package/kernel/mac80211/patches/300-pending_work.patch
index 91781f92fd..81f03c532e 100644
--- a/package/kernel/mac80211/patches/300-pending_work.patch
+++ b/package/kernel/mac80211/patches/300-pending_work.patch
@@ -1013,13 +1013,13 @@
 +
 +	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;
@@ -1193,7 +1193,17 @@
  			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)
  {
@@ -1226,7 +1236,7 @@
  			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;
  
@@ -1248,7 +1258,7 @@
  				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);
  		}
  
@@ -1268,7 +1278,7 @@
  	}
  
  	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++;
  
@@ -1352,7 +1362,7 @@
  
  	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;
  
@@ -1362,7 +1372,7 @@
  	    (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;
@@ -1370,7 +1380,7 @@
  	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;
@@ -1381,7 +1391,7 @@
  
  	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;
@@ -1389,7 +1399,7 @@
  	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);
@@ -1432,7 +1442,7 @@
  		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);
@@ -1441,7 +1451,7 @@
  		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;
@@ -1450,7 +1460,7 @@
  	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);
@@ -1473,7 +1483,7 @@
  }
  
  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;
@@ -1483,7 +1493,7 @@
  			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;
@@ -1492,7 +1502,7 @@
  			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.
  		 */
@@ -1501,7 +1511,7 @@
  		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);
@@ -1510,7 +1520,7 @@
  			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 {
@@ -1519,7 +1529,7 @@
  			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);
@@ -1527,7 +1537,7 @@
  		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;
@@ -1537,7 +1547,61 @@
  	}
 --- 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);
  
@@ -1547,7 +1611,7 @@
  		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;
@@ -1555,7 +1619,7 @@
  
  	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);
@@ -1575,7 +1639,7 @@
  
  	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.
  */
@@ -1670,7 +1734,16 @@
  }
  
  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)
  {
@@ -1693,7 +1766,7 @@
  	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);
  
@@ -1702,7 +1775,7 @@
  
  	/* 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)
@@ -1711,7 +1784,7 @@
  
  	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");
  }
  
@@ -1720,7 +1793,7 @@
  {
  	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);
@@ -1729,7 +1802,7 @@
  
  	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);
  
@@ -1742,7 +1815,7 @@
  	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);
@@ -1750,7 +1823,7 @@
  
  	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);
  
@@ -1759,7 +1832,7 @@
  	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) {
@@ -1844,7 +1917,7 @@
  	}
  
  	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;
  
@@ -1854,7 +1927,70 @@
  	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;
@@ -3517,7 +3653,15 @@
  	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
@@ -3539,7 +3683,7 @@
  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;
@@ -3582,7 +3726,23 @@
  
  /*
   * 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);
  
@@ -5453,15 +5613,18 @@
  	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);
  
  	/*
@@ -5481,7 +5644,15 @@
  
  	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;
@@ -5498,7 +5669,7 @@
  		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 |
@@ -5508,6 +5679,14 @@
  
  	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)
diff --git a/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch b/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
index e65292b340..7d69ced99b 100644
--- a/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
+++ b/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
@@ -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) },
diff --git a/package/kernel/mac80211/patches/501-ath9k-eeprom_endianess.patch b/package/kernel/mac80211/patches/501-ath9k-eeprom_endianess.patch
index 9588649457..284a82a273 100644
--- a/package/kernel/mac80211/patches/501-ath9k-eeprom_endianess.patch
+++ b/package/kernel/mac80211/patches/501-ath9k-eeprom_endianess.patch
@@ -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;
diff --git a/package/kernel/mac80211/patches/502-ath9k_ahb_init.patch b/package/kernel/mac80211/patches/502-ath9k_ahb_init.patch
index e951ec76f6..0a031392bc 100644
--- a/package/kernel/mac80211/patches/502-ath9k_ahb_init.patch
+++ b/package/kernel/mac80211/patches/502-ath9k_ahb_init.patch
@@ -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;
  	}
  
diff --git a/package/kernel/mac80211/patches/521-ath9k_cur_txpower.patch b/package/kernel/mac80211/patches/521-ath9k_cur_txpower.patch
index e101b249a3..9d5acb9a0f 100644
--- a/package/kernel/mac80211/patches/521-ath9k_cur_txpower.patch
+++ b/package/kernel/mac80211/patches/521-ath9k_cur_txpower.patch
@@ -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);
diff --git a/package/kernel/mac80211/patches/524-ath9k_use_configured_antenna_gain.patch b/package/kernel/mac80211/patches/524-ath9k_use_configured_antenna_gain.patch
index bc5bc0d4f8..20f94b6bc7 100644
--- a/package/kernel/mac80211/patches/524-ath9k_use_configured_antenna_gain.patch
+++ b/package/kernel/mac80211/patches/524-ath9k_use_configured_antenna_gain.patch
@@ -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) {
diff --git a/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch b/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch
index 78b6cd79d4..2d54849275 100644
--- a/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch
+++ b/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch
@@ -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
@@ -162,7 +162,7 @@
  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 */
diff --git a/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch b/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch
index 8cbe663892..e3125bf8be 100644
--- a/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch
+++ b/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch
@@ -125,7 +125,7 @@
  		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 */
  
diff --git a/package/kernel/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch b/package/kernel/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch
index 621caf71c2..779ed6498d 100644
--- a/package/kernel/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch
+++ b/package/kernel/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch
@@ -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;
-- 
cgit v1.2.3