xref: /freebsd/sys/dev/ath/if_ath_led.c (revision ec22a3a259193685afaea1667a39266264c65fd3)
1c65ee21dSAdrian Chadd /*-
2718cf2ccSPedro F. Giffuni  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
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 __FBSDID("$FreeBSD$");
34c65ee21dSAdrian Chadd 
35c65ee21dSAdrian Chadd /*
36c65ee21dSAdrian Chadd  * Driver for the Atheros Wireless LAN controller.
37c65ee21dSAdrian Chadd  *
38c65ee21dSAdrian Chadd  * This software is derived from work of Atsushi Onoe; his contribution
39c65ee21dSAdrian Chadd  * is greatly appreciated.
40c65ee21dSAdrian Chadd  */
41c65ee21dSAdrian Chadd 
42c65ee21dSAdrian Chadd #include "opt_inet.h"
43c65ee21dSAdrian Chadd #include "opt_ath.h"
44c65ee21dSAdrian Chadd /*
45c65ee21dSAdrian Chadd  * This is needed for register operations which are performed
46c65ee21dSAdrian Chadd  * by the driver - eg, calls to ath_hal_gettsf32().
47c65ee21dSAdrian Chadd  */
48c65ee21dSAdrian Chadd #include "opt_ah.h"
49c65ee21dSAdrian Chadd #include "opt_wlan.h"
50c65ee21dSAdrian Chadd 
51c65ee21dSAdrian Chadd #include <sys/param.h>
52c65ee21dSAdrian Chadd #include <sys/systm.h>
53c65ee21dSAdrian Chadd #include <sys/sysctl.h>
54c65ee21dSAdrian Chadd #include <sys/mbuf.h>
55c65ee21dSAdrian Chadd #include <sys/malloc.h>
56c65ee21dSAdrian Chadd #include <sys/lock.h>
57c65ee21dSAdrian Chadd #include <sys/mutex.h>
58c65ee21dSAdrian Chadd #include <sys/kernel.h>
59c65ee21dSAdrian Chadd #include <sys/socket.h>
60c65ee21dSAdrian Chadd #include <sys/sockio.h>
61c65ee21dSAdrian Chadd #include <sys/errno.h>
62c65ee21dSAdrian Chadd #include <sys/callout.h>
63c65ee21dSAdrian Chadd #include <sys/bus.h>
64c65ee21dSAdrian Chadd #include <sys/endian.h>
65c65ee21dSAdrian Chadd #include <sys/kthread.h>
66c65ee21dSAdrian Chadd #include <sys/taskqueue.h>
67c65ee21dSAdrian Chadd #include <sys/priv.h>
68c65ee21dSAdrian Chadd #include <sys/module.h>
69c65ee21dSAdrian Chadd #include <sys/ktr.h>
70c65ee21dSAdrian Chadd #include <sys/smp.h>	/* for mp_ncpus */
71c65ee21dSAdrian Chadd 
72c65ee21dSAdrian Chadd #include <machine/bus.h>
73c65ee21dSAdrian Chadd 
74c65ee21dSAdrian Chadd #include <net/if.h>
75c65ee21dSAdrian Chadd #include <net/if_dl.h>
76c65ee21dSAdrian Chadd #include <net/if_media.h>
77c65ee21dSAdrian Chadd #include <net/if_types.h>
78c65ee21dSAdrian Chadd #include <net/if_arp.h>
79c65ee21dSAdrian Chadd #include <net/ethernet.h>
80c65ee21dSAdrian Chadd #include <net/if_llc.h>
81*ec22a3a2SJustin Hibbits #include <net/if_var.h>
82c65ee21dSAdrian Chadd 
83c65ee21dSAdrian Chadd #include <net80211/ieee80211_var.h>
84c65ee21dSAdrian Chadd #include <net80211/ieee80211_regdomain.h>
85c65ee21dSAdrian Chadd #ifdef IEEE80211_SUPPORT_SUPERG
86c65ee21dSAdrian Chadd #include <net80211/ieee80211_superg.h>
87c65ee21dSAdrian Chadd #endif
88c65ee21dSAdrian Chadd #ifdef IEEE80211_SUPPORT_TDMA
89c65ee21dSAdrian Chadd #include <net80211/ieee80211_tdma.h>
90c65ee21dSAdrian Chadd #endif
91c65ee21dSAdrian Chadd 
92c65ee21dSAdrian Chadd #include <net/bpf.h>
93c65ee21dSAdrian Chadd 
94c65ee21dSAdrian Chadd #ifdef INET
95c65ee21dSAdrian Chadd #include <netinet/in.h>
96c65ee21dSAdrian Chadd #include <netinet/if_ether.h>
97c65ee21dSAdrian Chadd #endif
98c65ee21dSAdrian Chadd 
99c65ee21dSAdrian Chadd #include <dev/ath/if_athvar.h>
100c65ee21dSAdrian Chadd #include <dev/ath/ath_hal/ah_devid.h>		/* XXX for softled */
101c65ee21dSAdrian Chadd #include <dev/ath/ath_hal/ah_diagcodes.h>
102c65ee21dSAdrian Chadd 
103c65ee21dSAdrian Chadd #include <dev/ath/if_ath_debug.h>
104c65ee21dSAdrian Chadd #include <dev/ath/if_ath_misc.h>
105c65ee21dSAdrian Chadd 
106c65ee21dSAdrian Chadd #include <dev/ath/if_ath_led.h>
107c65ee21dSAdrian Chadd 
108c65ee21dSAdrian Chadd /*
109c65ee21dSAdrian Chadd  * Software LED driver routines.
110c65ee21dSAdrian Chadd  */
111c65ee21dSAdrian Chadd 
112c65ee21dSAdrian Chadd /*
113c65ee21dSAdrian Chadd  * XXX TODO: move the LED sysctls here.
114c65ee21dSAdrian Chadd  */
115c65ee21dSAdrian Chadd 
1166558ffd9SAdrian Chadd /*
1173440495aSAdrian Chadd  * Configure the hardware for software and LED blinking.
1183440495aSAdrian Chadd  * The user may choose to configure part of each, depending upon the
1193440495aSAdrian Chadd  * NIC being used.
1206558ffd9SAdrian Chadd  *
1213440495aSAdrian Chadd  * This requires the configuration to be set before this function
1223440495aSAdrian Chadd  * is called.
1236558ffd9SAdrian Chadd  */
1246558ffd9SAdrian Chadd void
1256558ffd9SAdrian Chadd ath_led_config(struct ath_softc *sc)
1266558ffd9SAdrian Chadd {
127f5c30c4eSAdrian Chadd 
128f5c30c4eSAdrian Chadd 	ATH_LOCK(sc);
129f5c30c4eSAdrian Chadd 	ath_power_set_power_state(sc, HAL_PM_AWAKE);
130f5c30c4eSAdrian Chadd 	ATH_UNLOCK(sc);
131f5c30c4eSAdrian Chadd 
1326558ffd9SAdrian Chadd 	/* Software LED blinking - GPIO controlled LED */
1336558ffd9SAdrian Chadd 	if (sc->sc_softled) {
1346558ffd9SAdrian Chadd 		ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_ledpin,
1356479ef78SAdrian Chadd 		    HAL_GPIO_OUTPUT_MUX_AS_OUTPUT);
1366558ffd9SAdrian Chadd 		ath_hal_gpioset(sc->sc_ah, sc->sc_ledpin, !sc->sc_ledon);
1376558ffd9SAdrian Chadd 	}
1386558ffd9SAdrian Chadd 
1396558ffd9SAdrian Chadd 	/* Hardware LED blinking - MAC controlled LED */
1403440495aSAdrian Chadd 	if (sc->sc_hardled) {
1413440495aSAdrian Chadd 		/*
1423440495aSAdrian Chadd 		 * Only enable each LED if required.
1433440495aSAdrian Chadd 		 *
1443440495aSAdrian Chadd 		 * Some NICs only have one LED connected; others may
1453440495aSAdrian Chadd 		 * have GPIO1/GPIO2 connected to other hardware.
1463440495aSAdrian Chadd 		 */
1473440495aSAdrian Chadd 		if (sc->sc_led_pwr_pin > 0)
1483440495aSAdrian Chadd 			ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_led_pwr_pin,
1496479ef78SAdrian Chadd 			    HAL_GPIO_OUTPUT_MUX_MAC_POWER_LED);
1503440495aSAdrian Chadd 		if (sc->sc_led_net_pin > 0)
1513440495aSAdrian Chadd 			ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_led_net_pin,
1526479ef78SAdrian Chadd 			    HAL_GPIO_OUTPUT_MUX_MAC_NETWORK_LED);
1533440495aSAdrian Chadd 	}
154f5c30c4eSAdrian Chadd 
155f5c30c4eSAdrian Chadd 	ATH_LOCK(sc);
156f5c30c4eSAdrian Chadd 	ath_power_restore_power_state(sc);
157f5c30c4eSAdrian Chadd 	ATH_UNLOCK(sc);
1586558ffd9SAdrian Chadd }
1596558ffd9SAdrian Chadd 
160c65ee21dSAdrian Chadd static void
161c65ee21dSAdrian Chadd ath_led_done(void *arg)
162c65ee21dSAdrian Chadd {
163c65ee21dSAdrian Chadd 	struct ath_softc *sc = arg;
164c65ee21dSAdrian Chadd 
165c65ee21dSAdrian Chadd 	sc->sc_blinking = 0;
166c65ee21dSAdrian Chadd }
167c65ee21dSAdrian Chadd 
168c65ee21dSAdrian Chadd /*
169c65ee21dSAdrian Chadd  * Turn the LED off: flip the pin and then set a timer so no
170c65ee21dSAdrian Chadd  * update will happen for the specified duration.
171c65ee21dSAdrian Chadd  */
172c65ee21dSAdrian Chadd static void
173c65ee21dSAdrian Chadd ath_led_off(void *arg)
174c65ee21dSAdrian Chadd {
175c65ee21dSAdrian Chadd 	struct ath_softc *sc = arg;
176c65ee21dSAdrian Chadd 
177c65ee21dSAdrian Chadd 	ath_hal_gpioset(sc->sc_ah, sc->sc_ledpin, !sc->sc_ledon);
178c65ee21dSAdrian Chadd 	callout_reset(&sc->sc_ledtimer, sc->sc_ledoff, ath_led_done, sc);
179c65ee21dSAdrian Chadd }
180c65ee21dSAdrian Chadd 
181c65ee21dSAdrian Chadd /*
182c65ee21dSAdrian Chadd  * Blink the LED according to the specified on/off times.
183c65ee21dSAdrian Chadd  */
184c65ee21dSAdrian Chadd static void
185c65ee21dSAdrian Chadd ath_led_blink(struct ath_softc *sc, int on, int off)
186c65ee21dSAdrian Chadd {
187c65ee21dSAdrian Chadd 	DPRINTF(sc, ATH_DEBUG_LED, "%s: on %u off %u\n", __func__, on, off);
188c65ee21dSAdrian Chadd 	ath_hal_gpioset(sc->sc_ah, sc->sc_ledpin, sc->sc_ledon);
189c65ee21dSAdrian Chadd 	sc->sc_blinking = 1;
190c65ee21dSAdrian Chadd 	sc->sc_ledoff = off;
191c65ee21dSAdrian Chadd 	callout_reset(&sc->sc_ledtimer, on, ath_led_off, sc);
192c65ee21dSAdrian Chadd }
193c65ee21dSAdrian Chadd 
194c65ee21dSAdrian Chadd void
195c65ee21dSAdrian Chadd ath_led_event(struct ath_softc *sc, int rix)
196c65ee21dSAdrian Chadd {
197c65ee21dSAdrian Chadd 	sc->sc_ledevent = ticks;	/* time of last event */
198c65ee21dSAdrian Chadd 	if (sc->sc_blinking)		/* don't interrupt active blink */
199c65ee21dSAdrian Chadd 		return;
200c65ee21dSAdrian Chadd 	ath_led_blink(sc, sc->sc_hwmap[rix].ledon, sc->sc_hwmap[rix].ledoff);
201c65ee21dSAdrian Chadd }
202