svn commit: r245556 - head/sys/dev/ath

Adrian Chadd adrian at FreeBSD.org
Thu Jan 17 16:43:59 UTC 2013


Author: adrian
Date: Thu Jan 17 16:43:59 2013
New Revision: 245556
URL: http://svnweb.freebsd.org/changeset/base/245556

Log:
  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

Modified:
  head/sys/dev/ath/if_ath.c

Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c	Thu Jan 17 16:39:21 2013	(r245555)
+++ head/sys/dev/ath/if_ath.c	Thu Jan 17 16:43:59 2013	(r245556)
@@ -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) {
+		ath_reset(ifp, ATH_RESET_NOLOSS);
 		if_printf(ifp, "bb hang detected (0x%x), resetting\n", hangs);
+	} else {
 		ath_reset(ifp, ATH_RESET_NOLOSS);
-	} else
 		ieee80211_beacon_miss(ifp->if_l2com);
+	}
 }
 
 /*
@@ -5056,6 +5064,7 @@ ath_newstate(struct ieee80211vap *vap, e
 	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, e
 			 * 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:
 			/*


More information about the svn-src-all mailing list