svn commit: r206928 - in stable/8/sys: dev/siba modules/siba_bwn
Weongyo Jeong
weongyo at FreeBSD.org
Tue Apr 20 21:29:54 UTC 2010
Author: weongyo
Date: Tue Apr 20 21:29:53 2010
New Revision: 206928
URL: http://svn.freebsd.org/changeset/base/206928
Log:
MFC r203319:
Adds siba_bwn module which is used with bwn(4). Main purpose of this
module is to distinguish parts of Silicon Backplane and of Broadcom
Wireless.
Added:
stable/8/sys/dev/siba/siba_bwn.c
- copied unchanged from r203319, head/sys/dev/siba/siba_bwn.c
stable/8/sys/dev/siba/siba_core.c
- copied unchanged from r203319, head/sys/dev/siba/siba_core.c
stable/8/sys/modules/siba_bwn/
- copied from r203319, head/sys/modules/siba_bwn/
Modified:
stable/8/sys/dev/siba/siba.c
stable/8/sys/dev/siba/siba_cc.c (contents, props changed)
stable/8/sys/dev/siba/siba_ids.h
stable/8/sys/dev/siba/siba_pcib.c
stable/8/sys/dev/siba/sibareg.h
stable/8/sys/dev/siba/sibavar.h
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/dev/uath/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/xen/xenpci/ (props changed)
Modified: stable/8/sys/dev/siba/siba.c
==============================================================================
--- stable/8/sys/dev/siba/siba.c Tue Apr 20 21:24:32 2010 (r206927)
+++ stable/8/sys/dev/siba/siba.c Tue Apr 20 21:29:53 2010 (r206928)
@@ -37,9 +37,9 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
-#include <dev/siba/sibavar.h>
-#include <dev/siba/sibareg.h>
#include <dev/siba/siba_ids.h>
+#include <dev/siba/sibareg.h>
+#include <dev/siba/sibavar.h>
/*
* TODO: De-mipsify this code.
@@ -77,7 +77,7 @@ static struct siba_devid siba_devids[] =
"MIPS core" },
{ SIBA_VID_BROADCOM, SIBA_DEVID_ETHERNET, SIBA_REV_ANY,
"Ethernet core" },
- { SIBA_VID_BROADCOM, SIBA_DEVID_USB, SIBA_REV_ANY,
+ { SIBA_VID_BROADCOM, SIBA_DEVID_USB11_HOSTDEV, SIBA_REV_ANY,
"USB host controller" },
{ SIBA_VID_BROADCOM, SIBA_DEVID_IPSEC, SIBA_REV_ANY,
"IPSEC accelerator" },
@@ -103,7 +103,6 @@ static struct siba_devid *
static struct resource_list *
siba_get_reslist(device_t, device_t);
static uint8_t siba_getirq(uint16_t);
-static uint8_t siba_getncores(uint16_t);
static int siba_print_all_resources(device_t dev);
static int siba_print_child(device_t, device_t);
static int siba_probe(device_t);
@@ -112,30 +111,7 @@ int siba_read_ivar(device_t, device_t,
static struct siba_devinfo *
siba_setup_devinfo(device_t, uint8_t);
int siba_write_ivar(device_t, device_t, int, uintptr_t);
-
-/*
- * Earlier ChipCommon revisions have hardcoded number of cores
- * present dependent on the ChipCommon ID.
- */
-static uint8_t
-siba_getncores(uint16_t ccid)
-{
- uint8_t ncores;
-
- switch (ccid) {
- case SIBA_CCID_SENTRY5:
- ncores = 7;
- break;
- case SIBA_CCID_BCM4710:
- case SIBA_CCID_BCM4704:
- ncores = 9;
- break;
- default:
- ncores = 0;
- }
-
- return (ncores);
-}
+uint8_t siba_getncores(device_t, uint16_t);
/*
* On the Sentry5, the system bus IRQs are the same as the
@@ -156,7 +132,7 @@ siba_getirq(uint16_t devid)
case SIBA_DEVID_IPSEC:
irq = 2;
break;
- case SIBA_DEVID_USB:
+ case SIBA_DEVID_USB11_HOSTDEV:
irq = 3;
break;
case SIBA_DEVID_PCI:
@@ -188,7 +164,7 @@ siba_probe(device_t dev)
uint16_t ccid;
int rid;
- sc->sc_dev = dev;
+ sc->siba_dev = dev;
//rman_debug = 1; /* XXX */
@@ -197,24 +173,24 @@ siba_probe(device_t dev)
* was compiled with.
*/
rid = MIPS_MEM_RID;
- sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+ sc->siba_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
- if (sc->sc_mem == NULL) {
+ if (sc->siba_mem_res == NULL) {
device_printf(dev, "unable to allocate probe aperture\n");
return (ENXIO);
}
- sc->sc_bt = rman_get_bustag(sc->sc_mem);
- sc->sc_bh = rman_get_bushandle(sc->sc_mem);
- sc->sc_maddr = rman_get_start(sc->sc_mem);
- sc->sc_msize = rman_get_size(sc->sc_mem);
+ sc->siba_mem_bt = rman_get_bustag(sc->siba_mem_res);
+ sc->siba_mem_bh = rman_get_bushandle(sc->siba_mem_res);
+ sc->siba_maddr = rman_get_start(sc->siba_mem_res);
+ sc->siba_msize = rman_get_size(sc->siba_mem_res);
if (siba_debug) {
device_printf(dev, "start %08x len %08x\n",
- sc->sc_maddr, sc->sc_msize);
+ sc->siba_maddr, sc->siba_msize);
}
- idlo = siba_read_4(sc, 0, SIBA_CORE_IDLO);
- idhi = siba_read_4(sc, 0, SIBA_CORE_IDHI);
+ idlo = siba_mips_read_4(sc, 0, SIBA_IDLOW);
+ idhi = siba_mips_read_4(sc, 0, SIBA_IDHIGH);
ccid = ((idhi & 0x8ff0) >> 4);
if (siba_debug) {
device_printf(dev, "idlo = %08x\n", idlo);
@@ -256,7 +232,7 @@ siba_probe(device_t dev)
uint16_t cc_id;
uint16_t cc_rev;
- ccidreg = siba_read_4(sc, 0, SIBA_CC_CCID);
+ ccidreg = siba_mips_read_4(sc, 0, SIBA_CC_CHIPID);
cc_id = (ccidreg & SIBA_CC_IDMASK);
cc_rev = (ccidreg & SIBA_CC_REVMASK) >> SIBA_CC_REVSHIFT;
if (siba_debug) {
@@ -264,9 +240,9 @@ siba_probe(device_t dev)
ccidreg, cc_id, cc_rev);
}
- sc->sc_ncores = siba_getncores(cc_id);
+ sc->siba_ncores = siba_getncores(dev, cc_id);
if (siba_debug) {
- device_printf(dev, "%d cores detected.\n", sc->sc_ncores);
+ device_printf(dev, "%d cores detected.\n", sc->siba_ncores);
}
/*
@@ -275,36 +251,38 @@ siba_probe(device_t dev)
*/
rid = MIPS_MEM_RID;
int result;
- result = bus_release_resource(dev, SYS_RES_MEMORY, rid, sc->sc_mem);
+ result = bus_release_resource(dev, SYS_RES_MEMORY, rid,
+ sc->siba_mem_res);
if (result != 0) {
device_printf(dev, "error %d releasing resource\n", result);
return (ENXIO);
}
uint32_t total;
- total = sc->sc_ncores * SIBA_CORE_LEN;
+ total = sc->siba_ncores * SIBA_CORE_LEN;
/* XXX Don't allocate the entire window until we
* enumerate the bus. Once the bus has been enumerated,
* and instance variables/children instantiated + populated,
* release the resource so children may attach.
*/
- sc->sc_mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
- sc->sc_maddr, sc->sc_maddr + total - 1, total, RF_ACTIVE);
- if (sc->sc_mem == NULL) {
+ sc->siba_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
+ sc->siba_maddr, sc->siba_maddr + total - 1, total, RF_ACTIVE);
+ if (sc->siba_mem_res == NULL) {
device_printf(dev, "unable to allocate entire aperture\n");
return (ENXIO);
}
- sc->sc_bt = rman_get_bustag(sc->sc_mem);
- sc->sc_bh = rman_get_bushandle(sc->sc_mem);
- sc->sc_maddr = rman_get_start(sc->sc_mem);
- sc->sc_msize = rman_get_size(sc->sc_mem);
+ sc->siba_mem_bt = rman_get_bustag(sc->siba_mem_res);
+ sc->siba_mem_bh = rman_get_bushandle(sc->siba_mem_res);
+ sc->siba_maddr = rman_get_start(sc->siba_mem_res);
+ sc->siba_msize = rman_get_size(sc->siba_mem_res);
if (siba_debug) {
device_printf(dev, "after remapping: start %08x len %08x\n",
- sc->sc_maddr, sc->sc_msize);
+ sc->siba_maddr, sc->siba_msize);
}
- bus_set_resource(dev, SYS_RES_MEMORY, rid, sc->sc_maddr, sc->sc_msize);
+ bus_set_resource(dev, SYS_RES_MEMORY, rid, sc->siba_maddr,
+ sc->siba_msize);
/*
* We need a manager for the space we claim on nexus to
@@ -313,12 +291,13 @@ siba_probe(device_t dev)
* otherwise it may be claimed elsewhere.
* XXX move to softc
*/
- mem_rman.rm_start = sc->sc_maddr;
- mem_rman.rm_end = sc->sc_maddr + sc->sc_msize - 1;
+ mem_rman.rm_start = sc->siba_maddr;
+ mem_rman.rm_end = sc->siba_maddr + sc->siba_msize - 1;
mem_rman.rm_type = RMAN_ARRAY;
mem_rman.rm_descr = "SiBa I/O memory addresses";
if (rman_init(&mem_rman) != 0 ||
- rman_manage_region(&mem_rman, mem_rman.rm_start, mem_rman.rm_end) != 0) {
+ rman_manage_region(&mem_rman, mem_rman.rm_start,
+ mem_rman.rm_end) != 0) {
panic("%s: mem_rman", __func__);
}
@@ -344,7 +323,7 @@ siba_attach(device_t dev)
* NB: only one core may be mapped at any time if the siba bus
* is the child of a PCI or PCMCIA bus.
*/
- for (idx = 0; idx < sc->sc_ncores; idx++) {
+ for (idx = 0; idx < sc->siba_ncores; idx++) {
sdi = siba_setup_devinfo(dev, idx);
child = device_add_child(dev, NULL, -1);
if (child == NULL)
@@ -483,13 +462,14 @@ siba_setup_devinfo(device_t dev, uint8_t
sdi = malloc(sizeof(*sdi), M_DEVBUF, M_WAITOK | M_ZERO);
resource_list_init(&sdi->sdi_rl);
- idlo = siba_read_4(sc, idx, SIBA_CORE_IDLO);
- idhi = siba_read_4(sc, idx, SIBA_CORE_IDHI);
+ idlo = siba_mips_read_4(sc, idx, SIBA_IDLOW);
+ idhi = siba_mips_read_4(sc, idx, SIBA_IDHIGH);
- vendorid = (idhi & SIBA_IDHIGH_VC) >> SIBA_IDHIGH_VC_SHIFT;
+ vendorid = (idhi & SIBA_IDHIGH_VENDORMASK) >>
+ SIBA_IDHIGH_VENDOR_SHIFT;
devid = ((idhi & 0x8ff0) >> 4);
- rev = (idhi & SIBA_IDHIGH_RCLO);
- rev |= (idhi & SIBA_IDHIGH_RCHI) >> SIBA_IDHIGH_RCHI_SHIFT;
+ rev = (idhi & SIBA_IDHIGH_REVLO);
+ rev |= (idhi & SIBA_IDHIGH_REVHI) >> SIBA_IDHIGH_REVHI_SHIFT;
sdi->sdi_vid = vendorid;
sdi->sdi_devid = devid;
@@ -500,7 +480,7 @@ siba_setup_devinfo(device_t dev, uint8_t
/*
* Determine memory window on bus and irq if one is needed.
*/
- baseaddr = sc->sc_maddr + (idx * SIBA_CORE_LEN);
+ baseaddr = sc->siba_maddr + (idx * SIBA_CORE_LEN);
resource_list_add(&sdi->sdi_rl, SYS_RES_MEMORY,
MIPS_MEM_RID, /* XXX */
baseaddr, baseaddr + SIBA_CORE_LEN - 1, SIBA_CORE_LEN);
Copied: stable/8/sys/dev/siba/siba_bwn.c (from r203319, head/sys/dev/siba/siba_bwn.c)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ stable/8/sys/dev/siba/siba_bwn.c Tue Apr 20 21:29:53 2010 (r206928, copy of r203319, head/sys/dev/siba/siba_bwn.c)
@@ -0,0 +1,366 @@
+/*-
+ * Copyright (c) 2009-2010 Weongyo Jeong <weongyo at freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Sonics Silicon Backplane front-end for bwn(4).
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/module.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/errno.h>
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <net/if_media.h>
+#include <net/if_arp.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+
+#include <dev/siba/siba_ids.h>
+#include <dev/siba/sibareg.h>
+#include <dev/siba/sibavar.h>
+
+/*
+ * PCI glue.
+ */
+
+struct siba_bwn_softc {
+ /* Child driver using MSI. */
+ device_t ssc_msi_child;
+ struct siba_softc ssc_siba;
+};
+
+#define BS_BAR 0x10
+#define PCI_VENDOR_BROADCOM 0x14e4
+#define N(a) (sizeof(a) / sizeof(a[0]))
+
+static const struct siba_dev {
+ uint16_t vid;
+ uint16_t did;
+ const char *desc;
+} siba_devices[] = {
+ { PCI_VENDOR_BROADCOM, 0x4301, "Broadcom BCM4301 802.11b Wireless" },
+ { PCI_VENDOR_BROADCOM, 0x4306, "Unknown" },
+ { PCI_VENDOR_BROADCOM, 0x4307, "Broadcom BCM4307 802.11b Wireless" },
+ { PCI_VENDOR_BROADCOM, 0x4311, "Broadcom BCM4311 802.11b/g Wireless" },
+ { PCI_VENDOR_BROADCOM, 0x4312,
+ "Broadcom BCM4312 802.11a/b/g Wireless" },
+ { PCI_VENDOR_BROADCOM, 0x4315, "Broadcom BCM4312 802.11b/g Wireless" },
+ { PCI_VENDOR_BROADCOM, 0x4318, "Broadcom BCM4318 802.11b/g Wireless" },
+ { PCI_VENDOR_BROADCOM, 0x4319,
+ "Broadcom BCM4318 802.11a/b/g Wireless" },
+ { PCI_VENDOR_BROADCOM, 0x4320, "Broadcom BCM4306 802.11b/g Wireless" },
+ { PCI_VENDOR_BROADCOM, 0x4321, "Broadcom BCM4306 802.11a Wireless" },
+ { PCI_VENDOR_BROADCOM, 0x4324,
+ "Broadcom BCM4309 802.11a/b/g Wireless" },
+ { PCI_VENDOR_BROADCOM, 0x4325, "Broadcom BCM4306 802.11b/g Wireless" },
+ { PCI_VENDOR_BROADCOM, 0x4328, "Unknown" },
+ { PCI_VENDOR_BROADCOM, 0x4329, "Unknown" },
+ { PCI_VENDOR_BROADCOM, 0x432b, "Unknown" }
+};
+
+device_t siba_add_child(device_t, struct siba_softc *, int, const char *,
+ int);
+int siba_core_attach(struct siba_softc *);
+int siba_core_detach(struct siba_softc *);
+int siba_core_suspend(struct siba_softc *);
+int siba_core_resume(struct siba_softc *);
+
+static int
+siba_bwn_probe(device_t dev)
+{
+ int i;
+ uint16_t did, vid;
+
+ did = pci_get_device(dev);
+ vid = pci_get_vendor(dev);
+
+ for (i = 0; i < N(siba_devices); i++) {
+ if (siba_devices[i].did == did && siba_devices[i].vid == vid) {
+ device_set_desc(dev, siba_devices[i].desc);
+ return (BUS_PROBE_DEFAULT);
+ }
+ }
+ return (ENXIO);
+}
+
+static int
+siba_bwn_attach(device_t dev)
+{
+ struct siba_bwn_softc *ssc = device_get_softc(dev);
+ struct siba_softc *siba = &ssc->ssc_siba;
+
+ siba->siba_dev = dev;
+ siba->siba_type = SIBA_TYPE_PCI;
+
+ /*
+ * Enable bus mastering.
+ */
+ pci_enable_busmaster(dev);
+
+ /*
+ * Setup memory-mapping of PCI registers.
+ */
+ siba->siba_mem_rid = SIBA_PCIR_BAR;
+ siba->siba_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+ &siba->siba_mem_rid, RF_ACTIVE);
+ if (siba->siba_mem_res == NULL) {
+ device_printf(dev, "cannot map register space\n");
+ return (ENXIO);
+ }
+ siba->siba_mem_bt = rman_get_bustag(siba->siba_mem_res);
+ siba->siba_mem_bh = rman_get_bushandle(siba->siba_mem_res);
+
+ /* Get more PCI information */
+ siba->siba_pci_did = pci_get_device(dev);
+ siba->siba_pci_vid = pci_get_vendor(dev);
+ siba->siba_pci_subvid = pci_get_subvendor(dev);
+ siba->siba_pci_subdid = pci_get_subdevice(dev);
+
+ return (siba_core_attach(siba));
+}
+
+static int
+siba_bwn_detach(device_t dev)
+{
+ struct siba_bwn_softc *ssc = device_get_softc(dev);
+ struct siba_softc *siba = &ssc->ssc_siba;
+
+ /* check if device was removed */
+ siba->siba_invalid = !bus_child_present(dev);
+
+ pci_disable_busmaster(dev);
+ bus_generic_detach(dev);
+ siba_core_detach(siba);
+
+ bus_release_resource(dev, SYS_RES_MEMORY, BS_BAR, siba->siba_mem_res);
+
+ return (0);
+}
+
+static int
+siba_bwn_shutdown(device_t dev)
+{
+ device_t *devlistp;
+ int devcnt, error = 0, i;
+
+ error = device_get_children(dev, &devlistp, &devcnt);
+ if (error != 0)
+ return (error);
+
+ for (i = 0 ; i < devcnt ; i++)
+ device_shutdown(devlistp[i]);
+ free(devlistp, M_TEMP);
+ return (0);
+}
+
+static int
+siba_bwn_suspend(device_t dev)
+{
+ struct siba_bwn_softc *ssc = device_get_softc(dev);
+ struct siba_softc *siba = &ssc->ssc_siba;
+ device_t *devlistp;
+ int devcnt, error = 0, i, j;
+
+ error = device_get_children(dev, &devlistp, &devcnt);
+ if (error != 0)
+ return (error);
+
+ for (i = 0 ; i < devcnt ; i++) {
+ error = DEVICE_SUSPEND(devlistp[i]);
+ if (error) {
+ for (j = 0; j < i; i++)
+ DEVICE_RESUME(devlistp[j]);
+ return (error);
+ }
+ }
+ free(devlistp, M_TEMP);
+ return (siba_core_suspend(siba));
+}
+
+static int
+siba_bwn_resume(device_t dev)
+{
+ struct siba_bwn_softc *ssc = device_get_softc(dev);
+ struct siba_softc *siba = &ssc->ssc_siba;
+ device_t *devlistp;
+ int devcnt, error = 0, i;
+
+ error = siba_core_resume(siba);
+ if (error != 0)
+ return (error);
+
+ error = device_get_children(dev, &devlistp, &devcnt);
+ if (error != 0)
+ return (error);
+
+ for (i = 0 ; i < devcnt ; i++)
+ DEVICE_RESUME(devlistp[i]);
+ free(devlistp, M_TEMP);
+ return (0);
+}
+
+static device_t
+siba_bwn_add_child(device_t dev, int order, const char *name, int unit)
+{
+ struct siba_bwn_softc *ssc = device_get_softc(dev);
+ struct siba_softc *siba = &ssc->ssc_siba;
+
+ return (siba_add_child(dev, siba, order, name, unit));
+}
+
+/* proxying to the parent */
+static struct resource *
+siba_bwn_alloc_resource(device_t dev, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+
+ return (BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
+ type, rid, start, end, count, flags));
+}
+
+/* proxying to the parent */
+static int
+siba_bwn_release_resource(device_t dev, device_t child, int type,
+ int rid, struct resource *r)
+{
+
+ return (BUS_RELEASE_RESOURCE(device_get_parent(dev), dev, type,
+ rid, r));
+}
+
+/* proxying to the parent */
+static int
+siba_bwn_setup_intr(device_t dev, device_t child, struct resource *irq,
+ int flags, driver_filter_t *filter, driver_intr_t *intr, void *arg,
+ void **cookiep)
+{
+
+ return (BUS_SETUP_INTR(device_get_parent(dev), dev, irq, flags,
+ filter, intr, arg, cookiep));
+}
+
+/* proxying to the parent */
+static int
+siba_bwn_teardown_intr(device_t dev, device_t child, struct resource *irq,
+ void *cookie)
+{
+
+ return (BUS_TEARDOWN_INTR(device_get_parent(dev), dev, irq, cookie));
+}
+
+static int
+siba_bwn_find_extcap(device_t dev, device_t child, int capability,
+ int *capreg)
+{
+
+ return (pci_find_extcap(dev, capability, capreg));
+}
+
+static int
+siba_bwn_alloc_msi(device_t dev, device_t child, int *count)
+{
+ struct siba_bwn_softc *ssc;
+ int error;
+
+ ssc = device_get_softc(dev);
+ if (ssc->ssc_msi_child != NULL)
+ return (EBUSY);
+ error = pci_alloc_msi(dev, count);
+ if (error == 0)
+ ssc->ssc_msi_child = child;
+ return (error);
+}
+
+static int
+siba_bwn_release_msi(device_t dev, device_t child)
+{
+ struct siba_bwn_softc *ssc;
+ int error;
+
+ ssc = device_get_softc(dev);
+ if (ssc->ssc_msi_child != child)
+ return (ENXIO);
+ error = pci_release_msi(dev);
+ if (error == 0)
+ ssc->ssc_msi_child = NULL;
+ return (error);
+}
+
+static int
+siba_bwn_msi_count(device_t dev, device_t child)
+{
+
+ return (pci_msi_count(dev));
+}
+
+static device_method_t siba_bwn_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, siba_bwn_probe),
+ DEVMETHOD(device_attach, siba_bwn_attach),
+ DEVMETHOD(device_detach, siba_bwn_detach),
+ DEVMETHOD(device_shutdown, siba_bwn_shutdown),
+ DEVMETHOD(device_suspend, siba_bwn_suspend),
+ DEVMETHOD(device_resume, siba_bwn_resume),
+
+ /* Bus interface */
+ DEVMETHOD(bus_add_child, siba_bwn_add_child),
+ DEVMETHOD(bus_alloc_resource, siba_bwn_alloc_resource),
+ DEVMETHOD(bus_release_resource, siba_bwn_release_resource),
+ DEVMETHOD(bus_setup_intr, siba_bwn_setup_intr),
+ DEVMETHOD(bus_teardown_intr, siba_bwn_teardown_intr),
+
+ /* PCI interface */
+ DEVMETHOD(pci_find_extcap, siba_bwn_find_extcap),
+ DEVMETHOD(pci_alloc_msi, siba_bwn_alloc_msi),
+ DEVMETHOD(pci_release_msi, siba_bwn_release_msi),
+ DEVMETHOD(pci_msi_count, siba_bwn_msi_count),
+
+ { 0,0 }
+};
+static driver_t siba_bwn_driver = {
+ "siba_bwn",
+ siba_bwn_methods,
+ sizeof(struct siba_bwn_softc)
+};
+static devclass_t siba_bwn_devclass;
+DRIVER_MODULE(siba_bwn, pci, siba_bwn_driver, siba_bwn_devclass, 0, 0);
+MODULE_VERSION(siba_bwn, 1);
Modified: stable/8/sys/dev/siba/siba_cc.c
==============================================================================
--- stable/8/sys/dev/siba/siba_cc.c Tue Apr 20 21:24:32 2010 (r206927)
+++ stable/8/sys/dev/siba/siba_cc.c Tue Apr 20 21:29:53 2010 (r206928)
@@ -55,9 +55,9 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
-#include <dev/siba/sibavar.h>
-#include <dev/siba/sibareg.h>
#include <dev/siba/siba_ids.h>
+#include <dev/siba/sibareg.h>
+#include <dev/siba/sibavar.h>
static int siba_cc_attach(device_t);
static int siba_cc_probe(device_t);
Copied: stable/8/sys/dev/siba/siba_core.c (from r203319, head/sys/dev/siba/siba_core.c)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ stable/8/sys/dev/siba/siba_core.c Tue Apr 20 21:29:53 2010 (r206928, copy of r203319, head/sys/dev/siba/siba_core.c)
@@ -0,0 +1,2007 @@
+/*-
+ * Copyright (c) 2009-2010 Weongyo Jeong <weongyo at freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * the Sonics Silicon Backplane driver.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/module.h>
+#include <sys/kernel.h>
+#include <sys/endian.h>
+#include <sys/errno.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <net/if_media.h>
+#include <net/if_arp.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+
+#include <dev/siba/siba_ids.h>
+#include <dev/siba/sibareg.h>
+#include <dev/siba/sibavar.h>
+
+#ifdef SIBA_DEBUG
+enum {
+ SIBA_DEBUG_SCAN = 0x00000001, /* scan */
+ SIBA_DEBUG_PMU = 0x00000002, /* PMU */
+ SIBA_DEBUG_PLL = 0x00000004, /* PLL */
+ SIBA_DEBUG_SWITCHCORE = 0x00000008, /* switching core */
+ SIBA_DEBUG_SPROM = 0x00000010, /* SPROM */
+ SIBA_DEBUG_CORE = 0x00000020, /* handling cores */
+ SIBA_DEBUG_ANY = 0xffffffff
+};
+#define DPRINTF(siba, m, fmt, ...) do { \
+ if (siba->siba_debug & (m)) \
+ printf(fmt, __VA_ARGS__); \
+} while (0)
+#else
+#define DPRINTF(siba, m, fmt, ...) do { (void) siba; } while (0)
+#endif
+#define N(a) (sizeof(a) / sizeof(a[0]))
+
+static void siba_pci_gpio(struct siba_softc *, uint32_t, int);
+static void siba_scan(struct siba_softc *);
+static int siba_switchcore(struct siba_softc *, uint8_t);
+static int siba_pci_switchcore_sub(struct siba_softc *, uint8_t);
+static uint32_t siba_scan_read_4(struct siba_softc *, uint8_t, uint16_t);
+static uint16_t siba_dev2chipid(struct siba_softc *);
+static uint16_t siba_pci_read_2(struct siba_dev_softc *, uint16_t);
+static uint32_t siba_pci_read_4(struct siba_dev_softc *, uint16_t);
+static void siba_pci_write_2(struct siba_dev_softc *, uint16_t, uint16_t);
+static void siba_pci_write_4(struct siba_dev_softc *, uint16_t, uint32_t);
+static void siba_cc_clock(struct siba_cc *,
+ enum siba_clock);
+static void siba_cc_pmu_init(struct siba_cc *);
+static void siba_cc_power_init(struct siba_cc *);
+static void siba_cc_powerup_delay(struct siba_cc *);
+static int siba_cc_clockfreq(struct siba_cc *, int);
+static void siba_cc_pmu1_pll0_init(struct siba_cc *, uint32_t);
+static void siba_cc_pmu0_pll0_init(struct siba_cc *, uint32_t);
+static enum siba_clksrc siba_cc_clksrc(struct siba_cc *);
+static const struct siba_cc_pmu1_plltab *siba_cc_pmu1_plltab_find(uint32_t);
+static uint32_t siba_cc_pll_read(struct siba_cc *, uint32_t);
+static void siba_cc_pll_write(struct siba_cc *, uint32_t,
+ uint32_t);
+static const struct siba_cc_pmu0_plltab *
+ siba_cc_pmu0_plltab_findentry(uint32_t);
+static int siba_pci_sprom(struct siba_softc *, struct siba_sprom *);
+static int siba_sprom_read(struct siba_softc *, uint16_t *, uint16_t);
+static int sprom_check_crc(const uint16_t *, size_t);
+static uint8_t siba_crc8(uint8_t, uint8_t);
+static void siba_sprom_r123(struct siba_sprom *, const uint16_t *);
+static void siba_sprom_r45(struct siba_sprom *, const uint16_t *);
+static void siba_sprom_r8(struct siba_sprom *, const uint16_t *);
+static int8_t siba_sprom_r123_antgain(uint8_t, const uint16_t *, uint16_t,
+ uint16_t);
+static uint32_t siba_tmslow_reject_bitmask(struct siba_dev_softc *);
+static uint32_t siba_pcicore_read_4(struct siba_pci *, uint16_t);
+static void siba_pcicore_write_4(struct siba_pci *, uint16_t, uint32_t);
+static uint32_t siba_pcie_read(struct siba_pci *, uint32_t);
+static void siba_pcie_write(struct siba_pci *, uint32_t, uint32_t);
+static void siba_pcie_mdio_write(struct siba_pci *, uint8_t, uint8_t,
+ uint16_t);
+static void siba_pci_read_multi_1(struct siba_dev_softc *, void *, size_t,
+ uint16_t);
+static void siba_pci_read_multi_2(struct siba_dev_softc *, void *, size_t,
+ uint16_t);
+static void siba_pci_read_multi_4(struct siba_dev_softc *, void *, size_t,
+ uint16_t);
+static void siba_pci_write_multi_1(struct siba_dev_softc *, const void *,
+ size_t, uint16_t);
+static void siba_pci_write_multi_2(struct siba_dev_softc *, const void *,
+ size_t, uint16_t);
+static void siba_pci_write_multi_4(struct siba_dev_softc *, const void *,
+ size_t, uint16_t);
+static const char *siba_core_name(uint16_t);
+static void siba_pcicore_init(struct siba_pci *);
+device_t siba_add_child(device_t, struct siba_softc *, int, const char *,
+ int);
+int siba_core_attach(struct siba_softc *);
+int siba_core_detach(struct siba_softc *);
+int siba_core_suspend(struct siba_softc *);
+int siba_core_resume(struct siba_softc *);
+uint8_t siba_getncores(device_t, uint16_t);
+
+static const struct siba_bus_ops siba_pci_ops = {
+ .read_2 = siba_pci_read_2,
+ .read_4 = siba_pci_read_4,
+ .write_2 = siba_pci_write_2,
+ .write_4 = siba_pci_write_4,
+ .read_multi_1 = siba_pci_read_multi_1,
+ .read_multi_2 = siba_pci_read_multi_2,
+ .read_multi_4 = siba_pci_read_multi_4,
+ .write_multi_1 = siba_pci_write_multi_1,
+ .write_multi_2 = siba_pci_write_multi_2,
+ .write_multi_4 = siba_pci_write_multi_4,
+};
+
+static const struct siba_cc_pmu_res_updown siba_cc_pmu_4325_updown[] =
+ SIBA_CC_PMU_4325_RES_UPDOWN;
+static const struct siba_cc_pmu_res_depend siba_cc_pmu_4325_depend[] =
+ SIBA_CC_PMU_4325_RES_DEPEND;
+static const struct siba_cc_pmu_res_updown siba_cc_pmu_4328_updown[] =
+ SIBA_CC_PMU_4328_RES_UPDOWN;
+static const struct siba_cc_pmu_res_depend siba_cc_pmu_4328_depend[] =
+ SIBA_CC_PMU_4328_RES_DEPEND;
+static const struct siba_cc_pmu0_plltab siba_cc_pmu0_plltab[] =
+ SIBA_CC_PMU0_PLLTAB_ENTRY;
+static const struct siba_cc_pmu1_plltab siba_cc_pmu1_plltab[] =
+ SIBA_CC_PMU1_PLLTAB_ENTRY;
+
+int
+siba_core_attach(struct siba_softc *siba)
+{
+ struct siba_cc *scc;
+ int error;
+
+ KASSERT(siba->siba_type == SIBA_TYPE_PCI,
+ ("unsupported BUS type (%#x)", siba->siba_type));
+
+ siba->siba_ops = &siba_pci_ops;
+
+ siba_pci_gpio(siba, SIBA_GPIO_CRYSTAL | SIBA_GPIO_PLL, 1);
+ siba_scan(siba);
+
+ /* XXX init PCI or PCMCIA host devices */
+
+ siba_powerup(siba, 0);
+
+ /* init ChipCommon */
+ scc = &siba->siba_cc;
+ if (scc->scc_dev != NULL) {
+ siba_cc_pmu_init(scc);
+ siba_cc_power_init(scc);
+ siba_cc_clock(scc, SIBA_CLOCK_FAST);
+ siba_cc_powerup_delay(scc);
+ }
+
+ /* fetch various internal informations for PCI */
+ siba->siba_board_vendor = pci_read_config(siba->siba_dev,
+ PCIR_SUBVEND_0, 2);
+ siba->siba_board_type = pci_read_config(siba->siba_dev, PCIR_SUBDEV_0,
+ 2);
+ siba->siba_board_rev = pci_read_config(siba->siba_dev, PCIR_REVID, 2);
+ error = siba_pci_sprom(siba, &siba->siba_sprom);
+ if (error) {
+ siba_powerdown(siba);
+ return (error);
+ }
+
+ siba_powerdown(siba);
+ return (0);
+}
+
+int
+siba_core_detach(struct siba_softc *siba)
+{
+ device_t *devlistp;
+ int devcnt, error = 0, i;
+
+ error = device_get_children(siba->siba_dev, &devlistp, &devcnt);
+ if (error != 0)
+ return (0);
+
+ for ( i = 0 ; i < devcnt ; i++)
+ device_delete_child(siba->siba_dev, devlistp[i]);
+ free(devlistp, M_TEMP);
+ return (0);
+}
+
+static void
+siba_pci_gpio(struct siba_softc *siba, uint32_t what, int on)
+{
+ uint32_t in, out;
+ uint16_t status;
+
+ if (siba->siba_type != SIBA_TYPE_PCI)
+ return;
+
+ out = pci_read_config(siba->siba_dev, SIBA_GPIO_OUT, 4);
+ if (on == 0) {
+ if (what & SIBA_GPIO_PLL)
+ out |= SIBA_GPIO_PLL;
+ if (what & SIBA_GPIO_CRYSTAL)
+ out &= ~SIBA_GPIO_CRYSTAL;
+ pci_write_config(siba->siba_dev, SIBA_GPIO_OUT, out, 4);
+ pci_write_config(siba->siba_dev, SIBA_GPIO_OUT_EN,
+ pci_read_config(siba->siba_dev,
+ SIBA_GPIO_OUT_EN, 4) | what, 4);
+ return;
+ }
+
+ in = pci_read_config(siba->siba_dev, SIBA_GPIO_IN, 4);
+ if ((in & SIBA_GPIO_CRYSTAL) != SIBA_GPIO_CRYSTAL) {
+ if (what & SIBA_GPIO_CRYSTAL) {
+ out |= SIBA_GPIO_CRYSTAL;
+ if (what & SIBA_GPIO_PLL)
+ out |= SIBA_GPIO_PLL;
+ pci_write_config(siba->siba_dev, SIBA_GPIO_OUT, out, 4);
+ pci_write_config(siba->siba_dev,
+ SIBA_GPIO_OUT_EN, pci_read_config(siba->siba_dev,
+ SIBA_GPIO_OUT_EN, 4) | what, 4);
+ DELAY(1000);
+ }
+ if (what & SIBA_GPIO_PLL) {
+ out &= ~SIBA_GPIO_PLL;
+ pci_write_config(siba->siba_dev, SIBA_GPIO_OUT, out, 4);
+ DELAY(5000);
+ }
+ }
+
+ status = pci_read_config(siba->siba_dev, PCIR_STATUS, 2);
+ status &= ~PCIM_STATUS_STABORT;
+ pci_write_config(siba->siba_dev, PCIR_STATUS, status, 2);
+}
+
+static void
+siba_scan(struct siba_softc *siba)
+{
+ struct siba_dev_softc *sd;
+ uint32_t idhi, tmp;
+ int base, dev_i = 0, error, i, is_pcie, n_80211 = 0, n_cc = 0,
+ n_pci = 0;
+
+ KASSERT(siba->siba_type == SIBA_TYPE_PCI,
+ ("unsupported BUS type (%#x)", siba->siba_type));
+
+ siba->siba_ndevs = 0;
+ error = siba_switchcore(siba, 0); /* need the first core */
+ if (error)
+ return;
+
+ idhi = siba_scan_read_4(siba, 0, SIBA_IDHIGH);
+ if (SIBA_IDHIGH_CORECODE(idhi) == SIBA_DEVID_CHIPCOMMON) {
+ tmp = siba_scan_read_4(siba, 0, SIBA_CC_CHIPID);
+ siba->siba_chipid = SIBA_CC_ID(tmp);
+ siba->siba_chiprev = SIBA_CC_REV(tmp);
+ siba->siba_chippkg = SIBA_CC_PKG(tmp);
+ if (SIBA_IDHIGH_REV(idhi) >= 4)
+ siba->siba_ndevs = SIBA_CC_NCORES(tmp);
+ siba->siba_cc.scc_caps = siba_scan_read_4(siba, 0,
+ SIBA_CC_CAPS);
+ } else {
+ if (siba->siba_type == SIBA_TYPE_PCI) {
+ siba->siba_chipid = siba_dev2chipid(siba);
+ siba->siba_chiprev = pci_read_config(siba->siba_dev,
+ PCIR_REVID, 2);
+ siba->siba_chippkg = 0;
+ } else {
+ siba->siba_chipid = 0x4710;
+ siba->siba_chiprev = 0;
+ siba->siba_chippkg = 0;
+ }
+ }
+ if (siba->siba_ndevs == 0)
+ siba->siba_ndevs = siba_getncores(siba->siba_dev,
+ siba->siba_chipid);
+ if (siba->siba_ndevs > SIBA_MAX_CORES) {
+ device_printf(siba->siba_dev,
+ "too many siba cores (max %d %d)\n",
+ SIBA_MAX_CORES, siba->siba_ndevs);
+ return;
+ }
+
+ /* looking basic information about each cores/devices */
+ for (i = 0; i < siba->siba_ndevs; i++) {
+ error = siba_switchcore(siba, i);
+ if (error)
+ return;
+ sd = &(siba->siba_devs[dev_i]);
+ idhi = siba_scan_read_4(siba, i, SIBA_IDHIGH);
+ sd->sd_bus = siba;
+ sd->sd_id.sd_device = SIBA_IDHIGH_CORECODE(idhi);
+ sd->sd_id.sd_rev = SIBA_IDHIGH_REV(idhi);
+ sd->sd_id.sd_vendor = SIBA_IDHIGH_VENDOR(idhi);
+ sd->sd_ops = siba->siba_ops;
+ sd->sd_coreidx = i;
+
+ DPRINTF(siba, SIBA_DEBUG_SCAN,
+ "core %d (%s) found (cc %#xrev %#x vendor %#x)\n",
+ i, siba_core_name(sd->sd_id.sd_device),
+ sd->sd_id.sd_device, sd->sd_id.sd_rev, sd->sd_id.vendor);
+
+ switch (sd->sd_id.sd_device) {
+ case SIBA_DEVID_CHIPCOMMON:
+ n_cc++;
+ if (n_cc > 1) {
+ device_printf(siba->siba_dev,
+ "warn: multiple ChipCommon\n");
+ break;
+ }
+ siba->siba_cc.scc_dev = sd;
+ break;
+ case SIBA_DEVID_80211:
+ n_80211++;
+ if (n_80211 > 1) {
+ device_printf(siba->siba_dev,
+ "warn: multiple 802.11 core\n");
+ continue;
+ }
+ break;
+ case SIBA_DEVID_PCI:
+ case SIBA_DEVID_PCIE:
+ n_pci++;
+ error = pci_find_extcap(siba->siba_dev, PCIY_EXPRESS,
+ &base);
+ is_pcie = (error == 0) ? 1 : 0;
+
+ if (n_pci > 1) {
+ device_printf(siba->siba_dev,
+ "warn: multiple PCI(E) cores\n");
+ break;
+ }
+ if (sd->sd_id.sd_device == SIBA_DEVID_PCI &&
+ is_pcie == 1)
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-stable
mailing list