[openwrt/openwrt] realtek: phy: reorganize package handling

LEDE Commits lede-commits at lists.infradead.org
Tue Dec 23 08:50:26 PST 2025


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

commit 53dfb3e2e8e9726a6c2540932a7b5ebe3c36fd84
Author: Markus Stockhausen <markus.stockhausen at gmx.de>
AuthorDate: Wed Dec 17 20:07:36 2025 +0100

    realtek: phy: reorganize package handling
    
    With kernel 6.18 the package shared structure will be hidden from
    the phy drivers. Workaround that in advance by providing a shared
    private structure that covers all information that is needed for
    normal operation.
    
    For further simplification provide a new join() function that takes
    care of a consistent initialization.
    
    Signed-off-by: Markus Stockhausen <markus.stockhausen at gmx.de>
    Link: https://github.com/openwrt/openwrt/pull/21204
    Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
---
 .../files-6.12/drivers/net/phy/rtl83xx-phy.c       | 65 +++++++++++++++-------
 1 file changed, 45 insertions(+), 20 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 3281c5d7ad..a4e19bf399 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
@@ -53,13 +53,51 @@ extern struct rtl83xx_soc_info soc_info;
 #define RTL821X_MEDIA_PAGE_FIBRE	3
 #define RTL821X_MEDIA_PAGE_INTERNAL	8
 
+#define RTL821X_JOIN_FIRST		0
+#define RTL821X_JOIN_LAST		1
+#define RTL821X_JOIN_OTHER		2
+
 static const struct firmware rtl838x_8380_fw;
 static const struct firmware rtl838x_8214fc_fw;
 static const struct firmware rtl838x_8218b_fw;
 
+struct rtl821x_shared_priv {
+	int base_addr;
+	int ports;
+};
+
+/* TODO: for kernel 6.18 drop this function and use it from phy_package library instead */
+static void *phy_package_get_priv(struct phy_device *phydev)
+{
+	return phydev->shared->priv;
+}
+
+static int rtl821x_package_join(struct phy_device *phydev, int ports)
+{
+	struct rtl821x_shared_priv *shared_priv;
+	int base_addr = phydev->mdio.addr & ~(ports - 1);
+
+	devm_phy_package_join(&phydev->mdio.dev, phydev, base_addr,
+			      sizeof(struct rtl821x_shared_priv));
+
+	shared_priv = phy_package_get_priv(phydev);
+	shared_priv->base_addr = base_addr;
+	shared_priv->ports++;
+
+	if (shared_priv->ports == 1)
+		return RTL821X_JOIN_FIRST;
+
+	if (shared_priv->ports == ports)
+		return RTL821X_JOIN_LAST;
+
+	return RTL821X_JOIN_OTHER;
+}
+
 static inline struct phy_device *get_package_phy(struct phy_device *phydev, int port)
 {
-	return mdiobus_get_phy(phydev->mdio.bus, phydev->shared->base_addr + port);
+	struct rtl821x_shared_priv *shared_priv = phy_package_get_priv(phydev);
+
+	return mdiobus_get_phy(phydev->mdio.bus, shared_priv->base_addr + port);
 }
 
 static inline struct phy_device *get_base_phy(struct phy_device *phydev)
@@ -839,11 +877,9 @@ static const struct sfp_upstream_ops rtl8214fc_sfp_ops = {
 
 static int rtl8214fc_phy_probe(struct phy_device *phydev)
 {
-	int base_addr = phydev->mdio.addr & ~3;
 	int ret = 0;
 
-	devm_phy_package_join(&phydev->mdio.dev, phydev, base_addr, 0);
-	if (phydev->mdio.addr == base_addr + 3) {
+	if (rtl821x_package_join(phydev, 4) == RTL821X_JOIN_LAST) {
 		if (soc_info.family == RTL8380_FAMILY_ID)
 			ret = rtl8380_configure_rtl8214fc(get_base_phy(phydev));
 		if (ret)
@@ -855,10 +891,7 @@ static int rtl8214fc_phy_probe(struct phy_device *phydev)
 
 static int rtl8214c_phy_probe(struct phy_device *phydev)
 {
-	int base_addr = phydev->mdio.addr & ~3;
-
-	devm_phy_package_join(&phydev->mdio.dev, phydev, base_addr, 0);
-	if (phydev->mdio.addr == base_addr + 3)
+	if (rtl821x_package_join(phydev, 4) == RTL821X_JOIN_LAST)
 		return rtl8380_configure_rtl8214c(get_base_phy(phydev));
 
 	return 0;
@@ -866,10 +899,7 @@ static int rtl8214c_phy_probe(struct phy_device *phydev)
 
 static int rtl8218b_ext_phy_probe(struct phy_device *phydev)
 {
-	int base_addr = phydev->mdio.addr & ~7;
-
-	devm_phy_package_join(&phydev->mdio.dev, phydev, base_addr, 0);
-	if (phydev->mdio.addr == base_addr + 7) {
+	if (rtl821x_package_join(phydev, 8) == RTL821X_JOIN_LAST) {
 		if (soc_info.family == RTL8380_FAMILY_ID)
 			return rtl8380_configure_ext_rtl8218b(get_base_phy(phydev));
 	}
@@ -879,15 +909,12 @@ static int rtl8218b_ext_phy_probe(struct phy_device *phydev)
 
 static int rtl8218b_int_phy_probe(struct phy_device *phydev)
 {
-	int base_addr = phydev->mdio.addr & ~7;
-
 	if (soc_info.family != RTL8380_FAMILY_ID)
 		return -ENODEV;
-	if (base_addr >= 24)
+	if (phydev->mdio.addr >= 24)
 		return -ENODEV;
 
-	devm_phy_package_join(&phydev->mdio.dev, phydev, base_addr, 0);
-	if (phydev->mdio.addr == base_addr + 7)
+	if (rtl821x_package_join(phydev, 8) == RTL821X_JOIN_LAST)
 		return rtl8380_configure_int_rtl8218b(get_base_phy(phydev));
 
 	return 0;
@@ -895,9 +922,7 @@ static int rtl8218b_int_phy_probe(struct phy_device *phydev)
 
 static int rtl8218x_phy_probe(struct phy_device *phydev)
 {
-	int base_addr = phydev->mdio.addr & ~7;
-
-	devm_phy_package_join(&phydev->mdio.dev, phydev, base_addr, 0);
+	rtl821x_package_join(phydev, 8);
 
 	return 0;
 }




More information about the lede-commits mailing list