mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-07-05 11:57:06 +08:00
generic: fix probe issues with RealTek RTL8221B PHY
Import patch "net: phy: realtek: mark existing MMDs as present" When using Clause-45 mode to access RealTek RTL8221B 2.5G PHYs some versions of the PHY fail to report the MMDs present on the PHY. Mark MMDs PMAPMD, PCS and AN which are always existing according to the datasheet as present to fix that. Signed-off-by: Daniel Golle <daniel@makrotopia.org> Tested-by: Aleksander Jan Bajkowski <olek2@wp.pl> Tested-by: Juan Pedro Paredes Caballero <juanpedro.paredes@gmail.com>
This commit is contained in:
parent
7c6a43a264
commit
0866dba045
@ -1,104 +0,0 @@
|
||||
From 9155098547fb1172d4fa536f3f6bc9d42f59d08c Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Sat, 22 Apr 2023 03:26:01 +0100
|
||||
Subject: [PATCH] net: phy: realtek: setup ALDPS on RTL822x
|
||||
|
||||
Setup Link Down Power Saving Mode according the DTS property
|
||||
just like for RTL821x 1GE PHYs.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/phy/realtek/realtek_main.c | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -82,6 +82,10 @@
|
||||
|
||||
#define RTL822X_VND2_GANLPAR 0xa414
|
||||
|
||||
+#define RTL8221B_PHYCR1 0xa430
|
||||
+#define RTL8221B_PHYCR1_ALDPS_EN BIT(2)
|
||||
+#define RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN BIT(12)
|
||||
+
|
||||
#define RTL8366RB_POWER_SAVE 0x15
|
||||
#define RTL8366RB_POWER_SAVE_ON BIT(12)
|
||||
|
||||
@@ -1207,6 +1211,25 @@ static int rtl8251b_c45_match_phy_device
|
||||
return rtlgen_is_c45_match(phydev, RTL_8251B, true);
|
||||
}
|
||||
|
||||
+static int rtl822x_aldps_probe(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct device *dev = &phydev->mdio.dev;
|
||||
+ int val;
|
||||
+
|
||||
+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, RTL8221B_PHYCR1);
|
||||
+ if (val < 0)
|
||||
+ return val;
|
||||
+
|
||||
+ if (of_property_read_bool(dev->of_node, "realtek,aldps-enable"))
|
||||
+ val |= RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN;
|
||||
+ else
|
||||
+ val &= ~(RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN);
|
||||
+
|
||||
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL8221B_PHYCR1, val);
|
||||
+
|
||||
+ return rtl822x_probe(phydev);
|
||||
+}
|
||||
+
|
||||
static int rtlgen_resume(struct phy_device *phydev)
|
||||
{
|
||||
int ret = genphy_resume(phydev);
|
||||
@@ -1478,6 +1501,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
PHY_ID_MATCH_EXACT(0x001cc838),
|
||||
.name = "RTL8226-CG 2.5Gbps PHY",
|
||||
+ .probe = rtl822x_aldps_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
@@ -1489,6 +1513,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
PHY_ID_MATCH_EXACT(0x001cc848),
|
||||
.name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
|
||||
+ .probe = rtl822x_aldps_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
@@ -1503,7 +1528,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,
|
||||
- .probe = rtl822x_probe,
|
||||
+ .probe = rtl822x_aldps_probe,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
@@ -1517,7 +1542,7 @@ static struct phy_driver realtek_drvs[]
|
||||
.match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
|
||||
.soft_reset = genphy_soft_reset,
|
||||
- .probe = rtl822x_probe,
|
||||
+ .probe = rtl822x_aldps_probe,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.get_features = rtl822x_c45_get_features,
|
||||
@@ -1529,7 +1554,7 @@ static struct phy_driver realtek_drvs[]
|
||||
.match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
|
||||
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
|
||||
.soft_reset = genphy_soft_reset,
|
||||
- .probe = rtl822x_probe,
|
||||
+ .probe = rtl822x_aldps_probe,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
@@ -1543,7 +1568,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)",
|
||||
.soft_reset = genphy_soft_reset,
|
||||
- .probe = rtl822x_probe,
|
||||
+ .probe = rtl822x_aldps_probe,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.get_features = rtl822x_c45_get_features,
|
@ -0,0 +1,42 @@
|
||||
From 9155098547fb1172d4fa536f3f6bc9d42f59d08c Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Sat, 22 Apr 2023 03:26:01 +0100
|
||||
Subject: [PATCH] net: phy: realtek: setup ALDPS on RTL822x
|
||||
|
||||
Setup Link Down Power Saving Mode according the DTS property
|
||||
just like for RTL821x 1GE PHYs.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/phy/realtek/realtek_main.c | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -82,6 +82,10 @@
|
||||
|
||||
#define RTL822X_VND2_GANLPAR 0xa414
|
||||
|
||||
+#define RTL8221B_PHYCR1 0xa430
|
||||
+#define RTL8221B_PHYCR1_ALDPS_EN BIT(2)
|
||||
+#define RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN BIT(12)
|
||||
+
|
||||
#define RTL8366RB_POWER_SAVE 0x15
|
||||
#define RTL8366RB_POWER_SAVE_ON BIT(12)
|
||||
|
||||
@@ -889,6 +893,15 @@ static int rtl822xb_config_init(struct p
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
+ if (of_property_read_bool(phydev->mdio.dev.of_node, "realtek,aldps-enable"))
|
||||
+ ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, RTL8221B_PHYCR1,
|
||||
+ RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN);
|
||||
+ else
|
||||
+ ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, RTL8221B_PHYCR1,
|
||||
+ RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
/* Disable SGMII AN */
|
||||
ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7588, 0x2);
|
||||
if (ret < 0)
|
@ -14,7 +14,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Mieczyslaw Nalewaj <namiltd@yahoo.com>
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -1157,10 +1157,32 @@ static int rtl8226_match_phy_device(stru
|
||||
@@ -1166,10 +1166,32 @@ static int rtl8226_match_phy_device(stru
|
||||
static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id,
|
||||
bool is_c45)
|
||||
{
|
||||
|
@ -12,7 +12,7 @@ Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -1387,6 +1387,51 @@ static irqreturn_t rtl9000a_handle_inter
|
||||
@@ -1377,6 +1377,51 @@ static irqreturn_t rtl9000a_handle_inter
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@ -64,39 +64,39 @@ Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
|
||||
static struct phy_driver realtek_drvs[] = {
|
||||
{
|
||||
PHY_ID_MATCH_EXACT(0x00008201),
|
||||
@@ -1549,6 +1594,8 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1537,6 +1582,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_aldps_probe,
|
||||
.probe = rtl822x_probe,
|
||||
.get_features = rtl822x_get_features,
|
||||
@@ -1563,6 +1610,8 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1551,6 +1598,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_aldps_probe,
|
||||
.probe = rtl822x_probe,
|
||||
.config_init = rtl822xb_config_init,
|
||||
@@ -1575,6 +1624,8 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1563,6 +1612,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_aldps_probe,
|
||||
.probe = rtl822x_probe,
|
||||
.get_features = rtl822x_get_features,
|
||||
@@ -1589,6 +1640,8 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1577,6 +1628,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_aldps_probe,
|
||||
.probe = rtl822x_probe,
|
||||
.config_init = rtl822xb_config_init,
|
||||
|
@ -0,0 +1,27 @@
|
||||
From 1addfb042a9d27788a0fb2c2935045b56fd8560e Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Thu, 23 Jan 2025 03:25:29 +0000
|
||||
Subject: [PATCH] net: phy: realtek: mark existing MMDs as present
|
||||
|
||||
When using Clause-45 mode to access RealTek RTL8221B 2.5G PHYs some
|
||||
versions of the PHY fail to report the MMDs present on the PHY.
|
||||
Mark MMDs PMAPMD, PCS and AN which are always existing according to
|
||||
the datasheet as present to fix that.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/phy/realtek/realtek_main.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -1043,6 +1043,9 @@ static int rtl822x_c45_get_features(stru
|
||||
linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT,
|
||||
phydev->supported);
|
||||
|
||||
+ phydev->c45_ids.mmds_present |= MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS |
|
||||
+ MDIO_DEVS_AN;
|
||||
+
|
||||
return genphy_c45_pma_read_abilities(phydev);
|
||||
}
|
||||
|
@ -0,0 +1,58 @@
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Thu, 30 Jan 2025 05:33:12 +0000
|
||||
Subject: [PATCH] net: phy: realtek: work around broken SerDes
|
||||
|
||||
For still unknown reasons the SerDes init sequence may sometimes
|
||||
time out because a self-clearing bit never clears, indicating the
|
||||
PHY has entered an unrecoverable error state.
|
||||
|
||||
Work-around the issue by triggering a hardware reset and retry the
|
||||
setup sequence while warning the user that this has happened.
|
||||
This is really more of a work-around than a fix, and should be
|
||||
replaced by a better actual fix in future (hopefully).
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -923,6 +923,22 @@ static int rtl822xb_config_init(struct p
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int rtl822xb_config_init_war(struct phy_device *phydev)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = rtl822xb_config_init(phydev);
|
||||
+
|
||||
+ if (ret == -ETIMEDOUT) {
|
||||
+ phydev_warn(phydev, "SerDes setup timed out, retrying\n");
|
||||
+ phy_device_reset(phydev, 1);
|
||||
+ phy_device_reset(phydev, 0);
|
||||
+ ret = rtl822xb_config_init(phydev);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int rtl822xb_get_rate_matching(struct phy_device *phydev,
|
||||
phy_interface_t iface)
|
||||
{
|
||||
@@ -1605,7 +1621,7 @@ static struct phy_driver realtek_drvs[]
|
||||
.handle_interrupt = rtl8221b_handle_interrupt,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.probe = rtl822x_probe,
|
||||
- .config_init = rtl822xb_config_init,
|
||||
+ .config_init = rtl822xb_config_init_war,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.get_features = rtl822x_c45_get_features,
|
||||
.config_aneg = rtl822x_c45_config_aneg,
|
||||
@@ -1635,7 +1651,7 @@ static struct phy_driver realtek_drvs[]
|
||||
.handle_interrupt = rtl8221b_handle_interrupt,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.probe = rtl822x_probe,
|
||||
- .config_init = rtl822xb_config_init,
|
||||
+ .config_init = rtl822xb_config_init_war,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.get_features = rtl822x_c45_get_features,
|
||||
.config_aneg = rtl822x_c45_config_aneg,
|
@ -0,0 +1,27 @@
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Thu, 30 Jan 2025 05:38:31 +0000
|
||||
Subject: [PATCH] net: phy: realtek: disable MDIO broadcast
|
||||
|
||||
RealTek's PHYs by default also listen on MDIO address 0 which is defined
|
||||
as broadcast address. This can lead to problems if there is an actual PHY
|
||||
(such as MT7981 built-in PHY) present at this address, as accessing that
|
||||
PHY may then confuse the RealTek PHY.
|
||||
|
||||
Disabled listening on the MDIO broadcast address to avoid such problems.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -849,6 +849,11 @@ static int rtl822xb_config_init(struct p
|
||||
phydev->host_interfaces) ||
|
||||
phydev->interface == PHY_INTERFACE_MODE_SGMII;
|
||||
|
||||
+ /* disable listening on MDIO broadcast address (0) */
|
||||
+ ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, 0xa430, BIT(13));
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
/* fill in possible interfaces */
|
||||
__assign_bit(PHY_INTERFACE_MODE_2500BASEX, phydev->possible_interfaces,
|
||||
has_2500);
|
Loading…
x
Reference in New Issue
Block a user