xref: /freebsd/sys/dev/ath/if_ath_sysctl.c (revision a812392203d7c4c3f0db9d8a0f3391374c49c71f)
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_var.h>
66 #include <net/if_dl.h>
67 #include <net/if_media.h>
68 #include <net/if_types.h>
69 #include <net/if_arp.h>
70 #include <net/ethernet.h>
71 #include <net/if_llc.h>
72 
73 #include <net80211/ieee80211_var.h>
74 #include <net80211/ieee80211_regdomain.h>
75 #ifdef IEEE80211_SUPPORT_SUPERG
76 #include <net80211/ieee80211_superg.h>
77 #endif
78 #ifdef IEEE80211_SUPPORT_TDMA
79 #include <net80211/ieee80211_tdma.h>
80 #endif
81 
82 #include <net/bpf.h>
83 
84 #ifdef INET
85 #include <netinet/in.h>
86 #include <netinet/if_ether.h>
87 #endif
88 
89 #include <dev/ath/if_athvar.h>
90 #include <dev/ath/ath_hal/ah_devid.h>		/* XXX for softled */
91 #include <dev/ath/ath_hal/ah_diagcodes.h>
92 
93 #include <dev/ath/if_ath_debug.h>
94 #include <dev/ath/if_ath_led.h>
95 #include <dev/ath/if_ath_misc.h>
96 #include <dev/ath/if_ath_tx.h>
97 #include <dev/ath/if_ath_sysctl.h>
98 
99 #ifdef ATH_TX99_DIAG
100 #include <dev/ath/ath_tx99/ath_tx99.h>
101 #endif
102 
103 #ifdef	ATH_DEBUG_ALQ
104 #include <dev/ath/if_ath_alq.h>
105 #endif
106 
107 static int
108 ath_sysctl_slottime(SYSCTL_HANDLER_ARGS)
109 {
110 	struct ath_softc *sc = arg1;
111 	u_int slottime;
112 	int error;
113 
114 	ATH_LOCK(sc);
115 	ath_power_set_power_state(sc, HAL_PM_AWAKE);
116 	slottime = ath_hal_getslottime(sc->sc_ah);
117 	ATH_UNLOCK(sc);
118 
119 	error = sysctl_handle_int(oidp, &slottime, 0, req);
120 	if (error || !req->newptr)
121 		goto finish;
122 
123 	error = !ath_hal_setslottime(sc->sc_ah, slottime) ? EINVAL : 0;
124 
125 finish:
126 	ATH_LOCK(sc);
127 	ath_power_restore_power_state(sc);
128 	ATH_UNLOCK(sc);
129 
130 	return error;
131 }
132 
133 static int
134 ath_sysctl_acktimeout(SYSCTL_HANDLER_ARGS)
135 {
136 	struct ath_softc *sc = arg1;
137 	u_int acktimeout = ath_hal_getacktimeout(sc->sc_ah);
138 	int error;
139 
140 	error = sysctl_handle_int(oidp, &acktimeout, 0, req);
141 	if (error || !req->newptr)
142 		return error;
143 	return !ath_hal_setacktimeout(sc->sc_ah, acktimeout) ? EINVAL : 0;
144 }
145 
146 static int
147 ath_sysctl_ctstimeout(SYSCTL_HANDLER_ARGS)
148 {
149 	struct ath_softc *sc = arg1;
150 	u_int ctstimeout = ath_hal_getctstimeout(sc->sc_ah);
151 	int error;
152 
153 	error = sysctl_handle_int(oidp, &ctstimeout, 0, req);
154 	if (error || !req->newptr)
155 		return error;
156 	return !ath_hal_setctstimeout(sc->sc_ah, ctstimeout) ? EINVAL : 0;
157 }
158 
159 static int
160 ath_sysctl_softled(SYSCTL_HANDLER_ARGS)
161 {
162 	struct ath_softc *sc = arg1;
163 	int softled = sc->sc_softled;
164 	int error;
165 
166 	error = sysctl_handle_int(oidp, &softled, 0, req);
167 	if (error || !req->newptr)
168 		return error;
169 	softled = (softled != 0);
170 	if (softled != sc->sc_softled) {
171 		if (softled) {
172 			/* NB: handle any sc_ledpin change */
173 			ath_led_config(sc);
174 		}
175 		sc->sc_softled = softled;
176 	}
177 	return 0;
178 }
179 
180 static int
181 ath_sysctl_ledpin(SYSCTL_HANDLER_ARGS)
182 {
183 	struct ath_softc *sc = arg1;
184 	int ledpin = sc->sc_ledpin;
185 	int error;
186 
187 	error = sysctl_handle_int(oidp, &ledpin, 0, req);
188 	if (error || !req->newptr)
189 		return error;
190 	if (ledpin != sc->sc_ledpin) {
191 		sc->sc_ledpin = ledpin;
192 		if (sc->sc_softled) {
193 			ath_led_config(sc);
194 		}
195 	}
196 	return 0;
197 }
198 
199 static int
200 ath_sysctl_hardled(SYSCTL_HANDLER_ARGS)
201 {
202 	struct ath_softc *sc = arg1;
203 	int hardled = sc->sc_hardled;
204 	int error;
205 
206 	error = sysctl_handle_int(oidp, &hardled, 0, req);
207 	if (error || !req->newptr)
208 		return error;
209 	hardled = (hardled != 0);
210 	if (hardled != sc->sc_hardled) {
211 		if (hardled) {
212 			/* NB: handle any sc_ledpin change */
213 			ath_led_config(sc);
214 		}
215 		sc->sc_hardled = hardled;
216 	}
217 	return 0;
218 }
219 
220 static int
221 ath_sysctl_txantenna(SYSCTL_HANDLER_ARGS)
222 {
223 	struct ath_softc *sc = arg1;
224 	u_int txantenna = ath_hal_getantennaswitch(sc->sc_ah);
225 	int error;
226 
227 	error = sysctl_handle_int(oidp, &txantenna, 0, req);
228 	if (!error && req->newptr) {
229 		/* XXX assumes 2 antenna ports */
230 		if (txantenna < HAL_ANT_VARIABLE || txantenna > HAL_ANT_FIXED_B)
231 			return EINVAL;
232 		ath_hal_setantennaswitch(sc->sc_ah, txantenna);
233 		/*
234 		 * NB: with the switch locked this isn't meaningful,
235 		 *     but set it anyway so things like radiotap get
236 		 *     consistent info in their data.
237 		 */
238 		sc->sc_txantenna = txantenna;
239 	}
240 	return error;
241 }
242 
243 static int
244 ath_sysctl_rxantenna(SYSCTL_HANDLER_ARGS)
245 {
246 	struct ath_softc *sc = arg1;
247 	u_int defantenna = ath_hal_getdefantenna(sc->sc_ah);
248 	int error;
249 
250 	error = sysctl_handle_int(oidp, &defantenna, 0, req);
251 	if (!error && req->newptr)
252 		ath_hal_setdefantenna(sc->sc_ah, defantenna);
253 	return error;
254 }
255 
256 static int
257 ath_sysctl_diversity(SYSCTL_HANDLER_ARGS)
258 {
259 	struct ath_softc *sc = arg1;
260 	u_int diversity = ath_hal_getdiversity(sc->sc_ah);
261 	int error;
262 
263 	error = sysctl_handle_int(oidp, &diversity, 0, req);
264 	if (error || !req->newptr)
265 		return error;
266 	if (!ath_hal_setdiversity(sc->sc_ah, diversity))
267 		return EINVAL;
268 	sc->sc_diversity = diversity;
269 	return 0;
270 }
271 
272 static int
273 ath_sysctl_diag(SYSCTL_HANDLER_ARGS)
274 {
275 	struct ath_softc *sc = arg1;
276 	u_int32_t diag;
277 	int error;
278 
279 	if (!ath_hal_getdiag(sc->sc_ah, &diag))
280 		return EINVAL;
281 	error = sysctl_handle_int(oidp, &diag, 0, req);
282 	if (error || !req->newptr)
283 		return error;
284 	return !ath_hal_setdiag(sc->sc_ah, diag) ? EINVAL : 0;
285 }
286 
287 static int
288 ath_sysctl_tpscale(SYSCTL_HANDLER_ARGS)
289 {
290 	struct ath_softc *sc = arg1;
291 	struct ifnet *ifp = sc->sc_ifp;
292 	u_int32_t scale;
293 	int error;
294 
295 	(void) ath_hal_gettpscale(sc->sc_ah, &scale);
296 	error = sysctl_handle_int(oidp, &scale, 0, req);
297 	if (error || !req->newptr)
298 		return error;
299 	return !ath_hal_settpscale(sc->sc_ah, scale) ? EINVAL :
300 	    (ifp->if_drv_flags & IFF_DRV_RUNNING) ?
301 	      ath_reset(ifp, ATH_RESET_NOLOSS) : 0;
302 }
303 
304 static int
305 ath_sysctl_tpc(SYSCTL_HANDLER_ARGS)
306 {
307 	struct ath_softc *sc = arg1;
308 	u_int tpc = ath_hal_gettpc(sc->sc_ah);
309 	int error;
310 
311 	error = sysctl_handle_int(oidp, &tpc, 0, req);
312 	if (error || !req->newptr)
313 		return error;
314 	return !ath_hal_settpc(sc->sc_ah, tpc) ? EINVAL : 0;
315 }
316 
317 static int
318 ath_sysctl_rfkill(SYSCTL_HANDLER_ARGS)
319 {
320 	struct ath_softc *sc = arg1;
321 	struct ifnet *ifp = sc->sc_ifp;
322 	struct ath_hal *ah = sc->sc_ah;
323 	u_int rfkill = ath_hal_getrfkill(ah);
324 	int error;
325 
326 	error = sysctl_handle_int(oidp, &rfkill, 0, req);
327 	if (error || !req->newptr)
328 		return error;
329 	if (rfkill == ath_hal_getrfkill(ah))	/* unchanged */
330 		return 0;
331 	if (!ath_hal_setrfkill(ah, rfkill))
332 		return EINVAL;
333 	return (ifp->if_drv_flags & IFF_DRV_RUNNING) ?
334 	    ath_reset(ifp, ATH_RESET_FULL) : 0;
335 }
336 
337 static int
338 ath_sysctl_txagg(SYSCTL_HANDLER_ARGS)
339 {
340 	struct ath_softc *sc = arg1;
341 	int i, t, param = 0;
342 	int error;
343 	struct ath_buf *bf;
344 
345 	error = sysctl_handle_int(oidp, &param, 0, req);
346 	if (error || !req->newptr)
347 		return error;
348 
349 	if (param != 1)
350 		return 0;
351 
352 	printf("no tx bufs (empty list): %d\n", sc->sc_stats.ast_tx_getnobuf);
353 	printf("no tx bufs (was busy): %d\n", sc->sc_stats.ast_tx_getbusybuf);
354 
355 	printf("aggr single packet: %d\n",
356 	    sc->sc_aggr_stats.aggr_single_pkt);
357 	printf("aggr single packet w/ BAW closed: %d\n",
358 	    sc->sc_aggr_stats.aggr_baw_closed_single_pkt);
359 	printf("aggr non-baw packet: %d\n",
360 	    sc->sc_aggr_stats.aggr_nonbaw_pkt);
361 	printf("aggr aggregate packet: %d\n",
362 	    sc->sc_aggr_stats.aggr_aggr_pkt);
363 	printf("aggr single packet low hwq: %d\n",
364 	    sc->sc_aggr_stats.aggr_low_hwq_single_pkt);
365 	printf("aggr single packet RTS aggr limited: %d\n",
366 	    sc->sc_aggr_stats.aggr_rts_aggr_limited);
367 	printf("aggr sched, no work: %d\n",
368 	    sc->sc_aggr_stats.aggr_sched_nopkt);
369 	for (i = 0; i < 64; i++) {
370 		printf("%2d: %10d ", i, sc->sc_aggr_stats.aggr_pkts[i]);
371 		if (i % 4 == 3)
372 			printf("\n");
373 	}
374 	printf("\n");
375 
376 	for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
377 		if (ATH_TXQ_SETUP(sc, i)) {
378 			printf("HW TXQ %d: axq_depth=%d, axq_aggr_depth=%d, "
379 			    "axq_fifo_depth=%d, holdingbf=%p\n",
380 			    i,
381 			    sc->sc_txq[i].axq_depth,
382 			    sc->sc_txq[i].axq_aggr_depth,
383 			    sc->sc_txq[i].axq_fifo_depth,
384 			    sc->sc_txq[i].axq_holdingbf);
385 		}
386 	}
387 
388 	i = t = 0;
389 	ATH_TXBUF_LOCK(sc);
390 	TAILQ_FOREACH(bf, &sc->sc_txbuf, bf_list) {
391 		if (bf->bf_flags & ATH_BUF_BUSY) {
392 			printf("Busy: %d\n", t);
393 			i++;
394 		}
395 		t++;
396 	}
397 	ATH_TXBUF_UNLOCK(sc);
398 	printf("Total TX buffers: %d; Total TX buffers busy: %d (%d)\n",
399 	    t, i, sc->sc_txbuf_cnt);
400 
401 	i = t = 0;
402 	ATH_TXBUF_LOCK(sc);
403 	TAILQ_FOREACH(bf, &sc->sc_txbuf_mgmt, bf_list) {
404 		if (bf->bf_flags & ATH_BUF_BUSY) {
405 			printf("Busy: %d\n", t);
406 			i++;
407 		}
408 		t++;
409 	}
410 	ATH_TXBUF_UNLOCK(sc);
411 	printf("Total mgmt TX buffers: %d; Total mgmt TX buffers busy: %d\n",
412 	    t, i);
413 
414 	ATH_RX_LOCK(sc);
415 	for (i = 0; i < 2; i++) {
416 		printf("%d: fifolen: %d/%d; head=%d; tail=%d; m_pending=%p, m_holdbf=%p\n",
417 		    i,
418 		    sc->sc_rxedma[i].m_fifo_depth,
419 		    sc->sc_rxedma[i].m_fifolen,
420 		    sc->sc_rxedma[i].m_fifo_head,
421 		    sc->sc_rxedma[i].m_fifo_tail,
422 		    sc->sc_rxedma[i].m_rxpending,
423 		    sc->sc_rxedma[i].m_holdbf);
424 	}
425 	i = 0;
426 	TAILQ_FOREACH(bf, &sc->sc_rxbuf, bf_list) {
427 		i++;
428 	}
429 	printf("Total RX buffers in free list: %d buffers\n",
430 	    i);
431 	ATH_RX_UNLOCK(sc);
432 
433 	return 0;
434 }
435 
436 static int
437 ath_sysctl_rfsilent(SYSCTL_HANDLER_ARGS)
438 {
439 	struct ath_softc *sc = arg1;
440 	u_int rfsilent;
441 	int error;
442 
443 	(void) ath_hal_getrfsilent(sc->sc_ah, &rfsilent);
444 	error = sysctl_handle_int(oidp, &rfsilent, 0, req);
445 	if (error || !req->newptr)
446 		return error;
447 	if (!ath_hal_setrfsilent(sc->sc_ah, rfsilent))
448 		return EINVAL;
449 	/*
450 	 * Earlier chips (< AR5212) have up to 8 GPIO
451 	 * pins exposed.
452 	 *
453 	 * AR5416 and later chips have many more GPIO
454 	 * pins (up to 16) so the mask is expanded to
455 	 * four bits.
456 	 */
457 	sc->sc_rfsilentpin = rfsilent & 0x3c;
458 	sc->sc_rfsilentpol = (rfsilent & 0x2) != 0;
459 	return 0;
460 }
461 
462 static int
463 ath_sysctl_tpack(SYSCTL_HANDLER_ARGS)
464 {
465 	struct ath_softc *sc = arg1;
466 	u_int32_t tpack;
467 	int error;
468 
469 	(void) ath_hal_gettpack(sc->sc_ah, &tpack);
470 	error = sysctl_handle_int(oidp, &tpack, 0, req);
471 	if (error || !req->newptr)
472 		return error;
473 	return !ath_hal_settpack(sc->sc_ah, tpack) ? EINVAL : 0;
474 }
475 
476 static int
477 ath_sysctl_tpcts(SYSCTL_HANDLER_ARGS)
478 {
479 	struct ath_softc *sc = arg1;
480 	u_int32_t tpcts;
481 	int error;
482 
483 	(void) ath_hal_gettpcts(sc->sc_ah, &tpcts);
484 	error = sysctl_handle_int(oidp, &tpcts, 0, req);
485 	if (error || !req->newptr)
486 		return error;
487 	return !ath_hal_settpcts(sc->sc_ah, tpcts) ? EINVAL : 0;
488 }
489 
490 static int
491 ath_sysctl_intmit(SYSCTL_HANDLER_ARGS)
492 {
493 	struct ath_softc *sc = arg1;
494 	int intmit, error;
495 
496 	intmit = ath_hal_getintmit(sc->sc_ah);
497 	error = sysctl_handle_int(oidp, &intmit, 0, req);
498 	if (error || !req->newptr)
499 		return error;
500 
501 	/* reusing error; 1 here means "good"; 0 means "fail" */
502 	error = ath_hal_setintmit(sc->sc_ah, intmit);
503 	if (! error)
504 		return EINVAL;
505 
506 	/*
507 	 * Reset the hardware here - disabling ANI in the HAL
508 	 * doesn't reset ANI related registers, so it'll leave
509 	 * things in an inconsistent state.
510 	 */
511 	if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
512 		ath_reset(sc->sc_ifp, ATH_RESET_NOLOSS);
513 
514 	return 0;
515 }
516 
517 #ifdef IEEE80211_SUPPORT_TDMA
518 static int
519 ath_sysctl_setcca(SYSCTL_HANDLER_ARGS)
520 {
521 	struct ath_softc *sc = arg1;
522 	int setcca, error;
523 
524 	setcca = sc->sc_setcca;
525 	error = sysctl_handle_int(oidp, &setcca, 0, req);
526 	if (error || !req->newptr)
527 		return error;
528 	sc->sc_setcca = (setcca != 0);
529 	return 0;
530 }
531 #endif /* IEEE80211_SUPPORT_TDMA */
532 
533 static int
534 ath_sysctl_forcebstuck(SYSCTL_HANDLER_ARGS)
535 {
536 	struct ath_softc *sc = arg1;
537 	int val = 0;
538 	int error;
539 
540 	error = sysctl_handle_int(oidp, &val, 0, req);
541 	if (error || !req->newptr)
542 		return error;
543 	if (val == 0)
544 		return 0;
545 
546 	taskqueue_enqueue_fast(sc->sc_tq, &sc->sc_bstucktask);
547 	val = 0;
548 	return 0;
549 }
550 
551 static int
552 ath_sysctl_hangcheck(SYSCTL_HANDLER_ARGS)
553 {
554 	struct ath_softc *sc = arg1;
555 	int val = 0;
556 	int error;
557 	uint32_t mask = 0xffffffff;
558 	uint32_t *sp;
559 	uint32_t rsize;
560 	struct ath_hal *ah = sc->sc_ah;
561 
562 	error = sysctl_handle_int(oidp, &val, 0, req);
563 	if (error || !req->newptr)
564 		return error;
565 	if (val == 0)
566 		return 0;
567 
568 	/* Do a hang check */
569 	if (!ath_hal_getdiagstate(ah, HAL_DIAG_CHECK_HANGS,
570 	    &mask, sizeof(mask),
571 	    (void *) &sp, &rsize))
572 		return (0);
573 	device_printf(sc->sc_dev, "%s: sp=0x%08x\n", __func__, *sp);
574 
575 	val = 0;
576 	return 0;
577 }
578 
579 #ifdef ATH_DEBUG_ALQ
580 static int
581 ath_sysctl_alq_log(SYSCTL_HANDLER_ARGS)
582 {
583 	struct ath_softc *sc = arg1;
584 	int error, enable;
585 
586 	enable = (sc->sc_alq.sc_alq_isactive);
587 
588 	error = sysctl_handle_int(oidp, &enable, 0, req);
589 	if (error || !req->newptr)
590 		return (error);
591 	else if (enable)
592 		error = if_ath_alq_start(&sc->sc_alq);
593 	else
594 		error = if_ath_alq_stop(&sc->sc_alq);
595 	return (error);
596 }
597 
598 /*
599  * Attach the ALQ debugging if required.
600  */
601 static void
602 ath_sysctl_alq_attach(struct ath_softc *sc)
603 {
604 	struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
605 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
606 	struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
607 
608 	tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "alq", CTLFLAG_RD,
609 	    NULL, "Atheros ALQ logging parameters");
610 	child = SYSCTL_CHILDREN(tree);
611 
612 	SYSCTL_ADD_STRING(ctx, child, OID_AUTO, "filename",
613 	    CTLFLAG_RW, sc->sc_alq.sc_alq_filename, 0, "ALQ filename");
614 
615 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
616 		"enable", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
617 		ath_sysctl_alq_log, "I", "");
618 
619 	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
620 		"debugmask", CTLFLAG_RW, &sc->sc_alq.sc_alq_debug, 0,
621 		"ALQ debug mask");
622 
623 	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
624 		"numlost", CTLFLAG_RW, &sc->sc_alq.sc_alq_numlost, 0,
625 		"number lost");
626 }
627 #endif /* ATH_DEBUG_ALQ */
628 
629 void
630 ath_sysctlattach(struct ath_softc *sc)
631 {
632 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
633 	struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
634 	struct ath_hal *ah = sc->sc_ah;
635 
636 	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
637 		"countrycode", CTLFLAG_RD, &sc->sc_eecc, 0,
638 		"EEPROM country code");
639 	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
640 		"regdomain", CTLFLAG_RD, &sc->sc_eerd, 0,
641 		"EEPROM regdomain code");
642 #ifdef	ATH_DEBUG
643 	SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
644 		"debug", CTLFLAG_RW, &sc->sc_debug,
645 		"control debugging printfs");
646 #endif
647 #ifdef	ATH_DEBUG_ALQ
648 	SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
649 		"ktrdebug", CTLFLAG_RW, &sc->sc_ktrdebug,
650 		"control debugging KTR");
651 #endif /* ATH_DEBUG_ALQ */
652 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
653 		"slottime", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
654 		ath_sysctl_slottime, "I", "802.11 slot time (us)");
655 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
656 		"acktimeout", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
657 		ath_sysctl_acktimeout, "I", "802.11 ACK timeout (us)");
658 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
659 		"ctstimeout", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
660 		ath_sysctl_ctstimeout, "I", "802.11 CTS timeout (us)");
661 
662 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
663 		"softled", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
664 		ath_sysctl_softled, "I", "enable/disable software LED support");
665 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
666 		"ledpin", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
667 		ath_sysctl_ledpin, "I", "GPIO pin connected to LED");
668 	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
669 		"ledon", CTLFLAG_RW, &sc->sc_ledon, 0,
670 		"setting to turn LED on");
671 	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
672 		"ledidle", CTLFLAG_RW, &sc->sc_ledidle, 0,
673 		"idle time for inactivity LED (ticks)");
674 
675 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
676 		"hardled", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
677 		ath_sysctl_hardled, "I", "enable/disable hardware LED support");
678 	/* XXX Laziness - configure pins, then flip hardled off/on */
679 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
680 		"led_net_pin", CTLFLAG_RW, &sc->sc_led_net_pin, 0,
681 		"MAC Network LED pin, or -1 to disable");
682 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
683 		"led_pwr_pin", CTLFLAG_RW, &sc->sc_led_pwr_pin, 0,
684 		"MAC Power LED pin, or -1 to disable");
685 
686 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
687 		"txantenna", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
688 		ath_sysctl_txantenna, "I", "antenna switch");
689 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
690 		"rxantenna", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
691 		ath_sysctl_rxantenna, "I", "default/rx antenna");
692 	if (ath_hal_hasdiversity(ah))
693 		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
694 			"diversity", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
695 			ath_sysctl_diversity, "I", "antenna diversity");
696 	sc->sc_txintrperiod = ATH_TXINTR_PERIOD;
697 	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
698 		"txintrperiod", CTLFLAG_RW, &sc->sc_txintrperiod, 0,
699 		"tx descriptor batching");
700 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
701 		"diag", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
702 		ath_sysctl_diag, "I", "h/w diagnostic control");
703 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
704 		"tpscale", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
705 		ath_sysctl_tpscale, "I", "tx power scaling");
706 	if (ath_hal_hastpc(ah)) {
707 		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
708 			"tpc", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
709 			ath_sysctl_tpc, "I", "enable/disable per-packet TPC");
710 		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
711 			"tpack", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
712 			ath_sysctl_tpack, "I", "tx power for ack frames");
713 		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
714 			"tpcts", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
715 			ath_sysctl_tpcts, "I", "tx power for cts frames");
716 	}
717 	if (ath_hal_hasrfsilent(ah)) {
718 		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
719 			"rfsilent", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
720 			ath_sysctl_rfsilent, "I", "h/w RF silent config");
721 		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
722 			"rfkill", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
723 			ath_sysctl_rfkill, "I", "enable/disable RF kill switch");
724 	}
725 
726 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
727 		"txagg", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
728 		ath_sysctl_txagg, "I", "");
729 
730 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
731 		"forcebstuck", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
732 		ath_sysctl_forcebstuck, "I", "");
733 
734 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
735 		"hangcheck", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
736 		ath_sysctl_hangcheck, "I", "");
737 
738 	if (ath_hal_hasintmit(ah)) {
739 		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
740 			"intmit", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
741 			ath_sysctl_intmit, "I", "interference mitigation");
742 	}
743 	sc->sc_monpass = HAL_RXERR_DECRYPT | HAL_RXERR_MIC;
744 	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
745 		"monpass", CTLFLAG_RW, &sc->sc_monpass, 0,
746 		"mask of error frames to pass when monitoring");
747 
748 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
749 		"hwq_limit_nonaggr", CTLFLAG_RW, &sc->sc_hwq_limit_nonaggr, 0,
750 		"Hardware non-AMPDU queue depth before software-queuing TX frames");
751 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
752 		"hwq_limit_aggr", CTLFLAG_RW, &sc->sc_hwq_limit_aggr, 0,
753 		"Hardware AMPDU queue depth before software-queuing TX frames");
754 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
755 		"tid_hwq_lo", CTLFLAG_RW, &sc->sc_tid_hwq_lo, 0,
756 		"");
757 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
758 		"tid_hwq_hi", CTLFLAG_RW, &sc->sc_tid_hwq_hi, 0,
759 		"");
760 
761 	/* Aggregate length twiddles */
762 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
763 		"aggr_limit", CTLFLAG_RW, &sc->sc_aggr_limit, 0,
764 		"Maximum A-MPDU size, or 0 for 'default'");
765 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
766 		"rts_aggr_limit", CTLFLAG_RW, &sc->sc_rts_aggr_limit, 0,
767 		"Maximum A-MPDU size for RTS-protected frames, or '0' "
768 		"for default");
769 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
770 		"delim_min_pad", CTLFLAG_RW, &sc->sc_delim_min_pad, 0,
771 		"Enforce a minimum number of delimiters per A-MPDU "
772 		" sub-frame");
773 
774 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
775 		"txq_data_minfree", CTLFLAG_RW, &sc->sc_txq_data_minfree,
776 		0, "Minimum free buffers before adding a data frame"
777 		" to the TX queue");
778 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
779 		"txq_mcastq_maxdepth", CTLFLAG_RW,
780 		&sc->sc_txq_mcastq_maxdepth, 0,
781 		"Maximum buffer depth for multicast/broadcast frames");
782 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
783 		"txq_node_maxdepth", CTLFLAG_RW,
784 		&sc->sc_txq_node_maxdepth, 0,
785 		"Maximum buffer depth for a single node");
786 
787 #if 0
788 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
789 		"cabq_enable", CTLFLAG_RW,
790 		&sc->sc_cabq_enable, 0,
791 		"Whether to transmit on the CABQ or not");
792 #endif
793 
794 #ifdef IEEE80211_SUPPORT_TDMA
795 	if (ath_hal_macversion(ah) > 0x78) {
796 		sc->sc_tdmadbaprep = 2;
797 		SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
798 			"dbaprep", CTLFLAG_RW, &sc->sc_tdmadbaprep, 0,
799 			"TDMA DBA preparation time");
800 		sc->sc_tdmaswbaprep = 10;
801 		SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
802 			"swbaprep", CTLFLAG_RW, &sc->sc_tdmaswbaprep, 0,
803 			"TDMA SWBA preparation time");
804 		SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
805 			"guardtime", CTLFLAG_RW, &sc->sc_tdmaguard, 0,
806 			"TDMA slot guard time");
807 		SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
808 			"superframe", CTLFLAG_RD, &sc->sc_tdmabintval, 0,
809 			"TDMA calculated super frame");
810 		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
811 			"setcca", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
812 			ath_sysctl_setcca, "I", "enable CCA control");
813 	}
814 #endif
815 
816 #ifdef	ATH_DEBUG_ALQ
817 	ath_sysctl_alq_attach(sc);
818 #endif
819 }
820 
821 static int
822 ath_sysctl_clearstats(SYSCTL_HANDLER_ARGS)
823 {
824 	struct ath_softc *sc = arg1;
825 	int val = 0;
826 	int error;
827 
828 	error = sysctl_handle_int(oidp, &val, 0, req);
829 	if (error || !req->newptr)
830 		return error;
831 	if (val == 0)
832 		return 0;       /* Not clearing the stats is still valid */
833 	memset(&sc->sc_stats, 0, sizeof(sc->sc_stats));
834 	memset(&sc->sc_aggr_stats, 0, sizeof(sc->sc_aggr_stats));
835 	memset(&sc->sc_intr_stats, 0, sizeof(sc->sc_intr_stats));
836 
837 	val = 0;
838 	return 0;
839 }
840 
841 static void
842 ath_sysctl_stats_attach_rxphyerr(struct ath_softc *sc, struct sysctl_oid_list *parent)
843 {
844 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
845 	struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
846 	struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
847 	int i;
848 	char sn[8];
849 
850 	tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "rx_phy_err", CTLFLAG_RD, NULL, "Per-code RX PHY Errors");
851 	child = SYSCTL_CHILDREN(tree);
852 	for (i = 0; i < 64; i++) {
853 		snprintf(sn, sizeof(sn), "%d", i);
854 		SYSCTL_ADD_UINT(ctx, child, OID_AUTO, sn, CTLFLAG_RD, &sc->sc_stats.ast_rx_phy[i], 0, "");
855 	}
856 }
857 
858 static void
859 ath_sysctl_stats_attach_intr(struct ath_softc *sc,
860     struct sysctl_oid_list *parent)
861 {
862 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
863 	struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
864 	struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
865 	int i;
866 	char sn[8];
867 
868 	tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "sync_intr",
869 	    CTLFLAG_RD, NULL, "Sync interrupt statistics");
870 	child = SYSCTL_CHILDREN(tree);
871 	for (i = 0; i < 32; i++) {
872 		snprintf(sn, sizeof(sn), "%d", i);
873 		SYSCTL_ADD_UINT(ctx, child, OID_AUTO, sn, CTLFLAG_RD,
874 		    &sc->sc_intr_stats.sync_intr[i], 0, "");
875 	}
876 }
877 
878 void
879 ath_sysctl_stats_attach(struct ath_softc *sc)
880 {
881 	struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
882 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
883 	struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
884 
885 	/* Create "clear" node */
886 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
887 	    "clear_stats", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
888 	    ath_sysctl_clearstats, "I", "clear stats");
889 
890 	/* Create stats node */
891 	tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD,
892 	    NULL, "Statistics");
893 	child = SYSCTL_CHILDREN(tree);
894 
895 	/* This was generated from if_athioctl.h */
896 
897 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_watchdog", CTLFLAG_RD,
898 	    &sc->sc_stats.ast_watchdog, 0, "device reset by watchdog");
899 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_hardware", CTLFLAG_RD,
900 	    &sc->sc_stats.ast_hardware, 0, "fatal hardware error interrupts");
901 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_bmiss", CTLFLAG_RD,
902 	    &sc->sc_stats.ast_bmiss, 0, "beacon miss interrupts");
903 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_bmiss_phantom", CTLFLAG_RD,
904 	    &sc->sc_stats.ast_bmiss_phantom, 0, "beacon miss interrupts");
905 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_bstuck", CTLFLAG_RD,
906 	    &sc->sc_stats.ast_bstuck, 0, "beacon stuck interrupts");
907 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rxorn", CTLFLAG_RD,
908 	    &sc->sc_stats.ast_rxorn, 0, "rx overrun interrupts");
909 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rxeol", CTLFLAG_RD,
910 	    &sc->sc_stats.ast_rxeol, 0, "rx eol interrupts");
911 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_txurn", CTLFLAG_RD,
912 	    &sc->sc_stats.ast_txurn, 0, "tx underrun interrupts");
913 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_mib", CTLFLAG_RD,
914 	    &sc->sc_stats.ast_mib, 0, "mib interrupts");
915 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_intrcoal", CTLFLAG_RD,
916 	    &sc->sc_stats.ast_intrcoal, 0, "interrupts coalesced");
917 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_packets", CTLFLAG_RD,
918 	    &sc->sc_stats.ast_tx_packets, 0, "packet sent on the interface");
919 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_mgmt", CTLFLAG_RD,
920 	    &sc->sc_stats.ast_tx_mgmt, 0, "management frames transmitted");
921 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_discard", CTLFLAG_RD,
922 	    &sc->sc_stats.ast_tx_discard, 0, "frames discarded prior to assoc");
923 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_qstop", CTLFLAG_RD,
924 	    &sc->sc_stats.ast_tx_qstop, 0, "output stopped 'cuz no buffer");
925 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_encap", CTLFLAG_RD,
926 	    &sc->sc_stats.ast_tx_encap, 0, "tx encapsulation failed");
927 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nonode", CTLFLAG_RD,
928 	    &sc->sc_stats.ast_tx_nonode, 0, "tx failed 'cuz no node");
929 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nombuf", CTLFLAG_RD,
930 	    &sc->sc_stats.ast_tx_nombuf, 0, "tx failed 'cuz no mbuf");
931 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nomcl", CTLFLAG_RD,
932 	    &sc->sc_stats.ast_tx_nomcl, 0, "tx failed 'cuz no cluster");
933 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_linear", CTLFLAG_RD,
934 	    &sc->sc_stats.ast_tx_linear, 0, "tx linearized to cluster");
935 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nodata", CTLFLAG_RD,
936 	    &sc->sc_stats.ast_tx_nodata, 0, "tx discarded empty frame");
937 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_busdma", CTLFLAG_RD,
938 	    &sc->sc_stats.ast_tx_busdma, 0, "tx failed for dma resrcs");
939 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_xretries", CTLFLAG_RD,
940 	    &sc->sc_stats.ast_tx_xretries, 0, "tx failed 'cuz too many retries");
941 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_fifoerr", CTLFLAG_RD,
942 	    &sc->sc_stats.ast_tx_fifoerr, 0, "tx failed 'cuz FIFO underrun");
943 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_filtered", CTLFLAG_RD,
944 	    &sc->sc_stats.ast_tx_filtered, 0, "tx failed 'cuz xmit filtered");
945 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_shortretry", CTLFLAG_RD,
946 	    &sc->sc_stats.ast_tx_shortretry, 0, "tx on-chip retries (short)");
947 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_longretry", CTLFLAG_RD,
948 	    &sc->sc_stats.ast_tx_longretry, 0, "tx on-chip retries (long)");
949 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_badrate", CTLFLAG_RD,
950 	    &sc->sc_stats.ast_tx_badrate, 0, "tx failed 'cuz bogus xmit rate");
951 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_noack", CTLFLAG_RD,
952 	    &sc->sc_stats.ast_tx_noack, 0, "tx frames with no ack marked");
953 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_rts", CTLFLAG_RD,
954 	    &sc->sc_stats.ast_tx_rts, 0, "tx frames with rts enabled");
955 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_cts", CTLFLAG_RD,
956 	    &sc->sc_stats.ast_tx_cts, 0, "tx frames with cts enabled");
957 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_shortpre", CTLFLAG_RD,
958 	    &sc->sc_stats.ast_tx_shortpre, 0, "tx frames with short preamble");
959 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_altrate", CTLFLAG_RD,
960 	    &sc->sc_stats.ast_tx_altrate, 0, "tx frames with alternate rate");
961 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_protect", CTLFLAG_RD,
962 	    &sc->sc_stats.ast_tx_protect, 0, "tx frames with protection");
963 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_ctsburst", CTLFLAG_RD,
964 	    &sc->sc_stats.ast_tx_ctsburst, 0, "tx frames with cts and bursting");
965 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_ctsext", CTLFLAG_RD,
966 	    &sc->sc_stats.ast_tx_ctsext, 0, "tx frames with cts extension");
967 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_nombuf", CTLFLAG_RD,
968 	    &sc->sc_stats.ast_rx_nombuf, 0, "rx setup failed 'cuz no mbuf");
969 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_busdma", CTLFLAG_RD,
970 	    &sc->sc_stats.ast_rx_busdma, 0, "rx setup failed for dma resrcs");
971 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_orn", CTLFLAG_RD,
972 	    &sc->sc_stats.ast_rx_orn, 0, "rx failed 'cuz of desc overrun");
973 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_crcerr", CTLFLAG_RD,
974 	    &sc->sc_stats.ast_rx_crcerr, 0, "rx failed 'cuz of bad CRC");
975 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_fifoerr", CTLFLAG_RD,
976 	    &sc->sc_stats.ast_rx_fifoerr, 0, "rx failed 'cuz of FIFO overrun");
977 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_badcrypt", CTLFLAG_RD,
978 	    &sc->sc_stats.ast_rx_badcrypt, 0, "rx failed 'cuz decryption");
979 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_badmic", CTLFLAG_RD,
980 	    &sc->sc_stats.ast_rx_badmic, 0, "rx failed 'cuz MIC failure");
981 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_phyerr", CTLFLAG_RD,
982 	    &sc->sc_stats.ast_rx_phyerr, 0, "rx failed 'cuz of PHY err");
983 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_tooshort", CTLFLAG_RD,
984 	    &sc->sc_stats.ast_rx_tooshort, 0, "rx discarded 'cuz frame too short");
985 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_toobig", CTLFLAG_RD,
986 	    &sc->sc_stats.ast_rx_toobig, 0, "rx discarded 'cuz frame too large");
987 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_packets", CTLFLAG_RD,
988 	    &sc->sc_stats.ast_rx_packets, 0, "packet recv on the interface");
989 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_mgt", CTLFLAG_RD,
990 	    &sc->sc_stats.ast_rx_mgt, 0, "management frames received");
991 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_ctl", CTLFLAG_RD,
992 	    &sc->sc_stats.ast_rx_ctl, 0, "rx discarded 'cuz ctl frame");
993 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_be_xmit", CTLFLAG_RD,
994 	    &sc->sc_stats.ast_be_xmit, 0, "beacons transmitted");
995 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_be_nombuf", CTLFLAG_RD,
996 	    &sc->sc_stats.ast_be_nombuf, 0, "beacon setup failed 'cuz no mbuf");
997 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_per_cal", CTLFLAG_RD,
998 	    &sc->sc_stats.ast_per_cal, 0, "periodic calibration calls");
999 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_per_calfail", CTLFLAG_RD,
1000 	    &sc->sc_stats.ast_per_calfail, 0, "periodic calibration failed");
1001 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_per_rfgain", CTLFLAG_RD,
1002 	    &sc->sc_stats.ast_per_rfgain, 0, "periodic calibration rfgain reset");
1003 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rate_calls", CTLFLAG_RD,
1004 	    &sc->sc_stats.ast_rate_calls, 0, "rate control checks");
1005 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rate_raise", CTLFLAG_RD,
1006 	    &sc->sc_stats.ast_rate_raise, 0, "rate control raised xmit rate");
1007 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rate_drop", CTLFLAG_RD,
1008 	    &sc->sc_stats.ast_rate_drop, 0, "rate control dropped xmit rate");
1009 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ant_defswitch", CTLFLAG_RD,
1010 	    &sc->sc_stats.ast_ant_defswitch, 0, "rx/default antenna switches");
1011 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ant_txswitch", CTLFLAG_RD,
1012 	    &sc->sc_stats.ast_ant_txswitch, 0, "tx antenna switches");
1013 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_cabq_xmit", CTLFLAG_RD,
1014 	    &sc->sc_stats.ast_cabq_xmit, 0, "cabq frames transmitted");
1015 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_cabq_busy", CTLFLAG_RD,
1016 	    &sc->sc_stats.ast_cabq_busy, 0, "cabq found busy");
1017 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_raw", CTLFLAG_RD,
1018 	    &sc->sc_stats.ast_tx_raw, 0, "tx frames through raw api");
1019 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ff_txok", CTLFLAG_RD,
1020 	    &sc->sc_stats.ast_ff_txok, 0, "fast frames tx'd successfully");
1021 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ff_txerr", CTLFLAG_RD,
1022 	    &sc->sc_stats.ast_ff_txerr, 0, "fast frames tx'd w/ error");
1023 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ff_rx", CTLFLAG_RD,
1024 	    &sc->sc_stats.ast_ff_rx, 0, "fast frames rx'd");
1025 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ff_flush", CTLFLAG_RD,
1026 	    &sc->sc_stats.ast_ff_flush, 0, "fast frames flushed from staging q");
1027 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_qfull", CTLFLAG_RD,
1028 	    &sc->sc_stats.ast_tx_qfull, 0, "tx dropped 'cuz of queue limit");
1029 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nobuf", CTLFLAG_RD,
1030 	    &sc->sc_stats.ast_tx_nobuf, 0, "tx dropped 'cuz no ath buffer");
1031 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tdma_update", CTLFLAG_RD,
1032 	    &sc->sc_stats.ast_tdma_update, 0, "TDMA slot timing updates");
1033 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tdma_timers", CTLFLAG_RD,
1034 	    &sc->sc_stats.ast_tdma_timers, 0, "TDMA slot update set beacon timers");
1035 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tdma_tsf", CTLFLAG_RD,
1036 	    &sc->sc_stats.ast_tdma_tsf, 0, "TDMA slot update set TSF");
1037 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tdma_ack", CTLFLAG_RD,
1038 	    &sc->sc_stats.ast_tdma_ack, 0, "TDMA tx failed 'cuz ACK required");
1039 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_raw_fail", CTLFLAG_RD,
1040 	    &sc->sc_stats.ast_tx_raw_fail, 0, "raw tx failed 'cuz h/w down");
1041 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nofrag", CTLFLAG_RD,
1042 	    &sc->sc_stats.ast_tx_nofrag, 0, "tx dropped 'cuz no ath frag buffer");
1043 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_be_missed", CTLFLAG_RD,
1044 	    &sc->sc_stats.ast_be_missed, 0, "number of -missed- beacons");
1045 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ani_cal", CTLFLAG_RD,
1046 	    &sc->sc_stats.ast_ani_cal, 0, "number of ANI polls");
1047 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_agg", CTLFLAG_RD,
1048 	    &sc->sc_stats.ast_rx_agg, 0, "number of aggregate frames received");
1049 
1050 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_halfgi", CTLFLAG_RD,
1051 	    &sc->sc_stats.ast_rx_halfgi, 0, "number of frames received with half-GI");
1052 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_2040", CTLFLAG_RD,
1053 	    &sc->sc_stats.ast_rx_2040, 0, "number of HT/40 frames received");
1054 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_pre_crc_err", CTLFLAG_RD,
1055 	    &sc->sc_stats.ast_rx_pre_crc_err, 0, "number of delimeter-CRC errors detected");
1056 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_post_crc_err", CTLFLAG_RD,
1057 	    &sc->sc_stats.ast_rx_post_crc_err, 0, "number of post-delimiter CRC errors detected");
1058 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_decrypt_busy_err", CTLFLAG_RD,
1059 	    &sc->sc_stats.ast_rx_decrypt_busy_err, 0, "number of frames received w/ busy decrypt engine");
1060 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_hi_rx_chain", CTLFLAG_RD,
1061 	    &sc->sc_stats.ast_rx_hi_rx_chain, 0, "");
1062 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_htprotect", CTLFLAG_RD,
1063 	    &sc->sc_stats.ast_tx_htprotect, 0, "HT tx frames with protection");
1064 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_hitqueueend", CTLFLAG_RD,
1065 	    &sc->sc_stats.ast_rx_hitqueueend, 0, "RX hit queue end");
1066 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_timeout", CTLFLAG_RD,
1067 	    &sc->sc_stats.ast_tx_timeout, 0, "TX Global Timeout");
1068 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_cst", CTLFLAG_RD,
1069 	    &sc->sc_stats.ast_tx_cst, 0, "TX Carrier Sense Timeout");
1070 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_xtxop", CTLFLAG_RD,
1071 	    &sc->sc_stats.ast_tx_xtxop, 0, "TX exceeded TXOP");
1072 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_timerexpired", CTLFLAG_RD,
1073 	    &sc->sc_stats.ast_tx_timerexpired, 0, "TX exceeded TX_TIMER register");
1074 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_desccfgerr", CTLFLAG_RD,
1075 	    &sc->sc_stats.ast_tx_desccfgerr, 0, "TX Descriptor Cfg Error");
1076 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_swretries", CTLFLAG_RD,
1077 	    &sc->sc_stats.ast_tx_swretries, 0, "TX software retry count");
1078 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_swretrymax", CTLFLAG_RD,
1079 	    &sc->sc_stats.ast_tx_swretrymax, 0, "TX software retry max reached");
1080 
1081 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_data_underrun", CTLFLAG_RD,
1082 	    &sc->sc_stats.ast_tx_data_underrun, 0, "");
1083 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_delim_underrun", CTLFLAG_RD,
1084 	    &sc->sc_stats.ast_tx_delim_underrun, 0, "");
1085 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_aggr_failall", CTLFLAG_RD,
1086 	    &sc->sc_stats.ast_tx_aggr_failall, 0,
1087 	    "Number of aggregate TX failures (whole frame)");
1088 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_aggr_ok", CTLFLAG_RD,
1089 	    &sc->sc_stats.ast_tx_aggr_ok, 0,
1090 	    "Number of aggregate TX OK completions (subframe)");
1091 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_aggr_fail", CTLFLAG_RD,
1092 	    &sc->sc_stats.ast_tx_aggr_fail, 0,
1093 	    "Number of aggregate TX failures (subframe)");
1094 
1095 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_intr", CTLFLAG_RD,
1096 	    &sc->sc_stats.ast_rx_intr, 0, "RX interrupts");
1097 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_intr", CTLFLAG_RD,
1098 	    &sc->sc_stats.ast_tx_intr, 0, "TX interrupts");
1099 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_mcastq_overflow",
1100 	    CTLFLAG_RD, &sc->sc_stats.ast_tx_mcastq_overflow, 0,
1101 	    "Number of multicast frames exceeding maximum mcast queue depth");
1102 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_keymiss", CTLFLAG_RD,
1103 	    &sc->sc_stats.ast_rx_keymiss, 0, "");
1104 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_swfiltered", CTLFLAG_RD,
1105 	    &sc->sc_stats.ast_tx_swfiltered, 0, "");
1106 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_stbc",
1107 	    CTLFLAG_RD, &sc->sc_stats.ast_rx_stbc, 0,
1108 	    "Number of STBC frames received");
1109 
1110 	/* Attach the RX phy error array */
1111 	ath_sysctl_stats_attach_rxphyerr(sc, child);
1112 
1113 	/* Attach the interrupt statistics array */
1114 	ath_sysctl_stats_attach_intr(sc, child);
1115 }
1116 
1117 /*
1118  * This doesn't necessarily belong here (because it's HAL related, not
1119  * driver related).
1120  */
1121 void
1122 ath_sysctl_hal_attach(struct ath_softc *sc)
1123 {
1124 	struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
1125 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
1126 	struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
1127 
1128 	tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "hal", CTLFLAG_RD,
1129 	    NULL, "Atheros HAL parameters");
1130 	child = SYSCTL_CHILDREN(tree);
1131 
1132 	sc->sc_ah->ah_config.ah_debug = 0;
1133 	SYSCTL_ADD_INT(ctx, child, OID_AUTO, "debug", CTLFLAG_RW,
1134 	    &sc->sc_ah->ah_config.ah_debug, 0, "Atheros HAL debugging printfs");
1135 
1136 	sc->sc_ah->ah_config.ah_ar5416_biasadj = 0;
1137 	SYSCTL_ADD_INT(ctx, child, OID_AUTO, "ar5416_biasadj", CTLFLAG_RW,
1138 	    &sc->sc_ah->ah_config.ah_ar5416_biasadj, 0,
1139 	    "Enable 2GHz AR5416 direction sensitivity bias adjust");
1140 
1141 	sc->sc_ah->ah_config.ah_dma_beacon_response_time = 2;
1142 	SYSCTL_ADD_INT(ctx, child, OID_AUTO, "dma_brt", CTLFLAG_RW,
1143 	    &sc->sc_ah->ah_config.ah_dma_beacon_response_time, 0,
1144 	    "Atheros HAL DMA beacon response time");
1145 
1146 	sc->sc_ah->ah_config.ah_sw_beacon_response_time = 10;
1147 	SYSCTL_ADD_INT(ctx, child, OID_AUTO, "sw_brt", CTLFLAG_RW,
1148 	    &sc->sc_ah->ah_config.ah_sw_beacon_response_time, 0,
1149 	    "Atheros HAL software beacon response time");
1150 
1151 	sc->sc_ah->ah_config.ah_additional_swba_backoff = 0;
1152 	SYSCTL_ADD_INT(ctx, child, OID_AUTO, "swba_backoff", CTLFLAG_RW,
1153 	    &sc->sc_ah->ah_config.ah_additional_swba_backoff, 0,
1154 	    "Atheros HAL additional SWBA backoff time");
1155 
1156 	sc->sc_ah->ah_config.ah_force_full_reset = 0;
1157 	SYSCTL_ADD_INT(ctx, child, OID_AUTO, "force_full_reset", CTLFLAG_RW,
1158 	    &sc->sc_ah->ah_config.ah_force_full_reset, 0,
1159 	    "Force full chip reset rather than a warm reset");
1160 
1161 	/*
1162 	 * This is initialised by the driver.
1163 	 */
1164 	SYSCTL_ADD_INT(ctx, child, OID_AUTO, "serialise_reg_war", CTLFLAG_RW,
1165 	    &sc->sc_ah->ah_config.ah_serialise_reg_war, 0,
1166 	    "Force register access serialisation");
1167 }
1168