]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
realtek: mdio: add helper that disables polling
authorMarkus Stockhausen <markus.stockhausen@gmx.de>
Tue, 5 May 2026 17:05:21 +0000 (19:05 +0200)
committerRobert Marko <robimarko@gmail.com>
Mon, 11 May 2026 08:32:29 +0000 (10:32 +0200)
Each device specific implementation disables the hardware polling
differently. Harmonize this by providing a central helper. With
this

- disable polling at the very beginning
- remove unneeded sleeping (SDK does not need it too)
- add checks for regmap returncodes

Especially for RTL839x avoid to disable hardware polling at all.
It is enough that the port specific polling is disabled during
configuration.

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

index 37b6a95ae9cb4a3576c2872386da4403c8203f99..957a1743005d75ab0f372108b0fc55ca4b646701 100644 (file)
@@ -95,6 +95,7 @@
 #define RTMDIO_930X_SMI_PORT0_15_POLLING_SEL   (0xCA08)
 #define RTMDIO_930X_SMI_PORT16_27_POLLING_SEL  (0xCA0C)
 #define RTMDIO_930X_SMI_MAC_TYPE_CTRL          (0xCA04)
+#define RTMDIO_930X_SMI_POLL_CTRL              (0xca90)
 #define RTMDIO_930X_SMI_PRVTE_POLLING_CTRL     (0xCA10)
 #define RTMDIO_930X_SMI_10G_POLLING_REG0_CFG   (0xCBB4)
 #define RTMDIO_930X_SMI_10G_POLLING_REG9_CFG   (0xCBB8)
@@ -224,6 +225,7 @@ struct rtmdio_config {
        u16 num_busses;
        u16 num_pages;
        u16 num_phys;
+       u32 poll_ctrl;
        int port_map_base;
        int (*read_c22)(struct mii_bus *bus, u32 pn, u32 page, u32 reg, u32 *val);
        int (*read_c45)(struct mii_bus *bus, u32 pn, u32 devnum, u32 regnum, u32 *val);
@@ -601,6 +603,25 @@ static int rtmdio_write_c22(struct mii_bus *bus, int phy, int regnum, u16 val)
        return 0;
 }
 
+static int rtmdio_poll_port(struct rtmdio_ctrl *ctrl, int pn, bool active)
+{
+       return regmap_assign_bits(ctrl->map, ctrl->cfg->poll_ctrl + (pn / 32) * 4,
+                                 BIT(pn % 32), active);
+}
+
+static int rtmdio_disable_polling(struct rtmdio_ctrl *ctrl)
+{
+       int pn, ret;
+
+       for (pn = 0; pn < ctrl->cfg->num_phys; pn++) {
+               ret = rtmdio_poll_port(ctrl, pn, false);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
 static int rtmdio_setup_smi_topology(struct rtmdio_ctrl *ctrl)
 {
        u32 reg, mask, val, pn;
@@ -710,9 +731,6 @@ static int rtmdio_838x_setup_ctrl(struct rtmdio_ctrl *ctrl)
 
 static void rtmdio_838x_setup_polling(struct rtmdio_ctrl *ctrl)
 {
-       /* Disable MAC polling for PHY config. It will be activated later in the DSA driver */
-       regmap_write(ctrl->map, RTMDIO_838X_SMI_POLL_CTRL, 0);
-
        /*
         * Control bits EX_PHY_MAN_xxx have an important effect on the detection of the media
         * status (fibre/copper) of a PHY. Once activated, register MAC_LINK_MEDIA_STS can
@@ -724,22 +742,6 @@ static void rtmdio_838x_setup_polling(struct rtmdio_ctrl *ctrl)
                           test_bit(24, ctrl->valid_ports));
 }
 
-static int rtmdio_839x_setup_ctrl(struct rtmdio_ctrl *ctrl)
-{
-       return 0;
-
-       pr_debug("%s called\n", __func__);
-       /* BUG: The following does not work, but should! */
-       /* Disable MAC polling the PHY so that we can start configuration */
-       regmap_write(ctrl->map, RTMDIO_839X_SMI_PORT_POLLING_CTRL, 0);
-       regmap_write(ctrl->map, RTMDIO_839X_SMI_PORT_POLLING_CTRL + 4, 0);
-       /* Disable PHY polling via SoC */
-       regmap_clear_bits(ctrl->map, RTMDIO_839X_SMI_GLB_CTRL, BIT(7));
-
-       /* Probably should reset all PHYs here... */
-       return 0;
-}
-
 static int rtmdio_930x_setup_ctrl(struct rtmdio_ctrl *ctrl)
 {
        int ret;
@@ -809,11 +811,6 @@ static int rtmdio_931x_setup_ctrl(struct rtmdio_ctrl *ctrl)
 {
        int ret;
 
-       /* Disable polling for configuration purposes */
-       regmap_write(ctrl->map, RTMDIO_931X_SMI_PORT_POLLING_CTRL, 0);
-       regmap_write(ctrl->map, RTMDIO_931X_SMI_PORT_POLLING_CTRL + 4, 0);
-       msleep(100);
-
        /* Define C22/C45 bus feature set (bit 1 of SMI_SETx_FMT_SEL) */
        for (int smi_bus = 0; smi_bus < ctrl->cfg->num_busses; smi_bus++) {
                ret = regmap_assign_bits(ctrl->map, RTMDIO_931X_SMI_GLB_CTRL1,
@@ -997,18 +994,24 @@ static int rtmdio_probe(struct platform_device *pdev)
        if (IS_ERR(ctrl->map))
                return PTR_ERR(ctrl->map);
 
-       ret = rtmdio_map_ports(dev);
+       ret = rtmdio_disable_polling(ctrl);
        if (ret)
                return ret;
 
-       ret = rtmdio_setup_smi_topology(ctrl);
+       ret = rtmdio_map_ports(dev);
        if (ret)
                return ret;
 
-       ret = ctrl->cfg->setup_ctrl(ctrl);
+       ret = rtmdio_setup_smi_topology(ctrl);
        if (ret)
                return ret;
 
+       if (ctrl->cfg->setup_ctrl) {
+               ret = ctrl->cfg->setup_ctrl(ctrl);
+               if (ret)
+                       return ret;
+       }
+
        device_for_each_child_node_scoped(dev, child) {
                ret = rtmdio_probe_one(dev, ctrl, child);
                if (ret)
@@ -1028,6 +1031,7 @@ static const struct rtmdio_config rtmdio_838x_cfg = {
        .num_busses     = RTMDIO_838X_NUM_BUSSES,
        .num_pages      = RTMDIO_838X_NUM_PAGES,
        .num_phys       = 28,
+       .poll_ctrl      = RTMDIO_838X_SMI_POLL_CTRL,
        .port_map_base  = RTMDIO_838X_SMI_PORT0_5_ADDR_CTRL,
        .read_c22       = rtmdio_838x_read_c22,
        .read_c45       = rtmdio_838x_read_c45,
@@ -1048,11 +1052,11 @@ static const struct rtmdio_config rtmdio_839x_cfg = {
        .num_busses     = RTMDIO_839X_NUM_BUSSES,
        .num_pages      = RTMDIO_839X_NUM_PAGES,
        .num_phys       = 52,
+       .poll_ctrl      = RTMDIO_839X_SMI_PORT_POLLING_CTRL,
        .read_c22       = rtmdio_839x_read_c22,
        .read_c45       = rtmdio_839x_read_c45,
        .ret_mask       = GENMASK(15, 0),
        .ret_reg        = RTMDIO_839X_PHYREG_DATA_CTRL,
-       .setup_ctrl     = rtmdio_839x_setup_ctrl,
        .smi_base       = RTMDIO_839X_PHYREG_ACCESS_CTRL,
        .smi_size       = sizeof(struct rtmdio_839x_smi_access),
        .write_c22      = rtmdio_839x_write_c22,
@@ -1067,6 +1071,7 @@ static const struct rtmdio_config rtmdio_930x_cfg = {
        .num_busses     = RTMDIO_930X_NUM_BUSSES,
        .num_pages      = RTMDIO_930X_NUM_PAGES,
        .num_phys       = 28,
+       .poll_ctrl      = RTMDIO_930X_SMI_POLL_CTRL,
        .port_map_base  = RTMDIO_930X_SMI_PORT0_5_ADDR_CTRL,
        .read_c22       = rtmdio_930x_read_c22,
        .read_c45       = rtmdio_930x_read_c45,
@@ -1088,6 +1093,7 @@ static const struct rtmdio_config rtmdio_931x_cfg = {
        .num_busses     = RTMDIO_931X_NUM_BUSSES,
        .num_pages      = RTMDIO_931X_NUM_PAGES,
        .num_phys       = 56,
+       .poll_ctrl      = RTMDIO_931X_SMI_PORT_POLLING_CTRL,
        .port_map_base  = RTMDIO_931X_SMI_PORT_ADDR_CTRL,
        .read_c22       = rtmdio_931x_read_c22,
        .read_c45       = rtmdio_931x_read_c45,