Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 31 Jan 2010 21:18:23 +0000 (UTC)
From:      Weongyo Jeong <weongyo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r203319 - in head/sys: dev/siba modules/siba_bwn
Message-ID:  <201001312118.o0VLINKJ041832@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: weongyo
Date: Sun Jan 31 21:18:22 2010
New Revision: 203319
URL: http://svn.freebsd.org/changeset/base/203319

Log:
  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:
  head/sys/dev/siba/siba_bwn.c   (contents, props changed)
  head/sys/dev/siba/siba_core.c   (contents, props changed)
  head/sys/modules/siba_bwn/
  head/sys/modules/siba_bwn/Makefile   (contents, props changed)
Modified:
  head/sys/dev/siba/siba.c
  head/sys/dev/siba/siba_cc.c
  head/sys/dev/siba/siba_ids.h
  head/sys/dev/siba/siba_pcib.c
  head/sys/dev/siba/sibareg.h
  head/sys/dev/siba/sibavar.h

Modified: head/sys/dev/siba/siba.c
==============================================================================
--- head/sys/dev/siba/siba.c	Sun Jan 31 20:02:42 2010	(r203318)
+++ head/sys/dev/siba/siba.c	Sun Jan 31 21:18:22 2010	(r203319)
@@ -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);

Added: head/sys/dev/siba/siba_bwn.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/siba/siba_bwn.c	Sun Jan 31 21:18:22 2010	(r203319)
@@ -0,0 +1,366 @@
+/*-
+ * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@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: head/sys/dev/siba/siba_cc.c
==============================================================================
--- head/sys/dev/siba/siba_cc.c	Sun Jan 31 20:02:42 2010	(r203318)
+++ head/sys/dev/siba/siba_cc.c	Sun Jan 31 21:18:22 2010	(r203319)
@@ -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);

Added: head/sys/dev/siba/siba_core.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/siba/siba_core.c	Sun Jan 31 21:18:22 2010	(r203319)
@@ -0,0 +1,2007 @@
+/*-
+ * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@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 ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201001312118.o0VLINKJ041832>