* [PATCH net-next 0/5] net: phy: realtek: simplify and reunify C22/C45 drivers
@ 2026-01-09 3:02 Daniel Golle
2026-01-09 3:03 ` [PATCH net-next 1/5] net: phy: realtek: support interrupt also for C22 variants Daniel Golle
` (4 more replies)
0 siblings, 5 replies; 16+ messages in thread
From: Daniel Golle @ 2026-01-09 3:02 UTC (permalink / raw)
To: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
Vladimir Oltean, Michael Klein, Aleksander Jan Bajkowski, netdev,
linux-kernel
The RTL8221B PHY variants (VB-CG and VM-CG) were previously split into
separate C22 and C45 driver instances to support copper SFP modules
using the RollBall MDIO-over-I2C protocol, which only supports Clause-45
access. However, this split created significant code duplication and
complexity.
Commit 8af2136e77989 ("net: phy: realtek: add helper
RTL822X_VND2_C22_REG") exposed that RealTek PHYs map all standard
Clause-22 registers into MDIO_MMD_VEND2 at offset 0xa400.
With commit 1850ec20d6e71 ("net: phy: realtek: use paged access for
MDIO_MMD_VEND2 in C22 mode") it is now possible to access all MMD
registers transparently, regardless of whether the PHY is accessed via
C22 or C45 MDIO.
Further improve the translation logic for this register mapping, so a
single unified driver works efficiently with both access methods,
reducing code duplication.
The series also includes cleanup to remove unnecessary paged operations
on registers that aren't actually affected by page selection.
Testing was done on RTL8211F and RTL8221B-VB-CG (the latter in both
C22 and C45 modes).
Daniel Golle (5):
net: phy: realtek: support interrupt also for C22 variants
net: phy: realtek: simplify C22 reg access via MDIO_MMD_VEND2
net: phy: realtek: reunify C22 and C45 drivers
net: phy: realtek: demystify PHYSR register location
net: phy: realtek: simplify bogus paged operations
drivers/net/phy/realtek/realtek_main.c | 122 ++++++++++---------------
1 file changed, 47 insertions(+), 75 deletions(-)
--
2.52.0
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH net-next 1/5] net: phy: realtek: support interrupt also for C22 variants
2026-01-09 3:02 [PATCH net-next 0/5] net: phy: realtek: simplify and reunify C22/C45 drivers Daniel Golle
@ 2026-01-09 3:03 ` Daniel Golle
2026-01-09 3:03 ` [PATCH net-next 2/5] net: phy: realtek: simplify C22 reg access via MDIO_MMD_VEND2 Daniel Golle
` (3 subsequent siblings)
4 siblings, 0 replies; 16+ messages in thread
From: Daniel Golle @ 2026-01-09 3:03 UTC (permalink / raw)
To: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
Vladimir Oltean, Michael Klein, Aleksander Jan Bajkowski, netdev,
linux-kernel
Now that access to MDIO_MMD_VEND2 works transparently also in Clause-22
mode, add interrupt support also for the C22 variants of the
RTL8221B-VB-CG and RTL8221B-VM-CG. This results in the C22 and C45
driver instances now having all the same features implemented.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
drivers/net/phy/realtek/realtek_main.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c
index eb5b540ada0e5..7302b25b8908b 100644
--- a/drivers/net/phy/realtek/realtek_main.c
+++ b/drivers/net/phy/realtek/realtek_main.c
@@ -2275,6 +2275,8 @@ static struct phy_driver realtek_drvs[] = {
}, {
.match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
+ .config_intr = rtl8221b_config_intr,
+ .handle_interrupt = rtl8221b_handle_interrupt,
.probe = rtl822x_probe,
.get_features = rtl822x_get_features,
.config_aneg = rtl822x_config_aneg,
@@ -2307,6 +2309,8 @@ static struct phy_driver realtek_drvs[] = {
}, {
.match_phy_device = rtl8221b_vm_cg_c22_match_phy_device,
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
+ .config_intr = rtl8221b_config_intr,
+ .handle_interrupt = rtl8221b_handle_interrupt,
.probe = rtl822x_probe,
.get_features = rtl822x_get_features,
.config_aneg = rtl822x_config_aneg,
--
2.52.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH net-next 2/5] net: phy: realtek: simplify C22 reg access via MDIO_MMD_VEND2
2026-01-09 3:02 [PATCH net-next 0/5] net: phy: realtek: simplify and reunify C22/C45 drivers Daniel Golle
2026-01-09 3:03 ` [PATCH net-next 1/5] net: phy: realtek: support interrupt also for C22 variants Daniel Golle
@ 2026-01-09 3:03 ` Daniel Golle
2026-01-09 7:27 ` Heiner Kallweit
2026-01-09 21:32 ` Russell King (Oracle)
2026-01-09 3:03 ` [PATCH net-next 3/5] net: phy: realtek: reunify C22 and C45 drivers Daniel Golle
` (2 subsequent siblings)
4 siblings, 2 replies; 16+ messages in thread
From: Daniel Golle @ 2026-01-09 3:03 UTC (permalink / raw)
To: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
Vladimir Oltean, Michael Klein, Aleksander Jan Bajkowski, netdev,
linux-kernel
RealTek 2.5GE PHYs have all standard Clause-22 registers mapped also
inside MDIO_MMD_VEND2 at offset 0xa400. This is used mainly in case the
PHY is inside a copper SFP module which uses the RollBall MDIO-over-I2C
method which *only* supports Clause-45. In order to support such
modules, the PHY driver has previously been split into a C22-only and
C45-only instances, creating quite a bit of redundancy and confusion.
In preparation of reunifying the two driver instances, add support for
translating MDIO_MMD_VEND2 registers 0xa400 to 0xa438 back to standard
Clause-22 access in case the PHY is accessed on a Clause-22 bus.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
drivers/net/phy/realtek/realtek_main.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c
index 7302b25b8908b..886694ff995f6 100644
--- a/drivers/net/phy/realtek/realtek_main.c
+++ b/drivers/net/phy/realtek/realtek_main.c
@@ -143,6 +143,7 @@
#define RTL822X_VND2_TO_PAGE(reg) ((reg) >> 4)
#define RTL822X_VND2_TO_PAGE_REG(reg) (16 + (((reg) & GENMASK(3, 0)) >> 1))
+#define RTL822X_VND2_TO_C22_REG(reg) (((reg) - 0xa400) / 2)
#define RTL822X_VND2_C22_REG(reg) (0xa400 + 2 * (reg))
#define RTL8221B_VND2_INER 0xa4d2
@@ -1264,6 +1265,11 @@ static int rtl822xb_read_mmd(struct phy_device *phydev, int devnum, u16 reg)
return mmd_phy_read(phydev->mdio.bus, phydev->mdio.addr,
phydev->is_c45, devnum, reg);
+ /* Simplify access to C22-registers addressed inside MDIO_MMD_VEND2 */
+ if (reg >= RTL822X_VND2_C22_REG(0) &&
+ reg <= RTL822X_VND2_C22_REG(30))
+ return __phy_read(phydev, RTL822X_VND2_TO_C22_REG(reg));
+
/* Use paged access for MDIO_MMD_VEND2 over Clause-22 */
page = RTL822X_VND2_TO_PAGE(reg);
oldpage = __phy_read(phydev, RTL821x_PAGE_SELECT);
@@ -1299,6 +1305,11 @@ static int rtl822xb_write_mmd(struct phy_device *phydev, int devnum, u16 reg,
return mmd_phy_write(phydev->mdio.bus, phydev->mdio.addr,
phydev->is_c45, devnum, reg, val);
+ /* Simplify access to C22-registers addressed inside MDIO_MMD_VEND2 */
+ if (reg >= RTL822X_VND2_C22_REG(0) &&
+ reg <= RTL822X_VND2_C22_REG(30))
+ return __phy_write(phydev, RTL822X_VND2_TO_C22_REG(reg), val);
+
/* Use paged access for MDIO_MMD_VEND2 over Clause-22 */
page = RTL822X_VND2_TO_PAGE(reg);
oldpage = __phy_read(phydev, RTL821x_PAGE_SELECT);
--
2.52.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH net-next 3/5] net: phy: realtek: reunify C22 and C45 drivers
2026-01-09 3:02 [PATCH net-next 0/5] net: phy: realtek: simplify and reunify C22/C45 drivers Daniel Golle
2026-01-09 3:03 ` [PATCH net-next 1/5] net: phy: realtek: support interrupt also for C22 variants Daniel Golle
2026-01-09 3:03 ` [PATCH net-next 2/5] net: phy: realtek: simplify C22 reg access via MDIO_MMD_VEND2 Daniel Golle
@ 2026-01-09 3:03 ` Daniel Golle
2026-01-09 13:18 ` Andrew Lunn
2026-01-09 3:03 ` [PATCH net-next 4/5] net: phy: realtek: demystify PHYSR register location Daniel Golle
2026-01-09 3:03 ` [PATCH net-next 5/5] net: phy: realtek: simplify bogus paged operations Daniel Golle
4 siblings, 1 reply; 16+ messages in thread
From: Daniel Golle @ 2026-01-09 3:03 UTC (permalink / raw)
To: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
Vladimir Oltean, Michael Klein, Aleksander Jan Bajkowski, netdev,
linux-kernel
Reunify the split C22/C45 drivers for the RTL8221B-VB-CG 2.5Gbps and
RTL8221B-VM-CG 2.5Gbps PHYs back into a single driver.
This is possible now by using all the driver operations previously used
by the C45 driver, as transparent access to all MMDs including
MDIO_MMD_VEND2 is now possible also over Clause-22 MDIO.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
drivers/net/phy/realtek/realtek_main.c | 72 ++++++--------------------
1 file changed, 16 insertions(+), 56 deletions(-)
diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c
index 886694ff995f6..d07d60bc1ce34 100644
--- a/drivers/net/phy/realtek/realtek_main.c
+++ b/drivers/net/phy/realtek/realtek_main.c
@@ -1879,28 +1879,18 @@ static int rtl8221b_match_phy_device(struct phy_device *phydev,
return phydev->phy_id == RTL_8221B && rtlgen_supports_mmd(phydev);
}
-static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev,
- const struct phy_driver *phydrv)
+static int rtl8221b_vb_cg_match_phy_device(struct phy_device *phydev,
+ const struct phy_driver *phydrv)
{
- return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false);
+ return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true) ||
+ rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false);
}
-static int rtl8221b_vb_cg_c45_match_phy_device(struct phy_device *phydev,
- const struct phy_driver *phydrv)
+static int rtl8221b_vm_cg_match_phy_device(struct phy_device *phydev,
+ const struct phy_driver *phydrv)
{
- return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true);
-}
-
-static int rtl8221b_vm_cg_c22_match_phy_device(struct phy_device *phydev,
- const struct phy_driver *phydrv)
-{
- return rtlgen_is_c45_match(phydev, RTL_8221B_VM_CG, false);
-}
-
-static int rtl8221b_vm_cg_c45_match_phy_device(struct phy_device *phydev,
- const struct phy_driver *phydrv)
-{
- return rtlgen_is_c45_match(phydev, RTL_8221B_VM_CG, true);
+ return rtlgen_is_c45_match(phydev, RTL_8221B_VM_CG, true) ||
+ rtlgen_is_c45_match(phydev, RTL_8221B_VM_CG, false);
}
static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev,
@@ -2284,27 +2274,8 @@ static struct phy_driver realtek_drvs[] = {
.read_mmd = rtl822xb_read_mmd,
.write_mmd = rtl822xb_write_mmd,
}, {
- .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
- .name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
- .config_intr = rtl8221b_config_intr,
- .handle_interrupt = rtl8221b_handle_interrupt,
- .probe = rtl822x_probe,
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
- .config_init = rtl822xb_config_init,
- .inband_caps = rtl822x_inband_caps,
- .config_inband = rtl822x_config_inband,
- .get_rate_matching = rtl822xb_get_rate_matching,
- .read_status = rtl822xb_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
- .read_page = rtl821x_read_page,
- .write_page = rtl821x_write_page,
- .read_mmd = rtl822xb_read_mmd,
- .write_mmd = rtl822xb_write_mmd,
- }, {
- .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
- .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
+ .match_phy_device = rtl8221b_vb_cg_match_phy_device,
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY",
.config_intr = rtl8221b_config_intr,
.handle_interrupt = rtl8221b_handle_interrupt,
.probe = rtl822x_probe,
@@ -2317,28 +2288,13 @@ static struct phy_driver realtek_drvs[] = {
.read_status = rtl822xb_c45_read_status,
.suspend = genphy_c45_pma_suspend,
.resume = rtlgen_c45_resume,
- }, {
- .match_phy_device = rtl8221b_vm_cg_c22_match_phy_device,
- .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
- .config_intr = rtl8221b_config_intr,
- .handle_interrupt = rtl8221b_handle_interrupt,
- .probe = rtl822x_probe,
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
- .config_init = rtl822xb_config_init,
- .inband_caps = rtl822x_inband_caps,
- .config_inband = rtl822x_config_inband,
- .get_rate_matching = rtl822xb_get_rate_matching,
- .read_status = rtl822xb_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
.read_page = rtl821x_read_page,
.write_page = rtl821x_write_page,
.read_mmd = rtl822xb_read_mmd,
.write_mmd = rtl822xb_write_mmd,
}, {
- .match_phy_device = rtl8221b_vm_cg_c45_match_phy_device,
- .name = "RTL8221B-VM-CG 2.5Gbps PHY (C45)",
+ .match_phy_device = rtl8221b_vm_cg_match_phy_device,
+ .name = "RTL8221B-VM-CG 2.5Gbps PHY",
.config_intr = rtl8221b_config_intr,
.handle_interrupt = rtl8221b_handle_interrupt,
.probe = rtl822x_probe,
@@ -2351,6 +2307,10 @@ static struct phy_driver realtek_drvs[] = {
.read_status = rtl822xb_c45_read_status,
.suspend = genphy_c45_pma_suspend,
.resume = rtlgen_c45_resume,
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ .read_mmd = rtl822xb_read_mmd,
+ .write_mmd = rtl822xb_write_mmd,
}, {
.match_phy_device = rtl8251b_c45_match_phy_device,
.name = "RTL8251B 5Gbps PHY",
--
2.52.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH net-next 4/5] net: phy: realtek: demystify PHYSR register location
2026-01-09 3:02 [PATCH net-next 0/5] net: phy: realtek: simplify and reunify C22/C45 drivers Daniel Golle
` (2 preceding siblings ...)
2026-01-09 3:03 ` [PATCH net-next 3/5] net: phy: realtek: reunify C22 and C45 drivers Daniel Golle
@ 2026-01-09 3:03 ` Daniel Golle
2026-01-09 7:32 ` Heiner Kallweit
2026-01-09 3:03 ` [PATCH net-next 5/5] net: phy: realtek: simplify bogus paged operations Daniel Golle
4 siblings, 1 reply; 16+ messages in thread
From: Daniel Golle @ 2026-01-09 3:03 UTC (permalink / raw)
To: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
Vladimir Oltean, Michael Klein, Aleksander Jan Bajkowski, netdev,
linux-kernel
Turns out that register address RTL_VND2_PHYSR (0xa434) maps to
Clause-22 register MII_RESV2. Use that to get rid of yet another magic
number, and rename access macros accordingly.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
drivers/net/phy/realtek/realtek_main.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c
index d07d60bc1ce34..5712372c71f91 100644
--- a/drivers/net/phy/realtek/realtek_main.c
+++ b/drivers/net/phy/realtek/realtek_main.c
@@ -178,12 +178,12 @@
#define RTL9000A_GINMR 0x14
#define RTL9000A_GINMR_LINK_STATUS BIT(4)
-#define RTL_VND2_PHYSR 0xa434
-#define RTL_VND2_PHYSR_DUPLEX BIT(3)
-#define RTL_VND2_PHYSR_SPEEDL GENMASK(5, 4)
-#define RTL_VND2_PHYSR_SPEEDH GENMASK(10, 9)
-#define RTL_VND2_PHYSR_MASTER BIT(11)
-#define RTL_VND2_PHYSR_SPEED_MASK (RTL_VND2_PHYSR_SPEEDL | RTL_VND2_PHYSR_SPEEDH)
+#define RTL_PHYSR MII_RESV2
+#define RTL_PHYSR_DUPLEX BIT(3)
+#define RTL_PHYSR_SPEEDL GENMASK(5, 4)
+#define RTL_PHYSR_SPEEDH GENMASK(10, 9)
+#define RTL_PHYSR_MASTER BIT(11)
+#define RTL_PHYSR_SPEED_MASK (RTL_PHYSR_SPEEDL | RTL_PHYSR_SPEEDH)
#define RTL_MDIO_PCS_EEE_ABLE 0xa5c4
#define RTL_MDIO_AN_EEE_ADV 0xa5d0
@@ -1102,12 +1102,12 @@ static void rtlgen_decode_physr(struct phy_device *phydev, int val)
* 0: Half Duplex
* 1: Full Duplex
*/
- if (val & RTL_VND2_PHYSR_DUPLEX)
+ if (val & RTL_PHYSR_DUPLEX)
phydev->duplex = DUPLEX_FULL;
else
phydev->duplex = DUPLEX_HALF;
- switch (val & RTL_VND2_PHYSR_SPEED_MASK) {
+ switch (val & RTL_PHYSR_SPEED_MASK) {
case 0x0000:
phydev->speed = SPEED_10;
break;
@@ -1135,7 +1135,7 @@ static void rtlgen_decode_physr(struct phy_device *phydev, int val)
* 1: Master Mode
*/
if (phydev->speed >= 1000) {
- if (val & RTL_VND2_PHYSR_MASTER)
+ if (val & RTL_PHYSR_MASTER)
phydev->master_slave_state = MASTER_SLAVE_STATE_MASTER;
else
phydev->master_slave_state = MASTER_SLAVE_STATE_SLAVE;
@@ -1155,8 +1155,7 @@ static int rtlgen_read_status(struct phy_device *phydev)
if (!phydev->link)
return 0;
- val = phy_read_paged(phydev, RTL822X_VND2_TO_PAGE(RTL_VND2_PHYSR),
- RTL822X_VND2_TO_PAGE_REG(RTL_VND2_PHYSR));
+ val = phy_read(phydev, RTL_PHYSR);
if (val < 0)
return val;
@@ -1622,7 +1621,8 @@ static int rtl822x_c45_read_status(struct phy_device *phydev)
}
/* Read actual speed from vendor register. */
- val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL_VND2_PHYSR);
+ val = phy_read_mmd(phydev, MDIO_MMD_VEND2,
+ RTL822X_VND2_C22_REG(RTL_PHYSR));
if (val < 0)
return val;
--
2.52.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH net-next 5/5] net: phy: realtek: simplify bogus paged operations
2026-01-09 3:02 [PATCH net-next 0/5] net: phy: realtek: simplify and reunify C22/C45 drivers Daniel Golle
` (3 preceding siblings ...)
2026-01-09 3:03 ` [PATCH net-next 4/5] net: phy: realtek: demystify PHYSR register location Daniel Golle
@ 2026-01-09 3:03 ` Daniel Golle
4 siblings, 0 replies; 16+ messages in thread
From: Daniel Golle @ 2026-01-09 3:03 UTC (permalink / raw)
To: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Daniel Golle,
Vladimir Oltean, Michael Klein, Aleksander Jan Bajkowski, netdev,
linux-kernel
Only registers 0x10~0x17 are affected by the value in the page
selection register 0x1f. Hence there is no point in using paged
operations when accessing any other registers.
Simplify the driver by using the normal phy_read and phy_write
operations for registers which are anyway not affected by paging.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
drivers/net/phy/realtek/realtek_main.c | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)
diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c
index 5712372c71f91..e3687e4216052 100644
--- a/drivers/net/phy/realtek/realtek_main.c
+++ b/drivers/net/phy/realtek/realtek_main.c
@@ -67,7 +67,6 @@
#define RTL8211E_DELAY_MASK GENMASK(13, 11)
/* RTL8211F PHY configuration */
-#define RTL8211F_PHYCR_PAGE 0xa43
#define RTL8211F_PHYCR1 0x18
#define RTL8211F_ALDPS_PLL_OFF BIT(1)
#define RTL8211F_ALDPS_ENABLE BIT(2)
@@ -77,7 +76,6 @@
#define RTL8211F_CLKOUT_EN BIT(0)
#define RTL8211F_PHYCR2_PHY_EEE_ENABLE BIT(5)
-#define RTL8211F_INSR_PAGE 0xa43
#define RTL8211F_INSR 0x1d
/* RTL8211F LED configuration */
@@ -332,7 +330,7 @@ static int rtl8211f_ack_interrupt(struct phy_device *phydev)
{
int err;
- err = phy_read_paged(phydev, RTL8211F_INSR_PAGE, RTL8211F_INSR);
+ err = phy_read(phydev, RTL8211F_INSR);
return (err < 0) ? err : 0;
}
@@ -478,7 +476,7 @@ static irqreturn_t rtl8211f_handle_interrupt(struct phy_device *phydev)
{
int irq_status;
- irq_status = phy_read_paged(phydev, RTL8211F_INSR_PAGE, RTL8211F_INSR);
+ irq_status = phy_read(phydev, RTL8211F_INSR);
if (irq_status < 0) {
phy_error(phydev);
return IRQ_NONE;
@@ -669,8 +667,8 @@ static int rtl8211f_config_clk_out(struct phy_device *phydev)
RTL8211FVD_CLKOUT_REG,
RTL8211FVD_CLKOUT_EN, 0);
else
- ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE,
- RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN, 0);
+ ret = phy_modify(phydev, RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN,
+ 0);
if (ret)
return ret;
@@ -695,15 +693,14 @@ static int rtl8211f_config_aldps(struct phy_device *phydev)
if (!priv->enable_aldps)
return 0;
- return phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR1,
- mask, mask);
+ return phy_modify(phydev, RTL8211F_PHYCR1, mask, mask);
}
static int rtl8211f_config_phy_eee(struct phy_device *phydev)
{
/* Disable PHY-mode EEE so LPI is passed to the MAC */
- return phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR2,
- RTL8211F_PHYCR2_PHY_EEE_ENABLE, 0);
+ return phy_modify(phydev, RTL8211F_PHYCR2,
+ RTL8211F_PHYCR2_PHY_EEE_ENABLE, 0);
}
static int rtl8211f_config_init(struct phy_device *phydev)
@@ -769,7 +766,7 @@ static int rtl8211f_suspend(struct phy_device *phydev)
goto err;
/* Read the INSR to clear any pending interrupt */
- phy_read_paged(phydev, RTL8211F_INSR_PAGE, RTL8211F_INSR);
+ phy_read(phydev, RTL8211F_INSR);
/* Reset the WoL to ensure that an event is picked up.
* Unless we do this, even if we receive another packet,
--
2.52.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 2/5] net: phy: realtek: simplify C22 reg access via MDIO_MMD_VEND2
2026-01-09 3:03 ` [PATCH net-next 2/5] net: phy: realtek: simplify C22 reg access via MDIO_MMD_VEND2 Daniel Golle
@ 2026-01-09 7:27 ` Heiner Kallweit
2026-01-09 21:32 ` Russell King (Oracle)
1 sibling, 0 replies; 16+ messages in thread
From: Heiner Kallweit @ 2026-01-09 7:27 UTC (permalink / raw)
To: Daniel Golle, Andrew Lunn, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Vladimir Oltean,
Michael Klein, Aleksander Jan Bajkowski, netdev, linux-kernel
On 1/9/2026 4:03 AM, Daniel Golle wrote:
> RealTek 2.5GE PHYs have all standard Clause-22 registers mapped also
> inside MDIO_MMD_VEND2 at offset 0xa400. This is used mainly in case the
> PHY is inside a copper SFP module which uses the RollBall MDIO-over-I2C
> method which *only* supports Clause-45. In order to support such
> modules, the PHY driver has previously been split into a C22-only and
> C45-only instances, creating quite a bit of redundancy and confusion.
>
To complement: RTL812x MAC/PHY chips allow access to MDIO_MMD_VEND2 of the
integrated PHY only. There is no native C22 MDIO access.
> In preparation of reunifying the two driver instances, add support for
> translating MDIO_MMD_VEND2 registers 0xa400 to 0xa438 back to standard
> Clause-22 access in case the PHY is accessed on a Clause-22 bus.
>
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
> drivers/net/phy/realtek/realtek_main.c | 11 +++++++++++
> 1 file changed, 11 insertions(+)
>
> diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c
> index 7302b25b8908b..886694ff995f6 100644
> --- a/drivers/net/phy/realtek/realtek_main.c
> +++ b/drivers/net/phy/realtek/realtek_main.c
> @@ -143,6 +143,7 @@
>
> #define RTL822X_VND2_TO_PAGE(reg) ((reg) >> 4)
> #define RTL822X_VND2_TO_PAGE_REG(reg) (16 + (((reg) & GENMASK(3, 0)) >> 1))
> +#define RTL822X_VND2_TO_C22_REG(reg) (((reg) - 0xa400) / 2)
> #define RTL822X_VND2_C22_REG(reg) (0xa400 + 2 * (reg))
>
> #define RTL8221B_VND2_INER 0xa4d2
> @@ -1264,6 +1265,11 @@ static int rtl822xb_read_mmd(struct phy_device *phydev, int devnum, u16 reg)
> return mmd_phy_read(phydev->mdio.bus, phydev->mdio.addr,
> phydev->is_c45, devnum, reg);
>
> + /* Simplify access to C22-registers addressed inside MDIO_MMD_VEND2 */
> + if (reg >= RTL822X_VND2_C22_REG(0) &&
> + reg <= RTL822X_VND2_C22_REG(30))
> + return __phy_read(phydev, RTL822X_VND2_TO_C22_REG(reg));
> +
> /* Use paged access for MDIO_MMD_VEND2 over Clause-22 */
> page = RTL822X_VND2_TO_PAGE(reg);
> oldpage = __phy_read(phydev, RTL821x_PAGE_SELECT);
> @@ -1299,6 +1305,11 @@ static int rtl822xb_write_mmd(struct phy_device *phydev, int devnum, u16 reg,
> return mmd_phy_write(phydev->mdio.bus, phydev->mdio.addr,
> phydev->is_c45, devnum, reg, val);
>
> + /* Simplify access to C22-registers addressed inside MDIO_MMD_VEND2 */
> + if (reg >= RTL822X_VND2_C22_REG(0) &&
> + reg <= RTL822X_VND2_C22_REG(30))
> + return __phy_write(phydev, RTL822X_VND2_TO_C22_REG(reg), val);
> +
> /* Use paged access for MDIO_MMD_VEND2 over Clause-22 */
> page = RTL822X_VND2_TO_PAGE(reg);
> oldpage = __phy_read(phydev, RTL821x_PAGE_SELECT);
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 4/5] net: phy: realtek: demystify PHYSR register location
2026-01-09 3:03 ` [PATCH net-next 4/5] net: phy: realtek: demystify PHYSR register location Daniel Golle
@ 2026-01-09 7:32 ` Heiner Kallweit
2026-01-09 12:26 ` Daniel Golle
0 siblings, 1 reply; 16+ messages in thread
From: Heiner Kallweit @ 2026-01-09 7:32 UTC (permalink / raw)
To: Daniel Golle, Andrew Lunn, Russell King, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Vladimir Oltean,
Michael Klein, Aleksander Jan Bajkowski, netdev, linux-kernel
On 1/9/2026 4:03 AM, Daniel Golle wrote:
> Turns out that register address RTL_VND2_PHYSR (0xa434) maps to
> Clause-22 register MII_RESV2. Use that to get rid of yet another magic
> number, and rename access macros accordingly.
>
RTL_VND2_PHYSR is documented in the datasheet, at least for RTL8221B(I)-VB-CG.
(this datasheet is publicly available, I don't have access to other datasheets)
MII_RESV2 isn't documented there. Is MII_RESV2 documented in any other datasheet?
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
> drivers/net/phy/realtek/realtek_main.c | 24 ++++++++++++------------
> 1 file changed, 12 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c
> index d07d60bc1ce34..5712372c71f91 100644
> --- a/drivers/net/phy/realtek/realtek_main.c
> +++ b/drivers/net/phy/realtek/realtek_main.c
> @@ -178,12 +178,12 @@
> #define RTL9000A_GINMR 0x14
> #define RTL9000A_GINMR_LINK_STATUS BIT(4)
>
> -#define RTL_VND2_PHYSR 0xa434
> -#define RTL_VND2_PHYSR_DUPLEX BIT(3)
> -#define RTL_VND2_PHYSR_SPEEDL GENMASK(5, 4)
> -#define RTL_VND2_PHYSR_SPEEDH GENMASK(10, 9)
> -#define RTL_VND2_PHYSR_MASTER BIT(11)
> -#define RTL_VND2_PHYSR_SPEED_MASK (RTL_VND2_PHYSR_SPEEDL | RTL_VND2_PHYSR_SPEEDH)
> +#define RTL_PHYSR MII_RESV2
> +#define RTL_PHYSR_DUPLEX BIT(3)
> +#define RTL_PHYSR_SPEEDL GENMASK(5, 4)
> +#define RTL_PHYSR_SPEEDH GENMASK(10, 9)
> +#define RTL_PHYSR_MASTER BIT(11)
> +#define RTL_PHYSR_SPEED_MASK (RTL_PHYSR_SPEEDL | RTL_PHYSR_SPEEDH)
>
> #define RTL_MDIO_PCS_EEE_ABLE 0xa5c4
> #define RTL_MDIO_AN_EEE_ADV 0xa5d0
> @@ -1102,12 +1102,12 @@ static void rtlgen_decode_physr(struct phy_device *phydev, int val)
> * 0: Half Duplex
> * 1: Full Duplex
> */
> - if (val & RTL_VND2_PHYSR_DUPLEX)
> + if (val & RTL_PHYSR_DUPLEX)
> phydev->duplex = DUPLEX_FULL;
> else
> phydev->duplex = DUPLEX_HALF;
>
> - switch (val & RTL_VND2_PHYSR_SPEED_MASK) {
> + switch (val & RTL_PHYSR_SPEED_MASK) {
> case 0x0000:
> phydev->speed = SPEED_10;
> break;
> @@ -1135,7 +1135,7 @@ static void rtlgen_decode_physr(struct phy_device *phydev, int val)
> * 1: Master Mode
> */
> if (phydev->speed >= 1000) {
> - if (val & RTL_VND2_PHYSR_MASTER)
> + if (val & RTL_PHYSR_MASTER)
> phydev->master_slave_state = MASTER_SLAVE_STATE_MASTER;
> else
> phydev->master_slave_state = MASTER_SLAVE_STATE_SLAVE;
> @@ -1155,8 +1155,7 @@ static int rtlgen_read_status(struct phy_device *phydev)
> if (!phydev->link)
> return 0;
>
> - val = phy_read_paged(phydev, RTL822X_VND2_TO_PAGE(RTL_VND2_PHYSR),
> - RTL822X_VND2_TO_PAGE_REG(RTL_VND2_PHYSR));
> + val = phy_read(phydev, RTL_PHYSR);
> if (val < 0)
> return val;
>
> @@ -1622,7 +1621,8 @@ static int rtl822x_c45_read_status(struct phy_device *phydev)
> }
>
> /* Read actual speed from vendor register. */
> - val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL_VND2_PHYSR);
> + val = phy_read_mmd(phydev, MDIO_MMD_VEND2,
> + RTL822X_VND2_C22_REG(RTL_PHYSR));
> if (val < 0)
> return val;
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 4/5] net: phy: realtek: demystify PHYSR register location
2026-01-09 7:32 ` Heiner Kallweit
@ 2026-01-09 12:26 ` Daniel Golle
2026-01-09 17:31 ` Daniel Golle
0 siblings, 1 reply; 16+ messages in thread
From: Daniel Golle @ 2026-01-09 12:26 UTC (permalink / raw)
To: Heiner Kallweit
Cc: Andrew Lunn, Russell King, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Vladimir Oltean, Michael Klein,
Aleksander Jan Bajkowski, netdev, linux-kernel
On Fri, Jan 09, 2026 at 08:32:33AM +0100, Heiner Kallweit wrote:
> On 1/9/2026 4:03 AM, Daniel Golle wrote:
> > Turns out that register address RTL_VND2_PHYSR (0xa434) maps to
> > Clause-22 register MII_RESV2. Use that to get rid of yet another magic
> > number, and rename access macros accordingly.
> >
>
> RTL_VND2_PHYSR is documented in the datasheet, at least for RTL8221B(I)-VB-CG.
> (this datasheet is publicly available, I don't have access to other datasheets)
> MII_RESV2 isn't documented there. Is MII_RESV2 documented in any other datasheet?
No datasheet mentions the nature of paging only affecting registers
0x10~0x17, I've figured that out by code analysis and testing (ie.
dumping all registers for all known/used pages using mdio-tools in
userspace, and writing to PHYCR1 toggling BIT(13) and confirming that it
affects the PHY in the expected way). Don't ask me why they ommit this
in the datasheets, I suspect the people writing the datasheets are given
some auto-generated code and also don't have unterstanding of the actual
internals (maybe to "protect" their precious IP?).
Anyway, as RTL_VND2_PHYSR is 0xa434 on MDIO_MMD_VEND2, and we know that
0xa400~0xa43c maps to the standard C22 registers, I concluded that
0xa434 on MDIO_MMD_VEND2 is identical to C22 register 0x1a, ie.
MII_RESV2. I've also noticed that the mechanism to translate registers
on MDIO_MMD_VEND2 to paged C22 registers only makes use of registers
0x10~0x17, so it became apparent that other registers are not affected
by paging.
I've confirmed all that by testing on RTL8211F and RTL8221B. As pointed
out this also holds true for internal PHYs on r8169 which emulate C22
registers in the exact same way. Hence the PHY driver can be simplified,
as there is no need to set and restore the page around the reading of
PHYSR.
>
> > Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> > ---
> > drivers/net/phy/realtek/realtek_main.c | 24 ++++++++++++------------
> > 1 file changed, 12 insertions(+), 12 deletions(-)
> >
> > diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c
> > index d07d60bc1ce34..5712372c71f91 100644
> > --- a/drivers/net/phy/realtek/realtek_main.c
> > +++ b/drivers/net/phy/realtek/realtek_main.c
> > @@ -178,12 +178,12 @@
> > #define RTL9000A_GINMR 0x14
> > #define RTL9000A_GINMR_LINK_STATUS BIT(4)
> >
> > -#define RTL_VND2_PHYSR 0xa434
> > -#define RTL_VND2_PHYSR_DUPLEX BIT(3)
> > -#define RTL_VND2_PHYSR_SPEEDL GENMASK(5, 4)
> > -#define RTL_VND2_PHYSR_SPEEDH GENMASK(10, 9)
> > -#define RTL_VND2_PHYSR_MASTER BIT(11)
> > -#define RTL_VND2_PHYSR_SPEED_MASK (RTL_VND2_PHYSR_SPEEDL | RTL_VND2_PHYSR_SPEEDH)
> > +#define RTL_PHYSR MII_RESV2
> > +#define RTL_PHYSR_DUPLEX BIT(3)
> > +#define RTL_PHYSR_SPEEDL GENMASK(5, 4)
> > +#define RTL_PHYSR_SPEEDH GENMASK(10, 9)
> > +#define RTL_PHYSR_MASTER BIT(11)
> > +#define RTL_PHYSR_SPEED_MASK (RTL_PHYSR_SPEEDL | RTL_PHYSR_SPEEDH)
> >
> > #define RTL_MDIO_PCS_EEE_ABLE 0xa5c4
> > #define RTL_MDIO_AN_EEE_ADV 0xa5d0
> > @@ -1102,12 +1102,12 @@ static void rtlgen_decode_physr(struct phy_device *phydev, int val)
> > * 0: Half Duplex
> > * 1: Full Duplex
> > */
> > - if (val & RTL_VND2_PHYSR_DUPLEX)
> > + if (val & RTL_PHYSR_DUPLEX)
> > phydev->duplex = DUPLEX_FULL;
> > else
> > phydev->duplex = DUPLEX_HALF;
> >
> > - switch (val & RTL_VND2_PHYSR_SPEED_MASK) {
> > + switch (val & RTL_PHYSR_SPEED_MASK) {
> > case 0x0000:
> > phydev->speed = SPEED_10;
> > break;
> > @@ -1135,7 +1135,7 @@ static void rtlgen_decode_physr(struct phy_device *phydev, int val)
> > * 1: Master Mode
> > */
> > if (phydev->speed >= 1000) {
> > - if (val & RTL_VND2_PHYSR_MASTER)
> > + if (val & RTL_PHYSR_MASTER)
> > phydev->master_slave_state = MASTER_SLAVE_STATE_MASTER;
> > else
> > phydev->master_slave_state = MASTER_SLAVE_STATE_SLAVE;
> > @@ -1155,8 +1155,7 @@ static int rtlgen_read_status(struct phy_device *phydev)
> > if (!phydev->link)
> > return 0;
> >
> > - val = phy_read_paged(phydev, RTL822X_VND2_TO_PAGE(RTL_VND2_PHYSR),
> > - RTL822X_VND2_TO_PAGE_REG(RTL_VND2_PHYSR));
> > + val = phy_read(phydev, RTL_PHYSR);
> > if (val < 0)
> > return val;
> >
> > @@ -1622,7 +1621,8 @@ static int rtl822x_c45_read_status(struct phy_device *phydev)
> > }
> >
> > /* Read actual speed from vendor register. */
> > - val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL_VND2_PHYSR);
> > + val = phy_read_mmd(phydev, MDIO_MMD_VEND2,
> > + RTL822X_VND2_C22_REG(RTL_PHYSR));
> > if (val < 0)
> > return val;
> >
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 3/5] net: phy: realtek: reunify C22 and C45 drivers
2026-01-09 3:03 ` [PATCH net-next 3/5] net: phy: realtek: reunify C22 and C45 drivers Daniel Golle
@ 2026-01-09 13:18 ` Andrew Lunn
2026-01-09 13:25 ` Daniel Golle
0 siblings, 1 reply; 16+ messages in thread
From: Andrew Lunn @ 2026-01-09 13:18 UTC (permalink / raw)
To: Daniel Golle
Cc: Heiner Kallweit, Russell King, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Vladimir Oltean, Michael Klein,
Aleksander Jan Bajkowski, netdev, linux-kernel
On Fri, Jan 09, 2026 at 03:03:33AM +0000, Daniel Golle wrote:
> Reunify the split C22/C45 drivers for the RTL8221B-VB-CG 2.5Gbps and
> RTL8221B-VM-CG 2.5Gbps PHYs back into a single driver.
> This is possible now by using all the driver operations previously used
> by the C45 driver, as transparent access to all MMDs including
> MDIO_MMD_VEND2 is now possible also over Clause-22 MDIO.
>
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
> drivers/net/phy/realtek/realtek_main.c | 72 ++++++--------------------
> 1 file changed, 16 insertions(+), 56 deletions(-)
>
> diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c
> index 886694ff995f6..d07d60bc1ce34 100644
> --- a/drivers/net/phy/realtek/realtek_main.c
> +++ b/drivers/net/phy/realtek/realtek_main.c
> @@ -1879,28 +1879,18 @@ static int rtl8221b_match_phy_device(struct phy_device *phydev,
> return phydev->phy_id == RTL_8221B && rtlgen_supports_mmd(phydev);
> }
>
> -static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev,
> - const struct phy_driver *phydrv)
> +static int rtl8221b_vb_cg_match_phy_device(struct phy_device *phydev,
> + const struct phy_driver *phydrv)
> {
> - return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false);
> + return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true) ||
> + rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false);
Are there any calls left to rtlgen_is_c45_match() which don't || true
and false? If not, maybe add another patch which removes the bool
parameter?
Andrew
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 3/5] net: phy: realtek: reunify C22 and C45 drivers
2026-01-09 13:18 ` Andrew Lunn
@ 2026-01-09 13:25 ` Daniel Golle
2026-01-10 14:28 ` Heiner Kallweit
0 siblings, 1 reply; 16+ messages in thread
From: Daniel Golle @ 2026-01-09 13:25 UTC (permalink / raw)
To: Andrew Lunn
Cc: Heiner Kallweit, Russell King, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Vladimir Oltean, Michael Klein,
Aleksander Jan Bajkowski, netdev, linux-kernel
On Fri, Jan 09, 2026 at 02:18:14PM +0100, Andrew Lunn wrote:
> On Fri, Jan 09, 2026 at 03:03:33AM +0000, Daniel Golle wrote:
> > Reunify the split C22/C45 drivers for the RTL8221B-VB-CG 2.5Gbps and
> > RTL8221B-VM-CG 2.5Gbps PHYs back into a single driver.
> > This is possible now by using all the driver operations previously used
> > by the C45 driver, as transparent access to all MMDs including
> > MDIO_MMD_VEND2 is now possible also over Clause-22 MDIO.
> >
> > Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> > ---
> > drivers/net/phy/realtek/realtek_main.c | 72 ++++++--------------------
> > 1 file changed, 16 insertions(+), 56 deletions(-)
> >
> > diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c
> > index 886694ff995f6..d07d60bc1ce34 100644
> > --- a/drivers/net/phy/realtek/realtek_main.c
> > +++ b/drivers/net/phy/realtek/realtek_main.c
> > @@ -1879,28 +1879,18 @@ static int rtl8221b_match_phy_device(struct phy_device *phydev,
> > return phydev->phy_id == RTL_8221B && rtlgen_supports_mmd(phydev);
> > }
> >
> > -static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev,
> > - const struct phy_driver *phydrv)
> > +static int rtl8221b_vb_cg_match_phy_device(struct phy_device *phydev,
> > + const struct phy_driver *phydrv)
> > {
> > - return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false);
> > + return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true) ||
> > + rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false);
>
> Are there any calls left to rtlgen_is_c45_match() which don't || true
> and false? If not, maybe add another patch which removes the bool
> parameter?
At this point it is still used by
---
static int rtl8251b_c45_match_phy_device(struct phy_device *phydev,
const struct phy_driver *phydrv)
{
return rtlgen_is_c45_match(phydev, RTL_8251B, true);
}
---
This 5G PHY supposedly supports only C45 mode, I don't know if it
actually needs the .match_phy_device at all or could also simply use
PHY_ID_MATCH_EXACT(RTL_8251B) instead, I don't have any device using
it so I can't test that.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 4/5] net: phy: realtek: demystify PHYSR register location
2026-01-09 12:26 ` Daniel Golle
@ 2026-01-09 17:31 ` Daniel Golle
2026-01-09 20:19 ` Daniel Golle
0 siblings, 1 reply; 16+ messages in thread
From: Daniel Golle @ 2026-01-09 17:31 UTC (permalink / raw)
To: Heiner Kallweit
Cc: Andrew Lunn, Russell King, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Vladimir Oltean, Michael Klein,
Aleksander Jan Bajkowski, netdev, linux-kernel
On Fri, Jan 09, 2026 at 12:26:42PM +0000, Daniel Golle wrote:
> On Fri, Jan 09, 2026 at 08:32:33AM +0100, Heiner Kallweit wrote:
> > On 1/9/2026 4:03 AM, Daniel Golle wrote:
> > > Turns out that register address RTL_VND2_PHYSR (0xa434) maps to
> > > Clause-22 register MII_RESV2. Use that to get rid of yet another magic
> > > number, and rename access macros accordingly.
> > >
> >
> > RTL_VND2_PHYSR is documented in the datasheet, at least for RTL8221B(I)-VB-CG.
> > (this datasheet is publicly available, I don't have access to other datasheets)
> > MII_RESV2 isn't documented there. Is MII_RESV2 documented in any other datasheet?
>
> No datasheet mentions the nature of paging only affecting registers
> 0x10~0x17, I've figured that out by code analysis and testing (ie.
> dumping all registers for all known/used pages using mdio-tools in
> userspace, and writing to PHYCR1 toggling BIT(13) and confirming that it
> affects the PHY in the expected way). Don't ask me why they ommit this
> in the datasheets, I suspect the people writing the datasheets are given
> some auto-generated code and also don't have unterstanding of the actual
> internals (maybe to "protect" their precious IP?).
>
> Anyway, as RTL_VND2_PHYSR is 0xa434 on MDIO_MMD_VEND2, and we know that
> 0xa400~0xa43c maps to the standard C22 registers, I concluded that
> 0xa434 on MDIO_MMD_VEND2 is identical to C22 register 0x1a, ie.
> MII_RESV2. I've also noticed that the mechanism to translate registers
> on MDIO_MMD_VEND2 to paged C22 registers only makes use of registers
> 0x10~0x17, so it became apparent that other registers are not affected
> by paging.
>
> I've confirmed all that by testing on RTL8211F and RTL8221B. As pointed
> out this also holds true for internal PHYs on r8169 which emulate C22
> registers in the exact same way. Hence the PHY driver can be simplified,
> as there is no need to set and restore the page around the reading of
> PHYSR.
Just did some additional testing also with r8169 (with internal 2.5G PHY
0x001cc840), and PHYSR reads fine as MII_RESV2, letting the Ethernet
driver handle the mapping to MDIO_MMD_VEND2 instead of using a paged
read in the PHY driver.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 4/5] net: phy: realtek: demystify PHYSR register location
2026-01-09 17:31 ` Daniel Golle
@ 2026-01-09 20:19 ` Daniel Golle
0 siblings, 0 replies; 16+ messages in thread
From: Daniel Golle @ 2026-01-09 20:19 UTC (permalink / raw)
To: Heiner Kallweit
Cc: Andrew Lunn, Russell King, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Vladimir Oltean, Michael Klein,
Aleksander Jan Bajkowski, netdev, linux-kernel
On Fri, Jan 09, 2026 at 05:31:40PM +0000, Daniel Golle wrote:
> On Fri, Jan 09, 2026 at 12:26:42PM +0000, Daniel Golle wrote:
> > On Fri, Jan 09, 2026 at 08:32:33AM +0100, Heiner Kallweit wrote:
> > > On 1/9/2026 4:03 AM, Daniel Golle wrote:
> > > > Turns out that register address RTL_VND2_PHYSR (0xa434) maps to
> > > > Clause-22 register MII_RESV2. Use that to get rid of yet another magic
> > > > number, and rename access macros accordingly.
> > > >
> > >
> > > RTL_VND2_PHYSR is documented in the datasheet, at least for RTL8221B(I)-VB-CG.
> > > (this datasheet is publicly available, I don't have access to other datasheets)
> > > MII_RESV2 isn't documented there. Is MII_RESV2 documented in any other datasheet?
> >
> > No datasheet mentions the nature of paging only affecting registers
> > 0x10~0x17, I've figured that out by code analysis and testing (ie.
> > dumping all registers for all known/used pages using mdio-tools in
> > userspace, and writing to PHYCR1 toggling BIT(13) and confirming that it
> > affects the PHY in the expected way). Don't ask me why they ommit this
> > in the datasheets, I suspect the people writing the datasheets are given
> > some auto-generated code and also don't have unterstanding of the actual
> > internals (maybe to "protect" their precious IP?).
> >
> > Anyway, as RTL_VND2_PHYSR is 0xa434 on MDIO_MMD_VEND2, and we know that
> > 0xa400~0xa43c maps to the standard C22 registers, I concluded that
> > 0xa434 on MDIO_MMD_VEND2 is identical to C22 register 0x1a, ie.
> > MII_RESV2. I've also noticed that the mechanism to translate registers
> > on MDIO_MMD_VEND2 to paged C22 registers only makes use of registers
> > 0x10~0x17, so it became apparent that other registers are not affected
> > by paging.
> >
> > I've confirmed all that by testing on RTL8211F and RTL8221B. As pointed
> > out this also holds true for internal PHYs on r8169 which emulate C22
> > registers in the exact same way. Hence the PHY driver can be simplified,
> > as there is no need to set and restore the page around the reading of
> > PHYSR.
>
> Just did some additional testing also with r8169 (with internal 2.5G PHY
> 0x001cc840), and PHYSR reads fine as MII_RESV2, letting the Ethernet
> driver handle the mapping to MDIO_MMD_VEND2 instead of using a paged
> read in the PHY driver.
>
Same for 10ec:8168
("Realtek Semiconductor Co., Ltd. RTL8111/8168/8211/8411 PCI Express Gigabit Ethernet Controller (rev 15)")
with PHY ID 0x001cc800 ("Generic FE-GE Realtek PHY"), works all fine
with this series applied.
So I agree that for r8169 this change doesn't make a difference, but
for standalone PHYs it does make things more simple and also means
less MDIO operations (1 instead of 3) to do the same thing.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 2/5] net: phy: realtek: simplify C22 reg access via MDIO_MMD_VEND2
2026-01-09 3:03 ` [PATCH net-next 2/5] net: phy: realtek: simplify C22 reg access via MDIO_MMD_VEND2 Daniel Golle
2026-01-09 7:27 ` Heiner Kallweit
@ 2026-01-09 21:32 ` Russell King (Oracle)
2026-01-09 22:21 ` Daniel Golle
1 sibling, 1 reply; 16+ messages in thread
From: Russell King (Oracle) @ 2026-01-09 21:32 UTC (permalink / raw)
To: Daniel Golle
Cc: Andrew Lunn, Heiner Kallweit, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Vladimir Oltean, Michael Klein,
Aleksander Jan Bajkowski, netdev, linux-kernel
On Fri, Jan 09, 2026 at 03:03:22AM +0000, Daniel Golle wrote:
> RealTek 2.5GE PHYs have all standard Clause-22 registers mapped also
> inside MDIO_MMD_VEND2 at offset 0xa400. This is used mainly in case the
> PHY is inside a copper SFP module which uses the RollBall MDIO-over-I2C
> method which *only* supports Clause-45.
It isn't just Rollball. There are SoCs out there which have separate
MDIO buses, one bus signals at 3.3V and can generate only clause 22
frames. The other operates at 1.2V and can only generate clause 45
frames.
While hardware may elect to generate and recognise either frame types
at either voltage, this goes some way to explain why there are
implementations that only support one or the other on a particular
pair of MDC/MDIO wires.
Armada 8040 has this setup - there is one MDIO bus that only supports
clause 22 frames, and there is a separate MDIO bus that only supports
clause 45 frames.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 2/5] net: phy: realtek: simplify C22 reg access via MDIO_MMD_VEND2
2026-01-09 21:32 ` Russell King (Oracle)
@ 2026-01-09 22:21 ` Daniel Golle
0 siblings, 0 replies; 16+ messages in thread
From: Daniel Golle @ 2026-01-09 22:21 UTC (permalink / raw)
To: Russell King (Oracle)
Cc: Andrew Lunn, Heiner Kallweit, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Vladimir Oltean, Michael Klein,
Aleksander Jan Bajkowski, netdev, linux-kernel
On Fri, Jan 09, 2026 at 09:32:18PM +0000, Russell King (Oracle) wrote:
> On Fri, Jan 09, 2026 at 03:03:22AM +0000, Daniel Golle wrote:
> > RealTek 2.5GE PHYs have all standard Clause-22 registers mapped also
> > inside MDIO_MMD_VEND2 at offset 0xa400. This is used mainly in case the
> > PHY is inside a copper SFP module which uses the RollBall MDIO-over-I2C
> > method which *only* supports Clause-45.
>
> It isn't just Rollball. There are SoCs out there which have separate
> MDIO buses, one bus signals at 3.3V and can generate only clause 22
> frames. The other operates at 1.2V and can only generate clause 45
> frames.
>
> While hardware may elect to generate and recognise either frame types
> at either voltage, this goes some way to explain why there are
> implementations that only support one or the other on a particular
> pair of MDC/MDIO wires.
>
> Armada 8040 has this setup - there is one MDIO bus that only supports
> clause 22 frames, and there is a separate MDIO bus that only supports
> clause 45 frames.
Interesting. And a bit annoying. I wasn't aware of the electrical
difference (signal voltage).
Never the less, even with this change applied you now get a driver which
uses *only* Clause-45 access in case phydev->is_45 is true, and only
Clause-22 in case phydev->is_45 is false.
From what I understood this was the intended outcome of having two
dedicated drivers, and you can have the very same results now with a
single driver. If you would like me to broaden the commit message and
clarify this, please let me know.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 3/5] net: phy: realtek: reunify C22 and C45 drivers
2026-01-09 13:25 ` Daniel Golle
@ 2026-01-10 14:28 ` Heiner Kallweit
0 siblings, 0 replies; 16+ messages in thread
From: Heiner Kallweit @ 2026-01-10 14:28 UTC (permalink / raw)
To: Daniel Golle, Andrew Lunn
Cc: Russell King, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Vladimir Oltean, Michael Klein,
Aleksander Jan Bajkowski, netdev, linux-kernel
On 1/9/2026 2:25 PM, Daniel Golle wrote:
> On Fri, Jan 09, 2026 at 02:18:14PM +0100, Andrew Lunn wrote:
>> On Fri, Jan 09, 2026 at 03:03:33AM +0000, Daniel Golle wrote:
>>> Reunify the split C22/C45 drivers for the RTL8221B-VB-CG 2.5Gbps and
>>> RTL8221B-VM-CG 2.5Gbps PHYs back into a single driver.
>>> This is possible now by using all the driver operations previously used
>>> by the C45 driver, as transparent access to all MMDs including
>>> MDIO_MMD_VEND2 is now possible also over Clause-22 MDIO.
>>>
>>> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
>>> ---
>>> drivers/net/phy/realtek/realtek_main.c | 72 ++++++--------------------
>>> 1 file changed, 16 insertions(+), 56 deletions(-)
>>>
>>> diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c
>>> index 886694ff995f6..d07d60bc1ce34 100644
>>> --- a/drivers/net/phy/realtek/realtek_main.c
>>> +++ b/drivers/net/phy/realtek/realtek_main.c
>>> @@ -1879,28 +1879,18 @@ static int rtl8221b_match_phy_device(struct phy_device *phydev,
>>> return phydev->phy_id == RTL_8221B && rtlgen_supports_mmd(phydev);
>>> }
>>>
>>> -static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev,
>>> - const struct phy_driver *phydrv)
>>> +static int rtl8221b_vb_cg_match_phy_device(struct phy_device *phydev,
>>> + const struct phy_driver *phydrv)
>>> {
>>> - return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false);
>>> + return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true) ||
>>> + rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false);
>>
>> Are there any calls left to rtlgen_is_c45_match() which don't || true
>> and false? If not, maybe add another patch which removes the bool
>> parameter?
>
> At this point it is still used by
> ---
> static int rtl8251b_c45_match_phy_device(struct phy_device *phydev,
> const struct phy_driver *phydrv)
> {
> return rtlgen_is_c45_match(phydev, RTL_8251B, true);
> }
> ---
>
> This 5G PHY supposedly supports only C45 mode, I don't know if it
> actually needs the .match_phy_device at all or could also simply use
> PHY_ID_MATCH_EXACT(RTL_8251B) instead, I don't have any device using
> it so I can't test that.
Yes, match_phy_device is needed. This PHY ID also matches the internal PHY
of RTL8126. And RTL8126 doesn't support speaking c45 to its internal PHY.
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2026-01-10 14:28 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-09 3:02 [PATCH net-next 0/5] net: phy: realtek: simplify and reunify C22/C45 drivers Daniel Golle
2026-01-09 3:03 ` [PATCH net-next 1/5] net: phy: realtek: support interrupt also for C22 variants Daniel Golle
2026-01-09 3:03 ` [PATCH net-next 2/5] net: phy: realtek: simplify C22 reg access via MDIO_MMD_VEND2 Daniel Golle
2026-01-09 7:27 ` Heiner Kallweit
2026-01-09 21:32 ` Russell King (Oracle)
2026-01-09 22:21 ` Daniel Golle
2026-01-09 3:03 ` [PATCH net-next 3/5] net: phy: realtek: reunify C22 and C45 drivers Daniel Golle
2026-01-09 13:18 ` Andrew Lunn
2026-01-09 13:25 ` Daniel Golle
2026-01-10 14:28 ` Heiner Kallweit
2026-01-09 3:03 ` [PATCH net-next 4/5] net: phy: realtek: demystify PHYSR register location Daniel Golle
2026-01-09 7:32 ` Heiner Kallweit
2026-01-09 12:26 ` Daniel Golle
2026-01-09 17:31 ` Daniel Golle
2026-01-09 20:19 ` Daniel Golle
2026-01-09 3:03 ` [PATCH net-next 5/5] net: phy: realtek: simplify bogus paged operations Daniel Golle
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox