From 84a102df7e9c8b8f5a430f343284dcfc9c516a25 Mon Sep 17 00:00:00 2001 From: Samin Guo Date: Fri, 4 Nov 2022 09:42:40 +0800 Subject: [PATCH] net:phy:motorcomm: Fix the problem that phytool cannot be used by YT8531 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 --- drivers/net/phy/motorcomm.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c index 5a2c4ff..cecb07b 100644 --- a/drivers/net/phy/motorcomm.c +++ b/drivers/net/phy/motorcomm.c @@ -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, -- 2.7.4