[openwrt/openwrt] kernel: backport upstream realtek PHY patches

LEDE Commits lede-commits at lists.infradead.org
Sat Nov 15 11:44:27 PST 2025


hauke pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/787c1106d51b3c6c8c35f51303c123aedda9da88

commit 787c1106d51b3c6c8c35f51303c123aedda9da88
Author: Aleksander Jan Bajkowski <olek2 at wp.pl>
AuthorDate: Sun Nov 2 16:11:08 2025 +0100

    kernel: backport upstream realtek PHY patches
    
    Changelog:
    18aa36238a4d: net: phy: realtek: add interrupt support for RTL8221B
    61958b33ef0b: net: phy: realtek: Add RTL8224 cable testing support
    ffff5c8fc2af: net: phy: realtek: fix rtl8221b-vm-cg name
    2c67301584f2: net: phy: realtek: Avoid PHYCR2 access if PHYCR2 not present
    f63f21e82eca: net: phy: realtek: support for TRIGGER_NETDEV_LINK on RTL8211E and RTL8211F
    a9b24b3583ae: net: phy: realtek: add error handling to rtl8211f_get_wol
    
    Signed-off-by: Aleksander Jan Bajkowski <olek2 at wp.pl>
    Link: https://github.com/openwrt/openwrt/pull/20650
    Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
---
 ...ltek-add-error-handling-to-rtl8211f_get_w.patch |  39 +++
 ...ltek-support-for-TRIGGER_NETDEV_LINK-on-R.patch | 105 ++++++++
 ...ltek-Avoid-PHYCR2-access-if-PHYCR2-not-pr.patch |  61 +++++
 ...8-net-phy-realtek-fix-rtl8221b-vm-cg-name.patch |  70 ++++++
 ...realtek-Add-RTL8224-cable-testing-support.patch | 272 +++++++++++++++++++++
 ...ealtek-add-interrupt-support-for-RTL8221B.patch | 105 ++++++++
 ...ltek-add-error-handling-to-rtl8211f_get_w.patch |  39 +++
 ...ltek-support-for-TRIGGER_NETDEV_LINK-on-R.patch | 105 ++++++++
 ...ltek-Avoid-PHYCR2-access-if-PHYCR2-not-pr.patch |  61 +++++
 ...8-net-phy-realtek-fix-rtl8221b-vm-cg-name.patch |  70 ++++++
 ...realtek-Add-RTL8224-cable-testing-support.patch | 272 +++++++++++++++++++++
 ...ealtek-add-interrupt-support-for-RTL8221B.patch | 105 ++++++++
 ...altek-use-genphy_soft_reset-for-2.5G-PHYs.patch |  26 +-
 ...ek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch |   4 +-
 ...ltek-make-sure-paged-read-is-protected-by.patch |   2 +-
 .../720-04-net-phy-realtek-setup-aldps.patch       |   8 +-
 ...-realtek-detect-early-version-of-RTL8221B.patch |   2 +-
 ...phy-realtek-support-interrupt-of-RTL8221B.patch | 102 --------
 ...phy-realtek-mark-existing-MMDs-as-present.patch |   2 +-
 ...net-phy-realtek-work-around-broken-serdes.patch |   6 +-
 ...09-net-phy-realtek-disable-MDIO-broadcast.patch |   2 +-
 ...altek-use-genphy_soft_reset-for-2.5G-PHYs.patch |  28 +--
 ...ek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch |   4 +-
 ...ltek-make-sure-paged-read-is-protected-by.patch |   2 +-
 .../720-04-net-phy-realtek-setup-aldps.patch       |   8 +-
 ...-realtek-detect-early-version-of-RTL8221B.patch |   2 +-
 ...phy-realtek-support-interrupt-of-RTL8221B.patch | 102 --------
 ...phy-realtek-mark-existing-MMDs-as-present.patch |   2 +-
 ...net-phy-realtek-work-around-broken-serdes.patch |   6 +-
 ...09-net-phy-realtek-disable-MDIO-broadcast.patch |   2 +-
 30 files changed, 1357 insertions(+), 257 deletions(-)

diff --git a/target/linux/generic/backport-6.12/784-01-v6.17-net-phy-realtek-add-error-handling-to-rtl8211f_get_w.patch b/target/linux/generic/backport-6.12/784-01-v6.17-net-phy-realtek-add-error-handling-to-rtl8211f_get_w.patch
new file mode 100644
index 0000000000..5f3b119a89
--- /dev/null
+++ b/target/linux/generic/backport-6.12/784-01-v6.17-net-phy-realtek-add-error-handling-to-rtl8211f_get_w.patch
@@ -0,0 +1,39 @@
+From a9b24b3583ae1da7dbda031f141264f2da260219 Mon Sep 17 00:00:00 2001
+From: Daniel Braunwarth <daniel.braunwarth at kuka.com>
+Date: Tue, 24 Jun 2025 16:17:33 +0200
+Subject: [PATCH] net: phy: realtek: add error handling to rtl8211f_get_wol
+
+We should check if the WOL settings was successfully read from the PHY.
+
+In case this fails we cannot just use the error code and proceed.
+
+Signed-off-by: Daniel Braunwarth <daniel.braunwarth at kuka.com>
+Reported-by: Jon Hunter <jonathanh at nvidia.com>
+Closes: https://lore.kernel.org/baaa083b-9a69-460f-ab35-2a7cb3246ffd@nvidia.com
+Reviewed-by: Andrew Lunn <andrew at lunn.ch>
+Link: https://patch.msgid.link/20250624-realtek_fixes-v1-1-02a0b7c369bc@kuka.com
+Signed-off-by: Jakub Kicinski <kuba at kernel.org>
+---
+ drivers/net/phy/realtek/realtek_main.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/phy/realtek/realtek_main.c
++++ b/drivers/net/phy/realtek/realtek_main.c
+@@ -436,9 +436,15 @@ static irqreturn_t rtl8211f_handle_inter
+ 
+ static void rtl8211f_get_wol(struct phy_device *dev, struct ethtool_wolinfo *wol)
+ {
++	int wol_events;
++
+ 	wol->supported = WAKE_MAGIC;
+-	if (phy_read_paged(dev, RTL8211F_WOL_SETTINGS_PAGE, RTL8211F_WOL_SETTINGS_EVENTS)
+-	    & RTL8211F_WOL_EVENT_MAGIC)
++
++	wol_events = phy_read_paged(dev, RTL8211F_WOL_SETTINGS_PAGE, RTL8211F_WOL_SETTINGS_EVENTS);
++	if (wol_events < 0)
++		return;
++
++	if (wol_events & RTL8211F_WOL_EVENT_MAGIC)
+ 		wol->wolopts = WAKE_MAGIC;
+ }
+ 
diff --git a/target/linux/generic/backport-6.12/784-02-v6.18-net-phy-realtek-support-for-TRIGGER_NETDEV_LINK-on-R.patch b/target/linux/generic/backport-6.12/784-02-v6.18-net-phy-realtek-support-for-TRIGGER_NETDEV_LINK-on-R.patch
new file mode 100644
index 0000000000..83ea4928e9
--- /dev/null
+++ b/target/linux/generic/backport-6.12/784-02-v6.18-net-phy-realtek-support-for-TRIGGER_NETDEV_LINK-on-R.patch
@@ -0,0 +1,105 @@
+From f63f21e82ecafd288b100ea161247820bf1e92c4 Mon Sep 17 00:00:00 2001
+From: Aleksander Jan Bajkowski <olek2 at wp.pl>
+Date: Mon, 25 Aug 2025 23:09:49 +0200
+Subject: [PATCH] net: phy: realtek: support for TRIGGER_NETDEV_LINK on
+ RTL8211E and RTL8211F
+
+This patch adds support for the TRIGGER_NETDEV_LINK trigger. It activates
+the LED when a link is established, regardless of the speed.
+
+Tested on Orange Pi PC2 with RTL8211E PHY.
+
+Signed-off-by: Aleksander Jan Bajkowski <olek2 at wp.pl>
+Reviewed-by: Andrew Lunn <andrew at lunn.ch>
+Link: https://patch.msgid.link/20250825211059.143231-1-olek2@wp.pl
+Signed-off-by: Jakub Kicinski <kuba at kernel.org>
+---
+ drivers/net/phy/realtek/realtek_main.c | 39 +++++++++++++++++++++-----
+ 1 file changed, 32 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/phy/realtek/realtek_main.c
++++ b/drivers/net/phy/realtek/realtek_main.c
+@@ -648,7 +648,8 @@ static int rtl821x_resume(struct phy_dev
+ static int rtl8211x_led_hw_is_supported(struct phy_device *phydev, u8 index,
+ 					unsigned long rules)
+ {
+-	const unsigned long mask = BIT(TRIGGER_NETDEV_LINK_10) |
++	const unsigned long mask = BIT(TRIGGER_NETDEV_LINK) |
++				   BIT(TRIGGER_NETDEV_LINK_10) |
+ 				   BIT(TRIGGER_NETDEV_LINK_100) |
+ 				   BIT(TRIGGER_NETDEV_LINK_1000) |
+ 				   BIT(TRIGGER_NETDEV_RX) |
+@@ -706,6 +707,12 @@ static int rtl8211f_led_hw_control_get(s
+ 	if (val & RTL8211F_LEDCR_LINK_1000)
+ 		__set_bit(TRIGGER_NETDEV_LINK_1000, rules);
+ 
++	if ((val & RTL8211F_LEDCR_LINK_10) &&
++	    (val & RTL8211F_LEDCR_LINK_100) &&
++	    (val & RTL8211F_LEDCR_LINK_1000)) {
++		__set_bit(TRIGGER_NETDEV_LINK, rules);
++	}
++
+ 	if (val & RTL8211F_LEDCR_ACT_TXRX) {
+ 		__set_bit(TRIGGER_NETDEV_RX, rules);
+ 		__set_bit(TRIGGER_NETDEV_TX, rules);
+@@ -723,14 +730,20 @@ static int rtl8211f_led_hw_control_set(s
+ 	if (index >= RTL8211x_LED_COUNT)
+ 		return -EINVAL;
+ 
+-	if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
++	if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
++	    test_bit(TRIGGER_NETDEV_LINK_10, &rules)) {
+ 		reg |= RTL8211F_LEDCR_LINK_10;
++	}
+ 
+-	if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
++	if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
++	    test_bit(TRIGGER_NETDEV_LINK_100, &rules)) {
+ 		reg |= RTL8211F_LEDCR_LINK_100;
++	}
+ 
+-	if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
++	if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
++	    test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) {
+ 		reg |= RTL8211F_LEDCR_LINK_1000;
++	}
+ 
+ 	if (test_bit(TRIGGER_NETDEV_RX, &rules) ||
+ 	    test_bit(TRIGGER_NETDEV_TX, &rules)) {
+@@ -778,6 +791,12 @@ static int rtl8211e_led_hw_control_get(s
+ 	if (cr2 & RTL8211E_LEDCR2_LINK_1000)
+ 		__set_bit(TRIGGER_NETDEV_LINK_1000, rules);
+ 
++	if ((cr2 & RTL8211E_LEDCR2_LINK_10) &&
++	    (cr2 & RTL8211E_LEDCR2_LINK_100) &&
++	    (cr2 & RTL8211E_LEDCR2_LINK_1000)) {
++		__set_bit(TRIGGER_NETDEV_LINK, rules);
++	}
++
+ 	return ret;
+ }
+ 
+@@ -805,14 +824,20 @@ static int rtl8211e_led_hw_control_set(s
+ 	if (ret < 0)
+ 		return ret;
+ 
+-	if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
++	if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
++	    test_bit(TRIGGER_NETDEV_LINK_10, &rules)) {
+ 		cr2 |= RTL8211E_LEDCR2_LINK_10;
++	}
+ 
+-	if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
++	if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
++	    test_bit(TRIGGER_NETDEV_LINK_100, &rules)) {
+ 		cr2 |= RTL8211E_LEDCR2_LINK_100;
++	}
+ 
+-	if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
++	if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
++	    test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) {
+ 		cr2 |= RTL8211E_LEDCR2_LINK_1000;
++	}
+ 
+ 	cr2 <<= RTL8211E_LEDCR2_SHIFT * index;
+ 	ret = rtl821x_modify_ext_page(phydev, RTL8211E_LEDCR_EXT_PAGE,
diff --git a/target/linux/generic/backport-6.12/784-03-v6.18-net-phy-realtek-Avoid-PHYCR2-access-if-PHYCR2-not-pr.patch b/target/linux/generic/backport-6.12/784-03-v6.18-net-phy-realtek-Avoid-PHYCR2-access-if-PHYCR2-not-pr.patch
new file mode 100644
index 0000000000..681b234fc5
--- /dev/null
+++ b/target/linux/generic/backport-6.12/784-03-v6.18-net-phy-realtek-Avoid-PHYCR2-access-if-PHYCR2-not-pr.patch
@@ -0,0 +1,61 @@
+From 2c67301584f2671e320236df6bbe75ae09feb4d0 Mon Sep 17 00:00:00 2001
+From: Marek Vasut <marek.vasut at mailbox.org>
+Date: Sat, 11 Oct 2025 13:02:49 +0200
+Subject: [PATCH] net: phy: realtek: Avoid PHYCR2 access if PHYCR2 not present
+
+The driver is currently checking for PHYCR2 register presence in
+rtl8211f_config_init(), but it does so after accessing PHYCR2 to
+disable EEE. This was introduced in commit bfc17c165835 ("net:
+phy: realtek: disable PHY-mode EEE"). Move the PHYCR2 presence
+test before the EEE disablement and simplify the code.
+
+Fixes: bfc17c165835 ("net: phy: realtek: disable PHY-mode EEE")
+Signed-off-by: Marek Vasut <marek.vasut at mailbox.org>
+Reviewed-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
+Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
+Link: https://patch.msgid.link/20251011110309.12664-1-marek.vasut@mailbox.org
+Signed-off-by: Jakub Kicinski <kuba at kernel.org>
+---
+ drivers/net/phy/realtek/realtek_main.c | 23 +++++++++++------------
+ 1 file changed, 11 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/phy/realtek/realtek_main.c
++++ b/drivers/net/phy/realtek/realtek_main.c
+@@ -589,26 +589,25 @@ static int rtl8211f_config_init(struct p
+ 			str_enabled_disabled(val_rxdly));
+ 	}
+ 
++	if (!priv->has_phycr2)
++		return 0;
++
+ 	/* Disable PHY-mode EEE so LPI is passed to the MAC */
+ 	ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR2,
+ 			       RTL8211F_PHYCR2_PHY_EEE_ENABLE, 0);
+ 	if (ret)
+ 		return ret;
+ 
+-	if (priv->has_phycr2) {
+-		ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE,
+-				       RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN,
+-				       priv->phycr2);
+-		if (ret < 0) {
+-			dev_err(dev, "clkout configuration failed: %pe\n",
+-				ERR_PTR(ret));
+-			return ret;
+-		}
+-
+-		return genphy_soft_reset(phydev);
++	ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE,
++			       RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN,
++			       priv->phycr2);
++	if (ret < 0) {
++		dev_err(dev, "clkout configuration failed: %pe\n",
++			ERR_PTR(ret));
++		return ret;
+ 	}
+ 
+-	return 0;
++	return genphy_soft_reset(phydev);
+ }
+ 
+ static int rtl821x_suspend(struct phy_device *phydev)
diff --git a/target/linux/generic/backport-6.12/784-04-v6.18-net-phy-realtek-fix-rtl8221b-vm-cg-name.patch b/target/linux/generic/backport-6.12/784-04-v6.18-net-phy-realtek-fix-rtl8221b-vm-cg-name.patch
new file mode 100644
index 0000000000..402bdeb9a3
--- /dev/null
+++ b/target/linux/generic/backport-6.12/784-04-v6.18-net-phy-realtek-fix-rtl8221b-vm-cg-name.patch
@@ -0,0 +1,70 @@
+From ffff5c8fc2af2218a3332b3d5b97654599d50cde Mon Sep 17 00:00:00 2001
+From: Aleksander Jan Bajkowski <olek2 at wp.pl>
+Date: Thu, 16 Oct 2025 21:22:52 +0200
+Subject: [PATCH] net: phy: realtek: fix rtl8221b-vm-cg name
+
+When splitting the RTL8221B-VM-CG into C22 and C45 variants, the name was
+accidentally changed to RTL8221B-VN-CG. This patch brings back the previous
+part number.
+
+Fixes: ad5ce743a6b0 ("net: phy: realtek: Add driver instances for rtl8221b via Clause 45")
+Signed-off-by: Aleksander Jan Bajkowski <olek2 at wp.pl>
+Reviewed-by: Simon Horman <horms at kernel.org>
+Link: https://patch.msgid.link/20251016192325.2306757-1-olek2@wp.pl
+Signed-off-by: Jakub Kicinski <kuba at kernel.org>
+---
+ drivers/net/phy/realtek/realtek_main.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/phy/realtek/realtek_main.c
++++ b/drivers/net/phy/realtek/realtek_main.c
+@@ -156,7 +156,7 @@
+ #define RTL_8211FVD_PHYID			0x001cc878
+ #define RTL_8221B				0x001cc840
+ #define RTL_8221B_VB_CG				0x001cc849
+-#define RTL_8221B_VN_CG				0x001cc84a
++#define RTL_8221B_VM_CG				0x001cc84a
+ #define RTL_8251B				0x001cc862
+ #define RTL_8261C				0x001cc890
+ 
+@@ -1415,16 +1415,16 @@ static int rtl8221b_vb_cg_c45_match_phy_
+ 	return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true);
+ }
+ 
+-static int rtl8221b_vn_cg_c22_match_phy_device(struct phy_device *phydev,
++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_VN_CG, false);
++	return rtlgen_is_c45_match(phydev, RTL_8221B_VM_CG, false);
+ }
+ 
+-static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev,
++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_VN_CG, true);
++	return rtlgen_is_c45_match(phydev, RTL_8221B_VM_CG, true);
+ }
+ 
+ static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev,
+@@ -1771,7 +1771,7 @@ static struct phy_driver realtek_drvs[]
+ 		.suspend        = genphy_c45_pma_suspend,
+ 		.resume         = rtlgen_c45_resume,
+ 	}, {
+-		.match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
++		.match_phy_device = rtl8221b_vm_cg_c22_match_phy_device,
+ 		.name           = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
+ 		.probe		= rtl822x_probe,
+ 		.get_features   = rtl822x_get_features,
+@@ -1784,8 +1784,8 @@ 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)",
++		.match_phy_device = rtl8221b_vm_cg_c45_match_phy_device,
++		.name           = "RTL8221B-VM-CG 2.5Gbps PHY (C45)",
+ 		.probe		= rtl822x_probe,
+ 		.config_init    = rtl822xb_config_init,
+ 		.get_rate_matching = rtl822xb_get_rate_matching,
diff --git a/target/linux/generic/backport-6.12/784-05-v6.19-net-phy-realtek-Add-RTL8224-cable-testing-support.patch b/target/linux/generic/backport-6.12/784-05-v6.19-net-phy-realtek-Add-RTL8224-cable-testing-support.patch
new file mode 100644
index 0000000000..90a3dc1f7b
--- /dev/null
+++ b/target/linux/generic/backport-6.12/784-05-v6.19-net-phy-realtek-Add-RTL8224-cable-testing-support.patch
@@ -0,0 +1,272 @@
+From 61958b33ef0bab1c1874c933cd3910f495526782 Mon Sep 17 00:00:00 2001
+From: Issam Hamdi <ih at simonwunderlich.de>
+Date: Fri, 24 Oct 2025 11:49:00 +0200
+Subject: [PATCH] net: phy: realtek: Add RTL8224 cable testing support
+
+The RTL8224 can detect open pairs and short types (in same pair or some
+other pair). The distance to this problem can be estimated. This is done
+for each of the 4 pairs separately.
+
+It is not meant to be run while there is an active link partner because
+this interferes with the active test pulses.
+
+Output with open 50 m cable:
+
+  Pair A code Open Circuit, source: TDR
+  Pair A, fault length: 51.79m, source: TDR
+  Pair B code Open Circuit, source: TDR
+  Pair B, fault length: 51.28m, source: TDR
+  Pair C code Open Circuit, source: TDR
+  Pair C, fault length: 50.46m, source: TDR
+  Pair D code Open Circuit, source: TDR
+  Pair D, fault length: 51.12m, source: TDR
+
+Terminated cable:
+
+  Pair A code OK, source: TDR
+  Pair B code OK, source: TDR
+  Pair C code OK, source: TDR
+  Pair D code OK, source: TDR
+
+Shorted cable (both short types are at roughly the same distance)
+
+  Pair A code Short to another pair, source: TDR
+  Pair A, fault length: 2.35m, source: TDR
+  Pair B code Short to another pair, source: TDR
+  Pair B, fault length: 2.15m, source: TDR
+  Pair C code OK, source: TDR
+  Pair D code Short within Pair, source: TDR
+  Pair D, fault length: 1.94m, source: TDR
+
+Signed-off-by: Issam Hamdi <ih at simonwunderlich.de>
+Co-developed-by: Sven Eckelmann <se at simonwunderlich.de>
+Signed-off-by: Sven Eckelmann <se at simonwunderlich.de>
+Reviewed-by: Andrew Lunn <andrew at lunn.ch>
+Link: https://patch.msgid.link/20251024-rtl8224-cable-test-v1-1-e3cda89ac98f@simonwunderlich.de
+Signed-off-by: Jakub Kicinski <kuba at kernel.org>
+---
+ drivers/net/phy/realtek/realtek_main.c | 187 +++++++++++++++++++++++++
+ 1 file changed, 187 insertions(+)
+
+--- a/drivers/net/phy/realtek/realtek_main.c
++++ b/drivers/net/phy/realtek/realtek_main.c
+@@ -8,6 +8,7 @@
+  * Copyright (c) 2004 Freescale Semiconductor, Inc.
+  */
+ #include <linux/bitops.h>
++#include <linux/ethtool_netlink.h>
+ #include <linux/of.h>
+ #include <linux/phy.h>
+ #include <linux/netdevice.h>
+@@ -129,6 +130,27 @@
+  */
+ #define RTL822X_VND2_C22_REG(reg)		(0xa400 + 2 * (reg))
+ 
++#define RTL8224_MII_RTCT			0x11
++#define RTL8224_MII_RTCT_ENABLE			BIT(0)
++#define RTL8224_MII_RTCT_PAIR_A			BIT(4)
++#define RTL8224_MII_RTCT_PAIR_B			BIT(5)
++#define RTL8224_MII_RTCT_PAIR_C			BIT(6)
++#define RTL8224_MII_RTCT_PAIR_D			BIT(7)
++#define RTL8224_MII_RTCT_DONE			BIT(15)
++
++#define RTL8224_MII_SRAM_ADDR			0x1b
++#define RTL8224_MII_SRAM_DATA			0x1c
++
++#define RTL8224_SRAM_RTCT_FAULT(pair)		(0x8026 + (pair) * 4)
++#define RTL8224_SRAM_RTCT_FAULT_BUSY		BIT(0)
++#define RTL8224_SRAM_RTCT_FAULT_OPEN		BIT(3)
++#define RTL8224_SRAM_RTCT_FAULT_SAME_SHORT	BIT(4)
++#define RTL8224_SRAM_RTCT_FAULT_OK		BIT(5)
++#define RTL8224_SRAM_RTCT_FAULT_DONE		BIT(6)
++#define RTL8224_SRAM_RTCT_FAULT_CROSS_SHORT	BIT(7)
++
++#define RTL8224_SRAM_RTCT_LEN(pair)		(0x8028 + (pair) * 4)
++
+ #define RTL8366RB_POWER_SAVE			0x15
+ #define RTL8366RB_POWER_SAVE_ON			BIT(12)
+ 
+@@ -1345,6 +1367,168 @@ static int rtl822xb_c45_read_status(stru
+ 	return 0;
+ }
+ 
++static int rtl8224_cable_test_start(struct phy_device *phydev)
++{
++	u32 val;
++	int ret;
++
++	/* disable auto-negotiation and force 1000/Full */
++	ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2,
++			     RTL822X_VND2_C22_REG(MII_BMCR),
++			     BMCR_ANENABLE | BMCR_SPEED100 | BMCR_SPEED10,
++			     BMCR_SPEED1000 | BMCR_FULLDPLX);
++	if (ret)
++		return ret;
++
++	mdelay(500);
++
++	/* trigger cable test */
++	val = RTL8224_MII_RTCT_ENABLE;
++	val |= RTL8224_MII_RTCT_PAIR_A;
++	val |= RTL8224_MII_RTCT_PAIR_B;
++	val |= RTL8224_MII_RTCT_PAIR_C;
++	val |= RTL8224_MII_RTCT_PAIR_D;
++
++	return phy_modify_mmd(phydev, MDIO_MMD_VEND2,
++			      RTL822X_VND2_C22_REG(RTL8224_MII_RTCT),
++			      RTL8224_MII_RTCT_DONE, val);
++}
++
++static int rtl8224_sram_read(struct phy_device *phydev, u32 reg)
++{
++	int ret;
++
++	ret = phy_write_mmd(phydev, MDIO_MMD_VEND2,
++			    RTL822X_VND2_C22_REG(RTL8224_MII_SRAM_ADDR),
++			    reg);
++	if (ret)
++		return ret;
++
++	return phy_read_mmd(phydev, MDIO_MMD_VEND2,
++			    RTL822X_VND2_C22_REG(RTL8224_MII_SRAM_DATA));
++}
++
++static int rtl8224_pair_len_get(struct phy_device *phydev, u32 pair)
++{
++	int cable_len;
++	u32 reg_len;
++	int ret;
++	u32 cm;
++
++	reg_len = RTL8224_SRAM_RTCT_LEN(pair);
++
++	ret = rtl8224_sram_read(phydev, reg_len);
++	if (ret < 0)
++		return ret;
++
++	cable_len = ret & 0xff00;
++
++	ret = rtl8224_sram_read(phydev, reg_len + 1);
++	if (ret < 0)
++		return ret;
++
++	cable_len |= (ret & 0xff00) >> 8;
++
++	cable_len -= 620;
++	cable_len = max(cable_len, 0);
++
++	cm = cable_len * 100 / 78;
++
++	return cm;
++}
++
++static int rtl8224_cable_test_result_trans(u32 result)
++{
++	if (!(result & RTL8224_SRAM_RTCT_FAULT_DONE))
++		return -EBUSY;
++
++	if (result & RTL8224_SRAM_RTCT_FAULT_OK)
++		return ETHTOOL_A_CABLE_RESULT_CODE_OK;
++
++	if (result & RTL8224_SRAM_RTCT_FAULT_OPEN)
++		return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
++
++	if (result & RTL8224_SRAM_RTCT_FAULT_SAME_SHORT)
++		return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
++
++	if (result & RTL8224_SRAM_RTCT_FAULT_BUSY)
++		return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
++
++	if (result & RTL8224_SRAM_RTCT_FAULT_CROSS_SHORT)
++		return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT;
++
++	return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
++}
++
++static int rtl8224_cable_test_report_pair(struct phy_device *phydev, unsigned int pair)
++{
++	int fault_rslt;
++	int ret;
++
++	ret = rtl8224_sram_read(phydev, RTL8224_SRAM_RTCT_FAULT(pair));
++	if (ret < 0)
++		return ret;
++
++	fault_rslt = rtl8224_cable_test_result_trans(ret);
++	if (fault_rslt < 0)
++		return 0;
++
++	ret = ethnl_cable_test_result(phydev, pair, fault_rslt);
++	if (ret < 0)
++		return ret;
++
++	switch (fault_rslt) {
++	case ETHTOOL_A_CABLE_RESULT_CODE_OPEN:
++	case ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT:
++	case ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT:
++		ret = rtl8224_pair_len_get(phydev, pair);
++		if (ret < 0)
++			return ret;
++
++		return ethnl_cable_test_fault_length(phydev, pair, ret);
++	default:
++		return  0;
++	}
++}
++
++static int rtl8224_cable_test_report(struct phy_device *phydev, bool *finished)
++{
++	unsigned int pair;
++	int ret;
++
++	for (pair = ETHTOOL_A_CABLE_PAIR_A; pair <= ETHTOOL_A_CABLE_PAIR_D; pair++) {
++		ret = rtl8224_cable_test_report_pair(phydev, pair);
++		if (ret == -EBUSY) {
++			*finished = false;
++			return 0;
++		}
++
++		if (ret < 0)
++			return ret;
++	}
++
++	return 0;
++}
++
++static int rtl8224_cable_test_get_status(struct phy_device *phydev, bool *finished)
++{
++	int ret;
++
++	*finished = false;
++
++	ret = phy_read_mmd(phydev, MDIO_MMD_VEND2,
++			   RTL822X_VND2_C22_REG(RTL8224_MII_RTCT));
++	if (ret < 0)
++		return ret;
++
++	if (!(ret & RTL8224_MII_RTCT_DONE))
++		return 0;
++
++	*finished = true;
++
++	return rtl8224_cable_test_report(phydev, finished);
++}
++
+ static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
+ {
+ 	int val;
+@@ -1822,11 +2006,14 @@ static struct phy_driver realtek_drvs[]
+ 	}, {
+ 		PHY_ID_MATCH_EXACT(0x001ccad0),
+ 		.name		= "RTL8224 2.5Gbps PHY",
++		.flags		= PHY_POLL_CABLE_TEST,
+ 		.get_features   = rtl822x_c45_get_features,
+ 		.config_aneg    = rtl822x_c45_config_aneg,
+ 		.read_status    = rtl822x_c45_read_status,
+ 		.suspend        = genphy_c45_pma_suspend,
+ 		.resume         = rtlgen_c45_resume,
++		.cable_test_start = rtl8224_cable_test_start,
++		.cable_test_get_status = rtl8224_cable_test_get_status,
+ 	}, {
+ 		PHY_ID_MATCH_EXACT(0x001cc961),
+ 		.name		= "RTL8366RB Gigabit Ethernet",
diff --git a/target/linux/generic/backport-6.12/784-06-v6.19-net-phy-realtek-add-interrupt-support-for-RTL8221B.patch b/target/linux/generic/backport-6.12/784-06-v6.19-net-phy-realtek-add-interrupt-support-for-RTL8221B.patch
new file mode 100644
index 0000000000..496174b251
--- /dev/null
+++ b/target/linux/generic/backport-6.12/784-06-v6.19-net-phy-realtek-add-interrupt-support-for-RTL8221B.patch
@@ -0,0 +1,105 @@
+From 18aa36238a4d835c1644dcccd63d32c7fdd4b310 Mon Sep 17 00:00:00 2001
+From: Jianhui Zhao <zhaojh329 at gmail.com>
+Date: Sun, 2 Nov 2025 16:26:37 +0100
+Subject: [PATCH] net: phy: realtek: add interrupt support for RTL8221B
+
+This commit introduces interrupt support for RTL8221B (C45 mode).
+Interrupts are mapped on the VEND2 page. VEND2 registers are only
+accessible via C45 reads and cannot be accessed by C45 over C22.
+
+Signed-off-by: Jianhui Zhao <zhaojh329 at gmail.com>
+[Enable only link state change interrupts]
+Signed-off-by: Aleksander Jan Bajkowski <olek2 at wp.pl>
+Reviewed-by: Andrew Lunn <andrew at lunn.ch>
+Link: https://patch.msgid.link/20251102152644.1676482-1-olek2@wp.pl
+Signed-off-by: Jakub Kicinski <kuba at kernel.org>
+---
+ drivers/net/phy/realtek/realtek_main.c | 56 ++++++++++++++++++++++++++
+ 1 file changed, 56 insertions(+)
+
+--- a/drivers/net/phy/realtek/realtek_main.c
++++ b/drivers/net/phy/realtek/realtek_main.c
+@@ -130,6 +130,11 @@
+  */
+ #define RTL822X_VND2_C22_REG(reg)		(0xa400 + 2 * (reg))
+ 
++#define RTL8221B_VND2_INER			0xa4d2
++#define RTL8221B_VND2_INER_LINK_STATUS		BIT(4)
++
++#define RTL8221B_VND2_INSR			0xa4d4
++
+ #define RTL8224_MII_RTCT			0x11
+ #define RTL8224_MII_RTCT_ENABLE			BIT(0)
+ #define RTL8224_MII_RTCT_PAIR_A			BIT(4)
+@@ -1772,6 +1777,53 @@ 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, MDIO_MMD_VEND2, RTL8221B_VND2_INSR);
++
++	return (err < 0) ? err : 0;
++}
++
++static int rtl8221b_config_intr(struct phy_device *phydev)
++{
++	int err;
++
++	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
++		err = rtl8221b_ack_interrupt(phydev);
++		if (err)
++			return err;
++
++		err = phy_write_mmd(phydev, MDIO_MMD_VEND2, RTL8221B_VND2_INER,
++				    RTL8221B_VND2_INER_LINK_STATUS);
++	} else {
++		err = phy_write_mmd(phydev, MDIO_MMD_VEND2,
++				    RTL8221B_VND2_INER, 0);
++		if (err)
++			return err;
++
++		err = rtl8221b_ack_interrupt(phydev);
++	}
++
++	return err;
++}
++
++static irqreturn_t rtl8221b_handle_interrupt(struct phy_device *phydev)
++{
++	int err;
++
++	err = rtl8221b_ack_interrupt(phydev);
++	if (err) {
++		phy_error(phydev);
++		return IRQ_NONE;
++	}
++
++	phy_trigger_machine(phydev);
++
++	return IRQ_HANDLED;
++}
++
+ static struct phy_driver realtek_drvs[] = {
+ 	{
+ 		PHY_ID_MATCH_EXACT(0x00008201),
+@@ -1946,6 +1998,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,
+ 		.config_init    = rtl822xb_config_init,
+ 		.get_rate_matching = rtl822xb_get_rate_matching,
+@@ -1970,6 +2024,8 @@ static struct phy_driver realtek_drvs[]
+ 	}, {
+ 		.match_phy_device = rtl8221b_vm_cg_c45_match_phy_device,
+ 		.name           = "RTL8221B-VM-CG 2.5Gbps PHY (C45)",
++		.config_intr	= rtl8221b_config_intr,
++		.handle_interrupt = rtl8221b_handle_interrupt,
+ 		.probe		= rtl822x_probe,
+ 		.config_init    = rtl822xb_config_init,
+ 		.get_rate_matching = rtl822xb_get_rate_matching,
diff --git a/target/linux/generic/backport-6.6/784-01-v6.17-net-phy-realtek-add-error-handling-to-rtl8211f_get_w.patch b/target/linux/generic/backport-6.6/784-01-v6.17-net-phy-realtek-add-error-handling-to-rtl8211f_get_w.patch
new file mode 100644
index 0000000000..5f3b119a89
--- /dev/null
+++ b/target/linux/generic/backport-6.6/784-01-v6.17-net-phy-realtek-add-error-handling-to-rtl8211f_get_w.patch
@@ -0,0 +1,39 @@
+From a9b24b3583ae1da7dbda031f141264f2da260219 Mon Sep 17 00:00:00 2001
+From: Daniel Braunwarth <daniel.braunwarth at kuka.com>
+Date: Tue, 24 Jun 2025 16:17:33 +0200
+Subject: [PATCH] net: phy: realtek: add error handling to rtl8211f_get_wol
+
+We should check if the WOL settings was successfully read from the PHY.
+
+In case this fails we cannot just use the error code and proceed.
+
+Signed-off-by: Daniel Braunwarth <daniel.braunwarth at kuka.com>
+Reported-by: Jon Hunter <jonathanh at nvidia.com>
+Closes: https://lore.kernel.org/baaa083b-9a69-460f-ab35-2a7cb3246ffd@nvidia.com
+Reviewed-by: Andrew Lunn <andrew at lunn.ch>
+Link: https://patch.msgid.link/20250624-realtek_fixes-v1-1-02a0b7c369bc@kuka.com
+Signed-off-by: Jakub Kicinski <kuba at kernel.org>
+---
+ drivers/net/phy/realtek/realtek_main.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/phy/realtek/realtek_main.c
++++ b/drivers/net/phy/realtek/realtek_main.c
+@@ -436,9 +436,15 @@ static irqreturn_t rtl8211f_handle_inter
+ 
+ static void rtl8211f_get_wol(struct phy_device *dev, struct ethtool_wolinfo *wol)
+ {
++	int wol_events;
++
+ 	wol->supported = WAKE_MAGIC;
+-	if (phy_read_paged(dev, RTL8211F_WOL_SETTINGS_PAGE, RTL8211F_WOL_SETTINGS_EVENTS)
+-	    & RTL8211F_WOL_EVENT_MAGIC)
++
++	wol_events = phy_read_paged(dev, RTL8211F_WOL_SETTINGS_PAGE, RTL8211F_WOL_SETTINGS_EVENTS);
++	if (wol_events < 0)
++		return;
++
++	if (wol_events & RTL8211F_WOL_EVENT_MAGIC)
+ 		wol->wolopts = WAKE_MAGIC;
+ }
+ 
diff --git a/target/linux/generic/backport-6.6/784-02-v6.18-net-phy-realtek-support-for-TRIGGER_NETDEV_LINK-on-R.patch b/target/linux/generic/backport-6.6/784-02-v6.18-net-phy-realtek-support-for-TRIGGER_NETDEV_LINK-on-R.patch
new file mode 100644
index 0000000000..83ea4928e9
--- /dev/null
+++ b/target/linux/generic/backport-6.6/784-02-v6.18-net-phy-realtek-support-for-TRIGGER_NETDEV_LINK-on-R.patch
@@ -0,0 +1,105 @@
+From f63f21e82ecafd288b100ea161247820bf1e92c4 Mon Sep 17 00:00:00 2001
+From: Aleksander Jan Bajkowski <olek2 at wp.pl>
+Date: Mon, 25 Aug 2025 23:09:49 +0200
+Subject: [PATCH] net: phy: realtek: support for TRIGGER_NETDEV_LINK on
+ RTL8211E and RTL8211F
+
+This patch adds support for the TRIGGER_NETDEV_LINK trigger. It activates
+the LED when a link is established, regardless of the speed.
+
+Tested on Orange Pi PC2 with RTL8211E PHY.
+
+Signed-off-by: Aleksander Jan Bajkowski <olek2 at wp.pl>
+Reviewed-by: Andrew Lunn <andrew at lunn.ch>
+Link: https://patch.msgid.link/20250825211059.143231-1-olek2@wp.pl
+Signed-off-by: Jakub Kicinski <kuba at kernel.org>
+---
+ drivers/net/phy/realtek/realtek_main.c | 39 +++++++++++++++++++++-----
+ 1 file changed, 32 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/phy/realtek/realtek_main.c
++++ b/drivers/net/phy/realtek/realtek_main.c
+@@ -648,7 +648,8 @@ static int rtl821x_resume(struct phy_dev
+ static int rtl8211x_led_hw_is_supported(struct phy_device *phydev, u8 index,
+ 					unsigned long rules)
+ {
+-	const unsigned long mask = BIT(TRIGGER_NETDEV_LINK_10) |
++	const unsigned long mask = BIT(TRIGGER_NETDEV_LINK) |
++				   BIT(TRIGGER_NETDEV_LINK_10) |
+ 				   BIT(TRIGGER_NETDEV_LINK_100) |
+ 				   BIT(TRIGGER_NETDEV_LINK_1000) |
+ 				   BIT(TRIGGER_NETDEV_RX) |
+@@ -706,6 +707,12 @@ static int rtl8211f_led_hw_control_get(s
+ 	if (val & RTL8211F_LEDCR_LINK_1000)
+ 		__set_bit(TRIGGER_NETDEV_LINK_1000, rules);
+ 
++	if ((val & RTL8211F_LEDCR_LINK_10) &&
++	    (val & RTL8211F_LEDCR_LINK_100) &&
++	    (val & RTL8211F_LEDCR_LINK_1000)) {
++		__set_bit(TRIGGER_NETDEV_LINK, rules);
++	}
++
+ 	if (val & RTL8211F_LEDCR_ACT_TXRX) {
+ 		__set_bit(TRIGGER_NETDEV_RX, rules);
+ 		__set_bit(TRIGGER_NETDEV_TX, rules);
+@@ -723,14 +730,20 @@ static int rtl8211f_led_hw_control_set(s
+ 	if (index >= RTL8211x_LED_COUNT)
+ 		return -EINVAL;
+ 
+-	if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
++	if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
++	    test_bit(TRIGGER_NETDEV_LINK_10, &rules)) {
+ 		reg |= RTL8211F_LEDCR_LINK_10;
++	}
+ 
+-	if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
++	if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
++	    test_bit(TRIGGER_NETDEV_LINK_100, &rules)) {
+ 		reg |= RTL8211F_LEDCR_LINK_100;
++	}
+ 
+-	if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
++	if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
++	    test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) {
+ 		reg |= RTL8211F_LEDCR_LINK_1000;
++	}
+ 
+ 	if (test_bit(TRIGGER_NETDEV_RX, &rules) ||
+ 	    test_bit(TRIGGER_NETDEV_TX, &rules)) {
+@@ -778,6 +791,12 @@ static int rtl8211e_led_hw_control_get(s
+ 	if (cr2 & RTL8211E_LEDCR2_LINK_1000)
+ 		__set_bit(TRIGGER_NETDEV_LINK_1000, rules);
+ 
++	if ((cr2 & RTL8211E_LEDCR2_LINK_10) &&
++	    (cr2 & RTL8211E_LEDCR2_LINK_100) &&
++	    (cr2 & RTL8211E_LEDCR2_LINK_1000)) {
++		__set_bit(TRIGGER_NETDEV_LINK, rules);
++	}
++
+ 	return ret;
+ }
+ 
+@@ -805,14 +824,20 @@ static int rtl8211e_led_hw_control_set(s
+ 	if (ret < 0)
+ 		return ret;
+ 
+-	if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
++	if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
++	    test_bit(TRIGGER_NETDEV_LINK_10, &rules)) {
+ 		cr2 |= RTL8211E_LEDCR2_LINK_10;
++	}
+ 
+-	if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
++	if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
++	    test_bit(TRIGGER_NETDEV_LINK_100, &rules)) {
+ 		cr2 |= RTL8211E_LEDCR2_LINK_100;
++	}
+ 
+-	if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
++	if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
++	    test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) {
+ 		cr2 |= RTL8211E_LEDCR2_LINK_1000;
++	}
+ 
+ 	cr2 <<= RTL8211E_LEDCR2_SHIFT * index;
+ 	ret = rtl821x_modify_ext_page(phydev, RTL8211E_LEDCR_EXT_PAGE,
diff --git a/target/linux/generic/backport-6.6/784-03-v6.18-net-phy-realtek-Avoid-PHYCR2-access-if-PHYCR2-not-pr.patch b/target/linux/generic/backport-6.6/784-03-v6.18-net-phy-realtek-Avoid-PHYCR2-access-if-PHYCR2-not-pr.patch
new file mode 100644
index 0000000000..681b234fc5
--- /dev/null
+++ b/target/linux/generic/backport-6.6/784-03-v6.18-net-phy-realtek-Avoid-PHYCR2-access-if-PHYCR2-not-pr.patch
@@ -0,0 +1,61 @@
+From 2c67301584f2671e320236df6bbe75ae09feb4d0 Mon Sep 17 00:00:00 2001
+From: Marek Vasut <marek.vasut at mailbox.org>
+Date: Sat, 11 Oct 2025 13:02:49 +0200
+Subject: [PATCH] net: phy: realtek: Avoid PHYCR2 access if PHYCR2 not present
+
+The driver is currently checking for PHYCR2 register presence in
+rtl8211f_config_init(), but it does so after accessing PHYCR2 to
+disable EEE. This was introduced in commit bfc17c165835 ("net:
+phy: realtek: disable PHY-mode EEE"). Move the PHYCR2 presence
+test before the EEE disablement and simplify the code.
+
+Fixes: bfc17c165835 ("net: phy: realtek: disable PHY-mode EEE")
+Signed-off-by: Marek Vasut <marek.vasut at mailbox.org>
+Reviewed-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
+Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
+Link: https://patch.msgid.link/20251011110309.12664-1-marek.vasut@mailbox.org
+Signed-off-by: Jakub Kicinski <kuba at kernel.org>
+---
+ drivers/net/phy/realtek/realtek_main.c | 23 +++++++++++------------
+ 1 file changed, 11 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/phy/realtek/realtek_main.c
++++ b/drivers/net/phy/realtek/realtek_main.c
+@@ -589,26 +589,25 @@ static int rtl8211f_config_init(struct p
+ 			str_enabled_disabled(val_rxdly));
+ 	}
+ 
++	if (!priv->has_phycr2)
++		return 0;
++
+ 	/* Disable PHY-mode EEE so LPI is passed to the MAC */
+ 	ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR2,
+ 			       RTL8211F_PHYCR2_PHY_EEE_ENABLE, 0);
+ 	if (ret)
+ 		return ret;
+ 
+-	if (priv->has_phycr2) {
+-		ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE,
+-				       RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN,
+-				       priv->phycr2);
+-		if (ret < 0) {
+-			dev_err(dev, "clkout configuration failed: %pe\n",
+-				ERR_PTR(ret));
+-			return ret;
+-		}
+-
+-		return genphy_soft_reset(phydev);
++	ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE,
++			       RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN,
++			       priv->phycr2);
++	if (ret < 0) {
++		dev_err(dev, "clkout configuration failed: %pe\n",
++			ERR_PTR(ret));
++		return ret;
+ 	}
+ 
+-	return 0;
++	return genphy_soft_reset(phydev);
+ }
+ 
+ static int rtl821x_suspend(struct phy_device *phydev)
diff --git a/target/linux/generic/backport-6.6/784-04-v6.18-net-phy-realtek-fix-rtl8221b-vm-cg-name.patch b/target/linux/generic/backport-6.6/784-04-v6.18-net-phy-realtek-fix-rtl8221b-vm-cg-name.patch
new file mode 100644
index 0000000000..a3a2ed0aea
--- /dev/null
+++ b/target/linux/generic/backport-6.6/784-04-v6.18-net-phy-realtek-fix-rtl8221b-vm-cg-name.patch
@@ -0,0 +1,70 @@
+From ffff5c8fc2af2218a3332b3d5b97654599d50cde Mon Sep 17 00:00:00 2001
+From: Aleksander Jan Bajkowski <olek2 at wp.pl>
+Date: Thu, 16 Oct 2025 21:22:52 +0200
+Subject: [PATCH] net: phy: realtek: fix rtl8221b-vm-cg name
+
+When splitting the RTL8221B-VM-CG into C22 and C45 variants, the name was
+accidentally changed to RTL8221B-VN-CG. This patch brings back the previous
+part number.
+
+Fixes: ad5ce743a6b0 ("net: phy: realtek: Add driver instances for rtl8221b via Clause 45")
+Signed-off-by: Aleksander Jan Bajkowski <olek2 at wp.pl>
+Reviewed-by: Simon Horman <horms at kernel.org>
+Link: https://patch.msgid.link/20251016192325.2306757-1-olek2@wp.pl
+Signed-off-by: Jakub Kicinski <kuba at kernel.org>
+---
+ drivers/net/phy/realtek/realtek_main.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/phy/realtek/realtek_main.c
++++ b/drivers/net/phy/realtek/realtek_main.c
+@@ -156,7 +156,7 @@
+ #define RTL_8211FVD_PHYID			0x001cc878
+ #define RTL_8221B				0x001cc840
+ #define RTL_8221B_VB_CG				0x001cc849
+-#define RTL_8221B_VN_CG				0x001cc84a
++#define RTL_8221B_VM_CG				0x001cc84a
+ #define RTL_8251B				0x001cc862
+ #define RTL_8261C				0x001cc890
+ 
+@@ -1387,16 +1387,16 @@ static int rtl8221b_vb_cg_c45_match_phy_
+ 	return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true);
+ }
+ 
+-static int rtl8221b_vn_cg_c22_match_phy_device(struct phy_device *phydev,
++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_VN_CG, false);
++	return rtlgen_is_c45_match(phydev, RTL_8221B_VM_CG, false);
+ }
+ 
+-static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev,
++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_VN_CG, true);
++	return rtlgen_is_c45_match(phydev, RTL_8221B_VM_CG, true);
+ }
+ 
+ static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev,
+@@ -1743,7 +1743,7 @@ static struct phy_driver realtek_drvs[]
+ 		.suspend        = genphy_c45_pma_suspend,
+ 		.resume         = rtlgen_c45_resume,
+ 	}, {
+-		.match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
++		.match_phy_device = rtl8221b_vm_cg_c22_match_phy_device,
+ 		.name           = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
+ 		.probe		= rtl822x_probe,
+ 		.get_features   = rtl822x_get_features,
+@@ -1756,8 +1756,8 @@ 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)",
++		.match_phy_device = rtl8221b_vm_cg_c45_match_phy_device,
++		.name           = "RTL8221B-VM-CG 2.5Gbps PHY (C45)",
+ 		.probe		= rtl822x_probe,
+ 		.config_init    = rtl822xb_config_init,
+ 		.get_rate_matching = rtl822xb_get_rate_matching,
diff --git a/target/linux/generic/backport-6.6/784-05-v6.19-net-phy-realtek-Add-RTL8224-cable-testing-support.patch b/target/linux/generic/backport-6.6/784-05-v6.19-net-phy-realtek-Add-RTL8224-cable-testing-support.patch
new file mode 100644
index 0000000000..ffdb02c12d
--- /dev/null
+++ b/target/linux/generic/backport-6.6/784-05-v6.19-net-phy-realtek-Add-RTL8224-cable-testing-support.patch
@@ -0,0 +1,272 @@
+From 61958b33ef0bab1c1874c933cd3910f495526782 Mon Sep 17 00:00:00 2001
+From: Issam Hamdi <ih at simonwunderlich.de>
+Date: Fri, 24 Oct 2025 11:49:00 +0200
+Subject: [PATCH] net: phy: realtek: Add RTL8224 cable testing support
+
+The RTL8224 can detect open pairs and short types (in same pair or some
+other pair). The distance to this problem can be estimated. This is done
+for each of the 4 pairs separately.
+
+It is not meant to be run while there is an active link partner because
+this interferes with the active test pulses.
+
+Output with open 50 m cable:
+
+  Pair A code Open Circuit, source: TDR
+  Pair A, fault length: 51.79m, source: TDR
+  Pair B code Open Circuit, source: TDR
+  Pair B, fault length: 51.28m, source: TDR
+  Pair C code Open Circuit, source: TDR
+  Pair C, fault length: 50.46m, source: TDR
+  Pair D code Open Circuit, source: TDR
+  Pair D, fault length: 51.12m, source: TDR
+
+Terminated cable:
+
+  Pair A code OK, source: TDR
+  Pair B code OK, source: TDR
+  Pair C code OK, source: TDR
+  Pair D code OK, source: TDR
+
+Shorted cable (both short types are at roughly the same distance)
+
+  Pair A code Short to another pair, source: TDR
+  Pair A, fault length: 2.35m, source: TDR
+  Pair B code Short to another pair, source: TDR
+  Pair B, fault length: 2.15m, source: TDR
+  Pair C code OK, source: TDR
+  Pair D code Short within Pair, source: TDR
+  Pair D, fault length: 1.94m, source: TDR
+
+Signed-off-by: Issam Hamdi <ih at simonwunderlich.de>
+Co-developed-by: Sven Eckelmann <se at simonwunderlich.de>
+Signed-off-by: Sven Eckelmann <se at simonwunderlich.de>
+Reviewed-by: Andrew Lunn <andrew at lunn.ch>
+Link: https://patch.msgid.link/20251024-rtl8224-cable-test-v1-1-e3cda89ac98f@simonwunderlich.de
+Signed-off-by: Jakub Kicinski <kuba at kernel.org>
+---
+ drivers/net/phy/realtek/realtek_main.c | 187 +++++++++++++++++++++++++
+ 1 file changed, 187 insertions(+)
+
+--- a/drivers/net/phy/realtek/realtek_main.c
++++ b/drivers/net/phy/realtek/realtek_main.c
+@@ -8,6 +8,7 @@
+  * Copyright (c) 2004 Freescale Semiconductor, Inc.
+  */
+ #include <linux/bitops.h>
++#include <linux/ethtool_netlink.h>
+ #include <linux/of.h>
+ #include <linux/phy.h>
+ #include <linux/netdevice.h>
+@@ -129,6 +130,27 @@
+  */
+ #define RTL822X_VND2_C22_REG(reg)		(0xa400 + 2 * (reg))
+ 
++#define RTL8224_MII_RTCT			0x11
++#define RTL8224_MII_RTCT_ENABLE			BIT(0)
++#define RTL8224_MII_RTCT_PAIR_A			BIT(4)
++#define RTL8224_MII_RTCT_PAIR_B			BIT(5)
++#define RTL8224_MII_RTCT_PAIR_C			BIT(6)
++#define RTL8224_MII_RTCT_PAIR_D			BIT(7)
++#define RTL8224_MII_RTCT_DONE			BIT(15)
++
++#define RTL8224_MII_SRAM_ADDR			0x1b
++#define RTL8224_MII_SRAM_DATA			0x1c
++
++#define RTL8224_SRAM_RTCT_FAULT(pair)		(0x8026 + (pair) * 4)
++#define RTL8224_SRAM_RTCT_FAULT_BUSY		BIT(0)
++#define RTL8224_SRAM_RTCT_FAULT_OPEN		BIT(3)
++#define RTL8224_SRAM_RTCT_FAULT_SAME_SHORT	BIT(4)
++#define RTL8224_SRAM_RTCT_FAULT_OK		BIT(5)
++#define RTL8224_SRAM_RTCT_FAULT_DONE		BIT(6)
++#define RTL8224_SRAM_RTCT_FAULT_CROSS_SHORT	BIT(7)
++
++#define RTL8224_SRAM_RTCT_LEN(pair)		(0x8028 + (pair) * 4)
++
+ #define RTL8366RB_POWER_SAVE			0x15
+ #define RTL8366RB_POWER_SAVE_ON			BIT(12)
+ 
+@@ -1317,6 +1339,168 @@ static int rtl822xb_c45_read_status(stru
+ 	return 0;
+ }
+ 
++static int rtl8224_cable_test_start(struct phy_device *phydev)
++{
++	u32 val;
++	int ret;
++
++	/* disable auto-negotiation and force 1000/Full */
++	ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2,
++			     RTL822X_VND2_C22_REG(MII_BMCR),
++			     BMCR_ANENABLE | BMCR_SPEED100 | BMCR_SPEED10,
++			     BMCR_SPEED1000 | BMCR_FULLDPLX);
++	if (ret)
++		return ret;
++
++	mdelay(500);
++
++	/* trigger cable test */
++	val = RTL8224_MII_RTCT_ENABLE;
++	val |= RTL8224_MII_RTCT_PAIR_A;
++	val |= RTL8224_MII_RTCT_PAIR_B;
++	val |= RTL8224_MII_RTCT_PAIR_C;
++	val |= RTL8224_MII_RTCT_PAIR_D;
++
++	return phy_modify_mmd(phydev, MDIO_MMD_VEND2,
++			      RTL822X_VND2_C22_REG(RTL8224_MII_RTCT),
++			      RTL8224_MII_RTCT_DONE, val);
++}
++
++static int rtl8224_sram_read(struct phy_device *phydev, u32 reg)
++{
++	int ret;
++
++	ret = phy_write_mmd(phydev, MDIO_MMD_VEND2,
++			    RTL822X_VND2_C22_REG(RTL8224_MII_SRAM_ADDR),
++			    reg);
++	if (ret)
++		return ret;
++
++	return phy_read_mmd(phydev, MDIO_MMD_VEND2,
++			    RTL822X_VND2_C22_REG(RTL8224_MII_SRAM_DATA));
++}
++
++static int rtl8224_pair_len_get(struct phy_device *phydev, u32 pair)
++{
++	int cable_len;
++	u32 reg_len;
++	int ret;
++	u32 cm;
++
++	reg_len = RTL8224_SRAM_RTCT_LEN(pair);
++
++	ret = rtl8224_sram_read(phydev, reg_len);
++	if (ret < 0)
++		return ret;
++
++	cable_len = ret & 0xff00;
++
++	ret = rtl8224_sram_read(phydev, reg_len + 1);
++	if (ret < 0)
++		return ret;
++
++	cable_len |= (ret & 0xff00) >> 8;
++
++	cable_len -= 620;
++	cable_len = max(cable_len, 0);
++
++	cm = cable_len * 100 / 78;
++
++	return cm;
++}
++
++static int rtl8224_cable_test_result_trans(u32 result)
++{
++	if (!(result & RTL8224_SRAM_RTCT_FAULT_DONE))
++		return -EBUSY;
++
++	if (result & RTL8224_SRAM_RTCT_FAULT_OK)
++		return ETHTOOL_A_CABLE_RESULT_CODE_OK;
++
++	if (result & RTL8224_SRAM_RTCT_FAULT_OPEN)
++		return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
++
++	if (result & RTL8224_SRAM_RTCT_FAULT_SAME_SHORT)
++		return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
++
++	if (result & RTL8224_SRAM_RTCT_FAULT_BUSY)
++		return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
++
++	if (result & RTL8224_SRAM_RTCT_FAULT_CROSS_SHORT)
++		return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT;
++
++	return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
++}
++
++static int rtl8224_cable_test_report_pair(struct phy_device *phydev, unsigned int pair)
++{
++	int fault_rslt;
++	int ret;
++
++	ret = rtl8224_sram_read(phydev, RTL8224_SRAM_RTCT_FAULT(pair));
++	if (ret < 0)
++		return ret;
++
++	fault_rslt = rtl8224_cable_test_result_trans(ret);
++	if (fault_rslt < 0)
++		return 0;
++
++	ret = ethnl_cable_test_result(phydev, pair, fault_rslt);
++	if (ret < 0)
++		return ret;
++
++	switch (fault_rslt) {
++	case ETHTOOL_A_CABLE_RESULT_CODE_OPEN:
++	case ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT:
++	case ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT:
++		ret = rtl8224_pair_len_get(phydev, pair);
++		if (ret < 0)
++			return ret;
++
++		return ethnl_cable_test_fault_length(phydev, pair, ret);
++	default:
++		return  0;
++	}
++}
++
++static int rtl8224_cable_test_report(struct phy_device *phydev, bool *finished)
++{
++	unsigned int pair;
++	int ret;
++
++	for (pair = ETHTOOL_A_CABLE_PAIR_A; pair <= ETHTOOL_A_CABLE_PAIR_D; pair++) {
++		ret = rtl8224_cable_test_report_pair(phydev, pair);
++		if (ret == -EBUSY) {
++			*finished = false;
++			return 0;
++		}
++
++		if (ret < 0)
++			return ret;
++	}
++
++	return 0;
++}
++
++static int rtl8224_cable_test_get_status(struct phy_device *phydev, bool *finished)
++{
++	int ret;
++
++	*finished = false;
++
++	ret = phy_read_mmd(phydev, MDIO_MMD_VEND2,
++			   RTL822X_VND2_C22_REG(RTL8224_MII_RTCT));
++	if (ret < 0)
++		return ret;
++
++	if (!(ret & RTL8224_MII_RTCT_DONE))
++		return 0;
++
++	*finished = true;
++
++	return rtl8224_cable_test_report(phydev, finished);
++}
++
+ static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
+ {
+ 	int val;
+@@ -1794,11 +1978,14 @@ static struct phy_driver realtek_drvs[]
+ 	}, {
+ 		PHY_ID_MATCH_EXACT(0x001ccad0),
+ 		.name		= "RTL8224 2.5Gbps PHY",
++		.flags		= PHY_POLL_CABLE_TEST,
+ 		.get_features   = rtl822x_c45_get_features,
+ 		.config_aneg    = rtl822x_c45_config_aneg,
+ 		.read_status    = rtl822x_c45_read_status,
+ 		.suspend        = genphy_c45_pma_suspend,
+ 		.resume         = rtlgen_c45_resume,
++		.cable_test_start = rtl8224_cable_test_start,
++		.cable_test_get_status = rtl8224_cable_test_get_status,
+ 	}, {
+ 		PHY_ID_MATCH_EXACT(0x001cc961),
+ 		.name		= "RTL8366RB Gigabit Ethernet",
diff --git a/target/linux/generic/backport-6.6/784-06-v6.19-net-phy-realtek-add-interrupt-support-for-RTL8221B.patch b/target/linux/generic/backport-6.6/784-06-v6.19-net-phy-realtek-add-interrupt-support-for-RTL8221B.patch
new file mode 100644
index 0000000000..17b3085e80
--- /dev/null
+++ b/target/linux/generic/backport-6.6/784-06-v6.19-net-phy-realtek-add-interrupt-support-for-RTL8221B.patch
@@ -0,0 +1,105 @@
+From 18aa36238a4d835c1644dcccd63d32c7fdd4b310 Mon Sep 17 00:00:00 2001
+From: Jianhui Zhao <zhaojh329 at gmail.com>
+Date: Sun, 2 Nov 2025 16:26:37 +0100
+Subject: [PATCH] net: phy: realtek: add interrupt support for RTL8221B
+
+This commit introduces interrupt support for RTL8221B (C45 mode).
+Interrupts are mapped on the VEND2 page. VEND2 registers are only
+accessible via C45 reads and cannot be accessed by C45 over C22.
+
+Signed-off-by: Jianhui Zhao <zhaojh329 at gmail.com>
+[Enable only link state change interrupts]
+Signed-off-by: Aleksander Jan Bajkowski <olek2 at wp.pl>
+Reviewed-by: Andrew Lunn <andrew at lunn.ch>
+Link: https://patch.msgid.link/20251102152644.1676482-1-olek2@wp.pl
+Signed-off-by: Jakub Kicinski <kuba at kernel.org>
+---
+ drivers/net/phy/realtek/realtek_main.c | 56 ++++++++++++++++++++++++++
+ 1 file changed, 56 insertions(+)
+
+--- a/drivers/net/phy/realtek/realtek_main.c
++++ b/drivers/net/phy/realtek/realtek_main.c
+@@ -130,6 +130,11 @@
+  */
+ #define RTL822X_VND2_C22_REG(reg)		(0xa400 + 2 * (reg))
+ 
++#define RTL8221B_VND2_INER			0xa4d2
++#define RTL8221B_VND2_INER_LINK_STATUS		BIT(4)
++
++#define RTL8221B_VND2_INSR			0xa4d4
++
+ #define RTL8224_MII_RTCT			0x11
+ #define RTL8224_MII_RTCT_ENABLE			BIT(0)
+ #define RTL8224_MII_RTCT_PAIR_A			BIT(4)
+@@ -1744,6 +1749,53 @@ 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, MDIO_MMD_VEND2, RTL8221B_VND2_INSR);
++
++	return (err < 0) ? err : 0;
++}
++
++static int rtl8221b_config_intr(struct phy_device *phydev)
++{
++	int err;
++
++	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
++		err = rtl8221b_ack_interrupt(phydev);
++		if (err)
++			return err;
++
++		err = phy_write_mmd(phydev, MDIO_MMD_VEND2, RTL8221B_VND2_INER,
++				    RTL8221B_VND2_INER_LINK_STATUS);
++	} else {
++		err = phy_write_mmd(phydev, MDIO_MMD_VEND2,
++				    RTL8221B_VND2_INER, 0);
++		if (err)
++			return err;
++
++		err = rtl8221b_ack_interrupt(phydev);
++	}
++
++	return err;
++}
++
++static irqreturn_t rtl8221b_handle_interrupt(struct phy_device *phydev)
++{
++	int err;
++
++	err = rtl8221b_ack_interrupt(phydev);
++	if (err) {
++		phy_error(phydev);
++		return IRQ_NONE;
++	}
++
++	phy_trigger_machine(phydev);
++
++	return IRQ_HANDLED;
++}
++
+ static struct phy_driver realtek_drvs[] = {
+ 	{
+ 		PHY_ID_MATCH_EXACT(0x00008201),
+@@ -1918,6 +1970,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,
+ 		.config_init    = rtl822xb_config_init,
+ 		.get_rate_matching = rtl822xb_get_rate_matching,
+@@ -1942,6 +1996,8 @@ static struct phy_driver realtek_drvs[]
+ 	}, {
+ 		.match_phy_device = rtl8221b_vm_cg_c45_match_phy_device,
+ 		.name           = "RTL8221B-VM-CG 2.5Gbps PHY (C45)",
++		.config_intr	= rtl8221b_config_intr,
++		.handle_interrupt = rtl8221b_handle_interrupt,
+ 		.probe		= rtl822x_probe,
+ 		.config_init    = rtl822xb_config_init,
+ 		.get_rate_matching = rtl822xb_get_rate_matching,
diff --git a/target/linux/generic/pending-6.12/720-01-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch b/target/linux/generic/pending-6.12/720-01-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch
index a4cb71b83b..c36749800a 100644
--- a/target/linux/generic/pending-6.12/720-01-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch
+++ b/target/linux/generic/pending-6.12/720-01-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch
@@ -15,7 +15,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
 
 --- a/drivers/net/phy/realtek/realtek_main.c
 +++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -1675,6 +1675,7 @@ static struct phy_driver realtek_drvs[]
+@@ -1941,6 +1941,7 @@ static struct phy_driver realtek_drvs[]
  	}, {
  		.name		= "RTL8226 2.5Gbps PHY",
  		.match_phy_device = rtl8226_match_phy_device,
@@ -23,7 +23,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
  		.get_features	= rtl822x_get_features,
  		.config_aneg	= rtl822x_config_aneg,
  		.read_status	= rtl822x_read_status,
-@@ -1685,6 +1686,7 @@ static struct phy_driver realtek_drvs[]
+@@ -1951,6 +1952,7 @@ static struct phy_driver realtek_drvs[]
  	}, {
  		.match_phy_device = rtl8221b_match_phy_device,
  		.name		= "RTL8226B_RTL8221B 2.5Gbps PHY",
@@ -31,7 +31,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
  		.get_features	= rtl822x_get_features,
  		.config_aneg	= rtl822x_config_aneg,
  		.config_init    = rtl822xb_config_init,
-@@ -1707,6 +1709,7 @@ static struct phy_driver realtek_drvs[]
+@@ -1973,6 +1975,7 @@ static struct phy_driver realtek_drvs[]
  	}, {
  		PHY_ID_MATCH_EXACT(0x001cc848),
  		.name           = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
@@ -39,7 +39,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
  		.get_features   = rtl822x_get_features,
  		.config_aneg    = rtl822x_config_aneg,
  		.config_init    = rtl822xb_config_init,
-@@ -1719,6 +1722,7 @@ static struct phy_driver realtek_drvs[]
+@@ -1985,6 +1988,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)",
@@ -47,26 +47,26 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
  		.probe		= rtl822x_probe,
  		.get_features   = rtl822x_get_features,
  		.config_aneg    = rtl822x_config_aneg,
-@@ -1732,6 +1736,7 @@ static struct phy_driver realtek_drvs[]
- 	}, {
- 		.match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
+@@ -2000,6 +2004,7 @@ static struct phy_driver realtek_drvs[]
  		.name           = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
+ 		.config_intr	= rtl8221b_config_intr,
+ 		.handle_interrupt = rtl8221b_handle_interrupt,
 +		.soft_reset     = rtl822x_c45_soft_reset,
  		.probe		= rtl822x_probe,
  		.config_init    = rtl822xb_config_init,
  		.get_rate_matching = rtl822xb_get_rate_matching,
-@@ -1743,6 +1748,7 @@ static struct phy_driver realtek_drvs[]
+@@ -2011,6 +2016,7 @@ static struct phy_driver realtek_drvs[]
  	}, {
- 		.match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
+ 		.match_phy_device = rtl8221b_vm_cg_c22_match_phy_device,
  		.name           = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
 +		.soft_reset     = genphy_soft_reset,
  		.probe		= rtl822x_probe,
  		.get_features   = rtl822x_get_features,
  		.config_aneg    = rtl822x_config_aneg,
-@@ -1756,6 +1762,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)",
+@@ -2026,6 +2032,7 @@ static struct phy_driver realtek_drvs[]
+ 		.name           = "RTL8221B-VM-CG 2.5Gbps PHY (C45)",
+ 		.config_intr	= rtl8221b_config_intr,
+ 		.handle_interrupt = rtl8221b_handle_interrupt,
 +		.soft_reset     = rtl822x_c45_soft_reset,
  		.probe		= rtl822x_probe,
  		.config_init    = rtl822xb_config_init,
diff --git a/target/linux/generic/pending-6.12/720-02-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch b/target/linux/generic/pending-6.12/720-02-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch
index e1d9808747..a3a205532f 100644
--- a/target/linux/generic/pending-6.12/720-02-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch
+++ b/target/linux/generic/pending-6.12/720-02-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch
@@ -20,7 +20,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
 
 --- a/drivers/net/phy/realtek/realtek_main.c
 +++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -1035,8 +1035,8 @@ static int rtl822x_probe(struct phy_devi
+@@ -1092,8 +1092,8 @@ static int rtl822x_probe(struct phy_devi
  static int rtl822x_set_serdes_option_mode(struct phy_device *phydev, bool gen1)
  {
  	bool has_2500, has_sgmii;
@@ -30,7 +30,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
  
  	has_2500 = test_bit(PHY_INTERFACE_MODE_2500BASEX,
  			    phydev->host_interfaces) ||
-@@ -1078,18 +1078,42 @@ static int rtl822x_set_serdes_option_mod
+@@ -1135,18 +1135,42 @@ static int rtl822x_set_serdes_option_mod
  				     RTL822X_VND1_SERDES_OPTION,
  				     RTL822X_VND1_SERDES_OPTION_MODE_MASK,
  				     mode);
diff --git a/target/linux/generic/pending-6.12/720-03-net-phy-realtek-make-sure-paged-read-is-protected-by.patch b/target/linux/generic/pending-6.12/720-03-net-phy-realtek-make-sure-paged-read-is-protected-by.patch
index 74bf74e012..1e3af07594 100644
--- a/target/linux/generic/pending-6.12/720-03-net-phy-realtek-make-sure-paged-read-is-protected-by.patch
+++ b/target/linux/generic/pending-6.12/720-03-net-phy-realtek-make-sure-paged-read-is-protected-by.patch
@@ -18,7 +18,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
 
 --- a/drivers/net/phy/realtek/realtek_main.c
 +++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -1343,9 +1343,11 @@ static bool rtlgen_supports_2_5gbps(stru
+@@ -1562,9 +1562,11 @@ static bool rtlgen_supports_2_5gbps(stru
  {
  	int val;
  
diff --git a/target/linux/generic/pending-6.12/720-04-net-phy-realtek-setup-aldps.patch b/target/linux/generic/pending-6.12/720-04-net-phy-realtek-setup-aldps.patch
index 6d1bf08600..5a908fcef5 100644
--- a/target/linux/generic/pending-6.12/720-04-net-phy-realtek-setup-aldps.patch
+++ b/target/linux/generic/pending-6.12/720-04-net-phy-realtek-setup-aldps.patch
@@ -13,9 +13,9 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
 
 --- a/drivers/net/phy/realtek/realtek_main.c
 +++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -129,6 +129,10 @@
-  */
- #define RTL822X_VND2_C22_REG(reg)		(0xa400 + 2 * (reg))
+@@ -156,6 +156,10 @@
+ 
+ #define RTL8224_SRAM_RTCT_LEN(pair)		(0x8028 + (pair) * 4)
  
 +#define RTL8221B_PHYCR1				0xa430
 +#define RTL8221B_PHYCR1_ALDPS_EN		BIT(2)
@@ -24,7 +24,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
  #define RTL8366RB_POWER_SAVE			0x15
  #define RTL8366RB_POWER_SAVE_ON			BIT(12)
  
-@@ -1095,6 +1099,15 @@ static int rtl822x_set_serdes_option_mod
+@@ -1152,6 +1156,15 @@ static int rtl822x_set_serdes_option_mod
  			return ret;
  	}
  
diff --git a/target/linux/generic/pending-6.12/720-05-net-phy-realtek-detect-early-version-of-RTL8221B.patch b/target/linux/generic/pending-6.12/720-05-net-phy-realtek-detect-early-version-of-RTL8221B.patch
index 186b3ff2b9..7c3a44eaea 100644
--- a/target/linux/generic/pending-6.12/720-05-net-phy-realtek-detect-early-version-of-RTL8221B.patch
+++ b/target/linux/generic/pending-6.12/720-05-net-phy-realtek-detect-early-version-of-RTL8221B.patch
@@ -14,7 +14,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
 Signed-off-by: Mieczyslaw Nalewaj <namiltd at yahoo.com>
 --- a/drivers/net/phy/realtek/realtek_main.c
 +++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -1400,10 +1400,32 @@ static int rtl8226_match_phy_device(stru
+@@ -1619,10 +1619,32 @@ static int rtl8226_match_phy_device(stru
  static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id,
  			       bool is_c45)
  {
diff --git a/target/linux/generic/pending-6.12/720-06-net-phy-realtek-support-interrupt-of-RTL8221B.patch b/target/linux/generic/pending-6.12/720-06-net-phy-realtek-support-interrupt-of-RTL8221B.patch
deleted file mode 100644
index e908af055f..0000000000
--- a/target/linux/generic/pending-6.12/720-06-net-phy-realtek-support-interrupt-of-RTL8221B.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-From d7943c31d57c11e1a517aa3ce2006fca44866870 Mon Sep 17 00:00:00 2001
-From: Jianhui Zhao <zhaojh329 at gmail.com>
-Date: Sun, 24 Sep 2023 22:15:00 +0800
-Subject: [PATCH] net: phy: realtek: add interrupt support for RTL8221B
-
-This commit introduces interrupt support for RTL8221B.
-
-Signed-off-by: Jianhui Zhao <zhaojh329 at gmail.com>
----
- drivers/net/phy/realtek/realtek_main.c | 47 +++++++++++++++++++++++++++++++++++++++
- 1 file changed, 47 insertions(+)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -1619,6 +1619,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, MDIO_MMD_VEND2, 0xa4d4);
-+
-+	return (err < 0) ? err : 0;
-+}
-+
-+static int rtl8221b_config_intr(struct phy_device *phydev)
-+{
-+	int err;
-+
-+	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
-+		err = rtl8221b_ack_interrupt(phydev);
-+		if (err)
-+			return err;
-+
-+		err = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xa4d2, 0x7ff);
-+	} else {
-+		err = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xa4d2, 0x0);
-+		if (err)
-+			return err;
-+
-+		err = rtl8221b_ack_interrupt(phydev);
-+	}
-+
-+	return err;
-+}
-+
-+static irqreturn_t rtl8221b_handle_interrupt(struct phy_device *phydev)
-+{
-+	int err;
-+
-+	err = rtl8221b_ack_interrupt(phydev);
-+	if (err) {
-+		phy_error(phydev);
-+		return IRQ_NONE;
-+	}
-+
-+	phy_trigger_machine(phydev);
-+
-+	return IRQ_HANDLED;
-+}
-+
- static struct phy_driver realtek_drvs[] = {
- 	{
- 		PHY_ID_MATCH_EXACT(0x00008201),
-@@ -1783,6 +1828,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,
- 		.soft_reset     = genphy_soft_reset,
- 		.probe		= rtl822x_probe,
- 		.get_features   = rtl822x_get_features,
-@@ -1797,6 +1844,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,
- 		.soft_reset     = rtl822x_c45_soft_reset,
- 		.probe		= rtl822x_probe,
- 		.config_init    = rtl822xb_config_init,
-@@ -1809,6 +1858,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,
- 		.soft_reset     = genphy_soft_reset,
- 		.probe		= rtl822x_probe,
- 		.get_features   = rtl822x_get_features,
-@@ -1823,6 +1874,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,
- 		.soft_reset     = rtl822x_c45_soft_reset,
- 		.probe		= rtl822x_probe,
- 		.config_init    = rtl822xb_config_init,
diff --git a/target/linux/generic/pending-6.12/720-07-net-phy-realtek-mark-existing-MMDs-as-present.patch b/target/linux/generic/pending-6.12/720-07-net-phy-realtek-mark-existing-MMDs-as-present.patch
index 4441a5039e..ed6e29ac8b 100644
--- a/target/linux/generic/pending-6.12/720-07-net-phy-realtek-mark-existing-MMDs-as-present.patch
+++ b/target/linux/generic/pending-6.12/720-07-net-phy-realtek-mark-existing-MMDs-as-present.patch
@@ -15,7 +15,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
 
 --- a/drivers/net/phy/realtek/realtek_main.c
 +++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -1259,6 +1259,9 @@ static int rtl822x_c45_get_features(stru
+@@ -1316,6 +1316,9 @@ static int rtl822x_c45_get_features(stru
  	linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT,
  			 phydev->supported);
  
diff --git a/target/linux/generic/pending-6.12/720-08-net-phy-realtek-work-around-broken-serdes.patch b/target/linux/generic/pending-6.12/720-08-net-phy-realtek-work-around-broken-serdes.patch
index d4920b5c97..fcf4350fe9 100644
--- a/target/linux/generic/pending-6.12/720-08-net-phy-realtek-work-around-broken-serdes.patch
+++ b/target/linux/generic/pending-6.12/720-08-net-phy-realtek-work-around-broken-serdes.patch
@@ -15,7 +15,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
 ---
 --- a/drivers/net/phy/realtek/realtek_main.c
 +++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -1139,6 +1139,22 @@ static int rtl822xb_config_init(struct p
+@@ -1196,6 +1196,22 @@ static int rtl822xb_config_init(struct p
  	return rtl822x_set_serdes_option_mode(phydev, false);
  }
  
@@ -38,7 +38,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
  static int rtl822xb_get_rate_matching(struct phy_device *phydev,
  				      phy_interface_t iface)
  {
-@@ -1851,7 +1867,7 @@ static struct phy_driver realtek_drvs[]
+@@ -2070,7 +2086,7 @@ static struct phy_driver realtek_drvs[]
  		.handle_interrupt = rtl8221b_handle_interrupt,
  		.soft_reset     = rtl822x_c45_soft_reset,
  		.probe		= rtl822x_probe,
@@ -47,7 +47,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
  		.get_rate_matching = rtl822xb_get_rate_matching,
  		.get_features   = rtl822x_c45_get_features,
  		.config_aneg    = rtl822x_c45_config_aneg,
-@@ -1881,7 +1897,7 @@ static struct phy_driver realtek_drvs[]
+@@ -2098,7 +2114,7 @@ static struct phy_driver realtek_drvs[]
  		.handle_interrupt = rtl8221b_handle_interrupt,
  		.soft_reset     = rtl822x_c45_soft_reset,
  		.probe		= rtl822x_probe,
diff --git a/target/linux/generic/pending-6.12/720-09-net-phy-realtek-disable-MDIO-broadcast.patch b/target/linux/generic/pending-6.12/720-09-net-phy-realtek-disable-MDIO-broadcast.patch
index 24db18c2a7..f2e009bc35 100644
--- a/target/linux/generic/pending-6.12/720-09-net-phy-realtek-disable-MDIO-broadcast.patch
+++ b/target/linux/generic/pending-6.12/720-09-net-phy-realtek-disable-MDIO-broadcast.patch
@@ -13,7 +13,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
 ---
 --- a/drivers/net/phy/realtek/realtek_main.c
 +++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -1050,6 +1050,11 @@ static int rtl822x_set_serdes_option_mod
+@@ -1107,6 +1107,11 @@ static int rtl822x_set_serdes_option_mod
  			     phydev->host_interfaces) ||
  		    phydev->interface == PHY_INTERFACE_MODE_SGMII;
  
diff --git a/target/linux/generic/pending-6.6/720-01-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch b/target/linux/generic/pending-6.6/720-01-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch
index deb6506186..5d8f37a264 100644
--- a/target/linux/generic/pending-6.6/720-01-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch
+++ b/target/linux/generic/pending-6.6/720-01-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch
@@ -15,7 +15,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
 
 --- a/drivers/net/phy/realtek/realtek_main.c
 +++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -1647,6 +1647,7 @@ static struct phy_driver realtek_drvs[]
+@@ -1913,6 +1913,7 @@ static struct phy_driver realtek_drvs[]
  	}, {
  		.name		= "RTL8226 2.5Gbps PHY",
  		.match_phy_device = rtl8226_match_phy_device,
@@ -23,7 +23,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
  		.get_features	= rtl822x_get_features,
  		.config_aneg	= rtl822x_config_aneg,
  		.read_status	= rtl822x_read_status,
-@@ -1657,6 +1658,7 @@ static struct phy_driver realtek_drvs[]
+@@ -1923,6 +1924,7 @@ static struct phy_driver realtek_drvs[]
  	}, {
  		.match_phy_device = rtl8221b_match_phy_device,
  		.name		= "RTL8226B_RTL8221B 2.5Gbps PHY",
@@ -31,7 +31,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
  		.get_features	= rtl822x_get_features,
  		.config_aneg	= rtl822x_config_aneg,
  		.config_init    = rtl822xb_config_init,
-@@ -1669,6 +1671,7 @@ static struct phy_driver realtek_drvs[]
+@@ -1935,6 +1937,7 @@ static struct phy_driver realtek_drvs[]
  	}, {
  		PHY_ID_MATCH_EXACT(0x001cc838),
  		.name           = "RTL8226-CG 2.5Gbps PHY",
@@ -39,7 +39,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
  		.get_features   = rtl822x_get_features,
  		.config_aneg    = rtl822x_config_aneg,
  		.read_status    = rtl822x_read_status,
-@@ -1679,6 +1682,7 @@ static struct phy_driver realtek_drvs[]
+@@ -1945,6 +1948,7 @@ static struct phy_driver realtek_drvs[]
  	}, {
  		PHY_ID_MATCH_EXACT(0x001cc848),
  		.name           = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
@@ -47,7 +47,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
  		.get_features   = rtl822x_get_features,
  		.config_aneg    = rtl822x_config_aneg,
  		.config_init    = rtl822xb_config_init,
-@@ -1691,6 +1695,7 @@ static struct phy_driver realtek_drvs[]
+@@ -1957,6 +1961,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)",
@@ -55,26 +55,26 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
  		.probe		= rtl822x_probe,
  		.get_features   = rtl822x_get_features,
  		.config_aneg    = rtl822x_config_aneg,
-@@ -1704,6 +1709,7 @@ static struct phy_driver realtek_drvs[]
- 	}, {
- 		.match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
+@@ -1972,6 +1977,7 @@ static struct phy_driver realtek_drvs[]
  		.name           = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
+ 		.config_intr	= rtl8221b_config_intr,
+ 		.handle_interrupt = rtl8221b_handle_interrupt,
 +		.soft_reset     = genphy_soft_reset,
  		.probe		= rtl822x_probe,
  		.config_init    = rtl822xb_config_init,
  		.get_rate_matching = rtl822xb_get_rate_matching,
-@@ -1715,6 +1721,7 @@ static struct phy_driver realtek_drvs[]
+@@ -1983,6 +1989,7 @@ static struct phy_driver realtek_drvs[]
  	}, {
- 		.match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
+ 		.match_phy_device = rtl8221b_vm_cg_c22_match_phy_device,
  		.name           = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
 +		.soft_reset     = genphy_soft_reset,
  		.probe		= rtl822x_probe,
  		.get_features   = rtl822x_get_features,
  		.config_aneg    = rtl822x_config_aneg,
-@@ -1728,6 +1735,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)",
+@@ -1998,6 +2005,7 @@ static struct phy_driver realtek_drvs[]
+ 		.name           = "RTL8221B-VM-CG 2.5Gbps PHY (C45)",
+ 		.config_intr	= rtl8221b_config_intr,
+ 		.handle_interrupt = rtl8221b_handle_interrupt,
 +		.soft_reset     = genphy_soft_reset,
  		.probe		= rtl822x_probe,
  		.config_init    = rtl822xb_config_init,
diff --git a/target/linux/generic/pending-6.6/720-02-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch b/target/linux/generic/pending-6.6/720-02-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch
index e11a7984d4..b148194308 100644
--- a/target/linux/generic/pending-6.6/720-02-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch
+++ b/target/linux/generic/pending-6.6/720-02-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch
@@ -20,7 +20,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
 
 --- a/drivers/net/phy/realtek/realtek_main.c
 +++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -1035,8 +1035,8 @@ static int rtl822x_probe(struct phy_devi
+@@ -1092,8 +1092,8 @@ static int rtl822x_probe(struct phy_devi
  static int rtl822xb_config_init(struct phy_device *phydev)
  {
  	bool has_2500, has_sgmii;
@@ -30,7 +30,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
  
  	has_2500 = test_bit(PHY_INTERFACE_MODE_2500BASEX,
  			    phydev->host_interfaces) ||
-@@ -1086,7 +1086,29 @@ static int rtl822xb_config_init(struct p
+@@ -1143,7 +1143,29 @@ static int rtl822xb_config_init(struct p
  	if (ret < 0)
  		return ret;
  
diff --git a/target/linux/generic/pending-6.6/720-03-net-phy-realtek-make-sure-paged-read-is-protected-by.patch b/target/linux/generic/pending-6.6/720-03-net-phy-realtek-make-sure-paged-read-is-protected-by.patch
index e6656445db..11ca797bae 100644
--- a/target/linux/generic/pending-6.6/720-03-net-phy-realtek-make-sure-paged-read-is-protected-by.patch
+++ b/target/linux/generic/pending-6.6/720-03-net-phy-realtek-make-sure-paged-read-is-protected-by.patch
@@ -18,7 +18,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
 
 --- a/drivers/net/phy/realtek/realtek_main.c
 +++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -1313,9 +1313,11 @@ static bool rtlgen_supports_2_5gbps(stru
+@@ -1532,9 +1532,11 @@ static bool rtlgen_supports_2_5gbps(stru
  {
  	int val;
  
diff --git a/target/linux/generic/pending-6.6/720-04-net-phy-realtek-setup-aldps.patch b/target/linux/generic/pending-6.6/720-04-net-phy-realtek-setup-aldps.patch
index b36e54717d..ae150daede 100644
--- a/target/linux/generic/pending-6.6/720-04-net-phy-realtek-setup-aldps.patch
+++ b/target/linux/generic/pending-6.6/720-04-net-phy-realtek-setup-aldps.patch
@@ -13,9 +13,9 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
 
 --- a/drivers/net/phy/realtek/realtek_main.c
 +++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -129,6 +129,10 @@
-  */
- #define RTL822X_VND2_C22_REG(reg)		(0xa400 + 2 * (reg))
+@@ -156,6 +156,10 @@
+ 
+ #define RTL8224_SRAM_RTCT_LEN(pair)		(0x8028 + (pair) * 4)
  
 +#define RTL8221B_PHYCR1				0xa430
 +#define RTL8221B_PHYCR1_ALDPS_EN		BIT(2)
@@ -24,7 +24,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
  #define RTL8366RB_POWER_SAVE			0x15
  #define RTL8366RB_POWER_SAVE_ON			BIT(12)
  
-@@ -1090,6 +1094,15 @@ static int rtl822xb_config_init(struct p
+@@ -1147,6 +1151,15 @@ static int rtl822xb_config_init(struct p
  	if (ret < 0)
  		return ret;
  
diff --git a/target/linux/generic/pending-6.6/720-05-net-phy-realtek-detect-early-version-of-RTL8221B.patch b/target/linux/generic/pending-6.6/720-05-net-phy-realtek-detect-early-version-of-RTL8221B.patch
index 2886babe57..b11b16d0ef 100644
--- a/target/linux/generic/pending-6.6/720-05-net-phy-realtek-detect-early-version-of-RTL8221B.patch
+++ b/target/linux/generic/pending-6.6/720-05-net-phy-realtek-detect-early-version-of-RTL8221B.patch
@@ -14,7 +14,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
 Signed-off-by: Mieczyslaw Nalewaj <namiltd at yahoo.com>
 --- a/drivers/net/phy/realtek/realtek_main.c
 +++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -1370,10 +1370,32 @@ static int rtl8226_match_phy_device(stru
+@@ -1589,10 +1589,32 @@ static int rtl8226_match_phy_device(stru
  static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id,
  			       bool is_c45)
  {
diff --git a/target/linux/generic/pending-6.6/720-06-net-phy-realtek-support-interrupt-of-RTL8221B.patch b/target/linux/generic/pending-6.6/720-06-net-phy-realtek-support-interrupt-of-RTL8221B.patch
deleted file mode 100644
index 29610d2767..0000000000
--- a/target/linux/generic/pending-6.6/720-06-net-phy-realtek-support-interrupt-of-RTL8221B.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-From d7943c31d57c11e1a517aa3ce2006fca44866870 Mon Sep 17 00:00:00 2001
-From: Jianhui Zhao <zhaojh329 at gmail.com>
-Date: Sun, 24 Sep 2023 22:15:00 +0800
-Subject: [PATCH] net: phy: realtek: add interrupt support for RTL8221B
-
-This commit introduces interrupt support for RTL8221B.
-
-Signed-off-by: Jianhui Zhao <zhaojh329 at gmail.com>
----
- drivers/net/phy/realtek/realtek_main.c | 47 +++++++++++++++++++++++++++++++++++++++
- 1 file changed, 47 insertions(+)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -1589,6 +1589,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, MDIO_MMD_VEND2, 0xa4d4);
-+
-+	return (err < 0) ? err : 0;
-+}
-+
-+static int rtl8221b_config_intr(struct phy_device *phydev)
-+{
-+	int err;
-+
-+	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
-+		err = rtl8221b_ack_interrupt(phydev);
-+		if (err)
-+			return err;
-+
-+		err = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xa4d2, 0x7ff);
-+	} else {
-+		err = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xa4d2, 0x0);
-+		if (err)
-+			return err;
-+
-+		err = rtl8221b_ack_interrupt(phydev);
-+	}
-+
-+	return err;
-+}
-+
-+static irqreturn_t rtl8221b_handle_interrupt(struct phy_device *phydev)
-+{
-+	int err;
-+
-+	err = rtl8221b_ack_interrupt(phydev);
-+	if (err) {
-+		phy_error(phydev);
-+		return IRQ_NONE;
-+	}
-+
-+	phy_trigger_machine(phydev);
-+
-+	return IRQ_HANDLED;
-+}
-+
- static struct phy_driver realtek_drvs[] = {
- 	{
- 		PHY_ID_MATCH_EXACT(0x00008201),
-@@ -1754,6 +1799,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,
- 		.soft_reset     = genphy_soft_reset,
- 		.probe		= rtl822x_probe,
- 		.get_features   = rtl822x_get_features,
-@@ -1768,6 +1815,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,
- 		.soft_reset     = genphy_soft_reset,
- 		.probe		= rtl822x_probe,
- 		.config_init    = rtl822xb_config_init,
-@@ -1780,6 +1829,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,
- 		.soft_reset     = genphy_soft_reset,
- 		.probe		= rtl822x_probe,
- 		.get_features   = rtl822x_get_features,
-@@ -1794,6 +1845,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,
- 		.soft_reset     = genphy_soft_reset,
- 		.probe		= rtl822x_probe,
- 		.config_init    = rtl822xb_config_init,
diff --git a/target/linux/generic/pending-6.6/720-07-net-phy-realtek-mark-existing-MMDs-as-present.patch b/target/linux/generic/pending-6.6/720-07-net-phy-realtek-mark-existing-MMDs-as-present.patch
index 20bd666fd2..93544c438c 100644
--- a/target/linux/generic/pending-6.6/720-07-net-phy-realtek-mark-existing-MMDs-as-present.patch
+++ b/target/linux/generic/pending-6.6/720-07-net-phy-realtek-mark-existing-MMDs-as-present.patch
@@ -15,7 +15,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
 
 --- a/drivers/net/phy/realtek/realtek_main.c
 +++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -1244,6 +1244,9 @@ static int rtl822x_c45_get_features(stru
+@@ -1301,6 +1301,9 @@ static int rtl822x_c45_get_features(stru
  	linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT,
  			 phydev->supported);
  
diff --git a/target/linux/generic/pending-6.6/720-08-net-phy-realtek-work-around-broken-serdes.patch b/target/linux/generic/pending-6.6/720-08-net-phy-realtek-work-around-broken-serdes.patch
index 1b6978547d..f1696042aa 100644
--- a/target/linux/generic/pending-6.6/720-08-net-phy-realtek-work-around-broken-serdes.patch
+++ b/target/linux/generic/pending-6.6/720-08-net-phy-realtek-work-around-broken-serdes.patch
@@ -15,7 +15,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
 ---
 --- a/drivers/net/phy/realtek/realtek_main.c
 +++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -1124,6 +1124,22 @@ static int rtl822xb_config_init(struct p
+@@ -1181,6 +1181,22 @@ static int rtl822xb_config_init(struct p
  	return 0;
  }
  
@@ -38,7 +38,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
  static int rtl822xb_get_rate_matching(struct phy_device *phydev,
  				      phy_interface_t iface)
  {
-@@ -1822,7 +1838,7 @@ static struct phy_driver realtek_drvs[]
+@@ -2041,7 +2057,7 @@ static struct phy_driver realtek_drvs[]
  		.handle_interrupt = rtl8221b_handle_interrupt,
  		.soft_reset     = genphy_soft_reset,
  		.probe		= rtl822x_probe,
@@ -47,7 +47,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
  		.get_rate_matching = rtl822xb_get_rate_matching,
  		.get_features   = rtl822x_c45_get_features,
  		.config_aneg    = rtl822x_c45_config_aneg,
-@@ -1852,7 +1868,7 @@ static struct phy_driver realtek_drvs[]
+@@ -2069,7 +2085,7 @@ static struct phy_driver realtek_drvs[]
  		.handle_interrupt = rtl8221b_handle_interrupt,
  		.soft_reset     = genphy_soft_reset,
  		.probe		= rtl822x_probe,
diff --git a/target/linux/generic/pending-6.6/720-09-net-phy-realtek-disable-MDIO-broadcast.patch b/target/linux/generic/pending-6.6/720-09-net-phy-realtek-disable-MDIO-broadcast.patch
index bb20750033..8ed075a2e0 100644
--- a/target/linux/generic/pending-6.6/720-09-net-phy-realtek-disable-MDIO-broadcast.patch
+++ b/target/linux/generic/pending-6.6/720-09-net-phy-realtek-disable-MDIO-broadcast.patch
@@ -13,7 +13,7 @@ Signed-off-by: Daniel Golle <daniel at makrotopia.org>
 ---
 --- a/drivers/net/phy/realtek/realtek_main.c
 +++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -1050,6 +1050,11 @@ static int rtl822xb_config_init(struct p
+@@ -1107,6 +1107,11 @@ static int rtl822xb_config_init(struct p
  			     phydev->host_interfaces) ||
  		    phydev->interface == PHY_INTERFACE_MODE_SGMII;
  




More information about the lede-commits mailing list