Fix hangs (exposed by spectral scan activity) in STA mode when the

chip hangs.

* Always do a reset in ath_bmiss_proc(), regardless of whether the
  hardware is "hung" or not.  Specifically, for spectral scan, there's
  likely a whole bunch of potential hangs that we don't (yet) recognise
  in the HAL.  So to avoid staying RX deaf persisting until the station
  disassociates, just do a no-loss reset.

* Set sc_beacons=1 in STA mode.  During a reset, the beacon programming
  isn't done.  (It's likely I need to set sc_syncbeacons during a hang
  reset, but I digress.)  Thus after a reset, there's no beacon timer
  programming to send a BMISS interrupt if beacons aren't heard ..
  thus if the AP disappears, you won't get notified and you'll have to
  reset your interface.

This hasn't yet fixed all of the hangs that I've seen when debugging
spectral scan, but it's certainly reduced the hang frequency and it
should improve general STA stability in very noisy environments.

Tested:

* AR9280, STA mode, spectral scan off/on

PR:		kern/175227
This commit is contained in:
adrian 2013-01-17 16:43:59 +00:00
parent fbc0640f87
commit 0aa13972fd

View File

@ -1883,11 +1883,19 @@ ath_bmiss_proc(void *arg, int pending)
DPRINTF(sc, ATH_DEBUG_ANY, "%s: pending %u\n", __func__, pending);
/*
* Do a reset upon any becaon miss event.
*
* It may be a non-recognised RX clear hang which needs a reset
* to clear.
*/
if (ath_hal_gethangstate(sc->sc_ah, 0xff, &hangs) && hangs != 0) {
if_printf(ifp, "bb hang detected (0x%x), resetting\n", hangs);
ath_reset(ifp, ATH_RESET_NOLOSS);
} else
if_printf(ifp, "bb hang detected (0x%x), resetting\n", hangs);
} else {
ath_reset(ifp, ATH_RESET_NOLOSS);
ieee80211_beacon_miss(ifp->if_l2com);
}
}
/*
@ -5056,6 +5064,7 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
int i, error, stamode;
u_int32_t rfilt;
int csa_run_transition = 0;
static const HAL_LED_STATE leds[] = {
HAL_LED_INIT, /* IEEE80211_S_INIT */
HAL_LED_SCAN, /* IEEE80211_S_SCAN */
@ -5200,10 +5209,32 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
* force a beacon update so we pick up a lack of
* beacons from an AP in CAC and thus force a
* scan.
*
* And, there's also corner cases here where
* after a scan, the AP may have disappeared.
* In that case, we may not receive an actual
* beacon to update the beacon timer and thus we
* won't get notified of the missing beacons.
*/
sc->sc_syncbeacon = 1;
#if 0
if (csa_run_transition)
#endif
ath_beacon_config(sc, vap);
/*
* PR: kern/175227
*
* Reconfigure beacons during reset; as otherwise
* we won't get the beacon timers reprogrammed
* after a reset and thus we won't pick up a
* beacon miss interrupt.
*
* Hopefully we'll see a beacon before the BMISS
* timer fires (too often), leading to a STA
* disassociation.
*/
sc->sc_beacons = 1;
break;
case IEEE80211_M_MONITOR:
/*