Skip to content

Commit 7b3ce53

Browse files
authored
Backport realtek phy driver changes for RTL8125D (home-assistant#4014)
As pointed out in [1] by @cdce8p, the RTL8125D has an internal PHY that also needs some changes to be backported. Also, move the patches to more targeted directories is it would be otherwise applied to RPi 6.6 kernel with failures. We can move it back to the top-level patches directory once RPi moves to kernel 6.12. [1] home-assistant#3880 (comment)
1 parent 7bc7f66 commit 7b3ce53

10 files changed

Lines changed: 515 additions & 3 deletions

buildroot-external/patches/linux/0002-r8169-add-support-for-RTL8125D.patch renamed to buildroot-external/board/arm-uefi/generic-aarch64/patches/linux/0001-r8169-add-support-for-RTL8125D.patch

File renamed without changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
From acc8d5ec4b6cdbf0a9625a9f9d3710b52555f3b2 Mon Sep 17 00:00:00 2001
2+
From: Heiner Kallweit <hkallweit1@gmail.com>
3+
Date: Tue, 15 Oct 2024 07:47:14 +0200
4+
Subject: [PATCH] net: phy: realtek: merge the drivers for internal NBase-T
5+
PHY's
6+
MIME-Version: 1.0
7+
Content-Type: text/plain; charset=UTF-8
8+
Content-Transfer-Encoding: 8bit
9+
10+
The Realtek RTL8125/RTL8126 NBase-T MAC/PHY chips have internal PHY's
11+
which are register-compatible, at least for the registers we use here.
12+
So let's use just one PHY driver to support all of them.
13+
These internal PHY's exist also as external C45 PHY's, but on the
14+
internal PHY's no access to MMD registers is possible. This can be
15+
used to differentiate between the internal and external version.
16+
17+
As a side effect the drivers for two now external-only drivers don't
18+
require read_mmd/write_mmd hooks any longer.
19+
20+
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
21+
Link: https://patch.msgid.link/c57081a6-811f-4571-ab35-34f4ca6de9af@gmail.com
22+
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
23+
Upstream: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=f87a17ed3b51fba4dfdd8f8b643b5423a85fc551
24+
Signed-off-by: Jan Čermák <sairon@sairon.cz>
25+
---
26+
drivers/net/phy/realtek.c | 53 +++++++++++++++++++++++++++++++--------
27+
1 file changed, 43 insertions(+), 10 deletions(-)
28+
29+
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
30+
index 166f6a7283731..830a0d337de5d 100644
31+
--- a/drivers/net/phy/realtek.c
32+
+++ b/drivers/net/phy/realtek.c
33+
@@ -92,6 +92,7 @@
34+
35+
#define RTL_GENERIC_PHYID 0x001cc800
36+
#define RTL_8211FVD_PHYID 0x001cc878
37+
+#define RTL_8221B 0x001cc840
38+
#define RTL_8221B_VB_CG 0x001cc849
39+
#define RTL_8221B_VN_CG 0x001cc84a
40+
#define RTL_8251B 0x001cc862
41+
@@ -1040,6 +1041,23 @@ static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
42+
return val >= 0 && val & MDIO_PMA_SPEED_2_5G;
43+
}
44+
45+
+/* On internal PHY's MMD reads over C22 always return 0.
46+
+ * Check a MMD register which is known to be non-zero.
47+
+ */
48+
+static bool rtlgen_supports_mmd(struct phy_device *phydev)
49+
+{
50+
+ int val;
51+
+
52+
+ phy_lock_mdio_bus(phydev);
53+
+ __phy_write(phydev, MII_MMD_CTRL, MDIO_MMD_PCS);
54+
+ __phy_write(phydev, MII_MMD_DATA, MDIO_PCS_EEE_ABLE);
55+
+ __phy_write(phydev, MII_MMD_CTRL, MDIO_MMD_PCS | MII_MMD_CTRL_NOINCR);
56+
+ val = __phy_read(phydev, MII_MMD_DATA);
57+
+ phy_unlock_mdio_bus(phydev);
58+
+
59+
+ return val > 0;
60+
+}
61+
+
62+
static int rtlgen_match_phy_device(struct phy_device *phydev)
63+
{
64+
return phydev->phy_id == RTL_GENERIC_PHYID &&
65+
@@ -1049,7 +1067,8 @@ static int rtlgen_match_phy_device(struct phy_device *phydev)
66+
static int rtl8226_match_phy_device(struct phy_device *phydev)
67+
{
68+
return phydev->phy_id == RTL_GENERIC_PHYID &&
69+
- rtlgen_supports_2_5gbps(phydev);
70+
+ rtlgen_supports_2_5gbps(phydev) &&
71+
+ rtlgen_supports_mmd(phydev);
72+
}
73+
74+
static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id,
75+
@@ -1061,6 +1080,11 @@ static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id,
76+
return !is_c45 && (id == phydev->phy_id);
77+
}
78+
79+
+static int rtl8221b_match_phy_device(struct phy_device *phydev)
80+
+{
81+
+ return phydev->phy_id == RTL_8221B && rtlgen_supports_mmd(phydev);
82+
+}
83+
+
84+
static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev)
85+
{
86+
return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false);
87+
@@ -1081,9 +1105,21 @@ static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev)
88+
return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true);
89+
}
90+
91+
-static int rtl8251b_c22_match_phy_device(struct phy_device *phydev)
92+
+static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev)
93+
{
94+
- return rtlgen_is_c45_match(phydev, RTL_8251B, false);
95+
+ if (phydev->is_c45)
96+
+ return false;
97+
+
98+
+ switch (phydev->phy_id) {
99+
+ case RTL_GENERIC_PHYID:
100+
+ case RTL_8221B:
101+
+ case RTL_8251B:
102+
+ break;
103+
+ default:
104+
+ return false;
105+
+ }
106+
+
107+
+ return rtlgen_supports_2_5gbps(phydev) && !rtlgen_supports_mmd(phydev);
108+
}
109+
110+
static int rtl8251b_c45_match_phy_device(struct phy_device *phydev)
111+
@@ -1345,10 +1381,8 @@ static struct phy_driver realtek_drvs[] = {
112+
.resume = rtlgen_resume,
113+
.read_page = rtl821x_read_page,
114+
.write_page = rtl821x_write_page,
115+
- .read_mmd = rtl822x_read_mmd,
116+
- .write_mmd = rtl822x_write_mmd,
117+
}, {
118+
- PHY_ID_MATCH_EXACT(0x001cc840),
119+
+ .match_phy_device = rtl8221b_match_phy_device,
120+
.name = "RTL8226B_RTL8221B 2.5Gbps PHY",
121+
.get_features = rtl822x_get_features,
122+
.config_aneg = rtl822x_config_aneg,
123+
@@ -1359,8 +1393,6 @@ static struct phy_driver realtek_drvs[] = {
124+
.resume = rtlgen_resume,
125+
.read_page = rtl821x_read_page,
126+
.write_page = rtl821x_write_page,
127+
- .read_mmd = rtl822x_read_mmd,
128+
- .write_mmd = rtl822x_write_mmd,
129+
}, {
130+
PHY_ID_MATCH_EXACT(0x001cc838),
131+
.name = "RTL8226-CG 2.5Gbps PHY",
132+
@@ -1438,8 +1470,9 @@ static struct phy_driver realtek_drvs[] = {
133+
.read_page = rtl821x_read_page,
134+
.write_page = rtl821x_write_page,
135+
}, {
136+
- .match_phy_device = rtl8251b_c22_match_phy_device,
137+
- .name = "RTL8126A-internal 5Gbps PHY",
138+
+ .match_phy_device = rtl_internal_nbaset_match_phy_device,
139+
+ .name = "Realtek Internal NBASE-T PHY",
140+
+ .flags = PHY_IS_INTERNAL,
141+
.get_features = rtl822x_get_features,
142+
.config_aneg = rtl822x_config_aneg,
143+
.read_status = rtl822x_read_status,
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
From 7ab842c714924784cae4b6ab229997905b096b4f Mon Sep 17 00:00:00 2001
2+
From: Heiner Kallweit <hkallweit1@gmail.com>
3+
Date: Thu, 17 Oct 2024 18:01:13 +0200
4+
Subject: [PATCH] net: phy: realtek: add RTL8125D-internal PHY
5+
MIME-Version: 1.0
6+
Content-Type: text/plain; charset=UTF-8
7+
Content-Transfer-Encoding: 8bit
8+
9+
The first boards show up with Realtek's RTL8125D. This MAC/PHY chip
10+
comes with an integrated 2.5Gbps PHY with ID 0x001cc841. It's not
11+
clear yet whether there's an external version of this PHY and how
12+
Realtek calls it, therefore use the numeric id for now.
13+
14+
Link: https://lore.kernel.org/netdev/2ada65e1-5dfa-456c-9334-2bc51272e9da@gmail.com/T/
15+
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
16+
Message-ID: <7d2924de-053b-44d2-a479-870dc3878170@gmail.com>
17+
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
18+
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
19+
Upstream: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=8989bad541133c43550bff2b80edbe37b8fb9659
20+
Signed-off-by: Jan Čermák <sairon@sairon.cz>
21+
---
22+
drivers/net/phy/realtek.c | 1 +
23+
1 file changed, 1 insertion(+)
24+
25+
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
26+
index 830a0d337de5d..8ce5705af69c5 100644
27+
--- a/drivers/net/phy/realtek.c
28+
+++ b/drivers/net/phy/realtek.c
29+
@@ -1114,6 +1114,7 @@ static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev)
30+
case RTL_GENERIC_PHYID:
31+
case RTL_8221B:
32+
case RTL_8251B:
33+
+ case 0x001cc841:
34+
break;
35+
default:
36+
return false;
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
From f0fb974644a132ecc4bd2dc5cce9622435d0ec13 Mon Sep 17 00:00:00 2001
2+
From: Heiner Kallweit <hkallweit1@gmail.com>
3+
Date: Thu, 24 Oct 2024 22:42:33 +0200
4+
Subject: [PATCH] r8169: add support for RTL8125D
5+
MIME-Version: 1.0
6+
Content-Type: text/plain; charset=UTF-8
7+
Content-Transfer-Encoding: 8bit
8+
9+
This adds support for new chip version RTL8125D, which can be found on
10+
boards like Gigabyte X870E AORUS ELITE WIFI7. Firmware rtl8125d-1.fw
11+
for this chip version is available in linux-firmware already.
12+
13+
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
14+
Reviewed-by: Simon Horman <horms@kernel.org>
15+
Link: https://patch.msgid.link/d0306912-e88e-4c25-8b5d-545ae8834c0c@gmail.com
16+
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
17+
Upstream: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=f75d1fbe7809bc5ed134204b920fd9e2fc5db1df
18+
Signed-off-by: Jan Čermák <sairon@sairon.cz>
19+
---
20+
drivers/net/ethernet/realtek/r8169.h | 1 +
21+
drivers/net/ethernet/realtek/r8169_main.c | 23 +++++++++++++------
22+
.../net/ethernet/realtek/r8169_phy_config.c | 10 ++++++++
23+
3 files changed, 27 insertions(+), 7 deletions(-)
24+
25+
diff --git a/drivers/net/ethernet/realtek/r8169.h b/drivers/net/ethernet/realtek/r8169.h
26+
index e2db944e6fa8b..be4c9622618d8 100644
27+
--- a/drivers/net/ethernet/realtek/r8169.h
28+
+++ b/drivers/net/ethernet/realtek/r8169.h
29+
@@ -68,6 +68,7 @@ enum mac_version {
30+
/* support for RTL_GIGA_MAC_VER_60 has been removed */
31+
RTL_GIGA_MAC_VER_61,
32+
RTL_GIGA_MAC_VER_63,
33+
+ RTL_GIGA_MAC_VER_64,
34+
RTL_GIGA_MAC_VER_65,
35+
RTL_GIGA_MAC_VER_66,
36+
RTL_GIGA_MAC_NONE
37+
diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
38+
index 5ed2818bac257..1cbde7ebd6f30 100644
39+
--- a/drivers/net/ethernet/realtek/r8169_main.c
40+
+++ b/drivers/net/ethernet/realtek/r8169_main.c
41+
@@ -55,6 +55,7 @@
42+
#define FIRMWARE_8107E_2 "rtl_nic/rtl8107e-2.fw"
43+
#define FIRMWARE_8125A_3 "rtl_nic/rtl8125a-3.fw"
44+
#define FIRMWARE_8125B_2 "rtl_nic/rtl8125b-2.fw"
45+
+#define FIRMWARE_8125D_1 "rtl_nic/rtl8125d-1.fw"
46+
#define FIRMWARE_8126A_2 "rtl_nic/rtl8126a-2.fw"
47+
#define FIRMWARE_8126A_3 "rtl_nic/rtl8126a-3.fw"
48+
49+
@@ -138,6 +139,7 @@ static const struct {
50+
[RTL_GIGA_MAC_VER_61] = {"RTL8125A", FIRMWARE_8125A_3},
51+
/* reserve 62 for CFG_METHOD_4 in the vendor driver */
52+
[RTL_GIGA_MAC_VER_63] = {"RTL8125B", FIRMWARE_8125B_2},
53+
+ [RTL_GIGA_MAC_VER_64] = {"RTL8125D", FIRMWARE_8125D_1},
54+
[RTL_GIGA_MAC_VER_65] = {"RTL8126A", FIRMWARE_8126A_2},
55+
[RTL_GIGA_MAC_VER_66] = {"RTL8126A", FIRMWARE_8126A_3},
56+
};
57+
@@ -707,6 +709,7 @@ MODULE_FIRMWARE(FIRMWARE_8168FP_3);
58+
MODULE_FIRMWARE(FIRMWARE_8107E_2);
59+
MODULE_FIRMWARE(FIRMWARE_8125A_3);
60+
MODULE_FIRMWARE(FIRMWARE_8125B_2);
61+
+MODULE_FIRMWARE(FIRMWARE_8125D_1);
62+
MODULE_FIRMWARE(FIRMWARE_8126A_2);
63+
MODULE_FIRMWARE(FIRMWARE_8126A_3);
64+
65+
@@ -2098,10 +2101,7 @@ static void rtl_set_eee_txidle_timer(struct rtl8169_private *tp)
66+
tp->tx_lpi_timer = timer_val;
67+
r8168_mac_ocp_write(tp, 0xe048, timer_val);
68+
break;
69+
- case RTL_GIGA_MAC_VER_61:
70+
- case RTL_GIGA_MAC_VER_63:
71+
- case RTL_GIGA_MAC_VER_65:
72+
- case RTL_GIGA_MAC_VER_66:
73+
+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_66:
74+
tp->tx_lpi_timer = timer_val;
75+
RTL_W16(tp, EEE_TXIDLE_TIMER_8125, timer_val);
76+
break;
77+
@@ -2233,6 +2233,9 @@ static enum mac_version rtl8169_get_mac_version(u16 xid, bool gmii)
78+
{ 0x7cf, 0x64a, RTL_GIGA_MAC_VER_66 },
79+
{ 0x7cf, 0x649, RTL_GIGA_MAC_VER_65 },
80+
81+
+ /* 8125D family. */
82+
+ { 0x7cf, 0x688, RTL_GIGA_MAC_VER_64 },
83+
+
84+
/* 8125B family. */
85+
{ 0x7cf, 0x641, RTL_GIGA_MAC_VER_63 },
86+
87+
@@ -2500,9 +2503,7 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp)
88+
case RTL_GIGA_MAC_VER_61:
89+
RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST);
90+
break;
91+
- case RTL_GIGA_MAC_VER_63:
92+
- case RTL_GIGA_MAC_VER_65:
93+
- case RTL_GIGA_MAC_VER_66:
94+
+ case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_66:
95+
RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST |
96+
RX_PAUSE_SLOT_ON);
97+
break;
98+
@@ -3814,6 +3815,12 @@ static void rtl_hw_start_8125b(struct rtl8169_private *tp)
99+
rtl_hw_start_8125_common(tp);
100+
}
101+
102+
+static void rtl_hw_start_8125d(struct rtl8169_private *tp)
103+
+{
104+
+ rtl_set_def_aspm_entry_latency(tp);
105+
+ rtl_hw_start_8125_common(tp);
106+
+}
107+
+
108+
static void rtl_hw_start_8126a(struct rtl8169_private *tp)
109+
{
110+
rtl_set_def_aspm_entry_latency(tp);
111+
@@ -3862,6 +3869,7 @@ static void rtl_hw_config(struct rtl8169_private *tp)
112+
[RTL_GIGA_MAC_VER_53] = rtl_hw_start_8117,
113+
[RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125a_2,
114+
[RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b,
115+
+ [RTL_GIGA_MAC_VER_64] = rtl_hw_start_8125d,
116+
[RTL_GIGA_MAC_VER_65] = rtl_hw_start_8126a,
117+
[RTL_GIGA_MAC_VER_66] = rtl_hw_start_8126a,
118+
};
119+
@@ -3879,6 +3887,7 @@ static void rtl_hw_start_8125(struct rtl8169_private *tp)
120+
/* disable interrupt coalescing */
121+
switch (tp->mac_version) {
122+
case RTL_GIGA_MAC_VER_61:
123+
+ case RTL_GIGA_MAC_VER_64:
124+
for (i = 0xa00; i < 0xb00; i += 4)
125+
RTL_W32(tp, i, 0);
126+
break;
127+
diff --git a/drivers/net/ethernet/realtek/r8169_phy_config.c b/drivers/net/ethernet/realtek/r8169_phy_config.c
128+
index cf29b12084826..d09b2a41cd062 100644
129+
--- a/drivers/net/ethernet/realtek/r8169_phy_config.c
130+
+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
131+
@@ -1104,6 +1104,15 @@ static void rtl8125b_hw_phy_config(struct rtl8169_private *tp,
132+
rtl8125b_config_eee_phy(phydev);
133+
}
134+
135+
+static void rtl8125d_hw_phy_config(struct rtl8169_private *tp,
136+
+ struct phy_device *phydev)
137+
+{
138+
+ r8169_apply_firmware(tp);
139+
+ rtl8125_legacy_force_mode(phydev);
140+
+ rtl8168g_disable_aldps(phydev);
141+
+ rtl8125b_config_eee_phy(phydev);
142+
+}
143+
+
144+
static void rtl8126a_hw_phy_config(struct rtl8169_private *tp,
145+
struct phy_device *phydev)
146+
{
147+
@@ -1160,6 +1169,7 @@ void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
148+
[RTL_GIGA_MAC_VER_53] = rtl8117_hw_phy_config,
149+
[RTL_GIGA_MAC_VER_61] = rtl8125a_2_hw_phy_config,
150+
[RTL_GIGA_MAC_VER_63] = rtl8125b_hw_phy_config,
151+
+ [RTL_GIGA_MAC_VER_64] = rtl8125d_hw_phy_config,
152+
[RTL_GIGA_MAC_VER_65] = rtl8126a_hw_phy_config,
153+
[RTL_GIGA_MAC_VER_66] = rtl8126a_hw_phy_config,
154+
};

0 commit comments

Comments
 (0)