Work around some rather annoying chip hangs in the AR9331 chip.
If powersave is enabled and there are any transitions to network or full sleep - even if they're pretty damned brief - eventually something messes up somewhere and the bus glue between the AR9331 SoC and the AR9331 wifi stops working. It shows up as stuck DMA and LOCAL_TIMEOUT interrupts. Both ath9k and the reference driver does a full chip reset if things get stuck. So: * teach the AR9330 HAL about the force_full_reset option I added a couple of years ago; * if the chip is currently in full-sleep, do a full-reset; * if TX DMA and/or RX DMA are still enabled (eg, they did get stuck during reset) then do a full-reset. Tested: * AR9331 SoC, STA mode
This commit is contained in:
parent
afb69e6b3e
commit
2dc7b713de
@ -1987,13 +1987,25 @@ HAL_BOOL
|
|||||||
ar9300_chip_reset(struct ath_hal *ah, struct ieee80211_channel *chan)
|
ar9300_chip_reset(struct ath_hal *ah, struct ieee80211_channel *chan)
|
||||||
{
|
{
|
||||||
struct ath_hal_9300 *ahp = AH9300(ah);
|
struct ath_hal_9300 *ahp = AH9300(ah);
|
||||||
|
int type = HAL_RESET_WARM;
|
||||||
|
|
||||||
OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->ic_freq : 0);
|
OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->ic_freq : 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Warm reset is optimistic.
|
* Warm reset is optimistic.
|
||||||
|
*
|
||||||
|
* If the TX/RX DMA engines aren't shut down (eg, they're
|
||||||
|
* wedged) then we're better off doing a full cold reset
|
||||||
|
* to try and shake that condition.
|
||||||
*/
|
*/
|
||||||
if (!ar9300_set_reset_reg(ah, HAL_RESET_WARM)) {
|
if (ahp->ah_chip_full_sleep ||
|
||||||
|
(ah->ah_config.ah_force_full_reset == 1) ||
|
||||||
|
OS_REG_READ(ah, AR_Q_TXE) ||
|
||||||
|
(OS_REG_READ(ah, AR_CR) & AR_CR_RXE)) {
|
||||||
|
type = HAL_RESET_COLD;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ar9300_set_reset_reg(ah, type)) {
|
||||||
return AH_FALSE;
|
return AH_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user