+++ /dev/null
-From 7ff82416de8295c61423ef6fd75f052d3837d2f7 Mon Sep 17 00:00:00 2001
-From: Alexander Couzens <lynxis@fe80.eu>
-Date: Wed, 1 Feb 2023 19:23:29 +0100
-Subject: [PATCH] net: mediatek: sgmii: ensure the SGMII PHY is powered down on
- configuration
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The code expect the PHY to be in power down which is only true after reset.
-Allow changes of the SGMII parameters more than once.
-
-Only power down when reconfiguring to avoid bouncing the link when there's
-no reason to - based on code from Russell King.
-
-There are cases when the SGMII_PHYA_PWD register contains 0x9 which
-prevents SGMII from working. The SGMII still shows link but no traffic
-can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was
-taken from a good working state of the SGMII interface.
-
-Fixes: 42c03844e93d ("net-next: mediatek: add support for MediaTek MT7622 SoC")
-Suggested-by: Russell King (Oracle) <linux@armlinux.org.uk>
-Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
-[ bmork: rebased and squashed into one patch ]
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Bjørn Mork <bjorn@mork.no>
-Acked-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 ++
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 39 +++++++++++++++------
- 2 files changed, 30 insertions(+), 11 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1063,11 +1063,13 @@ struct mtk_soc_data {
- * @regmap: The register map pointing at the range used to setup
- * SGMII modes
- * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap
-+ * @interface: Currently configured interface mode
- * @pcs: Phylink PCS structure
- */
- struct mtk_pcs {
- struct regmap *regmap;
- u32 ana_rgc3;
-+ phy_interface_t interface;
- struct phylink_pcs pcs;
- };
-
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -24,6 +24,10 @@ static int mtk_pcs_setup_mode_an(struct
- {
- unsigned int val;
-
-+ regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val);
-+ val &= ~RG_PHY_SPEED_MASK;
-+ 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);
-@@ -36,9 +40,6 @@ 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);
-
- return 0;
-
-@@ -69,11 +70,6 @@ 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 */
-- regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
-- val &= ~SGMII_PHYA_PWD;
-- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
--
- return 0;
- }
-
-@@ -85,12 +81,32 @@ static int mtk_pcs_config(struct phylink
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
- int err = 0;
-
-+ if (mpcs->interface != interface) {
-+ /* PHYA power down */
-+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
-+ SGMII_PHYA_PWD, SGMII_PHYA_PWD);
-+
-+ mpcs->interface = interface;
-+ }
-+
- /* Setup SGMIISYS with the determined property */
- 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);
-
-+ /* Release PHYA power down state
-+ * Only removing bit SGMII_PHYA_PWD isn't enough.
-+ * There are cases when the SGMII_PHYA_PWD register contains 0x9 which
-+ * prevents SGMII from working. The SGMII still shows link but no traffic
-+ * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was
-+ * taken from a good working state of the SGMII interface.
-+ * Unknown how much the QPHY needs but it is racy without a sleep.
-+ * Tested on mt7622 & mt7986.
-+ */
-+ usleep_range(50, 100);
-+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
-+
- return err;
- }
-
-@@ -145,6 +161,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].interface = PHY_INTERFACE_MODE_NA;
- }
-
- return 0;
--- /dev/null
+From b6a709cb51f7bdc55c01cec886098a9753ce8c28 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Thu, 27 Oct 2022 14:10:42 +0100
+Subject: [PATCH 01/10] net: mtk_eth_soc: add definitions for PCS
+
+As a result of help from Frank Wunderlich to investigate and test, we
+know a bit more about the PCS on the Mediatek platforms. Update the
+definitions from this investigation.
+
+This PCS appears similar, but not identical to the Lynx PCS.
+
+Although not included in this patch, but for future reference, the PHY
+ID registers at offset 4 read as 0x4d544950 'MTIP'.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -501,8 +501,10 @@
+ #define ETHSYS_DMA_AG_MAP_PPE BIT(2)
+
+ /* SGMII subsystem config registers */
+-/* Register to auto-negotiation restart */
++/* BMCR (low 16) BMSR (high 16) */
+ #define SGMSYS_PCS_CONTROL_1 0x0
++#define SGMII_BMCR GENMASK(15, 0)
++#define SGMII_BMSR GENMASK(31, 16)
+ #define SGMII_AN_RESTART BIT(9)
+ #define SGMII_ISOLATE BIT(10)
+ #define SGMII_AN_ENABLE BIT(12)
+@@ -512,13 +514,18 @@
+ #define SGMII_PCS_FAULT BIT(23)
+ #define SGMII_AN_EXPANSION_CLR BIT(30)
+
++#define SGMSYS_PCS_ADVERTISE 0x8
++#define SGMII_ADVERTISE GENMASK(15, 0)
++#define SGMII_LPA GENMASK(31, 16)
++
+ /* Register to programmable link timer, the unit in 2 * 8ns */
+ #define SGMSYS_PCS_LINK_TIMER 0x18
+-#define SGMII_LINK_TIMER_DEFAULT (0x186a0 & GENMASK(19, 0))
++#define SGMII_LINK_TIMER_MASK GENMASK(19, 0)
++#define SGMII_LINK_TIMER_DEFAULT (0x186a0 & SGMII_LINK_TIMER_MASK)
+
+ /* Register to control remote fault */
+ #define SGMSYS_SGMII_MODE 0x20
+-#define SGMII_IF_MODE_BIT0 BIT(0)
++#define SGMII_IF_MODE_SGMII BIT(0)
+ #define SGMII_SPEED_DUPLEX_AN BIT(1)
+ #define SGMII_SPEED_MASK GENMASK(3, 2)
+ #define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0)
+++ /dev/null
-From 9d32637122de88f1ef614c29703f0e050cad342e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
-Date: Wed, 1 Feb 2023 19:23:30 +0100
-Subject: [PATCH] net: mediatek: sgmii: fix duplex configuration
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The logic of the duplex bit is inverted. Setting it means half
-duplex, not full duplex.
-
-Fix and rename macro to avoid confusion.
-
-Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII")
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Bjørn Mork <bjorn@mork.no>
-Acked-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 +-
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 6 +++---
- 2 files changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -524,7 +524,7 @@
- #define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0)
- #define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1)
- #define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2)
--#define SGMII_DUPLEX_FULL BIT(4)
-+#define SGMII_DUPLEX_HALF BIT(4)
- #define SGMII_IF_MODE_BIT5 BIT(5)
- #define SGMII_REMOTE_FAULT_DIS BIT(8)
- #define SGMII_CODE_SYNC_SET_VAL BIT(9)
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -66,7 +66,7 @@ static int mtk_pcs_setup_mode_force(stru
-
- /* Set the speed etc but leave the duplex unchanged */
- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
-- val &= SGMII_DUPLEX_FULL | ~SGMII_IF_MODE_MASK;
-+ val &= SGMII_DUPLEX_HALF | ~SGMII_IF_MODE_MASK;
- val |= SGMII_SPEED_1000;
- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
-
-@@ -131,9 +131,10 @@ static void mtk_pcs_link_up(struct phyli
-
- /* SGMII force duplex setting */
- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
-- val &= ~SGMII_DUPLEX_FULL;
-- if (duplex == DUPLEX_FULL)
-- val |= SGMII_DUPLEX_FULL;
-+
-+ val &= ~SGMII_DUPLEX_HALF;
-+ if (duplex != DUPLEX_FULL)
-+ val |= SGMII_DUPLEX_HALF;
-
- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
- }
--- /dev/null
+From 5cf7797526ee81bea0f627bccaa3d887f48f53e0 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Thu, 27 Oct 2022 14:10:47 +0100
+Subject: [PATCH 02/10] net: mtk_eth_soc: eliminate unnecessary error handling
+
+The functions called by the pcs_config() method always return zero, so
+there is no point trying to handle an error from these functions. Make
+these functions void, eliminate the "err" variable and simply return
+zero from the pcs_config() function itself.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_sgmii.c | 18 ++++++------------
+ 1 file changed, 6 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -20,7 +20,7 @@ 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 void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
+ {
+ unsigned int val;
+
+@@ -39,16 +39,13 @@ static int mtk_pcs_setup_mode_an(struct
+ regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
+ val &= ~SGMII_PHYA_PWD;
+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
+-
+- return 0;
+-
+ }
+
+ /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
+ * fixed speed.
+ */
+-static int mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs,
+- phy_interface_t interface)
++static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs,
++ phy_interface_t interface)
+ {
+ unsigned int val;
+
+@@ -73,8 +70,6 @@ static int mtk_pcs_setup_mode_force(stru
+ regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
+ val &= ~SGMII_PHYA_PWD;
+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
+-
+- return 0;
+ }
+
+ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
+@@ -83,15 +78,14 @@ static int mtk_pcs_config(struct phylink
+ bool permit_pause_to_mac)
+ {
+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
+- int err = 0;
+
+ /* Setup SGMIISYS with the determined property */
+ if (interface != PHY_INTERFACE_MODE_SGMII)
+- err = mtk_pcs_setup_mode_force(mpcs, interface);
++ mtk_pcs_setup_mode_force(mpcs, interface);
+ else if (phylink_autoneg_inband(mode))
+- err = mtk_pcs_setup_mode_an(mpcs);
++ mtk_pcs_setup_mode_an(mpcs);
+
+- return err;
++ return 0;
+ }
+
+ static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
+++ /dev/null
-From 3337a6e04ddf2923a1bdcf3d31b3b52412bf82dd Mon Sep 17 00:00:00 2001
-From: Alexander Couzens <lynxis@fe80.eu>
-Date: Wed, 1 Feb 2023 19:23:31 +0100
-Subject: [PATCH] mtk_sgmii: enable PCS polling to allow SFP work
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Currently there is no IRQ handling (even the SGMII supports it).
-Enable polling to support SFP ports.
-
-Fixes: 14a44ab0330d ("net: mtk_eth_soc: partially convert to phylink_pcs")
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
-[ bmork: changed "1" => "true" ]
-Signed-off-by: Bjørn Mork <bjorn@mork.no>
-Acked-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- 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
-@@ -162,6 +162,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 = true;
- ss->pcs[i].interface = PHY_INTERFACE_MODE_NA;
- }
-
--- /dev/null
+From c000dca098002da193b98099df051c9ead0cacb4 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Thu, 27 Oct 2022 14:10:52 +0100
+Subject: [PATCH 03/10] net: mtk_eth_soc: add pcs_get_state() implementation
+
+Add a pcs_get_state() implementation which uses the advertisements
+to compute the resulting link modes, and BMSR contents to determine
+negotiation and link status.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.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
+@@ -19,6 +19,20 @@ static struct mtk_pcs *pcs_to_mtk_pcs(st
+ return container_of(pcs, struct mtk_pcs, pcs);
+ }
+
++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 bm, adv;
++
++ /* Read the BMSR and LPA */
++ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
++ regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
++
++ phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm),
++ FIELD_GET(SGMII_LPA, adv));
++}
++
+ /* For SGMII interface mode */
+ static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
+ {
+@@ -117,6 +131,7 @@ static void mtk_pcs_link_up(struct phyli
+ }
+
+ static const struct phylink_pcs_ops mtk_pcs_ops = {
++ .pcs_get_state = mtk_pcs_get_state,
+ .pcs_config = mtk_pcs_config,
+ .pcs_an_restart = mtk_pcs_restart_an,
+ .pcs_link_up = mtk_pcs_link_up,
--- /dev/null
+From 0d2351dc2768061689abd4de1529fa206bbd574e Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Thu, 27 Oct 2022 14:10:58 +0100
+Subject: [PATCH 04/10] net: mtk_eth_soc: convert mtk_sgmii to use
+ regmap_update_bits()
+
+mtk_sgmii does a lot of read-modify-write operations, for which there
+is a specific regmap function. Use this function instead of open-coding
+the operations.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_sgmii.c | 61 ++++++++++-------------
+ 1 file changed, 26 insertions(+), 35 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -36,23 +36,18 @@ static void mtk_pcs_get_state(struct phy
+ /* For SGMII interface mode */
+ static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
+ {
+- unsigned int val;
+-
+ /* Setup the link timer and QPHY power up inside SGMIISYS */
+ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
+ SGMII_LINK_TIMER_DEFAULT);
+
+- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
+- val |= SGMII_REMOTE_FAULT_DIS;
+- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
+-
+- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
+- 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_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
++ SGMII_REMOTE_FAULT_DIS, SGMII_REMOTE_FAULT_DIS);
++
++ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
++ SGMII_AN_RESTART, SGMII_AN_RESTART);
++
++ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
++ SGMII_PHYA_PWD, 0);
+ }
+
+ /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
+@@ -61,29 +56,26 @@ static void mtk_pcs_setup_mode_an(struct
+ static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs,
+ phy_interface_t interface)
+ {
+- unsigned int val;
++ unsigned int rgc3;
+
+- 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);
++ rgc3 = RG_PHY_SPEED_3_125G;
++
++ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
++ RG_PHY_SPEED_3_125G, rgc3);
+
+ /* Disable SGMII AN */
+- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
+- val &= ~SGMII_AN_ENABLE;
+- regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
++ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
++ SGMII_AN_ENABLE, 0);
+
+ /* Set the speed etc but leave the duplex unchanged */
+- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
+- val &= SGMII_DUPLEX_FULL | ~SGMII_IF_MODE_MASK;
+- val |= SGMII_SPEED_1000;
+- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
++ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
++ SGMII_IF_MODE_MASK & ~SGMII_DUPLEX_FULL,
++ SGMII_SPEED_1000);
+
+ /* 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_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
++ SGMII_PHYA_PWD, 0);
+ }
+
+ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
+@@ -105,29 +97,28 @@ static int mtk_pcs_config(struct phylink
+ static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
+ {
+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
+- unsigned int val;
+
+- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
+- val |= SGMII_AN_RESTART;
+- regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
++ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
++ SGMII_AN_RESTART, SGMII_AN_RESTART);
+ }
+
+ static void mtk_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
+ phy_interface_t interface, int speed, int duplex)
+ {
+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
+- unsigned int val;
++ unsigned int sgm_mode;
+
+ if (!phy_interface_mode_is_8023z(interface))
+ return;
+
+ /* SGMII force duplex setting */
+- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
+- val &= ~SGMII_DUPLEX_FULL;
+ if (duplex == DUPLEX_FULL)
+- val |= SGMII_DUPLEX_FULL;
++ sgm_mode = SGMII_DUPLEX_FULL;
++ else
++ sgm_mode = 0;
+
+- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
++ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
++ SGMII_DUPLEX_FULL, sgm_mode);
+ }
+
+ static const struct phylink_pcs_ops mtk_pcs_ops = {
--- /dev/null
+From 12198c3a410fe69843e335c1bbf6d4c2a4d48e4e Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Thu, 27 Oct 2022 14:11:03 +0100
+Subject: [PATCH 05/10] net: mtk_eth_soc: add out of band forcing of speed and
+ duplex in pcs_link_up
+
+Add support for forcing the link speed and duplex setting in the
+pcs_link_up() method for out of band modes, which will be useful when
+we finish converting the pcs_config() method. Until then, we still have
+to force duplex for 802.3z modes to work correctly.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_sgmii.c | 28 ++++++++++++++---------
+ 1 file changed, 17 insertions(+), 11 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -108,17 +108,23 @@ static void mtk_pcs_link_up(struct phyli
+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
+ unsigned int sgm_mode;
+
+- if (!phy_interface_mode_is_8023z(interface))
+- return;
++ if (!phylink_autoneg_inband(mode) ||
++ phy_interface_mode_is_8023z(interface)) {
++ /* Force the speed and duplex setting */
++ if (speed == SPEED_10)
++ sgm_mode = SGMII_SPEED_10;
++ else if (speed == SPEED_100)
++ sgm_mode = SGMII_SPEED_100;
++ else
++ sgm_mode = SGMII_SPEED_1000;
+
+- /* SGMII force duplex setting */
+- if (duplex == DUPLEX_FULL)
+- sgm_mode = SGMII_DUPLEX_FULL;
+- else
+- sgm_mode = 0;
++ if (duplex == DUPLEX_FULL)
++ sgm_mode |= SGMII_DUPLEX_FULL;
+
+- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
+- SGMII_DUPLEX_FULL, sgm_mode);
++ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
++ SGMII_DUPLEX_FULL | SGMII_SPEED_MASK,
++ sgm_mode);
++ }
+ }
+
+ static const struct phylink_pcs_ops mtk_pcs_ops = {
--- /dev/null
+From 6f38fffe2179dd29612aea2c67c46ed6682b4e46 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Thu, 27 Oct 2022 14:11:08 +0100
+Subject: [PATCH 06/10] net: mtk_eth_soc: move PHY power up
+
+The PHY power up is common to both configuration paths, so move it into
+the parent function. We need to do this for all serdes modes.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_sgmii.c | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -45,9 +45,6 @@ static void mtk_pcs_setup_mode_an(struct
+
+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
+ SGMII_AN_RESTART, SGMII_AN_RESTART);
+-
+- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
+- SGMII_PHYA_PWD, 0);
+ }
+
+ /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
+@@ -72,10 +69,6 @@ static void mtk_pcs_setup_mode_force(str
+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
+ SGMII_IF_MODE_MASK & ~SGMII_DUPLEX_FULL,
+ SGMII_SPEED_1000);
+-
+- /* Release PHYA power down state */
+- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
+- SGMII_PHYA_PWD, 0);
+ }
+
+ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
+@@ -91,6 +84,10 @@ static int mtk_pcs_config(struct phylink
+ else if (phylink_autoneg_inband(mode))
+ mtk_pcs_setup_mode_an(mpcs);
+
++ /* Release PHYA power down state */
++ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
++ SGMII_PHYA_PWD, 0);
++
+ return 0;
+ }
+
--- /dev/null
+From f752c0df13dfeb721c11d3debb79f08cf437344f Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Thu, 27 Oct 2022 14:11:13 +0100
+Subject: [PATCH 07/10] net: mtk_eth_soc: move interface speed selection
+
+Move the selection of the underlying interface speed to the pcs_config
+function, so we always program the interface speed.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_sgmii.c | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -53,14 +53,6 @@ static void mtk_pcs_setup_mode_an(struct
+ static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs,
+ phy_interface_t interface)
+ {
+- unsigned int rgc3;
+-
+- if (interface == PHY_INTERFACE_MODE_2500BASEX)
+- rgc3 = RG_PHY_SPEED_3_125G;
+-
+- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
+- RG_PHY_SPEED_3_125G, rgc3);
+-
+ /* Disable SGMII AN */
+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
+ SGMII_AN_ENABLE, 0);
+@@ -77,6 +69,16 @@ static int mtk_pcs_config(struct phylink
+ bool permit_pause_to_mac)
+ {
+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
++ unsigned int rgc3;
++
++ if (interface == PHY_INTERFACE_MODE_2500BASEX)
++ rgc3 = RG_PHY_SPEED_3_125G;
++ else
++ rgc3 = 0;
++
++ /* Configure the underlying interface speed */
++ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
++ RG_PHY_SPEED_3_125G, rgc3);
+
+ /* Setup SGMIISYS with the determined property */
+ if (interface != PHY_INTERFACE_MODE_SGMII)
--- /dev/null
+From c125c66ea71b9377ae2478c4f1b87b180cc5c6ef Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Thu, 27 Oct 2022 14:11:18 +0100
+Subject: [PATCH 08/10] net: mtk_eth_soc: add advertisement programming
+
+Program the advertisement into the mtk PCS block.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_sgmii.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -70,16 +70,27 @@ static int mtk_pcs_config(struct phylink
+ {
+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
+ unsigned int rgc3;
++ int advertise;
++ bool changed;
+
+ if (interface == PHY_INTERFACE_MODE_2500BASEX)
+ rgc3 = RG_PHY_SPEED_3_125G;
+ else
+ rgc3 = 0;
+
++ advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
++ advertising);
++ if (advertise < 0)
++ return advertise;
++
+ /* Configure the underlying interface speed */
+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
+ RG_PHY_SPEED_3_125G, rgc3);
+
++ /* Update the advertisement, noting whether it has changed */
++ regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
++ SGMII_ADVERTISE, advertise, &changed);
++
+ /* Setup SGMIISYS with the determined property */
+ if (interface != PHY_INTERFACE_MODE_SGMII)
+ mtk_pcs_setup_mode_force(mpcs, interface);
+@@ -90,7 +101,7 @@ static int mtk_pcs_config(struct phylink
+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
+ SGMII_PHYA_PWD, 0);
+
+- return 0;
++ return changed;
+ }
+
+ static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
--- /dev/null
+From 3027d89f87707e7f3e5b683e0d37a32afb5bde96 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Thu, 27 Oct 2022 14:11:23 +0100
+Subject: [PATCH 09/10] net: mtk_eth_soc: move and correct link timer
+ programming
+
+Program the link timer appropriately for the interface mode being
+used, using the newly introduced phylink helper that provides the
+nanosecond link timer interval.
+
+The intervals are 1.6ms for SGMII based protocols and 10ms for
+802.3z based protocols.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_sgmii.c | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -36,10 +36,6 @@ static void mtk_pcs_get_state(struct phy
+ /* For SGMII interface mode */
+ static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
+ {
+- /* Setup the link timer and QPHY power up inside SGMIISYS */
+- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
+- SGMII_LINK_TIMER_DEFAULT);
+-
+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
+ SGMII_REMOTE_FAULT_DIS, SGMII_REMOTE_FAULT_DIS);
+
+@@ -69,8 +65,8 @@ static int mtk_pcs_config(struct phylink
+ bool permit_pause_to_mac)
+ {
+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
++ int advertise, link_timer;
+ unsigned int rgc3;
+- int advertise;
+ bool changed;
+
+ if (interface == PHY_INTERFACE_MODE_2500BASEX)
+@@ -83,6 +79,10 @@ static int mtk_pcs_config(struct phylink
+ if (advertise < 0)
+ return advertise;
+
++ link_timer = phylink_get_link_timer_ns(interface);
++ if (link_timer < 0)
++ return link_timer;
++
+ /* Configure the underlying interface speed */
+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
+ RG_PHY_SPEED_3_125G, rgc3);
+@@ -91,6 +91,9 @@ static int mtk_pcs_config(struct phylink
+ regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
+ SGMII_ADVERTISE, advertise, &changed);
+
++ /* Setup the link timer and QPHY power up inside SGMIISYS */
++ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
++
+ /* Setup SGMIISYS with the determined property */
+ if (interface != PHY_INTERFACE_MODE_SGMII)
+ mtk_pcs_setup_mode_force(mpcs, interface);
--- /dev/null
+From 81b0f12a2a8a1699a7d49c3995e5f71e4ec018e6 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Thu, 27 Oct 2022 14:11:28 +0100
+Subject: [PATCH 10/10] net: mtk_eth_soc: add support for in-band 802.3z
+ negotiation
+
+As a result of help from Frank Wunderlich to investigate and test, we
+now know how to program this PCS for in-band 802.3z negotiation. Add
+support for this by moving the contents of the two functions into the
+common mtk_pcs_config() function and adding the register settings for
+802.3z negotiation.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_sgmii.c | 77 ++++++++++++-----------
+ 1 file changed, 42 insertions(+), 35 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -33,41 +33,15 @@ static void mtk_pcs_get_state(struct phy
+ FIELD_GET(SGMII_LPA, adv));
+ }
+
+-/* For SGMII interface mode */
+-static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
+-{
+- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
+- SGMII_REMOTE_FAULT_DIS, SGMII_REMOTE_FAULT_DIS);
+-
+- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
+- SGMII_AN_RESTART, SGMII_AN_RESTART);
+-}
+-
+-/* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
+- * fixed speed.
+- */
+-static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs,
+- phy_interface_t interface)
+-{
+- /* Disable SGMII AN */
+- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
+- SGMII_AN_ENABLE, 0);
+-
+- /* Set the speed etc but leave the duplex unchanged */
+- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
+- SGMII_IF_MODE_MASK & ~SGMII_DUPLEX_FULL,
+- SGMII_SPEED_1000);
+-}
+-
+ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
+ phy_interface_t interface,
+ const unsigned long *advertising,
+ bool permit_pause_to_mac)
+ {
+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
++ unsigned int rgc3, sgm_mode, bmcr;
+ int advertise, link_timer;
+- unsigned int rgc3;
+- bool changed;
++ bool changed, use_an;
+
+ if (interface == PHY_INTERFACE_MODE_2500BASEX)
+ rgc3 = RG_PHY_SPEED_3_125G;
+@@ -83,6 +57,37 @@ static int mtk_pcs_config(struct phylink
+ if (link_timer < 0)
+ return link_timer;
+
++ /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
++ * we assume that fixes it's speed at bitrate = line rate (in
++ * other words, 1000Mbps or 2500Mbps).
++ */
++ if (interface == PHY_INTERFACE_MODE_SGMII) {
++ sgm_mode = SGMII_IF_MODE_SGMII;
++ if (phylink_autoneg_inband(mode)) {
++ sgm_mode |= SGMII_REMOTE_FAULT_DIS |
++ SGMII_SPEED_DUPLEX_AN;
++ use_an = true;
++ } else {
++ use_an = false;
++ }
++ } else if (phylink_autoneg_inband(mode)) {
++ /* 1000base-X or 2500base-X autoneg */
++ sgm_mode = SGMII_REMOTE_FAULT_DIS;
++ use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
++ advertising);
++ } else {
++ /* 1000base-X or 2500base-X without autoneg */
++ sgm_mode = 0;
++ use_an = false;
++ }
++
++ if (use_an) {
++ /* FIXME: Do we need to set AN_RESTART here? */
++ bmcr = SGMII_AN_RESTART | SGMII_AN_ENABLE;
++ } else {
++ bmcr = 0;
++ }
++
+ /* Configure the underlying interface speed */
+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
+ RG_PHY_SPEED_3_125G, rgc3);
+@@ -94,11 +99,14 @@ static int mtk_pcs_config(struct phylink
+ /* Setup the link timer and QPHY power up inside SGMIISYS */
+ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
+
+- /* Setup SGMIISYS with the determined property */
+- if (interface != PHY_INTERFACE_MODE_SGMII)
+- mtk_pcs_setup_mode_force(mpcs, interface);
+- else if (phylink_autoneg_inband(mode))
+- mtk_pcs_setup_mode_an(mpcs);
++ /* Update the sgmsys mode register */
++ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
++ SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
++ SGMII_IF_MODE_SGMII, sgm_mode);
++
++ /* Update the BMCR */
++ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
++ SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr);
+
+ /* Release PHYA power down state */
+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
+@@ -121,8 +129,7 @@ static void mtk_pcs_link_up(struct phyli
+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
+ unsigned int sgm_mode;
+
+- if (!phylink_autoneg_inband(mode) ||
+- phy_interface_mode_is_8023z(interface)) {
++ if (!phylink_autoneg_inband(mode)) {
+ /* Force the speed and duplex setting */
+ if (speed == SPEED_10)
+ sgm_mode = SGMII_SPEED_10;
--- /dev/null
+From 7ff82416de8295c61423ef6fd75f052d3837d2f7 Mon Sep 17 00:00:00 2001
+From: Alexander Couzens <lynxis@fe80.eu>
+Date: Wed, 1 Feb 2023 19:23:29 +0100
+Subject: [PATCH 11/13] net: mediatek: sgmii: ensure the SGMII PHY is powered
+ down on configuration
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The code expect the PHY to be in power down which is only true after reset.
+Allow changes of the SGMII parameters more than once.
+
+Only power down when reconfiguring to avoid bouncing the link when there's
+no reason to - based on code from Russell King.
+
+There are cases when the SGMII_PHYA_PWD register contains 0x9 which
+prevents SGMII from working. The SGMII still shows link but no traffic
+can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was
+taken from a good working state of the SGMII interface.
+
+Fixes: 42c03844e93d ("net-next: mediatek: add support for MediaTek MT7622 SoC")
+Suggested-by: Russell King (Oracle) <linux@armlinux.org.uk>
+Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
+[ bmork: rebased and squashed into one patch ]
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Acked-by: Daniel Golle <daniel@makrotopia.org>
+Tested-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 ++
+ drivers/net/ethernet/mediatek/mtk_sgmii.c | 39 +++++++++++++++------
+ 2 files changed, 30 insertions(+), 11 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -1070,11 +1070,13 @@ struct mtk_soc_data {
+ * @regmap: The register map pointing at the range used to setup
+ * SGMII modes
+ * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap
++ * @interface: Currently configured interface mode
+ * @pcs: Phylink PCS structure
+ */
+ struct mtk_pcs {
+ struct regmap *regmap;
+ u32 ana_rgc3;
++ phy_interface_t interface;
+ struct phylink_pcs pcs;
+ };
+
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -43,11 +43,6 @@ static int mtk_pcs_config(struct phylink
+ int advertise, link_timer;
+ bool changed, use_an;
+
+- if (interface == PHY_INTERFACE_MODE_2500BASEX)
+- rgc3 = RG_PHY_SPEED_3_125G;
+- else
+- rgc3 = 0;
+-
+ advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
+ advertising);
+ if (advertise < 0)
+@@ -88,9 +83,22 @@ static int mtk_pcs_config(struct phylink
+ bmcr = 0;
+ }
+
+- /* Configure the underlying interface speed */
+- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
+- RG_PHY_SPEED_3_125G, rgc3);
++ if (mpcs->interface != interface) {
++ /* PHYA power down */
++ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
++ SGMII_PHYA_PWD, SGMII_PHYA_PWD);
++
++ if (interface == PHY_INTERFACE_MODE_2500BASEX)
++ rgc3 = RG_PHY_SPEED_3_125G;
++ else
++ rgc3 = 0;
++
++ /* Configure the underlying interface speed */
++ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
++ RG_PHY_SPEED_3_125G, rgc3);
++
++ mpcs->interface = interface;
++ }
+
+ /* Update the advertisement, noting whether it has changed */
+ regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
+@@ -108,9 +116,17 @@ static int mtk_pcs_config(struct phylink
+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
+ SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr);
+
+- /* Release PHYA power down state */
+- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
+- SGMII_PHYA_PWD, 0);
++ /* Release PHYA power down state
++ * Only removing bit SGMII_PHYA_PWD isn't enough.
++ * There are cases when the SGMII_PHYA_PWD register contains 0x9 which
++ * prevents SGMII from working. The SGMII still shows link but no traffic
++ * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was
++ * taken from a good working state of the SGMII interface.
++ * Unknown how much the QPHY needs but it is racy without a sleep.
++ * Tested on mt7622 & mt7986.
++ */
++ usleep_range(50, 100);
++ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
+
+ return changed;
+ }
+@@ -171,6 +187,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].interface = PHY_INTERFACE_MODE_NA;
+ }
+
+ return 0;
--- /dev/null
+From 9d32637122de88f1ef614c29703f0e050cad342e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
+Date: Wed, 1 Feb 2023 19:23:30 +0100
+Subject: [PATCH 12/13] net: mediatek: sgmii: fix duplex configuration
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The logic of the duplex bit is inverted. Setting it means half
+duplex, not full duplex.
+
+Fix and rename macro to avoid confusion.
+
+Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII")
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Acked-by: Daniel Golle <daniel@makrotopia.org>
+Tested-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 +-
+ drivers/net/ethernet/mediatek/mtk_sgmii.c | 6 +++---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -531,7 +531,7 @@
+ #define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0)
+ #define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1)
+ #define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2)
+-#define SGMII_DUPLEX_FULL BIT(4)
++#define SGMII_DUPLEX_HALF BIT(4)
+ #define SGMII_IF_MODE_BIT5 BIT(5)
+ #define SGMII_REMOTE_FAULT_DIS BIT(8)
+ #define SGMII_CODE_SYNC_SET_VAL BIT(9)
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -154,11 +154,11 @@ static void mtk_pcs_link_up(struct phyli
+ else
+ sgm_mode = SGMII_SPEED_1000;
+
+- if (duplex == DUPLEX_FULL)
+- sgm_mode |= SGMII_DUPLEX_FULL;
++ if (duplex != DUPLEX_FULL)
++ sgm_mode |= SGMII_DUPLEX_HALF;
+
+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
+- SGMII_DUPLEX_FULL | SGMII_SPEED_MASK,
++ SGMII_DUPLEX_HALF | SGMII_SPEED_MASK,
+ sgm_mode);
+ }
+ }
--- /dev/null
+From 3337a6e04ddf2923a1bdcf3d31b3b52412bf82dd Mon Sep 17 00:00:00 2001
+From: Alexander Couzens <lynxis@fe80.eu>
+Date: Wed, 1 Feb 2023 19:23:31 +0100
+Subject: [PATCH 13/13] mtk_sgmii: enable PCS polling to allow SFP work
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Currently there is no IRQ handling (even the SGMII supports it).
+Enable polling to support SFP ports.
+
+Fixes: 14a44ab0330d ("net: mtk_eth_soc: partially convert to phylink_pcs")
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
+[ bmork: changed "1" => "true" ]
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Acked-by: Daniel Golle <daniel@makrotopia.org>
+Tested-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ 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
+@@ -187,6 +187,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 = true;
+ ss->pcs[i].interface = PHY_INTERFACE_MODE_NA;
+ }
+
--- /dev/null
+From 611e2dabb4b3243d176739fd6a5a34d007fa3f86 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 14 Mar 2023 00:34:26 +0000
+Subject: [PATCH 1/2] net: ethernet: mtk_eth_soc: reset PCS state
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Reset the internal PCS state machine when changing interface mode.
+This prevents confusing the state machine when changing interface
+modes, e.g. from SGMII to 2500Base-X or vice-versa.
+
+Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII")
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Tested-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++++
+ drivers/net/ethernet/mediatek/mtk_sgmii.c | 4 ++++
+ 2 files changed, 8 insertions(+)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -539,6 +539,10 @@
+ #define SGMII_SEND_AN_ERROR_EN BIT(11)
+ #define SGMII_IF_MODE_MASK GENMASK(5, 1)
+
++/* Register to reset SGMII design */
++#define SGMII_RESERVED_0 0x34
++#define SGMII_SW_RESET BIT(0)
++
+ /* Register to set SGMII speed, ANA RG_ Control Signals III*/
+ #define SGMSYS_ANA_RG_CS3 0x2028
+ #define RG_PHY_SPEED_MASK (BIT(2) | BIT(3))
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -88,6 +88,10 @@ static int mtk_pcs_config(struct phylink
+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
+ SGMII_PHYA_PWD, SGMII_PHYA_PWD);
+
++ /* Reset SGMII PCS state */
++ regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0,
++ SGMII_SW_RESET, SGMII_SW_RESET);
++
+ if (interface == PHY_INTERFACE_MODE_2500BASEX)
+ rgc3 = RG_PHY_SPEED_3_125G;
+ else
--- /dev/null
+From 6e933a804c7db8be64f367f33e63cd7dcc302ebb Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 14 Mar 2023 00:34:45 +0000
+Subject: [PATCH 2/2] net: ethernet: mtk_eth_soc: only write values if needed
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Only restart auto-negotiation and write link timer if actually
+necessary. This prevents losing the link in case of minor
+changes.
+
+Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII")
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Tested-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/mediatek/mtk_sgmii.c | 24 +++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -38,20 +38,16 @@ static int mtk_pcs_config(struct phylink
+ const unsigned long *advertising,
+ bool permit_pause_to_mac)
+ {
++ bool mode_changed = false, changed, use_an;
+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
+ unsigned int rgc3, sgm_mode, bmcr;
+ int advertise, link_timer;
+- bool changed, use_an;
+
+ advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
+ advertising);
+ if (advertise < 0)
+ return advertise;
+
+- link_timer = phylink_get_link_timer_ns(interface);
+- if (link_timer < 0)
+- return link_timer;
+-
+ /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
+ * we assume that fixes it's speed at bitrate = line rate (in
+ * other words, 1000Mbps or 2500Mbps).
+@@ -77,13 +73,16 @@ static int mtk_pcs_config(struct phylink
+ }
+
+ if (use_an) {
+- /* FIXME: Do we need to set AN_RESTART here? */
+- bmcr = SGMII_AN_RESTART | SGMII_AN_ENABLE;
++ bmcr = SGMII_AN_ENABLE;
+ } else {
+ bmcr = 0;
+ }
+
+ if (mpcs->interface != interface) {
++ link_timer = phylink_get_link_timer_ns(interface);
++ if (link_timer < 0)
++ return link_timer;
++
+ /* PHYA power down */
+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
+ SGMII_PHYA_PWD, SGMII_PHYA_PWD);
+@@ -101,16 +100,17 @@ static int mtk_pcs_config(struct phylink
+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
+ RG_PHY_SPEED_3_125G, rgc3);
+
++ /* Setup the link timer */
++ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
++
+ mpcs->interface = interface;
++ mode_changed = true;
+ }
+
+ /* Update the advertisement, noting whether it has changed */
+ regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
+ SGMII_ADVERTISE, advertise, &changed);
+
+- /* Setup the link timer and QPHY power up inside SGMIISYS */
+- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
+-
+ /* Update the sgmsys mode register */
+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
+ SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
+@@ -118,7 +118,7 @@ static int mtk_pcs_config(struct phylink
+
+ /* Update the BMCR */
+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
+- SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr);
++ SGMII_AN_ENABLE, bmcr);
+
+ /* Release PHYA power down state
+ * Only removing bit SGMII_PHYA_PWD isn't enough.
+@@ -132,7 +132,7 @@ static int mtk_pcs_config(struct phylink
+ usleep_range(50, 100);
+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
+
+- return changed;
++ return changed || mode_changed;
+ }
+
+ static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
+++ /dev/null
-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
-@@ -139,10 +139,28 @@ 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, SGMSYS_PCS_CONTROL_1, &val);
-+ state->an_complete = !!(val & SGMII_AN_COMPLETE);
-+ state->link = !!(val & SGMII_LINK_STATYS);
-+ if (!state->link)
-+ return;
-+
-+ regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val);
-+ state->speed = val & RG_PHY_SPEED_3_125G ? SPEED_2500 : SPEED_1000;
-+ 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)
+++ /dev/null
-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);
-
-
+++ /dev/null
-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
-@@ -20,12 +20,14 @@ 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;
-
- 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 */
-@@ -94,7 +96,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);
-
- /* Release PHYA power down state
- * Only removing bit SGMII_PHYA_PWD isn't enough.
+++ /dev/null
-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
-@@ -67,7 +67,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_HALF | ~SGMII_IF_MODE_MASK;
- val |= SGMII_SPEED_1000;
.rxd_size = sizeof(struct mtk_rx_dma_v2),
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1026,6 +1026,8 @@ struct mtk_reg_map {
+@@ -1037,6 +1037,8 @@ struct mtk_reg_map {
* the extra setup for those pins used by GMAC.
* @hash_offset Flow table hash offset.
* @foe_entry_size Foe table entry size.
* @txd_size Tx DMA descriptor size.
* @rxd_size Rx DMA descriptor size.
* @rx_irq_done_mask Rx irq done register mask.
-@@ -1043,6 +1045,7 @@ struct mtk_soc_data {
+@@ -1054,6 +1056,7 @@ struct mtk_soc_data {
u8 hash_offset;
u16 foe_entry_size;
netdev_features_t hw_features;
+++ /dev/null
-From b66105968b8c37c26a75b9da9281cbc1c8f73594 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 22 Jan 2023 23:58:36 +0000
-Subject: [PATCH] net: ethernet: mtk_eth_soc: reset PCS state
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Reset PCS state when changing interface mode.
-
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Tested-by: Bjørn Mork <bjorn@mork.no>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++++
- drivers/net/ethernet/mediatek/mtk_sgmii.c | 4 ++++
- 2 files changed, 8 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -530,6 +530,10 @@
- #define SGMII_SEND_AN_ERROR_EN BIT(11)
- #define SGMII_IF_MODE_MASK GENMASK(5, 1)
-
-+/* Register to reset SGMII design */
-+#define SGMII_RESERVED_0 0x34
-+#define SGMII_SW_RESET BIT(0)
-+
- /* Register to set SGMII speed, ANA RG_ Control Signals III*/
- #define SGMSYS_ANA_RG_CS3 0x2028
- #define RG_PHY_SPEED_MASK (BIT(2) | BIT(3))
---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
-+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
-@@ -90,6 +90,10 @@ static int mtk_pcs_config(struct phylink
- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
- SGMII_PHYA_PWD, SGMII_PHYA_PWD);
-
-+ /* Reset SGMII PCS state */
-+ regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0,
-+ SGMII_SW_RESET, SGMII_SW_RESET);
-+
- mpcs->interface = interface;
- }
-
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1319,6 +1319,9 @@ int mtk_gmac_rgmii_path_setup(struct mtk
+@@ -1326,6 +1326,9 @@ int mtk_gmac_rgmii_path_setup(struct mtk
int mtk_eth_offload_init(struct mtk_eth *eth);
int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
void *type_data);