* [PATCH net-next 0/5] net: mdio: realtek-rtl9300: Refactor initialization and port lookup
@ 2026-06-07 12:54 Markus Stockhausen
2026-06-07 12:54 ` [PATCH net-next 1/5] dt-bindings: net: realtek,rtl9301-mdio: Add RTL931x series Markus Stockhausen
` (4 more replies)
0 siblings, 5 replies; 8+ messages in thread
From: Markus Stockhausen @ 2026-06-07 12:54 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel, robh, krzk+dt, conor+dt, devicetree
Cc: Markus Stockhausen
The Realtek Otto switch platform consists of four different series
- RTL838x aka maple : 28 port 1G Switches
- RTL839x aka cypress : 52 port 1G Switches
- RTL930x aka longan : 28 port 1G/2.5G/10G Switches
- RTL931x aka mango : 56 port 1G/2.5G/10G Switches
This patch series adds support for the RTL931x devices. For this
- Enhance device tree binding.
- Implement final cleanups and enhancments for the driver.
- Add RTL931x coding.
Remark: Instead of this series it was planned to bring support for
hardware polling configuration first. It turns out that more testing
is needed, especially for the RTL83xx SoCs. So add this lineup of
devices, that are known to have no obvious bus parallel access
issues (at least from testing and vendor SDK perspective).
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
Markus Stockhausen (5):
dt-bindings: net: realtek,rtl9301-mdio: Add RTL931x series
net: mdio: realtek-rtl9300: Add prefix to register field defines
net: mdio: realtek-rtl9300: Make otto_emdio_read_cmd() generic
net: mdio: realtek-rtl9300: Add registers for high port count modes
net: mdio: realtek-rtl9300: Add support for RTL931x
.../bindings/net/realtek,rtl9301-mdio.yaml | 6 +
drivers/net/mdio/mdio-realtek-rtl9300.c | 210 +++++++++++++++---
2 files changed, 183 insertions(+), 33 deletions(-)
--
2.54.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH net-next 1/5] dt-bindings: net: realtek,rtl9301-mdio: Add RTL931x series
2026-06-07 12:54 [PATCH net-next 0/5] net: mdio: realtek-rtl9300: Refactor initialization and port lookup Markus Stockhausen
@ 2026-06-07 12:54 ` Markus Stockhausen
2026-06-07 13:10 ` Krzysztof Kozlowski
2026-06-07 12:54 ` [PATCH net-next 2/5] net: mdio: realtek-rtl9300: Add prefix to register field defines Markus Stockhausen
` (3 subsequent siblings)
4 siblings, 1 reply; 8+ messages in thread
From: Markus Stockhausen @ 2026-06-07 12:54 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel, robh, krzk+dt, conor+dt, devicetree
Cc: Markus Stockhausen
The 10G Realtek Otto switches are divided into two series
- Longan: RTL930x up to 28 ports
- Mango : RTL931x up to 56 ports
The Mango based devices have 3 different SoCs RTL9311, RTL9312 and RTL9313.
The MDIO controller of these switches works like the existing RTL930x
logic but has different characteristics and different registers. Add new
compatibles in the device tree.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
.../devicetree/bindings/net/realtek,rtl9301-mdio.yaml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml b/Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml
index 02e4e33e9969..494c92601e09 100644
--- a/Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml
+++ b/Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml
@@ -19,6 +19,12 @@ properties:
- realtek,rtl9303-mdio
- const: realtek,rtl9301-mdio
- const: realtek,rtl9301-mdio
+ - items:
+ - enum:
+ - realtek,rtl9312-mdio
+ - realtek,rtl9313-mdio
+ - const: realtek,rtl9311-mdio
+ - const: realtek,rtl9311-mdio
'#address-cells':
const: 1
--
2.54.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH net-next 2/5] net: mdio: realtek-rtl9300: Add prefix to register field defines
2026-06-07 12:54 [PATCH net-next 0/5] net: mdio: realtek-rtl9300: Refactor initialization and port lookup Markus Stockhausen
2026-06-07 12:54 ` [PATCH net-next 1/5] dt-bindings: net: realtek,rtl9301-mdio: Add RTL931x series Markus Stockhausen
@ 2026-06-07 12:54 ` Markus Stockhausen
2026-06-07 12:54 ` [PATCH net-next 3/5] net: mdio: realtek-rtl9300: Make otto_emdio_read_cmd() generic Markus Stockhausen
` (2 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Markus Stockhausen @ 2026-06-07 12:54 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel, robh, krzk+dt, conor+dt, devicetree
Cc: Markus Stockhausen
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.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/mdio-realtek-rtl9300.c | 63 +++++++++++++------------
1 file changed, 32 insertions(+), 31 deletions(-)
diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
index 92c8f2512476..007a07136fa1 100644
--- 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 mii_bus *bus, u32 cmd,
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(struct mii_bus *bus, int port, int regnum, u
{
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(struct mii_bus *bus, int port,
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(struct mii_bus *bus, int port,
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 platform_device *pdev)
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,
--
2.54.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH net-next 3/5] net: mdio: realtek-rtl9300: Make otto_emdio_read_cmd() generic
2026-06-07 12:54 [PATCH net-next 0/5] net: mdio: realtek-rtl9300: Refactor initialization and port lookup Markus Stockhausen
2026-06-07 12:54 ` [PATCH net-next 1/5] dt-bindings: net: realtek,rtl9301-mdio: Add RTL931x series Markus Stockhausen
2026-06-07 12:54 ` [PATCH net-next 2/5] net: mdio: realtek-rtl9300: Add prefix to register field defines Markus Stockhausen
@ 2026-06-07 12:54 ` Markus Stockhausen
2026-06-07 12:54 ` [PATCH net-next 4/5] net: mdio: realtek-rtl9300: Add registers for high port count modes Markus Stockhausen
2026-06-07 12:54 ` [PATCH net-next 5/5] net: mdio: realtek-rtl9300: Add support for RTL931x Markus Stockhausen
4 siblings, 0 replies; 8+ messages in thread
From: Markus Stockhausen @ 2026-06-07 12:54 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel, robh, krzk+dt, conor+dt, devicetree
Cc: Markus Stockhausen
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.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/mdio-realtek-rtl9300.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
index 007a07136fa1..0068beff785b 100644
--- 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_bus *bus, u32 cmd,
}
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 mii_bus *bus, u32 cmd,
if (ret)
return ret;
- *value = FIELD_GET(RTL9300_PHY_CTRL_DATA, *value);
+ *value = (*value & mask) >> __ffs(mask);
return 0;
}
@@ -230,7 +230,8 @@ static int otto_emdio_9300_read_c22(struct mii_bus *bus, int port, int regnum, u
.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(struct mii_bus *bus, int port,
.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,
--
2.54.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH net-next 4/5] net: mdio: realtek-rtl9300: Add registers for high port count modes
2026-06-07 12:54 [PATCH net-next 0/5] net: mdio: realtek-rtl9300: Refactor initialization and port lookup Markus Stockhausen
` (2 preceding siblings ...)
2026-06-07 12:54 ` [PATCH net-next 3/5] net: mdio: realtek-rtl9300: Make otto_emdio_read_cmd() generic Markus Stockhausen
@ 2026-06-07 12:54 ` Markus Stockhausen
2026-06-07 12:54 ` [PATCH net-next 5/5] net: mdio: realtek-rtl9300: Add support for RTL931x Markus Stockhausen
4 siblings, 0 replies; 8+ messages in thread
From: Markus Stockhausen @ 2026-06-07 12:54 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel, robh, krzk+dt, conor+dt, devicetree
Cc: Markus Stockhausen
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.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/mdio-realtek-rtl9300.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
index 0068beff785b..33c00b6ba8f8 100644
--- 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_bus *bus, u32 cmd,
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;
--
2.54.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH net-next 5/5] net: mdio: realtek-rtl9300: Add support for RTL931x
2026-06-07 12:54 [PATCH net-next 0/5] net: mdio: realtek-rtl9300: Refactor initialization and port lookup Markus Stockhausen
` (3 preceding siblings ...)
2026-06-07 12:54 ` [PATCH net-next 4/5] net: mdio: realtek-rtl9300: Add registers for high port count modes Markus Stockhausen
@ 2026-06-07 12:54 ` Markus Stockhausen
4 siblings, 0 replies; 8+ messages in thread
From: Markus Stockhausen @ 2026-06-07 12:54 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel, robh, krzk+dt, conor+dt, devicetree
Cc: Markus Stockhausen
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.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/mdio-realtek-rtl9300.c | 123 +++++++++++++++++++++++-
1 file changed, 122 insertions(+), 1 deletion(-)
diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
index 33c00b6ba8f8..dbd52f921909 100644
--- 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(struct mii_bus *bus, int port,
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_controller(struct otto_emdio_priv *priv)
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_emdio_9300_info = {
.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);
--
2.54.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH net-next 1/5] dt-bindings: net: realtek,rtl9301-mdio: Add RTL931x series
2026-06-07 12:54 ` [PATCH net-next 1/5] dt-bindings: net: realtek,rtl9301-mdio: Add RTL931x series Markus Stockhausen
@ 2026-06-07 13:10 ` Krzysztof Kozlowski
2026-06-07 16:09 ` AW: " Markus Stockhausen
0 siblings, 1 reply; 8+ messages in thread
From: Krzysztof Kozlowski @ 2026-06-07 13:10 UTC (permalink / raw)
To: Markus Stockhausen, andrew, hkallweit1, linux, davem, edumazet,
kuba, pabeni, netdev, chris.packham, daniel, robh, krzk+dt,
conor+dt, devicetree
On 07/06/2026 14:54, Markus Stockhausen wrote:
> Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
> ---
> .../devicetree/bindings/net/realtek,rtl9301-mdio.yaml | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml b/Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml
> index 02e4e33e9969..494c92601e09 100644
> --- a/Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml
> +++ b/Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml
> @@ -19,6 +19,12 @@ properties:
> - realtek,rtl9303-mdio
> - const: realtek,rtl9301-mdio
> - const: realtek,rtl9301-mdio
> + - items:
> + - enum:
> + - realtek,rtl9312-mdio
> + - realtek,rtl9313-mdio
> + - const: realtek,rtl9311-mdio
> + - const: realtek,rtl9311-mdio
That one is part of enum with other single entries - rtl9301.
>
> '#address-cells':
> const: 1
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 8+ messages in thread
* AW: [PATCH net-next 1/5] dt-bindings: net: realtek,rtl9301-mdio: Add RTL931x series
2026-06-07 13:10 ` Krzysztof Kozlowski
@ 2026-06-07 16:09 ` Markus Stockhausen
0 siblings, 0 replies; 8+ messages in thread
From: Markus Stockhausen @ 2026-06-07 16:09 UTC (permalink / raw)
To: 'Krzysztof Kozlowski', andrew, hkallweit1, linux, davem,
edumazet, kuba, pabeni, netdev, chris.packham, daniel, robh,
krzk+dt, conor+dt, devicetree
Hi Krzysztof,
> Von: Krzysztof Kozlowski <krzk@kernel.org>
> Gesendet: Sonntag, 7. Juni 2026 15:11
> Betreff: Re: [PATCH net-next 1/5] dt-bindings: net: realtek,rtl9301-mdio: Add RTL931x series
>
> > On 07/06/2026 14:54, Markus Stockhausen wrote:
> > Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
> > ---
> > .../devicetree/bindings/net/realtek,rtl9301-mdio.yaml | 6 ++++++
> > 1 file changed, 6 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml b/Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml
> > index 02e4e33e9969..494c92601e09 100644
> > --- a/Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml
> > +++ b/Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml
> > @@ -19,6 +19,12 @@ properties:
> > - realtek,rtl9303-mdio
> > - const: realtek,rtl9301-mdio
> > - const: realtek,rtl9301-mdio
> > + - items:
> > + - enum:
> > + - realtek,rtl9312-mdio
> > + - realtek,rtl9313-mdio
> > + - const: realtek,rtl9311-mdio
> > + - const: realtek,rtl9311-mdio
>
> That one is part of enum with other single entries - rtl9301.
This way?
oneOf:
- items:
- enum:
- realtek,rtl9302b-mdio
- realtek,rtl9302c-mdio
- realtek,rtl9303-mdio
- const: realtek,rtl9301-mdio
- items:
- enum:
- realtek,rtl9312-mdio
- realtek,rtl9313-mdio
- const: realtek,rtl9311-mdio
- enum:
- realtek,rtl9301-mdio
- realtek,rtl9311-mdio
Thanks in advance.
Markus
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-06-07 16:10 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-07 12:54 [PATCH net-next 0/5] net: mdio: realtek-rtl9300: Refactor initialization and port lookup Markus Stockhausen
2026-06-07 12:54 ` [PATCH net-next 1/5] dt-bindings: net: realtek,rtl9301-mdio: Add RTL931x series Markus Stockhausen
2026-06-07 13:10 ` Krzysztof Kozlowski
2026-06-07 16:09 ` AW: " Markus Stockhausen
2026-06-07 12:54 ` [PATCH net-next 2/5] net: mdio: realtek-rtl9300: Add prefix to register field defines Markus Stockhausen
2026-06-07 12:54 ` [PATCH net-next 3/5] net: mdio: realtek-rtl9300: Make otto_emdio_read_cmd() generic Markus Stockhausen
2026-06-07 12:54 ` [PATCH net-next 4/5] net: mdio: realtek-rtl9300: Add registers for high port count modes Markus Stockhausen
2026-06-07 12:54 ` [PATCH net-next 5/5] net: mdio: realtek-rtl9300: Add support for RTL931x Markus Stockhausen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox