Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 27 Nov 2012 02:23:45 +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: r243590 - head/sys/dev/ath
Message-ID:  <201211270223.qAR2Nj3B046878@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Tue Nov 27 02:23:45 2012
New Revision: 243590
URL: http://svnweb.freebsd.org/changeset/base/243590

Log:
  Fix the TDMA nexttbtt programming for 802.11n chips.
  
  The existing logic wrapped programming nexttbtt at 65535 TU.
  This is not good enough for the 11n chips, whose nexttbtt register
  (GENERIC_TIMER_0) has an initial value from 0..2^31-1 TSF.
  So converting the TU to TSF had the counter wrap at (65535 << 10) TSF.
  
  Once this wrap occured, the nexttbtt value was very very low, much
  lower than the current TSF value.  At this point, the nexttbtt timer
  would constantly fire, leading to the TX queue being constantly gated
  open.. and when this occured, the sender was not correctly transmitting
  in its slot but just able to continuously transmit.  The master would
  then delay transmitting its beacon until after the air became free
  (which I guess would be after the burst interval, before the next burst
  interval would quickly follow) and that big delta in master beacon TX
  would start causing big swings in the slot timing adjustment.
  
  With this change, the nexttbtt value is allowed to go all the way up
  to the maximum value permissable by the 32 bit representation.
  I haven't yet tested it to that point; I really should.  The AR5212
  HAL now filters out values above 65535 TU for the beacon configuration
  (and the relevant legal values for SWBA, DBA and NEXTATIM) and the
  AR5416 HAL just dutifully programs in what it should.
  
  With this, TDMA is now useful on the 802.11n chips.
  
  Tested:
  
  * AR5416, AR9280 TDMA slave
  * AR5413 TDMA slave

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

Modified: head/sys/dev/ath/if_ath_tdma.c
==============================================================================
--- head/sys/dev/ath/if_ath_tdma.c	Tue Nov 27 02:19:35 2012	(r243589)
+++ head/sys/dev/ath/if_ath_tdma.c	Tue Nov 27 02:23:45 2012	(r243590)
@@ -281,7 +281,7 @@ ath_tdma_update(struct ieee80211_node *n
 	struct ath_softc *sc = ic->ic_ifp->if_softc;
 	struct ath_hal *ah = sc->sc_ah;
 	const HAL_RATE_TABLE *rt = sc->sc_currates;
-	u_int64_t tsf, rstamp, nextslot, nexttbtt;
+	u_int64_t tsf, rstamp, nextslot, nexttbtt, nexttbtt_full;
 	u_int32_t txtime, nextslottu;
 	int32_t tudelta, tsfdelta;
 	const struct ath_rx_status *rs;
@@ -326,7 +326,11 @@ ath_tdma_update(struct ieee80211_node *n
 	    rt->info[rix].shortPreamble);
 	/* NB: << 9 is to cvt to TU and /2 */
 	nextslot = (rstamp - txtime) + (sc->sc_tdmabintval << 9);
-	nextslottu = TSF_TO_TU(nextslot>>32, nextslot) & HAL_BEACON_PERIOD;
+	/*
+	 * For 802.11n chips: nextslottu needs to be the full TSF space,
+	 * not just 0..65535 TU.
+	 */
+	nextslottu = TSF_TO_TU(nextslot>>32, nextslot);
 
 	/*
 	 * Retrieve the hardware NextTBTT in usecs
@@ -350,7 +354,16 @@ ath_tdma_update(struct ieee80211_node *n
 	 * value, tsfdelta ends up becoming very negative and all
 	 * of the adjustments get very messed up.
 	 */
-	nexttbtt = ath_hal_getnexttbtt(ah) % (TU_TO_TSF(HAL_BEACON_PERIOD + 1));
+	
+	/*
+	 * We need to track the full nexttbtt rather than having it
+	 * truncated at HAL_BEACON_PERIOD, as programming the
+	 * nexttbtt (and related) registers for the 11n chips is
+	 * actually going to take the full 32 bit space, rather than
+	 * just 0..65535 TU.
+	 */
+	nexttbtt_full = ath_hal_getnexttbtt(ah);
+	nexttbtt = nexttbtt_full % (TU_TO_TSF(HAL_BEACON_PERIOD + 1));
 	tsfdelta = (int32_t)((nextslot % TU_TO_TSF(HAL_BEACON_PERIOD + 1)) - nexttbtt);
 
 	DPRINTF(sc, ATH_DEBUG_TDMA_TIMER,
@@ -371,7 +384,7 @@ ath_tdma_update(struct ieee80211_node *n
 		TDMA_SAMPLE(sc->sc_avgtsfdeltap, 0);
 		TDMA_SAMPLE(sc->sc_avgtsfdeltam, 0);
 	}
-	tudelta = nextslottu - TSF_TO_TU(nexttbtt >> 32, nexttbtt);
+	tudelta = nextslottu - TSF_TO_TU(nexttbtt_full >> 32, nexttbtt_full);
 
 	/*
 	 * Copy sender's timetstamp into tdma ie so they can



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