xref: /freebsd/sys/dev/ath/if_ath_led.c (revision 685dc743)
1c65ee21dSAdrian Chadd /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3718cf2ccSPedro F. Giffuni  *
4c65ee21dSAdrian Chadd  * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
5c65ee21dSAdrian Chadd  * All rights reserved.
6c65ee21dSAdrian Chadd  *
7c65ee21dSAdrian Chadd  * Redistribution and use in source and binary forms, with or without
8c65ee21dSAdrian Chadd  * modification, are permitted provided that the following conditions
9c65ee21dSAdrian Chadd  * are met:
10c65ee21dSAdrian Chadd  * 1. Redistributions of source code must retain the above copyright
11c65ee21dSAdrian Chadd  *    notice, this list of conditions and the following disclaimer,
12c65ee21dSAdrian Chadd  *    without modification.
13c65ee21dSAdrian Chadd  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
14c65ee21dSAdrian Chadd  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
15c65ee21dSAdrian Chadd  *    redistribution must be conditioned upon including a substantially
16c65ee21dSAdrian Chadd  *    similar Disclaimer requirement for further binary redistribution.
17c65ee21dSAdrian Chadd  *
18c65ee21dSAdrian Chadd  * NO WARRANTY
19c65ee21dSAdrian Chadd  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20c65ee21dSAdrian Chadd  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21c65ee21dSAdrian Chadd  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
22c65ee21dSAdrian Chadd  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23c65ee21dSAdrian Chadd  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
24c65ee21dSAdrian Chadd  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25c65ee21dSAdrian Chadd  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26c65ee21dSAdrian Chadd  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
27c65ee21dSAdrian Chadd  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28c65ee21dSAdrian Chadd  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
29c65ee21dSAdrian Chadd  * THE POSSIBILITY OF SUCH DAMAGES.
30c65ee21dSAdrian Chadd  */
31c65ee21dSAdrian Chadd 
32c65ee21dSAdrian Chadd #include <sys/cdefs.h>
33c65ee21dSAdrian Chadd /*
34c65ee21dSAdrian Chadd  * Driver for the Atheros Wireless LAN controller.
35c65ee21dSAdrian Chadd  *
36c65ee21dSAdrian Chadd  * This software is derived from work of Atsushi Onoe; his contribution
37c65ee21dSAdrian Chadd  * is greatly appreciated.
38c65ee21dSAdrian Chadd  */
39c65ee21dSAdrian Chadd 
40c65ee21dSAdrian Chadd #include "opt_inet.h"
41c65ee21dSAdrian Chadd #include "opt_ath.h"
42c65ee21dSAdrian Chadd /*
43c65ee21dSAdrian Chadd  * This is needed for register operations which are performed
44c65ee21dSAdrian Chadd  * by the driver - eg, calls to ath_hal_gettsf32().
45c65ee21dSAdrian Chadd  */
46c65ee21dSAdrian Chadd #include "opt_ah.h"
47c65ee21dSAdrian Chadd #include "opt_wlan.h"
48c65ee21dSAdrian Chadd 
49c65ee21dSAdrian Chadd #include <sys/param.h>
50c65ee21dSAdrian Chadd #include <sys/systm.h>
51c65ee21dSAdrian Chadd #include <sys/sysctl.h>
52c65ee21dSAdrian Chadd #include <sys/mbuf.h>
53c65ee21dSAdrian Chadd #include <sys/malloc.h>
54c65ee21dSAdrian Chadd #include <sys/lock.h>
55c65ee21dSAdrian Chadd #include <sys/mutex.h>
56c65ee21dSAdrian Chadd #include <sys/kernel.h>
57c65ee21dSAdrian Chadd #include <sys/socket.h>
58c65ee21dSAdrian Chadd #include <sys/sockio.h>
59c65ee21dSAdrian Chadd #include <sys/errno.h>
60c65ee21dSAdrian Chadd #include <sys/callout.h>
61c65ee21dSAdrian Chadd #include <sys/bus.h>
62c65ee21dSAdrian Chadd #include <sys/endian.h>
63c65ee21dSAdrian Chadd #include <sys/kthread.h>
64c65ee21dSAdrian Chadd #include <sys/taskqueue.h>
65c65ee21dSAdrian Chadd #include <sys/priv.h>
66c65ee21dSAdrian Chadd #include <sys/module.h>
67c65ee21dSAdrian Chadd #include <sys/ktr.h>
68c65ee21dSAdrian Chadd #include <sys/smp.h>	/* for mp_ncpus */
69c65ee21dSAdrian Chadd 
70c65ee21dSAdrian Chadd #include <machine/bus.h>
71c65ee21dSAdrian Chadd 
72c65ee21dSAdrian Chadd #include <net/if.h>
73c65ee21dSAdrian Chadd #include <net/if_dl.h>
74c65ee21dSAdrian Chadd #include <net/if_media.h>
75c65ee21dSAdrian Chadd #include <net/if_types.h>
76c65ee21dSAdrian Chadd #include <net/if_arp.h>
77c65ee21dSAdrian Chadd #include <net/ethernet.h>
78c65ee21dSAdrian Chadd #include <net/if_llc.h>
79ec22a3a2SJustin Hibbits #include <net/if_var.h>
80c65ee21dSAdrian Chadd 
81c65ee21dSAdrian Chadd #include <net80211/ieee80211_var.h>
82c65ee21dSAdrian Chadd #include <net80211/ieee80211_regdomain.h>
83c65ee21dSAdrian Chadd #ifdef IEEE80211_SUPPORT_SUPERG
84c65ee21dSAdrian Chadd #include <net80211/ieee80211_superg.h>
85c65ee21dSAdrian Chadd #endif
86c65ee21dSAdrian Chadd #ifdef IEEE80211_SUPPORT_TDMA
87c65ee21dSAdrian Chadd #include <net80211/ieee80211_tdma.h>
88c65ee21dSAdrian Chadd #endif
89c65ee21dSAdrian Chadd 
90c65ee21dSAdrian Chadd #include <net/bpf.h>
91c65ee21dSAdrian Chadd 
92c65ee21dSAdrian Chadd #ifdef INET
93c65ee21dSAdrian Chadd #include <netinet/in.h>
94c65ee21dSAdrian Chadd #include <netinet/if_ether.h>
95c65ee21dSAdrian Chadd #endif
96c65ee21dSAdrian Chadd 
97c65ee21dSAdrian Chadd #include <dev/ath/if_athvar.h>
98c65ee21dSAdrian Chadd #include <dev/ath/ath_hal/ah_devid.h>		/* XXX for softled */
99c65ee21dSAdrian Chadd #include <dev/ath/ath_hal/ah_diagcodes.h>
100c65ee21dSAdrian Chadd 
101c65ee21dSAdrian Chadd #include <dev/ath/if_ath_debug.h>
102c65ee21dSAdrian Chadd #include <dev/ath/if_ath_misc.h>
103c65ee21dSAdrian Chadd 
104c65ee21dSAdrian Chadd #include <dev/ath/if_ath_led.h>
105c65ee21dSAdrian Chadd 
106c65ee21dSAdrian Chadd /*
107c65ee21dSAdrian Chadd  * Software LED driver routines.
108c65ee21dSAdrian Chadd  */
109c65ee21dSAdrian Chadd 
110c65ee21dSAdrian Chadd /*
111c65ee21dSAdrian Chadd  * XXX TODO: move the LED sysctls here.
112c65ee21dSAdrian Chadd  */
113c65ee21dSAdrian Chadd 
1146558ffd9SAdrian Chadd /*
1153440495aSAdrian Chadd  * Configure the hardware for software and LED blinking.
1163440495aSAdrian Chadd  * The user may choose to configure part of each, depending upon the
1173440495aSAdrian Chadd  * NIC being used.
1186558ffd9SAdrian Chadd  *
1193440495aSAdrian Chadd  * This requires the configuration to be set before this function
1203440495aSAdrian Chadd  * is called.
1216558ffd9SAdrian Chadd  */
1226558ffd9SAdrian Chadd void
ath_led_config(struct ath_softc * sc)1236558ffd9SAdrian Chadd ath_led_config(struct ath_softc *sc)
1246558ffd9SAdrian Chadd {
125f5c30c4eSAdrian Chadd 
126f5c30c4eSAdrian Chadd 	ATH_LOCK(sc);
127f5c30c4eSAdrian Chadd 	ath_power_set_power_state(sc, HAL_PM_AWAKE);
128f5c30c4eSAdrian Chadd 	ATH_UNLOCK(sc);
129f5c30c4eSAdrian Chadd 
1306558ffd9SAdrian Chadd 	/* Software LED blinking - GPIO controlled LED */
1316558ffd9SAdrian Chadd 	if (sc->sc_softled) {
1326558ffd9SAdrian Chadd 		ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_ledpin,
1336479ef78SAdrian Chadd 		    HAL_GPIO_OUTPUT_MUX_AS_OUTPUT);
1346558ffd9SAdrian Chadd 		ath_hal_gpioset(sc->sc_ah, sc->sc_ledpin, !sc->sc_ledon);
1356558ffd9SAdrian Chadd 	}
1366558ffd9SAdrian Chadd 
1376558ffd9SAdrian Chadd 	/* Hardware LED blinking - MAC controlled LED */
1383440495aSAdrian Chadd 	if (sc->sc_hardled) {
1393440495aSAdrian Chadd 		/*
1403440495aSAdrian Chadd 		 * Only enable each LED if required.
1413440495aSAdrian Chadd 		 *
1423440495aSAdrian Chadd 		 * Some NICs only have one LED connected; others may
1433440495aSAdrian Chadd 		 * have GPIO1/GPIO2 connected to other hardware.
1443440495aSAdrian Chadd 		 */
1453440495aSAdrian Chadd 		if (sc->sc_led_pwr_pin > 0)
1463440495aSAdrian Chadd 			ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_led_pwr_pin,
1476479ef78SAdrian Chadd 			    HAL_GPIO_OUTPUT_MUX_MAC_POWER_LED);
1483440495aSAdrian Chadd 		if (sc->sc_led_net_pin > 0)
1493440495aSAdrian Chadd 			ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_led_net_pin,
1506479ef78SAdrian Chadd 			    HAL_GPIO_OUTPUT_MUX_MAC_NETWORK_LED);
1513440495aSAdrian Chadd 	}
152f5c30c4eSAdrian Chadd 
153f5c30c4eSAdrian Chadd 	ATH_LOCK(sc);
154f5c30c4eSAdrian Chadd 	ath_power_restore_power_state(sc);
155f5c30c4eSAdrian Chadd 	ATH_UNLOCK(sc);
1566558ffd9SAdrian Chadd }
1576558ffd9SAdrian Chadd 
158c65ee21dSAdrian Chadd static void
ath_led_done(void * arg)159c65ee21dSAdrian Chadd ath_led_done(void *arg)
160c65ee21dSAdrian Chadd {
161c65ee21dSAdrian Chadd 	struct ath_softc *sc = arg;
162c65ee21dSAdrian Chadd 
163c65ee21dSAdrian Chadd 	sc->sc_blinking = 0;
164c65ee21dSAdrian Chadd }
165c65ee21dSAdrian Chadd 
166c65ee21dSAdrian Chadd /*
167c65ee21dSAdrian Chadd  * Turn the LED off: flip the pin and then set a timer so no
168c65ee21dSAdrian Chadd  * update will happen for the specified duration.
169c65ee21dSAdrian Chadd  */
170c65ee21dSAdrian Chadd static void
ath_led_off(void * arg)171c65ee21dSAdrian Chadd ath_led_off(void *arg)
172c65ee21dSAdrian Chadd {
173c65ee21dSAdrian Chadd 	struct ath_softc *sc = arg;
174c65ee21dSAdrian Chadd 
175c65ee21dSAdrian Chadd 	ath_hal_gpioset(sc->sc_ah, sc->sc_ledpin, !sc->sc_ledon);
176c65ee21dSAdrian Chadd 	callout_reset(&sc->sc_ledtimer, sc->sc_ledoff, ath_led_done, sc);
177c65ee21dSAdrian Chadd }
178c65ee21dSAdrian Chadd 
179c65ee21dSAdrian Chadd /*
180c65ee21dSAdrian Chadd  * Blink the LED according to the specified on/off times.
181c65ee21dSAdrian Chadd  */
182c65ee21dSAdrian Chadd static void
ath_led_blink(struct ath_softc * sc,int on,int off)183c65ee21dSAdrian Chadd ath_led_blink(struct ath_softc *sc, int on, int off)
184c65ee21dSAdrian Chadd {
185c65ee21dSAdrian Chadd 	DPRINTF(sc, ATH_DEBUG_LED, "%s: on %u off %u\n", __func__, on, off);
186c65ee21dSAdrian Chadd 	ath_hal_gpioset(sc->sc_ah, sc->sc_ledpin, sc->sc_ledon);
187c65ee21dSAdrian Chadd 	sc->sc_blinking = 1;
188c65ee21dSAdrian Chadd 	sc->sc_ledoff = off;
189c65ee21dSAdrian Chadd 	callout_reset(&sc->sc_ledtimer, on, ath_led_off, sc);
190c65ee21dSAdrian Chadd }
191c65ee21dSAdrian Chadd 
192c65ee21dSAdrian Chadd void
ath_led_event(struct ath_softc * sc,int rix)193c65ee21dSAdrian Chadd ath_led_event(struct ath_softc *sc, int rix)
194c65ee21dSAdrian Chadd {
195c65ee21dSAdrian Chadd 	sc->sc_ledevent = ticks;	/* time of last event */
196c65ee21dSAdrian Chadd 	if (sc->sc_blinking)		/* don't interrupt active blink */
197c65ee21dSAdrian Chadd 		return;
198c65ee21dSAdrian Chadd 	ath_led_blink(sc, sc->sc_hwmap[rix].ledon, sc->sc_hwmap[rix].ledoff);
199c65ee21dSAdrian Chadd }
200