]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
realtek: mdio/dsa: refactor mdio bus initialization
authorMarkus Stockhausen <markus.stockhausen@gmx.de>
Mon, 12 Jan 2026 15:43:40 +0000 (16:43 +0100)
committerHauke Mehrtens <hauke@hauke-m.de>
Wed, 21 Jan 2026 22:32:54 +0000 (23:32 +0100)
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 <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/21438
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
target/linux/realtek/files-6.12/drivers/net/mdio/mdio-realtek-otto.c

index b87497fe6a43e863fd4ae6e928ded4d8f0a18ccd..20e3f555c25732c4b11a70b90b3ee75b20e55533 100644 (file)
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 
+#include <linux/fwnode_mdio.h>
 #include <linux/mutex.h>
 #include <linux/of_mdio.h>
 #include <linux/of_net.h>
@@ -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 = {