- Fix setting of PHY LEDs Mode B bit on RTL8211F.
- Rename pending Realtek PHY patches.
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
--- /dev/null
+From a2f5c505b4378cd6fc7c4a44ff3665ccef2037db Mon Sep 17 00:00:00 2001
+From: Sava Jakovljev <savaj@meyersound.com>
+Date: Wed, 21 Aug 2024 04:16:57 +0200
+Subject: [PATCH] net: phy: realtek: Fix setting of PHY LEDs Mode B bit on
+ RTL8211F
+
+The current implementation incorrectly sets the mode bit of the PHY chip.
+Bit 15 (RTL8211F_LEDCR_MODE) should not be shifted together with the
+configuration nibble of a LED- it should be set independently of the
+index of the LED being configured.
+As a consequence, the RTL8211F LED control is actually operating in Mode A.
+Fix the error by or-ing final register value to write with a const-value of
+RTL8211F_LEDCR_MODE, thus setting Mode bit explicitly.
+
+Fixes: 17784801d888 ("net: phy: realtek: Add support for PHY LEDs on RTL8211F")
+Signed-off-by: Sava Jakovljev <savaj@meyersound.com>
+Reviewed-by: Marek Vasut <marex@denx.de>
+Link: https://patch.msgid.link/PAWP192MB21287372F30C4E55B6DF6158C38E2@PAWP192MB2128.EURP192.PROD.OUTLOOK.COM
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/phy/realtek.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -555,7 +555,7 @@ static int rtl8211f_led_hw_control_set(s
+ unsigned long rules)
+ {
+ const u16 mask = RTL8211F_LEDCR_MASK << (RTL8211F_LEDCR_SHIFT * index);
+- u16 reg = RTL8211F_LEDCR_MODE; /* Mode B */
++ u16 reg = 0;
+
+ if (index >= RTL8211F_LED_COUNT)
+ return -EINVAL;
+@@ -575,6 +575,7 @@ static int rtl8211f_led_hw_control_set(s
+ }
+
+ reg <<= RTL8211F_LEDCR_SHIFT * index;
++ reg |= RTL8211F_LEDCR_MODE; /* Mode B */
+
+ return phy_modify_paged(phydev, 0xd04, RTL8211F_LEDCR, mask, reg);
+ }
--- /dev/null
+From 85cd45580f5e3b26068cccb7d6173f200e754dc0 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sun, 2 Apr 2023 23:56:16 +0100
+Subject: [PATCH 1/2] net: phy: realtek: use genphy_soft_reset for 2.5G PHYs
+
+Some vendor bootloaders do weird things with those PHYs which result in
+link modes being reported wrongly. Start from a clean sheet by resetting
+the PHY.
+
+Reported-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/phy/realtek.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -1325,6 +1325,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .name = "RTL8226 2.5Gbps PHY",
+ .match_phy_device = rtl8226_match_phy_device,
++ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .read_status = rtl822x_read_status,
+@@ -1337,6 +1338,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ PHY_ID_MATCH_EXACT(0x001cc840),
+ .name = "RTL8226B_RTL8221B 2.5Gbps PHY",
++ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
+@@ -1351,6 +1353,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ PHY_ID_MATCH_EXACT(0x001cc838),
+ .name = "RTL8226-CG 2.5Gbps PHY",
++ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .read_status = rtl822x_read_status,
+@@ -1361,6 +1364,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,
+@@ -1373,6 +1377,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,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
+@@ -1385,6 +1390,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,
+ .config_init = rtl822xb_config_init,
+ .get_rate_matching = rtl822xb_get_rate_matching,
+ .get_features = rtl822x_c45_get_features,
+@@ -1395,6 +1401,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,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
+@@ -1407,6 +1414,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,
+ .config_init = rtl822xb_config_init,
+ .get_rate_matching = rtl822xb_get_rate_matching,
+ .get_features = rtl822x_c45_get_features,
--- /dev/null
+From d54ef6aea00e7a6ace439baade6ad0aa38ee4b04 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Mon, 3 Apr 2023 01:21:57 +0300
+Subject: [PATCH 287/326] net: phy: realtek: disable SGMII in-band AN for 2.5G
+ PHYs
+
+MAC drivers don't use SGMII in-band autonegotiation unless told to do so
+in device tree using 'managed = "in-band-status"'. When using MDIO to
+access a PHY, in-band-status is unneeded as we have link-status via
+MDIO. Switch off SGMII in-band autonegotiation using magic values.
+
+Reported-by: Chen Minqiang <ptpt52@gmail.com>
+Reported-by: Chukun Pan <amadeus@jmu.edu.cn>
+Reported-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
+Tested-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/phy/realtek.c | 27 +++++++++++++++++++++++++--
+ 1 file changed, 25 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -786,8 +786,8 @@ static int rtl822x_write_mmd(struct phy_
+ static int rtl822xb_config_init(struct phy_device *phydev)
+ {
+ bool has_2500, has_sgmii;
++ int ret, val;
+ u16 mode;
+- int ret;
+
+ has_2500 = test_bit(PHY_INTERFACE_MODE_2500BASEX,
+ phydev->host_interfaces) ||
+@@ -837,7 +837,29 @@ static int rtl822xb_config_init(struct p
+ if (ret < 0)
+ return ret;
+
+- return phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
++ if (ret < 0)
++ return ret;
++
++ /* Disable SGMII AN */
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7588, 0x2);
++ if (ret < 0)
++ return ret;
++
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7589, 0x71d0);
++ if (ret < 0)
++ return ret;
++
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7587, 0x3);
++ if (ret < 0)
++ return ret;
++
++ ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, 0x7587,
++ val, !(val & BIT(0)), 500, 100000, false);
++ if (ret < 0)
++ return ret;
++
++ return 0;
+ }
+
+ static int rtl822xb_get_rate_matching(struct phy_device *phydev,
--- /dev/null
+From 4dd2cc9b91ecb25f278a2c55e07e6455e9000e6b Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sat, 22 Apr 2023 01:21:14 +0100
+Subject: [PATCH] net: phy: realtek: make sure paged read is protected by mutex
+
+As we cannot rely on phy_read_paged function before the PHY is
+identified, the paged read in rtlgen_supports_2_5gbps needs to be open
+coded as it is being called by the match_phy_device function, ie. before
+.read_page and .write_page have been populated.
+
+Make sure it is also protected by the MDIO bus mutex and use
+rtl821x_write_page instead of 3 individually locked MDIO bus operations.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/phy/realtek.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -1052,9 +1052,11 @@ static bool rtlgen_supports_2_5gbps(stru
+ {
+ int val;
+
+- phy_write(phydev, RTL821x_PAGE_SELECT, 0xa61);
+- val = phy_read(phydev, 0x13);
+- phy_write(phydev, RTL821x_PAGE_SELECT, 0);
++ mutex_lock(&phydev->mdio.bus->mdio_lock);
++ rtl821x_write_page(phydev, 0xa61);
++ val = __phy_read(phydev, 0x13);
++ rtl821x_write_page(phydev, 0);
++ mutex_unlock(&phydev->mdio.bus->mdio_lock);
+
+ return val >= 0 && val & MDIO_PMA_SPEED_2_5G;
+ }
--- /dev/null
+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;
--- /dev/null
+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);
+ }
--- /dev/null
+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.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -82,6 +82,10 @@
+
+ #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 RTL8366RB_POWER_SAVE 0x15
+ #define RTL8366RB_POWER_SAVE_ON BIT(12)
+
+@@ -1107,6 +1111,25 @@ static int rtl8221b_vn_cg_c45_match_phy_
+ return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true);
+ }
+
++static int rtl822x_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 0;
++}
++
+ static int rtlgen_resume(struct phy_device *phydev)
+ {
+ int ret = genphy_resume(phydev);
+@@ -1382,6 +1405,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ PHY_ID_MATCH_EXACT(0x001cc838),
+ .name = "RTL8226-CG 2.5Gbps PHY",
++ .probe = rtl822x_probe,
+ .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[]
+ }, {
+ PHY_ID_MATCH_EXACT(0x001cc848),
+ .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
++ .probe = rtl822x_probe,
+ .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[]
+ }, {
+ .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
++ .probe = rtl822x_probe,
+ .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[]
+ }, {
+ .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
++ .probe = rtl822x_probe,
+ .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[]
+ }, {
+ .match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
+ .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
++ .probe = rtl822x_probe,
+ .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[]
+ }, {
+ .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
+ .name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
++ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .config_init = rtl822xb_config_init,
+ .get_rate_matching = rtl822xb_get_rate_matching,
--- /dev/null
+From 0de82310d2b32e78ff79d42c08b1122a6ede3778 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sun, 30 Apr 2023 00:15:41 +0100
+Subject: [PATCH] net: phy: realtek: detect early version of RTL8221B
+
+Early versions (?) of the RTL8221B PHY cannot be identified in a regular
+Clause-45 bus scan as the PHY doesn't report the implemented MMDs
+correctly but returns 0 instead.
+Implement custom identify function using the PKGID instead of iterating
+over the implemented MMDs.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+[forward-port by @namiltd]
+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
+ static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id,
+ bool is_c45)
+ {
+- if (phydev->is_c45)
+- return is_c45 && (id == phydev->c45_ids.device_ids[1]);
+- else
++ if (phydev->is_c45) {
++ u32 rid;
++
++ if (!is_c45)
++ return 0;
++
++ rid = phydev->c45_ids.device_ids[1];
++ if ((rid == 0xffffffff) && phydev->mdio.bus->read_c45) {
++ int val;
++
++ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID1);
++ if (val < 0)
++ return 0;
++
++ rid = val << 16;
++ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID2);
++ if (val < 0)
++ return 0;
++
++ rid |= val;
++ }
++
++ return (id == rid);
++ } else {
+ return !is_c45 && (id == phydev->phy_id);
++ }
+ }
+
+ static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev)
--- /dev/null
+From d7943c31d57c11e1a517aa3ce2006fca44866870 Mon Sep 17 00:00:00 2001
+From: Jianhui Zhao <zhaojh329@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@gmail.com>
+---
+ drivers/net/phy/realtek.c | 47 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 47 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -1287,6 +1287,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),
+@@ -1453,6 +1498,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,
+ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+@@ -1467,6 +1514,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,
+ .soft_reset = genphy_soft_reset,
+ .config_init = rtl822xb_config_init,
+@@ -1479,6 +1528,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,
+ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+@@ -1493,6 +1544,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,
+ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .config_init = rtl822xb_config_init,
+++ /dev/null
-From 85cd45580f5e3b26068cccb7d6173f200e754dc0 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 2 Apr 2023 23:56:16 +0100
-Subject: [PATCH 1/2] net: phy: realtek: use genphy_soft_reset for 2.5G PHYs
-
-Some vendor bootloaders do weird things with those PHYs which result in
-link modes being reported wrongly. Start from a clean sheet by resetting
-the PHY.
-
-Reported-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -1324,6 +1324,7 @@ static struct phy_driver realtek_drvs[]
- }, {
- .name = "RTL8226 2.5Gbps PHY",
- .match_phy_device = rtl8226_match_phy_device,
-+ .soft_reset = genphy_soft_reset,
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
- .read_status = rtl822x_read_status,
-@@ -1336,6 +1337,7 @@ static struct phy_driver realtek_drvs[]
- }, {
- PHY_ID_MATCH_EXACT(0x001cc840),
- .name = "RTL8226B_RTL8221B 2.5Gbps PHY",
-+ .soft_reset = genphy_soft_reset,
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
- .config_init = rtl822xb_config_init,
-@@ -1350,6 +1352,7 @@ static struct phy_driver realtek_drvs[]
- }, {
- PHY_ID_MATCH_EXACT(0x001cc838),
- .name = "RTL8226-CG 2.5Gbps PHY",
-+ .soft_reset = genphy_soft_reset,
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
- .read_status = rtl822x_read_status,
-@@ -1360,6 +1363,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,
-@@ -1372,6 +1376,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,
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
- .config_init = rtl822xb_config_init,
-@@ -1384,6 +1389,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,
- .config_init = rtl822xb_config_init,
- .get_rate_matching = rtl822xb_get_rate_matching,
- .get_features = rtl822x_c45_get_features,
-@@ -1394,6 +1400,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,
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
- .config_init = rtl822xb_config_init,
-@@ -1406,6 +1413,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,
- .config_init = rtl822xb_config_init,
- .get_rate_matching = rtl822xb_get_rate_matching,
- .get_features = rtl822x_c45_get_features,
+++ /dev/null
-From d54ef6aea00e7a6ace439baade6ad0aa38ee4b04 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 01:21:57 +0300
-Subject: [PATCH 287/326] net: phy: realtek: disable SGMII in-band AN for 2.5G
- PHYs
-
-MAC drivers don't use SGMII in-band autonegotiation unless told to do so
-in device tree using 'managed = "in-band-status"'. When using MDIO to
-access a PHY, in-band-status is unneeded as we have link-status via
-MDIO. Switch off SGMII in-band autonegotiation using magic values.
-
-Reported-by: Chen Minqiang <ptpt52@gmail.com>
-Reported-by: Chukun Pan <amadeus@jmu.edu.cn>
-Reported-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
-Tested-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 27 +++++++++++++++++++++++++--
- 1 file changed, 25 insertions(+), 2 deletions(-)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -785,8 +785,8 @@ static int rtl822x_write_mmd(struct phy_
- static int rtl822xb_config_init(struct phy_device *phydev)
- {
- bool has_2500, has_sgmii;
-+ int ret, val;
- u16 mode;
-- int ret;
-
- has_2500 = test_bit(PHY_INTERFACE_MODE_2500BASEX,
- phydev->host_interfaces) ||
-@@ -836,7 +836,29 @@ static int rtl822xb_config_init(struct p
- if (ret < 0)
- return ret;
-
-- return phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Disable SGMII AN */
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7588, 0x2);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7589, 0x71d0);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7587, 0x3);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, 0x7587,
-+ val, !(val & BIT(0)), 500, 100000, false);
-+ if (ret < 0)
-+ return ret;
-+
-+ return 0;
- }
-
- static int rtl822xb_get_rate_matching(struct phy_device *phydev,
+++ /dev/null
-From 4dd2cc9b91ecb25f278a2c55e07e6455e9000e6b Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sat, 22 Apr 2023 01:21:14 +0100
-Subject: [PATCH] net: phy: realtek: make sure paged read is protected by mutex
-
-As we cannot rely on phy_read_paged function before the PHY is
-identified, the paged read in rtlgen_supports_2_5gbps needs to be open
-coded as it is being called by the match_phy_device function, ie. before
-.read_page and .write_page have been populated.
-
-Make sure it is also protected by the MDIO bus mutex and use
-rtl821x_write_page instead of 3 individually locked MDIO bus operations.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -1051,9 +1051,11 @@ static bool rtlgen_supports_2_5gbps(stru
- {
- int val;
-
-- phy_write(phydev, RTL821x_PAGE_SELECT, 0xa61);
-- val = phy_read(phydev, 0x13);
-- phy_write(phydev, RTL821x_PAGE_SELECT, 0);
-+ mutex_lock(&phydev->mdio.bus->mdio_lock);
-+ rtl821x_write_page(phydev, 0xa61);
-+ val = __phy_read(phydev, 0x13);
-+ rtl821x_write_page(phydev, 0);
-+ mutex_unlock(&phydev->mdio.bus->mdio_lock);
-
- return val >= 0 && val & MDIO_PMA_SPEED_2_5G;
- }
+++ /dev/null
-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
-@@ -909,7 +909,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;
+++ /dev/null
-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
-@@ -949,6 +949,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);
- }
+++ /dev/null
-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.c | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -82,6 +82,10 @@
-
- #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 RTL8366RB_POWER_SAVE 0x15
- #define RTL8366RB_POWER_SAVE_ON BIT(12)
-
-@@ -1106,6 +1110,25 @@ static int rtl8221b_vn_cg_c45_match_phy_
- return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true);
- }
-
-+static int rtl822x_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 0;
-+}
-+
- static int rtlgen_resume(struct phy_device *phydev)
- {
- int ret = genphy_resume(phydev);
-@@ -1381,6 +1404,7 @@ static struct phy_driver realtek_drvs[]
- }, {
- PHY_ID_MATCH_EXACT(0x001cc838),
- .name = "RTL8226-CG 2.5Gbps PHY",
-+ .probe = rtl822x_probe,
- .soft_reset = genphy_soft_reset,
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
-@@ -1392,6 +1416,7 @@ static struct phy_driver realtek_drvs[]
- }, {
- PHY_ID_MATCH_EXACT(0x001cc848),
- .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
-+ .probe = rtl822x_probe,
- .soft_reset = genphy_soft_reset,
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
-@@ -1405,6 +1430,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)",
-+ .probe = rtl822x_probe,
- .soft_reset = genphy_soft_reset,
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
-@@ -1418,6 +1444,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)",
-+ .probe = rtl822x_probe,
- .soft_reset = genphy_soft_reset,
- .config_init = rtl822xb_config_init,
- .get_rate_matching = rtl822xb_get_rate_matching,
-@@ -1429,6 +1456,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)",
-+ .probe = rtl822x_probe,
- .soft_reset = genphy_soft_reset,
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
-@@ -1442,6 +1470,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)",
-+ .probe = rtl822x_probe,
- .soft_reset = genphy_soft_reset,
- .config_init = rtl822xb_config_init,
- .get_rate_matching = rtl822xb_get_rate_matching,
+++ /dev/null
-From 0de82310d2b32e78ff79d42c08b1122a6ede3778 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 30 Apr 2023 00:15:41 +0100
-Subject: [PATCH] net: phy: realtek: detect early version of RTL8221B
-
-Early versions (?) of the RTL8221B PHY cannot be identified in a regular
-Clause-45 bus scan as the PHY doesn't report the implemented MMDs
-correctly but returns 0 instead.
-Implement custom identify function using the PKGID instead of iterating
-over the implemented MMDs.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-[forward-port by @namiltd]
-Signed-off-by: Mieczyslaw Nalewaj <namiltd@yahoo.com>
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -1084,10 +1084,32 @@ static int rtl8226_match_phy_device(stru
- static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id,
- bool is_c45)
- {
-- if (phydev->is_c45)
-- return is_c45 && (id == phydev->c45_ids.device_ids[1]);
-- else
-+ if (phydev->is_c45) {
-+ u32 rid;
-+
-+ if (!is_c45)
-+ return 0;
-+
-+ rid = phydev->c45_ids.device_ids[1];
-+ if ((rid == 0xffffffff) && phydev->mdio.bus->read_c45) {
-+ int val;
-+
-+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID1);
-+ if (val < 0)
-+ return 0;
-+
-+ rid = val << 16;
-+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID2);
-+ if (val < 0)
-+ return 0;
-+
-+ rid |= val;
-+ }
-+
-+ return (id == rid);
-+ } else {
- return !is_c45 && (id == phydev->phy_id);
-+ }
- }
-
- static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev)
+++ /dev/null
-From d7943c31d57c11e1a517aa3ce2006fca44866870 Mon Sep 17 00:00:00 2001
-From: Jianhui Zhao <zhaojh329@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@gmail.com>
----
- drivers/net/phy/realtek.c | 47 +++++++++++++++++++++++++++++++++++++++
- 1 file changed, 47 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -1286,6 +1286,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),
-@@ -1452,6 +1497,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,
- .probe = rtl822x_probe,
- .soft_reset = genphy_soft_reset,
- .get_features = rtl822x_get_features,
-@@ -1466,6 +1513,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,
- .soft_reset = genphy_soft_reset,
- .config_init = rtl822xb_config_init,
-@@ -1478,6 +1527,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,
- .probe = rtl822x_probe,
- .soft_reset = genphy_soft_reset,
- .get_features = rtl822x_get_features,
-@@ -1492,6 +1543,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,
- .probe = rtl822x_probe,
- .soft_reset = genphy_soft_reset,
- .config_init = rtl822xb_config_init,