aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGabor Juhos <juhosg@openwrt.org>2011-06-21 05:23:51 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-06-22 16:09:57 -0400
commit7d95847c9b3631d31f657d8cede153b518ed9e2e (patch)
tree033508bc12802ca4e5121d61f3893e112e625e2c
parent4187afa29a73fec1f68243c03437e7c1b37f315d (diff)
ath9k: add external_reset callback to ath9k_platfom_data for AR9330
The patch adds a callback to ath9k_platform_data. If the callback is provided by the platform code, then it can be used to hard reset the WMAC device. The callback is required for doing a hard reset of the AR9330 chips to get them working again after a hang. Signed-off-by: Gabor Juhos <juhosg@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c35
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c1
-rw-r--r--include/linux/ath9k_platform.h1
4 files changed, 38 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 4da5284c7773..839ba64c9e49 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)
1161 rst_flags |= AR_RTC_RC_MAC_COLD; 1161 rst_flags |= AR_RTC_RC_MAC_COLD;
1162 } 1162 }
1163 1163
1164 if (AR_SREV_9330(ah)) {
1165 int npend = 0;
1166 int i;
1167
1168 /* AR9330 WAR:
1169 * call external reset function to reset WMAC if:
1170 * - doing a cold reset
1171 * - we have pending frames in the TX queues
1172 */
1173
1174 for (i = 0; i < AR_NUM_QCU; i++) {
1175 npend = ath9k_hw_numtxpending(ah, i);
1176 if (npend)
1177 break;
1178 }
1179
1180 if (ah->external_reset &&
1181 (npend || type == ATH9K_RESET_COLD)) {
1182 int reset_err = 0;
1183
1184 ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET,
1185 "reset MAC via external reset\n");
1186
1187 reset_err = ah->external_reset();
1188 if (reset_err) {
1189 ath_err(ath9k_hw_common(ah),
1190 "External reset failed, err=%d\n",
1191 reset_err);
1192 return false;
1193 }
1194
1195 REG_WRITE(ah, AR_RTC_RESET, 1);
1196 }
1197 }
1198
1164 REG_WRITE(ah, AR_RTC_RC, rst_flags); 1199 REG_WRITE(ah, AR_RTC_RC, rst_flags);
1165 1200
1166 REGWRITE_BUFFER_FLUSH(ah); 1201 REGWRITE_BUFFER_FLUSH(ah);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 0749fa8c3a58..818acdd1ba90 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -863,6 +863,7 @@ struct ath_hw {
863 863
864 bool is_clk_25mhz; 864 bool is_clk_25mhz;
865 int (*get_mac_revision)(void); 865 int (*get_mac_revision)(void);
866 int (*external_reset)(void);
866}; 867};
867 868
868struct ath_bus_ops { 869struct ath_bus_ops {
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 1851c222fff0..50103b2792b5 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -575,6 +575,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
575 sc->sc_ah->led_pin = pdata->led_pin; 575 sc->sc_ah->led_pin = pdata->led_pin;
576 ah->is_clk_25mhz = pdata->is_clk_25mhz; 576 ah->is_clk_25mhz = pdata->is_clk_25mhz;
577 ah->get_mac_revision = pdata->get_mac_revision; 577 ah->get_mac_revision = pdata->get_mac_revision;
578 ah->external_reset = pdata->external_reset;
578 } 579 }
579 580
580 common = ath9k_hw_common(ah); 581 common = ath9k_hw_common(ah);
diff --git a/include/linux/ath9k_platform.h b/include/linux/ath9k_platform.h
index c207607acada..6e3f54f37844 100644
--- a/include/linux/ath9k_platform.h
+++ b/include/linux/ath9k_platform.h
@@ -31,6 +31,7 @@ struct ath9k_platform_data {
31 31
32 bool is_clk_25mhz; 32 bool is_clk_25mhz;
33 int (*get_mac_revision)(void); 33 int (*get_mac_revision)(void);
34 int (*external_reset)(void);
34}; 35};
35 36
36#endif /* _LINUX_ATH9K_PLATFORM_H */ 37#endif /* _LINUX_ATH9K_PLATFORM_H */