Source-Changes-HG archive

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

[src/trunk]: src Add support for KSZ80[0456]1, KSZ8721, KSZ9[01]31, KS8731 an...



details:   https://anonhg.NetBSD.org/src/rev/9a3457000ccf
branches:  trunk
changeset: 460868:9a3457000ccf
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Wed Nov 06 16:02:53 2019 +0000

description:
Add support for KSZ80[0456]1, KSZ8721, KSZ9[01]31, KS8731 and KSZ9477.
It also supports LAN7430's internal PHY. First wrote by nisimura@ and added
some device support by me. Not tested well.

diffstat:

 share/man/man4/micphy.4 |   10 +-
 sys/dev/mii/micphy.c    |  212 ++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 194 insertions(+), 28 deletions(-)

diffs (truncated from 324 to 300 lines):

diff -r d62abbcf09ac -r 9a3457000ccf share/man/man4/micphy.4
--- a/share/man/man4/micphy.4   Wed Nov 06 16:00:33 2019 +0000
+++ b/share/man/man4/micphy.4   Wed Nov 06 16:02:53 2019 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: micphy.4,v 1.2 2014/03/03 09:10:46 wiz Exp $
+.\"    $NetBSD: micphy.4,v 1.3 2019/11/06 16:02:53 msaitoh Exp $
 .\"
 .\" Copyright (c) 2014 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -15,18 +15,20 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd March 3, 2014
+.Dd November 6, 2019
 .Dt MICPHY 4
 .Os
 .Sh NAME
 .Nm micphy
-.Nd Micrel KSZ9021 10/100/1000 PHY driver
+.Nd Micrel KSZ8xxx 10/100 and KSZ9xxx 10/100/1000 PHY driver
 .Sh SYNOPSIS
 .Cd "micphy* at mii? phy ?"
 .Sh DESCRIPTION
 The
 .Nm
-driver currently supports only Micrel KSZ9021RN PHY.
+driver currently supports KSZ80[2345689]1, KSZ87[23]x, KSZ90[23]1, KSZ9131 and
+KSZ9477.
+It also supports LAN7430's internal PHY.
 The driver has a fixup for
 .Xr evbarm/cpsw 4
 which requires Gig-E PHYs to adjust RGMII signal timing.
diff -r d62abbcf09ac -r 9a3457000ccf sys/dev/mii/micphy.c
--- a/sys/dev/mii/micphy.c      Wed Nov 06 16:00:33 2019 +0000
+++ b/sys/dev/mii/micphy.c      Wed Nov 06 16:02:53 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: micphy.c,v 1.8 2019/03/25 07:34:13 msaitoh Exp $       */
+/*     $NetBSD: micphy.c,v 1.9 2019/11/06 16:02:53 msaitoh Exp $       */
 
 /*-
  * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -55,11 +55,11 @@
  */
 
 /*
- * Driver for Micrel KSZ9021RN PHYs
+ * Driver for Micrel KSZ8xxx 10/100 and KSZ9xxx 10/100/1000 PHY.
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: micphy.c,v 1.8 2019/03/25 07:34:13 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: micphy.c,v 1.9 2019/11/06 16:02:53 msaitoh Exp $");
 
 #include "opt_mii.h"
 
@@ -87,19 +87,98 @@
     DVF_DETACH_SHUTDOWN);
 
 static int     micphy_service(struct mii_softc *, struct mii_data *, int);
+static void    micphy_status(struct mii_softc *);
 static void    micphy_fixup(struct mii_softc *, int, int, device_t);
 
 static const struct mii_phy_funcs micphy_funcs = {
-       micphy_service, ukphy_status, micphy_reset,
+       micphy_service, micphy_status, micphy_reset,
+};
+
+struct micphy_softc {
+       struct mii_softc sc_mii;
+       uint32_t sc_lstype;     /* Type of link status register */
 };
 
 static const struct mii_phydesc micphys[] = {
-       MII_PHY_DESC(MICREL, KSZ8081),
-       MII_PHY_DESC(MICREL, KSZ9021RNI),
+       MII_PHY_DESC(MICREL, KSZ8041),
+       MII_PHY_DESC(MICREL, KSZ8051), /* +8021,8031 */
+       MII_PHY_DESC(MICREL, KSZ8061),
+       MII_PHY_DESC(MICREL, KSZ8081), /* +8051,8091 */
+       MII_PHY_DESC(MICREL, KS8737),
+       MII_PHY_DESC(MICREL, KSZ9021_8001_8721),
+       MII_PHY_DESC(MICREL, KSZ9031),
+       MII_PHY_DESC(MICREL, KSZ9131),
+       MII_PHY_DESC(MICREL, KSZ9477), /* +LAN7430internal */
        MII_PHY_END,
 };
 
-#define        MII_KSZ8081_PHYCTL2                     0x1f
+/*
+ * Model Rev. Media  LSTYPE Devices       
+ *
+ * 0x11              100    1F_42  KSZ8041
+ * 0x13              100    1F_42? KSZ8041RNLI
+ * 0x15           ?  100    1E_20  KSZ8051
+ *      0x5  100    1E_20  KSZ8021
+ *      0x6  100    1E_20  KSZ8031
+ * 0x16           ?  100    1E_20  KSZ8081
+ *        ?  100    1E_20  KSZ8091
+ * 0x17              100    1E_20  KSZ8061
+ * 0x21         0x0  giga   GIGA   KSZ9021
+ *      0x1  giga   GIGA   KSZ9021RLRN
+ *      0x9  100    1F_42  KSZ8721BL/SL
+ *      0x9  100    none?  KSZ8721CL
+ *      0xa  100    1F_42  KSZ8001
+ * 0x22              giga   GIGA   KSZ9031
+ * 0x23           1? gigasw GIGA   KSZ9477 (No master/slave bit) 
+ *        5? giga   GIGA   LAN7430internal
+ * 0x24              giga   GIGA   KSZ9131        
+ * 0x32              100    1F_42  KS8737         
+ */
+
+/* Type of link status register */
+#define MICPHYF_LSTYPE_DEFAULT 0
+#define MICPHYF_LSTYPE_1F_42   1
+#define MICPHYF_LSTYPE_1E_20   2
+#define MICPHYF_LSTYPE_GIGA    3
+
+/* Return if the device is Gigabit (KSZ9021) */
+#define KSZ_MODEL21H_GIGA(rev)                 \
+       ((((rev) & 0x0e) == 0) ? true : false)
+
+#define KSZ_XREG_CONTROL       0x0b
+#define KSZ_XREG_WRITE         0x0c
+#define KSZ_XREG_READ          0x0d
+#define KSZ_XREG_CTL_SEL_READ  0x0000
+#define KSZ_XREG_CTL_SEL_WRITE 0x8000
+
+#define REG_RGMII_CLOCK_AND_CONTROL    0x104
+#define REG_RGMII_RX_DATA              0x105
+
+/* PHY control 1 register for 10/100 PHYs (KSZ80[235689]1) */
+#define KSZ8051_PHYCTL1                0x1e
+#define KSZ8051_PHY_LINK       0x0100
+#define KSZ8051_PHY_MDIX       0x0020
+#define KSZ8051_PHY_FDX                0x0004
+#define KSZ8051_PHY_SPD_MASK   0x0003
+#define KSZ8051_PHY_SPD_10T    0x0001
+#define KSZ8051_PHY_SPD_100TX  0x0002
+
+/* PHY control 2 register for 10/100 PHYs (KSZ8041, KSZ8721 and KSZ8001) */
+#define        KSZ8041_PHYCTL2         0x1f
+#define KSZ8041_PHY_ACOMP      0x0080
+#define KSZ8041_PHY_SPD_MASK   0x001c
+#define KSZ8041_PHY_SPD_10T    0x0004
+#define KSZ8041_PHY_SPD_100TX  0x0008
+#define KSZ8041_PHY_FDX                0x0010
+#define KSZ8051_PHYCTL2                0x1f
+
+/* PHY control register for Gigabit PHYs */
+#define KSZ_GPHYCTL            0x1f
+#define KSZ_GPHY_SPD_1000T     0x0040
+#define KSZ_GPHY_SPD_100TX     0x0020
+#define KSZ_GPHY_SPD_10T       0x0010
+#define KSZ_GPHY_FDX           0x0008
+#define KSZ_GPHY_1000T_MS      0x0004
 
 static int
 micphymatch(device_t parent, cfdata_t match, void *aux)
@@ -115,7 +194,8 @@
 static void
 micphyattach(device_t parent, device_t self, void *aux)
 {
-       struct mii_softc *sc = device_private(self);
+       struct micphy_softc *msc = device_private(self);
+       struct mii_softc *sc = &msc->sc_mii;
        struct mii_attach_args *ma = aux;
        struct mii_data *mii = ma->mii_data;
        int model = MII_MODEL(ma->mii_id2);
@@ -134,6 +214,25 @@
        sc->mii_flags = ma->mii_flags;
        sc->mii_anegticks = MII_ANEGTICKS;
 
+       if ((sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8041)
+           || (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8041RNLI)
+           || (sc->mii_mpd_model == MII_MODEL_MICREL_KS8737)
+           || ((sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9021_8001_8721)
+               && !KSZ_MODEL21H_GIGA(sc->mii_mpd_rev))) {
+               msc->sc_lstype = MICPHYF_LSTYPE_1F_42;
+       } else if ((sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8051)
+           || (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8081)
+           || (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8061)) {
+               msc->sc_lstype = MICPHYF_LSTYPE_1E_20;
+       } else if (((sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9021_8001_8721)
+               && KSZ_MODEL21H_GIGA(sc->mii_mpd_rev))
+           || (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9031)
+           || (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9477)
+           || (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9131)) {
+               msc->sc_lstype = MICPHYF_LSTYPE_GIGA;
+       } else
+               msc->sc_lstype = MICPHYF_LSTYPE_DEFAULT;
+
        PHY_RESET(sc);
 
        micphy_fixup(sc, model, rev, parent);
@@ -164,10 +263,10 @@
         * behavior).
         */
        if (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8081)
-               PHY_READ(sc, MII_KSZ8081_PHYCTL2, &reg);
+               PHY_READ(sc, KSZ8051_PHYCTL2, &reg);
        mii_phy_reset(sc);
        if (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8081)
-               PHY_WRITE(sc, MII_KSZ8081_PHYCTL2, reg);
+               PHY_WRITE(sc, KSZ8051_PHYCTL2, reg);
 }
 
 static int
@@ -223,24 +322,15 @@
        return 0;
 }
 
-#define XREG_CONTROL   0x0b
-#define XREG_WRITE     0x0c
-#define XREG_READ      0x0d
-#define XREG_CTL_SEL_READ      0x0000
-#define XREG_CTL_SEL_WRITE     0x8000
-
-#define REG_RGMII_CLOCK_AND_CONTROL    0x104
-#define REG_RGMII_RX_DATA              0x105
-
 static void
 micphy_writexreg(struct mii_softc *sc, uint32_t reg, uint32_t wval)
 {
        uint16_t rval __debugused;
 
-       PHY_WRITE(sc, XREG_CONTROL, XREG_CTL_SEL_WRITE | reg);
-       PHY_WRITE(sc, XREG_WRITE, wval);
-       PHY_WRITE(sc, XREG_CONTROL, XREG_CTL_SEL_READ | reg);
-       PHY_READ(sc, XREG_READ, &rval);
+       PHY_WRITE(sc, KSZ_XREG_CONTROL, KSZ_XREG_CTL_SEL_WRITE | reg);
+       PHY_WRITE(sc, KSZ_XREG_WRITE, wval);
+       PHY_WRITE(sc, KSZ_XREG_CONTROL, KSZ_XREG_CTL_SEL_READ | reg);
+       PHY_READ(sc, KSZ_XREG_READ, &rval);
        KDASSERT(wval == rval);
 }
 
@@ -248,7 +338,7 @@
 micphy_fixup(struct mii_softc *sc, int model, int rev, device_t parent)
 {
        switch (model) {
-       case MII_MODEL_MICREL_KSZ9021RNI:
+       case MII_MODEL_MICREL_KSZ9021_8001_8721:
                if (!device_is_a(parent, "cpsw"))
                        break;
 
@@ -268,3 +358,77 @@
 
        return;
 }
+
+static void
+micphy_status(struct mii_softc *sc)
+{
+       struct micphy_softc *msc = device_private(sc->mii_dev);
+       struct mii_data *mii = sc->mii_pdata;
+       uint16_t bmsr, bmcr, sr;
+
+       /* For unknown devices */
+       if (msc->sc_lstype == MICPHYF_LSTYPE_DEFAULT) {
+               ukphy_status(sc);
+               return;
+       }
+
+       mii->mii_media_status = IFM_AVALID;
+       mii->mii_media_active = IFM_ETHER;
+
+       PHY_READ(sc, MII_BMCR, &bmcr);
+
+       PHY_READ(sc, MII_BMSR, &bmsr);
+       PHY_READ(sc, MII_BMSR, &bmsr);
+       if (bmsr & BMSR_LINK)
+               mii->mii_media_status |= IFM_ACTIVE;
+
+       if (bmcr & BMCR_AUTOEN) {
+               if ((bmsr & BMSR_ACOMP) == 0) {
+                       mii->mii_media_active |= IFM_NONE;
+                       return;
+               }
+       }
+
+       if (msc->sc_lstype == MICPHYF_LSTYPE_1F_42) {
+               PHY_READ(sc, KSZ8041_PHYCTL2, &sr);
+               if ((sr & KSZ8041_PHY_SPD_MASK) == 0)
+                       mii->mii_media_active |= IFM_NONE;
+               else if (sr & KSZ8041_PHY_SPD_100TX)
+                       mii->mii_media_active |= IFM_100_TX;
+               else if (sr & KSZ8041_PHY_SPD_10T)
+                       mii->mii_media_active |= IFM_10_T;
+               if (sr & KSZ8041_PHY_FDX)
+                       mii->mii_media_active |= IFM_FDX
+                           | mii_phy_flowstatus(sc);
+       } else if (msc->sc_lstype == MICPHYF_LSTYPE_1E_20) {
+               PHY_READ(sc, KSZ8051_PHYCTL1, &sr);
+               if ((sr & KSZ8051_PHY_SPD_MASK) == 0)
+                       mii->mii_media_active |= IFM_NONE;
+               else if (sr & KSZ8051_PHY_SPD_100TX)
+                       mii->mii_media_active |= IFM_100_TX;
+               else if (sr & KSZ8051_PHY_SPD_10T)
+                       mii->mii_media_active |= IFM_10_T;



Home | Main Index | Thread Index | Old Index