summaryrefslogtreecommitdiff
path: root/package/mac80211/patches/570-ath9k-add-external_reset-callback-to-ath9k_platfom_d.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/mac80211/patches/570-ath9k-add-external_reset-callback-to-ath9k_platfom_d.patch')
-rw-r--r--package/mac80211/patches/570-ath9k-add-external_reset-callback-to-ath9k_platfom_d.patch82
1 files changed, 82 insertions, 0 deletions
diff --git a/package/mac80211/patches/570-ath9k-add-external_reset-callback-to-ath9k_platfom_d.patch b/package/mac80211/patches/570-ath9k-add-external_reset-callback-to-ath9k_platfom_d.patch
new file mode 100644
index 0000000000..c5beaa0f95
--- /dev/null
+++ b/package/mac80211/patches/570-ath9k-add-external_reset-callback-to-ath9k_platfom_d.patch
@@ -0,0 +1,82 @@
+diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
+index 323b6ab..5d373fc 100644
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -1161,6 +1161,41 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
+ rst_flags |= AR_RTC_RC_MAC_COLD;
+ }
+
++ if (AR_SREV_9330(ah)) {
++ int npend = 0;
++ int i;
++
++ /* AR9330 WAR:
++ * call external reset function to reset WMAC if:
++ * - doing a cold reset
++ * - we have pending frames in the TX queues
++ */
++
++ for (i = 0; i < AR_NUM_QCU; i++) {
++ npend = ath9k_hw_numtxpending(ah, i);
++ if (npend)
++ break;
++ }
++
++ if (ah->external_reset &&
++ (npend || type == ATH9K_RESET_COLD)) {
++ int reset_err = 0;
++
++ ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET,
++ "reset MAC via external reset\n");
++
++ reset_err = ah->external_reset();
++ if (reset_err) {
++ ath_err(ath9k_hw_common(ah),
++ "External reset failed, err=%d\n",
++ reset_err);
++ return false;
++ }
++
++ REG_WRITE(ah, AR_RTC_RESET, 1);
++ }
++ }
++
+ REG_WRITE(ah, AR_RTC_RC, rst_flags);
+
+ REGWRITE_BUFFER_FLUSH(ah);
+diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
+index 8d9ac49..f29a806 100644
+--- a/drivers/net/wireless/ath/ath9k/hw.h
++++ b/drivers/net/wireless/ath/ath9k/hw.h
+@@ -864,6 +864,7 @@ struct ath_hw {
+
+ bool is_clk_25mhz;
+ int (*get_mac_revision)(void);
++ int (*external_reset)(void);
+ };
+
+ struct ath_bus_ops {
+diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
+index 5ffabb9..f517649 100644
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -576,6 +576,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
+ sc->sc_ah->led_pin = pdata->led_pin;
+ ah->is_clk_25mhz = pdata->is_clk_25mhz;
+ ah->get_mac_revision = pdata->get_mac_revision;
++ ah->external_reset = pdata->external_reset;
+ }
+
+ common = ath9k_hw_common(ah);
+diff --git a/include/linux/ath9k_platform.h b/include/linux/ath9k_platform.h
+index c207607..6e3f54f 100644
+--- a/include/linux/ath9k_platform.h
++++ b/include/linux/ath9k_platform.h
+@@ -31,6 +31,7 @@ struct ath9k_platform_data {
+
+ bool is_clk_25mhz;
+ int (*get_mac_revision)(void);
++ int (*external_reset)(void);
+ };
+
+ #endif /* _LINUX_ATH9K_PLATFORM_H */