1 diff -urN madwifi-ng-r2377-20070526.old/ath/if_ath.c madwifi-ng-r2377-20070526.dev/ath/if_ath.c
2 --- madwifi-ng-r2377-20070526.old/ath/if_ath.c 2007-05-26 18:51:08.747757680 +0200
3 +++ madwifi-ng-r2377-20070526.dev/ath/if_ath.c 2007-05-26 18:51:08.841743392 +0200
4 @@ -4373,16 +4373,31 @@
5 struct ieee80211com *ic = &sc->sc_ic;
6 struct ath_hal *ah = sc->sc_ah;
7 struct ieee80211_node *ni;
8 - u_int32_t nexttbtt, intval;
9 + u_int32_t nexttbtt = 0;
11 + u_int64_t tsf, hw_tsf;
12 + u_int32_t tsftu, hw_tsftu;
13 + int should_reset_tsf = 0;
16 vap = TAILQ_FIRST(&ic->ic_vaps); /* XXX */
20 - /* extract tstamp from last beacon and convert to TU */
21 - nexttbtt = TSF_TO_TU(LE_READ_4(ni->ni_tstamp.data + 4),
22 - LE_READ_4(ni->ni_tstamp.data));
23 + hw_tsf = ath_hal_gettsf64(ah);
24 + tsf = le64_to_cpu(ni->ni_tstamp.tsf);
25 + hw_tsftu = hw_tsf >> 10;
28 + /* we should reset hw TSF only once, so we increment
29 + ni_tstamp.tsf to avoid resetting the hw TSF multiple
33 + should_reset_tsf = 1;
34 + ni->ni_tstamp.tsf = cpu_to_le64(1);
37 /* XXX conditionalize multi-bss support? */
38 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
40 @@ -4396,20 +4411,61 @@
41 if (sc->sc_stagbeacons)
42 intval /= ATH_BCBUF; /* for staggered beacons */
43 if ((sc->sc_nostabeacons) &&
44 - (vap->iv_opmode == IEEE80211_M_HOSTAP))
46 + (vap->iv_opmode == IEEE80211_M_HOSTAP))
47 + should_reset_tsf = 1;
49 intval = ni->ni_intval & HAL_BEACON_PERIOD;
50 - if (nexttbtt == 0) /* e.g. for ap mode */
53 + sc->sc_syncbeacon = 0;
54 + if (should_reset_tsf) {
56 + /* We just created the interface and TSF will be reset to
57 + zero, so next beacon will be sent at the next intval
61 - else if (intval) /* NB: can be 0 for monitor mode */
62 - nexttbtt = roundup(nexttbtt, intval);
63 - DPRINTF(sc, ATH_DEBUG_BEACON, "%s: nexttbtt %u intval %u (%u)\n",
64 - __func__, nexttbtt, intval, ni->ni_intval);
65 + } else if (intval) { /* NB: can be 0 for monitor mode */
68 + /* We do not receive any beacons or probe response. Since
69 + a beacon should be sent every 'intval' ms, we compute
70 + the next beacon timestamp using the hardware TSF. We
71 + ensure that it is at least FUDGE ms ahead of the
72 + current TSF. Otherwise, we use the next beacon
75 + nexttbtt = roundup(hw_tsftu +1, intval);
76 + while (nexttbtt <= hw_tsftu + FUDGE) {
82 + /* We do receive a beacon from someone else in the past,
83 + but the hw TSF has not been updated (otherwise we
84 + would have tsf >= hw_tsf). Since we cannot use the
85 + hardware TSF, we will do nothing and wait for the
86 + next beacon. In order to do so, we set sc->syncbeacon
89 + sc->sc_syncbeacon = 1;
90 + goto ath_beacon_config_debug;
92 + /* We do receive a beacon in the past, normal case. We
93 + make sure that the timestamp is at least FUDGE ms
94 + ahead of the hardware TSF */
96 + nexttbtt = tsftu + intval;
97 + while (nexttbtt <= hw_tsftu + FUDGE) {
104 if (ic->ic_opmode == IEEE80211_M_STA && !(sc->sc_nostabeacons)) {
108 int dtimperiod, dtimcount;
109 int cfpperiod, cfpcount;
111 @@ -4425,13 +4481,13 @@
112 dtimcount = 0; /* XXX? */
113 cfpperiod = 1; /* NB: no PCF support yet */
117 * Pull nexttbtt forward to reflect the current
118 * TSF and calculate dtim+cfp state for the result.
120 - tsf = ath_hal_gettsf64(ah);
121 - tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
123 + if (nexttbtt == 0) /* e.g. for ap mode */
127 if (--dtimcount < 0) {
128 @@ -4439,7 +4495,7 @@
130 cfpcount = cfpperiod - 1;
132 - } while (nexttbtt < tsftu);
133 + } while (nexttbtt < hw_tsftu + FUDGE);
135 memset(&bs, 0, sizeof(bs));
136 bs.bs_intval = intval;
137 @@ -4491,7 +4547,7 @@
138 DPRINTF(sc, ATH_DEBUG_BEACON,
139 "%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",
141 - (unsigned long long) tsf, tsftu,
142 + (unsigned long long) hw_tsf, hw_tsftu,
146 @@ -4510,7 +4566,7 @@
147 ath_hal_intrset(ah, sc->sc_imask);
149 ath_hal_intrset(ah, 0);
150 - if (nexttbtt == intval)
151 + if (should_reset_tsf)
152 intval |= HAL_BEACON_RESET_TSF;
153 if (ic->ic_opmode == IEEE80211_M_IBSS) {
155 @@ -4547,8 +4603,40 @@
156 if (ic->ic_opmode == IEEE80211_M_IBSS && sc->sc_hasveol)
157 ath_beacon_start_adhoc(sc, vap);
159 - sc->sc_syncbeacon = 0;
162 + ath_beacon_config_debug:
164 + /* we print all debug messages here, in order to preserve the
165 + time critical aspect of this function */
167 + DPRINTF(sc, ATH_DEBUG_BEACON,
168 + "%s: ni=%p tsf=%llu hw_tsf=%llu tsftu=%u hw_tsftu=%u\n",
169 + __func__, ni, tsf, hw_tsf, tsftu, hw_tsftu);
171 + if (should_reset_tsf) {
172 + /* we just created the interface */
173 + DPRINTF(sc, ATH_DEBUG_BEACON, "%s: first beacon\n",__func__);
176 + /* we do not receive any beacons or probe response */
177 + DPRINTF(sc, ATH_DEBUG_BEACON,
178 + "%s: no beacon received...\n",__func__);
180 + if (tsf > hw_tsf) {
181 + /* we do receive a beacon and the hw TSF has not been updated */
182 + DPRINTF(sc, ATH_DEBUG_BEACON,
183 + "%s: beacon received, but TSF is incorrect\n",__func__);
185 + /* we do receive a beacon in the past, normal case */
186 + DPRINTF(sc, ATH_DEBUG_BEACON,
187 + "%s: beacon received, TSF is correct\n",__func__);
192 + DPRINTF(sc, ATH_DEBUG_BEACON, "%s: nexttbtt=%u intval=%u\n",
193 + __func__,nexttbtt, intval & HAL_BEACON_PERIOD);