if_ath_led.c revision 237611
1133359Sobrien/*- 2133359Sobrien * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 3133359Sobrien * All rights reserved. 4186690Sobrien * 5133359Sobrien * Redistribution and use in source and binary forms, with or without 6133359Sobrien * modification, are permitted provided that the following conditions 7133359Sobrien * are met: 8133359Sobrien * 1. Redistributions of source code must retain the above copyright 9133359Sobrien * notice, this list of conditions and the following disclaimer, 10133359Sobrien * without modification. 11133359Sobrien * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12133359Sobrien * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13133359Sobrien * redistribution must be conditioned upon including a substantially 14186690Sobrien * similar Disclaimer requirement for further binary redistribution. 15133359Sobrien * 16133359Sobrien * NO WARRANTY 17133359Sobrien * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18133359Sobrien * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19133359Sobrien * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20133359Sobrien * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21133359Sobrien * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22133359Sobrien * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23133359Sobrien * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24133359Sobrien * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25133359Sobrien * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26133359Sobrien * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27133359Sobrien * THE POSSIBILITY OF SUCH DAMAGES. 28226048Sobrien */ 29226048Sobrien 30226048Sobrien#include <sys/cdefs.h> 31226048Sobrien__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath_led.c 237611 2012-06-26 22:16:53Z adrian $"); 32226048Sobrien 33133359Sobrien/* 34191736Sobrien * Driver for the Atheros Wireless LAN controller. 35191736Sobrien * 36276415Sdelphij * This software is derived from work of Atsushi Onoe; his contribution 37191736Sobrien * is greatly appreciated. 38191736Sobrien */ 39133359Sobrien 40133359Sobrien#include "opt_inet.h" 41133359Sobrien#include "opt_ath.h" 42133359Sobrien/* 43133359Sobrien * This is needed for register operations which are performed 44133359Sobrien * by the driver - eg, calls to ath_hal_gettsf32(). 45133359Sobrien */ 46133359Sobrien#include "opt_ah.h" 47186690Sobrien#include "opt_wlan.h" 48169942Sobrien 49186690Sobrien#include <sys/param.h> 50133359Sobrien#include <sys/systm.h> 51133359Sobrien#include <sys/sysctl.h> 52133359Sobrien#include <sys/mbuf.h> 53133359Sobrien#include <sys/malloc.h> 54133359Sobrien#include <sys/lock.h> 55133359Sobrien#include <sys/mutex.h> 56133359Sobrien#include <sys/kernel.h> 57133359Sobrien#include <sys/socket.h> 58133359Sobrien#include <sys/sockio.h> 59133359Sobrien#include <sys/errno.h> 60133359Sobrien#include <sys/callout.h> 61133359Sobrien#include <sys/bus.h> 62133359Sobrien#include <sys/endian.h> 63133359Sobrien#include <sys/kthread.h> 64133359Sobrien#include <sys/taskqueue.h> 65186690Sobrien#include <sys/priv.h> 66186690Sobrien#include <sys/module.h> 67186690Sobrien#include <sys/ktr.h> 68186690Sobrien#include <sys/smp.h> /* for mp_ncpus */ 69186690Sobrien 70186690Sobrien#include <machine/bus.h> 71186690Sobrien 72186690Sobrien#include <net/if.h> 73186690Sobrien#include <net/if_dl.h> 74133359Sobrien#include <net/if_media.h> 75133359Sobrien#include <net/if_types.h> 76186690Sobrien#include <net/if_arp.h> 77226048Sobrien#include <net/ethernet.h> 78175296Sobrien#include <net/if_llc.h> 79175296Sobrien 80175296Sobrien#include <net80211/ieee80211_var.h> 81133359Sobrien#include <net80211/ieee80211_regdomain.h> 82159764Sobrien#ifdef IEEE80211_SUPPORT_SUPERG 83159764Sobrien#include <net80211/ieee80211_superg.h> 84159764Sobrien#endif 85159764Sobrien#ifdef IEEE80211_SUPPORT_TDMA 86226048Sobrien#include <net80211/ieee80211_tdma.h> 87226048Sobrien#endif 88226048Sobrien 89226048Sobrien#include <net/bpf.h> 90226048Sobrien 91226048Sobrien#ifdef INET 92226048Sobrien#include <netinet/in.h> 93226048Sobrien#include <netinet/if_ether.h> 94226048Sobrien#endif 95226048Sobrien 96226048Sobrien#include <dev/ath/if_athvar.h> 97226048Sobrien#include <dev/ath/ath_hal/ah_devid.h> /* XXX for softled */ 98226048Sobrien#include <dev/ath/ath_hal/ah_diagcodes.h> 99226048Sobrien 100226048Sobrien#include <dev/ath/if_ath_debug.h> 101226048Sobrien#include <dev/ath/if_ath_misc.h> 102226048Sobrien 103267843Sdelphij#include <dev/ath/if_ath_led.h> 104226048Sobrien 105267843Sdelphij/* 106226048Sobrien * Software LED driver routines. 107267843Sdelphij */ 108226048Sobrien 109267843Sdelphij/* 110226048Sobrien * XXX TODO: move the LED sysctls here. 111267843Sdelphij */ 112267843Sdelphij 113267843Sdelphij 114267843Sdelphij/* 115267843Sdelphij * Configure the hardware for software and LED blinking. 116267843Sdelphij * The user may choose to configure part of each, depending upon the 117267843Sdelphij * NIC being used. 118226048Sobrien * 119226048Sobrien * This requires the configuration to be set before this function 120226048Sobrien * is called. 121226048Sobrien */ 122226048Sobrienvoid 123226048Sobrienath_led_config(struct ath_softc *sc) 124226048Sobrien{ 125226048Sobrien /* Software LED blinking - GPIO controlled LED */ 126226048Sobrien if (sc->sc_softled) { 127226048Sobrien ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_ledpin, 128226048Sobrien HAL_GPIO_OUTPUT_MUX_AS_OUTPUT); 129267843Sdelphij ath_hal_gpioset(sc->sc_ah, sc->sc_ledpin, !sc->sc_ledon); 130226048Sobrien } 131276415Sdelphij 132267843Sdelphij /* Hardware LED blinking - MAC controlled LED */ 133226048Sobrien if (sc->sc_hardled) { 134226048Sobrien /* 135226048Sobrien * Only enable each LED if required. 136226048Sobrien * 137226048Sobrien * Some NICs only have one LED connected; others may 138226048Sobrien * have GPIO1/GPIO2 connected to other hardware. 139226048Sobrien */ 140226048Sobrien if (sc->sc_led_pwr_pin > 0) 141226048Sobrien ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_led_pwr_pin, 142226048Sobrien HAL_GPIO_OUTPUT_MUX_MAC_POWER_LED); 143226048Sobrien if (sc->sc_led_net_pin > 0) 144226048Sobrien ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_led_net_pin, 145226048Sobrien HAL_GPIO_OUTPUT_MUX_MAC_NETWORK_LED); 146226048Sobrien } 147226048Sobrien} 148226048Sobrien 149226048Sobrienstatic void 150226048Sobrienath_led_done(void *arg) 151226048Sobrien{ 152226048Sobrien struct ath_softc *sc = arg; 153226048Sobrien 154226048Sobrien sc->sc_blinking = 0; 155226048Sobrien} 156226048Sobrien 157226048Sobrien/* 158226048Sobrien * Turn the LED off: flip the pin and then set a timer so no 159226048Sobrien * update will happen for the specified duration. 160226048Sobrien */ 161226048Sobrienstatic void 162226048Sobrienath_led_off(void *arg) 163226048Sobrien{ 164226048Sobrien struct ath_softc *sc = arg; 165226048Sobrien 166226048Sobrien ath_hal_gpioset(sc->sc_ah, sc->sc_ledpin, !sc->sc_ledon); 167226048Sobrien callout_reset(&sc->sc_ledtimer, sc->sc_ledoff, ath_led_done, sc); 168226048Sobrien} 169226048Sobrien 170226048Sobrien/* 171226048Sobrien * Blink the LED according to the specified on/off times. 172226048Sobrien */ 173226048Sobrienstatic void 174226048Sobrienath_led_blink(struct ath_softc *sc, int on, int off) 175226048Sobrien{ 176226048Sobrien DPRINTF(sc, ATH_DEBUG_LED, "%s: on %u off %u\n", __func__, on, off); 177276415Sdelphij ath_hal_gpioset(sc->sc_ah, sc->sc_ledpin, sc->sc_ledon); 178226048Sobrien sc->sc_blinking = 1; 179226048Sobrien sc->sc_ledoff = off; 180226048Sobrien callout_reset(&sc->sc_ledtimer, on, ath_led_off, sc); 181226048Sobrien} 182226048Sobrien 183226048Sobrienvoid 184226048Sobrienath_led_event(struct ath_softc *sc, int rix) 185226048Sobrien{ 186226048Sobrien sc->sc_ledevent = ticks; /* time of last event */ 187226048Sobrien if (sc->sc_blinking) /* don't interrupt active blink */ 188226048Sobrien return; 189226048Sobrien ath_led_blink(sc, sc->sc_hwmap[rix].ledon, sc->sc_hwmap[rix].ledoff); 190226048Sobrien} 191226048Sobrien