Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 15 Dec 2006 05:58:15 -0800
From:      "Wes L. Zuber" <wes@uia.net>
To:        freebsd-drivers@FreeBSD.org
Subject:   Dell SC440 and Broadcom 5787
Message-ID:  <C04F8CB2-2FF8-44F2-95BA-65B75FC3DB28@uia.net>

next in thread | raw e-mail | index | archive | help
Hi there folks,

Scott Long has committed (to HEAD) support for the Broadcom 5787 Nic  
found on the new Dell SC440.

Here are the patches for 6.1 support.

The bge patch should be applied from within the /sys/dev/bge
directory.  The brgphy patch should be applied from within the
/sys/dev/mii d


Index: if_bge.c
===================================================================
RCS file: /usr1/ncvs/src/sys/dev/bge/if_bge.c,v
retrieving revision 1.91.2.13
diff -u -r1.91.2.13 if_bge.c
--- if_bge.c	4 Mar 2006 09:34:48 -0000	1.91.2.13
+++ if_bge.c	14 Dec 2006 16:40:51 -0000
@@ -32,7 +32,7 @@
   */

  #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/bge/if_bge.c,v 1.91.2.13 2006/03/04  
09:34:48 oleg Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/bge/if_bge.c,v 1.91.2.18 2006/10/13  
08:05:55 glebius Exp $");

  /*
   * Broadcom BCM570x family gigabit ethernet driver for FreeBSD.
@@ -79,6 +79,7 @@
  #include <sys/kernel.h>
  #include <sys/module.h>
  #include <sys/socket.h>
+#include <sys/sysctl.h>

  #include <net/if.h>
  #include <net/if_arp.h>
@@ -95,7 +96,6 @@
  #include <netinet/in.h>
  #include <netinet/ip.h>

-#include <machine/clock.h>      /* for DELAY */
  #include <machine/bus.h>
  #include <machine/resource.h>
  #include <sys/bus.h>
@@ -111,8 +111,6 @@

  #include <dev/bge/if_bgereg.h>

-#include "opt_bge.h"
-
  #define BGE_CSUM_FEATURES	(CSUM_IP | CSUM_TCP | CSUM_UDP)
  #define ETHER_MIN_NOPAD		(ETHER_MIN_LEN - ETHER_CRC_LEN) /* i.e.,  
60 */

@@ -129,150 +127,268 @@
   * ID burned into it, though it will always be overriden by the vendor
   * ID in the EEPROM. Just to be safe, we cover all possibilities.
   */
-#define BGE_DEVDESC_MAX		64	/* Maximum device description length */
+static struct bge_type {
+	uint16_t	bge_vid;
+	uint16_t	bge_did;
+} bge_devs[] = {
+	{ ALTEON_VENDORID,	ALTEON_DEVICEID_BCM5700 },
+	{ ALTEON_VENDORID,	ALTEON_DEVICEID_BCM5701 },
+
+	{ ALTIMA_VENDORID,	ALTIMA_DEVICE_AC1000 },
+	{ ALTIMA_VENDORID,	ALTIMA_DEVICE_AC1002 },
+	{ ALTIMA_VENDORID,	ALTIMA_DEVICE_AC9100 },
+
+	{ APPLE_VENDORID,	APPLE_DEVICE_BCM5701 },
+
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5700 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5701 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5702 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5702_ALT },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5702X },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5703 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5703_ALT },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5703X },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5704C },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5704S },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5704S_ALT },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5705 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5705F },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5705K },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5705M },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5705M_ALT },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5714C },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5714S },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5715 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5715S },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5720 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5721 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5750 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5750M },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5751 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5751F },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5751M },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5752 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5752M },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5753 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5753F },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5753M },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5754 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5754M },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5755 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5755M },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5780 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5780S },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5781 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5782 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5786 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5787 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5787M },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5788 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5789 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5901 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5901A2 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5903M },
+
+	{ SK_VENDORID,		SK_DEVICEID_ALTIMA },

-static struct bge_type bge_devs[] = {
-	{ ALT_VENDORID,	ALT_DEVICEID_BCM5700,
-		"Broadcom BCM5700 Gigabit Ethernet" },
-	{ ALT_VENDORID,	ALT_DEVICEID_BCM5701,
-		"Broadcom BCM5701 Gigabit Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5700,
-		"Broadcom BCM5700 Gigabit Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5701,
-		"Broadcom BCM5701 Gigabit Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5702,
-		"Broadcom BCM5702 Gigabit Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5702X,
-		"Broadcom BCM5702X Gigabit Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5703,
-		"Broadcom BCM5703 Gigabit Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5703X,
-		"Broadcom BCM5703X Gigabit Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5704C,
-		"Broadcom BCM5704C Dual Gigabit Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5704S,
-		"Broadcom BCM5704S Dual Gigabit Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5705,
-		"Broadcom BCM5705 Gigabit Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5705K,
-		"Broadcom BCM5705K Gigabit Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5705M,
-		"Broadcom BCM5705M Gigabit Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5705M_ALT,
-		"Broadcom BCM5705M Gigabit Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5714C,
-		"Broadcom BCM5714C Gigabit Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5721,
-		"Broadcom BCM5721 Gigabit Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5750,
-		"Broadcom BCM5750 Gigabit Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5750M,
-		"Broadcom BCM5750M Gigabit Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5751,
-		"Broadcom BCM5751 Gigabit Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5751M,
-		"Broadcom BCM5751M Gigabit Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5752,
-		"Broadcom BCM5752 Gigabit Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5782,
-		"Broadcom BCM5782 Gigabit Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5788,
-		"Broadcom BCM5788 Gigabit Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5789,
-		"Broadcom BCM5789 Gigabit Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5901,
-		"Broadcom BCM5901 Fast Ethernet" },
-	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5901A2,
-		"Broadcom BCM5901A2 Fast Ethernet" },
-	{ SK_VENDORID, SK_DEVICEID_ALTIMA,
-		"SysKonnect Gigabit Ethernet" },
-	{ ALTIMA_VENDORID, ALTIMA_DEVICE_AC1000,
-		"Altima AC1000 Gigabit Ethernet" },
-	{ ALTIMA_VENDORID, ALTIMA_DEVICE_AC1002,
-		"Altima AC1002 Gigabit Ethernet" },
-	{ ALTIMA_VENDORID, ALTIMA_DEVICE_AC9100,
-		"Altima AC9100 Gigabit Ethernet" },
-	{ 0, 0, NULL }
+	{ TC_VENDORID,		TC_DEVICEID_3C996 },
+
+	{ 0, 0 }
  };

-static int bge_probe		(device_t);
-static int bge_attach		(device_t);
-static int bge_detach		(device_t);
-static int bge_suspend		(device_t);
-static int bge_resume		(device_t);
-static void bge_release_resources
-				(struct bge_softc *);
-static void bge_dma_map_addr	(void *, bus_dma_segment_t *, int, int);
-static int bge_dma_alloc	(device_t);
-static void bge_dma_free	(struct bge_softc *);
-
-static void bge_txeof		(struct bge_softc *);
-static void bge_rxeof		(struct bge_softc *);
-
-static void bge_tick_locked	(struct bge_softc *);
-static void bge_tick		(void *);
-static void bge_stats_update	(struct bge_softc *);
-static void bge_stats_update_regs
-				(struct bge_softc *);
-static int bge_encap		(struct bge_softc *, struct mbuf *,
-					u_int32_t *);
-
-static void bge_intr		(void *);
-static void bge_start_locked	(struct ifnet *);
-static void bge_start		(struct ifnet *);
-static int bge_ioctl		(struct ifnet *, u_long, caddr_t);
-static void bge_init_locked	(struct bge_softc *);
-static void bge_init		(void *);
-static void bge_stop		(struct bge_softc *);
-static void bge_watchdog		(struct ifnet *);
-static void bge_shutdown		(device_t);
-static int bge_ifmedia_upd	(struct ifnet *);
-static void bge_ifmedia_sts	(struct ifnet *, struct ifmediareq *);
-
-static u_int8_t	bge_eeprom_getbyte	(struct bge_softc *, int,  
u_int8_t *);
-static int bge_read_eeprom	(struct bge_softc *, caddr_t, int, int);
-
-static void bge_setmulti	(struct bge_softc *);
-
-static int bge_newbuf_std	(struct bge_softc *, int, struct mbuf *);
-static int bge_newbuf_jumbo	(struct bge_softc *, int, struct mbuf *);
-static int bge_init_rx_ring_std	(struct bge_softc *);
-static void bge_free_rx_ring_std	(struct bge_softc *);
-static int bge_init_rx_ring_jumbo	(struct bge_softc *);
-static void bge_free_rx_ring_jumbo	(struct bge_softc *);
-static void bge_free_tx_ring	(struct bge_softc *);
-static int bge_init_tx_ring	(struct bge_softc *);
+static const struct bge_vendor {
+	uint16_t	v_id;
+	const char	*v_name;
+} bge_vendors[] = {
+	{ ALTEON_VENDORID,	"Alteon" },
+	{ ALTIMA_VENDORID,	"Altima" },
+	{ APPLE_VENDORID,	"Apple" },
+	{ BCOM_VENDORID,	"Broadcom" },
+	{ SK_VENDORID,		"SysKonnect" },
+	{ TC_VENDORID,		"3Com" },

-static int bge_chipinit		(struct bge_softc *);
-static int bge_blockinit	(struct bge_softc *);
+	{ 0, NULL }
+};
+	
+static const struct bge_revision {
+	uint32_t	br_chipid;
+	const char	*br_name;
+} bge_revisions[] = {
+	{ BGE_CHIPID_BCM5700_A0,	"BCM5700 A0" },
+	{ BGE_CHIPID_BCM5700_A1,	"BCM5700 A1" },
+	{ BGE_CHIPID_BCM5700_B0,	"BCM5700 B0" },
+	{ BGE_CHIPID_BCM5700_B1,	"BCM5700 B1" },
+	{ BGE_CHIPID_BCM5700_B2,	"BCM5700 B2" },
+	{ BGE_CHIPID_BCM5700_B3,	"BCM5700 B3" },
+	{ BGE_CHIPID_BCM5700_ALTIMA,	"BCM5700 Altima" },
+	{ BGE_CHIPID_BCM5700_C0,	"BCM5700 C0" },
+	{ BGE_CHIPID_BCM5701_A0,	"BCM5701 A0" },
+	{ BGE_CHIPID_BCM5701_B0,	"BCM5701 B0" },
+	{ BGE_CHIPID_BCM5701_B2,	"BCM5701 B2" },
+	{ BGE_CHIPID_BCM5701_B5,	"BCM5701 B5" },
+	{ BGE_CHIPID_BCM5703_A0,	"BCM5703 A0" },
+	{ BGE_CHIPID_BCM5703_A1,	"BCM5703 A1" },
+	{ BGE_CHIPID_BCM5703_A2,	"BCM5703 A2" },
+	{ BGE_CHIPID_BCM5703_A3,	"BCM5703 A3" },
+	{ BGE_CHIPID_BCM5703_B0,	"BCM5703 B0" },
+	{ BGE_CHIPID_BCM5704_A0,	"BCM5704 A0" },
+	{ BGE_CHIPID_BCM5704_A1,	"BCM5704 A1" },
+	{ BGE_CHIPID_BCM5704_A2,	"BCM5704 A2" },
+	{ BGE_CHIPID_BCM5704_A3,	"BCM5704 A3" },
+	{ BGE_CHIPID_BCM5704_B0,	"BCM5704 B0" },
+	{ BGE_CHIPID_BCM5705_A0,	"BCM5705 A0" },
+	{ BGE_CHIPID_BCM5705_A1,	"BCM5705 A1" },
+	{ BGE_CHIPID_BCM5705_A2,	"BCM5705 A2" },
+	{ BGE_CHIPID_BCM5705_A3,	"BCM5705 A3" },
+	{ BGE_CHIPID_BCM5750_A0,	"BCM5750 A0" },
+	{ BGE_CHIPID_BCM5750_A1,	"BCM5750 A1" },
+	{ BGE_CHIPID_BCM5750_A3,	"BCM5750 A3" },
+	{ BGE_CHIPID_BCM5750_B0,	"BCM5750 B0" },
+	{ BGE_CHIPID_BCM5750_B1,	"BCM5750 B1" },
+	{ BGE_CHIPID_BCM5750_C0,	"BCM5750 C0" },
+	{ BGE_CHIPID_BCM5750_C1,	"BCM5750 C1" },
+	{ BGE_CHIPID_BCM5750_C2,	"BCM5750 C2" },
+	{ BGE_CHIPID_BCM5714_A0,	"BCM5714 A0" },
+	{ BGE_CHIPID_BCM5752_A0,	"BCM5752 A0" },
+	{ BGE_CHIPID_BCM5752_A1,	"BCM5752 A1" },
+	{ BGE_CHIPID_BCM5752_A2,	"BCM5752 A2" },
+	{ BGE_CHIPID_BCM5714_B0,	"BCM5714 B0" },
+	{ BGE_CHIPID_BCM5714_B3,	"BCM5714 B3" },
+	{ BGE_CHIPID_BCM5715_A0,	"BCM5715 A0" },
+	{ BGE_CHIPID_BCM5715_A1,	"BCM5715 A1" },
+	/* 5784 and 5787 share the same ASIC ID */
+	{ BGE_CHIPID_BCM5787_A0,	"BCM5754/5787 A0" },
+	{ BGE_CHIPID_BCM5787_A1,	"BCM5754/5787 A1" },
+	{ BGE_CHIPID_BCM5787_A2,	"BCM5754/5787 A2" },

-#ifdef notdef
-static u_int8_t bge_vpd_readbyte(struct bge_softc *, int);
-static void bge_vpd_read_res	(struct bge_softc *, struct vpd_res *,  
int);
-static void bge_vpd_read	(struct bge_softc *);
-#endif
+	{ 0, NULL }
+};
+
+/*
+ * Some defaults for major revisions, so that newer steppings
+ * that we don't know about have a shot at working.
+ */
+static const struct bge_revision bge_majorrevs[] = {
+	{ BGE_ASICREV_BCM5700,		"unknown BCM5700" },
+	{ BGE_ASICREV_BCM5701,		"unknown BCM5701" },
+	{ BGE_ASICREV_BCM5703,		"unknown BCM5703" },
+	{ BGE_ASICREV_BCM5704,		"unknown BCM5704" },
+	{ BGE_ASICREV_BCM5705,		"unknown BCM5705" },
+	{ BGE_ASICREV_BCM5750,		"unknown BCM5750" },
+	{ BGE_ASICREV_BCM5714_A0,	"unknown BCM5714" },
+	{ BGE_ASICREV_BCM5752,		"unknown BCM5752" },
+	{ BGE_ASICREV_BCM5780,		"unknown BCM5780" },
+	{ BGE_ASICREV_BCM5714,		"unknown BCM5714" },
+	{ BGE_ASICREV_BCM5755,		"unknown BCM5755" },
+	/* 5784 and 5787 share the same ASIC ID */
+	{ BGE_ASICREV_BCM5787,		"unknown BCM5754/5787" },

-static u_int32_t bge_readmem_ind
-				(struct bge_softc *, int);
-static void bge_writemem_ind	(struct bge_softc *, int, int);
+	{ 0, NULL }
+};
+
+#define BGE_IS_5705_OR_BEYOND(sc)			   \
+	((sc)->bge_asicrev == BGE_ASICREV_BCM5705	|| \
+	 (sc)->bge_asicrev == BGE_ASICREV_BCM5750	|| \
+	 (sc)->bge_asicrev == BGE_ASICREV_BCM5714_A0	|| \
+	 (sc)->bge_asicrev == BGE_ASICREV_BCM5780	|| \
+	 (sc)->bge_asicrev == BGE_ASICREV_BCM5714	|| \
+	 (sc)->bge_asicrev == BGE_ASICREV_BCM5752	|| \
+	 (sc)->bge_asicrev == BGE_ASICREV_BCM5755	|| \
+	 (sc)->bge_asicrev == BGE_ASICREV_BCM5787)
+
+#define BGE_IS_575X_PLUS(sc)				   \
+	((sc)->bge_asicrev == BGE_ASICREV_BCM5750	|| \
+	 (sc)->bge_asicrev == BGE_ASICREV_BCM5714_A0	|| \
+	 (sc)->bge_asicrev == BGE_ASICREV_BCM5780	|| \
+	 (sc)->bge_asicrev == BGE_ASICREV_BCM5714	|| \
+	 (sc)->bge_asicrev == BGE_ASICREV_BCM5752	|| \
+	 (sc)->bge_asicrev == BGE_ASICREV_BCM5755	|| \
+	 (sc)->bge_asicrev == BGE_ASICREV_BCM5787)
+
+#define BGE_IS_5714_FAMILY(sc)				   \
+	((sc)->bge_asicrev == BGE_ASICREV_BCM5714_A0	|| \
+	 (sc)->bge_asicrev == BGE_ASICREV_BCM5780	|| \
+	 (sc)->bge_asicrev == BGE_ASICREV_BCM5714)
+
+#define BGE_IS_JUMBO_CAPABLE(sc) \
+	((sc)->bge_asicrev == BGE_ASICREV_BCM5700	|| \
+	 (sc)->bge_asicrev == BGE_ASICREV_BCM5701	|| \
+	 (sc)->bge_asicrev == BGE_ASICREV_BCM5703	|| \
+	 (sc)->bge_asicrev == BGE_ASICREV_BCM5704)
+
+const struct bge_revision * bge_lookup_rev(uint32_t);
+const struct bge_vendor * bge_lookup_vendor(uint16_t);
+static int bge_probe(device_t);
+static int bge_attach(device_t);
+static int bge_detach(device_t);
+static int bge_suspend(device_t);
+static int bge_resume(device_t);
+static void bge_release_resources(struct bge_softc *);
+static void bge_dma_map_addr(void *, bus_dma_segment_t *, int, int);
+static int bge_dma_alloc(device_t);
+static void bge_dma_free(struct bge_softc *);
+
+static void bge_txeof(struct bge_softc *);
+static void bge_rxeof(struct bge_softc *);
+
+static void bge_tick_locked(struct bge_softc *);
+static void bge_tick(void *);
+static void bge_stats_update(struct bge_softc *);
+static void bge_stats_update_regs(struct bge_softc *);
+static int bge_encap(struct bge_softc *, struct mbuf *, uint32_t *);
+
+static void bge_intr(void *);
+static void bge_start_locked(struct ifnet *);
+static void bge_start(struct ifnet *);
+static int bge_ioctl(struct ifnet *, u_long, caddr_t);
+static void bge_init_locked(struct bge_softc *);
+static void bge_init(void *);
+static void bge_stop(struct bge_softc *);
+static void bge_watchdog(struct ifnet *);
+static void bge_shutdown(device_t);
+static int bge_ifmedia_upd_locked(struct ifnet *);
+static int bge_ifmedia_upd(struct ifnet *);
+static void bge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
+
+static uint8_t bge_eeprom_getbyte(struct bge_softc *, int, uint8_t *);
+static int bge_read_eeprom(struct bge_softc *, caddr_t, int, int);
+
+static void bge_setmulti(struct bge_softc *);
+
+static int bge_newbuf_std(struct bge_softc *, int, struct mbuf *);
+static int bge_newbuf_jumbo(struct bge_softc *, int, struct mbuf *);
+static int bge_init_rx_ring_std(struct bge_softc *);
+static void bge_free_rx_ring_std(struct bge_softc *);
+static int bge_init_rx_ring_jumbo(struct bge_softc *);
+static void bge_free_rx_ring_jumbo(struct bge_softc *);
+static void bge_free_tx_ring(struct bge_softc *);
+static int bge_init_tx_ring(struct bge_softc *);
+
+static int bge_chipinit(struct bge_softc *);
+static int bge_blockinit(struct bge_softc *);
+
+static uint32_t bge_readmem_ind(struct bge_softc *, int);
+static void bge_writemem_ind(struct bge_softc *, int, int);
  #ifdef notdef
-static u_int32_t bge_readreg_ind
-				(struct bge_softc *, int);
+static uint32_t bge_readreg_ind(struct bge_softc *, int);
  #endif
-static void bge_writereg_ind	(struct bge_softc *, int, int);
+static void bge_writereg_ind(struct bge_softc *, int, int);
+static void bge_writemem_direct(struct bge_softc *, int, int);

-static int bge_miibus_readreg	(device_t, int, int);
-static int bge_miibus_writereg	(device_t, int, int, int);
-static void bge_miibus_statchg	(device_t);
+static int bge_miibus_readreg(device_t, int, int);
+static int bge_miibus_writereg(device_t, int, int, int);
+static void bge_miibus_statchg(device_t);
  #ifdef DEVICE_POLLING
-static void bge_poll		(struct ifnet *ifp, enum poll_cmd cmd,
-				    int count);
-static void bge_poll_locked	(struct ifnet *ifp, enum poll_cmd cmd,
-				    int count);
+static void bge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count);
  #endif

-static void bge_reset		(struct bge_softc *);
-static void bge_link_upd	(struct bge_softc *);
+static void bge_reset(struct bge_softc *);
+static void bge_link_upd(struct bge_softc *);
+
+static int bge_sysctl_debug_info(SYSCTL_HANDLER_ARGS);
+static int bge_sysctl_reg_read(SYSCTL_HANDLER_ARGS);
+static int bge_sysctl_mem_read(SYSCTL_HANDLER_ARGS);
+static void bge_add_sysctls(struct bge_softc *);

  static device_method_t bge_methods[] = {
  	/* Device interface */
@@ -306,23 +422,25 @@
  DRIVER_MODULE(bge, pci, bge_driver, bge_devclass, 0, 0);
  DRIVER_MODULE(miibus, bge, miibus_driver, miibus_devclass, 0, 0);

-static u_int32_t
-bge_readmem_ind(sc, off)
-	struct bge_softc *sc;
-	int off;
+static int bge_fake_autoneg = 0;
+TUNABLE_INT("hw.bge.fake_autoneg", &bge_fake_autoneg);
+
+static uint32_t
+bge_readmem_ind(struct bge_softc *sc, int off)
  {
  	device_t dev;
+	uint32_t val;

  	dev = sc->bge_dev;

  	pci_write_config(dev, BGE_PCI_MEMWIN_BASEADDR, off, 4);
-	return(pci_read_config(dev, BGE_PCI_MEMWIN_DATA, 4));
+	val = pci_read_config(dev, BGE_PCI_MEMWIN_DATA, 4);
+	pci_write_config(dev, BGE_PCI_MEMWIN_BASEADDR, 0, 4);
+	return (val);
  }

  static void
-bge_writemem_ind(sc, off, val)
-	struct bge_softc *sc;
-	int off, val;
+bge_writemem_ind(struct bge_softc *sc, int off, int val)
  {
  	device_t dev;

@@ -330,29 +448,24 @@

  	pci_write_config(dev, BGE_PCI_MEMWIN_BASEADDR, off, 4);
  	pci_write_config(dev, BGE_PCI_MEMWIN_DATA, val, 4);
-
-	return;
+	pci_write_config(dev, BGE_PCI_MEMWIN_BASEADDR, 0, 4);
  }

  #ifdef notdef
-static u_int32_t
-bge_readreg_ind(sc, off)
-	struct bge_softc *sc;
-	int off;
+static uint32_t
+bge_readreg_ind(struct bge_softc *sc, int off)
  {
  	device_t dev;

  	dev = sc->bge_dev;

  	pci_write_config(dev, BGE_PCI_REG_BASEADDR, off, 4);
-	return(pci_read_config(dev, BGE_PCI_REG_DATA, 4));
+	return (pci_read_config(dev, BGE_PCI_REG_DATA, 4));
  }
  #endif

  static void
-bge_writereg_ind(sc, off, val)
-	struct bge_softc *sc;
-	int off, val;
+bge_writereg_ind(struct bge_softc *sc, int off, int val)
  {
  	device_t dev;

@@ -360,8 +473,12 @@

  	pci_write_config(dev, BGE_PCI_REG_BASEADDR, off, 4);
  	pci_write_config(dev, BGE_PCI_REG_DATA, val, 4);
+}

-	return;
+static void
+bge_writemem_direct(struct bge_softc *sc, int off, int val)
+{
+	CSR_WRITE_4(sc, off, val);
  }

  /*
@@ -369,11 +486,7 @@
   */

  static void
-bge_dma_map_addr(arg, segs, nseg, error)
-	void *arg;
-	bus_dma_segment_t *segs;
-	int nseg;
-	int error;
+bge_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int  
error)
  {
  	struct bge_dmamap_arg *ctx;

@@ -388,116 +501,19 @@
  	}

  	ctx->bge_busaddr = segs->ds_addr;
-
-	return;
-}
-
-#ifdef notdef
-static u_int8_t
-bge_vpd_readbyte(sc, addr)
-	struct bge_softc *sc;
-	int addr;
-{
-	int i;
-	device_t dev;
-	u_int32_t val;
-
-	dev = sc->bge_dev;
-	pci_write_config(dev, BGE_PCI_VPD_ADDR, addr, 2);
-	for (i = 0; i < BGE_TIMEOUT * 10; i++) {
-		DELAY(10);
-		if (pci_read_config(dev, BGE_PCI_VPD_ADDR, 2) & BGE_VPD_FLAG)
-			break;
-	}
-
-	if (i == BGE_TIMEOUT) {
-		device_printf(sc->bge_dev, "VPD read timed out\n");
-		return(0);
-	}
-
-	val = pci_read_config(dev, BGE_PCI_VPD_DATA, 4);
-
-	return((val >> ((addr % 4) * 8)) & 0xFF);
-}
-
-static void
-bge_vpd_read_res(sc, res, addr)
-	struct bge_softc *sc;
-	struct vpd_res *res;
-	int addr;
-{
-	int i;
-	u_int8_t *ptr;
-
-	ptr = (u_int8_t *)res;
-	for (i = 0; i < sizeof(struct vpd_res); i++)
-		ptr[i] = bge_vpd_readbyte(sc, i + addr);
-
-	return;
  }

-static void
-bge_vpd_read(sc)
-	struct bge_softc *sc;
-{
-	int pos = 0, i;
-	struct vpd_res res;
-
-	if (sc->bge_vpd_prodname != NULL)
-		free(sc->bge_vpd_prodname, M_DEVBUF);
-	if (sc->bge_vpd_readonly != NULL)
-		free(sc->bge_vpd_readonly, M_DEVBUF);
-	sc->bge_vpd_prodname = NULL;
-	sc->bge_vpd_readonly = NULL;
-
-	bge_vpd_read_res(sc, &res, pos);
-
-	if (res.vr_id != VPD_RES_ID) {
-		device_printf(sc->bge_dev,
-		    "bad VPD resource id: expected %x got %x\n", VPD_RES_ID,
-		    res.vr_id);
-		return;
-	}
-
-	pos += sizeof(res);
-	sc->bge_vpd_prodname = malloc(res.vr_len + 1, M_DEVBUF, M_NOWAIT);
-	for (i = 0; i < res.vr_len; i++)
-		sc->bge_vpd_prodname[i] = bge_vpd_readbyte(sc, i + pos);
-	sc->bge_vpd_prodname[i] = '\0';
-	pos += i;
-
-	bge_vpd_read_res(sc, &res, pos);
-
-	if (res.vr_id != VPD_RES_READ) {
-		device_printf(sc->bge_dev,
-		    "bad VPD resource id: expected %x got %x\n", VPD_RES_READ,
-		    res.vr_id);
-		return;
-	}
-
-	pos += sizeof(res);
-	sc->bge_vpd_readonly = malloc(res.vr_len, M_DEVBUF, M_NOWAIT);
-	for (i = 0; i < res.vr_len + 1; i++)
-		sc->bge_vpd_readonly[i] = bge_vpd_readbyte(sc, i + pos);
-
-	return;
-}
-#endif
-
  /*
   * Read a byte of data stored in the EEPROM at address 'addr.' The
   * BCM570x supports both the traditional bitbang interface and an
   * auto access interface for reading the EEPROM. We use the auto
   * access method.
   */
-static u_int8_t
-bge_eeprom_getbyte(sc, addr, dest)
-	struct bge_softc *sc;
-	int addr;
-	u_int8_t *dest;
+static uint8_t
+bge_eeprom_getbyte(struct bge_softc *sc, int addr, uint8_t *dest)
  {
  	int i;
-	u_int32_t byte = 0;
+	uint32_t byte = 0;

  	/*
  	 * Enable use of auto EEPROM access so we can avoid
@@ -522,7 +538,7 @@

  	if (i == BGE_TIMEOUT) {
  		device_printf(sc->bge_dev, "EEPROM read timed out\n");
-		return(1);
+		return (1);
  	}

  	/* Get result. */
@@ -530,39 +546,33 @@

  	*dest = (byte >> ((addr % 4) * 8)) & 0xFF;

-	return(0);
+	return (0);
  }

  /*
   * Read a sequence of bytes from the EEPROM.
   */
  static int
-bge_read_eeprom(sc, dest, off, cnt)
-	struct bge_softc *sc;
-	caddr_t dest;
-	int off;
-	int cnt;
+bge_read_eeprom(struct bge_softc *sc, caddr_t dest, int off, int cnt)
  {
-	int err = 0, i;
-	u_int8_t byte = 0;
+	int i, error = 0;
+	uint8_t byte = 0;

  	for (i = 0; i < cnt; i++) {
-		err = bge_eeprom_getbyte(sc, off + i, &byte);
-		if (err)
+		error = bge_eeprom_getbyte(sc, off + i, &byte);
+		if (error)
  			break;
  		*(dest + i) = byte;
  	}

-	return(err ? 1 : 0);
+	return (error ? 1 : 0);
  }

  static int
-bge_miibus_readreg(dev, phy, reg)
-	device_t dev;
-	int phy, reg;
+bge_miibus_readreg(device_t dev, int phy, int reg)
  {
  	struct bge_softc *sc;
-	u_int32_t val, autopoll;
+	uint32_t val, autopoll;
  	int i;

  	sc = device_get_softc(dev);
@@ -577,7 +587,7 @@
  	 * special-cased.
  	 */
  	if (phy != 1)
-		return(0);
+		return (0);

  	/* Reading with autopolling on may trigger PCI errors */
  	autopoll = CSR_READ_4(sc, BGE_MI_MODE);
@@ -610,18 +620,16 @@
  	}

  	if (val & BGE_MICOMM_READFAIL)
-		return(0);
+		return (0);

-	return(val & 0xFFFF);
+	return (val & 0xFFFF);
  }

  static int
-bge_miibus_writereg(dev, phy, reg, val)
-	device_t dev;
-	int phy, reg, val;
+bge_miibus_writereg(device_t dev, int phy, int reg, int val)
  {
  	struct bge_softc *sc;
-	u_int32_t autopoll;
+	uint32_t autopoll;
  	int i;

  	sc = device_get_softc(dev);
@@ -648,15 +656,14 @@

  	if (i == BGE_TIMEOUT) {
  		if_printf(sc->bge_ifp, "PHY read timed out\n");
-		return(0);
+		return (0);
  	}

-	return(0);
+	return (0);
  }

  static void
-bge_miibus_statchg(dev)
-	device_t dev;
+bge_miibus_statchg(device_t dev)
  {
  	struct bge_softc *sc;
  	struct mii_data *mii;
@@ -665,39 +672,32 @@
  	mii = device_get_softc(sc->bge_miibus);

  	BGE_CLRBIT(sc, BGE_MAC_MODE, BGE_MACMODE_PORTMODE);
-	if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T) {
+	if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T)
  		BGE_SETBIT(sc, BGE_MAC_MODE, BGE_PORTMODE_GMII);
-	} else {
+	else
  		BGE_SETBIT(sc, BGE_MAC_MODE, BGE_PORTMODE_MII);
-	}

-	if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) {
+	if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
  		BGE_CLRBIT(sc, BGE_MAC_MODE, BGE_MACMODE_HALF_DUPLEX);
-	} else {
+	else
  		BGE_SETBIT(sc, BGE_MAC_MODE, BGE_MACMODE_HALF_DUPLEX);
-	}
-
-	return;
  }

  /*
   * Intialize a standard receive ring descriptor.
   */
  static int
-bge_newbuf_std(sc, i, m)
-	struct bge_softc	*sc;
-	int			i;
-	struct mbuf		*m;
-{
-	struct mbuf		*m_new = NULL;
-	struct bge_rx_bd	*r;
-	struct bge_dmamap_arg	ctx;
-	int			error;
+bge_newbuf_std(struct bge_softc *sc, int i, struct mbuf *m)
+{
+	struct mbuf *m_new = NULL;
+	struct bge_rx_bd *r;
+	struct bge_dmamap_arg ctx;
+	int error;

  	if (m == NULL) {
  		m_new = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
  		if (m_new == NULL)
-			return(ENOBUFS);
+			return (ENOBUFS);
  		m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
  	} else {
  		m_new = m;
@@ -705,7 +705,7 @@
  		m_new->m_data = m_new->m_ext.ext_buf;
  	}

-	if (!sc->bge_rx_alignment_bug)
+	if ((sc->bge_flags & BGE_FLAG_RX_ALIGNBUG) == 0)
  		m_adj(m_new, ETHER_ALIGN);
  	sc->bge_cdata.bge_rx_std_chain[i] = m_new;
  	r = &sc->bge_ldata.bge_rx_std_ring[i];
@@ -719,7 +719,7 @@
  			sc->bge_cdata.bge_rx_std_chain[i] = NULL;
  			m_freem(m_new);
  		}
-		return(ENOMEM);
+		return (ENOMEM);
  	}
  	r->bge_addr.bge_addr_lo = BGE_ADDR_LO(ctx.bge_busaddr);
  	r->bge_addr.bge_addr_hi = BGE_ADDR_HI(ctx.bge_busaddr);
@@ -731,7 +731,7 @@
  	    sc->bge_cdata.bge_rx_std_dmamap[i],
  	    BUS_DMASYNC_PREREAD);

-	return(0);
+	return (0);
  }

  /*
@@ -739,10 +739,7 @@
   * a jumbo buffer from the pool managed internally by the driver.
   */
  static int
-bge_newbuf_jumbo(sc, i, m)
-	struct bge_softc *sc;
-	int i;
-	struct mbuf *m;
+bge_newbuf_jumbo(struct bge_softc *sc, int i, struct mbuf *m)
  {
  	bus_dma_segment_t segs[BGE_NSEG_JUMBO];
  	struct bge_extrx_bd *r;
@@ -753,12 +750,12 @@
  	if (m == NULL) {
  		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
  		if (m_new == NULL)
-			return(ENOBUFS);
+			return (ENOBUFS);

  		m_cljget(m_new, M_DONTWAIT, MJUM9BYTES);
  		if (!(m_new->m_flags & M_EXT)) {
  			m_freem(m_new);
-			return(ENOBUFS);
+			return (ENOBUFS);
  		}
  		m_new->m_len = m_new->m_pkthdr.len = MJUM9BYTES;
  	} else {
@@ -767,7 +764,7 @@
  		m_new->m_data = m_new->m_ext.ext_buf;
  	}

-	if (!sc->bge_rx_alignment_bug)
+	if ((sc->bge_flags & BGE_FLAG_RX_ALIGNBUG) == 0)
  		m_adj(m_new, ETHER_ALIGN);

  	error = bus_dmamap_load_mbuf_sg(sc->bge_cdata.bge_mtag_jumbo,
@@ -776,7 +773,7 @@
  	if (error) {
  		if (m == NULL)
  			m_freem(m_new);
-		return(error);
+		return (error);
  	}
  	sc->bge_cdata.bge_rx_jumbo_chain[i] = m_new;

@@ -823,14 +820,13 @@
   * the NIC.
   */
  static int
-bge_init_rx_ring_std(sc)
-	struct bge_softc *sc;
+bge_init_rx_ring_std(struct bge_softc *sc)
  {
  	int i;

  	for (i = 0; i < BGE_SSLOTS; i++) {
  		if (bge_newbuf_std(sc, i, NULL) == ENOBUFS)
-			return(ENOBUFS);
+			return (ENOBUFS);
  	};

  	bus_dmamap_sync(sc->bge_cdata.bge_rx_std_ring_tag,
@@ -840,12 +836,11 @@
  	sc->bge_std = i - 1;
  	CSR_WRITE_4(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);

-	return(0);
+	return (0);
  }

  static void
-bge_free_rx_ring_std(sc)
-	struct bge_softc *sc;
+bge_free_rx_ring_std(struct bge_softc *sc)
  {
  	int i;

@@ -862,20 +857,17 @@
  		bzero((char *)&sc->bge_ldata.bge_rx_std_ring[i],
  		    sizeof(struct bge_rx_bd));
  	}
-
-	return;
  }

  static int
-bge_init_rx_ring_jumbo(sc)
-	struct bge_softc *sc;
+bge_init_rx_ring_jumbo(struct bge_softc *sc)
  {
  	struct bge_rcb *rcb;
  	int i;

  	for (i = 0; i < BGE_JUMBO_RX_RING_CNT; i++) {
  		if (bge_newbuf_jumbo(sc, i, NULL) == ENOBUFS)
-			return(ENOBUFS);
+			return (ENOBUFS);
  	};

  	bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag,
@@ -891,12 +883,11 @@

  	CSR_WRITE_4(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo);

-	return(0);
+	return (0);
  }

  static void
-bge_free_rx_ring_jumbo(sc)
-	struct bge_softc *sc;
+bge_free_rx_ring_jumbo(struct bge_softc *sc)
  {
  	int i;

@@ -913,13 +904,10 @@
  		bzero((char *)&sc->bge_ldata.bge_rx_jumbo_ring[i],
  		    sizeof(struct bge_extrx_bd));
  	}
-
-	return;
  }

  static void
-bge_free_tx_ring(sc)
-	struct bge_softc *sc;
+bge_free_tx_ring(struct bge_softc *sc)
  {
  	int i;

@@ -939,13 +927,10 @@
  		bzero((char *)&sc->bge_ldata.bge_tx_ring[i],
  		    sizeof(struct bge_tx_bd));
  	}
-
-	return;
  }

  static int
-bge_init_tx_ring(sc)
-	struct bge_softc *sc;
+bge_init_tx_ring(struct bge_softc *sc)
  {
  	sc->bge_txcnt = 0;
  	sc->bge_tx_saved_considx = 0;
@@ -964,16 +949,15 @@
  	if (sc->bge_chiprev == BGE_CHIPREV_5700_BX)
  		CSR_WRITE_4(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);

-	return(0);
+	return (0);
  }

  static void
-bge_setmulti(sc)
-	struct bge_softc *sc;
+bge_setmulti(struct bge_softc *sc)
  {
  	struct ifnet *ifp;
  	struct ifmultiaddr *ifma;
-	u_int32_t hashes[4] = { 0, 0, 0, 0 };
+	uint32_t hashes[4] = { 0, 0, 0, 0 };
  	int h, i;

  	BGE_LOCK_ASSERT(sc);
@@ -1003,8 +987,6 @@

  	for (i = 0; i < 4; i++)
  		CSR_WRITE_4(sc, BGE_MAR0 + (i * 4), hashes[i]);
-
-	return;
  }

  /*
@@ -1012,11 +994,10 @@
   * self-test results.
   */
  static int
-bge_chipinit(sc)
-	struct bge_softc *sc;
+bge_chipinit(struct bge_softc *sc)
  {
-	int			i;
-	u_int32_t		dma_rw_ctl;
+	uint32_t dma_rw_ctl;
+	int i;

  	/* Set endian type before we access any non-PCI registers. */
  	pci_write_config(sc->bge_dev, BGE_PCI_MISC_CTL, BGE_INIT, 4);
@@ -1027,7 +1008,7 @@
  	 */
  	if (CSR_READ_4(sc, BGE_RXCPU_MODE) & BGE_RXCPUMODE_ROMFAIL) {
  		device_printf(sc->bge_dev, "RX CPU self-diagnostics failed!\n");
-		return(ENODEV);
+		return (ENODEV);
  	}

  	/* Clear the MAC control register */
@@ -1038,32 +1019,36 @@
  	 * internal memory.
  	 */
  	for (i = BGE_STATS_BLOCK;
-	    i < BGE_STATS_BLOCK_END + 1; i += sizeof(u_int32_t))
+	    i < BGE_STATS_BLOCK_END + 1; i += sizeof(uint32_t))
  		BGE_MEMWIN_WRITE(sc, i, 0);

  	for (i = BGE_STATUS_BLOCK;
-	    i < BGE_STATUS_BLOCK_END + 1; i += sizeof(u_int32_t))
+	    i < BGE_STATUS_BLOCK_END + 1; i += sizeof(uint32_t))
  		BGE_MEMWIN_WRITE(sc, i, 0);

  	/* Set up the PCI DMA control register. */
-	if (sc->bge_pcie) {
+	if (sc->bge_flags & BGE_FLAG_PCIE) {
+		/* PCI Express bus */
  		dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD |
  		    (0xf << BGE_PCIDMARWCTL_RD_WAT_SHIFT) |
  		    (0x2 << BGE_PCIDMARWCTL_WR_WAT_SHIFT);
-	} else if (pci_read_config(sc->bge_dev, BGE_PCI_PCISTATE, 4) &
-	    BGE_PCISTATE_PCI_BUSMODE) {
-		/* Conventional PCI bus */
-		dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD |
-		    (0x7 << BGE_PCIDMARWCTL_RD_WAT_SHIFT) |
-		    (0x7 << BGE_PCIDMARWCTL_WR_WAT_SHIFT) |
-		    (0x0F);
-	} else {
+	} else if (sc->bge_flags & BGE_FLAG_PCIX) {
  		/* PCI-X bus */
-		/*
-		 * The 5704 uses a different encoding of read/write
-		 * watermarks.
-		 */
-		if (sc->bge_asicrev == BGE_ASICREV_BCM5704)
+		if (BGE_IS_5714_FAMILY(sc)) {
+			dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD;
+			dma_rw_ctl &= ~BGE_PCIDMARWCTL_ONEDMA_ATONCE; /* XXX */
+			/* XXX magic values, Broadcom-supplied Linux driver */
+			if (sc->bge_asicrev == BGE_ASICREV_BCM5780)
+				dma_rw_ctl |= (1 << 20) | (1 << 18) |
+				    BGE_PCIDMARWCTL_ONEDMA_ATONCE;
+			else
+				dma_rw_ctl |= (1 << 20) | (1 << 18) | (1 << 15);
+
+		} else if (sc->bge_asicrev == BGE_ASICREV_BCM5704)
+			/*
+			 * The 5704 uses a different encoding of read/write
+			 * watermarks.
+			 */
  			dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD |
  			    (0x7 << BGE_PCIDMARWCTL_RD_WAT_SHIFT) |
  			    (0x3 << BGE_PCIDMARWCTL_WR_WAT_SHIFT);
@@ -1079,18 +1064,22 @@
  		 */
  		if (sc->bge_asicrev == BGE_ASICREV_BCM5703 ||
  		    sc->bge_asicrev == BGE_ASICREV_BCM5704) {
-			u_int32_t tmp;
+			uint32_t tmp;

  			tmp = CSR_READ_4(sc, BGE_PCI_CLKCTL) & 0x1f;
  			if (tmp == 0x6 || tmp == 0x7)
  				dma_rw_ctl |= BGE_PCIDMARWCTL_ONEDMA_ATONCE;
  		}
-	}
+	} else
+		/* Conventional PCI bus */
+		dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD |
+		    (0x7 << BGE_PCIDMARWCTL_RD_WAT_SHIFT) |
+		    (0x7 << BGE_PCIDMARWCTL_WR_WAT_SHIFT) |
+		    (0x0F);

  	if (sc->bge_asicrev == BGE_ASICREV_BCM5703 ||
  	    sc->bge_asicrev == BGE_ASICREV_BCM5704 ||
-	    sc->bge_asicrev == BGE_ASICREV_BCM5705 ||
-	    sc->bge_asicrev == BGE_ASICREV_BCM5750)
+	    sc->bge_asicrev == BGE_ASICREV_BCM5705)
  		dma_rw_ctl &= ~BGE_PCIDMARWCTL_MINDMA;
  	pci_write_config(sc->bge_dev, BGE_PCI_DMA_RW_CTL, dma_rw_ctl, 4);

@@ -1121,17 +1110,17 @@
  	/* Set the timer prescaler (always 66Mhz) */
  	CSR_WRITE_4(sc, BGE_MISC_CFG, 65 << 1/*BGE_32BITTIME_66MHZ*/);

-	return(0);
+	return (0);
  }

  static int
-bge_blockinit(sc)
-	struct bge_softc *sc;
+bge_blockinit(struct bge_softc *sc)
  {
  	struct bge_rcb *rcb;
  	bus_size_t vrcb;
  	bge_hostaddr taddr;
  	int i;
+	uint32_t val;

  	/*
  	 * Initialize the memory window pointer register so that
@@ -1143,10 +1132,9 @@

  	/* Note: the BCM5704 has a smaller mbuf space than other chips. */

-	if (sc->bge_asicrev != BGE_ASICREV_BCM5705 &&
-	    sc->bge_asicrev != BGE_ASICREV_BCM5750) {
+	if ((sc->bge_flags & BGE_FLAG_5705_PLUS) == 0) {
  		/* Configure mbuf memory pool */
-		if (sc->bge_extram) {
+		if (sc->bge_flags & BGE_FLAG_EXTRAM) {
  			CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_BASEADDR,
  			    BGE_EXT_SSRAM);
  			if (sc->bge_asicrev == BGE_ASICREV_BCM5704)
@@ -1169,8 +1157,7 @@
  	}

  	/* Configure mbuf pool watermarks */
-	if (sc->bge_asicrev == BGE_ASICREV_BCM5705 ||
-	    sc->bge_asicrev == BGE_ASICREV_BCM5750) {
+	if ((sc->bge_flags & BGE_FLAG_5705_PLUS) == 0) {
  		CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0);
  		CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x10);
  	} else {
@@ -1184,8 +1171,7 @@
  	CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_HIWAT, 10);

  	/* Enable buffer manager */
-	if (sc->bge_asicrev != BGE_ASICREV_BCM5705 &&
-	    sc->bge_asicrev != BGE_ASICREV_BCM5750) {
+	if ((sc->bge_flags & BGE_FLAG_5705_PLUS) == 0) {
  		CSR_WRITE_4(sc, BGE_BMAN_MODE,
  		    BGE_BMANMODE_ENABLE|BGE_BMANMODE_LOMBUF_ATTN);

@@ -1199,7 +1185,7 @@
  		if (i == BGE_TIMEOUT) {
  			device_printf(sc->bge_dev,
  			    "buffer manager failed to start\n");
-			return(ENXIO);
+			return (ENXIO);
  		}
  	}

@@ -1216,7 +1202,7 @@

  	if (i == BGE_TIMEOUT) {
  		device_printf(sc->bge_dev, "flow-through queue init failed\n");
-		return(ENXIO);
+		return (ENXIO);
  	}

  	/* Initialize the standard RX ring control block */
@@ -1227,13 +1213,12 @@
  	    BGE_ADDR_HI(sc->bge_ldata.bge_rx_std_ring_paddr);
  	bus_dmamap_sync(sc->bge_cdata.bge_rx_std_ring_tag,
  	    sc->bge_cdata.bge_rx_std_ring_map, BUS_DMASYNC_PREREAD);
-	if (sc->bge_asicrev == BGE_ASICREV_BCM5705 ||
-	    sc->bge_asicrev == BGE_ASICREV_BCM5750)
+	if (sc->bge_flags & BGE_FLAG_5705_PLUS)
  		rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(512, 0);
  	else
  		rcb->bge_maxlen_flags =
  		    BGE_RCB_MAXLEN_FLAGS(BGE_MAX_FRAMELEN, 0);
-	if (sc->bge_extram)
+	if (sc->bge_flags & BGE_FLAG_EXTRAM)
  		rcb->bge_nicaddr = BGE_EXT_STD_RX_RINGS;
  	else
  		rcb->bge_nicaddr = BGE_STD_RX_RINGS;
@@ -1250,8 +1235,7 @@
  	 * using this ring (i.e. once we set the MTU
  	 * high enough to require it).
  	 */
-	if (sc->bge_asicrev != BGE_ASICREV_BCM5705 &&
-	    sc->bge_asicrev != BGE_ASICREV_BCM5750) {
+	if (sc->bge_flags & BGE_FLAG_JUMBO) {
  		rcb = &sc->bge_ldata.bge_info.bge_jumbo_rx_rcb;

  		rcb->bge_hostaddr.bge_addr_lo =
@@ -1263,7 +1247,7 @@
  		    BUS_DMASYNC_PREREAD);
  		rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(0,
  		    BGE_RCB_FLAG_USE_EXT_RX_BD|BGE_RCB_FLAG_RING_DISABLED);
-		if (sc->bge_extram)
+		if (sc->bge_flags & BGE_FLAG_EXTRAM)
  			rcb->bge_nicaddr = BGE_EXT_JUMBO_RX_RINGS;
  		else
  			rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS;
@@ -1289,7 +1273,12 @@
  	 * values are 1/8th the number of descriptors allocated to
  	 * each ring.
  	 */
-	CSR_WRITE_4(sc, BGE_RBDI_STD_REPL_THRESH, BGE_STD_RX_RING_CNT/8);
+	if (sc->bge_flags & BGE_FLAG_5705_PLUS)
+		val = 8;
+	else
+		val = BGE_STD_RX_RING_CNT / 8;
+
+	CSR_WRITE_4(sc, BGE_RBDI_STD_REPL_THRESH, val);
  	CSR_WRITE_4(sc, BGE_RBDI_JUMBO_REPL_THRESH, BGE_JUMBO_RX_RING_CNT/8);

  	/*
@@ -1312,8 +1301,7 @@
  	RCB_WRITE_4(sc, vrcb, bge_hostaddr.bge_addr_lo, taddr.bge_addr_lo);
  	RCB_WRITE_4(sc, vrcb, bge_nicaddr,
  	    BGE_NIC_TXRING_ADDR(0, BGE_TX_RING_CNT));
-	if (sc->bge_asicrev != BGE_ASICREV_BCM5705 &&
-	    sc->bge_asicrev != BGE_ASICREV_BCM5750)
+	if ((sc->bge_flags & BGE_FLAG_5705_PLUS) == 0)
  		RCB_WRITE_4(sc, vrcb, bge_maxlen_flags,
  		    BGE_RCB_MAXLEN_FLAGS(BGE_TX_RING_CNT, 0));

@@ -1327,7 +1315,7 @@
  		    BGE_RCB_FLAG_RING_DISABLED));
  		RCB_WRITE_4(sc, vrcb, bge_nicaddr, 0);
  		CSR_WRITE_4(sc, BGE_MBX_RX_CONS0_LO +
-		    (i * (sizeof(u_int64_t))), 0);
+		    (i * (sizeof(uint64_t))), 0);
  		vrcb += sizeof(struct bge_rcb);
  	}

@@ -1352,9 +1340,9 @@

  	/* Set random backoff seed for TX */
  	CSR_WRITE_4(sc, BGE_TX_RANDOM_BACKOFF,
-	    IFP2ENADDR(sc->bge_ifp)[0] + IFP2ENADDR(sc->bge_ifp)[1] +
-	    IFP2ENADDR(sc->bge_ifp)[2] + IFP2ENADDR(sc->bge_ifp)[3] +
-	    IFP2ENADDR(sc->bge_ifp)[4] + IFP2ENADDR(sc->bge_ifp)[5] +
+	    IF_LLADDR(sc->bge_ifp)[0] + IF_LLADDR(sc->bge_ifp)[1] +
+	    IF_LLADDR(sc->bge_ifp)[2] + IF_LLADDR(sc->bge_ifp)[3] +
+	    IF_LLADDR(sc->bge_ifp)[4] + IF_LLADDR(sc->bge_ifp)[5] +
  	    BGE_TX_BACKOFF_SEED_MASK);

  	/* Set inter-packet gap */
@@ -1389,7 +1377,7 @@
  	if (i == BGE_TIMEOUT) {
  		device_printf(sc->bge_dev,
  		    "host coalescing engine failed to idle\n");
-		return(ENXIO);
+		return (ENXIO);
  	}

  	/* Set up host coalescing defaults */
@@ -1397,8 +1385,7 @@
  	CSR_WRITE_4(sc, BGE_HCC_TX_COAL_TICKS, sc->bge_tx_coal_ticks);
  	CSR_WRITE_4(sc, BGE_HCC_RX_MAX_COAL_BDS, sc->bge_rx_max_coal_bds);
  	CSR_WRITE_4(sc, BGE_HCC_TX_MAX_COAL_BDS, sc->bge_tx_max_coal_bds);
-	if (sc->bge_asicrev != BGE_ASICREV_BCM5705 &&
-	    sc->bge_asicrev != BGE_ASICREV_BCM5750) {
+	if ((sc->bge_flags & BGE_FLAG_5705_PLUS) == 0) {
  		CSR_WRITE_4(sc, BGE_HCC_RX_COAL_TICKS_INT, 0);
  		CSR_WRITE_4(sc, BGE_HCC_TX_COAL_TICKS_INT, 0);
  	}
@@ -1406,8 +1393,7 @@
  	CSR_WRITE_4(sc, BGE_HCC_TX_MAX_COAL_BDS_INT, 0);

  	/* Set up address of statistics block */
-	if (sc->bge_asicrev != BGE_ASICREV_BCM5705 &&
-	    sc->bge_asicrev != BGE_ASICREV_BCM5750) {
+	if ((sc->bge_flags & BGE_FLAG_5705_PLUS) == 0) {
  		CSR_WRITE_4(sc, BGE_HCC_STATS_ADDR_HI,
  		    BGE_ADDR_HI(sc->bge_ldata.bge_stats_paddr));
  		CSR_WRITE_4(sc, BGE_HCC_STATS_ADDR_LO,
@@ -1436,8 +1422,7 @@
  	CSR_WRITE_4(sc, BGE_RXLP_MODE, BGE_RXLPMODE_ENABLE);

  	/* Turn on RX list selector state machine. */
-	if (sc->bge_asicrev != BGE_ASICREV_BCM5705 &&
-	    sc->bge_asicrev != BGE_ASICREV_BCM5750)
+	if ((sc->bge_flags & BGE_FLAG_5705_PLUS) == 0)
  		CSR_WRITE_4(sc, BGE_RXLS_MODE, BGE_RXLSMODE_ENABLE);

  	/* Turn on DMA, clear stats */
@@ -1445,7 +1430,8 @@
  	    BGE_MACMODE_RXDMA_ENB|BGE_MACMODE_RX_STATS_CLEAR|
  	    BGE_MACMODE_TX_STATS_CLEAR|BGE_MACMODE_RX_STATS_ENB|
  	    BGE_MACMODE_TX_STATS_ENB|BGE_MACMODE_FRMHDR_DMA_ENB|
-	    (sc->bge_tbi ? BGE_PORTMODE_TBI : BGE_PORTMODE_MII));
+	    ((sc->bge_flags & BGE_FLAG_TBI) ? BGE_PORTMODE_TBI :
+	    BGE_PORTMODE_MII));

  	/* Set misc. local control, enable interrupts on attentions */
  	CSR_WRITE_4(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_INTR_ONATTN);
@@ -1459,13 +1445,19 @@
  #endif

  	/* Turn on DMA completion state machine */
-	if (sc->bge_asicrev != BGE_ASICREV_BCM5705 &&
-	    sc->bge_asicrev != BGE_ASICREV_BCM5750)
+	if ((sc->bge_flags & BGE_FLAG_5705_PLUS) == 0)
  		CSR_WRITE_4(sc, BGE_DMAC_MODE, BGE_DMACMODE_ENABLE);

+
+	val = BGE_WDMAMODE_ENABLE|BGE_WDMAMODE_ALL_ATTNS;
+
+	/* Enable host coalescing bug fix. */
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5755 ||
+	    sc->bge_asicrev == BGE_ASICREV_BCM5787)
+			val |= (1 << 29);
+
  	/* Turn on write DMA state machine */
-	CSR_WRITE_4(sc, BGE_WDMA_MODE,
-	    BGE_WDMAMODE_ENABLE|BGE_WDMAMODE_ALL_ATTNS);
+	CSR_WRITE_4(sc, BGE_WDMA_MODE, val);

  	/* Turn on read DMA state machine */
  	CSR_WRITE_4(sc, BGE_RDMA_MODE,
@@ -1481,8 +1473,7 @@
  	CSR_WRITE_4(sc, BGE_RDBDI_MODE, BGE_RDBDIMODE_ENABLE);

  	/* Turn on Mbuf cluster free state machine */
-	if (sc->bge_asicrev != BGE_ASICREV_BCM5705 &&
-	    sc->bge_asicrev != BGE_ASICREV_BCM5750)
+	if ((sc->bge_flags & BGE_FLAG_5705_PLUS) == 0)
  		CSR_WRITE_4(sc, BGE_MBCF_MODE, BGE_MBCFMODE_ENABLE);

  	/* Turn on send BD completion state machine */
@@ -1511,12 +1502,12 @@
  	CSR_WRITE_4(sc, BGE_MI_STS, 0);

  	/* Enable PHY auto polling (for MII/GMII only) */
-	if (sc->bge_tbi) {
+	if (sc->bge_flags & BGE_FLAG_TBI) {
  		CSR_WRITE_4(sc, BGE_MI_STS, BGE_MISTS_LINK);
  	} else {
  		BGE_SETBIT(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL|10<<16);
  		if (sc->bge_asicrev == BGE_ASICREV_BCM5700 &&
-		    sc->bge_chipid != BGE_CHIPID_BCM5700_B1)
+		    sc->bge_chipid != BGE_CHIPID_BCM5700_B2)
  			CSR_WRITE_4(sc, BGE_MAC_EVT_ENB,
  			    BGE_EVTENB_MI_INTERRUPT);
  	}
@@ -1535,81 +1526,110 @@
  	/* Enable link state change attentions. */
  	BGE_SETBIT(sc, BGE_MAC_EVT_ENB, BGE_EVTENB_LINK_CHANGED);

-	return(0);
+	return (0);
+}
+
+const struct bge_revision *
+bge_lookup_rev(uint32_t chipid)
+{
+	const struct bge_revision *br;
+
+	for (br = bge_revisions; br->br_name != NULL; br++) {
+		if (br->br_chipid == chipid)
+			return (br);
+	}
+
+	for (br = bge_majorrevs; br->br_name != NULL; br++) {
+		if (br->br_chipid == BGE_ASICREV(chipid))
+			return (br);
+	}
+
+	return (NULL);
+}
+
+const struct bge_vendor *
+bge_lookup_vendor(uint16_t vid)
+{
+	const struct bge_vendor *v;
+
+	for (v = bge_vendors; v->v_name != NULL; v++)
+		if (v->v_id == vid)
+			return (v);
+		
+	panic("%s: unknown vendor %d", __func__, vid);
+	return (NULL);
  }

  /*
   * Probe for a Broadcom chip. Check the PCI vendor and device IDs
- * against our list and return its name if we find a match. Note
- * that since the Broadcom controller contains VPD support, we
+ * against our list and return its name if we find a match.
+ *
+ * Note that since the Broadcom controller contains VPD support, we
   * can get the device name string from the controller itself instead
   * of the compiled-in string. This is a little slow, but it guarantees
- * we'll always announce the right product name.
+ * we'll always announce the right product name. Unfortunately, this
+ * is possible only later in bge_attach(), when we have established
+ * access to EEPROM.
   */
  static int
-bge_probe(dev)
-	device_t dev;
+bge_probe(device_t dev)
  {
-	struct bge_type *t;
-	struct bge_softc *sc;
-	char *descbuf;
-
-	t = bge_devs;
+	struct bge_type *t = bge_devs;
+	struct bge_softc *sc = device_get_softc(dev);

-	sc = device_get_softc(dev);
  	bzero(sc, sizeof(struct bge_softc));
  	sc->bge_dev = dev;

-	while(t->bge_name != NULL) {
+	while(t->bge_vid != 0) {
  		if ((pci_get_vendor(dev) == t->bge_vid) &&
  		    (pci_get_device(dev) == t->bge_did)) {
-#ifdef notdef
-			bge_vpd_read(sc);
-			device_set_desc(dev, sc->bge_vpd_prodname);
-#endif
-			descbuf = malloc(BGE_DEVDESC_MAX, M_TEMP, M_NOWAIT);
-			if (descbuf == NULL)
-				return(ENOMEM);
-			snprintf(descbuf, BGE_DEVDESC_MAX,
-			    "%s, ASIC rev. %#04x", t->bge_name,
-			    pci_read_config(dev, BGE_PCI_MISC_CTL, 4) >> 16);
-			device_set_desc_copy(dev, descbuf);
+			char buf[64];
+			const struct bge_revision *br;
+			const struct bge_vendor *v;
+			uint32_t id;
+
+			id = pci_read_config(dev, BGE_PCI_MISC_CTL, 4) &
+			    BGE_PCIMISCCTL_ASICREV;
+			br = bge_lookup_rev(id);
+			id >>= 16;
+			v = bge_lookup_vendor(t->bge_vid);
+			if (br == NULL)
+				snprintf(buf, 64, "%s unknown ASIC (%#04x)",
+				    v->v_name, id);
+			else
+				snprintf(buf, 64, "%s %s, ASIC rev. %#04x",
+				    v->v_name, br->br_name, id);
+			device_set_desc_copy(dev, buf);
  			if (pci_get_subvendor(dev) == DELL_VENDORID)
-				sc->bge_no_3_led = 1;
-			free(descbuf, M_TEMP);
-			return(0);
+				sc->bge_flags |= BGE_FLAG_NO3LED;
+			return (0);
  		}
  		t++;
  	}

-	return(ENXIO);
+	return (ENXIO);
  }

  static void
-bge_dma_free(sc)
-	struct bge_softc *sc;
+bge_dma_free(struct bge_softc *sc)
  {
  	int i;

-
-	/* Destroy DMA maps for RX buffers */
-
+	/* Destroy DMA maps for RX buffers. */
  	for (i = 0; i < BGE_STD_RX_RING_CNT; i++) {
  		if (sc->bge_cdata.bge_rx_std_dmamap[i])
  			bus_dmamap_destroy(sc->bge_cdata.bge_mtag,
  			    sc->bge_cdata.bge_rx_std_dmamap[i]);
  	}

-	/* Destroy DMA maps for jumbo RX buffers */
-
+	/* Destroy DMA maps for jumbo RX buffers. */
  	for (i = 0; i < BGE_JUMBO_RX_RING_CNT; i++) {
  		if (sc->bge_cdata.bge_rx_jumbo_dmamap[i])
  			bus_dmamap_destroy(sc->bge_cdata.bge_mtag_jumbo,
  			    sc->bge_cdata.bge_rx_jumbo_dmamap[i]);
  	}

-	/* Destroy DMA maps for TX buffers */
-
+	/* Destroy DMA maps for TX buffers. */
  	for (i = 0; i < BGE_TX_RING_CNT; i++) {
  		if (sc->bge_cdata.bge_tx_dmamap[i])
  			bus_dmamap_destroy(sc->bge_cdata.bge_mtag,
@@ -1620,8 +1640,7 @@
  		bus_dma_tag_destroy(sc->bge_cdata.bge_mtag);


-	/* Destroy standard RX ring */
-
+	/* Destroy standard RX ring. */
  	if (sc->bge_cdata.bge_rx_std_ring_map)
  		bus_dmamap_unload(sc->bge_cdata.bge_rx_std_ring_tag,
  		    sc->bge_cdata.bge_rx_std_ring_map);
@@ -1633,8 +1652,7 @@
  	if (sc->bge_cdata.bge_rx_std_ring_tag)
  		bus_dma_tag_destroy(sc->bge_cdata.bge_rx_std_ring_tag);

-	/* Destroy jumbo RX ring */
-
+	/* Destroy jumbo RX ring. */
  	if (sc->bge_cdata.bge_rx_jumbo_ring_map)
  		bus_dmamap_unload(sc->bge_cdata.bge_rx_jumbo_ring_tag,
  		    sc->bge_cdata.bge_rx_jumbo_ring_map);
@@ -1648,8 +1666,7 @@
  	if (sc->bge_cdata.bge_rx_jumbo_ring_tag)
  		bus_dma_tag_destroy(sc->bge_cdata.bge_rx_jumbo_ring_tag);

-	/* Destroy RX return ring */
-
+	/* Destroy RX return ring. */
  	if (sc->bge_cdata.bge_rx_return_ring_map)
  		bus_dmamap_unload(sc->bge_cdata.bge_rx_return_ring_tag,
  		    sc->bge_cdata.bge_rx_return_ring_map);
@@ -1663,8 +1680,7 @@
  	if (sc->bge_cdata.bge_rx_return_ring_tag)
  		bus_dma_tag_destroy(sc->bge_cdata.bge_rx_return_ring_tag);

-	/* Destroy TX ring */
-
+	/* Destroy TX ring. */
  	if (sc->bge_cdata.bge_tx_ring_map)
  		bus_dmamap_unload(sc->bge_cdata.bge_tx_ring_tag,
  		    sc->bge_cdata.bge_tx_ring_map);
@@ -1677,8 +1693,7 @@
  	if (sc->bge_cdata.bge_tx_ring_tag)
  		bus_dma_tag_destroy(sc->bge_cdata.bge_tx_ring_tag);

-	/* Destroy status block */
-
+	/* Destroy status block. */
  	if (sc->bge_cdata.bge_status_map)
  		bus_dmamap_unload(sc->bge_cdata.bge_status_tag,
  		    sc->bge_cdata.bge_status_map);
@@ -1691,8 +1706,7 @@
  	if (sc->bge_cdata.bge_status_tag)
  		bus_dma_tag_destroy(sc->bge_cdata.bge_status_tag);

-	/* Destroy statistics block */
-
+	/* Destroy statistics block. */
  	if (sc->bge_cdata.bge_stats_map)
  		bus_dmamap_unload(sc->bge_cdata.bge_stats_tag,
  		    sc->bge_cdata.bge_stats_map);
@@ -1705,21 +1719,17 @@
  	if (sc->bge_cdata.bge_stats_tag)
  		bus_dma_tag_destroy(sc->bge_cdata.bge_stats_tag);

-	/* Destroy the parent tag */
-
+	/* Destroy the parent tag. */
  	if (sc->bge_cdata.bge_parent_tag)
  		bus_dma_tag_destroy(sc->bge_cdata.bge_parent_tag);
-
-	return;
  }

  static int
-bge_dma_alloc(dev)
-	device_t dev;
+bge_dma_alloc(device_t dev)
  {
+	struct bge_dmamap_arg ctx;
  	struct bge_softc *sc;
  	int i, error;
-	struct bge_dmamap_arg ctx;

  	sc = device_get_softc(dev);

@@ -1756,32 +1766,29 @@
  		return (ENOMEM);
  	}

-	/* Create DMA maps for RX buffers */
-
+	/* Create DMA maps for RX buffers. */
  	for (i = 0; i < BGE_STD_RX_RING_CNT; i++) {
  		error = bus_dmamap_create(sc->bge_cdata.bge_mtag, 0,
  			    &sc->bge_cdata.bge_rx_std_dmamap[i]);
  		if (error) {
  			device_printf(sc->bge_dev,
  			    "can't create DMA map for RX\n");
-			return(ENOMEM);
+			return (ENOMEM);
  		}
  	}

-	/* Create DMA maps for TX buffers */
-
+	/* Create DMA maps for TX buffers. */
  	for (i = 0; i < BGE_TX_RING_CNT; i++) {
  		error = bus_dmamap_create(sc->bge_cdata.bge_mtag, 0,
  			    &sc->bge_cdata.bge_tx_dmamap[i]);
  		if (error) {
  			device_printf(sc->bge_dev,
  			    "can't create DMA map for RX\n");
-			return(ENOMEM);
+			return (ENOMEM);
  		}
  	}

-	/* Create tag for standard RX ring */
-
+	/* Create tag for standard RX ring. */
  	error = bus_dma_tag_create(sc->bge_cdata.bge_parent_tag,
  	    PAGE_SIZE, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL,
  	    NULL, BGE_STD_RX_RING_SZ, 1, BGE_STD_RX_RING_SZ, 0,
@@ -1792,8 +1799,7 @@
  		return (ENOMEM);
  	}

-	/* Allocate DMA'able memory for standard RX ring */
-
+	/* Allocate DMA'able memory for standard RX ring. */
  	error = bus_dmamem_alloc(sc->bge_cdata.bge_rx_std_ring_tag,
  	    (void **)&sc->bge_ldata.bge_rx_std_ring, BUS_DMA_NOWAIT,
  	    &sc->bge_cdata.bge_rx_std_ring_map);
@@ -1802,8 +1808,7 @@

  	bzero((char *)sc->bge_ldata.bge_rx_std_ring, BGE_STD_RX_RING_SZ);

-	/* Load the address of the standard RX ring */
-
+	/* Load the address of the standard RX ring. */
  	ctx.bge_maxsegs = 1;
  	ctx.sc = sc;

@@ -1816,38 +1821,19 @@

  	sc->bge_ldata.bge_rx_std_ring_paddr = ctx.bge_busaddr;

-	if (sc->bge_asicrev != BGE_ASICREV_BCM5705 &&
-	    sc->bge_asicrev != BGE_ASICREV_BCM5750) {
-
-		/*
-		 * Create tag for jumbo mbufs.
-		 * This is really a bit of a kludge. We allocate a special
-		 * jumbo buffer pool which (thanks to the way our DMA
-		 * memory allocation works) will consist of contiguous
-		 * pages. This means that even though a jumbo buffer might
-		 * be larger than a page size, we don't really need to
-		 * map it into more than one DMA segment. However, the
-		 * default mbuf tag will result in multi-segment mappings,
-		 * so we have to create a special jumbo mbuf tag that
-		 * lets us get away with mapping the jumbo buffers as
-		 * a single segment. I think eventually the driver should
-		 * be changed so that it uses ordinary mbufs and cluster
-		 * buffers, i.e. jumbo frames can span multiple DMA
-		 * descriptors. But that's a project for another day.
-		 */
-
+	/* Create tags for jumbo mbufs. */
+	if (sc->bge_flags & BGE_FLAG_JUMBO) {
  		error = bus_dma_tag_create(sc->bge_cdata.bge_parent_tag,
  		    1, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL,
  		    NULL, MJUM9BYTES, BGE_NSEG_JUMBO, PAGE_SIZE,
  		    0, NULL, NULL, &sc->bge_cdata.bge_mtag_jumbo);
-
  		if (error) {
  			device_printf(sc->bge_dev,
-			    "could not allocate dma tag\n");
+			    "could not allocate jumbo dma tag\n");
  			return (ENOMEM);
  		}

-		/* Create tag for jumbo RX ring */
+		/* Create tag for jumbo RX ring. */
  		error = bus_dma_tag_create(sc->bge_cdata.bge_parent_tag,
  		    PAGE_SIZE, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL,
  		    NULL, BGE_JUMBO_RX_RING_SZ, 1, BGE_JUMBO_RX_RING_SZ, 0,
@@ -1855,11 +1841,11 @@

  		if (error) {
  			device_printf(sc->bge_dev,
-			    "could not allocate dma tag\n");
+			    "could not allocate jumbo ring dma tag\n");
  			return (ENOMEM);
  		}

-		/* Allocate DMA'able memory for jumbo RX ring */
+		/* Allocate DMA'able memory for jumbo RX ring. */
  		error = bus_dmamem_alloc(sc->bge_cdata.bge_rx_jumbo_ring_tag,
  		    (void **)&sc->bge_ldata.bge_rx_jumbo_ring,
  		    BUS_DMA_NOWAIT | BUS_DMA_ZERO,
@@ -1867,7 +1853,7 @@
  		if (error)
  			return (ENOMEM);

-		/* Load the address of the jumbo RX ring */
+		/* Load the address of the jumbo RX ring. */
  		ctx.bge_maxsegs = 1;
  		ctx.sc = sc;

@@ -1881,22 +1867,20 @@

  		sc->bge_ldata.bge_rx_jumbo_ring_paddr = ctx.bge_busaddr;

-		/* Create DMA maps for jumbo RX buffers */
-
+		/* Create DMA maps for jumbo RX buffers. */
  		for (i = 0; i < BGE_JUMBO_RX_RING_CNT; i++) {
  			error = bus_dmamap_create(sc->bge_cdata.bge_mtag_jumbo,
  				    0, &sc->bge_cdata.bge_rx_jumbo_dmamap[i]);
  			if (error) {
  				device_printf(sc->bge_dev,
-				    "can't create DMA map for RX\n");
-				return(ENOMEM);
+				    "can't create DMA map for jumbo RX\n");
+				return (ENOMEM);
  			}
  		}

  	}

-	/* Create tag for RX return ring */
-
+	/* Create tag for RX return ring. */
  	error = bus_dma_tag_create(sc->bge_cdata.bge_parent_tag,
  	    PAGE_SIZE, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL,
  	    NULL, BGE_RX_RTN_RING_SZ(sc), 1, BGE_RX_RTN_RING_SZ(sc), 0,
@@ -1907,8 +1891,7 @@
  		return (ENOMEM);
  	}

-	/* Allocate DMA'able memory for RX return ring */
-
+	/* Allocate DMA'able memory for RX return ring. */
  	error = bus_dmamem_alloc(sc->bge_cdata.bge_rx_return_ring_tag,
  	    (void **)&sc->bge_ldata.bge_rx_return_ring, BUS_DMA_NOWAIT,
  	    &sc->bge_cdata.bge_rx_return_ring_map);
@@ -1918,8 +1901,7 @@
  	bzero((char *)sc->bge_ldata.bge_rx_return_ring,
  	    BGE_RX_RTN_RING_SZ(sc));

-	/* Load the address of the RX return ring */
-
+	/* Load the address of the RX return ring. */
  	ctx.bge_maxsegs = 1;
  	ctx.sc = sc;

@@ -1933,8 +1915,7 @@

  	sc->bge_ldata.bge_rx_return_ring_paddr = ctx.bge_busaddr;

-	/* Create tag for TX ring */
-
+	/* Create tag for TX ring. */
  	error = bus_dma_tag_create(sc->bge_cdata.bge_parent_tag,
  	    PAGE_SIZE, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL,
  	    NULL, BGE_TX_RING_SZ, 1, BGE_TX_RING_SZ, 0, NULL, NULL,
@@ -1945,8 +1926,7 @@
  		return (ENOMEM);
  	}

-	/* Allocate DMA'able memory for TX ring */
-
+	/* Allocate DMA'able memory for TX ring. */
  	error = bus_dmamem_alloc(sc->bge_cdata.bge_tx_ring_tag,
  	    (void **)&sc->bge_ldata.bge_tx_ring, BUS_DMA_NOWAIT,
  	    &sc->bge_cdata.bge_tx_ring_map);
@@ -1955,8 +1935,7 @@

  	bzero((char *)sc->bge_ldata.bge_tx_ring, BGE_TX_RING_SZ);

-	/* Load the address of the TX ring */
-
+	/* Load the address of the TX ring. */
  	ctx.bge_maxsegs = 1;
  	ctx.sc = sc;

@@ -1969,8 +1948,7 @@

  	sc->bge_ldata.bge_tx_ring_paddr = ctx.bge_busaddr;

-	/* Create tag for status block */
-
+	/* Create tag for status block. */
  	error = bus_dma_tag_create(sc->bge_cdata.bge_parent_tag,
  	    PAGE_SIZE, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL,
  	    NULL, BGE_STATUS_BLK_SZ, 1, BGE_STATUS_BLK_SZ, 0,
@@ -1981,8 +1959,7 @@
  		return (ENOMEM);
  	}

-	/* Allocate DMA'able memory for status block */
-
+	/* Allocate DMA'able memory for status block. */
  	error = bus_dmamem_alloc(sc->bge_cdata.bge_status_tag,
  	    (void **)&sc->bge_ldata.bge_status_block, BUS_DMA_NOWAIT,
  	    &sc->bge_cdata.bge_status_map);
@@ -1991,8 +1968,7 @@

  	bzero((char *)sc->bge_ldata.bge_status_block, BGE_STATUS_BLK_SZ);

-	/* Load the address of the status block */
-
+	/* Load the address of the status block. */
  	ctx.sc = sc;
  	ctx.bge_maxsegs = 1;

@@ -2005,8 +1981,7 @@

  	sc->bge_ldata.bge_status_block_paddr = ctx.bge_busaddr;

-	/* Create tag for statistics block */
-
+	/* Create tag for statistics block. */
  	error = bus_dma_tag_create(sc->bge_cdata.bge_parent_tag,
  	    PAGE_SIZE, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL,
  	    NULL, BGE_STATS_SZ, 1, BGE_STATS_SZ, 0, NULL, NULL,
@@ -2017,8 +1992,7 @@
  		return (ENOMEM);
  	}

-	/* Allocate DMA'able memory for statistics block */
-
+	/* Allocate DMA'able memory for statistics block. */
  	error = bus_dmamem_alloc(sc->bge_cdata.bge_stats_tag,
  	    (void **)&sc->bge_ldata.bge_stats, BUS_DMA_NOWAIT,
  	    &sc->bge_cdata.bge_stats_map);
@@ -2027,8 +2001,7 @@

  	bzero((char *)sc->bge_ldata.bge_stats, BGE_STATS_SZ);

-	/* Load the address of the statstics block */
-
+	/* Load the address of the statstics block. */
  	ctx.sc = sc;
  	ctx.bge_maxsegs = 1;

@@ -2041,19 +2014,19 @@

  	sc->bge_ldata.bge_stats_paddr = ctx.bge_busaddr;

-	return(0);
+	return (0);
  }

  static int
-bge_attach(dev)
-	device_t dev;
+bge_attach(device_t dev)
  {
  	struct ifnet *ifp;
  	struct bge_softc *sc;
-	u_int32_t hwcfg = 0;
-	u_int32_t mac_tmp = 0;
+	uint32_t hwcfg = 0;
+	uint32_t mac_tmp = 0;
  	u_char eaddr[6];
  	int error = 0, rid;
+	int reg;

  	sc = device_get_softc(dev);
  	sc->bge_dev = dev;
@@ -2076,7 +2049,7 @@
  	sc->bge_btag = rman_get_bustag(sc->bge_res);
  	sc->bge_bhandle = rman_get_bushandle(sc->bge_res);

-	/* Allocate interrupt */
+	/* Allocate interrupt. */
  	rid = 0;

  	sc->bge_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
@@ -2098,27 +2071,40 @@
  	sc->bge_asicrev = BGE_ASICREV(sc->bge_chipid);
  	sc->bge_chiprev = BGE_CHIPREV(sc->bge_chipid);

-	/*
-	 * Treat the 5714 and the 5752 like the 5750 until we have more info
-	 * on this chip.
-	 */
-	if (sc->bge_asicrev == BGE_ASICREV_BCM5714 ||
-            sc->bge_asicrev == BGE_ASICREV_BCM5752)
-		sc->bge_asicrev = BGE_ASICREV_BCM5750;
+	if (BGE_IS_575X_PLUS(sc)) {
+		sc->bge_flags |= BGE_FLAG_575X_PLUS;
+		sc->bge_flags |= BGE_FLAG_5705_PLUS;
+	}
+	if (BGE_IS_5705_OR_BEYOND(sc))
+		sc->bge_flags |= BGE_FLAG_5705_PLUS;
+	if (BGE_IS_JUMBO_CAPABLE(sc))
+		sc->bge_flags |= BGE_FLAG_JUMBO;

  	/*
-	 * XXX: Broadcom Linux driver.  Not in specs or eratta.
-	 * PCI-Express?
+	 * Check if this is a PCI-X or PCI Express device.
  	 */
-	if (sc->bge_asicrev == BGE_ASICREV_BCM5750) {
-		u_int32_t v;
-
-		v = pci_read_config(dev, BGE_PCI_MSI_CAPID, 4);
-		if (((v >> 8) & 0xff) == BGE_PCIE_CAPID_REG) {
-			v = pci_read_config(dev, BGE_PCIE_CAPID_REG, 4);
-			if ((v & 0xff) == BGE_PCIE_CAPID)
-				sc->bge_pcie = 1;
-		}
+#if __FreeBSD_version > 700000
+	if (pci_find_extcap(dev, PCIY_EXPRESS, &reg) == 0) {
+		/*
+		 * Found a PCI Express capabilities register, this
+		 * must be a PCI Express device.
+		 */
+		if (reg != 0)
+			sc->bge_flags |= BGE_FLAG_PCIE;
+#else
+	if (sc->bge_flags & BGE_FLAG_5705_PLUS) {
+		reg = pci_read_config(dev, BGE_PCIE_CAPID_REG, 4);
+		if ((reg & 0xff) == BGE_PCIE_CAPID)
+			sc->bge_flags |= BGE_FLAG_PCIE;
+#endif
+	} else {
+		/*
+		 * Check if the device is in PCI-X Mode.
+		 * (This bit is not valid on PCI Express controllers.)
+		 */
+		if ((pci_read_config(sc->bge_dev, BGE_PCI_PCISTATE, 4) &
+		    BGE_PCISTATE_PCI_BUSMODE) == 0)
+			sc->bge_flags |= BGE_FLAG_PCIX;
  	}

  	/* Try to reset the chip. */
@@ -2152,8 +2138,7 @@
  	}

  	/* 5705 limits RX return ring to 512 entries. */
-	if (sc->bge_asicrev == BGE_ASICREV_BCM5705 ||
-	    sc->bge_asicrev == BGE_ASICREV_BCM5750)
+	if (sc->bge_flags & BGE_FLAG_5705_PLUS)
  		sc->bge_return_ring_cnt = BGE_RETURN_RING_CNT_5705;
  	else
  		sc->bge_return_ring_cnt = BGE_RETURN_RING_CNT;
@@ -2170,8 +2155,8 @@
  	sc->bge_stat_ticks = BGE_TICKS_PER_SEC;
  	sc->bge_rx_coal_ticks = 150;
  	sc->bge_tx_coal_ticks = 150;
-	sc->bge_rx_max_coal_bds = 64;
-	sc->bge_tx_max_coal_bds = 128;
+	sc->bge_rx_max_coal_bds = 10;
+	sc->bge_tx_max_coal_bds = 10;

  	/* Set up ifnet structure */
  	ifp = sc->bge_ifp = if_alloc(IFT_ETHER);
@@ -2200,7 +2185,7 @@
  	ifp->if_capabilities |= IFCAP_POLLING;
  #endif

-        /*
+	/*
  	 * 5700 B0 chips do not support checksumming correctly due
  	 * to hardware bugs.
  	 */
@@ -2233,13 +2218,13 @@
  	}

  	if ((hwcfg & BGE_HWCFG_MEDIA) == BGE_MEDIA_FIBER)
-		sc->bge_tbi = 1;
+		sc->bge_flags |= BGE_FLAG_TBI;

  	/* The SysKonnect SK-9D41 is a 1000baseSX card. */
  	if ((pci_read_config(dev, BGE_PCI_SUBSYS, 4) >> 16) ==  
SK_SUBSYSID_9D41)
-		sc->bge_tbi = 1;
+		sc->bge_flags |= BGE_FLAG_TBI;

-	if (sc->bge_tbi) {
+	if (sc->bge_flags & BGE_FLAG_TBI) {
  		ifmedia_init(&sc->bge_ifmedia, IFM_IMASK,
  		    bge_ifmedia_upd, bge_ifmedia_sts);
  		ifmedia_add(&sc->bge_ifmedia, IFM_ETHER|IFM_1000_SX, 0, NULL);
@@ -2269,18 +2254,9 @@
  	 * which do not support unaligned accesses, we will realign the
  	 * payloads by copying the received packets.
  	 */
-	switch (sc->bge_chipid) {
-	case BGE_CHIPID_BCM5701_A0:
-	case BGE_CHIPID_BCM5701_B0:
-	case BGE_CHIPID_BCM5701_B2:
-	case BGE_CHIPID_BCM5701_B5:
-		/* If in PCI-X mode, work around the alignment bug. */
-		if ((pci_read_config(dev, BGE_PCI_PCISTATE, 4) &
-		    (BGE_PCISTATE_PCI_BUSMODE | BGE_PCISTATE_PCI_BUSSPEED)) ==
-		    BGE_PCISTATE_PCI_BUSSPEED)
-			sc->bge_rx_alignment_bug = 1;
-		break;
-	}
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5701 &&
+	    (sc->bge_flags & BGE_FLAG_PCIX))
+                sc->bge_flags |= BGE_FLAG_RX_ALIGNBUG;

  	/*
  	 * Call MI attach routine.
@@ -2299,13 +2275,14 @@
  		device_printf(sc->bge_dev, "couldn't set up irq\n");
  	}

+	bge_add_sysctls(sc);
+
  fail:
-	return(error);
+	return (error);
  }

  static int
-bge_detach(dev)
-	device_t dev;
+bge_detach(device_t dev)
  {
  	struct bge_softc *sc;
  	struct ifnet *ifp;
@@ -2325,7 +2302,7 @@

  	ether_ifdetach(ifp);

-	if (sc->bge_tbi) {
+	if (sc->bge_flags & BGE_FLAG_TBI) {
  		ifmedia_removeall(&sc->bge_ifmedia);
  	} else {
  		bus_generic_detach(dev);
@@ -2334,12 +2311,11 @@

  	bge_release_resources(sc);

-	return(0);
+	return (0);
  }

  static void
-bge_release_resources(sc)
-	struct bge_softc *sc;
+bge_release_resources(struct bge_softc *sc)
  {
  	device_t dev;

@@ -2368,20 +2344,26 @@

  	if (mtx_initialized(&sc->bge_mtx))	/* XXX */
  		BGE_LOCK_DESTROY(sc);
-
-	return;
  }

  static void
-bge_reset(sc)
-	struct bge_softc *sc;
+bge_reset(struct bge_softc *sc)
  {
  	device_t dev;
-	u_int32_t cachesize, command, pcistate, reset;
+	uint32_t cachesize, command, pcistate, reset;
+	void (*write_op)(struct bge_softc *, int, int);
  	int i, val = 0;

  	dev = sc->bge_dev;

+	if (sc->bge_flags & BGE_FLAG_5705_PLUS)
+		if (sc->bge_flags & BGE_FLAG_PCIE)
+			write_op = bge_writemem_direct;
+		else
+			write_op = bge_writemem_ind;
+	else
+		write_op = bge_writereg_ind;
+
  	/* Save some important PCI state. */
  	cachesize = pci_read_config(dev, BGE_PCI_CACHESZ, 4);
  	command = pci_read_config(dev, BGE_PCI_CMD, 4);
@@ -2391,10 +2373,27 @@
  	    BGE_PCIMISCCTL_INDIRECT_ACCESS|BGE_PCIMISCCTL_MASK_PCI_INTR|
  	BGE_HIF_SWAP_OPTIONS|BGE_PCIMISCCTL_PCISTATE_RW, 4);

+	/* Disable fastboot on controllers that support it. */
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5752 ||
+	    sc->bge_asicrev == BGE_ASICREV_BCM5755 ||
+	    sc->bge_asicrev == BGE_ASICREV_BCM5787) {
+		if (bootverbose)
+			device_printf(sc->bge_dev, "%s: Disabling fastboot\n",
+			    __FUNCTION__);
+		CSR_WRITE_4(sc, BGE_FASTBOOT_PC, 0x0);
+	}
+
+	/*
+	 * Write the magic number to SRAM at offset 0xB50.
+	 * When firmware finishes its initialization it will
+	 * write ~BGE_MAGIC_NUMBER to the same location.
+	 */
+	bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);
+
  	reset = BGE_MISCCFG_RESET_CORE_CLOCKS|(65<<1);

  	/* XXX: Broadcom Linux driver. */
-	if (sc->bge_pcie) {
+	if (sc->bge_flags & BGE_FLAG_PCIE) {
  		if (CSR_READ_4(sc, 0x7e2c) == 0x60)	/* PCIE 1.0 */
  			CSR_WRITE_4(sc, 0x7e2c, 0x20);
  		if (sc->bge_chipid != BGE_CHIPID_BCM5750_A0) {
@@ -2404,13 +2403,20 @@
  		}
  	}

+	/*
+	 * Set GPHY Power Down Override to leave GPHY
+	 * powered up in D0 uninitialized.
+	 */
+	if (sc->bge_flags & BGE_FLAG_5705_PLUS)
+		reset |= 0x04000000;
+
  	/* Issue global reset */
-	bge_writereg_ind(sc, BGE_MISC_CFG, reset);
+	write_op(sc, BGE_MISC_CFG, reset);

  	DELAY(1000);

  	/* XXX: Broadcom Linux driver. */
-	if (sc->bge_pcie) {
+	if (sc->bge_flags & BGE_FLAG_PCIE) {
  		if (sc->bge_chipid == BGE_CHIPID_BCM5750_A0) {
  			uint32_t v;

@@ -2418,31 +2424,29 @@
  			v = pci_read_config(dev, 0xc4, 4);
  			pci_write_config(dev, 0xc4, v | (1<<15), 4);
  		}
-		/* Set PCIE max payload size and clear error status. */
+		/* Set PCIE max payload size to 128 bytes and clear error status. */
  		pci_write_config(dev, 0xd8, 0xf5000, 4);
  	}

-	/* Reset some of the PCI state that got zapped by reset */
+	/* Reset some of the PCI state that got zapped by reset. */
  	pci_write_config(dev, BGE_PCI_MISC_CTL,
  	    BGE_PCIMISCCTL_INDIRECT_ACCESS|BGE_PCIMISCCTL_MASK_PCI_INTR|
  	    BGE_HIF_SWAP_OPTIONS|BGE_PCIMISCCTL_PCISTATE_RW, 4);
  	pci_write_config(dev, BGE_PCI_CACHESZ, cachesize, 4);
  	pci_write_config(dev, BGE_PCI_CMD, command, 4);
-	bge_writereg_ind(sc, BGE_MISC_CFG, (65 << 1));
+	write_op(sc, BGE_MISC_CFG, (65 << 1));

  	/* Enable memory arbiter. */
-	if (sc->bge_asicrev != BGE_ASICREV_BCM5705 &&
-	    sc->bge_asicrev != BGE_ASICREV_BCM5750)
+	if (BGE_IS_5714_FAMILY(sc)) {
+		uint32_t val;
+
+		val = CSR_READ_4(sc, BGE_MARB_MODE);
+		CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE | val);
+	} else
  		CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE);

  	/*
-	 * Prevent PXE restart: write a magic number to the
-	 * general communications memory at 0xB50.
-	 */
-	bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);
-	/*
-	 * Poll the value location we just wrote until
-	 * we see the 1's complement of the magic number.
+	 * Poll until we see the 1's complement of the magic number.
  	 * This indicates that the firmware initialization
  	 * is complete.
  	 */
@@ -2454,8 +2458,7 @@
  	}

  	if (i == BGE_TIMEOUT) {
-		device_printf(sc->bge_dev, "firmware handshake timed out\n");
-		return;
+		device_printf(sc->bge_dev, "firmware handshake timed out!  found =  
0x%08X\n", val);
  	}

  	/*
@@ -2472,7 +2475,12 @@
  		DELAY(10);
  	}

-	/* Fix up byte swapping */
+	if (sc->bge_flags & BGE_FLAG_PCIE) {
+		reset = bge_readmem_ind(sc, 0x7c00);
+		bge_writemem_ind(sc, 0x7c00, reset | (1 << 25));
+	}
+
+	/* Fix up byte swapping. */
  	CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS|
  	    BGE_MODECTL_BYTESWAP_DATA);

@@ -2483,7 +2491,8 @@
  	 * adjustment to insure the SERDES drive level is set
  	 * to 1.2V.
  	 */
-	if (sc->bge_asicrev == BGE_ASICREV_BCM5704 && sc->bge_tbi) {
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5704 &&
+	    (sc->bge_flags & BGE_FLAG_TBI)) {
  		uint32_t serdescfg;
  		serdescfg = CSR_READ_4(sc, BGE_SERDES_CFG);
  		serdescfg = (serdescfg & ~0xFFF) | 0x880;
@@ -2491,15 +2500,14 @@
  	}

  	/* XXX: Broadcom Linux driver. */
-	if (sc->bge_pcie && sc->bge_chipid != BGE_CHIPID_BCM5750_A0) {
+	if ((sc->bge_flags & BGE_FLAG_PCIE) &&
+	    (sc->bge_chipid != BGE_CHIPID_BCM5750_A0)) {
  		uint32_t v;

  		v = CSR_READ_4(sc, 0x7c00);
  		CSR_WRITE_4(sc, 0x7c00, v | (1<<25));
  	}
  	DELAY(10000);
-
-	return;
  }

  /*
@@ -2512,15 +2520,14 @@
   */

  static void
-bge_rxeof(sc)
-	struct bge_softc *sc;
+bge_rxeof(struct bge_softc *sc)
  {
  	struct ifnet *ifp;
  	int stdcnt = 0, jumbocnt = 0;

  	BGE_LOCK_ASSERT(sc);

-	/* Nothing to do */
+	/* Nothing to do. */
  	if (sc->bge_rx_saved_considx ==
  	    sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx)
  		return;
@@ -2531,20 +2538,16 @@
  	    sc->bge_cdata.bge_rx_return_ring_map, BUS_DMASYNC_POSTREAD);
  	bus_dmamap_sync(sc->bge_cdata.bge_rx_std_ring_tag,
  	    sc->bge_cdata.bge_rx_std_ring_map, BUS_DMASYNC_POSTREAD);
-	if (sc->bge_asicrev != BGE_ASICREV_BCM5705 &&
-	    sc->bge_asicrev != BGE_ASICREV_BCM5750) {
+	if (sc->bge_flags & BGE_FLAG_JUMBO)
  		bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag,
-		    sc->bge_cdata.bge_rx_jumbo_ring_map,
-		    BUS_DMASYNC_POSTREAD);
-	}
+		    sc->bge_cdata.bge_rx_jumbo_ring_map, BUS_DMASYNC_POSTREAD);

  	while(sc->bge_rx_saved_considx !=
  	    sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx) {
  		struct bge_rx_bd	*cur_rx;
-		u_int32_t		rxidx;
-		struct ether_header	*eh;
+		uint32_t		rxidx;
  		struct mbuf		*m = NULL;
-		u_int16_t		vlan_tag = 0;
+		uint16_t		vlan_tag = 0;
  		int			have_tag = 0;

  #ifdef DEVICE_POLLING
@@ -2616,13 +2619,12 @@
  		 * For architectures with strict alignment we must make sure
  		 * the payload is aligned.
  		 */
-		if (sc->bge_rx_alignment_bug) {
+		if (sc->bge_flags & BGE_FLAG_RX_ALIGNBUG) {
  			bcopy(m->m_data, m->m_data + ETHER_ALIGN,
  			    cur_rx->bge_len);
  			m->m_data += ETHER_ALIGN;
  		}
  #endif
-		eh = mtod(m, struct ether_header *);
  		m->m_pkthdr.len = m->m_len = cur_rx->bge_len - ETHER_CRC_LEN;
  		m->m_pkthdr.rcvif = ifp;

@@ -2659,13 +2661,10 @@
  	if (stdcnt > 0)
  		bus_dmamap_sync(sc->bge_cdata.bge_rx_std_ring_tag,
  		    sc->bge_cdata.bge_rx_std_ring_map, BUS_DMASYNC_PREWRITE);
-	if (sc->bge_asicrev != BGE_ASICREV_BCM5705 &&
-	    sc->bge_asicrev != BGE_ASICREV_BCM5750) {
-		if (jumbocnt > 0)
-			bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag,
-			    sc->bge_cdata.bge_rx_jumbo_ring_map,
-			    BUS_DMASYNC_PREWRITE);
-	}
+
+	if ((sc->bge_flags & BGE_FLAG_JUMBO) && jumbocnt > 0)
+		bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag,
+		    sc->bge_cdata.bge_rx_jumbo_ring_map, BUS_DMASYNC_PREWRITE);

  	CSR_WRITE_4(sc, BGE_MBX_RX_CONS0_LO, sc->bge_rx_saved_considx);
  	if (stdcnt)
@@ -2675,15 +2674,14 @@
  }

  static void
-bge_txeof(sc)
-	struct bge_softc *sc;
+bge_txeof(struct bge_softc *sc)
  {
  	struct bge_tx_bd *cur_tx = NULL;
  	struct ifnet *ifp;

  	BGE_LOCK_ASSERT(sc);

-	/* Nothing to do */
+	/* Nothing to do. */
  	if (sc->bge_tx_saved_considx ==
  	    sc->bge_ldata.bge_status_block->bge_idx[0].bge_tx_cons_idx)
  		return;
@@ -2699,7 +2697,7 @@
  	 */
  	while (sc->bge_tx_saved_considx !=
  	    sc->bge_ldata.bge_status_block->bge_idx[0].bge_tx_cons_idx) {
-		u_int32_t		idx = 0;
+		uint32_t		idx = 0;

  		idx = sc->bge_tx_saved_considx;
  		cur_tx = &sc->bge_ldata.bge_tx_ring[idx];
@@ -2728,25 +2726,19 @@
  bge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
  {
  	struct bge_softc *sc = ifp->if_softc;
+	uint32_t statusword;
  	
  	BGE_LOCK(sc);
-	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
-		bge_poll_locked(ifp, cmd, count);
-	BGE_UNLOCK(sc);
-}
-
-static void
-bge_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count)
-{
-	struct bge_softc *sc = ifp->if_softc;
-	uint32_t statusword;
-
-	BGE_LOCK_ASSERT(sc);
+	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+		BGE_UNLOCK(sc);
+		return;
+	}

  	bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
  	    sc->bge_cdata.bge_status_map, BUS_DMASYNC_POSTREAD);

-	statusword = atomic_readandclear_32(&sc->bge_ldata.bge_status_block- 
 >bge_status);
+	statusword = atomic_readandclear_32(
+	    &sc->bge_ldata.bge_status_block->bge_status);

  	bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
  	    sc->bge_cdata.bge_status_map, BUS_DMASYNC_PREREAD);
@@ -2757,8 +2749,9 @@

  	if (cmd == POLL_AND_CHECK_STATUS)
  		if ((sc->bge_asicrev == BGE_ASICREV_BCM5700 &&
-		    sc->bge_chipid != BGE_CHIPID_BCM5700_B1) ||
-		    sc->bge_link_evt || sc->bge_tbi)
+		    sc->bge_chipid != BGE_CHIPID_BCM5700_B2) ||
+		    sc->bge_link_evt ||
+		    (sc->bge_flags & BGE_FLAG_TBI))
  			bge_link_upd(sc);

  	sc->rxcycles = count;
@@ -2766,12 +2759,13 @@
  	bge_txeof(sc);
  	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
  		bge_start_locked(ifp);
+
+	BGE_UNLOCK(sc);
  }
  #endif /* DEVICE_POLLING */

  static void
-bge_intr(xsc)
-	void *xsc;
+bge_intr(void *xsc)
  {
  	struct bge_softc *sc;
  	struct ifnet *ifp;
@@ -2790,64 +2784,53 @@
  	}
  #endif

-	bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
-	    sc->bge_cdata.bge_status_map, BUS_DMASYNC_POSTREAD);
+	/*
+	 * Do the mandatory PCI flush as well as get the link status.
+	 */
+	statusword = CSR_READ_4(sc, BGE_MAC_STS) & BGE_MACSTAT_LINK_CHANGED;

-	statusword =
-	    atomic_readandclear_32(&sc->bge_ldata.bge_status_block- 
 >bge_status);
+	/* Ack interrupt and stop others from occuring. */
+	CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0);

+	/* Make sure the descriptor ring indexes are coherent. */
+	bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
+	    sc->bge_cdata.bge_status_map, BUS_DMASYNC_POSTREAD);
  	bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
  	    sc->bge_cdata.bge_status_map, BUS_DMASYNC_PREREAD);

-#ifdef notdef
-	/* Avoid this for now -- checking this register is expensive. */
-	/* Make sure this is really our interrupt. */
-	if (!(CSR_READ_4(sc, BGE_MISC_LOCAL_CTL) & BGE_MLC_INTR_STATE))
-		return;
-#endif
-	/* Ack interrupt and stop others from occuring. */
-	CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 1);
-
  	if ((sc->bge_asicrev == BGE_ASICREV_BCM5700 &&
-	    sc->bge_chipid != BGE_CHIPID_BCM5700_B1) ||
-	    statusword & BGE_STATFLAG_LINKSTATE_CHANGED || sc->bge_link_evt)
+	    sc->bge_chipid != BGE_CHIPID_BCM5700_B2) ||
+	    statusword || sc->bge_link_evt)
  		bge_link_upd(sc);

  	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
-		/* Check RX return ring producer/consumer */
+		/* Check RX return ring producer/consumer. */
  		bge_rxeof(sc);

-		/* Check TX ring producer/consumer */
+		/* Check TX ring producer/consumer. */
  		bge_txeof(sc);
  	}

-	/* Re-enable interrupts. */
-	CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0);
-
  	if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
  	    !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
  		bge_start_locked(ifp);

  	BGE_UNLOCK(sc);
-
-	return;
  }

  static void
-bge_tick_locked(sc)
-	struct bge_softc *sc;
+bge_tick_locked(struct bge_softc *sc)
  {
  	struct mii_data *mii = NULL;

  	BGE_LOCK_ASSERT(sc);

-	if (sc->bge_asicrev == BGE_ASICREV_BCM5705 ||
-	    sc->bge_asicrev == BGE_ASICREV_BCM5750)
+	if (sc->bge_flags & BGE_FLAG_5705_PLUS)
  		bge_stats_update_regs(sc);
  	else
  		bge_stats_update(sc);

-	if (!sc->bge_tbi) {
+	if ((sc->bge_flags & BGE_FLAG_TBI) == 0) {
  		mii = device_get_softc(sc->bge_miibus);
  		mii_tick(mii);
  	} else {
@@ -2857,7 +2840,7 @@
  		 * and trigger interrupt.
  		 */
  #ifdef DEVICE_POLLING
-		/* In polling mode we poll link state in bge_poll_locked() */
+		/* In polling mode we poll link state in bge_poll(). */
  		if (!(sc->bge_ifp->if_capenable & IFCAP_POLLING))
  #endif
  		{
@@ -2870,8 +2853,7 @@
  }

  static void
-bge_tick(xsc)
-	void *xsc;
+bge_tick(void *xsc)
  {
  	struct bge_softc *sc;

@@ -2883,18 +2865,17 @@
  }

  static void
-bge_stats_update_regs(sc)
-	struct bge_softc *sc;
+bge_stats_update_regs(struct bge_softc *sc)
  {
-	struct ifnet *ifp;
  	struct bge_mac_stats_regs stats;
-	u_int32_t *s;
-	u_long cnt;			/* current register value */
+	struct ifnet *ifp;
+	uint32_t *s;
+	u_long cnt;	/* current register value */
  	int i;

  	ifp = sc->bge_ifp;

-	s = (u_int32_t *)&stats;
+	s = (uint32_t *)&stats;
  	for (i = 0; i < sizeof(struct bge_mac_stats_regs); i += 4) {
  		*s = CSR_READ_4(sc, BGE_RX_STATS + i);
  		s++;
@@ -2910,12 +2891,11 @@
  }

  static void
-bge_stats_update(sc)
-	struct bge_softc *sc;
+bge_stats_update(struct bge_softc *sc)
  {
  	struct ifnet *ifp;
  	bus_size_t stats;
-	u_long cnt;			/* current register value */
+	u_long cnt;	/* current register value */

  	ifp = sc->bge_ifp;

@@ -2999,10 +2979,7 @@
   * pointers to descriptors.
   */
  static int
-bge_encap(sc, m_head, txidx)
-	struct bge_softc *sc;
-	struct mbuf *m_head;
-	uint32_t *txidx;
+bge_encap(struct bge_softc *sc, struct mbuf *m_head, uint32_t *txidx)
  {
  	bus_dma_segment_t	segs[BGE_NSEG_NEW];
  	bus_dmamap_t		map;
@@ -3032,7 +3009,7 @@
  	map = sc->bge_cdata.bge_tx_dmamap[idx];
  	error = bus_dmamap_load_mbuf_sg(sc->bge_cdata.bge_mtag, map,
  	    m_head, segs, &nsegs, BUS_DMA_NOWAIT);
-        if (error) {
+	if (error) {
  		if (error == EFBIG) {
  			struct mbuf *m0;

@@ -3044,7 +3021,7 @@
  			    map, m_head, segs, &nsegs, BUS_DMA_NOWAIT);
  		}
  		if (error)
-			return (error);
+			return (error);
  	}

  	/*
@@ -3100,8 +3077,7 @@
   * to the mbuf data regions directly in the transmit descriptors.
   */
  static void
-bge_start_locked(ifp)
-	struct ifnet *ifp;
+bge_start_locked(struct ifnet *ifp)
  {
  	struct bge_softc *sc;
  	struct mbuf *m_head = NULL;
@@ -3112,7 +3088,6 @@

  	if (!sc->bge_link || IFQ_DRV_IS_EMPTY(&ifp->if_snd))
  		return;
-
  	prodidx = sc->bge_tx_prodidx;

  	while(sc->bge_cdata.bge_tx_chain[prodidx] == NULL) {
@@ -3162,12 +3137,11 @@
  		BPF_MTAP(ifp, m_head);
  	}

-	if (count == 0) {
-		/* no packets were dequeued */
+	if (count == 0)
+		/* No packets were dequeued. */
  		return;
-	}

-	/* Transmit */
+	/* Transmit. */
  	CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
  	/* 5700 b2 errata */
  	if (sc->bge_chiprev == BGE_CHIPREV_5700_BX)
@@ -3179,8 +3153,6 @@
  	 * Set a timeout in case the chip goes out to lunch.
  	 */
  	ifp->if_timer = 5;
-
-	return;
  }

  /*
@@ -3188,8 +3160,7 @@
   * to the mbuf data regions directly in the transmit descriptors.
   */
  static void
-bge_start(ifp)
-	struct ifnet *ifp;
+bge_start(struct ifnet *ifp)
  {
  	struct bge_softc *sc;

@@ -3200,11 +3171,13 @@
  }

  static void
-bge_init_locked(sc)
-	struct bge_softc *sc;
+bge_init_locked(struct bge_softc *sc)
  {
  	struct ifnet *ifp;
-	u_int16_t *m;
+	uint16_t *m;
+#if 0
+	int i, j;
+#endif

  	BGE_LOCK_ASSERT(sc);

@@ -3234,7 +3207,7 @@
  	    ETHER_HDR_LEN + ETHER_CRC_LEN + ETHER_VLAN_ENCAP_LEN);

  	/* Load our MAC address. */
-	m = (u_int16_t *)&IFP2ENADDR(sc->bge_ifp)[0];
+	m = (uint16_t *)IF_LLADDR(sc->bge_ifp);
  	CSR_WRITE_4(sc, BGE_MAC_ADDR1_LO, htons(m[0]));
  	CSR_WRITE_4(sc, BGE_MAC_ADDR1_HI, (htons(m[1]) << 16) | htons(m[2]));

@@ -3257,7 +3230,7 @@
  	 * entry of the ring.
  	 */
  	if (sc->bge_chipid == BGE_CHIPID_BCM5705_A0) {
-		u_int32_t		v, i;
+		uint32_t		v, i;
  		for (i = 0; i < 10; i++) {
  			DELAY(20);
  			v = bge_readmem_ind(sc, BGE_STD_RX_RINGS + 8);
@@ -3273,16 +3246,16 @@
  	if (ifp->if_mtu > (ETHERMTU + ETHER_HDR_LEN + ETHER_CRC_LEN))
  		bge_init_rx_ring_jumbo(sc);

-	/* Init our RX return ring index */
+	/* Init our RX return ring index. */
  	sc->bge_rx_saved_considx = 0;

  	/* Init TX ring. */
  	bge_init_tx_ring(sc);

-	/* Turn on transmitter */
+	/* Turn on transmitter. */
  	BGE_SETBIT(sc, BGE_TX_MODE, BGE_TXMODE_ENABLE);

-	/* Turn on receiver */
+	/* Turn on receiver. */
  	BGE_SETBIT(sc, BGE_RX_MODE, BGE_RXMODE_ENABLE);

  	/* Tell firmware we're alive. */
@@ -3306,54 +3279,86 @@
  	CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0);
  	}
  	
-	bge_ifmedia_upd(ifp);
+	bge_ifmedia_upd_locked(ifp);
+
+#define BGE_RX_RULE_MASK 0x7fffffff
+	CSR_WRITE_4(sc, BGE_RX_BD_RULES_CTL0, 0xc2000000 & BGE_RX_RULE_MASK);
+	CSR_WRITE_4(sc, BGE_RX_BD_RULES_MASKVAL0,0xffffffff &  
BGE_RX_RULE_MASK);
+	CSR_WRITE_4(sc, BGE_RX_BD_RULES_CTL1, 0x86000004 & BGE_RX_RULE_MASK);
+	CSR_WRITE_4(sc, BGE_RX_BD_RULES_MASKVAL1,0xffffffff &  
BGE_RX_RULE_MASK);
+
+	/* Configure DMA resource watermarks */
+	CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_LOWAT, 5);
+	CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_HIWAT, 10);
+
+#if 0
+	if ((sc->bge_hw_flags & BGE_FLAG_5705_PLUS) &&
+	    !(sc->bge_hw_flags & BGE_FLAG_5780))
+		limit = 8;
+	else
+		limit = 16;
+	/* XXX ASF limit -= 4 */
+	switch (limit) {
+	case 16:
+#endif

  	ifp->if_drv_flags |= IFF_DRV_RUNNING;
  	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;

  	callout_reset(&sc->bge_stat_ch, hz, bge_tick, sc);
+
  }

  static void
-bge_init(xsc)
-	void *xsc;
+bge_init(void *xsc)
  {
  	struct bge_softc *sc = xsc;

  	BGE_LOCK(sc);
  	bge_init_locked(sc);
  	BGE_UNLOCK(sc);
-
-	return;
  }

  /*
   * Set media options.
   */
  static int
-bge_ifmedia_upd(ifp)
-	struct ifnet *ifp;
+bge_ifmedia_upd(struct ifnet *ifp)
  {
-	struct bge_softc *sc;
+	struct bge_softc *sc = ifp->if_softc;
+	int res;
+
+	BGE_LOCK(sc);
+	res = bge_ifmedia_upd_locked(ifp);
+	BGE_UNLOCK(sc);
+
+	return (res);
+}
+
+static int
+bge_ifmedia_upd_locked(struct ifnet *ifp)
+{
+	struct bge_softc *sc = ifp->if_softc;
  	struct mii_data *mii;
  	struct ifmedia *ifm;

-	sc = ifp->if_softc;
+	BGE_LOCK_ASSERT(sc);
+
  	ifm = &sc->bge_ifmedia;

  	/* If this is a 1000baseX NIC, enable the TBI port. */
-	if (sc->bge_tbi) {
+	if (sc->bge_flags & BGE_FLAG_TBI) {
  		if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
-			return(EINVAL);
+			return (EINVAL);
  		switch(IFM_SUBTYPE(ifm->ifm_media)) {
  		case IFM_AUTO:
-#ifndef BGE_FAKE_AUTONEG
  			/*
  			 * The BCM5704 ASIC appears to have a special
  			 * mechanism for programming the autoneg
  			 * advertisement registers in TBI mode.
  			 */
-			if (sc->bge_asicrev == BGE_ASICREV_BCM5704) {
+			if (bge_fake_autoneg == 0 &&
+			    sc->bge_asicrev == BGE_ASICREV_BCM5704) {
  				uint32_t sgdig;
  				CSR_WRITE_4(sc, BGE_TX_TBI_AUTONEG, 0);
  				sgdig = CSR_READ_4(sc, BGE_SGDIG_CFG);
@@ -3365,7 +3370,6 @@
  				DELAY(5);
  				CSR_WRITE_4(sc, BGE_SGDIG_CFG, sgdig);
  			}
-#endif
  			break;
  		case IFM_1000_SX:
  			if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX) {
@@ -3377,9 +3381,9 @@
  			}
  			break;
  		default:
-			return(EINVAL);
+			return (EINVAL);
  		}
-		return(0);
+		return (0);
  	}

  	sc->bge_link_evt++;
@@ -3392,33 +3396,37 @@
  	}
  	mii_mediachg(mii);

-	return(0);
+	return (0);
  }

  /*
   * Report current media status.
   */
  static void
-bge_ifmedia_sts(ifp, ifmr)
-	struct ifnet *ifp;
-	struct ifmediareq *ifmr;
+bge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
  {
-	struct bge_softc *sc;
+	struct bge_softc *sc = ifp->if_softc;
  	struct mii_data *mii;

-	sc = ifp->if_softc;
+	BGE_LOCK(sc);

-	if (sc->bge_tbi) {
+	if (sc->bge_flags & BGE_FLAG_TBI) {
  		ifmr->ifm_status = IFM_AVALID;
  		ifmr->ifm_active = IFM_ETHER;
  		if (CSR_READ_4(sc, BGE_MAC_STS) &
  		    BGE_MACSTAT_TBI_PCS_SYNCHED)
  			ifmr->ifm_status |= IFM_ACTIVE;
+		else {
+			ifmr->ifm_active |= IFM_NONE;
+			BGE_UNLOCK(sc);
+			return;
+		}
  		ifmr->ifm_active |= IFM_1000_SX;
  		if (CSR_READ_4(sc, BGE_MAC_MODE) & BGE_MACMODE_HALF_DUPLEX)
  			ifmr->ifm_active |= IFM_HDX;
  		else
  			ifmr->ifm_active |= IFM_FDX;
+		BGE_UNLOCK(sc);
  		return;
  	}

@@ -3427,28 +3435,26 @@
  	ifmr->ifm_active = mii->mii_media_active;
  	ifmr->ifm_status = mii->mii_media_status;

-	return;
+	BGE_UNLOCK(sc);
  }

  static int
-bge_ioctl(ifp, command, data)
-	struct ifnet *ifp;
-	u_long command;
-	caddr_t data;
+bge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
  {
  	struct bge_softc *sc = ifp->if_softc;
  	struct ifreq *ifr = (struct ifreq *) data;
-	int mask, error = 0;
  	struct mii_data *mii;
+	int mask, error = 0;

-	switch(command) {
+	switch (command) {
  	case SIOCSIFMTU:
-		/* Disallow jumbo frames on 5705. */
-		if (((sc->bge_asicrev == BGE_ASICREV_BCM5705 ||
-		      sc->bge_asicrev == BGE_ASICREV_BCM5750) &&
-		    ifr->ifr_mtu > ETHERMTU) || ifr->ifr_mtu > BGE_JUMBO_MTU)
+		if (ifr->ifr_mtu < ETHERMIN ||
+		    ((sc->bge_flags & BGE_FLAG_JUMBO) &&
+		    ifr->ifr_mtu > BGE_JUMBO_MTU) ||
+		    (!(sc->bge_flags & BGE_FLAG_JUMBO) &&
+		    ifr->ifr_mtu > ETHERMTU))
  			error = EINVAL;
-		else {
+		else if (ifp->if_mtu != ifr->ifr_mtu) {
  			ifp->if_mtu = ifr->ifr_mtu;
  			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
  			bge_init(sc);
@@ -3500,7 +3506,7 @@
  		break;
  	case SIOCSIFMEDIA:
  	case SIOCGIFMEDIA:
-		if (sc->bge_tbi) {
+		if (sc->bge_flags & BGE_FLAG_TBI) {
  			error = ifmedia_ioctl(ifp, ifr,
  			    &sc->bge_ifmedia, command);
  		} else {
@@ -3516,14 +3522,14 @@
  			if (ifr->ifr_reqcap & IFCAP_POLLING) {
  				error = ether_poll_register(bge_poll, ifp);
  				if (error)
-					return(error);
+					return (error);
  				BGE_LOCK(sc);
  				BGE_SETBIT(sc, BGE_PCI_MISC_CTL,
  				    BGE_PCIMISCCTL_MASK_PCI_INTR);
  				CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 1);
  				CSR_WRITE_4(sc, BGE_HCC_RX_MAX_COAL_BDS_INT, 1);
  				CSR_WRITE_4(sc, BGE_HCC_TX_MAX_COAL_BDS_INT, 1);
-				ifp->if_capenable |= IFCAP_POLLING;
+				ifp->if_capenable |= IFCAP_POLLING;
  				BGE_UNLOCK(sc);
  			} else {
  				error = ether_poll_deregister(ifp);
@@ -3553,12 +3559,11 @@
  		break;
  	}

-	return(error);
+	return (error);
  }

  static void
-bge_watchdog(ifp)
-	struct ifnet *ifp;
+bge_watchdog(struct ifnet *ifp)
  {
  	struct bge_softc *sc;

@@ -3570,8 +3575,6 @@
  	bge_init(sc);

  	ifp->if_oerrors++;
-
-	return;
  }

  /*
@@ -3579,8 +3582,7 @@
   * RX and TX lists.
   */
  static void
-bge_stop(sc)
-	struct bge_softc *sc;
+bge_stop(struct bge_softc *sc)
  {
  	struct ifnet *ifp;
  	struct ifmedia_entry *ifm;
@@ -3591,34 +3593,32 @@

  	ifp = sc->bge_ifp;

-	if (!sc->bge_tbi)
+	if ((sc->bge_flags & BGE_FLAG_TBI) == 0)
  		mii = device_get_softc(sc->bge_miibus);

  	callout_stop(&sc->bge_stat_ch);

  	/*
-	 * Disable all of the receiver blocks
+	 * Disable all of the receiver blocks.
  	 */
  	BGE_CLRBIT(sc, BGE_RX_MODE, BGE_RXMODE_ENABLE);
  	BGE_CLRBIT(sc, BGE_RBDI_MODE, BGE_RBDIMODE_ENABLE);
  	BGE_CLRBIT(sc, BGE_RXLP_MODE, BGE_RXLPMODE_ENABLE);
-	if (sc->bge_asicrev != BGE_ASICREV_BCM5705 &&
-	    sc->bge_asicrev != BGE_ASICREV_BCM5750)
+	if ((sc->bge_flags & BGE_FLAG_5705_PLUS) == 0)
  		BGE_CLRBIT(sc, BGE_RXLS_MODE, BGE_RXLSMODE_ENABLE);
  	BGE_CLRBIT(sc, BGE_RDBDI_MODE, BGE_RBDIMODE_ENABLE);
  	BGE_CLRBIT(sc, BGE_RDC_MODE, BGE_RDCMODE_ENABLE);
  	BGE_CLRBIT(sc, BGE_RBDC_MODE, BGE_RBDCMODE_ENABLE);

  	/*
-	 * Disable all of the transmit blocks
+	 * Disable all of the transmit blocks.
  	 */
  	BGE_CLRBIT(sc, BGE_SRS_MODE, BGE_SRSMODE_ENABLE);
  	BGE_CLRBIT(sc, BGE_SBDI_MODE, BGE_SBDIMODE_ENABLE);
  	BGE_CLRBIT(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE);
  	BGE_CLRBIT(sc, BGE_RDMA_MODE, BGE_RDMAMODE_ENABLE);
  	BGE_CLRBIT(sc, BGE_SDC_MODE, BGE_SDCMODE_ENABLE);
-	if (sc->bge_asicrev != BGE_ASICREV_BCM5705 &&
-	    sc->bge_asicrev != BGE_ASICREV_BCM5750)
+	if ((sc->bge_flags & BGE_FLAG_5705_PLUS) == 0)
  		BGE_CLRBIT(sc, BGE_DMAC_MODE, BGE_DMACMODE_ENABLE);
  	BGE_CLRBIT(sc, BGE_SBDC_MODE, BGE_SBDCMODE_ENABLE);

@@ -3628,13 +3628,11 @@
  	 */
  	BGE_CLRBIT(sc, BGE_HCC_MODE, BGE_HCCMODE_ENABLE);
  	BGE_CLRBIT(sc, BGE_WDMA_MODE, BGE_WDMAMODE_ENABLE);
-	if (sc->bge_asicrev != BGE_ASICREV_BCM5705 &&
-	    sc->bge_asicrev != BGE_ASICREV_BCM5750)
+	if ((sc->bge_flags & BGE_FLAG_5705_PLUS) == 0)
  		BGE_CLRBIT(sc, BGE_MBCF_MODE, BGE_MBCFMODE_ENABLE);
  	CSR_WRITE_4(sc, BGE_FTQ_RESET, 0xFFFFFFFF);
  	CSR_WRITE_4(sc, BGE_FTQ_RESET, 0);
-	if (sc->bge_asicrev != BGE_ASICREV_BCM5705 &&
-	    sc->bge_asicrev != BGE_ASICREV_BCM5750) {
+	if ((sc->bge_flags & BGE_FLAG_5705_PLUS) == 0) {
  		BGE_CLRBIT(sc, BGE_BMAN_MODE, BGE_BMANMODE_ENABLE);
  		BGE_CLRBIT(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE);
  	}
@@ -3652,8 +3650,7 @@
  	bge_free_rx_ring_std(sc);

  	/* Free jumbo RX list. */
-	if (sc->bge_asicrev != BGE_ASICREV_BCM5705 &&
-	    sc->bge_asicrev != BGE_ASICREV_BCM5750)
+	if (sc->bge_flags & BGE_FLAG_JUMBO)
  		bge_free_rx_ring_jumbo(sc);

  	/* Free TX buffers. */
@@ -3664,7 +3661,7 @@
  	 * unchanged so that things will be put back to normal when
  	 * we bring the interface back up.
  	 */
-	if (!sc->bge_tbi) {
+	if ((sc->bge_flags & BGE_FLAG_TBI) == 0) {
  		itmp = ifp->if_flags;
  		ifp->if_flags |= IFF_UP;
  		/*
@@ -3700,8 +3697,7 @@
   * get confused by errant DMAs when rebooting.
   */
  static void
-bge_shutdown(dev)
-	device_t dev;
+bge_shutdown(device_t dev)
  {
  	struct bge_softc *sc;

@@ -3711,8 +3707,6 @@
  	bge_stop(sc);
  	bge_reset(sc);
  	BGE_UNLOCK(sc);
-
-	return;
  }

  static int
@@ -3748,15 +3742,14 @@
  }

  static void
-bge_link_upd(sc)
-	struct bge_softc *sc;
+bge_link_upd(struct bge_softc *sc)
  {
  	struct mii_data *mii;
  	uint32_t link, status;

  	BGE_LOCK_ASSERT(sc);

-	/* Clear 'pending link event' flag */
+	/* Clear 'pending link event' flag. */
  	sc->bge_link_evt = 0;

  	/*
@@ -3771,11 +3764,11 @@
  	 * the interrupt handler.
  	 *
  	 * XXX: perhaps link state detection procedure used for
-	 * BGE_CHIPID_BCM5700_B1 can be used for others BCM5700 revisions.
+	 * BGE_CHIPID_BCM5700_B2 can be used for others BCM5700 revisions.
  	 */

  	if (sc->bge_asicrev == BGE_ASICREV_BCM5700 &&
-	    sc->bge_chipid != BGE_CHIPID_BCM5700_B1) {
+	    sc->bge_chipid != BGE_CHIPID_BCM5700_B2) {
  		status = CSR_READ_4(sc, BGE_MAC_STS);
  		if (status & BGE_MACSTAT_MI_INTERRUPT) {
  			callout_stop(&sc->bge_stat_ch);
@@ -3796,7 +3789,7 @@
  					if_printf(sc->bge_ifp, "link DOWN\n");
  			}

-			/* Clear the interrupt */
+			/* Clear the interrupt. */
  			CSR_WRITE_4(sc, BGE_MAC_EVT_ENB,
  			    BGE_EVTENB_MI_INTERRUPT);
  			bge_miibus_readreg(sc->bge_dev, 1, BRGPHY_MII_ISR);
@@ -3804,9 +3797,9 @@
  			    BRGPHY_INTRS);
  		}
  		return;
-	}
+	}

-	if (sc->bge_tbi) {
+	if (sc->bge_flags & BGE_FLAG_TBI) {
  		status = CSR_READ_4(sc, BGE_MAC_STS);
  		if (status & BGE_MACSTAT_TBI_PCS_SYNCHED) {
  			if (!sc->bge_link) {
@@ -3817,7 +3810,8 @@
  				CSR_WRITE_4(sc, BGE_MAC_STS, 0xFFFFFFFF);
  				if (bootverbose)
  					if_printf(sc->bge_ifp, "link UP\n");
-				if_link_state_change(sc->bge_ifp, LINK_STATE_UP);
+				if_link_state_change(sc->bge_ifp,
+				    LINK_STATE_UP);
  			}
  		} else if (sc->bge_link) {
  			sc->bge_link = 0;
@@ -3827,7 +3821,7 @@
  		}
  	/* Discard link events for MII/GMII cards if MI auto-polling  
disabled */
  	} else if (CSR_READ_4(sc, BGE_MI_MODE) & BGE_MIMODE_AUTOPOLL) {
-		/*
+		/*
  		 * Some broken BCM chips have BGE_STATFLAG_LINKSTATE_CHANGED bit
  		 * in status word always set. Workaround this bug by reading
  		 * PHY link status directly.
@@ -3856,8 +3850,142 @@
  		}
  	}

-	/* Clear the attention */
+	/* Clear the attention. */
  	CSR_WRITE_4(sc, BGE_MAC_STS, BGE_MACSTAT_SYNC_CHANGED|
  	    BGE_MACSTAT_CFG_CHANGED|BGE_MACSTAT_MI_COMPLETE|
  	    BGE_MACSTAT_LINK_CHANGED);
  }
+
+static void
+bge_add_sysctls(struct bge_softc *sc)
+{
+	struct sysctl_ctx_list *ctx;
+	struct sysctl_oid_list *children;
+
+	ctx = device_get_sysctl_ctx(sc->bge_dev);
+	children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->bge_dev));
+
+	SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "debug_info",
+	    CTLTYPE_INT | CTLFLAG_RW, sc, 0, bge_sysctl_debug_info, "I",
+	    "Debug Information");
+
+	SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "reg_read",
+	    CTLTYPE_INT | CTLFLAG_RW, sc, 0, bge_sysctl_reg_read, "I",
+	    "Register Read");
+
+	SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "mem_read",
+	    CTLTYPE_INT | CTLFLAG_RW, sc, 0, bge_sysctl_mem_read, "I",
+	    "Memory Read");
+
+	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, "stat_IfHcInOctets",
+	    CTLFLAG_RD,
+	    &sc->bge_ldata.bge_stats->rxstats.ifHCInOctets.bge_addr_lo,
+	    "Bytes received");
+
+	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, "stat_IfHcOutOctets",
+	    CTLFLAG_RD,
+	    &sc->bge_ldata.bge_stats->txstats.ifHCOutOctets.bge_addr_lo,
+	    "Bytes received");
+}
+
+static int
+bge_sysctl_debug_info(SYSCTL_HANDLER_ARGS)
+{
+	struct bge_softc *sc;
+	uint16_t *sbdata;
+	int error;
+	int result;
+	int i, j;
+
+	result = -1;
+	error = sysctl_handle_int(oidp, &result, 0, req);
+	if (error || (req->newptr == NULL))
+		return (error);
+
+	if (result == 1) {
+		sc = (struct bge_softc *)arg1;
+
+		sbdata = (uint16_t *)sc->bge_ldata.bge_status_block;
+		printf("Status Block:\n");
+		for (i = 0x0; i < (BGE_STATUS_BLK_SZ / 4); ) {
+			printf("%06x:", i);
+			for (j = 0; j < 8; j++) {
+				printf(" %04x", sbdata[i]);
+				i += 4;
+			}
+			printf("\n");
+		}
+
+		printf("Registers:\n");
+		for (i = 0x800; i < 0xa00; ) {
+			printf("%06x:", i);
+			for (j = 0; j < 8; j++) {
+				printf(" %08x", CSR_READ_4(sc, i));
+				i += 4;
+			}
+			printf("\n");
+		}
+
+		printf("Hardware Flags:\n");
+		if (sc->bge_flags & BGE_FLAG_575X_PLUS)
+			printf(" - 575X Plus\n");
+		if (sc->bge_flags & BGE_FLAG_5705_PLUS)
+			printf(" - 5705 Plus\n");
+		if (sc->bge_flags & BGE_FLAG_JUMBO)
+			printf(" - Supports Jumbo Frames\n");
+		if (sc->bge_flags & BGE_FLAG_PCIX)
+			printf(" - PCI-X Bus\n");
+		if (sc->bge_flags & BGE_FLAG_PCIE)
+			printf(" - PCI Express Bus\n");
+		if (sc->bge_flags & BGE_FLAG_NO3LED)
+			printf(" - No 3 LEDs\n");
+		if (sc->bge_flags & BGE_FLAG_RX_ALIGNBUG)
+			printf(" - RX Alignment Bug\n");
+	}
+
+	return (error);
+}
+
+static int
+bge_sysctl_reg_read(SYSCTL_HANDLER_ARGS)
+{
+	struct bge_softc *sc;
+	int error;
+	uint16_t result;
+	uint32_t val;
+
+	result = -1;
+	error = sysctl_handle_int(oidp, &result, 0, req);
+	if (error || (req->newptr == NULL))
+		return (error);
+
+	if (result < 0x8000) {
+		sc = (struct bge_softc *)arg1;
+		val = CSR_READ_4(sc, result);
+		printf("reg 0x%06X = 0x%08X\n", result, val);
+	}
+
+	return (error);
+}
+
+static int
+bge_sysctl_mem_read(SYSCTL_HANDLER_ARGS)
+{
+	struct bge_softc *sc;
+	int error;
+	uint16_t result;
+	uint32_t val;
+
+	result = -1;
+	error = sysctl_handle_int(oidp, &result, 0, req);
+	if (error || (req->newptr == NULL))
+		return (error);
+
+	if (result < 0x8000) {
+		sc = (struct bge_softc *)arg1;
+		val = bge_readmem_ind(sc, result);
+		printf("mem 0x%06X = 0x%08X\n", result, val);
+	}
+
+	return (error);
+}
Index: if_bgereg.h
===================================================================
RCS file: /usr1/ncvs/src/sys/dev/bge/if_bgereg.h,v
retrieving revision 1.36.2.4
diff -u -r1.36.2.4 if_bgereg.h
--- if_bgereg.h	5 Feb 2006 18:07:15 -0000	1.36.2.4
+++ if_bgereg.h	14 Dec 2006 16:40:51 -0000
@@ -30,7 +30,7 @@
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF  
ADVISED OF
   * THE POSSIBILITY OF SUCH DAMAGE.
   *
- * $FreeBSD: src/sys/dev/bge/if_bgereg.h,v 1.36.2.4 2006/02/05  
18:07:15 oleg Exp $
+ * $FreeBSD: src/sys/dev/bge/if_bgereg.h,v 1.36.2.8 2006/10/13  
08:05:55 glebius Exp $
   */

  /*
@@ -224,9 +224,12 @@

  #define BGE_CHIPID_TIGON_I		0x40000000
  #define BGE_CHIPID_TIGON_II		0x60000000
+#define BGE_CHIPID_BCM5700_A0		0x70000000
+#define BGE_CHIPID_BCM5700_A1		0x70010000
  #define BGE_CHIPID_BCM5700_B0		0x71000000
-#define BGE_CHIPID_BCM5700_B1		0x71020000
-#define BGE_CHIPID_BCM5700_B2		0x71030000
+#define BGE_CHIPID_BCM5700_B1		0x71010000
+#define BGE_CHIPID_BCM5700_B2		0x71020000
+#define BGE_CHIPID_BCM5700_B3		0x71030000
  #define BGE_CHIPID_BCM5700_ALTIMA	0x71040000
  #define BGE_CHIPID_BCM5700_C0		0x72000000
  #define BGE_CHIPID_BCM5701_A0		0x00000000	/* grrrr */
@@ -236,27 +239,58 @@
  #define BGE_CHIPID_BCM5703_A0		0x10000000
  #define BGE_CHIPID_BCM5703_A1		0x10010000
  #define BGE_CHIPID_BCM5703_A2		0x10020000
+#define BGE_CHIPID_BCM5703_A3		0x10030000
+#define BGE_CHIPID_BCM5703_B0		0x11000000
  #define BGE_CHIPID_BCM5704_A0		0x20000000
  #define BGE_CHIPID_BCM5704_A1		0x20010000
  #define BGE_CHIPID_BCM5704_A2		0x20020000
+#define BGE_CHIPID_BCM5704_A3		0x20030000
+#define BGE_CHIPID_BCM5704_B0		0x21000000
  #define BGE_CHIPID_BCM5705_A0		0x30000000
  #define BGE_CHIPID_BCM5705_A1		0x30010000
  #define BGE_CHIPID_BCM5705_A2		0x30020000
  #define BGE_CHIPID_BCM5705_A3		0x30030000
  #define BGE_CHIPID_BCM5750_A0		0x40000000
  #define BGE_CHIPID_BCM5750_A1		0x40010000
+#define BGE_CHIPID_BCM5750_A3		0x40030000
+#define BGE_CHIPID_BCM5750_B0		0x40100000
+#define BGE_CHIPID_BCM5750_B1		0x41010000
+#define BGE_CHIPID_BCM5750_C0		0x42000000
+#define BGE_CHIPID_BCM5750_C1		0x42010000
+#define BGE_CHIPID_BCM5750_C2		0x42020000
  #define BGE_CHIPID_BCM5714_A0		0x50000000
+#define BGE_CHIPID_BCM5752_A0		0x60000000
+#define BGE_CHIPID_BCM5752_A1		0x60010000
+#define BGE_CHIPID_BCM5752_A2		0x60020000
+#define BGE_CHIPID_BCM5714_B0		0x80000000
+#define BGE_CHIPID_BCM5714_B3		0x80030000
+#define BGE_CHIPID_BCM5715_A0		0x90000000
+#define BGE_CHIPID_BCM5715_A1		0x90010000
+#define BGE_CHIPID_BCM5755_A0		0xa0000000
+#define BGE_CHIPID_BCM5755_A1		0xa0010000
+#define BGE_CHIPID_BCM5755_A2		0xa0020000
+#define BGE_CHIPID_BCM5754_A0		0xb0000000
+#define BGE_CHIPID_BCM5754_A1		0xb0010000
+#define BGE_CHIPID_BCM5754_A2		0xb0020000
+#define BGE_CHIPID_BCM5787_A0		0xb0000000
+#define BGE_CHIPID_BCM5787_A1		0xb0010000
+#define BGE_CHIPID_BCM5787_A2		0xb0020000

  /* shorthand one */
  #define BGE_ASICREV(x)			((x) >> 28)
-#define BGE_ASICREV_BCM5700		0x07
  #define BGE_ASICREV_BCM5701		0x00
  #define BGE_ASICREV_BCM5703		0x01
  #define BGE_ASICREV_BCM5704		0x02
  #define BGE_ASICREV_BCM5705		0x03
  #define BGE_ASICREV_BCM5750		0x04
-#define BGE_ASICREV_BCM5714		0x05
+#define BGE_ASICREV_BCM5714_A0		0x05
  #define BGE_ASICREV_BCM5752		0x06
+#define BGE_ASICREV_BCM5700		0x07
+#define BGE_ASICREV_BCM5780		0x08
+#define BGE_ASICREV_BCM5714		0x09
+#define BGE_ASICREV_BCM5755		0x0a
+#define BGE_ASICREV_BCM5754		0x0b
+#define BGE_ASICREV_BCM5787		0x0b

  /* chip revisions */
  #define BGE_CHIPREV(x)			((x) >> 24)
@@ -1160,7 +1194,7 @@
  #define BGE_HCCMODE_ENABLE		0x00000002
  #define BGE_HCCMODE_ATTN		0x00000004
  #define BGE_HCCMODE_COAL_NOW		0x00000008
-#define BGE_HCCMODE_MSI_BITS		0x0x000070
+#define BGE_HCCMODE_MSI_BITS		0x00000070
  #define BGE_HCCMODE_STATBLK_SIZE	0x00000180

  #define BGE_STATBLKSZ_FULL		0x00000000
@@ -1632,6 +1666,7 @@
  #define BGE_EE_CTL			0x6840
  #define BGE_MDI_CTL			0x6844
  #define BGE_EE_DELAY			0x6848
+#define BGE_FASTBOOT_PC			0x6894

  /* Mode control register */
  #define BGE_MODECTL_INT_SNDCOAL_ONLY	0x00000001
@@ -1752,26 +1787,26 @@
  #define BGE_MAGIC_NUMBER                0x4B657654

  typedef struct {
-	u_int32_t		bge_addr_hi;
-	u_int32_t		bge_addr_lo;
+	uint32_t		bge_addr_hi;
+	uint32_t		bge_addr_lo;
  } bge_hostaddr;

  #define BGE_HOSTADDR(x, y)						\
  	do {								\
-		(x).bge_addr_lo = ((u_int64_t) (y) & 0xffffffff);	\
-		(x).bge_addr_hi = ((u_int64_t) (y) >> 32);		\
+		(x).bge_addr_lo = ((uint64_t) (y) & 0xffffffff);	\
+		(x).bge_addr_hi = ((uint64_t) (y) >> 32);		\
  	} while(0)

  #define BGE_ADDR_LO(y)	\
-	((u_int64_t) (y) & 0xFFFFFFFF)
+	((uint64_t) (y) & 0xFFFFFFFF)
  #define BGE_ADDR_HI(y)	\
-	((u_int64_t) (y) >> 32)
+	((uint64_t) (y) >> 32)

  /* Ring control block structure */
  struct bge_rcb {
  	bge_hostaddr		bge_hostaddr;
-	u_int32_t		bge_maxlen_flags;
-	u_int32_t		bge_nicaddr;
+	uint32_t		bge_maxlen_flags;
+	uint32_t		bge_nicaddr;
  };

  #define	RCB_WRITE_4(sc, rcb, offset, val) \
@@ -1785,15 +1820,15 @@
  struct bge_tx_bd {
  	bge_hostaddr		bge_addr;
  #if BYTE_ORDER == LITTLE_ENDIAN
-	u_int16_t		bge_flags;
-	u_int16_t		bge_len;
-	u_int16_t		bge_vlan_tag;
-	u_int16_t		bge_rsvd;
+	uint16_t		bge_flags;
+	uint16_t		bge_len;
+	uint16_t		bge_vlan_tag;
+	uint16_t		bge_rsvd;
  #else
-	u_int16_t		bge_len;
-	u_int16_t		bge_flags;
-	u_int16_t		bge_rsvd;
-	u_int16_t		bge_vlan_tag;
+	uint16_t		bge_len;
+	uint16_t		bge_flags;
+	uint16_t		bge_rsvd;
+	uint16_t		bge_vlan_tag;
  #endif
  };

@@ -1817,26 +1852,26 @@
  struct bge_rx_bd {
  	bge_hostaddr		bge_addr;
  #if BYTE_ORDER == LITTLE_ENDIAN
-	u_int16_t		bge_len;
-	u_int16_t		bge_idx;
-	u_int16_t		bge_flags;
-	u_int16_t		bge_type;
-	u_int16_t		bge_tcp_udp_csum;
-	u_int16_t		bge_ip_csum;
-	u_int16_t		bge_vlan_tag;
-	u_int16_t		bge_error_flag;
+	uint16_t		bge_len;
+	uint16_t		bge_idx;
+	uint16_t		bge_flags;
+	uint16_t		bge_type;
+	uint16_t		bge_tcp_udp_csum;
+	uint16_t		bge_ip_csum;
+	uint16_t		bge_vlan_tag;
+	uint16_t		bge_error_flag;
  #else
-	u_int16_t		bge_idx;
-	u_int16_t		bge_len;
-	u_int16_t		bge_type;
-	u_int16_t		bge_flags;
-	u_int16_t		bge_ip_csum;
-	u_int16_t		bge_tcp_udp_csum;
-	u_int16_t		bge_error_flag;
-	u_int16_t		bge_vlan_tag;
+	uint16_t		bge_idx;
+	uint16_t		bge_len;
+	uint16_t		bge_type;
+	uint16_t		bge_flags;
+	uint16_t		bge_ip_csum;
+	uint16_t		bge_tcp_udp_csum;
+	uint16_t		bge_error_flag;
+	uint16_t		bge_vlan_tag;
  #endif
-	u_int32_t		bge_rsvd;
-	u_int32_t		bge_opaque;
+	uint32_t		bge_rsvd;
+	uint32_t		bge_opaque;
  };

  struct bge_extrx_bd {
@@ -1844,38 +1879,38 @@
  	bge_hostaddr		bge_addr2;
  	bge_hostaddr		bge_addr3;
  #if BYTE_ORDER == LITTLE_ENDIAN
-	u_int16_t		bge_len2;
-	u_int16_t		bge_len1;
-	u_int16_t		bge_rsvd1;
-	u_int16_t		bge_len3;
+	uint16_t		bge_len2;
+	uint16_t		bge_len1;
+	uint16_t		bge_rsvd1;
+	uint16_t		bge_len3;
  #else
-	u_int16_t		bge_len1;
-	u_int16_t		bge_len2;
-	u_int16_t		bge_len3;
-	u_int16_t		bge_rsvd1;
+	uint16_t		bge_len1;
+	uint16_t		bge_len2;
+	uint16_t		bge_len3;
+	uint16_t		bge_rsvd1;
  #endif
  	bge_hostaddr		bge_addr0;
  #if BYTE_ORDER == LITTLE_ENDIAN
-	u_int16_t		bge_len0;
-	u_int16_t		bge_idx;
-	u_int16_t		bge_flags;
-	u_int16_t		bge_type;
-	u_int16_t		bge_tcp_udp_csum;
-	u_int16_t		bge_ip_csum;
-	u_int16_t		bge_vlan_tag;
-	u_int16_t		bge_error_flag;
+	uint16_t		bge_len0;
+	uint16_t		bge_idx;
+	uint16_t		bge_flags;
+	uint16_t		bge_type;
+	uint16_t		bge_tcp_udp_csum;
+	uint16_t		bge_ip_csum;
+	uint16_t		bge_vlan_tag;
+	uint16_t		bge_error_flag;
  #else
-	u_int16_t		bge_idx;
-	u_int16_t		bge_len0;
-	u_int16_t		bge_type;
-	u_int16_t		bge_flags;
-	u_int16_t		bge_ip_csum;
-	u_int16_t		bge_tcp_udp_csum;
-	u_int16_t		bge_error_flag;
-	u_int16_t		bge_vlan_tag;
+	uint16_t		bge_idx;
+	uint16_t		bge_len0;
+	uint16_t		bge_type;
+	uint16_t		bge_flags;
+	uint16_t		bge_ip_csum;
+	uint16_t		bge_tcp_udp_csum;
+	uint16_t		bge_error_flag;
+	uint16_t		bge_vlan_tag;
  #endif
-	u_int32_t		bge_rsvd0;
-	u_int32_t		bge_opaque;
+	uint32_t		bge_rsvd0;
+	uint32_t		bge_opaque;
  };

  #define BGE_RXBDFLAG_END		0x0004
@@ -1898,27 +1933,27 @@

  struct bge_sts_idx {
  #if BYTE_ORDER == LITTLE_ENDIAN
-	u_int16_t		bge_rx_prod_idx;
-	u_int16_t		bge_tx_cons_idx;
+	uint16_t		bge_rx_prod_idx;
+	uint16_t		bge_tx_cons_idx;
  #else
-	u_int16_t		bge_tx_cons_idx;
-	u_int16_t		bge_rx_prod_idx;
+	uint16_t		bge_tx_cons_idx;
+	uint16_t		bge_rx_prod_idx;
  #endif
  };

  struct bge_status_block {
-	u_int32_t		bge_status;
-	u_int32_t		bge_rsvd0;
+	uint32_t		bge_status;
+	uint32_t		bge_rsvd0;
  #if BYTE_ORDER == LITTLE_ENDIAN
-	u_int16_t		bge_rx_jumbo_cons_idx;
-	u_int16_t		bge_rx_std_cons_idx;
-	u_int16_t		bge_rx_mini_cons_idx;
-	u_int16_t		bge_rsvd1;
+	uint16_t		bge_rx_jumbo_cons_idx;
+	uint16_t		bge_rx_std_cons_idx;
+	uint16_t		bge_rx_mini_cons_idx;
+	uint16_t		bge_rsvd1;
  #else
-	u_int16_t		bge_rx_std_cons_idx;
-	u_int16_t		bge_rx_jumbo_cons_idx;
-	u_int16_t		bge_rsvd1;
-	u_int16_t		bge_rx_mini_cons_idx;
+	uint16_t		bge_rx_std_cons_idx;
+	uint16_t		bge_rx_jumbo_cons_idx;
+	uint16_t		bge_rsvd1;
+	uint16_t		bge_rx_mini_cons_idx;
  #endif
  	struct bge_sts_idx	bge_idx[16];
  };
@@ -1939,43 +1974,66 @@
  #define BCOM_VENDORID			0x14E4
  #define BCOM_DEVICEID_BCM5700		0x1644
  #define BCOM_DEVICEID_BCM5701		0x1645
-#define BCOM_DEVICEID_BCM5702		0x16A6
-#define BCOM_DEVICEID_BCM5702X		0x16C6
-#define BCOM_DEVICEID_BCM5703		0x16A7
-#define BCOM_DEVICEID_BCM5703X		0x16C7
+#define BCOM_DEVICEID_BCM5702		0x1646
+#define BCOM_DEVICEID_BCM5702X		0x16A6
+#define BCOM_DEVICEID_BCM5702_ALT	0x16C6
+#define BCOM_DEVICEID_BCM5703		0x1647
+#define BCOM_DEVICEID_BCM5703X		0x16A7
+#define BCOM_DEVICEID_BCM5703_ALT	0x16C7
  #define BCOM_DEVICEID_BCM5704C		0x1648
  #define BCOM_DEVICEID_BCM5704S		0x16A8
+#define BCOM_DEVICEID_BCM5704S_ALT	0x1649
  #define BCOM_DEVICEID_BCM5705		0x1653
  #define BCOM_DEVICEID_BCM5705K		0x1654
-#define BCOM_DEVICEID_BCM5721		0x1659
+#define BCOM_DEVICEID_BCM5705F		0x166E
  #define BCOM_DEVICEID_BCM5705M		0x165D
  #define BCOM_DEVICEID_BCM5705M_ALT	0x165E
  #define BCOM_DEVICEID_BCM5714C		0x1668
+#define BCOM_DEVICEID_BCM5714S		0x1669
+#define BCOM_DEVICEID_BCM5715		0x1678
+#define BCOM_DEVICEID_BCM5715S		0x1679
+#define BCOM_DEVICEID_BCM5720		0x1658
+#define BCOM_DEVICEID_BCM5721		0x1659
  #define BCOM_DEVICEID_BCM5750		0x1676
  #define BCOM_DEVICEID_BCM5750M		0x167C
  #define BCOM_DEVICEID_BCM5751		0x1677
+#define BCOM_DEVICEID_BCM5751F		0x167E
  #define BCOM_DEVICEID_BCM5751M		0x167D
  #define BCOM_DEVICEID_BCM5752		0x1600
+#define BCOM_DEVICEID_BCM5752M		0x1601
+#define BCOM_DEVICEID_BCM5753		0x16F7
+#define BCOM_DEVICEID_BCM5753F		0x16FE
+#define BCOM_DEVICEID_BCM5753M		0x16FD
+#define BCOM_DEVICEID_BCM5754		0x167A
+#define BCOM_DEVICEID_BCM5754M		0x1672
+#define BCOM_DEVICEID_BCM5755		0x167B
+#define BCOM_DEVICEID_BCM5755M		0x1673
+#define BCOM_DEVICEID_BCM5780		0x166A
+#define BCOM_DEVICEID_BCM5780S		0x166B
+#define BCOM_DEVICEID_BCM5781		0x16DD
  #define BCOM_DEVICEID_BCM5782		0x1696
+#define BCOM_DEVICEID_BCM5786		0x169A
+#define BCOM_DEVICEID_BCM5787		0x169B
+#define BCOM_DEVICEID_BCM5787M		0x1693
  #define BCOM_DEVICEID_BCM5788		0x169C
  #define BCOM_DEVICEID_BCM5789		0x169D
  #define BCOM_DEVICEID_BCM5901		0x170D
  #define BCOM_DEVICEID_BCM5901A2		0x170E
+#define BCOM_DEVICEID_BCM5903M		0x16FF

  /*
   * Alteon AceNIC PCI vendor/device ID.
   */
-#define ALT_VENDORID			0x12AE
-#define ALT_DEVICEID_ACENIC		0x0001
-#define ALT_DEVICEID_ACENIC_COPPER	0x0002
-#define ALT_DEVICEID_BCM5700		0x0003
-#define ALT_DEVICEID_BCM5701		0x0004
+#define ALTEON_VENDORID			0x12AE
+#define ALTEON_DEVICEID_ACENIC		0x0001
+#define ALTEON_DEVICEID_ACENIC_COPPER	0x0002
+#define ALTEON_DEVICEID_BCM5700		0x0003
+#define ALTEON_DEVICEID_BCM5701		0x0004

  /*
- * 3Com 3c985 PCI vendor/device ID.
+ * 3Com 3c996 PCI vendor/device ID.
   */
  #define TC_VENDORID			0x10B7
-#define TC_DEVICEID_3C985		0x0001
  #define TC_DEVICEID_3C996		0x0003

  /*
@@ -2001,6 +2059,12 @@
  #define DELL_VENDORID			0x1028

  /*
+ * Apple PCI vendor ID.
+ */
+#define APPLE_VENDORID			0x106b
+#define APPLE_DEVICE_BCM5701		0x1645
+
+/*
   * Offset of MAC address inside EEPROM.
   */
  #define BGE_EE_MAC_OFFSET		0x7C
@@ -2129,43 +2193,43 @@

  /* Stats counters access through registers */
  struct bge_mac_stats_regs {
-	u_int32_t		ifHCOutOctets;
-	u_int32_t		Reserved0;
-	u_int32_t		etherStatsCollisions;
-	u_int32_t		outXonSent;
-	u_int32_t		outXoffSent;
-	u_int32_t		Reserved1;
-	u_int32_t		dot3StatsInternalMacTransmitErrors;
-	u_int32_t		dot3StatsSingleCollisionFrames;
-	u_int32_t		dot3StatsMultipleCollisionFrames;
-	u_int32_t		dot3StatsDeferredTransmissions;
-	u_int32_t		Reserved2;
-	u_int32_t		dot3StatsExcessiveCollisions;
-	u_int32_t		dot3StatsLateCollisions;
-	u_int32_t		Reserved3[14];
-	u_int32_t		ifHCOutUcastPkts;
-	u_int32_t		ifHCOutMulticastPkts;
-	u_int32_t		ifHCOutBroadcastPkts;
-	u_int32_t		Reserved4[2];
-	u_int32_t		ifHCInOctets;
-	u_int32_t		Reserved5;
-	u_int32_t		etherStatsFragments;
-	u_int32_t		ifHCInUcastPkts;
-	u_int32_t		ifHCInMulticastPkts;
-	u_int32_t		ifHCInBroadcastPkts;
-	u_int32_t		dot3StatsFCSErrors;
-	u_int32_t		dot3StatsAlignmentErrors;
-	u_int32_t		xonPauseFramesReceived;
-	u_int32_t		xoffPauseFramesReceived;
-	u_int32_t		macControlFramesReceived;
-	u_int32_t		xoffStateEntered;
-	u_int32_t		dot3StatsFramesTooLong;
-	u_int32_t		etherStatsJabbers;
-	u_int32_t		etherStatsUndersizePkts;
+	uint32_t		ifHCOutOctets;
+	uint32_t		Reserved0;
+	uint32_t		etherStatsCollisions;
+	uint32_t		outXonSent;
+	uint32_t		outXoffSent;
+	uint32_t		Reserved1;
+	uint32_t		dot3StatsInternalMacTransmitErrors;
+	uint32_t		dot3StatsSingleCollisionFrames;
+	uint32_t		dot3StatsMultipleCollisionFrames;
+	uint32_t		dot3StatsDeferredTransmissions;
+	uint32_t		Reserved2;
+	uint32_t		dot3StatsExcessiveCollisions;
+	uint32_t		dot3StatsLateCollisions;
+	uint32_t		Reserved3[14];
+	uint32_t		ifHCOutUcastPkts;
+	uint32_t		ifHCOutMulticastPkts;
+	uint32_t		ifHCOutBroadcastPkts;
+	uint32_t		Reserved4[2];
+	uint32_t		ifHCInOctets;
+	uint32_t		Reserved5;
+	uint32_t		etherStatsFragments;
+	uint32_t		ifHCInUcastPkts;
+	uint32_t		ifHCInMulticastPkts;
+	uint32_t		ifHCInBroadcastPkts;
+	uint32_t		dot3StatsFCSErrors;
+	uint32_t		dot3StatsAlignmentErrors;
+	uint32_t		xonPauseFramesReceived;
+	uint32_t		xoffPauseFramesReceived;
+	uint32_t		macControlFramesReceived;
+	uint32_t		xoffStateEntered;
+	uint32_t		dot3StatsFramesTooLong;
+	uint32_t		etherStatsJabbers;
+	uint32_t		etherStatsUndersizePkts;
  };

  struct bge_stats {
-	u_int8_t		Reserved0[256];
+	uint8_t		Reserved0[256];

  	/* Statistics maintained by Receive MAC. */
  	struct bge_rx_mac_stats rxstats;
@@ -2202,7 +2266,7 @@
  	bge_hostaddr		nicAvoidedInterrupts;
  	bge_hostaddr		nicSendThresholdHit;

-	u_int8_t		Reserved4[320];
+	uint8_t		Reserved4[320];
  };

  /*
@@ -2238,14 +2302,14 @@

  /* VPD structures */
  struct vpd_res {
-	u_int8_t		vr_id;
-	u_int8_t		vr_len;
-	u_int8_t		vr_pad;
+	uint8_t		vr_id;
+	uint8_t		vr_len;
+	uint8_t		vr_pad;
  };

  struct vpd_key {
  	char			vk_key[2];
-	u_int8_t		vk_len;
+	uint8_t		vk_len;
  };

  #define VPD_RES_ID	0x82	/* ID string */
@@ -2286,8 +2350,8 @@
  #define BGE_JSLOTS	384

  #define BGE_JRAWLEN (BGE_JUMBO_FRAMELEN + ETHER_ALIGN)
-#define BGE_JLEN (BGE_JRAWLEN + (sizeof(u_int64_t) - \
-	(BGE_JRAWLEN % sizeof(u_int64_t))))
+#define BGE_JLEN (BGE_JRAWLEN + (sizeof(uint64_t) - \
+	(BGE_JRAWLEN % sizeof(uint64_t))))
  #define BGE_JPAGESZ PAGE_SIZE
  #define BGE_RESID (BGE_JPAGESZ - (BGE_JLEN * BGE_JSLOTS) %  
BGE_JPAGESZ)
  #define BGE_JMEM ((BGE_JLEN * BGE_JSLOTS) + BGE_RESID)
@@ -2363,18 +2427,12 @@
  struct bge_dmamap_arg {
  	struct bge_softc	*sc;
  	bus_addr_t		bge_busaddr;
-	u_int16_t		bge_flags;
+	uint16_t		bge_flags;
  	int			bge_idx;
  	int			bge_maxsegs;
  	struct bge_tx_bd	*bge_ring;
  };

-struct bge_type {
-	u_int16_t		bge_vid;
-	u_int16_t		bge_did;
-	char			*bge_name;
-};
-
  #define BGE_HWREV_TIGON		0x01
  #define BGE_HWREV_TIGON_II	0x02
  #define BGE_TIMEOUT		100000
@@ -2396,29 +2454,36 @@
  	struct resource		*bge_irq;
  	struct resource		*bge_res;
  	struct ifmedia		bge_ifmedia;	/* TBI media info */
-	u_int8_t		bge_extram;	/* has external SSRAM */
-	u_int8_t		bge_tbi;
-	u_int8_t		bge_rx_alignment_bug;
-	u_int32_t		bge_chipid;
-	u_int8_t		bge_asicrev;
-	u_int8_t		bge_chiprev;
-	u_int8_t		bge_no_3_led;
-	u_int8_t		bge_pcie;
+	uint32_t		bge_chipid;
+	uint8_t			bge_asicrev;
+	uint8_t			bge_chiprev;
+	int			bge_flags;
+#define BGE_FLAG_EXTRAM		0x00000001	/* External SSRAM (unused) */
+#define BGE_FLAG_TBI		0x00000002
+#define BGE_FLAG_RX_ALIGNBUG	0x00000004
+#define BGE_FLAG_NO3LED		0x00000008
+#define BGE_FLAG_PCIX		0x00000010
+#define BGE_FLAG_PCIE		0x00000020
+#define BGE_FLAG_JUMBO		0x00000040
+#define BGE_FLAG_5700_FAMILY	0x00000100
+#define BGE_FLAG_5705_PLUS	0x00000200
+#define BGE_FLAG_5714_FAMILY	0x00000400
+#define BGE_FLAG_575X_PLUS	0x00000800
  	struct bge_ring_data	bge_ldata;	/* rings */
  	struct bge_chain_data	bge_cdata;	/* mbufs */
-	u_int16_t		bge_tx_saved_considx;
-	u_int16_t		bge_rx_saved_considx;
-	u_int16_t		bge_ev_saved_considx;
-	u_int16_t		bge_return_ring_cnt;
-	u_int16_t		bge_std;	/* current std ring head */
-	u_int16_t		bge_jumbo;	/* current jumo ring head */
-	u_int32_t		bge_stat_ticks;
-	u_int32_t		bge_rx_coal_ticks;
-	u_int32_t		bge_tx_coal_ticks;
-	u_int32_t		bge_tx_prodidx;
-	u_int32_t		bge_rx_max_coal_bds;
-	u_int32_t		bge_tx_max_coal_bds;
-	u_int32_t		bge_tx_buf_ratio;
+	uint16_t		bge_tx_saved_considx;
+	uint16_t		bge_rx_saved_considx;
+	uint16_t		bge_ev_saved_considx;
+	uint16_t		bge_return_ring_cnt;
+	uint16_t		bge_std;	/* current std ring head */
+	uint16_t		bge_jumbo;	/* current jumo ring head */
+	uint32_t		bge_stat_ticks;
+	uint32_t		bge_rx_coal_ticks;
+	uint32_t		bge_tx_coal_ticks;
+	uint32_t		bge_tx_prodidx;
+	uint32_t		bge_rx_max_coal_bds;
+	uint32_t		bge_tx_max_coal_bds;
+	uint32_t		bge_tx_buf_ratio;
  	int			bge_if_flags;
  	int			bge_txcnt;
  	int			bge_link;	/* link state */
Index: brgphy.c
===================================================================
RCS file: /usr1/ncvs/src/sys/dev/mii/brgphy.c,v
retrieving revision 1.34.2.3.2.2
diff -u -r1.34.2.3.2.2 brgphy.c
--- brgphy.c	12 Apr 2006 18:38:59 -0000	1.34.2.3.2.2
+++ brgphy.c	14 Dec 2006 17:41:17 -0000
@@ -31,7 +31,7 @@
   */

  #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/mii/brgphy.c,v 1.34.2.3.2.2  
2006/04/12 18:38:59 ps Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/mii/brgphy.c,v 1.34.2.7 2006/10/21  
00:26:41 yongari Exp $");

  /*
   * Driver for the Broadcom BCR5400 1000baseTX PHY. Speed is always
@@ -110,73 +110,85 @@
  	if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_xxBROADCOM &&
  	    MII_MODEL(ma->mii_id2) == MII_MODEL_xxBROADCOM_BCM5400) {
  		device_set_desc(dev, MII_STR_xxBROADCOM_BCM5400);
-		return(0);
+		return(BUS_PROBE_DEFAULT);
  	}

  	if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_xxBROADCOM &&
  	    MII_MODEL(ma->mii_id2) == MII_MODEL_xxBROADCOM_BCM5401) {
  		device_set_desc(dev, MII_STR_xxBROADCOM_BCM5401);
-		return(0);
+		return(BUS_PROBE_DEFAULT);
  	}

  	if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_xxBROADCOM &&
  	    MII_MODEL(ma->mii_id2) == MII_MODEL_xxBROADCOM_BCM5411) {
  		device_set_desc(dev, MII_STR_xxBROADCOM_BCM5411);
-		return(0);
+		return(BUS_PROBE_DEFAULT);
+	}
+
+	if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_xxBROADCOM &&
+	    MII_MODEL(ma->mii_id2) == MII_MODEL_xxBROADCOM_BCM5752) {
+		device_set_desc(dev, MII_STR_xxBROADCOM_BCM5752);
+		return(BUS_PROBE_DEFAULT);
  	}

  	if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_xxBROADCOM &&
  	    MII_MODEL(ma->mii_id2) == MII_MODEL_xxBROADCOM_BCM5701) {
  		device_set_desc(dev, MII_STR_xxBROADCOM_BCM5701);
-		return(0);
+		return(BUS_PROBE_DEFAULT);
  	}

  	if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_xxBROADCOM &&
  	    MII_MODEL(ma->mii_id2) == MII_MODEL_xxBROADCOM_BCM5703) {
  		device_set_desc(dev, MII_STR_xxBROADCOM_BCM5703);
-		return(0);
+		return(BUS_PROBE_DEFAULT);
  	}

  	if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_xxBROADCOM &&
  	    MII_MODEL(ma->mii_id2) == MII_MODEL_xxBROADCOM_BCM5704) {
  		device_set_desc(dev, MII_STR_xxBROADCOM_BCM5704);
-		return(0);
+		return(BUS_PROBE_DEFAULT);
  	}

  	if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_xxBROADCOM &&
  	    MII_MODEL(ma->mii_id2) == MII_MODEL_xxBROADCOM_BCM5705) {
  		device_set_desc(dev, MII_STR_xxBROADCOM_BCM5705);
-		return(0);
+		return(BUS_PROBE_DEFAULT);
  	}

  	if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_xxBROADCOM &&
  	    MII_MODEL(ma->mii_id2) == MII_MODEL_xxBROADCOM_BCM5750) {
  		device_set_desc(dev, MII_STR_xxBROADCOM_BCM5750);
-		return(0);
+		return(BUS_PROBE_DEFAULT);
  	}

  	if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_xxBROADCOM &&
  	    MII_MODEL(ma->mii_id2) == MII_MODEL_xxBROADCOM_BCM5714) {
  		device_set_desc(dev, MII_STR_xxBROADCOM_BCM5714);
-		return(0);
+		return(BUS_PROBE_DEFAULT);
  	}

  	if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_xxBROADCOM &&
  	    MII_MODEL(ma->mii_id2) == MII_MODEL_xxBROADCOM_BCM5780) {
  		device_set_desc(dev, MII_STR_xxBROADCOM_BCM5780);
-		return (0);
+		return (BUS_PROBE_DEFAULT);
  	}

  	if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_xxBROADCOM &&
  	    MII_MODEL(ma->mii_id2) == MII_MODEL_xxBROADCOM_BCM5706C) {
  		device_set_desc(dev, MII_STR_xxBROADCOM_BCM5706C);
-		return(0);
+		return(BUS_PROBE_DEFAULT);
  	}

  	if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_xxBROADCOM &&
  	    MII_MODEL(ma->mii_id2) == MII_MODEL_xxBROADCOM_BCM5708C) {
  		device_set_desc(dev, MII_STR_xxBROADCOM_BCM5708C);
-		return(0);
+		return(BUS_PROBE_DEFAULT);
+	}
+
+	if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_xxBROADCOM_ALT1 &&
+	    MII_MODEL(ma->mii_id2) == MII_MODEL_xxBROADCOM_BCM5754) {
+		device_set_desc(dev, MII_STR_xxBROADCOM_BCM5754);
+		return(BUS_PROBE_DEFAULT);
  	}

  	return(ENXIO);
@@ -665,6 +677,7 @@
  		bcm5704_load_dspcode(sc);
  		break;
  	case MII_MODEL_xxBROADCOM_BCM5750:
+	case MII_MODEL_xxBROADCOM_BCM5752:
  	case MII_MODEL_xxBROADCOM_BCM5714:
  	case MII_MODEL_xxBROADCOM_BCM5780:
  	case MII_MODEL_xxBROADCOM_BCM5706C:
@@ -701,7 +714,7 @@
  		PHY_WRITE(sc, BRGPHY_MII_AUXCTL, val | (1 << 15) | (1 << 4));

  		/* Enable Link LED on Dell boxes */
-		if (bge_sc->bge_no_3_led) {
+		if (bge_sc->bge_flags & BGE_FLAG_NO3LED) {
  			PHY_WRITE(sc, BRGPHY_MII_PHY_EXTCTL,
  		    	PHY_READ(sc, BRGPHY_MII_PHY_EXTCTL)
  			    & ~BRGPHY_PHY_EXTCTL_3_LED);
Index: miidevs
===================================================================
RCS file: /usr1/ncvs/src/sys/dev/mii/miidevs,v
retrieving revision 1.30.2.1.2.1
diff -u -r1.30.2.1.2.1 miidevs
--- miidevs	12 Apr 2006 18:09:28 -0000	1.30.2.1.2.1
+++ miidevs	14 Dec 2006 17:39:05 -0000
@@ -1,4 +1,4 @@
-$FreeBSD: src/sys/dev/mii/miidevs,v 1.30.2.1.2.1 2006/04/12 18:09:28  
ps Exp $
+$FreeBSD: src/sys/dev/mii/miidevs,v 1.30.2.4 2006/10/21 00:25:38  
yongari Exp $
  /*$NetBSD: miidevs,v 1.6 1999/05/14 11:37:30 drochner Exp $*/

  /*-
@@ -54,6 +54,7 @@
  oui BROADCOM			0x001018	Broadcom Corporation
  oui CICADA			0x0003F1	Cicada Semiconductor
  oui DAVICOM			0x00606e	Davicom Semiconductor
+oui ICPLUS			0x0090c3	IC Plus Corp.
  oui ICS				0x00a0be	Integrated Circuit Systems
  oui INTEL			0x00aa00	Intel
  oui JATO			0x00e083	Jato Technologies
@@ -79,6 +80,7 @@
  	(ie, ordered as on the wire) */
  oui xxALTIMA			0x000895	Altima Communications
  oui xxBROADCOM			0x000818	Broadcom Corporation
+oui xxBROADCOM_ALT1		0x0050ef	Broadcom Corporation
  oui xxICS			0x00057d	Integrated Circuit Systems
  oui xxSEEQ			0x0005be	Seeq
  oui xxSIS			0x000760	Silicon Integrated Systems
@@ -117,6 +119,8 @@
  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
+model xxBROADCOM BCM5754	0x000e BCM5754 10/100/1000baseTX PHY
+model xxBROADCOM BCM5752	0x0010 BCM5752 10/100/1000baseTX PHY
  model xxBROADCOM BCM5701	0x0011 BCM5701 10/100/1000baseTX PHY
  model xxBROADCOM BCM5703	0x0016 BCM5703 10/100/1000baseTX PHY
  model xxBROADCOM BCM5704	0x0019 BCM5704 10/100/1000baseTX PHY
@@ -138,6 +142,9 @@
  /* Integrated Circuit Systems PHYs */
  model xxICS 1890		0x0002 ICS1890 10/100 media interface

+/* IC Plus Corp. PHYs */
+model ICPLUS IP1000A		0x0008 IC Plus 10/100/1000 media interface
+
  /* Intel PHYs */
  model xxINTEL I82553AB		0x0000 i83553 10/100 media interface
  model INTEL I82555		0x0015 i82555 10/100 media interface




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?C04F8CB2-2FF8-44F2-95BA-65B75FC3DB28>