/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting4* All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer,11* without modification.12* 2. Redistributions in binary form must reproduce at minimum a disclaimer13* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any14* redistribution must be conditioned upon including a substantially15* similar Disclaimer requirement for further binary redistribution.16*17* NO WARRANTY18* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS19* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT20* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY21* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL22* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,23* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF24* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS25* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER26* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)27* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF28* THE POSSIBILITY OF SUCH DAMAGES.29*/3031#include <sys/cdefs.h>32/*33* Driver for the Atheros Wireless LAN controller.34*35* This software is derived from work of Atsushi Onoe; his contribution36* is greatly appreciated.37*/3839#include "opt_inet.h"40#include "opt_ath.h"41/*42* This is needed for register operations which are performed43* by the driver - eg, calls to ath_hal_gettsf32().44*/45#include "opt_ah.h"46#include "opt_wlan.h"4748#include <sys/param.h>49#include <sys/systm.h>50#include <sys/sysctl.h>51#include <sys/mbuf.h>52#include <sys/malloc.h>53#include <sys/lock.h>54#include <sys/mutex.h>55#include <sys/kernel.h>56#include <sys/socket.h>57#include <sys/sockio.h>58#include <sys/errno.h>59#include <sys/callout.h>60#include <sys/bus.h>61#include <sys/endian.h>62#include <sys/kthread.h>63#include <sys/taskqueue.h>64#include <sys/priv.h>65#include <sys/module.h>66#include <sys/ktr.h>67#include <sys/smp.h> /* for mp_ncpus */6869#include <machine/bus.h>7071#include <net/if.h>72#include <net/if_dl.h>73#include <net/if_media.h>74#include <net/if_types.h>75#include <net/if_arp.h>76#include <net/ethernet.h>77#include <net/if_llc.h>78#include <net/if_var.h>7980#include <net80211/ieee80211_var.h>81#include <net80211/ieee80211_regdomain.h>82#ifdef IEEE80211_SUPPORT_SUPERG83#include <net80211/ieee80211_superg.h>84#endif85#ifdef IEEE80211_SUPPORT_TDMA86#include <net80211/ieee80211_tdma.h>87#endif8889#include <net/bpf.h>9091#ifdef INET92#include <netinet/in.h>93#include <netinet/if_ether.h>94#endif9596#include <dev/ath/if_athvar.h>97#include <dev/ath/ath_hal/ah_devid.h> /* XXX for softled */98#include <dev/ath/ath_hal/ah_diagcodes.h>99100#include <dev/ath/if_ath_debug.h>101#include <dev/ath/if_ath_misc.h>102103#include <dev/ath/if_ath_led.h>104105/*106* Software LED driver routines.107*/108109/*110* XXX TODO: move the LED sysctls here.111*/112113/*114* Configure the hardware for software and LED blinking.115* The user may choose to configure part of each, depending upon the116* NIC being used.117*118* This requires the configuration to be set before this function119* is called.120*/121void122ath_led_config(struct ath_softc *sc)123{124125ATH_LOCK(sc);126ath_power_set_power_state(sc, HAL_PM_AWAKE);127ATH_UNLOCK(sc);128129/* Software LED blinking - GPIO controlled LED */130if (sc->sc_softled) {131ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_ledpin,132HAL_GPIO_OUTPUT_MUX_AS_OUTPUT);133ath_hal_gpioset(sc->sc_ah, sc->sc_ledpin, !sc->sc_ledon);134}135136/* Hardware LED blinking - MAC controlled LED */137if (sc->sc_hardled) {138/*139* Only enable each LED if required.140*141* Some NICs only have one LED connected; others may142* have GPIO1/GPIO2 connected to other hardware.143*/144if (sc->sc_led_pwr_pin > 0)145ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_led_pwr_pin,146HAL_GPIO_OUTPUT_MUX_MAC_POWER_LED);147if (sc->sc_led_net_pin > 0)148ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_led_net_pin,149HAL_GPIO_OUTPUT_MUX_MAC_NETWORK_LED);150}151152ATH_LOCK(sc);153ath_power_restore_power_state(sc);154ATH_UNLOCK(sc);155}156157static void158ath_led_done(void *arg)159{160struct ath_softc *sc = arg;161162sc->sc_blinking = 0;163}164165/*166* Turn the LED off: flip the pin and then set a timer so no167* update will happen for the specified duration.168*/169static void170ath_led_off(void *arg)171{172struct ath_softc *sc = arg;173174ath_hal_gpioset(sc->sc_ah, sc->sc_ledpin, !sc->sc_ledon);175callout_reset(&sc->sc_ledtimer, sc->sc_ledoff, ath_led_done, sc);176}177178/*179* Blink the LED according to the specified on/off times.180*/181static void182ath_led_blink(struct ath_softc *sc, int on, int off)183{184DPRINTF(sc, ATH_DEBUG_LED, "%s: on %u off %u\n", __func__, on, off);185ath_hal_gpioset(sc->sc_ah, sc->sc_ledpin, sc->sc_ledon);186sc->sc_blinking = 1;187sc->sc_ledoff = off;188callout_reset(&sc->sc_ledtimer, on, ath_led_off, sc);189}190191void192ath_led_event(struct ath_softc *sc, int rix)193{194sc->sc_ledevent = ticks; /* time of last event */195if (sc->sc_blinking) /* don't interrupt active blink */196return;197ath_led_blink(sc, sc->sc_hwmap[rix].ledon, sc->sc_hwmap[rix].ledoff);198}199200201