mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-15 18:03:30 +00:00
generic: net: phy: realtek: various improvements
Follow the advise of Russell King allows to greatly improve the driver for RealTek's 1G and 2.5G Ethernet PHYs. The results are full/half duplex as well as Gbit master/slave property being read from PHY Specific Status Register (PHYSR), and fixes regarding link-partner advertisement. Signed-off-by: Daniel Golle <daniel@makrotopia.org>
This commit is contained in:
parent
3b3ed936ec
commit
8858bea842
@ -24,7 +24,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
#define RTL8366RB_POWER_SAVE 0x15
|
||||
#define RTL8366RB_POWER_SAVE_ON BIT(12)
|
||||
|
||||
@@ -1107,6 +1111,25 @@ static int rtl8221b_vn_cg_c45_match_phy_
|
||||
@@ -1102,6 +1106,25 @@ static int rtl8221b_vn_cg_c45_match_phy_
|
||||
return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true);
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
static int rtlgen_resume(struct phy_device *phydev)
|
||||
{
|
||||
int ret = genphy_resume(phydev);
|
||||
@@ -1382,6 +1405,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1377,6 +1400,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
PHY_ID_MATCH_EXACT(0x001cc838),
|
||||
.name = "RTL8226-CG 2.5Gbps PHY",
|
||||
@ -58,7 +58,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
@@ -1393,6 +1417,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1388,6 +1412,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
PHY_ID_MATCH_EXACT(0x001cc848),
|
||||
.name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
|
||||
@ -66,7 +66,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
@@ -1406,6 +1431,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1401,6 +1426,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)",
|
||||
@ -74,7 +74,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
@@ -1419,6 +1445,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1414,6 +1440,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)",
|
||||
@ -82,7 +82,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
@@ -1430,6 +1457,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1425,6 +1452,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)",
|
||||
@ -90,7 +90,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
@@ -1443,6 +1471,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1438,6 +1466,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)",
|
@ -1,26 +0,0 @@
|
||||
From 92c8b9d558160d94b981dd8a2b9c47657627ffdc Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Sat, 22 Apr 2023 01:23:08 +0100
|
||||
Subject: [PATCH 2/3] net: phy: realtek: use inline functions for 10GbE
|
||||
advertisement
|
||||
|
||||
Use existing generic inline functions to encode local advertisement
|
||||
of 10GbE link modes as well as to decode link-partner advertisement.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/phy/realtek.c | 22 +++++-----------------
|
||||
1 file changed, 5 insertions(+), 17 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -910,7 +910,8 @@ static int rtl822x_config_aneg(struct ph
|
||||
|
||||
ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
|
||||
MDIO_AN_10GBT_CTRL_ADV2_5G |
|
||||
- MDIO_AN_10GBT_CTRL_ADV5G,
|
||||
+ MDIO_AN_10GBT_CTRL_ADV5G |
|
||||
+ MDIO_AN_10GBT_CTRL_ADV10G,
|
||||
adv);
|
||||
if (ret < 0)
|
||||
return ret;
|
@ -1,28 +0,0 @@
|
||||
From 929bb4d3cfbc7878326c0771a01a636d49c54b40 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Sat, 22 Apr 2023 01:25:39 +0100
|
||||
Subject: [PATCH 3/3] net: phy: realtek: check validity of 10GbE link-partner
|
||||
advertisement
|
||||
|
||||
Only use link-partner advertisement bits for 10GbE modes if they are
|
||||
actually valid. Check LOCALOK and REMOTEOK bits and clear 10GbE modes
|
||||
unless both of them are set.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/phy/realtek.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -950,6 +950,10 @@ static int rtl822x_read_status(struct ph
|
||||
if (lpadv < 0)
|
||||
return lpadv;
|
||||
|
||||
+ if (!(lpadv & MDIO_AN_10GBT_STAT_REMOK) ||
|
||||
+ !(lpadv & MDIO_AN_10GBT_STAT_LOCOK))
|
||||
+ lpadv = 0;
|
||||
+
|
||||
mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising,
|
||||
lpadv);
|
||||
}
|
@ -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.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -1085,10 +1085,32 @@ static int rtl8226_match_phy_device(stru
|
||||
@@ -1080,10 +1080,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.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -1287,6 +1287,51 @@ static irqreturn_t rtl9000a_handle_inter
|
||||
@@ -1282,6 +1282,51 @@ static irqreturn_t rtl9000a_handle_inter
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
|
||||
static struct phy_driver realtek_drvs[] = {
|
||||
{
|
||||
PHY_ID_MATCH_EXACT(0x00008201),
|
||||
@@ -1453,6 +1498,8 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1448,6 +1493,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)",
|
||||
@ -73,7 +73,7 @@ Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
|
||||
.probe = rtl822x_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
@@ -1467,6 +1514,8 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1462,6 +1509,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)",
|
||||
@ -82,7 +82,7 @@ Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
|
||||
.probe = rtl822x_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.config_init = rtl822xb_config_init,
|
||||
@@ -1479,6 +1528,8 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1474,6 +1523,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)",
|
||||
@ -91,7 +91,7 @@ Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
|
||||
.probe = rtl822x_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
@@ -1493,6 +1544,8 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1488,6 +1539,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)",
|
@ -0,0 +1,117 @@
|
||||
From 66d82d3f04623e9c096e12c10ca51141c345ee84 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 8 Oct 2024 20:59:51 +0100
|
||||
Subject: [PATCH] net: phy: realtek: read duplex and gbit master from PHYSR
|
||||
register
|
||||
|
||||
The PHYSR MMD register is present and defined equally for all RTL82xx
|
||||
Ethernet PHYs.
|
||||
Read duplex and gbit master bits from rtlgen_decode_speed() and rename
|
||||
it to rtlgen_decode_physr().
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/phy/realtek.c | 48 ++++++++++++++++++++++++++++++++-------
|
||||
1 file changed, 40 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -80,20 +80,24 @@
|
||||
|
||||
#define RTL822X_VND2_GANLPAR 0xa414
|
||||
|
||||
-#define RTL822X_VND2_PHYSR 0xa434
|
||||
-
|
||||
#define RTL8221B_PHYCR1 0xa430
|
||||
#define RTL8221B_PHYCR1_ALDPS_EN BIT(2)
|
||||
#define RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN BIT(12)
|
||||
|
||||
+#define RTL_VND2_PHYSR 0xa434
|
||||
+#define RTL_VND2_PHYSR_LINK BIT(2)
|
||||
+#define RTL_VND2_PHYSR_DUPLEX BIT(3)
|
||||
+#define RTL_VND2_PHYSR_SPEEDL GENMASK(5, 4)
|
||||
+#define RTL_VND2_PHYSR_SPEEDH GENMASK(10, 9)
|
||||
+#define RTL_VND2_PHYSR_MASTER BIT(11)
|
||||
+#define RTL_VND2_PHYSR_SPEED_MASK (RTL_VND2_PHYSR_SPEEDL | RTL_VND2_PHYSR_SPEEDH)
|
||||
+
|
||||
#define RTL8366RB_POWER_SAVE 0x15
|
||||
#define RTL8366RB_POWER_SAVE_ON BIT(12)
|
||||
|
||||
#define RTL9000A_GINMR 0x14
|
||||
#define RTL9000A_GINMR_LINK_STATUS BIT(4)
|
||||
|
||||
-#define RTLGEN_SPEED_MASK 0x0630
|
||||
-
|
||||
#define RTL_GENERIC_PHYID 0x001cc800
|
||||
#define RTL_8211FVD_PHYID 0x001cc878
|
||||
#define RTL_8221B_VB_CG 0x001cc849
|
||||
@@ -661,9 +665,24 @@ static int rtl8366rb_config_init(struct
|
||||
}
|
||||
|
||||
/* get actual speed to cover the downshift case */
|
||||
-static void rtlgen_decode_speed(struct phy_device *phydev, int val)
|
||||
+static void rtlgen_decode_physr(struct phy_device *phydev, int val)
|
||||
{
|
||||
- switch (val & RTLGEN_SPEED_MASK) {
|
||||
+ /* bit 2
|
||||
+ * 0: Link not OK
|
||||
+ * 1: Link OK
|
||||
+ */
|
||||
+ phydev->link = !!(val & RTL_VND2_PHYSR_LINK);
|
||||
+
|
||||
+ /* bit 3
|
||||
+ * 0: Half Duplex
|
||||
+ * 1: Full Duplex
|
||||
+ */
|
||||
+ if (val & RTL_VND2_PHYSR_DUPLEX)
|
||||
+ phydev->duplex = DUPLEX_FULL;
|
||||
+ else
|
||||
+ phydev->duplex = DUPLEX_HALF;
|
||||
+
|
||||
+ switch (val & RTL_VND2_PHYSR_SPEED_MASK) {
|
||||
case 0x0000:
|
||||
phydev->speed = SPEED_10;
|
||||
break;
|
||||
@@ -685,6 +704,19 @@ static void rtlgen_decode_speed(struct p
|
||||
default:
|
||||
break;
|
||||
}
|
||||
+
|
||||
+ /* bit 11
|
||||
+ * 0: Slave Mode
|
||||
+ * 1: Master Mode
|
||||
+ */
|
||||
+ if (phydev->speed >= 1000) {
|
||||
+ if (val & RTL_VND2_PHYSR_MASTER)
|
||||
+ phydev->master_slave_state = MASTER_SLAVE_STATE_MASTER;
|
||||
+ else
|
||||
+ phydev->master_slave_state = MASTER_SLAVE_STATE_SLAVE;
|
||||
+ } else {
|
||||
+ phydev->master_slave_state = MASTER_SLAVE_STATE_UNSUPPORTED;
|
||||
+ }
|
||||
}
|
||||
|
||||
static int rtlgen_read_status(struct phy_device *phydev)
|
||||
@@ -702,7 +734,7 @@ static int rtlgen_read_status(struct phy
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
- rtlgen_decode_speed(phydev, val);
|
||||
+ rtlgen_decode_physr(phydev, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1030,11 +1062,11 @@ static int rtl822x_c45_read_status(struc
|
||||
return 0;
|
||||
|
||||
/* Read actual speed from vendor register. */
|
||||
- val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_PHYSR);
|
||||
+ val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL_VND2_PHYSR);
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
- rtlgen_decode_speed(phydev, val);
|
||||
+ rtlgen_decode_physr(phydev, val);
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
From eaca24de0c0e64145c130759207da32594d2e5d1 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 8 Oct 2024 21:05:47 +0100
|
||||
Subject: [PATCH 2/3] net: phy: realtek: change order of calls in C22
|
||||
read_status()
|
||||
|
||||
Always call rtlgen_read_status() first, so genphy_read_status() which
|
||||
is called by it clears bits in case auto-negotiation has not completed.
|
||||
Also clear 10GBT link-partner advertisement bits in case auto-negotiation
|
||||
is disabled or has not completed.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/phy/realtek.c | 22 +++++++++++++++-------
|
||||
1 file changed, 15 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -979,17 +979,25 @@ static void rtl822xb_update_interface(st
|
||||
|
||||
static int rtl822x_read_status(struct phy_device *phydev)
|
||||
{
|
||||
- if (phydev->autoneg == AUTONEG_ENABLE) {
|
||||
- int lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
|
||||
+ int lpadv, ret;
|
||||
|
||||
- if (lpadv < 0)
|
||||
- return lpadv;
|
||||
+ ret = rtlgen_read_status(phydev);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
|
||||
- mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising,
|
||||
- lpadv);
|
||||
+ if (phydev->autoneg == AUTONEG_DISABLE ||
|
||||
+ !phydev->autoneg_complete) {
|
||||
+ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, 0);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
- return rtlgen_read_status(phydev);
|
||||
+ lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
|
||||
+ if (lpadv < 0)
|
||||
+ return lpadv;
|
||||
+
|
||||
+ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int rtl822xb_read_status(struct phy_device *phydev)
|
@ -0,0 +1,28 @@
|
||||
From 8b137d1e405dc90300ba577db44c70f0e026636e Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 8 Oct 2024 21:09:19 +0100
|
||||
Subject: [PATCH 3/3] net: phy: realtek: clear 1000Base-T link partner
|
||||
advertisement
|
||||
|
||||
Clear 1000Base-T link partner advertisement bits in Clause-45
|
||||
read_status() function in case auto-negotiation is disabled or has not
|
||||
been completed.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/phy/realtek.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -1056,6 +1056,10 @@ static int rtl822x_c45_read_status(struc
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
+ if (phydev->autoneg == AUTONEG_DISABLE ||
|
||||
+ !genphy_c45_aneg_done(phydev))
|
||||
+ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, 0);
|
||||
+
|
||||
/* Vendor register as C45 has no standardized support for 1000BaseT */
|
||||
if (phydev->autoneg == AUTONEG_ENABLE) {
|
||||
val = phy_read_mmd(phydev, MDIO_MMD_VEND2,
|
Loading…
Reference in New Issue
Block a user