[PATCH net-next 2/5] net: phy: realtek: simplify C22 reg access via MDIO_MMD_VEND2

Daniel Golle posted 5 patches 1 month ago
There is a newer version of this series
[PATCH net-next 2/5] net: phy: realtek: simplify C22 reg access via MDIO_MMD_VEND2
Posted by Daniel Golle 1 month ago
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
Re: [PATCH net-next 2/5] net: phy: realtek: simplify C22 reg access via MDIO_MMD_VEND2
Posted by Russell King (Oracle) 1 month ago
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!
Re: [PATCH net-next 2/5] net: phy: realtek: simplify C22 reg access via MDIO_MMD_VEND2
Posted by Daniel Golle 1 month ago
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.
Re: [PATCH net-next 2/5] net: phy: realtek: simplify C22 reg access via MDIO_MMD_VEND2
Posted by Heiner Kallweit 1 month ago
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);