Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 13 Jan 2006 14:02:36 -0800 (PST)
From:      Doug Ambrisko <ambrisko@ambrisko.com>
To:        freebsd-net@freebsd.org
Subject:   Re: bge BCM5721/BCM5750 fixes to work with IPMI
Message-ID:  <200601132202.k0DM2avs099728@ambrisko.com>

next in thread | raw e-mail | index | archive | help
Doug Ambrisko writes:
| Here are some first pass patches to make the bge driver not break IPMI.
| This was tested on a Dell PE850:
|   bge0: <Broadcom BCM5721 Gigabit Ethernet, ASIC rev. 0x4101> mem 0xfe6f0000-0xfe6fffff irq 16 at device 0.0 on pci4
|   miibus1: <MII bus> on bge0
|   brgphy0: <BCM5750 10/100/1000baseTX PHY> on miibus1
|   brgphy0:  10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, 1000baseTX, 1000baseTX-FDX, auto
| 
| It shouldn't break other bge cards and it might work with other Broadcom
| IPMI capable chips (they seem to have different usages).  Please let me know 
| how this goes.
| 
| I gleaned this info. from the Linux drivers.  YMMV. 

I have an updated patch for -current as of today and fixed some issues.
It's getting closer to something that is final.  The only issues are 
"sharing" access to the PHY since both the device driver and the ASF/IPMI 
internal firmware stack also talks to the PHY.  If this is not done 
carefully it can take the chip off the net.  It can also return bogus 
values randomly due to contention.  Broadcom's Linux driver just skips 
talking to it at times and returns the expected values.  I've tried my 
best at dealing with this.  I need to get some doc's that might explain 
how we can share talking to the PHY rather then guessing.  This now works 
after PXE and non PXE boots and with chips not running the internal 
ASF/IPMI stack.

Let me know if it causes problems or works.

Doug A.

Index: if_bge.c
===================================================================
RCS file: /usr/local/cvsroot/freebsd/src/sys/dev/bge/if_bge.c,v
retrieving revision 1.113
diff -u -p -r1.113 if_bge.c
--- if_bge.c	13 Jan 2006 08:59:40 -0000	1.113
+++ if_bge.c	13 Jan 2006 21:52:53 -0000
@@ -271,7 +271,12 @@ static void bge_poll_locked	(struct ifne
 				    int count);
 #endif
 
-static void bge_reset		(struct bge_softc *);
+#define BGE_RESET_START 1
+#define BGE_RESET_STOP  2
+static void bge_sig_post_reset(struct bge_softc *, int);
+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 device_method_t bge_methods[] = {
@@ -579,6 +584,15 @@ bge_miibus_readreg(dev, phy, reg)
 	if (phy != 1)
 		return(0);
 
+	if (sc->bge_asf_mode & ASF_STACKUP) {
+		BGE_CLRBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
+		for (i = 0; i < BGE_TIMEOUT; i++) {
+			val = CSR_READ_4(sc, BGE_MI_COMM);
+			if (!(val & BGE_MICOMM_BUSY))
+				break;
+		}
+	}
+
 	/* Reading with autopolling on may trigger PCI errors */
 	autopoll = CSR_READ_4(sc, BGE_MI_MODE);
 	if (autopoll & BGE_MIMODE_AUTOPOLL) {
@@ -609,6 +623,26 @@ done:
 		DELAY(40);
 	}
 
+	if (sc->bge_asf_mode & ASF_STACKUP)
+		BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
+        if (sc->bge_asf_mode & ASF_STACKUP
+	    && pci_get_device(sc->bge_dev) == BCOM_DEVICEID_BCM5721) {
+		switch (reg) {
+                case MII_PHYIDR1:
+                        val = 0x0020;
+			break;
+                case MII_PHYIDR2:
+                        val = 0x6180;
+			break; 
+                case MII_BMSR:
+			val |= BMSR_100TXFDX | BMSR_100TXHDX | BMSR_10TFDX
+				| BMSR_10THDX | BMSR_EXTSTAT
+				| BMSR_MFPS
+				| BMSR_ANEG | BMSR_EXTCAP;
+			break;
+		}
+        }
+
 	if (val & BGE_MICOMM_READFAIL)
 		return(0);
 
@@ -626,6 +660,15 @@ bge_miibus_writereg(dev, phy, reg, val)
 
 	sc = device_get_softc(dev);
 
+	if (sc->bge_asf_mode & ASF_STACKUP) {
+		BGE_CLRBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
+		for (i = 0; i < BGE_TIMEOUT; i++) {
+			val = CSR_READ_4(sc, BGE_MI_COMM);
+			if (!(val & BGE_MICOMM_BUSY))
+				break;
+		}
+	}
+
 	/* Reading with autopolling on may trigger PCI errors */
 	autopoll = CSR_READ_4(sc, BGE_MI_MODE);
 	if (autopoll & BGE_MIMODE_AUTOPOLL) {
@@ -646,6 +689,9 @@ bge_miibus_writereg(dev, phy, reg, val)
 		DELAY(40);
 	}
 
+	if (sc->bge_asf_mode & ASF_STACKUP)
+		BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
+
 	if (i == BGE_TIMEOUT) {
 		if_printf(sc->bge_ifp, "PHY read timed out\n");
 		return(0);
@@ -660,10 +706,21 @@ bge_miibus_statchg(dev)
 {
 	struct bge_softc *sc;
 	struct mii_data *mii;
+	int i, val;
 
 	sc = device_get_softc(dev);
 	mii = device_get_softc(sc->bge_miibus);
 
+
+	if (sc->bge_asf_mode & ASF_STACKUP) {
+		BGE_CLRBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
+		for (i = 0; i < BGE_TIMEOUT; i++) {
+			val = CSR_READ_4(sc, BGE_MI_COMM);
+			if (!(val & BGE_MICOMM_BUSY))
+				break;
+		}
+	}
+
 	BGE_CLRBIT(sc, BGE_MAC_MODE, BGE_MACMODE_PORTMODE);
 	if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T) {
 		BGE_SETBIT(sc, BGE_MAC_MODE, BGE_PORTMODE_GMII);
@@ -677,6 +734,9 @@ bge_miibus_statchg(dev)
 		BGE_SETBIT(sc, BGE_MAC_MODE, BGE_MACMODE_HALF_DUPLEX);
 	}
 
+	if (sc->bge_asf_mode & ASF_STACKUP)
+		BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
+
 	return;
 }
 
@@ -1004,6 +1064,78 @@ bge_setmulti(sc)
 	return;
 }
 
+static void
+bge_sig_pre_reset(sc, type)
+	struct bge_softc *sc;
+	int type;
+{
+	bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);
+
+	if (sc->bge_asf_mode & ASF_NEW_HANDSHAKE) {
+		switch (type) {
+		case BGE_RESET_START:
+			bge_writemem_ind(sc, BGE_SDI_STATUS, 0x1); /* START */
+			break;
+		case BGE_RESET_STOP:
+			bge_writemem_ind(sc, BGE_SDI_STATUS, 0x2); /* UNLOAD */
+			break;
+		}
+	}
+}
+
+static void
+bge_sig_post_reset(sc, type)
+	struct bge_softc *sc;
+	int type;
+{
+	if (sc->bge_asf_mode & ASF_NEW_HANDSHAKE) {
+		switch (type) {
+		case BGE_RESET_START:
+			bge_writemem_ind(sc, BGE_SDI_STATUS, 0x80000001); 
+			/* START DONE */
+			break;
+		case BGE_RESET_STOP:
+			bge_writemem_ind(sc, BGE_SDI_STATUS, 0x80000002); 
+			break;
+		}
+	}
+}
+
+static void
+bge_sig_legacy(sc, type)
+	struct bge_softc *sc;
+	int type;
+{
+	if (sc->bge_asf_mode) {
+		switch (type) {
+		case BGE_RESET_START:
+			bge_writemem_ind(sc, BGE_SDI_STATUS, 0x1); /* START */
+			break;
+		case BGE_RESET_STOP:
+			bge_writemem_ind(sc, BGE_SDI_STATUS, 0x2); /* UNLOAD */
+			break;
+		}
+	}
+}
+
+void bge_stop_fw(struct bge_softc *);
+void
+bge_stop_fw(sc)
+	struct bge_softc *sc;
+{
+	int i;
+
+	if (sc->bge_asf_mode) {
+		bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM_FW, BGE_FW_PAUSE);
+
+		for (i = 0; i < 100; i++ ) {
+			if (!(CSR_READ_4(sc, BGE_CPU_EVENT) & (1 << 14)))
+				break;
+			DELAY(10);
+		}
+	}
+}
+
 /*
  * Do endian, PCI and DMA initialization. Also check the on-board ROM
  * self-test results.
@@ -1015,9 +1147,10 @@ bge_chipinit(sc)
 	int			i;
 	u_int32_t		dma_rw_ctl;
 
-	/* Set endian type before we access any non-PCI registers. */
+	/* Set endianness before we access any non-PCI registers. */
 	pci_write_config(sc->bge_dev, BGE_PCI_MISC_CTL, BGE_INIT, 4);
 
+#ifdef DJA 
 	/*
 	 * Check the 'ROM failed' bit on the RX CPU to see if
 	 * self-tests passed.
@@ -1026,7 +1159,7 @@ bge_chipinit(sc)
 		device_printf(sc->bge_dev, "RX CPU self-diagnostics failed!\n");
 		return(ENODEV);
 	}
-
+#endif
 	/* Clear the MAC control register */
 	CSR_WRITE_4(sc, BGE_MAC_MODE, 0);
 
@@ -1097,6 +1230,8 @@ bge_chipinit(sc)
 	CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS|
 	    BGE_MODECTL_MAC_ATTN_INTR|BGE_MODECTL_HOST_SEND_BDS|
 	    BGE_MODECTL_TX_NO_PHDR_CSUM|BGE_MODECTL_RX_NO_PHDR_CSUM);
+	if (sc->bge_asf_mode & ASF_STACKUP)
+		BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
 
 	/*
 	 * Disable memory write invalidate.  Apparently it is not supported
@@ -2051,6 +2186,7 @@ bge_attach(dev)
 	u_int32_t mac_tmp = 0;
 	u_char eaddr[6];
 	int error = 0, rid;
+	int trys;
 
 	sc = device_get_softc(dev);
 	sc->bge_dev = dev;
@@ -2118,8 +2254,34 @@ bge_attach(dev)
 		}
 	}
 
+	sc->bge_asf_mode = 0;
+	if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_SIG)
+	    == BGE_MAGIC_NUMBER) {
+		if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_NICCFG)
+		    & BGE_HWCFG_ASF) {
+			sc->bge_asf_mode |= ASF_ENABLE;
+			if (CSR_READ_4(sc, BGE_MODE_CTL)
+			    & BGE_MODECTL_STACKUP ) {
+				sc->bge_asf_mode |= ASF_STACKUP;
+			}
+			if (sc->bge_asicrev == BGE_ASICREV_BCM5750) {
+				sc->bge_asf_mode |= ASF_NEW_HANDSHAKE;
+			}
+		}
+	}
+
 	/* Try to reset the chip. */
-	bge_reset(sc);
+	bge_stop_fw(sc);
+	bge_sig_pre_reset(sc, BGE_RESET_STOP);
+	if (bge_reset(sc)) {
+		device_printf(sc->bge_dev, "chip reset failed\n");
+		bge_release_resources(sc);
+		error = ENXIO;
+		goto fail;
+	}
+
+	bge_sig_legacy(sc, BGE_RESET_STOP);
+	bge_sig_post_reset(sc, BGE_RESET_STOP);
 
 	if (bge_chipinit(sc)) {
 		device_printf(sc->bge_dev, "chip initialization failed\n");
@@ -2249,13 +2411,30 @@ bge_attach(dev)
 		/*
 		 * Do transceiver setup.
 		 */
+		/* DJA reset */
+		BGE_CLRBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
+#if DJA
+		bge_miibus_writereg(sc->bge_dev, 1, MII_BMCR, BMCR_RESET);
+		DELAY(100000);
+#endif
+		/* DJA done reset */
+again:
+		trys = 0;
 		if (mii_phy_probe(dev, &sc->bge_miibus,
 		    bge_ifmedia_upd, bge_ifmedia_sts)) {
+			if (trys++ < 4) {
+				device_printf(sc->bge_dev, "Try again\n");
+				bge_miibus_writereg(sc->bge_dev, 1, MII_BMCR, BMCR_RESET);
+				goto again;
+			}
+
 			device_printf(sc->bge_dev, "MII without any PHY!\n");
 			bge_release_resources(sc);
 			error = ENXIO;
 			goto fail;
 		}
+		if (sc->bge_asf_mode & ASF_STACKUP)
+			BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
 	}
 
 	/*
@@ -2369,7 +2548,7 @@ bge_release_resources(sc)
 	return;
 }
 
-static void
+static int
 bge_reset(sc)
 	struct bge_softc *sc;
 {
@@ -2432,11 +2611,26 @@ bge_reset(sc)
 	    sc->bge_asicrev != BGE_ASICREV_BCM5750)
 		CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE);
 
+#if DJA
+	DELAY(1000000);
+	/*
+	 * Check the 'ROM failed' bit on the RX CPU to see if
+	 * self-tests passed.
+	 */
+	if (CSR_READ_4(sc, BGE_RXCPU_MODE) & BGE_RXCPUMODE_ROMFAIL) {
+		device_printf(sc->bge_dev, "RX CPU self-diagnostics failed!\n");
+		return(ENODEV);
+	}
+#endif
+
+#ifdef ASF /* this conflicts with ASF/IPMI and is done in bge_sig_pre_reset*/
 	/*
 	 * Prevent PXE restart: write a magic number to the
 	 * general communications memory at 0xB50.
 	 */
 	bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);
+#endif
+
 	/*
 	 * Poll the value location we just wrote until
 	 * we see the 1's complement of the magic number.
@@ -2452,7 +2646,7 @@ bge_reset(sc)
 
 	if (i == BGE_TIMEOUT) {
 		device_printf(sc->bge_dev, "firmware handshake timed out\n");
-		return;
+		return(0);
 	}
 
 	/*
@@ -2472,6 +2666,8 @@ bge_reset(sc)
 	/* Fix up byte swapping */
 	CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS|
 	    BGE_MODECTL_BYTESWAP_DATA);
+	if (sc->bge_asf_mode & ASF_STACKUP)
+		BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
 
 	CSR_WRITE_4(sc, BGE_MAC_MODE, 0);
 
@@ -2496,7 +2692,7 @@ bge_reset(sc)
 	}
 	DELAY(10000);
 
-	return;
+	return(0);
 }
 
 /*
@@ -2672,6 +2868,7 @@ bge_txeof(sc)
 {
 	struct bge_tx_bd *cur_tx = NULL;
 	struct ifnet *ifp;
+	int acked = 0;
 
 	BGE_LOCK_ASSERT(sc);
 
@@ -2703,12 +2900,38 @@ bge_txeof(sc)
 		}
 		sc->bge_txcnt--;
 		BGE_INC(sc->bge_tx_saved_considx, BGE_TX_RING_CNT);
-		ifp->if_timer = 0;
+		ifp->if_timer = (sc->bge_txcnt == 0) ? 0 : 5;
+
+		acked = 1;
 	}
 
 	if (cur_tx != NULL)
 		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 
+	switch (sc->bge_chipid) {
+	case BGE_CHIPID_BCM5701_A0:
+	case BGE_CHIPID_BCM5701_B0:
+	case BGE_CHIPID_BCM5701_B2:
+	case BGE_CHIPID_BCM5701_B5:
+		/*
+		 * Sometimes the RX engine never gets started.  We detect
+		 * this by checking to see if we have sent some packets and
+		 * never got a packet.  If we haven't got a packet reset.
+		 * this is only triggered if we sent packets.
+		 */
+
+		if (acked && ifp->if_opackets > 5 && !ifp->if_ipackets) {
+			device_printf(sc->bge_dev, "reset the card packets out %ld in %ld\n"
+			    , ifp->if_opackets,
+			ifp->if_ipackets);
+			ifp->if_flags &=~ IFF_DRV_RUNNING;
+			bge_stop(sc);
+			bge_init(sc);
+		}
+		break;
+	}
+
+
 	return;
 }
 
@@ -2836,7 +3059,10 @@ bge_tick_locked(sc)
 
 	if (!sc->bge_tbi) {
 		mii = device_get_softc(sc->bge_miibus);
-		mii_tick(mii);
+		/* Don't mess with the PHY in IPMI/ASP mode */
+		if (!((sc->bge_asf_mode & ASF_STACKUP)
+		     && (sc->bge_link)))
+			mii_tick(mii);
 	}
 
 	callout_reset(&sc->bge_stat_ch, hz, bge_tick, sc);
@@ -3187,7 +3413,13 @@ bge_init_locked(sc)
 
 	/* Cancel pending I/O and flush buffers. */
 	bge_stop(sc);
+
+	bge_stop_fw(sc);
+	bge_sig_pre_reset(sc, BGE_RESET_START);
 	bge_reset(sc);
+	bge_sig_legacy(sc, BGE_RESET_START);
+	bge_sig_post_reset(sc, BGE_RESET_START);
+
 	bge_chipinit(sc);
 
 	/*
@@ -3270,14 +3502,14 @@ bge_init_locked(sc)
 		CSR_WRITE_4(sc, BGE_HCC_TX_MAX_COAL_BDS_INT, 1);
 	} else
 #endif
-	
+
 	/* Enable host interrupts. */
 	{
 	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_ifmedia_upd(ifp);
 
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
@@ -3426,32 +3658,39 @@ bge_ioctl(ifp, command, data)
 		}
 		break;
 	case SIOCSIFFLAGS:
-		BGE_LOCK(sc);
 		if (ifp->if_flags & IFF_UP) {
-			/*
-			 * If only the state of the PROMISC flag changed,
-			 * then just use the 'set promisc mode' command
-			 * instead of reinitializing the entire NIC. Doing
-			 * a full re-init means reloading the firmware and
-			 * waiting for it to start up, which may take a
-			 * second or two.
-			 */
-			if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
+			u_int16_t *m;
+			/* Load our MAC address. */
+			m = (u_int16_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]));
+
+			if (ifp->if_flags & IFF_DRV_RUNNING &&
 			    ifp->if_flags & IFF_PROMISC &&
 			    !(sc->bge_if_flags & IFF_PROMISC)) {
 				BGE_SETBIT(sc, BGE_RX_MODE,
 				    BGE_RXMODE_RX_PROMISC);
-			} else if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
+			} else if (ifp->if_flags & IFF_DRV_RUNNING &&
 			    !(ifp->if_flags & IFF_PROMISC) &&
 			    sc->bge_if_flags & IFF_PROMISC) {
 				BGE_CLRBIT(sc, BGE_RX_MODE,
 				    BGE_RXMODE_RX_PROMISC);
-			} else
-				bge_init_locked(sc);
-		} else {
-			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
-				bge_stop(sc);
 			}
+
+			/* Turn on transmitter */
+			BGE_SETBIT(sc, BGE_TX_MODE, BGE_TXMODE_ENABLE);
+
+			/* Turn on receiver */
+			BGE_SETBIT(sc, BGE_RX_MODE, BGE_RXMODE_ENABLE);
+			bge_init(sc);
+		} else {
+			/* Turn off transmitter */
+			BGE_CLRBIT(sc, BGE_TX_MODE, BGE_TXMODE_ENABLE);
+
+			/* Turn off receiver */
+			BGE_CLRBIT(sc, BGE_RX_MODE, BGE_RXMODE_ENABLE);
+			bge_init(sc);
 		}
 		sc->bge_if_flags = ifp->if_flags;
 		BGE_UNLOCK(sc);
@@ -3614,7 +3853,16 @@ bge_stop(sc)
 	/*
 	 * Tell firmware we're shutting down.
 	 */
-	BGE_CLRBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
+
+	bge_stop_fw(sc);
+	bge_sig_pre_reset(sc, BGE_RESET_STOP);
+	bge_reset(sc);
+	bge_sig_legacy(sc, BGE_RESET_STOP);
+	bge_sig_post_reset(sc, BGE_RESET_STOP);
+	if (sc->bge_asf_mode & ASF_STACKUP)
+		BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
+	else
+		BGE_CLRBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
 
 	/* Free the RX lists. */
 	bge_free_rx_ring_std(sc);
Index: if_bgereg.h
===================================================================
RCS file: /usr/local/cvsroot/freebsd/src/sys/dev/bge/if_bgereg.h,v
retrieving revision 1.42
diff -u -p -r1.42 if_bgereg.h
--- if_bgereg.h	23 Dec 2005 02:04:41 -0000	1.42
+++ if_bgereg.h	13 Jan 2006 21:52:53 -0000
@@ -74,6 +74,8 @@
 #define BGE_SOFTWARE_GENCOMM		0x00000B50
 #define BGE_SOFTWARE_GENCOMM_SIG	0x00000B54
 #define BGE_SOFTWARE_GENCOMM_NICCFG	0x00000B58
+#define BGE_SOFTWARE_GENCOMM_FW		0x00000B78
+#define    BGE_FW_PAUSE			0x00000002
 #define BGE_SOFTWARE_GENCOMM_END	0x00000FFF
 #define BGE_UNMAPPED			0x00001000
 #define BGE_UNMAPPED_END		0x00001FFF
@@ -1627,6 +1629,7 @@
 #define BGE_MODE_CTL			0x6800
 #define BGE_MISC_CFG			0x6804
 #define BGE_MISC_LOCAL_CTL		0x6808
+#define BGE_CPU_EVENT			0x6810
 #define BGE_EE_ADDR			0x6838
 #define BGE_EE_DATA			0x683C
 #define BGE_EE_CTL			0x6840
@@ -2009,6 +2012,7 @@ struct bge_status_block {
 #define BGE_HWCFG_VOLTAGE		0x00000003
 #define BGE_HWCFG_PHYLED_MODE		0x0000000C
 #define BGE_HWCFG_MEDIA			0x00000030
+#define BGE_HWCFG_ASF			0x00000080
 
 #define BGE_VOLTAGE_1POINT3		0x00000000
 #define BGE_VOLTAGE_1POINT8		0x00000001
@@ -2385,6 +2389,10 @@ struct bge_bcom_hack {
 	int			val;
 };
 
+#define ASF_ENABLE		1
+#define ASF_NEW_HANDSHAKE	2
+#define ASF_STACKUP		4
+
 struct bge_softc {
 	struct ifnet		*bge_ifp;	/* interface info */
 	device_t		bge_dev;
@@ -2403,6 +2411,7 @@ struct bge_softc {
 	u_int8_t		bge_asicrev;
 	u_int8_t		bge_chiprev;
 	u_int8_t		bge_no_3_led;
+	u_int8_t		bge_asf_mode;
 	u_int8_t		bge_pcie;
 	struct bge_ring_data	bge_ldata;	/* rings */
 	struct bge_chain_data	bge_cdata;	/* mbufs */



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