madwifi: merge fixes from trunk
[openwrt/svn-archive/archive.git] / package / madwifi / patches / 448-beacon_handling_fixes.patch
1 --- a/ath/if_ath.c
2 +++ b/ath/if_ath.c
3 @@ -160,7 +160,7 @@ static int ath_check_beacon_done(struct
4 static void ath_beacon_send(struct ath_softc *, int *, uint64_t hw_tsf);
5 static void ath_beacon_return(struct ath_softc *, struct ath_buf *);
6 static void ath_beacon_free(struct ath_softc *);
7 -static void ath_beacon_config(struct ath_softc *, struct ieee80211vap *);
8 +static void ath_beacon_config(struct ath_softc *, struct ieee80211vap *, int);
9 static void ath_hw_beacon_stop(struct ath_softc *sc);
10 static int ath_desc_alloc(struct ath_softc *);
11 static void ath_desc_free(struct ath_softc *);
12 @@ -387,13 +387,11 @@ static void ath_set_timing(struct ath_so
13 /* calibrate every 30 secs in steady state but check every second at first. */
14 static int ath_calinterval = ATH_SHORT_CALINTERVAL;
15 static int ath_xchanmode = AH_TRUE; /* enable extended channels */
16 -static int ath_maxvaps = ATH_MAXVAPS_DEFAULT; /* set default maximum vaps */
17 static int bstuck_thresh = BSTUCK_THRESH; /* Stuck beacon count required for reset */
18 static char *autocreate = NULL;
19 static char *ratectl = DEF_RATE_CTL;
20 static int rfkill = 0;
21 static int tpc = 1;
22 -static int maxvaps = -1;
23 static int xchanmode = -1;
24 #include "ath_wprobe.c"
25 static int beacon_cal = 1;
26 @@ -432,7 +430,6 @@ static struct notifier_block ath_event_b
27
28 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52))
29 MODULE_PARM(beacon_cal, "i");
30 -MODULE_PARM(maxvaps, "i");
31 MODULE_PARM(xchanmode, "i");
32 MODULE_PARM(rfkill, "i");
33 #ifdef ATH_CAP_TPC
34 @@ -444,7 +441,6 @@ MODULE_PARM(ratectl, "s");
35 #else
36 #include <linux/moduleparam.h>
37 module_param(beacon_cal, int, 0600);
38 -module_param(maxvaps, int, 0600);
39 module_param(xchanmode, int, 0600);
40 module_param(rfkill, int, 0600);
41 #ifdef ATH_CAP_TPC
42 @@ -454,7 +450,6 @@ module_param(bstuck_thresh, int, 0600);
43 module_param(autocreate, charp, 0600);
44 module_param(ratectl, charp, 0600);
45 #endif
46 -MODULE_PARM_DESC(maxvaps, "Maximum VAPs");
47 MODULE_PARM_DESC(xchanmode, "Enable/disable extended channel mode");
48 MODULE_PARM_DESC(rfkill, "Enable/disable RFKILL capability");
49 #ifdef ATH_CAP_TPC
50 @@ -512,7 +507,7 @@ MODULE_PARM_DESC(ieee80211_debug, "Load-
51 * and use the higher bits as the index of the VAP.
52 */
53 #define ATH_SET_VAP_BSSID_MASK(bssid_mask) \
54 - ((bssid_mask)[0] &= ~(((ath_maxvaps-1) << 2) | 0x02))
55 + ((bssid_mask)[0] &= ~(((ATH_MAXVAPS_BCN-1) << 2) | 0x02))
56 #define ATH_GET_VAP_ID(bssid) ((bssid)[0] >> 2)
57 #define ATH_SET_VAP_BSSID(bssid, id) \
58 do { \
59 @@ -604,8 +599,8 @@ ath_attach(u_int16_t devid, struct net_d
60
61 /* Allocate space for dynamically determined maximum VAP count */
62 sc->sc_bslot =
63 - kmalloc(ath_maxvaps * sizeof(struct ieee80211vap*), GFP_KERNEL);
64 - memset(sc->sc_bslot, 0, ath_maxvaps * sizeof(struct ieee80211vap*));
65 + kmalloc(ATH_MAXVAPS_BCN * sizeof(struct ieee80211vap*), GFP_KERNEL);
66 + memset(sc->sc_bslot, 0, ATH_MAXVAPS_BCN * sizeof(struct ieee80211vap*));
67
68 /*
69 * Cache line size is used to size and align various
70 @@ -694,13 +689,6 @@ ath_attach(u_int16_t devid, struct net_d
71 for (i = 0; i < sc->sc_keymax; i++)
72 ath_hal_keyreset(ah, i);
73
74 - if (maxvaps != -1) {
75 - ath_maxvaps = maxvaps;
76 - if (ath_maxvaps < ATH_MAXVAPS_MIN)
77 - ath_maxvaps = ATH_MAXVAPS_MIN;
78 - else if (ath_maxvaps > ATH_MAXVAPS_MAX)
79 - ath_maxvaps = ATH_MAXVAPS_MAX;
80 - }
81 if (xchanmode != -1)
82 ath_xchanmode = xchanmode;
83 error = ath_getchannels(dev);
84 @@ -1349,12 +1337,6 @@ ath_vap_create(struct ieee80211com *ic,
85 return NULL;
86 }
87
88 - if (sc->sc_nvaps >= ath_maxvaps) {
89 - EPRINTF(sc, "Too many virtual APs (%d already exist).\n",
90 - sc->sc_nvaps);
91 - return NULL;
92 - }
93 -
94 dev = alloc_etherdev(sizeof(struct ath_vap) + sc->sc_rc->arc_vap_space);
95 if (dev == NULL) {
96 /* XXX msg */
97 @@ -1424,7 +1406,7 @@ ath_vap_create(struct ieee80211com *ic,
98 TAILQ_FOREACH(v, &ic->ic_vaps, iv_next)
99 id_mask |= (1 << ATH_GET_VAP_ID(v->iv_myaddr));
100
101 - for (id = 0; id < ath_maxvaps; id++) {
102 + for (id = 0; id < ATH_MAXVAPS_BCN; id++) {
103 /* get the first available slot */
104 if ((id_mask & (1 << id)) == 0) {
105 ATH_SET_VAP_BSSID(vap->iv_myaddr, id);
106 @@ -1451,11 +1433,11 @@ ath_vap_create(struct ieee80211com *ic,
107 /* Assign the VAP to a beacon xmit slot. As
108 * above, this cannot fail to find one. */
109 avp->av_bslot = 0;
110 - for (slot = 0; slot < ath_maxvaps; slot++)
111 + for (slot = 0; slot < ATH_MAXVAPS_BCN; slot++)
112 if (sc->sc_bslot[slot] == NULL) {
113 /* XXX: Hack, space out slots to better
114 * deal with misses. */
115 - if (slot + 1 < ath_maxvaps &&
116 + if (slot + 1 < ATH_MAXVAPS_BCN &&
117 sc->sc_bslot[slot+1] == NULL) {
118 avp->av_bslot = slot + 1;
119 break;
120 @@ -1463,8 +1445,11 @@ ath_vap_create(struct ieee80211com *ic,
121 avp->av_bslot = slot;
122 /* NB: keep looking for a double slot */
123 }
124 - KASSERT(sc->sc_bslot[avp->av_bslot] == NULL,
125 - ("beacon slot %u not empty?", avp->av_bslot));
126 + if (sc->sc_bslot[avp->av_bslot]) {
127 + free_netdev(dev);
128 + return NULL;
129 + }
130 +
131 sc->sc_bslot[avp->av_bslot] = vap;
132 sc->sc_nbcnvaps++;
133
134 @@ -1475,15 +1460,7 @@ ath_vap_create(struct ieee80211com *ic,
135 * of staggered beacons.
136 */
137 /* XXX check for beacon interval too small */
138 - if (ath_maxvaps > 4) {
139 - DPRINTF(sc, ATH_DEBUG_BEACON,
140 - "Staggered beacons are not "
141 - "possible with maxvaps set "
142 - "to %d.\n", ath_maxvaps);
143 - sc->sc_stagbeacons = 0;
144 - } else {
145 - sc->sc_stagbeacons = 1;
146 - }
147 + sc->sc_stagbeacons = 1;
148 }
149 DPRINTF(sc, ATH_DEBUG_BEACON, "sc->sc_stagbeacons %sabled\n",
150 (sc->sc_stagbeacons ? "en" : "dis"));
151 @@ -1553,7 +1530,7 @@ ath_vap_create(struct ieee80211com *ic,
152 if (ath_startrecv(sc) != 0) /* restart recv */
153 EPRINTF(sc, "Unable to start receive logic.\n");
154 if (sc->sc_beacons)
155 - ath_beacon_config(sc, NULL); /* restart beacons */
156 + ath_beacon_config(sc, NULL, 0); /* restart beacons */
157 ath_hal_intrset(ah, sc->sc_imask);
158 }
159
160 @@ -1681,7 +1658,7 @@ ath_vap_delete(struct ieee80211vap *vap)
161 if (ath_startrecv(sc) != 0) /* restart recv. */
162 EPRINTF(sc, "Unable to start receive logic.\n");
163 if (sc->sc_beacons)
164 - ath_beacon_config(sc, NULL); /* restart beacons */
165 + ath_beacon_config(sc, NULL, 0); /* restart beacons */
166 ath_hal_intrset(ah, sc->sc_imask);
167 }
168 }
169 @@ -3066,7 +3043,7 @@ ath_reset(struct net_device *dev)
170 */
171 ath_chan_change(sc, c);
172 if (sc->sc_beacons)
173 - ath_beacon_config(sc, NULL); /* restart beacons */
174 + ath_beacon_config(sc, NULL, 1); /* restart beacons */
175 ath_hal_intrset(ah, sc->sc_imask);
176 ath_set_ack_bitrate(sc, sc->sc_ackrate);
177 netif_wake_queue(dev); /* restart xmit */
178 @@ -4763,7 +4740,7 @@ ath_check_beacon_done(struct ath_softc *
179 /*
180 * check if the last beacon went out with the mode change flag set.
181 */
182 - for (slot = 0; slot < ath_maxvaps; slot++) {
183 + for (slot = 0; slot < ATH_MAXVAPS_BCN; slot++) {
184 if (sc->sc_bslot[slot]) {
185 vap = sc->sc_bslot[slot];
186 break;
187 @@ -4968,7 +4945,7 @@ ath_beacon_alloc_internal(struct ath_sof
188 * has a timestamp in one beacon interval while the
189 * others get a timestamp aligned to the next interval.
190 */
191 - tuadjust = (ni->ni_intval * (ath_maxvaps - avp->av_bslot)) / ath_maxvaps;
192 + tuadjust = (ni->ni_intval * (ATH_MAXVAPS_BCN - avp->av_bslot)) / ATH_MAXVAPS_BCN;
193 tsfadjust = cpu_to_le64(tuadjust << 10); /* TU->TSF */
194
195 DPRINTF(sc, ATH_DEBUG_BEACON,
196 @@ -5361,8 +5338,8 @@ ath_beacon_send(struct ath_softc *sc, in
197 u_int32_t tsftu;
198
199 tsftu = hw_tsf >> 10; /* NB: 64 -> 32: See note far above. */
200 - slot = ((tsftu % ic->ic_lintval) * ath_maxvaps) / ic->ic_lintval;
201 - vap = sc->sc_bslot[(slot + 1) % ath_maxvaps];
202 + slot = ((tsftu % ic->ic_lintval) * ATH_MAXVAPS_BCN) / ic->ic_lintval;
203 + vap = sc->sc_bslot[(slot + 1) % ATH_MAXVAPS_BCN];
204 DPRINTF(sc, ATH_DEBUG_BEACON_PROC,
205 "Slot %d [tsf %llu tsftu %llu intval %u] vap %p\n",
206 slot, (unsigned long long)hw_tsf,
207 @@ -5377,7 +5354,7 @@ ath_beacon_send(struct ath_softc *sc, in
208 u_int32_t *bflink = NULL;
209
210 /* XXX: rotate/randomize order? */
211 - for (slot = 0; slot < ath_maxvaps; slot++) {
212 + for (slot = 0; slot < ATH_MAXVAPS_BCN; slot++) {
213 if ((vap = sc->sc_bslot[slot]) != NULL) {
214 if ((bf = ath_beacon_generate(
215 sc, vap,
216 @@ -5418,7 +5395,7 @@ ath_beacon_send(struct ath_softc *sc, in
217 * again. If we miss a beacon for that slot then we'll be
218 * slow to transition but we'll be sure at least one beacon
219 * interval has passed. When bursting slot is always left
220 - * set to ath_maxvaps so this check is a no-op.
221 + * set to ATH_MAXVAPS_BCN so this check is a no-op.
222 */
223 /* XXX locking */
224 if (sc->sc_updateslot == UPDATE) {
225 @@ -5526,7 +5503,7 @@ ath_beacon_free(struct ath_softc *sc)
226 * (2^(32 + 10 - 1) - 1)us is a really long time.
227 */
228 static void
229 -ath_beacon_config(struct ath_softc *sc, struct ieee80211vap *vap)
230 +ath_beacon_config(struct ath_softc *sc, struct ieee80211vap *vap, int reset)
231 {
232 struct ieee80211com *ic = &sc->sc_ic;
233 struct ath_hal *ah = sc->sc_ah;
234 @@ -5553,7 +5530,7 @@ ath_beacon_config(struct ath_softc *sc,
235 /* We should reset hw TSF only once, so we increment
236 * ni_tstamp.tsf to avoid resetting the hw TSF multiple
237 * times */
238 - if (tsf == 0) {
239 + if (tsf == 0 || reset) {
240 reset_tsf = 1;
241 ni->ni_tstamp.tsf = cpu_to_le64(1);
242 }
243 @@ -5567,7 +5544,7 @@ ath_beacon_config(struct ath_softc *sc,
244 /* NB: the beacon interval is kept internally in TUs */
245 intval = ic->ic_lintval & HAL_BEACON_PERIOD;
246 if (sc->sc_stagbeacons)
247 - intval /= ath_maxvaps; /* for staggered beacons */
248 + intval /= ATH_MAXVAPS_BCN; /* for staggered beacons */
249 if ((sc->sc_nostabeacons) &&
250 (vap->iv_opmode == IEEE80211_M_HOSTAP))
251 reset_tsf = 1;
252 @@ -5583,31 +5560,24 @@ ath_beacon_config(struct ath_softc *sc,
253 * time */
254 nexttbtt = intval;
255 } else if (intval) { /* NB: can be 0 for monitor mode */
256 - if (tsf == 1) {
257 - /* We have not received any beacons or probe
258 - * responses. Since a beacon should be sent
259 - * every 'intval' ms, we compute the next
260 - * beacon timestamp using the hardware TSF. We
261 - * ensure that it is at least FUDGE TUs ahead
262 - * of the current TSF. Otherwise, we use the
263 - * next beacon timestamp again */
264 - nexttbtt = roundup(hw_tsftu + FUDGE, intval);
265 - }
266 - else if (ic->ic_opmode == IEEE80211_M_IBSS) {
267 - if (tsf > hw_tsf) {
268 - /* We received a beacon, but the HW TSF has
269 - * not been updated (otherwise hw_tsf > tsf)
270 - * We cannot use the hardware TSF, so we
271 - * wait to synchronize beacons again. */
272 - sc->sc_syncbeacon = 1;
273 - goto ath_beacon_config_debug;
274 - } else {
275 - /* Normal case: we received a beacon to which
276 - * we have synchronized. Make sure that nexttbtt
277 - * is at least FUDGE TU ahead of hw_tsf */
278 - nexttbtt = tsftu + roundup(hw_tsftu + FUDGE -
279 - tsftu, intval);
280 - }
281 + if ((tsf > hw_tsf) && (ic->ic_opmode == IEEE80211_M_IBSS)) {
282 + /* We received a beacon, but the HW TSF has
283 + * not been updated (otherwise hw_tsf > tsf)
284 + * We cannot use the hardware TSF, so we
285 + * wait to synchronize beacons again. */
286 + sc->sc_syncbeacon = 1;
287 + goto ath_beacon_config_debug;
288 + } else if ((tsftu + FUDGE) > hw_tsftu) {
289 + if (tsftu > hw_tsftu + 2 * intval)
290 + nexttbtt = roundup(hw_tsftu + FUDGE, intval);
291 + else
292 + nexttbtt = tsftu;
293 + } else {
294 + /* Normal case: we received a beacon to which
295 + * we have synchronized. Make sure that nexttbtt
296 + * is at least FUDGE TU ahead of hw_tsf */
297 + nexttbtt = tsftu + roundup(hw_tsftu + FUDGE -
298 + tsftu, intval);
299 }
300 }
301
302 @@ -5730,9 +5700,6 @@ ath_beacon_config(struct ath_softc *sc,
303 ath_beacon_dturbo_config(vap, intval &
304 ~(HAL_BEACON_RESET_TSF | HAL_BEACON_ENA));
305 #endif
306 - if ((nexttbtt & HAL_BEACON_PERIOD) - (ath_hal_gettsf32(ah) >> 10)
307 - <= ath_hal_sw_beacon_response_time)
308 - nexttbtt += intval;
309 sc->sc_nexttbtt = nexttbtt;
310
311 /* stop beacons before reconfiguring the timers to avoid race
312 @@ -5889,7 +5856,7 @@ ath_desc_alloc(struct ath_softc *sc)
313
314 /* XXX allocate beacon state together with VAP */
315 error = ath_descdma_setup(sc, &sc->sc_bdma, &sc->sc_bbuf,
316 - "beacon", ath_maxvaps, 1);
317 + "beacon", ATH_MAXVAPS_BCN, 1);
318 if (error != 0) {
319 ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf,
320 BUS_DMA_TODEVICE);
321 @@ -6680,7 +6647,7 @@ ath_recv_mgmt(struct ieee80211vap * vap,
322 /* Resync beacon timers using the tsf of the
323 * beacon frame we just received. */
324 vap->iv_flags_ext &= ~IEEE80211_FEXT_APPIE_UPDATE;
325 - ath_beacon_config(sc, vap);
326 + ath_beacon_config(sc, vap, 0);
327 DPRINTF(sc, ATH_DEBUG_BEACON,
328 "Updated beacon timers\n");
329 }
330 @@ -9359,7 +9326,7 @@ ath_chan_set(struct ath_softc *sc, struc
331 * HW seems to turn off beacons during turbo mode switch.
332 */
333 if (sc->sc_beacons && !sc->sc_dfs_cac)
334 - ath_beacon_config(sc, NULL);
335 + ath_beacon_config(sc, NULL, 0);
336 /*
337 * Re-enable interrupts.
338 */
339 @@ -9813,7 +9780,7 @@ ath_newstate(struct ieee80211vap *vap, e
340 ATH_DEBUG_BEACON_PROC,
341 "Beacons reconfigured by %p[%s]!\n",
342 vap, vap->iv_nickname);
343 - ath_beacon_config(sc, vap);
344 + ath_beacon_config(sc, vap, 1);
345 sc->sc_beacons = 1;
346 }
347 } else {
348 @@ -9948,9 +9915,6 @@ ath_dfs_cac_completed(unsigned long data
349 }
350 netif_wake_queue(dev);
351 ath_reset(dev);
352 - if (sc->sc_beacons) {
353 - ath_beacon_config(sc, NULL);
354 - }
355 dev->watchdog_timeo = 5 * HZ; /* restore normal timeout */
356 } else {
357 do_gettimeofday(&tv);
358 @@ -11473,9 +11437,6 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
359 case ATH_OUTDOOR:
360 val = ic->ic_country_outdoor;
361 break;
362 - case ATH_MAXVAPS:
363 - val = ath_maxvaps;
364 - break;
365 case ATH_REGDOMAIN:
366 ath_hal_getregdomain(ah, &val);
367 break;
368 @@ -11606,12 +11567,6 @@ static const ctl_table ath_sysctl_templa
369 .extra2 = (void *)ATH_OUTDOOR,
370 },
371 { .ctl_name = CTL_AUTO,
372 - .procname = "maxvaps",
373 - .mode = 0444,
374 - .proc_handler = ath_sysctl_halparam,
375 - .extra2 = (void *)ATH_MAXVAPS,
376 - },
377 - { .ctl_name = CTL_AUTO,
378 .procname = "regdomain",
379 .mode = 0644,
380 .proc_handler = ath_sysctl_halparam,
381 @@ -11928,13 +11883,6 @@ static ctl_table ath_static_sysctls[] =
382 },
383 #endif
384 { .ctl_name = CTL_AUTO,
385 - .procname = "maxvaps",
386 - .mode = 0444,
387 - .data = &ath_maxvaps,
388 - .maxlen = sizeof(ath_maxvaps),
389 - .proc_handler = proc_dointvec
390 - },
391 - { .ctl_name = CTL_AUTO,
392 .procname = "xchanmode",
393 .mode = 0444,
394 .data = &ath_xchanmode,
395 --- a/ath/if_athvar.h
396 +++ b/ath/if_athvar.h
397 @@ -211,9 +211,7 @@ static inline struct net_device *_alloc_
398 #define ATH_RXBUF 40 /* number of RX buffers */
399 #define ATH_TXBUF 200 /* number of TX buffers */
400
401 -#define ATH_MAXVAPS_MIN 2 /* minimum number of beacon buffers */
402 -#define ATH_MAXVAPS_MAX 64 /* maximum number of beacon buffers */
403 -#define ATH_MAXVAPS_DEFAULT 4 /* default number of beacon buffers */
404 +#define ATH_MAXVAPS_BCN 4 /* maximum number of beacon buffers */
405
406 /* free buffer threshold to restart net dev */
407 #define ATH_TXBUF_FREE_THRESHOLD (ATH_TXBUF / 20)