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>
This commit is contained in:
parent
4187afa29a
commit
7d95847c9b
|
@ -1161,6 +1161,41 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
|
||||||
rst_flags |= AR_RTC_RC_MAC_COLD;
|
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);
|
REG_WRITE(ah, AR_RTC_RC, rst_flags);
|
||||||
|
|
||||||
REGWRITE_BUFFER_FLUSH(ah);
|
REGWRITE_BUFFER_FLUSH(ah);
|
||||||
|
|
|
@ -863,6 +863,7 @@ struct ath_hw {
|
||||||
|
|
||||||
bool is_clk_25mhz;
|
bool is_clk_25mhz;
|
||||||
int (*get_mac_revision)(void);
|
int (*get_mac_revision)(void);
|
||||||
|
int (*external_reset)(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ath_bus_ops {
|
struct ath_bus_ops {
|
||||||
|
|
|
@ -575,6 +575,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
|
||||||
sc->sc_ah->led_pin = pdata->led_pin;
|
sc->sc_ah->led_pin = pdata->led_pin;
|
||||||
ah->is_clk_25mhz = pdata->is_clk_25mhz;
|
ah->is_clk_25mhz = pdata->is_clk_25mhz;
|
||||||
ah->get_mac_revision = pdata->get_mac_revision;
|
ah->get_mac_revision = pdata->get_mac_revision;
|
||||||
|
ah->external_reset = pdata->external_reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
common = ath9k_hw_common(ah);
|
common = ath9k_hw_common(ah);
|
||||||
|
|
|
@ -31,6 +31,7 @@ struct ath9k_platform_data {
|
||||||
|
|
||||||
bool is_clk_25mhz;
|
bool is_clk_25mhz;
|
||||||
int (*get_mac_revision)(void);
|
int (*get_mac_revision)(void);
|
||||||
|
int (*external_reset)(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _LINUX_ATH9K_PLATFORM_H */
|
#endif /* _LINUX_ATH9K_PLATFORM_H */
|
||||||
|
|
Loading…
Reference in New Issue