summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorMarcus Glocker <mglocker@cvs.openbsd.org>2007-10-18 05:56:16 +0000
committerMarcus Glocker <mglocker@cvs.openbsd.org>2007-10-18 05:56:16 +0000
commit024f3df0062008ce2087603099c549c9817efac4 (patch)
tree26f75bcb3cdc5859a02277181161371db1f97a2b /sys/dev
parent72fc5a49fe02d2c1e51324bb423b249f7aef654c (diff)
Add some first LEDs support. Tested on my cardbus Linksys WPC54G Ver 3.
Diff ported from DragonFlyBSD
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ic/bwi.c109
-rw-r--r--sys/dev/ic/bwireg.h27
-rw-r--r--sys/dev/ic/bwivar.h12
3 files changed, 144 insertions, 4 deletions
diff --git a/sys/dev/ic/bwi.c b/sys/dev/ic/bwi.c
index 11a5256093d..8cc57d68458 100644
--- a/sys/dev/ic/bwi.c
+++ b/sys/dev/ic/bwi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bwi.c,v 1.61 2007/10/04 05:44:42 mglocker Exp $ */
+/* $OpenBSD: bwi.c,v 1.62 2007/10/18 05:56:15 mglocker Exp $ */
/*
* Copyright (c) 2007 The DragonFly Project. All rights reserved.
@@ -258,6 +258,8 @@ int bwi_regwin_switch(struct bwi_softc *, struct bwi_regwin *,
struct bwi_regwin **);
int bwi_regwin_select(struct bwi_softc *, int);
void bwi_regwin_info(struct bwi_softc *, uint16_t *, uint8_t *);
+void bwi_led_attach(struct bwi_softc *);
+void bwi_led_newstate(struct bwi_softc *, enum ieee80211_state);
int bwi_bbp_attach(struct bwi_softc *);
int bwi_bus_init(struct bwi_softc *, struct bwi_mac *);
void bwi_get_card_flags(struct bwi_softc *);
@@ -657,7 +659,7 @@ bwi_attach(struct bwi_softc *sc)
bwi_get_card_flags(sc);
- /* TODO: LED */
+ bwi_led_attach(sc);
for (i = 0; i < sc->sc_nmac; ++i) {
struct bwi_regwin *old;
@@ -5875,6 +5877,107 @@ bwi_regwin_info(struct bwi_softc *sc, uint16_t *type, uint8_t *rev)
*type, *rev, __SHIFTOUT(val, BWI_ID_HI_REGWIN_VENDOR_MASK));
}
+void
+bwi_led_attach(struct bwi_softc *sc)
+{
+ const static uint8_t led_default_act[BWI_LED_MAX] = {
+ BWI_LED_ACT_ACTIVE,
+ BWI_LED_ACT_2GHZ,
+ BWI_LED_ACT_5GHZ,
+ BWI_LED_ACT_OFF
+ };
+
+ uint16_t gpio, val[BWI_LED_MAX];
+ int i;
+
+ gpio = bwi_read_sprom(sc, BWI_SPROM_GPIO01);
+ val[0] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_0);
+ val[1] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_1);
+
+ gpio = bwi_read_sprom(sc, BWI_SPROM_GPIO23);
+ val[2] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_2);
+ val[3] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_3);
+
+ for (i = 0; i < BWI_LED_MAX; ++i) {
+ struct bwi_led *led = &sc->sc_leds[i];
+
+ if (val[i] == 0xff) {
+ led->l_act = led_default_act[i];
+ if (i == 0 && sc->sc_pci_subvid == PCI_VENDOR_COMPAQ)
+ led->l_act = BWI_LED_ACT_RFEN;
+ } else {
+ if (val[i] & BWI_LED_ACT_LOW)
+ led->l_flags |= BWI_LED_F_ACTLOW;
+ led->l_act = __SHIFTOUT(val[i], BWI_LED_ACT_MASK);
+ }
+
+ DPRINTF("%dth led, act %d, lowact %d\n",
+ i, led->l_act, led->l_flags & BWI_LED_F_ACTLOW);
+ }
+}
+
+void
+bwi_led_newstate(struct bwi_softc *sc, enum ieee80211_state nstate)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ uint16_t val;
+ int i;
+
+ if ((ic->ic_if.if_flags & IFF_RUNNING) == 0)
+ return;
+
+ val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL);
+ for (i = 0; i < BWI_LED_MAX; ++i) {
+ struct bwi_led *led = &sc->sc_leds[i];
+ int on;
+
+ if (led->l_act == BWI_LED_ACT_UNKN ||
+ led->l_act == BWI_LED_ACT_NULL) {
+ /* Don't touch it */
+ continue;
+ }
+
+ switch (led->l_act) {
+ case BWI_LED_ACT_ON: /* Always on */
+ on = 1;
+ break;
+ case BWI_LED_ACT_OFF: /* Always off */
+ case BWI_LED_ACT_5GHZ: /* TODO: 11A */
+ case BWI_LED_ACT_MID: /* Blinking ones */
+ case BWI_LED_ACT_FAST:
+ on = 0;
+ break;
+ default:
+ on = 1;
+ switch (nstate) {
+ case IEEE80211_S_INIT:
+ on = 0;
+ break;
+ case IEEE80211_S_RUN:
+ if (led->l_act == BWI_LED_ACT_11G &&
+ ic->ic_curmode != IEEE80211_MODE_11G)
+ on = 0;
+ break;
+ default:
+ if (led->l_act == BWI_LED_ACT_RUN ||
+ led->l_act == BWI_LED_ACT_ACTIVE)
+ on = 0;
+ break;
+ }
+ break;
+ }
+
+ if (led->l_flags & BWI_LED_F_ACTLOW)
+ on = !on;
+
+ if (on)
+ val |= (1 << i);
+ else
+ val &= ~(1 << i);
+ }
+ CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val);
+}
+
int
bwi_bbp_attach(struct bwi_softc *sc)
{
@@ -6659,6 +6762,8 @@ bwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
timeout_del(&sc->sc_scan_ch);
timeout_del(&sc->sc_calib_ch);
+ bwi_led_newstate(sc, nstate);
+
if (nstate == IEEE80211_S_INIT)
goto back;
diff --git a/sys/dev/ic/bwireg.h b/sys/dev/ic/bwireg.h
index 9a02ddb05da..78c3a7fe4d6 100644
--- a/sys/dev/ic/bwireg.h
+++ b/sys/dev/ic/bwireg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bwireg.h,v 1.5 2007/09/30 22:26:10 mglocker Exp $ */
+/* $OpenBSD: bwireg.h,v 1.6 2007/10/18 05:56:15 mglocker Exp $ */
/*
* Copyright (c) 2007 The DragonFly Project. All rights reserved.
@@ -314,6 +314,7 @@
#define BWI_ADDR_FILTER_BSSID 3
#define BWI_ADDR_FILTER_DATA 0x422
+#define BWI_MAC_GPIO_CTRL 0x049c
#define BWI_MAC_GPIO_MASK 0x049e
#define BWI_MAC_PRE_TBTT 0x0612
#define BWI_MAC_SLOTTIME 0x0684
@@ -369,6 +370,12 @@
#define BWI_SPROM_CARD_INFO_LOCALE (0x0f << 8)
#define BWI_SPROM_LOCALE_JAPAN 5
#define BWI_SPROM_PA_PARAM_11BG 0x5e
+#define BWI_SPROM_GPIO01 0x64
+#define BWI_SPROM_GPIO_0 0x00ff
+#define BWI_SPROM_GPIO_1 0xff00
+#define BWI_SPROM_GPIO23 0x0066
+#define BWI_SPROM_GPIO_2 0x00ff
+#define BWI_SPROM_GPIO_3 0xff00
#define BWI_SPROM_MAX_TXPWR 0x68
#define BWI_SPROM_MAX_TXPWR_MASK_11BG 0x00ff /* XXX */
#define BWI_SPROM_MAX_TXPWR_MASK_11A 0xff00 /* XXX */
@@ -391,6 +398,24 @@
#define BWI_CARD_F_ALT_IQ (1 << 15) /* alternate I/Q */
/*
+ * PROM GPIO
+ */
+#define BWI_LED_ACT_LOW (1 << 7)
+#define BWI_LED_ACT_MASK 0x7f
+#define BWI_LED_ACT_OFF 0
+#define BWI_LED_ACT_ON 1
+#define BWI_LED_ACT_ACTIVE 2
+#define BWI_LED_ACT_RFEN 3
+#define BWI_LED_ACT_5GHZ 4
+#define BWI_LED_ACT_2GHZ 5
+#define BWI_LED_ACT_11G 6
+#define BWI_LED_ACT_MID 7
+#define BWI_LED_ACT_FAST 8
+#define BWI_LED_ACT_UNKN 9
+#define BWI_LED_ACT_RUN 10
+#define BWI_LED_ACT_NULL 11
+
+/*
* BBP IDs
*/
#define BWI_BBPID_BCM4301 0x4301
diff --git a/sys/dev/ic/bwivar.h b/sys/dev/ic/bwivar.h
index d54cfdeffaf..22682f032f2 100644
--- a/sys/dev/ic/bwivar.h
+++ b/sys/dev/ic/bwivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bwivar.h,v 1.18 2007/10/04 05:44:43 mglocker Exp $ */
+/* $OpenBSD: bwivar.h,v 1.19 2007/10/18 05:56:15 mglocker Exp $ */
/*
* Copyright (c) 2007 The DragonFly Project. All rights reserved.
@@ -256,6 +256,13 @@ struct bwi_fw_iv {
} iv_val;
} __packed;
+struct bwi_led {
+ uint8_t l_flags; /* BWI_LED_F_ */
+ uint8_t l_act; /* BWI_LED_ACT_ */
+};
+
+#define BWI_LED_F_ACTLOW 0x1
+
enum bwi_clock_mode {
BWI_CLOCK_MODE_SLOW,
BWI_CLOCK_MODE_FAST,
@@ -422,6 +429,7 @@ do { \
} while (0)
#define BWI_MAC_MAX 2
+#define BWI_LED_MAX 4
enum bwi_bus_space {
BWI_BUS_SPACE_30BIT = 1,
@@ -508,6 +516,8 @@ struct bwi_softc {
int sc_nmac;
struct bwi_mac sc_mac[BWI_MAC_MAX];
+
+ struct bwi_led sc_leds[BWI_LED_MAX];
enum bwi_bus_space sc_bus_space;