Home | History | Annotate | Line # | Download | only in ic
ath_netbsd.c revision 1.3.2.5
      1  1.3.2.5    yamt /*	$NetBSD: ath_netbsd.c,v 1.3.2.5 2007/12/07 17:29:51 yamt Exp $ */
      2  1.3.2.1    yamt 
      3      1.1  dyoung /*-
      4      1.1  dyoung  * Copyright (c) 2003, 2004 David Young
      5      1.1  dyoung  * All rights reserved.
      6      1.1  dyoung  *
      7      1.1  dyoung  * Redistribution and use in source and binary forms, with or without
      8      1.1  dyoung  * modification, are permitted provided that the following conditions
      9      1.1  dyoung  * are met:
     10      1.1  dyoung  * 1. Redistributions of source code must retain the above copyright
     11      1.1  dyoung  *    notice, this list of conditions and the following disclaimer.
     12      1.1  dyoung  * 2. Redistributions in binary form must reproduce the above copyright
     13      1.1  dyoung  *    notice, this list of conditions and the following disclaimer in the
     14      1.1  dyoung  *    documentation and/or other materials provided with the distribution.
     15      1.1  dyoung  * 3. The name of the author may not be used to endorse or promote products
     16      1.1  dyoung  *    derived from this software without specific prior written permission.
     17      1.1  dyoung  *
     18      1.1  dyoung  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     19      1.1  dyoung  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     20      1.1  dyoung  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     21      1.1  dyoung  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     22      1.1  dyoung  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     23      1.1  dyoung  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24      1.1  dyoung  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25      1.1  dyoung  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26      1.1  dyoung  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27      1.1  dyoung  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28      1.1  dyoung  */
     29  1.3.2.1    yamt 
     30  1.3.2.1    yamt #include <sys/cdefs.h>
     31  1.3.2.5    yamt __KERNEL_RCSID(0, "$NetBSD: ath_netbsd.c,v 1.3.2.5 2007/12/07 17:29:51 yamt Exp $");
     32  1.3.2.1    yamt 
     33      1.1  dyoung #include <sys/param.h>
     34      1.1  dyoung #include <sys/types.h>
     35      1.1  dyoung #include <sys/errno.h>
     36  1.3.2.2    yamt #include <sys/systm.h>
     37      1.1  dyoung #include <sys/sysctl.h>
     38  1.3.2.2    yamt #include <sys/mbuf.h>
     39      1.1  dyoung #include <sys/malloc.h>
     40      1.1  dyoung #include <sys/lock.h>
     41      1.1  dyoung #include <sys/kernel.h>
     42      1.1  dyoung #include <sys/socket.h>
     43      1.1  dyoung #include <sys/sockio.h>
     44      1.1  dyoung #include <sys/sysctl.h>
     45      1.1  dyoung #include <sys/callout.h>
     46  1.3.2.4    yamt #include <sys/bus.h>
     47      1.1  dyoung #include <machine/stdarg.h>
     48      1.1  dyoung #include <sys/endian.h>
     49      1.2  martin #include <sys/device.h>
     50      1.1  dyoung 
     51      1.1  dyoung #include <net/if.h>
     52      1.1  dyoung #include <net/if_dl.h>
     53      1.1  dyoung #include <net/if_media.h>
     54      1.1  dyoung #include <net/if_arp.h>
     55      1.1  dyoung #include <net/if_ether.h>
     56      1.1  dyoung #include <net/if_llc.h>
     57      1.1  dyoung 
     58      1.1  dyoung #include <net80211/ieee80211_netbsd.h>
     59      1.1  dyoung #include <net80211/ieee80211_var.h>
     60      1.1  dyoung #include <dev/ic/ath_netbsd.h>
     61      1.1  dyoung #include <dev/ic/athvar.h>
     62      1.3  dyoung 
     63      1.1  dyoung void
     64  1.3.2.5    yamt device_printf(device_t dev, const char *fmt, ...)
     65      1.1  dyoung {
     66  1.3.2.5    yamt 	va_list ap;
     67      1.1  dyoung 
     68  1.3.2.5    yamt 	va_start(ap, fmt);
     69  1.3.2.5    yamt 	printf("%s: ", device_xname(dev));
     70  1.3.2.5    yamt 	vprintf(fmt, ap);
     71  1.3.2.5    yamt 	va_end(ap);
     72      1.1  dyoung 	return;
     73      1.1  dyoung }
     74      1.1  dyoung 
     75      1.1  dyoung /*
     76  1.3.2.1    yamt  * Setup sysctl(3) MIB, hw.ath.*.
     77      1.1  dyoung  *
     78      1.1  dyoung  * TBD condition CTLFLAG_PERMANENT on being an LKM or not
     79      1.1  dyoung  */
     80      1.1  dyoung SYSCTL_SETUP(sysctl_ath, "sysctl ath subtree setup")
     81      1.1  dyoung {
     82      1.1  dyoung 	int rc;
     83      1.1  dyoung 	const struct sysctlnode *cnode, *rnode;
     84      1.1  dyoung 
     85      1.1  dyoung 	if ((rnode = ath_sysctl_treetop(clog)) == NULL)
     86      1.1  dyoung 		return;
     87      1.1  dyoung 
     88      1.1  dyoung 	if ((rc = SYSCTL_GLOBAL_INT(CTLFLAG_READWRITE, "dwell",
     89      1.1  dyoung 	    "channel dwell time (ms) for AP/station scanning",
     90      1.1  dyoung 	    dwelltime)) != 0)
     91      1.1  dyoung 		goto err;
     92      1.1  dyoung 
     93      1.1  dyoung 	if ((rc = SYSCTL_GLOBAL_INT(CTLFLAG_READWRITE, "calibrate",
     94      1.1  dyoung 	    "chip calibration interval (secs)", calinterval)) != 0)
     95      1.1  dyoung 		goto err;
     96      1.1  dyoung 
     97      1.1  dyoung 	if ((rc = SYSCTL_GLOBAL_INT(CTLFLAG_READWRITE, "outdoor",
     98      1.1  dyoung 	    "outdoor operation", outdoor)) != 0)
     99      1.1  dyoung 		goto err;
    100      1.1  dyoung 
    101      1.1  dyoung 	/* country code */
    102      1.1  dyoung 	if ((rc = SYSCTL_GLOBAL_INT(CTLFLAG_READWRITE,
    103      1.1  dyoung 	    "countrycode", "country code", countrycode)) != 0)
    104      1.1  dyoung 		goto err;
    105      1.1  dyoung 
    106      1.1  dyoung 	/* regulatory domain */
    107  1.3.2.1    yamt 	if ((rc = SYSCTL_GLOBAL_INT(CTLFLAG_READWRITE, "regdomain",
    108  1.3.2.1    yamt 	    "EEPROM regdomain code", regdomain)) != 0)
    109      1.1  dyoung 		goto err;
    110      1.1  dyoung 
    111      1.1  dyoung 	if ((rc = SYSCTL_GLOBAL_INT(CTLFLAG_READWRITE, "debug",
    112      1.1  dyoung 	    "control debugging printfs", debug)) != 0)
    113      1.1  dyoung 		goto err;
    114      1.1  dyoung 
    115  1.3.2.1    yamt 	if ((rc = SYSCTL_GLOBAL_INT(CTLFLAG_READONLY, "rxbuf",
    116  1.3.2.1    yamt 	    "rx buffers allocated", rxbuf)) != 0)
    117  1.3.2.1    yamt 		goto err;
    118  1.3.2.1    yamt 	if ((rc = SYSCTL_GLOBAL_INT(CTLFLAG_READONLY, "txbuf",
    119  1.3.2.1    yamt 	    "tx buffers allocated", txbuf)) != 0)
    120  1.3.2.1    yamt 		goto err;
    121  1.3.2.1    yamt 
    122      1.1  dyoung 	return;
    123      1.1  dyoung err:
    124      1.1  dyoung 	printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
    125      1.1  dyoung }
    126      1.1  dyoung 
    127      1.1  dyoung static int
    128      1.1  dyoung ath_sysctl_slottime(SYSCTLFN_ARGS)
    129      1.1  dyoung {
    130      1.1  dyoung 	struct ath_softc *sc;
    131      1.1  dyoung 	struct sysctlnode node;
    132      1.1  dyoung 	u_int slottime;
    133      1.1  dyoung 	int error;
    134      1.1  dyoung 
    135      1.1  dyoung 	node = *rnode;
    136      1.1  dyoung 	sc = (struct ath_softc *)node.sysctl_data;
    137      1.1  dyoung 	slottime = ath_hal_getslottime(sc->sc_ah);
    138      1.1  dyoung 	node.sysctl_data = &slottime;
    139      1.1  dyoung 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    140      1.1  dyoung 	if (error || newp == NULL)
    141      1.1  dyoung 		return error;
    142      1.1  dyoung 	return !ath_hal_setslottime(sc->sc_ah, slottime) ? EINVAL : 0;
    143      1.1  dyoung }
    144      1.1  dyoung 
    145      1.1  dyoung static int
    146      1.1  dyoung ath_sysctl_acktimeout(SYSCTLFN_ARGS)
    147      1.1  dyoung {
    148      1.1  dyoung 	struct ath_softc *sc;
    149      1.1  dyoung 	struct sysctlnode node;
    150      1.1  dyoung 	u_int acktimeout;
    151      1.1  dyoung 	int error;
    152      1.1  dyoung 
    153      1.1  dyoung 	node = *rnode;
    154      1.1  dyoung 	sc = (struct ath_softc *)node.sysctl_data;
    155      1.1  dyoung 	acktimeout = ath_hal_getacktimeout(sc->sc_ah);
    156      1.1  dyoung 	node.sysctl_data = &acktimeout;
    157      1.1  dyoung 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    158      1.1  dyoung 	if (error || newp == NULL)
    159      1.1  dyoung 		return error;
    160      1.1  dyoung 	return !ath_hal_setacktimeout(sc->sc_ah, acktimeout) ? EINVAL : 0;
    161      1.1  dyoung }
    162      1.1  dyoung 
    163      1.1  dyoung static int
    164      1.1  dyoung ath_sysctl_ctstimeout(SYSCTLFN_ARGS)
    165      1.1  dyoung {
    166      1.1  dyoung 	struct ath_softc *sc;
    167      1.1  dyoung 	struct sysctlnode node;
    168      1.1  dyoung 	u_int ctstimeout;
    169      1.1  dyoung 	int error;
    170      1.1  dyoung 
    171      1.1  dyoung 	node = *rnode;
    172      1.1  dyoung 	sc = (struct ath_softc *)node.sysctl_data;
    173      1.1  dyoung 	ctstimeout = ath_hal_getctstimeout(sc->sc_ah);
    174      1.1  dyoung 	node.sysctl_data = &ctstimeout;
    175      1.1  dyoung 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    176      1.1  dyoung 	if (error || newp == NULL)
    177      1.1  dyoung 		return error;
    178      1.1  dyoung 	return !ath_hal_setctstimeout(sc->sc_ah, ctstimeout) ? EINVAL : 0;
    179      1.1  dyoung }
    180      1.1  dyoung 
    181      1.1  dyoung static int
    182      1.1  dyoung ath_sysctl_softled(SYSCTLFN_ARGS)
    183      1.1  dyoung {
    184      1.1  dyoung 	struct ath_softc *sc;
    185      1.1  dyoung 	struct sysctlnode node;
    186      1.1  dyoung 	int softled;
    187      1.1  dyoung 	int error;
    188      1.1  dyoung 
    189      1.1  dyoung 	node = *rnode;
    190      1.1  dyoung 	sc = (struct ath_softc *)node.sysctl_data;
    191      1.1  dyoung 	softled = sc->sc_softled;
    192      1.1  dyoung 	node.sysctl_data = &softled;
    193      1.1  dyoung 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    194      1.1  dyoung 	if (error || newp == NULL)
    195      1.1  dyoung 		return error;
    196      1.1  dyoung 	softled = (softled != 0);
    197      1.1  dyoung 	if (softled != sc->sc_softled) {
    198      1.1  dyoung 		if (softled) {
    199      1.1  dyoung 			/* NB: handle any sc_ledpin change */
    200      1.1  dyoung 			ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_ledpin);
    201      1.1  dyoung 			ath_hal_gpioset(sc->sc_ah, sc->sc_ledpin,
    202      1.1  dyoung 				!sc->sc_ledon);
    203      1.1  dyoung 		}
    204      1.1  dyoung 		sc->sc_softled = softled;
    205      1.1  dyoung 	}
    206      1.1  dyoung 	return 0;
    207      1.1  dyoung }
    208      1.1  dyoung 
    209      1.1  dyoung static int
    210      1.1  dyoung ath_sysctl_rxantenna(SYSCTLFN_ARGS)
    211      1.1  dyoung {
    212      1.1  dyoung 	struct ath_softc *sc;
    213      1.1  dyoung 	struct sysctlnode node;
    214      1.1  dyoung 	u_int defantenna;
    215      1.1  dyoung 	int error;
    216      1.1  dyoung 
    217      1.1  dyoung 	node = *rnode;
    218      1.1  dyoung 	sc = (struct ath_softc *)node.sysctl_data;
    219      1.1  dyoung 	defantenna = ath_hal_getdefantenna(sc->sc_ah);
    220      1.1  dyoung 	node.sysctl_data = &defantenna;
    221      1.1  dyoung 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    222      1.1  dyoung 	if (error || newp == NULL)
    223      1.1  dyoung 		return error;
    224      1.1  dyoung 	ath_hal_setdefantenna(sc->sc_ah, defantenna);
    225      1.1  dyoung 	return 0;
    226      1.1  dyoung }
    227      1.1  dyoung 
    228      1.1  dyoung static int
    229      1.1  dyoung ath_sysctl_diversity(SYSCTLFN_ARGS)
    230      1.1  dyoung {
    231      1.1  dyoung 	struct ath_softc *sc;
    232      1.1  dyoung 	struct sysctlnode node;
    233      1.1  dyoung 	u_int diversity;
    234      1.1  dyoung 	int error;
    235      1.1  dyoung 
    236      1.1  dyoung 	node = *rnode;
    237      1.1  dyoung 	sc = (struct ath_softc *)node.sysctl_data;
    238      1.1  dyoung 	diversity = sc->sc_diversity;
    239      1.1  dyoung 	node.sysctl_data = &diversity;
    240      1.1  dyoung 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    241      1.1  dyoung 	if (error || newp == NULL)
    242      1.1  dyoung 		return error;
    243      1.1  dyoung 	if (!ath_hal_setdiversity(sc->sc_ah, diversity))
    244      1.1  dyoung 		return EINVAL;
    245      1.1  dyoung 	sc->sc_diversity = diversity;
    246      1.1  dyoung 	return 0;
    247      1.1  dyoung }
    248      1.1  dyoung 
    249      1.1  dyoung static int
    250      1.1  dyoung ath_sysctl_diag(SYSCTLFN_ARGS)
    251      1.1  dyoung {
    252      1.1  dyoung 	struct ath_softc *sc;
    253      1.1  dyoung 	struct sysctlnode node;
    254      1.1  dyoung 	u_int32_t diag;
    255      1.1  dyoung 	int error;
    256      1.1  dyoung 
    257      1.1  dyoung 	node = *rnode;
    258      1.1  dyoung 	sc = (struct ath_softc *)node.sysctl_data;
    259      1.1  dyoung 	if (!ath_hal_getdiag(sc->sc_ah, &diag))
    260      1.1  dyoung 		return EINVAL;
    261      1.1  dyoung 	node.sysctl_data = &diag;
    262      1.1  dyoung 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    263      1.1  dyoung 	if (error || newp == NULL)
    264      1.1  dyoung 		return error;
    265      1.1  dyoung 	return !ath_hal_setdiag(sc->sc_ah, diag) ? EINVAL : 0;
    266      1.1  dyoung }
    267      1.1  dyoung 
    268      1.1  dyoung static int
    269      1.1  dyoung ath_sysctl_tpscale(SYSCTLFN_ARGS)
    270      1.1  dyoung {
    271      1.1  dyoung 	struct ath_softc *sc;
    272      1.1  dyoung 	struct sysctlnode node;
    273      1.1  dyoung 	u_int32_t scale;
    274      1.1  dyoung 	int error;
    275      1.1  dyoung 
    276      1.1  dyoung 	node = *rnode;
    277      1.1  dyoung 	sc = (struct ath_softc *)node.sysctl_data;
    278  1.3.2.1    yamt 	(void)ath_hal_gettpscale(sc->sc_ah, &scale);
    279      1.1  dyoung 	node.sysctl_data = &scale;
    280      1.1  dyoung 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    281      1.1  dyoung 	if (error || newp == NULL)
    282      1.1  dyoung 		return error;
    283      1.1  dyoung 	return !ath_hal_settpscale(sc->sc_ah, scale)
    284      1.1  dyoung 	    ? EINVAL
    285      1.1  dyoung 	    : ath_reset(&sc->sc_if);
    286      1.1  dyoung }
    287      1.1  dyoung 
    288      1.1  dyoung static int
    289      1.1  dyoung ath_sysctl_tpc(SYSCTLFN_ARGS)
    290      1.1  dyoung {
    291      1.1  dyoung 	struct ath_softc *sc;
    292      1.1  dyoung 	struct sysctlnode node;
    293      1.1  dyoung 	u_int tpc;
    294      1.1  dyoung 	int error;
    295      1.1  dyoung 
    296      1.1  dyoung 	node = *rnode;
    297      1.1  dyoung 	sc = (struct ath_softc *)node.sysctl_data;
    298      1.1  dyoung 	tpc = ath_hal_gettpc(sc->sc_ah);
    299      1.1  dyoung 	node.sysctl_data = &tpc;
    300      1.1  dyoung 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    301      1.1  dyoung 	if (error || newp == NULL)
    302      1.1  dyoung 		return error;
    303      1.1  dyoung 	return !ath_hal_settpc(sc->sc_ah, tpc) ? EINVAL : 0;
    304      1.1  dyoung }
    305      1.1  dyoung 
    306  1.3.2.1    yamt static int
    307  1.3.2.1    yamt ath_sysctl_rfkill(SYSCTLFN_ARGS)
    308  1.3.2.1    yamt {
    309  1.3.2.1    yamt 	struct ath_softc *sc;
    310  1.3.2.1    yamt 	struct sysctlnode node;
    311  1.3.2.1    yamt 	u_int rfkill;
    312  1.3.2.1    yamt 	int error;
    313  1.3.2.1    yamt 
    314  1.3.2.1    yamt 	node = *rnode;
    315  1.3.2.1    yamt 	sc = (struct ath_softc *)node.sysctl_data;
    316  1.3.2.1    yamt 	rfkill = ath_hal_getrfkill(sc->sc_ah);
    317  1.3.2.1    yamt 	node.sysctl_data = &rfkill;
    318  1.3.2.1    yamt 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    319  1.3.2.1    yamt 	if (error || newp == NULL)
    320  1.3.2.1    yamt 		return error;
    321  1.3.2.1    yamt 	return !ath_hal_setrfkill(sc->sc_ah, rfkill) ? EINVAL : 0;
    322  1.3.2.1    yamt }
    323  1.3.2.1    yamt 
    324  1.3.2.1    yamt static int
    325  1.3.2.1    yamt ath_sysctl_rfsilent(SYSCTLFN_ARGS)
    326  1.3.2.1    yamt {
    327  1.3.2.1    yamt 	struct ath_softc *sc;
    328  1.3.2.1    yamt 	struct sysctlnode node;
    329  1.3.2.1    yamt 	u_int rfsilent;
    330  1.3.2.1    yamt 	int error;
    331  1.3.2.1    yamt 
    332  1.3.2.1    yamt 	node = *rnode;
    333  1.3.2.1    yamt 	sc = (struct ath_softc *)node.sysctl_data;
    334  1.3.2.1    yamt 	(void)ath_hal_getrfsilent(sc->sc_ah, &rfsilent);
    335  1.3.2.1    yamt 	node.sysctl_data = &rfsilent;
    336  1.3.2.1    yamt 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    337  1.3.2.1    yamt 	if (error || newp == NULL)
    338  1.3.2.1    yamt 		return error;
    339  1.3.2.1    yamt 	return !ath_hal_setrfsilent(sc->sc_ah, rfsilent) ? EINVAL : 0;
    340  1.3.2.1    yamt }
    341  1.3.2.1    yamt 
    342  1.3.2.1    yamt static int
    343  1.3.2.1    yamt ath_sysctl_regdomain(SYSCTLFN_ARGS)
    344  1.3.2.1    yamt {
    345  1.3.2.1    yamt 	struct ath_softc *sc;
    346  1.3.2.1    yamt 	struct sysctlnode node;
    347  1.3.2.1    yamt 	u_int32_t rd;
    348  1.3.2.1    yamt 	int error;
    349  1.3.2.1    yamt 
    350  1.3.2.1    yamt 	node = *rnode;
    351  1.3.2.1    yamt 	sc = (struct ath_softc *)node.sysctl_data;
    352  1.3.2.1    yamt 	if (!ath_hal_getregdomain(sc->sc_ah, &rd))
    353  1.3.2.1    yamt 		return EINVAL;
    354  1.3.2.1    yamt 	node.sysctl_data = &rd;
    355  1.3.2.1    yamt 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    356  1.3.2.1    yamt 	if (error || newp == NULL)
    357  1.3.2.1    yamt 		return error;
    358  1.3.2.1    yamt 	return !ath_hal_setregdomain(sc->sc_ah, rd) ? EINVAL : 0;
    359  1.3.2.1    yamt }
    360  1.3.2.1    yamt 
    361  1.3.2.1    yamt static int
    362  1.3.2.1    yamt ath_sysctl_tpack(SYSCTLFN_ARGS)
    363  1.3.2.1    yamt {
    364  1.3.2.1    yamt 	struct ath_softc *sc;
    365  1.3.2.1    yamt 	struct sysctlnode node;
    366  1.3.2.1    yamt 	u_int32_t tpack;
    367  1.3.2.1    yamt 	int error;
    368  1.3.2.1    yamt 
    369  1.3.2.1    yamt 	node = *rnode;
    370  1.3.2.1    yamt 	sc = (struct ath_softc *)node.sysctl_data;
    371  1.3.2.1    yamt 	(void)ath_hal_gettpack(sc->sc_ah, &tpack);
    372  1.3.2.1    yamt 	node.sysctl_data = &tpack;
    373  1.3.2.1    yamt 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    374  1.3.2.1    yamt 	if (error || newp == NULL)
    375  1.3.2.1    yamt 		return error;
    376  1.3.2.1    yamt 	return !ath_hal_settpack(sc->sc_ah, tpack) ? EINVAL : 0;
    377  1.3.2.1    yamt }
    378  1.3.2.1    yamt 
    379  1.3.2.1    yamt static int
    380  1.3.2.1    yamt ath_sysctl_tpcts(SYSCTLFN_ARGS)
    381  1.3.2.1    yamt {
    382  1.3.2.1    yamt 	struct ath_softc *sc;
    383  1.3.2.1    yamt 	struct sysctlnode node;
    384  1.3.2.1    yamt 	u_int32_t tpcts;
    385  1.3.2.1    yamt 	int error;
    386  1.3.2.1    yamt 
    387  1.3.2.1    yamt 	node = *rnode;
    388  1.3.2.1    yamt 	sc = (struct ath_softc *)node.sysctl_data;
    389  1.3.2.1    yamt 	(void)ath_hal_gettpcts(sc->sc_ah, &tpcts);
    390  1.3.2.1    yamt 	node.sysctl_data = &tpcts;
    391  1.3.2.1    yamt 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    392  1.3.2.1    yamt 	if (error || newp == NULL)
    393  1.3.2.1    yamt 		return error;
    394  1.3.2.1    yamt 	return !ath_hal_settpcts(sc->sc_ah, tpcts) ? EINVAL : 0;
    395  1.3.2.1    yamt }
    396  1.3.2.1    yamt 
    397  1.3.2.1    yamt const struct sysctlnode *
    398      1.3  dyoung ath_sysctl_instance(const char *dvname, struct sysctllog **log)
    399      1.3  dyoung {
    400      1.3  dyoung 	int rc;
    401      1.3  dyoung 	const struct sysctlnode *rnode;
    402      1.3  dyoung 
    403      1.3  dyoung 	if ((rc = sysctl_createv(log, 0, NULL, &rnode,
    404      1.3  dyoung 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL,
    405      1.3  dyoung 	    NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0)
    406      1.3  dyoung 		goto err;
    407      1.3  dyoung 
    408      1.3  dyoung 	if ((rc = sysctl_createv(log, 0, &rnode, &rnode,
    409      1.3  dyoung 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, dvname,
    410      1.3  dyoung 	    SYSCTL_DESCR("ath information and options"),
    411      1.3  dyoung 	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
    412      1.3  dyoung 		goto err;
    413      1.3  dyoung 
    414      1.3  dyoung 	return rnode;
    415      1.3  dyoung err:
    416      1.3  dyoung 	printf("%s: sysctl_createv failed, rc = %d\n", __func__, rc);
    417      1.3  dyoung 	return NULL;
    418      1.3  dyoung }
    419      1.3  dyoung 
    420      1.1  dyoung const struct sysctlnode *
    421      1.1  dyoung ath_sysctl_treetop(struct sysctllog **log)
    422      1.1  dyoung {
    423      1.1  dyoung 	int rc;
    424      1.1  dyoung 	const struct sysctlnode *rnode;
    425      1.1  dyoung 
    426      1.1  dyoung 	if ((rc = sysctl_createv(log, 0, NULL, &rnode,
    427      1.1  dyoung 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL,
    428      1.1  dyoung 	    NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0)
    429      1.1  dyoung 		goto err;
    430      1.1  dyoung 
    431      1.1  dyoung 	if ((rc = sysctl_createv(log, 0, &rnode, &rnode,
    432      1.1  dyoung 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "ath",
    433      1.1  dyoung 	    SYSCTL_DESCR("ath information and options"),
    434      1.1  dyoung 	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
    435      1.1  dyoung 		goto err;
    436      1.1  dyoung 
    437      1.1  dyoung 	return rnode;
    438      1.1  dyoung err:
    439      1.1  dyoung 	printf("%s: sysctl_createv failed, rc = %d\n", __func__, rc);
    440      1.1  dyoung 	return NULL;
    441      1.1  dyoung }
    442      1.1  dyoung 
    443      1.1  dyoung void
    444      1.1  dyoung ath_sysctlattach(struct ath_softc *sc)
    445      1.1  dyoung {
    446      1.1  dyoung 	int rc;
    447      1.1  dyoung 	struct sysctllog **log = &sc->sc_sysctllog;
    448      1.1  dyoung 	const struct sysctlnode *cnode, *rnode;
    449      1.1  dyoung 
    450      1.1  dyoung 	ath_hal_getcountrycode(sc->sc_ah, &sc->sc_countrycode);
    451  1.3.2.1    yamt 	(void)ath_hal_getregdomain(sc->sc_ah, &sc->sc_regdomain);
    452      1.1  dyoung 	sc->sc_debug = ath_debug;
    453      1.1  dyoung 	sc->sc_txintrperiod = ATH_TXINTR_PERIOD;
    454      1.1  dyoung 
    455      1.3  dyoung 	if ((rnode = ath_sysctl_instance(sc->sc_dev.dv_xname, log)) == NULL)
    456      1.1  dyoung 		return;
    457      1.1  dyoung 
    458      1.1  dyoung 	if ((rc = SYSCTL_INT(0, countrycode, "EEPROM country code")) != 0)
    459      1.1  dyoung 		goto err;
    460      1.1  dyoung 
    461      1.1  dyoung 	if ((rc = SYSCTL_INT(CTLFLAG_READWRITE, debug,
    462      1.1  dyoung 	    "control debugging printfs")) != 0)
    463      1.1  dyoung 		goto err;
    464      1.1  dyoung 
    465      1.1  dyoung #if 0
    466      1.1  dyoung 	/* channel dwell time (ms) for AP/station scanning */
    467      1.1  dyoung 	if ((rc = SYSCTL_INT(CTLFLAG_READWRITE, dwell,
    468      1.1  dyoung 	    "Channel dwell time (ms) for scanning")) != 0)
    469      1.1  dyoung 		goto err;
    470      1.1  dyoung #endif
    471      1.1  dyoung 
    472      1.1  dyoung 	if ((rc = SYSCTL_INT_SUBR(CTLFLAG_READWRITE, slottime,
    473      1.1  dyoung 	    "802.11 slot time (us)")) != 0)
    474      1.1  dyoung 		goto err;
    475      1.1  dyoung 	if ((rc = SYSCTL_INT_SUBR(CTLFLAG_READWRITE, acktimeout,
    476      1.1  dyoung 	    "802.11 ACK timeout (us)")) != 0)
    477      1.1  dyoung 		goto err;
    478      1.1  dyoung 	if ((rc = SYSCTL_INT_SUBR(CTLFLAG_READWRITE, ctstimeout,
    479      1.1  dyoung 	    "802.11 CTS timeout (us)")) != 0)
    480      1.1  dyoung 		goto err;
    481      1.1  dyoung 	if ((rc = SYSCTL_INT_SUBR(CTLFLAG_READWRITE, softled,
    482      1.1  dyoung 	    "enable/disable software LED support")) != 0)
    483      1.1  dyoung 		goto err;
    484      1.1  dyoung 	if ((rc = SYSCTL_INT(CTLFLAG_READWRITE, ledpin,
    485      1.1  dyoung 	    "GPIO pin connected to LED")) != 0)
    486      1.1  dyoung 		goto err;
    487      1.1  dyoung 	if ((rc = SYSCTL_INT(CTLFLAG_READWRITE, ledon,
    488      1.1  dyoung 	    "setting to turn LED on")) != 0)
    489      1.1  dyoung 		goto err;
    490      1.1  dyoung 	if ((rc = SYSCTL_INT(CTLFLAG_READWRITE, ledidle,
    491      1.1  dyoung 	    "idle time for inactivity LED (ticks)")) != 0)
    492      1.1  dyoung 		goto err;
    493      1.1  dyoung 	if ((rc = SYSCTL_INT(CTLFLAG_READWRITE, txantenna,
    494      1.1  dyoung 	    "tx antenna (0=auto)")) != 0)
    495      1.1  dyoung 		goto err;
    496      1.1  dyoung 	if ((rc = SYSCTL_INT_SUBR(CTLFLAG_READWRITE, rxantenna,
    497      1.1  dyoung 	    "default/rx antenna")) != 0)
    498      1.1  dyoung 		goto err;
    499  1.3.2.1    yamt 	if (ath_hal_hasdiversity(sc->sc_ah)) {
    500      1.1  dyoung 		if ((rc = SYSCTL_INT_SUBR(CTLFLAG_READWRITE, diversity,
    501      1.1  dyoung 		    "antenna diversity")) != 0)
    502      1.1  dyoung 			goto err;
    503      1.1  dyoung 	}
    504      1.1  dyoung 	if ((rc = SYSCTL_INT(CTLFLAG_READWRITE, txintrperiod,
    505      1.1  dyoung 	    "tx descriptor batching")) != 0)
    506      1.1  dyoung 		goto err;
    507      1.1  dyoung 	if ((rc = SYSCTL_INT_SUBR(CTLFLAG_READWRITE, diag,
    508      1.1  dyoung 	    "h/w diagnostic control")) != 0)
    509      1.1  dyoung 		goto err;
    510      1.1  dyoung 	if ((rc = SYSCTL_INT_SUBR(CTLFLAG_READWRITE, tpscale,
    511      1.1  dyoung 	    "tx power scaling")) != 0)
    512      1.1  dyoung 		goto err;
    513  1.3.2.1    yamt 	if (ath_hal_hastpc(sc->sc_ah)) {
    514      1.1  dyoung 		if ((rc = SYSCTL_INT_SUBR(CTLFLAG_READWRITE, tpc,
    515      1.1  dyoung 		    "enable/disable per-packet TPC")) != 0)
    516      1.1  dyoung 			goto err;
    517  1.3.2.1    yamt 		if ((rc = SYSCTL_INT_SUBR(CTLFLAG_READWRITE, tpack,
    518  1.3.2.1    yamt 		    "tx power for ack frames")) != 0)
    519  1.3.2.1    yamt 			goto err;
    520  1.3.2.1    yamt 		if ((rc = SYSCTL_INT_SUBR(CTLFLAG_READWRITE, tpcts,
    521  1.3.2.1    yamt 		    "tx power for cts frames")) != 0)
    522  1.3.2.1    yamt 			goto err;
    523      1.1  dyoung 	}
    524  1.3.2.1    yamt 	if (ath_hal_hasrfsilent(sc->sc_ah)) {
    525  1.3.2.1    yamt 		if ((rc = SYSCTL_INT_SUBR(CTLFLAG_READWRITE, rfsilent,
    526  1.3.2.1    yamt 		    "h/w RF silent config")) != 0)
    527  1.3.2.1    yamt 			goto err;
    528  1.3.2.1    yamt 		if ((rc = SYSCTL_INT_SUBR(CTLFLAG_READWRITE, rfkill,
    529  1.3.2.1    yamt 		    "enable/disable RF kill switch")) != 0)
    530  1.3.2.1    yamt 			goto err;
    531  1.3.2.1    yamt 	}
    532  1.3.2.1    yamt 	if ((rc = SYSCTL_INT_SUBR(CTLFLAG_READWRITE, regdomain,
    533  1.3.2.1    yamt 	    "EEPROM regdomain code")) != 0)
    534  1.3.2.1    yamt 		goto err;
    535      1.1  dyoung 	return;
    536      1.1  dyoung err:
    537      1.1  dyoung 	printf("%s: sysctl_createv failed, rc = %d\n", __func__, rc);
    538      1.1  dyoung }
    539