Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 13 Oct 2008 19:12:10 +0100
From:      Bruce M Simpson <bms@incunabulum.net>
To:        freebsd-embedded@freebsd.org
Subject:   [PATCH] Probe and attach bfe(4) on WGT634U
Message-ID:  <48F38F7A.8000902@incunabulum.net>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------050603050405090201050903
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Hi,

Here is a patch (against -CURRENT in SVN) which gets bfe(4) to probe and 
attach to the on-board EMAC core on the Netgear WGT634U.

Note that it doesn't currently work -- there appears to be an interrupt 
routing problem -- however the fact that we are able to read the PHY 
registers suggests we are firmly on the right track.

This PHY is in fact the "roboswitch"; there are additional registers in 
the PHY space which control VLAN filtering, etc which the bmphy(4) 
driver doesn't handle.

If you comment out the BOOTP directives in the SENTRY5 config, you'll 
see that it will attempt to network boot, however no packets actually 
leave the interface and the BOOTP appears to stall.

The documentation states that MIPS hardware interrupt 1 is used for the 
EMAC core, however, lots of "stray hard interrupt 2" messages suggests 
it's using 2. I'm not sure if the interrupt routing is working properly 
-- simply using 2 doesn't solve the problem.

The uart really needs to be made to work in native mode -- at the 
moment, the CFE firmware console driver is used, and this doesn't appear 
to support interrupt-driven I/O -- and as such, it isn't possible to 
break into DDB using the ALT_BREAK_TO_DEBUGGER sequence.

cheers
BMS

--------------050603050405090201050903
Content-Type: text/plain;
 name="bfe-siba.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="bfe-siba.diff"

Index: mips/conf/SENTRY5
===================================================================
--- mips/conf/SENTRY5	(revision 183816)
+++ mips/conf/SENTRY5	(working copy)
@@ -21,9 +21,11 @@
 #
 # * The Broadcom CPUs have no FPU. Attempting to detect one by reading CP1's
 #   status register causes an unhandled boot-time exception. An FPU emulator
-#   will be necessary to support multi-user boot.
+#   will be necessary to support multi-user boot (or build with -msoft-float).
 #
 
+# XXX This gets to mountroot w/o bfe or pci in, but that is useless. 
+
 machine		mips
 ident		SENTRY5
 cpu		CPU_MIPS4KC
@@ -36,27 +38,27 @@
 # bus enumeration there
 files		"../sentry5/files.sentry5"
 hints		"SENTRY5.hints"
+env		"SENTRY5.env"
 
-# sentry5 normally ships with cfe firmware; use the console for now
-options		CFE
-options		CFE_CONSOLE
-options		ALT_BREAK_TO_DEBUGGER
-
-# cfe loader expects kernel at 0x80001000 for mips32 w/o backwards
-# offsets in the linked elf image (see ldscript hack)
-# XXX can we conditionalize the linker stuff on options CFE?
-options		KERNVIRTADDR=0x80001000
-
-makeoptions	LDSCRIPT_NAME=	ldscript.mips.cfe
-
 #makeoptions	ARCH_FLAGS=-march=mips32
 makeoptions	MIPS_LITTLE_ENDIAN=defined
 makeoptions	DEBUG=-g		#Build kernel with gdb(1) debug symbols
 makeoptions	MODULES_OVERRIDE=""
+makeoptions	LDSCRIPT_NAME=	ldscript.mips.cfe
 
 options		DDB
 options		KDB
+options		ALT_BREAK_TO_DEBUGGER
 
+options		KTR
+options		KTR_VERBOSE
+options		KTR_MASK=KTR_BUSDMA
+
+# Use the CFE console for now.
+# It defaults to uart1 on the wgt634u, so won't clash with uart0.
+options		CFE
+options		CFE_CONSOLE
+
 options		SCHED_4BSD		#4BSD scheduler
 options		INET			#InterNETworking
 options		NFSCLIENT		#Network Filesystem Client
@@ -64,35 +66,55 @@
 options		PSEUDOFS		#Pseudo-filesystem framework
 options		_KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions
 
+options 	MUTEX_NOINLINE		#Mutex inlines are space hogs
+options 	RWLOCK_NOINLINE		#rwlock inlines are space hogs
+options 	SX_NOINLINE		#sx inliens are space hogs
+
+# XXX Until we can get disk drivers to attach above,
+# we will need to attempt network boot.
+# XXX stray hard interrupt 2...
+# bfe interrupt handling ain't right, temporary reroute
+# manual path applied, need to get to nitty gritty of how
+# interrupt routing works on the siba.
+#options 	BOOTP
+#options 	BOOTP_NFSROOT
+#options 	BOOTP_NFSV3
+#options 	BOOTP_WIRED_TO=bfe0
+#options 	BOOTP_COMPAT
+
+options		NFSCLIENT               #Network Filesystem Client
+options		NFSLOCKD                #Network Lock Manager
+options		NFS_ROOT                #NFS usable as /, requires NFSCLIENT
+
 # Debugging for use in -current
 options		INVARIANTS
 options		INVARIANT_SUPPORT
 
-#options		BUS_DEBUG
-#makeoptions	BUS_DEBUG
+options		VERBOSE_SYSINIT
+options		BUS_DEBUG
 
+# XXX notyet; need to be auto probed children of siba_cc.
+# XXX clock divisor most likely incorrect when banging uart manually.
+device		uart
+device		uart_ns8250
+
 device		siba			# Sonics SiliconBackplane
-device		pci			# siba_pcib
 
-device		bfe			# XXX will build both pci and siba
-device		miibus			# attachments
+device		bfe
+device		miibus
 
+# No PCI while we figure stuff out.
+#device		pci			# siba_pcib
+
 # pci devices
 # notyet:
 #device		ath			# in pci slot
 #device		ath_hal			# in pci slot
 
-device		usb			# USB Bus (required)
-device		uhci			# UHCI PCI->USB interface
-device		ehci			# EHCI PCI->USB interface (USB 2.0)
+#device		usb			# USB Bus (required)
+#device		uhci			# UHCI PCI->USB interface
+#device		ehci			# EHCI PCI->USB interface (USB 2.0)
 
-# need to teach the code to ignore the bridge....
-
-
-# XXX notyet; need to be auto probed children of siba_cc.
-#device		uart
-#device		uart_ns8250
-
 device		loop
 device		ether
 device		md
Index: mips/conf/SENTRY5.hints
===================================================================
--- mips/conf/SENTRY5.hints	(revision 183815)
+++ mips/conf/SENTRY5.hints	(working copy)
@@ -1,5 +1,19 @@
 # $FreeBSD$
 hint.siba.0.at="nexus0"
-hint.siba.0.maddr="0x18000000"
-hint.siba.0.msize="0x1000"
-# XXX irq?
+hint.siba.0.maddr=0x18000000
+hint.siba.0.msize=0x1000
+
+# XXX uart hints are not actually used yet.
+
+# uart0
+#hint.uart.0.at="siba0"
+#hint.uart.0.maddr=0x18000300
+#hint.uart.0.msize=0x8
+#hint.uart.0.irq=0
+
+# uart1
+#hint.uart.1.at="siba0"
+#hint.uart.1.maddr="0x18000400"
+#hint.uart.1.msize="0x8"
+#hint.uart.1.irq=0
+#hint.uart.1.disabled=1
Index: mips/mips/busdma_machdep.c
===================================================================
--- mips/mips/busdma_machdep.c	(revision 183815)
+++ mips/mips/busdma_machdep.c	(working copy)
@@ -25,7 +25,7 @@
  *
  */
 
-#define NO_DMA
+//#define NO_DMA
 
 /*-
  * Copyright (c) 1997, 1998, 2001 The NetBSD Foundation, Inc.
Index: mips/sentry5/siba_cc.c
===================================================================
--- mips/sentry5/siba_cc.c	(revision 183815)
+++ mips/sentry5/siba_cc.c	(working copy)
@@ -61,7 +61,7 @@
 
 static int	siba_cc_attach(device_t);
 static int	siba_cc_probe(device_t);
-static void	siba_cc_intr(void *v);
+//static void	siba_cc_intr(void *v);
 
 static int
 siba_cc_probe(device_t dev)
@@ -85,7 +85,7 @@
 {
 	//struct siba_cc_softc *sc = device_get_softc(dev);
 	struct resource *mem;
-	struct resource *irq;
+	//struct resource *irq;
 	int rid;
 
 	/*
@@ -101,6 +101,7 @@
 		return (ENXIO);
 	}
 
+#if 0
 	rid = 0;
 	irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 0);
 	if (irq == NULL) {
@@ -124,17 +125,28 @@
 		device_printf(dev, "unable to setup intr\n");
 		return (ENXIO);
 	}
+#endif
 
-	/* TODO: attach uart child */
+#if 0
+	device_add_child(dev, "uart", 0);
+	device_add_child(dev, "uart", 1);
+	bus_generic_probe(dev);
+	bus_generic_attach(dev);
+#endif
 
 	return (0);
 }
 
+#if 0
+// XXX: interrupt not actually used, except for the UARTs,
+// or external interface, which is assumed to be parallel flash.
 static void
-siba_cc_intr(void *v)
+siba_cc_intr(void *v __unused)
 {
 
+	printf("%s: called\n", __func__);
 }
+#endif
 
 static device_method_t siba_cc_methods[] = {
 	/* Device interface */
Index: mips/sentry5/s5_machdep.c
===================================================================
--- mips/sentry5/s5_machdep.c	(revision 183815)
+++ mips/sentry5/s5_machdep.c	(working copy)
@@ -91,6 +91,7 @@
 mips_init(void)
 {
 	int i;
+        char *p;
 
 	printf("entry: mips_init()\n");
 
@@ -129,6 +130,23 @@
 
 	physmem = realmem;
 
+	/* use static kernel environment if so configured */
+	if (envmode == 1)
+		kern_envp = static_env;
+
+	/*
+	 * Catch case of boot_verbose set in environment.
+	 */
+	if ((p = getenv("boot_verbose")) != NULL) {
+		if (strcmp(p, "yes") == 0 || strcmp(p, "YES") == 0) {
+			boothowto |= RB_VERBOSE;
+		}
+		freeenv(p);
+	}
+
+	if (boothowto & RB_VERBOSE)
+		bootverbose = 1;
+
 	init_param1();
 	init_param2(physmem);
 	mips_cpu_init();
@@ -156,8 +174,7 @@
 void
 platform_reset(void)
 {
-
-#if defined(CFE)
+#if 0 && defined(CFE)
 	cfe_exit(0, 0);
 #else
 	*((volatile uint8_t *)MIPS_PHYS_TO_KSEG1(SENTRY5_EXTIFADR)) = 0x80;
Index: mips/sentry5/files.sentry5
===================================================================
--- mips/sentry5/files.sentry5	(revision 183815)
+++ mips/sentry5/files.sentry5	(working copy)
@@ -10,5 +10,9 @@
 dev/siba/siba_pcib.c				optional siba pci
 mips/sentry5/siba_cc.c			optional siba
 
+mips/sentry5/uart_cpu_sentry5.c        optional uart
+mips/sentry5/uart_bus_sentry5.c        optional uart
+dev/uart/uart_dev_ns8250.c              optional uart
+
 # notyet
 #mips/sentry5/siba_mips.c			optional siba
Index: mips/sentry5/uart_cpu_sentry5.c
===================================================================
--- mips/sentry5/uart_cpu_sentry5.c	(revision 0)
+++ mips/sentry5/uart_cpu_sentry5.c	(revision 0)
@@ -0,0 +1,101 @@
+/*-
+ * Copyright (c) 2006 Wojciech A. Koszek <wkoszek@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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE.
+ *
+ * $Id$
+ */
+/*
+ * Skeleton of this file was based on respective code for ARM
+ * code written by Olivier Houchard.
+ */
+/*
+ * XXXMIPS: This file is hacked from arm/... . XXXMIPS here means this file is
+ * experimental and was written for MIPS32 port.
+ */
+#include "opt_uart.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/cons.h>
+
+#include <machine/bus.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+
+#include <mips/sentry5/s5reg.h>
+
+bus_space_tag_t uart_bus_space_io;
+bus_space_tag_t uart_bus_space_mem;
+
+extern struct uart_ops sentry5_usart_ops;
+extern struct bus_space sentry5_bs_tag;
+
+int
+uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
+{
+	return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0);
+}
+
+int
+uart_cpu_getdev(int devtype, struct uart_devinfo *di)
+{
+
+	/* XXX Don't attach this at boot-time as a console. */
+	if (devtype == UART_DEV_CONSOLE)
+		return (ENXIO);
+
+	di->ops = uart_getops(&uart_ns8250_class);
+	di->bas.chan = 0;
+	di->bas.bst = 0;
+#if 0
+	di->bas.regshft = 0;
+	di->bas.rclk = 0;
+#else
+	/* XXX hardcoded values for 200MHz BCM5365P */
+	di->bas.regshft = 1;
+	di->bas.rclk = 1843200;
+#endif
+	di->baudrate = 115200;
+	di->databits = 8;
+	di->stopbits = 1;
+	di->parity = UART_PARITY_NONE;
+
+#if 0
+	uart_bus_space_io = MIPS_PHYS_TO_KSEG1(SENTRY5_UART1ADR);
+	uart_bus_space_mem = MIPS_PHYS_TO_KSEG1(SENTRY5_UART1ADR);
+	di->bas.bsh = MIPS_PHYS_TO_KSEG1(SENTRY5_UART1ADR);
+#else
+	/* XXX try uart 0 */
+	uart_bus_space_io = MIPS_PHYS_TO_KSEG1(SENTRY5_UART0ADR);
+	uart_bus_space_mem = MIPS_PHYS_TO_KSEG1(SENTRY5_UART0ADR);
+	di->bas.bsh = MIPS_PHYS_TO_KSEG1(SENTRY5_UART0ADR);
+#endif
+
+	return (0);
+}
Index: mips/sentry5/uart_bus_sentry5.c
===================================================================
--- mips/sentry5/uart_bus_sentry5.c	(revision 0)
+++ mips/sentry5/uart_bus_sentry5.c	(revision 0)
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 2007 Bruce M. Simpson.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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
+ * $Id$
+ */
+/*
+ * Skeleton of this file was based on respective code for ARM
+ * code written by Olivier Houchard.
+ */
+
+/*
+ * XXXMIPS: This file is hacked from arm/... . XXXMIPS here means this file is
+ * experimental and was written for MIPS32 port.
+ */
+#include "opt_uart.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
+#include <dev/pci/pcivar.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_bus.h>
+#include <dev/uart/uart_cpu.h>
+
+#include <mips/sentry5/s5reg.h>
+
+#include "uart_if.h"
+
+static int uart_sentry5_probe(device_t dev);
+
+extern struct uart_class sentry5_uart_class;
+
+static device_method_t uart_sentry5_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		uart_sentry5_probe),
+	DEVMETHOD(device_attach,	uart_bus_attach),
+	DEVMETHOD(device_detach,	uart_bus_detach),
+	{ 0, 0 }
+};
+
+static driver_t uart_sentry5_driver = {
+	uart_driver_name,
+	uart_sentry5_methods,
+	sizeof(struct uart_softc),
+};
+
+extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
+static int
+uart_sentry5_probe(device_t dev)
+{
+	struct uart_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs);
+	sc->sc_class = &uart_ns8250_class;
+	bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
+	sc->sc_sysdev->bas.bst = 0;
+	sc->sc_sysdev->bas.bsh = MIPS_PHYS_TO_KSEG1(SENTRY5_UART1ADR);
+	sc->sc_bas.bst = 0;
+	sc->sc_bas.bsh = MIPS_PHYS_TO_KSEG1(SENTRY5_UART1ADR);
+	return(uart_bus_probe(dev, 0, 0, 0, 0));
+}
+
+DRIVER_MODULE(uart, obio, uart_sentry5_driver, uart_devclass, 0, 0);
Index: dev/siba/siba.c
===================================================================
--- dev/siba/siba.c	(revision 183815)
+++ dev/siba/siba.c	(working copy)
@@ -44,7 +44,6 @@
 /*
  * TODO: De-mipsify this code.
  * TODO: cpu clock calculation. -> move to siba_cc instance
- * TODO: Hardwire IRQs for attached cores on siba at probe time.
  * TODO: Support detach.
  * TODO: Power management.
  * TODO: code cleanup.
@@ -150,11 +149,20 @@
 	case SIBA_DEVID_CHIPCOMMON:
 		irq = 0;
 		break;
+        /* XXX: For some reason it seems to want irq2 */
 	case SIBA_DEVID_ETHERNET:
+#ifdef notyet
 		irq = 1;
+#else
+                irq = 2;
+#endif
 		break;
 	case SIBA_DEVID_IPSEC:
+#ifdef notyet
 		irq = 2;
+#else
+                irq = 0xFF;
+#endif
 		break;
 	case SIBA_DEVID_USB:
 		irq = 3;
@@ -479,6 +487,7 @@
 	uint32_t idlo, idhi, rev;
 	uint16_t vendorid, devid;
 	bus_addr_t baseaddr;
+	u_long corelen;
 
 	sdi = malloc(sizeof(*sdi), M_DEVBUF, M_WAITOK | M_ZERO);
 	resource_list_init(&sdi->sdi_rl);
@@ -500,10 +509,16 @@
 	/*
 	 * Determine memory window on bus and irq if one is needed.
 	 */
+	if (idx == 0)
+		corelen = 0x300;	/* leave room for uart */
+	else
+		corelen = SIBA_CORE_LEN;
+
 	baseaddr = sc->sc_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);
+	    baseaddr,
+	    baseaddr + corelen - 1, corelen);
 
 	if (sdi->sdi_irq != 0xff) {
 		resource_list_add(&sdi->sdi_rl, SYS_RES_IRQ,
Index: dev/bfe/if_bfe.c
===================================================================
--- dev/bfe/if_bfe.c	(revision 183815)
+++ dev/bfe/if_bfe.c	(working copy)
@@ -29,6 +29,7 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#include <sys/kdb.h>
 #include <sys/systm.h>
 #include <sys/bus.h>
 #include <sys/endian.h>
@@ -59,28 +60,11 @@
 
 #include <dev/bfe/if_bfereg.h>
 
-MODULE_DEPEND(bfe, pci, 1, 1, 1);
-MODULE_DEPEND(bfe, ether, 1, 1, 1);
-MODULE_DEPEND(bfe, miibus, 1, 1, 1);
-
 /* "device miibus" required.  See GENERIC if you get errors here. */
 #include "miibus_if.h"
 
 #define BFE_DEVDESC_MAX		64	/* Maximum device description length */
 
-static struct bfe_type bfe_devs[] = {
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM4401,
-		"Broadcom BCM4401 Fast Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM4401B0,
-		"Broadcom BCM4401-B0 Fast Ethernet" },
-		{ 0, 0, NULL }
-};
-
-static int  bfe_probe				(device_t);
-static int  bfe_attach				(device_t);
-static int  bfe_detach				(device_t);
-static int  bfe_suspend				(device_t);
-static int  bfe_resume				(device_t);
 static void bfe_release_resources	(struct bfe_softc *);
 static void bfe_intr				(void *);
 static int  bfe_encap				(struct bfe_softc *, struct mbuf **);
@@ -91,7 +75,6 @@
 static void bfe_init_locked			(void *);
 static void bfe_stop				(struct bfe_softc *);
 static void bfe_watchdog			(struct bfe_softc *);
-static int  bfe_shutdown			(device_t);
 static void bfe_tick				(void *);
 static void bfe_txeof				(struct bfe_softc *);
 static void bfe_rxeof				(struct bfe_softc *);
@@ -105,9 +88,6 @@
 static void bfe_pci_setup			(struct bfe_softc *, u_int32_t);
 static int  bfe_ifmedia_upd			(struct ifnet *);
 static void bfe_ifmedia_sts			(struct ifnet *, struct ifmediareq *);
-static int  bfe_miibus_readreg		(device_t, int, int);
-static int  bfe_miibus_writereg		(device_t, int, int, int);
-static void bfe_miibus_statchg		(device_t);
 static int  bfe_wait_bit			(struct bfe_softc *, u_int32_t, u_int32_t,
 		u_long, const int);
 static void bfe_get_config			(struct bfe_softc *sc);
@@ -128,60 +108,8 @@
 static void bfe_cam_write			(struct bfe_softc *, u_char *, int);
 static int  sysctl_bfe_stats		(SYSCTL_HANDLER_ARGS);
 
-static device_method_t bfe_methods[] = {
-	/* Device interface */
-	DEVMETHOD(device_probe,		bfe_probe),
-	DEVMETHOD(device_attach,	bfe_attach),
-	DEVMETHOD(device_detach,	bfe_detach),
-	DEVMETHOD(device_shutdown,	bfe_shutdown),
-	DEVMETHOD(device_suspend,	bfe_suspend),
-	DEVMETHOD(device_resume,	bfe_resume),
+devclass_t bfe_devclass;
 
-	/* bus interface */
-	DEVMETHOD(bus_print_child,	bus_generic_print_child),
-	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
-
-	/* MII interface */
-	DEVMETHOD(miibus_readreg,	bfe_miibus_readreg),
-	DEVMETHOD(miibus_writereg,	bfe_miibus_writereg),
-	DEVMETHOD(miibus_statchg,	bfe_miibus_statchg),
-
-	{ 0, 0 }
-};
-
-static driver_t bfe_driver = {
-	"bfe",
-	bfe_methods,
-	sizeof(struct bfe_softc)
-};
-
-static devclass_t bfe_devclass;
-
-DRIVER_MODULE(bfe, pci, bfe_driver, bfe_devclass, 0, 0);
-DRIVER_MODULE(miibus, bfe, miibus_driver, miibus_devclass, 0, 0);
-
-/*
- * Probe for a Broadcom 4401 chip.
- */
-static int
-bfe_probe(device_t dev)
-{
-	struct bfe_type *t;
-
-	t = bfe_devs;
-
-	while (t->bfe_name != NULL) {
-		if (pci_get_vendor(dev) == t->bfe_vid &&
-		    pci_get_device(dev) == t->bfe_did) {
-			device_set_desc(dev, t->bfe_name);
-			return (BUS_PROBE_DEFAULT);
-		}
-		t++;
-	}
-
-	return (ENXIO);
-}
-
 struct bfe_dmamap_arg {
 	bus_addr_t	bfe_busaddr;
 };
@@ -430,7 +358,7 @@
 	}
 }
 
-static int
+int
 bfe_attach(device_t dev)
 {
 	struct ifnet *ifp = NULL;
@@ -447,9 +375,13 @@
 	/*
 	 * Map control/status registers.
 	 */
-	pci_enable_busmaster(dev);
+	if (sc->bfe_bus_type == BFE_BUS_PCI) {
+		pci_enable_busmaster(dev);
+		rid = PCIR_BAR(0);
+	} else if (sc->bfe_bus_type == BFE_BUS_SIBA) {
+		rid = 0x20;		/* XXX MIPS hardcoded */
+	}
 
-	rid = PCIR_BAR(0);
 	sc->bfe_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
 			RF_ACTIVE);
 	if (sc->bfe_res == NULL) {
@@ -475,6 +407,8 @@
 		goto fail;
 	}
 
+       // kdb_enter(KDB_WHY_UNSET, "bfe dmamem alloc done");
+
 	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
 	    "stats", CTLTYPE_INT | CTLFLAG_RW, sc, 0, sysctl_bfe_stats,
@@ -498,13 +432,16 @@
 	ifp->if_snd.ifq_drv_maxlen = BFE_TX_QLEN;
 	IFQ_SET_READY(&ifp->if_snd);
 
+        //device_printf(dev, "attempting to get config\n");
 	bfe_get_config(sc);
 
 	/* Reset the chip and turn on the PHY */
+        //device_printf(dev, "attempting to reset chip\n");
 	BFE_LOCK(sc);
 	bfe_chip_reset(sc);
 	BFE_UNLOCK(sc);
 
+        //device_printf(dev, "attempting to probe phy\n");
 	if (mii_phy_probe(dev, &sc->bfe_miibus,
 				bfe_ifmedia_upd, bfe_ifmedia_sts)) {
 		device_printf(dev, "MII without any PHY!\n");
@@ -512,6 +449,7 @@
 		goto fail;
 	}
 
+        //device_printf(dev, "attempting to attach i/f to stack\n");
 	ether_ifattach(ifp, sc->bfe_enaddr);
 
 	/*
@@ -524,6 +462,7 @@
 	/*
 	 * Hook interrupt last to avoid having to lock softc
 	 */
+        //device_printf(dev, "attempting to hook irqs\n");
 	error = bus_setup_intr(dev, sc->bfe_irq, INTR_TYPE_NET | INTR_MPSAFE,
 			NULL, bfe_intr, sc, &sc->bfe_intrhand);
 
@@ -537,7 +476,7 @@
 	return (error);
 }
 
-static int
+int
 bfe_detach(device_t dev)
 {
 	struct bfe_softc *sc;
@@ -576,7 +515,7 @@
  * Stop all chip I/O so that the kernel's probe routines don't
  * get confused by errant DMAs when rebooting.
  */
-static int
+int
 bfe_shutdown(device_t dev)
 {
 	struct bfe_softc *sc;
@@ -590,7 +529,7 @@
 	return (0);
 }
 
-static int
+int
 bfe_suspend(device_t dev)
 {
 	struct bfe_softc *sc;
@@ -603,7 +542,7 @@
 	return (0);
 }
 
-static int
+int
 bfe_resume(device_t dev)
 {
 	struct bfe_softc *sc;
@@ -624,7 +563,7 @@
 	return (0);
 }
 
-static int
+int
 bfe_miibus_readreg(device_t dev, int phy, int reg)
 {
 	struct bfe_softc *sc;
@@ -638,7 +577,7 @@
 	return (ret);
 }
 
-static int
+int
 bfe_miibus_writereg(device_t dev, int phy, int reg, int val)
 {
 	struct bfe_softc *sc;
@@ -651,7 +590,7 @@
 	return (0);
 }
 
-static void
+void
 bfe_miibus_statchg(device_t dev)
 {
 	struct bfe_softc *sc;
@@ -840,9 +779,34 @@
 	return (0);
 }
 
+/*
+ * XXX: The SiBa version of bfe does not have an eeprom.
+ * We may also need to know the external clock speed of
+ * the SoC to set up the MDIO registers correctly.
+ */
 static void
-bfe_get_config(struct bfe_softc *sc)
+bfe_siba_get_config(struct bfe_softc *sc)
 {
+
+        /* XXX this is bogus */
+	sc->bfe_enaddr[0] = 0x00;
+	sc->bfe_enaddr[1] = 0x0f;
+	sc->bfe_enaddr[2] = 0xb5;
+	sc->bfe_enaddr[3] = 0x3d;
+	sc->bfe_enaddr[4] = 0x52;
+	sc->bfe_enaddr[5] = 0x90;
+
+	sc->bfe_phyaddr = 0x01;    /* XXX */
+
+        /* unused fields */
+	sc->bfe_mdc_port = 0;
+	sc->bfe_core_unit = 0;
+	sc->bfe_dma_offset = 0;
+}
+
+static void
+bfe_pci_get_config(struct bfe_softc *sc)
+{
 	u_int8_t eeprom[128];
 
 	bfe_read_eeprom(sc, eeprom);
@@ -862,6 +826,17 @@
 }
 
 static void
+bfe_get_config(struct bfe_softc *sc)
+{
+
+	if (sc->bfe_bus_type == BFE_BUS_PCI) {
+		bfe_pci_get_config(sc);
+	} else if (sc->bfe_bus_type == BFE_BUS_SIBA) {
+		bfe_siba_get_config(sc);
+	}
+}
+
+static void
 bfe_pci_setup(struct bfe_softc *sc, u_int32_t cores)
 {
 	u_int32_t bar_orig, pci_rev, val;
@@ -934,7 +909,8 @@
 	BFE_LOCK_ASSERT(sc);
 
 	/* Set the interrupt vector for the enet core */
-	bfe_pci_setup(sc, BFE_INTVEC_ENET0);
+	if (sc->bfe_bus_type == BFE_BUS_PCI)
+		bfe_pci_setup(sc, BFE_INTVEC_ENET0);
 
 	/* is core up? */
 	val = CSR_READ_4(sc, BFE_SBTMSLOW) &
@@ -1455,6 +1431,8 @@
 
 	BFE_LOCK(sc);
 
+        device_printf(sc->bfe_dev, "bfe_intr called\n");
+
 	istat = CSR_READ_4(sc, BFE_ISTAT);
 
 	/*
@@ -1972,3 +1950,7 @@
 
 	return (error);
 }
+
+MODULE_DEPEND(bfe, ether, 1, 1, 1);
+MODULE_DEPEND(bfe, miibus, 1, 1, 1);
+DRIVER_MODULE(miibus, bfe, miibus_driver, miibus_devclass, 0, 0);
Index: dev/bfe/if_bfereg.h
===================================================================
--- dev/bfe/if_bfereg.h	(revision 183815)
+++ dev/bfe/if_bfereg.h	(working copy)
@@ -421,6 +421,7 @@
 
 #define BCOM_VENDORID           0x14E4
 #define BCOM_DEVICEID_BCM4401   0x4401
+#define BCOM_DEVICEID_BCM4713	0x4713
 #define BCOM_DEVICEID_BCM4401B0	0x170c
 
 #define PCI_SETBIT(dev, reg, x, s)  \
@@ -430,6 +431,7 @@
 
 #define BFE_TX_LIST_CNT         128
 #define BFE_RX_LIST_CNT         128
+
 #define BFE_TX_LIST_SIZE        BFE_TX_LIST_CNT * sizeof(struct bfe_desc)
 #define BFE_RX_LIST_SIZE        BFE_RX_LIST_CNT * sizeof(struct bfe_desc)
 #define BFE_RX_OFFSET           30
@@ -457,6 +459,9 @@
 
 #define BFE_INC(x, y)       (x) = ((x) == ((y)-1)) ? 0 : (x)+1
 
+#define BFE_BUS_PCI	(0)	/* device lives on a PCI bus */
+#define BFE_BUS_SIBA	(1)	/* device lives on a SiBa bus */
+
 struct bfe_tx_data {
     struct mbuf     *bfe_mbuf;
     bus_dmamap_t     bfe_map;
@@ -612,6 +617,7 @@
     u_int8_t                bfe_phyaddr; /* Address of the card's PHY */
     u_int8_t                bfe_mdc_port;
     u_int8_t                bfe_core_unit;
+    u_int8_t                bfe_bus_type;
     u_char                  bfe_enaddr[6];
     int                     bfe_if_flags;
 };
@@ -623,4 +629,16 @@
     char        *bfe_name;
 };
 
+int	bfe_attach(device_t);
+int	bfe_detach(device_t);
+int	bfe_suspend(device_t);
+int	bfe_resume(device_t);
+int	bfe_shutdown(device_t);
+
+int	bfe_miibus_readreg(device_t, int, int);
+int	bfe_miibus_writereg(device_t, int, int, int);
+void	bfe_miibus_statchg(device_t);
+
+extern devclass_t bfe_devclass;
+
 #endif /* _BFE_H */
Index: dev/mii/miidevs
===================================================================
--- dev/mii/miidevs	(revision 183815)
+++ dev/mii/miidevs	(working copy)
@@ -130,6 +130,7 @@
 model BROADCOM BCM5201		0x0021 BCM5201 10/100baseTX PHY
 model BROADCOM BCM5221		0x001e BCM5221 10/100baseTX PHY
 model BROADCOM BCM4401		0x0036 BCM4401 10/100baseTX PHY
+model BROADCOM BCM5365		0x0037 BCM5365 10/100baseTX PHY
 model xxBROADCOM BCM5400	0x0004 Broadcom 1000baseTX PHY
 model xxBROADCOM BCM5401	0x0005 BCM5401 10/100/1000baseTX PHY
 model xxBROADCOM BCM5411	0x0007 BCM5411 10/100/1000baseTX PHY
Index: dev/mii/bmtphy.c
===================================================================
--- dev/mii/bmtphy.c	(revision 183815)
+++ dev/mii/bmtphy.c	(working copy)
@@ -124,6 +124,7 @@
 	MII_PHY_DESC(BROADCOM, BCM4401),
 	MII_PHY_DESC(BROADCOM, BCM5201),
 	MII_PHY_DESC(BROADCOM, BCM5221),
+	MII_PHY_DESC(BROADCOM, BCM5365), /* TODO: Add switch driver. */
 	MII_PHY_END
 };
 

--------------050603050405090201050903--



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