Date: Fri, 19 Oct 2007 09:18:34 GMT From: Kevin Lo <kevlo@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 127754 for review Message-ID: <200710190918.l9J9IYNn098328@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=127754 Change 127754 by kevlo@kevlo_rtsl on 2007/10/19 09:18:18 Add LEDs support. Tested on my cardbus Asus WL-100G. Obtained from: DragonflyBSD Affected files ... .. //depot/projects/wifi/sys/dev/bwi/if_bwi.c#8 edit .. //depot/projects/wifi/sys/dev/bwi/if_bwireg.h#3 edit .. //depot/projects/wifi/sys/dev/bwi/if_bwivar.h#4 edit Differences ... ==== //depot/projects/wifi/sys/dev/bwi/if_bwi.c#8 (text+ko) ==== @@ -193,6 +193,9 @@ static void bwi_regwin_info(struct bwi_softc *, uint16_t *, uint8_t *); static int bwi_regwin_select(struct bwi_softc *, int); +static void bwi_led_attach(struct bwi_softc *); +static void bwi_led_newstate(struct bwi_softc *, enum ieee80211_state); + static const struct { uint16_t did_min; uint16_t did_max; @@ -317,7 +320,7 @@ bwi_get_card_flags(sc); - /* TODO: LED */ + bwi_led_attach(sc); for (i = 0; i < sc->sc_nmac; ++i) { struct bwi_regwin *old; @@ -1531,6 +1534,8 @@ callout_stop(&sc->sc_calib_ch); callout_stop(&sc->sc_amrr_ch); + bwi_led_newstate(sc, nstate); + if (nstate == IEEE80211_S_INIT) goto back; @@ -3483,6 +3488,109 @@ bpf_mtap2(sc->sc_drvbpf, &sc->sc_rx_th, sc->sc_rx_th_len, m); } +static void +bwi_led_attach(struct bwi_softc *sc) +{ +#define PCI_VENDOR_COMPAQ 0x0e11 + 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(sc, "%dth led, act %d, lowact %d\n", + i, led->l_act, led->l_flags & BWI_LED_F_ACTLOW); + } +#undef PCI_VENDOR_COMPAQ +} + +static 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_ifp->if_drv_flags & IFF_DRV_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); +} + /* * Covert PLCP signal/rate field to net80211 rate (.5Mbits/s) */ ==== //depot/projects/wifi/sys/dev/bwi/if_bwireg.h#3 (text+ko) ==== @@ -318,6 +318,7 @@ #define BWI_ADDR_FILTER_BSSID 3 #define BWI_ADDR_FILTER_DATA 0x422 +#define BWI_MAC_GPIO_CTRL 0x49c #define BWI_MAC_GPIO_MASK 0x49e #define BWI_MAC_PRE_TBTT 0x612 #define BWI_MAC_SLOTTIME 0x684 @@ -376,6 +377,12 @@ #define BWI_SPROM_CARD_INFO_LOCALE __BITS(11, 8) #define BWI_SPROM_LOCALE_JAPAN 5 #define BWI_SPROM_PA_PARAM_11BG 0x5e +#define BWI_SPROM_GPIO01 0x64 +#define BWI_SPROM_GPIO_0 __BITS(7, 0) +#define BWI_SPROM_GPIO_1 __BITS(15, 8) +#define BWI_SPROM_GPIO23 0x66 +#define BWI_SPROM_GPIO_2 __BITS(7, 0) +#define BWI_SPROM_GPIO_3 __BITS(15, 8) #define BWI_SPROM_MAX_TXPWR 0x68 #define BWI_SPROM_MAX_TXPWR_MASK_11BG __BITS(7, 0) /* XXX */ #define BWI_SPROM_MAX_TXPWR_MASK_11A __BITS(15, 8) /* XXX */ @@ -399,6 +406,24 @@ #define BWI_CARD_F_ALT_IQ __BIT(15) /* alternate I/Q */ /* + * SPROM GPIO + */ +#define BWI_LED_ACT_LOW __BIT(7) +#define BWI_LED_ACT_MASK __BITS(6, 0) +#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 ==== //depot/projects/wifi/sys/dev/bwi/if_bwivar.h#4 (text+ko) ==== @@ -281,6 +281,13 @@ #define BWI_FW_IV_OFS_MASK __BITS(14, 0) #define BWI_FW_IV_IS_32BIT __BIT(15) +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, @@ -448,6 +455,7 @@ } while (0) #define BWI_MAC_MAX 2 +#define BWI_LED_MAX 4 enum bwi_bus_space { BWI_BUS_SPACE_30BIT = 1, @@ -535,6 +543,8 @@ 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; bus_dma_tag_t sc_parent_dtag;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200710190918.l9J9IYNn098328>