generic: net: phy: realtek: various improvements
authorDaniel Golle <daniel@makrotopia.org>
Tue, 8 Oct 2024 23:19:26 +0000 (00:19 +0100)
committerDaniel Golle <daniel@makrotopia.org>
Wed, 9 Oct 2024 01:36:22 +0000 (02:36 +0100)
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.

Fixes: #14504
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
target/linux/generic/pending-6.6/720-04-net-phy-realtek-introduce-rtl822x_probe.patch [new file with mode: 0644]
target/linux/generic/pending-6.6/720-04-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch [deleted file]
target/linux/generic/pending-6.6/720-05-net-phy-realtek-check-validity-of-10GbE-link-partner.patch [deleted file]
target/linux/generic/pending-6.6/720-05-net-phy-realtek-detect-early-version-of-RTL8221B.patch [new file with mode: 0644]
target/linux/generic/pending-6.6/720-06-net-phy-realtek-introduce-rtl822x_probe.patch [deleted file]
target/linux/generic/pending-6.6/720-06-net-phy-realtek-support-interrupt-of-RTL8221B.patch [new file with mode: 0644]
target/linux/generic/pending-6.6/720-07-net-phy-realtek-detect-early-version-of-RTL8221B.patch [deleted file]
target/linux/generic/pending-6.6/720-07-net-phy-realtek-read-duplex-and-gbit-master-from-PHY.patch [new file with mode: 0644]
target/linux/generic/pending-6.6/720-08-net-phy-realtek-change-order-of-calls-in-C22-read_st.patch [new file with mode: 0644]
target/linux/generic/pending-6.6/720-08-net-phy-realtek-support-interrupt-of-RTL8221B.patch [deleted file]
target/linux/generic/pending-6.6/720-09-net-phy-realtek-clear-1000Base-T-link-partner-advert.patch [new file with mode: 0644]

diff --git a/target/linux/generic/pending-6.6/720-04-net-phy-realtek-introduce-rtl822x_probe.patch b/target/linux/generic/pending-6.6/720-04-net-phy-realtek-introduce-rtl822x_probe.patch
new file mode 100644 (file)
index 0000000..7350d3a
--- /dev/null
@@ -0,0 +1,100 @@
+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)
+@@ -1102,6 +1106,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);
+@@ -1377,6 +1400,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,
+@@ -1388,6 +1412,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,
+@@ -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)",
++              .probe          = rtl822x_probe,
+               .soft_reset     = genphy_soft_reset,
+               .get_features   = rtl822x_get_features,
+               .config_aneg    = rtl822x_config_aneg,
+@@ -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)",
++              .probe          = rtl822x_probe,
+               .soft_reset     = genphy_soft_reset,
+               .config_init    = rtl822xb_config_init,
+               .get_rate_matching = rtl822xb_get_rate_matching,
+@@ -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)",
++              .probe          = rtl822x_probe,
+               .soft_reset     = genphy_soft_reset,
+               .get_features   = rtl822x_get_features,
+               .config_aneg    = rtl822x_config_aneg,
+@@ -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)",
++              .probe          = rtl822x_probe,
+               .soft_reset     = genphy_soft_reset,
+               .config_init    = rtl822xb_config_init,
+               .get_rate_matching = rtl822xb_get_rate_matching,
diff --git a/target/linux/generic/pending-6.6/720-04-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch b/target/linux/generic/pending-6.6/720-04-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch
deleted file mode 100644 (file)
index 8b20451..0000000
+++ /dev/null
@@ -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;
diff --git a/target/linux/generic/pending-6.6/720-05-net-phy-realtek-check-validity-of-10GbE-link-partner.patch b/target/linux/generic/pending-6.6/720-05-net-phy-realtek-check-validity-of-10GbE-link-partner.patch
deleted file mode 100644 (file)
index 1ba3353..0000000
+++ /dev/null
@@ -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);
-       }
diff --git a/target/linux/generic/pending-6.6/720-05-net-phy-realtek-detect-early-version-of-RTL8221B.patch b/target/linux/generic/pending-6.6/720-05-net-phy-realtek-detect-early-version-of-RTL8221B.patch
new file mode 100644 (file)
index 0000000..204d7a0
--- /dev/null
@@ -0,0 +1,52 @@
+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
+@@ -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)
+ {
+-      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)
diff --git a/target/linux/generic/pending-6.6/720-06-net-phy-realtek-introduce-rtl822x_probe.patch b/target/linux/generic/pending-6.6/720-06-net-phy-realtek-introduce-rtl822x_probe.patch
deleted file mode 100644 (file)
index ee4de59..0000000
+++ /dev/null
@@ -1,100 +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.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,
diff --git a/target/linux/generic/pending-6.6/720-06-net-phy-realtek-support-interrupt-of-RTL8221B.patch b/target/linux/generic/pending-6.6/720-06-net-phy-realtek-support-interrupt-of-RTL8221B.patch
new file mode 100644 (file)
index 0000000..0ae7b38
--- /dev/null
@@ -0,0 +1,102 @@
+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
+@@ -1282,6 +1282,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),
+@@ -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)",
++              .config_intr    = rtl8221b_config_intr,
++              .handle_interrupt = rtl8221b_handle_interrupt,
+               .probe          = rtl822x_probe,
+               .soft_reset     = genphy_soft_reset,
+               .get_features   = rtl822x_get_features,
+@@ -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)",
++              .config_intr    = rtl8221b_config_intr,
++              .handle_interrupt = rtl8221b_handle_interrupt,
+               .probe          = rtl822x_probe,
+               .soft_reset     = genphy_soft_reset,
+               .config_init    = rtl822xb_config_init,
+@@ -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)",
++              .config_intr    = rtl8221b_config_intr,
++              .handle_interrupt = rtl8221b_handle_interrupt,
+               .probe          = rtl822x_probe,
+               .soft_reset     = genphy_soft_reset,
+               .get_features   = rtl822x_get_features,
+@@ -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)",
++              .config_intr    = rtl8221b_config_intr,
++              .handle_interrupt = rtl8221b_handle_interrupt,
+               .probe          = rtl822x_probe,
+               .soft_reset     = genphy_soft_reset,
+               .config_init    = rtl822xb_config_init,
diff --git a/target/linux/generic/pending-6.6/720-07-net-phy-realtek-detect-early-version-of-RTL8221B.patch b/target/linux/generic/pending-6.6/720-07-net-phy-realtek-detect-early-version-of-RTL8221B.patch
deleted file mode 100644 (file)
index cca5da0..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-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)
diff --git a/target/linux/generic/pending-6.6/720-07-net-phy-realtek-read-duplex-and-gbit-master-from-PHY.patch b/target/linux/generic/pending-6.6/720-07-net-phy-realtek-read-duplex-and-gbit-master-from-PHY.patch
new file mode 100644 (file)
index 0000000..d609d59
--- /dev/null
@@ -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;
+ }
diff --git a/target/linux/generic/pending-6.6/720-08-net-phy-realtek-change-order-of-calls-in-C22-read_st.patch b/target/linux/generic/pending-6.6/720-08-net-phy-realtek-change-order-of-calls-in-C22-read_st.patch
new file mode 100644 (file)
index 0000000..8a7ad8a
--- /dev/null
@@ -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)
diff --git a/target/linux/generic/pending-6.6/720-08-net-phy-realtek-support-interrupt-of-RTL8221B.patch b/target/linux/generic/pending-6.6/720-08-net-phy-realtek-support-interrupt-of-RTL8221B.patch
deleted file mode 100644 (file)
index ee28bfb..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-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,
diff --git a/target/linux/generic/pending-6.6/720-09-net-phy-realtek-clear-1000Base-T-link-partner-advert.patch b/target/linux/generic/pending-6.6/720-09-net-phy-realtek-clear-1000Base-T-link-partner-advert.patch
new file mode 100644 (file)
index 0000000..824be84
--- /dev/null
@@ -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,