]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/ath/if_ath_sysctl.c
Implement a separate, smaller pool of ath_buf entries for use by management
[FreeBSD/FreeBSD.git] / sys / dev / ath / if_ath_sysctl.c
1 /*-
2  * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer,
10  *    without modification.
11  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13  *    redistribution must be conditioned upon including a substantially
14  *    similar Disclaimer requirement for further binary redistribution.
15  *
16  * NO WARRANTY
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27  * THE POSSIBILITY OF SUCH DAMAGES.
28  */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 /*
34  * Driver for the Atheros Wireless LAN controller.
35  *
36  * This software is derived from work of Atsushi Onoe; his contribution
37  * is greatly appreciated.
38  */
39
40 #include "opt_inet.h"
41 #include "opt_ath.h"
42 #include "opt_wlan.h"
43
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/sysctl.h>
47 #include <sys/mbuf.h>
48 #include <sys/malloc.h>
49 #include <sys/lock.h>
50 #include <sys/mutex.h>
51 #include <sys/kernel.h>
52 #include <sys/socket.h>
53 #include <sys/sockio.h>
54 #include <sys/errno.h>
55 #include <sys/callout.h>
56 #include <sys/bus.h>
57 #include <sys/endian.h>
58 #include <sys/kthread.h>
59 #include <sys/taskqueue.h>
60 #include <sys/priv.h>
61
62 #include <machine/bus.h>
63
64 #include <net/if.h>
65 #include <net/if_dl.h>
66 #include <net/if_media.h>
67 #include <net/if_types.h>
68 #include <net/if_arp.h>
69 #include <net/ethernet.h>
70 #include <net/if_llc.h>
71
72 #include <net80211/ieee80211_var.h>
73 #include <net80211/ieee80211_regdomain.h>
74 #ifdef IEEE80211_SUPPORT_SUPERG
75 #include <net80211/ieee80211_superg.h>
76 #endif
77 #ifdef IEEE80211_SUPPORT_TDMA
78 #include <net80211/ieee80211_tdma.h>
79 #endif
80
81 #include <net/bpf.h>
82
83 #ifdef INET
84 #include <netinet/in.h>
85 #include <netinet/if_ether.h>
86 #endif
87
88 #include <dev/ath/if_athvar.h>
89 #include <dev/ath/ath_hal/ah_devid.h>           /* XXX for softled */
90 #include <dev/ath/ath_hal/ah_diagcodes.h>
91
92 #include <dev/ath/if_ath_debug.h>
93 #include <dev/ath/if_ath_led.h>
94 #include <dev/ath/if_ath_misc.h>
95 #include <dev/ath/if_ath_tx.h>
96 #include <dev/ath/if_ath_sysctl.h>
97
98 #ifdef ATH_TX99_DIAG
99 #include <dev/ath/ath_tx99/ath_tx99.h>
100 #endif
101
102 static int
103 ath_sysctl_slottime(SYSCTL_HANDLER_ARGS)
104 {
105         struct ath_softc *sc = arg1;
106         u_int slottime = ath_hal_getslottime(sc->sc_ah);
107         int error;
108
109         error = sysctl_handle_int(oidp, &slottime, 0, req);
110         if (error || !req->newptr)
111                 return error;
112         return !ath_hal_setslottime(sc->sc_ah, slottime) ? EINVAL : 0;
113 }
114
115 static int
116 ath_sysctl_acktimeout(SYSCTL_HANDLER_ARGS)
117 {
118         struct ath_softc *sc = arg1;
119         u_int acktimeout = ath_hal_getacktimeout(sc->sc_ah);
120         int error;
121
122         error = sysctl_handle_int(oidp, &acktimeout, 0, req);
123         if (error || !req->newptr)
124                 return error;
125         return !ath_hal_setacktimeout(sc->sc_ah, acktimeout) ? EINVAL : 0;
126 }
127
128 static int
129 ath_sysctl_ctstimeout(SYSCTL_HANDLER_ARGS)
130 {
131         struct ath_softc *sc = arg1;
132         u_int ctstimeout = ath_hal_getctstimeout(sc->sc_ah);
133         int error;
134
135         error = sysctl_handle_int(oidp, &ctstimeout, 0, req);
136         if (error || !req->newptr)
137                 return error;
138         return !ath_hal_setctstimeout(sc->sc_ah, ctstimeout) ? EINVAL : 0;
139 }
140
141 static int
142 ath_sysctl_softled(SYSCTL_HANDLER_ARGS)
143 {
144         struct ath_softc *sc = arg1;
145         int softled = sc->sc_softled;
146         int error;
147
148         error = sysctl_handle_int(oidp, &softled, 0, req);
149         if (error || !req->newptr)
150                 return error;
151         softled = (softled != 0);
152         if (softled != sc->sc_softled) {
153                 if (softled) {
154                         /* NB: handle any sc_ledpin change */
155                         ath_led_config(sc);
156                 }
157                 sc->sc_softled = softled;
158         }
159         return 0;
160 }
161
162 static int
163 ath_sysctl_ledpin(SYSCTL_HANDLER_ARGS)
164 {
165         struct ath_softc *sc = arg1;
166         int ledpin = sc->sc_ledpin;
167         int error;
168
169         error = sysctl_handle_int(oidp, &ledpin, 0, req);
170         if (error || !req->newptr)
171                 return error;
172         if (ledpin != sc->sc_ledpin) {
173                 sc->sc_ledpin = ledpin;
174                 if (sc->sc_softled) {
175                         ath_led_config(sc);
176                 }
177         }
178         return 0;
179 }
180
181 static int
182 ath_sysctl_hardled(SYSCTL_HANDLER_ARGS)
183 {
184         struct ath_softc *sc = arg1;
185         int hardled = sc->sc_hardled;
186         int error;
187
188         error = sysctl_handle_int(oidp, &hardled, 0, req);
189         if (error || !req->newptr)
190                 return error;
191         hardled = (hardled != 0);
192         if (hardled != sc->sc_hardled) {
193                 if (hardled) {
194                         /* NB: handle any sc_ledpin change */
195                         ath_led_config(sc);
196                 }
197                 sc->sc_hardled = hardled;
198         }
199         return 0;
200 }
201
202 static int
203 ath_sysctl_txantenna(SYSCTL_HANDLER_ARGS)
204 {
205         struct ath_softc *sc = arg1;
206         u_int txantenna = ath_hal_getantennaswitch(sc->sc_ah);
207         int error;
208
209         error = sysctl_handle_int(oidp, &txantenna, 0, req);
210         if (!error && req->newptr) {
211                 /* XXX assumes 2 antenna ports */
212                 if (txantenna < HAL_ANT_VARIABLE || txantenna > HAL_ANT_FIXED_B)
213                         return EINVAL;
214                 ath_hal_setantennaswitch(sc->sc_ah, txantenna);
215                 /*
216                  * NB: with the switch locked this isn't meaningful,
217                  *     but set it anyway so things like radiotap get
218                  *     consistent info in their data.
219                  */
220                 sc->sc_txantenna = txantenna;
221         }
222         return error;
223 }
224
225 static int
226 ath_sysctl_rxantenna(SYSCTL_HANDLER_ARGS)
227 {
228         struct ath_softc *sc = arg1;
229         u_int defantenna = ath_hal_getdefantenna(sc->sc_ah);
230         int error;
231
232         error = sysctl_handle_int(oidp, &defantenna, 0, req);
233         if (!error && req->newptr)
234                 ath_hal_setdefantenna(sc->sc_ah, defantenna);
235         return error;
236 }
237
238 static int
239 ath_sysctl_diversity(SYSCTL_HANDLER_ARGS)
240 {
241         struct ath_softc *sc = arg1;
242         u_int diversity = ath_hal_getdiversity(sc->sc_ah);
243         int error;
244
245         error = sysctl_handle_int(oidp, &diversity, 0, req);
246         if (error || !req->newptr)
247                 return error;
248         if (!ath_hal_setdiversity(sc->sc_ah, diversity))
249                 return EINVAL;
250         sc->sc_diversity = diversity;
251         return 0;
252 }
253
254 static int
255 ath_sysctl_diag(SYSCTL_HANDLER_ARGS)
256 {
257         struct ath_softc *sc = arg1;
258         u_int32_t diag;
259         int error;
260
261         if (!ath_hal_getdiag(sc->sc_ah, &diag))
262                 return EINVAL;
263         error = sysctl_handle_int(oidp, &diag, 0, req);
264         if (error || !req->newptr)
265                 return error;
266         return !ath_hal_setdiag(sc->sc_ah, diag) ? EINVAL : 0;
267 }
268
269 static int
270 ath_sysctl_tpscale(SYSCTL_HANDLER_ARGS)
271 {
272         struct ath_softc *sc = arg1;
273         struct ifnet *ifp = sc->sc_ifp;
274         u_int32_t scale;
275         int error;
276
277         (void) ath_hal_gettpscale(sc->sc_ah, &scale);
278         error = sysctl_handle_int(oidp, &scale, 0, req);
279         if (error || !req->newptr)
280                 return error;
281         return !ath_hal_settpscale(sc->sc_ah, scale) ? EINVAL :
282             (ifp->if_drv_flags & IFF_DRV_RUNNING) ?
283               ath_reset(ifp, ATH_RESET_NOLOSS) : 0;
284 }
285
286 static int
287 ath_sysctl_tpc(SYSCTL_HANDLER_ARGS)
288 {
289         struct ath_softc *sc = arg1;
290         u_int tpc = ath_hal_gettpc(sc->sc_ah);
291         int error;
292
293         error = sysctl_handle_int(oidp, &tpc, 0, req);
294         if (error || !req->newptr)
295                 return error;
296         return !ath_hal_settpc(sc->sc_ah, tpc) ? EINVAL : 0;
297 }
298
299 static int
300 ath_sysctl_rfkill(SYSCTL_HANDLER_ARGS)
301 {
302         struct ath_softc *sc = arg1;
303         struct ifnet *ifp = sc->sc_ifp;
304         struct ath_hal *ah = sc->sc_ah;
305         u_int rfkill = ath_hal_getrfkill(ah);
306         int error;
307
308         error = sysctl_handle_int(oidp, &rfkill, 0, req);
309         if (error || !req->newptr)
310                 return error;
311         if (rfkill == ath_hal_getrfkill(ah))    /* unchanged */
312                 return 0;
313         if (!ath_hal_setrfkill(ah, rfkill))
314                 return EINVAL;
315         return (ifp->if_drv_flags & IFF_DRV_RUNNING) ?
316             ath_reset(ifp, ATH_RESET_FULL) : 0;
317 }
318
319 static int
320 ath_sysctl_txagg(SYSCTL_HANDLER_ARGS)
321 {
322         struct ath_softc *sc = arg1;
323         int i, t, param = 0;
324         int error;
325         struct ath_buf *bf;
326
327         error = sysctl_handle_int(oidp, &param, 0, req);
328         if (error || !req->newptr)
329                 return error;
330
331         if (param != 1)
332                 return 0;
333
334         printf("no tx bufs (empty list): %d\n", sc->sc_stats.ast_tx_getnobuf);
335         printf("no tx bufs (was busy): %d\n", sc->sc_stats.ast_tx_getbusybuf);
336
337         printf("aggr single packet: %d\n",
338             sc->sc_aggr_stats.aggr_single_pkt);
339         printf("aggr single packet w/ BAW closed: %d\n",
340             sc->sc_aggr_stats.aggr_baw_closed_single_pkt);
341         printf("aggr non-baw packet: %d\n",
342             sc->sc_aggr_stats.aggr_nonbaw_pkt);
343         printf("aggr aggregate packet: %d\n",
344             sc->sc_aggr_stats.aggr_aggr_pkt);
345         printf("aggr single packet low hwq: %d\n",
346             sc->sc_aggr_stats.aggr_low_hwq_single_pkt);
347         printf("aggr single packet RTS aggr limited: %d\n",
348             sc->sc_aggr_stats.aggr_rts_aggr_limited);
349         printf("aggr sched, no work: %d\n",
350             sc->sc_aggr_stats.aggr_sched_nopkt);
351         for (i = 0; i < 64; i++) {
352                 printf("%2d: %10d ", i, sc->sc_aggr_stats.aggr_pkts[i]);
353                 if (i % 4 == 3)
354                         printf("\n");
355         }
356         printf("\n");
357
358         for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
359                 if (ATH_TXQ_SETUP(sc, i)) {
360                         printf("HW TXQ %d: axq_depth=%d, axq_aggr_depth=%d\n",
361                             i,
362                             sc->sc_txq[i].axq_depth,
363                             sc->sc_txq[i].axq_aggr_depth);
364                 }
365         }
366
367         i = t = 0;
368         ATH_TXBUF_LOCK(sc);
369         TAILQ_FOREACH(bf, &sc->sc_txbuf, bf_list) {
370                 if (bf->bf_flags & ATH_BUF_BUSY) {
371                         printf("Busy: %d\n", t);
372                         i++;
373                 }
374                 t++;
375         }
376         ATH_TXBUF_UNLOCK(sc);
377         printf("Total TX buffers: %d; Total TX buffers busy: %d\n",
378             t, i);
379
380         i = t = 0;
381         ATH_TXBUF_LOCK(sc);
382         TAILQ_FOREACH(bf, &sc->sc_txbuf_mgmt, bf_list) {
383                 if (bf->bf_flags & ATH_BUF_BUSY) {
384                         printf("Busy: %d\n", t);
385                         i++;
386                 }
387                 t++;
388         }
389         ATH_TXBUF_UNLOCK(sc);
390         printf("Total mgmt TX buffers: %d; Total mgmt TX buffers busy: %d\n",
391             t, i);
392
393         return 0;
394 }
395
396 static int
397 ath_sysctl_rfsilent(SYSCTL_HANDLER_ARGS)
398 {
399         struct ath_softc *sc = arg1;
400         u_int rfsilent;
401         int error;
402
403         (void) ath_hal_getrfsilent(sc->sc_ah, &rfsilent);
404         error = sysctl_handle_int(oidp, &rfsilent, 0, req);
405         if (error || !req->newptr)
406                 return error;
407         if (!ath_hal_setrfsilent(sc->sc_ah, rfsilent))
408                 return EINVAL;
409         sc->sc_rfsilentpin = rfsilent & 0x1c;
410         sc->sc_rfsilentpol = (rfsilent & 0x2) != 0;
411         return 0;
412 }
413
414 static int
415 ath_sysctl_tpack(SYSCTL_HANDLER_ARGS)
416 {
417         struct ath_softc *sc = arg1;
418         u_int32_t tpack;
419         int error;
420
421         (void) ath_hal_gettpack(sc->sc_ah, &tpack);
422         error = sysctl_handle_int(oidp, &tpack, 0, req);
423         if (error || !req->newptr)
424                 return error;
425         return !ath_hal_settpack(sc->sc_ah, tpack) ? EINVAL : 0;
426 }
427
428 static int
429 ath_sysctl_tpcts(SYSCTL_HANDLER_ARGS)
430 {
431         struct ath_softc *sc = arg1;
432         u_int32_t tpcts;
433         int error;
434
435         (void) ath_hal_gettpcts(sc->sc_ah, &tpcts);
436         error = sysctl_handle_int(oidp, &tpcts, 0, req);
437         if (error || !req->newptr)
438                 return error;
439         return !ath_hal_settpcts(sc->sc_ah, tpcts) ? EINVAL : 0;
440 }
441
442 static int
443 ath_sysctl_intmit(SYSCTL_HANDLER_ARGS)
444 {
445         struct ath_softc *sc = arg1;
446         int intmit, error;
447
448         intmit = ath_hal_getintmit(sc->sc_ah);
449         error = sysctl_handle_int(oidp, &intmit, 0, req);
450         if (error || !req->newptr)
451                 return error;
452
453         /* reusing error; 1 here means "good"; 0 means "fail" */
454         error = ath_hal_setintmit(sc->sc_ah, intmit);
455         if (! error)
456                 return EINVAL;
457
458         /*
459          * Reset the hardware here - disabling ANI in the HAL
460          * doesn't reset ANI related registers, so it'll leave
461          * things in an inconsistent state.
462          */
463         if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
464                 ath_reset(sc->sc_ifp, ATH_RESET_NOLOSS);
465
466         return 0;
467 }
468
469 #ifdef IEEE80211_SUPPORT_TDMA
470 static int
471 ath_sysctl_setcca(SYSCTL_HANDLER_ARGS)
472 {
473         struct ath_softc *sc = arg1;
474         int setcca, error;
475
476         setcca = sc->sc_setcca;
477         error = sysctl_handle_int(oidp, &setcca, 0, req);
478         if (error || !req->newptr)
479                 return error;
480         sc->sc_setcca = (setcca != 0);
481         return 0;
482 }
483 #endif /* IEEE80211_SUPPORT_TDMA */
484
485 static int
486 ath_sysctl_forcebstuck(SYSCTL_HANDLER_ARGS)
487 {
488         struct ath_softc *sc = arg1;
489         int val = 0;
490         int error;
491
492         error = sysctl_handle_int(oidp, &val, 0, req);
493         if (error || !req->newptr)
494                 return error;
495         if (val == 0)
496                 return 0;
497
498         taskqueue_enqueue_fast(sc->sc_tq, &sc->sc_bstucktask);
499         val = 0;
500         return 0;
501 }
502
503 void
504 ath_sysctlattach(struct ath_softc *sc)
505 {
506         struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
507         struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
508         struct ath_hal *ah = sc->sc_ah;
509
510         SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
511                 "countrycode", CTLFLAG_RD, &sc->sc_eecc, 0,
512                 "EEPROM country code");
513         SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
514                 "regdomain", CTLFLAG_RD, &sc->sc_eerd, 0,
515                 "EEPROM regdomain code");
516 #ifdef  ATH_DEBUG
517         SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
518                 "debug", CTLFLAG_RW, &sc->sc_debug,
519                 "control debugging printfs");
520 #endif
521         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
522                 "slottime", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
523                 ath_sysctl_slottime, "I", "802.11 slot time (us)");
524         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
525                 "acktimeout", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
526                 ath_sysctl_acktimeout, "I", "802.11 ACK timeout (us)");
527         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
528                 "ctstimeout", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
529                 ath_sysctl_ctstimeout, "I", "802.11 CTS timeout (us)");
530
531         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
532                 "softled", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
533                 ath_sysctl_softled, "I", "enable/disable software LED support");
534         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
535                 "ledpin", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
536                 ath_sysctl_ledpin, "I", "GPIO pin connected to LED");
537         SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
538                 "ledon", CTLFLAG_RW, &sc->sc_ledon, 0,
539                 "setting to turn LED on");
540         SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
541                 "ledidle", CTLFLAG_RW, &sc->sc_ledidle, 0,
542                 "idle time for inactivity LED (ticks)");
543
544         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
545                 "hardled", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
546                 ath_sysctl_hardled, "I", "enable/disable hardware LED support");
547         /* XXX Laziness - configure pins, then flip hardled off/on */
548         SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
549                 "led_net_pin", CTLFLAG_RW, &sc->sc_led_net_pin, 0,
550                 "MAC Network LED pin, or -1 to disable");
551         SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
552                 "led_pwr_pin", CTLFLAG_RW, &sc->sc_led_pwr_pin, 0,
553                 "MAC Power LED pin, or -1 to disable");
554
555         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
556                 "txantenna", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
557                 ath_sysctl_txantenna, "I", "antenna switch");
558         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
559                 "rxantenna", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
560                 ath_sysctl_rxantenna, "I", "default/rx antenna");
561         if (ath_hal_hasdiversity(ah))
562                 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
563                         "diversity", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
564                         ath_sysctl_diversity, "I", "antenna diversity");
565         sc->sc_txintrperiod = ATH_TXINTR_PERIOD;
566         SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
567                 "txintrperiod", CTLFLAG_RW, &sc->sc_txintrperiod, 0,
568                 "tx descriptor batching");
569         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
570                 "diag", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
571                 ath_sysctl_diag, "I", "h/w diagnostic control");
572         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
573                 "tpscale", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
574                 ath_sysctl_tpscale, "I", "tx power scaling");
575         if (ath_hal_hastpc(ah)) {
576                 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
577                         "tpc", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
578                         ath_sysctl_tpc, "I", "enable/disable per-packet TPC");
579                 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
580                         "tpack", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
581                         ath_sysctl_tpack, "I", "tx power for ack frames");
582                 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
583                         "tpcts", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
584                         ath_sysctl_tpcts, "I", "tx power for cts frames");
585         }
586         if (ath_hal_hasrfsilent(ah)) {
587                 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
588                         "rfsilent", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
589                         ath_sysctl_rfsilent, "I", "h/w RF silent config");
590                 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
591                         "rfkill", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
592                         ath_sysctl_rfkill, "I", "enable/disable RF kill switch");
593         }
594
595         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
596                 "txagg", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
597                 ath_sysctl_txagg, "I", "");
598
599         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
600                 "forcebstuck", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
601                 ath_sysctl_forcebstuck, "I", "");
602
603         if (ath_hal_hasintmit(ah)) {
604                 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
605                         "intmit", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
606                         ath_sysctl_intmit, "I", "interference mitigation");
607         }
608         sc->sc_monpass = HAL_RXERR_DECRYPT | HAL_RXERR_MIC;
609         SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
610                 "monpass", CTLFLAG_RW, &sc->sc_monpass, 0,
611                 "mask of error frames to pass when monitoring");
612
613         SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
614                 "hwq_limit", CTLFLAG_RW, &sc->sc_hwq_limit, 0,
615                 "");
616         SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
617                 "tid_hwq_lo", CTLFLAG_RW, &sc->sc_tid_hwq_lo, 0,
618                 "");
619         SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
620                 "tid_hwq_hi", CTLFLAG_RW, &sc->sc_tid_hwq_hi, 0,
621                 "");
622
623 #if 0
624         SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
625                 "txq_data_minfree", CTLFLAG_RW, &sc->sc_txq_data_minfree,
626                 0, "Minimum free buffers before adding a data frame"
627                 " to the TX queue");
628 #endif
629         SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
630                 "txq_mcastq_maxdepth", CTLFLAG_RW,
631                 &sc->sc_txq_mcastq_maxdepth, 0,
632                 "Maximum buffer depth for multicast/broadcast frames");
633
634 #ifdef IEEE80211_SUPPORT_TDMA
635         if (ath_hal_macversion(ah) > 0x78) {
636                 sc->sc_tdmadbaprep = 2;
637                 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
638                         "dbaprep", CTLFLAG_RW, &sc->sc_tdmadbaprep, 0,
639                         "TDMA DBA preparation time");
640                 sc->sc_tdmaswbaprep = 10;
641                 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
642                         "swbaprep", CTLFLAG_RW, &sc->sc_tdmaswbaprep, 0,
643                         "TDMA SWBA preparation time");
644                 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
645                         "guardtime", CTLFLAG_RW, &sc->sc_tdmaguard, 0,
646                         "TDMA slot guard time");
647                 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
648                         "superframe", CTLFLAG_RD, &sc->sc_tdmabintval, 0,
649                         "TDMA calculated super frame");
650                 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
651                         "setcca", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
652                         ath_sysctl_setcca, "I", "enable CCA control");
653         }
654 #endif
655 }
656
657 static int
658 ath_sysctl_clearstats(SYSCTL_HANDLER_ARGS)
659 {
660         struct ath_softc *sc = arg1;
661         int val = 0;
662         int error;
663
664         error = sysctl_handle_int(oidp, &val, 0, req);
665         if (error || !req->newptr)
666                 return error;
667         if (val == 0)
668                 return 0;       /* Not clearing the stats is still valid */
669         memset(&sc->sc_stats, 0, sizeof(sc->sc_stats));
670         memset(&sc->sc_aggr_stats, 0, sizeof(sc->sc_aggr_stats));
671         memset(&sc->sc_intr_stats, 0, sizeof(sc->sc_intr_stats));
672
673         val = 0;
674         return 0;
675 }
676
677 static void
678 ath_sysctl_stats_attach_rxphyerr(struct ath_softc *sc, struct sysctl_oid_list *parent)
679 {
680         struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
681         struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
682         struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
683         int i;
684         char sn[8];
685
686         tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "rx_phy_err", CTLFLAG_RD, NULL, "Per-code RX PHY Errors");
687         child = SYSCTL_CHILDREN(tree);
688         for (i = 0; i < 64; i++) {
689                 snprintf(sn, sizeof(sn), "%d", i);
690                 SYSCTL_ADD_UINT(ctx, child, OID_AUTO, sn, CTLFLAG_RD, &sc->sc_stats.ast_rx_phy[i], 0, "");
691         }
692 }
693
694 static void
695 ath_sysctl_stats_attach_intr(struct ath_softc *sc,
696     struct sysctl_oid_list *parent)
697 {
698         struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
699         struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
700         struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
701         int i;
702         char sn[8];
703
704         tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "sync_intr",
705             CTLFLAG_RD, NULL, "Sync interrupt statistics");
706         child = SYSCTL_CHILDREN(tree);
707         for (i = 0; i < 32; i++) {
708                 snprintf(sn, sizeof(sn), "%d", i);
709                 SYSCTL_ADD_UINT(ctx, child, OID_AUTO, sn, CTLFLAG_RD,
710                     &sc->sc_intr_stats.sync_intr[i], 0, "");
711         }
712 }
713
714 void
715 ath_sysctl_stats_attach(struct ath_softc *sc)
716 {
717         struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
718         struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
719         struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
720  
721         /* Create "clear" node */
722         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
723             "clear_stats", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
724             ath_sysctl_clearstats, "I", "clear stats");
725
726         /* Create stats node */
727         tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD,
728             NULL, "Statistics");
729         child = SYSCTL_CHILDREN(tree);
730
731         /* This was generated from if_athioctl.h */
732
733         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_watchdog", CTLFLAG_RD,
734             &sc->sc_stats.ast_watchdog, 0, "device reset by watchdog");
735         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_hardware", CTLFLAG_RD,
736             &sc->sc_stats.ast_hardware, 0, "fatal hardware error interrupts");
737         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_bmiss", CTLFLAG_RD,
738             &sc->sc_stats.ast_bmiss, 0, "beacon miss interrupts");
739         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_bmiss_phantom", CTLFLAG_RD,
740             &sc->sc_stats.ast_bmiss_phantom, 0, "beacon miss interrupts");
741         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_bstuck", CTLFLAG_RD,
742             &sc->sc_stats.ast_bstuck, 0, "beacon stuck interrupts");
743         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rxorn", CTLFLAG_RD,
744             &sc->sc_stats.ast_rxorn, 0, "rx overrun interrupts");
745         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rxeol", CTLFLAG_RD,
746             &sc->sc_stats.ast_rxeol, 0, "rx eol interrupts");
747         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_txurn", CTLFLAG_RD,
748             &sc->sc_stats.ast_txurn, 0, "tx underrun interrupts");
749         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_mib", CTLFLAG_RD,
750             &sc->sc_stats.ast_mib, 0, "mib interrupts");
751         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_intrcoal", CTLFLAG_RD,
752             &sc->sc_stats.ast_intrcoal, 0, "interrupts coalesced");
753         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_packets", CTLFLAG_RD,
754             &sc->sc_stats.ast_tx_packets, 0, "packet sent on the interface");
755         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_mgmt", CTLFLAG_RD,
756             &sc->sc_stats.ast_tx_mgmt, 0, "management frames transmitted");
757         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_discard", CTLFLAG_RD,
758             &sc->sc_stats.ast_tx_discard, 0, "frames discarded prior to assoc");
759         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_qstop", CTLFLAG_RD,
760             &sc->sc_stats.ast_tx_qstop, 0, "output stopped 'cuz no buffer");
761         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_encap", CTLFLAG_RD,
762             &sc->sc_stats.ast_tx_encap, 0, "tx encapsulation failed");
763         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nonode", CTLFLAG_RD,
764             &sc->sc_stats.ast_tx_nonode, 0, "tx failed 'cuz no node");
765         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nombuf", CTLFLAG_RD,
766             &sc->sc_stats.ast_tx_nombuf, 0, "tx failed 'cuz no mbuf");
767         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nomcl", CTLFLAG_RD,
768             &sc->sc_stats.ast_tx_nomcl, 0, "tx failed 'cuz no cluster");
769         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_linear", CTLFLAG_RD,
770             &sc->sc_stats.ast_tx_linear, 0, "tx linearized to cluster");
771         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nodata", CTLFLAG_RD,
772             &sc->sc_stats.ast_tx_nodata, 0, "tx discarded empty frame");
773         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_busdma", CTLFLAG_RD,
774             &sc->sc_stats.ast_tx_busdma, 0, "tx failed for dma resrcs");
775         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_xretries", CTLFLAG_RD,
776             &sc->sc_stats.ast_tx_xretries, 0, "tx failed 'cuz too many retries");
777         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_fifoerr", CTLFLAG_RD,
778             &sc->sc_stats.ast_tx_fifoerr, 0, "tx failed 'cuz FIFO underrun");
779         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_filtered", CTLFLAG_RD,
780             &sc->sc_stats.ast_tx_filtered, 0, "tx failed 'cuz xmit filtered");
781         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_shortretry", CTLFLAG_RD,
782             &sc->sc_stats.ast_tx_shortretry, 0, "tx on-chip retries (short)");
783         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_longretry", CTLFLAG_RD,
784             &sc->sc_stats.ast_tx_longretry, 0, "tx on-chip retries (long)");
785         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_badrate", CTLFLAG_RD,
786             &sc->sc_stats.ast_tx_badrate, 0, "tx failed 'cuz bogus xmit rate");
787         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_noack", CTLFLAG_RD,
788             &sc->sc_stats.ast_tx_noack, 0, "tx frames with no ack marked");
789         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_rts", CTLFLAG_RD,
790             &sc->sc_stats.ast_tx_rts, 0, "tx frames with rts enabled");
791         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_cts", CTLFLAG_RD,
792             &sc->sc_stats.ast_tx_cts, 0, "tx frames with cts enabled");
793         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_shortpre", CTLFLAG_RD,
794             &sc->sc_stats.ast_tx_shortpre, 0, "tx frames with short preamble");
795         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_altrate", CTLFLAG_RD,
796             &sc->sc_stats.ast_tx_altrate, 0, "tx frames with alternate rate");
797         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_protect", CTLFLAG_RD,
798             &sc->sc_stats.ast_tx_protect, 0, "tx frames with protection");
799         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_ctsburst", CTLFLAG_RD,
800             &sc->sc_stats.ast_tx_ctsburst, 0, "tx frames with cts and bursting");
801         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_ctsext", CTLFLAG_RD,
802             &sc->sc_stats.ast_tx_ctsext, 0, "tx frames with cts extension");
803         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_nombuf", CTLFLAG_RD,
804             &sc->sc_stats.ast_rx_nombuf, 0, "rx setup failed 'cuz no mbuf");
805         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_busdma", CTLFLAG_RD,
806             &sc->sc_stats.ast_rx_busdma, 0, "rx setup failed for dma resrcs");
807         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_orn", CTLFLAG_RD,
808             &sc->sc_stats.ast_rx_orn, 0, "rx failed 'cuz of desc overrun");
809         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_crcerr", CTLFLAG_RD,
810             &sc->sc_stats.ast_rx_crcerr, 0, "rx failed 'cuz of bad CRC");
811         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_fifoerr", CTLFLAG_RD,
812             &sc->sc_stats.ast_rx_fifoerr, 0, "rx failed 'cuz of FIFO overrun");
813         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_badcrypt", CTLFLAG_RD,
814             &sc->sc_stats.ast_rx_badcrypt, 0, "rx failed 'cuz decryption");
815         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_badmic", CTLFLAG_RD,
816             &sc->sc_stats.ast_rx_badmic, 0, "rx failed 'cuz MIC failure");
817         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_phyerr", CTLFLAG_RD,
818             &sc->sc_stats.ast_rx_phyerr, 0, "rx failed 'cuz of PHY err");
819         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_tooshort", CTLFLAG_RD,
820             &sc->sc_stats.ast_rx_tooshort, 0, "rx discarded 'cuz frame too short");
821         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_toobig", CTLFLAG_RD,
822             &sc->sc_stats.ast_rx_toobig, 0, "rx discarded 'cuz frame too large");
823         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_packets", CTLFLAG_RD,
824             &sc->sc_stats.ast_rx_packets, 0, "packet recv on the interface");
825         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_mgt", CTLFLAG_RD,
826             &sc->sc_stats.ast_rx_mgt, 0, "management frames received");
827         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_ctl", CTLFLAG_RD,
828             &sc->sc_stats.ast_rx_ctl, 0, "rx discarded 'cuz ctl frame");
829         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_be_xmit", CTLFLAG_RD,
830             &sc->sc_stats.ast_be_xmit, 0, "beacons transmitted");
831         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_be_nombuf", CTLFLAG_RD,
832             &sc->sc_stats.ast_be_nombuf, 0, "beacon setup failed 'cuz no mbuf");
833         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_per_cal", CTLFLAG_RD,
834             &sc->sc_stats.ast_per_cal, 0, "periodic calibration calls");
835         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_per_calfail", CTLFLAG_RD,
836             &sc->sc_stats.ast_per_calfail, 0, "periodic calibration failed");
837         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_per_rfgain", CTLFLAG_RD,
838             &sc->sc_stats.ast_per_rfgain, 0, "periodic calibration rfgain reset");
839         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rate_calls", CTLFLAG_RD,
840             &sc->sc_stats.ast_rate_calls, 0, "rate control checks");
841         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rate_raise", CTLFLAG_RD,
842             &sc->sc_stats.ast_rate_raise, 0, "rate control raised xmit rate");
843         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rate_drop", CTLFLAG_RD,
844             &sc->sc_stats.ast_rate_drop, 0, "rate control dropped xmit rate");
845         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ant_defswitch", CTLFLAG_RD,
846             &sc->sc_stats.ast_ant_defswitch, 0, "rx/default antenna switches");
847         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ant_txswitch", CTLFLAG_RD,
848             &sc->sc_stats.ast_ant_txswitch, 0, "tx antenna switches");
849         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_cabq_xmit", CTLFLAG_RD,
850             &sc->sc_stats.ast_cabq_xmit, 0, "cabq frames transmitted");
851         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_cabq_busy", CTLFLAG_RD,
852             &sc->sc_stats.ast_cabq_busy, 0, "cabq found busy");
853         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_raw", CTLFLAG_RD,
854             &sc->sc_stats.ast_tx_raw, 0, "tx frames through raw api");
855         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ff_txok", CTLFLAG_RD,
856             &sc->sc_stats.ast_ff_txok, 0, "fast frames tx'd successfully");
857         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ff_txerr", CTLFLAG_RD,
858             &sc->sc_stats.ast_ff_txerr, 0, "fast frames tx'd w/ error");
859         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ff_rx", CTLFLAG_RD,
860             &sc->sc_stats.ast_ff_rx, 0, "fast frames rx'd");
861         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ff_flush", CTLFLAG_RD,
862             &sc->sc_stats.ast_ff_flush, 0, "fast frames flushed from staging q");
863         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_qfull", CTLFLAG_RD,
864             &sc->sc_stats.ast_tx_qfull, 0, "tx dropped 'cuz of queue limit");
865         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nobuf", CTLFLAG_RD,
866             &sc->sc_stats.ast_tx_nobuf, 0, "tx dropped 'cuz no ath buffer");
867         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tdma_update", CTLFLAG_RD,
868             &sc->sc_stats.ast_tdma_update, 0, "TDMA slot timing updates");
869         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tdma_timers", CTLFLAG_RD,
870             &sc->sc_stats.ast_tdma_timers, 0, "TDMA slot update set beacon timers");
871         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tdma_tsf", CTLFLAG_RD,
872             &sc->sc_stats.ast_tdma_tsf, 0, "TDMA slot update set TSF");
873         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tdma_ack", CTLFLAG_RD,
874             &sc->sc_stats.ast_tdma_ack, 0, "TDMA tx failed 'cuz ACK required");
875         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_raw_fail", CTLFLAG_RD,
876             &sc->sc_stats.ast_tx_raw_fail, 0, "raw tx failed 'cuz h/w down");
877         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nofrag", CTLFLAG_RD,
878             &sc->sc_stats.ast_tx_nofrag, 0, "tx dropped 'cuz no ath frag buffer");
879         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_be_missed", CTLFLAG_RD,
880             &sc->sc_stats.ast_be_missed, 0, "number of -missed- beacons");
881         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ani_cal", CTLFLAG_RD,
882             &sc->sc_stats.ast_ani_cal, 0, "number of ANI polls");
883         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_agg", CTLFLAG_RD,
884             &sc->sc_stats.ast_rx_agg, 0, "number of aggregate frames received");
885
886         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_halfgi", CTLFLAG_RD,
887             &sc->sc_stats.ast_rx_halfgi, 0, "number of frames received with half-GI");
888         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_2040", CTLFLAG_RD,
889             &sc->sc_stats.ast_rx_2040, 0, "number of HT/40 frames received");
890         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_pre_crc_err", CTLFLAG_RD,
891             &sc->sc_stats.ast_rx_pre_crc_err, 0, "number of delimeter-CRC errors detected");
892         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_post_crc_err", CTLFLAG_RD,
893             &sc->sc_stats.ast_rx_post_crc_err, 0, "number of post-delimiter CRC errors detected");
894         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_decrypt_busy_err", CTLFLAG_RD,
895             &sc->sc_stats.ast_rx_decrypt_busy_err, 0, "number of frames received w/ busy decrypt engine");
896         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_hi_rx_chain", CTLFLAG_RD,
897             &sc->sc_stats.ast_rx_hi_rx_chain, 0, "");
898         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_htprotect", CTLFLAG_RD,
899             &sc->sc_stats.ast_tx_htprotect, 0, "HT tx frames with protection");
900         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_hitqueueend", CTLFLAG_RD,
901             &sc->sc_stats.ast_rx_hitqueueend, 0, "RX hit queue end");
902         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_timeout", CTLFLAG_RD,
903             &sc->sc_stats.ast_tx_timeout, 0, "TX Global Timeout");
904         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_cst", CTLFLAG_RD,
905             &sc->sc_stats.ast_tx_cst, 0, "TX Carrier Sense Timeout");
906         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_xtxop", CTLFLAG_RD,
907             &sc->sc_stats.ast_tx_xtxop, 0, "TX exceeded TXOP");
908         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_timerexpired", CTLFLAG_RD,
909             &sc->sc_stats.ast_tx_timerexpired, 0, "TX exceeded TX_TIMER register");
910         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_desccfgerr", CTLFLAG_RD,
911             &sc->sc_stats.ast_tx_desccfgerr, 0, "TX Descriptor Cfg Error");
912         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_swretries", CTLFLAG_RD,
913             &sc->sc_stats.ast_tx_swretries, 0, "TX software retry count");
914         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_swretrymax", CTLFLAG_RD,
915             &sc->sc_stats.ast_tx_swretrymax, 0, "TX software retry max reached");
916
917         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_data_underrun", CTLFLAG_RD,
918             &sc->sc_stats.ast_tx_data_underrun, 0, "");
919         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_delim_underrun", CTLFLAG_RD,
920             &sc->sc_stats.ast_tx_delim_underrun, 0, "");
921         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_aggr_failall", CTLFLAG_RD,
922             &sc->sc_stats.ast_tx_aggr_failall, 0,
923             "Number of aggregate TX failures (whole frame)");
924         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_aggr_ok", CTLFLAG_RD,
925             &sc->sc_stats.ast_tx_aggr_ok, 0,
926             "Number of aggregate TX OK completions (subframe)");
927         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_aggr_fail", CTLFLAG_RD,
928             &sc->sc_stats.ast_tx_aggr_fail, 0,
929             "Number of aggregate TX failures (subframe)");
930
931         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_intr", CTLFLAG_RD,
932             &sc->sc_stats.ast_rx_intr, 0, "RX interrupts");
933         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_intr", CTLFLAG_RD,
934             &sc->sc_stats.ast_tx_intr, 0, "TX interrupts");
935         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_mcastq_overflow",
936             CTLFLAG_RD, &sc->sc_stats.ast_tx_mcastq_overflow, 0,
937             "Number of multicast frames exceeding maximum mcast queue depth");
938         
939         /* Attach the RX phy error array */
940         ath_sysctl_stats_attach_rxphyerr(sc, child);
941
942         /* Attach the interrupt statistics array */
943         ath_sysctl_stats_attach_intr(sc, child);
944 }
945
946 /*
947  * This doesn't necessarily belong here (because it's HAL related, not
948  * driver related).
949  */
950 void
951 ath_sysctl_hal_attach(struct ath_softc *sc)
952 {
953         struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
954         struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
955         struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
956
957         tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "hal", CTLFLAG_RD,
958             NULL, "Atheros HAL parameters");
959         child = SYSCTL_CHILDREN(tree);
960
961         sc->sc_ah->ah_config.ah_debug = 0;
962         SYSCTL_ADD_INT(ctx, child, OID_AUTO, "debug", CTLFLAG_RW,
963             &sc->sc_ah->ah_config.ah_debug, 0, "Atheros HAL debugging printfs");
964
965         sc->sc_ah->ah_config.ah_ar5416_biasadj = 0;
966         SYSCTL_ADD_INT(ctx, child, OID_AUTO, "ar5416_biasadj", CTLFLAG_RW,
967             &sc->sc_ah->ah_config.ah_ar5416_biasadj, 0,
968             "Enable 2GHz AR5416 direction sensitivity bias adjust");
969
970         sc->sc_ah->ah_config.ah_dma_beacon_response_time = 2;
971         SYSCTL_ADD_INT(ctx, child, OID_AUTO, "dma_brt", CTLFLAG_RW,
972             &sc->sc_ah->ah_config.ah_dma_beacon_response_time, 0,
973             "Atheros HAL DMA beacon response time");
974
975         sc->sc_ah->ah_config.ah_sw_beacon_response_time = 10;
976         SYSCTL_ADD_INT(ctx, child, OID_AUTO, "sw_brt", CTLFLAG_RW,
977             &sc->sc_ah->ah_config.ah_sw_beacon_response_time, 0,
978             "Atheros HAL software beacon response time");
979
980         sc->sc_ah->ah_config.ah_additional_swba_backoff = 0;
981         SYSCTL_ADD_INT(ctx, child, OID_AUTO, "swba_backoff", CTLFLAG_RW,
982             &sc->sc_ah->ah_config.ah_additional_swba_backoff, 0,
983             "Atheros HAL additional SWBA backoff time");
984
985         sc->sc_ah->ah_config.ah_force_full_reset = 0;
986         SYSCTL_ADD_INT(ctx, child, OID_AUTO, "force_full_reset", CTLFLAG_RW,
987             &sc->sc_ah->ah_config.ah_force_full_reset, 0,
988             "Force full chip reset rather than a warm reset");
989
990         /*
991          * This is initialised by the driver.
992          */
993         SYSCTL_ADD_INT(ctx, child, OID_AUTO, "serialise_reg_war", CTLFLAG_RW,
994             &sc->sc_ah->ah_config.ah_serialise_reg_war, 0,
995             "Force register access serialisation");
996 }