Index: build/jam/HaikuImage
===================================================================
--- build/jam/HaikuImage	(wersja 28342)
+++ build/jam/HaikuImage	(kopia robocza)
@@ -136,7 +136,7 @@
 	$(X86_ONLY)via_rhine wb840 $(X86_ONLY)ipro100 $(X86_ONLY)nforce
 	#vlance
 	$(X86_ONLY)marvell_yukon $(X86_ONLY)syskonnect usb_ecm
-	$(GPL_ONLY)bcm440x $(GPL_ONLY)bcm570x
+	$(GPL_ONLY)bcm440x $(GPL_ONLY)bcm570x broadcom_bcm570x
 ;
 #BEOS_ADD_ONS_DRIVERS_ACPI = $(X86_ONLY)acpi_button ;
 BEOS_ADD_ONS_BUS_MANAGERS = pci $(X86_ONLY)ps2 $(X86_ONLY)isa ide scsi
Index: src/add-ons/kernel/drivers/network/broadcom_bcm570x/dev/bge/if_bgereg.h
===================================================================
--- src/add-ons/kernel/drivers/network/broadcom_bcm570x/dev/bge/if_bgereg.h	(wersja 28342)
+++ src/add-ons/kernel/drivers/network/broadcom_bcm570x/dev/bge/if_bgereg.h	(kopia robocza)
@@ -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.73 2007/05/22 19:22:58 jkim Exp $
+ * $FreeBSD: src/sys/dev/bge/if_bgereg.h,v 1.73.2.4 2008/06/27 03:24:54 jhb Exp $
  */
 
 /*
@@ -277,12 +277,15 @@
 #define	BGE_CHIPID_BCM5755_A0		0xa0000000
 #define	BGE_CHIPID_BCM5755_A1		0xa0010000
 #define	BGE_CHIPID_BCM5755_A2		0xa0020000
+#define BGE_CHIPID_BCM5722_A0           0xa2000000
 #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
+#define BGE_CHIPID_BCM5906_A1           0xc0010000
+#define BGE_CHIPID_BCM5906_A2           0xc0020000
 
 /* shorthand one */
 #define	BGE_ASICREV(x)			((x) >> 28)
@@ -299,6 +302,7 @@
 #define	BGE_ASICREV_BCM5755		0x0a
 #define	BGE_ASICREV_BCM5754		0x0b
 #define	BGE_ASICREV_BCM5787		0x0b
+#define BGE_ASICREV_BCM5906             0x0c
 
 /* chip revisions */
 #define	BGE_CHIPREV(x)			((x) >> 24)
@@ -1438,7 +1442,18 @@
 #define	BGE_RXCPUSTAT_MA_REQ_FIFOOFLOW	0x40000000
 #define	BGE_RXCPUSTAT_BLOCKING_READ	0x80000000
 
+/*
+ * V? CPU registers
+ */
+#define BGE_VCPU_STATUS                 0x5100
+#define BGE_VCPU_EXT_CTRL               0x6890
 
+#define BGE_VCPU_STATUS_INIT_DONE       0x04000000
+#define BGE_VCPU_STATUS_DRV_RESET       0x08000000
+
+#define BGE_VCPU_EXT_CTRL_HALT_CPU      0x00400000
+#define BGE_VCPU_EXT_CTRL_DISABLE_WOL   0x20000000
+
 /*
  * TX CPU registers
  */
@@ -1684,6 +1699,56 @@
 #define	BGE_EE_DELAY			0x6848
 #define	BGE_FASTBOOT_PC			0x6894
 
+/*
+ * NVRAM Control registers
+ */
+#define BGE_NVRAM_CMD                   0x7000
+#define BGE_NVRAM_STAT                  0x7004
+#define BGE_NVRAM_WRDATA                0x7008
+#define BGE_NVRAM_ADDR                  0x700c
+#define BGE_NVRAM_RDDATA                0x7010
+#define BGE_NVRAM_CFG1                  0x7014
+#define BGE_NVRAM_CFG2                  0x7018
+#define BGE_NVRAM_CFG3                  0x701c
+#define BGE_NVRAM_SWARB                 0x7020
+#define BGE_NVRAM_ACCESS                0x7024
+#define BGE_NVRAM_WRITE1                0x7028
+
+#define BGE_NVRAMCMD_RESET              0x00000001
+#define BGE_NVRAMCMD_DONE               0x00000008
+#define BGE_NVRAMCMD_START              0x00000010
+#define BGE_NVRAMCMD_WR                 0x00000020 /* 1 = wr, 0 = rd */
+#define BGE_NVRAMCMD_ERASE              0x00000040
+#define BGE_NVRAMCMD_FIRST              0x00000080
+#define BGE_NVRAMCMD_LAST               0x00000100
+
+#define BGE_NVRAM_READCMD \
+        (BGE_NVRAMCMD_FIRST|BGE_NVRAMCMD_LAST| \
+        BGE_NVRAMCMD_START|BGE_NVRAMCMD_DONE)
+#define BGE_NVRAM_WRITECMD \
+        (BGE_NVRAMCMD_FIRST|BGE_NVRAMCMD_LAST| \
+        BGE_NVRAMCMD_START|BGE_NVRAMCMD_DONE|BGE_NVRAMCMD_WR)
+
+#define BGE_NVRAMSWARB_SET0             0x00000001
+#define BGE_NVRAMSWARB_SET1             0x00000002
+#define BGE_NVRAMSWARB_SET2             0x00000003
+#define BGE_NVRAMSWARB_SET3             0x00000004
+#define BGE_NVRAMSWARB_CLR0             0x00000010
+#define BGE_NVRAMSWARB_CLR1             0x00000020
+#define BGE_NVRAMSWARB_CLR2             0x00000040
+#define BGE_NVRAMSWARB_CLR3             0x00000080
+#define BGE_NVRAMSWARB_GNT0             0x00000100
+#define BGE_NVRAMSWARB_GNT1             0x00000200
+#define BGE_NVRAMSWARB_GNT2             0x00000400
+#define BGE_NVRAMSWARB_GNT3             0x00000800
+#define BGE_NVRAMSWARB_REQ0             0x00001000
+#define BGE_NVRAMSWARB_REQ1             0x00002000
+#define BGE_NVRAMSWARB_REQ2             0x00004000
+#define BGE_NVRAMSWARB_REQ3             0x00008000
+
+#define BGE_NVRAMACC_ENABLE             0x00000001
+#define BGE_NVRAMACC_WRENABLE           0x00000002
+
 /* Mode control register */
 #define	BGE_MODECTL_INT_SNDCOAL_ONLY	0x00000001
 #define	BGE_MODECTL_BYTESWAP_NONFRAME	0x00000002
@@ -1711,6 +1776,10 @@
 /* Misc. config register */
 #define	BGE_MISCCFG_RESET_CORE_CLOCKS	0x00000001
 #define	BGE_MISCCFG_TIMER_PRESCALER	0x000000FE
+#define BGE_MISCCFG_BOARD_ID            0x0001E000
+#define BGE_MISCCFG_BOARD_ID_5788       0x00010000
+#define BGE_MISCCFG_BOARD_ID_5788M      0x00018000
+#define BGE_MISCCFG_EPHY_IDDQ           0x00200000
 
 #define	BGE_32BITTIME_66MHZ		(0x41 << 1)
 
@@ -2011,6 +2080,7 @@
 #define	BCOM_DEVICEID_BCM5715S		0x1679
 #define	BCOM_DEVICEID_BCM5720		0x1658
 #define	BCOM_DEVICEID_BCM5721		0x1659
+#define BCOM_DEVICEID_BCM5722           0x165A
 #define	BCOM_DEVICEID_BCM5750		0x1676
 #define	BCOM_DEVICEID_BCM5750M		0x167C
 #define	BCOM_DEVICEID_BCM5751		0x1677
@@ -2037,6 +2107,8 @@
 #define	BCOM_DEVICEID_BCM5901		0x170D
 #define	BCOM_DEVICEID_BCM5901A2		0x170E
 #define	BCOM_DEVICEID_BCM5903M		0x16FF
+#define BCOM_DEVICEID_BCM5906           0x1712
+#define BCOM_DEVICEID_BCM5906M          0x1713
 
 /*
  * Alteon AceNIC PCI vendor/device ID.
@@ -2090,6 +2162,7 @@
  * Offset of MAC address inside EEPROM.
  */
 #define	BGE_EE_MAC_OFFSET		0x7C
+#define BGE_EE_MAC_OFFSET_5906          0x10
 #define	BGE_EE_HWCFG_OFFSET		0xC8
 
 #define	BGE_HWCFG_VOLTAGE		0x00000003
@@ -2458,7 +2531,8 @@
 	uint32_t		bge_flags;
 #define	BGE_FLAG_TBI		0x00000001
 #define	BGE_FLAG_JUMBO		0x00000002
-#define	BGE_FLAG_EEPROM		0x00000004
+#define BGE_FLAG_WIRESPEED      0x00000004
+#define BGE_FLAG_EADDR          0x00000008
 #define	BGE_FLAG_MSI		0x00000100
 #define	BGE_FLAG_PCIX		0x00000200
 #define	BGE_FLAG_PCIE		0x00000400
@@ -2474,6 +2548,7 @@
 #define	BGE_FLAG_BER_BUG	0x02000000
 #define	BGE_FLAG_ADJUST_TRIM	0x04000000
 #define	BGE_FLAG_CRC_BUG	0x08000000
+#define BGE_FLAG_5788           0x20000000
 	uint32_t		bge_chipid;
 	uint8_t			bge_asicrev;
 	uint8_t			bge_chiprev;
@@ -2506,6 +2581,8 @@
 #ifdef DEVICE_POLLING
 	int			rxcycles;
 #endif /* DEVICE_POLLING */
+	u_int32_t	bge_intr_status;
+	int			transmitting;
 };
 
 #define	BGE_LOCK_INIT(_sc, _name) \
@@ -2514,3 +2591,4 @@
 #define	BGE_LOCK_ASSERT(_sc)	mtx_assert(&(_sc)->bge_mtx, MA_OWNED)
 #define	BGE_UNLOCK(_sc)		mtx_unlock(&(_sc)->bge_mtx)
 #define	BGE_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->bge_mtx)
+
Index: src/add-ons/kernel/drivers/network/broadcom_bcm570x/dev/bge/if_bge.c
===================================================================
--- src/add-ons/kernel/drivers/network/broadcom_bcm570x/dev/bge/if_bge.c	(wersja 28342)
+++ src/add-ons/kernel/drivers/network/broadcom_bcm570x/dev/bge/if_bge.c	(kopia robocza)
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/bge/if_bge.c,v 1.198 2007/09/30 11:05:14 marius Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/bge/if_bge.c,v 1.198.2.9 2008/06/27 03:24:54 jhb Exp $");
 
 /*
  * Broadcom BCM570x family gigabit ethernet driver for FreeBSD.
@@ -169,6 +169,7 @@
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5715S },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5720 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5721 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5722 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5750 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5750M },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5751 },
@@ -195,6 +196,8 @@
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5901 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5901A2 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5903M },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5906 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5906M },
 
 	{ SK_VENDORID,		SK_DEVICEID_ALTIMA },
 
@@ -205,7 +208,7 @@
 
 static const struct bge_vendor {
 	uint16_t	v_id;
-	const char	*v_name;
+const char	*v_name;
 } bge_vendors[] = {
 	{ ALTEON_VENDORID,	"Alteon" },
 	{ ALTIMA_VENDORID,	"Altima" },
@@ -219,7 +222,7 @@
 	
 static const struct bge_revision {
 	uint32_t	br_chipid;
-	const char	*br_name;
+const char	*br_name;
 } bge_revisions[] = {
 	{ BGE_CHIPID_BCM5700_A0,	"BCM5700 A0" },
 	{ BGE_CHIPID_BCM5700_A1,	"BCM5700 A1" },
@@ -267,10 +270,13 @@
 	{ BGE_CHIPID_BCM5755_A0,	"BCM5755 A0" },
 	{ BGE_CHIPID_BCM5755_A1,	"BCM5755 A1" },
 	{ BGE_CHIPID_BCM5755_A2,	"BCM5755 A2" },
+	{ BGE_CHIPID_BCM5722_A0,	"BCM5722 A0" },
 	/* 5754 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" },
+	{ BGE_CHIPID_BCM5906_A1,	"BCM5906 A1" },
+	{ BGE_CHIPID_BCM5906_A2,	"BCM5906 A2" },
 
 	{ 0, NULL }
 };
@@ -293,6 +299,7 @@
 	{ BGE_ASICREV_BCM5755,		"unknown BCM5755" },
 	/* 5754 and 5787 share the same ASIC ID */
 	{ BGE_ASICREV_BCM5787,		"unknown BCM5754/5787" },
+	{ BGE_ASICREV_BCM5906,		"unknown BCM5906" },
 
 	{ 0, NULL }
 };
@@ -305,6 +312,9 @@
 
 const struct bge_revision * bge_lookup_rev(uint32_t);
 const struct bge_vendor * bge_lookup_vendor(uint16_t);
+
+typedef int	(*bge_eaddr_fcn_t)(struct bge_softc *, uint8_t[]);
+
 static int bge_probe(device_t);
 static int bge_attach(device_t);
 static int bge_detach(device_t);
@@ -315,6 +325,12 @@
 static int bge_dma_alloc(device_t);
 static void bge_dma_free(struct bge_softc *);
 
+static int bge_get_eaddr_fw(struct bge_softc *sc, uint8_t ether_addr[]);
+static int bge_get_eaddr_mem(struct bge_softc *, uint8_t[]);
+static int bge_get_eaddr_nvram(struct bge_softc *, uint8_t[]);
+static int bge_get_eaddr_eeprom(struct bge_softc *, uint8_t[]);
+static int bge_get_eaddr(struct bge_softc *, uint8_t[]);
+
 static void bge_txeof(struct bge_softc *);
 static void bge_rxeof(struct bge_softc *);
 
@@ -337,6 +353,9 @@
 static int bge_ifmedia_upd(struct ifnet *);
 static void bge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
 
+static uint8_t bge_nvram_getbyte(struct bge_softc *, int, uint8_t *);
+static int bge_read_nvram(struct bge_softc *, caddr_t, int, int);
+
 static uint8_t bge_eeprom_getbyte(struct bge_softc *, int, uint8_t *);
 static int bge_read_eeprom(struct bge_softc *, caddr_t, int, int);
 
@@ -356,9 +375,11 @@
 static int bge_chipinit(struct bge_softc *);
 static int bge_blockinit(struct bge_softc *);
 
-static int bge_has_eeprom(struct bge_softc *);
+static int bge_has_eaddr(struct bge_softc *);
 static uint32_t bge_readmem_ind(struct bge_softc *, int);
 static void bge_writemem_ind(struct bge_softc *, int, int);
+//bge_writembx() used in glue.c
+void bge_writembx(struct bge_softc *, int, int);
 #ifdef notdef
 static uint32_t bge_readreg_ind(struct bge_softc *, int);
 #endif
@@ -378,7 +399,7 @@
 static void bge_sig_legacy(struct bge_softc *, int);
 static void bge_sig_pre_reset(struct bge_softc *, int);
 static int bge_reset(struct bge_softc *);
-static void bge_link_upd(struct bge_softc *);
+/*static*/ void bge_link_upd(struct bge_softc *);
 
 /*
  * The BGE_REGISTER_DEBUG option is only for low-level debugging.  It may
@@ -425,7 +446,7 @@
 DRIVER_MODULE(bge, pci, bge_driver, bge_devclass, 0, 0);
 DRIVER_MODULE(miibus, bge, miibus_driver, miibus_devclass, 0, 0);
 
-static int bge_allow_asf = 1;
+static int bge_allow_asf = 0;
 
 TUNABLE_INT("hw.bge.allow_asf", &bge_allow_asf);
 
@@ -440,7 +461,7 @@
 #define	SPARC64_OFW_SUBVENDOR		"subsystem-vendor-id"
 
 static int
-bge_has_eeprom(struct bge_softc *sc)
+bge_has_eaddr(struct bge_softc *sc)
 {
 #ifdef __sparc64__
 	char buf[sizeof(SPARC64_BLADE_1500_PATH_BGE)];
@@ -533,6 +554,15 @@
 	CSR_WRITE_4(sc, off, val);
 }
 
+void
+bge_writembx(struct bge_softc *sc, int off, int val)
+{
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5906)
+		off += BGE_LPMBX_IRQ0_HI - BGE_MBX_IRQ0_HI;
+
+	CSR_WRITE_4(sc, off, val);
+}
+
 /*
  * Map a single buffer address.
  */
@@ -555,7 +585,79 @@
 	ctx->bge_busaddr = segs->ds_addr;
 }
 
+static uint8_t
+bge_nvram_getbyte(struct bge_softc *sc, int addr, uint8_t *dest)
+{
+	uint32_t access, byte = 0;
+	int i;
+
+	/* Lock. */
+	CSR_WRITE_4(sc, BGE_NVRAM_SWARB, BGE_NVRAMSWARB_SET1);
+	for (i = 0; i < 8000; i++) {
+		if (CSR_READ_4(sc, BGE_NVRAM_SWARB) & BGE_NVRAMSWARB_GNT1)
+			break;
+		DELAY(20);
+	}
+	if (i == 8000)
+		return (1);
+
+	/* Enable access. */
+	access = CSR_READ_4(sc, BGE_NVRAM_ACCESS);
+	CSR_WRITE_4(sc, BGE_NVRAM_ACCESS, access | BGE_NVRAMACC_ENABLE);
+
+	CSR_WRITE_4(sc, BGE_NVRAM_ADDR, addr & 0xfffffffc);
+	CSR_WRITE_4(sc, BGE_NVRAM_CMD, BGE_NVRAM_READCMD);
+	for (i = 0; i < BGE_TIMEOUT * 10; i++) {
+		DELAY(10);
+		if (CSR_READ_4(sc, BGE_NVRAM_CMD) & BGE_NVRAMCMD_DONE) {
+			DELAY(10);
+			break;
+		}
+	}
+
+	if (i == BGE_TIMEOUT * 10) {
+		if_printf(sc->bge_ifp, "nvram read timed out\n");
+		return (1);
+	}
+
+	/* Get result. */
+	byte = CSR_READ_4(sc, BGE_NVRAM_RDDATA);
+
+	*dest = (bswap32(byte) >> ((addr % 4) * 8)) & 0xFF;
+
+	/* Disable access. */
+	CSR_WRITE_4(sc, BGE_NVRAM_ACCESS, access);
+
+	/* Unlock. */
+	CSR_WRITE_4(sc, BGE_NVRAM_SWARB, BGE_NVRAMSWARB_CLR1);
+	CSR_READ_4(sc, BGE_NVRAM_SWARB);
+
+	return (0);
+}
+
 /*
+ * Read a sequence of bytes from NVRAM.
+ */
+static int
+bge_read_nvram(struct bge_softc *sc, caddr_t dest, int off, int cnt)
+{
+	int err = 0, i;
+	uint8_t byte = 0;
+
+	if (sc->bge_asicrev != BGE_ASICREV_BCM5906)
+		return (1);
+
+	for (i = 0; i < cnt; i++) {
+		err = bge_nvram_getbyte(sc, off + i, &byte);
+		if (err)
+			break;
+		*(dest + i) = byte;
+	}
+
+	return (err ? 1 : 0);
+}
+
+/*
  * 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
@@ -659,11 +761,14 @@
 	}
 
 	if (i == BGE_TIMEOUT) {
-		device_printf(sc->bge_dev, "PHY read timed out\n");
+		device_printf(sc->bge_dev,
+		    "PHY read timed out (phy %d, reg %d, val 0x%08x)\n",
+		    phy, reg, val);
 		val = 0;
 		goto done;
 	}
 
+	DELAY(5);
 	val = CSR_READ_4(sc, BGE_MI_COMM);
 
 done:
@@ -687,6 +792,10 @@
 
 	sc = device_get_softc(dev);
 
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5906 &&
+	    (reg == BRGPHY_MII_1000CTL || reg == BRGPHY_MII_AUXCTL))
+		return(0);
+
 	/* Reading with autopolling on may trigger PCI errors */
 	autopoll = CSR_READ_4(sc, BGE_MI_MODE);
 	if (autopoll & BGE_MIMODE_AUTOPOLL) {
@@ -699,12 +808,17 @@
 
 	for (i = 0; i < BGE_TIMEOUT; i++) {
 		DELAY(10);
-		if (!(CSR_READ_4(sc, BGE_MI_COMM) & BGE_MICOMM_BUSY))
+		if (!(CSR_READ_4(sc, BGE_MI_COMM) & BGE_MICOMM_BUSY)) {
+			DELAY(5);
+			CSR_READ_4(sc, BGE_MI_COMM); /* dummy read */
 			break;
 	}
+	}
 
 	if (i == BGE_TIMEOUT) {
-		device_printf(sc->bge_dev, "PHY write timed out\n");
+		device_printf(sc->bge_dev,
+		    "PHY write timed out (phy %d, reg %d, val %d)\n",
+		    phy, reg, val);
 		return (0);
 	}
 
@@ -887,7 +1001,7 @@
 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
 	sc->bge_std = i - 1;
-	CSR_WRITE_4(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
+	bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
 
 	return (0);
 }
@@ -934,7 +1048,7 @@
 				    BGE_RCB_FLAG_USE_EXT_RX_BD);
 	CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_MAXLEN_FLAGS, rcb->bge_maxlen_flags);
 
-	CSR_WRITE_4(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo);
+	bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo);
 
 	return (0);
 }
@@ -990,17 +1104,17 @@
 
 	/* Initialize transmit producer index for host-memory send ring. */
 	sc->bge_tx_prodidx = 0;
-	CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx);
+	bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx);
 
 	/* 5700 b2 errata */
 	if (sc->bge_chiprev == BGE_CHIPREV_5700_BX)
-		CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx);
+		bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx);
 
 	/* NIC-memory send ring not used; initialize to zero. */
-	CSR_WRITE_4(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
+	bge_writembx(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
 	/* 5700 b2 errata */
 	if (sc->bge_chiprev == BGE_CHIPREV_5700_BX)
-		CSR_WRITE_4(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
+		bge_writembx(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
 
 	return (0);
 }
@@ -1168,10 +1282,10 @@
 	/*
 	 * Check the 'ROM failed' bit on the RX CPU to see if
 	 * self-tests passed. Skip this check when there's no
-	 * EEPROM fitted, since in that case it will always
-	 * fail.
+	 * chip containing the Ethernet address fitted, since
+	 * in that case it will always fail.
 	 */
-	if ((sc->bge_flags & BGE_FLAG_EEPROM) &&
+	if ((sc->bge_flags & BGE_FLAG_EADDR) &&
 	    CSR_READ_4(sc, BGE_RXCPU_MODE) & BGE_RXCPUMODE_ROMFAIL) {
 		device_printf(sc->bge_dev, "RX CPU self-diagnostics failed!\n");
 		return (ENODEV);
@@ -1271,6 +1385,16 @@
 	/* Set the timer prescaler (always 66Mhz) */
 	CSR_WRITE_4(sc, BGE_MISC_CFG, BGE_32BITTIME_66MHZ);
 
+	/* XXX: The Linux tg3 driver does this at the start of brgphy_reset. */
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5906) {
+		DELAY(40);	/* XXX */
+
+		/* Put PHY into ready state */
+		BGE_CLRBIT(sc, BGE_MISC_CFG, BGE_MISCCFG_EPHY_IDDQ);
+		CSR_READ_4(sc, BGE_MISC_CFG); /* Flush */
+		DELAY(40);
+	}
+
 	return (0);
 }
 
@@ -1308,14 +1432,19 @@
 	}
 
 	/* Configure mbuf pool watermarks */
-	if (!(BGE_IS_5705_PLUS(sc))) {
+	if (!BGE_IS_5705_PLUS(sc)) {
+		CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x50);
+		CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x20);
+		CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x60);
+	} else if (sc->bge_asicrev == BGE_ASICREV_BCM5906) {
 		CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0);
+		CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x04);
+		CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x10);
+	} else {
+		CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0);
 		CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x10);
-	} else {
-		CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x50);
-		CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x20);
+		CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x60);
 	}
-	CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x60);
 
 	/* Configure DMA resource watermarks */
 	CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_LOWAT, 5);
@@ -1421,6 +1550,9 @@
 	 * requirement of all 575x family chips.  The Linux driver sets
 	 * the lower threshold for all 5705 family chips as well, but there
 	 * are reports that it might not need to be so strict.
+	 *
+	 * XXX Linux does some extra fiddling here for the 5906 parts as
+	 * well.
 	 */
 	if (BGE_IS_5705_PLUS(sc))
 		val = 8;
@@ -1462,15 +1594,15 @@
 		    BGE_RCB_MAXLEN_FLAGS(sc->bge_return_ring_cnt,
 		    BGE_RCB_FLAG_RING_DISABLED));
 		RCB_WRITE_4(sc, vrcb, bge_nicaddr, 0);
-		CSR_WRITE_4(sc, BGE_MBX_RX_CONS0_LO +
+		bge_writembx(sc, BGE_MBX_RX_CONS0_LO +
 		    (i * (sizeof(uint64_t))), 0);
 		vrcb += sizeof(struct bge_rcb);
 	}
 
 	/* Initialize RX ring indexes */
-	CSR_WRITE_4(sc, BGE_MBX_RX_STD_PROD_LO, 0);
-	CSR_WRITE_4(sc, BGE_MBX_RX_JUMBO_PROD_LO, 0);
-	CSR_WRITE_4(sc, BGE_MBX_RX_MINI_PROD_LO, 0);
+	bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, 0);
+	bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, 0);
+	bge_writembx(sc, BGE_MBX_RX_MINI_PROD_LO, 0);
 
 	/*
 	 * Set up RX return ring 0
@@ -1679,7 +1811,7 @@
 const struct bge_revision *
 bge_lookup_rev(uint32_t chipid)
 {
-	const struct bge_revision *br;
+const struct bge_revision *br;
 
 	for (br = bge_revisions; br->br_name != NULL; br++) {
 		if (br->br_chipid == chipid)
@@ -1697,7 +1829,7 @@
 const struct bge_vendor *
 bge_lookup_vendor(uint16_t vid)
 {
-	const struct bge_vendor *v;
+const struct bge_vendor *v;
 
 	for (v = bge_vendors; v->v_name != NULL; v++)
 		if (v->v_id == vid)
@@ -1730,8 +1862,8 @@
 	while(t->bge_vid != 0) {
 		if ((vid == t->bge_vid) && (did == t->bge_did)) {
 			char model[64], buf[96];
-			const struct bge_revision *br;
-			const struct bge_vendor *v;
+const struct bge_revision *br;
+const struct bge_vendor *v;
 			uint32_t id;
 
 			id = pci_read_config(dev, BGE_PCI_MISC_CTL, 4) &
@@ -1740,7 +1872,7 @@
 			v = bge_lookup_vendor(vid);
 			{
 #if __FreeBSD_version > 700024
-				const char *pname;
+const char *pname;
 
 				if (pci_get_vpd_ident(dev, &pname) == 0)
 					snprintf(model, 64, "%s", pname);
@@ -1892,16 +2024,10 @@
 	/*
 	 * Allocate the parent bus DMA tag appropriate for PCI.
 	 */
-	error = bus_dma_tag_create(bus_get_dma_tag(sc->bge_dev), /* parent */
-			1, 0,			/* alignment, boundary */
-			BUS_SPACE_MAXADDR,	/* lowaddr */
-			BUS_SPACE_MAXADDR,	/* highaddr */
-			NULL, NULL,		/* filter, filterarg */
-			MAXBSIZE, BGE_NSEG_NEW,	/* maxsize, nsegments */
-			BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
-			0,			/* flags */
-			NULL, NULL,		/* lockfunc, lockarg */
-			&sc->bge_cdata.bge_parent_tag);
+	error = bus_dma_tag_create(bus_get_dma_tag(sc->bge_dev),
+	    1, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,	NULL,
+	    NULL, BUS_SPACE_MAXSIZE_32BIT, 0, BUS_SPACE_MAXSIZE_32BIT,
+	    0, NULL, NULL, &sc->bge_cdata.bge_parent_tag);
 
 	if (error != 0) {
 		device_printf(sc->bge_dev,
@@ -1910,7 +2036,7 @@
 	}
 
 	/*
-	 * Create tag for RX mbufs.
+	 * Create tag for mbufs.
 	 */
 	error = bus_dma_tag_create(sc->bge_cdata.bge_parent_tag, 1,
 	    0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL,
@@ -2229,13 +2355,13 @@
 {
 	struct ifnet *ifp;
 	struct bge_softc *sc;
-	uint32_t hwcfg = 0;
-	uint32_t mac_tmp = 0;
+	uint32_t hwcfg = 0, misccfg;
 	u_char eaddr[ETHER_ADDR_LEN];
 	int error, reg, rid, trys;
 
 	sc = device_get_softc(dev);
 	sc->bge_dev = dev;
+	sc->transmitting = 0;
 
 	/*
 	 * Map control/status registers.
@@ -2263,9 +2389,19 @@
 	sc->bge_asicrev = BGE_ASICREV(sc->bge_chipid);
 	sc->bge_chiprev = BGE_CHIPREV(sc->bge_chipid);
 
-	if (bge_has_eeprom(sc))
-		sc->bge_flags |= BGE_FLAG_EEPROM;
+	/*
+	 * Don't enable Ethernet@WireSpeed for the 5700, 5906, or the
+	 * 5705 A0 and A1 chips.
+	 */
+	if (sc->bge_asicrev != BGE_ASICREV_BCM5700 &&
+	    sc->bge_asicrev != BGE_ASICREV_BCM5906 &&
+	    sc->bge_chipid != BGE_CHIPID_BCM5705_A0 &&
+	    sc->bge_chipid != BGE_CHIPID_BCM5705_A1)
+		sc->bge_flags |= BGE_FLAG_WIRESPEED;
 
+	if (bge_has_eaddr(sc))
+		sc->bge_flags |= BGE_FLAG_EADDR;
+
 	/* Save chipset family. */
 	switch (sc->bge_asicrev) {
 	case BGE_ASICREV_BCM5700:
@@ -2283,6 +2419,7 @@
 	case BGE_ASICREV_BCM5752:
 	case BGE_ASICREV_BCM5755:
 	case BGE_ASICREV_BCM5787:
+	case BGE_ASICREV_BCM5906:
 		sc->bge_flags |= BGE_FLAG_575X_PLUS;
 		/* FALLTHRU */
 	case BGE_ASICREV_BCM5705:
@@ -2302,13 +2439,24 @@
 	if (BGE_IS_5705_PLUS(sc) &&
 	    !(sc->bge_flags & BGE_FLAG_ADJUST_TRIM)) {
 		if (sc->bge_asicrev == BGE_ASICREV_BCM5755 ||
-		    sc->bge_asicrev == BGE_ASICREV_BCM5787)
+		    sc->bge_asicrev == BGE_ASICREV_BCM5787) {
+			if (sc->bge_chipid != BGE_CHIPID_BCM5722_A0)
 			sc->bge_flags |= BGE_FLAG_JITTER_BUG;
-		else
+		} else if (sc->bge_asicrev != BGE_ASICREV_BCM5906)
 			sc->bge_flags |= BGE_FLAG_BER_BUG;
 	}
 
+
   	/*
+	 * We could possibly check for BCOM_DEVICEID_BCM5788 in bge_probe()
+	 * but I do not know the DEVICEID for the 5788M.
+	 */
+	misccfg = CSR_READ_4(sc, BGE_MISC_CFG) & BGE_MISCCFG_BOARD_ID;
+	if (misccfg == BGE_MISCCFG_BOARD_ID_5788 ||
+	    misccfg == BGE_MISCCFG_BOARD_ID_5788M)
+		sc->bge_flags |= BGE_FLAG_5788;
+
+  	/*
 	 * Check if this is a PCI-X or PCI Express device.
   	 */
 #if __FreeBSD_version > 602101
@@ -2414,29 +2562,13 @@
 		goto fail;
 	}
 
-#ifdef __sparc64__
-	if ((sc->bge_flags & BGE_FLAG_EEPROM) == 0)
-		OF_getetheraddr(dev, eaddr);
-	else
-#endif
-	{
-		mac_tmp = bge_readmem_ind(sc, 0x0C14);
-		if ((mac_tmp >> 16) == 0x484B) {
-			eaddr[0] = (u_char)(mac_tmp >> 8);
-			eaddr[1] = (u_char)mac_tmp;
-			mac_tmp = bge_readmem_ind(sc, 0x0C18);
-			eaddr[2] = (u_char)(mac_tmp >> 24);
-			eaddr[3] = (u_char)(mac_tmp >> 16);
-			eaddr[4] = (u_char)(mac_tmp >> 8);
-			eaddr[5] = (u_char)mac_tmp;
-		} else if (bge_read_eeprom(sc, eaddr,
-		    BGE_EE_MAC_OFFSET + 2, ETHER_ADDR_LEN)) {
+	error = bge_get_eaddr(sc, eaddr);
+	if (error) {
 			device_printf(sc->bge_dev,
 			    "failed to read station address\n");
 			error = ENXIO;
 			goto fail;
 		}
-	}
 
 	/* 5705 limits RX return ring to 512 entries. */
 	if (BGE_IS_5705_PLUS(sc))
@@ -2507,7 +2639,8 @@
 	 */
 	if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_SIG) == BGE_MAGIC_NUMBER)
 		hwcfg = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_NICCFG);
-	else if (sc->bge_flags & BGE_FLAG_EEPROM) {
+	else if ((sc->bge_flags & BGE_FLAG_EADDR) &&
+	    (sc->bge_asicrev != BGE_ASICREV_BCM5906)) {
 		if (bge_read_eeprom(sc, (caddr_t)&hwcfg, BGE_EE_HWCFG_OFFSET,
 		    sizeof(hwcfg))) {
 			device_printf(sc->bge_dev, "failed to read EEPROM\n");
@@ -2682,13 +2815,14 @@
 bge_reset(struct bge_softc *sc)
 {
 	device_t dev;
-	uint32_t cachesize, command, pcistate, reset;
+	uint32_t cachesize, command, pcistate, reset, val;
 	void (*write_op)(struct bge_softc *, int, int);
-	int i, val = 0;
+	int i;
 
 	dev = sc->bge_dev;
 
-	if (BGE_IS_575X_PLUS(sc) && !BGE_IS_5714_FAMILY(sc)) {
+	if (BGE_IS_575X_PLUS(sc) && !BGE_IS_5714_FAMILY(sc) &&
+	    (sc->bge_asicrev != BGE_ASICREV_BCM5906)) {
 		if (sc->bge_flags & BGE_FLAG_PCIE)
 			write_op = bge_writemem_direct;
 		else
@@ -2744,16 +2878,23 @@
 	/* Issue global reset */
 	write_op(sc, BGE_MISC_CFG, reset);
 
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5906) {
+		val = CSR_READ_4(sc, BGE_VCPU_STATUS);
+		CSR_WRITE_4(sc, BGE_VCPU_STATUS,
+		    val | BGE_VCPU_STATUS_DRV_RESET);
+		val = CSR_READ_4(sc, BGE_VCPU_EXT_CTRL);
+		CSR_WRITE_4(sc, BGE_VCPU_EXT_CTRL,
+		    val & ~BGE_VCPU_EXT_CTRL_HALT_CPU);
+	}
+
 	DELAY(1000);
 
 	/* XXX: Broadcom Linux driver. */
 	if (sc->bge_flags & BGE_FLAG_PCIE) {
 		if (sc->bge_chipid == BGE_CHIPID_BCM5750_A0) {
-			uint32_t v;
-
 			DELAY(500000); /* wait for link training to complete */
-			v = pci_read_config(dev, 0xC4, 4);
-			pci_write_config(dev, 0xC4, v | (1 << 15), 4);
+			val = pci_read_config(dev, 0xC4, 4);
+			pci_write_config(dev, 0xC4, val | (1 << 15), 4);
 		}
 		/*
 		 * Set PCIE max payload size to 128 bytes and clear error
@@ -2772,8 +2913,6 @@
 
 	/* Re-enable MSI, if neccesary, and enable the memory arbiter. */
 	if (BGE_IS_5714_FAMILY(sc)) {
-		uint32_t val;
-
 		/* This chip disables MSI on reset. */
 		if (sc->bge_flags & BGE_FLAG_MSI) {
 			val = pci_read_config(dev, BGE_PCI_MSI_CTL, 2);
@@ -2788,10 +2927,23 @@
 	} else
 		CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE);
 
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5906) {
+		for (i = 0; i < BGE_TIMEOUT; i++) {
+			val = CSR_READ_4(sc, BGE_VCPU_STATUS);
+			if (val & BGE_VCPU_STATUS_INIT_DONE)
+				break;
+			DELAY(100);
+		}
+		if (i == BGE_TIMEOUT) {
+			device_printf(sc->bge_dev, "reset timed out\n");
+			return (1);
+		}
+	} else {
 	/*
 	 * Poll until we see the 1's complement of the magic number.
 	 * This indicates that the firmware initialization is complete.
-	 * We expect this to fail if no EEPROM is fitted though.
+		 * We expect this to fail if no chip containing the Ethernet
+		 * address is fitted though.
 	 */
 	for (i = 0; i < BGE_TIMEOUT; i++) {
 		DELAY(10);
@@ -2800,9 +2952,10 @@
 			break;
 	}
 
-	if ((sc->bge_flags & BGE_FLAG_EEPROM) && i == BGE_TIMEOUT)
+		if ((sc->bge_flags & BGE_FLAG_EADDR) && i == BGE_TIMEOUT)
 		device_printf(sc->bge_dev, "firmware handshake timed out, "
 		    "found 0x%08x\n", val);
+	}
 
 	/*
 	 * XXX Wait for the value of the PCISTATE register to
@@ -2840,20 +2993,16 @@
 	 */
 	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;
-		CSR_WRITE_4(sc, BGE_SERDES_CFG, serdescfg);
+		val = CSR_READ_4(sc, BGE_SERDES_CFG);
+		val = (val & ~0xFFF) | 0x880;
+		CSR_WRITE_4(sc, BGE_SERDES_CFG, val);
 	}
 
 	/* XXX: Broadcom Linux driver. */
 	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));
+		val = CSR_READ_4(sc, 0x7C00);
+		CSR_WRITE_4(sc, 0x7C00, val | (1 << 25));
 	}
 	DELAY(10000);
 
@@ -3022,11 +3171,11 @@
 		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);
+	bge_writembx(sc, BGE_MBX_RX_CONS0_LO, sc->bge_rx_saved_considx);
 	if (stdcnt)
-		CSR_WRITE_4(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
+		bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
 	if (jumbocnt)
-		CSR_WRITE_4(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo);
+		bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo);
 #ifdef notyet
 	/*
 	 * This register wraps very quickly under heavy packet drops.
@@ -3168,12 +3317,20 @@
 	 * the status check).  So toggling would probably be a pessimization
 	 * even with MSI.  It would only be needed for using a task queue.
 	 */
-	CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0);
+#ifndef __HAIKU__
+	bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);
+#endif
 
 	/*
 	 * Do the mandatory PCI flush as well as get the link status.
 	 */
-	statusword = CSR_READ_4(sc, BGE_MAC_STS) & BGE_MACSTAT_LINK_CHANGED;
+#ifndef __HAIKU__ 
+        statusword = CSR_READ_4(sc, BGE_MAC_STS) & BGE_MACSTAT_LINK_CHANGED; 
+#else 
+        /* Get the statusword as saved in __haiku_disable_interrupts 
+         * and clear the saved value */ 
+        statusword = atomic_and((int32 *)&sc->bge_intr_status, 0) & BGE_MACSTAT_LINK_CHANGED; 
+#endif 
 
 	/* Make sure the descriptor ring indexes are coherent. */
 	bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
@@ -3181,10 +3338,13 @@
 	bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
 	    sc->bge_cdata.bge_status_map, BUS_DMASYNC_PREREAD);
 
-	if ((sc->bge_asicrev == BGE_ASICREV_BCM5700 &&
-	    sc->bge_chipid != BGE_CHIPID_BCM5700_B2) ||
-	    statusword || sc->bge_link_evt)
-		bge_link_upd(sc);
+        /* TODO: bge_link_upd is probably not correct with interrupt changes 
+         * May need to also use the saved statusword... */ 
+//QQQ
+	//if ((sc->bge_asicrev == BGE_ASICREV_BCM5700 &&
+	//    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. */
@@ -3255,7 +3415,11 @@
 #endif
 		{
 		sc->bge_link_evt++;
+		if (sc->bge_asicrev == BGE_ASICREV_BCM5700 ||
+		    sc->bge_flags & BGE_FLAG_5788)
 		BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_INTR_SET);
+		else
+			BGE_SETBIT(sc, BGE_HCC_MODE, BGE_HCCMODE_COAL_NOW);
 		}
 	}
 
@@ -3390,7 +3554,8 @@
 	error = bus_dmamap_load_mbuf_sg(sc->bge_cdata.bge_mtag, map, m, segs,
 	    &nsegs, BUS_DMA_NOWAIT);
 	if (error == EFBIG) {
-		m = m_defrag(m, M_DONTWAIT);
+		//m = m_collapse(m, M_DONTWAIT, BGE_NSEG_NEW);
+		panic("m_collapse not implemented");
 		if (m == NULL) {
 			m_freem(*m_head);
 			*m_head = NULL;
@@ -3482,7 +3647,8 @@
 
 	sc = ifp->if_softc;
 
-	if (!sc->bge_link || IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+	//if (!sc->bge_link || IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+	if (IFQ_DRV_IS_EMPTY(&ifp->if_snd))
 		return;
 
 	prodidx = sc->bge_tx_prodidx;
@@ -3544,11 +3710,12 @@
 		/* No packets were dequeued. */
 		return;
 
+	sc -> transmitting = 1;
 	/* Transmit. */
-	CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
+	bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
 	/* 5700 b2 errata */
 	if (sc->bge_chiprev == BGE_CHIPREV_5700_BX)
-		CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
+		bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
 
 	sc->bge_tx_prodidx = prodidx;
 
@@ -3675,15 +3842,16 @@
 	if (ifp->if_capenable & IFCAP_POLLING) {
 		BGE_SETBIT(sc, BGE_PCI_MISC_CTL,
 		    BGE_PCIMISCCTL_MASK_PCI_INTR);
-		CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 1);
+		bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);
 	} else
 #endif
 
 	/* Enable host interrupts. */
+//QQQ
 	{
 	BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_CLEAR_INTA);
 	BGE_CLRBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
-	CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0);
+	bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);
 	}
 	
 	bge_ifmedia_upd_locked(ifp);
@@ -3783,6 +3951,24 @@
 	}
 	mii_mediachg(mii);
 
+	/*
+	 * Force an interrupt so that we will call bge_link_upd
+	 * if needed and clear any pending link state attention.
+	 * Without this we are not getting any further interrupts
+	 * for link state changes and thus will not UP the link and
+	 * not be able to send in bge_start_locked. The only
+	 * way to get things working was to receive a packet and
+	 * get an RX intr.
+	 * bge_tick should help for fiber cards and we might not
+	 * need to do this here if BGE_FLAG_TBI is set but as
+	 * we poll for fiber anyway it should not harm.
+	 */
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5700 ||
+	    sc->bge_flags & BGE_FLAG_5788)
+		BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_INTR_SET);
+	else
+		BGE_SETBIT(sc, BGE_HCC_MODE, BGE_HCCMODE_COAL_NOW);
+
 	return (0);
 }
 
@@ -3906,7 +4092,7 @@
 				BGE_LOCK(sc);
 				BGE_SETBIT(sc, BGE_PCI_MISC_CTL,
 				    BGE_PCIMISCCTL_MASK_PCI_INTR);
-				CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 1);
+				bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);
 				ifp->if_capenable |= IFCAP_POLLING;
 				BGE_UNLOCK(sc);
 			} else {
@@ -3915,7 +4101,7 @@
 				BGE_LOCK(sc);
 				BGE_CLRBIT(sc, BGE_PCI_MISC_CTL,
 				    BGE_PCIMISCCTL_MASK_PCI_INTR);
-				CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0);
+				bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);
 				ifp->if_capenable &= ~IFCAP_POLLING;
 				BGE_UNLOCK(sc);
 			}
@@ -4040,7 +4226,7 @@
 
 	/* Disable host interrupts. */
 	BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
-	CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 1);
+	bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);
 
 	/*
 	 * Tell firmware we're shutting down.
@@ -4083,6 +4269,11 @@
 		 */
 		if (mii != NULL) {
 			ifm = mii->mii_media.ifm_cur;
+			if (ifm == NULL)
+			{
+				panic("bge_stop: ifm == NULL");
+				return ;
+			}
 			mtmp = ifm->ifm_media;
 			ifm->ifm_media = IFM_ETHER | IFM_NONE;
 			mii_mediachg(mii);
@@ -4150,12 +4341,13 @@
 	return (0);
 }
 
-static void
+/*static*/ void
 bge_link_upd(struct bge_softc *sc)
 {
 	struct mii_data *mii;
 	uint32_t link, status;
 
+
 	BGE_LOCK_ASSERT(sc);
 
 	/* Clear 'pending link event' flag. */
@@ -4232,15 +4424,19 @@
 		 * in status word always set. Workaround this bug by reading
 		 * PHY link status directly.
 		 */
+#define lnDbg do {printf("%s: %s: %d\n", __FILE__,__func__, __LINE__); } while(0)
+		lnDbg;
 		link = (CSR_READ_4(sc, BGE_MI_STS) & BGE_MISTS_LINK) ? 1 : 0;
 
 		if (link != sc->bge_link ||
 		    sc->bge_asicrev == BGE_ASICREV_BCM5700) {
+		lnDbg;
 			mii = device_get_softc(sc->bge_miibus);
 			mii_pollstat(mii);
 			if (!sc->bge_link &&
 			    mii->mii_media_status & IFM_ACTIVE &&
 			    IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
+		lnDbg;
 				sc->bge_link++;
 				if (bootverbose)
 					if_printf(sc->bge_ifp, "link UP\n");
@@ -4263,6 +4459,8 @@
 	CSR_WRITE_4(sc, BGE_MAC_STS, BGE_MACSTAT_SYNC_CHANGED |
 	    BGE_MACSTAT_CFG_CHANGED | BGE_MACSTAT_MI_COMPLETE |
 	    BGE_MACSTAT_LINK_CHANGED);
+
+	dprintf("bge_link_upd, sc->bge_link=0x%x\n", sc->bge_link);
 }
 
 #define BGE_SYSCTL_STAT(sc, ctx, desc, parent, node, oid) \
@@ -4295,6 +4493,9 @@
 
 #endif
 
+	if (BGE_IS_5705_PLUS(sc))
+		return;
+
 	tree = SYSCTL_ADD_NODE(ctx, children, OID_AUTO, "stats", CTLFLAG_RD,
 	    NULL, "BGE Statistics");
 	schildren = children = SYSCTL_CHILDREN(tree);
@@ -4417,16 +4618,12 @@
 {
 	struct bge_softc *sc;
 	uint32_t result;
-	int base, offset;
+	int offset;
 
 	sc = (struct bge_softc *)arg1;
 	offset = arg2;
-	if (BGE_IS_5705_PLUS(sc))
-		base = BGE_MAC_STATS;
-	else
-		base = BGE_MEMWIN_START + BGE_STATS_BLOCK;
-	result = CSR_READ_4(sc, base + offset + offsetof(bge_hostaddr,
-	    bge_addr_lo));
+	result = CSR_READ_4(sc, BGE_MEMWIN_START + BGE_STATS_BLOCK + offset +
+	    offsetof(bge_hostaddr, bge_addr_lo));
 	return (sysctl_handle_int(oidp, &result, 0, req));
 }
 
@@ -4537,3 +4734,79 @@
 	return (error);
 }
 #endif
+
+static int
+bge_get_eaddr_fw(struct bge_softc *sc, uint8_t ether_addr[])
+{
+
+	if (sc->bge_flags & BGE_FLAG_EADDR)
+		return (1);
+
+#ifdef __sparc64__
+	OF_getetheraddr(sc->bge_dev, ether_addr);
+	return (0);
+#endif
+	return (1);
+}
+
+static int
+bge_get_eaddr_mem(struct bge_softc *sc, uint8_t ether_addr[])
+{
+	uint32_t mac_addr;
+
+	mac_addr = bge_readmem_ind(sc, 0x0c14);
+	if ((mac_addr >> 16) == 0x484b) {
+		ether_addr[0] = (uint8_t)(mac_addr >> 8);
+		ether_addr[1] = (uint8_t)mac_addr;
+		mac_addr = bge_readmem_ind(sc, 0x0c18);
+		ether_addr[2] = (uint8_t)(mac_addr >> 24);
+		ether_addr[3] = (uint8_t)(mac_addr >> 16);
+		ether_addr[4] = (uint8_t)(mac_addr >> 8);
+		ether_addr[5] = (uint8_t)mac_addr;
+		return (0);
+	}
+	return (1);
+}
+
+static int
+bge_get_eaddr_nvram(struct bge_softc *sc, uint8_t ether_addr[])
+{
+	int mac_offset = BGE_EE_MAC_OFFSET;
+
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5906)
+		mac_offset = BGE_EE_MAC_OFFSET_5906;
+
+	return (bge_read_nvram(sc, ether_addr, mac_offset + 2,
+	    ETHER_ADDR_LEN));
+}
+
+static int
+bge_get_eaddr_eeprom(struct bge_softc *sc, uint8_t ether_addr[])
+{
+
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5906)
+		return (1);
+
+	return (bge_read_eeprom(sc, ether_addr, BGE_EE_MAC_OFFSET + 2,
+	   ETHER_ADDR_LEN));
+}
+
+static int
+bge_get_eaddr(struct bge_softc *sc, uint8_t eaddr[])
+{
+static const bge_eaddr_fcn_t bge_eaddr_funcs[] = {
+		/* NOTE: Order is critical */
+		bge_get_eaddr_fw,
+		bge_get_eaddr_mem,
+		bge_get_eaddr_nvram,
+		bge_get_eaddr_eeprom,
+		NULL
+	};
+const bge_eaddr_fcn_t *func;
+
+	for (func = bge_eaddr_funcs; *func != NULL; ++func) {
+		if ((*func)(sc, eaddr) == 0)
+			break;
+	}
+	return (*func == NULL ? ENXIO : 0);
+}
Index: src/add-ons/kernel/drivers/network/broadcom_bcm570x/dev/bge/glue.c
===================================================================
--- src/add-ons/kernel/drivers/network/broadcom_bcm570x/dev/bge/glue.c	(wersja 28342)
+++ src/add-ons/kernel/drivers/network/broadcom_bcm570x/dev/bge/glue.c	(kopia robocza)
@@ -5,6 +5,7 @@
 
 
 #include <sys/bus.h>
+#include "if_bgereg.h"
 
 
 HAIKU_FBSD_DRIVER_GLUE(broadcom_bcm570x, bge, pci);
@@ -25,3 +26,41 @@
 	return __haiku_probe_miibus(dev, drivers);
 }
 
+int 
+__haiku_disable_interrupts(device_t dev) 
+{ 
+        struct bge_softc *sc = device_get_softc(dev); 
+ 
+        // Obtain the status and return 0 if the bge did not set the intr 
+        u_int32_t status = CSR_READ_4(sc, BGE_MAC_STS); 
+	// status & 0x1000 for media change, sc->transmitting if sending a packet
+	// use BGE_PCI_PCISTATE to check interrupt source like in the Linux driver
+	if ( ((status & 0x1000)==0)&&(sc->transmitting==0) && ((pci_read_config(sc->bge_dev, BGE_PCI_PCISTATE,4) & BGE_PCISTATE_INTR_STATE) != 0)) {
+                return 0; 
+        } 
+	sc->transmitting=0;
+ 
+        // Clear the interrupt, the bge intr handler will take care of it 
+        BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR); 
+        bge_writembx(sc, BGE_MBX_IRQ0_LO, 1); 
+ 
+        // save the status for the interrupt handler 
+        atomic_or((int32 *)&sc->bge_intr_status, status); 
+// *** 
+	if ((sc->bge_asicrev == BGE_ASICREV_BCM5700 &&
+	    sc->bge_chipid != BGE_CHIPID_BCM5700_B2) ||
+	    (status&0x1000) || sc->bge_link_evt)
+		bge_link_upd(sc);
+// *** 
+        return 1; 
+} 
+ 
+ 
+void 
+__haiku_reenable_interrupts(device_t dev) 
+{
+        struct bge_softc *sc = device_get_softc(dev); 
+        BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_CLEAR_INTA); 
+        BGE_CLRBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR); 
+        bge_writembx(sc, BGE_MBX_IRQ0_LO, 0); 
+} 
Index: src/libs/compat/freebsd_network/compat/sys/mbuf.h
===================================================================
--- src/libs/compat/freebsd_network/compat/sys/mbuf.h	(wersja 28342)
+++ src/libs/compat/freebsd_network/compat/sys/mbuf.h	(kopia robocza)
@@ -82,6 +82,9 @@
 
 #define M_BCAST			0x00000200
 #define M_MCAST			0x00000400
+#define M_FRAG			0x00000800
+#define M_FIRSTFRAG		0x00001000
+#define M_LASTFRAG		0x00002000
 #define	M_VLANTAG		0x00010000
 
 #define CSUM_IP			0x0001
@@ -124,6 +127,7 @@
 struct mbuf *m_get(int how, short type);
 struct mbuf *m_gethdr(int how, short type);
 void m_clget(struct mbuf *m, int how);
+void * m_cljget(struct mbuf *m, int how, int size); 
 
 void m_extadd(struct mbuf *m, caddr_t buffer, u_int size,
     void (*freeHook)(void *, void *), void *args, int flags, int type);
Index: src/libs/compat/freebsd_network/fbsd_mii_physubr.c
===================================================================
--- src/libs/compat/freebsd_network/fbsd_mii_physubr.c	(wersja 28342)
+++ src/libs/compat/freebsd_network/fbsd_mii_physubr.c	(kopia robocza)
@@ -510,8 +510,9 @@
 	}
 
 	if (sc->mii_capabilities & BMSR_ANEG) {
-		ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst),
-		    MII_NMEDIA);	/* intentionally invalid index */
+		dprintf("don't know how to handle sc->mii_capabilities & BMSR_ANEG\n");
+		//ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst),
+		    //MII_NMEDIA);	/* intentionally invalid index */
 		PRINT("auto");
 	}
 #undef ADD
Index: src/libs/compat/freebsd_network/mbuf.c
===================================================================
--- src/libs/compat/freebsd_network/mbuf.c	(wersja 28342)
+++ src/libs/compat/freebsd_network/mbuf.c	(kopia robocza)
@@ -150,6 +150,36 @@
 	construct_ext_mbuf(m, how);
 }
 
+	/* 
+	 * Comment from the freebsd (mbuf.h): 
+	 * m_cljget() is different from m_clget() as it can allocate clusters without 
+	 * attaching them to an mbuf.  In that case the return value is the pointer 
+	 * to the cluster of the requested size.  If an mbuf was specified, it gets 
+	 * the cluster attached to it and the return value can be safely ignored. 
+	 * For size it takes MCLBYTES, MJUMPAGESIZE, MJUM9BYTES, MJUM16BYTES. 
+	 */ 
+	void * 
+	m_cljget(struct mbuf *m, int how, int size) 
+	{ 
+	        // TODO: implement this 
+	        panic("m_cljget not yet implemented"); 
+	        return (void *) NULL; 
+	 
+	/* 
+	//      This is the freebsd code 
+	        uma_zone_t zone; 
+	 
+	        if (m && m->m_flags & M_EXT) 
+	                printf("%s: %p mbuf already has cluster\n", __func__, m); 
+	        if (m != NULL) 
+	                m->m_ext.ext_buf = NULL; 
+	 
+	        zone = m_getzone(size); 
+	        return (uma_zalloc_arg(zone, m, how)); 
+	*/ 
+	} 
+	 
+	 
 
 void
 m_freem(struct mbuf *mb)
