429ed164aa3365b1847dbd0fd9814b0699e12b05
[openwrt/svn-archive/archive.git] / package / madwifi / patches / 116-adhoc_beacon_PR_1033.patch
1 Index: madwifi-ng-r2525-20070630/ath/if_ath.c
2 ===================================================================
3 --- madwifi-ng-r2525-20070630.orig/ath/if_ath.c 2007-07-03 23:02:29.069860500 +0200
4 +++ madwifi-ng-r2525-20070630/ath/if_ath.c 2007-07-03 23:02:29.657897250 +0200
5 @@ -4422,16 +4422,31 @@
6 struct ieee80211com *ic = &sc->sc_ic;
7 struct ath_hal *ah = sc->sc_ah;
8 struct ieee80211_node *ni;
9 - u_int32_t nexttbtt, intval;
10 + u_int32_t nexttbtt = 0;
11 + u_int32_t intval;
12 + u_int64_t tsf, hw_tsf;
13 + u_int32_t tsftu, hw_tsftu;
14 + int should_reset_tsf = 0;
15
16 if (vap == NULL)
17 vap = TAILQ_FIRST(&ic->ic_vaps); /* XXX */
18
19 ni = vap->iv_bss;
20
21 - /* extract tstamp from last beacon and convert to TU */
22 - nexttbtt = TSF_TO_TU(LE_READ_4(ni->ni_tstamp.data + 4),
23 - LE_READ_4(ni->ni_tstamp.data));
24 + hw_tsf = ath_hal_gettsf64(ah);
25 + tsf = le64_to_cpu(ni->ni_tstamp.tsf);
26 + hw_tsftu = hw_tsf >> 10;
27 + tsftu = tsf >> 10;
28 +
29 + /* we should reset hw TSF only once, so we increment
30 + ni_tstamp.tsf to avoid resetting the hw TSF multiple
31 + times */
32 +
33 + if (tsf == 0) {
34 + should_reset_tsf = 1;
35 + ni->ni_tstamp.tsf = cpu_to_le64(1);
36 + }
37 +
38 /* XXX conditionalize multi-bss support? */
39 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
40 /*
41 @@ -4445,20 +4460,61 @@
42 if (sc->sc_stagbeacons)
43 intval /= ATH_BCBUF; /* for staggered beacons */
44 if ((sc->sc_nostabeacons) &&
45 - (vap->iv_opmode == IEEE80211_M_HOSTAP))
46 - nexttbtt = 0;
47 + (vap->iv_opmode == IEEE80211_M_HOSTAP))
48 + should_reset_tsf = 1;
49 } else
50 intval = ni->ni_intval & HAL_BEACON_PERIOD;
51 - if (nexttbtt == 0) /* e.g. for ap mode */
52 +
53 +#define FUDGE 2
54 + sc->sc_syncbeacon = 0;
55 + if (should_reset_tsf) {
56 +
57 + /* We just created the interface and TSF will be reset to
58 + zero, so next beacon will be sent at the next intval
59 + time */
60 +
61 nexttbtt = intval;
62 - else if (intval) /* NB: can be 0 for monitor mode */
63 - nexttbtt = roundup(nexttbtt, intval);
64 - DPRINTF(sc, ATH_DEBUG_BEACON, "%s: nexttbtt %u intval %u (%u)\n",
65 - __func__, nexttbtt, intval, ni->ni_intval);
66 + } else if (intval) { /* NB: can be 0 for monitor mode */
67 + if (tsf == 1) {
68 +
69 + /* We do not receive any beacons or probe response. Since
70 + a beacon should be sent every 'intval' ms, we compute
71 + the next beacon timestamp using the hardware TSF. We
72 + ensure that it is at least FUDGE ms ahead of the
73 + current TSF. Otherwise, we use the next beacon
74 + timestamp again */
75 +
76 + nexttbtt = roundup(hw_tsftu +1, intval);
77 + while (nexttbtt <= hw_tsftu + FUDGE) {
78 + nexttbtt += intval;
79 + }
80 + } else {
81 + if (tsf > hw_tsf) {
82 +
83 + /* We do receive a beacon from someone else in the past,
84 + but the hw TSF has not been updated (otherwise we
85 + would have tsf >= hw_tsf). Since we cannot use the
86 + hardware TSF, we will do nothing and wait for the
87 + next beacon. In order to do so, we set sc->syncbeacon
88 + again */
89 +
90 + sc->sc_syncbeacon = 1;
91 + goto ath_beacon_config_debug;
92 + } else {
93 + /* We do receive a beacon in the past, normal case. We
94 + make sure that the timestamp is at least FUDGE ms
95 + ahead of the hardware TSF */
96 +
97 + nexttbtt = tsftu + intval;
98 + while (nexttbtt <= hw_tsftu + FUDGE) {
99 + nexttbtt += intval;
100 + }
101 + }
102 + }
103 + }
104 +
105 if (ic->ic_opmode == IEEE80211_M_STA && !(sc->sc_nostabeacons)) {
106 HAL_BEACON_STATE bs;
107 - u_int64_t tsf;
108 - u_int32_t tsftu;
109 int dtimperiod, dtimcount;
110 int cfpperiod, cfpcount;
111
112 @@ -4474,13 +4530,13 @@
113 dtimcount = 0; /* XXX? */
114 cfpperiod = 1; /* NB: no PCF support yet */
115 cfpcount = 0;
116 -#define FUDGE 2
117 /*
118 * Pull nexttbtt forward to reflect the current
119 * TSF and calculate dtim+cfp state for the result.
120 */
121 - tsf = ath_hal_gettsf64(ah);
122 - tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
123 + nexttbtt = tsftu;
124 + if (nexttbtt == 0) /* e.g. for ap mode */
125 + nexttbtt = intval;
126 do {
127 nexttbtt += intval;
128 if (--dtimcount < 0) {
129 @@ -4488,7 +4544,7 @@
130 if (--cfpcount < 0)
131 cfpcount = cfpperiod - 1;
132 }
133 - } while (nexttbtt < tsftu);
134 + } while (nexttbtt < hw_tsftu + FUDGE);
135 #undef FUDGE
136 memset(&bs, 0, sizeof(bs));
137 bs.bs_intval = intval;
138 @@ -4540,7 +4596,7 @@
139 DPRINTF(sc, ATH_DEBUG_BEACON,
140 "%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 __func__,
142 - (unsigned long long) tsf, tsftu,
143 + (unsigned long long) hw_tsf, hw_tsftu,
144 bs.bs_intval,
145 bs.bs_nexttbtt,
146 bs.bs_dtimperiod,
147 @@ -4562,7 +4618,7 @@
148 ath_hal_intrset(ah, sc->sc_imask);
149 } else {
150 ath_hal_intrset(ah, 0);
151 - if (nexttbtt == intval)
152 + if (should_reset_tsf)
153 intval |= HAL_BEACON_RESET_TSF;
154 if (ic->ic_opmode == IEEE80211_M_IBSS) {
155 /*
156 @@ -4599,8 +4655,40 @@
157 if (ic->ic_opmode == IEEE80211_M_IBSS && sc->sc_hasveol)
158 ath_beacon_start_adhoc(sc, vap);
159 }
160 - sc->sc_syncbeacon = 0;
161 #undef TSF_TO_TU
162 +
163 + ath_beacon_config_debug:
164 +
165 + /* we print all debug messages here, in order to preserve the
166 + time critical aspect of this function */
167 +
168 + DPRINTF(sc, ATH_DEBUG_BEACON,
169 + "%s: ni=%p tsf=%llu hw_tsf=%llu tsftu=%u hw_tsftu=%u\n",
170 + __func__, ni, tsf, hw_tsf, tsftu, hw_tsftu);
171 +
172 + if (should_reset_tsf) {
173 + /* we just created the interface */
174 + DPRINTF(sc, ATH_DEBUG_BEACON, "%s: first beacon\n",__func__);
175 + } else {
176 + if (tsf == 1) {
177 + /* we do not receive any beacons or probe response */
178 + DPRINTF(sc, ATH_DEBUG_BEACON,
179 + "%s: no beacon received...\n",__func__);
180 + } else {
181 + if (tsf > hw_tsf) {
182 + /* we do receive a beacon and the hw TSF has not been updated */
183 + DPRINTF(sc, ATH_DEBUG_BEACON,
184 + "%s: beacon received, but TSF is incorrect\n",__func__);
185 + } else {
186 + /* we do receive a beacon in the past, normal case */
187 + DPRINTF(sc, ATH_DEBUG_BEACON,
188 + "%s: beacon received, TSF is correct\n",__func__);
189 + }
190 + }
191 + }
192 +
193 + DPRINTF(sc, ATH_DEBUG_BEACON, "%s: nexttbtt=%u intval=%u\n",
194 + __func__,nexttbtt, intval & HAL_BEACON_PERIOD);
195 }
196
197 static int