[PATCH net-next 4/8] net: mdio: realtek-rtl9300: Configure hardware polling during probing
From: Markus Stockhausen <hidden>
Date: 2026-06-13 11:30:22
Also in:
linux-devicetree
Subsystem:
ethernet phy library, networking drivers, the rest · Maintainers:
Andrew Lunn, Heiner Kallweit, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
During bus probing the PHYs are initialized and firmware might be loaded. This often requires complex access sequences where the switch hardware polling might interfere badly. The polling can be configured with one or two 32 bit mask registers. Each bit enables (=1) or disables (=0) the polling of the corresponding port. Provide a helper to enable/disable polling for a specific port. With this disable hardware polling temporarily during bus probing and enable it afterwards according to the device tree topology. Nice side effect: This patch brings the hardware polling into a consistent state for devices where U-Boot does not take care. Signed-off-by: Markus Stockhausen <redacted> --- drivers/net/mdio/mdio-realtek-rtl9300.c | 26 ++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
index c3a9eeca3154..a7fd075947b6 100644
--- a/drivers/net/mdio/mdio-realtek-rtl9300.c
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c@@ -137,6 +137,7 @@ #define RTL9300_PHY_CTRL_INDATA GENMASK(31, 16) #define RTL9300_PHY_CTRL_DATA GENMASK(15, 0) #define RTL9300_SMI_ACCESS_PHY_CTRL_3 0xcb7c +#define RTL9300_SMI_POLL_CTRL 0xca90 #define RTL9300_SMI_PORT0_5_ADDR_CTRL 0xcb80 #define RTL9310_NUM_BUSES 4
@@ -162,6 +163,7 @@ #define RTL9310_PHY_CTRL_INDATA GENMASK(15, 0) #define RTL9310_SMI_INDRT_ACCESS_MMD_CTRL 0x0c18 #define RTL9310_SMI_PORT_ADDR_CTRL 0x0c74 +#define RTL9310_SMI_PORT_POLLING_CTRL 0x0ccc #define RTL9310_SMI_PORT_POLLING_SEL 0x0c9c #define PHY_CTRL_CMD BIT(0)
@@ -210,6 +212,7 @@ struct otto_emdio_info { u8 num_buses; u8 num_ports; u16 num_pages; + u32 poll_ctrl; int (*setup_controller)(struct otto_emdio_priv *priv); int (*read_c22)(struct mii_bus *bus, int port, int regnum, u32 *value); int (*read_c45)(struct mii_bus *bus, int port, int dev_addr, int regnum, u32 *value);
@@ -245,6 +248,12 @@ static struct otto_emdio_priv *otto_emdio_bus_to_priv(struct mii_bus *bus) return chan->priv; } +static int otto_emdio_set_port_polling(struct otto_emdio_priv *priv, int port, bool active) +{ + return regmap_assign_bits(priv->regmap, priv->info->poll_ctrl + (port / 32) * 4, + BIT(port % 32), active); +} + static int otto_emdio_run_cmd(struct mii_bus *bus, u32 cmd, struct otto_emdio_cmd_regs *cmd_data) {
@@ -735,7 +744,7 @@ static int otto_emdio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct otto_emdio_priv *priv; - int err; + int port, err; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv)
@@ -750,6 +759,13 @@ static int otto_emdio_probe(struct platform_device *pdev) if (IS_ERR(priv->regmap)) return PTR_ERR(priv->regmap); + /* Avoid issues with complex firmware loads. */ + for (port = 0; port < priv->info->num_ports; port++) { + err = otto_emdio_set_port_polling(priv, port, false); + if (err) + return err; + } + platform_set_drvdata(pdev, priv); err = otto_emdio_map_ports(dev);
@@ -772,6 +788,12 @@ static int otto_emdio_probe(struct platform_device *pdev) return err; } + for_each_set_bit(port, priv->valid_ports, priv->info->num_ports) { + err = otto_emdio_set_port_polling(priv, port, true); + if (err) + return err; + } + return 0; }
@@ -790,6 +812,7 @@ static const struct otto_emdio_info otto_emdio_9300_info = { .num_buses = RTL9300_NUM_BUSES, .num_ports = RTL9300_NUM_PORTS, .num_pages = RTL9300_NUM_PAGES, + .poll_ctrl = RTL9300_SMI_POLL_CTRL, .setup_controller = otto_emdio_9300_setup_controller, .read_c22 = otto_emdio_9300_read_c22, .read_c45 = otto_emdio_9300_read_c45,
@@ -815,6 +838,7 @@ static const struct otto_emdio_info otto_emdio_9310_info = { .num_buses = RTL9310_NUM_BUSES, .num_pages = RTL9310_NUM_PAGES, .num_ports = RTL9310_NUM_PORTS, + .poll_ctrl = RTL9310_SMI_PORT_POLLING_CTRL, .setup_controller = otto_emdio_9310_setup_controller, .read_c22 = otto_emdio_9310_read_c22, .read_c45 = otto_emdio_9310_read_c45,
--
2.54.0