Author: loos
Date: Fri Dec 30 19:55:04 2016
New Revision: 310852
URL: https://svnweb.freebsd.org/changeset/base/310852

Log:
  MFC of r303230, r303253 and r303420:
  
  Add support for the Microchip/Micrel KSZ9031 Gigabit Ethernet PHY.
  
  Enable the build of micphy as part of generic miibus build, but only for
  FDT enabled systems.
  
  The Micrel PHYs reads the optional external delays from DTB.
  
  Tested on uBMC and uFW.
  
  Sponsored by: Rubicon Communications (Netgate)

Modified:
  stable/11/sys/arm/altera/socfpga/files.socfpga
  stable/11/sys/conf/files
  stable/11/sys/dev/mii/micphy.c
  stable/11/sys/dev/mii/miidevs
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/arm/altera/socfpga/files.socfpga
==============================================================================
--- stable/11/sys/arm/altera/socfpga/files.socfpga      Fri Dec 30 19:43:23 
2016        (r310851)
+++ stable/11/sys/arm/altera/socfpga/files.socfpga      Fri Dec 30 19:55:04 
2016        (r310852)
@@ -9,7 +9,6 @@ arm/altera/socfpga/socfpga_rstmgr.c             sta
 arm/altera/socfpga/socfpga_mp.c                        optional smp
 arm/altera/socfpga/socfpga_gpio.c              optional gpio
 
-dev/mii/micphy.c                               optional micphy
 dev/mmc/host/dwmmc.c                           optional dwmmc
 
 # BERI specific

Modified: stable/11/sys/conf/files
==============================================================================
--- stable/11/sys/conf/files    Fri Dec 30 19:43:23 2016        (r310851)
+++ stable/11/sys/conf/files    Fri Dec 30 19:55:04 2016        (r310852)
@@ -2094,6 +2094,7 @@ dev/mii/icsphy.c          optional miibus | icsp
 dev/mii/ip1000phy.c            optional miibus | ip1000phy
 dev/mii/jmphy.c                        optional miibus | jmphy
 dev/mii/lxtphy.c               optional miibus | lxtphy
+dev/mii/micphy.c               optional miibus fdt | micphy fdt
 dev/mii/mii.c                  optional miibus | mii
 dev/mii/mii_bitbang.c          optional miibus | mii_bitbang
 dev/mii/mii_physubr.c          optional miibus | mii

Modified: stable/11/sys/dev/mii/micphy.c
==============================================================================
--- stable/11/sys/dev/mii/micphy.c      Fri Dec 30 19:43:23 2016        
(r310851)
+++ stable/11/sys/dev/mii/micphy.c      Fri Dec 30 19:55:04 2016        
(r310852)
@@ -67,6 +67,14 @@ __FBSDID("$FreeBSD$");
 #define        MII_KSZPHY_CLK_CONTROL_PAD_SKEW         0x104
 #define        MII_KSZPHY_RX_DATA_PAD_SKEW             0x105
 #define        MII_KSZPHY_TX_DATA_PAD_SKEW             0x106
+/* KSZ9031 */
+#define        MII_KSZ9031_MMD_ACCESS_CTRL             0x0d
+#define        MII_KSZ9031_MMD_ACCESS_DATA             0x0e
+#define         MII_KSZ9031_MMD_DATA_NOINC             (1 << 14)
+#define        MII_KSZ9031_CONTROL_PAD_SKEW            0x4
+#define        MII_KSZ9031_RX_DATA_PAD_SKEW            0x5
+#define        MII_KSZ9031_TX_DATA_PAD_SKEW            0x6
+#define        MII_KSZ9031_CLOCK_PAD_SKEW              0x8
 
 #define        PS_TO_REG(p)    ((p) / 200)
 
@@ -95,6 +103,7 @@ DRIVER_MODULE(micphy, miibus, micphy_dri
 
 static const struct mii_phydesc micphys[] = {
        MII_PHY_DESC(MICREL, KSZ9021),
+       MII_PHY_DESC(MICREL, KSZ9031),
        MII_PHY_END
 };
 
@@ -104,48 +113,128 @@ static const struct mii_phy_funcs micphy
        mii_phy_reset
 };
 
+static uint32_t
+ksz9031_read(struct mii_softc *sc, uint32_t devaddr, uint32_t reg)
+{
+       /* Set up device address and register. */
+        PHY_WRITE(sc, MII_KSZ9031_MMD_ACCESS_CTRL, devaddr);
+        PHY_WRITE(sc, MII_KSZ9031_MMD_ACCESS_DATA, reg);
+
+       /* Select register data for MMD and read the value. */
+        PHY_WRITE(sc, MII_KSZ9031_MMD_ACCESS_CTRL,
+           MII_KSZ9031_MMD_DATA_NOINC | devaddr);
+
+       return (PHY_READ(sc, MII_KSZ9031_MMD_ACCESS_DATA));
+}
+
+static void
+ksz9031_write(struct mii_softc *sc, uint32_t devaddr, uint32_t reg,
+       uint32_t val)
+{
+
+       /* Set up device address and register. */
+       PHY_WRITE(sc, MII_KSZ9031_MMD_ACCESS_CTRL, devaddr);
+       PHY_WRITE(sc, MII_KSZ9031_MMD_ACCESS_DATA, reg);
+
+       /* Select register data for MMD and write the value. */
+       PHY_WRITE(sc, MII_KSZ9031_MMD_ACCESS_CTRL,
+           MII_KSZ9031_MMD_DATA_NOINC | devaddr);
+       PHY_WRITE(sc, MII_KSZ9031_MMD_ACCESS_DATA, val);
+}
+
+static uint32_t
+ksz9021_read(struct mii_softc *sc, uint32_t reg)
+{
+
+       PHY_WRITE(sc, MII_KSZPHY_EXTREG, reg);
+
+       return (PHY_READ(sc, MII_KSZPHY_EXTREG_READ));
+}
+
 static void
-micphy_write(struct mii_softc *sc, uint32_t reg, uint32_t val)
+ksz9021_write(struct mii_softc *sc, uint32_t reg, uint32_t val)
 {
 
        PHY_WRITE(sc, MII_KSZPHY_EXTREG, KSZPHY_EXTREG_WRITE | reg);
        PHY_WRITE(sc, MII_KSZPHY_EXTREG_WRITE, val);
 }
 
-static int
-ksz9021_load_values(struct mii_softc *sc, phandle_t node, uint32_t reg,
-                       char *field1, char *field2,
-                       char *field3, char *field4)
+static void
+ksz90x1_load_values(struct mii_softc *sc, phandle_t node,
+    uint32_t dev, uint32_t reg, char *field1, uint32_t f1mask, int f1off,
+    char *field2, uint32_t f2mask, int f2off, char *field3, uint32_t f3mask,
+    int f3off, char *field4, uint32_t f4mask, int f4off)
 {
        pcell_t dts_value[1];
        int len;
        int val;
 
-       val = 0;
+       if (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9031)
+               val = ksz9031_read(sc, dev, reg);
+       else
+               val = ksz9021_read(sc, reg);
 
        if ((len = OF_getproplen(node, field1)) > 0) {
                OF_getencprop(node, field1, dts_value, len);
-               val = PS_TO_REG(dts_value[0]);
+               val &= ~(f1mask << f1off);
+               val |= (PS_TO_REG(dts_value[0]) & f1mask) << f1off;
        }
 
-       if ((len = OF_getproplen(node, field2)) > 0) {
+       if (field2 != NULL && (len = OF_getproplen(node, field2)) > 0) {
                OF_getencprop(node, field2, dts_value, len);
-               val |= PS_TO_REG(dts_value[0]) << 4;
+               val &= ~(f2mask << f2off);
+               val |= (PS_TO_REG(dts_value[0]) & f2mask) << f2off;
        }
 
-       if ((len = OF_getproplen(node, field3)) > 0) {
+       if (field3 != NULL && (len = OF_getproplen(node, field3)) > 0) {
                OF_getencprop(node, field3, dts_value, len);
-               val |= PS_TO_REG(dts_value[0]) << 8;
+               val &= ~(f3mask << f3off);
+               val |= (PS_TO_REG(dts_value[0]) & f3mask) << f3off;
        }
 
-       if ((len = OF_getproplen(node, field4)) > 0) {
+       if (field4 != NULL && (len = OF_getproplen(node, field4)) > 0) {
                OF_getencprop(node, field4, dts_value, len);
-               val |= PS_TO_REG(dts_value[0]) << 12;
+               val &= ~(f4mask << f4off);
+               val |= (PS_TO_REG(dts_value[0]) & f4mask) << f4off;
        }
 
-       micphy_write(sc, reg, val);
+       if (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9031)
+               ksz9031_write(sc, dev, reg, val);
+       else
+               ksz9021_write(sc, reg, val);
+}
 
-       return (0);
+static void
+ksz9031_load_values(struct mii_softc *sc, phandle_t node)
+{
+
+       ksz90x1_load_values(sc, node, 2, MII_KSZ9031_CONTROL_PAD_SKEW,
+           "txen-skew-ps", 0xf, 0, "rxdv-skew-ps", 0xf, 4,
+           NULL, 0, 0, NULL, 0, 0);
+       ksz90x1_load_values(sc, node, 2, MII_KSZ9031_RX_DATA_PAD_SKEW,
+           "rxd0-skew-ps", 0xf, 0, "rxd1-skew-ps", 0xf, 4,
+           "rxd2-skew-ps", 0xf, 8, "rxd3-skew-ps", 0xf, 12);
+       ksz90x1_load_values(sc, node, 2, MII_KSZ9031_TX_DATA_PAD_SKEW,
+           "txd0-skew-ps", 0xf, 0, "txd1-skew-ps", 0xf, 4,
+           "txd2-skew-ps", 0xf, 8, "txd3-skew-ps", 0xf, 12);
+       ksz90x1_load_values(sc, node, 2, MII_KSZ9031_CLOCK_PAD_SKEW,
+           "rxc-skew-ps", 0x1f, 0, "txc-skew-ps", 0x1f, 5,
+           NULL, 0, 0, NULL, 0, 0);
+}
+
+static void
+ksz9021_load_values(struct mii_softc *sc, phandle_t node)
+{
+
+       ksz90x1_load_values(sc, node, 0, MII_KSZPHY_CLK_CONTROL_PAD_SKEW,
+           "txen-skew-ps", 0xf, 0, "txc-skew-ps", 0xf, 4,
+           "rxdv-skew-ps", 0xf, 8, "rxc-skew-ps", 0xf, 12);
+       ksz90x1_load_values(sc, node, 0, MII_KSZPHY_RX_DATA_PAD_SKEW,
+           "rxd0-skew-ps", 0xf, 0, "rxd1-skew-ps", 0xf, 4,
+           "rxd2-skew-ps", 0xf, 8, "rxd3-skew-ps", 0xf, 12);
+       ksz90x1_load_values(sc, node, 0, MII_KSZPHY_TX_DATA_PAD_SKEW,
+           "txd0-skew-ps", 0xf, 0, "txd1-skew-ps", 0xf, 4,
+           "txd2-skew-ps", 0xf, 8, "txd3-skew-ps", 0xf, 12);
 }
 
 static int
@@ -174,17 +263,10 @@ micphy_attach(device_t dev)
        if ((node = ofw_bus_get_node(parent)) == -1)
                return (ENXIO);
 
-       ksz9021_load_values(sc, node, MII_KSZPHY_CLK_CONTROL_PAD_SKEW,
-                       "txen-skew-ps", "txc-skew-ps",
-                       "rxdv-skew-ps", "rxc-skew-ps");
-
-       ksz9021_load_values(sc, node, MII_KSZPHY_RX_DATA_PAD_SKEW,
-                       "rxd0-skew-ps", "rxd1-skew-ps",
-                       "rxd2-skew-ps", "rxd3-skew-ps");
-
-       ksz9021_load_values(sc, node, MII_KSZPHY_TX_DATA_PAD_SKEW,
-                       "txd0-skew-ps", "txd1-skew-ps",
-                       "txd2-skew-ps", "txd3-skew-ps");
+       if (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9031)
+               ksz9031_load_values(sc, node);
+       else
+               ksz9021_load_values(sc, node);
 
        return (0);
 }

Modified: stable/11/sys/dev/mii/miidevs
==============================================================================
--- stable/11/sys/dev/mii/miidevs       Fri Dec 30 19:43:23 2016        
(r310851)
+++ stable/11/sys/dev/mii/miidevs       Fri Dec 30 19:55:04 2016        
(r310852)
@@ -283,6 +283,7 @@ model MARVELL E1111         0x000c Marvell 88E1
 
 /* Micrel PHYs */
 model MICREL KSZ9021           0x0021 Micrel KSZ9021 10/100/1000 PHY
+model MICREL KSZ9031           0x0022 Micrel KSZ9031 10/100/1000 PHY
 
 /* Myson Technology PHYs */
 model xxMYSON MTD972           0x0000 MTD972 10/100 media interface
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to