[source] ath9k: use external reset on AR91xx and QCA955x to improve stability

LEDE Commits lede-commits at lists.infradead.org
Fri Jul 15 05:20:16 PDT 2016


nbd pushed a commit to source.git, branch master:
https://git.lede-project.org/?p=source.git;a=commitdiff;h=98e4b504b45c5d6e68a48fc815e3d2a5d0d2ba13

commit 98e4b504b45c5d6e68a48fc815e3d2a5d0d2ba13
Author: Felix Fietkau <nbd at nbd.name>
AuthorDate: Sat Jul 9 15:31:35 2016 +0200

    ath9k: use external reset on AR91xx and QCA955x to improve stability
    
    Signed-off-by: Felix Fietkau <nbd at nbd.name>
---
 ...h9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch |  25 +++++
 ...ath9k_hw-issue-external-reset-for-QCA9550.patch | 125 +++++++++++++++++++++
 .../mac80211/patches/542-ath9k_debugfs_diag.patch  |   4 +-
 .../544-ath9k-ar933x-usb-hang-workaround.patch     |  10 +-
 4 files changed, 157 insertions(+), 7 deletions(-)

diff --git a/package/kernel/mac80211/patches/321-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch b/package/kernel/mac80211/patches/321-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch
new file mode 100644
index 0000000..9caa76d
--- /dev/null
+++ b/package/kernel/mac80211/patches/321-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch
@@ -0,0 +1,25 @@
+From: Felix Fietkau <nbd at nbd.name>
+Date: Sat, 9 Jul 2016 15:25:24 +0200
+Subject: [PATCH] ath9k_hw: reset AHB-WMAC interface on AR91xx
+
+Should fix a few stability issues
+
+Signed-off-by: Felix Fietkau <nbd at nbd.name>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -1398,8 +1398,12 @@ static bool ath9k_hw_set_reset(struct at
+ 	if (!AR_SREV_9100(ah))
+ 		REG_WRITE(ah, AR_RC, 0);
+ 
+-	if (AR_SREV_9100(ah))
++	if (AR_SREV_9100(ah)) {
++		/* Reset the AHB-WMAC interface */
++		if (ah->external_reset)
++			ah->external_reset();
+ 		udelay(50);
++	}
+ 
+ 	return true;
+ }
diff --git a/package/kernel/mac80211/patches/322-ath9k_hw-issue-external-reset-for-QCA9550.patch b/package/kernel/mac80211/patches/322-ath9k_hw-issue-external-reset-for-QCA9550.patch
new file mode 100644
index 0000000..5d4e849
--- /dev/null
+++ b/package/kernel/mac80211/patches/322-ath9k_hw-issue-external-reset-for-QCA9550.patch
@@ -0,0 +1,125 @@
+From: Felix Fietkau <nbd at nbd.name>
+Date: Sat, 9 Jul 2016 15:26:44 +0200
+Subject: [PATCH] ath9k_hw: issue external reset for QCA9550
+
+The RTC interface on the SoC needs to be reset along with the rest of
+the WMAC.
+
+Signed-off-by: Felix Fietkau <nbd at nbd.name>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -1275,39 +1275,56 @@ void ath9k_hw_get_delta_slope_vals(struc
+ 	*coef_exponent = coef_exp - 16;
+ }
+ 
+-/* AR9330 WAR:
+- * call external reset function to reset WMAC if:
+- * - doing a cold reset
+- * - we have pending frames in the TX queues.
+- */
+-static bool ath9k_hw_ar9330_reset_war(struct ath_hw *ah, int type)
++static bool ath9k_hw_need_external_reset(struct ath_hw *ah, int type)
+ {
+-	int i, npend = 0;
++	int i;
+ 
+-	for (i = 0; i < AR_NUM_QCU; i++) {
+-		npend = ath9k_hw_numtxpending(ah, i);
+-		if (npend)
+-			break;
++	if (type == ATH9K_RESET_COLD)
++		return true;
++
++	if (AR_SREV_9550(ah))
++		return true;
++
++	/* AR9330 WAR:
++	 * call external reset function to reset WMAC if:
++	 * - doing a cold reset
++	 * - we have pending frames in the TX queues.
++	 */
++	if (AR_SREV_9330(ah)) {
++		for (i = 0; i < AR_NUM_QCU; i++) {
++			if (ath9k_hw_numtxpending(ah, i))
++				return true;
++		}
+ 	}
+ 
+-	if (ah->external_reset &&
+-	    (npend || type == ATH9K_RESET_COLD)) {
+-		int reset_err = 0;
++	return false;
++}
+ 
+-		ath_dbg(ath9k_hw_common(ah), RESET,
+-			"reset MAC via external reset\n");
++static bool ath9k_hw_external_reset(struct ath_hw *ah, int type)
++{
++	int err;
+ 
+-		reset_err = ah->external_reset();
+-		if (reset_err) {
+-			ath_err(ath9k_hw_common(ah),
+-				"External reset failed, err=%d\n",
+-				reset_err);
+-			return false;
+-		}
++	if (!ah->external_reset || !ath9k_hw_need_external_reset(ah, type))
++		return true;
+ 
+-		REG_WRITE(ah, AR_RTC_RESET, 1);
++	ath_dbg(ath9k_hw_common(ah), RESET,
++		"reset MAC via external reset\n");
++
++	err = ah->external_reset();
++	if (err) {
++		ath_err(ath9k_hw_common(ah),
++			"External reset failed, err=%d\n", err);
++		return false;
++	}
++
++	if (AR_SREV_9550(ah)) {
++		REG_WRITE(ah, AR_RTC_RESET, 0);
++		udelay(10);
+ 	}
+ 
++	REG_WRITE(ah, AR_RTC_RESET, 1);
++	udelay(10);
++
+ 	return true;
+ }
+ 
+@@ -1360,24 +1377,23 @@ static bool ath9k_hw_set_reset(struct at
+ 			rst_flags |= AR_RTC_RC_MAC_COLD;
+ 	}
+ 
+-	if (AR_SREV_9330(ah)) {
+-		if (!ath9k_hw_ar9330_reset_war(ah, type))
+-			return false;
+-	}
+-
+ 	if (ath9k_hw_mci_is_enabled(ah))
+ 		ar9003_mci_check_gpm_offset(ah);
+ 
+ 	/* DMA HALT added to resolve ar9300 and ar9580 bus error during
+-	 * RTC_RC reg read
++	 * RTC_RC reg read. Also needed for AR9550 external reset
+ 	 */
+-	if (AR_SREV_9300(ah) || AR_SREV_9580(ah)) {
++	if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9550(ah)) {
+ 		REG_SET_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
+ 		ath9k_hw_wait(ah, AR_CFG, AR_CFG_HALT_ACK, AR_CFG_HALT_ACK,
+ 			      20 * AH_WAIT_TIMEOUT);
+-		REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
+ 	}
+ 
++	ath9k_hw_external_reset(ah, type);
++
++	if (AR_SREV_9300(ah) || AR_SREV_9580(ah))
++		REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
++
+ 	REG_WRITE(ah, AR_RTC_RC, rst_flags);
+ 
+ 	REGWRITE_BUFFER_FLUSH(ah);
diff --git a/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch b/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch
index f4bb0f2..3b746dc 100644
--- a/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch
+++ b/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch
@@ -94,7 +94,7 @@
  struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
 --- a/drivers/net/wireless/ath/ath9k/hw.c
 +++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -1821,6 +1821,20 @@ u32 ath9k_hw_get_tsf_offset(struct times
+@@ -1841,6 +1841,20 @@ u32 ath9k_hw_get_tsf_offset(struct times
  }
  EXPORT_SYMBOL(ath9k_hw_get_tsf_offset);
  
@@ -115,7 +115,7 @@
  int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
  		   struct ath9k_hw_cal_data *caldata, bool fastcc)
  {
-@@ -2029,6 +2043,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+@@ -2049,6 +2063,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
  		ar9003_hw_disable_phy_restart(ah);
  
  	ath9k_hw_apply_gpio_override(ah);
diff --git a/package/kernel/mac80211/patches/544-ath9k-ar933x-usb-hang-workaround.patch b/package/kernel/mac80211/patches/544-ath9k-ar933x-usb-hang-workaround.patch
index 9462fca..b9c962e 100644
--- a/package/kernel/mac80211/patches/544-ath9k-ar933x-usb-hang-workaround.patch
+++ b/package/kernel/mac80211/patches/544-ath9k-ar933x-usb-hang-workaround.patch
@@ -20,9 +20,9 @@
  /******************/
  /* Chip Revisions */
  /******************/
-@@ -1397,6 +1410,9 @@ static bool ath9k_hw_set_reset(struct at
- 	if (AR_SREV_9100(ah))
+@@ -1417,6 +1430,9 @@ static bool ath9k_hw_set_reset(struct at
  		udelay(50);
+ 	}
  
 +	if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
 +		ath9k_hw_disable_pll_lock_detect(ah);
@@ -30,7 +30,7 @@
  	return true;
  }
  
-@@ -1496,6 +1512,9 @@ static bool ath9k_hw_chip_reset(struct a
+@@ -1516,6 +1532,9 @@ static bool ath9k_hw_chip_reset(struct a
  		ar9003_hw_internal_regulator_apply(ah);
  	ath9k_hw_init_pll(ah, chan);
  
@@ -40,7 +40,7 @@
  	return true;
  }
  
-@@ -1799,8 +1818,14 @@ static int ath9k_hw_do_fastcc(struct ath
+@@ -1819,8 +1838,14 @@ static int ath9k_hw_do_fastcc(struct ath
  	if (AR_SREV_9271(ah))
  		ar9002_hw_load_ani_reg(ah, chan);
  
@@ -55,7 +55,7 @@
  	return -EINVAL;
  }
  
-@@ -2054,6 +2079,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+@@ -2074,6 +2099,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st
  		ath9k_hw_set_radar_params(ah);
  	}
  



More information about the lede-commits mailing list