[openwrt/openwrt] realtek: mdio: use helper for smi topology setup

LEDE Commits lede-commits at lists.infradead.org
Mon Feb 16 06:44:29 PST 2026


robimarko pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/afbbf21714b6f0229d8efa37f47a74cfeac53379

commit afbbf21714b6f0229d8efa37f47a74cfeac53379
Author: Markus Stockhausen <markus.stockhausen at gmx.de>
AuthorDate: Fri Feb 13 19:58:37 2026 +0100

    realtek: mdio: use helper for smi topology setup
    
    On RTL930x, RTL931x and even RTL838x the smi topology is
    configured very similar. There is a bus mapping (RTL930x
    and RTL931x) and a port mapping (all three). Define a
    common helper that can take care of this setup and call
    it before bus registration.
    
    Signed-off-by: Markus Stockhausen <markus.stockhausen at gmx.de>
    Link: https://github.com/openwrt/openwrt/pull/22008
    Signed-off-by: Robert Marko <robimarko at gmail.com>
---
 .../drivers/net/mdio/mdio-realtek-otto.c           | 82 ++++++++++------------
 1 file changed, 38 insertions(+), 44 deletions(-)

diff --git a/target/linux/realtek/files-6.12/drivers/net/mdio/mdio-realtek-otto.c b/target/linux/realtek/files-6.12/drivers/net/mdio/mdio-realtek-otto.c
index d48b46a97b..cf4ca57bf3 100644
--- a/target/linux/realtek/files-6.12/drivers/net/mdio/mdio-realtek-otto.c
+++ b/target/linux/realtek/files-6.12/drivers/net/mdio/mdio-realtek-otto.c
@@ -44,6 +44,7 @@
 #define RTMDIO_838X_SMI_ACCESS_PHY_CTRL_2	(0xa1c0)
 #define RTMDIO_838X_SMI_ACCESS_PHY_CTRL_3	(0xa1c4)
 #define RTMDIO_838X_SMI_POLL_CTRL		(0xa17c)
+#define RTMDIO_838X_SMI_PORT0_5_ADDR_CTRL	(0xa1c8)
 
 #define RTMDIO_839X_CMD_FAIL			BIT(1)
 #define RTMDIO_839X_CMD_READ_C22		0
@@ -77,7 +78,7 @@
 #define RTMDIO_930X_SMI_10G_POLLING_REG0_CFG	(0xCBB4)
 #define RTMDIO_930X_SMI_10G_POLLING_REG9_CFG	(0xCBB8)
 #define RTMDIO_930X_SMI_10G_POLLING_REG10_CFG	(0xCBBC)
-#define RTMDIO_930X_SMI_PORT0_5_ADDR		(0xCB80)
+#define RTMDIO_930X_SMI_PORT0_5_ADDR_CTRL	(0xCB80)
 
 #define RTMDIO_931X_CMD_FAIL			BIT(1)
 #define RTMDIO_931X_CMD_READ_C22		0
@@ -96,7 +97,7 @@
 #define RTMDIO_931X_SMI_INDRT_ACCESS_MMD_CTRL	(0x0C18)
 #define RTMDIO_931X_MAC_L2_GLOBAL_CTRL2		(0x1358)
 #define RTMDIO_931X_SMI_PORT_POLLING_SEL	(0x0C9C)
-#define RTMDIO_931X_SMI_PORT_ADDR		(0x0C74)
+#define RTMDIO_931X_SMI_PORT_ADDR_CTRL		(0x0C74)
 #define RTMDIO_931X_SMI_10GPHY_POLLING_SEL0	(0x0CF0)
 #define RTMDIO_931X_SMI_10GPHY_POLLING_SEL1	(0x0CF4)
 #define RTMDIO_931X_SMI_10GPHY_POLLING_SEL2	(0x0CF8)
@@ -183,6 +184,8 @@ struct rtmdio_ctrl {
 struct rtmdio_config {
 	int cpu_port;
 	int raw_page;
+	int bus_map_base;
+	int port_map_base;
 	int (*read_mmd_phy)(struct mii_bus *bus, u32 port, u32 addr, u32 reg, u32 *val);
 	int (*read_phy)(struct mii_bus *bus, u32 port, u32 page, u32 reg, u32 *val);
 	int (*reset)(struct mii_bus *bus);
@@ -558,6 +561,31 @@ static int rtmdio_write(struct mii_bus *bus, int addr, int regnum, u16 val)
 	return 0;
 }
 
+static void rtmdio_setup_smi_topology(struct mii_bus *bus)
+{
+	struct rtmdio_ctrl *ctrl = bus->priv;
+	u32 reg, mask, val;
+
+	for (int addr = 0; addr < ctrl->cfg->cpu_port; addr++) {
+		if (ctrl->smi_bus[addr] < 0)
+			continue;
+
+		if (ctrl->cfg->bus_map_base) {
+			reg = (addr / 16) * 4;
+			mask = 0x3 << ((addr % 16) * 2);
+			val = ctrl->smi_bus[addr] << ((addr % 16) * 2);
+			regmap_update_bits(ctrl->map, ctrl->cfg->bus_map_base + reg, mask, val);
+		}
+
+		if (ctrl->cfg->port_map_base) {
+			reg = (addr / 6) * 4;
+			mask = 0x1f << ((addr % 6) * 5);
+			val = ctrl->smi_addr[addr] << ((addr % 6) * 5);
+			regmap_update_bits(ctrl->map, ctrl->cfg->port_map_base + reg, mask, val);
+		}
+	}
+}
+
 static u32 rtmdio_get_phy_id(struct phy_device *phydev)
 {
 	if (!phydev)
@@ -670,23 +698,7 @@ static int rtmdio_839x_reset(struct mii_bus *bus)
 static int rtmdio_930x_reset(struct mii_bus *bus)
 {
 	struct rtmdio_ctrl *ctrl = bus->priv;
-	unsigned int reg, mask, val;
-
-	/* Define bus topology */
-	for (int addr = 0; addr < ctrl->cfg->cpu_port; addr++) {
-		if (ctrl->smi_bus[addr] < 0)
-			continue;
-
-		reg = (addr / 6) * 4;
-		mask = 0x1f << ((addr % 6) * 5);
-		val = ctrl->smi_addr[addr] << (ffs(mask) - 1);
-		regmap_update_bits(ctrl->map, RTMDIO_930X_SMI_PORT0_5_ADDR + reg, mask, val);
-
-		reg = (addr / 16) * 4;
-		mask = 0x3 << ((addr % 16) * 2);
-		val = ctrl->smi_bus[addr] << (ffs(mask) - 1);
-		regmap_update_bits(ctrl->map, RTMDIO_930X_SMI_PORT0_15_POLLING_SEL + reg, mask, val);
-	}
+	unsigned int mask, val;
 
 	/* Define C22/C45 bus feature set */
 	for (int addr = 0; addr < RTMDIO_MAX_SMI_BUS; addr++) {
@@ -762,43 +774,18 @@ static void rtmdio_930x_setup_polling(struct mii_bus *bus)
 static int rtmdio_931x_reset(struct mii_bus *bus)
 {
 	struct rtmdio_ctrl *ctrl = bus->priv;
-	u32 poll_sel[4] = { 0 };
-	u32 poll_ctrl = 0;
 	u32 c45_mask = 0;
 
-	pr_info("%s called\n", __func__);
 	/* Disable port polling for configuration purposes */
 	regmap_write(ctrl->map, RTMDIO_931X_SMI_PORT_POLLING_CTRL, 0);
 	regmap_write(ctrl->map, RTMDIO_931X_SMI_PORT_POLLING_CTRL + 4, 0);
 	msleep(100);
 
-	/* Mapping of port to phy-addresses on an SMI bus */
-	for (int addr = 0; addr < ctrl->cfg->cpu_port; addr++) {
-		u32 pos;
-
-		if (ctrl->smi_bus[addr] < 0)
-			continue;
-
-		pos = (addr % 6) * 5;
-		regmap_update_bits(ctrl->map, RTMDIO_931X_SMI_PORT_ADDR + (addr / 6) * 4,
-				   0x1f << pos, ctrl->smi_addr[addr] << pos);
-		pos = (addr * 2) % 32;
-		poll_sel[addr / 16] |= ctrl->smi_bus[addr] << pos;
-		poll_ctrl |= BIT(20 + ctrl->smi_bus[addr]);
-	}
-
-	/* Configure which SMI bus is behind which port number */
-	for (int i = 0; i < RTMDIO_MAX_SMI_BUS; i++) {
-		pr_info("poll sel %d, %08x\n", i, poll_sel[i]);
-		regmap_write(ctrl->map, RTMDIO_931X_SMI_PORT_POLLING_SEL + (i * 4), poll_sel[i]);
-	}
-
 	/* Define C22/C45 bus feature set */
 	for (int i = 0; i < RTMDIO_MAX_SMI_BUS; i++) {
 		if (ctrl->smi_bus_isc45[i])
 			c45_mask |= 0x2 << (i * 2);  /* Std. C45, non-standard is 0x3 */
 	}
-	pr_info("%s: c45_mask: %08x", __func__, c45_mask);
 	regmap_update_bits(ctrl->map, RTMDIO_931X_SMI_GLB_CTRL1, GENMASK(7, 0), c45_mask);
 
 	return 0;
@@ -948,6 +935,8 @@ static int rtmdio_probe(struct platform_device *pdev)
 	snprintf(bus->id, MII_BUS_ID_SIZE, "realtek-mdio");
 
 	device_set_node(&bus->dev, of_fwnode_handle(dev->of_node));
+
+	rtmdio_setup_smi_topology(bus);
 	ret = devm_mdiobus_register(dev, bus);
 	if (ret)
 		return ret;
@@ -961,6 +950,7 @@ static int rtmdio_probe(struct platform_device *pdev)
 static const struct rtmdio_config rtmdio_838x_cfg = {
 	.cpu_port	= 28,
 	.raw_page	= 4095,
+	.port_map_base	= RTMDIO_838X_SMI_PORT0_5_ADDR_CTRL,
 	.read_mmd_phy	= rtmdio_838x_read_mmd_phy,
 	.read_phy	= rtmdio_838x_read_phy,
 	.reset		= rtmdio_838x_reset,
@@ -982,6 +972,8 @@ static const struct rtmdio_config rtmdio_839x_cfg = {
 static const struct rtmdio_config rtmdio_930x_cfg = {
 	.cpu_port	= 28,
 	.raw_page	= 4095,
+	.bus_map_base	= RTMDIO_930X_SMI_PORT0_15_POLLING_SEL,
+	.port_map_base	= RTMDIO_930X_SMI_PORT0_5_ADDR_CTRL,
 	.read_mmd_phy	= rtmdio_930x_read_mmd_phy,
 	.read_phy	= rtmdio_930x_read_phy,
 	.reset		= rtmdio_930x_reset,
@@ -993,6 +985,8 @@ static const struct rtmdio_config rtmdio_930x_cfg = {
 static const struct rtmdio_config rtmdio_931x_cfg = {
 	.cpu_port	= 56,
 	.raw_page	= 8191,
+	.bus_map_base	= RTMDIO_931X_SMI_PORT_POLLING_SEL,
+	.port_map_base	= RTMDIO_931X_SMI_PORT_ADDR_CTRL,
 	.read_mmd_phy	= rtmdio_931x_read_mmd_phy,
 	.read_phy	= rtmdio_931x_read_phy,
 	.reset		= rtmdio_931x_reset,




More information about the lede-commits mailing list