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