Add some sysctl to retrieve the radio state (and the debug level).

While here, fixe the return value in case where radio is off (suggested by
joerg@).
This commit is contained in:
degroote 2008-01-09 20:15:40 +00:00
parent 0d31ffa76d
commit 94aebeb732
2 changed files with 88 additions and 9 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_wpi.c,v 1.33 2007/12/09 20:28:10 jmcneill Exp $ */
/* $NetBSD: if_wpi.c,v 1.34 2008/01/09 20:15:40 degroote Exp $ */
/*-
* Copyright (c) 2006, 2007
@ -18,7 +18,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_wpi.c,v 1.33 2007/12/09 20:28:10 jmcneill Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_wpi.c,v 1.34 2008/01/09 20:15:40 degroote Exp $");
/*
* Driver for Intel PRO/Wireless 3945ABG 802.11 network adapters.
@ -164,6 +164,8 @@ static void wpi_hw_config(struct wpi_softc *);
static int wpi_init(struct ifnet *);
static void wpi_stop(struct ifnet *, int);
static bool wpi_resume(device_t);
static int wpi_getrfkill(struct wpi_softc *);
static void wpi_sysctlattach(struct wpi_softc *);
CFATTACH_DECL_NEW(wpi, sizeof (struct wpi_softc), wpi_match, wpi_attach,
wpi_detach, NULL);
@ -340,6 +342,8 @@ wpi_attach(device_t parent __unused, device_t self, void *aux)
sc->amrr.amrr_min_success_threshold = 1;
sc->amrr.amrr_max_success_threshold = 15;
wpi_sysctlattach(sc);
if (!pmf_device_register(self, NULL, wpi_resume))
aprint_error_dev(self, "couldn't establish power handler\n");
else
@ -3037,13 +3041,9 @@ wpi_init(struct ifnet *ifp)
}
/* Check the status of the radio switch */
wpi_mem_lock(sc);
tmp = wpi_mem_read(sc, WPI_MEM_RFKILL);
wpi_mem_unlock(sc);
if (!(tmp & 0x01)) {
if (wpi_getrfkill(sc)) {
aprint_error_dev(sc->sc_dev, "Radio is disabled by hardware switch\n");
error = EPERM; // XXX
error = EBUSY;
goto fail1;
}
@ -3137,3 +3137,80 @@ wpi_resume(device_t dv)
return true;
}
/*
* Return whether or not the radio is enabled in hardware
* (i.e. the rfkill switch is "off").
*/
static int
wpi_getrfkill(struct wpi_softc *sc)
{
uint32_t tmp;
wpi_mem_lock(sc);
tmp = wpi_mem_read(sc, WPI_MEM_RFKILL);
wpi_mem_unlock(sc);
return !(tmp & 0x01);
}
static int
wpi_sysctl_radio(SYSCTLFN_ARGS)
{
struct sysctlnode node;
struct wpi_softc *sc;
int val, error;
node = *rnode;
sc = (struct wpi_softc *)node.sysctl_data;
val = !wpi_getrfkill(sc);
node.sysctl_data = &val;
error = sysctl_lookup(SYSCTLFN_CALL(&node));
if (error || newp == NULL)
return error;
return 0;
}
static void
wpi_sysctlattach(struct wpi_softc *sc)
{
int rc;
const struct sysctlnode *rnode;
const struct sysctlnode *cnode;
struct sysctllog **clog = &sc->sc_sysctllog;
if ((rc = sysctl_createv(clog, 0, NULL, &rnode,
CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL,
NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0)
goto err;
if ((rc = sysctl_createv(clog, 0, &rnode, &rnode,
CTLFLAG_PERMANENT, CTLTYPE_NODE, device_xname(sc->sc_dev),
SYSCTL_DESCR("wpi controls and statistics"),
NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
goto err;
if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
CTLFLAG_PERMANENT, CTLTYPE_INT, "radio",
SYSCTL_DESCR("radio transmitter switch state (0=off, 1=on)"),
wpi_sysctl_radio, 0, sc, 0, CTL_CREATE, CTL_EOL)) != 0)
goto err;
#ifdef WPI_DEBUG
/* control debugging printfs */
if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
"debug", SYSCTL_DESCR("Enable debugging output"),
NULL, 0, &wpi_debug, 0, CTL_CREATE, CTL_EOL)) != 0)
goto err;
#endif
return;
err:
aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_wpivar.h,v 1.10 2007/12/09 20:28:11 jmcneill Exp $ */
/* $NetBSD: if_wpivar.h,v 1.11 2008/01/09 20:15:40 degroote Exp $ */
/*-
* Copyright (c) 2006
@ -186,4 +186,6 @@ struct wpi_softc {
#endif
bool is_scanning;
struct sysctllog *sc_sysctllog;
};