* [PATCH 1/9] net: mdio: realtek-rtl9300: Convert to generic prefix
2026-05-19 16:57 [PATCH 0/9] mdio: realtek-rtl9300: Groundwork for multi SOC support Markus Stockhausen
@ 2026-05-19 16:57 ` Markus Stockhausen
2026-05-19 17:51 ` Andrew Lunn
2026-05-19 16:57 ` [PATCH 2/9] net: mdio: realtek-rtl9300: Add device specific info structure Markus Stockhausen
` (7 subsequent siblings)
8 siblings, 1 reply; 26+ messages in thread
From: Markus Stockhausen @ 2026-05-19 16:57 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel
Cc: Markus Stockhausen
The Realtek MDIO driver currently only serves SOCs from the Realtek
RTL930x series. This is only one lineup of the Realtek Otto switch
series that also knows RTL838x, RTL839x, RTL931x devices.
All of these share the same MDIO logic but have individual properties.
To make clear what is devic specific and what is device independent
split the function/structure prefix as follows:
- for device specific helpers keep rtl9300_
- Rename generic functions and structures to rtl_
Remark: rtl9300_mdio_wait_ready is being renamed as the command bit
is always the same in all SOCs. The read/write functions are not
renamed (yet) because they will only fit the RTL930x SOCs.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/mdio-realtek-rtl9300.c | 82 ++++++++++++-------------
1 file changed, 41 insertions(+), 41 deletions(-)
diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
index 8d5fb014ca06..a3374d5241cb 100644
--- a/drivers/net/mdio/mdio-realtek-rtl9300.c
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
@@ -48,7 +48,7 @@
#define MAX_SMI_BUSSES 4
#define MAX_SMI_ADDR 0x1f
-struct rtl9300_mdio_priv {
+struct rtl_mdio_priv {
struct regmap *regmap;
struct mutex lock; /* protect HW access */
DECLARE_BITMAP(valid_ports, MAX_PORTS);
@@ -58,15 +58,15 @@ struct rtl9300_mdio_priv {
struct mii_bus *bus[MAX_SMI_BUSSES];
};
-struct rtl9300_mdio_chan {
- struct rtl9300_mdio_priv *priv;
+struct rtl_mdio_chan {
+ struct rtl_mdio_priv *priv;
u8 mdio_bus;
};
-static int rtl9300_mdio_phy_to_port(struct mii_bus *bus, int phy_id)
+static int rtl_mdio_phy_to_port(struct mii_bus *bus, int phy_id)
{
- struct rtl9300_mdio_chan *chan = bus->priv;
- struct rtl9300_mdio_priv *priv;
+ struct rtl_mdio_chan *chan = bus->priv;
+ struct rtl_mdio_priv *priv;
int i;
priv = chan->priv;
@@ -79,7 +79,7 @@ static int rtl9300_mdio_phy_to_port(struct mii_bus *bus, int phy_id)
return -ENOENT;
}
-static int rtl9300_mdio_wait_ready(struct rtl9300_mdio_priv *priv)
+static int rtl_mdio_wait_ready(struct rtl_mdio_priv *priv)
{
struct regmap *regmap = priv->regmap;
u32 val;
@@ -92,8 +92,8 @@ static int rtl9300_mdio_wait_ready(struct rtl9300_mdio_priv *priv)
static int rtl9300_mdio_read_c22(struct mii_bus *bus, int phy_id, int regnum)
{
- struct rtl9300_mdio_chan *chan = bus->priv;
- struct rtl9300_mdio_priv *priv;
+ struct rtl_mdio_chan *chan = bus->priv;
+ struct rtl_mdio_priv *priv;
struct regmap *regmap;
int port;
u32 val;
@@ -102,12 +102,12 @@ static int rtl9300_mdio_read_c22(struct mii_bus *bus, int phy_id, int regnum)
priv = chan->priv;
regmap = priv->regmap;
- port = rtl9300_mdio_phy_to_port(bus, phy_id);
+ port = rtl_mdio_phy_to_port(bus, phy_id);
if (port < 0)
return port;
mutex_lock(&priv->lock);
- err = rtl9300_mdio_wait_ready(priv);
+ err = rtl_mdio_wait_ready(priv);
if (err)
goto out_err;
@@ -123,7 +123,7 @@ static int rtl9300_mdio_read_c22(struct mii_bus *bus, int phy_id, int regnum)
if (err)
goto out_err;
- err = rtl9300_mdio_wait_ready(priv);
+ err = rtl_mdio_wait_ready(priv);
if (err)
goto out_err;
@@ -141,8 +141,8 @@ static int rtl9300_mdio_read_c22(struct mii_bus *bus, int phy_id, int regnum)
static int rtl9300_mdio_write_c22(struct mii_bus *bus, int phy_id, int regnum, u16 value)
{
- struct rtl9300_mdio_chan *chan = bus->priv;
- struct rtl9300_mdio_priv *priv;
+ struct rtl_mdio_chan *chan = bus->priv;
+ struct rtl_mdio_priv *priv;
struct regmap *regmap;
int port;
u32 val;
@@ -151,12 +151,12 @@ static int rtl9300_mdio_write_c22(struct mii_bus *bus, int phy_id, int regnum, u
priv = chan->priv;
regmap = priv->regmap;
- port = rtl9300_mdio_phy_to_port(bus, phy_id);
+ port = rtl_mdio_phy_to_port(bus, phy_id);
if (port < 0)
return port;
mutex_lock(&priv->lock);
- err = rtl9300_mdio_wait_ready(priv);
+ err = rtl_mdio_wait_ready(priv);
if (err)
goto out_err;
@@ -196,8 +196,8 @@ static int rtl9300_mdio_write_c22(struct mii_bus *bus, int phy_id, int regnum, u
static int rtl9300_mdio_read_c45(struct mii_bus *bus, int phy_id, int dev_addr, int regnum)
{
- struct rtl9300_mdio_chan *chan = bus->priv;
- struct rtl9300_mdio_priv *priv;
+ struct rtl_mdio_chan *chan = bus->priv;
+ struct rtl_mdio_priv *priv;
struct regmap *regmap;
int port;
u32 val;
@@ -206,12 +206,12 @@ static int rtl9300_mdio_read_c45(struct mii_bus *bus, int phy_id, int dev_addr,
priv = chan->priv;
regmap = priv->regmap;
- port = rtl9300_mdio_phy_to_port(bus, phy_id);
+ port = rtl_mdio_phy_to_port(bus, phy_id);
if (port < 0)
return port;
mutex_lock(&priv->lock);
- err = rtl9300_mdio_wait_ready(priv);
+ err = rtl_mdio_wait_ready(priv);
if (err)
goto out_err;
@@ -231,7 +231,7 @@ static int rtl9300_mdio_read_c45(struct mii_bus *bus, int phy_id, int dev_addr,
if (err)
goto out_err;
- err = rtl9300_mdio_wait_ready(priv);
+ err = rtl_mdio_wait_ready(priv);
if (err)
goto out_err;
@@ -250,8 +250,8 @@ static int rtl9300_mdio_read_c45(struct mii_bus *bus, int phy_id, int dev_addr,
static int rtl9300_mdio_write_c45(struct mii_bus *bus, int phy_id, int dev_addr,
int regnum, u16 value)
{
- struct rtl9300_mdio_chan *chan = bus->priv;
- struct rtl9300_mdio_priv *priv;
+ struct rtl_mdio_chan *chan = bus->priv;
+ struct rtl_mdio_priv *priv;
struct regmap *regmap;
int port;
u32 val;
@@ -260,12 +260,12 @@ static int rtl9300_mdio_write_c45(struct mii_bus *bus, int phy_id, int dev_addr,
priv = chan->priv;
regmap = priv->regmap;
- port = rtl9300_mdio_phy_to_port(bus, phy_id);
+ port = rtl_mdio_phy_to_port(bus, phy_id);
if (port < 0)
return port;
mutex_lock(&priv->lock);
- err = rtl9300_mdio_wait_ready(priv);
+ err = rtl_mdio_wait_ready(priv);
if (err)
goto out_err;
@@ -307,7 +307,7 @@ static int rtl9300_mdio_write_c45(struct mii_bus *bus, int phy_id, int dev_addr,
return err;
}
-static int rtl9300_mdiobus_init(struct rtl9300_mdio_priv *priv)
+static int rtl9300_mdiobus_init(struct rtl_mdio_priv *priv)
{
u32 glb_ctrl_mask = 0, glb_ctrl_val = 0;
struct regmap *regmap = priv->regmap;
@@ -350,10 +350,10 @@ static int rtl9300_mdiobus_init(struct rtl9300_mdio_priv *priv)
return 0;
}
-static int rtl9300_mdiobus_probe_one(struct device *dev, struct rtl9300_mdio_priv *priv,
- struct fwnode_handle *node)
+static int rtl_mdiobus_probe_one(struct device *dev, struct rtl_mdio_priv *priv,
+ struct fwnode_handle *node)
{
- struct rtl9300_mdio_chan *chan;
+ struct rtl_mdio_chan *chan;
struct mii_bus *bus;
u32 mdio_bus;
int err;
@@ -404,9 +404,9 @@ static int rtl9300_mdiobus_probe_one(struct device *dev, struct rtl9300_mdio_pri
* ethernet-ports node and build a mapping of the switch port to MDIO bus/addr
* based on the phy-handle.
*/
-static int rtl9300_mdiobus_map_ports(struct device *dev)
+static int rtl_mdiobus_map_ports(struct device *dev)
{
- struct rtl9300_mdio_priv *priv = dev_get_drvdata(dev);
+ struct rtl_mdio_priv *priv = dev_get_drvdata(dev);
struct device *parent = dev->parent;
int err;
@@ -462,10 +462,10 @@ static int rtl9300_mdiobus_map_ports(struct device *dev)
return 0;
}
-static int rtl9300_mdiobus_probe(struct platform_device *pdev)
+static int rtl_mdiobus_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct rtl9300_mdio_priv *priv;
+ struct rtl_mdio_priv *priv;
int err;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -482,12 +482,12 @@ static int rtl9300_mdiobus_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, priv);
- err = rtl9300_mdiobus_map_ports(dev);
+ err = rtl_mdiobus_map_ports(dev);
if (err)
return err;
device_for_each_child_node_scoped(dev, child) {
- err = rtl9300_mdiobus_probe_one(dev, priv, child);
+ err = rtl_mdiobus_probe_one(dev, priv, child);
if (err)
return err;
}
@@ -499,21 +499,21 @@ static int rtl9300_mdiobus_probe(struct platform_device *pdev)
return 0;
}
-static const struct of_device_id rtl9300_mdio_ids[] = {
+static const struct of_device_id rtl_mdio_ids[] = {
{ .compatible = "realtek,rtl9301-mdio" },
{}
};
-MODULE_DEVICE_TABLE(of, rtl9300_mdio_ids);
+MODULE_DEVICE_TABLE(of, rtl_mdio_ids);
-static struct platform_driver rtl9300_mdio_driver = {
- .probe = rtl9300_mdiobus_probe,
+static struct platform_driver rtl_mdio_driver = {
+ .probe = rtl_mdiobus_probe,
.driver = {
.name = "mdio-rtl9300",
- .of_match_table = rtl9300_mdio_ids,
+ .of_match_table = rtl_mdio_ids,
},
};
-module_platform_driver(rtl9300_mdio_driver);
+module_platform_driver(rtl_mdio_driver);
MODULE_DESCRIPTION("RTL9300 MDIO driver");
MODULE_LICENSE("GPL");
--
2.54.0
^ permalink raw reply related [flat|nested] 26+ messages in thread* Re: [PATCH 1/9] net: mdio: realtek-rtl9300: Convert to generic prefix
2026-05-19 16:57 ` [PATCH 1/9] net: mdio: realtek-rtl9300: Convert to generic prefix Markus Stockhausen
@ 2026-05-19 17:51 ` Andrew Lunn
0 siblings, 0 replies; 26+ messages in thread
From: Andrew Lunn @ 2026-05-19 17:51 UTC (permalink / raw)
To: Markus Stockhausen
Cc: hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel
On Tue, May 19, 2026 at 06:57:39PM +0200, Markus Stockhausen wrote:
> The Realtek MDIO driver currently only serves SOCs from the Realtek
> RTL930x series. This is only one lineup of the Realtek Otto switch
> series that also knows RTL838x, RTL839x, RTL931x devices.
>
> All of these share the same MDIO logic but have individual properties.
> To make clear what is devic specific and what is device independent
> split the function/structure prefix as follows:
>
> - for device specific helpers keep rtl9300_
> - Rename generic functions and structures to rtl_
Renaming makes sense, but maybe rtl_ is too generic. There are other
realtek MDIO implementation which this driver does not support.
How about putting otto into the name? rotto_ or rtlotto_ ?
Andrew
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 2/9] net: mdio: realtek-rtl9300: Add device specific info structure
2026-05-19 16:57 [PATCH 0/9] mdio: realtek-rtl9300: Groundwork for multi SOC support Markus Stockhausen
2026-05-19 16:57 ` [PATCH 1/9] net: mdio: realtek-rtl9300: Convert to generic prefix Markus Stockhausen
@ 2026-05-19 16:57 ` Markus Stockhausen
2026-05-19 16:57 ` [PATCH 3/9] net: mdio: realtek-rtl9300: Add ports to " Markus Stockhausen
` (6 subsequent siblings)
8 siblings, 0 replies; 26+ messages in thread
From: Markus Stockhausen @ 2026-05-19 16:57 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel
Cc: Markus Stockhausen
Device properties of the RTL930x SOCs are hardcoded into the MDIO driver.
This must be relaxed to support additional devices like the RTL838x or
RTL839x. These do not have 4 SMI buses but 1 or 2 instead.
To support multiple devices establish an info structure that contains
individual variations of each series. As a first use case add the number
of buses into this structure and use it where needed.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/mdio-realtek-rtl9300.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
index a3374d5241cb..140e6ac51e2b 100644
--- a/drivers/net/mdio/mdio-realtek-rtl9300.c
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
@@ -48,7 +48,14 @@
#define MAX_SMI_BUSSES 4
#define MAX_SMI_ADDR 0x1f
+#define RTL9300_NUM_BUSES 4
+
+struct rtl_mdio_info {
+ u8 num_buses;
+};
+
struct rtl_mdio_priv {
+ const struct rtl_mdio_info *info;
struct regmap *regmap;
struct mutex lock; /* protect HW access */
DECLARE_BITMAP(valid_ports, MAX_PORTS);
@@ -328,7 +335,7 @@ static int rtl9300_mdiobus_init(struct rtl_mdio_priv *priv)
/* Put the interfaces into C45 mode if required */
glb_ctrl_mask = GENMASK(19, 16);
- for (i = 0; i < MAX_SMI_BUSSES; i++)
+ for (i = 0; i < priv->info->num_buses; i++)
if (priv->smi_bus_is_c45[i])
glb_ctrl_val |= GLB_CTRL_INTF_SEL(i);
@@ -447,7 +454,7 @@ static int rtl_mdiobus_map_ports(struct device *dev)
if (err)
return err;
- if (bus >= MAX_SMI_BUSSES)
+ if (bus >= priv->info->num_buses)
return dev_err_probe(dev, -EINVAL, "illegal smi bus number %d\n", bus);
err = of_property_read_u32(phy_dn, "reg", &addr);
@@ -476,6 +483,7 @@ static int rtl_mdiobus_probe(struct platform_device *pdev)
if (err)
return err;
+ priv->info = device_get_match_data(dev);
priv->regmap = syscon_node_to_regmap(dev->parent->of_node);
if (IS_ERR(priv->regmap))
return PTR_ERR(priv->regmap);
@@ -499,8 +507,12 @@ static int rtl_mdiobus_probe(struct platform_device *pdev)
return 0;
}
+static const struct rtl_mdio_info rtl9300_mdio_info = {
+ .num_buses = RTL9300_NUM_BUSES,
+};
+
static const struct of_device_id rtl_mdio_ids[] = {
- { .compatible = "realtek,rtl9301-mdio" },
+ { .compatible = "realtek,rtl9301-mdio", .data = &rtl9300_mdio_info },
{}
};
MODULE_DEVICE_TABLE(of, rtl_mdio_ids);
--
2.54.0
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 3/9] net: mdio: realtek-rtl9300: Add ports to info structure
2026-05-19 16:57 [PATCH 0/9] mdio: realtek-rtl9300: Groundwork for multi SOC support Markus Stockhausen
2026-05-19 16:57 ` [PATCH 1/9] net: mdio: realtek-rtl9300: Convert to generic prefix Markus Stockhausen
2026-05-19 16:57 ` [PATCH 2/9] net: mdio: realtek-rtl9300: Add device specific info structure Markus Stockhausen
@ 2026-05-19 16:57 ` Markus Stockhausen
2026-05-19 17:27 ` Daniel Golle
2026-05-19 16:57 ` [PATCH 4/9] net: mdio: realtek-rtl9300: Add pages " Markus Stockhausen
` (5 subsequent siblings)
8 siblings, 1 reply; 26+ messages in thread
From: Markus Stockhausen @ 2026-05-19 16:57 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel
Cc: Markus Stockhausen
Each Realtek SOC series has different number of MDIO ports.
Make this configurable by adding a property to the info
structure. Switch the existing usage of MAX_PORTS to this
new property where needed.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/mdio-realtek-rtl9300.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
index 140e6ac51e2b..4533c2f68cab 100644
--- a/drivers/net/mdio/mdio-realtek-rtl9300.c
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
@@ -49,9 +49,11 @@
#define MAX_SMI_ADDR 0x1f
#define RTL9300_NUM_BUSES 4
+#define RTL9300_NUM_PORTS 28
struct rtl_mdio_info {
u8 num_buses;
+ u8 num_ports;
};
struct rtl_mdio_priv {
@@ -78,7 +80,7 @@ static int rtl_mdio_phy_to_port(struct mii_bus *bus, int phy_id)
priv = chan->priv;
- for_each_set_bit(i, priv->valid_ports, MAX_PORTS)
+ for_each_set_bit(i, priv->valid_ports, priv->info->num_ports)
if (priv->smi_bus[i] == chan->mdio_bus &&
priv->smi_addr[i] == phy_id)
return i;
@@ -323,7 +325,7 @@ static int rtl9300_mdiobus_init(struct rtl_mdio_priv *priv)
int i, err;
/* Associate the port with the SMI interface and PHY */
- for_each_set_bit(i, priv->valid_ports, MAX_PORTS) {
+ for_each_set_bit(i, priv->valid_ports, priv->info->num_ports) {
int pos;
pos = (i % 6) * 5;
@@ -444,7 +446,7 @@ static int rtl_mdiobus_map_ports(struct device *dev)
if (err)
return err;
- if (pn >= MAX_PORTS)
+ if (pn >= priv->info->num_ports)
return dev_err_probe(dev, -EINVAL, "illegal port number %d\n", pn);
if (test_bit(pn, priv->valid_ports))
@@ -509,6 +511,7 @@ static int rtl_mdiobus_probe(struct platform_device *pdev)
static const struct rtl_mdio_info rtl9300_mdio_info = {
.num_buses = RTL9300_NUM_BUSES,
+ .num_ports = RTL9300_NUM_PORTS,
};
static const struct of_device_id rtl_mdio_ids[] = {
--
2.54.0
^ permalink raw reply related [flat|nested] 26+ messages in thread* Re: [PATCH 3/9] net: mdio: realtek-rtl9300: Add ports to info structure
2026-05-19 16:57 ` [PATCH 3/9] net: mdio: realtek-rtl9300: Add ports to " Markus Stockhausen
@ 2026-05-19 17:27 ` Daniel Golle
2026-05-19 17:59 ` Andrew Lunn
0 siblings, 1 reply; 26+ messages in thread
From: Daniel Golle @ 2026-05-19 17:27 UTC (permalink / raw)
To: Markus Stockhausen
Cc: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham
On Tue, May 19, 2026 at 06:57:41PM +0200, Markus Stockhausen wrote:
> Each Realtek SOC series has different number of MDIO ports.
I don't think the term "MDIO ports" describes it well.
I'd say "switch ports", also because RTL9300_NUM_PORTS includes ports
used for SFP+ cages which aren't going to be (directly) associated
with any MDIO-connected PHY at all.
> Make this configurable by adding a property to the info
> structure. Switch the existing usage of MAX_PORTS to this
> new property where needed.
>
> Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
> ---
> drivers/net/mdio/mdio-realtek-rtl9300.c | 9 ++++++---
> 1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
> index 140e6ac51e2b..4533c2f68cab 100644
> --- a/drivers/net/mdio/mdio-realtek-rtl9300.c
> +++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
> @@ -49,9 +49,11 @@
> #define MAX_SMI_ADDR 0x1f
>
> #define RTL9300_NUM_BUSES 4
> +#define RTL9300_NUM_PORTS 28
>
> struct rtl_mdio_info {
> u8 num_buses;
> + u8 num_ports;
> };
>
> struct rtl_mdio_priv {
> @@ -78,7 +80,7 @@ static int rtl_mdio_phy_to_port(struct mii_bus *bus, int phy_id)
>
> priv = chan->priv;
>
> - for_each_set_bit(i, priv->valid_ports, MAX_PORTS)
> + for_each_set_bit(i, priv->valid_ports, priv->info->num_ports)
> if (priv->smi_bus[i] == chan->mdio_bus &&
> priv->smi_addr[i] == phy_id)
> return i;
> @@ -323,7 +325,7 @@ static int rtl9300_mdiobus_init(struct rtl_mdio_priv *priv)
> int i, err;
>
> /* Associate the port with the SMI interface and PHY */
> - for_each_set_bit(i, priv->valid_ports, MAX_PORTS) {
> + for_each_set_bit(i, priv->valid_ports, priv->info->num_ports) {
> int pos;
>
> pos = (i % 6) * 5;
> @@ -444,7 +446,7 @@ static int rtl_mdiobus_map_ports(struct device *dev)
> if (err)
> return err;
>
> - if (pn >= MAX_PORTS)
> + if (pn >= priv->info->num_ports)
> return dev_err_probe(dev, -EINVAL, "illegal port number %d\n", pn);
>
> if (test_bit(pn, priv->valid_ports))
> @@ -509,6 +511,7 @@ static int rtl_mdiobus_probe(struct platform_device *pdev)
>
> static const struct rtl_mdio_info rtl9300_mdio_info = {
> .num_buses = RTL9300_NUM_BUSES,
> + .num_ports = RTL9300_NUM_PORTS,
> };
>
> static const struct of_device_id rtl_mdio_ids[] = {
> --
> 2.54.0
>
^ permalink raw reply [flat|nested] 26+ messages in thread* Re: [PATCH 3/9] net: mdio: realtek-rtl9300: Add ports to info structure
2026-05-19 17:27 ` Daniel Golle
@ 2026-05-19 17:59 ` Andrew Lunn
2026-05-19 19:06 ` AW: " Markus Stockhausen
0 siblings, 1 reply; 26+ messages in thread
From: Andrew Lunn @ 2026-05-19 17:59 UTC (permalink / raw)
To: Daniel Golle
Cc: Markus Stockhausen, hkallweit1, linux, davem, edumazet, kuba,
pabeni, netdev, chris.packham
On Tue, May 19, 2026 at 06:27:55PM +0100, Daniel Golle wrote:
> On Tue, May 19, 2026 at 06:57:41PM +0200, Markus Stockhausen wrote:
> > Each Realtek SOC series has different number of MDIO ports.
>
> I don't think the term "MDIO ports" describes it well.
>
> I'd say "switch ports", also because RTL9300_NUM_PORTS includes ports
> used for SFP+ cages which aren't going to be (directly) associated
> with any MDIO-connected PHY at all.
Hi Markus
It would be good to take a step back and explain the concepts here in
the commit message. An MDIO bus as 32 addresses, as defined by
802.3. Why do we need the concept of a port when we have addresses?
Once you explain the concept, we can maybe suggest a better name. Or
throw the whole concept out because it is not needed.
Andrew
^ permalink raw reply [flat|nested] 26+ messages in thread* AW: [PATCH 3/9] net: mdio: realtek-rtl9300: Add ports to info structure
2026-05-19 17:59 ` Andrew Lunn
@ 2026-05-19 19:06 ` Markus Stockhausen
2026-05-19 20:14 ` Andrew Lunn
0 siblings, 1 reply; 26+ messages in thread
From: Markus Stockhausen @ 2026-05-19 19:06 UTC (permalink / raw)
To: 'Andrew Lunn', 'Daniel Golle'
Cc: hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham
Hi Andrew,
> Von: Andrew Lunn <andrew@lunn.ch>
> Gesendet: Dienstag, 19. Mai 2026 20:00
> An: Daniel Golle <daniel@makrotopia.org>
> Betreff: Re: [PATCH 3/9] net: mdio: realtek-rtl9300: Add ports to info
structure
>
> On Tue, May 19, 2026 at 06:27:55PM +0100, Daniel Golle wrote:
> > On Tue, May 19, 2026 at 06:57:41PM +0200, Markus Stockhausen wrote:
> > > Each Realtek SOC series has different number of MDIO ports.
> >
> > I don't think the term "MDIO ports" describes it well.
> >
> > I'd say "switch ports", also because RTL9300_NUM_PORTS includes ports
> > used for SFP+ cages which aren't going to be (directly) associated
> > with any MDIO-connected PHY at all.
>
> Hi Markus
>
> It would be good to take a step back and explain the concepts here in
> the commit message. An MDIO bus as 32 addresses, as defined by
> 802.3. Why do we need the concept of a port when we have addresses?
>
> Once you explain the concept, we can maybe suggest a better name. Or
> throw the whole concept out because it is not needed.
I'm just trying to give the properties in the info structure the right
name that resembles its function. The driver already builds upon
the "port" naming.
Where does this come from?
- The hardware has 1-4 SMI busses
- Each bus serves up to 32 addresses
- A switch has X physical ports
- The mdio controller can only be fed with "physical port"
To make this work:
- port->bus/address hardware mapping registers are set up. [1]
- Driver exposes bus/address to kernel as usual
- During access driver converts bus/address to port [2]
- Driver issues command towards hardware via port
- Hardware maps that back to bus/address
So basically the driver needs an "port-like-index" for all
its operations. Looking at the initial PR history [2] I assume
this design was already hard enough to implement.
Markus
[1]
https://elixir.bootlin.com/linux/v6.18.1/source/drivers/net/mdio/mdio-realte
k-rtl9300.c#L319
[2]
https://elixir.bootlin.com/linux/v6.18.1/source/drivers/net/mdio/mdio-realte
k-rtl9300.c#L66
[3] https://marc.info/?l=linux-netdev&w=2&r=3&s=add+rtl9300+mdio+driver&q=b
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 3/9] net: mdio: realtek-rtl9300: Add ports to info structure
2026-05-19 19:06 ` AW: " Markus Stockhausen
@ 2026-05-19 20:14 ` Andrew Lunn
2026-05-19 20:36 ` AW: " Markus Stockhausen
2026-05-19 22:47 ` Daniel Golle
0 siblings, 2 replies; 26+ messages in thread
From: Andrew Lunn @ 2026-05-19 20:14 UTC (permalink / raw)
To: Markus Stockhausen
Cc: 'Daniel Golle', hkallweit1, linux, davem, edumazet, kuba,
pabeni, netdev, chris.packham
> > Hi Markus
> >
> > It would be good to take a step back and explain the concepts here in
> > the commit message. An MDIO bus as 32 addresses, as defined by
> > 802.3. Why do we need the concept of a port when we have addresses?
> >
> > Once you explain the concept, we can maybe suggest a better name. Or
> > throw the whole concept out because it is not needed.
>
> I'm just trying to give the properties in the info structure the right
> name that resembles its function. The driver already builds upon
> the "port" naming.
>
> Where does this come from?
>
> - The hardware has 1-4 SMI busses
> - Each bus serves up to 32 addresses
> - A switch has X physical ports
> - The mdio controller can only be fed with "physical port"
So in general, the MDIO API uses an address in the range 0-31, as
defined in C22/C45. I would try to do any sort of mapping of ports to
MDIO addresses in a layer above MDIO. Maybe that is not possible, i
only partially remember the discussion about this hardware. But if it
is going to get more complex, i really would suggest pulling it out
into a layer above, and let the MDIO driver simply do MDIO.
Andrew
^ permalink raw reply [flat|nested] 26+ messages in thread
* AW: [PATCH 3/9] net: mdio: realtek-rtl9300: Add ports to info structure
2026-05-19 20:14 ` Andrew Lunn
@ 2026-05-19 20:36 ` Markus Stockhausen
2026-05-19 22:47 ` Daniel Golle
1 sibling, 0 replies; 26+ messages in thread
From: Markus Stockhausen @ 2026-05-19 20:36 UTC (permalink / raw)
To: 'Andrew Lunn'
Cc: 'Daniel Golle', hkallweit1, linux, davem, edumazet, kuba,
pabeni, netdev, chris.packham
> Von: Andrew Lunn <andrew@lunn.ch>
> Gesendet: Dienstag, 19. Mai 2026 22:14
> An: Markus Stockhausen <markus.stockhausen@gmx.de>
> Betreff: Re: [PATCH 3/9] net: mdio: realtek-rtl9300: Add ports to info
structure
> .
> > Where does this come from?
> >
> > - The hardware has 1-4 SMI busses
> > - Each bus serves up to 32 addresses
> > - A switch has X physical ports
> > - The mdio controller can only be fed with "physical port"
>
> So in general, the MDIO API uses an address in the range 0-31, as
> defined in C22/C45. I would try to do any sort of mapping of ports to
> MDIO addresses in a layer above MDIO. Maybe that is not possible, i
> only partially remember the discussion about this hardware. But if it
> is going to get more complex, i really would suggest pulling it out
> into a layer above, and let the MDIO driver simply do MDIO.
Having spent a few months to get all this sorted out I can
say that the port concept is quite easy to understand and
is already quite simple implemented. One only needs to know
the chain
bus/address -> port -> bus/address
Current upstream codes uses 220 lines of code for only one
target. Downstream serves 4 devices with same quality and
error handling with the following metrics:
- 80 lines of code for central command runner
- 160 lines for all 16 SOC specific read/read_c45/write/write_c45 functions
- 80 lines of code for 4 generic command feeder functions
I finally want to add myself as maintainer for the driver.
Just in case that helps for the descision.
Markus
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 3/9] net: mdio: realtek-rtl9300: Add ports to info structure
2026-05-19 20:14 ` Andrew Lunn
2026-05-19 20:36 ` AW: " Markus Stockhausen
@ 2026-05-19 22:47 ` Daniel Golle
2026-05-20 1:09 ` Andrew Lunn
1 sibling, 1 reply; 26+ messages in thread
From: Daniel Golle @ 2026-05-19 22:47 UTC (permalink / raw)
To: Andrew Lunn
Cc: Markus Stockhausen, hkallweit1, linux, davem, edumazet, kuba,
pabeni, netdev, chris.packham
On Tue, May 19, 2026 at 10:14:24PM +0200, Andrew Lunn wrote:
> > > Hi Markus
> > >
> > > It would be good to take a step back and explain the concepts here in
> > > the commit message. An MDIO bus as 32 addresses, as defined by
> > > 802.3. Why do we need the concept of a port when we have addresses?
> > >
> > > Once you explain the concept, we can maybe suggest a better name. Or
> > > throw the whole concept out because it is not needed.
> >
> > I'm just trying to give the properties in the info structure the right
> > name that resembles its function. The driver already builds upon
> > the "port" naming.
> >
> > Where does this come from?
> >
> > - The hardware has 1-4 SMI busses
> > - Each bus serves up to 32 addresses
> > - A switch has X physical ports
> > - The mdio controller can only be fed with "physical port"
>
> So in general, the MDIO API uses an address in the range 0-31, as
> defined in C22/C45. I would try to do any sort of mapping of ports to
> MDIO addresses in a layer above MDIO. Maybe that is not possible, i
> only partially remember the discussion about this hardware. But if it
> is going to get more complex, i really would suggest pulling it out
> into a layer above, and let the MDIO driver simply do MDIO.
The problem is that the hardware doesn't let you access the MDIO
busses directly -- you *have to* setup a mapping and then access each
PHY using the mapped port index. Also hardware PHY polling *has* to be
used to configure the MAC as there is no (known) way to directly
configure most of the MACs (but only a small number which is typically
used for SFPs), so setting up the mapping also for that is mandatory
and cannot be avoided.
The driver does it's best to present MDIO busses with the PHYs available
with their actual (ie. as on the hardware) addresses 0-31 towards Linux,
so PHY drivers, packages or even userland tools all work as expected.
But internally it will have to setup this mapping port->(bus, phy), and
then reverse-resolve each (bus, phy)->port.
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 3/9] net: mdio: realtek-rtl9300: Add ports to info structure
2026-05-19 22:47 ` Daniel Golle
@ 2026-05-20 1:09 ` Andrew Lunn
[not found] ` <10121615-6F47-2A48-825A-0AC1E0C0F0C1@hxcore.ol>
0 siblings, 1 reply; 26+ messages in thread
From: Andrew Lunn @ 2026-05-20 1:09 UTC (permalink / raw)
To: Daniel Golle
Cc: Markus Stockhausen, hkallweit1, linux, davem, edumazet, kuba,
pabeni, netdev, chris.packham
> The problem is that the hardware doesn't let you access the MDIO
> busses directly -- you *have to* setup a mapping and then access each
> PHY using the mapped port index. Also hardware PHY polling *has* to be
> used to configure the MAC as there is no (known) way to directly
> configure most of the MACs (but only a small number which is typically
> used for SFPs), so setting up the mapping also for that is mandatory
> and cannot be avoided.
>
> The driver does it's best to present MDIO busses with the PHYs available
> with their actual (ie. as on the hardware) addresses 0-31 towards Linux,
> so PHY drivers, packages or even userland tools all work as expected.
> But internally it will have to setup this mapping port->(bus, phy), and
> then reverse-resolve each (bus, phy)->port.
Do any of these MDIO busses appear on the outside? Somewhere i can
connect an external PHY, or another switch in cascade?
Andrew
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 4/9] net: mdio: realtek-rtl9300: Add pages to info structure
2026-05-19 16:57 [PATCH 0/9] mdio: realtek-rtl9300: Groundwork for multi SOC support Markus Stockhausen
` (2 preceding siblings ...)
2026-05-19 16:57 ` [PATCH 3/9] net: mdio: realtek-rtl9300: Add ports to " Markus Stockhausen
@ 2026-05-19 16:57 ` Markus Stockhausen
2026-05-19 17:29 ` Daniel Golle
2026-05-19 18:07 ` Andrew Lunn
2026-05-19 16:57 ` [PATCH 5/9] net: mdio: realtek-rtl9300: Add register structure Markus Stockhausen
` (4 subsequent siblings)
8 siblings, 2 replies; 26+ messages in thread
From: Markus Stockhausen @ 2026-05-19 16:57 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel
Cc: Markus Stockhausen
The Realtek MDIO controller has a paging feature that allows to run C22
reads/writes in one turn. At least this holds true for attached Realtek
based PHYs. The controller is given the page, the register and the data
and it runs all the page switching in the background in hardware.
There is however one special page that allows to pass through all C22
commands directly to the PHY - without any caching. This so called raw
page is dependent of the hardware. It is the highest supported page
number minus 1. This is either 4095 for low port count SOCs (up to 28
ports) or 8191 for high port count SOCs (up to 56 ports).
Provide the number of supported pages as a device specific property.
The raw page directly derives from that as "num_pages - 1". Make use
of it where needed.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/mdio-realtek-rtl9300.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
index 4533c2f68cab..0ea691d9fc1b 100644
--- a/drivers/net/mdio/mdio-realtek-rtl9300.c
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
@@ -47,13 +47,16 @@
#define MAX_PORTS 28
#define MAX_SMI_BUSSES 4
#define MAX_SMI_ADDR 0x1f
+#define RAW_PAGE(x) ((x) - 1)
#define RTL9300_NUM_BUSES 4
+#define RTL9300_NUM_PAGES 4096
#define RTL9300_NUM_PORTS 28
struct rtl_mdio_info {
u8 num_buses;
u8 num_ports;
+ u16 num_pages;
};
struct rtl_mdio_priv {
@@ -126,7 +129,7 @@ static int rtl9300_mdio_read_c22(struct mii_bus *bus, int phy_id, int regnum)
val = FIELD_PREP(PHY_CTRL_REG_ADDR, regnum) |
FIELD_PREP(PHY_CTRL_PARK_PAGE, 0x1f) |
- FIELD_PREP(PHY_CTRL_MAIN_PAGE, 0xfff) |
+ FIELD_PREP(PHY_CTRL_MAIN_PAGE, RAW_PAGE(priv->info->num_pages)) |
PHY_CTRL_READ | PHY_CTRL_TYPE_C22 | PHY_CTRL_CMD;
err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_1, val);
if (err)
@@ -179,7 +182,7 @@ static int rtl9300_mdio_write_c22(struct mii_bus *bus, int phy_id, int regnum, u
val = FIELD_PREP(PHY_CTRL_REG_ADDR, regnum) |
FIELD_PREP(PHY_CTRL_PARK_PAGE, 0x1f) |
- FIELD_PREP(PHY_CTRL_MAIN_PAGE, 0xfff) |
+ FIELD_PREP(PHY_CTRL_MAIN_PAGE, RAW_PAGE(priv->info->num_pages)) |
PHY_CTRL_WRITE | PHY_CTRL_TYPE_C22 | PHY_CTRL_CMD;
err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_1, val);
if (err)
@@ -512,6 +515,7 @@ static int rtl_mdiobus_probe(struct platform_device *pdev)
static const struct rtl_mdio_info rtl9300_mdio_info = {
.num_buses = RTL9300_NUM_BUSES,
.num_ports = RTL9300_NUM_PORTS,
+ .num_pages = RTL9300_NUM_PAGES,
};
static const struct of_device_id rtl_mdio_ids[] = {
--
2.54.0
^ permalink raw reply related [flat|nested] 26+ messages in thread* Re: [PATCH 4/9] net: mdio: realtek-rtl9300: Add pages to info structure
2026-05-19 16:57 ` [PATCH 4/9] net: mdio: realtek-rtl9300: Add pages " Markus Stockhausen
@ 2026-05-19 17:29 ` Daniel Golle
2026-05-19 18:07 ` Andrew Lunn
1 sibling, 0 replies; 26+ messages in thread
From: Daniel Golle @ 2026-05-19 17:29 UTC (permalink / raw)
To: Markus Stockhausen
Cc: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham
On Tue, May 19, 2026 at 06:57:42PM +0200, Markus Stockhausen wrote:
> The Realtek MDIO controller has a paging feature that allows to run C22
> reads/writes in one turn. At least this holds true for attached Realtek
> based PHYs. The controller is given the page, the register and the data
> and it runs all the page switching in the background in hardware.
>
> There is however one special page that allows to pass through all C22
> commands directly to the PHY - without any caching. This so called raw
> page is dependent of the hardware. It is the highest supported page
> number minus 1. This is either 4095 for low port count SOCs (up to 28
> ports) or 8191 for high port count SOCs (up to 56 ports).
>
> Provide the number of supported pages as a device specific property.
> The raw page directly derives from that as "num_pages - 1". Make use
> of it where needed.
>
> Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
> ---
> drivers/net/mdio/mdio-realtek-rtl9300.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
> index 4533c2f68cab..0ea691d9fc1b 100644
> --- a/drivers/net/mdio/mdio-realtek-rtl9300.c
> +++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
> @@ -47,13 +47,16 @@
> #define MAX_PORTS 28
> #define MAX_SMI_BUSSES 4
> #define MAX_SMI_ADDR 0x1f
> +#define RAW_PAGE(x) ((x) - 1)
Maybe use
#define RAW_PAGE(priv) ((priv)->info->num_pages - 1)
as anyway you are only calling it in that way.
>
> #define RTL9300_NUM_BUSES 4
> +#define RTL9300_NUM_PAGES 4096
> #define RTL9300_NUM_PORTS 28
>
> struct rtl_mdio_info {
> u8 num_buses;
> u8 num_ports;
> + u16 num_pages;
> };
>
> struct rtl_mdio_priv {
> @@ -126,7 +129,7 @@ static int rtl9300_mdio_read_c22(struct mii_bus *bus, int phy_id, int regnum)
>
> val = FIELD_PREP(PHY_CTRL_REG_ADDR, regnum) |
> FIELD_PREP(PHY_CTRL_PARK_PAGE, 0x1f) |
> - FIELD_PREP(PHY_CTRL_MAIN_PAGE, 0xfff) |
> + FIELD_PREP(PHY_CTRL_MAIN_PAGE, RAW_PAGE(priv->info->num_pages)) |
> PHY_CTRL_READ | PHY_CTRL_TYPE_C22 | PHY_CTRL_CMD;
> err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_1, val);
> if (err)
> @@ -179,7 +182,7 @@ static int rtl9300_mdio_write_c22(struct mii_bus *bus, int phy_id, int regnum, u
>
> val = FIELD_PREP(PHY_CTRL_REG_ADDR, regnum) |
> FIELD_PREP(PHY_CTRL_PARK_PAGE, 0x1f) |
> - FIELD_PREP(PHY_CTRL_MAIN_PAGE, 0xfff) |
> + FIELD_PREP(PHY_CTRL_MAIN_PAGE, RAW_PAGE(priv->info->num_pages)) |
> PHY_CTRL_WRITE | PHY_CTRL_TYPE_C22 | PHY_CTRL_CMD;
> err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_1, val);
> if (err)
> @@ -512,6 +515,7 @@ static int rtl_mdiobus_probe(struct platform_device *pdev)
> static const struct rtl_mdio_info rtl9300_mdio_info = {
> .num_buses = RTL9300_NUM_BUSES,
> .num_ports = RTL9300_NUM_PORTS,
> + .num_pages = RTL9300_NUM_PAGES,
> };
>
> static const struct of_device_id rtl_mdio_ids[] = {
> --
> 2.54.0
>
^ permalink raw reply [flat|nested] 26+ messages in thread* Re: [PATCH 4/9] net: mdio: realtek-rtl9300: Add pages to info structure
2026-05-19 16:57 ` [PATCH 4/9] net: mdio: realtek-rtl9300: Add pages " Markus Stockhausen
2026-05-19 17:29 ` Daniel Golle
@ 2026-05-19 18:07 ` Andrew Lunn
1 sibling, 0 replies; 26+ messages in thread
From: Andrew Lunn @ 2026-05-19 18:07 UTC (permalink / raw)
To: Markus Stockhausen
Cc: hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel
On Tue, May 19, 2026 at 06:57:42PM +0200, Markus Stockhausen wrote:
> The Realtek MDIO controller has a paging feature that allows to run C22
> reads/writes in one turn.
You need to be careful with the wording here. C22 has no concept of
pages. Pages is a vendor concept not an 802.3 Clause 22 concept.
> At least this holds true for attached Realtek
> based PHYs.
And this makes the point.
< The controller is given the page, the register and the data
> and it runs all the page switching in the background in hardware.
> There is however one special page that allows to pass through all C22
> commands directly to the PHY - without any caching. This so called raw
> page is dependent of the hardware. It is the highest supported page
> number minus 1. This is either 4095 for low port count SOCs (up to 28
> ports) or 8191 for high port count SOCs (up to 56 ports).
>
> Provide the number of supported pages as a device specific property.
> The raw page directly derives from that as "num_pages - 1". Make use
> of it where needed.
I've not looked at the other commits yet, but i assume that in order
to not break the Linux model, every access goes through this raw
page. So why have the number of pages when all you need it to know the
raw page number?
Andrew
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 5/9] net: mdio: realtek-rtl9300: Add register structure
2026-05-19 16:57 [PATCH 0/9] mdio: realtek-rtl9300: Groundwork for multi SOC support Markus Stockhausen
` (3 preceding siblings ...)
2026-05-19 16:57 ` [PATCH 4/9] net: mdio: realtek-rtl9300: Add pages " Markus Stockhausen
@ 2026-05-19 16:57 ` Markus Stockhausen
2026-05-19 16:57 ` [PATCH 6/9] net: mdio: realtek-rtl9300: Add command/C22 register Markus Stockhausen
` (3 subsequent siblings)
8 siblings, 0 replies; 26+ messages in thread
From: Markus Stockhausen @ 2026-05-19 16:57 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel
Cc: Markus Stockhausen
The MDIO controller of the Realtek Otto switches has either 4 or 7 command
registers. This depends on the number of supported ports. These registers
are "scattered" around the MMIO block and their addresses depend on the
specific model.
Nevertheless all command registers share a common pattern:
- A mask register with one bit per addressed port
- A I/O data register that transfers the to be read/written data
- A C45 registers that takes devnum and regnum
- A C22 register (page/register) that also includes run/status bits
Provide an additional structure for these command registers so it can be
reused in two places.
1. For defining the register addresses in the regmap.
2. For defining the to be read/written data
This will ultimately result in access patterns like
static int rtl_run_cmd(u32 cmd, struct rtl_mdio_cmd_regs *cmd_regs, ...)
{
regmap_write(regmap, priv->info->reg->cmd_regs.c45_data,
cmd_regs->c45_data);
...
}
static int rtl9300_write_c45(...)
{
struct rtl_mdio_cmd_regs cmd_regs = {
.c45_data = ...
.io_data = ...,
.mask = ...,
};
return rtl_run_cmd(RTL9300_CMD_WRITE_C45, &cmd_regs, ...);
}
As a first step start with the C45 register.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/mdio-realtek-rtl9300.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
index 0ea691d9fc1b..e382f57b7738 100644
--- a/drivers/net/mdio/mdio-realtek-rtl9300.c
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
@@ -39,7 +39,7 @@
#define SMI_ACCESS_PHY_CTRL_2 0xcb78
#define PHY_CTRL_INDATA GENMASK(31, 16)
#define PHY_CTRL_DATA GENMASK(15, 0)
-#define SMI_ACCESS_PHY_CTRL_3 0xcb7c
+#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 SMI_PORT0_5_ADDR_CTRL 0xcb80
@@ -53,7 +53,12 @@
#define RTL9300_NUM_PAGES 4096
#define RTL9300_NUM_PORTS 28
+struct rtl_mdio_cmd_regs {
+ u32 c45_data;
+};
+
struct rtl_mdio_info {
+ struct rtl_mdio_cmd_regs cmd_regs;
u8 num_buses;
u8 num_ports;
u16 num_pages;
@@ -234,7 +239,7 @@ static int rtl9300_mdio_read_c45(struct mii_bus *bus, int phy_id, int dev_addr,
val = FIELD_PREP(PHY_CTRL_MMD_DEVAD, dev_addr) |
FIELD_PREP(PHY_CTRL_MMD_REG, regnum);
- err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_3, val);
+ err = regmap_write(regmap, priv->info->cmd_regs.c45_data, val);
if (err)
goto out_err;
@@ -292,7 +297,7 @@ static int rtl9300_mdio_write_c45(struct mii_bus *bus, int phy_id, int dev_addr,
val = FIELD_PREP(PHY_CTRL_MMD_DEVAD, dev_addr) |
FIELD_PREP(PHY_CTRL_MMD_REG, regnum);
- err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_3, val);
+ err = regmap_write(regmap, priv->info->cmd_regs.c45_data, val);
if (err)
goto out_err;
@@ -513,6 +518,9 @@ static int rtl_mdiobus_probe(struct platform_device *pdev)
}
static const struct rtl_mdio_info rtl9300_mdio_info = {
+ .cmd_regs = {
+ .c45_data = RTL9300_SMI_ACCESS_PHY_CTRL_3,
+ },
.num_buses = RTL9300_NUM_BUSES,
.num_ports = RTL9300_NUM_PORTS,
.num_pages = RTL9300_NUM_PAGES,
--
2.54.0
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 6/9] net: mdio: realtek-rtl9300: Add command/C22 register
2026-05-19 16:57 [PATCH 0/9] mdio: realtek-rtl9300: Groundwork for multi SOC support Markus Stockhausen
` (4 preceding siblings ...)
2026-05-19 16:57 ` [PATCH 5/9] net: mdio: realtek-rtl9300: Add register structure Markus Stockhausen
@ 2026-05-19 16:57 ` Markus Stockhausen
2026-05-19 16:57 ` [PATCH 7/9] net: mdio: realtek-rtl9300: Add I/O register Markus Stockhausen
` (2 subsequent siblings)
8 siblings, 0 replies; 26+ messages in thread
From: Markus Stockhausen @ 2026-05-19 16:57 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel
Cc: Markus Stockhausen
Command issuing/status bits and C22 data share the same register. In the
future the number of places where this register is used will be:
- 1 command runner
- 16 individual read/write/read_c45/read_c45 functions
So name the register c22_data to align with the existing c45_data
register and add it to the register structure. Make use of it
where needed.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/mdio-realtek-rtl9300.c | 38 +++++++++++++------------
1 file changed, 20 insertions(+), 18 deletions(-)
diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
index e382f57b7738..855c7935617f 100644
--- a/drivers/net/mdio/mdio-realtek-rtl9300.c
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
@@ -26,7 +26,7 @@
#define GLB_CTRL_INTF_SEL(intf) BIT(16 + (intf))
#define SMI_PORT0_15_POLLING_SEL 0xca08
#define SMI_ACCESS_PHY_CTRL_0 0xcb70
-#define SMI_ACCESS_PHY_CTRL_1 0xcb74
+#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)
@@ -54,6 +54,7 @@
#define RTL9300_NUM_PORTS 28
struct rtl_mdio_cmd_regs {
+ u32 c22_data;
u32 c45_data;
};
@@ -99,12 +100,12 @@ static int rtl_mdio_phy_to_port(struct mii_bus *bus, int phy_id)
static int rtl_mdio_wait_ready(struct rtl_mdio_priv *priv)
{
struct regmap *regmap = priv->regmap;
- u32 val;
+ u32 cmd_reg, val;
+ cmd_reg = priv->info->cmd_regs.c22_data; /* shared command/C22 register */
lockdep_assert_held(&priv->lock);
- return regmap_read_poll_timeout(regmap, SMI_ACCESS_PHY_CTRL_1,
- val, !(val & PHY_CTRL_CMD), 10, 1000);
+ return regmap_read_poll_timeout(regmap, cmd_reg, val, !(val & PHY_CTRL_CMD), 10, 1000);
}
static int rtl9300_mdio_read_c22(struct mii_bus *bus, int phy_id, int regnum)
@@ -112,12 +113,13 @@ static int rtl9300_mdio_read_c22(struct mii_bus *bus, int phy_id, int regnum)
struct rtl_mdio_chan *chan = bus->priv;
struct rtl_mdio_priv *priv;
struct regmap *regmap;
+ u32 cmd_reg, val;
int port;
- u32 val;
int err;
priv = chan->priv;
regmap = priv->regmap;
+ cmd_reg = priv->info->cmd_regs.c22_data; /* shared command/C22 register */
port = rtl_mdio_phy_to_port(bus, phy_id);
if (port < 0)
@@ -136,7 +138,7 @@ static int rtl9300_mdio_read_c22(struct mii_bus *bus, int phy_id, int regnum)
FIELD_PREP(PHY_CTRL_PARK_PAGE, 0x1f) |
FIELD_PREP(PHY_CTRL_MAIN_PAGE, RAW_PAGE(priv->info->num_pages)) |
PHY_CTRL_READ | PHY_CTRL_TYPE_C22 | PHY_CTRL_CMD;
- err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_1, val);
+ err = regmap_write(regmap, cmd_reg, val);
if (err)
goto out_err;
@@ -161,12 +163,13 @@ static int rtl9300_mdio_write_c22(struct mii_bus *bus, int phy_id, int regnum, u
struct rtl_mdio_chan *chan = bus->priv;
struct rtl_mdio_priv *priv;
struct regmap *regmap;
+ u32 cmd_reg, val;
int port;
- u32 val;
int err;
priv = chan->priv;
regmap = priv->regmap;
+ cmd_reg = priv->info->cmd_regs.c22_data; /* shared command/C22 register */
port = rtl_mdio_phy_to_port(bus, phy_id);
if (port < 0)
@@ -189,12 +192,11 @@ static int rtl9300_mdio_write_c22(struct mii_bus *bus, int phy_id, int regnum, u
FIELD_PREP(PHY_CTRL_PARK_PAGE, 0x1f) |
FIELD_PREP(PHY_CTRL_MAIN_PAGE, RAW_PAGE(priv->info->num_pages)) |
PHY_CTRL_WRITE | PHY_CTRL_TYPE_C22 | PHY_CTRL_CMD;
- err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_1, val);
+ err = regmap_write(regmap, cmd_reg, val);
if (err)
goto out_err;
- err = regmap_read_poll_timeout(regmap, SMI_ACCESS_PHY_CTRL_1,
- val, !(val & PHY_CTRL_CMD), 10, 100);
+ err = regmap_read_poll_timeout(regmap, cmd_reg, val, !(val & PHY_CTRL_CMD), 10, 100);
if (err)
goto out_err;
@@ -216,12 +218,13 @@ static int rtl9300_mdio_read_c45(struct mii_bus *bus, int phy_id, int dev_addr,
struct rtl_mdio_chan *chan = bus->priv;
struct rtl_mdio_priv *priv;
struct regmap *regmap;
+ u32 cmd_reg, val;
int port;
- u32 val;
int err;
priv = chan->priv;
regmap = priv->regmap;
+ cmd_reg = priv->info->cmd_regs.c22_data; /* shared command/C22 register */
port = rtl_mdio_phy_to_port(bus, phy_id);
if (port < 0)
@@ -243,8 +246,7 @@ static int rtl9300_mdio_read_c45(struct mii_bus *bus, int phy_id, int dev_addr,
if (err)
goto out_err;
- err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_1,
- PHY_CTRL_READ | PHY_CTRL_TYPE_C45 | PHY_CTRL_CMD);
+ err = regmap_write(regmap, cmd_reg, PHY_CTRL_READ | PHY_CTRL_TYPE_C45 | PHY_CTRL_CMD);
if (err)
goto out_err;
@@ -270,12 +272,13 @@ static int rtl9300_mdio_write_c45(struct mii_bus *bus, int phy_id, int dev_addr,
struct rtl_mdio_chan *chan = bus->priv;
struct rtl_mdio_priv *priv;
struct regmap *regmap;
+ u32 cmd_reg, val;
int port;
- u32 val;
int err;
priv = chan->priv;
regmap = priv->regmap;
+ cmd_reg = priv->info->cmd_regs.c22_data; /* shared command/C22 register */
port = rtl_mdio_phy_to_port(bus, phy_id);
if (port < 0)
@@ -301,13 +304,11 @@ static int rtl9300_mdio_write_c45(struct mii_bus *bus, int phy_id, int dev_addr,
if (err)
goto out_err;
- err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_1,
- PHY_CTRL_TYPE_C45 | PHY_CTRL_WRITE | PHY_CTRL_CMD);
+ err = regmap_write(regmap, cmd_reg, PHY_CTRL_TYPE_C45 | PHY_CTRL_WRITE | PHY_CTRL_CMD);
if (err)
goto out_err;
- err = regmap_read_poll_timeout(regmap, SMI_ACCESS_PHY_CTRL_1,
- val, !(val & PHY_CTRL_CMD), 10, 100);
+ err = regmap_read_poll_timeout(regmap, cmd_reg, val, !(val & PHY_CTRL_CMD), 10, 100);
if (err)
goto out_err;
@@ -519,6 +520,7 @@ static int rtl_mdiobus_probe(struct platform_device *pdev)
static const struct rtl_mdio_info rtl9300_mdio_info = {
.cmd_regs = {
+ .c22_data = RTL9300_SMI_ACCESS_PHY_CTRL_1,
.c45_data = RTL9300_SMI_ACCESS_PHY_CTRL_3,
},
.num_buses = RTL9300_NUM_BUSES,
--
2.54.0
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 7/9] net: mdio: realtek-rtl9300: Add I/O register
2026-05-19 16:57 [PATCH 0/9] mdio: realtek-rtl9300: Groundwork for multi SOC support Markus Stockhausen
` (5 preceding siblings ...)
2026-05-19 16:57 ` [PATCH 6/9] net: mdio: realtek-rtl9300: Add command/C22 register Markus Stockhausen
@ 2026-05-19 16:57 ` Markus Stockhausen
2026-05-19 16:57 ` [PATCH 8/9] net: mdio: realtek-rtl9300: Add mask register Markus Stockhausen
2026-05-19 16:57 ` [PATCH 9/9] net: mdio: realtek-rtl9300: Link I/O functions in info structure Markus Stockhausen
8 siblings, 0 replies; 26+ messages in thread
From: Markus Stockhausen @ 2026-05-19 16:57 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel
Cc: Markus Stockhausen
The MDIO data that needs to be written or read is handled by an I/O
register. Add that to the register structure and make use of it where
needed.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/mdio-realtek-rtl9300.c | 28 +++++++++++++++----------
1 file changed, 17 insertions(+), 11 deletions(-)
diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
index 855c7935617f..be6a0cfe4bb8 100644
--- a/drivers/net/mdio/mdio-realtek-rtl9300.c
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
@@ -36,7 +36,7 @@
#define PHY_CTRL_TYPE_C22 0
#define PHY_CTRL_CMD BIT(0)
#define PHY_CTRL_FAIL BIT(25)
-#define SMI_ACCESS_PHY_CTRL_2 0xcb78
+#define RTL9300_SMI_ACCESS_PHY_CTRL_2 0xcb78
#define PHY_CTRL_INDATA GENMASK(31, 16)
#define PHY_CTRL_DATA GENMASK(15, 0)
#define RTL9300_SMI_ACCESS_PHY_CTRL_3 0xcb7c
@@ -56,6 +56,7 @@
struct rtl_mdio_cmd_regs {
u32 c22_data;
u32 c45_data;
+ u32 io_data;
};
struct rtl_mdio_info {
@@ -112,13 +113,14 @@ static int rtl9300_mdio_read_c22(struct mii_bus *bus, int phy_id, int regnum)
{
struct rtl_mdio_chan *chan = bus->priv;
struct rtl_mdio_priv *priv;
+ u32 io_reg, cmd_reg, val;
struct regmap *regmap;
- u32 cmd_reg, val;
int port;
int err;
priv = chan->priv;
regmap = priv->regmap;
+ io_reg = priv->info->cmd_regs.io_data;
cmd_reg = priv->info->cmd_regs.c22_data; /* shared command/C22 register */
port = rtl_mdio_phy_to_port(bus, phy_id);
@@ -130,7 +132,7 @@ static int rtl9300_mdio_read_c22(struct mii_bus *bus, int phy_id, int regnum)
if (err)
goto out_err;
- err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_2, FIELD_PREP(PHY_CTRL_INDATA, port));
+ err = regmap_write(regmap, io_reg, FIELD_PREP(PHY_CTRL_INDATA, port));
if (err)
goto out_err;
@@ -146,7 +148,7 @@ static int rtl9300_mdio_read_c22(struct mii_bus *bus, int phy_id, int regnum)
if (err)
goto out_err;
- err = regmap_read(regmap, SMI_ACCESS_PHY_CTRL_2, &val);
+ err = regmap_read(regmap, io_reg, &val);
if (err)
goto out_err;
@@ -162,13 +164,14 @@ static int rtl9300_mdio_write_c22(struct mii_bus *bus, int phy_id, int regnum, u
{
struct rtl_mdio_chan *chan = bus->priv;
struct rtl_mdio_priv *priv;
+ u32 io_reg, cmd_reg, val;
struct regmap *regmap;
- u32 cmd_reg, val;
int port;
int err;
priv = chan->priv;
regmap = priv->regmap;
+ io_reg = priv->info->cmd_regs.io_data;
cmd_reg = priv->info->cmd_regs.c22_data; /* shared command/C22 register */
port = rtl_mdio_phy_to_port(bus, phy_id);
@@ -184,7 +187,7 @@ static int rtl9300_mdio_write_c22(struct mii_bus *bus, int phy_id, int regnum, u
if (err)
goto out_err;
- err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_2, FIELD_PREP(PHY_CTRL_INDATA, value));
+ err = regmap_write(regmap, io_reg, FIELD_PREP(PHY_CTRL_INDATA, value));
if (err)
goto out_err;
@@ -217,13 +220,14 @@ static int rtl9300_mdio_read_c45(struct mii_bus *bus, int phy_id, int dev_addr,
{
struct rtl_mdio_chan *chan = bus->priv;
struct rtl_mdio_priv *priv;
+ u32 io_reg, cmd_reg, val;
struct regmap *regmap;
- u32 cmd_reg, val;
int port;
int err;
priv = chan->priv;
regmap = priv->regmap;
+ io_reg = priv->info->cmd_regs.io_data;
cmd_reg = priv->info->cmd_regs.c22_data; /* shared command/C22 register */
port = rtl_mdio_phy_to_port(bus, phy_id);
@@ -236,7 +240,7 @@ static int rtl9300_mdio_read_c45(struct mii_bus *bus, int phy_id, int dev_addr,
goto out_err;
val = FIELD_PREP(PHY_CTRL_INDATA, port);
- err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_2, val);
+ err = regmap_write(regmap, io_reg, val);
if (err)
goto out_err;
@@ -254,7 +258,7 @@ static int rtl9300_mdio_read_c45(struct mii_bus *bus, int phy_id, int dev_addr,
if (err)
goto out_err;
- err = regmap_read(regmap, SMI_ACCESS_PHY_CTRL_2, &val);
+ err = regmap_read(regmap, io_reg, &val);
if (err)
goto out_err;
@@ -271,13 +275,14 @@ static int rtl9300_mdio_write_c45(struct mii_bus *bus, int phy_id, int dev_addr,
{
struct rtl_mdio_chan *chan = bus->priv;
struct rtl_mdio_priv *priv;
+ u32 io_reg, cmd_reg, val;
struct regmap *regmap;
- u32 cmd_reg, val;
int port;
int err;
priv = chan->priv;
regmap = priv->regmap;
+ io_reg = priv->info->cmd_regs.io_data;
cmd_reg = priv->info->cmd_regs.c22_data; /* shared command/C22 register */
port = rtl_mdio_phy_to_port(bus, phy_id);
@@ -294,7 +299,7 @@ static int rtl9300_mdio_write_c45(struct mii_bus *bus, int phy_id, int dev_addr,
goto out_err;
val = FIELD_PREP(PHY_CTRL_INDATA, value);
- err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_2, val);
+ err = regmap_write(regmap, io_reg, val);
if (err)
goto out_err;
@@ -522,6 +527,7 @@ static const struct rtl_mdio_info rtl9300_mdio_info = {
.cmd_regs = {
.c22_data = RTL9300_SMI_ACCESS_PHY_CTRL_1,
.c45_data = RTL9300_SMI_ACCESS_PHY_CTRL_3,
+ .io_data = RTL9300_SMI_ACCESS_PHY_CTRL_2,
},
.num_buses = RTL9300_NUM_BUSES,
.num_ports = RTL9300_NUM_PORTS,
--
2.54.0
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 8/9] net: mdio: realtek-rtl9300: Add mask register
2026-05-19 16:57 [PATCH 0/9] mdio: realtek-rtl9300: Groundwork for multi SOC support Markus Stockhausen
` (6 preceding siblings ...)
2026-05-19 16:57 ` [PATCH 7/9] net: mdio: realtek-rtl9300: Add I/O register Markus Stockhausen
@ 2026-05-19 16:57 ` Markus Stockhausen
2026-05-19 18:43 ` Andrew Lunn
2026-05-19 16:57 ` [PATCH 9/9] net: mdio: realtek-rtl9300: Link I/O functions in info structure Markus Stockhausen
8 siblings, 1 reply; 26+ messages in thread
From: Markus Stockhausen @ 2026-05-19 16:57 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel
Cc: Markus Stockhausen
MDIO write commands take a register mask that specifies to which PHYs
the data is written. Depending on the SOC type and the number of
supported PHYs this is either one or two mask registers. The driver
currently only supports the 28 port RTL930x SOCs. So provide only the
mask register for the lower 32 ports. Add it to the register structure
and make use of it where needed.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/mdio-realtek-rtl9300.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
index be6a0cfe4bb8..f43403a7f39a 100644
--- a/drivers/net/mdio/mdio-realtek-rtl9300.c
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
@@ -25,7 +25,7 @@
#define SMI_GLB_CTRL 0xca00
#define GLB_CTRL_INTF_SEL(intf) BIT(16 + (intf))
#define SMI_PORT0_15_POLLING_SEL 0xca08
-#define SMI_ACCESS_PHY_CTRL_0 0xcb70
+#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)
@@ -57,6 +57,7 @@ struct rtl_mdio_cmd_regs {
u32 c22_data;
u32 c45_data;
u32 io_data;
+ u32 mask_low;
};
struct rtl_mdio_info {
@@ -183,7 +184,7 @@ static int rtl9300_mdio_write_c22(struct mii_bus *bus, int phy_id, int regnum, u
if (err)
goto out_err;
- err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_0, BIT(port));
+ err = regmap_write(regmap, priv->info->cmd_regs.mask_low, BIT(port));
if (err)
goto out_err;
@@ -294,7 +295,7 @@ static int rtl9300_mdio_write_c45(struct mii_bus *bus, int phy_id, int dev_addr,
if (err)
goto out_err;
- err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_0, BIT(port));
+ err = regmap_write(regmap, priv->info->cmd_regs.mask_low, BIT(port));
if (err)
goto out_err;
@@ -528,6 +529,7 @@ static const struct rtl_mdio_info rtl9300_mdio_info = {
.c22_data = RTL9300_SMI_ACCESS_PHY_CTRL_1,
.c45_data = RTL9300_SMI_ACCESS_PHY_CTRL_3,
.io_data = RTL9300_SMI_ACCESS_PHY_CTRL_2,
+ .mask_low = RTL9300_SMI_ACCESS_PHY_CTRL_0,
},
.num_buses = RTL9300_NUM_BUSES,
.num_ports = RTL9300_NUM_PORTS,
--
2.54.0
^ permalink raw reply related [flat|nested] 26+ messages in thread* Re: [PATCH 8/9] net: mdio: realtek-rtl9300: Add mask register
2026-05-19 16:57 ` [PATCH 8/9] net: mdio: realtek-rtl9300: Add mask register Markus Stockhausen
@ 2026-05-19 18:43 ` Andrew Lunn
0 siblings, 0 replies; 26+ messages in thread
From: Andrew Lunn @ 2026-05-19 18:43 UTC (permalink / raw)
To: Markus Stockhausen
Cc: hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel
On Tue, May 19, 2026 at 06:57:46PM +0200, Markus Stockhausen wrote:
> MDIO write commands take a register mask that specifies to which PHYs
> the data is written. Depending on the SOC type and the number of
> supported PHYs this is either one or two mask registers. The driver
> currently only supports the 28 port RTL930x SOCs. So provide only the
> mask register for the lower 32 ports.
802.3 C22 and C45 defines that an MDIO bus has 32 addresses. So i
don't understand why you would need anything other than 32?
Andrew
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 9/9] net: mdio: realtek-rtl9300: Link I/O functions in info structure
2026-05-19 16:57 [PATCH 0/9] mdio: realtek-rtl9300: Groundwork for multi SOC support Markus Stockhausen
` (7 preceding siblings ...)
2026-05-19 16:57 ` [PATCH 8/9] net: mdio: realtek-rtl9300: Add mask register Markus Stockhausen
@ 2026-05-19 16:57 ` Markus Stockhausen
2026-05-19 18:46 ` Andrew Lunn
8 siblings, 1 reply; 26+ messages in thread
From: Markus Stockhausen @ 2026-05-19 16:57 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel
Cc: Markus Stockhausen
All SOCs have slightly different I/O functions. Make them device
specific by adding the functions into the info structure.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/mdio-realtek-rtl9300.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
index f43403a7f39a..eb318d31c27d 100644
--- a/drivers/net/mdio/mdio-realtek-rtl9300.c
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
@@ -65,6 +65,10 @@ struct rtl_mdio_info {
u8 num_buses;
u8 num_ports;
u16 num_pages;
+ int (*read_c22)(struct mii_bus *bus, int phy_id, int regnum);
+ int (*read_c45)(struct mii_bus *bus, int phy_id, int dev_addr, int regnum);
+ int (*write_c22)(struct mii_bus *bus, int phy_id, int regnum, u16 value);
+ int (*write_c45)(struct mii_bus *bus, int phy_id, int dev_addr, int regnum, u16 value);
};
struct rtl_mdio_priv {
@@ -404,11 +408,11 @@ static int rtl_mdiobus_probe_one(struct device *dev, struct rtl_mdio_priv *priv,
bus->name = "Realtek Switch MDIO Bus";
if (priv->smi_bus_is_c45[mdio_bus]) {
- bus->read_c45 = rtl9300_mdio_read_c45;
- bus->write_c45 = rtl9300_mdio_write_c45;
+ bus->read_c45 = priv->info->read_c45;
+ bus->write_c45 = priv->info->write_c45;
} else {
- bus->read = rtl9300_mdio_read_c22;
- bus->write = rtl9300_mdio_write_c22;
+ bus->read = priv->info->read_c22;
+ bus->write = priv->info->write_c22;
}
bus->parent = dev;
chan = bus->priv;
@@ -534,6 +538,10 @@ static const struct rtl_mdio_info rtl9300_mdio_info = {
.num_buses = RTL9300_NUM_BUSES,
.num_ports = RTL9300_NUM_PORTS,
.num_pages = RTL9300_NUM_PAGES,
+ .read_c22 = rtl9300_mdio_read_c22,
+ .read_c45 = rtl9300_mdio_read_c45,
+ .write_c22 = rtl9300_mdio_write_c22,
+ .write_c45 = rtl9300_mdio_write_c45,
};
static const struct of_device_id rtl_mdio_ids[] = {
--
2.54.0
^ permalink raw reply related [flat|nested] 26+ messages in thread* Re: [PATCH 9/9] net: mdio: realtek-rtl9300: Link I/O functions in info structure
2026-05-19 16:57 ` [PATCH 9/9] net: mdio: realtek-rtl9300: Link I/O functions in info structure Markus Stockhausen
@ 2026-05-19 18:46 ` Andrew Lunn
2026-05-19 19:25 ` AW: " Markus Stockhausen
0 siblings, 1 reply; 26+ messages in thread
From: Andrew Lunn @ 2026-05-19 18:46 UTC (permalink / raw)
To: Markus Stockhausen
Cc: hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel
On Tue, May 19, 2026 at 06:57:47PM +0200, Markus Stockhausen wrote:
> All SOCs have slightly different I/O functions. Make them device
> specific by adding the functions into the info structure.
If they are all different, why put all the registers into info? Is
there some level of sharing?
Andrew
^ permalink raw reply [flat|nested] 26+ messages in thread
* AW: [PATCH 9/9] net: mdio: realtek-rtl9300: Link I/O functions in info structure
2026-05-19 18:46 ` Andrew Lunn
@ 2026-05-19 19:25 ` Markus Stockhausen
2026-05-19 20:16 ` Andrew Lunn
0 siblings, 1 reply; 26+ messages in thread
From: Markus Stockhausen @ 2026-05-19 19:25 UTC (permalink / raw)
To: 'Andrew Lunn'
Cc: hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel
> Von: Andrew Lunn <andrew@lunn.ch>
> Gesendet: Dienstag, 19. Mai 2026 20:46
> An: Markus Stockhausen <markus.stockhausen@gmx.de>
> Betreff: Re: [PATCH 9/9] net: mdio: realtek-rtl9300: Link I/O functions in
info structure
>
> On Tue, May 19, 2026 at 06:57:47PM +0200, Markus Stockhausen wrote:
> > All SOCs have slightly different I/O functions. Make them device
> > specific by adding the functions into the info structure.
>
> If they are all different, why put all the registers into info? Is
> there some level of sharing?
Patch 5 tries to explain the sharing concept:
- A generic access function will always run the same way
- The info structure tells it where to write (registers)
- The indidivual access function tells it what to write (data)
Markus
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 9/9] net: mdio: realtek-rtl9300: Link I/O functions in info structure
2026-05-19 19:25 ` AW: " Markus Stockhausen
@ 2026-05-19 20:16 ` Andrew Lunn
2026-05-19 20:40 ` AW: " Markus Stockhausen
0 siblings, 1 reply; 26+ messages in thread
From: Andrew Lunn @ 2026-05-19 20:16 UTC (permalink / raw)
To: Markus Stockhausen
Cc: hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel
On Tue, May 19, 2026 at 09:25:30PM +0200, Markus Stockhausen wrote:
> > Von: Andrew Lunn <andrew@lunn.ch>
> > Gesendet: Dienstag, 19. Mai 2026 20:46
> > An: Markus Stockhausen <markus.stockhausen@gmx.de>
> > Betreff: Re: [PATCH 9/9] net: mdio: realtek-rtl9300: Link I/O functions in
> info structure
> >
> > On Tue, May 19, 2026 at 06:57:47PM +0200, Markus Stockhausen wrote:
> > > All SOCs have slightly different I/O functions. Make them device
> > > specific by adding the functions into the info structure.
> >
> > If they are all different, why put all the registers into info? Is
> > there some level of sharing?
>
> Patch 5 tries to explain the sharing concept:
>
> - A generic access function will always run the same way
> - The info structure tells it where to write (registers)
> - The indidivual access function tells it what to write (data)
What to write is a u16. What else is there, given this is MDIO?
Andrew
^ permalink raw reply [flat|nested] 26+ messages in thread* AW: [PATCH 9/9] net: mdio: realtek-rtl9300: Link I/O functions in info structure
2026-05-19 20:16 ` Andrew Lunn
@ 2026-05-19 20:40 ` Markus Stockhausen
0 siblings, 0 replies; 26+ messages in thread
From: Markus Stockhausen @ 2026-05-19 20:40 UTC (permalink / raw)
To: 'Andrew Lunn'
Cc: hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel
> Von: Andrew Lunn <andrew@lunn.ch>
> Gesendet: Dienstag, 19. Mai 2026 22:17
> An: Markus Stockhausen <markus.stockhausen@gmx.de>
> Betreff: Re: [PATCH 9/9] net: mdio: realtek-rtl9300: Link I/O functions in
info structure
> ...
> > Patch 5 tries to explain the sharing concept:
> >
> > - A generic access function will always run the same way
> > - The info structure tells it where to write (registers)
> > - The indidivual access function tells it what to write (data)
>
> What to write is a u16. What else is there, given this is MDIO?
With what I meant all required register data to write.
E.g. see downstream
static int rtmd_930x_write_c45(struct mii_bus *bus, u32 pn, u32 devnum, u32
regnum, u32 val)
{
struct rtmd_command_data cmd_data = {
.c45_data = RTMD_C45_DATA(devnum, regnum),
.io_data = val,
.port_mask_low = BIT(pn),
};
return rtmd_run_cmd(bus, RTMD_930X_CMD_WRITE_C45, &cmd_data, NULL);
}
Markus
^ permalink raw reply [flat|nested] 26+ messages in thread