PERFORCE change 77480 for review
Sam Leffler
sam at FreeBSD.org
Wed May 25 18:46:07 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=77480
Change 77480 by sam at sam_ebb on 2005/05/25 18:45:16
Cleanup/fixup sta-mode beacon timer handling: when nextTbtt
calculated from the last received beacon lags behind the h/w
TSF pull it forward so we always program a value that's in
the future (fixes problems with not resyncing properly when
returning on-channel after a bg scan). While here handle
dtim properly (can't do pcf until we collect PCFParms from the
beacon--if it's worth it).
Affected files ...
.. //depot/projects/vap/sys/dev/ath/if_ath.c#16 edit
Differences ...
==== //depot/projects/vap/sys/dev/ath/if_ath.c#16 (text+ko) ====
@@ -2887,14 +2887,16 @@
static void
ath_beacon_config(struct ath_softc *sc)
{
+#define TSF_TO_TU(_h,_l) (((_h) << 22) | ((_l) >> 10))
struct ieee80211vap *vap = sc->sc_bmaster;
struct ieee80211_node *ni = vap->iv_bss;
struct ieee80211com *ic = vap->iv_ic;
struct ath_hal *ah = sc->sc_ah;
u_int32_t nexttbtt, intval;
- nexttbtt = (LE_READ_4(ni->ni_tstamp.data + 4) << 22) |
- (LE_READ_4(ni->ni_tstamp.data) >> 10);
+ /* extract tstamp from last beacon and convert to TU */
+ nexttbtt = TSF_TO_TU(LE_READ_4(ni->ni_tstamp.data + 4),
+ LE_READ_4(ni->ni_tstamp.data));
intval = ni->ni_intval & HAL_BEACON_PERIOD;
/* XXX conditionalize multi-bss support? */
if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
@@ -2916,21 +2918,59 @@
__func__, nexttbtt, intval, ni->ni_intval);
if (vap->iv_opmode == IEEE80211_M_STA) {
HAL_BEACON_STATE bs;
+ u_int64_t tsf;
+ u_int32_t tsftu;
+ int dtimperiod, dtimcount;
+ int cfpperiod, cfpcount;
- /* NB: no PCF support right now */
+ /*
+ * Setup dtim and cfp parameters according to
+ * last beacon we received (which may be none).
+ */
+ dtimperiod = vap->iv_dtim_period;
+ if (dtimperiod <= 0) /* NB: 0 if not known */
+ dtimperiod = 1;
+ dtimcount = vap->iv_dtim_count;
+ if (dtimcount >= dtimperiod) /* NB: sanity check */
+ dtimcount = 0; /* XXX? */
+ cfpperiod = 1; /* NB: no PCF support yet */
+ cfpcount = 0;
+#define FUDGE 2
+ /*
+ * Pull nexttbtt forward to reflect the current
+ * TSF and calculate dtim+cfp state for the result.
+ */
+ tsf = ath_hal_gettsf64(ah);
+ tsftu = TSF_TO_TU((u_int32_t)(tsf>>32), (u_int32_t)tsf) + FUDGE;
+ do {
+ nexttbtt += intval;
+ if (--dtimcount < 0) {
+ dtimcount = dtimperiod - 1;
+ if (--cfpcount < 0)
+ cfpcount = cfpperiod - 1;
+ }
+ } while (nexttbtt < tsftu);
+#undef FUDGE
memset(&bs, 0, sizeof(bs));
bs.bs_intval = intval;
bs.bs_nexttbtt = nexttbtt;
- bs.bs_dtimperiod = bs.bs_intval;
- bs.bs_nextdtim = nexttbtt;
+ bs.bs_dtimperiod = dtimperiod*intval;
+ bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
+ bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
+ bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
+ bs.bs_cfpmaxduration = 0;
+#if 0
/*
* The 802.11 layer records the offset to the DTIM
* bitmap while receiving beacons; use it here to
* enable h/w detection of our AID being marked in
* the bitmap vector (to indicate frames for us are
* pending at the AP).
+ * XXX do DTIM handling in s/w to WAR old h/w bugs
+ * XXX enable based on h/w rev for newer chips
*/
bs.bs_timoffset = ni->ni_timoff;
+#endif
/*
* Calculate the number of consecutive beacons to miss
* before taking a BMISS interrupt. The configuration
@@ -2959,8 +2999,9 @@
bs.bs_sleepduration = roundup(bs.bs_sleepduration, bs.bs_dtimperiod);
DPRINTF(sc, ATH_DEBUG_BEACON,
- "%s: intval %u nexttbtt %u dtim %u nextdtim %u bmiss %u sleep %u cfp:period %u maxdur %u next %u timoffset %u\n"
+ "%s: tsf %llu tsf:tu %u intval %u nexttbtt %u dtim %u nextdtim %u bmiss %u sleep %u cfp:period %u maxdur %u next %u timoffset %u\n"
, __func__
+ , tsf, tsftu
, bs.bs_intval
, bs.bs_nexttbtt
, bs.bs_dtimperiod
@@ -3012,6 +3053,7 @@
ath_beacon_proc(sc, 0);
}
sc->sc_syncbeacon = 0;
+#undef TSF_TO_TU
}
static void
More information about the p4-projects
mailing list