Index: build/jam/HaikuImage
===================================================================
--- build/jam/HaikuImage	(revision 28608)
+++ build/jam/HaikuImage	(working copy)
@@ -142,7 +142,7 @@
 	$(X86_ONLY)via_rhine wb840 $(X86_ONLY)ipro100 $(X86_ONLY)nforce
 	#vlance
 	$(X86_ONLY)marvell_yukon $(X86_ONLY)syskonnect usb_ecm
-	$(GPL_ONLY)bcm570x
+	broadcom570x
 ;
 #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/broadcom570x/dev/bge/if_bgereg.h
===================================================================
--- src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bgereg.h	(revision 28608)
+++ src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bgereg.h	(working copy)
@@ -2578,6 +2578,8 @@
 #ifdef DEVICE_POLLING
 	int			rxcycles;
 #endif /* DEVICE_POLLING */
+	u_int32_t		bge_intr_status;
+	int			bge_transmitting;
 };
 
 #define	BGE_LOCK_INIT(_sc, _name) \
Index: src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bge.c
===================================================================
--- src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bge.c	(revision 28608)
+++ src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bge.c	(working copy)
@@ -398,7 +398,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
@@ -2361,6 +2361,7 @@
 
 	sc = device_get_softc(dev);
 	sc->bge_dev = dev;
+	sc->bge_transmitting = 0;
 
 	/*
 	 * Map control/status registers.
@@ -3026,6 +3027,8 @@
 	    sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx)
 		return;
 
+	dprintf("bge_rxeof\n");
+
 	ifp = sc->bge_ifp;
 
 	bus_dmamap_sync(sc->bge_cdata.bge_rx_return_ring_tag,
@@ -3194,6 +3197,8 @@
 	    sc->bge_ldata.bge_status_block->bge_idx[0].bge_tx_cons_idx)
 		return;
 
+	dprintf("bge_txeof\n");
+
 	ifp = sc->bge_ifp;
 
 	bus_dmamap_sync(sc->bge_cdata.bge_tx_ring_tag,
@@ -3281,6 +3286,8 @@
 
 	sc = xsc;
 
+	dprintf("bge_intr, sc->bge_intr_status=0x%x\n", sc->bge_intr_status);
+
 	BGE_LOCK(sc);
 
 	ifp = sc->bge_ifp;
@@ -3312,12 +3319,20 @@
 	 * the status check).  So toggling would probably be a pessimization
 	 * even with MSI.  It would only be needed for using a task queue.
 	 */
+#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;
+#ifdef __HAIKU__ 
+        /* 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; 
+#else 
+        statusword = CSR_READ_4(sc, BGE_MAC_STS) & BGE_MACSTAT_LINK_CHANGED; 
+#endif 
 
 	/* Make sure the descriptor ring indexes are coherent. */
 	bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
@@ -3325,10 +3340,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... */ 
+//FIXME: moved to glue.c, probably safe to remove
+	//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. */
@@ -3634,7 +3652,9 @@
 
 	sc = ifp->if_softc;
 
-	if (!sc->bge_link || IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+//FIXME: sc->bge_link isn't being properly set in bge_link_upd
+	//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;
@@ -3696,6 +3716,7 @@
 		/* No packets were dequeued. */
 		return;
 
+	sc -> bge_transmitting = 1;
 	/* Transmit. */
 	bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
 	/* 5700 b2 errata */
@@ -4253,6 +4275,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);
@@ -4320,7 +4347,7 @@
 	return (0);
 }
 
-static void
+/*static*/ void
 bge_link_upd(struct bge_softc *sc)
 {
 	struct mii_data *mii;
@@ -4402,15 +4429,20 @@
 		 * 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;
+		printf("bge: bge\n");
 		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");
@@ -4433,6 +4465,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) \
Index: src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/glue.c
===================================================================
--- src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/glue.c	(revision 28608)
+++ src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/glue.c	(working copy)
@@ -28,6 +28,51 @@
 	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->bge_transmitting==0) && ((pci_read_config(sc->bge_dev, BGE_PCI_PCISTATE,4) & BGE_PCISTATE_INTR_STATE) != 0)) {
+                return 0; 
+        } 
+	sc->bge_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; 
+} 
+//int
+//__haiku_disable_interrupts(device_t dev)
+//{
+//	struct bge_softc *sc = device_get_softc(dev);
+//
+//	uint32 statusword = CSR_READ_4(sc, BGE_MAC_STS) & BGE_MACSTAT_LINK_CHANGED;
+//
+//	if ((sc->bge_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 && !statusword
+//		&& (pci_read_config(sc->bge_dev, BGE_PCI_PCISTATE,4) & BGE_PCISTATE_INTR_STATE))
+//		return 0;
+//
+//	BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
+//	bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);
+//
+//	return 1;
+//}
+ 
 
 // copied from if_bge.c
 static void
@@ -39,30 +84,12 @@
 	CSR_WRITE_4(sc, off, val);
 }
 
-
-int
-__haiku_disable_interrupts(device_t dev)
+void 
+__haiku_reenable_interrupts(device_t dev) 
 {
-	struct bge_softc *sc = device_get_softc(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); 
+} 
 
-	uint32 statusword = CSR_READ_4(sc, BGE_MAC_STS) & BGE_MACSTAT_LINK_CHANGED;
-
-	if ((sc->bge_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 && !statusword
-		&& (pci_read_config(sc->bge_dev, BGE_PCI_PCISTATE,4) & BGE_PCISTATE_INTR_STATE))
-		return 0;
-
-	BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
-	bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);
-
-	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/fbsd_mii_physubr.c
===================================================================
--- src/libs/compat/freebsd_network/fbsd_mii_physubr.c	(revision 28608)
+++ src/libs/compat/freebsd_network/fbsd_mii_physubr.c	(working copy)
@@ -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
