]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
realtek: mdio: use regmap_bulk_write() in RTL838x path
authorMarkus Stockhausen <markus.stockhausen@gmx.de>
Mon, 27 Apr 2026 16:58:59 +0000 (18:58 +0200)
committerHauke Mehrtens <hauke@hauke-m.de>
Fri, 1 May 2026 10:14:50 +0000 (12:14 +0200)
The regmap conversion only replaced the old sw() macros with their
regmap counterparts. Neither access optimization nor error handling
took place. Redesign the mdio access as follows:

- The c22/c45/read/write functions only prepare a data structure
  that describes the to-be-executed command.
- rtmdio_xxxx_run_cmd() is enhanced to bulk write the data into the
  SoC, issue all the I/O and do proper error handling. Additionally
  the signature is changed to allow read & write operations.

The bulk commands introduce some subtle changes.

- Before this patch only the needed registers were written. After
  the conversion all phy control registers are set up.
- The register write order changes

This is no issue as the hardware starts operation when issuing the
run_cmd() and only accesses the needed registers per operation.

For now adapt only the RTL838x path. Where needed rename "err" to
"ret" for consistency with kernel conventions.

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/23092
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
target/linux/realtek/files-6.18/drivers/net/mdio/mdio-realtek-otto.c

index 2876ed2faa3f9591f460399ea741ace609fde2fd..a1893b3282da17afec4c4e001f97cf5f17214feb 100644 (file)
 #define RTMDIO_PHY_POLL_MMD(dev, reg, bit)     ((bit << 21) | (dev << 16) | (reg))
 
 /* MDIO bus registers/fields */
+#define RTMDIO_C45_DATA(devnum, regnum)                (((devnum) << 16) | ((regnum) & GENMASK(15, 0)))
+#define RTMDIO_DATA_MASK                       GENMASK(15, 0)
 #define RTMDIO_RUN                             BIT(0)
 
+#define RTMDIO_838X_C22_DATA(page, reg)                ((reg) << 20 | 0x1f << 15 | (page) << 3)
 #define RTMDIO_838X_PHY_PATCH_DONE             BIT(15)
 #define RTMDIO_838X_SMI_GLB_CTRL               (0xa100)
 #define RTMDIO_838X_SMI_ACCESS_PHY_CTRL_0      (0xa1b8)
@@ -45,7 +48,6 @@
 #define   RTMDIO_838X_CMD_WRITE_C45            (BIT(1) | BIT(2))
 #define   RTMDIO_838X_CMD_MASK                 GENMASK(2, 0)
 #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)
 
@@ -226,6 +228,13 @@ struct rtmdio_phy_info {
        unsigned int poll_lpa_1000;
 };
 
+struct rtmdio_838x_smi_access {
+       u32 ctrl_0;
+       u32 ctrl_1;
+       u32 ctrl_2;
+       u32 ctrl_3;
+};
+
 static int rtmdio_phy_to_port(struct mii_bus *bus, int phy)
 {
        struct rtmdio_chan *chan = bus->priv;
@@ -256,70 +265,71 @@ static int rtmdio_run_cmd(struct mii_bus *bus, int cmd, int mask, int regnum, in
        return ret;
 }
 
-static int rtmdio_838x_run_cmd(struct mii_bus *bus, int cmd)
+static int rtmdio_838x_run_cmd(struct mii_bus *bus, int cmd,
+                              struct rtmdio_838x_smi_access *smi_access, u32 *val)
 {
-       return rtmdio_run_cmd(bus, cmd, RTMDIO_838X_CMD_MASK,
-                             RTMDIO_838X_SMI_ACCESS_PHY_CTRL_1, RTMDIO_838X_CMD_FAIL);
+       struct rtmdio_ctrl *ctrl = rtmdio_ctrl_from_bus(bus);
+       int ret;
+
+       ret = regmap_bulk_write(ctrl->map, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_0,
+                               smi_access, sizeof(*smi_access) / sizeof(u32));
+       if (ret)
+               return ret;
+
+       ret = rtmdio_run_cmd(bus, cmd, RTMDIO_838X_CMD_MASK,
+                            RTMDIO_838X_SMI_ACCESS_PHY_CTRL_1, RTMDIO_838X_CMD_FAIL);
+       if (ret || !val)
+               return ret;
+
+       ret = regmap_read(ctrl->map, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_2, val);
+       if (!ret)
+               *val &= RTMDIO_DATA_MASK;
+
+       return ret;
 }
 
 static int rtmdio_838x_read_phy(struct mii_bus *bus, u32 pn, u32 page, u32 reg, u32 *val)
 {
-       struct rtmdio_ctrl *ctrl = rtmdio_ctrl_from_bus(bus);
-       u32 park_page = 31;
-       int err;
-
-       regmap_write(ctrl->map, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_0, BIT(pn));
-       regmap_write(ctrl->map, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_2, pn << 16);
-       regmap_write(ctrl->map, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_1,
-                    reg << 20 | park_page << 15 | page << 3);
-       err = rtmdio_838x_run_cmd(bus, RTMDIO_838X_CMD_READ_C22);
-       if (!err)
-               err = regmap_read(ctrl->map, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_2, val);
-       if (!err)
-               *val &= GENMASK(15, 0);
+       struct rtmdio_838x_smi_access smi_access = {
+               .ctrl_0 = BIT(pn),
+               .ctrl_1 = RTMDIO_838X_C22_DATA(page, reg),
+               .ctrl_2 = pn << 16,
+       };
 
-       return err;
+       return rtmdio_838x_run_cmd(bus, RTMDIO_838X_CMD_READ_C22, &smi_access, val);
 }
 
 static int rtmdio_838x_write_phy(struct mii_bus *bus, u32 pn, u32 page, u32 reg, u32 val)
 {
-       struct rtmdio_ctrl *ctrl = rtmdio_ctrl_from_bus(bus);
-       u32 park_page = 31;
+       struct rtmdio_838x_smi_access smi_access = {
+               .ctrl_0 = BIT(pn),
+               .ctrl_1 = RTMDIO_838X_C22_DATA(page, reg),
+               .ctrl_2 = val << 16,
+       };
 
-       regmap_write(ctrl->map, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_0, BIT(pn));
-       regmap_write(ctrl->map, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_2, val << 16);
-       regmap_write(ctrl->map, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_1,
-                    reg << 20 | park_page << 15 | page << 3);
-
-       return rtmdio_838x_run_cmd(bus, RTMDIO_838X_CMD_WRITE_C22);
+       return rtmdio_838x_run_cmd(bus, RTMDIO_838X_CMD_WRITE_C22, &smi_access, NULL);
 }
 
 static int rtmdio_838x_read_mmd_phy(struct mii_bus *bus, u32 pn, u32 devnum, u32 regnum, u32 *val)
 {
-       struct rtmdio_ctrl *ctrl = rtmdio_ctrl_from_bus(bus);
-       int err;
-
-       regmap_write(ctrl->map, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_0, BIT(pn));
-       regmap_write(ctrl->map, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_2, pn << 16);
-       regmap_write(ctrl->map, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_3, devnum << 16 | regnum);
-       err = rtmdio_838x_run_cmd(bus, RTMDIO_838X_CMD_READ_C45);
-       if (!err)
-               err = regmap_read(ctrl->map, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_2, val);
-       if (!err)
-               *val &= GENMASK(15, 0);
+       struct rtmdio_838x_smi_access smi_access = {
+               .ctrl_0 = BIT(pn),
+               .ctrl_2 = pn << 16,
+               .ctrl_3 = RTMDIO_C45_DATA(devnum, regnum),
+       };
 
-       return err;
+       return rtmdio_838x_run_cmd(bus, RTMDIO_838X_CMD_READ_C45, &smi_access, val);
 }
 
 static int rtmdio_838x_write_mmd_phy(struct mii_bus *bus, u32 pn, u32 devnum, u32 regnum, u32 val)
 {
-       struct rtmdio_ctrl *ctrl = rtmdio_ctrl_from_bus(bus);
-
-       regmap_write(ctrl->map, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_0, BIT(pn));
-       regmap_write(ctrl->map, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_2, val << 16);
-       regmap_write(ctrl->map, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_3, devnum << 16 | regnum);
+       struct rtmdio_838x_smi_access smi_access = {
+               .ctrl_0 = BIT(pn),
+               .ctrl_2 = val << 16,
+               .ctrl_3 = RTMDIO_C45_DATA(devnum, regnum),
+       };
 
-       return rtmdio_838x_run_cmd(bus, RTMDIO_838X_CMD_WRITE_C45);
+       return rtmdio_838x_run_cmd(bus, RTMDIO_838X_CMD_WRITE_C45, &smi_access, NULL);
 }
 
 static int rtmdio_839x_run_cmd(struct mii_bus *bus, int cmd)