mirror of
https://git.openwrt.org/openwrt/openwrt.git
synced 2026-01-28 03:37:17 +01:00
kernel: net: phy: realtek: replace patches with upstream backports
Replace downstream patches with backports of commits accepted upstream. Signed-off-by: Daniel Golle <daniel@makrotopia.org>
This commit is contained in:
parent
d93429888c
commit
2a7d374dcd
8 changed files with 409 additions and 136 deletions
|
|
@ -1,16 +1,20 @@
|
|||
From 65de36f5eae1c540115bf8f705f853718e9b6451 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 5 Jan 2026 14:51:47 +0000
|
||||
Subject: [PATCH] net: phy: export mmd_phy_read and mmd_phy_write to phylib.h
|
||||
Date: Mon, 5 Jan 2026 16:38:29 +0000
|
||||
Subject: [PATCH 3/5] net: phy: move mmd_phy_read and mmd_phy_write to phylib.h
|
||||
|
||||
Helper functions mmd_phy_read and mmd_phy_write are useful for PHYs
|
||||
which require custom MMD access functions for some but not all MMDs.
|
||||
Move mmd_phy_read and mmd_phy_write function prototypes from
|
||||
phylib-internal.h to phylib.h to make them available for PHY drivers.
|
||||
|
||||
This patch replaces pending upstream patch
|
||||
"net: phy: move mmd_phy_read and mmd_phy_write to phylib.h"
|
||||
for Linux 6.12.
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Link: https://patch.msgid.link/79169cd624a3572d426e42c7b13cd2654a35d0cb.1767630451.git.daniel@makrotopia.org
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
See also
|
||||
https://patchwork.kernel.org/project/netdevbpf/patch/79169cd624a3572d426e42c7b13cd2654a35d0cb.1767630451.git.daniel@makrotopia.org/
|
||||
Note that this patch replaces the commit above as neither phylink.h nor
|
||||
phylink-internal.h exist in Linux 6.12.
|
||||
--- a/drivers/net/phy/phy-core.c
|
||||
+++ b/drivers/net/phy/phy-core.c
|
||||
@@ -542,8 +542,8 @@ static void mmd_phy_indirect(struct mii_
|
||||
|
|
@ -47,7 +51,7 @@ https://patchwork.kernel.org/project/netdevbpf/patch/79169cd624a3572d426e42c7b13
|
|||
* __phy_read_mmd - Convenience function for reading a register
|
||||
--- a/include/linux/phy.h
|
||||
+++ b/include/linux/phy.h
|
||||
@@ -2054,6 +2054,11 @@ extern struct phy_driver genphy_c45_driv
|
||||
@@ -2027,6 +2027,11 @@ extern struct phy_driver genphy_c45_driv
|
||||
/* The gen10g_* functions are the old Clause 45 stub */
|
||||
int gen10g_config_aneg(struct phy_device *phydev);
|
||||
|
||||
|
|
@ -0,0 +1,229 @@
|
|||
From 50326b48f0cfbd9324668c5d2e08b39b59dc199f Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 5 Jan 2026 16:37:54 +0000
|
||||
Subject: [PATCH 1/5] net: phy: realtek: fix whitespace in struct phy_driver
|
||||
initializers
|
||||
|
||||
Consistently use tabs instead of spaces in struct phy_driver
|
||||
initializers.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
|
||||
Link: https://patch.msgid.link/42b0fac53c5c5646707ce3f3a6dacd2bc082a5b2.1767630451.git.daniel@makrotopia.org
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/phy/realtek/realtek_main.c | 146 ++++++++++++-------------
|
||||
1 file changed, 73 insertions(+), 73 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -1976,7 +1976,7 @@ static irqreturn_t rtl8221b_handle_inter
|
||||
static struct phy_driver realtek_drvs[] = {
|
||||
{
|
||||
PHY_ID_MATCH_EXACT(0x00008201),
|
||||
- .name = "RTL8201CP Ethernet",
|
||||
+ .name = "RTL8201CP Ethernet",
|
||||
.read_page = rtl821x_read_page,
|
||||
.write_page = rtl821x_write_page,
|
||||
}, {
|
||||
@@ -2102,7 +2102,7 @@ static struct phy_driver realtek_drvs[]
|
||||
.name = "RTL8226B_RTL8221B 2.5Gbps PHY",
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
- .config_init = rtl822xb_config_init,
|
||||
+ .config_init = rtl822xb_config_init,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.read_status = rtl822xb_read_status,
|
||||
.suspend = genphy_suspend,
|
||||
@@ -2111,112 +2111,112 @@ static struct phy_driver realtek_drvs[]
|
||||
.write_page = rtl821x_write_page,
|
||||
}, {
|
||||
PHY_ID_MATCH_EXACT(0x001cc838),
|
||||
- .name = "RTL8226-CG 2.5Gbps PHY",
|
||||
- .soft_reset = rtl822x_c45_soft_reset,
|
||||
- .get_features = rtl822x_c45_get_features,
|
||||
- .config_aneg = rtl822x_c45_config_aneg,
|
||||
- .config_init = rtl822x_config_init,
|
||||
- .read_status = rtl822xb_c45_read_status,
|
||||
- .suspend = genphy_c45_pma_suspend,
|
||||
- .resume = rtlgen_c45_resume,
|
||||
+ .name = "RTL8226-CG 2.5Gbps PHY",
|
||||
+ .soft_reset = rtl822x_c45_soft_reset,
|
||||
+ .get_features = rtl822x_c45_get_features,
|
||||
+ .config_aneg = rtl822x_c45_config_aneg,
|
||||
+ .config_init = rtl822x_config_init,
|
||||
+ .read_status = rtl822xb_c45_read_status,
|
||||
+ .suspend = genphy_c45_pma_suspend,
|
||||
+ .resume = rtlgen_c45_resume,
|
||||
}, {
|
||||
PHY_ID_MATCH_EXACT(0x001cc848),
|
||||
- .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
|
||||
- .get_features = rtl822x_get_features,
|
||||
- .config_aneg = rtl822x_config_aneg,
|
||||
- .config_init = rtl822xb_config_init,
|
||||
+ .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
|
||||
+ .get_features = rtl822x_get_features,
|
||||
+ .config_aneg = rtl822x_config_aneg,
|
||||
+ .config_init = rtl822xb_config_init,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
- .read_status = rtl822xb_read_status,
|
||||
- .suspend = genphy_suspend,
|
||||
- .resume = rtlgen_resume,
|
||||
- .read_page = rtl821x_read_page,
|
||||
- .write_page = rtl821x_write_page,
|
||||
+ .read_status = rtl822xb_read_status,
|
||||
+ .suspend = genphy_suspend,
|
||||
+ .resume = rtlgen_resume,
|
||||
+ .read_page = rtl821x_read_page,
|
||||
+ .write_page = rtl821x_write_page,
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
|
||||
- .name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
|
||||
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
|
||||
.probe = rtl822x_probe,
|
||||
- .get_features = rtl822x_get_features,
|
||||
- .config_aneg = rtl822x_config_aneg,
|
||||
- .config_init = rtl822xb_config_init,
|
||||
+ .get_features = rtl822x_get_features,
|
||||
+ .config_aneg = rtl822x_config_aneg,
|
||||
+ .config_init = rtl822xb_config_init,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
- .read_status = rtl822xb_read_status,
|
||||
- .suspend = genphy_suspend,
|
||||
- .resume = rtlgen_resume,
|
||||
- .read_page = rtl821x_read_page,
|
||||
- .write_page = rtl821x_write_page,
|
||||
+ .read_status = rtl822xb_read_status,
|
||||
+ .suspend = genphy_suspend,
|
||||
+ .resume = rtlgen_resume,
|
||||
+ .read_page = rtl821x_read_page,
|
||||
+ .write_page = rtl821x_write_page,
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
|
||||
- .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
|
||||
+ .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,
|
||||
+ .config_init = rtl822xb_config_init,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
- .get_features = rtl822x_c45_get_features,
|
||||
- .config_aneg = rtl822x_c45_config_aneg,
|
||||
- .read_status = rtl822xb_c45_read_status,
|
||||
- .suspend = genphy_c45_pma_suspend,
|
||||
- .resume = rtlgen_c45_resume,
|
||||
+ .get_features = rtl822x_c45_get_features,
|
||||
+ .config_aneg = rtl822x_c45_config_aneg,
|
||||
+ .read_status = rtl822xb_c45_read_status,
|
||||
+ .suspend = genphy_c45_pma_suspend,
|
||||
+ .resume = rtlgen_c45_resume,
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vm_cg_c22_match_phy_device,
|
||||
- .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
|
||||
+ .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
|
||||
.probe = rtl822x_probe,
|
||||
- .get_features = rtl822x_get_features,
|
||||
- .config_aneg = rtl822x_config_aneg,
|
||||
- .config_init = rtl822xb_config_init,
|
||||
+ .get_features = rtl822x_get_features,
|
||||
+ .config_aneg = rtl822x_config_aneg,
|
||||
+ .config_init = rtl822xb_config_init,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
- .read_status = rtl822xb_read_status,
|
||||
- .suspend = genphy_suspend,
|
||||
- .resume = rtlgen_resume,
|
||||
- .read_page = rtl821x_read_page,
|
||||
- .write_page = rtl821x_write_page,
|
||||
+ .read_status = rtl822xb_read_status,
|
||||
+ .suspend = genphy_suspend,
|
||||
+ .resume = rtlgen_resume,
|
||||
+ .read_page = rtl821x_read_page,
|
||||
+ .write_page = rtl821x_write_page,
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vm_cg_c45_match_phy_device,
|
||||
- .name = "RTL8221B-VM-CG 2.5Gbps PHY (C45)",
|
||||
+ .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,
|
||||
+ .config_init = rtl822xb_config_init,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
- .get_features = rtl822x_c45_get_features,
|
||||
- .config_aneg = rtl822x_c45_config_aneg,
|
||||
- .read_status = rtl822xb_c45_read_status,
|
||||
- .suspend = genphy_c45_pma_suspend,
|
||||
- .resume = rtlgen_c45_resume,
|
||||
+ .get_features = rtl822x_c45_get_features,
|
||||
+ .config_aneg = rtl822x_c45_config_aneg,
|
||||
+ .read_status = rtl822xb_c45_read_status,
|
||||
+ .suspend = genphy_c45_pma_suspend,
|
||||
+ .resume = rtlgen_c45_resume,
|
||||
}, {
|
||||
.match_phy_device = rtl8251b_c45_match_phy_device,
|
||||
- .name = "RTL8251B 5Gbps PHY",
|
||||
+ .name = "RTL8251B 5Gbps PHY",
|
||||
.probe = rtl822x_probe,
|
||||
- .get_features = rtl822x_get_features,
|
||||
- .config_aneg = rtl822x_config_aneg,
|
||||
- .read_status = rtl822x_read_status,
|
||||
- .suspend = genphy_suspend,
|
||||
- .resume = rtlgen_resume,
|
||||
- .read_page = rtl821x_read_page,
|
||||
- .write_page = rtl821x_write_page,
|
||||
+ .get_features = rtl822x_get_features,
|
||||
+ .config_aneg = rtl822x_config_aneg,
|
||||
+ .read_status = rtl822x_read_status,
|
||||
+ .suspend = genphy_suspend,
|
||||
+ .resume = rtlgen_resume,
|
||||
+ .read_page = rtl821x_read_page,
|
||||
+ .write_page = rtl821x_write_page,
|
||||
}, {
|
||||
.match_phy_device = rtl_internal_nbaset_match_phy_device,
|
||||
- .name = "Realtek Internal NBASE-T PHY",
|
||||
+ .name = "Realtek Internal NBASE-T PHY",
|
||||
.flags = PHY_IS_INTERNAL,
|
||||
.probe = rtl822x_probe,
|
||||
- .get_features = rtl822x_get_features,
|
||||
- .config_aneg = rtl822x_config_aneg,
|
||||
- .read_status = rtl822x_read_status,
|
||||
- .suspend = genphy_suspend,
|
||||
- .resume = rtlgen_resume,
|
||||
- .read_page = rtl821x_read_page,
|
||||
- .write_page = rtl821x_write_page,
|
||||
+ .get_features = rtl822x_get_features,
|
||||
+ .config_aneg = rtl822x_config_aneg,
|
||||
+ .read_status = rtl822x_read_status,
|
||||
+ .suspend = genphy_suspend,
|
||||
+ .resume = rtlgen_resume,
|
||||
+ .read_page = rtl821x_read_page,
|
||||
+ .write_page = rtl821x_write_page,
|
||||
.read_mmd = rtl822x_read_mmd,
|
||||
.write_mmd = rtl822x_write_mmd,
|
||||
}, {
|
||||
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,
|
||||
+ .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,
|
||||
}, {
|
||||
@@ -2235,7 +2235,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
PHY_ID_MATCH_EXACT(0x001ccb00),
|
||||
.name = "RTL9000AA_RTL9000AN Ethernet",
|
||||
- .features = PHY_BASIC_T1_FEATURES,
|
||||
+ .features = PHY_BASIC_T1_FEATURES,
|
||||
.config_init = rtl9000a_config_init,
|
||||
.config_aneg = rtl9000a_config_aneg,
|
||||
.read_status = rtl9000a_read_status,
|
||||
|
|
@ -1,22 +1,24 @@
|
|||
From 43a4dfb71e2d23bae10ae13b7314d0641321d35e Mon Sep 17 00:00:00 2001
|
||||
From 10fbd71fc5f9bef5018a35103d493307683ddca1 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Sat, 3 Jan 2026 02:53:59 +0000
|
||||
Subject: [PATCH 2/2] net: phy: realtek: implement configuring in-band an
|
||||
Date: Mon, 5 Jan 2026 16:38:12 +0000
|
||||
Subject: [PATCH 2/5] net: phy: realtek: implement configuring in-band an
|
||||
|
||||
Implement the inband_caps() and config_inband() PHY driver methods to
|
||||
allow configuring the use of in-band-status with SGMII and 2500Base-X on
|
||||
RTL8226 and RTL8221B 2.5GE PHYs.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Link: https://patch.msgid.link/82a78a06d67be19e856d646cf880b2021ea9d837.1767630451.git.daniel@makrotopia.org
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/phy/realtek/realtek_main.c | 67 ++++++++++++++++++++++++++
|
||||
1 file changed, 67 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -135,6 +135,15 @@
|
||||
#define RTL822X_VND2_TO_PAGE_REG(reg) (16 + (((reg) & GENMASK(3, 0)) >> 1))
|
||||
#define RTL822X_VND2_C22_REG(reg) (0xa400 + 2 * (reg))
|
||||
@@ -131,6 +131,15 @@
|
||||
#define RTL822X_VND1_SERDES_CTRL3_MODE_SGMII 0x02
|
||||
#define RTL822X_VND1_SERDES_CTRL3_MODE_2500BASEX 0x16
|
||||
|
||||
+#define RTL822X_VND1_SERDES_CMD 0x7587
|
||||
+#define RTL822X_VND1_SERDES_CMD_WRITE BIT(1)
|
||||
|
|
@ -27,10 +29,10 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||
+#define RTL822X_VND1_SERDES_INBAND_ENABLE 0x70d0
|
||||
+#define RTL822X_VND1_SERDES_DATA 0x7589
|
||||
+
|
||||
#define RTL8221B_VND2_INER 0xa4d2
|
||||
#define RTL8221B_VND2_INER_LINK_STATUS BIT(4)
|
||||
|
||||
@@ -1381,6 +1390,50 @@ static int rtl822xb_config_init(struct p
|
||||
/* RTL822X_VND2_XXXXX registers are only accessible when phydev->is_c45
|
||||
* is set, they cannot be accessed by C45-over-C22.
|
||||
*/
|
||||
@@ -1308,6 +1317,50 @@ static int rtl822xb_config_init(struct p
|
||||
return rtl822x_set_serdes_option_mode(phydev, false);
|
||||
}
|
||||
|
||||
|
|
@ -67,7 +69,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||
+}
|
||||
+
|
||||
+static unsigned int rtl822x_inband_caps(struct phy_device *phydev,
|
||||
+ phy_interface_t interface)
|
||||
+ phy_interface_t interface)
|
||||
+{
|
||||
+ switch (interface) {
|
||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
||||
|
|
@ -81,66 +83,66 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||
static int rtl822xb_get_rate_matching(struct phy_device *phydev,
|
||||
phy_interface_t iface)
|
||||
{
|
||||
@@ -2180,6 +2233,8 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -2103,6 +2156,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.config_init = rtl822xb_config_init,
|
||||
+ .inband_caps = rtl822x_inband_caps,
|
||||
+ .config_inband = rtl822x_config_inband,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.read_status = rtl822xb_read_status,
|
||||
.suspend = genphy_suspend,
|
||||
@@ -2195,6 +2250,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.get_features = rtl822x_c45_get_features,
|
||||
.config_aneg = rtl822x_c45_config_aneg,
|
||||
.config_init = rtl822x_config_init,
|
||||
@@ -2116,6 +2171,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.get_features = rtl822x_c45_get_features,
|
||||
.config_aneg = rtl822x_c45_config_aneg,
|
||||
.config_init = rtl822x_config_init,
|
||||
+ .inband_caps = rtl822x_inband_caps,
|
||||
+ .config_inband = rtl822x_config_inband,
|
||||
.read_status = rtl822xb_c45_read_status,
|
||||
.suspend = genphy_c45_pma_suspend,
|
||||
.resume = rtlgen_c45_resume,
|
||||
@@ -2207,6 +2264,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.read_status = rtl822xb_c45_read_status,
|
||||
.suspend = genphy_c45_pma_suspend,
|
||||
.resume = rtlgen_c45_resume,
|
||||
@@ -2125,6 +2182,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
+ .inband_caps = rtl822x_inband_caps,
|
||||
+ .config_inband = rtl822x_config_inband,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.read_status = rtl822xb_read_status,
|
||||
.suspend = genphy_suspend,
|
||||
@@ -2223,6 +2282,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.read_status = rtl822xb_read_status,
|
||||
.suspend = genphy_suspend,
|
||||
@@ -2138,6 +2197,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
+ .inband_caps = rtl822x_inband_caps,
|
||||
+ .config_inband = rtl822x_config_inband,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.read_status = rtl822xb_read_status,
|
||||
.suspend = genphy_suspend,
|
||||
@@ -2239,6 +2300,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.soft_reset = rtl822x_c45_soft_reset,
|
||||
.read_status = rtl822xb_read_status,
|
||||
.suspend = genphy_suspend,
|
||||
@@ -2151,6 +2212,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.handle_interrupt = rtl8221b_handle_interrupt,
|
||||
.probe = rtl822x_probe,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.config_init = rtl822xb_config_init,
|
||||
+ .inband_caps = rtl822x_inband_caps,
|
||||
+ .config_inband = rtl822x_config_inband,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.get_features = rtl822x_c45_get_features,
|
||||
.config_aneg = rtl822x_c45_config_aneg,
|
||||
@@ -2253,6 +2316,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.get_features = rtl822x_c45_get_features,
|
||||
.config_aneg = rtl822x_c45_config_aneg,
|
||||
@@ -2164,6 +2227,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
+ .inband_caps = rtl822x_inband_caps,
|
||||
+ .config_inband = rtl822x_config_inband,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.read_status = rtl822xb_read_status,
|
||||
.suspend = genphy_suspend,
|
||||
@@ -2269,6 +2334,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.soft_reset = rtl822x_c45_soft_reset,
|
||||
.read_status = rtl822xb_read_status,
|
||||
.suspend = genphy_suspend,
|
||||
@@ -2177,6 +2242,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.handle_interrupt = rtl8221b_handle_interrupt,
|
||||
.probe = rtl822x_probe,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.config_init = rtl822xb_config_init,
|
||||
+ .inband_caps = rtl822x_inband_caps,
|
||||
+ .config_inband = rtl822x_config_inband,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.get_features = rtl822x_c45_get_features,
|
||||
.config_aneg = rtl822x_c45_config_aneg,
|
||||
.get_features = rtl822x_c45_get_features,
|
||||
.config_aneg = rtl822x_c45_config_aneg,
|
||||
|
|
@ -1,25 +1,32 @@
|
|||
From a81850660c9fc259d090e9207f81e8e76d9494ce Mon Sep 17 00:00:00 2001
|
||||
From 1850ec20d6e71218c02329e5975591075dc972d3 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Sun, 4 Jan 2026 10:13:29 +0000
|
||||
Subject: [PATCH] net: phy: realtek: use paged access for MDIO_MMD_VEND2 in C22
|
||||
mode
|
||||
Date: Mon, 5 Jan 2026 16:38:59 +0000
|
||||
Subject: [PATCH 4/5] net: phy: realtek: use paged access for MDIO_MMD_VEND2 in
|
||||
C22 mode
|
||||
|
||||
RTL822x cannot access MDIO_MMD_VEND2 via MII_MMD_CTRL/MII_MMD_DATA. A
|
||||
mapping to use paged access needs to be used instead. All other MMD
|
||||
devices can be accessed as usual.
|
||||
|
||||
RTL822x cannot access MDIO_MMD_VEND2 via MII_MMD_CTRL/MII_MMD_DATA.
|
||||
A mapping to use paged access needs to be used instead.
|
||||
All other MMD devices can be accessed as usual.
|
||||
Implement phy_read_mmd and phy_write_mmd using paged access for
|
||||
MDIO_MMD_VEND2 in Clause-22 mode instead of relying on
|
||||
MII_MMD_CTRL/MII_MMD_DATA.
|
||||
This allows eg. rtl822x_config_aneg to work as expected in case the
|
||||
MDIO bus doesn't support Clause-45 access.
|
||||
MII_MMD_CTRL/MII_MMD_DATA. This allows eg. rtl822x_config_aneg to work
|
||||
as expected in case the MDIO bus doesn't support Clause-45 access.
|
||||
|
||||
Suggested-by: Bevan Weiss <bevan.weiss@gmail.com>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
|
||||
Link: https://patch.msgid.link/25aab7f02dac7c6022171455523e3db1435b0881.1767630451.git.daniel@makrotopia.org
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/phy/realtek/realtek_main.c | 91 +++++++++++++++++++++++++-
|
||||
1 file changed, 88 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -131,9 +131,8 @@
|
||||
#define RTL822X_VND1_SERDES_CTRL3_MODE_SGMII 0x02
|
||||
#define RTL822X_VND1_SERDES_CTRL3_MODE_2500BASEX 0x16
|
||||
@@ -140,9 +140,8 @@
|
||||
#define RTL822X_VND1_SERDES_INBAND_ENABLE 0x70d0
|
||||
#define RTL822X_VND1_SERDES_DATA 0x7589
|
||||
|
||||
-/* RTL822X_VND2_XXXXX registers are only accessible when phydev->is_c45
|
||||
- * is set, they cannot be accessed by C45-over-C22.
|
||||
|
|
@ -29,7 +36,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||
#define RTL822X_VND2_C22_REG(reg) (0xa400 + 2 * (reg))
|
||||
|
||||
#define RTL8221B_VND2_INER 0xa4d2
|
||||
@@ -1238,6 +1237,80 @@ static int rtl822x_probe(struct phy_devi
|
||||
@@ -1247,6 +1246,79 @@ static int rtl822x_probe(struct phy_devi
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -105,12 +112,11 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||
+
|
||||
+ return write_ret;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static int rtl822x_set_serdes_option_mode(struct phy_device *phydev, bool gen1)
|
||||
{
|
||||
bool has_2500, has_sgmii;
|
||||
@@ -2097,6 +2170,8 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -2150,6 +2222,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.resume = rtlgen_resume,
|
||||
.read_page = rtl821x_read_page,
|
||||
.write_page = rtl821x_write_page,
|
||||
|
|
@ -119,7 +125,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||
}, {
|
||||
.match_phy_device = rtl8221b_match_phy_device,
|
||||
.name = "RTL8226B_RTL8221B 2.5Gbps PHY",
|
||||
@@ -2109,6 +2184,8 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -2164,6 +2238,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.resume = rtlgen_resume,
|
||||
.read_page = rtl821x_read_page,
|
||||
.write_page = rtl821x_write_page,
|
||||
|
|
@ -127,40 +133,40 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||
+ .write_mmd = rtl822xb_write_mmd,
|
||||
}, {
|
||||
PHY_ID_MATCH_EXACT(0x001cc838),
|
||||
.name = "RTL8226-CG 2.5Gbps PHY",
|
||||
@@ -2119,6 +2196,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.read_status = rtl822xb_c45_read_status,
|
||||
.suspend = genphy_c45_pma_suspend,
|
||||
.resume = rtlgen_c45_resume,
|
||||
.name = "RTL8226-CG 2.5Gbps PHY",
|
||||
@@ -2176,6 +2252,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.read_status = rtl822xb_c45_read_status,
|
||||
.suspend = genphy_c45_pma_suspend,
|
||||
.resume = rtlgen_c45_resume,
|
||||
+ .read_mmd = rtl822xb_read_mmd,
|
||||
+ .write_mmd = rtl822xb_write_mmd,
|
||||
}, {
|
||||
PHY_ID_MATCH_EXACT(0x001cc848),
|
||||
.name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
|
||||
@@ -2131,6 +2210,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.resume = rtlgen_resume,
|
||||
.read_page = rtl821x_read_page,
|
||||
.write_page = rtl821x_write_page,
|
||||
.name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
|
||||
@@ -2190,6 +2268,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.resume = rtlgen_resume,
|
||||
.read_page = rtl821x_read_page,
|
||||
.write_page = rtl821x_write_page,
|
||||
+ .read_mmd = rtl822xb_read_mmd,
|
||||
+ .write_mmd = rtl822xb_write_mmd,
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
|
||||
@@ -2144,6 +2225,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.resume = rtlgen_resume,
|
||||
.read_page = rtl821x_read_page,
|
||||
.write_page = rtl821x_write_page,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
|
||||
@@ -2205,6 +2285,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.resume = rtlgen_resume,
|
||||
.read_page = rtl821x_read_page,
|
||||
.write_page = rtl821x_write_page,
|
||||
+ .read_mmd = rtl822xb_read_mmd,
|
||||
+ .write_mmd = rtl822xb_write_mmd,
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
|
||||
@@ -2170,6 +2253,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.resume = rtlgen_resume,
|
||||
.read_page = rtl821x_read_page,
|
||||
.write_page = rtl821x_write_page,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
|
||||
@@ -2235,6 +2317,8 @@ static struct phy_driver realtek_drvs[]
|
||||
.resume = rtlgen_resume,
|
||||
.read_page = rtl821x_read_page,
|
||||
.write_page = rtl821x_write_page,
|
||||
+ .read_mmd = rtl822xb_read_mmd,
|
||||
+ .write_mmd = rtl822xb_write_mmd,
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vm_cg_c45_match_phy_device,
|
||||
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C45)",
|
||||
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C45)",
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
From d8489935f5979b72e73de585037fe6fde7088bc3 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 5 Jan 2026 16:39:26 +0000
|
||||
Subject: [PATCH 5/5] net: phy: realtek: get rid of magic number in
|
||||
rtlgen_read_status()
|
||||
|
||||
Use newly introduced helper macros RTL822X_VND2_TO_PAGE and
|
||||
RTL822X_VND2_TO_PAGE_REG to access RTL_VEND2_PHYSR register over Clause-22
|
||||
paged access instead of using magic numbers.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
|
||||
Link: https://patch.msgid.link/a53d4577335fdda4d363db9bc4bf614fd3a56c9b.1767630451.git.daniel@makrotopia.org
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/phy/realtek/realtek_main.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -1153,7 +1153,8 @@ static int rtlgen_read_status(struct phy
|
||||
if (!phydev->link)
|
||||
return 0;
|
||||
|
||||
- val = phy_read_paged(phydev, 0xa43, 0x12);
|
||||
+ val = phy_read_paged(phydev, RTL822X_VND2_TO_PAGE(RTL_VND2_PHYSR),
|
||||
+ RTL822X_VND2_TO_PAGE_REG(RTL_VND2_PHYSR));
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
|
|
@ -15,59 +15,59 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -2163,6 +2163,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -2216,6 +2216,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.name = "RTL8226 2.5Gbps PHY",
|
||||
.match_phy_device = rtl8226_match_phy_device,
|
||||
+ .soft_reset = genphy_soft_reset,
|
||||
+ .soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.read_status = rtl822x_read_status,
|
||||
@@ -2175,6 +2176,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -2228,6 +2229,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_match_phy_device,
|
||||
.name = "RTL8226B_RTL8221B 2.5Gbps PHY",
|
||||
+ .soft_reset = genphy_soft_reset,
|
||||
+ .soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
@@ -2201,6 +2203,7 @@ static struct phy_driver realtek_drvs[]
|
||||
.config_init = rtl822xb_config_init,
|
||||
@@ -2258,6 +2260,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
PHY_ID_MATCH_EXACT(0x001cc848),
|
||||
.name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
|
||||
+ .soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
@@ -2215,6 +2218,7 @@ static struct phy_driver realtek_drvs[]
|
||||
.name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
|
||||
+ .soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
@@ -2274,6 +2277,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
|
||||
+ .soft_reset = genphy_soft_reset,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
|
||||
+ .soft_reset = genphy_soft_reset,
|
||||
.probe = rtl822x_probe,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
@@ -2232,6 +2236,7 @@ static struct phy_driver realtek_drvs[]
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
@@ -2293,6 +2297,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,
|
||||
+ .soft_reset = rtl822x_c45_soft_reset,
|
||||
.probe = rtl822x_probe,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
@@ -2243,6 +2248,7 @@ static struct phy_driver realtek_drvs[]
|
||||
.config_init = rtl822xb_config_init,
|
||||
.inband_caps = rtl822x_inband_caps,
|
||||
@@ -2306,6 +2311,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vm_cg_c22_match_phy_device,
|
||||
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
|
||||
+ .soft_reset = genphy_soft_reset,
|
||||
.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,
|
||||
@@ -2260,6 +2266,7 @@ static struct phy_driver realtek_drvs[]
|
||||
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C45)",
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
@@ -2325,6 +2331,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,
|
||||
+ .soft_reset = rtl822x_c45_soft_reset,
|
||||
.probe = rtl822x_probe,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.inband_caps = rtl822x_inband_caps,
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||
static int rtl821x_read_page(struct phy_device *phydev)
|
||||
{
|
||||
return __phy_read(phydev, RTL821x_PAGE_SELECT);
|
||||
@@ -1239,6 +1247,18 @@ static int rtl822x_write_mmd(struct phy_
|
||||
@@ -1240,6 +1248,18 @@ static int rtl822x_write_mmd(struct phy_
|
||||
|
||||
static int rtl822x_probe(struct phy_device *phydev)
|
||||
{
|
||||
|
|
@ -55,9 +55,9 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||
phydev->phy_id != RTL_GENERIC_PHYID)
|
||||
return rtl822x_hwmon_init(phydev);
|
||||
@@ -1320,6 +1340,19 @@ static int rtl822xb_write_mmd(struct phy
|
||||
return write_ret;
|
||||
}
|
||||
|
||||
|
||||
+static int rtl822x_init_phycr1(struct phy_device *phydev, bool no_aldps)
|
||||
+{
|
||||
+ struct rtl822x_priv *priv = phydev->priv;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
From 98a5d7606b7bc9136205969418385e4c9bf8ce56 Mon Sep 17 00:00:00 2001
|
||||
From 97f093d9c491f066e5c6bb5bd2e3758f61a9fb30 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 5 Jan 2026 16:59:06 +0000
|
||||
Subject: [PATCH] net: phy: realtek: support interrupt also for C22 variants
|
||||
Subject: [PATCH 1/3] net: phy: realtek: support interrupt also for C22
|
||||
variants
|
||||
|
||||
Now that access to MDIO_MMD_VEND2 works transparently also in Clause-22
|
||||
mode, add interrupt support also for the C22 variants of the
|
||||
RTL8221B-VB-CG and RTL8221B-VM-CG.
|
||||
RTL8221B-VB-CG and RTL8221B-VM-CG. This results in the C22 and C45
|
||||
driver instances now having all the same features implemented.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
|
|
@ -17,18 +19,18 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||
@@ -2347,6 +2347,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)",
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
|
||||
+ .config_intr = rtl8221b_config_intr,
|
||||
+ .handle_interrupt = rtl8221b_handle_interrupt,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.probe = rtl822x_probe,
|
||||
.get_features = rtl822x_get_features,
|
||||
.get_features = rtl822x_get_features,
|
||||
@@ -2381,6 +2383,8 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vm_cg_c22_match_phy_device,
|
||||
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
|
||||
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
|
||||
+ .config_intr = rtl8221b_config_intr,
|
||||
+ .handle_interrupt = rtl8221b_handle_interrupt,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.probe = rtl822x_probe,
|
||||
.get_features = rtl822x_get_features,
|
||||
.get_features = rtl822x_get_features,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue