summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcus Glocker <mglocker@cvs.openbsd.org>2007-03-16 22:22:25 +0000
committerMarcus Glocker <mglocker@cvs.openbsd.org>2007-03-16 22:22:25 +0000
commitbfa36cc5a14826af5e11edb51bcced3354b61eb3 (patch)
treebea4f50f1fbd2bf6553ceb590205673f6f157366
parentc60aab5ca3f6ff1a5a7a6acc8647b408664c6ba7 (diff)
Split the whole chip init stuff in bcw_init() into a new function
called bcw_chip_init(), according to the 80211Init steps in the spec.
-rw-r--r--sys/dev/ic/bcw.c283
1 files changed, 152 insertions, 131 deletions
diff --git a/sys/dev/ic/bcw.c b/sys/dev/ic/bcw.c
index 0479eebec80..107ed019ec4 100644
--- a/sys/dev/ic/bcw.c
+++ b/sys/dev/ic/bcw.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bcw.c,v 1.74 2007/03/16 15:28:54 mglocker Exp $ */
+/* $OpenBSD: bcw.c,v 1.75 2007/03/16 22:22:24 mglocker Exp $ */
/*
* Copyright (c) 2006 Jon Simola <jsimola@gmail.com>
@@ -130,6 +130,7 @@ int bcw_write_initvals(struct bcw_softc *,
int bcw_load_initvals(struct bcw_softc *);
void bcw_leds_switch_all(struct bcw_softc *, int);
int bcw_gpio_init(struct bcw_softc *);
+int bcw_chip_init(struct bcw_softc *);
/*
* PHY
@@ -1555,142 +1556,19 @@ bcw_txintr(struct bcw_softc *sc)
}
-/* initialize the interface */
+/*
+ * Initialize the interface
+ */
int
bcw_init(struct ifnet *ifp)
{
- struct bcw_softc *sc = ifp->if_softc;
- uint16_t val16;
- uint32_t val32;
- int error, i, tmp;
-
- BCW_WRITE(sc, BCW_MMIO_SBF, BCW_SBF_CORE_READY | BCW_SBF_400_MAGIC);
-
- /* load firmware */
- if ((error = bcw_load_firmware(sc)))
- return (error);
-
- /*
- * verify firmware revision
- */
- BCW_WRITE(sc, BCW_MMIO_GIR, 0xffffffff);
- BCW_WRITE(sc, BCW_MMIO_SBF, 0x00020402);
- for (i = 0; i < 50; i++) {
- if (BCW_READ(sc, BCW_MMIO_GIR) == BCW_INTR_READY)
- break;
- delay(10);
- }
- if (i == 50) {
- printf("%s: interrupt-ready timeout!\n", sc->sc_dev.dv_xname);
- return (1);
- }
- BCW_READ(sc, BCW_MMIO_GIR); /* dummy read */
-
- val16 = bcw_shm_read16(sc, BCW_SHM_SHARED, BCW_UCODE_REVISION);
-
- DPRINTF(("%s: Firmware revision 0x%x, patchlevel 0x%x "
- "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n",
- sc->sc_dev.dv_xname, val16,
- bcw_shm_read16(sc, BCW_SHM_SHARED, BCW_UCODE_PATCHLEVEL),
- (bcw_shm_read16(sc, BCW_SHM_SHARED, BCW_UCODE_DATE) >> 12)
- & 0xf,
- (bcw_shm_read16(sc, BCW_SHM_SHARED, BCW_UCODE_DATE) >> 8)
- & 0xf,
- bcw_shm_read16(sc, BCW_SHM_SHARED, BCW_UCODE_DATE)
- & 0xff,
- (bcw_shm_read16(sc, BCW_SHM_SHARED, BCW_UCODE_TIME) >> 11)
- & 0x1f,
- (bcw_shm_read16(sc, BCW_SHM_SHARED, BCW_UCODE_TIME) >> 5)
- & 0x3f,
- bcw_shm_read16(sc, BCW_SHM_SHARED, BCW_UCODE_TIME)
- & 0x1f));
-
- if (val16 > 0x128) {
- printf("%s: no support for this firmware revision!\n",
- sc->sc_dev.dv_xname);
- return (1);
- }
+ struct bcw_softc *sc = ifp->if_softc;
+ int error;
- /* initialize GPIO */
- if ((error = bcw_gpio_init(sc)))
+ /* initialize chip */
+ if ((error = bcw_chip_init(sc)))
return (error);
- /* load init values */
- if ((error = bcw_load_initvals(sc)))
- return (error);
-
- /* turn radio on */
- bcw_radio_on(sc);
-
- BCW_WRITE16(sc, 0x03e6, 0);
- if ((error = bcw_phy_init(sc)))
- return (error);
-
- /* select initial interference mitigation */
- tmp = sc->sc_radio_interfmode;
- sc->sc_radio_interfmode = BCW_RADIO_INTERFMODE_NONE;
- bcw_radio_set_interf_mitigation(sc, tmp);
-
- bcw_phy_set_antenna_diversity(sc);
- bcw_radio_set_txantenna(sc, BCW_RADIO_TXANTENNA_DEFAULT);
- if (sc->sc_phy_type == BCW_PHY_TYPEB) {
- val16 = BCW_READ16(sc, 0x005e);
- val16 |= 0x0004;
- BCW_WRITE16(sc, 0x005e, val16);
- }
- BCW_WRITE(sc, 0x0100, 0x01000000);
- if (sc->sc_core[sc->sc_currentcore].rev < 5)
- BCW_WRITE(sc, 0x010c, 0x01000000);
-
- val32 = BCW_READ(sc, BCW_MMIO_SBF);
- val32 &= ~BCW_SBF_ADHOC;
- BCW_WRITE(sc, BCW_MMIO_SBF, val32);
- val32 = BCW_READ(sc, BCW_MMIO_SBF);
- val32 |= BCW_SBF_ADHOC;
- BCW_WRITE(sc, BCW_MMIO_SBF, val32);
-
- val32 = BCW_READ(sc, BCW_MMIO_SBF);
- val32 |= 0x100000;
- BCW_WRITE(sc, BCW_MMIO_SBF, val32);
-
- if (bcw_using_pio(sc)) {
- BCW_WRITE(sc, 0x0210, 0x00000100);
- BCW_WRITE(sc, 0x0230, 0x00000100);
- BCW_WRITE(sc, 0x0250, 0x00000100);
- BCW_WRITE(sc, 0x0270, 0x00000100);
- bcw_shm_write16(sc, BCW_SHM_SHARED, 0x0034, 0);
- }
-
- /* probe response timeout value */
- bcw_shm_write16(sc, BCW_SHM_SHARED, 0x0074, 0);
-
- /* initially set the wireless operation mode */
- bcw_set_opmode(ifp);
-
- if (sc->sc_core[sc->sc_currentcore].rev < 3) {
- BCW_WRITE16(sc, 0x060e, 0);
- BCW_WRITE16(sc, 0x0610, 0x8000);
- BCW_WRITE16(sc, 0x0604, 0);
- BCW_WRITE16(sc, 0x0606, 0x0200);
- } else {
- BCW_WRITE(sc, 0x0188, 0x80000000);
- BCW_WRITE(sc, 0x018c, 0x02000000);
- }
- BCW_WRITE(sc, BCW_MMIO_GIR, 0x00004000);
- BCW_WRITE(sc, BCW_MMIO_DMA0_INT_MASK, 0x0001dc00);
- BCW_WRITE(sc, BCW_MMIO_DMA1_INT_MASK, 0x0000dc00);
- BCW_WRITE(sc, BCW_MMIO_DMA2_INT_MASK, 0x0000dc00);
- BCW_WRITE(sc, BCW_MMIO_DMA3_INT_MASK, 0x0001dc00);
- BCW_WRITE(sc, BCW_MMIO_DMA4_INT_MASK, 0x0000dc00);
- BCW_WRITE(sc, BCW_MMIO_DMA5_INT_MASK, 0x0000dc00);
-
- val32 = BCW_READ(sc, BCW_CIR_SBTMSTATELOW);
- val32 |= 0x00100000;
- BCW_WRITE(sc, BCW_CIR_SBTMSTATELOW, val32);
- /* TODO bcw_pctl_powerup_delay(sc) */
-
- DPRINTF(("%s: Chip initialized\n", sc->sc_dev.dv_xname));
-
/* start timer */
timeout_add(&sc->sc_timeout, hz);
@@ -2820,6 +2698,149 @@ bcw_gpio_init(struct bcw_softc *sc)
}
/*
+ * Initialize the chip
+ *
+ * http://bcm-specs.sipsolutions.net/ChipInit
+ */
+int
+bcw_chip_init(struct bcw_softc *sc)
+{
+ struct ifnet *ifp = &sc->sc_ic.ic_if;
+ uint16_t val16;
+ uint32_t val32;
+ int error, i, tmp;
+
+ BCW_WRITE(sc, BCW_MMIO_SBF, BCW_SBF_CORE_READY | BCW_SBF_400_MAGIC);
+
+ /* load firmware */
+ if ((error = bcw_load_firmware(sc)))
+ return (error);
+
+ /*
+ * verify firmware revision
+ */
+ BCW_WRITE(sc, BCW_MMIO_GIR, 0xffffffff);
+ BCW_WRITE(sc, BCW_MMIO_SBF, 0x00020402);
+ for (i = 0; i < 50; i++) {
+ if (BCW_READ(sc, BCW_MMIO_GIR) == BCW_INTR_READY)
+ break;
+ delay(10);
+ }
+ if (i == 50) {
+ printf("%s: interrupt-ready timeout!\n", sc->sc_dev.dv_xname);
+ return (1);
+ }
+ BCW_READ(sc, BCW_MMIO_GIR); /* dummy read */
+
+ val16 = bcw_shm_read16(sc, BCW_SHM_SHARED, BCW_UCODE_REVISION);
+
+ DPRINTF(("%s: Firmware revision 0x%x, patchlevel 0x%x "
+ "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n",
+ sc->sc_dev.dv_xname, val16,
+ bcw_shm_read16(sc, BCW_SHM_SHARED, BCW_UCODE_PATCHLEVEL),
+ (bcw_shm_read16(sc, BCW_SHM_SHARED, BCW_UCODE_DATE) >> 12)
+ & 0xf,
+ (bcw_shm_read16(sc, BCW_SHM_SHARED, BCW_UCODE_DATE) >> 8)
+ & 0xf,
+ bcw_shm_read16(sc, BCW_SHM_SHARED, BCW_UCODE_DATE)
+ & 0xff,
+ (bcw_shm_read16(sc, BCW_SHM_SHARED, BCW_UCODE_TIME) >> 11)
+ & 0x1f,
+ (bcw_shm_read16(sc, BCW_SHM_SHARED, BCW_UCODE_TIME) >> 5)
+ & 0x3f,
+ bcw_shm_read16(sc, BCW_SHM_SHARED, BCW_UCODE_TIME)
+ & 0x1f));
+
+ if (val16 > 0x128) {
+ printf("%s: no support for this firmware revision!\n",
+ sc->sc_dev.dv_xname);
+ return (1);
+ }
+
+ /* initialize GPIO */
+ if ((error = bcw_gpio_init(sc)))
+ return (error);
+
+ /* load init values */
+ if ((error = bcw_load_initvals(sc)))
+ return (error);
+
+ /* turn radio on */
+ bcw_radio_on(sc);
+
+ BCW_WRITE16(sc, 0x03e6, 0);
+ if ((error = bcw_phy_init(sc)))
+ return (error);
+
+ /* select initial interference mitigation */
+ tmp = sc->sc_radio_interfmode;
+ sc->sc_radio_interfmode = BCW_RADIO_INTERFMODE_NONE;
+ bcw_radio_set_interf_mitigation(sc, tmp);
+
+ bcw_phy_set_antenna_diversity(sc);
+ bcw_radio_set_txantenna(sc, BCW_RADIO_TXANTENNA_DEFAULT);
+ if (sc->sc_phy_type == BCW_PHY_TYPEB) {
+ val16 = BCW_READ16(sc, 0x005e);
+ val16 |= 0x0004;
+ BCW_WRITE16(sc, 0x005e, val16);
+ }
+ BCW_WRITE(sc, 0x0100, 0x01000000);
+ if (sc->sc_core[sc->sc_currentcore].rev < 5)
+ BCW_WRITE(sc, 0x010c, 0x01000000);
+
+ val32 = BCW_READ(sc, BCW_MMIO_SBF);
+ val32 &= ~BCW_SBF_ADHOC;
+ BCW_WRITE(sc, BCW_MMIO_SBF, val32);
+ val32 = BCW_READ(sc, BCW_MMIO_SBF);
+ val32 |= BCW_SBF_ADHOC;
+ BCW_WRITE(sc, BCW_MMIO_SBF, val32);
+
+ val32 = BCW_READ(sc, BCW_MMIO_SBF);
+ val32 |= 0x100000;
+ BCW_WRITE(sc, BCW_MMIO_SBF, val32);
+
+ if (bcw_using_pio(sc)) {
+ BCW_WRITE(sc, 0x0210, 0x00000100);
+ BCW_WRITE(sc, 0x0230, 0x00000100);
+ BCW_WRITE(sc, 0x0250, 0x00000100);
+ BCW_WRITE(sc, 0x0270, 0x00000100);
+ bcw_shm_write16(sc, BCW_SHM_SHARED, 0x0034, 0);
+ }
+
+ /* probe response timeout value */
+ bcw_shm_write16(sc, BCW_SHM_SHARED, 0x0074, 0);
+
+ /* initially set the wireless operation mode */
+ bcw_set_opmode(ifp);
+
+ if (sc->sc_core[sc->sc_currentcore].rev < 3) {
+ BCW_WRITE16(sc, 0x060e, 0);
+ BCW_WRITE16(sc, 0x0610, 0x8000);
+ BCW_WRITE16(sc, 0x0604, 0);
+ BCW_WRITE16(sc, 0x0606, 0x0200);
+ } else {
+ BCW_WRITE(sc, 0x0188, 0x80000000);
+ BCW_WRITE(sc, 0x018c, 0x02000000);
+ }
+ BCW_WRITE(sc, BCW_MMIO_GIR, 0x00004000);
+ BCW_WRITE(sc, BCW_MMIO_DMA0_INT_MASK, 0x0001dc00);
+ BCW_WRITE(sc, BCW_MMIO_DMA1_INT_MASK, 0x0000dc00);
+ BCW_WRITE(sc, BCW_MMIO_DMA2_INT_MASK, 0x0000dc00);
+ BCW_WRITE(sc, BCW_MMIO_DMA3_INT_MASK, 0x0001dc00);
+ BCW_WRITE(sc, BCW_MMIO_DMA4_INT_MASK, 0x0000dc00);
+ BCW_WRITE(sc, BCW_MMIO_DMA5_INT_MASK, 0x0000dc00);
+
+ val32 = BCW_READ(sc, BCW_CIR_SBTMSTATELOW);
+ val32 |= 0x00100000;
+ BCW_WRITE(sc, BCW_CIR_SBTMSTATELOW, val32);
+ /* TODO bcw_pctl_powerup_delay(sc) */
+
+ DPRINTF(("%s: Chip initialized\n", sc->sc_dev.dv_xname));
+
+ return (0);
+}
+
+/*
* PHY
*/
int