From c3677b3c7ec7cb83cd732dd3ca7ddcd8c393b288 Mon Sep 17 00:00:00 2001 From: mentor Date: Sat, 29 Dec 2007 17:27:55 +0000 Subject: [PATCH] * Add not about TU variables as the TSF (64-bit) is truncated into a TU (32-bit), even though it is right shifted by 10, but this is OK. * Use roundup() to calculate the next intval boundary for nexttbtt. This method is more simple to understand and computationally simpler. git-svn-id: http://madwifi-project.org/svn/madwifi/trunk@3099 0192ed92-7a03-0410-a25b-9323aeb14dbd --- ath/if_ath.c | 56 ++++++++++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 32 deletions(-) diff --git a/ath/if_ath.c b/ath/if_ath.c index 8217929..b6e40af 100644 --- a/ath/if_ath.c +++ b/ath/if_ath.c @@ -4585,8 +4585,6 @@ ath_beacon_generate(struct ath_softc *sc, struct ieee80211vap *vap, int *needmar static void ath_beacon_send(struct ath_softc *sc, int *needmark) { -#define TSF_TO_TU(_h,_l) \ - ((((u_int32_t)(_h)) << 22) | (((u_int32_t)(_l)) >> 10)) struct ath_hal *ah = sc->sc_ah; struct ieee80211vap *vap; struct ath_buf *bf; @@ -4630,17 +4628,16 @@ ath_beacon_send(struct ath_softc *sc, int *needmark) */ if (sc->sc_stagbeacons) { /* staggered beacons */ struct ieee80211com *ic = &sc->sc_ic; - u_int64_t tsf; - u_int32_t tsftu; + u_int64_t tsf, tsftu; tsf = ath_hal_gettsf64(ah); - tsftu = TSF_TO_TU(tsf >> 32, tsf); + tsftu = tsf >> 10; /* NB: 64 -> 32: See note far above. */ slot = ((tsftu % ic->ic_lintval) * ATH_BCBUF) / ic->ic_lintval; vap = sc->sc_bslot[(slot + 1) % ATH_BCBUF]; DPRINTF(sc, ATH_DEBUG_BEACON_PROC, - "%s: slot %d [tsf %llu tsftu %u intval %u] vap %p\n", - __func__, slot, (unsigned long long) tsf, tsftu, - ic->ic_lintval, vap); + "%s: slot %d [tsf %llu tsftu %llu intval %u] vap %p\n", + __func__, slot, (unsigned long long)tsf, + (unsigned long long)tsftu, ic->ic_lintval, vap); bfaddr = 0; if (vap != NULL) { bf = ath_beacon_generate(sc, vap, needmark); @@ -4745,7 +4742,6 @@ ath_beacon_send(struct ath_softc *sc, int *needmark) sc->sc_stats.ast_be_xmit++; /* XXX per-VAP? */ } -#undef TSF_TO_TU } /* @@ -4860,19 +4856,21 @@ ath_beacon_free(struct ath_softc *sc) * * Note : TBTT is Target Beacon Transmission Time (see IEEE 802.11-1999: 4 & * 11.2.1.3). + * + * Note: TSF is right shifter by 10 and then put into a 32-bit int, which will + * truncate. This does not affect the calculation as long as no more than one + * overflow/wraparound occurs between beacons. This is not going to happen as + * (2^(32 + 10 - 1) - 1)us is a really long time. */ static void ath_beacon_update_timers(struct ath_softc *sc, struct ieee80211vap *vap) { -#define TSF_TO_TU(_h,_l) \ - ((((u_int32_t)(_h)) << 22) | (((u_int32_t)(_l)) >> 10)) struct ieee80211com *ic = &sc->sc_ic; struct ath_hal *ah = sc->sc_ah; struct ieee80211_node *ni; - u_int32_t nexttbtt = 0; - u_int32_t intval; u_int64_t tsf, hw_tsf; u_int32_t tsftu, hw_tsftu; + u_int32_t intval, nexttbtt = 0; int reset_tsf = 0; if (vap == NULL) @@ -4883,7 +4881,7 @@ ath_beacon_update_timers(struct ath_softc *sc, struct ieee80211vap *vap) hw_tsf = ath_hal_gettsf64(ah); tsf = le64_to_cpu(ni->ni_tstamp.tsf); hw_tsftu = hw_tsf >> 10; - tsftu = tsf >> 10; + tsftu = tsf >> 10; /* NB: 64 -> 32. See note above. */ /* We should reset hw TSF only once, so we increment * ni_tstamp.tsf to avoid resetting the hw TSF multiple @@ -4923,14 +4921,10 @@ ath_beacon_update_timers(struct ath_softc *sc, struct ieee80211vap *vap) * responses. Since a beacon should be sent * every 'intval' ms, we compute the next * beacon timestamp using the hardware TSF. We - * ensure that it is at least FUDGE ms ahead + * ensure that it is at least FUDGE TUs ahead * of the current TSF. Otherwise, we use the * next beacon timestamp again */ - - nexttbtt = roundup(hw_tsftu +1, intval); - while (nexttbtt <= hw_tsftu + FUDGE) { - nexttbtt += intval; - } + nexttbtt = roundup(hw_tsftu + FUDGE, intval); } else { if (tsf > hw_tsf) { /* We received a beacon, but the HW TSF has @@ -4942,11 +4936,9 @@ ath_beacon_update_timers(struct ath_softc *sc, struct ieee80211vap *vap) } else { /* Normal case: we received a beacon to which * we have synchronized. Make sure that nexttbtt - * is at least FUDGE ms ahead of hw_tsf */ - nexttbtt = tsftu + intval; - while (nexttbtt <= hw_tsftu + FUDGE) { - nexttbtt += intval; - } + * is at least FUDGE TU ahead of hw_tsf */ + nexttbtt = tsftu + roundup(hw_tsftu + FUDGE - + tsftu, intval); } } } @@ -5035,7 +5027,7 @@ ath_beacon_update_timers(struct ath_softc *sc, struct ieee80211vap *vap) "nextdtim %u bmiss %u sleep %u cfp:period %u " "maxdur %u next %u timoffset %u\n", __func__, - (unsigned long long) tsf, tsftu, + (unsigned long long)tsf, tsftu, bs.bs_intval, bs.bs_nexttbtt, bs.bs_dtimperiod, @@ -5079,14 +5071,15 @@ ath_beacon_update_timers(struct ath_softc *sc, struct ieee80211vap *vap) ath_hal_intrset(ah, sc->sc_imask); } sc->sc_syncbeacon = 0; -#undef TSF_TO_TU ath_beacon_config_debug: /* We print all debug messages here, in order to preserve the * time critical aspect of this function */ DPRINTF(sc, ATH_DEBUG_BEACON, "%s: ni=%p tsf=%llu hw_tsf=%llu tsftu=%u hw_tsftu=%u\n", - __func__, ni, tsf, hw_tsf, tsftu, hw_tsftu); + __func__, ni, + (unsigned long long)tsf, (unsigned long long)hw_tsf, + tsftu, hw_tsftu); if (reset_tsf) { /* We just created the interface */ @@ -5113,8 +5106,9 @@ ath_beacon_config_debug: } } - DPRINTF(sc, ATH_DEBUG_BEACON, "%s: nexttbtt=%10x intval=%u%s%s imask=%s%s\n", - __func__, nexttbtt, intval & HAL_BEACON_PERIOD, + DPRINTF(sc, ATH_DEBUG_BEACON, + "%s: nexttbtt=%10x intval=%u%s%s imask=%s%s\n", __func__, + nexttbtt, intval & HAL_BEACON_PERIOD, intval & HAL_BEACON_ENA ? " HAL_BEACON_ENA" : "", intval & HAL_BEACON_RESET_TSF ? " HAL_BEACON_RESET_TSF" : "", sc->sc_imask & HAL_INT_BMISS ? " HAL_INT_BMISS" : "", @@ -5972,7 +5966,6 @@ ath_recv_mgmt(struct ieee80211_node *ni, struct sk_buff *skb, case IEEE80211_FC0_SUBTYPE_PROBE_RESP: if (vap->iv_opmode == IEEE80211_M_IBSS && vap->iv_state == IEEE80211_S_RUN) { - /* Don't merge if we have a desired BSSID */ if (vap->iv_flags & IEEE80211_F_DESBSSID) break; @@ -5985,7 +5978,6 @@ ath_recv_mgmt(struct ieee80211_node *ni, struct sk_buff *skb, * reconfiguration happens through callback to * ath_newstate as the state machine will go from * RUN -> RUN when this happens. */ - hw_tsf = ath_hal_gettsf64(sc->sc_ah); hw_tu = hw_tsf >> 10; beacon_tsf = le64_to_cpu(ni->ni_tstamp.tsf); -- 2.35.1