net: phy: dp83867: increase SGMII autoneg timer duration
authorMax Uvarov <muvarov@gmail.com>
Tue, 28 May 2019 10:00:50 +0000 (13:00 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 1 Dec 2019 08:14:19 +0000 (09:14 +0100)
commit 1a97a477e666cbdededab93bd3754e508f0c09d7 upstream.

After reset SGMII Autoneg timer is set to 2us (bits 6 and 5 are 01).
That is not enough to finalize autonegatiation on some devices.
Increase this timer duration to maximum supported 16ms.

Signed-off-by: Max Uvarov <muvarov@gmail.com>
Cc: Heiner Kallweit <hkallweit1@gmail.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
[ adapted for kernels without phy_modify_mmd ]
Signed-off-by: Adrian Bunk <bunk@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/phy/dp83867.c

index 81106314e6da5fc877f08e1cf671bbc513ee2f3b..e03e91d5f1b1bda70e28f2c0cfdb9d40ef1c0ff4 100644 (file)
 
 /* Extended Registers */
 #define DP83867_CFG4            0x0031
+#define DP83867_CFG4_SGMII_ANEG_MASK (BIT(5) | BIT(6))
+#define DP83867_CFG4_SGMII_ANEG_TIMER_11MS   (3 << 5)
+#define DP83867_CFG4_SGMII_ANEG_TIMER_800US  (2 << 5)
+#define DP83867_CFG4_SGMII_ANEG_TIMER_2US    (1 << 5)
+#define DP83867_CFG4_SGMII_ANEG_TIMER_16MS   (0 << 5)
+
 #define DP83867_RGMIICTL       0x0032
 #define DP83867_STRAP_STS1     0x006E
 #define DP83867_RGMIIDCTL      0x0086
@@ -300,6 +306,18 @@ static int dp83867_config_init(struct phy_device *phydev)
 
                if (ret)
                        return ret;
+
+               /* After reset SGMII Autoneg timer is set to 2us (bits 6 and 5
+                * are 01). That is not enough to finalize autoneg on some
+                * devices. Increase this timer duration to maximum 16ms.
+                */
+               val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4);
+               val &= ~DP83867_CFG4_SGMII_ANEG_MASK;
+               val |= DP83867_CFG4_SGMII_ANEG_TIMER_16MS;
+               ret = phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4, val);
+
+               if (ret)
+                       return ret;
        }
 
        /* Enable Interrupt output INT_OE in CFG3 register */