diff options
author | Marcus Glocker <mglocker@cvs.openbsd.org> | 2007-03-20 21:14:40 +0000 |
---|---|---|
committer | Marcus Glocker <mglocker@cvs.openbsd.org> | 2007-03-20 21:14:40 +0000 |
commit | f9b62c4b41fe2c222a87dde4272749410575ae78 (patch) | |
tree | 154f19b49555e1470003a0faf0aa2b70a8b05352 /sys/dev/ic | |
parent | 771af2de94f62953b1534e0e23fa50222a910775 (diff) |
Fix crystal on/off routine (no more panic). Add two new routines to
set and clear the device's MAC filter.
Diffstat (limited to 'sys/dev/ic')
-rw-r--r-- | sys/dev/ic/bcw.c | 108 | ||||
-rw-r--r-- | sys/dev/ic/bcwreg.h | 10 |
2 files changed, 87 insertions, 31 deletions
diff --git a/sys/dev/ic/bcw.c b/sys/dev/ic/bcw.c index a48da4df1ba..6914ea13563 100644 --- a/sys/dev/ic/bcw.c +++ b/sys/dev/ic/bcw.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bcw.c,v 1.79 2007/03/20 13:52:48 mglocker Exp $ */ +/* $OpenBSD: bcw.c,v 1.80 2007/03/20 21:14:39 mglocker Exp $ */ /* * Copyright (c) 2006 Jon Simola <jsimola@gmail.com> @@ -98,6 +98,9 @@ void bcw_start(struct ifnet *); void bcw_stop(struct ifnet *, int); void bcw_watchdog(struct ifnet *); void bcw_set_opmode(struct ifnet *); +void bcw_macfilter_set(struct bcw_softc *, uint16_t, + const uint8_t *); +void bcw_macfilter_clear(struct bcw_softc *, uint16_t); void bcw_mac_enable(struct bcw_softc *); uint32_t bcw_intr_enable(struct bcw_softc *, uint32_t); uint32_t bcw_intr_disable(struct bcw_softc *, uint32_t); @@ -906,6 +909,11 @@ bcw_attach(struct bcw_softc *sc) sc->sc_board_vendor, sc->sc_board_type, sc->sc_board_rev)); /* + * Turn crystal on + */ + bcw_powercontrol_crystal_on(sc); + + /* * Try and change to the ChipCommon Core */ if (bcw_change_core(sc, 0) == 0) @@ -1288,15 +1296,13 @@ bcw_attach(struct bcw_softc *sc) */ /* - * XXX TODO still for the card attach: - * - Disable the 80211 Core (and wrapper for on/off) - * - Setup LEDs to blink in whatever fashionable manner + * Turn crystal off */ - //bcw_powercontrol_crystal_off(sc); /* TODO Fix panic! */ + bcw_powercontrol_crystal_off(sc); /* * Allocate DMA-safe memory for ring descriptors. - * The receive and transmit rings are 4k aligned + * The receive and transmit rings are 4k aligned. */ bcw_alloc_rx_ring(sc, &sc->sc_rxring, BCW_RX_RING_COUNT); bcw_alloc_tx_ring(sc, &sc->sc_txring, BCW_TX_RING_COUNT); @@ -1305,7 +1311,7 @@ bcw_attach(struct bcw_softc *sc) ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ ic->ic_state = IEEE80211_S_INIT; - /* set device capabilities - keep it simple */ + /* Set device capabilities - keep it simple */ ic->ic_caps = IEEE80211_C_IBSS; /* IBSS mode supported */ /* Set supported rates */ @@ -1497,6 +1503,33 @@ bcw_set_opmode(struct ifnet *ifp) BCW_WRITE16(sc, 0x0612, val); } +void +bcw_macfilter_set(struct bcw_softc *sc, uint16_t offset, const uint8_t *mac) +{ + uint16_t data; + + offset |= 0x0020; + BCW_WRITE16(sc, BCW_MMIO_MACFILTER_CONTROL, offset); + + data = mac[0]; + data |= mac[1] << 8; + BCW_WRITE16(sc, BCW_MMIO_MACFILTER_DATA, data); + data = mac[2]; + data |= mac[3] << 8; + BCW_WRITE16(sc, BCW_MMIO_MACFILTER_DATA, data); + data = mac[4]; + data |= mac[5] << 8; + BCW_WRITE16(sc, BCW_MMIO_MACFILTER_DATA, data); +} + +void +bcw_macfilter_clear(struct bcw_softc *sc, uint16_t offset) +{ + const uint8_t zero_addr[ETHER_ADDR_LEN] = { 0 }; + + bcw_macfilter_set(sc, offset, zero_addr); +} + /* * Enable MAC on a PHY * @@ -1546,6 +1579,7 @@ bcw_intr(void *arg) struct bcw_softc *sc = arg; uint32_t reason; #endif + return (0); } @@ -1581,12 +1615,20 @@ int bcw_init(struct ifnet *ifp) { struct bcw_softc *sc = ifp->if_softc; + //struct ieee80211com *ic = &sc->sc_ic; int error; /* initialize 80211 core */ if ((error = bcw_80211_core_init(sc, 1))) /* XXX */ return (error); +#if 0 + bcw_macfilter_clear(sc, BCW_MACFILTER_ASSOC); + bcw_macfilter_set(sc, BCW_MACFILTER_SELF, ic->ic_myaddr); + bcw_mac_enable(sc); + bcw_intr_enable(sc, BCW_INTR_INITIAL); +#endif + /* start timer */ timeout_add(&sc->sc_timeout, hz); @@ -2190,41 +2232,47 @@ bcw_free_tx_ring(struct bcw_softc *sc, struct bcw_tx_ring *ring) void bcw_powercontrol_crystal_on(struct bcw_softc *sc) { - uint32_t sbval; + uint32_t val; - sbval = (sc->sc_conf_read)(sc->sc_dev_softc, BCW_GPIOI); - if ((sbval & BCW_PCTL_XTAL_POWERUP) != BCW_PCTL_XTAL_POWERUP) { - sbval = (sc->sc_conf_read)(sc->sc_dev_softc, BCW_GPIOO); - sbval |= (BCW_PCTL_XTAL_POWERUP & BCW_PCTL_PLL_POWERDOWN); - (sc->sc_conf_write)(sc->sc_dev_softc, BCW_GPIOO, sbval); - delay(1000); - sbval = (sc->sc_conf_read)(sc->sc_dev_softc, BCW_GPIOO); - sbval &= ~BCW_PCTL_PLL_POWERDOWN; - (sc->sc_conf_write)(sc->sc_dev_softc, BCW_GPIOO, sbval); - delay(5000); - } + val = (sc->sc_conf_read)(sc->sc_dev_softc, BCW_GPIOI); + if ((val & BCW_PCTL_XTAL_POWERUP) == BCW_PCTL_XTAL_POWERUP) + return; /* crystal is already on */ + + val = (sc->sc_conf_read)(sc->sc_dev_softc, BCW_GPIOO); + val |= (BCW_PCTL_XTAL_POWERUP | BCW_PCTL_PLL_POWERDOWN); + (sc->sc_conf_write)(sc->sc_dev_softc, BCW_GPIOO, val); + (sc->sc_conf_write)(sc->sc_dev_softc, BCW_GPIOE, val); + + delay(1000); + + val = (sc->sc_conf_read)(sc->sc_dev_softc, BCW_GPIOO); + val &= ~BCW_PCTL_PLL_POWERDOWN; + (sc->sc_conf_write)(sc->sc_dev_softc, BCW_GPIOO, val); + + delay(5000); } void bcw_powercontrol_crystal_off(struct bcw_softc *sc) { - uint32_t sbval; + uint32_t val; - /* XXX Return if radio is hardware disabled */ + /* TODO return if radio is hardware disabled */ if (sc->sc_chip_rev < 5) return; - if ((sc->sc_sprom.boardflags & BCW_BF_XTAL) == BCW_BF_XTAL) + if ((sc->sc_sprom.boardflags & BCW_BF_XTAL)) return; - /* XXX bcw_powercontrol_clock_slow() */ + /* TODO bcw_powercontrol_clock_slow() */ + + val = (sc->sc_conf_read)(sc->sc_dev_softc, BCW_GPIOO); + val |= BCW_PCTL_PLL_POWERDOWN; + val &= ~BCW_PCTL_XTAL_POWERUP; + (sc->sc_conf_write)(sc->sc_dev_softc, BCW_GPIOO, val); - sbval = (sc->sc_conf_read)(sc->sc_dev_softc, BCW_GPIOO); - sbval |= BCW_PCTL_PLL_POWERDOWN; - sbval &= ~BCW_PCTL_XTAL_POWERUP; - (sc->sc_conf_write)(sc->sc_dev_softc, BCW_GPIOO, sbval); - sbval = (sc->sc_conf_read)(sc->sc_dev_softc, BCW_GPIOE); - sbval |= BCW_PCTL_PLL_POWERDOWN | BCW_PCTL_XTAL_POWERUP; - (sc->sc_conf_write)(sc->sc_dev_softc, BCW_GPIOE, sbval); + val = (sc->sc_conf_read)(sc->sc_dev_softc, BCW_GPIOE); + val |= (BCW_PCTL_PLL_POWERDOWN | BCW_PCTL_XTAL_POWERUP); + (sc->sc_conf_write)(sc->sc_dev_softc, BCW_GPIOE, val); } int diff --git a/sys/dev/ic/bcwreg.h b/sys/dev/ic/bcwreg.h index 010bf944cd2..e4e097b133a 100644 --- a/sys/dev/ic/bcwreg.h +++ b/sys/dev/ic/bcwreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bcwreg.h,v 1.23 2007/03/20 11:55:36 mglocker Exp $ */ +/* $OpenBSD: bcwreg.h,v 1.24 2007/03/20 21:14:39 mglocker Exp $ */ /* * Copyright (c) 2006 Jon Simola <jsimola@gmail.com> @@ -55,6 +55,8 @@ #define BCW_MMIO_RADIO_DATA_HIGH 0x3f8 #define BCW_MMIO_PHY_CONTROL 0x3fc #define BCW_MMIO_PHY_DATA 0x3fe +#define BCW_MMIO_MACFILTER_CONTROL 0x420 +#define BCW_MMIO_MACFILTER_DATA 0x422 #define BCW_MMIO_GPIO_CONTROL 0x49c #define BCW_MMIO_GPIO_MASK 0x49e @@ -117,6 +119,12 @@ #define BCW_SHM_UCODE 0x0300 /* + * MAC filter offsets + */ +#define BCW_MACFILTER_SELF 0 +#define BCW_MACFILTER_ASSOC 0x0003 + +/* * Power control */ #define BCW_PCTL_IN 0xb0 |