1c65ee21dSAdrian Chadd /*-
2*4d846d26SWarner 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