diff options
author | Marcus Glocker <mglocker@cvs.openbsd.org> | 2006-12-06 19:21:46 +0000 |
---|---|---|
committer | Marcus Glocker <mglocker@cvs.openbsd.org> | 2006-12-06 19:21:46 +0000 |
commit | 481941268c9ea63c8c4a41c0e5d17f2017e81bed (patch) | |
tree | 130cb0f5e2729e19c76322d008f35932e10c3a24 | |
parent | cda371b9624e25284a31f2cb0d04702c88bdd8e8 (diff) |
From Jon Simola <simola@mecha.com>:
Add bus-specific config space read and write functions, this fixes the
attach for ian@darwinsys.com and properly enumerates multiple cores.
-rw-r--r-- | sys/dev/cardbus/if_bcw_cardbus.c | 22 | ||||
-rw-r--r-- | sys/dev/ic/bcw.c | 124 | ||||
-rw-r--r-- | sys/dev/ic/bcwreg.h | 4 | ||||
-rw-r--r-- | sys/dev/ic/bcwvar.h | 9 | ||||
-rw-r--r-- | sys/dev/pci/if_bcw_pci.c | 25 |
5 files changed, 130 insertions, 54 deletions
diff --git a/sys/dev/cardbus/if_bcw_cardbus.c b/sys/dev/cardbus/if_bcw_cardbus.c index 38d473c7e0d..3c51ca6cc2f 100644 --- a/sys/dev/cardbus/if_bcw_cardbus.c +++ b/sys/dev/cardbus/if_bcw_cardbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bcw_cardbus.c,v 1.3 2006/11/22 23:46:49 brad Exp $ */ +/* $OpenBSD: if_bcw_cardbus.c,v 1.4 2006/12/06 19:21:45 mglocker Exp $ */ /* * Copyright (c) 2006 Jon Simola <jsimola@gmail.com> @@ -64,6 +64,8 @@ void bcw_cardbus_power(struct bcw_softc *, int); void bcw_cardbus_setup(struct bcw_cardbus_softc *); int bcw_cardbus_enable(struct bcw_softc *); void bcw_cardbus_disable(struct bcw_softc *); +void bcw_cardbus_conf_write(struct bcw_softc *, u_int32_t, u_int32_t); +u_int32_t bcw_cardbus_conf_read(struct bcw_softc *, u_int32_t); struct cfattach bcw_cardbus_ca = { sizeof (struct bcw_cardbus_softc), bcw_cardbus_match, @@ -105,12 +107,18 @@ bcw_cardbus_attach(struct device *parent, struct device *self, void *aux) csc->sc_ct = ct; csc->sc_tag = ca->ca_tag; csc->sc_intrline = ca->ca_intrline; + sc->sc_ca.ca_tag = ca->ca_tag; + sc->sc_ca.ca_ct = ca->ca_ct; /* power management hooks */ sc->sc_enable = bcw_cardbus_enable; sc->sc_disable = bcw_cardbus_disable; sc->sc_power = bcw_cardbus_power; + /* config register read/write functions */ + sc->sc_conf_read = bcw_cardbus_conf_read; + sc->sc_conf_write = bcw_cardbus_conf_write; + /* map control/status registers */ error = Cardbus_mapreg_map(ct, CARDBUS_BASE0_REG, CARDBUS_MAPREG_TYPE_MEM, 0, &sc->sc_iot, @@ -246,3 +254,15 @@ bcw_cardbus_disable(struct bcw_softc *sc) /* power down the socket */ Cardbus_function_disable(ct); } + +void +bcw_cardbus_conf_write(struct bcw_softc *sc, u_int32_t reg, u_int32_t val) +{ + Cardbus_conf_write(sc->sc_ca.ca_ct, sc->sc_ca.ca_tag, reg, val); +} + +u_int32_t +bcw_cardbus_conf_read(struct bcw_softc *sc, u_int32_t reg) +{ + return Cardbus_conf_read(sc->sc_ca.ca_ct, sc->sc_ca.ca_tag, reg); +} diff --git a/sys/dev/ic/bcw.c b/sys/dev/ic/bcw.c index 6721a83e872..7fc3cc176da 100644 --- a/sys/dev/ic/bcw.c +++ b/sys/dev/ic/bcw.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bcw.c,v 1.8 2006/11/29 21:34:06 mglocker Exp $ */ +/* $OpenBSD: bcw.c,v 1.9 2006/12/06 19:21:45 mglocker Exp $ */ /* * Copyright (c) 2006 Jon Simola <jsimola@gmail.com> @@ -56,6 +56,7 @@ #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> #include <dev/pci/pcidevs.h> +#include <dev/cardbus/cardbusvar.h> #include <dev/ic/bcwreg.h> #include <dev/ic/bcwvar.h> @@ -90,6 +91,7 @@ int bcw_media_change(struct ifnet *); void bcw_media_status(struct ifnet *, struct ifmediareq *); /* fashionably new functions */ int bcw_validatechipaccess(struct bcw_softc *); +void bcw_powercontrol_crystal_off(struct bcw_softc *); struct cfdriver bcw_cd = { NULL, "bcw", DV_IFNET @@ -137,20 +139,9 @@ bcw_attach(struct bcw_softc *sc) * below for an example of just figuring out what the chip id is and * how many cores it has. */ - - /* - * XXX Can we read BCW_ADDR_SPACE0 and see if it returns a likely - * Core? On the 4318 that only has an 802.11 core, it always reads as - * some garbage, so if we do a read first we could set a "singlecore" - * flag instead of thrashing around trying to select non-existant - * cores. Testing requires cards that do have multiple cores. This - * would also simplify identifying cards into 3 classes early: - * - Multiple Cores without a Chip Common Core - * - Multiple Cores with a Chip Common Core - * - Single Core - */ - - sbval = bus_space_read_4(sc->sc_iot, sc->sc_ioh, BCW_ADDR_SPACE0); +#if 0 + sbval = pci_conf_read(sc->sc_pa.pa_pc, sc->sc_pa.pa_tag, + BCW_ADDR_SPACE0); if ((sbval & 0xffff0000) != 0x18000000) { DPRINTF(("\n%s: Trial Core read was 0x%x, single core only?\n", sc->sc_dev.dv_xname, sbval)); @@ -158,18 +149,17 @@ bcw_attach(struct bcw_softc *sc) } else DPRINTF(("\n%s: Trial Core read was 0x%x\n", sc->sc_dev.dv_xname, sbval)); - +#endif /* * Try and change to the ChipCommon Core */ for (i = 0; i < 10; i++) { - bus_space_write_4(sc->sc_iot, sc->sc_ioh, BCW_ADDR_SPACE0, - BCW_CORE_SELECT(0)); + (sc->sc_conf_write)(sc, BCW_ADDR_SPACE0, BCW_CORE_SELECT(0)); delay(10); - sbval = bus_space_read_4(sc->sc_iot, sc->sc_ioh, - BCW_ADDR_SPACE0); + sbval = (sc->sc_conf_read)(sc, BCW_ADDR_SPACE0); if (sbval == BCW_CORE_SELECT(0)) { - DPRINTF(("%s: Selected ChipCommon Core\n")); + DPRINTF(("%s: Selected ChipCommon Core\n", + sc->sc_dev.dv_xname)); break; } delay(10); @@ -259,8 +249,8 @@ bcw_attach(struct bcw_softc *sc) break; default: sc->sc_chipid = sc->sc_prodid; - /* XXX educated guess */ - sc->sc_numcores = 1; + /* Set to max */ + sc->sc_numcores = BCW_MAX_CORES; } /* end of switch */ } /* End of if/else */ @@ -270,25 +260,27 @@ bcw_attach(struct bcw_softc *sc) /* Identify each core */ if (sc->sc_numcores >= 2) { /* Exclude single core chips */ - for (i = 0; i <= sc->sc_numcores; i++) { - DPRINTF(("%s: Trying core %d -\n", - sc->sc_dev.dv_xname, i)); - bus_space_write_4(sc->sc_iot, sc->sc_ioh, - BCW_ADDR_SPACE0, BCW_CORE_SELECT(i)); + for (i = 0; i < sc->sc_numcores; i++) { +// DPRINTF(("%s: Trying core %d -\n", +// sc->sc_dev.dv_xname, i)); + (sc->sc_conf_write)(sc, BCW_ADDR_SPACE0, + BCW_CORE_SELECT(i)); /* loop to see if the selected core shows up */ for (j = 0; j < 10; j++) { - sbval=bus_space_read_4(sc->sc_iot, sc->sc_ioh, - BCW_ADDR_SPACE0); - DPRINTF(("%s: read %d for core %d = 0x%x\n", - sc->sc_dev.dv_xname, j, i, sbval)); + sbval = (sc->sc_conf_read)(sc, BCW_ADDR_SPACE0); +// DPRINTF(("%s: read %d for core %d = 0x%x\n", +// sc->sc_dev.dv_xname, j, i, sbval)); if (sbval == BCW_CORE_SELECT(i)) break; delay(10); } - if (j < 10) + if (j < 10) { + sbval = bus_space_read_4(sc->sc_iot, + sc->sc_ioh, BCW_CIR_SBID_HI); DPRINTF(("%s: Found core %d of type 0x%x\n", sc->sc_dev.dv_xname, i, (sbval & 0x00008ff0) >> 4)); - //sc->sc_core[i].id = (sbval & 0x00008ff0) >> 4; + } + sc->sc_core[i].id = (sbval & 0x00008ff0) >> 4; } /* End of For loop */ } @@ -296,15 +288,22 @@ bcw_attach(struct bcw_softc *sc) * XXX Attach cores to the backplane, if we have more than one */ // ??? if (!sc->sc_singlecore) { +#if 0 if (sc->sc_havecommon == 1) { sbval = bus_space_read_4(sc->sc_iot, sc->sc_ioh, BCW_PCICR); sbval |= 0x1 << 8; /* XXX hardcoded bitmask of single core */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, BCW_PCICR, sbval); } - +#endif /* + * XXX Select the 802.11 core, then * Get and display the PHY info from the MIMO */ + for (i=0; i < sc->sc_numcores; i++) { + if (sc->sc_core[i].id == BCW_CORE_80211) + (sc->sc_conf_write)(sc, BCW_ADDR_SPACE0, + BCW_CORE_SELECT(i)); + } sbval = bus_space_read_2(sc->sc_iot, sc->sc_ioh, 0x3E0); sc->sc_phy_version = (sbval&0xf000)>>12; sc->sc_phy_rev = sbval&0xf; @@ -512,8 +511,9 @@ bcw_attach(struct bcw_softc *sc) /* Read antenna gain from SPROM and multiply by 4 */ sbval = bus_space_read_2(sc->sc_iot, sc->sc_ioh, BCW_SPROM_ANTGAIN); /* If unset, assume 2 */ - if((sbval == 0) || (sbval == 0xffff)) sbval = 0x0202; - if(sc->sc_phy_type == BCW_PHY_TYPEA) + if ((sbval == 0) || (sbval == 0xffff)) + sbval = 0x0202; + if (sc->sc_phy_type == BCW_PHY_TYPEA) sc->sc_radio_gain = (sbval & 0xff); else sc->sc_radio_gain = ((sbval & 0xff00) >> 8); @@ -600,9 +600,9 @@ bcw_attach(struct bcw_softc *sc) /* * XXX TODO still for the card attach: * - Disable the 80211 Core (and wrapper for on/off) - * - Powercontrol Crystal Off (and write a wrapper for on/off) * - Setup LEDs to blink in whatever fashionable manner */ + bcw_powercontrol_crystal_off(sc); /* * Allocate DMA-safe memory for ring descriptors. @@ -916,8 +916,7 @@ bcw_intr(void *xsc) sc = xsc; for (wantinit = 0; wantinit == 0;) { - intstatus = bus_space_read_4(sc->sc_iot, sc->sc_ioh, - BCW_INT_STS); + intstatus = (sc->sc_conf_read)(sc, BCW_INT_STS); /* ignore if not ours, or unsolicited interrupts */ intstatus &= sc->sc_intmask; @@ -927,8 +926,7 @@ bcw_intr(void *xsc) handled = 1; /* Ack interrupt */ - bus_space_write_4(sc->sc_iot, sc->sc_ioh, BCW_INT_STS, - intstatus); + (sc->sc_conf_write)(sc, BCW_INT_STS, intstatus); /* Receive interrupts. */ if (intstatus & I_RI) @@ -1375,12 +1373,22 @@ bcw_reset(struct bcw_softc *sc) u_int32_t val; u_int32_t reject; + /* Really stupid PCI space dump */ +#if 0 + for (i=0xe00; i<0x1000; i+=4) { + if ((i % 16) == 0) + DPRINTF(("%s: 0x%04x - ",sc->sc_dev.dv_xname, i)); + DPRINTF(("0x%08x ",bus_space_read_4(sc->sc_iot, sc->sc_ioh,i))); + if ((i % 16) == 12) DPRINTF(("\n")); + } +#endif /* * Figure out what revision the Sonic Backplane is, as the position * of the Reject bit changed. Save the revision in the softc, and * use the local variable 'reject' in all the bit banging. */ sbval = bus_space_read_4(sc->sc_iot, sc->sc_ioh, BCW_CIR_SBID_LO); + sc->sc_sbrev = (sbval & SBREV_MASK) >> SBREV_MASK_SHIFT; switch (sc->sc_sbrev) { case 0: @@ -2129,15 +2137,37 @@ bcw_powercontrol_crystal_on(struct bcw_softc *sc) { u_int32_t sbval; - sbval = bus_space_read_4(sc->sc_iot, sc->sc_ioh, BCW_GPIOI); + sbval = (sc->sc_conf_read)(sc, BCW_GPIOI); if ((sbval & BCW_XTALPOWERUP) != BCW_XTALPOWERUP) { - sbval = bus_space_read_4(sc->sc_iot, sc->sc_ioh, BCW_GPIOO); + sbval = (sc->sc_conf_read)(sc, BCW_GPIOO); sbval |= (BCW_XTALPOWERUP & BCW_PLLPOWERDOWN); - bus_space_write_4(sc->sc_iot, sc->sc_ioh, BCW_GPIOO, sbval); + (sc->sc_conf_write)(sc, BCW_GPIOO, sbval); delay(1000); - sbval = bus_space_read_4(sc->sc_iot, sc->sc_ioh, BCW_GPIOO); + sbval = (sc->sc_conf_read)(sc, BCW_GPIOO); sbval &= ~BCW_PLLPOWERDOWN; - bus_space_write_4(sc->sc_iot, sc->sc_ioh, BCW_GPIOO, sbval); + (sc->sc_conf_write)(sc, BCW_GPIOO, sbval); delay(5000); } } + +void +bcw_powercontrol_crystal_off(struct bcw_softc *sc) +{ + u_int32_t sbval; + + /* XXX Return if radio is hardware disabled */ + if (sc->sc_corerev < 5) + return; + if ((sc->sc_boardflags & BCW_BF_XTAL) == BCW_BF_XTAL) + return; + + /* XXX bcw_powercontrol_clock_slow() */ + + sbval = (sc->sc_conf_read)(sc, BCW_GPIOO); + sbval |= BCW_PLLPOWERDOWN; + sbval &= ~BCW_XTALPOWERUP; + (sc->sc_conf_write)(sc, BCW_GPIOO, sbval); + sbval = (sc->sc_conf_read)(sc, BCW_GPIOE); + sbval |= BCW_PLLPOWERDOWN | BCW_XTALPOWERUP; + (sc->sc_conf_write)(sc, BCW_GPIOE, sbval); +} diff --git a/sys/dev/ic/bcwreg.h b/sys/dev/ic/bcwreg.h index 2c6e30d9d0d..19b17661ad1 100644 --- a/sys/dev/ic/bcwreg.h +++ b/sys/dev/ic/bcwreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bcwreg.h,v 1.4 2006/11/24 20:27:41 mglocker Exp $ */ +/* $OpenBSD: bcwreg.h,v 1.5 2006/12/06 19:21:45 mglocker Exp $ */ /* * Copyright (c) 2006 Jon Simola <jsimola@gmail.com> @@ -52,9 +52,11 @@ #define BCW_CORE_COMMON 0x800 #define BCW_CORE_PCI 0x804 #define BCW_CORE_ENET 0x806 +#define BCW_CORE_PCMCIA 0x80d #define BCW_CORE_80211 0x812 #define BCW_CORE_PCIE 0x820 #define BCW_CORE_MIMOPHY 0x821 +#define BCW_CORE_NONEXIST 0x8ff #define BCW_CORE_COMMON_CHIPID 0x0 diff --git a/sys/dev/ic/bcwvar.h b/sys/dev/ic/bcwvar.h index 08f59231442..b857cb374a4 100644 --- a/sys/dev/ic/bcwvar.h +++ b/sys/dev/ic/bcwvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bcwvar.h,v 1.7 2006/11/29 21:34:06 mglocker Exp $ */ +/* $OpenBSD: bcwvar.h,v 1.8 2006/12/06 19:21:45 mglocker Exp $ */ /* * Copyright (c) 2006 Jon Simola <jsimola@gmail.com> @@ -128,6 +128,10 @@ struct bcw_softc { int (*sc_enable)(struct bcw_softc *); void (*sc_disable)(struct bcw_softc *); void (*sc_power)(struct bcw_softc *, int); + void (*sc_conf_write)(struct bcw_softc *, + u_int32_t, u_int32_t); + u_int32_t (*sc_conf_read)(struct bcw_softc *, u_int32_t); + struct timeout sc_scan_to; bus_dma_tag_t sc_dmat; @@ -137,6 +141,7 @@ struct bcw_softc { void *bcw_intrhand; const char *bcw_intrstr; /* interrupt description */ struct pci_attach_args sc_pa; + struct cardbus_attach_args sc_ca; u_int32_t sc_phy; /* eeprom indicated phy */ struct bcw_dma_slot *bcw_rx_ring; /* receive ring */ struct bcw_dma_slot *bcw_tx_ring; /* transmit ring */ @@ -152,7 +157,7 @@ struct bcw_softc { u_int16_t sc_chipid; /* Chip ID */ u_int16_t sc_chiprev; /* Chip Revision */ u_int16_t sc_prodid; /* Product ID */ -// struct bcw_core core[BCW_MAX_CORES]; + struct bcw_core sc_core[BCW_MAX_CORES]; // struct bcw_radio radio[BCW_MAX_RADIOS]; u_int16_t sc_phy_version; u_int16_t sc_phy_type; diff --git a/sys/dev/pci/if_bcw_pci.c b/sys/dev/pci/if_bcw_pci.c index a1bd93e0dff..b38f74e3194 100644 --- a/sys/dev/pci/if_bcw_pci.c +++ b/sys/dev/pci/if_bcw_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bcw_pci.c,v 1.5 2006/11/29 21:34:06 mglocker Exp $ */ +/* $OpenBSD: if_bcw_pci.c,v 1.6 2006/12/06 19:21:45 mglocker Exp $ */ /* * Copyright (c) 2006 Jon Simola <jsimola@gmail.com> @@ -60,6 +60,7 @@ #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> #include <dev/pci/pcidevs.h> +#include <dev/cardbus/cardbusvar.h> #include <dev/ic/bcwreg.h> #include <dev/ic/bcwvar.h> @@ -95,6 +96,8 @@ int bcw_pci_match(struct device *, void *, void *); int bcw_pci_enable(struct bcw_softc *sc); void bcw_pci_disable(struct bcw_softc *sc); void bcw_pci_attach(struct device *, struct device *, void *); +void bcw_pci_conf_write(struct bcw_softc *, u_int32_t, u_int32_t); +u_int32_t bcw_pci_conf_read(struct bcw_softc *, u_int32_t); struct cfattach bcw_pci_ca = { sizeof(struct bcw_pci_softc), bcw_pci_match, bcw_pci_attach @@ -150,6 +153,8 @@ bcw_pci_attach(struct device *parent, struct device *self, void *aux) psc->psc_pc = pa->pa_pc; psc->psc_pcitag = pa->pa_tag; + sc->sc_pa.pa_pc = pa->pa_pc; + sc->sc_pa.pa_tag = pa->pa_tag; /* Get it out of power save mode if needed. */ if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT, &pmreg, 0)) { @@ -216,6 +221,8 @@ bcw_pci_attach(struct device *parent, struct device *self, void *aux) sc->sc_enable = bcw_pci_enable; sc->sc_disable = bcw_pci_disable; + sc->sc_conf_write = bcw_pci_conf_write; + sc->sc_conf_read = bcw_pci_conf_read; /* * Get some PCI based info into the softc @@ -234,9 +241,9 @@ bcw_pci_attach(struct device *parent, struct device *self, void *aux) * Clear PCI_STATUS_TARGET_TARGET_ABORT, Docs and Linux call it * PCI_STATUS_SIG_TARGET_ABORT - should use pci_conf_read/write? */ - bus_space_write_4(sc->sc_iot, sc->sc_ioh, + pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, - bus_space_read_4(sc->sc_iot, sc->sc_ioh, + pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) & ~PCI_STATUS_TARGET_TARGET_ABORT); @@ -247,3 +254,15 @@ bcw_pci_attach(struct device *parent, struct device *self, void *aux) bcw_attach(sc); } + +void +bcw_pci_conf_write(struct bcw_softc *sc, u_int32_t reg, u_int32_t val) +{ + pci_conf_write(sc->sc_pa.pa_pc, sc->sc_pa.pa_tag, reg, val); +} + +u_int32_t +bcw_pci_conf_read(struct bcw_softc *sc, u_int32_t reg) +{ + return pci_conf_read(sc->sc_pa.pa_pc, sc->sc_pa.pa_tag, reg); +} |