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 | |