update madwifi to latest trunk - performance enhancements
[openwrt/openwrt.git] / package / madwifi / patches / 116-adhoc_beacon_PR_1033.patch
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;
10 + u_int32_t intval;
11 + u_int64_t tsf, hw_tsf;
12 + u_int32_t tsftu, hw_tsftu;
13 + int should_reset_tsf = 0;
14
15 if (vap == NULL)
16 vap = TAILQ_FIRST(&ic->ic_vaps); /* XXX */
17
18 ni = vap->iv_bss;
19
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;
26 + tsftu = tsf >> 10;
27 +
28 + /* we should reset hw TSF only once, so we increment
29 + ni_tstamp.tsf to avoid resetting the hw TSF multiple
30 + times */
31 +
32 + if (tsf == 0) {
33 + should_reset_tsf = 1;
34 + ni->ni_tstamp.tsf = cpu_to_le64(1);
35 + }
36 +
37 /* XXX conditionalize multi-bss support? */
38 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
39 /*
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))
45 - nexttbtt = 0;
46 + (vap->iv_opmode == IEEE80211_M_HOSTAP))
47 + should_reset_tsf = 1;
48 } else
49 intval = ni->ni_intval & HAL_BEACON_PERIOD;
50 - if (nexttbtt == 0) /* e.g. for ap mode */
51 +
52 +#define FUDGE 2
53 + sc->sc_syncbeacon = 0;
54 + if (should_reset_tsf) {
55 +
56 + /* We just created the interface and TSF will be reset to
57 + zero, so next beacon will be sent at the next intval
58 + time */
59 +
60 nexttbtt = 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 */
66 + if (tsf == 1) {
67 +
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
73 + timestamp again */
74 +
75 + nexttbtt = roundup(hw_tsftu +1, intval);
76 + while (nexttbtt <= hw_tsftu + FUDGE) {
77 + nexttbtt += intval;
78 + }
79 + } else {
80 + if (tsf > hw_tsf) {
81 +
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
87 + again */
88 +
89 + sc->sc_syncbeacon = 1;
90 + goto ath_beacon_config_debug;
91 + } else {
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 */
95 +
96 + nexttbtt = tsftu + intval;
97 + while (nexttbtt <= hw_tsftu + FUDGE) {
98 + nexttbtt += intval;
99 + }
100 + }
101 + }
102 + }
103 +
104 if (ic->ic_opmode == IEEE80211_M_STA && !(sc->sc_nostabeacons)) {
105 HAL_BEACON_STATE bs;
106 - u_int64_t tsf;
107 - u_int32_t tsftu;
108 int dtimperiod, dtimcount;
109 int cfpperiod, cfpcount;
110
111 @@ -4425,13 +4481,13 @@
112 dtimcount = 0; /* XXX? */
113 cfpperiod = 1; /* NB: no PCF support yet */
114 cfpcount = 0;
115 -#define FUDGE 2
116 /*
117 * Pull nexttbtt forward to reflect the current
118 * TSF and calculate dtim+cfp state for the result.
119 */
120 - tsf = ath_hal_gettsf64(ah);
121 - tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
122 + nexttbtt = tsftu;
123 + if (nexttbtt == 0) /* e.g. for ap mode */
124 + nexttbtt = intval;
125 do {
126 nexttbtt += intval;
127 if (--dtimcount < 0) {
128 @@ -4439,7 +4495,7 @@
129 if (--cfpcount < 0)
130 cfpcount = cfpperiod - 1;
131 }
132 - } while (nexttbtt < tsftu);
133 + } while (nexttbtt < hw_tsftu + FUDGE);
134 #undef 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",
140 __func__,
141 - (unsigned long long) tsf, tsftu,
142 + (unsigned long long) hw_tsf, hw_tsftu,
143 bs.bs_intval,
144 bs.bs_nexttbtt,
145 bs.bs_dtimperiod,
146 @@ -4510,7 +4566,7 @@
147 ath_hal_intrset(ah, sc->sc_imask);
148 } else {
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) {
154 /*
155 @@ -4547,8 +4603,40 @@
156 if (ic->ic_opmode == IEEE80211_M_IBSS && sc->sc_hasveol)
157 ath_beacon_start_adhoc(sc, vap);
158 }
159 - sc->sc_syncbeacon = 0;
160 #undef TSF_TO_TU
161 +
162 + ath_beacon_config_debug:
163 +
164 + /* we print all debug messages here, in order to preserve the
165 + time critical aspect of this function */
166 +
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);
170 +
171 + if (should_reset_tsf) {
172 + /* we just created the interface */
173 + DPRINTF(sc, ATH_DEBUG_BEACON, "%s: first beacon\n",__func__);
174 + } else {
175 + if (tsf == 1) {
176 + /* we do not receive any beacons or probe response */
177 + DPRINTF(sc, ATH_DEBUG_BEACON,
178 + "%s: no beacon received...\n",__func__);
179 + } else {
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__);
184 + } else {
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__);
188 + }
189 + }
190 + }
191 +
192 + DPRINTF(sc, ATH_DEBUG_BEACON, "%s: nexttbtt=%u intval=%u\n",
193 + __func__,nexttbtt, intval & HAL_BEACON_PERIOD);
194 }
195
196 static int