From: Markus Stockhausen Date: Mon, 12 Jan 2026 15:43:40 +0000 (+0100) Subject: realtek: mdio/dsa: refactor mdio bus initialization X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3b73474f712b86efe1a364b7a1d172c1629418e1;p=thirdparty%2Fopenwrt.git realtek: mdio/dsa: refactor mdio bus initialization The mdio driver currently determines the smi bus and address from the realtek,smi-address attribute of the phy. To better reflect the topology and align with upstream, the phys should be relocated below their associated bus. As an interim solution the following dts notation is in focus. mdio_ctrl: mdio-controller { mdio_bus0: mdio-bus@0 { reg = <0>; phy0: ethernet-phy@0 { reg = <0>; compatible = "ethernet-phy-ieee802.3-c45"; realtek,smi-address = <8>; }; &mdio_bus1 { reg = <1>; phy16: ethernet-phy@16 { reg = <16>; compatible = "ethernet-phy-ieee802.3-c45"; realtek,smi-address = <2>; }; } With this - the phy reg property still denotes the port number - the bus number can be derived from the parent bus node. - the bus address is taken from realtek,smi-address Refactor bus initialization so it can handle phy nodes below multiple bus nodes. Signed-off-by: Markus Stockhausen Link: https://github.com/openwrt/openwrt/pull/21438 Signed-off-by: Hauke Mehrtens --- 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 b87497fe6a4..20e3f555c25 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 @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only +#include #include #include #include @@ -149,6 +150,7 @@ struct rtmdio_bus_priv { bool raw[RTMDIO_MAX_PORT]; int smi_bus[RTMDIO_MAX_PORT]; u8 smi_addr[RTMDIO_MAX_PORT]; + struct device_node *dn[RTMDIO_MAX_PORT]; bool smi_bus_isc45[RTMDIO_MAX_SMI_BUS]; }; @@ -1012,31 +1014,21 @@ static int rtmdio_reset(struct mii_bus *bus) static int rtmdio_probe(struct platform_device *pdev) { - struct device_node *dn; struct device *dev = &pdev->dev; struct rtmdio_bus_priv *priv; + struct device_node *dn; struct mii_bus *bus; - int addr; + int ret, addr; bus = devm_mdiobus_alloc_size(dev, sizeof(*priv)); if (!bus) return -ENOMEM; priv = bus->priv; + priv->cfg = (const struct rtmdio_config *)device_get_match_data(dev); for (addr = 0; addr < RTMDIO_MAX_PORT; addr++) priv->smi_bus[addr] = -1; - priv->cfg = (const struct rtmdio_config *)device_get_match_data(dev); - - bus->name = "Realtek MDIO bus"; - bus->reset = rtmdio_reset; - bus->read = rtmdio_read; - bus->write = rtmdio_write; - bus->read_c45 = rtmdio_read_c45; - bus->write_c45 = rtmdio_write_c45; - bus->parent = dev; - bus->phy_mask = ~(BIT_ULL(priv->cfg->cpu_port) - 1ULL); - for_each_node_by_name(dn, "ethernet-phy") { u32 smi_addr[2]; @@ -1063,17 +1055,34 @@ static int rtmdio_probe(struct platform_device *pdev) if (of_device_is_compatible(dn, "ethernet-phy-ieee802.3-c45")) priv->smi_bus_isc45[priv->smi_bus[addr]] = true; - } - dn = of_find_compatible_node(NULL, NULL, "realtek,rtl83xx-switch"); - if (!dn) { - dev_err(dev, "No RTL switch node in DTS\n"); - return -ENODEV; + priv->dn[addr] = dn; } + bus->name = "Realtek MDIO bus"; + bus->reset = rtmdio_reset; + bus->read = rtmdio_read; + bus->write = rtmdio_write; + bus->read_c45 = rtmdio_read_c45; + bus->write_c45 = rtmdio_write_c45; + bus->parent = dev; + bus->phy_mask = ~0; snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(dev)); - return devm_of_mdiobus_register(dev, bus, dev->of_node); + device_set_node(&bus->dev, of_fwnode_handle(dev->of_node)); + ret = devm_mdiobus_register(dev, bus); + if (ret) + return ret; + + for (addr = 0; addr < priv->cfg->cpu_port; addr++) { + if (priv->dn[addr]) { + ret = fwnode_mdiobus_register_phy(bus, of_fwnode_handle(priv->dn[addr]), addr); + if (ret) + return ret; + } + } + + return 0; } static const struct rtmdio_config rtmdio_838x_cfg = {