Branch oldpackages for 14.07
[14.07/packages.git] / net / 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)