[openwrt/openwrt] realtek: phy: late phy package patching

LEDE Commits lede-commits at lists.infradead.org
Fri Aug 29 15:20:44 PDT 2025


hauke pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/a1043fda8b77e096d225e43a3c6671d385d46176

commit a1043fda8b77e096d225e43a3c6671d385d46176
Author: Markus Stockhausen <markus.stockhausen at gmx.de>
AuthorDate: Tue Aug 19 05:06:37 2025 -0400

    realtek: phy: late phy package patching
    
    Currently phy packages (like RTL8214x/RTL8218x) are patched and
    initialized as soon as the first phy of the package is found.
    In this situation the shared structure is not finalized because
    devm_phy_package_join() has only been called for the first phy.
    This is no issue as the patching directly hammers the bus addresses
    for the follow-up phys.
    
    In the future we want to simplify the package handling and allow
    to access all phy_device structures from only one phy_device of
    the package. With this we can use normal phy_read/phy_write.
    
    Switch the probing logic to "late patching". With this we will
    initialize the firmware of the package when the last phy of the
    package has been found and thus the shared structure is complete.
    
    Provide get_base_phy() as the first package helper that allows
    to determine the first phy of the package from any other phy.
    
    While we are here drop the shared structure that only repeats the
    phy name and has no other use.
    
    Signed-off-by: Markus Stockhausen <markus.stockhausen at gmx.de>
    Link: https://github.com/openwrt/openwrt/pull/19810
    Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
---
 .../files-6.12/drivers/net/phy/rtl83xx-phy.c       | 89 ++++++----------------
 .../files-6.12/drivers/net/phy/rtl83xx-phy.h       |  4 -
 2 files changed, 25 insertions(+), 68 deletions(-)

diff --git a/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c b/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c
index 1cf18b5ca3..01f24080b8 100644
--- a/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c
+++ b/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c
@@ -106,6 +106,11 @@ static const struct firmware rtl838x_8380_fw;
 static const struct firmware rtl838x_8214fc_fw;
 static const struct firmware rtl838x_8218b_fw;
 
+static inline struct phy_device *get_base_phy(struct phy_device *phydev)
+{
+	return mdiobus_get_phy(phydev->mdio.bus, phydev->shared->base_addr);
+}
+
 static u64 disable_polling(int port)
 {
 	u64 saved_state;
@@ -3576,20 +3581,13 @@ static const struct sfp_upstream_ops rtl8214fc_sfp_ops = {
 
 static int rtl8214fc_phy_probe(struct phy_device *phydev)
 {
-	struct device *dev = &phydev->mdio.dev;
-	int addr = phydev->mdio.addr;
+	int base_addr = phydev->mdio.addr & ~3;
 	int ret = 0;
 
-	/* All base addresses of the PHYs start at multiples of 8 */
-	devm_phy_package_join(dev, phydev, addr & (~7),
-				sizeof(struct rtl83xx_shared_private));
-
-	if (!(addr % 8)) {
-		struct rtl83xx_shared_private *shared = phydev->shared->priv;
-		shared->name = "RTL8214FC";
-		/* Configuration must be done while patching still possible */
+	devm_phy_package_join(&phydev->mdio.dev, phydev, base_addr, 0);
+	if (phydev->mdio.addr == base_addr + 3) {
 		if (soc_info.family == RTL8380_FAMILY_ID)
-			ret = rtl8380_configure_rtl8214fc(phydev);
+			ret = rtl8380_configure_rtl8214fc(get_base_phy(phydev));
 		if (ret)
 			return ret;
 	}
@@ -3599,39 +3597,23 @@ static int rtl8214fc_phy_probe(struct phy_device *phydev)
 
 static int rtl8214c_phy_probe(struct phy_device *phydev)
 {
-	struct device *dev = &phydev->mdio.dev;
-	int addr = phydev->mdio.addr;
-
-	/* All base addresses of the PHYs start at multiples of 8 */
-	devm_phy_package_join(dev, phydev, addr & (~7),
-				sizeof(struct rtl83xx_shared_private));
+	int base_addr = phydev->mdio.addr & ~3;
 
-	if (!(addr % 8)) {
-		struct rtl83xx_shared_private *shared = phydev->shared->priv;
-		shared->name = "RTL8214C";
-		/* Configuration must be done whil patching still possible */
-		return rtl8380_configure_rtl8214c(phydev);
-	}
+	devm_phy_package_join(&phydev->mdio.dev, phydev, base_addr, 0);
+	if (phydev->mdio.addr == base_addr + 3)
+		return rtl8380_configure_rtl8214c(get_base_phy(phydev));
 
 	return 0;
 }
 
 static int rtl8218b_ext_phy_probe(struct phy_device *phydev)
 {
-	struct device *dev = &phydev->mdio.dev;
-	int addr = phydev->mdio.addr;
+	int base_addr = phydev->mdio.addr & ~7;
 
-	/* All base addresses of the PHYs start at multiples of 8 */
-	devm_phy_package_join(dev, phydev, addr & (~7),
-				sizeof(struct rtl83xx_shared_private));
-
-	if (!(addr % 8)) {
-		struct rtl83xx_shared_private *shared = phydev->shared->priv;
-		shared->name = "RTL8218B (external)";
-		if (soc_info.family == RTL8380_FAMILY_ID) {
-			/* Configuration must be done while patching still possible */
-			return rtl8380_configure_ext_rtl8218b(phydev);
-		}
+	devm_phy_package_join(&phydev->mdio.dev, phydev, base_addr, 0);
+	if (phydev->mdio.addr == base_addr + 7) {
+		if (soc_info.family == RTL8380_FAMILY_ID)
+			return rtl8380_configure_ext_rtl8218b(get_base_phy(phydev));
 	}
 
 	return 0;
@@ -3639,46 +3621,25 @@ static int rtl8218b_ext_phy_probe(struct phy_device *phydev)
 
 static int rtl8218b_int_phy_probe(struct phy_device *phydev)
 {
-	struct device *dev = &phydev->mdio.dev;
-	int addr = phydev->mdio.addr;
+	int base_addr = phydev->mdio.addr & ~7;
 
 	if (soc_info.family != RTL8380_FAMILY_ID)
 		return -ENODEV;
-	if (addr >= 24)
+	if (base_addr >= 24)
 		return -ENODEV;
 
-	pr_debug("%s: id: %d\n", __func__, addr);
-	/* All base addresses of the PHYs start at multiples of 8 */
-	devm_phy_package_join(dev, phydev, addr & (~7),
-			      sizeof(struct rtl83xx_shared_private));
-
-	if (!(addr % 8)) {
-		struct rtl83xx_shared_private *shared = phydev->shared->priv;
-		shared->name = "RTL8218B (internal)";
-		/* Configuration must be done while patching still possible */
-		return rtl8380_configure_int_rtl8218b(phydev);
-	}
+	devm_phy_package_join(&phydev->mdio.dev, phydev, base_addr, 0);
+	if (phydev->mdio.addr == base_addr + 7)
+		return rtl8380_configure_int_rtl8218b(get_base_phy(phydev));
 
 	return 0;
 }
 
 static int rtl8218d_phy_probe(struct phy_device *phydev)
 {
-	struct device *dev = &phydev->mdio.dev;
-	int addr = phydev->mdio.addr;
+	int base_addr = phydev->mdio.addr & ~7;
 
-	pr_debug("%s: id: %d\n", __func__, addr);
-	/* All base addresses of the PHYs start at multiples of 8 */
-	devm_phy_package_join(dev, phydev, addr & (~7),
-			      sizeof(struct rtl83xx_shared_private));
-
-	/* All base addresses of the PHYs start at multiples of 8 */
-	if (!(addr % 8)) {
-		struct rtl83xx_shared_private *shared = phydev->shared->priv;
-		shared->name = "RTL8218D";
-		/* Configuration must be done while patching still possible */
-/* TODO:		return configure_rtl8218d(phydev); */
-	}
+	devm_phy_package_join(&phydev->mdio.dev, phydev, base_addr, 0);
 
 	return 0;
 }
diff --git a/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.h b/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.h
index 652e27a5c5..2f55fb0d90 100644
--- a/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.h
+++ b/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.h
@@ -1,9 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
 
-struct rtl83xx_shared_private {
-	char *name;
-};
-
 struct __attribute__ ((__packed__)) part {
 	uint16_t start;
 	uint8_t wordsize;




More information about the lede-commits mailing list