From 048fc8f0c149731229463f6fe97ce0a536b33a99 Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@openwrt.org>
Date: Sat, 5 Oct 2013 12:12:21 +0000
Subject: [PATCH] ath9k: fix tx queueing issues after background scans

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

SVN-Revision: 38304
---
 .../mac80211/patches/300-pending_work.patch   | 67 +++++++++++++++----
 .../patches/512-ath9k_channelbw_debugfs.patch |  4 +-
 .../patches/521-ath9k_cur_txpower.patch       |  4 +-
 ...24-ath9k_use_configured_antenna_gain.patch |  2 +-
 .../patches/542-ath9k_debugfs_diag.patch      |  2 +-
 5 files changed, 60 insertions(+), 19 deletions(-)

diff --git a/package/kernel/mac80211/patches/300-pending_work.patch b/package/kernel/mac80211/patches/300-pending_work.patch
index 95e87fa84c..3f1f7e3be0 100644
--- a/package/kernel/mac80211/patches/300-pending_work.patch
+++ b/package/kernel/mac80211/patches/300-pending_work.patch
@@ -1519,17 +1519,58 @@
  		ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work,
  				     msecs_to_jiffies(ATH_PLL_WORK_INTERVAL));
  
-@@ -238,9 +237,6 @@ static bool ath_complete_reset(struct at
+@@ -209,6 +208,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;
++	int i;
+ 
+ 	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
+ 		}
+ 	work:
  		ath_restart_work(sc);
- 	}
+-	}
  
 -	if ((ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) && sc->ant_rx != 3)
 -		ath_ant_comb_update(sc);
--
++		for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
++			if (!ATH_TXQ_SETUP(sc, i))
++				continue;
++
++			spin_lock_bh(&sc->tx.txq[i].axq_lock);
++			ath_txq_schedule(sc, &sc->tx.txq[i]);
++			spin_unlock_bh(&sc->tx.txq[i].axq_lock);
++		}
++	}
+ 
  	ieee80211_wake_queues(sc->hw);
  
- 	return true;
-@@ -966,6 +962,8 @@ static int ath9k_add_interface(struct ie
+@@ -543,21 +549,10 @@ chip_reset:
+ 
+ static int ath_reset(struct ath_softc *sc)
+ {
+-	int i, r;
++	int r;
+ 
+ 	ath9k_ps_wakeup(sc);
+-
+ 	r = ath_reset_internal(sc, NULL);
+-
+-	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+-		if (!ATH_TXQ_SETUP(sc, i))
+-			continue;
+-
+-		spin_lock_bh(&sc->tx.txq[i].axq_lock);
+-		ath_txq_schedule(sc, &sc->tx.txq[i]);
+-		spin_unlock_bh(&sc->tx.txq[i].axq_lock);
+-	}
+-
+ 	ath9k_ps_restore(sc);
+ 
+ 	return r;
+@@ -966,6 +961,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);
@@ -1538,7 +1579,7 @@
  
  	mutex_lock(&sc->mutex);
  
-@@ -979,6 +977,12 @@ static int ath9k_add_interface(struct ie
+@@ -979,6 +976,12 @@ static int ath9k_add_interface(struct ie
  	if (ath9k_uses_beacons(vif->type))
  		ath9k_beacon_assign_slot(sc, vif);
  
@@ -1551,7 +1592,7 @@
  	mutex_unlock(&sc->mutex);
  	return 0;
  }
-@@ -1016,6 +1020,7 @@ static void ath9k_remove_interface(struc
+@@ -1016,6 +1019,7 @@ static void ath9k_remove_interface(struc
  {
  	struct ath_softc *sc = hw->priv;
  	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -1559,7 +1600,7 @@
  
  	ath_dbg(common, CONFIG, "Detach Interface\n");
  
-@@ -1030,6 +1035,8 @@ static void ath9k_remove_interface(struc
+@@ -1030,6 +1034,8 @@ static void ath9k_remove_interface(struc
  	ath9k_calculate_summary_state(hw, NULL);
  	ath9k_ps_restore(sc);
  
@@ -1568,7 +1609,7 @@
  	mutex_unlock(&sc->mutex);
  }
  
-@@ -1193,8 +1200,6 @@ static int ath9k_config(struct ieee80211
+@@ -1193,8 +1199,6 @@ static int ath9k_config(struct ieee80211
  
  	if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) {
  		struct ieee80211_channel *curchan = hw->conf.chandef.chan;
@@ -1577,7 +1618,7 @@
  		int pos = curchan->hw_value;
  		int old_pos = -1;
  		unsigned long flags;
-@@ -1202,8 +1207,8 @@ static int ath9k_config(struct ieee80211
+@@ -1202,8 +1206,8 @@ static int ath9k_config(struct ieee80211
  		if (ah->curchan)
  			old_pos = ah->curchan - &ah->channels[0];
  
@@ -1588,7 +1629,7 @@
  
  		/* update survey stats for the old channel before switching */
  		spin_lock_irqsave(&common->cc_lock, flags);
-@@ -1211,7 +1216,7 @@ static int ath9k_config(struct ieee80211
+@@ -1211,7 +1215,7 @@ static int ath9k_config(struct ieee80211
  		spin_unlock_irqrestore(&common->cc_lock, flags);
  
  		ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos],
@@ -1597,7 +1638,7 @@
  
  		/*
  		 * If the operating channel changes, change the survey in-use flags
-@@ -1374,9 +1379,6 @@ static void ath9k_sta_notify(struct ieee
+@@ -1374,9 +1378,6 @@ static void ath9k_sta_notify(struct ieee
  	struct ath_softc *sc = hw->priv;
  	struct ath_node *an = (struct ath_node *) sta->drv_priv;
  
@@ -1607,7 +1648,7 @@
  	switch (cmd) {
  	case STA_NOTIFY_SLEEP:
  		an->sleeping = true;
-@@ -2094,7 +2096,7 @@ static void ath9k_wow_add_pattern(struct
+@@ -2094,7 +2095,7 @@ static void ath9k_wow_add_pattern(struct
  {
  	struct ath_hw *ah = sc->sc_ah;
  	struct ath9k_wow_pattern *wow_pattern = NULL;
diff --git a/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch b/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch
index 69923242ae..c805e2aa2e 100644
--- a/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch
+++ b/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch
@@ -72,7 +72,7 @@
  	debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
 --- a/drivers/net/wireless/ath/ath9k/main.c
 +++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1200,8 +1200,10 @@ static int ath9k_config(struct ieee80211
+@@ -1199,8 +1199,10 @@ static int ath9k_config(struct ieee80211
  
  	if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) {
  		struct ieee80211_channel *curchan = hw->conf.chandef.chan;
@@ -83,7 +83,7 @@
  		unsigned long flags;
  
  		if (ah->curchan)
-@@ -1238,7 +1240,23 @@ static int ath9k_config(struct ieee80211
+@@ -1237,7 +1239,23 @@ static int ath9k_config(struct ieee80211
  			memset(&sc->survey[pos], 0, sizeof(struct survey_info));
  		}
  
diff --git a/package/kernel/mac80211/patches/521-ath9k_cur_txpower.patch b/package/kernel/mac80211/patches/521-ath9k_cur_txpower.patch
index 22691910fe..b67dda7e82 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
-@@ -286,8 +286,12 @@ static int ath_reset_internal(struct ath
+@@ -296,8 +296,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);
-@@ -1299,6 +1303,7 @@ static int ath9k_config(struct ieee80211
+@@ -1298,6 +1302,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 48b5f31dc1..7dd0482972 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
-@@ -1299,7 +1299,10 @@ static int ath9k_config(struct ieee80211
+@@ -1298,7 +1298,10 @@ static int ath9k_config(struct ieee80211
  	}
  
  	if (changed & IEEE80211_CONF_CHANGE_POWER) {
diff --git a/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch b/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch
index 521f031625..c014bacb73 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
-@@ -462,6 +462,11 @@ irqreturn_t ath_isr(int irq, void *dev)
+@@ -472,6 +472,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 */
  
-- 
2.30.2