xref: /freebsd/sys/dev/ath/if_ath_sysctl.c (revision fae50821ae22099d0406090228bc4c5b6af693ad)
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 	sc->sc_rfsilentpin = rfsilent & 0x1c;
450 	sc->sc_rfsilentpol = (rfsilent & 0x2) != 0;
451 	return 0;
452 }
453 
454 static int
455 ath_sysctl_tpack(SYSCTL_HANDLER_ARGS)
456 {
457 	struct ath_softc *sc = arg1;
458 	u_int32_t tpack;
459 	int error;
460 
461 	(void) ath_hal_gettpack(sc->sc_ah, &tpack);
462 	error = sysctl_handle_int(oidp, &tpack, 0, req);
463 	if (error || !req->newptr)
464 		return error;
465 	return !ath_hal_settpack(sc->sc_ah, tpack) ? EINVAL : 0;
466 }
467 
468 static int
469 ath_sysctl_tpcts(SYSCTL_HANDLER_ARGS)
470 {
471 	struct ath_softc *sc = arg1;
472 	u_int32_t tpcts;
473 	int error;
474 
475 	(void) ath_hal_gettpcts(sc->sc_ah, &tpcts);
476 	error = sysctl_handle_int(oidp, &tpcts, 0, req);
477 	if (error || !req->newptr)
478 		return error;
479 	return !ath_hal_settpcts(sc->sc_ah, tpcts) ? EINVAL : 0;
480 }
481 
482 static int
483 ath_sysctl_intmit(SYSCTL_HANDLER_ARGS)
484 {
485 	struct ath_softc *sc = arg1;
486 	int intmit, error;
487 
488 	intmit = ath_hal_getintmit(sc->sc_ah);
489 	error = sysctl_handle_int(oidp, &intmit, 0, req);
490 	if (error || !req->newptr)
491 		return error;
492 
493 	/* reusing error; 1 here means "good"; 0 means "fail" */
494 	error = ath_hal_setintmit(sc->sc_ah, intmit);
495 	if (! error)
496 		return EINVAL;
497 
498 	/*
499 	 * Reset the hardware here - disabling ANI in the HAL
500 	 * doesn't reset ANI related registers, so it'll leave
501 	 * things in an inconsistent state.
502 	 */
503 	if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
504 		ath_reset(sc->sc_ifp, ATH_RESET_NOLOSS);
505 
506 	return 0;
507 }
508 
509 #ifdef IEEE80211_SUPPORT_TDMA
510 static int
511 ath_sysctl_setcca(SYSCTL_HANDLER_ARGS)
512 {
513 	struct ath_softc *sc = arg1;
514 	int setcca, error;
515 
516 	setcca = sc->sc_setcca;
517 	error = sysctl_handle_int(oidp, &setcca, 0, req);
518 	if (error || !req->newptr)
519 		return error;
520 	sc->sc_setcca = (setcca != 0);
521 	return 0;
522 }
523 #endif /* IEEE80211_SUPPORT_TDMA */
524 
525 static int
526 ath_sysctl_forcebstuck(SYSCTL_HANDLER_ARGS)
527 {
528 	struct ath_softc *sc = arg1;
529 	int val = 0;
530 	int error;
531 
532 	error = sysctl_handle_int(oidp, &val, 0, req);
533 	if (error || !req->newptr)
534 		return error;
535 	if (val == 0)
536 		return 0;
537 
538 	taskqueue_enqueue_fast(sc->sc_tq, &sc->sc_bstucktask);
539 	val = 0;
540 	return 0;
541 }
542 
543 static int
544 ath_sysctl_hangcheck(SYSCTL_HANDLER_ARGS)
545 {
546 	struct ath_softc *sc = arg1;
547 	int val = 0;
548 	int error;
549 	uint32_t mask = 0xffffffff;
550 	uint32_t *sp;
551 	uint32_t rsize;
552 	struct ath_hal *ah = sc->sc_ah;
553 
554 	error = sysctl_handle_int(oidp, &val, 0, req);
555 	if (error || !req->newptr)
556 		return error;
557 	if (val == 0)
558 		return 0;
559 
560 	/* Do a hang check */
561 	if (!ath_hal_getdiagstate(ah, HAL_DIAG_CHECK_HANGS,
562 	    &mask, sizeof(mask),
563 	    (void *) &sp, &rsize))
564 		return (0);
565 	device_printf(sc->sc_dev, "%s: sp=0x%08x\n", __func__, *sp);
566 
567 	val = 0;
568 	return 0;
569 }
570 
571 #ifdef ATH_DEBUG_ALQ
572 static int
573 ath_sysctl_alq_log(SYSCTL_HANDLER_ARGS)
574 {
575 	struct ath_softc *sc = arg1;
576 	int error, enable;
577 
578 	enable = (sc->sc_alq.sc_alq_isactive);
579 
580 	error = sysctl_handle_int(oidp, &enable, 0, req);
581 	if (error || !req->newptr)
582 		return (error);
583 	else if (enable)
584 		error = if_ath_alq_start(&sc->sc_alq);
585 	else
586 		error = if_ath_alq_stop(&sc->sc_alq);
587 	return (error);
588 }
589 
590 /*
591  * Attach the ALQ debugging if required.
592  */
593 static void
594 ath_sysctl_alq_attach(struct ath_softc *sc)
595 {
596 	struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
597 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
598 	struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
599 
600 	tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "alq", CTLFLAG_RD,
601 	    NULL, "Atheros ALQ logging parameters");
602 	child = SYSCTL_CHILDREN(tree);
603 
604 	SYSCTL_ADD_STRING(ctx, child, OID_AUTO, "filename",
605 	    CTLFLAG_RW, sc->sc_alq.sc_alq_filename, 0, "ALQ filename");
606 
607 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
608 		"enable", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
609 		ath_sysctl_alq_log, "I", "");
610 
611 	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
612 		"debugmask", CTLFLAG_RW, &sc->sc_alq.sc_alq_debug, 0,
613 		"ALQ debug mask");
614 
615 	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
616 		"numlost", CTLFLAG_RW, &sc->sc_alq.sc_alq_numlost, 0,
617 		"number lost");
618 }
619 #endif /* ATH_DEBUG_ALQ */
620 
621 void
622 ath_sysctlattach(struct ath_softc *sc)
623 {
624 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
625 	struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
626 	struct ath_hal *ah = sc->sc_ah;
627 
628 	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
629 		"countrycode", CTLFLAG_RD, &sc->sc_eecc, 0,
630 		"EEPROM country code");
631 	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
632 		"regdomain", CTLFLAG_RD, &sc->sc_eerd, 0,
633 		"EEPROM regdomain code");
634 #ifdef	ATH_DEBUG
635 	SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
636 		"debug", CTLFLAG_RW, &sc->sc_debug,
637 		"control debugging printfs");
638 #endif
639 #ifdef	ATH_DEBUG_ALQ
640 	SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
641 		"ktrdebug", CTLFLAG_RW, &sc->sc_ktrdebug,
642 		"control debugging KTR");
643 #endif /* ATH_DEBUG_ALQ */
644 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
645 		"slottime", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
646 		ath_sysctl_slottime, "I", "802.11 slot time (us)");
647 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
648 		"acktimeout", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
649 		ath_sysctl_acktimeout, "I", "802.11 ACK timeout (us)");
650 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
651 		"ctstimeout", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
652 		ath_sysctl_ctstimeout, "I", "802.11 CTS timeout (us)");
653 
654 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
655 		"softled", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
656 		ath_sysctl_softled, "I", "enable/disable software LED support");
657 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
658 		"ledpin", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
659 		ath_sysctl_ledpin, "I", "GPIO pin connected to LED");
660 	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
661 		"ledon", CTLFLAG_RW, &sc->sc_ledon, 0,
662 		"setting to turn LED on");
663 	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
664 		"ledidle", CTLFLAG_RW, &sc->sc_ledidle, 0,
665 		"idle time for inactivity LED (ticks)");
666 
667 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
668 		"hardled", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
669 		ath_sysctl_hardled, "I", "enable/disable hardware LED support");
670 	/* XXX Laziness - configure pins, then flip hardled off/on */
671 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
672 		"led_net_pin", CTLFLAG_RW, &sc->sc_led_net_pin, 0,
673 		"MAC Network LED pin, or -1 to disable");
674 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
675 		"led_pwr_pin", CTLFLAG_RW, &sc->sc_led_pwr_pin, 0,
676 		"MAC Power LED pin, or -1 to disable");
677 
678 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
679 		"txantenna", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
680 		ath_sysctl_txantenna, "I", "antenna switch");
681 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
682 		"rxantenna", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
683 		ath_sysctl_rxantenna, "I", "default/rx antenna");
684 	if (ath_hal_hasdiversity(ah))
685 		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
686 			"diversity", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
687 			ath_sysctl_diversity, "I", "antenna diversity");
688 	sc->sc_txintrperiod = ATH_TXINTR_PERIOD;
689 	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
690 		"txintrperiod", CTLFLAG_RW, &sc->sc_txintrperiod, 0,
691 		"tx descriptor batching");
692 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
693 		"diag", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
694 		ath_sysctl_diag, "I", "h/w diagnostic control");
695 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
696 		"tpscale", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
697 		ath_sysctl_tpscale, "I", "tx power scaling");
698 	if (ath_hal_hastpc(ah)) {
699 		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
700 			"tpc", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
701 			ath_sysctl_tpc, "I", "enable/disable per-packet TPC");
702 		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
703 			"tpack", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
704 			ath_sysctl_tpack, "I", "tx power for ack frames");
705 		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
706 			"tpcts", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
707 			ath_sysctl_tpcts, "I", "tx power for cts frames");
708 	}
709 	if (ath_hal_hasrfsilent(ah)) {
710 		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
711 			"rfsilent", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
712 			ath_sysctl_rfsilent, "I", "h/w RF silent config");
713 		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
714 			"rfkill", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
715 			ath_sysctl_rfkill, "I", "enable/disable RF kill switch");
716 	}
717 
718 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
719 		"txagg", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
720 		ath_sysctl_txagg, "I", "");
721 
722 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
723 		"forcebstuck", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
724 		ath_sysctl_forcebstuck, "I", "");
725 
726 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
727 		"hangcheck", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
728 		ath_sysctl_hangcheck, "I", "");
729 
730 	if (ath_hal_hasintmit(ah)) {
731 		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
732 			"intmit", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
733 			ath_sysctl_intmit, "I", "interference mitigation");
734 	}
735 	sc->sc_monpass = HAL_RXERR_DECRYPT | HAL_RXERR_MIC;
736 	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
737 		"monpass", CTLFLAG_RW, &sc->sc_monpass, 0,
738 		"mask of error frames to pass when monitoring");
739 
740 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
741 		"hwq_limit_nonaggr", CTLFLAG_RW, &sc->sc_hwq_limit_nonaggr, 0,
742 		"Hardware non-AMPDU queue depth before software-queuing TX frames");
743 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
744 		"hwq_limit_aggr", CTLFLAG_RW, &sc->sc_hwq_limit_aggr, 0,
745 		"Hardware AMPDU queue depth before software-queuing TX frames");
746 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
747 		"tid_hwq_lo", CTLFLAG_RW, &sc->sc_tid_hwq_lo, 0,
748 		"");
749 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
750 		"tid_hwq_hi", CTLFLAG_RW, &sc->sc_tid_hwq_hi, 0,
751 		"");
752 
753 	/* Aggregate length twiddles */
754 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
755 		"aggr_limit", CTLFLAG_RW, &sc->sc_aggr_limit, 0,
756 		"Maximum A-MPDU size, or 0 for 'default'");
757 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
758 		"rts_aggr_limit", CTLFLAG_RW, &sc->sc_rts_aggr_limit, 0,
759 		"Maximum A-MPDU size for RTS-protected frames, or '0' "
760 		"for default");
761 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
762 		"delim_min_pad", CTLFLAG_RW, &sc->sc_delim_min_pad, 0,
763 		"Enforce a minimum number of delimiters per A-MPDU "
764 		" sub-frame");
765 
766 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
767 		"txq_data_minfree", CTLFLAG_RW, &sc->sc_txq_data_minfree,
768 		0, "Minimum free buffers before adding a data frame"
769 		" to the TX queue");
770 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
771 		"txq_mcastq_maxdepth", CTLFLAG_RW,
772 		&sc->sc_txq_mcastq_maxdepth, 0,
773 		"Maximum buffer depth for multicast/broadcast frames");
774 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
775 		"txq_node_maxdepth", CTLFLAG_RW,
776 		&sc->sc_txq_node_maxdepth, 0,
777 		"Maximum buffer depth for a single node");
778 
779 #if 0
780 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
781 		"cabq_enable", CTLFLAG_RW,
782 		&sc->sc_cabq_enable, 0,
783 		"Whether to transmit on the CABQ or not");
784 #endif
785 
786 #ifdef IEEE80211_SUPPORT_TDMA
787 	if (ath_hal_macversion(ah) > 0x78) {
788 		sc->sc_tdmadbaprep = 2;
789 		SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
790 			"dbaprep", CTLFLAG_RW, &sc->sc_tdmadbaprep, 0,
791 			"TDMA DBA preparation time");
792 		sc->sc_tdmaswbaprep = 10;
793 		SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
794 			"swbaprep", CTLFLAG_RW, &sc->sc_tdmaswbaprep, 0,
795 			"TDMA SWBA preparation time");
796 		SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
797 			"guardtime", CTLFLAG_RW, &sc->sc_tdmaguard, 0,
798 			"TDMA slot guard time");
799 		SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
800 			"superframe", CTLFLAG_RD, &sc->sc_tdmabintval, 0,
801 			"TDMA calculated super frame");
802 		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
803 			"setcca", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
804 			ath_sysctl_setcca, "I", "enable CCA control");
805 	}
806 #endif
807 
808 #ifdef	ATH_DEBUG_ALQ
809 	ath_sysctl_alq_attach(sc);
810 #endif
811 }
812 
813 static int
814 ath_sysctl_clearstats(SYSCTL_HANDLER_ARGS)
815 {
816 	struct ath_softc *sc = arg1;
817 	int val = 0;
818 	int error;
819 
820 	error = sysctl_handle_int(oidp, &val, 0, req);
821 	if (error || !req->newptr)
822 		return error;
823 	if (val == 0)
824 		return 0;       /* Not clearing the stats is still valid */
825 	memset(&sc->sc_stats, 0, sizeof(sc->sc_stats));
826 	memset(&sc->sc_aggr_stats, 0, sizeof(sc->sc_aggr_stats));
827 	memset(&sc->sc_intr_stats, 0, sizeof(sc->sc_intr_stats));
828 
829 	val = 0;
830 	return 0;
831 }
832 
833 static void
834 ath_sysctl_stats_attach_rxphyerr(struct ath_softc *sc, struct sysctl_oid_list *parent)
835 {
836 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
837 	struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
838 	struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
839 	int i;
840 	char sn[8];
841 
842 	tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "rx_phy_err", CTLFLAG_RD, NULL, "Per-code RX PHY Errors");
843 	child = SYSCTL_CHILDREN(tree);
844 	for (i = 0; i < 64; i++) {
845 		snprintf(sn, sizeof(sn), "%d", i);
846 		SYSCTL_ADD_UINT(ctx, child, OID_AUTO, sn, CTLFLAG_RD, &sc->sc_stats.ast_rx_phy[i], 0, "");
847 	}
848 }
849 
850 static void
851 ath_sysctl_stats_attach_intr(struct ath_softc *sc,
852     struct sysctl_oid_list *parent)
853 {
854 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
855 	struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
856 	struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
857 	int i;
858 	char sn[8];
859 
860 	tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "sync_intr",
861 	    CTLFLAG_RD, NULL, "Sync interrupt statistics");
862 	child = SYSCTL_CHILDREN(tree);
863 	for (i = 0; i < 32; i++) {
864 		snprintf(sn, sizeof(sn), "%d", i);
865 		SYSCTL_ADD_UINT(ctx, child, OID_AUTO, sn, CTLFLAG_RD,
866 		    &sc->sc_intr_stats.sync_intr[i], 0, "");
867 	}
868 }
869 
870 void
871 ath_sysctl_stats_attach(struct ath_softc *sc)
872 {
873 	struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
874 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
875 	struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
876 
877 	/* Create "clear" node */
878 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
879 	    "clear_stats", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
880 	    ath_sysctl_clearstats, "I", "clear stats");
881 
882 	/* Create stats node */
883 	tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD,
884 	    NULL, "Statistics");
885 	child = SYSCTL_CHILDREN(tree);
886 
887 	/* This was generated from if_athioctl.h */
888 
889 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_watchdog", CTLFLAG_RD,
890 	    &sc->sc_stats.ast_watchdog, 0, "device reset by watchdog");
891 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_hardware", CTLFLAG_RD,
892 	    &sc->sc_stats.ast_hardware, 0, "fatal hardware error interrupts");
893 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_bmiss", CTLFLAG_RD,
894 	    &sc->sc_stats.ast_bmiss, 0, "beacon miss interrupts");
895 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_bmiss_phantom", CTLFLAG_RD,
896 	    &sc->sc_stats.ast_bmiss_phantom, 0, "beacon miss interrupts");
897 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_bstuck", CTLFLAG_RD,
898 	    &sc->sc_stats.ast_bstuck, 0, "beacon stuck interrupts");
899 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rxorn", CTLFLAG_RD,
900 	    &sc->sc_stats.ast_rxorn, 0, "rx overrun interrupts");
901 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rxeol", CTLFLAG_RD,
902 	    &sc->sc_stats.ast_rxeol, 0, "rx eol interrupts");
903 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_txurn", CTLFLAG_RD,
904 	    &sc->sc_stats.ast_txurn, 0, "tx underrun interrupts");
905 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_mib", CTLFLAG_RD,
906 	    &sc->sc_stats.ast_mib, 0, "mib interrupts");
907 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_intrcoal", CTLFLAG_RD,
908 	    &sc->sc_stats.ast_intrcoal, 0, "interrupts coalesced");
909 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_packets", CTLFLAG_RD,
910 	    &sc->sc_stats.ast_tx_packets, 0, "packet sent on the interface");
911 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_mgmt", CTLFLAG_RD,
912 	    &sc->sc_stats.ast_tx_mgmt, 0, "management frames transmitted");
913 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_discard", CTLFLAG_RD,
914 	    &sc->sc_stats.ast_tx_discard, 0, "frames discarded prior to assoc");
915 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_qstop", CTLFLAG_RD,
916 	    &sc->sc_stats.ast_tx_qstop, 0, "output stopped 'cuz no buffer");
917 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_encap", CTLFLAG_RD,
918 	    &sc->sc_stats.ast_tx_encap, 0, "tx encapsulation failed");
919 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nonode", CTLFLAG_RD,
920 	    &sc->sc_stats.ast_tx_nonode, 0, "tx failed 'cuz no node");
921 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nombuf", CTLFLAG_RD,
922 	    &sc->sc_stats.ast_tx_nombuf, 0, "tx failed 'cuz no mbuf");
923 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nomcl", CTLFLAG_RD,
924 	    &sc->sc_stats.ast_tx_nomcl, 0, "tx failed 'cuz no cluster");
925 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_linear", CTLFLAG_RD,
926 	    &sc->sc_stats.ast_tx_linear, 0, "tx linearized to cluster");
927 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nodata", CTLFLAG_RD,
928 	    &sc->sc_stats.ast_tx_nodata, 0, "tx discarded empty frame");
929 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_busdma", CTLFLAG_RD,
930 	    &sc->sc_stats.ast_tx_busdma, 0, "tx failed for dma resrcs");
931 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_xretries", CTLFLAG_RD,
932 	    &sc->sc_stats.ast_tx_xretries, 0, "tx failed 'cuz too many retries");
933 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_fifoerr", CTLFLAG_RD,
934 	    &sc->sc_stats.ast_tx_fifoerr, 0, "tx failed 'cuz FIFO underrun");
935 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_filtered", CTLFLAG_RD,
936 	    &sc->sc_stats.ast_tx_filtered, 0, "tx failed 'cuz xmit filtered");
937 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_shortretry", CTLFLAG_RD,
938 	    &sc->sc_stats.ast_tx_shortretry, 0, "tx on-chip retries (short)");
939 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_longretry", CTLFLAG_RD,
940 	    &sc->sc_stats.ast_tx_longretry, 0, "tx on-chip retries (long)");
941 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_badrate", CTLFLAG_RD,
942 	    &sc->sc_stats.ast_tx_badrate, 0, "tx failed 'cuz bogus xmit rate");
943 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_noack", CTLFLAG_RD,
944 	    &sc->sc_stats.ast_tx_noack, 0, "tx frames with no ack marked");
945 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_rts", CTLFLAG_RD,
946 	    &sc->sc_stats.ast_tx_rts, 0, "tx frames with rts enabled");
947 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_cts", CTLFLAG_RD,
948 	    &sc->sc_stats.ast_tx_cts, 0, "tx frames with cts enabled");
949 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_shortpre", CTLFLAG_RD,
950 	    &sc->sc_stats.ast_tx_shortpre, 0, "tx frames with short preamble");
951 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_altrate", CTLFLAG_RD,
952 	    &sc->sc_stats.ast_tx_altrate, 0, "tx frames with alternate rate");
953 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_protect", CTLFLAG_RD,
954 	    &sc->sc_stats.ast_tx_protect, 0, "tx frames with protection");
955 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_ctsburst", CTLFLAG_RD,
956 	    &sc->sc_stats.ast_tx_ctsburst, 0, "tx frames with cts and bursting");
957 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_ctsext", CTLFLAG_RD,
958 	    &sc->sc_stats.ast_tx_ctsext, 0, "tx frames with cts extension");
959 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_nombuf", CTLFLAG_RD,
960 	    &sc->sc_stats.ast_rx_nombuf, 0, "rx setup failed 'cuz no mbuf");
961 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_busdma", CTLFLAG_RD,
962 	    &sc->sc_stats.ast_rx_busdma, 0, "rx setup failed for dma resrcs");
963 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_orn", CTLFLAG_RD,
964 	    &sc->sc_stats.ast_rx_orn, 0, "rx failed 'cuz of desc overrun");
965 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_crcerr", CTLFLAG_RD,
966 	    &sc->sc_stats.ast_rx_crcerr, 0, "rx failed 'cuz of bad CRC");
967 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_fifoerr", CTLFLAG_RD,
968 	    &sc->sc_stats.ast_rx_fifoerr, 0, "rx failed 'cuz of FIFO overrun");
969 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_badcrypt", CTLFLAG_RD,
970 	    &sc->sc_stats.ast_rx_badcrypt, 0, "rx failed 'cuz decryption");
971 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_badmic", CTLFLAG_RD,
972 	    &sc->sc_stats.ast_rx_badmic, 0, "rx failed 'cuz MIC failure");
973 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_phyerr", CTLFLAG_RD,
974 	    &sc->sc_stats.ast_rx_phyerr, 0, "rx failed 'cuz of PHY err");
975 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_tooshort", CTLFLAG_RD,
976 	    &sc->sc_stats.ast_rx_tooshort, 0, "rx discarded 'cuz frame too short");
977 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_toobig", CTLFLAG_RD,
978 	    &sc->sc_stats.ast_rx_toobig, 0, "rx discarded 'cuz frame too large");
979 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_packets", CTLFLAG_RD,
980 	    &sc->sc_stats.ast_rx_packets, 0, "packet recv on the interface");
981 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_mgt", CTLFLAG_RD,
982 	    &sc->sc_stats.ast_rx_mgt, 0, "management frames received");
983 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_ctl", CTLFLAG_RD,
984 	    &sc->sc_stats.ast_rx_ctl, 0, "rx discarded 'cuz ctl frame");
985 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_be_xmit", CTLFLAG_RD,
986 	    &sc->sc_stats.ast_be_xmit, 0, "beacons transmitted");
987 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_be_nombuf", CTLFLAG_RD,
988 	    &sc->sc_stats.ast_be_nombuf, 0, "beacon setup failed 'cuz no mbuf");
989 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_per_cal", CTLFLAG_RD,
990 	    &sc->sc_stats.ast_per_cal, 0, "periodic calibration calls");
991 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_per_calfail", CTLFLAG_RD,
992 	    &sc->sc_stats.ast_per_calfail, 0, "periodic calibration failed");
993 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_per_rfgain", CTLFLAG_RD,
994 	    &sc->sc_stats.ast_per_rfgain, 0, "periodic calibration rfgain reset");
995 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rate_calls", CTLFLAG_RD,
996 	    &sc->sc_stats.ast_rate_calls, 0, "rate control checks");
997 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rate_raise", CTLFLAG_RD,
998 	    &sc->sc_stats.ast_rate_raise, 0, "rate control raised xmit rate");
999 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rate_drop", CTLFLAG_RD,
1000 	    &sc->sc_stats.ast_rate_drop, 0, "rate control dropped xmit rate");
1001 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ant_defswitch", CTLFLAG_RD,
1002 	    &sc->sc_stats.ast_ant_defswitch, 0, "rx/default antenna switches");
1003 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ant_txswitch", CTLFLAG_RD,
1004 	    &sc->sc_stats.ast_ant_txswitch, 0, "tx antenna switches");
1005 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_cabq_xmit", CTLFLAG_RD,
1006 	    &sc->sc_stats.ast_cabq_xmit, 0, "cabq frames transmitted");
1007 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_cabq_busy", CTLFLAG_RD,
1008 	    &sc->sc_stats.ast_cabq_busy, 0, "cabq found busy");
1009 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_raw", CTLFLAG_RD,
1010 	    &sc->sc_stats.ast_tx_raw, 0, "tx frames through raw api");
1011 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ff_txok", CTLFLAG_RD,
1012 	    &sc->sc_stats.ast_ff_txok, 0, "fast frames tx'd successfully");
1013 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ff_txerr", CTLFLAG_RD,
1014 	    &sc->sc_stats.ast_ff_txerr, 0, "fast frames tx'd w/ error");
1015 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ff_rx", CTLFLAG_RD,
1016 	    &sc->sc_stats.ast_ff_rx, 0, "fast frames rx'd");
1017 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ff_flush", CTLFLAG_RD,
1018 	    &sc->sc_stats.ast_ff_flush, 0, "fast frames flushed from staging q");
1019 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_qfull", CTLFLAG_RD,
1020 	    &sc->sc_stats.ast_tx_qfull, 0, "tx dropped 'cuz of queue limit");
1021 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nobuf", CTLFLAG_RD,
1022 	    &sc->sc_stats.ast_tx_nobuf, 0, "tx dropped 'cuz no ath buffer");
1023 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tdma_update", CTLFLAG_RD,
1024 	    &sc->sc_stats.ast_tdma_update, 0, "TDMA slot timing updates");
1025 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tdma_timers", CTLFLAG_RD,
1026 	    &sc->sc_stats.ast_tdma_timers, 0, "TDMA slot update set beacon timers");
1027 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tdma_tsf", CTLFLAG_RD,
1028 	    &sc->sc_stats.ast_tdma_tsf, 0, "TDMA slot update set TSF");
1029 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tdma_ack", CTLFLAG_RD,
1030 	    &sc->sc_stats.ast_tdma_ack, 0, "TDMA tx failed 'cuz ACK required");
1031 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_raw_fail", CTLFLAG_RD,
1032 	    &sc->sc_stats.ast_tx_raw_fail, 0, "raw tx failed 'cuz h/w down");
1033 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nofrag", CTLFLAG_RD,
1034 	    &sc->sc_stats.ast_tx_nofrag, 0, "tx dropped 'cuz no ath frag buffer");
1035 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_be_missed", CTLFLAG_RD,
1036 	    &sc->sc_stats.ast_be_missed, 0, "number of -missed- beacons");
1037 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ani_cal", CTLFLAG_RD,
1038 	    &sc->sc_stats.ast_ani_cal, 0, "number of ANI polls");
1039 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_agg", CTLFLAG_RD,
1040 	    &sc->sc_stats.ast_rx_agg, 0, "number of aggregate frames received");
1041 
1042 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_halfgi", CTLFLAG_RD,
1043 	    &sc->sc_stats.ast_rx_halfgi, 0, "number of frames received with half-GI");
1044 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_2040", CTLFLAG_RD,
1045 	    &sc->sc_stats.ast_rx_2040, 0, "number of HT/40 frames received");
1046 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_pre_crc_err", CTLFLAG_RD,
1047 	    &sc->sc_stats.ast_rx_pre_crc_err, 0, "number of delimeter-CRC errors detected");
1048 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_post_crc_err", CTLFLAG_RD,
1049 	    &sc->sc_stats.ast_rx_post_crc_err, 0, "number of post-delimiter CRC errors detected");
1050 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_decrypt_busy_err", CTLFLAG_RD,
1051 	    &sc->sc_stats.ast_rx_decrypt_busy_err, 0, "number of frames received w/ busy decrypt engine");
1052 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_hi_rx_chain", CTLFLAG_RD,
1053 	    &sc->sc_stats.ast_rx_hi_rx_chain, 0, "");
1054 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_htprotect", CTLFLAG_RD,
1055 	    &sc->sc_stats.ast_tx_htprotect, 0, "HT tx frames with protection");
1056 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_hitqueueend", CTLFLAG_RD,
1057 	    &sc->sc_stats.ast_rx_hitqueueend, 0, "RX hit queue end");
1058 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_timeout", CTLFLAG_RD,
1059 	    &sc->sc_stats.ast_tx_timeout, 0, "TX Global Timeout");
1060 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_cst", CTLFLAG_RD,
1061 	    &sc->sc_stats.ast_tx_cst, 0, "TX Carrier Sense Timeout");
1062 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_xtxop", CTLFLAG_RD,
1063 	    &sc->sc_stats.ast_tx_xtxop, 0, "TX exceeded TXOP");
1064 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_timerexpired", CTLFLAG_RD,
1065 	    &sc->sc_stats.ast_tx_timerexpired, 0, "TX exceeded TX_TIMER register");
1066 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_desccfgerr", CTLFLAG_RD,
1067 	    &sc->sc_stats.ast_tx_desccfgerr, 0, "TX Descriptor Cfg Error");
1068 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_swretries", CTLFLAG_RD,
1069 	    &sc->sc_stats.ast_tx_swretries, 0, "TX software retry count");
1070 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_swretrymax", CTLFLAG_RD,
1071 	    &sc->sc_stats.ast_tx_swretrymax, 0, "TX software retry max reached");
1072 
1073 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_data_underrun", CTLFLAG_RD,
1074 	    &sc->sc_stats.ast_tx_data_underrun, 0, "");
1075 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_delim_underrun", CTLFLAG_RD,
1076 	    &sc->sc_stats.ast_tx_delim_underrun, 0, "");
1077 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_aggr_failall", CTLFLAG_RD,
1078 	    &sc->sc_stats.ast_tx_aggr_failall, 0,
1079 	    "Number of aggregate TX failures (whole frame)");
1080 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_aggr_ok", CTLFLAG_RD,
1081 	    &sc->sc_stats.ast_tx_aggr_ok, 0,
1082 	    "Number of aggregate TX OK completions (subframe)");
1083 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_aggr_fail", CTLFLAG_RD,
1084 	    &sc->sc_stats.ast_tx_aggr_fail, 0,
1085 	    "Number of aggregate TX failures (subframe)");
1086 
1087 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_intr", CTLFLAG_RD,
1088 	    &sc->sc_stats.ast_rx_intr, 0, "RX interrupts");
1089 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_intr", CTLFLAG_RD,
1090 	    &sc->sc_stats.ast_tx_intr, 0, "TX interrupts");
1091 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_mcastq_overflow",
1092 	    CTLFLAG_RD, &sc->sc_stats.ast_tx_mcastq_overflow, 0,
1093 	    "Number of multicast frames exceeding maximum mcast queue depth");
1094 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_keymiss", CTLFLAG_RD,
1095 	    &sc->sc_stats.ast_rx_keymiss, 0, "");
1096 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_swfiltered", CTLFLAG_RD,
1097 	    &sc->sc_stats.ast_tx_swfiltered, 0, "");
1098 	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_stbc",
1099 	    CTLFLAG_RD, &sc->sc_stats.ast_rx_stbc, 0,
1100 	    "Number of STBC frames received");
1101 
1102 	/* Attach the RX phy error array */
1103 	ath_sysctl_stats_attach_rxphyerr(sc, child);
1104 
1105 	/* Attach the interrupt statistics array */
1106 	ath_sysctl_stats_attach_intr(sc, child);
1107 }
1108 
1109 /*
1110  * This doesn't necessarily belong here (because it's HAL related, not
1111  * driver related).
1112  */
1113 void
1114 ath_sysctl_hal_attach(struct ath_softc *sc)
1115 {
1116 	struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
1117 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
1118 	struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
1119 
1120 	tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "hal", CTLFLAG_RD,
1121 	    NULL, "Atheros HAL parameters");
1122 	child = SYSCTL_CHILDREN(tree);
1123 
1124 	sc->sc_ah->ah_config.ah_debug = 0;
1125 	SYSCTL_ADD_INT(ctx, child, OID_AUTO, "debug", CTLFLAG_RW,
1126 	    &sc->sc_ah->ah_config.ah_debug, 0, "Atheros HAL debugging printfs");
1127 
1128 	sc->sc_ah->ah_config.ah_ar5416_biasadj = 0;
1129 	SYSCTL_ADD_INT(ctx, child, OID_AUTO, "ar5416_biasadj", CTLFLAG_RW,
1130 	    &sc->sc_ah->ah_config.ah_ar5416_biasadj, 0,
1131 	    "Enable 2GHz AR5416 direction sensitivity bias adjust");
1132 
1133 	sc->sc_ah->ah_config.ah_dma_beacon_response_time = 2;
1134 	SYSCTL_ADD_INT(ctx, child, OID_AUTO, "dma_brt", CTLFLAG_RW,
1135 	    &sc->sc_ah->ah_config.ah_dma_beacon_response_time, 0,
1136 	    "Atheros HAL DMA beacon response time");
1137 
1138 	sc->sc_ah->ah_config.ah_sw_beacon_response_time = 10;
1139 	SYSCTL_ADD_INT(ctx, child, OID_AUTO, "sw_brt", CTLFLAG_RW,
1140 	    &sc->sc_ah->ah_config.ah_sw_beacon_response_time, 0,
1141 	    "Atheros HAL software beacon response time");
1142 
1143 	sc->sc_ah->ah_config.ah_additional_swba_backoff = 0;
1144 	SYSCTL_ADD_INT(ctx, child, OID_AUTO, "swba_backoff", CTLFLAG_RW,
1145 	    &sc->sc_ah->ah_config.ah_additional_swba_backoff, 0,
1146 	    "Atheros HAL additional SWBA backoff time");
1147 
1148 	sc->sc_ah->ah_config.ah_force_full_reset = 0;
1149 	SYSCTL_ADD_INT(ctx, child, OID_AUTO, "force_full_reset", CTLFLAG_RW,
1150 	    &sc->sc_ah->ah_config.ah_force_full_reset, 0,
1151 	    "Force full chip reset rather than a warm reset");
1152 
1153 	/*
1154 	 * This is initialised by the driver.
1155 	 */
1156 	SYSCTL_ADD_INT(ctx, child, OID_AUTO, "serialise_reg_war", CTLFLAG_RW,
1157 	    &sc->sc_ah->ah_config.ah_serialise_reg_war, 0,
1158 	    "Force register access serialisation");
1159 }
1160