From: Daniel Golle <daniel@makrotopia.org>
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 <daniel@makrotopia.org>
---
--- a/drivers/net/phy/realtek/realtek_main.c
+++ b/drivers/net/phy/realtek/realtek_main.c
@@ -1345,6 +1345,22 @@ static int rtl822xb_config_init(struct p
 	return rtl822x_set_serdes_option_mode(phydev, false);
 }
 
+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)
 {
@@ -2219,7 +2235,7 @@ static struct phy_driver realtek_drvs[]
 		.handle_interrupt = rtl8221b_handle_interrupt,
 		.soft_reset     = rtl822x_c45_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,
@@ -2247,7 +2263,7 @@ static struct phy_driver realtek_drvs[]
 		.handle_interrupt = rtl8221b_handle_interrupt,
 		.soft_reset     = rtl822x_c45_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,
