diff options
Diffstat (limited to 'sys/dev/ath/if_ath_led.c')
-rw-r--r-- | sys/dev/ath/if_ath_led.c | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/sys/dev/ath/if_ath_led.c b/sys/dev/ath/if_ath_led.c new file mode 100644 index 000000000000..f4bd5ac8063e --- /dev/null +++ b/sys/dev/ath/if_ath_led.c @@ -0,0 +1,199 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any + * redistribution must be conditioned upon including a substantially + * similar Disclaimer requirement for further binary redistribution. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGES. + */ + +#include <sys/cdefs.h> +/* + * Driver for the Atheros Wireless LAN controller. + * + * This software is derived from work of Atsushi Onoe; his contribution + * is greatly appreciated. + */ + +#include "opt_inet.h" +#include "opt_ath.h" +/* + * This is needed for register operations which are performed + * by the driver - eg, calls to ath_hal_gettsf32(). + */ +#include "opt_ah.h" +#include "opt_wlan.h" + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/sysctl.h> +#include <sys/mbuf.h> +#include <sys/malloc.h> +#include <sys/lock.h> +#include <sys/mutex.h> +#include <sys/kernel.h> +#include <sys/socket.h> +#include <sys/sockio.h> +#include <sys/errno.h> +#include <sys/callout.h> +#include <sys/bus.h> +#include <sys/endian.h> +#include <sys/kthread.h> +#include <sys/taskqueue.h> +#include <sys/priv.h> +#include <sys/module.h> +#include <sys/ktr.h> +#include <sys/smp.h> /* for mp_ncpus */ + +#include <machine/bus.h> + +#include <net/if.h> +#include <net/if_dl.h> +#include <net/if_media.h> +#include <net/if_types.h> +#include <net/if_arp.h> +#include <net/ethernet.h> +#include <net/if_llc.h> +#include <net/if_var.h> + +#include <net80211/ieee80211_var.h> +#include <net80211/ieee80211_regdomain.h> +#ifdef IEEE80211_SUPPORT_SUPERG +#include <net80211/ieee80211_superg.h> +#endif +#ifdef IEEE80211_SUPPORT_TDMA +#include <net80211/ieee80211_tdma.h> +#endif + +#include <net/bpf.h> + +#ifdef INET +#include <netinet/in.h> +#include <netinet/if_ether.h> +#endif + +#include <dev/ath/if_athvar.h> +#include <dev/ath/ath_hal/ah_devid.h> /* XXX for softled */ +#include <dev/ath/ath_hal/ah_diagcodes.h> + +#include <dev/ath/if_ath_debug.h> +#include <dev/ath/if_ath_misc.h> + +#include <dev/ath/if_ath_led.h> + +/* + * Software LED driver routines. + */ + +/* + * XXX TODO: move the LED sysctls here. + */ + +/* + * Configure the hardware for software and LED blinking. + * The user may choose to configure part of each, depending upon the + * NIC being used. + * + * This requires the configuration to be set before this function + * is called. + */ +void +ath_led_config(struct ath_softc *sc) +{ + + ATH_LOCK(sc); + ath_power_set_power_state(sc, HAL_PM_AWAKE); + ATH_UNLOCK(sc); + + /* Software LED blinking - GPIO controlled LED */ + if (sc->sc_softled) { + ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_ledpin, + HAL_GPIO_OUTPUT_MUX_AS_OUTPUT); + ath_hal_gpioset(sc->sc_ah, sc->sc_ledpin, !sc->sc_ledon); + } + + /* Hardware LED blinking - MAC controlled LED */ + if (sc->sc_hardled) { + /* + * Only enable each LED if required. + * + * Some NICs only have one LED connected; others may + * have GPIO1/GPIO2 connected to other hardware. + */ + if (sc->sc_led_pwr_pin > 0) + ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_led_pwr_pin, + HAL_GPIO_OUTPUT_MUX_MAC_POWER_LED); + if (sc->sc_led_net_pin > 0) + ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_led_net_pin, + HAL_GPIO_OUTPUT_MUX_MAC_NETWORK_LED); + } + + ATH_LOCK(sc); + ath_power_restore_power_state(sc); + ATH_UNLOCK(sc); +} + +static void +ath_led_done(void *arg) +{ + struct ath_softc *sc = arg; + + sc->sc_blinking = 0; +} + +/* + * Turn the LED off: flip the pin and then set a timer so no + * update will happen for the specified duration. + */ +static void +ath_led_off(void *arg) +{ + struct ath_softc *sc = arg; + + ath_hal_gpioset(sc->sc_ah, sc->sc_ledpin, !sc->sc_ledon); + callout_reset(&sc->sc_ledtimer, sc->sc_ledoff, ath_led_done, sc); +} + +/* + * Blink the LED according to the specified on/off times. + */ +static void +ath_led_blink(struct ath_softc *sc, int on, int off) +{ + DPRINTF(sc, ATH_DEBUG_LED, "%s: on %u off %u\n", __func__, on, off); + ath_hal_gpioset(sc->sc_ah, sc->sc_ledpin, sc->sc_ledon); + sc->sc_blinking = 1; + sc->sc_ledoff = off; + callout_reset(&sc->sc_ledtimer, on, ath_led_off, sc); +} + +void +ath_led_event(struct ath_softc *sc, int rix) +{ + sc->sc_ledevent = ticks; /* time of last event */ + if (sc->sc_blinking) /* don't interrupt active blink */ + return; + ath_led_blink(sc, sc->sc_hwmap[rix].ledon, sc->sc_hwmap[rix].ledoff); +} |