net: fman: fix 2.5G SGMII settings
authorshaohui xie <shaohui.xie@nxp.com>
Tue, 15 Nov 2016 06:36:47 +0000 (14:36 +0800)
committerJoe Hershberger <joe.hershberger@ni.com>
Thu, 8 Dec 2016 16:36:22 +0000 (10:36 -0600)
The settings for 2.5G SGMII are wrong, which the 2.5G case is missed in
set_if_mode(), and the serdes PCS configuration are wrong, this patch uses
the correct settings took from Linux.

Signed-off-by: Shaohui Xie <Shaohui.Xie@nxp.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
drivers/net/fm/eth.c
drivers/net/fm/memac.c
include/fsl_memac.h

index eb8e93618f27614aad40287f0ad794e2273c977b..bf5f89b61ac6c791336531c0a253ae13af868b25 100644 (file)
@@ -45,9 +45,12 @@ static void dtsec_configure_serdes(struct fm_eth *priv)
 
 qsgmii_loop:
        /* SGMII IF mode + AN enable only for 1G SGMII, not for 2.5G */
-       value = PHY_SGMII_IF_MODE_SGMII;
-       if (!sgmii_2500)
-               value |= PHY_SGMII_IF_MODE_AN;
+       if (sgmii_2500)
+               value = PHY_SGMII_CR_PHY_RESET |
+                       PHY_SGMII_IF_SPEED_GIGABIT |
+                       PHY_SGMII_IF_MODE_SGMII;
+       else
+               value = PHY_SGMII_IF_MODE_SGMII | PHY_SGMII_IF_MODE_AN;
 
        memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x14, value);
 
@@ -55,15 +58,24 @@ qsgmii_loop:
        value = PHY_SGMII_DEV_ABILITY_SGMII;
        memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x4, value);
 
-       /* Adjust link timer for SGMII  -
-       1.6 ms in units of 8 ns = 2 * 10^5 = 0x30d40 */
-       memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x13, 0x3);
-       memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x12, 0xd40);
+       if (sgmii_2500) {
+               /* Adjust link timer for 2.5G SGMII,
+                * 1.6 ms in units of 3.2 ns:
+                * 1.6ms / 3.2ns = 5 * 10^5 = 0x7a120.
+                */
+               memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x13, 0x0007);
+               memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x12, 0xa120);
+       } else {
+               /* Adjust link timer for SGMII,
+                * 1.6 ms in units of 8 ns:
+                * 1.6ms / 8ns = 2 * 10^5 = 0x30d40.
+                */
+               memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x13, 0x0003);
+               memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x12, 0x0d40);
+       }
 
        /* Restart AN */
-       value = PHY_SGMII_CR_DEF_VAL;
-       if (!sgmii_2500)
-               value |= PHY_SGMII_CR_RESET_AN;
+       value = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN;
        memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0, value);
 
        if ((priv->enet_if == PHY_INTERFACE_MODE_QSGMII) && (i < 3)) {
@@ -391,6 +403,7 @@ static int fm_eth_startup(struct fm_eth *fm_eth)
 
        /* For some reason we need to set SPEED_100 */
        if (((fm_eth->enet_if == PHY_INTERFACE_MODE_SGMII) ||
+            (fm_eth->enet_if == PHY_INTERFACE_MODE_SGMII_2500) ||
             (fm_eth->enet_if == PHY_INTERFACE_MODE_QSGMII)) &&
              mac->set_if_mode)
                mac->set_if_mode(mac, fm_eth->enet_if, SPEED_100);
index 81a64bf656a2a21e35f024e4295667c95ecfa5fa..1b5779ceceb01d1995495ba95a34b9e0abd8036e 100644 (file)
@@ -90,6 +90,7 @@ static void memac_set_interface_mode(struct fsl_enet_mac *mac,
                if_mode |= (IF_MODE_GMII | IF_MODE_RM);
                break;
        case PHY_INTERFACE_MODE_SGMII:
+       case PHY_INTERFACE_MODE_SGMII_2500:
        case PHY_INTERFACE_MODE_QSGMII:
                if_mode &= ~IF_MODE_MASK;
                if_mode |= (IF_MODE_GMII);
index bed2a40bb274efdd24740209f4fa2fdb1d1db803..431c2a0cccc0df262324cbd4c32413d111b98703 100644 (file)
@@ -226,6 +226,7 @@ struct memac {
 #define PHY_SGMII_CR_PHY_RESET      0x8000
 #define PHY_SGMII_CR_RESET_AN       0x0200
 #define PHY_SGMII_CR_DEF_VAL        0x1140
+#define PHY_SGMII_IF_SPEED_GIGABIT  0x0008
 #define PHY_SGMII_DEV_ABILITY_SGMII 0x4001
 #define PHY_SGMII_IF_MODE_AN        0x0002
 #define PHY_SGMII_IF_MODE_SGMII     0x0001