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?) */
_______________________________________________
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-unsubscr...@freebsd.org"

Reply via email to