]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
realtek: mdio: use generic bus command function for RTL838x
authorMarkus Stockhausen <markus.stockhausen@gmx.de>
Tue, 13 Jan 2026 19:45:39 +0000 (20:45 +0100)
committerHauke Mehrtens <hauke@hauke-m.de>
Sat, 24 Jan 2026 22:40:24 +0000 (23:40 +0100)
The Realtek mdio bus works similar for all devices with only
minor family specific differences. Basically command issuing
follows a generic style. Write command type and a trigger.
Afterwards wait until the trigger flag goes back to zero (aka
"command complete"). Unify this sequence in a central helper.

RTL838x read/write callers of this helper use a strange style of
error handling by issuing goto statements. Refactor this for better
readability. Additionally remove all debug prints. These are not
needed as the central read/write handlers provide a common logging
mechanism.

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

index 896a08652c86a42f587b016d5c925dbdf87d8320..473d5000984856b9b443dfca7764c18b8b00059c 100644 (file)
 #define RTMDIO_SW_BASE                         ((volatile void *) 0xBB000000)
 
 /* MDIO bus registers */
+#define RTMDIO_838X_CMD_FAIL                   0
+#define RTMDIO_838X_CMD_READ_C22               0
+#define RTMDIO_838X_CMD_READ_C45               BIT(1)
+#define RTMDIO_838X_CMD_WRITE_C22              BIT(2)
+#define RTMDIO_838X_CMD_WRITE_C45              BIT(1) | BIT(2)
+#define RTMDIO_838X_CMD_MASK                   BIT(1) | BIT(2)
 #define RTMDIO_838X_SMI_GLB_CTRL               (0xa100)
 #define RTMDIO_838X_SMI_ACCESS_PHY_CTRL_0      (0xa1b8)
 #define RTMDIO_838X_SMI_ACCESS_PHY_CTRL_1      (0xa1bc)
@@ -175,48 +181,44 @@ struct rtmdio_phy_info {
        unsigned int poll_lpa_1000;
 };
 
-/* RTL838x specific MDIO functions */
-
-static int rtmdio_838x_smi_wait_op(int timeout)
+static int rtmdio_run_cmd(int cmd, int mask, int regnum, int fail)
 {
-       int ret = 0;
-       u32 val;
+       int ret, val;
 
-       ret = readx_poll_timeout(sw_r32, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_1,
-                                val, !(val & 0x1), 20, timeout);
+       sw_w32_mask(mask, cmd | 1, regnum);
+       ret = readx_poll_timeout(sw_r32, regnum, val, !(val & 1), 20, 500000);
        if (ret)
-               pr_err("%s: timeout\n", __func__);
+               WARN_ONCE(1, "mdio bus access timed out\n");
+       else if (val & fail) {
+               WARN_ONCE(1, "mdio bus access failed\n");
+               ret = -EIO;
+       }
 
        return ret;
 }
 
+/* RTL838x specific MDIO functions */
+
+static int rtmdio_838x_run_cmd(int cmd)
+{
+       return rtmdio_run_cmd(cmd, RTMDIO_838X_CMD_MASK,
+                             RTMDIO_838X_SMI_ACCESS_PHY_CTRL_1, RTMDIO_838X_CMD_FAIL);
+}
+
 /* Reads a register in a page from the PHY */
 static int rtmdio_838x_read_phy(u32 port, u32 page, u32 reg, u32 *val)
 {
-       u32 v, park_page = 0x1f << 15;
+       u32 park_page = 0x1f;
        int err;
 
-       if (port > 31) {
-               *val = 0xffff;
-               return 0;
-       }
-
-       if (page > 4095 || reg > 31)
-               return -ENOTSUPP;
-
        mutex_lock(&rtmdio_lock);
 
        sw_w32_mask(0xffff0000, port << 16, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_2);
-       v = reg << 20 | page << 3;
-       sw_w32(v | park_page, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_1);
-       sw_w32_mask(0, 1, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_1);
+       sw_w32(reg << 20 | page << 3 | park_page << 15, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_1);
+       err = rtmdio_838x_run_cmd(RTMDIO_838X_CMD_READ_C22);
+       if (!err)
+               *val = sw_r32(RTMDIO_838X_SMI_ACCESS_PHY_CTRL_2) & 0xffff;
 
-       err = rtmdio_838x_smi_wait_op(100000);
-       if (err)
-               goto errout;
-
-       *val = sw_r32(RTMDIO_838X_SMI_ACCESS_PHY_CTRL_2) & 0xffff;
-errout:
        mutex_unlock(&rtmdio_lock);
 
        return err;
@@ -225,23 +227,16 @@ errout:
 /* Write to a register in a page of the PHY */
 static int rtmdio_838x_write_phy(u32 port, u32 page, u32 reg, u32 val)
 {
-       u32 v, park_page = 0x1f << 15;
+       u32 park_page = 0x1f;
        int err;
 
-       val &= 0xffff;
-       if (port > 31 || page > 4095 || reg > 31)
-               return -ENOTSUPP;
-
        mutex_lock(&rtmdio_lock);
 
        sw_w32(BIT(port), RTMDIO_838X_SMI_ACCESS_PHY_CTRL_0);
        sw_w32_mask(0xffff0000, val << 16, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_2);
+       sw_w32(reg << 20 | page << 3 | park_page << 15, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_1);
+       err = rtmdio_838x_run_cmd(RTMDIO_838X_CMD_WRITE_C22);
 
-       v = reg << 20 | page << 3 | 0x4;
-       sw_w32(v | park_page, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_1);
-       sw_w32_mask(0, 1, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_1);
-
-       err = rtmdio_838x_smi_wait_op(100000);
        mutex_unlock(&rtmdio_lock);
 
        return err;
@@ -251,26 +246,16 @@ static int rtmdio_838x_write_phy(u32 port, u32 page, u32 reg, u32 val)
 static int rtmdio_838x_read_mmd_phy(u32 port, u32 addr, u32 reg, u32 *val)
 {
        int err;
-       u32 v;
 
        mutex_lock(&rtmdio_lock);
 
        sw_w32(1 << port, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_0);
        sw_w32_mask(0xffff0000, port << 16, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_2);
+       sw_w32(addr << 16 | reg, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_3);
+       err = rtmdio_838x_run_cmd(RTMDIO_838X_CMD_READ_C45);
+       if (!err)
+               *val = sw_r32(RTMDIO_838X_SMI_ACCESS_PHY_CTRL_2) & 0xffff;
 
-       v = addr << 16 | reg;
-       sw_w32(v, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_3);
-
-       /* mmd-access | read | cmd-start */
-       v = 1 << 1 | 0 << 2 | 1;
-       sw_w32(v, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_1);
-
-       err = rtmdio_838x_smi_wait_op(100000);
-       if (err)
-               goto errout;
-
-       *val = sw_r32(RTMDIO_838X_SMI_ACCESS_PHY_CTRL_2) & 0xffff;
-errout:
        mutex_unlock(&rtmdio_lock);
 
        return err;
@@ -280,21 +265,15 @@ errout:
 static int rtmdio_838x_write_mmd_phy(u32 port, u32 addr, u32 reg, u32 val)
 {
        int err;
-       u32 v;
 
-       pr_debug("MMD write: port %d, dev %d, reg %d, val %x\n", port, addr, reg, val);
-       val &= 0xffff;
        mutex_lock(&rtmdio_lock);
 
        sw_w32(1 << port, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_0);
        sw_w32_mask(0xffff0000, val << 16, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_2);
        sw_w32_mask(0x1f << 16, addr << 16, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_3);
        sw_w32_mask(0xffff, reg, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_3);
-       /* mmd-access | write | cmd-start */
-       v = 1 << 1 | 1 << 2 | 1;
-       sw_w32(v, RTMDIO_838X_SMI_ACCESS_PHY_CTRL_1);
+       err = rtmdio_838x_run_cmd(RTMDIO_838X_CMD_WRITE_C45);
 
-       err = rtmdio_838x_smi_wait_op(100000);
        mutex_unlock(&rtmdio_lock);
 
        return err;