Replace downstream RealTek PHY patches with backported ones.
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
--- /dev/null
+From 6c06c88fa838fcc1b7e5380facd086f57fd9d1c4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Sun, 4 Feb 2024 15:16:46 +0100
+Subject: [PATCH] net: mdio: add 2.5g and 5g related PMA speed constants
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add constants indicating 2.5g and 5g ability in the MMD PMA speed
+register.
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/98e15038-d96c-442f-93e4-410100d27866@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ include/uapi/linux/mdio.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/include/uapi/linux/mdio.h
++++ b/include/uapi/linux/mdio.h
+@@ -138,6 +138,8 @@
+ #define MDIO_PMA_SPEED_1000 0x0010 /* 1000M capable */
+ #define MDIO_PMA_SPEED_100 0x0020 /* 100M capable */
+ #define MDIO_PMA_SPEED_10 0x0040 /* 10M capable */
++#define MDIO_PMA_SPEED_2_5G 0x2000 /* 2.5G capable */
++#define MDIO_PMA_SPEED_5G 0x4000 /* 5G capable */
+ #define MDIO_PCS_SPEED_10P2B 0x0002 /* 10PASS-TS/2BASE-TL capable */
+ #define MDIO_PCS_SPEED_2_5G 0x0040 /* 2.5G capable */
+ #define MDIO_PCS_SPEED_5G 0x0080 /* 5G capable */
--- /dev/null
+From 5befa3728b855e9f75b29bb0069a1ca7f5bab2f7 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Wed, 31 Jan 2024 21:24:29 +0100
+Subject: [PATCH] net: phy: realtek: add support for RTL8126A-integrated 5Gbps
+ PHY
+
+A user reported that first consumer mainboards show up with a RTL8126A
+5Gbps MAC/PHY. This adds support for the integrated PHY, which is also
+available stand-alone. From a PHY driver perspective it's treated the
+same as the 2.5Gbps PHY's, we just have to support the new PHY ID.
+
+Reported-by: Joe Salmeri <jmscdba@gmail.com>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Tested-by: Joe Salmeri <jmscdba@gmail.com>
+Link: https://lore.kernel.org/r/0c8e67ea-6505-43d1-bd51-94e7ecd6e222@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/realtek.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -1050,6 +1050,16 @@ static struct phy_driver realtek_drvs[]
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ }, {
++ PHY_ID_MATCH_EXACT(0x001cc862),
++ .name = "RTL8251B 5Gbps PHY",
++ .get_features = rtl822x_get_features,
++ .config_aneg = rtl822x_config_aneg,
++ .read_status = rtl822x_read_status,
++ .suspend = genphy_suspend,
++ .resume = rtlgen_resume,
++ .read_page = rtl821x_read_page,
++ .write_page = rtl821x_write_page,
++ }, {
+ PHY_ID_MATCH_EXACT(0x001cc961),
+ .name = "RTL8366RB Gigabit Ethernet",
+ .config_init = &rtl8366rb_config_init,
--- /dev/null
+From 2b9ec5dfb8255656ca731ab9d9bf59d94566d377 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Sun, 4 Feb 2024 15:17:53 +0100
+Subject: [PATCH] net: phy: realtek: use generic MDIO constants
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Drop the ad-hoc MDIO constants used in the driver and use generic
+constants instead.
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/732a70d6-4191-4aae-8862-3716b062aa9e@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/realtek.c | 30 +++++++++++++-----------------
+ 1 file changed, 13 insertions(+), 17 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -57,14 +57,6 @@
+ #define RTL8366RB_POWER_SAVE 0x15
+ #define RTL8366RB_POWER_SAVE_ON BIT(12)
+
+-#define RTL_SUPPORTS_5000FULL BIT(14)
+-#define RTL_SUPPORTS_2500FULL BIT(13)
+-#define RTL_SUPPORTS_10000FULL BIT(0)
+-#define RTL_ADV_2500FULL BIT(7)
+-#define RTL_LPADV_10000FULL BIT(11)
+-#define RTL_LPADV_5000FULL BIT(6)
+-#define RTL_LPADV_2500FULL BIT(5)
+-
+ #define RTL9000A_GINMR 0x14
+ #define RTL9000A_GINMR_LINK_STATUS BIT(4)
+
+@@ -676,11 +668,11 @@ static int rtl822x_get_features(struct p
+ return val;
+
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+- phydev->supported, val & RTL_SUPPORTS_2500FULL);
++ phydev->supported, val & MDIO_PMA_SPEED_2_5G);
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+- phydev->supported, val & RTL_SUPPORTS_5000FULL);
++ phydev->supported, val & MDIO_PMA_SPEED_5G);
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+- phydev->supported, val & RTL_SUPPORTS_10000FULL);
++ phydev->supported, val & MDIO_SPEED_10G);
+
+ return genphy_read_abilities(phydev);
+ }
+@@ -694,10 +686,11 @@ static int rtl822x_config_aneg(struct ph
+
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+ phydev->advertising))
+- adv2500 = RTL_ADV_2500FULL;
++ adv2500 = MDIO_AN_10GBT_CTRL_ADV2_5G;
+
+ ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
+- RTL_ADV_2500FULL, adv2500);
++ MDIO_AN_10GBT_CTRL_ADV2_5G,
++ adv2500);
+ if (ret < 0)
+ return ret;
+ }
+@@ -716,11 +709,14 @@ static int rtl822x_read_status(struct ph
+ return lpadv;
+
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+- phydev->lp_advertising, lpadv & RTL_LPADV_10000FULL);
++ phydev->lp_advertising,
++ lpadv & MDIO_AN_10GBT_STAT_LP10G);
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+- phydev->lp_advertising, lpadv & RTL_LPADV_5000FULL);
++ phydev->lp_advertising,
++ lpadv & MDIO_AN_10GBT_STAT_LP5G);
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+- phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL);
++ phydev->lp_advertising,
++ lpadv & MDIO_AN_10GBT_STAT_LP2_5G);
+ }
+
+ ret = genphy_read_status(phydev);
+@@ -738,7 +734,7 @@ static bool rtlgen_supports_2_5gbps(stru
+ val = phy_read(phydev, 0x13);
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0);
+
+- return val >= 0 && val & RTL_SUPPORTS_2500FULL;
++ return val >= 0 && val & MDIO_PMA_SPEED_2_5G;
+ }
+
+ static int rtlgen_match_phy_device(struct phy_device *phydev)
--- /dev/null
+From db1bb7741ff29bf2cefcbc0ca567644e9ed1caa9 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Sun, 4 Feb 2024 15:18:50 +0100
+Subject: [PATCH] net: phy: realtek: add 5Gbps support to rtl822x_config_aneg()
+
+RTL8126 as an evolution of RTL8125 supports 5Gbps. rtl822x_config_aneg()
+is used by the PHY driver for the integrated PHY, therefore add 5Gbps
+support to it.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/5644ab50-e3e9-477c-96db-05cd5bdc2563@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/realtek.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -682,15 +682,19 @@ static int rtl822x_config_aneg(struct ph
+ int ret = 0;
+
+ if (phydev->autoneg == AUTONEG_ENABLE) {
+- u16 adv2500 = 0;
++ u16 adv = 0;
+
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+ phydev->advertising))
+- adv2500 = MDIO_AN_10GBT_CTRL_ADV2_5G;
++ adv |= MDIO_AN_10GBT_CTRL_ADV2_5G;
++ if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
++ phydev->advertising))
++ adv |= MDIO_AN_10GBT_CTRL_ADV5G;
+
+ ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
+- MDIO_AN_10GBT_CTRL_ADV2_5G,
+- adv2500);
++ MDIO_AN_10GBT_CTRL_ADV2_5G |
++ MDIO_AN_10GBT_CTRL_ADV5G,
++ adv);
+ if (ret < 0)
+ return ret;
+ }
--- /dev/null
+From b63cc73341e076961d564a74cc3d29b2fd444079 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Thu, 8 Feb 2024 07:59:18 +0100
+Subject: [PATCH] net: phy: realtek: use generic MDIO helpers to simplify the
+ code
+
+Use generic MDIO helpers to simplify the code.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/422ae70f-7305-45fd-ab3e-0dd604b9fd6c@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/realtek.c | 20 +++-----------------
+ 1 file changed, 3 insertions(+), 17 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -682,14 +682,7 @@ static int rtl822x_config_aneg(struct ph
+ int ret = 0;
+
+ if (phydev->autoneg == AUTONEG_ENABLE) {
+- u16 adv = 0;
+-
+- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+- phydev->advertising))
+- adv |= MDIO_AN_10GBT_CTRL_ADV2_5G;
+- if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+- phydev->advertising))
+- adv |= MDIO_AN_10GBT_CTRL_ADV5G;
++ u16 adv = linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising);
+
+ ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
+ MDIO_AN_10GBT_CTRL_ADV2_5G |
+@@ -712,15 +705,8 @@ static int rtl822x_read_status(struct ph
+ if (lpadv < 0)
+ return lpadv;
+
+- linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+- phydev->lp_advertising,
+- lpadv & MDIO_AN_10GBT_STAT_LP10G);
+- linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+- phydev->lp_advertising,
+- lpadv & MDIO_AN_10GBT_STAT_LP5G);
+- linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+- phydev->lp_advertising,
+- lpadv & MDIO_AN_10GBT_STAT_LP2_5G);
++ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising,
++ lpadv);
+ }
+
+ ret = genphy_read_status(phydev);
--- /dev/null
+From deb8af5243504e379878ae3f9a091b21422d65b2 Mon Sep 17 00:00:00 2001
+From: Alexander Couzens <lynxis@fe80.eu>
+Date: Tue, 9 Apr 2024 09:30:11 +0200
+Subject: [PATCH] net: phy: realtek: configure SerDes mode for rtl822xb PHYs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The rtl8221b and rtl8226b series support switching SerDes mode between
+2500base-x and sgmii based on the negotiated copper speed.
+
+Configure this switching mode according to SerDes modes supported by
+host.
+
+There is an additional datasheet for RTL8226B/RTL8221B called
+"SERDES MODE SETTING FLOW APPLICATION NOTE" where a sequence is
+described to setup interface and rate adapter mode.
+
+However, there is no documentation about the meaning of registers
+and bits, it's literally just magic numbers and pseudo-code.
+
+Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
+[ refactored, dropped HiSGMII mode and changed commit message ]
+Signed-off-by: Marek Behún <kabel@kernel.org>
+[ changed rtl822x_update_interface() to use vendor register ]
+[ always fill in possible interfaces ]
+[ only apply to rtl8221b and rtl8226b phy's ]
+[ set phydev->rate_matching in .config_init() ]
+Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
+
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: should come before them, without any blank lines. As the
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/realtek.c | 114 ++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 110 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -54,6 +54,16 @@
+ RTL8201F_ISR_LINK)
+ #define RTL8201F_IER 0x13
+
++#define RTL822X_VND1_SERDES_OPTION 0x697a
++#define RTL822X_VND1_SERDES_OPTION_MODE_MASK GENMASK(5, 0)
++#define RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX_SGMII 0
++#define RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX 2
++
++#define RTL822X_VND1_SERDES_CTRL3 0x7580
++#define RTL822X_VND1_SERDES_CTRL3_MODE_MASK GENMASK(5, 0)
++#define RTL822X_VND1_SERDES_CTRL3_MODE_SGMII 0x02
++#define RTL822X_VND1_SERDES_CTRL3_MODE_2500BASEX 0x16
++
+ #define RTL8366RB_POWER_SAVE 0x15
+ #define RTL8366RB_POWER_SAVE_ON BIT(12)
+
+@@ -659,6 +669,63 @@ static int rtl822x_write_mmd(struct phy_
+ return ret;
+ }
+
++static int rtl822xb_config_init(struct phy_device *phydev)
++{
++ bool has_2500, has_sgmii;
++ u16 mode;
++ int ret;
++
++ has_2500 = test_bit(PHY_INTERFACE_MODE_2500BASEX,
++ phydev->host_interfaces) ||
++ phydev->interface == PHY_INTERFACE_MODE_2500BASEX;
++
++ has_sgmii = test_bit(PHY_INTERFACE_MODE_SGMII,
++ phydev->host_interfaces) ||
++ phydev->interface == PHY_INTERFACE_MODE_SGMII;
++
++ /* fill in possible interfaces */
++ __assign_bit(PHY_INTERFACE_MODE_2500BASEX, phydev->possible_interfaces,
++ has_2500);
++ __assign_bit(PHY_INTERFACE_MODE_SGMII, phydev->possible_interfaces,
++ has_sgmii);
++
++ if (!has_2500 && !has_sgmii)
++ return 0;
++
++ /* determine SerDes option mode */
++ if (has_2500 && !has_sgmii) {
++ mode = RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX;
++ phydev->rate_matching = RATE_MATCH_PAUSE;
++ } else {
++ mode = RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX_SGMII;
++ phydev->rate_matching = RATE_MATCH_NONE;
++ }
++
++ /* the following sequence with magic numbers sets up the SerDes
++ * option mode
++ */
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x75f3, 0);
++ if (ret < 0)
++ return ret;
++
++ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND1,
++ RTL822X_VND1_SERDES_OPTION,
++ RTL822X_VND1_SERDES_OPTION_MODE_MASK,
++ mode);
++ if (ret < 0)
++ return ret;
++
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6a04, 0x0503);
++ if (ret < 0)
++ return ret;
++
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f10, 0xd455);
++ if (ret < 0)
++ return ret;
++
++ return phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
++}
++
+ static int rtl822x_get_features(struct phy_device *phydev)
+ {
+ int val;
+@@ -695,6 +762,28 @@ static int rtl822x_config_aneg(struct ph
+ return __genphy_config_aneg(phydev, ret);
+ }
+
++static void rtl822xb_update_interface(struct phy_device *phydev)
++{
++ int val;
++
++ if (!phydev->link)
++ return;
++
++ /* Change interface according to serdes mode */
++ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_CTRL3);
++ if (val < 0)
++ return;
++
++ switch (val & RTL822X_VND1_SERDES_CTRL3_MODE_MASK) {
++ case RTL822X_VND1_SERDES_CTRL3_MODE_2500BASEX:
++ phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
++ break;
++ case RTL822X_VND1_SERDES_CTRL3_MODE_SGMII:
++ phydev->interface = PHY_INTERFACE_MODE_SGMII;
++ break;
++ }
++}
++
+ static int rtl822x_read_status(struct phy_device *phydev)
+ {
+ int ret;
+@@ -716,6 +805,19 @@ static int rtl822x_read_status(struct ph
+ return rtlgen_get_speed(phydev);
+ }
+
++static int rtl822xb_read_status(struct phy_device *phydev)
++{
++ int ret;
++
++ ret = rtl822x_read_status(phydev);
++ if (ret < 0)
++ return ret;
++
++ rtl822xb_update_interface(phydev);
++
++ return 0;
++}
++
+ static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
+ {
+ int val;
+@@ -988,7 +1090,8 @@ static struct phy_driver realtek_drvs[]
+ .name = "RTL8226B_RTL8221B 2.5Gbps PHY",
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+- .read_status = rtl822x_read_status,
++ .config_init = rtl822xb_config_init,
++ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
+ .read_page = rtl821x_read_page,
+@@ -1010,7 +1113,8 @@ static struct phy_driver realtek_drvs[]
+ .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+- .read_status = rtl822x_read_status,
++ .config_init = rtl822xb_config_init,
++ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
+ .read_page = rtl821x_read_page,
+@@ -1020,7 +1124,8 @@ static struct phy_driver realtek_drvs[]
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY",
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+- .read_status = rtl822x_read_status,
++ .config_init = rtl822xb_config_init,
++ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
+ .read_page = rtl821x_read_page,
+@@ -1030,7 +1135,8 @@ static struct phy_driver realtek_drvs[]
+ .name = "RTL8221B-VM-CG 2.5Gbps PHY",
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+- .read_status = rtl822x_read_status,
++ .config_init = rtl822xb_config_init,
++ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
+ .read_page = rtl821x_read_page,
--- /dev/null
+From c189dbd738243be6775bb6878366bf63e27bfd05 Mon Sep 17 00:00:00 2001
+From: Eric Woudstra <ericwouds@gmail.com>
+Date: Tue, 9 Apr 2024 09:30:12 +0200
+Subject: [PATCH] net: phy: realtek: add get_rate_matching() for rtl822xb PHYs
+
+Uses vendor register to determine if SerDes is setup in rate-matching mode.
+
+Rate-matching only supported when SerDes is set to 2500base-x.
+
+Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/realtek.c | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -726,6 +726,27 @@ static int rtl822xb_config_init(struct p
+ return phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
+ }
+
++static int rtl822xb_get_rate_matching(struct phy_device *phydev,
++ phy_interface_t iface)
++{
++ int val;
++
++ /* Only rate matching at 2500base-x */
++ if (iface != PHY_INTERFACE_MODE_2500BASEX)
++ return RATE_MATCH_NONE;
++
++ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_OPTION);
++ if (val < 0)
++ return val;
++
++ if ((val & RTL822X_VND1_SERDES_OPTION_MODE_MASK) ==
++ RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX)
++ return RATE_MATCH_PAUSE;
++
++ /* RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX_SGMII */
++ return RATE_MATCH_NONE;
++}
++
+ static int rtl822x_get_features(struct phy_device *phydev)
+ {
+ int val;
+@@ -1091,6 +1112,7 @@ static struct phy_driver realtek_drvs[]
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
++ .get_rate_matching = rtl822xb_get_rate_matching,
+ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
+@@ -1114,6 +1136,7 @@ static struct phy_driver realtek_drvs[]
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
++ .get_rate_matching = rtl822xb_get_rate_matching,
+ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
+@@ -1125,6 +1148,7 @@ static struct phy_driver realtek_drvs[]
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
++ .get_rate_matching = rtl822xb_get_rate_matching,
+ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
+@@ -1136,6 +1160,7 @@ static struct phy_driver realtek_drvs[]
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
++ .get_rate_matching = rtl822xb_get_rate_matching,
+ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
--- /dev/null
+From ad5ce743a6b0329f642d80be50ef7b534e908fba Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Tue, 9 Apr 2024 09:30:13 +0200
+Subject: [PATCH] net: phy: realtek: Add driver instances for rtl8221b via
+ Clause 45
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Collected from several commits in [PATCH net-next]
+"Realtek RTL822x PHY rework to c45 and SerDes interface switching"
+
+The instances are used by Clause 45 only accessible PHY's on several sfp
+modules, which are using RollBall protocol.
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+[ Added matching functions to differentiate C45 instances ]
+Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
+
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/realtek.c | 135 ++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 131 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -64,6 +64,13 @@
+ #define RTL822X_VND1_SERDES_CTRL3_MODE_SGMII 0x02
+ #define RTL822X_VND1_SERDES_CTRL3_MODE_2500BASEX 0x16
+
++/* RTL822X_VND2_XXXXX registers are only accessible when phydev->is_c45
++ * is set, they cannot be accessed by C45-over-C22.
++ */
++#define RTL822X_VND2_GBCR 0xa412
++
++#define RTL822X_VND2_GANLPAR 0xa414
++
+ #define RTL8366RB_POWER_SAVE 0x15
+ #define RTL8366RB_POWER_SAVE_ON BIT(12)
+
+@@ -74,6 +81,9 @@
+
+ #define RTL_GENERIC_PHYID 0x001cc800
+ #define RTL_8211FVD_PHYID 0x001cc878
++#define RTL_8221B_VB_CG 0x001cc849
++#define RTL_8221B_VN_CG 0x001cc84a
++#define RTL_8251B 0x001cc862
+
+ MODULE_DESCRIPTION("Realtek PHY driver");
+ MODULE_AUTHOR("Johnson Leung");
+@@ -839,6 +849,67 @@ static int rtl822xb_read_status(struct p
+ return 0;
+ }
+
++static int rtl822x_c45_config_aneg(struct phy_device *phydev)
++{
++ bool changed = false;
++ int ret, val;
++
++ if (phydev->autoneg == AUTONEG_DISABLE)
++ return genphy_c45_pma_setup_forced(phydev);
++
++ ret = genphy_c45_an_config_aneg(phydev);
++ if (ret < 0)
++ return ret;
++ if (ret > 0)
++ changed = true;
++
++ val = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
++
++ /* Vendor register as C45 has no standardized support for 1000BaseT */
++ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2, RTL822X_VND2_GBCR,
++ ADVERTISE_1000FULL, val);
++ if (ret < 0)
++ return ret;
++ if (ret > 0)
++ changed = true;
++
++ return genphy_c45_check_and_restart_aneg(phydev, changed);
++}
++
++static int rtl822x_c45_read_status(struct phy_device *phydev)
++{
++ int ret, val;
++
++ ret = genphy_c45_read_status(phydev);
++ if (ret < 0)
++ return ret;
++
++ /* Vendor register as C45 has no standardized support for 1000BaseT */
++ if (phydev->autoneg == AUTONEG_ENABLE) {
++ val = phy_read_mmd(phydev, MDIO_MMD_VEND2,
++ RTL822X_VND2_GANLPAR);
++ if (val < 0)
++ return val;
++
++ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val);
++ }
++
++ return 0;
++}
++
++static int rtl822xb_c45_read_status(struct phy_device *phydev)
++{
++ int ret;
++
++ ret = rtl822x_c45_read_status(phydev);
++ if (ret < 0)
++ return ret;
++
++ rtl822xb_update_interface(phydev);
++
++ return 0;
++}
++
+ static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
+ {
+ int val;
+@@ -862,6 +933,35 @@ static int rtl8226_match_phy_device(stru
+ rtlgen_supports_2_5gbps(phydev);
+ }
+
++static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id,
++ bool is_c45)
++{
++ if (phydev->is_c45)
++ return is_c45 && (id == phydev->c45_ids.device_ids[1]);
++ else
++ return !is_c45 && (id == phydev->phy_id);
++}
++
++static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev)
++{
++ return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false);
++}
++
++static int rtl8221b_vb_cg_c45_match_phy_device(struct phy_device *phydev)
++{
++ return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true);
++}
++
++static int rtl8221b_vn_cg_c22_match_phy_device(struct phy_device *phydev)
++{
++ return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, false);
++}
++
++static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev)
++{
++ return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true);
++}
++
+ static int rtlgen_resume(struct phy_device *phydev)
+ {
+ int ret = genphy_resume(phydev);
+@@ -872,6 +972,15 @@ static int rtlgen_resume(struct phy_devi
+ return ret;
+ }
+
++static int rtlgen_c45_resume(struct phy_device *phydev)
++{
++ int ret = genphy_c45_pma_resume(phydev);
++
++ msleep(20);
++
++ return ret;
++}
++
+ static int rtl9000a_config_init(struct phy_device *phydev)
+ {
+ phydev->autoneg = AUTONEG_DISABLE;
+@@ -1143,8 +1252,8 @@ static struct phy_driver realtek_drvs[]
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ }, {
+- PHY_ID_MATCH_EXACT(0x001cc849),
+- .name = "RTL8221B-VB-CG 2.5Gbps PHY",
++ .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
++ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
+@@ -1155,8 +1264,17 @@ static struct phy_driver realtek_drvs[]
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ }, {
+- PHY_ID_MATCH_EXACT(0x001cc84a),
+- .name = "RTL8221B-VM-CG 2.5Gbps PHY",
++ .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
++ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
++ .config_init = rtl822xb_config_init,
++ .get_rate_matching = rtl822xb_get_rate_matching,
++ .config_aneg = rtl822x_c45_config_aneg,
++ .read_status = rtl822xb_c45_read_status,
++ .suspend = genphy_c45_pma_suspend,
++ .resume = rtlgen_c45_resume,
++ }, {
++ .match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
++ .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
+@@ -1167,6 +1285,15 @@ static struct phy_driver realtek_drvs[]
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ }, {
++ .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
++ .name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
++ .config_init = rtl822xb_config_init,
++ .get_rate_matching = rtl822xb_get_rate_matching,
++ .config_aneg = rtl822x_c45_config_aneg,
++ .read_status = rtl822xb_c45_read_status,
++ .suspend = genphy_c45_pma_suspend,
++ .resume = rtlgen_c45_resume,
++ }, {
+ PHY_ID_MATCH_EXACT(0x001cc862),
+ .name = "RTL8251B 5Gbps PHY",
+ .get_features = rtl822x_get_features,
--- /dev/null
+From 2e4ea707c7e04eb83e58c43e0e744bbdf6b23ff2 Mon Sep 17 00:00:00 2001
+From: Eric Woudstra <ericwouds@gmail.com>
+Date: Tue, 9 Apr 2024 09:30:14 +0200
+Subject: [PATCH] net: phy: realtek: Change rtlgen_get_speed() to
+ rtlgen_decode_speed()
+
+The value of the register to determine the speed, is retrieved
+differently when using Clause 45 only. To use the rtlgen_get_speed()
+function in this case, pass the value of the register as argument to
+rtlgen_get_speed(). The function would then always return 0, so change it
+to void. A better name for this function now is rtlgen_decode_speed().
+
+Replace a call to genphy_read_status() followed by rtlgen_get_speed()
+with a call to rtlgen_read_status() in rtl822x_read_status().
+
+Add reading speed to rtl822x_c45_read_status().
+
+Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
+
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/realtek.c | 46 +++++++++++++++++++++------------------
+ 1 file changed, 25 insertions(+), 21 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -71,6 +71,8 @@
+
+ #define RTL822X_VND2_GANLPAR 0xa414
+
++#define RTL822X_VND2_PHYSR 0xa434
++
+ #define RTL8366RB_POWER_SAVE 0x15
+ #define RTL8366RB_POWER_SAVE_ON BIT(12)
+
+@@ -551,17 +553,8 @@ static int rtl8366rb_config_init(struct
+ }
+
+ /* get actual speed to cover the downshift case */
+-static int rtlgen_get_speed(struct phy_device *phydev)
++static void rtlgen_decode_speed(struct phy_device *phydev, int val)
+ {
+- int val;
+-
+- if (!phydev->link)
+- return 0;
+-
+- val = phy_read_paged(phydev, 0xa43, 0x12);
+- if (val < 0)
+- return val;
+-
+ switch (val & RTLGEN_SPEED_MASK) {
+ case 0x0000:
+ phydev->speed = SPEED_10;
+@@ -584,19 +577,26 @@ static int rtlgen_get_speed(struct phy_d
+ default:
+ break;
+ }
+-
+- return 0;
+ }
+
+ static int rtlgen_read_status(struct phy_device *phydev)
+ {
+- int ret;
++ int ret, val;
+
+ ret = genphy_read_status(phydev);
+ if (ret < 0)
+ return ret;
+
+- return rtlgen_get_speed(phydev);
++ if (!phydev->link)
++ return 0;
++
++ val = phy_read_paged(phydev, 0xa43, 0x12);
++ if (val < 0)
++ return val;
++
++ rtlgen_decode_speed(phydev, val);
++
++ return 0;
+ }
+
+ static int rtlgen_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
+@@ -817,8 +817,6 @@ static void rtl822xb_update_interface(st
+
+ static int rtl822x_read_status(struct phy_device *phydev)
+ {
+- int ret;
+-
+ if (phydev->autoneg == AUTONEG_ENABLE) {
+ int lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
+
+@@ -829,11 +827,7 @@ static int rtl822x_read_status(struct ph
+ lpadv);
+ }
+
+- ret = genphy_read_status(phydev);
+- if (ret < 0)
+- return ret;
+-
+- return rtlgen_get_speed(phydev);
++ return rtlgen_read_status(phydev);
+ }
+
+ static int rtl822xb_read_status(struct phy_device *phydev)
+@@ -894,6 +888,16 @@ static int rtl822x_c45_read_status(struc
+ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val);
+ }
+
++ if (!phydev->link)
++ return 0;
++
++ /* Read actual speed from vendor register. */
++ val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_PHYSR);
++ if (val < 0)
++ return val;
++
++ rtlgen_decode_speed(phydev, val);
++
+ return 0;
+ }
+
--- /dev/null
+From 2d9ce64862705b33397d54dafecc5f51d8b1bb06 Mon Sep 17 00:00:00 2001
+From: Eric Woudstra <ericwouds@gmail.com>
+Date: Tue, 9 Apr 2024 09:30:15 +0200
+Subject: [PATCH] net: phy: realtek: add rtl822x_c45_get_features() to set
+ supported port
+
+Sets ETHTOOL_LINK_MODE_TP_BIT in phydev->supported.
+
+Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/realtek.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -843,6 +843,14 @@ static int rtl822xb_read_status(struct p
+ return 0;
+ }
+
++static int rtl822x_c45_get_features(struct phy_device *phydev)
++{
++ linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT,
++ phydev->supported);
++
++ return genphy_c45_pma_read_abilities(phydev);
++}
++
+ static int rtl822x_c45_config_aneg(struct phy_device *phydev)
+ {
+ bool changed = false;
+@@ -1272,6 +1280,7 @@ static struct phy_driver realtek_drvs[]
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
+ .config_init = rtl822xb_config_init,
+ .get_rate_matching = rtl822xb_get_rate_matching,
++ .get_features = rtl822x_c45_get_features,
+ .config_aneg = rtl822x_c45_config_aneg,
+ .read_status = rtl822xb_c45_read_status,
+ .suspend = genphy_c45_pma_suspend,
+@@ -1293,6 +1302,7 @@ static struct phy_driver realtek_drvs[]
+ .name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
+ .config_init = rtl822xb_config_init,
+ .get_rate_matching = rtl822xb_get_rate_matching,
++ .get_features = rtl822x_c45_get_features,
+ .config_aneg = rtl822x_c45_config_aneg,
+ .read_status = rtl822xb_c45_read_status,
+ .suspend = genphy_c45_pma_suspend,
+++ /dev/null
-From ace6abaa0f9203083fe4c0a6a74da2d96410b625 Mon Sep 17 00:00:00 2001
-From: Alexander Couzens <lynxis@fe80.eu>
-Date: Sat, 13 Aug 2022 12:49:33 +0200
-Subject: [PATCH 01/10] net: phy: realtek: rtl8221: allow to configure SERDES
- mode
-
-The rtl8221 supports multiple SERDES modes:
-- SGMII
-- 2500base-x
-- HiSGMII
-
-Further it supports rate adaption on SERDES links to allow
-slow ethernet speeds (10/100/1000mbit) to work on 2500base-x/HiSGMII
-links without reducing the SERDES speed.
-
-When operating without rate adapters the SERDES link will follow the
-ethernet speed.
-
-Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
----
- drivers/net/phy/realtek.c | 48 +++++++++++++++++++++++++++++++++++++++
- 1 file changed, 48 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -54,6 +54,15 @@
- RTL8201F_ISR_LINK)
- #define RTL8201F_IER 0x13
-
-+#define RTL8221B_MMD_SERDES_CTRL MDIO_MMD_VEND1
-+#define RTL8221B_MMD_PHY_CTRL MDIO_MMD_VEND2
-+#define RTL8221B_SERDES_OPTION 0x697a
-+#define RTL8221B_SERDES_OPTION_MODE_MASK GENMASK(5, 0)
-+#define RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII 0
-+#define RTL8221B_SERDES_OPTION_MODE_HISGMII_SGMII 1
-+#define RTL8221B_SERDES_OPTION_MODE_2500BASEX 2
-+#define RTL8221B_SERDES_OPTION_MODE_HISGMII 3
-+
- #define RTL8366RB_POWER_SAVE 0x15
- #define RTL8366RB_POWER_SAVE_ON BIT(12)
-
-@@ -879,6 +888,48 @@ static irqreturn_t rtl9000a_handle_inter
- return IRQ_HANDLED;
- }
-
-+static int rtl8221b_config_init(struct phy_device *phydev)
-+{
-+ u16 option_mode;
-+
-+ switch (phydev->interface) {
-+ case PHY_INTERFACE_MODE_2500BASEX:
-+ if (!phydev->is_c45) {
-+ option_mode = RTL8221B_SERDES_OPTION_MODE_2500BASEX;
-+ break;
-+ }
-+ fallthrough;
-+ case PHY_INTERFACE_MODE_SGMII:
-+ option_mode = RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII;
-+ break;
-+ default:
-+ return 0;
-+ }
-+
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL,
-+ 0x75f3, 0);
-+
-+ phy_modify_mmd_changed(phydev, RTL8221B_MMD_SERDES_CTRL,
-+ RTL8221B_SERDES_OPTION,
-+ RTL8221B_SERDES_OPTION_MODE_MASK, option_mode);
-+ switch (option_mode) {
-+ case RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII:
-+ case RTL8221B_SERDES_OPTION_MODE_2500BASEX:
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd455);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020);
-+ break;
-+ case RTL8221B_SERDES_OPTION_MODE_HISGMII_SGMII:
-+ case RTL8221B_SERDES_OPTION_MODE_HISGMII:
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd433);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
- static struct phy_driver realtek_drvs[] = {
- {
- PHY_ID_MATCH_EXACT(0x00008201),
-@@ -1033,6 +1084,7 @@ static struct phy_driver realtek_drvs[]
- PHY_ID_MATCH_EXACT(0x001cc849),
- .name = "RTL8221B-VB-CG 2.5Gbps PHY",
- .get_features = rtl822x_get_features,
-+ .config_init = rtl8221b_config_init,
- .config_aneg = rtl822x_config_aneg,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
-@@ -1044,6 +1096,7 @@ static struct phy_driver realtek_drvs[]
- .name = "RTL8221B-VM-CG 2.5Gbps PHY",
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
-+ .config_init = rtl8221b_config_init,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
+++ /dev/null
-From 312753d0aadba0f58841ae513b80fdbabc887523 Mon Sep 17 00:00:00 2001
-From: Chukun Pan <amadeus@jmu.edu.cn>
-Date: Wed, 8 Feb 2023 16:32:18 +0800
-Subject: [PATCH] net: phy: realtek: support switching between SGMII and
- 2500BASE-X for RTL822x series
-
-After commit ace6aba ("net: phy: realtek: rtl8221: allow to configure
-SERDES mode"), the rtl8221 phy can work in SGMII and 2500base-x modes
-respectively. So add interface automatic switching for rtl8221 phy to
-match various wire speeds.
-
-Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
----
- drivers/net/phy/realtek.c | 26 ++++++++++++++++++++++++--
- 1 file changed, 24 insertions(+), 2 deletions(-)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -714,6 +714,25 @@ static int rtl822x_config_aneg(struct ph
- return __genphy_config_aneg(phydev, ret);
- }
-
-+static void rtl822x_update_interface(struct phy_device *phydev)
-+{
-+ /* Automatically switch SERDES interface between
-+ * SGMII and 2500-BaseX according to speed.
-+ */
-+ switch (phydev->speed) {
-+ case SPEED_2500:
-+ phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
-+ break;
-+ case SPEED_1000:
-+ case SPEED_100:
-+ case SPEED_10:
-+ phydev->interface = PHY_INTERFACE_MODE_SGMII;
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
- static int rtl822x_read_status(struct phy_device *phydev)
- {
- int ret;
-@@ -732,11 +751,14 @@ static int rtl822x_read_status(struct ph
- phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL);
- }
-
-- ret = genphy_read_status(phydev);
-+ ret = rtlgen_read_status(phydev);
- if (ret < 0)
- return ret;
-
-- return rtlgen_get_speed(phydev);
-+ if (phydev->is_c45 && phydev->link)
-+ rtl822x_update_interface(phydev);
-+
-+ return 0;
- }
-
- static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
-@@ -1070,6 +1070,7 @@ static struct phy_driver realtek_drvs[]
- .write_page = rtl821x_write_page,
- .read_mmd = rtl822x_read_mmd,
- .write_mmd = rtl822x_write_mmd,
+@@ -1218,6 +1218,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .name = "RTL8226 2.5Gbps PHY",
+ .match_phy_device = rtl8226_match_phy_device,
+ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .read_status = rtl822x_read_status,
+@@ -1230,6 +1231,7 @@ static struct phy_driver realtek_drvs[]
}, {
PHY_ID_MATCH_EXACT(0x001cc840),
.name = "RTL8226B_RTL8221B 2.5Gbps PHY",
-@@ -1082,6 +1083,7 @@ static struct phy_driver realtek_drvs[]
- .write_page = rtl821x_write_page,
- .read_mmd = rtl822x_read_mmd,
- .write_mmd = rtl822x_write_mmd,
+ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
+@@ -1244,6 +1246,7 @@ static struct phy_driver realtek_drvs[]
}, {
PHY_ID_MATCH_EXACT(0x001cc838),
.name = "RTL8226-CG 2.5Gbps PHY",
-@@ -1092,6 +1094,7 @@ static struct phy_driver realtek_drvs[]
- .resume = rtlgen_resume,
- .read_page = rtl821x_read_page,
- .write_page = rtl821x_write_page,
+ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .read_status = rtl822x_read_status,
+@@ -1254,6 +1257,7 @@ static struct phy_driver realtek_drvs[]
}, {
PHY_ID_MATCH_EXACT(0x001cc848),
.name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
-@@ -1102,6 +1105,7 @@ static struct phy_driver realtek_drvs[]
- .resume = rtlgen_resume,
- .read_page = rtl821x_read_page,
- .write_page = rtl821x_write_page,
+ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
+@@ -1266,6 +1270,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
++ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
+@@ -1278,6 +1283,7 @@ static struct phy_driver realtek_drvs[]
}, {
- PHY_ID_MATCH_EXACT(0x001cc849),
- .name = "RTL8221B-VB-CG 2.5Gbps PHY",
-@@ -1113,6 +1117,7 @@ static struct phy_driver realtek_drvs[]
- .resume = rtlgen_resume,
- .read_page = rtl821x_read_page,
- .write_page = rtl821x_write_page,
+ .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
+ .soft_reset = genphy_soft_reset,
+ .config_init = rtl822xb_config_init,
+ .get_rate_matching = rtl822xb_get_rate_matching,
+ .get_features = rtl822x_c45_get_features,
+@@ -1288,6 +1294,7 @@ static struct phy_driver realtek_drvs[]
}, {
- PHY_ID_MATCH_EXACT(0x001cc84a),
- .name = "RTL8221B-VM-CG 2.5Gbps PHY",
-@@ -1124,6 +1129,7 @@ static struct phy_driver realtek_drvs[]
- .resume = rtlgen_resume,
- .read_page = rtl821x_read_page,
- .write_page = rtl821x_write_page,
+ .match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
+ .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
+ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
+@@ -1300,6 +1307,7 @@ static struct phy_driver realtek_drvs[]
}, {
- PHY_ID_MATCH_EXACT(0x001cc961),
- .name = "RTL8366RB Gigabit Ethernet",
+ .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
+ .name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
++ .soft_reset = genphy_soft_reset,
+ .config_init = rtl822xb_config_init,
+ .get_rate_matching = rtl822xb_get_rate_matching,
+ .get_features = rtl822x_c45_get_features,
-From 2b1b8c4c215af7988136401c902338d091d408a1 Mon Sep 17 00:00:00 2001
+From d54ef6aea00e7a6ace439baade6ad0aa38ee4b04 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Mon, 3 Apr 2023 01:21:57 +0300
-Subject: [PATCH 2/2] net: phy: realtek: disable SGMII in-band AN for 2.5G PHYs
+Subject: [PATCH 287/326] net: phy: realtek: disable SGMII in-band AN for 2.5G
+ PHYs
MAC drivers don't use SGMII in-band autonegotiation unless told to do so
in device tree using 'managed = "in-band-status"'. When using MDIO to
Tested-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
- drivers/net/phy/realtek.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
+ drivers/net/phy/realtek.c | 27 +++++++++++++++++++++++++--
+ 1 file changed, 25 insertions(+), 2 deletions(-)
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
-@@ -913,6 +913,7 @@ static irqreturn_t rtl9000a_handle_inter
- static int rtl8221b_config_init(struct phy_device *phydev)
+@@ -682,8 +682,8 @@ static int rtl822x_write_mmd(struct phy_
+ static int rtl822xb_config_init(struct phy_device *phydev)
{
- u16 option_mode;
-+ int val;
+ bool has_2500, has_sgmii;
++ int ret, val;
+ u16 mode;
+- int ret;
- switch (phydev->interface) {
- case PHY_INTERFACE_MODE_2500BASEX:
-@@ -949,6 +950,13 @@ static int rtl8221b_config_init(struct p
- break;
- }
+ has_2500 = test_bit(PHY_INTERFACE_MODE_2500BASEX,
+ phydev->host_interfaces) ||
+@@ -733,7 +733,29 @@ static int rtl822xb_config_init(struct p
+ if (ret < 0)
+ return ret;
+- return phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
++ if (ret < 0)
++ return ret;
++
+ /* Disable SGMII AN */
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7588, 0x2);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7589, 0x71d0);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7587, 0x3);
-+ phy_read_mmd_poll_timeout(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7587,
-+ val, !(val & BIT(0)), 500, 100000, false);
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7588, 0x2);
++ if (ret < 0)
++ return ret;
++
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7589, 0x71d0);
++ if (ret < 0)
++ return ret;
++
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7587, 0x3);
++ if (ret < 0)
++ return ret;
++
++ ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, 0x7587,
++ val, !(val & BIT(0)), 500, 100000, false);
++ if (ret < 0)
++ return ret;
+
- return 0;
++ return 0;
}
+ static int rtl822xb_get_rate_matching(struct phy_device *phydev,
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
-@@ -765,9 +765,11 @@ static bool rtlgen_supports_2_5gbps(stru
+@@ -948,9 +948,11 @@ static bool rtlgen_supports_2_5gbps(stru
{
int val;
+ rtl821x_write_page(phydev, 0);
+ mutex_unlock(&phydev->mdio.bus->mdio_lock);
- return val >= 0 && val & RTL_SUPPORTS_2500FULL;
+ return val >= 0 && val & MDIO_PMA_SPEED_2_5G;
}
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
-@@ -69,10 +69,6 @@
- #define RTL_SUPPORTS_5000FULL BIT(14)
- #define RTL_SUPPORTS_2500FULL BIT(13)
- #define RTL_SUPPORTS_10000FULL BIT(0)
--#define RTL_ADV_2500FULL BIT(7)
--#define RTL_LPADV_10000FULL BIT(11)
--#define RTL_LPADV_5000FULL BIT(6)
--#define RTL_LPADV_2500FULL BIT(5)
+@@ -806,7 +806,8 @@ static int rtl822x_config_aneg(struct ph
- #define RTL9000A_GINMR 0x14
- #define RTL9000A_GINMR_LINK_STATUS BIT(4)
-@@ -699,14 +695,11 @@ static int rtl822x_config_aneg(struct ph
- int ret = 0;
-
- if (phydev->autoneg == AUTONEG_ENABLE) {
-- u16 adv2500 = 0;
--
-- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
-- phydev->advertising))
-- adv2500 = RTL_ADV_2500FULL;
--
ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
-- RTL_ADV_2500FULL, adv2500);
-+ MDIO_AN_10GBT_CTRL_ADV10G |
+ MDIO_AN_10GBT_CTRL_ADV2_5G |
+- MDIO_AN_10GBT_CTRL_ADV5G,
+ MDIO_AN_10GBT_CTRL_ADV5G |
-+ MDIO_AN_10GBT_CTRL_ADV2_5G,
-+ linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising));
++ MDIO_AN_10GBT_CTRL_ADV10G,
+ adv);
if (ret < 0)
return ret;
- }
-@@ -743,12 +736,7 @@ static int rtl822x_read_status(struct ph
- if (lpadv < 0)
- return lpadv;
-
-- linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
-- phydev->lp_advertising, lpadv & RTL_LPADV_10000FULL);
-- linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
-- phydev->lp_advertising, lpadv & RTL_LPADV_5000FULL);
-- linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
-- phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL);
-+ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv);
- }
-
- ret = rtlgen_read_status(phydev);
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
-@@ -736,6 +736,10 @@ static int rtl822x_read_status(struct ph
+@@ -846,6 +846,10 @@ static int rtl822x_read_status(struct ph
if (lpadv < 0)
return lpadv;
+ !(lpadv & MDIO_AN_10GBT_STAT_LOCOK))
+ lpadv = 0;
+
- mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv);
+ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising,
+ lpadv);
}
-
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
-@@ -63,6 +63,10 @@
- #define RTL8221B_SERDES_OPTION_MODE_2500BASEX 2
- #define RTL8221B_SERDES_OPTION_MODE_HISGMII 3
+@@ -73,6 +73,10 @@
+
+ #define RTL822X_VND2_PHYSR 0xa434
+#define RTL8221B_PHYCR1 0xa430
+#define RTL8221B_PHYCR1_ALDPS_EN BIT(2)
#define RTL8366RB_POWER_SAVE 0x15
#define RTL8366RB_POWER_SAVE_ON BIT(12)
-@@ -778,6 +782,25 @@ static int rtl8226_match_phy_device(stru
- rtlgen_supports_2_5gbps(phydev);
+@@ -1003,6 +1007,25 @@ static int rtl8221b_vn_cg_c45_match_phy_
+ return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true);
}
+static int rtl822x_probe(struct phy_device *phydev)
+ struct device *dev = &phydev->mdio.dev;
+ int val;
+
-+ val = phy_read_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, RTL8221B_PHYCR1);
++ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, RTL8221B_PHYCR1);
+ if (val < 0)
+ return val;
+
+ else
+ val &= ~(RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN);
+
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, RTL8221B_PHYCR1, val);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL8221B_PHYCR1, val);
+
+ return 0;
+}
static int rtlgen_resume(struct phy_device *phydev)
{
int ret = genphy_resume(phydev);
-@@ -1091,6 +1114,7 @@ static struct phy_driver realtek_drvs[]
+@@ -1275,6 +1298,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ PHY_ID_MATCH_EXACT(0x001cc838),
.name = "RTL8226-CG 2.5Gbps PHY",
++ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
.get_features = rtl822x_get_features,
.config_aneg = rtl822x_config_aneg,
-+ .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
-@@ -1102,6 +1126,7 @@ static struct phy_driver realtek_drvs[]
+@@ -1286,6 +1310,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ PHY_ID_MATCH_EXACT(0x001cc848),
.name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
++ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
.get_features = rtl822x_get_features,
.config_aneg = rtl822x_config_aneg,
+@@ -1299,6 +1324,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
+ .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
-@@ -1114,6 +1139,7 @@ static struct phy_driver realtek_drvs[]
+ .soft_reset = genphy_soft_reset,
.get_features = rtl822x_get_features,
- .config_init = rtl8221b_config_init,
.config_aneg = rtl822x_config_aneg,
+@@ -1312,6 +1338,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
++ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .config_init = rtl822xb_config_init,
+ .get_rate_matching = rtl822xb_get_rate_matching,
+@@ -1323,6 +1350,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
+ .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
+ .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
-@@ -1126,6 +1152,7 @@ static struct phy_driver realtek_drvs[]
+ .soft_reset = genphy_soft_reset,
.get_features = rtl822x_get_features,
.config_aneg = rtl822x_config_aneg,
- .config_init = rtl8221b_config_init,
+@@ -1336,6 +1364,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
+ .name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
+ .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
+ .soft_reset = genphy_soft_reset,
+ .config_init = rtl822xb_config_init,
+ .get_rate_matching = rtl822xb_get_rate_matching,
+++ /dev/null
-From 0de82310d2b32e78ff79d42c08b1122a6ede3778 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 30 Apr 2023 00:15:41 +0100
-Subject: [PATCH] net: phy: realtek: detect early version of RTL8221B
-
-Early versions (?) of the RTL8221B PHY cannot be identified in a regular
-Clause-45 bus scan as the PHY doesn't report the implemented MMDs
-correctly but returns 0 instead.
-Implement custom identify function using the PKGID instead of iterating
-over the implemented MMDs.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -81,6 +81,7 @@
-
- #define RTL_GENERIC_PHYID 0x001cc800
- #define RTL_8211FVD_PHYID 0x001cc878
-+#define RTL_8221B_VB_CG_PHYID 0x001cc849
-
- MODULE_DESCRIPTION("Realtek PHY driver");
- MODULE_AUTHOR("Johnson Leung");
-@@ -782,6 +783,38 @@ static int rtl8226_match_phy_device(stru
- rtlgen_supports_2_5gbps(phydev);
- }
-
-+static int rtl8221b_vb_cg_match_phy_device(struct phy_device *phydev)
-+{
-+ int val;
-+ u32 id;
-+
-+ if (phydev->mdio.bus->read_c45) {
-+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID1);
-+ if (val < 0)
-+ return 0;
-+
-+ id = val << 16;
-+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID2);
-+ if (val < 0)
-+ return 0;
-+
-+ id |= val;
-+ } else {
-+ val = phy_read(phydev, MII_PHYSID1);
-+ if (val < 0)
-+ return 0;
-+
-+ id = val << 16;
-+ val = phy_read(phydev, MII_PHYSID2);
-+ if (val < 0)
-+ return 0;
-+
-+ id |= val;
-+ }
-+
-+ return (id == RTL_8221B_VB_CG_PHYID);
-+}
-+
- static int rtl822x_probe(struct phy_device *phydev)
- {
- struct device *dev = &phydev->mdio.dev;
-@@ -1134,7 +1167,7 @@ static struct phy_driver realtek_drvs[]
- .write_page = rtl821x_write_page,
- .soft_reset = genphy_soft_reset,
- }, {
-- PHY_ID_MATCH_EXACT(0x001cc849),
-+ .match_phy_device = rtl8221b_vb_cg_match_phy_device,
- .name = "RTL8221B-VB-CG 2.5Gbps PHY",
- .get_features = rtl822x_get_features,
- .config_init = rtl8221b_config_init,
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
-@@ -1010,6 +1010,51 @@ static int rtl8221b_config_init(struct p
- return 0;
+@@ -1161,6 +1161,51 @@ static irqreturn_t rtl9000a_handle_inter
+ return IRQ_HANDLED;
}
+static int rtl8221b_ack_interrupt(struct phy_device *phydev)
+{
+ int err;
+
-+ err = phy_read_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d4);
++ err = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xa4d4);
+
+ return (err < 0) ? err : 0;
+}
+ if (err)
+ return err;
+
-+ err = phy_write_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d2, 0x7ff);
++ err = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xa4d2, 0x7ff);
+ } else {
-+ err = phy_write_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d2, 0x0);
++ err = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xa4d2, 0x0);
+ if (err)
+ return err;
+
static struct phy_driver realtek_drvs[] = {
{
PHY_ID_MATCH_EXACT(0x00008201),
-@@ -1172,6 +1217,8 @@ static struct phy_driver realtek_drvs[]
+@@ -1324,6 +1369,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,
+ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+@@ -1338,6 +1385,8 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
++ .config_intr = rtl8221b_config_intr,
++ .handle_interrupt = rtl8221b_handle_interrupt,
+ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .config_init = rtl822xb_config_init,
+@@ -1350,6 +1399,8 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vn_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,
+ .soft_reset = genphy_soft_reset,
.get_features = rtl822x_get_features,
- .config_init = rtl8221b_config_init,
- .config_aneg = rtl822x_config_aneg,
+@@ -1364,6 +1415,8 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
+ .name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
+ .config_intr = rtl8221b_config_intr,
+ .handle_interrupt = rtl8221b_handle_interrupt,
.probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
+ .soft_reset = genphy_soft_reset,
+ .config_init = rtl822xb_config_init,