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