realtek: mdio: backport upstream patches

Another round of MDIO driver patches was accepted upstream.
Not production relevant as OpenWrt still uses the downstream
driver.

Link: https://github.com/openwrt/openwrt/pull/23768
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
This commit is contained in:
Markus Stockhausen
2026-06-13 16:36:31 +02:00
parent aa510aa47d
commit ee02f6f16b
4 changed files with 455 additions and 0 deletions
@@ -0,0 +1,147 @@
From 474400cf3f9faec064a35a7725c72a52f5ec6e5f Mon Sep 17 00:00:00 2001
From: Markus Stockhausen <markus.stockhausen@gmx.de>
Date: Sun, 7 Jun 2026 09:10:20 +0200
Subject: [PATCH 04/15] net: mdio: realtek-rtl9300: Add prefix to register
field defines
The current Realtek Otto MDIO driver has some define leftovers without
a SoC prefix. When adding new devices there will be an overlap for some
of them. Sort this out as follows:
- PHY_CTRL_CMD/PHY_CTRL_MMD_DEVAD/PHY_CTRL_MMD_REG are common for all
series. Leave them as is but move them into a separate block.
- Add RTL9300 prefix to all other defines and adapt the callers.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/mdio-realtek-rtl9300.c | 63 +++++++++++++------------
1 file changed, 32 insertions(+), 31 deletions(-)
--- a/drivers/net/mdio/mdio-realtek-rtl9300.c
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
@@ -59,23 +59,24 @@
#define RTL9300_SMI_PORT0_15_POLLING_SEL 0xca08
#define RTL9300_SMI_ACCESS_PHY_CTRL_0 0xcb70
#define RTL9300_SMI_ACCESS_PHY_CTRL_1 0xcb74
-#define PHY_CTRL_REG_ADDR GENMASK(24, 20)
-#define PHY_CTRL_PARK_PAGE GENMASK(19, 15)
-#define PHY_CTRL_MAIN_PAGE GENMASK(14, 3)
-#define PHY_CTRL_WRITE BIT(2)
-#define PHY_CTRL_READ 0
-#define PHY_CTRL_TYPE_C45 BIT(1)
-#define PHY_CTRL_TYPE_C22 0
-#define PHY_CTRL_CMD BIT(0)
-#define PHY_CTRL_FAIL BIT(25)
+#define RTL9300_PHY_CTRL_REG_ADDR GENMASK(24, 20)
+#define RTL9300_PHY_CTRL_PARK_PAGE GENMASK(19, 15)
+#define RTL9300_PHY_CTRL_MAIN_PAGE GENMASK(14, 3)
+#define RTL9300_PHY_CTRL_WRITE BIT(2)
+#define RTL9300_PHY_CTRL_READ 0
+#define RTL9300_PHY_CTRL_TYPE_C45 BIT(1)
+#define RTL9300_PHY_CTRL_TYPE_C22 0
+#define RTL9300_PHY_CTRL_FAIL BIT(25)
#define RTL9300_SMI_ACCESS_PHY_CTRL_2 0xcb78
-#define PHY_CTRL_INDATA GENMASK(31, 16)
-#define PHY_CTRL_DATA GENMASK(15, 0)
+#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 PHY_CTRL_MMD_DEVAD GENMASK(20, 16)
-#define PHY_CTRL_MMD_REG GENMASK(15, 0)
#define RTL9300_SMI_PORT0_5_ADDR_CTRL 0xcb80
+#define PHY_CTRL_CMD BIT(0)
+#define PHY_CTRL_MMD_DEVAD GENMASK(20, 16)
+#define PHY_CTRL_MMD_REG GENMASK(15, 0)
+
#define MAP_ADDRS_PER_REG 6
#define MAP_BITS_PER_ADDR 5
#define MAP_BITS_PER_BUS 2
@@ -204,7 +205,7 @@ static int otto_emdio_read_cmd(struct mi
if (ret)
return ret;
- *value = FIELD_GET(PHY_CTRL_DATA, *value);
+ *value = FIELD_GET(RTL9300_PHY_CTRL_DATA, *value);
return 0;
}
@@ -223,27 +224,27 @@ static int otto_emdio_9300_read_c22(stru
{
struct otto_emdio_priv *priv = otto_emdio_bus_to_priv(bus);
struct otto_emdio_cmd_regs cmd_data = {
- .c22_data = FIELD_PREP(PHY_CTRL_REG_ADDR, regnum) |
- FIELD_PREP(PHY_CTRL_PARK_PAGE, 0x1f) |
- FIELD_PREP(PHY_CTRL_MAIN_PAGE, RAW_PAGE(priv)),
- .io_data = FIELD_PREP(PHY_CTRL_INDATA, port),
+ .c22_data = FIELD_PREP(RTL9300_PHY_CTRL_REG_ADDR, regnum) |
+ FIELD_PREP(RTL9300_PHY_CTRL_PARK_PAGE, 0x1f) |
+ FIELD_PREP(RTL9300_PHY_CTRL_MAIN_PAGE, RAW_PAGE(priv)),
+ .io_data = FIELD_PREP(RTL9300_PHY_CTRL_INDATA, port),
};
- return otto_emdio_read_cmd(bus, PHY_CTRL_TYPE_C22, &cmd_data, value);
+ return otto_emdio_read_cmd(bus, RTL9300_PHY_CTRL_TYPE_C22, &cmd_data, value);
}
static int otto_emdio_9300_write_c22(struct mii_bus *bus, int port, int regnum, u16 value)
{
struct otto_emdio_priv *priv = otto_emdio_bus_to_priv(bus);
struct otto_emdio_cmd_regs cmd_data = {
- .c22_data = FIELD_PREP(PHY_CTRL_REG_ADDR, regnum) |
- FIELD_PREP(PHY_CTRL_PARK_PAGE, 0x1f) |
- FIELD_PREP(PHY_CTRL_MAIN_PAGE, RAW_PAGE(priv)),
- .io_data = FIELD_PREP(PHY_CTRL_INDATA, value),
+ .c22_data = FIELD_PREP(RTL9300_PHY_CTRL_REG_ADDR, regnum) |
+ FIELD_PREP(RTL9300_PHY_CTRL_PARK_PAGE, 0x1f) |
+ FIELD_PREP(RTL9300_PHY_CTRL_MAIN_PAGE, RAW_PAGE(priv)),
+ .io_data = FIELD_PREP(RTL9300_PHY_CTRL_INDATA, value),
.port_mask_low = BIT(port),
};
- return otto_emdio_write_cmd(bus, PHY_CTRL_TYPE_C22, &cmd_data);
+ return otto_emdio_write_cmd(bus, RTL9300_PHY_CTRL_TYPE_C22, &cmd_data);
}
static int otto_emdio_9300_read_c45(struct mii_bus *bus, int port,
@@ -252,10 +253,10 @@ static int otto_emdio_9300_read_c45(stru
struct otto_emdio_cmd_regs cmd_data = {
.c45_data = FIELD_PREP(PHY_CTRL_MMD_DEVAD, dev_addr) |
FIELD_PREP(PHY_CTRL_MMD_REG, regnum),
- .io_data = FIELD_PREP(PHY_CTRL_INDATA, port),
+ .io_data = FIELD_PREP(RTL9300_PHY_CTRL_INDATA, port),
};
- return otto_emdio_read_cmd(bus, PHY_CTRL_TYPE_C45, &cmd_data, value);
+ return otto_emdio_read_cmd(bus, RTL9300_PHY_CTRL_TYPE_C45, &cmd_data, value);
}
static int otto_emdio_9300_write_c45(struct mii_bus *bus, int port,
@@ -264,11 +265,11 @@ static int otto_emdio_9300_write_c45(str
struct otto_emdio_cmd_regs cmd_data = {
.c45_data = FIELD_PREP(PHY_CTRL_MMD_DEVAD, dev_addr) |
FIELD_PREP(PHY_CTRL_MMD_REG, regnum),
- .io_data = FIELD_PREP(PHY_CTRL_INDATA, value),
+ .io_data = FIELD_PREP(RTL9300_PHY_CTRL_INDATA, value),
.port_mask_low = BIT(port),
};
- return otto_emdio_write_cmd(bus, PHY_CTRL_TYPE_C45, &cmd_data);
+ return otto_emdio_write_cmd(bus, RTL9300_PHY_CTRL_TYPE_C45, &cmd_data);
}
static int otto_emdio_read_c22(struct mii_bus *bus, int phy_id, int regnum)
@@ -582,9 +583,9 @@ static int otto_emdio_probe(struct platf
static const struct otto_emdio_info otto_emdio_9300_info = {
.addr_map_base = RTL9300_SMI_PORT0_5_ADDR_CTRL,
.bus_map_base = RTL9300_SMI_PORT0_15_POLLING_SEL,
- .cmd_fail = PHY_CTRL_FAIL,
- .cmd_read = PHY_CTRL_READ,
- .cmd_write = PHY_CTRL_WRITE,
+ .cmd_fail = RTL9300_PHY_CTRL_FAIL,
+ .cmd_read = RTL9300_PHY_CTRL_READ,
+ .cmd_write = RTL9300_PHY_CTRL_WRITE,
.cmd_regs = {
.c22_data = RTL9300_SMI_ACCESS_PHY_CTRL_1,
.c45_data = RTL9300_SMI_ACCESS_PHY_CTRL_3,
@@ -0,0 +1,63 @@
From 2b24f54b8751e483a67443f93941a81c05ccce67 Mon Sep 17 00:00:00 2001
From: Markus Stockhausen <markus.stockhausen@gmx.de>
Date: Sun, 7 Jun 2026 10:12:51 +0200
Subject: [PATCH 05/15] net: mdio: realtek-rtl9300: Make otto_emdio_read_cmd()
generic
The otto_emdio_read_cmd() helper still uses RTL9300 specific properties.
This cannot be made generic as the I/O register has different layouts for
the different SoCs. E.g.
- RTL930x: data in bits 31-16, data out bits 15-0
- RTL931x: data in bits 15-0, data out bits 31-16
Add a mask parameter to the function signature and fill it properly
in the callers. As the masks will always have bits set from constant
defines, there is no need for a consistency check.
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/mdio-realtek-rtl9300.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
--- a/drivers/net/mdio/mdio-realtek-rtl9300.c
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
@@ -191,7 +191,7 @@ static int otto_emdio_run_cmd(struct mii
}
static int otto_emdio_read_cmd(struct mii_bus *bus, u32 cmd,
- struct otto_emdio_cmd_regs *cmd_data, u32 *value)
+ struct otto_emdio_cmd_regs *cmd_data, u32 mask, u32 *value)
{
struct otto_emdio_priv *priv = otto_emdio_bus_to_priv(bus);
int ret;
@@ -205,7 +205,7 @@ static int otto_emdio_read_cmd(struct mi
if (ret)
return ret;
- *value = FIELD_GET(RTL9300_PHY_CTRL_DATA, *value);
+ *value = field_get(mask, *value);
return 0;
}
@@ -230,7 +230,8 @@ static int otto_emdio_9300_read_c22(stru
.io_data = FIELD_PREP(RTL9300_PHY_CTRL_INDATA, port),
};
- return otto_emdio_read_cmd(bus, RTL9300_PHY_CTRL_TYPE_C22, &cmd_data, value);
+ return otto_emdio_read_cmd(bus, RTL9300_PHY_CTRL_TYPE_C22, &cmd_data,
+ RTL9300_PHY_CTRL_DATA, value);
}
static int otto_emdio_9300_write_c22(struct mii_bus *bus, int port, int regnum, u16 value)
@@ -256,7 +257,8 @@ static int otto_emdio_9300_read_c45(stru
.io_data = FIELD_PREP(RTL9300_PHY_CTRL_INDATA, port),
};
- return otto_emdio_read_cmd(bus, RTL9300_PHY_CTRL_TYPE_C45, &cmd_data, value);
+ return otto_emdio_read_cmd(bus, RTL9300_PHY_CTRL_TYPE_C45, &cmd_data,
+ RTL9300_PHY_CTRL_DATA, value);
}
static int otto_emdio_9300_write_c45(struct mii_bus *bus, int port,
@@ -0,0 +1,58 @@
From 2628d4b57215ff57c062644523badbabeb22a095 Mon Sep 17 00:00:00 2001
From: Markus Stockhausen <markus.stockhausen@gmx.de>
Date: Sun, 7 Jun 2026 09:24:09 +0200
Subject: [PATCH 06/15] net: mdio: realtek-rtl9300: Add registers for high port
count models
The high port count models of the Realtek Otto switches have additional
registers to instrument the MDIO controller. These are:
- High port mask: A bitfield that extends the already existing low port
mask to select ports starting from 32.
- Broadcast: This takes the port number during reads on the RTL931x.
- Extended page: Some additional page info. The SDK does not give much
information about this. Basically some fixed value must be written
into it during access.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/mdio-realtek-rtl9300.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
--- a/drivers/net/mdio/mdio-realtek-rtl9300.c
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
@@ -91,6 +91,10 @@ struct otto_emdio_cmd_regs {
u32 c45_data;
u32 io_data;
u32 port_mask_low;
+ /* additional registers for high port count models RTL839x/RTL931x */
+ u32 port_mask_high;
+ u32 broadcast;
+ u32 ext_page;
};
struct otto_emdio_priv {
@@ -164,6 +168,22 @@ static int otto_emdio_run_cmd(struct mii
return ret;
/* Fill all registers. Hardware will read only the needed bits depending on command */
+ if (info->cmd_regs.port_mask_high) {
+ /* Fill extra registers for high port count models */
+ ret = regmap_write(priv->regmap, info->cmd_regs.broadcast, cmd_data->broadcast);
+ if (ret)
+ return ret;
+
+ ret = regmap_write(priv->regmap, info->cmd_regs.ext_page, cmd_data->ext_page);
+ if (ret)
+ return ret;
+
+ ret = regmap_write(priv->regmap,
+ info->cmd_regs.port_mask_high, cmd_data->port_mask_high);
+ if (ret)
+ return ret;
+ }
+
ret = regmap_write(priv->regmap, info->cmd_regs.port_mask_low, cmd_data->port_mask_low);
if (ret)
return ret;
@@ -0,0 +1,187 @@
From 390dfbbd1ead27523853a21fd587b1285006a4ef Mon Sep 17 00:00:00 2001
From: Markus Stockhausen <markus.stockhausen@gmx.de>
Date: Sun, 7 Jun 2026 10:09:44 +0200
Subject: [PATCH 07/15] net: mdio: realtek-rtl9300: Add support for RTL931x
The MDIO driver has been prepared for multiple device support. Add all
required bits for the RTL931x (aka mango) series. This is straightforward
but some things are worth to be mentioned.
- In contrast to RTL930x the I/O register has the input/output fields
swapped. Upper 16 bits are for read/outputs, and the lower 16 bits
are for write/inputs.
- The supported "pages" are 8192 and thus the raw page is 8191
- The devices support up to 56 ports. Thus the MAX_PORTS definition
is increased by this commit.
- There are multiple global SMI controller registers with a different
layout from RTL930x devices. Therefore a separate setup_controller()
callback is added.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/mdio-realtek-rtl9300.c | 123 +++++++++++++++++++++++-
1 file changed, 122 insertions(+), 1 deletion(-)
--- a/drivers/net/mdio/mdio-realtek-rtl9300.c
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
@@ -73,6 +73,31 @@
#define RTL9300_SMI_ACCESS_PHY_CTRL_3 0xcb7c
#define RTL9300_SMI_PORT0_5_ADDR_CTRL 0xcb80
+#define RTL9310_NUM_BUSES 4
+#define RTL9310_NUM_PAGES 8192
+#define RTL9310_NUM_PORTS 56
+#define RTL9310_SMI_GLB_CTRL1 0x0cbc
+#define RTL9310_SMI_GLB_FMT_SEL_C45(intf) BIT((intf) * 2 + 1)
+#define RTL9310_SMI_INDRT_ACCESS_CTRL_0 0x0c00
+#define RTL9310_PHY_CTRL_REG_ADDR GENMASK(10, 6)
+#define RTL9310_PHY_CTRL_MAIN_PAGE GENMASK(23, 11)
+#define RTL9310_PHY_CTRL_READ 0
+#define RTL9310_PHY_CTRL_WRITE BIT(4)
+#define RTL9310_PHY_CTRL_TYPE_C45 BIT(3)
+#define RTL9310_PHY_CTRL_TYPE_C22 0
+#define RTL9310_PHY_CTRL_FAIL BIT(1)
+#define RTL9310_SMI_INDRT_ACCESS_BC_PHYID_CTRL 0x0c14
+#define RTL9310_BC_PORT_ID GENMASK(10, 5)
+#define RTL9310_SMI_INDRT_ACCESS_CTRL_1 0x0c04
+#define RTL9310_SMI_INDRT_ACCESS_CTRL_2_LOW 0x0c08
+#define RTL9310_SMI_INDRT_ACCESS_CTRL_2_HIGH 0x0c0c
+#define RTL9310_SMI_INDRT_ACCESS_CTRL_3 0x0c10 /* I/O fields flipped */
+#define RTL9310_PHY_CTRL_DATA GENMASK(31, 16)
+#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_SEL 0x0c9c
+
#define PHY_CTRL_CMD BIT(0)
#define PHY_CTRL_MMD_DEVAD GENMASK(20, 16)
#define PHY_CTRL_MMD_REG GENMASK(15, 0)
@@ -81,7 +106,7 @@
#define MAP_BITS_PER_ADDR 5
#define MAP_BITS_PER_BUS 2
#define MAP_BUSES_PER_REG 16
-#define MAX_PORTS 28
+#define MAX_PORTS 56
#define MAX_SMI_BUSSES 4
#define RAW_PAGE(priv) ((priv)->info->num_pages - 1)
@@ -294,6 +319,60 @@ static int otto_emdio_9300_write_c45(str
return otto_emdio_write_cmd(bus, RTL9300_PHY_CTRL_TYPE_C45, &cmd_data);
}
+static int otto_emdio_9310_read_c22(struct mii_bus *bus, int port, int regnum, u32 *value)
+{
+ struct otto_emdio_priv *priv = otto_emdio_bus_to_priv(bus);
+ struct otto_emdio_cmd_regs cmd_data = {
+ .broadcast = FIELD_PREP(RTL9310_BC_PORT_ID, port),
+ .c22_data = FIELD_PREP(RTL9310_PHY_CTRL_REG_ADDR, regnum) |
+ FIELD_PREP(RTL9310_PHY_CTRL_MAIN_PAGE, RAW_PAGE(priv)),
+ };
+
+ return otto_emdio_read_cmd(bus, RTL9310_PHY_CTRL_TYPE_C22, &cmd_data,
+ RTL9310_PHY_CTRL_DATA, value);
+}
+
+static int otto_emdio_9310_write_c22(struct mii_bus *bus, int port, int regnum, u16 value)
+{
+ struct otto_emdio_priv *priv = otto_emdio_bus_to_priv(bus);
+ struct otto_emdio_cmd_regs cmd_data = {
+ .c22_data = FIELD_PREP(RTL9310_PHY_CTRL_REG_ADDR, regnum) |
+ FIELD_PREP(RTL9310_PHY_CTRL_MAIN_PAGE, RAW_PAGE(priv)),
+ .io_data = FIELD_PREP(RTL9310_PHY_CTRL_INDATA, value),
+ .port_mask_high = (u32)(BIT_ULL(port) >> 32),
+ .port_mask_low = (u32)(BIT_ULL(port)),
+ };
+
+ return otto_emdio_write_cmd(bus, RTL9310_PHY_CTRL_TYPE_C22, &cmd_data);
+}
+
+static int otto_emdio_9310_read_c45(struct mii_bus *bus, int port,
+ int dev_addr, int regnum, u32 *value)
+{
+ struct otto_emdio_cmd_regs cmd_data = {
+ .broadcast = FIELD_PREP(RTL9310_BC_PORT_ID, port),
+ .c45_data = FIELD_PREP(PHY_CTRL_MMD_DEVAD, dev_addr) |
+ FIELD_PREP(PHY_CTRL_MMD_REG, regnum),
+ };
+
+ return otto_emdio_read_cmd(bus, RTL9310_PHY_CTRL_TYPE_C45, &cmd_data,
+ RTL9310_PHY_CTRL_DATA, value);
+}
+
+static int otto_emdio_9310_write_c45(struct mii_bus *bus, int port,
+ int dev_addr, int regnum, u16 value)
+{
+ struct otto_emdio_cmd_regs cmd_data = {
+ .c45_data = FIELD_PREP(PHY_CTRL_MMD_DEVAD, dev_addr) |
+ FIELD_PREP(PHY_CTRL_MMD_REG, regnum),
+ .io_data = FIELD_PREP(RTL9310_PHY_CTRL_INDATA, value),
+ .port_mask_high = (u32)(BIT_ULL(port) >> 32),
+ .port_mask_low = (u32)(BIT_ULL(port)),
+ };
+
+ return otto_emdio_write_cmd(bus, RTL9310_PHY_CTRL_TYPE_C45, &cmd_data);
+}
+
static int otto_emdio_read_c22(struct mii_bus *bus, int phy_id, int regnum)
{
struct otto_emdio_priv *priv = otto_emdio_bus_to_priv(bus);
@@ -413,6 +492,22 @@ static int otto_emdio_9300_setup_control
return 0;
}
+static int otto_emdio_9310_setup_controller(struct otto_emdio_priv *priv)
+{
+ int i, err;
+
+ /* Put the interfaces into C45 mode if required */
+ for (i = 0; i < priv->info->num_buses; i++) {
+ err = regmap_assign_bits(priv->regmap, RTL9310_SMI_GLB_CTRL1,
+ RTL9310_SMI_GLB_FMT_SEL_C45(i),
+ priv->smi_bus_is_c45[i]);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
static int otto_emdio_probe_one(struct device *dev, struct otto_emdio_priv *priv,
struct fwnode_handle *node)
{
@@ -624,8 +719,34 @@ static const struct otto_emdio_info otto
.write_c45 = otto_emdio_9300_write_c45,
};
+static const struct otto_emdio_info otto_emdio_9310_info = {
+ .addr_map_base = RTL9310_SMI_PORT_ADDR_CTRL,
+ .bus_map_base = RTL9310_SMI_PORT_POLLING_SEL,
+ .cmd_fail = RTL9310_PHY_CTRL_FAIL,
+ .cmd_read = RTL9310_PHY_CTRL_READ,
+ .cmd_write = RTL9310_PHY_CTRL_WRITE,
+ .cmd_regs = {
+ .broadcast = RTL9310_SMI_INDRT_ACCESS_BC_PHYID_CTRL,
+ .c22_data = RTL9310_SMI_INDRT_ACCESS_CTRL_0,
+ .c45_data = RTL9310_SMI_INDRT_ACCESS_MMD_CTRL,
+ .ext_page = RTL9310_SMI_INDRT_ACCESS_CTRL_1,
+ .io_data = RTL9310_SMI_INDRT_ACCESS_CTRL_3,
+ .port_mask_low = RTL9310_SMI_INDRT_ACCESS_CTRL_2_LOW,
+ .port_mask_high = RTL9310_SMI_INDRT_ACCESS_CTRL_2_HIGH,
+ },
+ .num_buses = RTL9310_NUM_BUSES,
+ .num_pages = RTL9310_NUM_PAGES,
+ .num_ports = RTL9310_NUM_PORTS,
+ .setup_controller = otto_emdio_9310_setup_controller,
+ .read_c22 = otto_emdio_9310_read_c22,
+ .read_c45 = otto_emdio_9310_read_c45,
+ .write_c22 = otto_emdio_9310_write_c22,
+ .write_c45 = otto_emdio_9310_write_c45,
+};
+
static const struct of_device_id otto_emdio_ids[] = {
{ .compatible = "realtek,rtl9301-mdio", .data = &otto_emdio_9300_info },
+ { .compatible = "realtek,rtl9311-mdio", .data = &otto_emdio_9310_info },
{}
};
MODULE_DEVICE_TABLE(of, otto_emdio_ids);