]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/ath/if_ath_tdma.c
Fix compilation after r368397.
[FreeBSD/FreeBSD.git] / sys / dev / ath / if_ath_tdma.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer,
12  *    without modification.
13  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
14  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
15  *    redistribution must be conditioned upon including a substantially
16  *    similar Disclaimer requirement for further binary redistribution.
17  *
18  * NO WARRANTY
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
22  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
24  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
27  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
29  * THE POSSIBILITY OF SUCH DAMAGES.
30  */
31
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34
35 /*
36  * Driver for the Atheros Wireless LAN controller.
37  *
38  * This software is derived from work of Atsushi Onoe; his contribution
39  * is greatly appreciated.
40  */
41
42 #include "opt_inet.h"
43 #include "opt_ath.h"
44 /*
45  * This is needed for register operations which are performed
46  * by the driver - eg, calls to ath_hal_gettsf32().
47  *
48  * It's also required for any AH_DEBUG checks in here, eg the
49  * module dependencies.
50  */
51 #include "opt_ah.h"
52 #include "opt_wlan.h"
53
54 #include <sys/param.h>
55 #include <sys/systm.h>
56 #include <sys/sysctl.h>
57 #include <sys/mbuf.h>
58 #include <sys/malloc.h>
59 #include <sys/lock.h>
60 #include <sys/mutex.h>
61 #include <sys/kernel.h>
62 #include <sys/socket.h>
63 #include <sys/sockio.h>
64 #include <sys/errno.h>
65 #include <sys/callout.h>
66 #include <sys/bus.h>
67 #include <sys/endian.h>
68 #include <sys/kthread.h>
69 #include <sys/taskqueue.h>
70 #include <sys/priv.h>
71 #include <sys/module.h>
72 #include <sys/ktr.h>
73 #include <sys/smp.h>    /* for mp_ncpus */
74
75 #include <machine/bus.h>
76
77 #include <net/if.h>
78 #include <net/if_var.h>
79 #include <net/if_dl.h>
80 #include <net/if_media.h>
81 #include <net/if_types.h>
82 #include <net/if_arp.h>
83 #include <net/ethernet.h>
84 #include <net/if_llc.h>
85
86 #include <net80211/ieee80211_var.h>
87 #include <net80211/ieee80211_regdomain.h>
88 #ifdef IEEE80211_SUPPORT_SUPERG
89 #include <net80211/ieee80211_superg.h>
90 #endif
91 #ifdef IEEE80211_SUPPORT_TDMA
92 #include <net80211/ieee80211_tdma.h>
93 #endif
94
95 #include <net/bpf.h>
96
97 #ifdef INET
98 #include <netinet/in.h>
99 #include <netinet/if_ether.h>
100 #endif
101
102 #include <dev/ath/if_athvar.h>
103 #include <dev/ath/ath_hal/ah_devid.h>           /* XXX for softled */
104 #include <dev/ath/ath_hal/ah_diagcodes.h>
105
106 #include <dev/ath/if_ath_debug.h>
107 #include <dev/ath/if_ath_misc.h>
108 #include <dev/ath/if_ath_tsf.h>
109 #include <dev/ath/if_ath_tx.h>
110 #include <dev/ath/if_ath_sysctl.h>
111 #include <dev/ath/if_ath_led.h>
112 #include <dev/ath/if_ath_keycache.h>
113 #include <dev/ath/if_ath_rx.h>
114 #include <dev/ath/if_ath_beacon.h>
115 #include <dev/ath/if_athdfs.h>
116
117 #ifdef ATH_TX99_DIAG
118 #include <dev/ath/ath_tx99/ath_tx99.h>
119 #endif
120
121 #ifdef  ATH_DEBUG_ALQ
122 #include <dev/ath/if_ath_alq.h>
123 #endif
124
125 #ifdef IEEE80211_SUPPORT_TDMA
126 #include <dev/ath/if_ath_tdma.h>
127
128 static void     ath_tdma_settimers(struct ath_softc *sc, u_int32_t nexttbtt,
129                     u_int32_t bintval);
130 static void     ath_tdma_bintvalsetup(struct ath_softc *sc,
131                     const struct ieee80211_tdma_state *tdma);
132 #endif /* IEEE80211_SUPPORT_TDMA */
133
134 #ifdef IEEE80211_SUPPORT_TDMA
135 static void
136 ath_tdma_settimers(struct ath_softc *sc, u_int32_t nexttbtt, u_int32_t bintval)
137 {
138         struct ath_hal *ah = sc->sc_ah;
139         HAL_BEACON_TIMERS bt;
140
141         bt.bt_intval = bintval | HAL_BEACON_ENA;
142         bt.bt_nexttbtt = nexttbtt;
143         bt.bt_nextdba = (nexttbtt<<3) - sc->sc_tdmadbaprep;
144         bt.bt_nextswba = (nexttbtt<<3) - sc->sc_tdmaswbaprep;
145         bt.bt_nextatim = nexttbtt+1;
146         /* Enables TBTT, DBA, SWBA timers by default */
147         bt.bt_flags = 0;
148 #if 0
149         DPRINTF(sc, ATH_DEBUG_TDMA_TIMER,
150             "%s: intval=%d (0x%08x) nexttbtt=%u (0x%08x), nextdba=%u (0x%08x), nextswba=%u (0x%08x),nextatim=%u (0x%08x)\n",
151             __func__,
152             bt.bt_intval,
153             bt.bt_intval,
154             bt.bt_nexttbtt,
155             bt.bt_nexttbtt,
156             bt.bt_nextdba,
157             bt.bt_nextdba,
158             bt.bt_nextswba,
159             bt.bt_nextswba,
160             bt.bt_nextatim,
161             bt.bt_nextatim);
162 #endif
163
164 #ifdef  ATH_DEBUG_ALQ
165         if (if_ath_alq_checkdebug(&sc->sc_alq, ATH_ALQ_TDMA_TIMER_SET)) {
166                 struct if_ath_alq_tdma_timer_set t;
167                 t.bt_intval = htobe32(bt.bt_intval);
168                 t.bt_nexttbtt = htobe32(bt.bt_nexttbtt);
169                 t.bt_nextdba = htobe32(bt.bt_nextdba);
170                 t.bt_nextswba = htobe32(bt.bt_nextswba);
171                 t.bt_nextatim = htobe32(bt.bt_nextatim);
172                 t.bt_flags = htobe32(bt.bt_flags);
173                 t.sc_tdmadbaprep = htobe32(sc->sc_tdmadbaprep);
174                 t.sc_tdmaswbaprep = htobe32(sc->sc_tdmaswbaprep);
175                 if_ath_alq_post(&sc->sc_alq, ATH_ALQ_TDMA_TIMER_SET,
176                     sizeof(t), (char *) &t);
177         }
178 #endif
179
180         DPRINTF(sc, ATH_DEBUG_TDMA_TIMER,
181             "%s: nexttbtt=%u (0x%08x), nexttbtt tsf=%lld (0x%08llx)\n",
182             __func__,
183             bt.bt_nexttbtt,
184             bt.bt_nexttbtt,
185             (long long) ( ((u_int64_t) (bt.bt_nexttbtt)) << 10),
186             (long long) ( ((u_int64_t) (bt.bt_nexttbtt)) << 10));
187         ath_hal_beaconsettimers(ah, &bt);
188 }
189
190 /*
191  * Calculate the beacon interval.  This is periodic in the
192  * superframe for the bss.  We assume each station is configured
193  * identically wrt transmit rate so the guard time we calculate
194  * above will be the same on all stations.  Note we need to
195  * factor in the xmit time because the hardware will schedule
196  * a frame for transmit if the start of the frame is within
197  * the burst time.  When we get hardware that properly kills
198  * frames in the PCU we can reduce/eliminate the guard time.
199  *
200  * Roundup to 1024 is so we have 1 TU buffer in the guard time
201  * to deal with the granularity of the nexttbtt timer.  11n MAC's
202  * with 1us timer granularity should allow us to reduce/eliminate
203  * this.
204  */
205 static void
206 ath_tdma_bintvalsetup(struct ath_softc *sc,
207         const struct ieee80211_tdma_state *tdma)
208 {
209         /* copy from vap state (XXX check all vaps have same value?) */
210         sc->sc_tdmaslotlen = tdma->tdma_slotlen;
211
212         sc->sc_tdmabintval = roundup((sc->sc_tdmaslotlen+sc->sc_tdmaguard) *
213                 tdma->tdma_slotcnt, 1024);
214         sc->sc_tdmabintval >>= 10;              /* TSF -> TU */
215         if (sc->sc_tdmabintval & 1)
216                 sc->sc_tdmabintval++;
217
218         if (tdma->tdma_slot == 0) {
219                 /*
220                  * Only slot 0 beacons; other slots respond.
221                  */
222                 sc->sc_imask |= HAL_INT_SWBA;
223                 sc->sc_tdmaswba = 0;            /* beacon immediately */
224         } else {
225                 /* XXX all vaps must be slot 0 or slot !0 */
226                 sc->sc_imask &= ~HAL_INT_SWBA;
227         }
228 }
229
230 /*
231  * Max 802.11 overhead.  This assumes no 4-address frames and
232  * the encapsulation done by ieee80211_encap (llc).  We also
233  * include potential crypto overhead.
234  */
235 #define IEEE80211_MAXOVERHEAD \
236         (sizeof(struct ieee80211_qosframe) \
237          + sizeof(struct llc) \
238          + IEEE80211_ADDR_LEN \
239          + IEEE80211_WEP_IVLEN \
240          + IEEE80211_WEP_KIDLEN \
241          + IEEE80211_WEP_CRCLEN \
242          + IEEE80211_WEP_MICLEN \
243          + IEEE80211_CRC_LEN)
244
245 /*
246  * Setup initially for tdma operation.  Start the beacon
247  * timers and enable SWBA if we are slot 0.  Otherwise
248  * we wait for slot 0 to arrive so we can sync up before
249  * starting to transmit.
250  */
251 void
252 ath_tdma_config(struct ath_softc *sc, struct ieee80211vap *vap)
253 {
254         struct ath_hal *ah = sc->sc_ah;
255         struct ieee80211com *ic = &sc->sc_ic;
256         const struct ieee80211_txparam *tp;
257         const struct ieee80211_tdma_state *tdma = NULL;
258         int rix;
259
260         if (vap == NULL) {
261                 vap = TAILQ_FIRST(&ic->ic_vaps);   /* XXX */
262                 if (vap == NULL) {
263                         device_printf(sc->sc_dev, "%s: no vaps?\n", __func__);
264                         return;
265                 }
266         }
267         /* XXX should take a locked ref to iv_bss */
268         tp = vap->iv_bss->ni_txparms;
269         /*
270          * Calculate the guard time for each slot.  This is the
271          * time to send a maximal-size frame according to the
272          * fixed/lowest transmit rate.  Note that the interface
273          * mtu does not include the 802.11 overhead so we must
274          * tack that on (ath_hal_computetxtime includes the
275          * preamble and plcp in its calculation).
276          */
277         tdma = vap->iv_tdma;
278         if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
279                 rix = ath_tx_findrix(sc, tp->ucastrate);
280         else
281                 rix = ath_tx_findrix(sc, tp->mcastrate);
282
283         /*
284          * If the chip supports enforcing TxOP on transmission,
285          * we can just delete the guard window.  It isn't at all required.
286          */
287         if (sc->sc_hasenforcetxop) {
288                 sc->sc_tdmaguard = 0;
289         } else {
290                 /* XXX short preamble assumed */
291                 /* XXX non-11n rate assumed */
292                 sc->sc_tdmaguard = ath_hal_computetxtime(ah, sc->sc_currates,
293                     vap->iv_ifp->if_mtu + IEEE80211_MAXOVERHEAD, rix, AH_TRUE,
294                     AH_TRUE);
295         }
296
297         ath_hal_intrset(ah, 0);
298
299         ath_beaconq_config(sc);                 /* setup h/w beacon q */
300         if (sc->sc_setcca)
301                 ath_hal_setcca(ah, AH_FALSE);   /* disable CCA */
302         ath_tdma_bintvalsetup(sc, tdma);        /* calculate beacon interval */
303         ath_tdma_settimers(sc, sc->sc_tdmabintval,
304                 sc->sc_tdmabintval | HAL_BEACON_RESET_TSF);
305         sc->sc_syncbeacon = 0;
306
307         sc->sc_avgtsfdeltap = TDMA_DUMMY_MARKER;
308         sc->sc_avgtsfdeltam = TDMA_DUMMY_MARKER;
309
310         ath_hal_intrset(ah, sc->sc_imask);
311
312         DPRINTF(sc, ATH_DEBUG_TDMA, "%s: slot %u len %uus cnt %u "
313             "bsched %u guard %uus bintval %u TU dba prep %u\n", __func__,
314             tdma->tdma_slot, tdma->tdma_slotlen, tdma->tdma_slotcnt,
315             tdma->tdma_bintval, sc->sc_tdmaguard, sc->sc_tdmabintval,
316             sc->sc_tdmadbaprep);
317
318 #ifdef  ATH_DEBUG_ALQ
319         if (if_ath_alq_checkdebug(&sc->sc_alq, ATH_ALQ_TDMA_TIMER_CONFIG)) {
320                 struct if_ath_alq_tdma_timer_config t;
321
322                 t.tdma_slot = htobe32(tdma->tdma_slot);
323                 t.tdma_slotlen = htobe32(tdma->tdma_slotlen);
324                 t.tdma_slotcnt = htobe32(tdma->tdma_slotcnt);
325                 t.tdma_bintval = htobe32(tdma->tdma_bintval);
326                 t.tdma_guard = htobe32(sc->sc_tdmaguard);
327                 t.tdma_scbintval = htobe32(sc->sc_tdmabintval);
328                 t.tdma_dbaprep = htobe32(sc->sc_tdmadbaprep);
329
330                 if_ath_alq_post(&sc->sc_alq, ATH_ALQ_TDMA_TIMER_CONFIG,
331                     sizeof(t), (char *) &t);
332         }
333 #endif  /* ATH_DEBUG_ALQ */
334 }
335
336 /*
337  * Update tdma operation.  Called from the 802.11 layer
338  * when a beacon is received from the TDMA station operating
339  * in the slot immediately preceding us in the bss.  Use
340  * the rx timestamp for the beacon frame to update our
341  * beacon timers so we follow their schedule.  Note that
342  * by using the rx timestamp we implicitly include the
343  * propagation delay in our schedule.
344  *
345  * XXX TODO: since the changes for the AR5416 and later chips
346  * involved changing the TSF/TU calculations, we need to make
347  * sure that various calculations wrap consistently.
348  *
349  * A lot of the problems stemmed from the calculations wrapping
350  * at 65,535 TU.  Since a lot of the math is still being done in
351  * TU, please audit it to ensure that when the TU values programmed
352  * into the timers wrap at (2^31)-1 TSF, all the various terms
353  * wrap consistently.
354  */
355 void
356 ath_tdma_update(struct ieee80211_node *ni,
357         const struct ieee80211_tdma_param *tdma, int changed)
358 {
359 #define TSF_TO_TU(_h,_l) \
360         ((((u_int32_t)(_h)) << 22) | (((u_int32_t)(_l)) >> 10))
361 #define TU_TO_TSF(_tu)  (((u_int64_t)(_tu)) << 10)
362         struct ieee80211vap *vap = ni->ni_vap;
363         struct ieee80211com *ic = ni->ni_ic;
364         struct ath_softc *sc = ic->ic_softc;
365         struct ath_hal *ah = sc->sc_ah;
366         const HAL_RATE_TABLE *rt = sc->sc_currates;
367         u_int64_t tsf, rstamp, nextslot, nexttbtt, nexttbtt_full;
368         u_int32_t txtime, nextslottu;
369         int32_t tudelta, tsfdelta;
370         const struct ath_rx_status *rs;
371         int rix;
372
373         sc->sc_stats.ast_tdma_update++;
374
375         /*
376          * Check for and adopt configuration changes.
377          */
378         if (changed != 0) {
379                 const struct ieee80211_tdma_state *ts = vap->iv_tdma;
380
381                 ath_tdma_bintvalsetup(sc, ts);
382                 if (changed & TDMA_UPDATE_SLOTLEN)
383                         ath_wme_update(ic);
384
385                 DPRINTF(sc, ATH_DEBUG_TDMA,
386                     "%s: adopt slot %u slotcnt %u slotlen %u us "
387                     "bintval %u TU\n", __func__,
388                     ts->tdma_slot, ts->tdma_slotcnt, ts->tdma_slotlen,
389                     sc->sc_tdmabintval);
390
391                 /* XXX right? */
392                 ath_hal_intrset(ah, sc->sc_imask);
393                 /* NB: beacon timers programmed below */
394         }
395
396         /* extend rx timestamp to 64 bits */
397         rs = sc->sc_lastrs;
398         tsf = ath_hal_gettsf64(ah);
399         rstamp = ath_extend_tsf(sc, rs->rs_tstamp, tsf);
400         /*
401          * The rx timestamp is set by the hardware on completing
402          * reception (at the point where the rx descriptor is DMA'd
403          * to the host).  To find the start of our next slot we
404          * must adjust this time by the time required to send
405          * the packet just received.
406          */
407         rix = rt->rateCodeToIndex[rs->rs_rate];
408
409         /*
410          * To calculate the packet duration for legacy rates, we
411          * only need the rix and preamble.
412          *
413          * For 11n non-aggregate frames, we also need the channel
414          * width and short/long guard interval.
415          *
416          * For 11n aggregate frames, the required hacks are a little
417          * more subtle.  You need to figure out the frame duration
418          * for each frame, including the delimiters.  However, when
419          * a frame isn't received successfully, we won't hear it
420          * (unless you enable reception of CRC errored frames), so
421          * your duration calculation is going to be off.
422          *
423          * However, we can assume that the beacon frames won't be
424          * transmitted as aggregate frames, so we should be okay.
425          * Just add a check to ensure that we aren't handed something
426          * bad.
427          *
428          * For ath_hal_pkt_txtime() - for 11n rates, shortPreamble is
429          * actually short guard interval. For legacy rates,
430          * it's short preamble.
431          */
432         txtime = ath_hal_pkt_txtime(ah, rt, rs->rs_datalen,
433             rix,
434             !! (rs->rs_flags & HAL_RX_2040),
435             (rix & 0x80) ?
436               (! (rs->rs_flags & HAL_RX_GI)) : rt->info[rix].shortPreamble,
437             AH_TRUE);
438         /* NB: << 9 is to cvt to TU and /2 */
439         nextslot = (rstamp - txtime) + (sc->sc_tdmabintval << 9);
440
441         /*
442          * For 802.11n chips: nextslottu needs to be the full TSF space,
443          * not just 0..65535 TU.
444          */
445         nextslottu = TSF_TO_TU(nextslot>>32, nextslot);
446         /*
447          * Retrieve the hardware NextTBTT in usecs
448          * and calculate the difference between what the
449          * other station thinks and what we have programmed.  This
450          * lets us figure how to adjust our timers to match.  The
451          * adjustments are done by pulling the TSF forward and possibly
452          * rewriting the beacon timers.
453          */
454         /*
455          * The logic here assumes the nexttbtt counter is in TSF
456          * but the prr-11n NICs are in TU.  The HAL shifts them
457          * to TSF but there's two important differences:
458          *
459          * + The TU->TSF values have 0's for the low 9 bits, and
460          * + The counter wraps at TU_TO_TSF(HAL_BEACON_PERIOD + 1) for
461          *   the pre-11n NICs, but not for the 11n NICs.
462          *
463          * So for now, just make sure the nexttbtt value we get
464          * matches the second issue or once nexttbtt exceeds this
465          * value, tsfdelta ends up becoming very negative and all
466          * of the adjustments get very messed up.
467          */
468
469         /*
470          * We need to track the full nexttbtt rather than having it
471          * truncated at HAL_BEACON_PERIOD, as programming the
472          * nexttbtt (and related) registers for the 11n chips is
473          * actually going to take the full 32 bit space, rather than
474          * just 0..65535 TU.
475          */
476         nexttbtt_full = ath_hal_getnexttbtt(ah);
477         nexttbtt = nexttbtt_full % (TU_TO_TSF(HAL_BEACON_PERIOD + 1));
478         tsfdelta = (int32_t)((nextslot % TU_TO_TSF(HAL_BEACON_PERIOD + 1)) - nexttbtt);
479
480         DPRINTF(sc, ATH_DEBUG_TDMA_TIMER,
481             "rs->rstamp %llu rstamp %llu tsf %llu txtime %d, nextslot %llu, "
482             "nextslottu %d, nextslottume %d\n",
483             (unsigned long long) rs->rs_tstamp,
484             (unsigned long long) rstamp,
485             (unsigned long long) tsf, txtime,
486             (unsigned long long) nextslot,
487             nextslottu, TSF_TO_TU(nextslot >> 32, nextslot));
488         DPRINTF(sc, ATH_DEBUG_TDMA,
489             "  beacon tstamp: %llu (0x%016llx)\n",
490             (unsigned long long) le64toh(ni->ni_tstamp.tsf),
491             (unsigned long long) le64toh(ni->ni_tstamp.tsf));
492
493         DPRINTF(sc, ATH_DEBUG_TDMA_TIMER,
494             "nexttbtt %llu (0x%08llx) tsfdelta %d avg +%d/-%d\n",
495             (unsigned long long) nexttbtt,
496             (long long) nexttbtt,
497             tsfdelta,
498             TDMA_AVG(sc->sc_avgtsfdeltap), TDMA_AVG(sc->sc_avgtsfdeltam));
499
500         if (tsfdelta < 0) {
501                 TDMA_SAMPLE(sc->sc_avgtsfdeltap, 0);
502                 TDMA_SAMPLE(sc->sc_avgtsfdeltam, -tsfdelta);
503                 tsfdelta = -tsfdelta % 1024;
504                 nextslottu++;
505         } else if (tsfdelta > 0) {
506                 TDMA_SAMPLE(sc->sc_avgtsfdeltap, tsfdelta);
507                 TDMA_SAMPLE(sc->sc_avgtsfdeltam, 0);
508                 tsfdelta = 1024 - (tsfdelta % 1024);
509                 nextslottu++;
510         } else {
511                 TDMA_SAMPLE(sc->sc_avgtsfdeltap, 0);
512                 TDMA_SAMPLE(sc->sc_avgtsfdeltam, 0);
513         }
514         tudelta = nextslottu - TSF_TO_TU(nexttbtt_full >> 32, nexttbtt_full);
515
516 #ifdef  ATH_DEBUG_ALQ
517         if (if_ath_alq_checkdebug(&sc->sc_alq, ATH_ALQ_TDMA_BEACON_STATE)) {
518                 struct if_ath_alq_tdma_beacon_state t;
519                 t.rx_tsf = htobe64(rstamp);
520                 t.beacon_tsf = htobe64(le64toh(ni->ni_tstamp.tsf));
521                 t.tsf64 = htobe64(tsf);
522                 t.nextslot_tsf = htobe64(nextslot);
523                 t.nextslot_tu = htobe32(nextslottu);
524                 t.txtime = htobe32(txtime);
525                 if_ath_alq_post(&sc->sc_alq, ATH_ALQ_TDMA_BEACON_STATE,
526                     sizeof(t), (char *) &t);
527         }
528
529         if (if_ath_alq_checkdebug(&sc->sc_alq, ATH_ALQ_TDMA_SLOT_CALC)) {
530                 struct if_ath_alq_tdma_slot_calc t;
531
532                 t.nexttbtt = htobe64(nexttbtt_full);
533                 t.next_slot = htobe64(nextslot);
534                 t.tsfdelta = htobe32(tsfdelta);
535                 t.avg_plus = htobe32(TDMA_AVG(sc->sc_avgtsfdeltap));
536                 t.avg_minus = htobe32(TDMA_AVG(sc->sc_avgtsfdeltam));
537
538                 if_ath_alq_post(&sc->sc_alq, ATH_ALQ_TDMA_SLOT_CALC,
539                     sizeof(t), (char *) &t);
540         }
541 #endif
542
543         /*
544          * Copy sender's timetstamp into tdma ie so they can
545          * calculate roundtrip time.  We submit a beacon frame
546          * below after any timer adjustment.  The frame goes out
547          * at the next TBTT so the sender can calculate the
548          * roundtrip by inspecting the tdma ie in our beacon frame.
549          *
550          * NB: This tstamp is subtlely preserved when
551          *     IEEE80211_BEACON_TDMA is marked (e.g. when the
552          *     slot position changes) because ieee80211_add_tdma
553          *     skips over the data.
554          */
555         memcpy(vap->iv_bcn_off.bo_tdma +
556                 __offsetof(struct ieee80211_tdma_param, tdma_tstamp),
557                 &ni->ni_tstamp.data, 8);
558 #if 0
559         DPRINTF(sc, ATH_DEBUG_TDMA_TIMER,
560             "tsf %llu nextslot %llu (%d, %d) nextslottu %u nexttbtt %llu (%d)\n",
561             (unsigned long long) tsf, (unsigned long long) nextslot,
562             (int)(nextslot - tsf), tsfdelta, nextslottu, nexttbtt, tudelta);
563 #endif
564         /*
565          * Adjust the beacon timers only when pulling them forward
566          * or when going back by less than the beacon interval.
567          * Negative jumps larger than the beacon interval seem to
568          * cause the timers to stop and generally cause instability.
569          * This basically filters out jumps due to missed beacons.
570          */
571         if (tudelta != 0 && (tudelta > 0 || -tudelta < sc->sc_tdmabintval)) {
572                 DPRINTF(sc, ATH_DEBUG_TDMA_TIMER,
573                     "%s: calling ath_tdma_settimers; nextslottu=%d, bintval=%d\n",
574                     __func__,
575                     nextslottu,
576                     sc->sc_tdmabintval);
577                 ath_tdma_settimers(sc, nextslottu, sc->sc_tdmabintval);
578                 sc->sc_stats.ast_tdma_timers++;
579         }
580         if (tsfdelta > 0) {
581                 uint64_t tsf;
582
583                 /* XXX should just teach ath_hal_adjusttsf() to do this */
584                 tsf = ath_hal_gettsf64(ah);
585                 ath_hal_settsf64(ah, tsf + tsfdelta);
586                 DPRINTF(sc, ATH_DEBUG_TDMA_TIMER,
587                     "%s: calling ath_hal_adjusttsf: TSF=%llu, tsfdelta=%d\n",
588                     __func__,
589                     (unsigned long long) tsf,
590                     tsfdelta);
591
592 #ifdef  ATH_DEBUG_ALQ
593                 if (if_ath_alq_checkdebug(&sc->sc_alq,
594                     ATH_ALQ_TDMA_TSF_ADJUST)) {
595                         struct if_ath_alq_tdma_tsf_adjust t;
596
597                         t.tsfdelta = htobe32(tsfdelta);
598                         t.tsf64_old = htobe64(tsf);
599                         t.tsf64_new = htobe64(tsf + tsfdelta);
600                         if_ath_alq_post(&sc->sc_alq, ATH_ALQ_TDMA_TSF_ADJUST,
601                             sizeof(t), (char *) &t);
602                 }
603 #endif  /* ATH_DEBUG_ALQ */
604                 sc->sc_stats.ast_tdma_tsf++;
605         }
606         ath_tdma_beacon_send(sc, vap);          /* prepare response */
607 #undef TU_TO_TSF
608 #undef TSF_TO_TU
609 }
610
611 /*
612  * Transmit a beacon frame at SWBA.  Dynamic updates
613  * to the frame contents are done as needed.
614  */
615 void
616 ath_tdma_beacon_send(struct ath_softc *sc, struct ieee80211vap *vap)
617 {
618         struct ath_hal *ah = sc->sc_ah;
619         struct ath_buf *bf;
620         int otherant;
621
622         /*
623          * Check if the previous beacon has gone out.  If
624          * not don't try to post another, skip this period
625          * and wait for the next.  Missed beacons indicate
626          * a problem and should not occur.  If we miss too
627          * many consecutive beacons reset the device.
628          */
629         if (ath_hal_numtxpending(ah, sc->sc_bhalq) != 0) {
630                 sc->sc_bmisscount++;
631                 DPRINTF(sc, ATH_DEBUG_BEACON,
632                         "%s: missed %u consecutive beacons\n",
633                         __func__, sc->sc_bmisscount);
634                 if (sc->sc_bmisscount >= ath_bstuck_threshold)
635                         taskqueue_enqueue(sc->sc_tq, &sc->sc_bstucktask);
636                 return;
637         }
638         if (sc->sc_bmisscount != 0) {
639                 DPRINTF(sc, ATH_DEBUG_BEACON,
640                         "%s: resume beacon xmit after %u misses\n",
641                         __func__, sc->sc_bmisscount);
642                 sc->sc_bmisscount = 0;
643         }
644
645         /*
646          * Check recent per-antenna transmit statistics and flip
647          * the default antenna if noticeably more frames went out
648          * on the non-default antenna.
649          * XXX assumes 2 anntenae
650          */
651         if (!sc->sc_diversity) {
652                 otherant = sc->sc_defant & 1 ? 2 : 1;
653                 if (sc->sc_ant_tx[otherant] > sc->sc_ant_tx[sc->sc_defant] + 2)
654                         ath_setdefantenna(sc, otherant);
655                 sc->sc_ant_tx[1] = sc->sc_ant_tx[2] = 0;
656         }
657
658         bf = ath_beacon_generate(sc, vap);
659         /* XXX We don't do cabq traffic, but just for completeness .. */
660         ATH_TXQ_LOCK(sc->sc_cabq);
661         ath_beacon_cabq_start(sc);
662         ATH_TXQ_UNLOCK(sc->sc_cabq);
663
664         if (bf != NULL) {
665                 /*
666                  * Stop any current dma and put the new frame on the queue.
667                  * This should never fail since we check above that no frames
668                  * are still pending on the queue.
669                  */
670                 if ((! sc->sc_isedma) &&
671                     (! ath_hal_stoptxdma(ah, sc->sc_bhalq))) {
672                         DPRINTF(sc, ATH_DEBUG_ANY,
673                                 "%s: beacon queue %u did not stop?\n",
674                                 __func__, sc->sc_bhalq);
675                         /* NB: the HAL still stops DMA, so proceed */
676                 }
677                 ath_hal_puttxbuf(ah, sc->sc_bhalq, bf->bf_daddr);
678                 ath_hal_txstart(ah, sc->sc_bhalq);
679
680                 sc->sc_stats.ast_be_xmit++;             /* XXX per-vap? */
681
682                 /*
683                  * Record local TSF for our last send for use
684                  * in arbitrating slot collisions.
685                  */
686                 /* XXX should take a locked ref to iv_bss */
687                 vap->iv_bss->ni_tstamp.tsf = ath_hal_gettsf64(ah);
688         }
689 }
690 #endif /* IEEE80211_SUPPORT_TDMA */