Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 26 Jun 2011 13:53:24 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r223568 - head/sys/dev/ath
Message-ID:  <201106261353.p5QDrOFc055142@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201106261353.p5QDrOFc055142>