Bug 134658 - [bce] bce driver fails on PowerEdge m610 blade.
Summary: [bce] bce driver fails on PowerEdge m610 blade.
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: Unspecified
Hardware: Any Any
: Normal Affects Only Me
Assignee: Pyun YongHyeon
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-05-18 17:50 UTC by Harald Jensas
Modified: 2010-04-15 21:41 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Harald Jensas 2009-05-18 17:50:02 UTC
bce driver fails to attach to Broadcom BCM5709 NIC in Dell PowerEdge m610 blade server.

From dmesg log:

pcib0: <ACPI Host-PCI bridge> port 0xcf8-0xcff on acpi0
pci0: <ACPI PCI bus> on pcib0
pcib1: <ACPI PCI-PCI bridge> at device 1.0 on pci0
pci1: <ACPI PCI bus> on pcib1
bce0: <Broadcom NetXtreme II BCM5709 1000Base-SX (C0)> mem 0xda000000-0xdbffffff irq 36 at device 0.0 on pci1
bce0: /usr/src/sys/dev/bce/if_bce.c(1044): No PHY found on child MII bus!
device_attach: bce0 attach returned 6
bce1: <Broadcom NetXtreme II BCM5709 1000Base-SX (C0)> mem 0xdc000000-0xddffffff irq 48 at device 0.1 on pci1
bce1: /usr/src/sys/dev/bce/if_bce.c(1044): No PHY found on child MII bus!
device_attach: bce1 attach returned 6

How-To-Repeat: Install FreeBSD 7.2 on Dell PowerEdge server with BroadCom BCM5709 LOM (Lan On Motherboard.)
Comment 1 Mark Linimon freebsd_committer freebsd_triage 2009-05-19 00:11:45 UTC
Responsible Changed
From-To: freebsd-amd64->freebsd-net

Take a guess that this is not amd64-specific.
Comment 2 David Christensen 2009-05-21 01:38:48 UTC
This is the expected behavior as the mii(4) SerDes support=20
for the 5709 was removed from immediately prior to the 7.2=20
release.  The PHY's ID is not present in miidevs.c.

Dave=
Comment 4 Tom Judge 2009-10-27 21:32:24 UTC
Hi,

This seems to be a duplicate of these 2:

kern/139761
kern/136417

Tom
Comment 5 Pyun YongHyeon freebsd_committer freebsd_triage 2010-03-18 21:54:05 UTC
State Changed
From-To: open->patched

Patch committed to HEAD(r205299, r205300). 


Comment 6 Pyun YongHyeon freebsd_committer freebsd_triage 2010-03-18 21:54:05 UTC
Responsible Changed
From-To: freebsd-net->yongari

Track.
Comment 7 dfilter service freebsd_committer freebsd_triage 2010-04-15 20:20:13 UTC
Author: yongari
Date: Thu Apr 15 19:19:59 2010
New Revision: 206678
URL: http://svn.freebsd.org/changeset/base/206678

Log:
  MFC r205299:
    - Added support for 5709S/5716S PHYs.
  
    Submitted by: pyunyh
    PR:	kern/134658, kern/136417, kern/139761, kern/140970

Modified:
  stable/8/sys/dev/mii/brgphy.c
  stable/8/sys/dev/mii/brgphyreg.h
  stable/8/sys/dev/mii/miidevs
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/dev/mii/brgphy.c
==============================================================================
--- stable/8/sys/dev/mii/brgphy.c	Thu Apr 15 19:19:38 2010	(r206677)
+++ stable/8/sys/dev/mii/brgphy.c	Thu Apr 15 19:19:59 2010	(r206678)
@@ -75,6 +75,7 @@ struct brgphy_softc {
 #define BRGPHY_5706S		0x0001
 #define BRGPHY_5708S		0x0002
 #define BRGPHY_NOANWAIT		0x0004
+#define BRGPHY_5709S		0x0008
 	int bce_phy_flags;	/* PHY flags transferred from the MAC driver */
 };
 
@@ -139,6 +140,7 @@ static const struct mii_phydesc brgphys[
 	MII_PHY_DESC(xxBROADCOM_ALT1, BCM5784),
 	MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709C),
 	MII_PHY_DESC(xxBROADCOM_ALT1, BCM5761),
+    MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709S),
 	MII_PHY_DESC(BROADCOM2, BCM5906),
 	MII_PHY_END
 };
@@ -216,30 +218,34 @@ brgphy_attach(device_t dev)
 		break;
 	case MII_OUI_xxBROADCOM:
 		switch (bsc->mii_model) {
-			case MII_MODEL_xxBROADCOM_BCM5706:
-			case MII_MODEL_xxBROADCOM_BCM5714:
-				/*
-				 * The 5464 PHY used in the 5706 supports both copper
-				 * and fiber interfaces over GMII.  Need to check the
-				 * shadow registers to see which mode is actually
-				 * in effect, and therefore whether we have 5706C or
-				 * 5706S.
-				 */
-				PHY_WRITE(sc, BRGPHY_MII_SHADOW_1C,
-					BRGPHY_SHADOW_1C_MODE_CTRL);
-				if (PHY_READ(sc, BRGPHY_MII_SHADOW_1C) &
-					BRGPHY_SHADOW_1C_ENA_1000X) {
-					bsc->serdes_flags |= BRGPHY_5706S;
-					sc->mii_flags |= MIIF_HAVEFIBER;
-				}
-				break;
+		case MII_MODEL_xxBROADCOM_BCM5706:
+		case MII_MODEL_xxBROADCOM_BCM5714:
+			/*
+			 * The 5464 PHY used in the 5706 supports both copper
+			 * and fiber interfaces over GMII.  Need to check the
+			 * shadow registers to see which mode is actually
+			 * in effect, and therefore whether we have 5706C or
+			 * 5706S.
+			 */
+			PHY_WRITE(sc, BRGPHY_MII_SHADOW_1C,
+				BRGPHY_SHADOW_1C_MODE_CTRL);
+			if (PHY_READ(sc, BRGPHY_MII_SHADOW_1C) &
+				BRGPHY_SHADOW_1C_ENA_1000X) {
+				bsc->serdes_flags |= BRGPHY_5706S;
+				sc->mii_flags |= MIIF_HAVEFIBER;
+			}
+			break;
 		} break;
 	case MII_OUI_xxBROADCOM_ALT1:
 		switch (bsc->mii_model) {
-			case MII_MODEL_xxBROADCOM_ALT1_BCM5708S:
-				bsc->serdes_flags |= BRGPHY_5708S;
-				sc->mii_flags |= MIIF_HAVEFIBER;
-				break;
+		case MII_MODEL_xxBROADCOM_ALT1_BCM5708S:
+			bsc->serdes_flags |= BRGPHY_5708S;
+			sc->mii_flags |= MIIF_HAVEFIBER;
+			break;
+        case MII_MODEL_xxBROADCOM_ALT1_BCM5709S:
+            bsc->serdes_flags |= BRGPHY_5709S;
+            sc->mii_flags |= MIIF_HAVEFIBER;
+            break;
 		} break;
 	default:
 		device_printf(dev, "Unrecognized OUI for PHY!\n");
@@ -631,6 +637,7 @@ brgphy_status(struct mii_softc *sc)
 			PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, BRGPHY_5708S_DIG_PG0);
 			xstat = PHY_READ(sc, BRGPHY_5708S_PG0_1000X_STAT1);
 
+            /* Check for MRBE auto-negotiated speed results. */
 			switch (xstat & BRGPHY_5708S_PG0_1000X_STAT1_SPEED_MASK) {
 			case BRGPHY_5708S_PG0_1000X_STAT1_SPEED_10:
 				mii->mii_media_active |= IFM_10_FL; break;
@@ -642,11 +649,40 @@ brgphy_status(struct mii_softc *sc)
 				mii->mii_media_active |= IFM_2500_SX; break;
 			}
 
+            /* Check for MRBE auto-negotiated duplex results. */
 			if (xstat & BRGPHY_5708S_PG0_1000X_STAT1_FDX)
 				mii->mii_media_active |= IFM_FDX;
 			else
 				mii->mii_media_active |= IFM_HDX;
-		}
+
+        } else if (bsc->serdes_flags & BRGPHY_5709S) {
+
+            /* Select GP Status Block of the AN MMD, get autoneg results. */
+            PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_GP_STATUS);
+			xstat = PHY_READ(sc, BRGPHY_GP_STATUS_TOP_ANEG_STATUS);
+
+            /* Restore IEEE0 block (assumed in all brgphy(4) code). */
+            PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
+
+            /* Check for MRBE auto-negotiated speed results. */
+            switch (xstat & BRGPHY_GP_STATUS_TOP_ANEG_SPEED_MASK) {
+			case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_10:
+				mii->mii_media_active |= IFM_10_FL; break;
+			case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_100:
+				mii->mii_media_active |= IFM_100_FX; break;
+			case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_1G:
+				mii->mii_media_active |= IFM_1000_SX; break;
+			case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_25G:
+				mii->mii_media_active |= IFM_2500_SX; break;
+			}
+
+            /* Check for MRBE auto-negotiated duplex results. */
+			if (xstat & BRGPHY_GP_STATUS_TOP_ANEG_FDX)
+				mii->mii_media_active |= IFM_FDX;
+			else
+				mii->mii_media_active |= IFM_HDX;
+        }
+
 	}
 
 #if 0
@@ -967,6 +1003,7 @@ brgphy_reset(struct mii_softc *sc)
 	struct bge_softc *bge_sc = NULL;
 	struct bce_softc *bce_sc = NULL;
 	struct ifnet *ifp;
+    int val;
 
 	/* Perform a standard PHY reset. */
 	mii_phy_reset(sc);
@@ -1089,7 +1126,49 @@ brgphy_reset(struct mii_softc *sc)
 					PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR,
 						BRGPHY_5708S_DIG_PG0);
 			}
-		} else if (BCE_CHIP_NUM(bce_sc) == BCE_CHIP_NUM_5709) {
+		} else if (BCE_CHIP_NUM(bce_sc) == BCE_CHIP_NUM_5709 &&
+			(bce_sc->bce_phy_flags & BCE_PHY_SERDES_FLAG)) {
+
+            /* Select the SerDes Digital block of the AN MMD. */
+            PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_SERDES_DIG);
+			val = PHY_READ(sc, BRGPHY_SERDES_DIG_1000X_CTL1);
+			val &= ~BRGPHY_SD_DIG_1000X_CTL1_AUTODET;
+			val |= BRGPHY_SD_DIG_1000X_CTL1_FIBER;
+			PHY_WRITE(sc, BRGPHY_SERDES_DIG_1000X_CTL1, val);
+
+            /* Select the Over 1G block of the AN MMD. */
+			PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_OVER_1G);
+
+            /* Enable autoneg "Next Page" to advertise 2.5G support. */
+            val = PHY_READ(sc, BRGPHY_OVER_1G_UNFORMAT_PG1);
+			if (bce_sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)
+				val |= BRGPHY_5708S_ANEG_NXT_PG_XMIT1_25G;
+			else
+				val &= ~BRGPHY_5708S_ANEG_NXT_PG_XMIT1_25G;
+			PHY_WRITE(sc, BRGPHY_OVER_1G_UNFORMAT_PG1, val);
+
+            /* Select the Multi-Rate Backplane Ethernet block of the AN MMD. */
+			PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_MRBE);
+
+            /* Enable MRBE speed autoneg. */
+            val = PHY_READ(sc, BRGPHY_MRBE_MSG_PG5_NP);
+			val |= BRGPHY_MRBE_MSG_PG5_NP_MBRE |
+			    BRGPHY_MRBE_MSG_PG5_NP_T2;
+			PHY_WRITE(sc, BRGPHY_MRBE_MSG_PG5_NP, val);
+
+            /* Select the Clause 73 User B0 block of the AN MMD. */
+            PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_CL73_USER_B0);
+
+            /* Enable MRBE speed autoneg. */
+			PHY_WRITE(sc, BRGPHY_CL73_USER_B0_MBRE_CTL1,
+			    BRGPHY_CL73_USER_B0_MBRE_CTL1_NP_AFT_BP |
+			    BRGPHY_CL73_USER_B0_MBRE_CTL1_STA_MGR |
+			    BRGPHY_CL73_USER_B0_MBRE_CTL1_ANEG);
+
+            /* Restore IEEE0 block (assumed in all brgphy(4) code). */
+            PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
+
+        } else if (BCE_CHIP_NUM(bce_sc) == BCE_CHIP_NUM_5709) {
 			if ((BCE_CHIP_REV(bce_sc) == BCE_CHIP_REV_Ax) ||
 				(BCE_CHIP_REV(bce_sc) == BCE_CHIP_REV_Bx))
 				brgphy_fixup_disable_early_dac(sc);

Modified: stable/8/sys/dev/mii/brgphyreg.h
==============================================================================
--- stable/8/sys/dev/mii/brgphyreg.h	Thu Apr 15 19:19:38 2010	(r206677)
+++ stable/8/sys/dev/mii/brgphyreg.h	Thu Apr 15 19:19:59 2010	(r206678)
@@ -359,6 +359,61 @@
 /* End: PHY register values for the 5708S SerDes PHY   */
 /*******************************************************/
 
+/*******************************************************/
+/* Begin: PHY register values for the 5709S SerDes PHY */
+/*******************************************************/
+
+/* 5709S SerDes "General Purpose Status" Registers */
+#define BRGPHY_BLOCK_ADDR_GP_STATUS		        0x8120
+#define BRGPHY_GP_STATUS_TOP_ANEG_STATUS	    0x1B
+#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_MASK	0x3F00
+#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_10	    0x0000
+#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_100	    0x0100
+#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_1G	    0x0200
+#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_25G	    0x0300
+#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_1GKX	0x0D00
+#define BRGPHY_GP_STATUS_TOP_ANEG_FDX		    0x0008
+#define BRGPHY_GP_STATUS_TOP_ANEG_LINK_UP	    0x0004
+#define BRGPHY_GP_STATUS_TOP_ANEG_CL73_COMP	    0x0001
+
+/* 5709S SerDes "SerDes Digital" Registers */
+#define BRGPHY_BLOCK_ADDR_SERDES_DIG		    0x8300
+#define	BRGPHY_SERDES_DIG_1000X_CTL1		    0x0010
+#define	BRGPHY_SD_DIG_1000X_CTL1_AUTODET	    0x0010
+#define	BRGPHY_SD_DIG_1000X_CTL1_FIBER		    0x0001
+
+/* 5709S SerDes "Over 1G" Registers */
+#define BRGPHY_BLOCK_ADDR_OVER_1G		        0x8320
+#define BRGPHY_OVER_1G_UNFORMAT_PG1		        0x19
+
+/* 5709S SerDes "Multi-Rate Backplane Ethernet" Registers */
+#define BRGPHY_BLOCK_ADDR_MRBE			        0x8350
+#define BRGPHY_MRBE_MSG_PG5_NP			        0x10
+#define BRGPHY_MRBE_MSG_PG5_NP_MBRE		        0x0001
+#define BRGPHY_MRBE_MSG_PG5_NP_T2		        0x0001
+
+/* 5709S SerDes "IEEE Clause 73 User B0" Registers */
+#define BRGPHY_BLOCK_ADDR_CL73_USER_B0		    0x8370
+#define BRGPHY_CL73_USER_B0_MBRE_CTL1		    0x12
+#define	BRGPHY_CL73_USER_B0_MBRE_CTL1_NP_AFT_BP	0x2000
+#define	BRGPHY_CL73_USER_B0_MBRE_CTL1_STA_MGR	0x4000
+#define	BRGPHY_CL73_USER_B0_MBRE_CTL1_ANEG	    0x8000
+
+/* 5709S SerDes "IEEE Clause 73 User B0" Registers */
+#define BRGPHY_BLOCK_ADDR_ADDR_EXT		        0xFFD0
+
+/* 5709S SerDes "Combo IEEE 0" Registers */
+#define BRGPHY_BLOCK_ADDR_COMBO_IEEE0		    0xFFE0
+
+#define BRGPHY_ADDR_EXT				            0x1E
+#define BRGPHY_BLOCK_ADDR			            0x1F
+
+#define BRGPHY_ADDR_EXT_AN_MMD			        0x3800
+
+/*******************************************************/
+/* End: PHY register values for the 5709S SerDes PHY   */
+/*******************************************************/
+
 #define	BRGPHY_INTRS	\
 	~(BRGPHY_IMR_LNK_CHG|BRGPHY_IMR_LSP_CHG|BRGPHY_IMR_DUP_CHG)
 

Modified: stable/8/sys/dev/mii/miidevs
==============================================================================
--- stable/8/sys/dev/mii/miidevs	Thu Apr 15 19:19:38 2010	(r206677)
+++ stable/8/sys/dev/mii/miidevs	Thu Apr 15 19:19:59 2010	(r206678)
@@ -157,6 +157,7 @@ model xxBROADCOM_ALT1 BCM5722	0x002d BCM
 model xxBROADCOM_ALT1 BCM5784	0x003a BCM5784 10/100/1000baseTX PHY
 model xxBROADCOM_ALT1 BCM5709C	0x003c BCM5709C 10/100/1000baseTX PHY
 model xxBROADCOM_ALT1 BCM5761	0x003d BCM5761 10/100/1000baseTX PHY
+model xxBROADCOM_ALT1 BCM5709S	0x003f BCM5709S 1000/2500baseSX PHY
 model BROADCOM2 BCM5906		0x0004 BCM5906 10/100baseTX PHY
 
 /* Cicada Semiconductor PHYs (now owned by Vitesse?) */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 8 dfilter service freebsd_committer freebsd_triage 2010-04-15 20:23:05 UTC
Author: yongari
Date: Thu Apr 15 19:22:55 2010
New Revision: 206679
URL: http://svn.freebsd.org/changeset/base/206679

Log:
  MFC r205299:
    - Added support for 5709S/5716S PHYs.
  
    Submitted by: pyunyh
    PR:	kern/134658, kern/136417, kern/139761, kern/140970

Modified:
  stable/7/sys/dev/mii/brgphy.c
  stable/7/sys/dev/mii/brgphyreg.h
  stable/7/sys/dev/mii/miidevs
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/   (props changed)
  stable/7/sys/contrib/dev/acpica/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/dev/mii/brgphy.c
==============================================================================
--- stable/7/sys/dev/mii/brgphy.c	Thu Apr 15 19:19:59 2010	(r206678)
+++ stable/7/sys/dev/mii/brgphy.c	Thu Apr 15 19:22:55 2010	(r206679)
@@ -75,6 +75,7 @@ struct brgphy_softc {
 #define BRGPHY_5706S		0x0001
 #define BRGPHY_5708S		0x0002
 #define BRGPHY_NOANWAIT		0x0004
+#define BRGPHY_5709S		0x0008
 	int bce_phy_flags;	/* PHY flags transferred from the MAC driver */
 };
 
@@ -139,6 +140,7 @@ static const struct mii_phydesc brgphys[
 	MII_PHY_DESC(xxBROADCOM_ALT1, BCM5784),
 	MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709C),
 	MII_PHY_DESC(xxBROADCOM_ALT1, BCM5761),
+    MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709S),
 	MII_PHY_DESC(BROADCOM2, BCM5906),
 	MII_PHY_END
 };
@@ -216,30 +218,34 @@ brgphy_attach(device_t dev)
 		break;
 	case MII_OUI_xxBROADCOM:
 		switch (bsc->mii_model) {
-			case MII_MODEL_xxBROADCOM_BCM5706:
-			case MII_MODEL_xxBROADCOM_BCM5714:
-				/*
-				 * The 5464 PHY used in the 5706 supports both copper
-				 * and fiber interfaces over GMII.  Need to check the
-				 * shadow registers to see which mode is actually
-				 * in effect, and therefore whether we have 5706C or
-				 * 5706S.
-				 */
-				PHY_WRITE(sc, BRGPHY_MII_SHADOW_1C,
-					BRGPHY_SHADOW_1C_MODE_CTRL);
-				if (PHY_READ(sc, BRGPHY_MII_SHADOW_1C) &
-					BRGPHY_SHADOW_1C_ENA_1000X) {
-					bsc->serdes_flags |= BRGPHY_5706S;
-					sc->mii_flags |= MIIF_HAVEFIBER;
-				}
-				break;
+		case MII_MODEL_xxBROADCOM_BCM5706:
+		case MII_MODEL_xxBROADCOM_BCM5714:
+			/*
+			 * The 5464 PHY used in the 5706 supports both copper
+			 * and fiber interfaces over GMII.  Need to check the
+			 * shadow registers to see which mode is actually
+			 * in effect, and therefore whether we have 5706C or
+			 * 5706S.
+			 */
+			PHY_WRITE(sc, BRGPHY_MII_SHADOW_1C,
+				BRGPHY_SHADOW_1C_MODE_CTRL);
+			if (PHY_READ(sc, BRGPHY_MII_SHADOW_1C) &
+				BRGPHY_SHADOW_1C_ENA_1000X) {
+				bsc->serdes_flags |= BRGPHY_5706S;
+				sc->mii_flags |= MIIF_HAVEFIBER;
+			}
+			break;
 		} break;
 	case MII_OUI_xxBROADCOM_ALT1:
 		switch (bsc->mii_model) {
-			case MII_MODEL_xxBROADCOM_ALT1_BCM5708S:
-				bsc->serdes_flags |= BRGPHY_5708S;
-				sc->mii_flags |= MIIF_HAVEFIBER;
-				break;
+		case MII_MODEL_xxBROADCOM_ALT1_BCM5708S:
+			bsc->serdes_flags |= BRGPHY_5708S;
+			sc->mii_flags |= MIIF_HAVEFIBER;
+			break;
+        case MII_MODEL_xxBROADCOM_ALT1_BCM5709S:
+            bsc->serdes_flags |= BRGPHY_5709S;
+            sc->mii_flags |= MIIF_HAVEFIBER;
+            break;
 		} break;
 	default:
 		device_printf(dev, "Unrecognized OUI for PHY!\n");
@@ -619,6 +625,7 @@ brgphy_status(struct mii_softc *sc)
 			PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, BRGPHY_5708S_DIG_PG0);
 			xstat = PHY_READ(sc, BRGPHY_5708S_PG0_1000X_STAT1);
 
+            /* Check for MRBE auto-negotiated speed results. */
 			switch (xstat & BRGPHY_5708S_PG0_1000X_STAT1_SPEED_MASK) {
 			case BRGPHY_5708S_PG0_1000X_STAT1_SPEED_10:
 				mii->mii_media_active |= IFM_10_FL; break;
@@ -630,11 +637,40 @@ brgphy_status(struct mii_softc *sc)
 				mii->mii_media_active |= IFM_2500_SX; break;
 			}
 
+            /* Check for MRBE auto-negotiated duplex results. */
 			if (xstat & BRGPHY_5708S_PG0_1000X_STAT1_FDX)
 				mii->mii_media_active |= IFM_FDX;
 			else
 				mii->mii_media_active |= IFM_HDX;
-		}
+
+        } else if (bsc->serdes_flags & BRGPHY_5709S) {
+
+            /* Select GP Status Block of the AN MMD, get autoneg results. */
+            PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_GP_STATUS);
+			xstat = PHY_READ(sc, BRGPHY_GP_STATUS_TOP_ANEG_STATUS);
+
+            /* Restore IEEE0 block (assumed in all brgphy(4) code). */
+            PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
+
+            /* Check for MRBE auto-negotiated speed results. */
+            switch (xstat & BRGPHY_GP_STATUS_TOP_ANEG_SPEED_MASK) {
+			case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_10:
+				mii->mii_media_active |= IFM_10_FL; break;
+			case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_100:
+				mii->mii_media_active |= IFM_100_FX; break;
+			case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_1G:
+				mii->mii_media_active |= IFM_1000_SX; break;
+			case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_25G:
+				mii->mii_media_active |= IFM_2500_SX; break;
+			}
+
+            /* Check for MRBE auto-negotiated duplex results. */
+			if (xstat & BRGPHY_GP_STATUS_TOP_ANEG_FDX)
+				mii->mii_media_active |= IFM_FDX;
+			else
+				mii->mii_media_active |= IFM_HDX;
+        }
+
 	}
 
 #if 0
@@ -955,6 +991,7 @@ brgphy_reset(struct mii_softc *sc)
 	struct bge_softc *bge_sc = NULL;
 	struct bce_softc *bce_sc = NULL;
 	struct ifnet *ifp;
+    int val;
 
 	/* Perform a standard PHY reset. */
 	mii_phy_reset(sc);
@@ -1077,7 +1114,49 @@ brgphy_reset(struct mii_softc *sc)
 					PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR,
 						BRGPHY_5708S_DIG_PG0);
 			}
-		} else if (BCE_CHIP_NUM(bce_sc) == BCE_CHIP_NUM_5709) {
+		} else if (BCE_CHIP_NUM(bce_sc) == BCE_CHIP_NUM_5709 &&
+			(bce_sc->bce_phy_flags & BCE_PHY_SERDES_FLAG)) {
+
+            /* Select the SerDes Digital block of the AN MMD. */
+            PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_SERDES_DIG);
+			val = PHY_READ(sc, BRGPHY_SERDES_DIG_1000X_CTL1);
+			val &= ~BRGPHY_SD_DIG_1000X_CTL1_AUTODET;
+			val |= BRGPHY_SD_DIG_1000X_CTL1_FIBER;
+			PHY_WRITE(sc, BRGPHY_SERDES_DIG_1000X_CTL1, val);
+
+            /* Select the Over 1G block of the AN MMD. */
+			PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_OVER_1G);
+
+            /* Enable autoneg "Next Page" to advertise 2.5G support. */
+            val = PHY_READ(sc, BRGPHY_OVER_1G_UNFORMAT_PG1);
+			if (bce_sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)
+				val |= BRGPHY_5708S_ANEG_NXT_PG_XMIT1_25G;
+			else
+				val &= ~BRGPHY_5708S_ANEG_NXT_PG_XMIT1_25G;
+			PHY_WRITE(sc, BRGPHY_OVER_1G_UNFORMAT_PG1, val);
+
+            /* Select the Multi-Rate Backplane Ethernet block of the AN MMD. */
+			PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_MRBE);
+
+            /* Enable MRBE speed autoneg. */
+            val = PHY_READ(sc, BRGPHY_MRBE_MSG_PG5_NP);
+			val |= BRGPHY_MRBE_MSG_PG5_NP_MBRE |
+			    BRGPHY_MRBE_MSG_PG5_NP_T2;
+			PHY_WRITE(sc, BRGPHY_MRBE_MSG_PG5_NP, val);
+
+            /* Select the Clause 73 User B0 block of the AN MMD. */
+            PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_CL73_USER_B0);
+
+            /* Enable MRBE speed autoneg. */
+			PHY_WRITE(sc, BRGPHY_CL73_USER_B0_MBRE_CTL1,
+			    BRGPHY_CL73_USER_B0_MBRE_CTL1_NP_AFT_BP |
+			    BRGPHY_CL73_USER_B0_MBRE_CTL1_STA_MGR |
+			    BRGPHY_CL73_USER_B0_MBRE_CTL1_ANEG);
+
+            /* Restore IEEE0 block (assumed in all brgphy(4) code). */
+            PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
+
+        } else if (BCE_CHIP_NUM(bce_sc) == BCE_CHIP_NUM_5709) {
 			if ((BCE_CHIP_REV(bce_sc) == BCE_CHIP_REV_Ax) ||
 				(BCE_CHIP_REV(bce_sc) == BCE_CHIP_REV_Bx))
 				brgphy_fixup_disable_early_dac(sc);

Modified: stable/7/sys/dev/mii/brgphyreg.h
==============================================================================
--- stable/7/sys/dev/mii/brgphyreg.h	Thu Apr 15 19:19:59 2010	(r206678)
+++ stable/7/sys/dev/mii/brgphyreg.h	Thu Apr 15 19:22:55 2010	(r206679)
@@ -359,6 +359,61 @@
 /* End: PHY register values for the 5708S SerDes PHY   */
 /*******************************************************/
 
+/*******************************************************/
+/* Begin: PHY register values for the 5709S SerDes PHY */
+/*******************************************************/
+
+/* 5709S SerDes "General Purpose Status" Registers */
+#define BRGPHY_BLOCK_ADDR_GP_STATUS		        0x8120
+#define BRGPHY_GP_STATUS_TOP_ANEG_STATUS	    0x1B
+#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_MASK	0x3F00
+#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_10	    0x0000
+#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_100	    0x0100
+#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_1G	    0x0200
+#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_25G	    0x0300
+#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_1GKX	0x0D00
+#define BRGPHY_GP_STATUS_TOP_ANEG_FDX		    0x0008
+#define BRGPHY_GP_STATUS_TOP_ANEG_LINK_UP	    0x0004
+#define BRGPHY_GP_STATUS_TOP_ANEG_CL73_COMP	    0x0001
+
+/* 5709S SerDes "SerDes Digital" Registers */
+#define BRGPHY_BLOCK_ADDR_SERDES_DIG		    0x8300
+#define	BRGPHY_SERDES_DIG_1000X_CTL1		    0x0010
+#define	BRGPHY_SD_DIG_1000X_CTL1_AUTODET	    0x0010
+#define	BRGPHY_SD_DIG_1000X_CTL1_FIBER		    0x0001
+
+/* 5709S SerDes "Over 1G" Registers */
+#define BRGPHY_BLOCK_ADDR_OVER_1G		        0x8320
+#define BRGPHY_OVER_1G_UNFORMAT_PG1		        0x19
+
+/* 5709S SerDes "Multi-Rate Backplane Ethernet" Registers */
+#define BRGPHY_BLOCK_ADDR_MRBE			        0x8350
+#define BRGPHY_MRBE_MSG_PG5_NP			        0x10
+#define BRGPHY_MRBE_MSG_PG5_NP_MBRE		        0x0001
+#define BRGPHY_MRBE_MSG_PG5_NP_T2		        0x0001
+
+/* 5709S SerDes "IEEE Clause 73 User B0" Registers */
+#define BRGPHY_BLOCK_ADDR_CL73_USER_B0		    0x8370
+#define BRGPHY_CL73_USER_B0_MBRE_CTL1		    0x12
+#define	BRGPHY_CL73_USER_B0_MBRE_CTL1_NP_AFT_BP	0x2000
+#define	BRGPHY_CL73_USER_B0_MBRE_CTL1_STA_MGR	0x4000
+#define	BRGPHY_CL73_USER_B0_MBRE_CTL1_ANEG	    0x8000
+
+/* 5709S SerDes "IEEE Clause 73 User B0" Registers */
+#define BRGPHY_BLOCK_ADDR_ADDR_EXT		        0xFFD0
+
+/* 5709S SerDes "Combo IEEE 0" Registers */
+#define BRGPHY_BLOCK_ADDR_COMBO_IEEE0		    0xFFE0
+
+#define BRGPHY_ADDR_EXT				            0x1E
+#define BRGPHY_BLOCK_ADDR			            0x1F
+
+#define BRGPHY_ADDR_EXT_AN_MMD			        0x3800
+
+/*******************************************************/
+/* End: PHY register values for the 5709S SerDes PHY   */
+/*******************************************************/
+
 #define	BRGPHY_INTRS	\
 	~(BRGPHY_IMR_LNK_CHG|BRGPHY_IMR_LSP_CHG|BRGPHY_IMR_DUP_CHG)
 

Modified: stable/7/sys/dev/mii/miidevs
==============================================================================
--- stable/7/sys/dev/mii/miidevs	Thu Apr 15 19:19:59 2010	(r206678)
+++ stable/7/sys/dev/mii/miidevs	Thu Apr 15 19:22:55 2010	(r206679)
@@ -152,6 +152,7 @@ model xxBROADCOM_ALT1 BCM5722	0x002d BCM
 model xxBROADCOM_ALT1 BCM5784	0x003a BCM5784 10/100/1000baseTX PHY
 model xxBROADCOM_ALT1 BCM5709C	0x003c BCM5709C 10/100/1000baseTX PHY
 model xxBROADCOM_ALT1 BCM5761	0x003d BCM5761 10/100/1000baseTX PHY
+model xxBROADCOM_ALT1 BCM5709S	0x003f BCM5709S 1000/2500baseSX PHY
 model BROADCOM2 BCM5906		0x0004 BCM5906 10/100baseTX PHY
 
 /* Cicada Semiconductor PHYs (now owned by Vitesse?) */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 9 dfilter service freebsd_committer freebsd_triage 2010-04-15 20:26:37 UTC
Author: yongari
Date: Thu Apr 15 19:26:28 2010
New Revision: 206680
URL: http://svn.freebsd.org/changeset/base/206680

Log:
  MFC r205300:
    - Added support for 5709S/5716S PHYs.
    - Update copyright to 2010.
    - Add new debug code for RV2P block.
    - Improve output formatting for various debug functions.
  
    PR:	kern/134658, kern/136417, kern/139761, kern/140970

Modified:
  stable/8/sys/dev/bce/if_bce.c
  stable/8/sys/dev/bce/if_bcefw.h
  stable/8/sys/dev/bce/if_bcereg.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/dev/bce/if_bce.c
==============================================================================
--- stable/8/sys/dev/bce/if_bce.c	Thu Apr 15 19:22:55 2010	(r206679)
+++ stable/8/sys/dev/bce/if_bce.c	Thu Apr 15 19:26:28 2010	(r206680)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2006-2009 Broadcom Corporation
+ * Copyright (c) 2006-2010 Broadcom Corporation
  *	David Christensen <davidch@broadcom.com>.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,9 @@ __FBSDID("$FreeBSD$");
  *   BCM5708C B1, B2
  *   BCM5708S B1, B2
  *   BCM5709C A1, C0
+ *   BCM5709S A1, C0
  * 	 BCM5716C C0
+ * 	 BCM5716S C0
  *
  * The following controllers are not supported by this driver:
  *   BCM5706C A0, A1 (pre-production)
@@ -46,7 +48,7 @@ __FBSDID("$FreeBSD$");
  *   BCM5708C A0, B0 (pre-production)
  *   BCM5708S A0, B0 (pre-production)
  *   BCM5709C A0  B0, B1, B2 (pre-production)
- *   BCM5709S A0, A1, B0, B1, B2, C0 (pre-production)
+ *   BCM5709S A0, B0, B1, B2 (pre-production)
  */
 
 #include "opt_bce.h"
@@ -320,6 +322,7 @@ static void bce_dump_rxp_state		(struct 
 static void bce_dump_tpat_state		(struct bce_softc *, int);
 static void bce_dump_cp_state		(struct bce_softc *, int);
 static void bce_dump_com_state		(struct bce_softc *, int);
+static void bce_dump_rv2p_state		(struct bce_softc *);
 static void bce_breakpoint			(struct bce_softc *);
 #endif
 
@@ -360,6 +363,7 @@ static int  bce_nvram_write			(struct bc
 /*                                                                          */
 /****************************************************************************/
 static void bce_get_media			(struct bce_softc *);
+static void bce_init_media			(struct bce_softc *);
 static void bce_dma_map_addr		(void *, bus_dma_segment_t *, int, int);
 static int  bce_dma_alloc			(device_t);
 static void bce_dma_free			(struct bce_softc *);
@@ -1096,7 +1100,10 @@ bce_attach(device_t dev)
 	else
 		ifp->if_baudrate = IF_Mbps(1000);
 
-	/* Check for an MII child bus by probing the PHY. */
+    /* Handle any special PHY initialization for SerDes PHYs. */
+    bce_init_media(sc);
+
+	/* MII child bus by probing the PHY. */
 	if (mii_phy_probe(dev, &sc->bce_miibus, bce_ifmedia_upd,
 		bce_ifmedia_sts)) {
 		BCE_PRINTF("%s(%d): No PHY found on child MII bus!\n",
@@ -1504,7 +1511,17 @@ bce_miibus_read_reg(device_t dev, int ph
 		return(0);
 	}
 
-	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
+    /*
+     * The 5709S PHY is an IEEE Clause 45 PHY
+     * with special mappings to work with IEEE
+     * Clause 22 register accesses.
+     */
+	if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
+		if (reg >= MII_BMCR && reg <= MII_ANLPRNP)
+			reg += 0x10;
+	}
+
+    if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
 		val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
 		val &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
 
@@ -1584,6 +1601,16 @@ bce_miibus_write_reg(device_t dev, int p
 
 	DB_PRINT_PHY_REG(reg, val);
 
+    /*
+     * The 5709S PHY is an IEEE Clause 45 PHY
+     * with special mappings to work with IEEE
+     * Clause 22 register accesses.
+     */
+	if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
+		if (reg >= MII_BMCR && reg <= MII_ANLPRNP)
+			reg += 0x10;
+	}
+
 	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
 		val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
 		val1 &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
@@ -2647,9 +2674,11 @@ bce_get_media(struct bce_softc *sc)
 				DBPRINT(sc, BCE_INFO_LOAD,
 					"BCM5709 s/w configured for SerDes.\n");
 				sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
+                break;
 			default:
 				DBPRINT(sc, BCE_INFO_LOAD,
 					"BCM5709 s/w configured for Copper.\n");
+                break;
 			}
 		} else {
 			switch (strap) {
@@ -2659,9 +2688,11 @@ bce_get_media(struct bce_softc *sc)
 				DBPRINT(sc, BCE_INFO_LOAD,
 					"BCM5709 s/w configured for SerDes.\n");
 				sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
+                break;
 			default:
 				DBPRINT(sc, BCE_INFO_LOAD,
 					"BCM5709 s/w configured for Copper.\n");
+                break;
 			}
 		}
 
@@ -2669,15 +2700,22 @@ bce_get_media(struct bce_softc *sc)
 		sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
 
 	if (sc->bce_phy_flags & BCE_PHY_SERDES_FLAG) {
+
 		sc->bce_flags |= BCE_NO_WOL_FLAG;
-		if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
+
+		/* 5708S, 5709S, and 5716S use a separate PHY for SerDes. */
+		if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) 
 			sc->bce_phy_addr = 2;
+
+		if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
+			sc->bce_phy_flags |= BCE_PHY_IEEE_CLAUSE_45_FLAG;
+
 			val = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG);
 			if (val & BCE_SHARED_HW_CFG_PHY_2_5G) {
 				sc->bce_phy_flags |= BCE_PHY_2_5G_CAPABLE_FLAG;
 				DBPRINT(sc, BCE_INFO_LOAD, "Found 2.5Gb capable adapter\n");
 			}
-		}
+        }
 	} else if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) ||
 		   (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708))
 		sc->bce_phy_flags |= BCE_PHY_CRC_FIX_FLAG;
@@ -2691,6 +2729,37 @@ bce_get_media_exit:
 
 
 /****************************************************************************/
+/* Performs PHY initialization required before MII drivers access the       */
+/* device.                                                                  */
+/*                                                                          */
+/* Returns:                                                                 */
+/*   Nothing.                                                               */
+/****************************************************************************/
+static void
+bce_init_media(struct bce_softc *sc)
+{
+	if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
+		/*
+		 * Configure 5709S/5716S PHYs to use traditional IEEE
+		 * Clause 22 method. Otherwise we have no way to attach
+		 * the PHY in mii(4) layer. PHY specific configuration
+		 * is done in mii layer.
+		 */
+
+        /* Select auto-negotiation MMD of the PHY. */
+        bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
+		    BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_ADDR_EXT);
+		bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
+		    BRGPHY_ADDR_EXT, BRGPHY_ADDR_EXT_AN_MMD);
+
+        /* Select IEEE0 block of AN MMD (assumed in all brgphy(4) code). */
+		bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
+		    BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
+	}
+}
+
+
+/****************************************************************************/
 /* Free any DMA memory owned by the driver.                                 */
 /*                                                                          */
 /* Scans through each data structre that requires DMA memory and frees      */
@@ -6679,7 +6748,7 @@ bce_tso_setup(struct bce_softc *sc, stru
 
 	DBPRINT(sc, BCE_EXTREME_SEND, "%s(): hdr_len = %d, e_hlen = %d, "
 	    "ip_hlen = %d, tcp_hlen = %d, ip_len = %d\n",
-	    __FUNCTION__, hdr_len, sizeof(struct ether_header), ip_hlen,
+	    __FUNCTION__, hdr_len, (int) sizeof(struct ether_header), ip_hlen,
 	    tcp_hlen, ip_len);
 
 	/* Set the LSO flag in the TX BD */
@@ -7943,7 +8012,7 @@ bce_sysctl_dump_tx_chain(SYSCTL_HANDLER_
 
         if (result == 1) {
                 sc = (struct bce_softc *)arg1;
-                bce_dump_tx_chain(sc, 0, USABLE_TX_BD);
+                bce_dump_tx_chain(sc, 0, TOTAL_TX_BD);
         }
 
         return error;
@@ -8626,7 +8695,7 @@ bce_add_sysctls(struct bce_softc *sc)
 /* Returns:                                                                 */
 /*   Nothing.                                                               */
 /****************************************************************************/
-static void
+static __attribute__ ((noinline)) void
 bce_freeze_controller(struct bce_softc *sc)
 {
 	u32 val;
@@ -8643,7 +8712,7 @@ bce_freeze_controller(struct bce_softc *
 /* Returns:                                                                 */
 /*   Nothing.                                                               */
 /****************************************************************************/
-static void
+static __attribute__ ((noinline)) void
 bce_unfreeze_controller(struct bce_softc *sc)
 {
 	u32 val;
@@ -8661,7 +8730,7 @@ bce_unfreeze_controller(struct bce_softc
 /* Returns:                                                                 */
 /*   Nothing.                                                               */
 /****************************************************************************/
-static void
+static __attribute__ ((noinline)) void
 bce_dump_enet(struct bce_softc *sc, struct mbuf *m)
 {
 	struct ether_vlan_header *eh;
@@ -8915,7 +8984,9 @@ bce_dump_pg_mbuf_chain(struct bce_softc 
 static __attribute__ ((noinline)) void
 bce_dump_txbd(struct bce_softc *sc, int idx, struct tx_bd *txbd)
 {
-	if (idx > MAX_TX_BD)
+    int i = 0;
+
+    if (idx > MAX_TX_BD)
 		/* Index out of range. */
 		BCE_PRINTF("tx_bd[0x%04X]: Invalid tx_bd index!\n", idx);
 	else if ((idx & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
@@ -8923,52 +8994,65 @@ bce_dump_txbd(struct bce_softc *sc, int 
 		BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
 			idx, txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo);
 	else {
-			/* Normal tx_bd entry. */
-			BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
-				"vlan tag= 0x%04X, flags = 0x%04X (", idx,
-				txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo,
-				txbd->tx_bd_mss_nbytes, txbd->tx_bd_vlan_tag,
-				txbd->tx_bd_flags);
-
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_CONN_FAULT)
-				printf(" CONN_FAULT");
-
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_TCP_UDP_CKSUM)
-				printf(" TCP_UDP_CKSUM");
+		/* Normal tx_bd entry. */
+		BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, mss_nbytes = 0x%08X, "
+			"vlan tag = 0x%04X, flags = 0x%04X (", idx,
+			txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo,
+			txbd->tx_bd_mss_nbytes, txbd->tx_bd_vlan_tag,
+			txbd->tx_bd_flags);
 
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_IP_CKSUM)
-				printf(" IP_CKSUM");
+		if (txbd->tx_bd_flags & TX_BD_FLAGS_CONN_FAULT) {
+			if (i>0) printf("|"); printf("CONN_FAULT"); i++;
+        }
 
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_VLAN_TAG)
-				printf("  VLAN");
+		if (txbd->tx_bd_flags & TX_BD_FLAGS_TCP_UDP_CKSUM) {
+            if (i>0) printf("|"); printf("TCP_UDP_CKSUM"); i++;
+        }
 
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_COAL_NOW)
-				printf(" COAL_NOW");
+        if (txbd->tx_bd_flags & TX_BD_FLAGS_IP_CKSUM) {
+            if (i>0) printf("|"); printf("IP_CKSUM"); i++;
+        }
 
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_DONT_GEN_CRC)
-				printf(" DONT_GEN_CRC");
+		if (txbd->tx_bd_flags & TX_BD_FLAGS_VLAN_TAG) {
+            if (i>0) printf("|"); printf("VLAN"); i++;
+        }
 
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_START)
-				printf(" START");
+		if (txbd->tx_bd_flags & TX_BD_FLAGS_COAL_NOW) {
+            if (i>0) printf("|"); printf("COAL_NOW"); i++;
+        }
 
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_END)
-				printf(" END");
+        if (txbd->tx_bd_flags & TX_BD_FLAGS_DONT_GEN_CRC) {
+            if (i>0) printf("|"); printf("DONT_GEN_CRC"); i++;
+        }
 
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_LSO)
-				printf(" LSO");
+        if (txbd->tx_bd_flags & TX_BD_FLAGS_START) {
+            if (i>0) printf("|"); printf("START"); i++;
+        }
 
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_OPTION_WORD)
-				printf(" OPTION_WORD");
+		if (txbd->tx_bd_flags & TX_BD_FLAGS_END) {
+            if (i>0) printf("|"); printf("END"); i++;
+        }
 
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_FLAGS)
-				printf(" FLAGS");
+		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_LSO) {
+            if (i>0) printf("|"); printf("LSO"); i++;
+        }
 
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_SNAP)
-				printf(" SNAP");
+        if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_OPTION_WORD) {
+            if (i>0) printf("|"); 
+            printf("SW_OPTION=%d", ((txbd->tx_bd_flags & 
+                TX_BD_FLAGS_SW_OPTION_WORD) >> 8)); i++;
+        }
 
-			printf(" )\n");
-		}
+		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_FLAGS) {
+            if (i>0) printf("|"); printf("SW_FLAGS"); i++;
+        }
 
+		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_SNAP) {
+            if (i>0) printf("|"); printf("SNAP)");
+        } else {
+            printf(")\n");
+        }
+    }
 }
 
 
@@ -9415,10 +9499,8 @@ bce_dump_tx_chain(struct bce_softc *sc, 
 
 	BCE_PRINTF("page size      = 0x%08X, tx chain pages        = 0x%08X\n",
 		(u32) BCM_PAGE_SIZE, (u32) TX_PAGES);
-
 	BCE_PRINTF("tx_bd per page = 0x%08X, usable tx_bd per page = 0x%08X\n",
 		(u32) TOTAL_TX_BD_PER_PAGE, (u32) USABLE_TX_BD_PER_PAGE);
-
 	BCE_PRINTF("total tx_bd    = 0x%08X\n", (u32) TOTAL_TX_BD);
 
 	BCE_PRINTF(
@@ -9426,11 +9508,11 @@ bce_dump_tx_chain(struct bce_softc *sc, 
 		"   tx_bd data   "
 		"----------------------------\n");
 
-	/* Now print out the tx_bd's themselves. */
+	/* Now print out a decoded list of TX buffer descriptors. */
 	for (int i = 0; i < count; i++) {
 	 	txbd = &sc->tx_bd_chain[TX_PAGE(tx_prod)][TX_IDX(tx_prod)];
 		bce_dump_txbd(sc, tx_prod, txbd);
-		tx_prod = NEXT_TX_BD(tx_prod);
+		tx_prod++;
 	}
 
 	BCE_PRINTF(
@@ -9530,6 +9612,17 @@ bce_dump_pg_chain(struct bce_softc *sc, 
 }
 #endif
 
+#define BCE_PRINT_RX_CONS(arg)                                          \
+if (sblk->status_rx_quick_consumer_index##arg)                          \
+    BCE_PRINTF("0x%04X(0x%04X) - rx_quick_consumer_index##arg\n",       \
+		sblk->status_rx_quick_consumer_index##arg,                      \
+		(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index##arg));
+
+#define BCE_PRINT_TX_CONS(arg)                                          \
+if (sblk->status_tx_quick_consumer_index##arg)                          \
+    BCE_PRINTF("0x%04X(0x%04X) - tx_quick_consumer_index##arg\n",       \
+        sblk->status_tx_quick_consumer_index##arg,                      \
+        (u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index##arg));
 
 /****************************************************************************/
 /* Prints out the status block from host memory.                            */
@@ -9549,90 +9642,28 @@ bce_dump_status_block(struct bce_softc *
 		"  Status Block  "
 		"----------------------------\n");
 
+    /* Theses indices are used for normal L2 drivers. */
 	BCE_PRINTF("    0x%08X - attn_bits\n",
 		sblk->status_attn_bits);
 
 	BCE_PRINTF("    0x%08X - attn_bits_ack\n",
 		sblk->status_attn_bits_ack);
 
-	BCE_PRINTF("0x%04X(0x%04X) - rx_cons0\n",
-		sblk->status_rx_quick_consumer_index0,
-		(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index0));
-
-	BCE_PRINTF("0x%04X(0x%04X) - tx_cons0\n",
-		sblk->status_tx_quick_consumer_index0,
-		(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index0));
+    BCE_PRINT_RX_CONS(0);
+    BCE_PRINT_TX_CONS(0)
 
 	BCE_PRINTF("        0x%04X - status_idx\n", sblk->status_idx);
 
 	/* Theses indices are not used for normal L2 drivers. */
-	if (sblk->status_rx_quick_consumer_index1)
-		BCE_PRINTF("0x%04X(0x%04X) - rx_cons1\n",
-			sblk->status_rx_quick_consumer_index1,
-			(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index1));
-
-	if (sblk->status_tx_quick_consumer_index1)
-		BCE_PRINTF("0x%04X(0x%04X) - tx_cons1\n",
-			sblk->status_tx_quick_consumer_index1,
-			(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index1));
-
-	if (sblk->status_rx_quick_consumer_index2)
-		BCE_PRINTF("0x%04X(0x%04X)- rx_cons2\n",
-			sblk->status_rx_quick_consumer_index2,
-			(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index2));
-
-	if (sblk->status_tx_quick_consumer_index2)
-		BCE_PRINTF("0x%04X(0x%04X) - tx_cons2\n",
-			sblk->status_tx_quick_consumer_index2,
-			(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index2));
-
-	if (sblk->status_rx_quick_consumer_index3)
-		BCE_PRINTF("0x%04X(0x%04X) - rx_cons3\n",
-			sblk->status_rx_quick_consumer_index3,
-			(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index3));
-
-	if (sblk->status_tx_quick_consumer_index3)
-		BCE_PRINTF("0x%04X(0x%04X) - tx_cons3\n",
-			sblk->status_tx_quick_consumer_index3,
-			(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index3));
-
-	if (sblk->status_rx_quick_consumer_index4 ||
-		sblk->status_rx_quick_consumer_index5)
-		BCE_PRINTF("rx_cons4  = 0x%08X, rx_cons5      = 0x%08X\n",
-			sblk->status_rx_quick_consumer_index4,
-			sblk->status_rx_quick_consumer_index5);
-
-	if (sblk->status_rx_quick_consumer_index6 ||
-		sblk->status_rx_quick_consumer_index7)
-		BCE_PRINTF("rx_cons6  = 0x%08X, rx_cons7      = 0x%08X\n",
-			sblk->status_rx_quick_consumer_index6,
-			sblk->status_rx_quick_consumer_index7);
-
-	if (sblk->status_rx_quick_consumer_index8 ||
-		sblk->status_rx_quick_consumer_index9)
-		BCE_PRINTF("rx_cons8  = 0x%08X, rx_cons9      = 0x%08X\n",
-			sblk->status_rx_quick_consumer_index8,
-			sblk->status_rx_quick_consumer_index9);
-
-	if (sblk->status_rx_quick_consumer_index10 ||
-		sblk->status_rx_quick_consumer_index11)
-		BCE_PRINTF("rx_cons10 = 0x%08X, rx_cons11     = 0x%08X\n",
-			sblk->status_rx_quick_consumer_index10,
-			sblk->status_rx_quick_consumer_index11);
-
-	if (sblk->status_rx_quick_consumer_index12 ||
-		sblk->status_rx_quick_consumer_index13)
-		BCE_PRINTF("rx_cons12 = 0x%08X, rx_cons13     = 0x%08X\n",
-			sblk->status_rx_quick_consumer_index12,
-			sblk->status_rx_quick_consumer_index13);
-
-	if (sblk->status_rx_quick_consumer_index14 ||
-		sblk->status_rx_quick_consumer_index15)
-		BCE_PRINTF("rx_cons14 = 0x%08X, rx_cons15     = 0x%08X\n",
-			sblk->status_rx_quick_consumer_index14,
-			sblk->status_rx_quick_consumer_index15);
+    BCE_PRINT_RX_CONS(1);   BCE_PRINT_RX_CONS(2);   BCE_PRINT_RX_CONS(3);
+    BCE_PRINT_RX_CONS(4);   BCE_PRINT_RX_CONS(5);   BCE_PRINT_RX_CONS(6);
+    BCE_PRINT_RX_CONS(7);   BCE_PRINT_RX_CONS(8);   BCE_PRINT_RX_CONS(9);
+    BCE_PRINT_RX_CONS(10);  BCE_PRINT_RX_CONS(11);  BCE_PRINT_RX_CONS(12);
+    BCE_PRINT_RX_CONS(13);  BCE_PRINT_RX_CONS(14);  BCE_PRINT_RX_CONS(15);
 
-	if (sblk->status_completion_producer_index ||
+    BCE_PRINT_TX_CONS(1);   BCE_PRINT_TX_CONS(2);   BCE_PRINT_TX_CONS(3);
+
+    if (sblk->status_completion_producer_index ||
 		sblk->status_cmd_consumer_index)
 		BCE_PRINTF("com_prod  = 0x%08X, cmd_cons      = 0x%08X\n",
 			sblk->status_completion_producer_index,
@@ -9645,6 +9676,14 @@ bce_dump_status_block(struct bce_softc *
 }
 
 
+#define BCE_PRINT_64BIT_STAT(arg)                                       \
+if (sblk->arg##_lo || sblk->arg##_hi)                               \
+	BCE_PRINTF("0x%08X:%08X : arg\n", sblk->arg##_hi, sblk->arg##_lo);
+
+#define BCE_PRINT_32BIT_STAT(arg)                                       \
+if (sblk->arg)                                                        \
+	BCE_PRINTF("         0x%08X : arg\n", sblk->arg);
+
 /****************************************************************************/
 /* Prints out the statistics block from host memory.                        */
 /*                                                                          */
@@ -9663,252 +9702,60 @@ bce_dump_stats_block(struct bce_softc *s
 		" Stats Block  (All Stats Not Shown Are 0) "
 		"---------------\n");
 
-	if (sblk->stat_IfHCInOctets_hi
-		|| sblk->stat_IfHCInOctets_lo)
-		BCE_PRINTF("0x%08X:%08X : "
-			"IfHcInOctets\n",
-			sblk->stat_IfHCInOctets_hi,
-			sblk->stat_IfHCInOctets_lo);
-
-	if (sblk->stat_IfHCInBadOctets_hi
-		|| sblk->stat_IfHCInBadOctets_lo)
-		BCE_PRINTF("0x%08X:%08X : "
-			"IfHcInBadOctets\n",
-			sblk->stat_IfHCInBadOctets_hi,
-			sblk->stat_IfHCInBadOctets_lo);
-
-	if (sblk->stat_IfHCOutOctets_hi
-		|| sblk->stat_IfHCOutOctets_lo)
-		BCE_PRINTF("0x%08X:%08X : "
-			"IfHcOutOctets\n",
-			sblk->stat_IfHCOutOctets_hi,
-			sblk->stat_IfHCOutOctets_lo);
-
-	if (sblk->stat_IfHCOutBadOctets_hi
-		|| sblk->stat_IfHCOutBadOctets_lo)
-		BCE_PRINTF("0x%08X:%08X : "
-			"IfHcOutBadOctets\n",
-			sblk->stat_IfHCOutBadOctets_hi,
-			sblk->stat_IfHCOutBadOctets_lo);
-
-	if (sblk->stat_IfHCInUcastPkts_hi
-		|| sblk->stat_IfHCInUcastPkts_lo)
-		BCE_PRINTF("0x%08X:%08X : "
-			"IfHcInUcastPkts\n",
-			sblk->stat_IfHCInUcastPkts_hi,
-			sblk->stat_IfHCInUcastPkts_lo);
-
-	if (sblk->stat_IfHCInBroadcastPkts_hi
-		|| sblk->stat_IfHCInBroadcastPkts_lo)
-		BCE_PRINTF("0x%08X:%08X : "
-			"IfHcInBroadcastPkts\n",
-			sblk->stat_IfHCInBroadcastPkts_hi,
-			sblk->stat_IfHCInBroadcastPkts_lo);
-
-	if (sblk->stat_IfHCInMulticastPkts_hi
-		|| sblk->stat_IfHCInMulticastPkts_lo)
-		BCE_PRINTF("0x%08X:%08X : "
-			"IfHcInMulticastPkts\n",
-			sblk->stat_IfHCInMulticastPkts_hi,
-			sblk->stat_IfHCInMulticastPkts_lo);
-
-	if (sblk->stat_IfHCOutUcastPkts_hi
-		|| sblk->stat_IfHCOutUcastPkts_lo)
-		BCE_PRINTF("0x%08X:%08X : "
-			"IfHcOutUcastPkts\n",
-			sblk->stat_IfHCOutUcastPkts_hi,
-			sblk->stat_IfHCOutUcastPkts_lo);
-
-	if (sblk->stat_IfHCOutBroadcastPkts_hi
-		|| sblk->stat_IfHCOutBroadcastPkts_lo)
-		BCE_PRINTF("0x%08X:%08X : "
-			"IfHcOutBroadcastPkts\n",
-			sblk->stat_IfHCOutBroadcastPkts_hi,
-			sblk->stat_IfHCOutBroadcastPkts_lo);
-
-	if (sblk->stat_IfHCOutMulticastPkts_hi
-		|| sblk->stat_IfHCOutMulticastPkts_lo)
-		BCE_PRINTF("0x%08X:%08X : "
-			"IfHcOutMulticastPkts\n",
-			sblk->stat_IfHCOutMulticastPkts_hi,
-			sblk->stat_IfHCOutMulticastPkts_lo);
-
-	if (sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors)
-		BCE_PRINTF("         0x%08X : "
-			"emac_tx_stat_dot3statsinternalmactransmiterrors\n",
-			sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
-
-	if (sblk->stat_Dot3StatsCarrierSenseErrors)
-		BCE_PRINTF("         0x%08X : Dot3StatsCarrierSenseErrors\n",
-			sblk->stat_Dot3StatsCarrierSenseErrors);
-
-	if (sblk->stat_Dot3StatsFCSErrors)
-		BCE_PRINTF("         0x%08X : Dot3StatsFCSErrors\n",
-			sblk->stat_Dot3StatsFCSErrors);
-
-	if (sblk->stat_Dot3StatsAlignmentErrors)
-		BCE_PRINTF("         0x%08X : Dot3StatsAlignmentErrors\n",
-			sblk->stat_Dot3StatsAlignmentErrors);
-
-	if (sblk->stat_Dot3StatsSingleCollisionFrames)
-		BCE_PRINTF("         0x%08X : Dot3StatsSingleCollisionFrames\n",
-			sblk->stat_Dot3StatsSingleCollisionFrames);
-
-	if (sblk->stat_Dot3StatsMultipleCollisionFrames)
-		BCE_PRINTF("         0x%08X : Dot3StatsMultipleCollisionFrames\n",
-			sblk->stat_Dot3StatsMultipleCollisionFrames);
-
-	if (sblk->stat_Dot3StatsDeferredTransmissions)
-		BCE_PRINTF("         0x%08X : Dot3StatsDeferredTransmissions\n",
-			sblk->stat_Dot3StatsDeferredTransmissions);
-
-	if (sblk->stat_Dot3StatsExcessiveCollisions)
-		BCE_PRINTF("         0x%08X : Dot3StatsExcessiveCollisions\n",
-			sblk->stat_Dot3StatsExcessiveCollisions);
-
-	if (sblk->stat_Dot3StatsLateCollisions)
-		BCE_PRINTF("         0x%08X : Dot3StatsLateCollisions\n",
-			sblk->stat_Dot3StatsLateCollisions);
-
-	if (sblk->stat_EtherStatsCollisions)
-		BCE_PRINTF("         0x%08X : EtherStatsCollisions\n",
-			sblk->stat_EtherStatsCollisions);
-
-	if (sblk->stat_EtherStatsFragments)
-		BCE_PRINTF("         0x%08X : EtherStatsFragments\n",
-			sblk->stat_EtherStatsFragments);
-
-	if (sblk->stat_EtherStatsJabbers)
-		BCE_PRINTF("         0x%08X : EtherStatsJabbers\n",
-			sblk->stat_EtherStatsJabbers);
-
-	if (sblk->stat_EtherStatsUndersizePkts)
-		BCE_PRINTF("         0x%08X : EtherStatsUndersizePkts\n",
-			sblk->stat_EtherStatsUndersizePkts);
-
-	if (sblk->stat_EtherStatsOversizePkts)
-		BCE_PRINTF("         0x%08X : EtherStatsOverrsizePkts\n",
-			sblk->stat_EtherStatsOversizePkts);
-
-	if (sblk->stat_EtherStatsPktsRx64Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsRx64Octets\n",
-			sblk->stat_EtherStatsPktsRx64Octets);
-
-	if (sblk->stat_EtherStatsPktsRx65Octetsto127Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsRx65Octetsto127Octets\n",
-			sblk->stat_EtherStatsPktsRx65Octetsto127Octets);
-
-	if (sblk->stat_EtherStatsPktsRx128Octetsto255Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsRx128Octetsto255Octets\n",
-			sblk->stat_EtherStatsPktsRx128Octetsto255Octets);
-
-	if (sblk->stat_EtherStatsPktsRx256Octetsto511Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsRx256Octetsto511Octets\n",
-			sblk->stat_EtherStatsPktsRx256Octetsto511Octets);
-
-	if (sblk->stat_EtherStatsPktsRx512Octetsto1023Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsRx512Octetsto1023Octets\n",
-			sblk->stat_EtherStatsPktsRx512Octetsto1023Octets);
-
-	if (sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsRx1024Octetsto1522Octets\n",
-			sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets);
-
-	if (sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsRx1523Octetsto9022Octets\n",
-			sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets);
-
-	if (sblk->stat_EtherStatsPktsTx64Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsTx64Octets\n",
-			sblk->stat_EtherStatsPktsTx64Octets);
-
-	if (sblk->stat_EtherStatsPktsTx65Octetsto127Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsTx65Octetsto127Octets\n",
-			sblk->stat_EtherStatsPktsTx65Octetsto127Octets);
-
-	if (sblk->stat_EtherStatsPktsTx128Octetsto255Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsTx128Octetsto255Octets\n",
-			sblk->stat_EtherStatsPktsTx128Octetsto255Octets);
-
-	if (sblk->stat_EtherStatsPktsTx256Octetsto511Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsTx256Octetsto511Octets\n",
-			sblk->stat_EtherStatsPktsTx256Octetsto511Octets);
-
-	if (sblk->stat_EtherStatsPktsTx512Octetsto1023Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsTx512Octetsto1023Octets\n",
-			sblk->stat_EtherStatsPktsTx512Octetsto1023Octets);
-
-	if (sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsTx1024Octetsto1522Octets\n",
-			sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets);
-
-	if (sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsTx1523Octetsto9022Octets\n",
-			sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets);
-
-	if (sblk->stat_XonPauseFramesReceived)
-		BCE_PRINTF("         0x%08X : XonPauseFramesReceived\n",
-			sblk->stat_XonPauseFramesReceived);
-
-	if (sblk->stat_XoffPauseFramesReceived)
-	   BCE_PRINTF("          0x%08X : XoffPauseFramesReceived\n",
-			sblk->stat_XoffPauseFramesReceived);
-
-	if (sblk->stat_OutXonSent)
-		BCE_PRINTF("         0x%08X : OutXonSent\n",
-			sblk->stat_OutXonSent);
-
-	if (sblk->stat_OutXoffSent)
-		BCE_PRINTF("         0x%08X : OutXoffSent\n",
-			sblk->stat_OutXoffSent);
-
-	if (sblk->stat_FlowControlDone)
-		BCE_PRINTF("         0x%08X : FlowControlDone\n",
-			sblk->stat_FlowControlDone);
-
-	if (sblk->stat_MacControlFramesReceived)
-		BCE_PRINTF("         0x%08X : MacControlFramesReceived\n",
-			sblk->stat_MacControlFramesReceived);
-
-	if (sblk->stat_XoffStateEntered)
-		BCE_PRINTF("         0x%08X : XoffStateEntered\n",
-			sblk->stat_XoffStateEntered);
-
-	if (sblk->stat_IfInFramesL2FilterDiscards)
-		BCE_PRINTF("         0x%08X : IfInFramesL2FilterDiscards\n",
-			sblk->stat_IfInFramesL2FilterDiscards);
-
-	if (sblk->stat_IfInRuleCheckerDiscards)
-		BCE_PRINTF("         0x%08X : IfInRuleCheckerDiscards\n",
-			sblk->stat_IfInRuleCheckerDiscards);
-
-	if (sblk->stat_IfInFTQDiscards)
-		BCE_PRINTF("         0x%08X : IfInFTQDiscards\n",
-			sblk->stat_IfInFTQDiscards);
-
-	if (sblk->stat_IfInMBUFDiscards)
-		BCE_PRINTF("         0x%08X : IfInMBUFDiscards\n",
-			sblk->stat_IfInMBUFDiscards);
-
-	if (sblk->stat_IfInRuleCheckerP4Hit)
-		BCE_PRINTF("         0x%08X : IfInRuleCheckerP4Hit\n",
-			sblk->stat_IfInRuleCheckerP4Hit);
-
-	if (sblk->stat_CatchupInRuleCheckerDiscards)
-		BCE_PRINTF("         0x%08X : CatchupInRuleCheckerDiscards\n",
-			sblk->stat_CatchupInRuleCheckerDiscards);
-
-	if (sblk->stat_CatchupInFTQDiscards)
-		BCE_PRINTF("         0x%08X : CatchupInFTQDiscards\n",
-			sblk->stat_CatchupInFTQDiscards);
-
-	if (sblk->stat_CatchupInMBUFDiscards)
-		BCE_PRINTF("         0x%08X : CatchupInMBUFDiscards\n",
-			sblk->stat_CatchupInMBUFDiscards);
-
-	if (sblk->stat_CatchupInRuleCheckerP4Hit)
-		BCE_PRINTF("         0x%08X : CatchupInRuleCheckerP4Hit\n",
-			sblk->stat_CatchupInRuleCheckerP4Hit);
+    BCE_PRINT_64BIT_STAT(stat_IfHCInOctets);
+    BCE_PRINT_64BIT_STAT(stat_IfHCInBadOctets);
+    BCE_PRINT_64BIT_STAT(stat_IfHCOutOctets);
+    BCE_PRINT_64BIT_STAT(stat_IfHCOutBadOctets);
+    BCE_PRINT_64BIT_STAT(stat_IfHCInUcastPkts);
+    BCE_PRINT_64BIT_STAT(stat_IfHCInBroadcastPkts);
+    BCE_PRINT_64BIT_STAT(stat_IfHCInMulticastPkts);
+    BCE_PRINT_64BIT_STAT(stat_IfHCOutUcastPkts);
+    BCE_PRINT_64BIT_STAT(stat_IfHCOutBroadcastPkts);
+    BCE_PRINT_64BIT_STAT(stat_IfHCOutMulticastPkts);
+    BCE_PRINT_32BIT_STAT(stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
+    BCE_PRINT_32BIT_STAT(stat_Dot3StatsCarrierSenseErrors);
+    BCE_PRINT_32BIT_STAT(stat_Dot3StatsFCSErrors);
+    BCE_PRINT_32BIT_STAT(stat_Dot3StatsAlignmentErrors);
+    BCE_PRINT_32BIT_STAT(stat_Dot3StatsSingleCollisionFrames);
+    BCE_PRINT_32BIT_STAT(stat_Dot3StatsMultipleCollisionFrames);
+    BCE_PRINT_32BIT_STAT(stat_Dot3StatsDeferredTransmissions);
+    BCE_PRINT_32BIT_STAT(stat_Dot3StatsExcessiveCollisions);
+    BCE_PRINT_32BIT_STAT(stat_Dot3StatsLateCollisions);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsCollisions);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsFragments);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsJabbers);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsUndersizePkts);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsOversizePkts);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx64Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx65Octetsto127Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx128Octetsto255Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx256Octetsto511Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx512Octetsto1023Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1024Octetsto1522Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1523Octetsto9022Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx64Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx65Octetsto127Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx128Octetsto255Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx256Octetsto511Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx512Octetsto1023Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1024Octetsto1522Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1523Octetsto9022Octets);
+    BCE_PRINT_32BIT_STAT(stat_XonPauseFramesReceived);
+    BCE_PRINT_32BIT_STAT(stat_XoffPauseFramesReceived);
+    BCE_PRINT_32BIT_STAT(stat_OutXonSent);
+    BCE_PRINT_32BIT_STAT(stat_OutXoffSent);
+    BCE_PRINT_32BIT_STAT(stat_FlowControlDone);
+    BCE_PRINT_32BIT_STAT(stat_MacControlFramesReceived);
+    BCE_PRINT_32BIT_STAT(stat_XoffStateEntered);
+    BCE_PRINT_32BIT_STAT(stat_IfInFramesL2FilterDiscards);
+    BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerDiscards);
+    BCE_PRINT_32BIT_STAT(stat_IfInFTQDiscards);
+    BCE_PRINT_32BIT_STAT(stat_IfInMBUFDiscards);
+    BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerP4Hit);
+    BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerDiscards);
+    BCE_PRINT_32BIT_STAT(stat_CatchupInFTQDiscards);
+    BCE_PRINT_32BIT_STAT(stat_CatchupInMBUFDiscards);
+    BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerP4Hit);
 
 	BCE_PRINTF(
 		"----------------------------"
@@ -10465,7 +10312,7 @@ static __attribute__ ((noinline)) void
 bce_dump_com_state(struct bce_softc *sc, int regs)
 {
 	u32 val;
-	u32 fw_version[3];
+	u32 fw_version[4];
 
 	BCE_PRINTF(
 		"----------------------------"
@@ -10508,12 +10355,76 @@ bce_dump_com_state(struct bce_softc *sc,
 
 
 /****************************************************************************/
+/* Prints out the Receive Virtual 2 Physical (RV2P) state.                  */
+/*                                                                          */
+/* Returns:                                                                 */
+/*   Nothing.                                                               */
+/****************************************************************************/
+static __attribute__ ((noinline)) void
+bce_dump_rv2p_state(struct bce_softc *sc)
+{
+	u32 val, pc1, pc2, fw_ver_high, fw_ver_low;
+
+	BCE_PRINTF(
+		"----------------------------"
+		"   RV2P State   "
+		"----------------------------\n");
+
+    /* Stall the RV2P processors. */
+    val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
+    val |= BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2;
+    REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
+
+    /* Read the firmware version. */
+    val = 0x00000001;
+    REG_WR_IND(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
+    fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
+    fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) & BCE_RV2P_INSTR_HIGH_HIGH;
+	BCE_PRINTF("RV2P1 Firmware version - 0x%08X:0x%08X\n", fw_ver_high, fw_ver_low);
+
+    val = 0x00000001;
+    REG_WR_IND(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
+    fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
+    fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) & BCE_RV2P_INSTR_HIGH_HIGH;
+    BCE_PRINTF("RV2P2 Firmware version - 0x%08X:0x%08X\n", fw_ver_high, fw_ver_low);
+
+    /* Resume the RV2P processors. */
+    val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
+    val &= ~(BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2);
+    REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
+
+    /* Fetch the program counter value. */
+	val = 0x68007800;
+    REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
+    val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
+    pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
+    pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
+    BCE_PRINTF("0x%08X - RV2P1 program counter (1st read)\n", pc1);
+    BCE_PRINTF("0x%08X - RV2P2 program counter (1st read)\n", pc2);
+
+    /* Fetch the program counter value again to see if it is advancing. */
+    val = 0x68007800;
+    REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
+    val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
+    pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
+    pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
+    BCE_PRINTF("0x%08X - RV2P1 program counter (2nd read)\n", pc1);
+    BCE_PRINTF("0x%08X - RV2P2 program counter (2nd read)\n", pc2);
+
+	BCE_PRINTF(
+		"----------------------------"
+		"----------------"
+		"----------------------------\n");
+}
+
+
+/****************************************************************************/
 /* Prints out the driver state and then enters the debugger.                */
 /*                                                                          */
 /* Returns:                                                                 */
 /*   Nothing.                                                               */
 /****************************************************************************/
-static void
+static __attribute__ ((noinline)) void
 bce_breakpoint(struct bce_softc *sc)
 {
 
@@ -10544,6 +10455,7 @@ bce_breakpoint(struct bce_softc *sc)
 		bce_dump_tpat_state(sc, 0);
 		bce_dump_cp_state(sc, 0);
 		bce_dump_com_state(sc, 0);
+        bce_dump_rv2p_state(sc);
 #ifdef BCE_JUMBO_HDRSPLIT
 		bce_dump_pgbd(sc, 0, NULL);
 		bce_dump_pg_mbuf_chain(sc, 0, USABLE_PG_BD);

Modified: stable/8/sys/dev/bce/if_bcefw.h
==============================================================================
--- stable/8/sys/dev/bce/if_bcefw.h	Thu Apr 15 19:22:55 2010	(r206679)
+++ stable/8/sys/dev/bce/if_bcefw.h	Thu Apr 15 19:26:28 2010	(r206680)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2006-2009 Broadcom Corporation
+ * Copyright (c) 2006-2010 Broadcom Corporation
  *	David Christensen <davidch@broadcom.com>.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without

Modified: stable/8/sys/dev/bce/if_bcereg.h
==============================================================================
--- stable/8/sys/dev/bce/if_bcereg.h	Thu Apr 15 19:22:55 2010	(r206679)
+++ stable/8/sys/dev/bce/if_bcereg.h	Thu Apr 15 19:26:28 2010	(r206680)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2006-2009 Broadcom Corporation
+ * Copyright (c) 2006-2010 Broadcom Corporation
  *	David Christensen <davidch@broadcom.com>.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -453,24 +453,10 @@
 	}
 
 /* Announces function entry. */
-#if 0
-#define DBENTER(cond)								 			\
-	u32 start_time = REG_RD(sc, BCE_TIMER_25MHZ_FREE_RUN);		\
-	u32 end_time;										  		\
-	DBPRINT(sc, (cond), "%s(enter)\n", __FUNCTION__);
-#endif
-
 #define DBENTER(cond)									  		\
 	DBPRINT(sc, (cond), "%s(enter)\n", __FUNCTION__)
 
 /* Announces function exit. */
-#if 0
-#define DBEXIT(cond, val)								  		\
-	end_time = REG_RD(sc, BCE_TIMER_25MHZ_FREE_RUN);	  		\
-	val += (u64) BCE_TIME_DELTA(start_time, end_time);			\
-	DBPRINT(sc, (cond), "%s(exit)\n", __FUNCTION__);
-#endif
-
 #define DBEXIT(cond)											\
 	DBPRINT(sc, (cond), "%s(exit)\n", __FUNCTION__)
 
@@ -6454,6 +6440,7 @@ struct bce_softc
 #define BCE_PHY_INT_MODE_MASK_FLAG			0x00000300
 #define BCE_PHY_INT_MODE_AUTO_POLLING_FLAG	0x00000100
 #define BCE_PHY_INT_MODE_LINK_READY_FLAG	0x00000200
+#define BCE_PHY_IEEE_CLAUSE_45_FLAG     	0x00000400
 
 	/* Values that need to be shared with the PHY driver. */
 	u32					bce_shared_hw_cfg;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 10 dfilter service freebsd_committer freebsd_triage 2010-04-15 20:28:28 UTC
Author: yongari
Date: Thu Apr 15 19:28:15 2010
New Revision: 206681
URL: http://svn.freebsd.org/changeset/base/206681

Log:
  MFC r205300:
    - Added support for 5709S/5716S PHYs.
    - Update copyright to 2010.
    - Add new debug code for RV2P block.
    - Improve output formatting for various debug functions.
  
    PR:	kern/134658, kern/136417, kern/139761, kern/140970

Modified:
  stable/7/sys/dev/bce/if_bce.c
  stable/7/sys/dev/bce/if_bcefw.h
  stable/7/sys/dev/bce/if_bcereg.h
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/   (props changed)
  stable/7/sys/contrib/dev/acpica/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/dev/bce/if_bce.c
==============================================================================
--- stable/7/sys/dev/bce/if_bce.c	Thu Apr 15 19:26:28 2010	(r206680)
+++ stable/7/sys/dev/bce/if_bce.c	Thu Apr 15 19:28:15 2010	(r206681)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2006-2009 Broadcom Corporation
+ * Copyright (c) 2006-2010 Broadcom Corporation
  *	David Christensen <davidch@broadcom.com>.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,9 @@ __FBSDID("$FreeBSD$");
  *   BCM5708C B1, B2
  *   BCM5708S B1, B2
  *   BCM5709C A1, C0
+ *   BCM5709S A1, C0
  * 	 BCM5716C C0
+ * 	 BCM5716S C0
  *
  * The following controllers are not supported by this driver:
  *   BCM5706C A0, A1 (pre-production)
@@ -46,7 +48,7 @@ __FBSDID("$FreeBSD$");
  *   BCM5708C A0, B0 (pre-production)
  *   BCM5708S A0, B0 (pre-production)
  *   BCM5709C A0  B0, B1, B2 (pre-production)
- *   BCM5709S A0, A1, B0, B1, B2, C0 (pre-production)
+ *   BCM5709S A0, B0, B1, B2 (pre-production)
  */
 
 #include "opt_bce.h"
@@ -320,6 +322,7 @@ static void bce_dump_rxp_state		(struct 
 static void bce_dump_tpat_state		(struct bce_softc *, int);
 static void bce_dump_cp_state		(struct bce_softc *, int);
 static void bce_dump_com_state		(struct bce_softc *, int);
+static void bce_dump_rv2p_state		(struct bce_softc *);
 static void bce_breakpoint			(struct bce_softc *);
 #endif
 
@@ -360,6 +363,7 @@ static int  bce_nvram_write			(struct bc
 /*                                                                          */
 /****************************************************************************/
 static void bce_get_media			(struct bce_softc *);
+static void bce_init_media			(struct bce_softc *);
 static void bce_dma_map_addr		(void *, bus_dma_segment_t *, int, int);
 static int  bce_dma_alloc			(device_t);
 static void bce_dma_free			(struct bce_softc *);
@@ -1096,7 +1100,10 @@ bce_attach(device_t dev)
 	else
 		ifp->if_baudrate = IF_Mbps(1000);
 
-	/* Check for an MII child bus by probing the PHY. */
+    /* Handle any special PHY initialization for SerDes PHYs. */
+    bce_init_media(sc);
+
+	/* MII child bus by probing the PHY. */
 	if (mii_phy_probe(dev, &sc->bce_miibus, bce_ifmedia_upd,
 		bce_ifmedia_sts)) {
 		BCE_PRINTF("%s(%d): No PHY found on child MII bus!\n",
@@ -1504,7 +1511,17 @@ bce_miibus_read_reg(device_t dev, int ph
 		return(0);
 	}
 
-	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
+    /*
+     * The 5709S PHY is an IEEE Clause 45 PHY
+     * with special mappings to work with IEEE
+     * Clause 22 register accesses.
+     */
+	if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
+		if (reg >= MII_BMCR && reg <= MII_ANLPRNP)
+			reg += 0x10;
+	}
+
+    if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
 		val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
 		val &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
 
@@ -1584,6 +1601,16 @@ bce_miibus_write_reg(device_t dev, int p
 
 	DB_PRINT_PHY_REG(reg, val);
 
+    /*
+     * The 5709S PHY is an IEEE Clause 45 PHY
+     * with special mappings to work with IEEE
+     * Clause 22 register accesses.
+     */
+	if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
+		if (reg >= MII_BMCR && reg <= MII_ANLPRNP)
+			reg += 0x10;
+	}
+
 	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
 		val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
 		val1 &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
@@ -2647,9 +2674,11 @@ bce_get_media(struct bce_softc *sc)
 				DBPRINT(sc, BCE_INFO_LOAD,
 					"BCM5709 s/w configured for SerDes.\n");
 				sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
+                break;
 			default:
 				DBPRINT(sc, BCE_INFO_LOAD,
 					"BCM5709 s/w configured for Copper.\n");
+                break;
 			}
 		} else {
 			switch (strap) {
@@ -2659,9 +2688,11 @@ bce_get_media(struct bce_softc *sc)
 				DBPRINT(sc, BCE_INFO_LOAD,
 					"BCM5709 s/w configured for SerDes.\n");
 				sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
+                break;
 			default:
 				DBPRINT(sc, BCE_INFO_LOAD,
 					"BCM5709 s/w configured for Copper.\n");
+                break;
 			}
 		}
 
@@ -2669,15 +2700,22 @@ bce_get_media(struct bce_softc *sc)
 		sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
 
 	if (sc->bce_phy_flags & BCE_PHY_SERDES_FLAG) {
+
 		sc->bce_flags |= BCE_NO_WOL_FLAG;
-		if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
+
+		/* 5708S, 5709S, and 5716S use a separate PHY for SerDes. */
+		if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) 
 			sc->bce_phy_addr = 2;
+
+		if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
+			sc->bce_phy_flags |= BCE_PHY_IEEE_CLAUSE_45_FLAG;
+
 			val = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG);
 			if (val & BCE_SHARED_HW_CFG_PHY_2_5G) {
 				sc->bce_phy_flags |= BCE_PHY_2_5G_CAPABLE_FLAG;
 				DBPRINT(sc, BCE_INFO_LOAD, "Found 2.5Gb capable adapter\n");
 			}
-		}
+        }
 	} else if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) ||
 		   (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708))
 		sc->bce_phy_flags |= BCE_PHY_CRC_FIX_FLAG;
@@ -2691,6 +2729,37 @@ bce_get_media_exit:
 
 
 /****************************************************************************/
+/* Performs PHY initialization required before MII drivers access the       */
+/* device.                                                                  */
+/*                                                                          */
+/* Returns:                                                                 */
+/*   Nothing.                                                               */
+/****************************************************************************/
+static void
+bce_init_media(struct bce_softc *sc)
+{
+	if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
+		/*
+		 * Configure 5709S/5716S PHYs to use traditional IEEE
+		 * Clause 22 method. Otherwise we have no way to attach
+		 * the PHY in mii(4) layer. PHY specific configuration
+		 * is done in mii layer.
+		 */
+
+        /* Select auto-negotiation MMD of the PHY. */
+        bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
+		    BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_ADDR_EXT);
+		bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
+		    BRGPHY_ADDR_EXT, BRGPHY_ADDR_EXT_AN_MMD);
+
+        /* Select IEEE0 block of AN MMD (assumed in all brgphy(4) code). */
+		bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
+		    BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
+	}
+}
+
+
+/****************************************************************************/
 /* Free any DMA memory owned by the driver.                                 */
 /*                                                                          */
 /* Scans through each data structre that requires DMA memory and frees      */
@@ -6679,7 +6748,7 @@ bce_tso_setup(struct bce_softc *sc, stru
 
 	DBPRINT(sc, BCE_EXTREME_SEND, "%s(): hdr_len = %d, e_hlen = %d, "
 	    "ip_hlen = %d, tcp_hlen = %d, ip_len = %d\n",
-	    __FUNCTION__, hdr_len, sizeof(struct ether_header), ip_hlen,
+	    __FUNCTION__, hdr_len, (int) sizeof(struct ether_header), ip_hlen,
 	    tcp_hlen, ip_len);
 
 	/* Set the LSO flag in the TX BD */
@@ -7943,7 +8012,7 @@ bce_sysctl_dump_tx_chain(SYSCTL_HANDLER_
 
         if (result == 1) {
                 sc = (struct bce_softc *)arg1;
-                bce_dump_tx_chain(sc, 0, USABLE_TX_BD);
+                bce_dump_tx_chain(sc, 0, TOTAL_TX_BD);
         }
 
         return error;
@@ -8626,7 +8695,7 @@ bce_add_sysctls(struct bce_softc *sc)
 /* Returns:                                                                 */
 /*   Nothing.                                                               */
 /****************************************************************************/
-static void
+static __attribute__ ((noinline)) void
 bce_freeze_controller(struct bce_softc *sc)
 {
 	u32 val;
@@ -8643,7 +8712,7 @@ bce_freeze_controller(struct bce_softc *
 /* Returns:                                                                 */
 /*   Nothing.                                                               */
 /****************************************************************************/
-static void
+static __attribute__ ((noinline)) void
 bce_unfreeze_controller(struct bce_softc *sc)
 {
 	u32 val;
@@ -8661,7 +8730,7 @@ bce_unfreeze_controller(struct bce_softc
 /* Returns:                                                                 */
 /*   Nothing.                                                               */
 /****************************************************************************/
-static void
+static __attribute__ ((noinline)) void
 bce_dump_enet(struct bce_softc *sc, struct mbuf *m)
 {
 	struct ether_vlan_header *eh;
@@ -8915,7 +8984,9 @@ bce_dump_pg_mbuf_chain(struct bce_softc 
 static __attribute__ ((noinline)) void
 bce_dump_txbd(struct bce_softc *sc, int idx, struct tx_bd *txbd)
 {
-	if (idx > MAX_TX_BD)
+    int i = 0;
+
+    if (idx > MAX_TX_BD)
 		/* Index out of range. */
 		BCE_PRINTF("tx_bd[0x%04X]: Invalid tx_bd index!\n", idx);
 	else if ((idx & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
@@ -8923,52 +8994,65 @@ bce_dump_txbd(struct bce_softc *sc, int 
 		BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
 			idx, txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo);
 	else {
-			/* Normal tx_bd entry. */
-			BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
-				"vlan tag= 0x%04X, flags = 0x%04X (", idx,
-				txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo,
-				txbd->tx_bd_mss_nbytes, txbd->tx_bd_vlan_tag,
-				txbd->tx_bd_flags);
-
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_CONN_FAULT)
-				printf(" CONN_FAULT");
-
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_TCP_UDP_CKSUM)
-				printf(" TCP_UDP_CKSUM");
+		/* Normal tx_bd entry. */
+		BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, mss_nbytes = 0x%08X, "
+			"vlan tag = 0x%04X, flags = 0x%04X (", idx,
+			txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo,
+			txbd->tx_bd_mss_nbytes, txbd->tx_bd_vlan_tag,
+			txbd->tx_bd_flags);
 
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_IP_CKSUM)
-				printf(" IP_CKSUM");
+		if (txbd->tx_bd_flags & TX_BD_FLAGS_CONN_FAULT) {
+			if (i>0) printf("|"); printf("CONN_FAULT"); i++;
+        }
 
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_VLAN_TAG)
-				printf("  VLAN");
+		if (txbd->tx_bd_flags & TX_BD_FLAGS_TCP_UDP_CKSUM) {
+            if (i>0) printf("|"); printf("TCP_UDP_CKSUM"); i++;
+        }
 
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_COAL_NOW)
-				printf(" COAL_NOW");
+        if (txbd->tx_bd_flags & TX_BD_FLAGS_IP_CKSUM) {
+            if (i>0) printf("|"); printf("IP_CKSUM"); i++;
+        }
 
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_DONT_GEN_CRC)
-				printf(" DONT_GEN_CRC");
+		if (txbd->tx_bd_flags & TX_BD_FLAGS_VLAN_TAG) {
+            if (i>0) printf("|"); printf("VLAN"); i++;
+        }
 
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_START)
-				printf(" START");
+		if (txbd->tx_bd_flags & TX_BD_FLAGS_COAL_NOW) {
+            if (i>0) printf("|"); printf("COAL_NOW"); i++;
+        }
 
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_END)
-				printf(" END");
+        if (txbd->tx_bd_flags & TX_BD_FLAGS_DONT_GEN_CRC) {
+            if (i>0) printf("|"); printf("DONT_GEN_CRC"); i++;
+        }
 
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_LSO)
-				printf(" LSO");
+        if (txbd->tx_bd_flags & TX_BD_FLAGS_START) {
+            if (i>0) printf("|"); printf("START"); i++;
+        }
 
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_OPTION_WORD)
-				printf(" OPTION_WORD");
+		if (txbd->tx_bd_flags & TX_BD_FLAGS_END) {
+            if (i>0) printf("|"); printf("END"); i++;
+        }
 
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_FLAGS)
-				printf(" FLAGS");
+		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_LSO) {
+            if (i>0) printf("|"); printf("LSO"); i++;
+        }
 
-			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_SNAP)
-				printf(" SNAP");
+        if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_OPTION_WORD) {
+            if (i>0) printf("|"); 
+            printf("SW_OPTION=%d", ((txbd->tx_bd_flags & 
+                TX_BD_FLAGS_SW_OPTION_WORD) >> 8)); i++;
+        }
 
-			printf(" )\n");
-		}
+		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_FLAGS) {
+            if (i>0) printf("|"); printf("SW_FLAGS"); i++;
+        }
 
+		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_SNAP) {
+            if (i>0) printf("|"); printf("SNAP)");
+        } else {
+            printf(")\n");
+        }
+    }
 }
 
 
@@ -9415,10 +9499,8 @@ bce_dump_tx_chain(struct bce_softc *sc, 
 
 	BCE_PRINTF("page size      = 0x%08X, tx chain pages        = 0x%08X\n",
 		(u32) BCM_PAGE_SIZE, (u32) TX_PAGES);
-
 	BCE_PRINTF("tx_bd per page = 0x%08X, usable tx_bd per page = 0x%08X\n",
 		(u32) TOTAL_TX_BD_PER_PAGE, (u32) USABLE_TX_BD_PER_PAGE);
-
 	BCE_PRINTF("total tx_bd    = 0x%08X\n", (u32) TOTAL_TX_BD);
 
 	BCE_PRINTF(
@@ -9426,11 +9508,11 @@ bce_dump_tx_chain(struct bce_softc *sc, 
 		"   tx_bd data   "
 		"----------------------------\n");
 
-	/* Now print out the tx_bd's themselves. */
+	/* Now print out a decoded list of TX buffer descriptors. */
 	for (int i = 0; i < count; i++) {
 	 	txbd = &sc->tx_bd_chain[TX_PAGE(tx_prod)][TX_IDX(tx_prod)];
 		bce_dump_txbd(sc, tx_prod, txbd);
-		tx_prod = NEXT_TX_BD(tx_prod);
+		tx_prod++;
 	}
 
 	BCE_PRINTF(
@@ -9530,6 +9612,17 @@ bce_dump_pg_chain(struct bce_softc *sc, 
 }
 #endif
 
+#define BCE_PRINT_RX_CONS(arg)                                          \
+if (sblk->status_rx_quick_consumer_index##arg)                          \
+    BCE_PRINTF("0x%04X(0x%04X) - rx_quick_consumer_index##arg\n",       \
+		sblk->status_rx_quick_consumer_index##arg,                      \
+		(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index##arg));
+
+#define BCE_PRINT_TX_CONS(arg)                                          \
+if (sblk->status_tx_quick_consumer_index##arg)                          \
+    BCE_PRINTF("0x%04X(0x%04X) - tx_quick_consumer_index##arg\n",       \
+        sblk->status_tx_quick_consumer_index##arg,                      \
+        (u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index##arg));
 
 /****************************************************************************/
 /* Prints out the status block from host memory.                            */
@@ -9549,90 +9642,28 @@ bce_dump_status_block(struct bce_softc *
 		"  Status Block  "
 		"----------------------------\n");
 
+    /* Theses indices are used for normal L2 drivers. */
 	BCE_PRINTF("    0x%08X - attn_bits\n",
 		sblk->status_attn_bits);
 
 	BCE_PRINTF("    0x%08X - attn_bits_ack\n",
 		sblk->status_attn_bits_ack);
 
-	BCE_PRINTF("0x%04X(0x%04X) - rx_cons0\n",
-		sblk->status_rx_quick_consumer_index0,
-		(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index0));
-
-	BCE_PRINTF("0x%04X(0x%04X) - tx_cons0\n",
-		sblk->status_tx_quick_consumer_index0,
-		(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index0));
+    BCE_PRINT_RX_CONS(0);
+    BCE_PRINT_TX_CONS(0)
 
 	BCE_PRINTF("        0x%04X - status_idx\n", sblk->status_idx);
 
 	/* Theses indices are not used for normal L2 drivers. */
-	if (sblk->status_rx_quick_consumer_index1)
-		BCE_PRINTF("0x%04X(0x%04X) - rx_cons1\n",
-			sblk->status_rx_quick_consumer_index1,
-			(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index1));
-
-	if (sblk->status_tx_quick_consumer_index1)
-		BCE_PRINTF("0x%04X(0x%04X) - tx_cons1\n",
-			sblk->status_tx_quick_consumer_index1,
-			(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index1));
-
-	if (sblk->status_rx_quick_consumer_index2)
-		BCE_PRINTF("0x%04X(0x%04X)- rx_cons2\n",
-			sblk->status_rx_quick_consumer_index2,
-			(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index2));
-
-	if (sblk->status_tx_quick_consumer_index2)
-		BCE_PRINTF("0x%04X(0x%04X) - tx_cons2\n",
-			sblk->status_tx_quick_consumer_index2,
-			(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index2));
-
-	if (sblk->status_rx_quick_consumer_index3)
-		BCE_PRINTF("0x%04X(0x%04X) - rx_cons3\n",
-			sblk->status_rx_quick_consumer_index3,
-			(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index3));
-
-	if (sblk->status_tx_quick_consumer_index3)
-		BCE_PRINTF("0x%04X(0x%04X) - tx_cons3\n",
-			sblk->status_tx_quick_consumer_index3,
-			(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index3));
-
-	if (sblk->status_rx_quick_consumer_index4 ||
-		sblk->status_rx_quick_consumer_index5)
-		BCE_PRINTF("rx_cons4  = 0x%08X, rx_cons5      = 0x%08X\n",
-			sblk->status_rx_quick_consumer_index4,
-			sblk->status_rx_quick_consumer_index5);
-
-	if (sblk->status_rx_quick_consumer_index6 ||
-		sblk->status_rx_quick_consumer_index7)
-		BCE_PRINTF("rx_cons6  = 0x%08X, rx_cons7      = 0x%08X\n",
-			sblk->status_rx_quick_consumer_index6,
-			sblk->status_rx_quick_consumer_index7);
-
-	if (sblk->status_rx_quick_consumer_index8 ||
-		sblk->status_rx_quick_consumer_index9)
-		BCE_PRINTF("rx_cons8  = 0x%08X, rx_cons9      = 0x%08X\n",
-			sblk->status_rx_quick_consumer_index8,
-			sblk->status_rx_quick_consumer_index9);
-
-	if (sblk->status_rx_quick_consumer_index10 ||
-		sblk->status_rx_quick_consumer_index11)
-		BCE_PRINTF("rx_cons10 = 0x%08X, rx_cons11     = 0x%08X\n",
-			sblk->status_rx_quick_consumer_index10,
-			sblk->status_rx_quick_consumer_index11);
-
-	if (sblk->status_rx_quick_consumer_index12 ||
-		sblk->status_rx_quick_consumer_index13)
-		BCE_PRINTF("rx_cons12 = 0x%08X, rx_cons13     = 0x%08X\n",
-			sblk->status_rx_quick_consumer_index12,
-			sblk->status_rx_quick_consumer_index13);
-
-	if (sblk->status_rx_quick_consumer_index14 ||
-		sblk->status_rx_quick_consumer_index15)
-		BCE_PRINTF("rx_cons14 = 0x%08X, rx_cons15     = 0x%08X\n",
-			sblk->status_rx_quick_consumer_index14,
-			sblk->status_rx_quick_consumer_index15);
+    BCE_PRINT_RX_CONS(1);   BCE_PRINT_RX_CONS(2);   BCE_PRINT_RX_CONS(3);
+    BCE_PRINT_RX_CONS(4);   BCE_PRINT_RX_CONS(5);   BCE_PRINT_RX_CONS(6);
+    BCE_PRINT_RX_CONS(7);   BCE_PRINT_RX_CONS(8);   BCE_PRINT_RX_CONS(9);
+    BCE_PRINT_RX_CONS(10);  BCE_PRINT_RX_CONS(11);  BCE_PRINT_RX_CONS(12);
+    BCE_PRINT_RX_CONS(13);  BCE_PRINT_RX_CONS(14);  BCE_PRINT_RX_CONS(15);
 
-	if (sblk->status_completion_producer_index ||
+    BCE_PRINT_TX_CONS(1);   BCE_PRINT_TX_CONS(2);   BCE_PRINT_TX_CONS(3);
+
+    if (sblk->status_completion_producer_index ||
 		sblk->status_cmd_consumer_index)
 		BCE_PRINTF("com_prod  = 0x%08X, cmd_cons      = 0x%08X\n",
 			sblk->status_completion_producer_index,
@@ -9645,6 +9676,14 @@ bce_dump_status_block(struct bce_softc *
 }
 
 
+#define BCE_PRINT_64BIT_STAT(arg)                                       \
+if (sblk->arg##_lo || sblk->arg##_hi)                               \
+	BCE_PRINTF("0x%08X:%08X : arg\n", sblk->arg##_hi, sblk->arg##_lo);
+
+#define BCE_PRINT_32BIT_STAT(arg)                                       \
+if (sblk->arg)                                                        \
+	BCE_PRINTF("         0x%08X : arg\n", sblk->arg);
+
 /****************************************************************************/
 /* Prints out the statistics block from host memory.                        */
 /*                                                                          */
@@ -9663,252 +9702,60 @@ bce_dump_stats_block(struct bce_softc *s
 		" Stats Block  (All Stats Not Shown Are 0) "
 		"---------------\n");
 
-	if (sblk->stat_IfHCInOctets_hi
-		|| sblk->stat_IfHCInOctets_lo)
-		BCE_PRINTF("0x%08X:%08X : "
-			"IfHcInOctets\n",
-			sblk->stat_IfHCInOctets_hi,
-			sblk->stat_IfHCInOctets_lo);
-
-	if (sblk->stat_IfHCInBadOctets_hi
-		|| sblk->stat_IfHCInBadOctets_lo)
-		BCE_PRINTF("0x%08X:%08X : "
-			"IfHcInBadOctets\n",
-			sblk->stat_IfHCInBadOctets_hi,
-			sblk->stat_IfHCInBadOctets_lo);
-
-	if (sblk->stat_IfHCOutOctets_hi
-		|| sblk->stat_IfHCOutOctets_lo)
-		BCE_PRINTF("0x%08X:%08X : "
-			"IfHcOutOctets\n",
-			sblk->stat_IfHCOutOctets_hi,
-			sblk->stat_IfHCOutOctets_lo);
-
-	if (sblk->stat_IfHCOutBadOctets_hi
-		|| sblk->stat_IfHCOutBadOctets_lo)
-		BCE_PRINTF("0x%08X:%08X : "
-			"IfHcOutBadOctets\n",
-			sblk->stat_IfHCOutBadOctets_hi,
-			sblk->stat_IfHCOutBadOctets_lo);
-
-	if (sblk->stat_IfHCInUcastPkts_hi
-		|| sblk->stat_IfHCInUcastPkts_lo)
-		BCE_PRINTF("0x%08X:%08X : "
-			"IfHcInUcastPkts\n",
-			sblk->stat_IfHCInUcastPkts_hi,
-			sblk->stat_IfHCInUcastPkts_lo);
-
-	if (sblk->stat_IfHCInBroadcastPkts_hi
-		|| sblk->stat_IfHCInBroadcastPkts_lo)
-		BCE_PRINTF("0x%08X:%08X : "
-			"IfHcInBroadcastPkts\n",
-			sblk->stat_IfHCInBroadcastPkts_hi,
-			sblk->stat_IfHCInBroadcastPkts_lo);
-
-	if (sblk->stat_IfHCInMulticastPkts_hi
-		|| sblk->stat_IfHCInMulticastPkts_lo)
-		BCE_PRINTF("0x%08X:%08X : "
-			"IfHcInMulticastPkts\n",
-			sblk->stat_IfHCInMulticastPkts_hi,
-			sblk->stat_IfHCInMulticastPkts_lo);
-
-	if (sblk->stat_IfHCOutUcastPkts_hi
-		|| sblk->stat_IfHCOutUcastPkts_lo)
-		BCE_PRINTF("0x%08X:%08X : "
-			"IfHcOutUcastPkts\n",
-			sblk->stat_IfHCOutUcastPkts_hi,
-			sblk->stat_IfHCOutUcastPkts_lo);
-
-	if (sblk->stat_IfHCOutBroadcastPkts_hi
-		|| sblk->stat_IfHCOutBroadcastPkts_lo)
-		BCE_PRINTF("0x%08X:%08X : "
-			"IfHcOutBroadcastPkts\n",
-			sblk->stat_IfHCOutBroadcastPkts_hi,
-			sblk->stat_IfHCOutBroadcastPkts_lo);
-
-	if (sblk->stat_IfHCOutMulticastPkts_hi
-		|| sblk->stat_IfHCOutMulticastPkts_lo)
-		BCE_PRINTF("0x%08X:%08X : "
-			"IfHcOutMulticastPkts\n",
-			sblk->stat_IfHCOutMulticastPkts_hi,
-			sblk->stat_IfHCOutMulticastPkts_lo);
-
-	if (sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors)
-		BCE_PRINTF("         0x%08X : "
-			"emac_tx_stat_dot3statsinternalmactransmiterrors\n",
-			sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
-
-	if (sblk->stat_Dot3StatsCarrierSenseErrors)
-		BCE_PRINTF("         0x%08X : Dot3StatsCarrierSenseErrors\n",
-			sblk->stat_Dot3StatsCarrierSenseErrors);
-
-	if (sblk->stat_Dot3StatsFCSErrors)
-		BCE_PRINTF("         0x%08X : Dot3StatsFCSErrors\n",
-			sblk->stat_Dot3StatsFCSErrors);
-
-	if (sblk->stat_Dot3StatsAlignmentErrors)
-		BCE_PRINTF("         0x%08X : Dot3StatsAlignmentErrors\n",
-			sblk->stat_Dot3StatsAlignmentErrors);
-
-	if (sblk->stat_Dot3StatsSingleCollisionFrames)
-		BCE_PRINTF("         0x%08X : Dot3StatsSingleCollisionFrames\n",
-			sblk->stat_Dot3StatsSingleCollisionFrames);
-
-	if (sblk->stat_Dot3StatsMultipleCollisionFrames)
-		BCE_PRINTF("         0x%08X : Dot3StatsMultipleCollisionFrames\n",
-			sblk->stat_Dot3StatsMultipleCollisionFrames);
-
-	if (sblk->stat_Dot3StatsDeferredTransmissions)
-		BCE_PRINTF("         0x%08X : Dot3StatsDeferredTransmissions\n",
-			sblk->stat_Dot3StatsDeferredTransmissions);
-
-	if (sblk->stat_Dot3StatsExcessiveCollisions)
-		BCE_PRINTF("         0x%08X : Dot3StatsExcessiveCollisions\n",
-			sblk->stat_Dot3StatsExcessiveCollisions);
-
-	if (sblk->stat_Dot3StatsLateCollisions)
-		BCE_PRINTF("         0x%08X : Dot3StatsLateCollisions\n",
-			sblk->stat_Dot3StatsLateCollisions);
-
-	if (sblk->stat_EtherStatsCollisions)
-		BCE_PRINTF("         0x%08X : EtherStatsCollisions\n",
-			sblk->stat_EtherStatsCollisions);
-
-	if (sblk->stat_EtherStatsFragments)
-		BCE_PRINTF("         0x%08X : EtherStatsFragments\n",
-			sblk->stat_EtherStatsFragments);
-
-	if (sblk->stat_EtherStatsJabbers)
-		BCE_PRINTF("         0x%08X : EtherStatsJabbers\n",
-			sblk->stat_EtherStatsJabbers);
-
-	if (sblk->stat_EtherStatsUndersizePkts)
-		BCE_PRINTF("         0x%08X : EtherStatsUndersizePkts\n",
-			sblk->stat_EtherStatsUndersizePkts);
-
-	if (sblk->stat_EtherStatsOversizePkts)
-		BCE_PRINTF("         0x%08X : EtherStatsOverrsizePkts\n",
-			sblk->stat_EtherStatsOversizePkts);
-
-	if (sblk->stat_EtherStatsPktsRx64Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsRx64Octets\n",
-			sblk->stat_EtherStatsPktsRx64Octets);
-
-	if (sblk->stat_EtherStatsPktsRx65Octetsto127Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsRx65Octetsto127Octets\n",
-			sblk->stat_EtherStatsPktsRx65Octetsto127Octets);
-
-	if (sblk->stat_EtherStatsPktsRx128Octetsto255Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsRx128Octetsto255Octets\n",
-			sblk->stat_EtherStatsPktsRx128Octetsto255Octets);
-
-	if (sblk->stat_EtherStatsPktsRx256Octetsto511Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsRx256Octetsto511Octets\n",
-			sblk->stat_EtherStatsPktsRx256Octetsto511Octets);
-
-	if (sblk->stat_EtherStatsPktsRx512Octetsto1023Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsRx512Octetsto1023Octets\n",
-			sblk->stat_EtherStatsPktsRx512Octetsto1023Octets);
-
-	if (sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsRx1024Octetsto1522Octets\n",
-			sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets);
-
-	if (sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsRx1523Octetsto9022Octets\n",
-			sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets);
-
-	if (sblk->stat_EtherStatsPktsTx64Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsTx64Octets\n",
-			sblk->stat_EtherStatsPktsTx64Octets);
-
-	if (sblk->stat_EtherStatsPktsTx65Octetsto127Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsTx65Octetsto127Octets\n",
-			sblk->stat_EtherStatsPktsTx65Octetsto127Octets);
-
-	if (sblk->stat_EtherStatsPktsTx128Octetsto255Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsTx128Octetsto255Octets\n",
-			sblk->stat_EtherStatsPktsTx128Octetsto255Octets);
-
-	if (sblk->stat_EtherStatsPktsTx256Octetsto511Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsTx256Octetsto511Octets\n",
-			sblk->stat_EtherStatsPktsTx256Octetsto511Octets);
-
-	if (sblk->stat_EtherStatsPktsTx512Octetsto1023Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsTx512Octetsto1023Octets\n",
-			sblk->stat_EtherStatsPktsTx512Octetsto1023Octets);
-
-	if (sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsTx1024Octetsto1522Octets\n",
-			sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets);
-
-	if (sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets)
-		BCE_PRINTF("         0x%08X : EtherStatsPktsTx1523Octetsto9022Octets\n",
-			sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets);
-
-	if (sblk->stat_XonPauseFramesReceived)
-		BCE_PRINTF("         0x%08X : XonPauseFramesReceived\n",
-			sblk->stat_XonPauseFramesReceived);
-
-	if (sblk->stat_XoffPauseFramesReceived)
-	   BCE_PRINTF("          0x%08X : XoffPauseFramesReceived\n",
-			sblk->stat_XoffPauseFramesReceived);
-
-	if (sblk->stat_OutXonSent)
-		BCE_PRINTF("         0x%08X : OutXonSent\n",
-			sblk->stat_OutXonSent);
-
-	if (sblk->stat_OutXoffSent)
-		BCE_PRINTF("         0x%08X : OutXoffSent\n",
-			sblk->stat_OutXoffSent);
-
-	if (sblk->stat_FlowControlDone)
-		BCE_PRINTF("         0x%08X : FlowControlDone\n",
-			sblk->stat_FlowControlDone);
-
-	if (sblk->stat_MacControlFramesReceived)
-		BCE_PRINTF("         0x%08X : MacControlFramesReceived\n",
-			sblk->stat_MacControlFramesReceived);
-
-	if (sblk->stat_XoffStateEntered)
-		BCE_PRINTF("         0x%08X : XoffStateEntered\n",
-			sblk->stat_XoffStateEntered);
-
-	if (sblk->stat_IfInFramesL2FilterDiscards)
-		BCE_PRINTF("         0x%08X : IfInFramesL2FilterDiscards\n",
-			sblk->stat_IfInFramesL2FilterDiscards);
-
-	if (sblk->stat_IfInRuleCheckerDiscards)
-		BCE_PRINTF("         0x%08X : IfInRuleCheckerDiscards\n",
-			sblk->stat_IfInRuleCheckerDiscards);
-
-	if (sblk->stat_IfInFTQDiscards)
-		BCE_PRINTF("         0x%08X : IfInFTQDiscards\n",
-			sblk->stat_IfInFTQDiscards);
-
-	if (sblk->stat_IfInMBUFDiscards)
-		BCE_PRINTF("         0x%08X : IfInMBUFDiscards\n",
-			sblk->stat_IfInMBUFDiscards);
-
-	if (sblk->stat_IfInRuleCheckerP4Hit)
-		BCE_PRINTF("         0x%08X : IfInRuleCheckerP4Hit\n",
-			sblk->stat_IfInRuleCheckerP4Hit);
-
-	if (sblk->stat_CatchupInRuleCheckerDiscards)
-		BCE_PRINTF("         0x%08X : CatchupInRuleCheckerDiscards\n",
-			sblk->stat_CatchupInRuleCheckerDiscards);
-
-	if (sblk->stat_CatchupInFTQDiscards)
-		BCE_PRINTF("         0x%08X : CatchupInFTQDiscards\n",
-			sblk->stat_CatchupInFTQDiscards);
-
-	if (sblk->stat_CatchupInMBUFDiscards)
-		BCE_PRINTF("         0x%08X : CatchupInMBUFDiscards\n",
-			sblk->stat_CatchupInMBUFDiscards);
-
-	if (sblk->stat_CatchupInRuleCheckerP4Hit)
-		BCE_PRINTF("         0x%08X : CatchupInRuleCheckerP4Hit\n",
-			sblk->stat_CatchupInRuleCheckerP4Hit);
+    BCE_PRINT_64BIT_STAT(stat_IfHCInOctets);
+    BCE_PRINT_64BIT_STAT(stat_IfHCInBadOctets);
+    BCE_PRINT_64BIT_STAT(stat_IfHCOutOctets);
+    BCE_PRINT_64BIT_STAT(stat_IfHCOutBadOctets);
+    BCE_PRINT_64BIT_STAT(stat_IfHCInUcastPkts);
+    BCE_PRINT_64BIT_STAT(stat_IfHCInBroadcastPkts);
+    BCE_PRINT_64BIT_STAT(stat_IfHCInMulticastPkts);
+    BCE_PRINT_64BIT_STAT(stat_IfHCOutUcastPkts);
+    BCE_PRINT_64BIT_STAT(stat_IfHCOutBroadcastPkts);
+    BCE_PRINT_64BIT_STAT(stat_IfHCOutMulticastPkts);
+    BCE_PRINT_32BIT_STAT(stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
+    BCE_PRINT_32BIT_STAT(stat_Dot3StatsCarrierSenseErrors);
+    BCE_PRINT_32BIT_STAT(stat_Dot3StatsFCSErrors);
+    BCE_PRINT_32BIT_STAT(stat_Dot3StatsAlignmentErrors);
+    BCE_PRINT_32BIT_STAT(stat_Dot3StatsSingleCollisionFrames);
+    BCE_PRINT_32BIT_STAT(stat_Dot3StatsMultipleCollisionFrames);
+    BCE_PRINT_32BIT_STAT(stat_Dot3StatsDeferredTransmissions);
+    BCE_PRINT_32BIT_STAT(stat_Dot3StatsExcessiveCollisions);
+    BCE_PRINT_32BIT_STAT(stat_Dot3StatsLateCollisions);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsCollisions);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsFragments);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsJabbers);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsUndersizePkts);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsOversizePkts);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx64Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx65Octetsto127Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx128Octetsto255Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx256Octetsto511Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx512Octetsto1023Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1024Octetsto1522Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1523Octetsto9022Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx64Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx65Octetsto127Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx128Octetsto255Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx256Octetsto511Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx512Octetsto1023Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1024Octetsto1522Octets);
+    BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1523Octetsto9022Octets);
+    BCE_PRINT_32BIT_STAT(stat_XonPauseFramesReceived);
+    BCE_PRINT_32BIT_STAT(stat_XoffPauseFramesReceived);
+    BCE_PRINT_32BIT_STAT(stat_OutXonSent);
+    BCE_PRINT_32BIT_STAT(stat_OutXoffSent);
+    BCE_PRINT_32BIT_STAT(stat_FlowControlDone);
+    BCE_PRINT_32BIT_STAT(stat_MacControlFramesReceived);
+    BCE_PRINT_32BIT_STAT(stat_XoffStateEntered);
+    BCE_PRINT_32BIT_STAT(stat_IfInFramesL2FilterDiscards);
+    BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerDiscards);
+    BCE_PRINT_32BIT_STAT(stat_IfInFTQDiscards);
+    BCE_PRINT_32BIT_STAT(stat_IfInMBUFDiscards);
+    BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerP4Hit);
+    BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerDiscards);
+    BCE_PRINT_32BIT_STAT(stat_CatchupInFTQDiscards);
+    BCE_PRINT_32BIT_STAT(stat_CatchupInMBUFDiscards);
+    BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerP4Hit);
 
 	BCE_PRINTF(
 		"----------------------------"
@@ -10465,7 +10312,7 @@ static __attribute__ ((noinline)) void
 bce_dump_com_state(struct bce_softc *sc, int regs)
 {
 	u32 val;
-	u32 fw_version[3];
+	u32 fw_version[4];
 
 	BCE_PRINTF(
 		"----------------------------"
@@ -10508,12 +10355,76 @@ bce_dump_com_state(struct bce_softc *sc,
 
 
 /****************************************************************************/
+/* Prints out the Receive Virtual 2 Physical (RV2P) state.                  */
+/*                                                                          */
+/* Returns:                                                                 */
+/*   Nothing.                                                               */
+/****************************************************************************/
+static __attribute__ ((noinline)) void
+bce_dump_rv2p_state(struct bce_softc *sc)
+{
+	u32 val, pc1, pc2, fw_ver_high, fw_ver_low;
+
+	BCE_PRINTF(
+		"----------------------------"
+		"   RV2P State   "
+		"----------------------------\n");
+
+    /* Stall the RV2P processors. */
+    val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
+    val |= BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2;
+    REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
+
+    /* Read the firmware version. */
+    val = 0x00000001;
+    REG_WR_IND(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
+    fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
+    fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) & BCE_RV2P_INSTR_HIGH_HIGH;
+	BCE_PRINTF("RV2P1 Firmware version - 0x%08X:0x%08X\n", fw_ver_high, fw_ver_low);
+
+    val = 0x00000001;
+    REG_WR_IND(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
+    fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
+    fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) & BCE_RV2P_INSTR_HIGH_HIGH;
+    BCE_PRINTF("RV2P2 Firmware version - 0x%08X:0x%08X\n", fw_ver_high, fw_ver_low);
+
+    /* Resume the RV2P processors. */
+    val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
+    val &= ~(BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2);
+    REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
+
+    /* Fetch the program counter value. */
+	val = 0x68007800;
+    REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
+    val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
+    pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
+    pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
+    BCE_PRINTF("0x%08X - RV2P1 program counter (1st read)\n", pc1);
+    BCE_PRINTF("0x%08X - RV2P2 program counter (1st read)\n", pc2);
+
+    /* Fetch the program counter value again to see if it is advancing. */
+    val = 0x68007800;
+    REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
+    val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
+    pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
+    pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
+    BCE_PRINTF("0x%08X - RV2P1 program counter (2nd read)\n", pc1);
+    BCE_PRINTF("0x%08X - RV2P2 program counter (2nd read)\n", pc2);
+
+	BCE_PRINTF(
+		"----------------------------"
+		"----------------"
+		"----------------------------\n");
+}
+
+
+/****************************************************************************/
 /* Prints out the driver state and then enters the debugger.                */
 /*                                                                          */
 /* Returns:                                                                 */
 /*   Nothing.                                                               */
 /****************************************************************************/
-static void
+static __attribute__ ((noinline)) void
 bce_breakpoint(struct bce_softc *sc)
 {
 
@@ -10544,6 +10455,7 @@ bce_breakpoint(struct bce_softc *sc)
 		bce_dump_tpat_state(sc, 0);
 		bce_dump_cp_state(sc, 0);
 		bce_dump_com_state(sc, 0);
+        bce_dump_rv2p_state(sc);
 #ifdef BCE_JUMBO_HDRSPLIT
 		bce_dump_pgbd(sc, 0, NULL);
 		bce_dump_pg_mbuf_chain(sc, 0, USABLE_PG_BD);

Modified: stable/7/sys/dev/bce/if_bcefw.h
==============================================================================
--- stable/7/sys/dev/bce/if_bcefw.h	Thu Apr 15 19:26:28 2010	(r206680)
+++ stable/7/sys/dev/bce/if_bcefw.h	Thu Apr 15 19:28:15 2010	(r206681)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2006-2009 Broadcom Corporation
+ * Copyright (c) 2006-2010 Broadcom Corporation
  *	David Christensen <davidch@broadcom.com>.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without

Modified: stable/7/sys/dev/bce/if_bcereg.h
==============================================================================
--- stable/7/sys/dev/bce/if_bcereg.h	Thu Apr 15 19:26:28 2010	(r206680)
+++ stable/7/sys/dev/bce/if_bcereg.h	Thu Apr 15 19:28:15 2010	(r206681)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2006-2009 Broadcom Corporation
+ * Copyright (c) 2006-2010 Broadcom Corporation
  *	David Christensen <davidch@broadcom.com>.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -453,24 +453,10 @@
 	}
 
 /* Announces function entry. */
-#if 0
-#define DBENTER(cond)								 			\
-	u32 start_time = REG_RD(sc, BCE_TIMER_25MHZ_FREE_RUN);		\
-	u32 end_time;										  		\
-	DBPRINT(sc, (cond), "%s(enter)\n", __FUNCTION__);
-#endif
-
 #define DBENTER(cond)									  		\
 	DBPRINT(sc, (cond), "%s(enter)\n", __FUNCTION__)
 
 /* Announces function exit. */
-#if 0
-#define DBEXIT(cond, val)								  		\
-	end_time = REG_RD(sc, BCE_TIMER_25MHZ_FREE_RUN);	  		\
-	val += (u64) BCE_TIME_DELTA(start_time, end_time);			\
-	DBPRINT(sc, (cond), "%s(exit)\n", __FUNCTION__);
-#endif
-
 #define DBEXIT(cond)											\
 	DBPRINT(sc, (cond), "%s(exit)\n", __FUNCTION__)
 
@@ -6451,6 +6437,7 @@ struct bce_softc
 #define BCE_PHY_INT_MODE_MASK_FLAG			0x00000300
 #define BCE_PHY_INT_MODE_AUTO_POLLING_FLAG	0x00000100
 #define BCE_PHY_INT_MODE_LINK_READY_FLAG	0x00000200
+#define BCE_PHY_IEEE_CLAUSE_45_FLAG     	0x00000400
 
 	/* Values that need to be shared with the PHY driver. */
 	u32					bce_shared_hw_cfg;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 11 Pyun YongHyeon freebsd_committer freebsd_triage 2010-04-15 21:41:14 UTC
State Changed
From-To: patched->closed

MFC complete. Thanks for reporting!