From: Daniel Golle Date: Sat, 3 Jan 2026 18:43:33 +0000 (+0000) Subject: kernel: net: phy: realtek: replace hack with proper fix X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=5652b98952c4da76060bbe051b521da3dba7164f;p=openwrt%2Fstaging%2Fxback.git kernel: net: phy: realtek: replace hack with proper fix RealTek's 2.5G PHYs suffer from an up to now inexplicable problem which results in the SerDes mode not being properly setup and disabling in-band AN leading to a timeout waiting for a busy-bit to clear. Up to now there has been a crude work-around: resetting the PHY and trying another time. The cause has now been found as a wrong access to register PHYCR1 on MDIO_MMD_VEND1 instead of MDIO_MMD_VEND2 when setting up ALDPS as well as disabling the MDIO broadcast address 0. In order to access MDIO_MMD_VEND2 on Clause-22-only busses a custom .read_mmd and .write_mmd ops are implemented, mapping MDIO_MMD_VEND2 to paged access as this is required. Also, as ALDPS by design disables the SerDes PCS of the PHY in case the link has been down for a while, move enabling ALDPS to the end of the config_init function to not face problems when configuring the interface mode and in-band AN. Signed-off-by: Daniel Golle --- diff --git a/target/linux/generic/pending-6.12/715-net-phy-export-mmd_phy_-functions.patch b/target/linux/generic/pending-6.12/715-net-phy-export-mmd_phy_-functions.patch new file mode 100644 index 0000000000..864dde0cef --- /dev/null +++ b/target/linux/generic/pending-6.12/715-net-phy-export-mmd_phy_-functions.patch @@ -0,0 +1,61 @@ +From: Daniel Golle +Date: Mon, 5 Jan 2026 14:51:47 +0000 +Subject: [PATCH] net: phy: export mmd_phy_read and mmd_phy_write to phylib.h + +Helper functions mmd_phy_read and mmd_phy_write are useful for PHYs +which require custom MMD access functions for some but not all MMDs. + +This patch replaces pending upstream patch +"net: phy: move mmd_phy_read and mmd_phy_write to phylib.h" +for Linux 6.12. + +See also +https://patchwork.kernel.org/project/netdevbpf/patch/79169cd624a3572d426e42c7b13cd2654a35d0cb.1767630451.git.daniel@makrotopia.org/ +--- a/drivers/net/phy/phy-core.c ++++ b/drivers/net/phy/phy-core.c +@@ -542,8 +542,8 @@ static void mmd_phy_indirect(struct mii_ + devad | MII_MMD_CTRL_NOINCR); + } + +-static int mmd_phy_read(struct mii_bus *bus, int phy_addr, bool is_c45, +- int devad, u32 regnum) ++int mmd_phy_read(struct mii_bus *bus, int phy_addr, bool is_c45, ++ int devad, u32 regnum) + { + if (is_c45) + return __mdiobus_c45_read(bus, phy_addr, devad, regnum); +@@ -552,9 +552,10 @@ static int mmd_phy_read(struct mii_bus * + /* Read the content of the MMD's selected register */ + return __mdiobus_read(bus, phy_addr, MII_MMD_DATA); + } ++EXPORT_SYMBOL_GPL(mmd_phy_read); + +-static int mmd_phy_write(struct mii_bus *bus, int phy_addr, bool is_c45, +- int devad, u32 regnum, u16 val) ++int mmd_phy_write(struct mii_bus *bus, int phy_addr, bool is_c45, ++ int devad, u32 regnum, u16 val) + { + if (is_c45) + return __mdiobus_c45_write(bus, phy_addr, devad, regnum, val); +@@ -563,6 +564,7 @@ static int mmd_phy_write(struct mii_bus + /* Write the data into MMD's selected register */ + return __mdiobus_write(bus, phy_addr, MII_MMD_DATA, val); + } ++EXPORT_SYMBOL_GPL(mmd_phy_write); + + /** + * __phy_read_mmd - Convenience function for reading a register +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -2054,6 +2054,11 @@ extern struct phy_driver genphy_c45_driv + /* The gen10g_* functions are the old Clause 45 stub */ + int gen10g_config_aneg(struct phy_device *phydev); + ++int mmd_phy_read(struct mii_bus *bus, int phy_addr, bool is_c45, ++ int devad, u32 regnum); ++int mmd_phy_write(struct mii_bus *bus, int phy_addr, bool is_c45, ++ int devad, u32 regnum, u16 val); ++ + static inline int phy_read_status(struct phy_device *phydev) + { + if (!phydev->drv) diff --git a/target/linux/generic/pending-6.12/720-00-net-phy-realtek-use-paged-access-for-MDIO_MMD_VEND2-.patch b/target/linux/generic/pending-6.12/720-00-net-phy-realtek-use-paged-access-for-MDIO_MMD_VEND2-.patch new file mode 100644 index 0000000000..165ec4c229 --- /dev/null +++ b/target/linux/generic/pending-6.12/720-00-net-phy-realtek-use-paged-access-for-MDIO_MMD_VEND2-.patch @@ -0,0 +1,166 @@ +From a81850660c9fc259d090e9207f81e8e76d9494ce Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Sun, 4 Jan 2026 10:13:29 +0000 +Subject: [PATCH] net: phy: realtek: use paged access for MDIO_MMD_VEND2 in C22 + mode + +RTL822x cannot access MDIO_MMD_VEND2 via MII_MMD_CTRL/MII_MMD_DATA. +A mapping to use paged access needs to be used instead. +All other MMD devices can be accessed as usual. +Implement phy_read_mmd and phy_write_mmd using paged access for +MDIO_MMD_VEND2 in Clause-22 mode instead of relying on +MII_MMD_CTRL/MII_MMD_DATA. +This allows eg. rtl822x_config_aneg to work as expected in case the +MDIO bus doesn't support Clause-45 access. + +Suggested-by: Bevan Weiss +Signed-off-by: Daniel Golle +--- a/drivers/net/phy/realtek/realtek_main.c ++++ b/drivers/net/phy/realtek/realtek_main.c +@@ -131,9 +131,8 @@ + #define RTL822X_VND1_SERDES_CTRL3_MODE_SGMII 0x02 + #define RTL822X_VND1_SERDES_CTRL3_MODE_2500BASEX 0x16 + +-/* RTL822X_VND2_XXXXX registers are only accessible when phydev->is_c45 +- * is set, they cannot be accessed by C45-over-C22. +- */ ++#define RTL822X_VND2_TO_PAGE(reg) ((reg) >> 4) ++#define RTL822X_VND2_TO_PAGE_REG(reg) (16 + (((reg) & GENMASK(3, 0)) >> 1)) + #define RTL822X_VND2_C22_REG(reg) (0xa400 + 2 * (reg)) + + #define RTL8221B_VND2_INER 0xa4d2 +@@ -1238,6 +1237,80 @@ static int rtl822x_probe(struct phy_devi + return 0; + } + ++/* RTL822x cannot access MDIO_MMD_VEND2 via MII_MMD_CTRL/MII_MMD_DATA. ++ * A mapping to use paged access needs to be used instead. ++ * All other MMD devices can be accessed as usual. ++ */ ++static int rtl822xb_read_mmd(struct phy_device *phydev, int devnum, u16 reg) ++{ ++ int oldpage, ret, read_ret; ++ u16 page; ++ ++ /* Use default method for all MMDs except MDIO_MMD_VEND2 or in case ++ * Clause-45 access is available ++ */ ++ if (devnum != MDIO_MMD_VEND2 || phydev->is_c45) ++ return mmd_phy_read(phydev->mdio.bus, phydev->mdio.addr, ++ phydev->is_c45, devnum, reg); ++ ++ /* Use paged access for MDIO_MMD_VEND2 over Clause-22 */ ++ page = RTL822X_VND2_TO_PAGE(reg); ++ oldpage = __phy_read(phydev, RTL821x_PAGE_SELECT); ++ if (oldpage < 0) ++ return oldpage; ++ ++ if (oldpage != page) { ++ ret = __phy_write(phydev, RTL821x_PAGE_SELECT, page); ++ if (ret < 0) ++ return ret; ++ } ++ ++ read_ret = __phy_read(phydev, RTL822X_VND2_TO_PAGE_REG(reg)); ++ if (oldpage != page) { ++ ret = __phy_write(phydev, RTL821x_PAGE_SELECT, oldpage); ++ if (ret < 0) ++ return ret; ++ } ++ ++ return read_ret; ++} ++ ++static int rtl822xb_write_mmd(struct phy_device *phydev, int devnum, u16 reg, ++ u16 val) ++{ ++ int oldpage, ret, write_ret; ++ u16 page; ++ ++ /* Use default method for all MMDs except MDIO_MMD_VEND2 or in case ++ * Clause-45 access is available ++ */ ++ if (devnum != MDIO_MMD_VEND2 || phydev->is_c45) ++ return mmd_phy_write(phydev->mdio.bus, phydev->mdio.addr, ++ phydev->is_c45, devnum, reg, val); ++ ++ /* Use paged access for MDIO_MMD_VEND2 over Clause-22 */ ++ page = RTL822X_VND2_TO_PAGE(reg); ++ oldpage = __phy_read(phydev, RTL821x_PAGE_SELECT); ++ if (oldpage < 0) ++ return oldpage; ++ ++ if (oldpage != page) { ++ ret = __phy_write(phydev, RTL821x_PAGE_SELECT, page); ++ if (ret < 0) ++ return ret; ++ } ++ ++ write_ret = __phy_write(phydev, RTL822X_VND2_TO_PAGE_REG(reg), val); ++ if (oldpage != page) { ++ ret = __phy_write(phydev, RTL821x_PAGE_SELECT, oldpage); ++ if (ret < 0) ++ return ret; ++ } ++ ++ return write_ret; ++} ++ ++ + static int rtl822x_set_serdes_option_mode(struct phy_device *phydev, bool gen1) + { + bool has_2500, has_sgmii; +@@ -2097,6 +2170,8 @@ static struct phy_driver realtek_drvs[] + .resume = rtlgen_resume, + .read_page = rtl821x_read_page, + .write_page = rtl821x_write_page, ++ .read_mmd = rtl822xb_read_mmd, ++ .write_mmd = rtl822xb_write_mmd, + }, { + .match_phy_device = rtl8221b_match_phy_device, + .name = "RTL8226B_RTL8221B 2.5Gbps PHY", +@@ -2109,6 +2184,8 @@ static struct phy_driver realtek_drvs[] + .resume = rtlgen_resume, + .read_page = rtl821x_read_page, + .write_page = rtl821x_write_page, ++ .read_mmd = rtl822xb_read_mmd, ++ .write_mmd = rtl822xb_write_mmd, + }, { + PHY_ID_MATCH_EXACT(0x001cc838), + .name = "RTL8226-CG 2.5Gbps PHY", +@@ -2119,6 +2196,8 @@ static struct phy_driver realtek_drvs[] + .read_status = rtl822xb_c45_read_status, + .suspend = genphy_c45_pma_suspend, + .resume = rtlgen_c45_resume, ++ .read_mmd = rtl822xb_read_mmd, ++ .write_mmd = rtl822xb_write_mmd, + }, { + PHY_ID_MATCH_EXACT(0x001cc848), + .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY", +@@ -2131,6 +2210,8 @@ static struct phy_driver realtek_drvs[] + .resume = rtlgen_resume, + .read_page = rtl821x_read_page, + .write_page = rtl821x_write_page, ++ .read_mmd = rtl822xb_read_mmd, ++ .write_mmd = rtl822xb_write_mmd, + }, { + .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device, + .name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)", +@@ -2144,6 +2225,8 @@ static struct phy_driver realtek_drvs[] + .resume = rtlgen_resume, + .read_page = rtl821x_read_page, + .write_page = rtl821x_write_page, ++ .read_mmd = rtl822xb_read_mmd, ++ .write_mmd = rtl822xb_write_mmd, + }, { + .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device, + .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)", +@@ -2170,6 +2253,8 @@ static struct phy_driver realtek_drvs[] + .resume = rtlgen_resume, + .read_page = rtl821x_read_page, + .write_page = rtl821x_write_page, ++ .read_mmd = rtl822xb_read_mmd, ++ .write_mmd = rtl822xb_write_mmd, + }, { + .match_phy_device = rtl8221b_vm_cg_c45_match_phy_device, + .name = "RTL8221B-VM-CG 2.5Gbps PHY (C45)", diff --git a/target/linux/generic/pending-6.12/720-01-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch b/target/linux/generic/pending-6.12/720-01-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch index ce4fd03115..8ee2628e0d 100644 --- a/target/linux/generic/pending-6.12/720-01-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch +++ b/target/linux/generic/pending-6.12/720-01-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch @@ -15,7 +15,7 @@ Signed-off-by: Daniel Golle --- a/drivers/net/phy/realtek/realtek_main.c +++ b/drivers/net/phy/realtek/realtek_main.c -@@ -2090,6 +2090,7 @@ static struct phy_driver realtek_drvs[] +@@ -2163,6 +2163,7 @@ static struct phy_driver realtek_drvs[] }, { .name = "RTL8226 2.5Gbps PHY", .match_phy_device = rtl8226_match_phy_device, @@ -23,7 +23,7 @@ Signed-off-by: Daniel Golle .get_features = rtl822x_get_features, .config_aneg = rtl822x_config_aneg, .read_status = rtl822x_read_status, -@@ -2100,6 +2101,7 @@ static struct phy_driver realtek_drvs[] +@@ -2175,6 +2176,7 @@ static struct phy_driver realtek_drvs[] }, { .match_phy_device = rtl8221b_match_phy_device, .name = "RTL8226B_RTL8221B 2.5Gbps PHY", @@ -31,7 +31,7 @@ Signed-off-by: Daniel Golle .get_features = rtl822x_get_features, .config_aneg = rtl822x_config_aneg, .config_init = rtl822xb_config_init, -@@ -2122,6 +2124,7 @@ static struct phy_driver realtek_drvs[] +@@ -2201,6 +2203,7 @@ static struct phy_driver realtek_drvs[] }, { PHY_ID_MATCH_EXACT(0x001cc848), .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY", @@ -39,7 +39,7 @@ Signed-off-by: Daniel Golle .get_features = rtl822x_get_features, .config_aneg = rtl822x_config_aneg, .config_init = rtl822xb_config_init, -@@ -2134,6 +2137,7 @@ static struct phy_driver realtek_drvs[] +@@ -2215,6 +2218,7 @@ static struct phy_driver realtek_drvs[] }, { .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device, .name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)", @@ -47,7 +47,7 @@ Signed-off-by: Daniel Golle .probe = rtl822x_probe, .get_features = rtl822x_get_features, .config_aneg = rtl822x_config_aneg, -@@ -2149,6 +2153,7 @@ static struct phy_driver realtek_drvs[] +@@ -2232,6 +2236,7 @@ static struct phy_driver realtek_drvs[] .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)", .config_intr = rtl8221b_config_intr, .handle_interrupt = rtl8221b_handle_interrupt, @@ -55,7 +55,7 @@ Signed-off-by: Daniel Golle .probe = rtl822x_probe, .config_init = rtl822xb_config_init, .get_rate_matching = rtl822xb_get_rate_matching, -@@ -2160,6 +2165,7 @@ static struct phy_driver realtek_drvs[] +@@ -2243,6 +2248,7 @@ static struct phy_driver realtek_drvs[] }, { .match_phy_device = rtl8221b_vm_cg_c22_match_phy_device, .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)", @@ -63,7 +63,7 @@ Signed-off-by: Daniel Golle .probe = rtl822x_probe, .get_features = rtl822x_get_features, .config_aneg = rtl822x_config_aneg, -@@ -2175,6 +2181,7 @@ static struct phy_driver realtek_drvs[] +@@ -2260,6 +2266,7 @@ static struct phy_driver realtek_drvs[] .name = "RTL8221B-VM-CG 2.5Gbps PHY (C45)", .config_intr = rtl8221b_config_intr, .handle_interrupt = rtl8221b_handle_interrupt, diff --git a/target/linux/generic/pending-6.12/720-02-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch b/target/linux/generic/pending-6.12/720-02-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch index 85b2dbd8c6..4ee4e763d4 100644 --- a/target/linux/generic/pending-6.12/720-02-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch +++ b/target/linux/generic/pending-6.12/720-02-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch @@ -20,7 +20,7 @@ Signed-off-by: Daniel Golle --- a/drivers/net/phy/realtek/realtek_main.c +++ b/drivers/net/phy/realtek/realtek_main.c -@@ -1241,8 +1241,8 @@ static int rtl822x_probe(struct phy_devi +@@ -1345,8 +1345,8 @@ static int rtl822xb_write_mmd(struct phy static int rtl822x_set_serdes_option_mode(struct phy_device *phydev, bool gen1) { bool has_2500, has_sgmii; @@ -30,7 +30,7 @@ Signed-off-by: Daniel Golle has_2500 = test_bit(PHY_INTERFACE_MODE_2500BASEX, phydev->host_interfaces) || -@@ -1284,18 +1284,42 @@ static int rtl822x_set_serdes_option_mod +@@ -1388,18 +1388,42 @@ static int rtl822x_set_serdes_option_mod RTL822X_VND1_SERDES_OPTION, RTL822X_VND1_SERDES_OPTION_MODE_MASK, mode); diff --git a/target/linux/generic/pending-6.12/720-03-net-phy-realtek-make-sure-paged-read-is-protected-by.patch b/target/linux/generic/pending-6.12/720-03-net-phy-realtek-make-sure-paged-read-is-protected-by.patch index d603be802e..710adf7e7a 100644 --- a/target/linux/generic/pending-6.12/720-03-net-phy-realtek-make-sure-paged-read-is-protected-by.patch +++ b/target/linux/generic/pending-6.12/720-03-net-phy-realtek-make-sure-paged-read-is-protected-by.patch @@ -18,7 +18,7 @@ Signed-off-by: Daniel Golle --- a/drivers/net/phy/realtek/realtek_main.c +++ b/drivers/net/phy/realtek/realtek_main.c -@@ -1711,9 +1711,11 @@ static bool rtlgen_supports_2_5gbps(stru +@@ -1815,9 +1815,11 @@ static bool rtlgen_supports_2_5gbps(stru { int val; diff --git a/target/linux/generic/pending-6.12/720-04-net-phy-realtek-setup-aldps.patch b/target/linux/generic/pending-6.12/720-04-net-phy-realtek-setup-aldps.patch index e65dc43cba..d4a625a76a 100644 --- a/target/linux/generic/pending-6.12/720-04-net-phy-realtek-setup-aldps.patch +++ b/target/linux/generic/pending-6.12/720-04-net-phy-realtek-setup-aldps.patch @@ -24,19 +24,68 @@ Signed-off-by: Daniel Golle #define RTL8366RB_POWER_SAVE 0x15 #define RTL8366RB_POWER_SAVE_ON BIT(12) -@@ -1301,6 +1305,15 @@ static int rtl822x_set_serdes_option_mod - return ret; - } - -+ if (of_property_read_bool(phydev->mdio.dev.of_node, "realtek,aldps-enable")) -+ ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, RTL8221B_PHYCR1, -+ RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN); -+ else -+ ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, RTL8221B_PHYCR1, -+ RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN); +@@ -208,6 +212,10 @@ struct rtl821x_priv { + u16 iner; + }; + ++struct rtl822x_priv { ++ bool enable_aldps; ++}; ++ + static int rtl821x_read_page(struct phy_device *phydev) + { + return __phy_read(phydev, RTL821x_PAGE_SELECT); +@@ -1231,6 +1239,18 @@ static int rtl822x_write_mmd(struct phy_ + + static int rtl822x_probe(struct phy_device *phydev) + { ++ struct device *dev = &phydev->mdio.dev; ++ struct rtl822x_priv *priv; ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ priv->enable_aldps = of_property_read_bool(dev->of_node, ++ "realtek,aldps-enable"); ++ ++ phydev->priv = priv; ++ + if (IS_ENABLED(CONFIG_REALTEK_PHY_HWMON) && + phydev->phy_id != RTL_GENERIC_PHYID) + return rtl822x_hwmon_init(phydev); +@@ -1342,6 +1362,19 @@ static int rtl822xb_write_mmd(struct phy + return write_ret; + } + ++static int rtl822x_init_phycr1(struct phy_device *phydev, bool no_aldps) ++{ ++ struct rtl822x_priv *priv = phydev->priv; ++ u16 val = 0; ++ ++ if (priv->enable_aldps && !no_aldps) ++ val = RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN; ++ ++ return phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2, RTL8221B_PHYCR1, ++ RTL8221B_PHYCR1_ALDPS_EN | ++ RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN, val); ++} ++ + static int rtl822x_set_serdes_option_mode(struct phy_device *phydev, bool gen1) + { + bool has_2500, has_sgmii; +@@ -1423,6 +1456,14 @@ static int rtl822x_set_serdes_option_mod + if (ret < 0) + return ret; + ++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020); + if (ret < 0) + return ret; + - /* Disable SGMII AN */ - ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7588, 0x2); - if (ret < 0) ++ ret = rtl822x_init_phycr1(phydev, false); ++ if (ret < 0) ++ return ret; ++ + return 0; + } + diff --git a/target/linux/generic/pending-6.12/720-05-net-phy-realtek-detect-early-version-of-RTL8221B.patch b/target/linux/generic/pending-6.12/720-05-net-phy-realtek-detect-early-version-of-RTL8221B.patch index 80023a0a51..7afa159588 100644 --- a/target/linux/generic/pending-6.12/720-05-net-phy-realtek-detect-early-version-of-RTL8221B.patch +++ b/target/linux/generic/pending-6.12/720-05-net-phy-realtek-detect-early-version-of-RTL8221B.patch @@ -14,7 +14,7 @@ Signed-off-by: Daniel Golle Signed-off-by: Mieczyslaw Nalewaj --- a/drivers/net/phy/realtek/realtek_main.c +++ b/drivers/net/phy/realtek/realtek_main.c -@@ -1768,10 +1768,32 @@ static int rtl8226_match_phy_device(stru +@@ -1900,10 +1900,32 @@ static int rtl8226_match_phy_device(stru static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id, bool is_c45) { diff --git a/target/linux/generic/pending-6.12/720-07-net-phy-realtek-mark-existing-MMDs-as-present.patch b/target/linux/generic/pending-6.12/720-07-net-phy-realtek-mark-existing-MMDs-as-present.patch index b06ddb09e2..50fa7c9efc 100644 --- a/target/linux/generic/pending-6.12/720-07-net-phy-realtek-mark-existing-MMDs-as-present.patch +++ b/target/linux/generic/pending-6.12/720-07-net-phy-realtek-mark-existing-MMDs-as-present.patch @@ -15,7 +15,7 @@ Signed-off-by: Daniel Golle --- a/drivers/net/phy/realtek/realtek_main.c +++ b/drivers/net/phy/realtek/realtek_main.c -@@ -1465,6 +1465,9 @@ static int rtl822x_c45_get_features(stru +@@ -1597,6 +1597,9 @@ static int rtl822x_c45_get_features(stru linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT, phydev->supported); diff --git a/target/linux/generic/pending-6.12/720-08-net-phy-realtek-work-around-broken-serdes.patch b/target/linux/generic/pending-6.12/720-08-net-phy-realtek-work-around-broken-serdes.patch deleted file mode 100644 index 5bde9d157d..0000000000 --- a/target/linux/generic/pending-6.12/720-08-net-phy-realtek-work-around-broken-serdes.patch +++ /dev/null @@ -1,58 +0,0 @@ -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 -@@ -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, diff --git a/target/linux/generic/pending-6.12/720-09-net-phy-realtek-disable-MDIO-broadcast.patch b/target/linux/generic/pending-6.12/720-09-net-phy-realtek-disable-MDIO-broadcast.patch index 4462e4b274..a23c88ebe5 100644 --- a/target/linux/generic/pending-6.12/720-09-net-phy-realtek-disable-MDIO-broadcast.patch +++ b/target/linux/generic/pending-6.12/720-09-net-phy-realtek-disable-MDIO-broadcast.patch @@ -13,15 +13,21 @@ Signed-off-by: Daniel Golle --- --- a/drivers/net/phy/realtek/realtek_main.c +++ b/drivers/net/phy/realtek/realtek_main.c -@@ -1256,6 +1256,11 @@ static int rtl822x_set_serdes_option_mod - phydev->host_interfaces) || - phydev->interface == PHY_INTERFACE_MODE_SGMII; +@@ -165,6 +165,7 @@ + #define RTL8221B_PHYCR1 0xa430 + #define RTL8221B_PHYCR1_ALDPS_EN BIT(2) + #define RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN BIT(12) ++#define RTL8221B_PHYCR1_PHYAD_0_EN BIT(13) -+ /* disable listening on MDIO broadcast address (0) */ -+ ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, 0xa430, BIT(13)); -+ if (ret < 0) -+ return ret; -+ - /* fill in possible interfaces */ - __assign_bit(PHY_INTERFACE_MODE_2500BASEX, phydev->possible_interfaces, - has_2500); + #define RTL8366RB_POWER_SAVE 0x15 + #define RTL8366RB_POWER_SAVE_ON BIT(12) +@@ -1372,7 +1373,8 @@ static int rtl822x_init_phycr1(struct ph + + return phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2, RTL8221B_PHYCR1, + RTL8221B_PHYCR1_ALDPS_EN | +- RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN, val); ++ RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN | ++ RTL8221B_PHYCR1_PHYAD_0_EN, val); + } + + static int rtl822x_set_serdes_option_mode(struct phy_device *phydev, bool gen1)