Thread (3 messages) 3 messages, 1 author, 18h ago

[PATCH net-next v2 2/2] net: phy: realtek: support unaligned RTL8224 PHY packages

DORMANTno replies

From: Oskari Lemmela <hidden>
Date: 2026-10-05 20:23:41
Also in: linux-devicetree, lkml
Subsystem: ethernet phy library, networking drivers, the rest · Maintainers: Andrew Lunn, Heiner Kallweit, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

From: Manuel Stocker <redacted>

The RTL8224 driver groups its four ports by rounding each PHY address
down to a multiple of four and uses the low two address bits as the
port index. This assumes that the first port's MDIO address is aligned
to a multiple of four.

The Hasivo S1100WP-8GT-2S+ uses two RTL8224 packages at MDIO addresses
1-4 and 5-8. Extend the driver to support such configurations by using
the base address from an ethernet-phy-package node when present and
calculating each port's offset relative to that address.

Use the package-relative port index to select the MDI pair order and
polarity fields. Reject PHY addresses outside the four-port package
and propagate explicit package errors rather than falling back to
another base address.

Keep the existing aligned-address assumption when no package node
is present.

Signed-off-by: Manuel Stocker <redacted>
[Oskari: rebased on net-next/main, reworded commit message]
Signed-off-by: Oskari Lemmela <redacted>
---
 drivers/net/phy/realtek/realtek_main.c | 49 +++++++++++++++++++++++---
 1 file changed, 44 insertions(+), 5 deletions(-)
diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c
index e14960192e79..91cf34d13420 100644
--- a/drivers/net/phy/realtek/realtek_main.c
+++ b/drivers/net/phy/realtek/realtek_main.c
@@ -355,6 +355,10 @@ struct rtl821x_priv {
 	u16 iner;
 };
 
+struct rtl8224_priv {
+	u8 port_offset;
+};
+
 struct rtl8261x_priv {
 	const char *fw_name;
 	u32 fw_sub_magic;
@@ -2723,7 +2727,8 @@ static int rtl8224_package_modify_mmd(struct phy_device *phydev, int devad,
 static int rtl8224_mdi_config_order(struct phy_device *phydev)
 {
 	struct device_node *np = phydev->mdio.dev.of_node;
-	u8 port_offset = phydev->mdio.addr & 3;
+	struct rtl8224_priv *priv = phydev->priv;
+	u8 port_offset = priv->port_offset;
 	u32 order = 0;
 	int ret;
 
@@ -2748,7 +2753,8 @@ static int rtl8224_mdi_config_order(struct phy_device *phydev)
 static int rtl8224_mdi_config_polarity(struct phy_device *phydev)
 {
 	struct device_node *np = phydev->mdio.dev.of_node;
-	u8 offset = (phydev->mdio.addr & 3) * 4;
+	struct rtl8224_priv *priv = phydev->priv;
+	u8 offset = priv->port_offset * 4;
 	u32 polarity = 0;
 	int ret;
 
@@ -2783,9 +2789,42 @@ static int rtl8224_config_init(struct phy_device *phydev)
 
 static int rtl8224_probe(struct phy_device *phydev)
 {
-	/* Chip exposes 4 ports, join all of them in the same package */
-	return devm_phy_package_join(&phydev->mdio.dev, phydev,
-				     phydev->mdio.addr & ~3, 0);
+	struct device *dev = &phydev->mdio.dev;
+	u32 base_addr = phydev->mdio.addr & ~3;
+	struct rtl8224_priv *priv;
+	struct device_node *np;
+	int ret;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	np = of_get_parent(dev->of_node);
+	if (of_node_name_eq(np, "ethernet-phy-package")) {
+		ret = of_property_read_u32(np, "reg", &base_addr);
+		of_node_put(np);
+		if (ret)
+			return dev_err_probe(dev, ret,
+					     "Missing or invalid PHY package reg\n");
+
+		if (phydev->mdio.addr < base_addr ||
+		    phydev->mdio.addr - base_addr >= 4)
+			return dev_err_probe(dev, -EINVAL,
+					     "PHY address outside RTL8224 package\n");
+
+		ret = devm_of_phy_package_join(dev, phydev, 0);
+	} else {
+		of_node_put(np);
+		/* Without a package node, assume four aligned PHY addresses. */
+		ret = devm_phy_package_join(dev, phydev, base_addr, 0);
+	}
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to join PHY package\n");
+
+	priv->port_offset = phydev->mdio.addr - base_addr;
+	phydev->priv = priv;
+
+	return 0;
 }
 
 static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
-- 
2.55.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help