summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2012-11-27 02:23:45 +0000
committeradrian <adrian@FreeBSD.org>2012-11-27 02:23:45 +0000
commitc5c46f8668be23d7b5cacaa2e18d493491fffa66 (patch)
tree83a981e60d8eac48d4df6b42a5ba8e4b9730399b
parentdd88093c5e77fb769fc9bd276dc47f4741474283 (diff)
downloadFreeBSD-src-c5c46f8668be23d7b5cacaa2e18d493491fffa66.zip
FreeBSD-src-c5c46f8668be23d7b5cacaa2e18d493491fffa66.tar.gz
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
-rw-r--r--sys/dev/ath/if_ath_tdma.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/sys/dev/ath/if_ath_tdma.c b/sys/dev/ath/if_ath_tdma.c
index e3f732c..0d91d54 100644
--- a/sys/dev/ath/if_ath_tdma.c
+++ b/sys/dev/ath/if_ath_tdma.c
@@ -281,7 +281,7 @@ ath_tdma_update(struct ieee80211_node *ni,
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 *ni,
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 *ni,
* 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 *ni,
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
OpenPOWER on IntegriCloud