From: Daniel Golle Date: Thu, 30 Jan 2025 05:33:12 +0000 Subject: [PATCH] net: phy: realtek: work around broken SerDes For still unknown reasons the SerDes init sequence may sometimes time out because a self-clearing bit never clears, indicating the PHY has entered an unrecoverable error state. Work-around the issue by triggering a hardware reset and retry the setup sequence while warning the user that this has happened. This is really more of a work-around than a fix, and should be replaced by a better actual fix in future (hopefully). Signed-off-by: Daniel Golle --- --- a/drivers/net/phy/realtek/realtek_main.c +++ b/drivers/net/phy/realtek/realtek_main.c @@ -923,6 +923,22 @@ static int rtl822xb_config_init(struct p return 0; } +static int rtl822xb_config_init_war(struct phy_device *phydev) +{ + int ret; + + ret = rtl822xb_config_init(phydev); + + if (ret == -ETIMEDOUT) { + phydev_warn(phydev, "SerDes setup timed out, retrying\n"); + phy_device_reset(phydev, 1); + phy_device_reset(phydev, 0); + ret = rtl822xb_config_init(phydev); + } + + return ret; +} + static int rtl822xb_get_rate_matching(struct phy_device *phydev, phy_interface_t iface) { @@ -1605,7 +1621,7 @@ static struct phy_driver realtek_drvs[] .handle_interrupt = rtl8221b_handle_interrupt, .soft_reset = genphy_soft_reset, .probe = rtl822x_probe, - .config_init = rtl822xb_config_init, + .config_init = rtl822xb_config_init_war, .get_rate_matching = rtl822xb_get_rate_matching, .get_features = rtl822x_c45_get_features, .config_aneg = rtl822x_c45_config_aneg, @@ -1635,7 +1651,7 @@ static struct phy_driver realtek_drvs[] .handle_interrupt = rtl8221b_handle_interrupt, .soft_reset = genphy_soft_reset, .probe = rtl822x_probe, - .config_init = rtl822xb_config_init, + .config_init = rtl822xb_config_init_war, .get_rate_matching = rtl822xb_get_rate_matching, .get_features = rtl822x_c45_get_features, .config_aneg = rtl822x_c45_config_aneg,