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