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