]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
realtek: mdio: move smi_addr attribute into port structure
authorMarkus Stockhausen <markus.stockhausen@gmx.de>
Wed, 25 Mar 2026 10:26:57 +0000 (11:26 +0100)
committerRobert Marko <robimarko@gmail.com>
Fri, 27 Mar 2026 19:51:43 +0000 (20:51 +0100)
The smi_addr attribute is defined per port. Move it into the new
port structure. As the devices have a maximum of 56 addresses
save some space and convert it to type u8.

While we are here harden the mapping routine that reads these
addresses from the DTS. For this check the value that is read into
smi_addr. This is usually the MDIO standard 0..31. Sadly RTL839x
devices are an exception from that and allow addresses 0..51.
To avoid device specific if/then/else cases for now implement
a "light" consistency check.

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/22604
Signed-off-by: Robert Marko <robimarko@gmail.com>
target/linux/realtek/files-6.12/drivers/net/mdio/mdio-realtek-otto.c

index 345d584c974f6611cd74a11b4f3be599e7c73288..47ada0f682155d26e88c8b066bc7b3cf78164a94 100644 (file)
 struct rtmdio_port {
        int page;
        bool raw;
+       u8 smi_addr;
        u8 smi_bus;
 };
 
@@ -182,7 +183,6 @@ struct rtmdio_ctrl {
        struct regmap *map;
        const struct rtmdio_config *cfg;
        struct rtmdio_port port[RTMDIO_MAX_PHY];
-       int smi_addr[RTMDIO_MAX_PHY];
        struct device_node *phy_node[RTMDIO_MAX_PHY];
        bool smi_bus_is_c45[RTMDIO_MAX_SMI_BUS];
        DECLARE_BITMAP(valid_ports, RTMDIO_MAX_PHY);
@@ -579,7 +579,7 @@ static void rtmdio_setup_smi_topology(struct mii_bus *bus)
                if (ctrl->cfg->port_map_base) {
                        reg = (addr / 6) * 4;
                        mask = 0x1f << ((addr % 6) * 5);
-                       val = ctrl->smi_addr[addr] << ((addr % 6) * 5);
+                       val = ctrl->port[addr].smi_addr << ((addr % 6) * 5);
                        regmap_update_bits(ctrl->map, ctrl->cfg->port_map_base + reg, mask, val);
                }
        }
@@ -838,7 +838,7 @@ static int rtmdio_reset(struct mii_bus *bus)
 static int rtmdio_map_ports(struct device *dev)
 {
        struct rtmdio_ctrl *ctrl = dev_get_drvdata(dev);
-       int smi_bus, addr;
+       int smi_bus, smi_addr, addr;
 
        struct device_node *switch_node __free(device_node) =
                of_get_child_by_name(dev->of_node->parent, "ethernet-switch");
@@ -869,10 +869,15 @@ static int rtmdio_map_ports(struct device *dev)
                        return dev_err_probe(dev, -EINVAL, "%pfwP duplicated port number\n",
                                             of_fwnode_handle(port));
 
-               if (of_property_read_u32(phy, "reg", &ctrl->smi_addr[addr]))
+               if (of_property_read_u32(phy, "reg", &smi_addr))
                        return dev_err_probe(dev, -EINVAL, "%pfwP no phy address\n",
                                             of_fwnode_handle(phy));
 
+               /* relaxed check as RTL839x uses MDIO addresses 0..51 */
+               if (smi_addr >= ctrl->cfg->num_phys)
+                       return dev_err_probe(dev, -EINVAL, "%pfwP illegal phy address\n",
+                                            of_fwnode_handle(phy));
+
                if (of_property_read_u32(phy->parent, "reg", &smi_bus))
                        return dev_err_probe(dev, -EINVAL, "%pfwP no bus address\n",
                                             of_fwnode_handle(phy->parent));
@@ -885,6 +890,7 @@ static int rtmdio_map_ports(struct device *dev)
                        ctrl->smi_bus_is_c45[smi_bus] = true;
 
                ctrl->port[addr].smi_bus = smi_bus;
+               ctrl->port[addr].smi_addr = smi_addr;
                ctrl->phy_node[addr] = of_node_get(phy);
                __set_bit(addr, ctrl->valid_ports);
        }