Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev - Fix detection of BGEPHYF_FIBER_{MII|TBI}



details:   https://anonhg.NetBSD.org/src/rev/a65262dce6fc
branches:  trunk
changeset: 796784:a65262dce6fc
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Tue Jun 17 21:37:20 2014 +0000

description:
- Fix detection of BGEPHYF_FIBER_{MII|TBI}
- Add BCM5708S support in brgphy(4). The auto negotiation may have some bugs.
- Add 2500SX support (not tested).
- Fix bit definition of BRGPHY_MRBE_MSG_PG5_NP_T2 from FreeBSD.

diffstat:

 sys/dev/mii/brgphy.c    |  387 +++++++++++++++++++++++++++++++++++------------
 sys/dev/mii/brgphyreg.h |   12 +-
 sys/dev/pci/if_bge.c    |   15 +-
 sys/dev/pci/if_bnx.c    |    6 +-
 sys/dev/pci/if_bnxreg.h |    5 +-
 5 files changed, 308 insertions(+), 117 deletions(-)

diffs (truncated from 671 to 300 lines):

diff -r d44fc2c3dffb -r a65262dce6fc sys/dev/mii/brgphy.c
--- a/sys/dev/mii/brgphy.c      Tue Jun 17 19:33:20 2014 +0000
+++ b/sys/dev/mii/brgphy.c      Tue Jun 17 21:37:20 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: brgphy.c,v 1.70 2014/06/16 16:48:16 msaitoh Exp $      */
+/*     $NetBSD: brgphy.c,v 1.71 2014/06/17 21:37:20 msaitoh Exp $      */
 
 /*-
  * Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: brgphy.c,v 1.70 2014/06/16 16:48:16 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: brgphy.c,v 1.71 2014/06/17 21:37:20 msaitoh Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -90,8 +90,10 @@
        struct mii_softc sc_mii;
        bool sc_isbge;
        bool sc_isbnx;
-       uint32_t sc_chipid;    /* parent's chipid */
-       uint32_t sc_phyflags;  /* parent's phyflags */
+       uint32_t sc_chipid;     /* parent's chipid */
+       uint32_t sc_phyflags;   /* parent's phyflags */
+       uint32_t sc_shared_hwcfg; /* shared hw config */
+       uint32_t sc_port_hwcfg; /* port specific hw config */
 };
 
 CFATTACH_DECL3_NEW(brgphy, sizeof(struct brgphy_softc),
@@ -99,7 +101,10 @@
     DVF_DETACH_SHUTDOWN);
 
 static int     brgphy_service(struct mii_softc *, struct mii_data *, int);
-static void    brgphy_status(struct mii_softc *);
+static void    brgphy_copper_status(struct mii_softc *);
+static void    brgphy_fiber_status(struct mii_softc *);
+static void    brgphy_5708s_status(struct mii_softc *);
+static void    brgphy_5709s_status(struct mii_softc *);
 static int     brgphy_mii_phy_auto(struct mii_softc *);
 static void    brgphy_loop(struct mii_softc *);
 static void    brgphy_reset(struct mii_softc *);
@@ -116,8 +121,20 @@
 static void    brgphy_eth_wirespeed(struct mii_softc *);
 
 
-static const struct mii_phy_funcs brgphy_funcs = {
-       brgphy_service, brgphy_status, brgphy_reset,
+static const struct mii_phy_funcs brgphy_copper_funcs = {
+       brgphy_service, brgphy_copper_status, brgphy_reset,
+};
+
+static const struct mii_phy_funcs brgphy_fiber_funcs = {
+       brgphy_service, brgphy_fiber_status, brgphy_reset,
+};
+
+static const struct mii_phy_funcs brgphy_5708s_funcs = {
+       brgphy_service, brgphy_5708s_status, brgphy_reset,
+};
+
+static const struct mii_phy_funcs brgphy_5709s_funcs = {
+       brgphy_service, brgphy_5709s_status, brgphy_reset,
 };
 
 static const struct mii_phydesc brgphys[] = {
@@ -178,6 +195,9 @@
        { MII_OUI_BROADCOM2,            MII_MODEL_BROADCOM2_BCM5482,
          MII_STR_BROADCOM2_BCM5482 },
 
+       { MII_OUI_BROADCOM2,            MII_MODEL_BROADCOM2_BCM5708S,
+         MII_STR_BROADCOM2_BCM5708S },
+
        { MII_OUI_BROADCOM2,            MII_MODEL_BROADCOM2_BCM5709C,
          MII_STR_BROADCOM2_BCM5709C },
 
@@ -264,7 +284,6 @@
        sc->mii_pdata = mii;
        sc->mii_flags = ma->mii_flags;
        sc->mii_anegticks = MII_ANEGTICKS;
-       sc->mii_funcs = &brgphy_funcs;
 
        if (device_is_a(parent, "bge"))
                bsc->sc_isbge = true;
@@ -281,10 +300,29 @@
                        aprint_error_dev(self, "failed to get chipid\n");
        }
 
+       if (bsc->sc_isbnx) {
+               /* Currently, only bnx use sc_shared_hwcfg and sc_port_hwcfg */
+               if (!prop_dictionary_get_uint32(dict, "shared_hwcfg",
+                       &bsc->sc_shared_hwcfg))
+                       aprint_error_dev(self, "failed to get shared_hwcfg\n");
+               if (!prop_dictionary_get_uint32(dict, "port_hwcfg",
+                       &bsc->sc_port_hwcfg))
+                       aprint_error_dev(self, "failed to get port_hwcfg\n");
+       }
+
+       if (sc->mii_flags & MIIF_HAVEFIBER) {
+               if (_BNX_CHIP_NUM(bsc->sc_chipid) == BNX_CHIP_NUM_5708)
+                       sc->mii_funcs = &brgphy_5708s_funcs;
+               else if (_BNX_CHIP_NUM(bsc->sc_chipid) == BNX_CHIP_NUM_5709)
+                       sc->mii_funcs = &brgphy_5709s_funcs;
+               else
+                       sc->mii_funcs = &brgphy_fiber_funcs;
+       } else
+               sc->mii_funcs = &brgphy_copper_funcs;
+
        PHY_RESET(sc);
 
-       sc->mii_capabilities =
-           PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
+       sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
        if (sc->mii_capabilities & BMSR_EXTSTAT)
                sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR);
 
@@ -363,6 +401,10 @@
                case IFM_AUTO:
                        (void) brgphy_mii_phy_auto(sc);
                        break;
+               case IFM_2500_SX:
+                       speed = BRGPHY_5708S_BMCR_2500;
+                       goto setit;
+               case IFM_1000_SX:
                case IFM_1000_T:
                        speed = BMCR_S1000;
                        goto setit;
@@ -383,7 +425,9 @@
                        PHY_WRITE(sc, MII_ANAR, ANAR_CSMA);
                        PHY_WRITE(sc, MII_BMCR, speed);
 
-                       if (IFM_SUBTYPE(ife->ifm_media) != IFM_1000_T)
+                       if ((IFM_SUBTYPE(ife->ifm_media) != IFM_1000_T) &&
+                           (IFM_SUBTYPE(ife->ifm_media) != IFM_1000_SX) &&
+                           (IFM_SUBTYPE(ife->ifm_media) != IFM_2500_SX))
                                break;
 
                        PHY_WRITE(sc, MII_100T2CR, gig);
@@ -492,7 +536,7 @@
 }
 
 static void
-brgphy_status(struct mii_softc *sc)
+brgphy_copper_status(struct mii_softc *sc)
 {
        struct mii_data *mii = sc->mii_pdata;
        struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
@@ -526,85 +570,46 @@
                        return;
                }
 
-               if ((sc->mii_mpd_oui == MII_OUI_BROADCOM2)
-                   && (sc->mii_mpd_model == MII_MODEL_BROADCOM2_BCM5709S)) {
-                       /*
-                        * 5709S has its own general purpose status registers
-                        */
-                       PHY_WRITE(sc, BRGPHY_BLOCK_ADDR,
-                           BRGPHY_BLOCK_ADDR_GP_STATUS);
-
-                       auxsts = PHY_READ(sc, BRGPHY_GP_STATUS_TOP_ANEG_STATUS);
-
-                       PHY_WRITE(sc, BRGPHY_BLOCK_ADDR,
-                           BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
+               auxsts = PHY_READ(sc, BRGPHY_MII_AUXSTS);
 
-                       switch (auxsts & 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;
-                       default:
-                               mii->mii_media_active |= IFM_NONE;
-                               mii->mii_media_status = 0;
-                               break;
-                       }
+               switch (auxsts & BRGPHY_AUXSTS_AN_RES) {
+               case BRGPHY_RES_1000FD:
+                       mii->mii_media_active |= IFM_1000_T | IFM_FDX;
+                       gtsr = PHY_READ(sc, MII_100T2SR);
+                       if (gtsr & GTSR_MS_RES)
+                               mii->mii_media_active |= IFM_ETH_MASTER;
+                       break;
 
-                       if (auxsts & BRGPHY_GP_STATUS_TOP_ANEG_FDX)
-                               mii->mii_media_active |= IFM_FDX;
-                       else
-                               mii->mii_media_active |= IFM_HDX;
-
-               } else {
-                       auxsts = PHY_READ(sc, BRGPHY_MII_AUXSTS);
+               case BRGPHY_RES_1000HD:
+                       mii->mii_media_active |= IFM_1000_T | IFM_HDX;
+                       gtsr = PHY_READ(sc, MII_100T2SR);
+                       if (gtsr & GTSR_MS_RES)
+                               mii->mii_media_active |= IFM_ETH_MASTER;
+                       break;
 
-                       switch (auxsts & BRGPHY_AUXSTS_AN_RES) {
-                       case BRGPHY_RES_1000FD:
-                               mii->mii_media_active |= IFM_1000_T | IFM_FDX;
-                               gtsr = PHY_READ(sc, MII_100T2SR);
-                               if (gtsr & GTSR_MS_RES)
-                                       mii->mii_media_active |= IFM_ETH_MASTER;
-                               break;
+               case BRGPHY_RES_100FD:
+                       mii->mii_media_active |= IFM_100_TX | IFM_FDX;
+                       break;
 
-                       case BRGPHY_RES_1000HD:
-                               mii->mii_media_active |= IFM_1000_T | IFM_HDX;
-                               gtsr = PHY_READ(sc, MII_100T2SR);
-                               if (gtsr & GTSR_MS_RES)
-                                       mii->mii_media_active |= IFM_ETH_MASTER;
-                               break;
+               case BRGPHY_RES_100T4:
+                       mii->mii_media_active |= IFM_100_T4 | IFM_HDX;
+                       break;
 
-                       case BRGPHY_RES_100FD:
-                               mii->mii_media_active |= IFM_100_TX | IFM_FDX;
-                               break;
+               case BRGPHY_RES_100HD:
+                       mii->mii_media_active |= IFM_100_TX | IFM_HDX;
+                       break;
 
-                       case BRGPHY_RES_100T4:
-                               mii->mii_media_active |= IFM_100_T4 | IFM_HDX;
-                               break;
-
-                       case BRGPHY_RES_100HD:
-                               mii->mii_media_active |= IFM_100_TX | IFM_HDX;
-                               break;
+               case BRGPHY_RES_10FD:
+                       mii->mii_media_active |= IFM_10_T | IFM_FDX;
+                       break;
 
-                       case BRGPHY_RES_10FD:
-                               mii->mii_media_active |= IFM_10_T | IFM_FDX;
-                               break;
+               case BRGPHY_RES_10HD:
+                       mii->mii_media_active |= IFM_10_T | IFM_HDX;
+                       break;
 
-                       case BRGPHY_RES_10HD:
-                               mii->mii_media_active |= IFM_10_T | IFM_HDX;
-                               break;
-
-                       default:
-                               mii->mii_media_active |= IFM_NONE;
-                               mii->mii_media_status = 0;
-                       }
+               default:
+                       mii->mii_media_active |= IFM_NONE;
+                       mii->mii_media_status = 0;
                }
 
                if (mii->mii_media_active & IFM_FDX)
@@ -614,6 +619,188 @@
                mii->mii_media_active = ife->ifm_media;
 }
 
+void
+brgphy_fiber_status(struct mii_softc *sc)
+{
+       struct mii_data *mii = sc->mii_pdata;
+       struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
+       int bmcr, bmsr;
+
+       mii->mii_media_status = IFM_AVALID;
+       mii->mii_media_active = IFM_ETHER;
+
+       bmsr = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR);
+       if (bmsr & BMSR_LINK)
+               mii->mii_media_status |= IFM_ACTIVE;
+
+       bmcr = PHY_READ(sc, MII_BMCR);
+       if (bmcr & BMCR_LOOP)
+               mii->mii_media_active |= IFM_LOOP;
+
+       if (bmcr & BMCR_AUTOEN) {
+               int val;
+
+               if ((bmsr & BMSR_ACOMP) == 0) {
+                       /* Erg, still trying, I guess... */
+                       mii->mii_media_active |= IFM_NONE;
+                       return;
+               }
+
+               mii->mii_media_active |= IFM_1000_SX;
+
+               val = PHY_READ(sc, MII_ANAR) &
+                     PHY_READ(sc, MII_ANLPAR);



Home | Main Index | Thread Index | Old Index