kernel: add pending mtk_sgmii and phy improvements from @lynxis
authorDaniel Golle <daniel@makrotopia.org>
Mon, 15 Aug 2022 16:50:10 +0000 (18:50 +0200)
committerDaniel Golle <daniel@makrotopia.org>
Tue, 30 Aug 2022 12:36:28 +0000 (13:36 +0100)
Add pending patches from Alexander 'lynxis' Couzens which are required
for RealTek NBase-T PHYs or SFP+ cages to work when connected to the
SGMII interface provided by recent MediaTek SoCs [1].
The patches for MT753x fix link speed limitation on CPU ports observed
by many users which is due to reset being carried out wrongly [2].

[1]: https://patchwork.kernel.org/project/netdevbpf/list/?series=669488&state=*
[2]: https://patchwork.kernel.org/project/netdevbpf/list/?series=669486&state=*

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
target/linux/generic/pending-5.15/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch [new file with mode: 0644]
target/linux/generic/pending-5.15/722-net-mt7531-only-do-PLL-once-after-the-reset.patch [new file with mode: 0644]
target/linux/generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch [new file with mode: 0644]
target/linux/generic/pending-5.15/724-net-mtk_sgmii-implement-mtk_pcs_ops.patch [new file with mode: 0644]
target/linux/generic/pending-5.15/725-net-mtk_sgmii-fix-powering-up-the-SGMII-phy.patch [new file with mode: 0644]
target/linux/generic/pending-5.15/726-net-mtk_sgmii-ensure-the-SGMII-PHY-is-powered-down-o.patch [new file with mode: 0644]
target/linux/generic/pending-5.15/727-net-mtk_sgmii-mtk_pcs_setup_mode_an-don-t-rely-on-re.patch [new file with mode: 0644]
target/linux/generic/pending-5.15/728-net-mtk_sgmii-set-the-speed-according-to-the-phy-int.patch [new file with mode: 0644]
target/linux/generic/pending-5.15/729-net-mtk_eth_soc-improve-comment.patch [new file with mode: 0644]
target/linux/generic/pending-5.15/730-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch [new file with mode: 0644]

diff --git a/target/linux/generic/pending-5.15/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch b/target/linux/generic/pending-5.15/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch
new file mode 100644 (file)
index 0000000..703a0b8
--- /dev/null
@@ -0,0 +1,101 @@
+From ace6abaa0f9203083fe4c0a6a74da2d96410b625 Mon Sep 17 00:00:00 2001
+From: Alexander Couzens <lynxis@fe80.eu>
+Date: Sat, 13 Aug 2022 12:49:33 +0200
+Subject: [PATCH 01/10] net: phy: realtek: rtl8221: allow to configure SERDES
+ mode
+
+The rtl8221 supports multiple SERDES modes:
+- SGMII
+- 2500base-x
+- HiSGMII
+
+Further it supports rate adaption on SERDES links to allow
+slow ethernet speeds (10/100/1000mbit) to work on 2500base-x/HiSGMII
+links without reducing the SERDES speed.
+
+When operating without rate adapters the SERDES link will follow the
+ethernet speed.
+
+Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
+---
+ drivers/net/phy/realtek.c | 48 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 48 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -53,6 +53,15 @@
+                                                RTL8201F_ISR_LINK)
+ #define RTL8201F_IER                          0x13
++#define RTL8221B_MMD_SERDES_CTRL              MDIO_MMD_VEND1
++#define RTL8221B_MMD_PHY_CTRL                 MDIO_MMD_VEND2
++#define RTL8221B_SERDES_OPTION                        0x697a
++#define RTL8221B_SERDES_OPTION_MODE_MASK      GENMASK(5, 0)
++#define RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII   0
++#define RTL8221B_SERDES_OPTION_MODE_HISGMII_SGMII     1
++#define RTL8221B_SERDES_OPTION_MODE_2500BASEX         2
++#define RTL8221B_SERDES_OPTION_MODE_HISGMII           3
++
+ #define RTL8366RB_POWER_SAVE                  0x15
+ #define RTL8366RB_POWER_SAVE_ON                       BIT(12)
+@@ -841,6 +850,43 @@ static irqreturn_t rtl9000a_handle_inter
+       return IRQ_HANDLED;
+ }
++static int rtl8221b_config_init(struct phy_device *phydev)
++{
++      u16 option_mode;
++
++      switch (phydev->interface) {
++      case PHY_INTERFACE_MODE_SGMII:
++      case PHY_INTERFACE_MODE_2500BASEX:
++              option_mode = RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII;
++              break;
++      default:
++              return 0;
++      }
++
++      phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL,
++                      0x75f3, 0);
++
++      phy_modify_mmd_changed(phydev, RTL8221B_MMD_SERDES_CTRL,
++                             RTL8221B_SERDES_OPTION,
++                             RTL8221B_SERDES_OPTION_MODE_MASK, option_mode);
++      switch (option_mode) {
++        case RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII:
++        case RTL8221B_SERDES_OPTION_MODE_2500BASEX:
++                phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503);
++                phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd455);
++                phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020);
++                break;
++        case RTL8221B_SERDES_OPTION_MODE_HISGMII_SGMII:
++        case RTL8221B_SERDES_OPTION_MODE_HISGMII:
++                phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503);
++                phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd433);
++                phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020);
++                break;
++      }
++
++      return 0;
++}
++
+ static struct phy_driver realtek_drvs[] = {
+       {
+               PHY_ID_MATCH_EXACT(0x00008201),
+@@ -981,6 +1027,7 @@ static struct phy_driver realtek_drvs[]
+               PHY_ID_MATCH_EXACT(0x001cc849),
+               .name           = "RTL8221B-VB-CG 2.5Gbps PHY",
+               .get_features   = rtl822x_get_features,
++              .config_init    = rtl8221b_config_init,
+               .config_aneg    = rtl822x_config_aneg,
+               .read_status    = rtl822x_read_status,
+               .suspend        = genphy_suspend,
+@@ -992,6 +1039,7 @@ static struct phy_driver realtek_drvs[]
+               .name           = "RTL8221B-VM-CG 2.5Gbps PHY",
+               .get_features   = rtl822x_get_features,
+               .config_aneg    = rtl822x_config_aneg,
++              .config_init    = rtl8221b_config_init,
+               .read_status    = rtl822x_read_status,
+               .suspend        = genphy_suspend,
+               .resume         = rtlgen_resume,
diff --git a/target/linux/generic/pending-5.15/722-net-mt7531-only-do-PLL-once-after-the-reset.patch b/target/linux/generic/pending-5.15/722-net-mt7531-only-do-PLL-once-after-the-reset.patch
new file mode 100644 (file)
index 0000000..6fd450d
--- /dev/null
@@ -0,0 +1,67 @@
+From 9fec662b54fc956b776df15c704e996c61292850 Mon Sep 17 00:00:00 2001
+From: Alexander Couzens <lynxis@fe80.eu>
+Date: Sat, 13 Aug 2022 13:05:09 +0200
+Subject: [PATCH 02/10] net: mt7531: only do PLL once after the reset
+
+Move the PLL init of the switch out of the pad configuration of the port
+6 (usally cpu port).
+
+Fix a unidirectional 100 mbit limitation on 1 gbit or 2.5 gbit links for
+outbound traffic on port 5 or port 6.
+
+Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
+---
+ drivers/net/dsa/mt7530.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -506,14 +506,19 @@ static bool mt7531_dual_sgmii_supported(
+ static int
+ mt7531_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
+ {
+-      struct mt7530_priv *priv = ds->priv;
++      return 0;
++}
++
++static void
++mt7531_pll_setup(struct mt7530_priv *priv)
++{
+       u32 top_sig;
+       u32 hwstrap;
+       u32 xtal;
+       u32 val;
+       if (mt7531_dual_sgmii_supported(priv))
+-              return 0;
++              return;
+       val = mt7530_read(priv, MT7531_CREV);
+       top_sig = mt7530_read(priv, MT7531_TOP_SIG_SR);
+@@ -592,8 +597,6 @@ mt7531_pad_setup(struct dsa_switch *ds,
+       val |= EN_COREPLL;
+       mt7530_write(priv, MT7531_PLLGP_EN, val);
+       usleep_range(25, 35);
+-
+-      return 0;
+ }
+ static void
+@@ -2326,6 +2329,8 @@ mt7531_setup(struct dsa_switch *ds)
+                    SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |
+                    SYS_CTRL_REG_RST);
++      mt7531_pll_setup(priv);
++
+       if (mt7531_dual_sgmii_supported(priv)) {
+               priv->p5_intf_sel = P5_INTF_SEL_GMAC5_SGMII;
+@@ -2882,8 +2887,6 @@ mt7531_cpu_port_config(struct dsa_switch
+       case 6:
+               interface = PHY_INTERFACE_MODE_2500BASEX;
+-              mt7531_pad_setup(ds, interface);
+-
+               priv->p6_interface = interface;
+               break;
+       default:
diff --git a/target/linux/generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch b/target/linux/generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch
new file mode 100644 (file)
index 0000000..cc12d72
--- /dev/null
@@ -0,0 +1,28 @@
+From 3fb8841513c4ec3a2e5d366df86230c45f239a57 Mon Sep 17 00:00:00 2001
+From: Alexander Couzens <lynxis@fe80.eu>
+Date: Sat, 13 Aug 2022 13:08:22 +0200
+Subject: [PATCH 03/10] net: mt7531: ensure all MACs are powered down before
+ reset
+
+The datasheet [1] explicit describes it as requirement for a reset.
+
+[1] MT7531 Reference Manual for Development Board rev 1.0, page 735
+
+Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
+---
+ drivers/net/dsa/mt7530.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -2324,6 +2324,10 @@ mt7531_setup(struct dsa_switch *ds)
+               return -ENODEV;
+       }
++      /* all MACs must be forced link-down before sw reset */
++      for (i = 0; i < MT7530_NUM_PORTS; i++)
++              mt7530_write(priv, MT7530_PMCR_P(i), MT7531_FORCE_LNK);
++
+       /* Reset the switch through internal reset */
+       mt7530_write(priv, MT7530_SYS_CTRL,
+                    SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |
diff --git a/target/linux/generic/pending-5.15/724-net-mtk_sgmii-implement-mtk_pcs_ops.patch b/target/linux/generic/pending-5.15/724-net-mtk_sgmii-implement-mtk_pcs_ops.patch
new file mode 100644 (file)
index 0000000..896f016
--- /dev/null
@@ -0,0 +1,44 @@
+From cbfed00575d15eafd85efd9619b7ecc0836a4aa7 Mon Sep 17 00:00:00 2001
+From: Alexander Couzens <lynxis@fe80.eu>
+Date: Sat, 13 Aug 2022 14:42:12 +0200
+Subject: [PATCH 04/10] net: mtk_sgmii: implement mtk_pcs_ops
+
+Implement mtk_pcs_ops for the SGMII pcs to read the current state
+of the hardware.
+
+Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
+[added DUPLEX_FULL]
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/ethernet/mediatek/mtk_sgmii.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -122,10 +122,26 @@ static void mtk_pcs_link_up(struct phyli
+       regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
+ }
++static void mtk_pcs_get_state(struct phylink_pcs *pcs, struct phylink_link_state *state)
++{
++      struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
++      unsigned int val;
++
++      regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val);
++      state->speed = val & RG_PHY_SPEED_3_125G ? SPEED_2500 : SPEED_1000;
++
++      regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
++      state->an_complete = !!(val & SGMII_AN_COMPLETE);
++      state->link = !!(val & SGMII_LINK_STATYS);
++      state->duplex = DUPLEX_FULL;
++      state->pause = 0;
++}
++
+ static const struct phylink_pcs_ops mtk_pcs_ops = {
+       .pcs_config = mtk_pcs_config,
+       .pcs_an_restart = mtk_pcs_restart_an,
+       .pcs_link_up = mtk_pcs_link_up,
++      .pcs_get_state = mtk_pcs_get_state,
+ };
+ int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3)
diff --git a/target/linux/generic/pending-5.15/725-net-mtk_sgmii-fix-powering-up-the-SGMII-phy.patch b/target/linux/generic/pending-5.15/725-net-mtk_sgmii-fix-powering-up-the-SGMII-phy.patch
new file mode 100644 (file)
index 0000000..0fa357d
--- /dev/null
@@ -0,0 +1,39 @@
+From 7f75f43fe2159123baa101fcc8c6faa0b0a4c598 Mon Sep 17 00:00:00 2001
+From: Alexander Couzens <lynxis@fe80.eu>
+Date: Sat, 13 Aug 2022 14:48:51 +0200
+Subject: [PATCH 05/10] net: mtk_sgmii: fix powering up the SGMII phy
+
+There are certain race condition when the SGMII_PHYA_PWD register still
+contains 0x9 which prevents the SGMII from working properly.
+
+The SGMII still shows link but no traffic can flow.
+
+Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
+---
+ drivers/net/ethernet/mediatek/mtk_sgmii.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -36,9 +36,7 @@ static int mtk_pcs_setup_mode_an(struct
+       val |= SGMII_AN_RESTART;
+       regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
+-      regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
+-      val &= ~SGMII_PHYA_PWD;
+-      regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
++      regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
+       return 0;
+@@ -70,9 +68,7 @@ static int mtk_pcs_setup_mode_force(stru
+       regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
+       /* Release PHYA power down state */
+-      regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
+-      val &= ~SGMII_PHYA_PWD;
+-      regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
++      regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
+       return 0;
+ }
diff --git a/target/linux/generic/pending-5.15/726-net-mtk_sgmii-ensure-the-SGMII-PHY-is-powered-down-o.patch b/target/linux/generic/pending-5.15/726-net-mtk_sgmii-ensure-the-SGMII-PHY-is-powered-down-o.patch
new file mode 100644 (file)
index 0000000..329b41c
--- /dev/null
@@ -0,0 +1,65 @@
+From 9daea9b71d060d93d7394ac465b2e5ee0b7e7bca Mon Sep 17 00:00:00 2001
+From: Alexander Couzens <lynxis@fe80.eu>
+Date: Mon, 15 Aug 2022 16:02:01 +0200
+Subject: [PATCH 06/10] net: mtk_sgmii: ensure the SGMII PHY is powered down on
+ configuration
+
+The code expect the PHY to be in power down (which is only true after reset).
+Allow the changes of SGMII parameters more than once.
+---
+ drivers/net/ethernet/mediatek/mtk_sgmii.c | 16 +++++++++++++++-
+ 1 file changed, 15 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -7,6 +7,7 @@
+  *
+  */
++#include <linux/delay.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/of.h>
+ #include <linux/phylink.h>
+@@ -24,6 +25,9 @@ static int mtk_pcs_setup_mode_an(struct
+ {
+       unsigned int val;
++      /* PHYA power down */
++      regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, SGMII_PHYA_PWD);
++
+       /* Setup the link timer and QPHY power up inside SGMIISYS */
+       regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
+                    SGMII_LINK_TIMER_DEFAULT);
+@@ -36,6 +40,10 @@ static int mtk_pcs_setup_mode_an(struct
+       val |= SGMII_AN_RESTART;
+       regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
++      /* Release PHYA power down state
++       * unknown how much the QPHY needs but it is racy without a sleep
++       */
++      usleep_range(50, 100);
+       regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
+       return 0;
+@@ -50,6 +58,9 @@ static int mtk_pcs_setup_mode_force(stru
+ {
+       unsigned int val;
++      /* PHYA power down */
++      regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, SGMII_PHYA_PWD);
++
+       regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val);
+       val &= ~RG_PHY_SPEED_MASK;
+       if (interface == PHY_INTERFACE_MODE_2500BASEX)
+@@ -67,7 +78,10 @@ static int mtk_pcs_setup_mode_force(stru
+       val |= SGMII_SPEED_1000;
+       regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
+-      /* Release PHYA power down state */
++      /* Release PHYA power down state
++       * unknown how much the QPHY needs but it is racy without a sleep
++       */
++      usleep_range(50, 100);
+       regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
+       return 0;
diff --git a/target/linux/generic/pending-5.15/727-net-mtk_sgmii-mtk_pcs_setup_mode_an-don-t-rely-on-re.patch b/target/linux/generic/pending-5.15/727-net-mtk_sgmii-mtk_pcs_setup_mode_an-don-t-rely-on-re.patch
new file mode 100644 (file)
index 0000000..5bc187c
--- /dev/null
@@ -0,0 +1,31 @@
+From e4dca7affb8c03438b63bdb5fddefd6ad2431cfd Mon Sep 17 00:00:00 2001
+From: Alexander Couzens <lynxis@fe80.eu>
+Date: Mon, 15 Aug 2022 14:59:29 +0200
+Subject: [PATCH 07/10] net: mtk_sgmii: mtk_pcs_setup_mode_an: don't rely on
+ register defaults
+
+Ensure autonegotiation is enabled.
+
+Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
+---
+ drivers/net/ethernet/mediatek/mtk_sgmii.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -32,12 +32,13 @@ static int mtk_pcs_setup_mode_an(struct
+       regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
+                    SGMII_LINK_TIMER_DEFAULT);
++      /* disable remote fault & enable auto neg */
+       regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
+-      val |= SGMII_REMOTE_FAULT_DIS;
++      val |= SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN;
+       regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
+       regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
+-      val |= SGMII_AN_RESTART;
++      val |= SGMII_AN_RESTART | SGMII_AN_ENABLE;
+       regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
+       /* Release PHYA power down state
diff --git a/target/linux/generic/pending-5.15/728-net-mtk_sgmii-set-the-speed-according-to-the-phy-int.patch b/target/linux/generic/pending-5.15/728-net-mtk_sgmii-set-the-speed-according-to-the-phy-int.patch
new file mode 100644 (file)
index 0000000..0b17f77
--- /dev/null
@@ -0,0 +1,47 @@
+From 952b64575613d26163a5afa5ff8bfdb57840091b Mon Sep 17 00:00:00 2001
+From: Alexander Couzens <lynxis@fe80.eu>
+Date: Mon, 15 Aug 2022 15:00:14 +0200
+Subject: [PATCH 08/10] net: mtk_sgmii: set the speed according to the phy
+ interface in AN
+
+The non auto-negotioting code path is setting the correct speed for the
+interface. Ensure auto-negotiation code path is doing it as well.
+
+Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
+---
+ drivers/net/ethernet/mediatek/mtk_sgmii.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -21,13 +21,20 @@ static struct mtk_pcs *pcs_to_mtk_pcs(st
+ }
+ /* For SGMII interface mode */
+-static int mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
++static int mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs, phy_interface_t interface)
+ {
+       unsigned int val;
+       /* PHYA power down */
+       regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, SGMII_PHYA_PWD);
++      /* Set SGMII phy speed */
++      regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val);
++      val &= ~RG_PHY_SPEED_MASK;
++      if (interface == PHY_INTERFACE_MODE_2500BASEX)
++              val |= RG_PHY_SPEED_3_125G;
++      regmap_write(mpcs->regmap, mpcs->ana_rgc3, val);
++
+       /* Setup the link timer and QPHY power up inside SGMIISYS */
+       regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
+                    SGMII_LINK_TIMER_DEFAULT);
+@@ -100,7 +107,7 @@ static int mtk_pcs_config(struct phylink
+       if (interface != PHY_INTERFACE_MODE_SGMII)
+               err = mtk_pcs_setup_mode_force(mpcs, interface);
+       else if (phylink_autoneg_inband(mode))
+-              err = mtk_pcs_setup_mode_an(mpcs);
++              err = mtk_pcs_setup_mode_an(mpcs, interface);
+       return err;
+ }
diff --git a/target/linux/generic/pending-5.15/729-net-mtk_eth_soc-improve-comment.patch b/target/linux/generic/pending-5.15/729-net-mtk_eth_soc-improve-comment.patch
new file mode 100644 (file)
index 0000000..8014485
--- /dev/null
@@ -0,0 +1,22 @@
+From 06773f19cffd6c9d34dcbc8320169afef5ab60ba Mon Sep 17 00:00:00 2001
+From: Alexander Couzens <lynxis@fe80.eu>
+Date: Mon, 15 Aug 2022 13:58:07 +0200
+Subject: [PATCH 09/10] net: mtk_eth_soc: improve comment
+
+Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
+---
+ drivers/net/ethernet/mediatek/mtk_sgmii.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -80,7 +80,8 @@ static int mtk_pcs_setup_mode_force(stru
+       val &= ~SGMII_AN_ENABLE;
+       regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
+-      /* Set the speed etc but leave the duplex unchanged */
++      /* Set the speed etc but leave the duplex unchanged.
++       * The SGMII mode for 2.5gbit is the same as for 1gbit, expect the speed in ANA_RGC3 */
+       regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
+       val &= SGMII_DUPLEX_FULL | ~SGMII_IF_MODE_MASK;
+       val |= SGMII_SPEED_1000;
diff --git a/target/linux/generic/pending-5.15/730-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch b/target/linux/generic/pending-5.15/730-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch
new file mode 100644 (file)
index 0000000..6c7fd6a
--- /dev/null
@@ -0,0 +1,23 @@
+From 95dcd0f223d7cab6e25bc19088016e5eb4ca1804 Mon Sep 17 00:00:00 2001
+From: Alexander Couzens <lynxis@fe80.eu>
+Date: Tue, 16 Aug 2022 00:22:11 +0200
+Subject: [PATCH 10/10] mtk_sgmii: enable PCS polling to allow SFP work
+
+Currently there is no IRQ handling (even the SGMII supports it).
+Enable polling to support SFP ports.
+
+Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
+---
+ drivers/net/ethernet/mediatek/mtk_sgmii.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -180,6 +180,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
+                       return PTR_ERR(ss->pcs[i].regmap);
+               ss->pcs[i].pcs.ops = &mtk_pcs_ops;
++              ss->pcs[i].pcs.poll = 1;
+       }
+       return 0;