net:phy:motorcomm: Fix the problem that phytool cannot be used by YT8531
authorSamin Guo <samin.guo@starfivetech.com>
Fri, 4 Nov 2022 01:42:40 +0000 (09:42 +0800)
committerSamin Guo <samin.guo@starfivetech.com>
Wed, 9 Nov 2022 10:06:56 +0000 (18:06 +0800)
phy_read_status should not judge the auto negotiation speed, which
will cause 0x1e to be frequently modified.

JH7110B In different speed modes, the tx_inverted  needs to be
dynamically updated to match the timming.

known issue:
Function yt8521_read_status, it will be executed once per second.
Can read and write ext reg (0xa001/a002/a003). This may causes the ext value
read by the phytool always is 0.

$ phytool write eth0/0/0x1e 0xa001
$ phytool read eth0/0/0x1f
0000

To avoid this problem, you can read 0x1f as fast as possible after
writing 0x1e.
$ phytool write eth0/0/0x1e 0xa001; phytool read eth0/0/0x1f
0x8160

Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
drivers/net/phy/motorcomm.c

index 5a2c4ff..cecb07b 100644 (file)
@@ -817,11 +817,14 @@ static struct device_node *ytphy_get_of_node(struct phy_device *phydev)
        return of_node->child;
 }
 
-static int ytphy_inverted(struct phy_device *phydev)
+static void ytphy_link_change_notify(struct phy_device *phydev)
 {
        u32 val;
        struct ytphy_priv_t *ytphy_priv = phydev->priv;
 
+       if (phydev->speed < 0)
+               return;
+
        val = ytphy_read_ext(phydev, YTPHY_EXTREG_RGMII_CONFIG1);
        switch (phydev->speed) {
        case SPEED_1000:
@@ -842,11 +845,9 @@ static int ytphy_inverted(struct phy_device *phydev)
        default:
                break;
        }
-
-       return ytphy_write_ext(phydev, YTPHY_EXTREG_RGMII_CONFIG1, val);
+       ytphy_write_ext(phydev, YTPHY_EXTREG_RGMII_CONFIG1, val);
 }
 
-
 static int ytphy_of_config(struct phy_device *phydev)
 {
        const struct device_node *of_node;
@@ -988,8 +989,6 @@ static int yt8521_adjust_status(struct phy_device *phydev, int val, int is_utp)
        phydev->speed = speed;
        phydev->duplex = duplex;
 
-       ytphy_inverted(phydev);
-
        return 0;
 }
 
@@ -1183,17 +1182,6 @@ static int yt8531S_config_init(struct phy_device *phydev)
        return ret;
 }
 
-static int yt8531_read_status(struct phy_device *phydev)
-{
-       int ret;
-
-       ret = genphy_read_status(phydev);
-       if (ret)
-               return ret;
-
-       return ytphy_inverted(phydev);
-}
-
 static int ytphy_probe(struct phy_device *phydev)
 {
        struct device *dev = &phydev->mdio.dev;
@@ -2169,6 +2157,7 @@ static struct phy_driver ytphy_drvs[] = {
                .read_status    = yt8521_read_status,
                .suspend        = yt8521_suspend,
                .resume         = yt8521_resume,
+               .link_change_notify = ytphy_link_change_notify,
 #if (YTPHY_WOL_FEATURE_ENABLE)
                .get_wol        = &ytphy_wol_feature_get,
                .set_wol        = &ytphy_wol_feature_set,
@@ -2201,9 +2190,10 @@ static struct phy_driver ytphy_drvs[] = {
                .probe         = ytphy_probe,
                .config_aneg   = genphy_config_aneg,
                .config_init   = yt8531_config_init,
-               .read_status   = yt8531_read_status,
+               .read_status   = genphy_read_status,
                .suspend       = genphy_suspend,
                .resume        = genphy_resume,
+               .link_change_notify = ytphy_link_change_notify,
 #if (YTPHY_WOL_FEATURE_ENABLE)
                .get_wol       = &ytphy_wol_feature_get,
                .set_wol       = &ytphy_wol_feature_set,