Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 18 Mar 2010 20:57:57 +0000 (UTC)
From:      David Christensen <davidch@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r205299 - head/sys/dev/mii
Message-ID:  <201003182057.o2IKvvVe035699@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: davidch
Date: Thu Mar 18 20:57:57 2010
New Revision: 205299
URL: http://svn.freebsd.org/changeset/base/205299

Log:
  - Added support for 5709S/5716S PHYs.
  
  Submitted by:	pyunyh
  MFC after:	2 weeks

Modified:
  head/sys/dev/mii/brgphy.c
  head/sys/dev/mii/brgphyreg.h
  head/sys/dev/mii/miidevs

Modified: head/sys/dev/mii/brgphy.c
==============================================================================
--- head/sys/dev/mii/brgphy.c	Thu Mar 18 20:30:25 2010	(r205298)
+++ head/sys/dev/mii/brgphy.c	Thu Mar 18 20:57:57 2010	(r205299)
@@ -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: head/sys/dev/mii/brgphyreg.h
==============================================================================
--- head/sys/dev/mii/brgphyreg.h	Thu Mar 18 20:30:25 2010	(r205298)
+++ head/sys/dev/mii/brgphyreg.h	Thu Mar 18 20:57:57 2010	(r205299)
@@ -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: head/sys/dev/mii/miidevs
==============================================================================
--- head/sys/dev/mii/miidevs	Thu Mar 18 20:30:25 2010	(r205298)
+++ head/sys/dev/mii/miidevs	Thu Mar 18 20:57:57 2010	(r205299)
@@ -150,6 +150,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?) */



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