Root/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)
408

Archive Download this file



interactive