svn commit: r223568 - head/sys/dev/ath
Adrian Chadd
adrian at FreeBSD.org
Sun Jun 26 13:53:25 UTC 2011
Author: adrian
Date: Sun Jun 26 13:53:24 2011
New Revision: 223568
URL: http://svn.freebsd.org/changeset/base/223568
Log:
Fix beacon transmission after a channel set.
The DFS code was tickling the channel set directly whilst going
through the state RUN -> CSA -> RUN. This only changed the channel;
it didn't go via ath_reset(). However in this driver, a channel
change always causes a chip reset, which resets the beacon timer
configuration and interrupt setup. This meant that data would go
out but as the beacon timers never fired, beacons would never
be queued.
The confusing part is that sometimes the state transition was
RUN -> SCAN -> CAC -> RUN (with CSA being in there sometimes);
going via SCAN would clear sc_beacons and thus the transition
to RUN would reprogram beacon transmission.
In case someone tries debugging why suspending a device currently
beaconing (versus just RX'ing beacons which is what occurs in STA
mode), add a silly comment which should hopefully land them at
this commit message. The call to ath_hal_reset() will be clearing
the beacon config and it may not be always reset.
Modified:
head/sys/dev/ath/if_ath.c
Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c Sun Jun 26 13:43:15 2011 (r223567)
+++ head/sys/dev/ath/if_ath.c Sun Jun 26 13:53:24 2011 (r223568)
@@ -1290,6 +1290,8 @@ ath_resume(struct ath_softc *sc)
HAL_GPIO_MUX_MAC_NETWORK_LED);
ath_hal_gpioset(ah, sc->sc_ledpin, !sc->sc_ledon);
}
+
+ /* XXX beacons ? */
}
void
@@ -1592,6 +1594,12 @@ ath_init(void *arg)
sc->sc_lastani = 0;
sc->sc_lastshortcal = 0;
sc->sc_doresetcal = AH_FALSE;
+ /*
+ * Beacon timers were cleared here; give ath_newstate()
+ * a hint that the beacon timers should be poked when
+ * things transition to the RUN state.
+ */
+ sc->sc_beacons = 0;
/*
* Setup the hardware after reset: the key cache
@@ -4468,6 +4476,19 @@ ath_chan_set(struct ath_softc *sc, struc
ath_chan_change(sc, chan);
/*
+ * Reset clears the beacon timers; reset them
+ * here if needed.
+ */
+ if (sc->sc_beacons) { /* restart beacons */
+#ifdef IEEE80211_SUPPORT_TDMA
+ if (sc->sc_tdma)
+ ath_tdma_config(sc, NULL);
+ else
+#endif
+ ath_beacon_config(sc, NULL);
+ }
+
+ /*
* Re-enable interrupts.
*/
ath_hal_intrset(ah, sc->sc_imask);
More information about the svn-src-head
mailing list