+++ /dev/null
-From 626cdca5b68acdc72d2533e2ed2306c06f296725 Mon Sep 17 00:00:00 2001
-From: Weijie Gao <weijie.gao@mediatek.com>
-Date: Fri, 10 Jan 2025 16:41:13 +0800
-Subject: [PATCH 1/3] net: mediatek: split ethernet switch code from mtk_eth.c
-
-mtk_eth.c contains not only the ethernet GMAC/DMA driver, but also
-some ethernet switch initialization code. As we may add more switch
-support in the future, it's better to move them out of mtk_eth.c to
-avoid increasing the code complexity.
-
-Since not all switches are supported for a particular board, Kconfig
-options are added to allow user to select which switch should be
-built into u-boot. If multiple switches are selected, auto-detecting
-can also be enabled.
-
-Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
----
- drivers/net/Kconfig | 21 +-
- drivers/net/Makefile | 2 +-
- drivers/net/mtk_eth/Kconfig | 35 +
- drivers/net/mtk_eth/Makefile | 9 +
- drivers/net/mtk_eth/mt7530.c | 281 ++++++++
- drivers/net/mtk_eth/mt7531.c | 293 +++++++++
- drivers/net/mtk_eth/mt753x.c | 262 ++++++++
- drivers/net/mtk_eth/mt753x.h | 286 ++++++++
- drivers/net/mtk_eth/mt7988.c | 160 +++++
- drivers/net/{ => mtk_eth}/mtk_eth.c | 971 ++++------------------------
- drivers/net/{ => mtk_eth}/mtk_eth.h | 301 ++-------
- 11 files changed, 1520 insertions(+), 1101 deletions(-)
- create mode 100644 drivers/net/mtk_eth/Kconfig
- create mode 100644 drivers/net/mtk_eth/Makefile
- create mode 100644 drivers/net/mtk_eth/mt7530.c
- create mode 100644 drivers/net/mtk_eth/mt7531.c
- create mode 100644 drivers/net/mtk_eth/mt753x.c
- create mode 100644 drivers/net/mtk_eth/mt753x.h
- create mode 100644 drivers/net/mtk_eth/mt7988.c
- rename drivers/net/{ => mtk_eth}/mtk_eth.c (62%)
- rename drivers/net/{ => mtk_eth}/mtk_eth.h (59%)
-
---- a/drivers/net/Kconfig
-+++ b/drivers/net/Kconfig
-@@ -966,26 +966,7 @@ config TSEC_ENET
- This driver implements support for the (Enhanced) Three-Speed
- Ethernet Controller found on Freescale SoCs.
-
--config MEDIATEK_ETH
-- bool "MediaTek Ethernet GMAC Driver"
-- select PHYLIB
-- select DM_GPIO
-- select DM_RESET
-- help
-- This Driver support MediaTek Ethernet GMAC
-- Say Y to enable support for the MediaTek Ethernet GMAC.
--
--if MEDIATEK_ETH
--
--config MTK_ETH_SGMII
-- bool
-- default y if ARCH_MEDIATEK && !TARGET_MT7623
--
--config MTK_ETH_XGMII
-- bool
-- default y if TARGET_MT7987 || TARGET_MT7988
--
--endif # MEDIATEK_ETH
-+source "drivers/net/mtk_eth/Kconfig"
-
- config HIFEMAC_ETH
- bool "HiSilicon Fast Ethernet Controller"
---- a/drivers/net/Makefile
-+++ b/drivers/net/Makefile
-@@ -67,7 +67,7 @@ obj-$(CONFIG_MDIO_MUX_MESON_GXL) += mdio
- obj-$(CONFIG_MDIO_MUX_MMIOREG) += mdio_mux_mmioreg.o
- obj-$(CONFIG_MDIO_MUX_SANDBOX) += mdio_mux_sandbox.o
- obj-$(CONFIG_MDIO_SANDBOX) += mdio_sandbox.o
--obj-$(CONFIG_MEDIATEK_ETH) += mtk_eth.o
-+obj-$(CONFIG_MEDIATEK_ETH) += mtk_eth/
- obj-$(CONFIG_MPC8XX_FEC) += mpc8xx_fec.o
- obj-$(CONFIG_MT7620_ETH) += mt7620-eth.o
- obj-$(CONFIG_MT7628_ETH) += mt7628-eth.o
---- /dev/null
-+++ b/drivers/net/mtk_eth/Kconfig
-@@ -0,0 +1,35 @@
-+
-+config MEDIATEK_ETH
-+ bool "MediaTek Ethernet GMAC Driver"
-+ select PHYLIB
-+ select DM_GPIO
-+ select DM_RESET
-+ help
-+ This Driver support MediaTek Ethernet GMAC
-+ Say Y to enable support for the MediaTek Ethernet GMAC.
-+
-+if MEDIATEK_ETH
-+
-+config MTK_ETH_SGMII
-+ bool
-+ default y if ARCH_MEDIATEK && !TARGET_MT7623
-+
-+config MTK_ETH_XGMII
-+ bool
-+ default y if TARGET_MT7988
-+
-+config MTK_ETH_SWITCH_MT7530
-+ bool "Support for MediaTek MT7530 ethernet switch"
-+ default y if TARGET_MT7623 || SOC_MT7621
-+
-+config MTK_ETH_SWITCH_MT7531
-+ bool "Support for MediaTek MT7531 ethernet switch"
-+ default y if TARGET_MT7622 || TARGET_MT7629 || TARGET_MT7981 || \
-+ TARGET_MT7986
-+
-+config MTK_ETH_SWITCH_MT7988
-+ bool "Support for MediaTek MT7988 built-in ethernet switch"
-+ depends on TARGET_MT7988
-+ default y
-+
-+endif # MEDIATEK_ETH
---- /dev/null
-+++ b/drivers/net/mtk_eth/Makefile
-@@ -0,0 +1,9 @@
-+# SPDX-License-Identifier: GPL-2.0+
-+#
-+# Copyright (C) 2025 MediaTek Inc.
-+# Author: Weijie Gao <weijie.gao@mediatek.com>
-+
-+obj-y += mtk_eth.o
-+obj-$(CONFIG_MTK_ETH_SWITCH_MT7530) += mt753x.o mt7530.o
-+obj-$(CONFIG_MTK_ETH_SWITCH_MT7531) += mt753x.o mt7531.o
-+obj-$(CONFIG_MTK_ETH_SWITCH_MT7988) += mt753x.o mt7988.o
---- /dev/null
-+++ b/drivers/net/mtk_eth/mt7530.c
-@@ -0,0 +1,281 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (C) 2025 MediaTek Inc.
-+ *
-+ * Author: Weijie Gao <weijie.gao@mediatek.com>
-+ * Author: Mark Lee <mark-mc.lee@mediatek.com>
-+ */
-+
-+#include <miiphy.h>
-+#include <linux/delay.h>
-+#include <linux/mdio.h>
-+#include <linux/mii.h>
-+#include "mtk_eth.h"
-+#include "mt753x.h"
-+
-+#define CHIP_REV 0x7ffc
-+#define CHIP_NAME_S 16
-+#define CHIP_NAME_M 0xffff0000
-+#define CHIP_REV_S 0
-+#define CHIP_REV_M 0x0f
-+
-+static void mt7530_core_reg_write(struct mt753x_switch_priv *priv, u32 reg,
-+ u32 val)
-+{
-+ u8 phy_addr = MT753X_PHY_ADDR(priv->phy_base, 0);
-+
-+ mtk_mmd_ind_write(priv->epriv.eth, phy_addr, 0x1f, reg, val);
-+}
-+
-+static int mt7530_pad_clk_setup(struct mt753x_switch_priv *priv, int mode)
-+{
-+ u32 ncpo1, ssc_delta;
-+
-+ switch (mode) {
-+ case PHY_INTERFACE_MODE_RGMII:
-+ ncpo1 = 0x0c80;
-+ ssc_delta = 0x87;
-+ break;
-+
-+ default:
-+ printf("error: xMII mode %d is not supported\n", mode);
-+ return -EINVAL;
-+ }
-+
-+ /* Disable MT7530 core clock */
-+ mt7530_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG, 0);
-+
-+ /* Disable MT7530 PLL */
-+ mt7530_core_reg_write(priv, CORE_GSWPLL_GRP1,
-+ (2 << RG_GSWPLL_POSDIV_200M_S) |
-+ (32 << RG_GSWPLL_FBKDIV_200M_S));
-+
-+ /* For MT7530 core clock = 500Mhz */
-+ mt7530_core_reg_write(priv, CORE_GSWPLL_GRP2,
-+ (1 << RG_GSWPLL_POSDIV_500M_S) |
-+ (25 << RG_GSWPLL_FBKDIV_500M_S));
-+
-+ /* Enable MT7530 PLL */
-+ mt7530_core_reg_write(priv, CORE_GSWPLL_GRP1,
-+ (2 << RG_GSWPLL_POSDIV_200M_S) |
-+ (32 << RG_GSWPLL_FBKDIV_200M_S) |
-+ RG_GSWPLL_EN_PRE);
-+
-+ udelay(20);
-+
-+ mt7530_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
-+
-+ /* Setup the MT7530 TRGMII Tx Clock */
-+ mt7530_core_reg_write(priv, CORE_PLL_GROUP5, ncpo1);
-+ mt7530_core_reg_write(priv, CORE_PLL_GROUP6, 0);
-+ mt7530_core_reg_write(priv, CORE_PLL_GROUP10, ssc_delta);
-+ mt7530_core_reg_write(priv, CORE_PLL_GROUP11, ssc_delta);
-+ mt7530_core_reg_write(priv, CORE_PLL_GROUP4, RG_SYSPLL_DDSFBK_EN |
-+ RG_SYSPLL_BIAS_EN | RG_SYSPLL_BIAS_LPF_EN);
-+
-+ mt7530_core_reg_write(priv, CORE_PLL_GROUP2,
-+ RG_SYSPLL_EN_NORMAL | RG_SYSPLL_VODEN |
-+ (1 << RG_SYSPLL_POSDIV_S));
-+
-+ mt7530_core_reg_write(priv, CORE_PLL_GROUP7,
-+ RG_LCDDS_PCW_NCPO_CHG | (3 << RG_LCCDS_C_S) |
-+ RG_LCDDS_PWDB | RG_LCDDS_ISO_EN);
-+
-+ /* Enable MT7530 core clock */
-+ mt7530_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG,
-+ REG_GSWCK_EN | REG_TRGMIICK_EN);
-+
-+ return 0;
-+}
-+
-+static void mt7530_mac_control(struct mtk_eth_switch_priv *swpriv, bool enable)
-+{
-+ struct mt753x_switch_priv *priv = (struct mt753x_switch_priv *)swpriv;
-+ u32 pmcr = FORCE_MODE;
-+
-+ if (enable)
-+ pmcr = priv->pmcr;
-+
-+ mt753x_reg_write(priv, PMCR_REG(6), pmcr);
-+}
-+
-+static int mt7530_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
-+{
-+ struct mt753x_switch_priv *priv = bus->priv;
-+
-+ if (devad < 0)
-+ return mtk_mii_read(priv->epriv.eth, addr, reg);
-+
-+ return mtk_mmd_ind_read(priv->epriv.eth, addr, devad, reg);
-+}
-+
-+static int mt7530_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
-+ u16 val)
-+{
-+ struct mt753x_switch_priv *priv = bus->priv;
-+
-+ if (devad < 0)
-+ return mtk_mii_write(priv->epriv.eth, addr, reg, val);
-+
-+ return mtk_mmd_ind_write(priv->epriv.eth, addr, devad, reg, val);
-+}
-+
-+static int mt7530_mdio_register(struct mt753x_switch_priv *priv)
-+{
-+ struct mii_dev *mdio_bus = mdio_alloc();
-+ int ret;
-+
-+ if (!mdio_bus)
-+ return -ENOMEM;
-+
-+ mdio_bus->read = mt7530_mdio_read;
-+ mdio_bus->write = mt7530_mdio_write;
-+ snprintf(mdio_bus->name, sizeof(mdio_bus->name), priv->epriv.sw->name);
-+
-+ mdio_bus->priv = priv;
-+
-+ ret = mdio_register(mdio_bus);
-+ if (ret) {
-+ mdio_free(mdio_bus);
-+ return ret;
-+ }
-+
-+ priv->mdio_bus = mdio_bus;
-+
-+ return 0;
-+}
-+
-+static int mt7530_setup(struct mtk_eth_switch_priv *swpriv)
-+{
-+ struct mt753x_switch_priv *priv = (struct mt753x_switch_priv *)swpriv;
-+ u16 phy_addr, phy_val;
-+ u32 i, val, txdrv;
-+
-+ priv->smi_addr = MT753X_DFL_SMI_ADDR;
-+ priv->reg_read = mt753x_mdio_reg_read;
-+ priv->reg_write = mt753x_mdio_reg_write;
-+
-+ if (!MTK_HAS_CAPS(priv->epriv.soc->caps, MTK_TRGMII_MT7621_CLK)) {
-+ /* Select 250MHz clk for RGMII mode */
-+ mtk_ethsys_rmw(priv->epriv.eth, ETHSYS_CLKCFG0_REG,
-+ ETHSYS_TRGMII_CLK_SEL362_5, 0);
-+
-+ txdrv = 8;
-+ } else {
-+ txdrv = 4;
-+ }
-+
-+ /* Modify HWTRAP first to allow direct access to internal PHYs */
-+ mt753x_reg_read(priv, HWTRAP_REG, &val);
-+ val |= CHG_TRAP;
-+ val &= ~C_MDIO_BPS;
-+ mt753x_reg_write(priv, MHWTRAP_REG, val);
-+
-+ /* Calculate the phy base address */
-+ val = ((val & SMI_ADDR_M) >> SMI_ADDR_S) << 3;
-+ priv->phy_base = (val | 0x7) + 1;
-+
-+ /* Turn off PHYs */
-+ for (i = 0; i < MT753X_NUM_PHYS; i++) {
-+ phy_addr = MT753X_PHY_ADDR(priv->phy_base, i);
-+ phy_val = mtk_mii_read(priv->epriv.eth, phy_addr, MII_BMCR);
-+ phy_val |= BMCR_PDOWN;
-+ mtk_mii_write(priv->epriv.eth, phy_addr, MII_BMCR, phy_val);
-+ }
-+
-+ /* Force MAC link down before reset */
-+ mt753x_reg_write(priv, PMCR_REG(5), FORCE_MODE);
-+ mt753x_reg_write(priv, PMCR_REG(6), FORCE_MODE);
-+
-+ /* MT7530 reset */
-+ mt753x_reg_write(priv, SYS_CTRL_REG, SW_SYS_RST | SW_REG_RST);
-+ udelay(100);
-+
-+ val = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) |
-+ MAC_MODE | FORCE_MODE |
-+ MAC_TX_EN | MAC_RX_EN |
-+ BKOFF_EN | BACKPR_EN |
-+ (SPEED_1000M << FORCE_SPD_S) |
-+ FORCE_DPX | FORCE_LINK;
-+
-+ /* MT7530 Port6: Forced 1000M/FD, FC disabled */
-+ priv->pmcr = val;
-+
-+ /* MT7530 Port5: Forced link down */
-+ mt753x_reg_write(priv, PMCR_REG(5), FORCE_MODE);
-+
-+ /* Keep MAC link down before starting eth */
-+ mt753x_reg_write(priv, PMCR_REG(6), FORCE_MODE);
-+
-+ /* MT7530 Port6: Set to RGMII */
-+ mt753x_reg_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_M, P6_INTF_MODE_RGMII);
-+
-+ /* Hardware Trap: Enable Port6, Disable Port5 */
-+ mt753x_reg_read(priv, HWTRAP_REG, &val);
-+ val |= CHG_TRAP | LOOPDET_DIS | P5_INTF_DIS |
-+ (P5_INTF_SEL_GMAC5 << P5_INTF_SEL_S) |
-+ (P5_INTF_MODE_RGMII << P5_INTF_MODE_S);
-+ val &= ~(C_MDIO_BPS | P6_INTF_DIS);
-+ mt753x_reg_write(priv, MHWTRAP_REG, val);
-+
-+ /* Setup switch core pll */
-+ mt7530_pad_clk_setup(priv, priv->epriv.phy_interface);
-+
-+ /* Lower Tx Driving for TRGMII path */
-+ for (i = 0 ; i < NUM_TRGMII_CTRL ; i++)
-+ mt753x_reg_write(priv, MT7530_TRGMII_TD_ODT(i),
-+ (txdrv << TD_DM_DRVP_S) |
-+ (txdrv << TD_DM_DRVN_S));
-+
-+ for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
-+ mt753x_reg_rmw(priv, MT7530_TRGMII_RD(i), RD_TAP_M, 16);
-+
-+ /* Enable port isolation to block inter-port communication */
-+ mt753x_port_isolation(priv);
-+
-+ /* Turn on PHYs */
-+ for (i = 0; i < MT753X_NUM_PHYS; i++) {
-+ phy_addr = MT753X_PHY_ADDR(priv->phy_base, i);
-+ phy_val = mtk_mii_read(priv->epriv.eth, phy_addr, MII_BMCR);
-+ phy_val &= ~BMCR_PDOWN;
-+ mtk_mii_write(priv->epriv.eth, phy_addr, MII_BMCR, phy_val);
-+ }
-+
-+ return mt7530_mdio_register(priv);
-+}
-+
-+static int mt7530_cleanup(struct mtk_eth_switch_priv *swpriv)
-+{
-+ struct mt753x_switch_priv *priv = (struct mt753x_switch_priv *)swpriv;
-+
-+ mdio_unregister(priv->mdio_bus);
-+
-+ return 0;
-+}
-+
-+static int mt7530_detect(struct mtk_eth_priv *priv)
-+{
-+ int ret;
-+ u32 rev;
-+
-+ ret = __mt753x_mdio_reg_read(priv, MT753X_DFL_SMI_ADDR, CHIP_REV, &rev);
-+ if (ret)
-+ return ret;
-+
-+ if (((rev & CHIP_NAME_M) >> CHIP_NAME_S) == 0x7530)
-+ return 0;
-+
-+ return -ENODEV;
-+}
-+
-+MTK_ETH_SWITCH(mt7530) = {
-+ .name = "mt7530",
-+ .desc = "MediaTek MT7530",
-+ .priv_size = sizeof(struct mt753x_switch_priv),
-+ .reset_wait_time = 1000,
-+
-+ .detect = mt7530_detect,
-+ .setup = mt7530_setup,
-+ .cleanup = mt7530_cleanup,
-+ .mac_control = mt7530_mac_control,
-+};
---- /dev/null
-+++ b/drivers/net/mtk_eth/mt7531.c
-@@ -0,0 +1,293 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (C) 2025 MediaTek Inc.
-+ *
-+ * Author: Weijie Gao <weijie.gao@mediatek.com>
-+ * Author: Mark Lee <mark-mc.lee@mediatek.com>
-+ */
-+
-+#include <miiphy.h>
-+#include <linux/delay.h>
-+#include <linux/mdio.h>
-+#include <linux/mii.h>
-+#include "mtk_eth.h"
-+#include "mt753x.h"
-+
-+#define CHIP_REV 0x781C
-+#define CHIP_NAME_S 16
-+#define CHIP_NAME_M 0xffff0000
-+#define CHIP_REV_S 0
-+#define CHIP_REV_M 0x0f
-+#define CHIP_REV_E1 0x0
-+
-+static int mt7531_core_reg_read(struct mt753x_switch_priv *priv, u32 reg)
-+{
-+ u8 phy_addr = MT753X_PHY_ADDR(priv->phy_base, 0);
-+
-+ return mt7531_mmd_read(priv, phy_addr, 0x1f, reg);
-+}
-+
-+static void mt7531_core_reg_write(struct mt753x_switch_priv *priv, u32 reg,
-+ u32 val)
-+{
-+ u8 phy_addr = MT753X_PHY_ADDR(priv->phy_base, 0);
-+
-+ mt7531_mmd_write(priv, phy_addr, 0x1f, reg, val);
-+}
-+
-+static void mt7531_core_pll_setup(struct mt753x_switch_priv *priv)
-+{
-+ /* Step 1 : Disable MT7531 COREPLL */
-+ mt753x_reg_rmw(priv, MT7531_PLLGP_EN, EN_COREPLL, 0);
-+
-+ /* Step 2: switch to XTAL output */
-+ mt753x_reg_rmw(priv, MT7531_PLLGP_EN, SW_CLKSW, SW_CLKSW);
-+
-+ mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_EN, 0);
-+
-+ /* Step 3: disable PLLGP and enable program PLLGP */
-+ mt753x_reg_rmw(priv, MT7531_PLLGP_EN, SW_PLLGP, SW_PLLGP);
-+
-+ /* Step 4: program COREPLL output frequency to 500MHz */
-+ mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_POSDIV_M,
-+ 2 << RG_COREPLL_POSDIV_S);
-+ udelay(25);
-+
-+ /* Currently, support XTAL 25Mhz only */
-+ mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_SDM_PCW_M,
-+ 0x140000 << RG_COREPLL_SDM_PCW_S);
-+
-+ /* Set feedback divide ratio update signal to high */
-+ mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_SDM_PCW_CHG,
-+ RG_COREPLL_SDM_PCW_CHG);
-+
-+ /* Wait for at least 16 XTAL clocks */
-+ udelay(10);
-+
-+ /* Step 5: set feedback divide ratio update signal to low */
-+ mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_SDM_PCW_CHG, 0);
-+
-+ /* add enable 325M clock for SGMII */
-+ mt753x_reg_write(priv, MT7531_ANA_PLLGP_CR5, 0xad0000);
-+
-+ /* add enable 250SSC clock for RGMII */
-+ mt753x_reg_write(priv, MT7531_ANA_PLLGP_CR2, 0x4f40000);
-+
-+ /*Step 6: Enable MT7531 PLL */
-+ mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_EN, RG_COREPLL_EN);
-+
-+ mt753x_reg_rmw(priv, MT7531_PLLGP_EN, EN_COREPLL, EN_COREPLL);
-+
-+ udelay(25);
-+}
-+
-+static int mt7531_port_sgmii_init(struct mt753x_switch_priv *priv, u32 port)
-+{
-+ if (port != 5 && port != 6) {
-+ printf("mt7531: port %d is not a SGMII port\n", port);
-+ return -EINVAL;
-+ }
-+
-+ /* Set SGMII GEN2 speed(2.5G) */
-+ mt753x_reg_rmw(priv, MT7531_PHYA_CTRL_SIGNAL3(port), SGMSYS_SPEED_MASK,
-+ FIELD_PREP(SGMSYS_SPEED_MASK, SGMSYS_SPEED_2500));
-+
-+ /* Disable SGMII AN */
-+ mt753x_reg_rmw(priv, MT7531_PCS_CONTROL_1(port),
-+ SGMII_AN_ENABLE, 0);
-+
-+ /* SGMII force mode setting */
-+ mt753x_reg_write(priv, MT7531_SGMII_MODE(port), SGMII_FORCE_MODE);
-+
-+ /* Release PHYA power down state */
-+ mt753x_reg_rmw(priv, MT7531_QPHY_PWR_STATE_CTRL(port),
-+ SGMII_PHYA_PWD, 0);
-+
-+ return 0;
-+}
-+
-+static int mt7531_port_rgmii_init(struct mt753x_switch_priv *priv, u32 port)
-+{
-+ u32 val;
-+
-+ if (port != 5) {
-+ printf("error: RGMII mode is not available for port %d\n",
-+ port);
-+ return -EINVAL;
-+ }
-+
-+ mt753x_reg_read(priv, MT7531_CLKGEN_CTRL, &val);
-+ val |= GP_CLK_EN;
-+ val &= ~GP_MODE_M;
-+ val |= GP_MODE_RGMII << GP_MODE_S;
-+ val |= TXCLK_NO_REVERSE;
-+ val |= RXCLK_NO_DELAY;
-+ val &= ~CLK_SKEW_IN_M;
-+ val |= CLK_SKEW_IN_NO_CHANGE << CLK_SKEW_IN_S;
-+ val &= ~CLK_SKEW_OUT_M;
-+ val |= CLK_SKEW_OUT_NO_CHANGE << CLK_SKEW_OUT_S;
-+ mt753x_reg_write(priv, MT7531_CLKGEN_CTRL, val);
-+
-+ return 0;
-+}
-+
-+static void mt7531_phy_setting(struct mt753x_switch_priv *priv)
-+{
-+ int i;
-+ u32 val;
-+
-+ for (i = 0; i < MT753X_NUM_PHYS; i++) {
-+ /* Enable HW auto downshift */
-+ mt7531_mii_write(priv, i, 0x1f, 0x1);
-+ val = mt7531_mii_read(priv, i, PHY_EXT_REG_14);
-+ val |= PHY_EN_DOWN_SHFIT;
-+ mt7531_mii_write(priv, i, PHY_EXT_REG_14, val);
-+
-+ /* PHY link down power saving enable */
-+ val = mt7531_mii_read(priv, i, PHY_EXT_REG_17);
-+ val |= PHY_LINKDOWN_POWER_SAVING_EN;
-+ mt7531_mii_write(priv, i, PHY_EXT_REG_17, val);
-+
-+ val = mt7531_mmd_read(priv, i, 0x1e, PHY_DEV1E_REG_0C6);
-+ val &= ~PHY_POWER_SAVING_M;
-+ val |= PHY_POWER_SAVING_TX << PHY_POWER_SAVING_S;
-+ mt7531_mmd_write(priv, i, 0x1e, PHY_DEV1E_REG_0C6, val);
-+ }
-+}
-+
-+static void mt7531_mac_control(struct mtk_eth_switch_priv *swpriv, bool enable)
-+{
-+ struct mt753x_switch_priv *priv = (struct mt753x_switch_priv *)swpriv;
-+ u32 pmcr = FORCE_MODE_LNK;
-+
-+ if (enable)
-+ pmcr = priv->pmcr;
-+
-+ mt753x_reg_write(priv, PMCR_REG(5), pmcr);
-+ mt753x_reg_write(priv, PMCR_REG(6), pmcr);
-+}
-+
-+static int mt7531_setup(struct mtk_eth_switch_priv *swpriv)
-+{
-+ struct mt753x_switch_priv *priv = (struct mt753x_switch_priv *)swpriv;
-+ u32 i, val, pmcr, port5_sgmii;
-+ u16 phy_addr, phy_val;
-+
-+ priv->smi_addr = MT753X_DFL_SMI_ADDR;
-+ priv->phy_base = (priv->smi_addr + 1) & MT753X_SMI_ADDR_MASK;
-+ priv->reg_read = mt753x_mdio_reg_read;
-+ priv->reg_write = mt753x_mdio_reg_write;
-+
-+ /* Turn off PHYs */
-+ for (i = 0; i < MT753X_NUM_PHYS; i++) {
-+ phy_addr = MT753X_PHY_ADDR(priv->phy_base, i);
-+ phy_val = mt7531_mii_read(priv, phy_addr, MII_BMCR);
-+ phy_val |= BMCR_PDOWN;
-+ mt7531_mii_write(priv, phy_addr, MII_BMCR, phy_val);
-+ }
-+
-+ /* Force MAC link down before reset */
-+ mt753x_reg_write(priv, PMCR_REG(5), FORCE_MODE_LNK);
-+ mt753x_reg_write(priv, PMCR_REG(6), FORCE_MODE_LNK);
-+
-+ /* Switch soft reset */
-+ mt753x_reg_write(priv, SYS_CTRL_REG, SW_SYS_RST | SW_REG_RST);
-+ udelay(100);
-+
-+ /* Enable MDC input Schmitt Trigger */
-+ mt753x_reg_rmw(priv, MT7531_SMT0_IOLB, SMT_IOLB_5_SMI_MDC_EN,
-+ SMT_IOLB_5_SMI_MDC_EN);
-+
-+ mt7531_core_pll_setup(priv);
-+
-+ mt753x_reg_read(priv, MT7531_TOP_SIG_SR, &val);
-+ port5_sgmii = !!(val & PAD_DUAL_SGMII_EN);
-+
-+ /* port5 support either RGMII or SGMII, port6 only support SGMII. */
-+ switch (priv->epriv.phy_interface) {
-+ case PHY_INTERFACE_MODE_RGMII:
-+ if (!port5_sgmii)
-+ mt7531_port_rgmii_init(priv, 5);
-+ break;
-+
-+ case PHY_INTERFACE_MODE_2500BASEX:
-+ mt7531_port_sgmii_init(priv, 6);
-+ if (port5_sgmii)
-+ mt7531_port_sgmii_init(priv, 5);
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ pmcr = MT7531_FORCE_MODE |
-+ (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) |
-+ MAC_MODE | MAC_TX_EN | MAC_RX_EN |
-+ BKOFF_EN | BACKPR_EN |
-+ FORCE_RX_FC | FORCE_TX_FC |
-+ (SPEED_1000M << FORCE_SPD_S) | FORCE_DPX |
-+ FORCE_LINK;
-+
-+ priv->pmcr = pmcr;
-+
-+ /* Keep MAC link down before starting eth */
-+ mt753x_reg_write(priv, PMCR_REG(5), FORCE_MODE_LNK);
-+ mt753x_reg_write(priv, PMCR_REG(6), FORCE_MODE_LNK);
-+
-+ /* Enable port isolation to block inter-port communication */
-+ mt753x_port_isolation(priv);
-+
-+ /* Turn on PHYs */
-+ for (i = 0; i < MT753X_NUM_PHYS; i++) {
-+ phy_addr = MT753X_PHY_ADDR(priv->phy_base, i);
-+ phy_val = mt7531_mii_read(priv, phy_addr, MII_BMCR);
-+ phy_val &= ~BMCR_PDOWN;
-+ mt7531_mii_write(priv, phy_addr, MII_BMCR, phy_val);
-+ }
-+
-+ mt7531_phy_setting(priv);
-+
-+ /* Enable Internal PHYs */
-+ val = mt7531_core_reg_read(priv, CORE_PLL_GROUP4);
-+ val |= MT7531_BYPASS_MODE;
-+ val &= ~MT7531_POWER_ON_OFF;
-+ mt7531_core_reg_write(priv, CORE_PLL_GROUP4, val);
-+
-+ return mt7531_mdio_register(priv);
-+}
-+
-+static int mt7531_cleanup(struct mtk_eth_switch_priv *swpriv)
-+{
-+ struct mt753x_switch_priv *priv = (struct mt753x_switch_priv *)swpriv;
-+
-+ mdio_unregister(priv->mdio_bus);
-+
-+ return 0;
-+}
-+
-+static int mt7531_detect(struct mtk_eth_priv *priv)
-+{
-+ int ret;
-+ u32 rev;
-+
-+ ret = __mt753x_mdio_reg_read(priv, MT753X_DFL_SMI_ADDR, CHIP_REV, &rev);
-+ if (ret)
-+ return ret;
-+
-+ if (((rev & CHIP_NAME_M) >> CHIP_NAME_S) == 0x7531)
-+ return 0;
-+
-+ return -ENODEV;
-+}
-+
-+MTK_ETH_SWITCH(mt7531) = {
-+ .name = "mt7531",
-+ .desc = "MediaTek MT7531",
-+ .priv_size = sizeof(struct mt753x_switch_priv),
-+ .reset_wait_time = 200,
-+
-+ .detect = mt7531_detect,
-+ .setup = mt7531_setup,
-+ .cleanup = mt7531_cleanup,
-+ .mac_control = mt7531_mac_control,
-+};
---- /dev/null
-+++ b/drivers/net/mtk_eth/mt753x.c
-@@ -0,0 +1,262 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (C) 2025 MediaTek Inc.
-+ *
-+ * Author: Weijie Gao <weijie.gao@mediatek.com>
-+ * Author: Mark Lee <mark-mc.lee@mediatek.com>
-+ */
-+
-+#include <errno.h>
-+#include <time.h>
-+#include "mtk_eth.h"
-+#include "mt753x.h"
-+
-+/*
-+ * MT753x Internal Register Address Bits
-+ * -------------------------------------------------------------------
-+ * | 15 14 13 12 11 10 9 8 7 6 | 5 4 3 2 | 1 0 |
-+ * |----------------------------------------|---------------|--------|
-+ * | Page Address | Reg Address | Unused |
-+ * -------------------------------------------------------------------
-+ */
-+
-+int __mt753x_mdio_reg_read(struct mtk_eth_priv *priv, u32 smi_addr, u32 reg,
-+ u32 *data)
-+{
-+ int ret, low_word, high_word;
-+
-+ /* Write page address */
-+ ret = mtk_mii_write(priv, smi_addr, 0x1f, reg >> 6);
-+ if (ret)
-+ return ret;
-+
-+ /* Read low word */
-+ low_word = mtk_mii_read(priv, smi_addr, (reg >> 2) & 0xf);
-+ if (low_word < 0)
-+ return low_word;
-+
-+ /* Read high word */
-+ high_word = mtk_mii_read(priv, smi_addr, 0x10);
-+ if (high_word < 0)
-+ return high_word;
-+
-+ if (data)
-+ *data = ((u32)high_word << 16) | (low_word & 0xffff);
-+
-+ return 0;
-+}
-+
-+int mt753x_mdio_reg_read(struct mt753x_switch_priv *priv, u32 reg, u32 *data)
-+{
-+ return __mt753x_mdio_reg_read(priv->epriv.eth, priv->smi_addr, reg,
-+ data);
-+}
-+
-+int mt753x_mdio_reg_write(struct mt753x_switch_priv *priv, u32 reg, u32 data)
-+{
-+ int ret;
-+
-+ /* Write page address */
-+ ret = mtk_mii_write(priv->epriv.eth, priv->smi_addr, 0x1f, reg >> 6);
-+ if (ret)
-+ return ret;
-+
-+ /* Write low word */
-+ ret = mtk_mii_write(priv->epriv.eth, priv->smi_addr, (reg >> 2) & 0xf,
-+ data & 0xffff);
-+ if (ret)
-+ return ret;
-+
-+ /* Write high word */
-+ return mtk_mii_write(priv->epriv.eth, priv->smi_addr, 0x10, data >> 16);
-+}
-+
-+int mt753x_reg_read(struct mt753x_switch_priv *priv, u32 reg, u32 *data)
-+{
-+ return priv->reg_read(priv, reg, data);
-+}
-+
-+int mt753x_reg_write(struct mt753x_switch_priv *priv, u32 reg, u32 data)
-+{
-+ return priv->reg_write(priv, reg, data);
-+}
-+
-+void mt753x_reg_rmw(struct mt753x_switch_priv *priv, u32 reg, u32 clr, u32 set)
-+{
-+ u32 val;
-+
-+ priv->reg_read(priv, reg, &val);
-+ val &= ~clr;
-+ val |= set;
-+ priv->reg_write(priv, reg, val);
-+}
-+
-+/* Indirect MDIO clause 22/45 access */
-+static int mt7531_mii_rw(struct mt753x_switch_priv *priv, int phy, int reg,
-+ u16 data, u32 cmd, u32 st)
-+{
-+ u32 val, timeout_ms;
-+ ulong timeout;
-+ int ret = 0;
-+
-+ val = (st << MDIO_ST_S) |
-+ ((cmd << MDIO_CMD_S) & MDIO_CMD_M) |
-+ ((phy << MDIO_PHY_ADDR_S) & MDIO_PHY_ADDR_M) |
-+ ((reg << MDIO_REG_ADDR_S) & MDIO_REG_ADDR_M);
-+
-+ if (cmd == MDIO_CMD_WRITE || cmd == MDIO_CMD_ADDR)
-+ val |= data & MDIO_RW_DATA_M;
-+
-+ mt753x_reg_write(priv, MT7531_PHY_IAC, val | PHY_ACS_ST);
-+
-+ timeout_ms = 100;
-+ timeout = get_timer(0);
-+ while (1) {
-+ mt753x_reg_read(priv, MT7531_PHY_IAC, &val);
-+
-+ if ((val & PHY_ACS_ST) == 0)
-+ break;
-+
-+ if (get_timer(timeout) > timeout_ms)
-+ return -ETIMEDOUT;
-+ }
-+
-+ if (cmd == MDIO_CMD_READ || cmd == MDIO_CMD_READ_C45) {
-+ mt753x_reg_read(priv, MT7531_PHY_IAC, &val);
-+ ret = val & MDIO_RW_DATA_M;
-+ }
-+
-+ return ret;
-+}
-+
-+int mt7531_mii_read(struct mt753x_switch_priv *priv, u8 phy, u8 reg)
-+{
-+ u8 phy_addr;
-+
-+ if (phy >= MT753X_NUM_PHYS)
-+ return -EINVAL;
-+
-+ phy_addr = MT753X_PHY_ADDR(priv->phy_base, phy);
-+
-+ return mt7531_mii_rw(priv, phy_addr, reg, 0, MDIO_CMD_READ,
-+ MDIO_ST_C22);
-+}
-+
-+int mt7531_mii_write(struct mt753x_switch_priv *priv, u8 phy, u8 reg, u16 val)
-+{
-+ u8 phy_addr;
-+
-+ if (phy >= MT753X_NUM_PHYS)
-+ return -EINVAL;
-+
-+ phy_addr = MT753X_PHY_ADDR(priv->phy_base, phy);
-+
-+ return mt7531_mii_rw(priv, phy_addr, reg, val, MDIO_CMD_WRITE,
-+ MDIO_ST_C22);
-+}
-+
-+int mt7531_mmd_read(struct mt753x_switch_priv *priv, u8 addr, u8 devad,
-+ u16 reg)
-+{
-+ u8 phy_addr;
-+ int ret;
-+
-+ if (addr >= MT753X_NUM_PHYS)
-+ return -EINVAL;
-+
-+ phy_addr = MT753X_PHY_ADDR(priv->phy_base, addr);
-+
-+ ret = mt7531_mii_rw(priv, phy_addr, devad, reg, MDIO_CMD_ADDR,
-+ MDIO_ST_C45);
-+ if (ret)
-+ return ret;
-+
-+ return mt7531_mii_rw(priv, phy_addr, devad, 0, MDIO_CMD_READ_C45,
-+ MDIO_ST_C45);
-+}
-+
-+int mt7531_mmd_write(struct mt753x_switch_priv *priv, u8 addr, u8 devad,
-+ u16 reg, u16 val)
-+{
-+ u8 phy_addr;
-+ int ret;
-+
-+ if (addr >= MT753X_NUM_PHYS)
-+ return 0;
-+
-+ phy_addr = MT753X_PHY_ADDR(priv->phy_base, addr);
-+
-+ ret = mt7531_mii_rw(priv, phy_addr, devad, reg, MDIO_CMD_ADDR,
-+ MDIO_ST_C45);
-+ if (ret)
-+ return ret;
-+
-+ return mt7531_mii_rw(priv, phy_addr, devad, val, MDIO_CMD_WRITE,
-+ MDIO_ST_C45);
-+}
-+
-+static int mt7531_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
-+{
-+ struct mt753x_switch_priv *priv = bus->priv;
-+
-+ if (devad < 0)
-+ return mt7531_mii_read(priv, addr, reg);
-+
-+ return mt7531_mmd_read(priv, addr, devad, reg);
-+}
-+
-+static int mt7531_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
-+ u16 val)
-+{
-+ struct mt753x_switch_priv *priv = bus->priv;
-+
-+ if (devad < 0)
-+ return mt7531_mii_write(priv, addr, reg, val);
-+
-+ return mt7531_mmd_write(priv, addr, devad, reg, val);
-+}
-+
-+int mt7531_mdio_register(struct mt753x_switch_priv *priv)
-+{
-+ struct mii_dev *mdio_bus = mdio_alloc();
-+ int ret;
-+
-+ if (!mdio_bus)
-+ return -ENOMEM;
-+
-+ mdio_bus->read = mt7531_mdio_read;
-+ mdio_bus->write = mt7531_mdio_write;
-+ snprintf(mdio_bus->name, sizeof(mdio_bus->name), priv->epriv.sw->name);
-+
-+ mdio_bus->priv = priv;
-+
-+ ret = mdio_register(mdio_bus);
-+ if (ret) {
-+ mdio_free(mdio_bus);
-+ return ret;
-+ }
-+
-+ priv->mdio_bus = mdio_bus;
-+
-+ return 0;
-+}
-+
-+void mt753x_port_isolation(struct mt753x_switch_priv *priv)
-+{
-+ u32 i;
-+
-+ for (i = 0; i < MT753X_NUM_PORTS; i++) {
-+ /* Set port matrix mode */
-+ if (i != 6)
-+ mt753x_reg_write(priv, PCR_REG(i),
-+ (0x40 << PORT_MATRIX_S));
-+ else
-+ mt753x_reg_write(priv, PCR_REG(i),
-+ (0x3f << PORT_MATRIX_S));
-+
-+ /* Set port mode to user port */
-+ mt753x_reg_write(priv, PVC_REG(i),
-+ (0x8100 << STAG_VPID_S) |
-+ (VLAN_ATTR_USER << VLAN_ATTR_S));
-+ }
-+}
---- /dev/null
-+++ b/drivers/net/mtk_eth/mt753x.h
-@@ -0,0 +1,286 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * Copyright (C) 2025 MediaTek Inc.
-+ *
-+ * Author: Weijie Gao <weijie.gao@mediatek.com>
-+ * Author: Mark Lee <mark-mc.lee@mediatek.com>
-+ */
-+
-+#ifndef _MTK_ETH_MT753X_H_
-+#define _MTK_ETH_MT753X_H_
-+
-+#include <phy.h>
-+#include <miiphy.h>
-+#include <linux/bitops.h>
-+#include <linux/bitfield.h>
-+
-+struct mtk_eth_priv;
-+
-+#define MT753X_NUM_PHYS 5
-+#define MT753X_NUM_PORTS 7
-+#define MT753X_DFL_SMI_ADDR 31
-+#define MT753X_SMI_ADDR_MASK 0x1f
-+
-+#define MT753X_PHY_ADDR(base, addr) \
-+ (((base) + (addr)) & 0x1f)
-+
-+/* MT7530 Registers */
-+#define PCR_REG(p) (0x2004 + (p) * 0x100)
-+#define PORT_MATRIX_S 16
-+#define PORT_MATRIX_M 0xff0000
-+
-+#define PVC_REG(p) (0x2010 + (p) * 0x100)
-+#define STAG_VPID_S 16
-+#define STAG_VPID_M 0xffff0000
-+#define VLAN_ATTR_S 6
-+#define VLAN_ATTR_M 0xc0
-+
-+/* VLAN_ATTR: VLAN attributes */
-+#define VLAN_ATTR_USER 0
-+#define VLAN_ATTR_STACK 1
-+#define VLAN_ATTR_TRANSLATION 2
-+#define VLAN_ATTR_TRANSPARENT 3
-+
-+#define PMCR_REG(p) (0x3000 + (p) * 0x100)
-+/* XXX: all fields of MT7530 are defined under GMAC_PORT_MCR
-+ * MT7531 specific fields are defined below
-+ */
-+#define FORCE_MODE_EEE1G BIT(25)
-+#define FORCE_MODE_EEE100 BIT(26)
-+#define FORCE_MODE_TX_FC BIT(27)
-+#define FORCE_MODE_RX_FC BIT(28)
-+#define FORCE_MODE_DPX BIT(29)
-+#define FORCE_MODE_SPD BIT(30)
-+#define FORCE_MODE_LNK BIT(31)
-+#define MT7531_FORCE_MODE FORCE_MODE_TX_FC | FORCE_MODE_RX_FC | \
-+ FORCE_MODE_DPX | FORCE_MODE_SPD | \
-+ FORCE_MODE_LNK
-+#define MT7988_FORCE_MODE FORCE_MODE_TX_FC | FORCE_MODE_RX_FC | \
-+ FORCE_MODE_DPX | FORCE_MODE_SPD | \
-+ FORCE_MODE_LNK
-+
-+/* MT7531 SGMII Registers */
-+#define MT7531_SGMII_REG_BASE 0x5000
-+#define MT7531_SGMII_REG_PORT_BASE 0x1000
-+#define MT7531_SGMII_REG(p, r) (MT7531_SGMII_REG_BASE + \
-+ (p) * MT7531_SGMII_REG_PORT_BASE + (r))
-+#define MT7531_PCS_CONTROL_1(p) MT7531_SGMII_REG(((p) - 5), 0x00)
-+#define MT7531_SGMII_MODE(p) MT7531_SGMII_REG(((p) - 5), 0x20)
-+#define MT7531_QPHY_PWR_STATE_CTRL(p) MT7531_SGMII_REG(((p) - 5), 0xe8)
-+#define MT7531_PHYA_CTRL_SIGNAL3(p) MT7531_SGMII_REG(((p) - 5), 0x128)
-+#define MT7531_PHYA_ANA_SYSPLL(p) MT7531_SGMII_REG(((p) - 5), 0x158)
-+/* XXX: all fields of MT7531 SGMII are defined under SGMSYS */
-+
-+/* MT753x System Control Register */
-+#define SYS_CTRL_REG 0x7000
-+#define SW_PHY_RST BIT(2)
-+#define SW_SYS_RST BIT(1)
-+#define SW_REG_RST BIT(0)
-+
-+/* MT7531 */
-+#define MT7531_PHY_IAC 0x701c
-+/* XXX: all fields are defined under GMAC_PIAC_REG */
-+
-+#define MT7531_CLKGEN_CTRL 0x7500
-+#define CLK_SKEW_OUT_S 8
-+#define CLK_SKEW_OUT_M 0x300
-+#define CLK_SKEW_IN_S 6
-+#define CLK_SKEW_IN_M 0xc0
-+#define RXCLK_NO_DELAY BIT(5)
-+#define TXCLK_NO_REVERSE BIT(4)
-+#define GP_MODE_S 1
-+#define GP_MODE_M 0x06
-+#define GP_CLK_EN BIT(0)
-+
-+/* Values of GP_MODE */
-+#define GP_MODE_RGMII 0
-+#define GP_MODE_MII 1
-+#define GP_MODE_REV_MII 2
-+
-+/* Values of CLK_SKEW_IN */
-+#define CLK_SKEW_IN_NO_CHANGE 0
-+#define CLK_SKEW_IN_DELAY_100PPS 1
-+#define CLK_SKEW_IN_DELAY_200PPS 2
-+#define CLK_SKEW_IN_REVERSE 3
-+
-+/* Values of CLK_SKEW_OUT */
-+#define CLK_SKEW_OUT_NO_CHANGE 0
-+#define CLK_SKEW_OUT_DELAY_100PPS 1
-+#define CLK_SKEW_OUT_DELAY_200PPS 2
-+#define CLK_SKEW_OUT_REVERSE 3
-+
-+#define HWTRAP_REG 0x7800
-+/* MT7530 Modified Hardware Trap Status Registers */
-+#define MHWTRAP_REG 0x7804
-+#define CHG_TRAP BIT(16)
-+#define LOOPDET_DIS BIT(14)
-+#define P5_INTF_SEL_S 13
-+#define P5_INTF_SEL_M 0x2000
-+#define SMI_ADDR_S 11
-+#define SMI_ADDR_M 0x1800
-+#define XTAL_FSEL_S 9
-+#define XTAL_FSEL_M 0x600
-+#define P6_INTF_DIS BIT(8)
-+#define P5_INTF_MODE_S 7
-+#define P5_INTF_MODE_M 0x80
-+#define P5_INTF_DIS BIT(6)
-+#define C_MDIO_BPS BIT(5)
-+#define CHIP_MODE_S 0
-+#define CHIP_MODE_M 0x0f
-+
-+/* P5_INTF_SEL: Interface type of Port5 */
-+#define P5_INTF_SEL_GPHY 0
-+#define P5_INTF_SEL_GMAC5 1
-+
-+/* P5_INTF_MODE: Interface mode of Port5 */
-+#define P5_INTF_MODE_GMII_MII 0
-+#define P5_INTF_MODE_RGMII 1
-+
-+#define MT7530_P6ECR 0x7830
-+#define P6_INTF_MODE_M 0x3
-+#define P6_INTF_MODE_S 0
-+
-+/* P6_INTF_MODE: Interface mode of Port6 */
-+#define P6_INTF_MODE_RGMII 0
-+#define P6_INTF_MODE_TRGMII 1
-+
-+#define MT7530_TRGMII_RD(n) (0x7a10 + (n) * 8)
-+#define RD_TAP_S 0
-+#define RD_TAP_M 0x7f
-+
-+#define MT7530_TRGMII_TD_ODT(n) (0x7a54 + (n) * 8)
-+/* XXX: all fields are defined under GMAC_TRGMII_TD_ODT */
-+
-+/* TOP Signals Status Register */
-+#define MT7531_TOP_SIG_SR 0x780c
-+#define PAD_MCM_SMI_EN BIT(0)
-+#define PAD_DUAL_SGMII_EN BIT(1)
-+
-+/* MT7531 PLLGP Registers */
-+#define MT7531_PLLGP_EN 0x7820
-+#define EN_COREPLL BIT(2)
-+#define SW_CLKSW BIT(1)
-+#define SW_PLLGP BIT(0)
-+
-+#define MT7531_PLLGP_CR0 0x78a8
-+#define RG_COREPLL_EN BIT(22)
-+#define RG_COREPLL_POSDIV_S 23
-+#define RG_COREPLL_POSDIV_M 0x3800000
-+#define RG_COREPLL_SDM_PCW_S 1
-+#define RG_COREPLL_SDM_PCW_M 0x3ffffe
-+#define RG_COREPLL_SDM_PCW_CHG BIT(0)
-+
-+/* MT7531 RGMII and SGMII PLL clock */
-+#define MT7531_ANA_PLLGP_CR2 0x78b0
-+#define MT7531_ANA_PLLGP_CR5 0x78bc
-+
-+/* MT7531 GPIO GROUP IOLB SMT0 Control */
-+#define MT7531_SMT0_IOLB 0x7f04
-+#define SMT_IOLB_5_SMI_MDC_EN BIT(5)
-+
-+/* MT7530 GPHY MDIO MMD Registers */
-+#define CORE_PLL_GROUP2 0x401
-+#define RG_SYSPLL_EN_NORMAL BIT(15)
-+#define RG_SYSPLL_VODEN BIT(14)
-+#define RG_SYSPLL_POSDIV_S 5
-+#define RG_SYSPLL_POSDIV_M 0x60
-+
-+#define CORE_PLL_GROUP4 0x403
-+#define MT7531_BYPASS_MODE BIT(4)
-+#define MT7531_POWER_ON_OFF BIT(5)
-+#define RG_SYSPLL_DDSFBK_EN BIT(12)
-+#define RG_SYSPLL_BIAS_EN BIT(11)
-+#define RG_SYSPLL_BIAS_LPF_EN BIT(10)
-+
-+#define CORE_PLL_GROUP5 0x404
-+#define RG_LCDDS_PCW_NCPO1_S 0
-+#define RG_LCDDS_PCW_NCPO1_M 0xffff
-+
-+#define CORE_PLL_GROUP6 0x405
-+#define RG_LCDDS_PCW_NCPO0_S 0
-+#define RG_LCDDS_PCW_NCPO0_M 0xffff
-+
-+#define CORE_PLL_GROUP7 0x406
-+#define RG_LCDDS_PWDB BIT(15)
-+#define RG_LCDDS_ISO_EN BIT(13)
-+#define RG_LCCDS_C_S 4
-+#define RG_LCCDS_C_M 0x70
-+#define RG_LCDDS_PCW_NCPO_CHG BIT(3)
-+
-+#define CORE_PLL_GROUP10 0x409
-+#define RG_LCDDS_SSC_DELTA_S 0
-+#define RG_LCDDS_SSC_DELTA_M 0xfff
-+
-+#define CORE_PLL_GROUP11 0x40a
-+#define RG_LCDDS_SSC_DELTA1_S 0
-+#define RG_LCDDS_SSC_DELTA1_M 0xfff
-+
-+#define CORE_GSWPLL_GRP1 0x40d
-+#define RG_GSWPLL_POSDIV_200M_S 12
-+#define RG_GSWPLL_POSDIV_200M_M 0x3000
-+#define RG_GSWPLL_EN_PRE BIT(11)
-+#define RG_GSWPLL_FBKDIV_200M_S 0
-+#define RG_GSWPLL_FBKDIV_200M_M 0xff
-+
-+#define CORE_GSWPLL_GRP2 0x40e
-+#define RG_GSWPLL_POSDIV_500M_S 8
-+#define RG_GSWPLL_POSDIV_500M_M 0x300
-+#define RG_GSWPLL_FBKDIV_500M_S 0
-+#define RG_GSWPLL_FBKDIV_500M_M 0xff
-+
-+#define CORE_TRGMII_GSW_CLK_CG 0x410
-+#define REG_GSWCK_EN BIT(0)
-+#define REG_TRGMIICK_EN BIT(1)
-+
-+/* Extend PHY Control Register 3 */
-+#define PHY_EXT_REG_14 0x14
-+
-+/* Fields of PHY_EXT_REG_14 */
-+#define PHY_EN_DOWN_SHFIT BIT(4)
-+
-+/* Extend PHY Control Register 4 */
-+#define PHY_EXT_REG_17 0x17
-+
-+/* Fields of PHY_EXT_REG_17 */
-+#define PHY_LINKDOWN_POWER_SAVING_EN BIT(4)
-+
-+/* PHY RXADC Control Register 7 */
-+#define PHY_DEV1E_REG_0C6 0x0c6
-+
-+/* Fields of PHY_DEV1E_REG_0C6 */
-+#define PHY_POWER_SAVING_S 8
-+#define PHY_POWER_SAVING_M 0x300
-+#define PHY_POWER_SAVING_TX 0x0
-+
-+struct mt753x_switch_priv {
-+ struct mtk_eth_switch_priv epriv;
-+ struct mii_dev *mdio_bus;
-+ u32 smi_addr;
-+ u32 phy_base;
-+ u32 pmcr;
-+
-+ int (*reg_read)(struct mt753x_switch_priv *priv, u32 reg, u32 *data);
-+ int (*reg_write)(struct mt753x_switch_priv *priv, u32 reg, u32 data);
-+};
-+
-+int __mt753x_mdio_reg_read(struct mtk_eth_priv *priv, u32 smi_addr, u32 reg,
-+ u32 *data);
-+int mt753x_mdio_reg_read(struct mt753x_switch_priv *priv, u32 reg, u32 *data);
-+int mt753x_mdio_reg_write(struct mt753x_switch_priv *priv, u32 reg, u32 data);
-+
-+int mt753x_reg_read(struct mt753x_switch_priv *priv, u32 reg, u32 *data);
-+int mt753x_reg_write(struct mt753x_switch_priv *priv, u32 reg, u32 data);
-+void mt753x_reg_rmw(struct mt753x_switch_priv *priv, u32 reg, u32 clr, u32 set);
-+
-+int mt7531_mii_read(struct mt753x_switch_priv *priv, u8 phy, u8 reg);
-+int mt7531_mii_write(struct mt753x_switch_priv *priv, u8 phy, u8 reg, u16 val);
-+int mt7531_mmd_read(struct mt753x_switch_priv *priv, u8 addr, u8 devad,
-+ u16 reg);
-+int mt7531_mmd_write(struct mt753x_switch_priv *priv, u8 addr, u8 devad,
-+ u16 reg, u16 val);
-+
-+int mt7531_mdio_register(struct mt753x_switch_priv *priv);
-+
-+void mt753x_port_isolation(struct mt753x_switch_priv *priv);
-+
-+#endif /* _MTK_ETH_MT753X_H_ */
---- /dev/null
-+++ b/drivers/net/mtk_eth/mt7988.c
-@@ -0,0 +1,160 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (C) 2025 MediaTek Inc.
-+ *
-+ * Author: Weijie Gao <weijie.gao@mediatek.com>
-+ * Author: Mark Lee <mark-mc.lee@mediatek.com>
-+ */
-+
-+#include <miiphy.h>
-+#include <linux/delay.h>
-+#include <linux/mdio.h>
-+#include <linux/mii.h>
-+#include <linux/io.h>
-+#include "mtk_eth.h"
-+#include "mt753x.h"
-+
-+static int mt7988_reg_read(struct mt753x_switch_priv *priv, u32 reg, u32 *data)
-+{
-+ *data = readl(priv->epriv.ethsys_base + GSW_BASE + reg);
-+
-+ return 0;
-+}
-+
-+static int mt7988_reg_write(struct mt753x_switch_priv *priv, u32 reg, u32 data)
-+{
-+ writel(data, priv->epriv.ethsys_base + GSW_BASE + reg);
-+
-+ return 0;
-+}
-+
-+static void mt7988_phy_setting(struct mt753x_switch_priv *priv)
-+{
-+ u16 val;
-+ u32 i;
-+
-+ for (i = 0; i < MT753X_NUM_PHYS; i++) {
-+ /* Enable HW auto downshift */
-+ mt7531_mii_write(priv, i, 0x1f, 0x1);
-+ val = mt7531_mii_read(priv, i, PHY_EXT_REG_14);
-+ val |= PHY_EN_DOWN_SHFIT;
-+ mt7531_mii_write(priv, i, PHY_EXT_REG_14, val);
-+
-+ /* PHY link down power saving enable */
-+ val = mt7531_mii_read(priv, i, PHY_EXT_REG_17);
-+ val |= PHY_LINKDOWN_POWER_SAVING_EN;
-+ mt7531_mii_write(priv, i, PHY_EXT_REG_17, val);
-+ }
-+}
-+
-+static void mt7988_mac_control(struct mtk_eth_switch_priv *swpriv, bool enable)
-+{
-+ struct mt753x_switch_priv *priv = (struct mt753x_switch_priv *)swpriv;
-+ u32 pmcr = FORCE_MODE_LNK;
-+
-+ if (enable)
-+ pmcr = priv->pmcr;
-+
-+ mt7988_reg_write(priv, PMCR_REG(6), pmcr);
-+}
-+
-+static int mt7988_setup(struct mtk_eth_switch_priv *swpriv)
-+{
-+ struct mt753x_switch_priv *priv = (struct mt753x_switch_priv *)swpriv;
-+ u16 phy_addr, phy_val;
-+ u32 pmcr;
-+ int i;
-+
-+ priv->smi_addr = MT753X_DFL_SMI_ADDR;
-+ priv->phy_base = (priv->smi_addr + 1) & MT753X_SMI_ADDR_MASK;
-+ priv->reg_read = mt7988_reg_read;
-+ priv->reg_write = mt7988_reg_write;
-+
-+ /* Turn off PHYs */
-+ for (i = 0; i < MT753X_NUM_PHYS; i++) {
-+ phy_addr = MT753X_PHY_ADDR(priv->phy_base, i);
-+ phy_val = mt7531_mii_read(priv, phy_addr, MII_BMCR);
-+ phy_val |= BMCR_PDOWN;
-+ mt7531_mii_write(priv, phy_addr, MII_BMCR, phy_val);
-+ }
-+
-+ switch (priv->epriv.phy_interface) {
-+ case PHY_INTERFACE_MODE_USXGMII:
-+ /* Use CPU bridge instead of actual USXGMII path */
-+
-+ /* Disable GDM1 RX CRC stripping */
-+ /* mtk_fe_rmw(priv, 0x500, BIT(16), 0); */
-+
-+ /* Set GDM1 no drop */
-+ mtk_fe_rmw(priv->epriv.eth, PSE_NO_DROP_CFG_REG, 0,
-+ PSE_NO_DROP_GDM1);
-+
-+ /* Enable GSW CPU bridge as USXGMII */
-+ /* mtk_fe_rmw(priv, 0x504, BIT(31), BIT(31)); */
-+
-+ /* Enable GDM1 to GSW CPU bridge */
-+ mtk_gmac_rmw(priv->epriv.eth, GMAC_MAC_MISC_REG, 0, BIT(0));
-+
-+ /* XGMAC force link up */
-+ mtk_gmac_rmw(priv->epriv.eth, GMAC_XGMAC_STS_REG, 0,
-+ P1_XGMAC_FORCE_LINK);
-+
-+ /* Setup GSW CPU bridge IPG */
-+ mtk_gmac_rmw(priv->epriv.eth, GMAC_GSW_CFG_REG,
-+ GSWTX_IPG_M | GSWRX_IPG_M,
-+ (0xB << GSWTX_IPG_S) | (0xB << GSWRX_IPG_S));
-+ break;
-+ default:
-+ printf("Error: MT7988 GSW does not support %s interface\n",
-+ phy_string_for_interface(priv->epriv.phy_interface));
-+ break;
-+ }
-+
-+ pmcr = MT7988_FORCE_MODE |
-+ (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) |
-+ MAC_MODE | MAC_TX_EN | MAC_RX_EN |
-+ BKOFF_EN | BACKPR_EN |
-+ FORCE_RX_FC | FORCE_TX_FC |
-+ (SPEED_1000M << FORCE_SPD_S) | FORCE_DPX |
-+ FORCE_LINK;
-+
-+ priv->pmcr = pmcr;
-+
-+ /* Keep MAC link down before starting eth */
-+ mt7988_reg_write(priv, PMCR_REG(6), FORCE_MODE_LNK);
-+
-+ /* Enable port isolation to block inter-port communication */
-+ mt753x_port_isolation(priv);
-+
-+ /* Turn on PHYs */
-+ for (i = 0; i < MT753X_NUM_PHYS; i++) {
-+ phy_addr = MT753X_PHY_ADDR(priv->phy_base, i);
-+ phy_val = mt7531_mii_read(priv, phy_addr, MII_BMCR);
-+ phy_val &= ~BMCR_PDOWN;
-+ mt7531_mii_write(priv, phy_addr, MII_BMCR, phy_val);
-+ }
-+
-+ mt7988_phy_setting(priv);
-+
-+ return mt7531_mdio_register(priv);
-+}
-+
-+static int mt7531_cleanup(struct mtk_eth_switch_priv *swpriv)
-+{
-+ struct mt753x_switch_priv *priv = (struct mt753x_switch_priv *)swpriv;
-+
-+ mdio_unregister(priv->mdio_bus);
-+
-+ return 0;
-+}
-+
-+MTK_ETH_SWITCH(mt7988) = {
-+ .name = "mt7988",
-+ .desc = "MediaTek MT7988 built-in switch",
-+ .priv_size = sizeof(struct mt753x_switch_priv),
-+ .reset_wait_time = 50,
-+
-+ .setup = mt7988_setup,
-+ .cleanup = mt7531_cleanup,
-+ .mac_control = mt7988_mac_control,
-+};
---- a/drivers/net/mtk_eth.c
-+++ /dev/null
-@@ -1,2280 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0
--/*
-- * Copyright (C) 2018 MediaTek Inc.
-- *
-- * Author: Weijie Gao <weijie.gao@mediatek.com>
-- * Author: Mark Lee <mark-mc.lee@mediatek.com>
-- */
--
--#include <cpu_func.h>
--#include <dm.h>
--#include <log.h>
--#include <malloc.h>
--#include <miiphy.h>
--#include <net.h>
--#include <regmap.h>
--#include <reset.h>
--#include <syscon.h>
--#include <wait_bit.h>
--#include <asm/cache.h>
--#include <asm/gpio.h>
--#include <asm/io.h>
--#include <dm/device_compat.h>
--#include <linux/delay.h>
--#include <linux/err.h>
--#include <linux/ioport.h>
--#include <linux/mdio.h>
--#include <linux/mii.h>
--#include <linux/printk.h>
--
--#include "mtk_eth.h"
--
--#define NUM_TX_DESC 32
--#define NUM_RX_DESC 32
--#define TX_TOTAL_BUF_SIZE (NUM_TX_DESC * PKTSIZE_ALIGN)
--#define RX_TOTAL_BUF_SIZE (NUM_RX_DESC * PKTSIZE_ALIGN)
--#define TOTAL_PKT_BUF_SIZE (TX_TOTAL_BUF_SIZE + RX_TOTAL_BUF_SIZE)
--
--#define MT753X_NUM_PHYS 5
--#define MT753X_NUM_PORTS 7
--#define MT753X_DFL_SMI_ADDR 31
--#define MT753X_SMI_ADDR_MASK 0x1f
--
--#define MT753X_PHY_ADDR(base, addr) \
-- (((base) + (addr)) & 0x1f)
--
--#define GDMA_FWD_TO_CPU \
-- (0x20000000 | \
-- GDM_ICS_EN | \
-- GDM_TCS_EN | \
-- GDM_UCS_EN | \
-- STRP_CRC | \
-- (DP_PDMA << MYMAC_DP_S) | \
-- (DP_PDMA << BC_DP_S) | \
-- (DP_PDMA << MC_DP_S) | \
-- (DP_PDMA << UN_DP_S))
--
--#define GDMA_BRIDGE_TO_CPU \
-- (0xC0000000 | \
-- GDM_ICS_EN | \
-- GDM_TCS_EN | \
-- GDM_UCS_EN | \
-- (DP_PDMA << MYMAC_DP_S) | \
-- (DP_PDMA << BC_DP_S) | \
-- (DP_PDMA << MC_DP_S) | \
-- (DP_PDMA << UN_DP_S))
--
--#define GDMA_FWD_DISCARD \
-- (0x20000000 | \
-- GDM_ICS_EN | \
-- GDM_TCS_EN | \
-- GDM_UCS_EN | \
-- STRP_CRC | \
-- (DP_DISCARD << MYMAC_DP_S) | \
-- (DP_DISCARD << BC_DP_S) | \
-- (DP_DISCARD << MC_DP_S) | \
-- (DP_DISCARD << UN_DP_S))
--
--enum mtk_switch {
-- SW_NONE,
-- SW_MT7530,
-- SW_MT7531,
-- SW_MT7988,
--};
--
--/* struct mtk_soc_data - This is the structure holding all differences
-- * among various plaforms
-- * @caps Flags shown the extra capability for the SoC
-- * @ana_rgc3: The offset for register ANA_RGC3 related to
-- * sgmiisys syscon
-- * @gdma_count: Number of GDMAs
-- * @pdma_base: Register base of PDMA block
-- * @txd_size: Tx DMA descriptor size.
-- * @rxd_size: Rx DMA descriptor size.
-- */
--struct mtk_soc_data {
-- u32 caps;
-- u32 ana_rgc3;
-- u32 gdma_count;
-- u32 pdma_base;
-- u32 txd_size;
-- u32 rxd_size;
--};
--
--struct mtk_eth_priv {
-- char pkt_pool[TOTAL_PKT_BUF_SIZE] __aligned(ARCH_DMA_MINALIGN);
--
-- void *tx_ring_noc;
-- void *rx_ring_noc;
--
-- int rx_dma_owner_idx0;
-- int tx_cpu_owner_idx0;
--
-- void __iomem *fe_base;
-- void __iomem *gmac_base;
-- void __iomem *sgmii_base;
-- void __iomem *gsw_base;
--
-- struct regmap *ethsys_regmap;
--
-- struct regmap *infra_regmap;
--
-- struct regmap *usxgmii_regmap;
-- struct regmap *xfi_pextp_regmap;
-- struct regmap *xfi_pll_regmap;
-- struct regmap *toprgu_regmap;
--
-- struct mii_dev *mdio_bus;
-- int (*mii_read)(struct mtk_eth_priv *priv, u8 phy, u8 reg);
-- int (*mii_write)(struct mtk_eth_priv *priv, u8 phy, u8 reg, u16 val);
-- int (*mmd_read)(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg);
-- int (*mmd_write)(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg,
-- u16 val);
--
-- const struct mtk_soc_data *soc;
-- int gmac_id;
-- int force_mode;
-- int speed;
-- int duplex;
-- int mdc;
-- bool pn_swap;
--
-- struct phy_device *phydev;
-- int phy_interface;
-- int phy_addr;
--
-- enum mtk_switch sw;
-- int (*switch_init)(struct mtk_eth_priv *priv);
-- void (*switch_mac_control)(struct mtk_eth_priv *priv, bool enable);
-- u32 mt753x_smi_addr;
-- u32 mt753x_phy_base;
-- u32 mt753x_pmcr;
-- u32 mt753x_reset_wait_time;
--
-- struct gpio_desc rst_gpio;
-- int mcm;
--
-- struct reset_ctl rst_fe;
-- struct reset_ctl rst_mcm;
--};
--
--static void mtk_pdma_write(struct mtk_eth_priv *priv, u32 reg, u32 val)
--{
-- writel(val, priv->fe_base + priv->soc->pdma_base + reg);
--}
--
--static void mtk_pdma_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr,
-- u32 set)
--{
-- clrsetbits_le32(priv->fe_base + priv->soc->pdma_base + reg, clr, set);
--}
--
--static void mtk_gdma_write(struct mtk_eth_priv *priv, int no, u32 reg,
-- u32 val)
--{
-- u32 gdma_base;
--
-- if (no == 2)
-- gdma_base = GDMA3_BASE;
-- else if (no == 1)
-- gdma_base = GDMA2_BASE;
-- else
-- gdma_base = GDMA1_BASE;
--
-- writel(val, priv->fe_base + gdma_base + reg);
--}
--
--static void mtk_fe_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, u32 set)
--{
-- clrsetbits_le32(priv->fe_base + reg, clr, set);
--}
--
--static u32 mtk_gmac_read(struct mtk_eth_priv *priv, u32 reg)
--{
-- return readl(priv->gmac_base + reg);
--}
--
--static void mtk_gmac_write(struct mtk_eth_priv *priv, u32 reg, u32 val)
--{
-- writel(val, priv->gmac_base + reg);
--}
--
--static void mtk_gmac_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, u32 set)
--{
-- clrsetbits_le32(priv->gmac_base + reg, clr, set);
--}
--
--static void mtk_ethsys_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr,
-- u32 set)
--{
-- uint val;
--
-- regmap_read(priv->ethsys_regmap, reg, &val);
-- val &= ~clr;
-- val |= set;
-- regmap_write(priv->ethsys_regmap, reg, val);
--}
--
--static void mtk_infra_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr,
-- u32 set)
--{
-- uint val;
--
-- regmap_read(priv->infra_regmap, reg, &val);
-- val &= ~clr;
-- val |= set;
-- regmap_write(priv->infra_regmap, reg, val);
--}
--
--static u32 mtk_gsw_read(struct mtk_eth_priv *priv, u32 reg)
--{
-- return readl(priv->gsw_base + reg);
--}
--
--static void mtk_gsw_write(struct mtk_eth_priv *priv, u32 reg, u32 val)
--{
-- writel(val, priv->gsw_base + reg);
--}
--
--/* Direct MDIO clause 22/45 access via SoC */
--static int mtk_mii_rw(struct mtk_eth_priv *priv, u8 phy, u8 reg, u16 data,
-- u32 cmd, u32 st)
--{
-- int ret;
-- u32 val;
--
-- val = (st << MDIO_ST_S) |
-- ((cmd << MDIO_CMD_S) & MDIO_CMD_M) |
-- (((u32)phy << MDIO_PHY_ADDR_S) & MDIO_PHY_ADDR_M) |
-- (((u32)reg << MDIO_REG_ADDR_S) & MDIO_REG_ADDR_M);
--
-- if (cmd == MDIO_CMD_WRITE || cmd == MDIO_CMD_ADDR)
-- val |= data & MDIO_RW_DATA_M;
--
-- mtk_gmac_write(priv, GMAC_PIAC_REG, val | PHY_ACS_ST);
--
-- ret = wait_for_bit_le32(priv->gmac_base + GMAC_PIAC_REG,
-- PHY_ACS_ST, 0, 5000, 0);
-- if (ret) {
-- pr_warn("MDIO access timeout\n");
-- return ret;
-- }
--
-- if (cmd == MDIO_CMD_READ || cmd == MDIO_CMD_READ_C45) {
-- val = mtk_gmac_read(priv, GMAC_PIAC_REG);
-- return val & MDIO_RW_DATA_M;
-- }
--
-- return 0;
--}
--
--/* Direct MDIO clause 22 read via SoC */
--static int mtk_mii_read(struct mtk_eth_priv *priv, u8 phy, u8 reg)
--{
-- return mtk_mii_rw(priv, phy, reg, 0, MDIO_CMD_READ, MDIO_ST_C22);
--}
--
--/* Direct MDIO clause 22 write via SoC */
--static int mtk_mii_write(struct mtk_eth_priv *priv, u8 phy, u8 reg, u16 data)
--{
-- return mtk_mii_rw(priv, phy, reg, data, MDIO_CMD_WRITE, MDIO_ST_C22);
--}
--
--/* Direct MDIO clause 45 read via SoC */
--static int mtk_mmd_read(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg)
--{
-- int ret;
--
-- ret = mtk_mii_rw(priv, addr, devad, reg, MDIO_CMD_ADDR, MDIO_ST_C45);
-- if (ret)
-- return ret;
--
-- return mtk_mii_rw(priv, addr, devad, 0, MDIO_CMD_READ_C45,
-- MDIO_ST_C45);
--}
--
--/* Direct MDIO clause 45 write via SoC */
--static int mtk_mmd_write(struct mtk_eth_priv *priv, u8 addr, u8 devad,
-- u16 reg, u16 val)
--{
-- int ret;
--
-- ret = mtk_mii_rw(priv, addr, devad, reg, MDIO_CMD_ADDR, MDIO_ST_C45);
-- if (ret)
-- return ret;
--
-- return mtk_mii_rw(priv, addr, devad, val, MDIO_CMD_WRITE,
-- MDIO_ST_C45);
--}
--
--/* Indirect MDIO clause 45 read via MII registers */
--static int mtk_mmd_ind_read(struct mtk_eth_priv *priv, u8 addr, u8 devad,
-- u16 reg)
--{
-- int ret;
--
-- ret = priv->mii_write(priv, addr, MII_MMD_ACC_CTL_REG,
-- (MMD_ADDR << MMD_CMD_S) |
-- ((devad << MMD_DEVAD_S) & MMD_DEVAD_M));
-- if (ret)
-- return ret;
--
-- ret = priv->mii_write(priv, addr, MII_MMD_ADDR_DATA_REG, reg);
-- if (ret)
-- return ret;
--
-- ret = priv->mii_write(priv, addr, MII_MMD_ACC_CTL_REG,
-- (MMD_DATA << MMD_CMD_S) |
-- ((devad << MMD_DEVAD_S) & MMD_DEVAD_M));
-- if (ret)
-- return ret;
--
-- return priv->mii_read(priv, addr, MII_MMD_ADDR_DATA_REG);
--}
--
--/* Indirect MDIO clause 45 write via MII registers */
--static int mtk_mmd_ind_write(struct mtk_eth_priv *priv, u8 addr, u8 devad,
-- u16 reg, u16 val)
--{
-- int ret;
--
-- ret = priv->mii_write(priv, addr, MII_MMD_ACC_CTL_REG,
-- (MMD_ADDR << MMD_CMD_S) |
-- ((devad << MMD_DEVAD_S) & MMD_DEVAD_M));
-- if (ret)
-- return ret;
--
-- ret = priv->mii_write(priv, addr, MII_MMD_ADDR_DATA_REG, reg);
-- if (ret)
-- return ret;
--
-- ret = priv->mii_write(priv, addr, MII_MMD_ACC_CTL_REG,
-- (MMD_DATA << MMD_CMD_S) |
-- ((devad << MMD_DEVAD_S) & MMD_DEVAD_M));
-- if (ret)
-- return ret;
--
-- return priv->mii_write(priv, addr, MII_MMD_ADDR_DATA_REG, val);
--}
--
--/*
-- * MT7530 Internal Register Address Bits
-- * -------------------------------------------------------------------
-- * | 15 14 13 12 11 10 9 8 7 6 | 5 4 3 2 | 1 0 |
-- * |----------------------------------------|---------------|--------|
-- * | Page Address | Reg Address | Unused |
-- * -------------------------------------------------------------------
-- */
--
--static int mt753x_reg_read(struct mtk_eth_priv *priv, u32 reg, u32 *data)
--{
-- int ret, low_word, high_word;
--
-- if (priv->sw == SW_MT7988) {
-- *data = mtk_gsw_read(priv, reg);
-- return 0;
-- }
--
-- /* Write page address */
-- ret = mtk_mii_write(priv, priv->mt753x_smi_addr, 0x1f, reg >> 6);
-- if (ret)
-- return ret;
--
-- /* Read low word */
-- low_word = mtk_mii_read(priv, priv->mt753x_smi_addr, (reg >> 2) & 0xf);
-- if (low_word < 0)
-- return low_word;
--
-- /* Read high word */
-- high_word = mtk_mii_read(priv, priv->mt753x_smi_addr, 0x10);
-- if (high_word < 0)
-- return high_word;
--
-- if (data)
-- *data = ((u32)high_word << 16) | (low_word & 0xffff);
--
-- return 0;
--}
--
--static int mt753x_reg_write(struct mtk_eth_priv *priv, u32 reg, u32 data)
--{
-- int ret;
--
-- if (priv->sw == SW_MT7988) {
-- mtk_gsw_write(priv, reg, data);
-- return 0;
-- }
--
-- /* Write page address */
-- ret = mtk_mii_write(priv, priv->mt753x_smi_addr, 0x1f, reg >> 6);
-- if (ret)
-- return ret;
--
-- /* Write low word */
-- ret = mtk_mii_write(priv, priv->mt753x_smi_addr, (reg >> 2) & 0xf,
-- data & 0xffff);
-- if (ret)
-- return ret;
--
-- /* Write high word */
-- return mtk_mii_write(priv, priv->mt753x_smi_addr, 0x10, data >> 16);
--}
--
--static void mt753x_reg_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr,
-- u32 set)
--{
-- u32 val;
--
-- mt753x_reg_read(priv, reg, &val);
-- val &= ~clr;
-- val |= set;
-- mt753x_reg_write(priv, reg, val);
--}
--
--/* Indirect MDIO clause 22/45 access */
--static int mt7531_mii_rw(struct mtk_eth_priv *priv, int phy, int reg, u16 data,
-- u32 cmd, u32 st)
--{
-- ulong timeout;
-- u32 val, timeout_ms;
-- int ret = 0;
--
-- val = (st << MDIO_ST_S) |
-- ((cmd << MDIO_CMD_S) & MDIO_CMD_M) |
-- ((phy << MDIO_PHY_ADDR_S) & MDIO_PHY_ADDR_M) |
-- ((reg << MDIO_REG_ADDR_S) & MDIO_REG_ADDR_M);
--
-- if (cmd == MDIO_CMD_WRITE || cmd == MDIO_CMD_ADDR)
-- val |= data & MDIO_RW_DATA_M;
--
-- mt753x_reg_write(priv, MT7531_PHY_IAC, val | PHY_ACS_ST);
--
-- timeout_ms = 100;
-- timeout = get_timer(0);
-- while (1) {
-- mt753x_reg_read(priv, MT7531_PHY_IAC, &val);
--
-- if ((val & PHY_ACS_ST) == 0)
-- break;
--
-- if (get_timer(timeout) > timeout_ms)
-- return -ETIMEDOUT;
-- }
--
-- if (cmd == MDIO_CMD_READ || cmd == MDIO_CMD_READ_C45) {
-- mt753x_reg_read(priv, MT7531_PHY_IAC, &val);
-- ret = val & MDIO_RW_DATA_M;
-- }
--
-- return ret;
--}
--
--static int mt7531_mii_ind_read(struct mtk_eth_priv *priv, u8 phy, u8 reg)
--{
-- u8 phy_addr;
--
-- if (phy >= MT753X_NUM_PHYS)
-- return -EINVAL;
--
-- phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, phy);
--
-- return mt7531_mii_rw(priv, phy_addr, reg, 0, MDIO_CMD_READ,
-- MDIO_ST_C22);
--}
--
--static int mt7531_mii_ind_write(struct mtk_eth_priv *priv, u8 phy, u8 reg,
-- u16 val)
--{
-- u8 phy_addr;
--
-- if (phy >= MT753X_NUM_PHYS)
-- return -EINVAL;
--
-- phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, phy);
--
-- return mt7531_mii_rw(priv, phy_addr, reg, val, MDIO_CMD_WRITE,
-- MDIO_ST_C22);
--}
--
--static int mt7531_mmd_ind_read(struct mtk_eth_priv *priv, u8 addr, u8 devad,
-- u16 reg)
--{
-- u8 phy_addr;
-- int ret;
--
-- if (addr >= MT753X_NUM_PHYS)
-- return -EINVAL;
--
-- phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, addr);
--
-- ret = mt7531_mii_rw(priv, phy_addr, devad, reg, MDIO_CMD_ADDR,
-- MDIO_ST_C45);
-- if (ret)
-- return ret;
--
-- return mt7531_mii_rw(priv, phy_addr, devad, 0, MDIO_CMD_READ_C45,
-- MDIO_ST_C45);
--}
--
--static int mt7531_mmd_ind_write(struct mtk_eth_priv *priv, u8 addr, u8 devad,
-- u16 reg, u16 val)
--{
-- u8 phy_addr;
-- int ret;
--
-- if (addr >= MT753X_NUM_PHYS)
-- return 0;
--
-- phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, addr);
--
-- ret = mt7531_mii_rw(priv, phy_addr, devad, reg, MDIO_CMD_ADDR,
-- MDIO_ST_C45);
-- if (ret)
-- return ret;
--
-- return mt7531_mii_rw(priv, phy_addr, devad, val, MDIO_CMD_WRITE,
-- MDIO_ST_C45);
--}
--
--static int mtk_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
--{
-- struct mtk_eth_priv *priv = bus->priv;
--
-- if (devad < 0)
-- return priv->mii_read(priv, addr, reg);
-- else
-- return priv->mmd_read(priv, addr, devad, reg);
--}
--
--static int mtk_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
-- u16 val)
--{
-- struct mtk_eth_priv *priv = bus->priv;
--
-- if (devad < 0)
-- return priv->mii_write(priv, addr, reg, val);
-- else
-- return priv->mmd_write(priv, addr, devad, reg, val);
--}
--
--static int mtk_mdio_register(struct udevice *dev)
--{
-- struct mtk_eth_priv *priv = dev_get_priv(dev);
-- struct mii_dev *mdio_bus = mdio_alloc();
-- int ret;
--
-- if (!mdio_bus)
-- return -ENOMEM;
--
-- /* Assign MDIO access APIs according to the switch/phy */
-- switch (priv->sw) {
-- case SW_MT7530:
-- priv->mii_read = mtk_mii_read;
-- priv->mii_write = mtk_mii_write;
-- priv->mmd_read = mtk_mmd_ind_read;
-- priv->mmd_write = mtk_mmd_ind_write;
-- break;
-- case SW_MT7531:
-- case SW_MT7988:
-- priv->mii_read = mt7531_mii_ind_read;
-- priv->mii_write = mt7531_mii_ind_write;
-- priv->mmd_read = mt7531_mmd_ind_read;
-- priv->mmd_write = mt7531_mmd_ind_write;
-- break;
-- default:
-- priv->mii_read = mtk_mii_read;
-- priv->mii_write = mtk_mii_write;
-- priv->mmd_read = mtk_mmd_read;
-- priv->mmd_write = mtk_mmd_write;
-- }
--
-- mdio_bus->read = mtk_mdio_read;
-- mdio_bus->write = mtk_mdio_write;
-- snprintf(mdio_bus->name, sizeof(mdio_bus->name), dev->name);
--
-- mdio_bus->priv = (void *)priv;
--
-- ret = mdio_register(mdio_bus);
--
-- if (ret)
-- return ret;
--
-- priv->mdio_bus = mdio_bus;
--
-- return 0;
--}
--
--static int mt753x_core_reg_read(struct mtk_eth_priv *priv, u32 reg)
--{
-- u8 phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, 0);
--
-- return priv->mmd_read(priv, phy_addr, 0x1f, reg);
--}
--
--static void mt753x_core_reg_write(struct mtk_eth_priv *priv, u32 reg, u32 val)
--{
-- u8 phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, 0);
--
-- priv->mmd_write(priv, phy_addr, 0x1f, reg, val);
--}
--
--static int mt7530_pad_clk_setup(struct mtk_eth_priv *priv, int mode)
--{
-- u32 ncpo1, ssc_delta;
--
-- switch (mode) {
-- case PHY_INTERFACE_MODE_RGMII:
-- ncpo1 = 0x0c80;
-- ssc_delta = 0x87;
-- break;
-- default:
-- printf("error: xMII mode %d not supported\n", mode);
-- return -EINVAL;
-- }
--
-- /* Disable MT7530 core clock */
-- mt753x_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG, 0);
--
-- /* Disable MT7530 PLL */
-- mt753x_core_reg_write(priv, CORE_GSWPLL_GRP1,
-- (2 << RG_GSWPLL_POSDIV_200M_S) |
-- (32 << RG_GSWPLL_FBKDIV_200M_S));
--
-- /* For MT7530 core clock = 500Mhz */
-- mt753x_core_reg_write(priv, CORE_GSWPLL_GRP2,
-- (1 << RG_GSWPLL_POSDIV_500M_S) |
-- (25 << RG_GSWPLL_FBKDIV_500M_S));
--
-- /* Enable MT7530 PLL */
-- mt753x_core_reg_write(priv, CORE_GSWPLL_GRP1,
-- (2 << RG_GSWPLL_POSDIV_200M_S) |
-- (32 << RG_GSWPLL_FBKDIV_200M_S) |
-- RG_GSWPLL_EN_PRE);
--
-- udelay(20);
--
-- mt753x_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
--
-- /* Setup the MT7530 TRGMII Tx Clock */
-- mt753x_core_reg_write(priv, CORE_PLL_GROUP5, ncpo1);
-- mt753x_core_reg_write(priv, CORE_PLL_GROUP6, 0);
-- mt753x_core_reg_write(priv, CORE_PLL_GROUP10, ssc_delta);
-- mt753x_core_reg_write(priv, CORE_PLL_GROUP11, ssc_delta);
-- mt753x_core_reg_write(priv, CORE_PLL_GROUP4, RG_SYSPLL_DDSFBK_EN |
-- RG_SYSPLL_BIAS_EN | RG_SYSPLL_BIAS_LPF_EN);
--
-- mt753x_core_reg_write(priv, CORE_PLL_GROUP2,
-- RG_SYSPLL_EN_NORMAL | RG_SYSPLL_VODEN |
-- (1 << RG_SYSPLL_POSDIV_S));
--
-- mt753x_core_reg_write(priv, CORE_PLL_GROUP7,
-- RG_LCDDS_PCW_NCPO_CHG | (3 << RG_LCCDS_C_S) |
-- RG_LCDDS_PWDB | RG_LCDDS_ISO_EN);
--
-- /* Enable MT7530 core clock */
-- mt753x_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG,
-- REG_GSWCK_EN | REG_TRGMIICK_EN);
--
-- return 0;
--}
--
--static void mt7530_mac_control(struct mtk_eth_priv *priv, bool enable)
--{
-- u32 pmcr = FORCE_MODE;
--
-- if (enable)
-- pmcr = priv->mt753x_pmcr;
--
-- mt753x_reg_write(priv, PMCR_REG(6), pmcr);
--}
--
--static int mt7530_setup(struct mtk_eth_priv *priv)
--{
-- u16 phy_addr, phy_val;
-- u32 val, txdrv;
-- int i;
--
-- if (!MTK_HAS_CAPS(priv->soc->caps, MTK_TRGMII_MT7621_CLK)) {
-- /* Select 250MHz clk for RGMII mode */
-- mtk_ethsys_rmw(priv, ETHSYS_CLKCFG0_REG,
-- ETHSYS_TRGMII_CLK_SEL362_5, 0);
--
-- txdrv = 8;
-- } else {
-- txdrv = 4;
-- }
--
-- /* Modify HWTRAP first to allow direct access to internal PHYs */
-- mt753x_reg_read(priv, HWTRAP_REG, &val);
-- val |= CHG_TRAP;
-- val &= ~C_MDIO_BPS;
-- mt753x_reg_write(priv, MHWTRAP_REG, val);
--
-- /* Calculate the phy base address */
-- val = ((val & SMI_ADDR_M) >> SMI_ADDR_S) << 3;
-- priv->mt753x_phy_base = (val | 0x7) + 1;
--
-- /* Turn off PHYs */
-- for (i = 0; i < MT753X_NUM_PHYS; i++) {
-- phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, i);
-- phy_val = priv->mii_read(priv, phy_addr, MII_BMCR);
-- phy_val |= BMCR_PDOWN;
-- priv->mii_write(priv, phy_addr, MII_BMCR, phy_val);
-- }
--
-- /* Force MAC link down before reset */
-- mt753x_reg_write(priv, PMCR_REG(5), FORCE_MODE);
-- mt753x_reg_write(priv, PMCR_REG(6), FORCE_MODE);
--
-- /* MT7530 reset */
-- mt753x_reg_write(priv, SYS_CTRL_REG, SW_SYS_RST | SW_REG_RST);
-- udelay(100);
--
-- val = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) |
-- MAC_MODE | FORCE_MODE |
-- MAC_TX_EN | MAC_RX_EN |
-- BKOFF_EN | BACKPR_EN |
-- (SPEED_1000M << FORCE_SPD_S) |
-- FORCE_DPX | FORCE_LINK;
--
-- /* MT7530 Port6: Forced 1000M/FD, FC disabled */
-- priv->mt753x_pmcr = val;
--
-- /* MT7530 Port5: Forced link down */
-- mt753x_reg_write(priv, PMCR_REG(5), FORCE_MODE);
--
-- /* Keep MAC link down before starting eth */
-- mt753x_reg_write(priv, PMCR_REG(6), FORCE_MODE);
--
-- /* MT7530 Port6: Set to RGMII */
-- mt753x_reg_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_M, P6_INTF_MODE_RGMII);
--
-- /* Hardware Trap: Enable Port6, Disable Port5 */
-- mt753x_reg_read(priv, HWTRAP_REG, &val);
-- val |= CHG_TRAP | LOOPDET_DIS | P5_INTF_DIS |
-- (P5_INTF_SEL_GMAC5 << P5_INTF_SEL_S) |
-- (P5_INTF_MODE_RGMII << P5_INTF_MODE_S);
-- val &= ~(C_MDIO_BPS | P6_INTF_DIS);
-- mt753x_reg_write(priv, MHWTRAP_REG, val);
--
-- /* Setup switch core pll */
-- mt7530_pad_clk_setup(priv, priv->phy_interface);
--
-- /* Lower Tx Driving for TRGMII path */
-- for (i = 0 ; i < NUM_TRGMII_CTRL ; i++)
-- mt753x_reg_write(priv, MT7530_TRGMII_TD_ODT(i),
-- (txdrv << TD_DM_DRVP_S) |
-- (txdrv << TD_DM_DRVN_S));
--
-- for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
-- mt753x_reg_rmw(priv, MT7530_TRGMII_RD(i), RD_TAP_M, 16);
--
-- /* Turn on PHYs */
-- for (i = 0; i < MT753X_NUM_PHYS; i++) {
-- phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, i);
-- phy_val = priv->mii_read(priv, phy_addr, MII_BMCR);
-- phy_val &= ~BMCR_PDOWN;
-- priv->mii_write(priv, phy_addr, MII_BMCR, phy_val);
-- }
--
-- return 0;
--}
--
--static void mt7531_core_pll_setup(struct mtk_eth_priv *priv, int mcm)
--{
-- /* Step 1 : Disable MT7531 COREPLL */
-- mt753x_reg_rmw(priv, MT7531_PLLGP_EN, EN_COREPLL, 0);
--
-- /* Step 2: switch to XTAL output */
-- mt753x_reg_rmw(priv, MT7531_PLLGP_EN, SW_CLKSW, SW_CLKSW);
--
-- mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_EN, 0);
--
-- /* Step 3: disable PLLGP and enable program PLLGP */
-- mt753x_reg_rmw(priv, MT7531_PLLGP_EN, SW_PLLGP, SW_PLLGP);
--
-- /* Step 4: program COREPLL output frequency to 500MHz */
-- mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_POSDIV_M,
-- 2 << RG_COREPLL_POSDIV_S);
-- udelay(25);
--
-- /* Currently, support XTAL 25Mhz only */
-- mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_SDM_PCW_M,
-- 0x140000 << RG_COREPLL_SDM_PCW_S);
--
-- /* Set feedback divide ratio update signal to high */
-- mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_SDM_PCW_CHG,
-- RG_COREPLL_SDM_PCW_CHG);
--
-- /* Wait for at least 16 XTAL clocks */
-- udelay(10);
--
-- /* Step 5: set feedback divide ratio update signal to low */
-- mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_SDM_PCW_CHG, 0);
--
-- /* add enable 325M clock for SGMII */
-- mt753x_reg_write(priv, MT7531_ANA_PLLGP_CR5, 0xad0000);
--
-- /* add enable 250SSC clock for RGMII */
-- mt753x_reg_write(priv, MT7531_ANA_PLLGP_CR2, 0x4f40000);
--
-- /*Step 6: Enable MT7531 PLL */
-- mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_EN, RG_COREPLL_EN);
--
-- mt753x_reg_rmw(priv, MT7531_PLLGP_EN, EN_COREPLL, EN_COREPLL);
--
-- udelay(25);
--}
--
--static int mt7531_port_sgmii_init(struct mtk_eth_priv *priv,
-- u32 port)
--{
-- if (port != 5 && port != 6) {
-- printf("mt7531: port %d is not a SGMII port\n", port);
-- return -EINVAL;
-- }
--
-- /* Set SGMII GEN2 speed(2.5G) */
-- mt753x_reg_rmw(priv, MT7531_PHYA_CTRL_SIGNAL3(port), SGMSYS_SPEED_MASK,
-- FIELD_PREP(SGMSYS_SPEED_MASK, SGMSYS_SPEED_2500));
--
-- /* Disable SGMII AN */
-- mt753x_reg_rmw(priv, MT7531_PCS_CONTROL_1(port),
-- SGMII_AN_ENABLE, 0);
--
-- /* SGMII force mode setting */
-- mt753x_reg_write(priv, MT7531_SGMII_MODE(port), SGMII_FORCE_MODE);
--
-- /* Release PHYA power down state */
-- mt753x_reg_rmw(priv, MT7531_QPHY_PWR_STATE_CTRL(port),
-- SGMII_PHYA_PWD, 0);
--
-- return 0;
--}
--
--static int mt7531_port_rgmii_init(struct mtk_eth_priv *priv, u32 port)
--{
-- u32 val;
--
-- if (port != 5) {
-- printf("error: RGMII mode is not available for port %d\n",
-- port);
-- return -EINVAL;
-- }
--
-- mt753x_reg_read(priv, MT7531_CLKGEN_CTRL, &val);
-- val |= GP_CLK_EN;
-- val &= ~GP_MODE_M;
-- val |= GP_MODE_RGMII << GP_MODE_S;
-- val |= TXCLK_NO_REVERSE;
-- val |= RXCLK_NO_DELAY;
-- val &= ~CLK_SKEW_IN_M;
-- val |= CLK_SKEW_IN_NO_CHANGE << CLK_SKEW_IN_S;
-- val &= ~CLK_SKEW_OUT_M;
-- val |= CLK_SKEW_OUT_NO_CHANGE << CLK_SKEW_OUT_S;
-- mt753x_reg_write(priv, MT7531_CLKGEN_CTRL, val);
--
-- return 0;
--}
--
--static void mt7531_phy_setting(struct mtk_eth_priv *priv)
--{
-- int i;
-- u32 val;
--
-- for (i = 0; i < MT753X_NUM_PHYS; i++) {
-- /* Enable HW auto downshift */
-- priv->mii_write(priv, i, 0x1f, 0x1);
-- val = priv->mii_read(priv, i, PHY_EXT_REG_14);
-- val |= PHY_EN_DOWN_SHFIT;
-- priv->mii_write(priv, i, PHY_EXT_REG_14, val);
--
-- /* PHY link down power saving enable */
-- val = priv->mii_read(priv, i, PHY_EXT_REG_17);
-- val |= PHY_LINKDOWN_POWER_SAVING_EN;
-- priv->mii_write(priv, i, PHY_EXT_REG_17, val);
--
-- val = priv->mmd_read(priv, i, 0x1e, PHY_DEV1E_REG_0C6);
-- val &= ~PHY_POWER_SAVING_M;
-- val |= PHY_POWER_SAVING_TX << PHY_POWER_SAVING_S;
-- priv->mmd_write(priv, i, 0x1e, PHY_DEV1E_REG_0C6, val);
-- }
--}
--
--static void mt7531_mac_control(struct mtk_eth_priv *priv, bool enable)
--{
-- u32 pmcr = FORCE_MODE_LNK;
--
-- if (enable)
-- pmcr = priv->mt753x_pmcr;
--
-- mt753x_reg_write(priv, PMCR_REG(5), pmcr);
-- mt753x_reg_write(priv, PMCR_REG(6), pmcr);
--}
--
--static int mt7531_setup(struct mtk_eth_priv *priv)
--{
-- u16 phy_addr, phy_val;
-- u32 val;
-- u32 pmcr;
-- u32 port5_sgmii;
-- int i;
--
-- priv->mt753x_phy_base = (priv->mt753x_smi_addr + 1) &
-- MT753X_SMI_ADDR_MASK;
--
-- /* Turn off PHYs */
-- for (i = 0; i < MT753X_NUM_PHYS; i++) {
-- phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, i);
-- phy_val = priv->mii_read(priv, phy_addr, MII_BMCR);
-- phy_val |= BMCR_PDOWN;
-- priv->mii_write(priv, phy_addr, MII_BMCR, phy_val);
-- }
--
-- /* Force MAC link down before reset */
-- mt753x_reg_write(priv, PMCR_REG(5), FORCE_MODE_LNK);
-- mt753x_reg_write(priv, PMCR_REG(6), FORCE_MODE_LNK);
--
-- /* Switch soft reset */
-- mt753x_reg_write(priv, SYS_CTRL_REG, SW_SYS_RST | SW_REG_RST);
-- udelay(100);
--
-- /* Enable MDC input Schmitt Trigger */
-- mt753x_reg_rmw(priv, MT7531_SMT0_IOLB, SMT_IOLB_5_SMI_MDC_EN,
-- SMT_IOLB_5_SMI_MDC_EN);
--
-- mt7531_core_pll_setup(priv, priv->mcm);
--
-- mt753x_reg_read(priv, MT7531_TOP_SIG_SR, &val);
-- port5_sgmii = !!(val & PAD_DUAL_SGMII_EN);
--
-- /* port5 support either RGMII or SGMII, port6 only support SGMII. */
-- switch (priv->phy_interface) {
-- case PHY_INTERFACE_MODE_RGMII:
-- if (!port5_sgmii)
-- mt7531_port_rgmii_init(priv, 5);
-- break;
-- case PHY_INTERFACE_MODE_2500BASEX:
-- mt7531_port_sgmii_init(priv, 6);
-- if (port5_sgmii)
-- mt7531_port_sgmii_init(priv, 5);
-- break;
-- default:
-- break;
-- }
--
-- pmcr = MT7531_FORCE_MODE |
-- (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) |
-- MAC_MODE | MAC_TX_EN | MAC_RX_EN |
-- BKOFF_EN | BACKPR_EN |
-- FORCE_RX_FC | FORCE_TX_FC |
-- (SPEED_1000M << FORCE_SPD_S) | FORCE_DPX |
-- FORCE_LINK;
--
-- priv->mt753x_pmcr = pmcr;
--
-- /* Keep MAC link down before starting eth */
-- mt753x_reg_write(priv, PMCR_REG(5), FORCE_MODE_LNK);
-- mt753x_reg_write(priv, PMCR_REG(6), FORCE_MODE_LNK);
--
-- /* Turn on PHYs */
-- for (i = 0; i < MT753X_NUM_PHYS; i++) {
-- phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, i);
-- phy_val = priv->mii_read(priv, phy_addr, MII_BMCR);
-- phy_val &= ~BMCR_PDOWN;
-- priv->mii_write(priv, phy_addr, MII_BMCR, phy_val);
-- }
--
-- mt7531_phy_setting(priv);
--
-- /* Enable Internal PHYs */
-- val = mt753x_core_reg_read(priv, CORE_PLL_GROUP4);
-- val |= MT7531_BYPASS_MODE;
-- val &= ~MT7531_POWER_ON_OFF;
-- mt753x_core_reg_write(priv, CORE_PLL_GROUP4, val);
--
-- return 0;
--}
--
--static void mt7988_phy_setting(struct mtk_eth_priv *priv)
--{
-- u16 val;
-- u32 i;
--
-- for (i = 0; i < MT753X_NUM_PHYS; i++) {
-- /* Enable HW auto downshift */
-- priv->mii_write(priv, i, 0x1f, 0x1);
-- val = priv->mii_read(priv, i, PHY_EXT_REG_14);
-- val |= PHY_EN_DOWN_SHFIT;
-- priv->mii_write(priv, i, PHY_EXT_REG_14, val);
--
-- /* PHY link down power saving enable */
-- val = priv->mii_read(priv, i, PHY_EXT_REG_17);
-- val |= PHY_LINKDOWN_POWER_SAVING_EN;
-- priv->mii_write(priv, i, PHY_EXT_REG_17, val);
-- }
--}
--
--static void mt7988_mac_control(struct mtk_eth_priv *priv, bool enable)
--{
-- u32 pmcr = FORCE_MODE_LNK;
--
-- if (enable)
-- pmcr = priv->mt753x_pmcr;
--
-- mt753x_reg_write(priv, PMCR_REG(6), pmcr);
--}
--
--static int mt7988_setup(struct mtk_eth_priv *priv)
--{
-- u16 phy_addr, phy_val;
-- u32 pmcr;
-- int i;
--
-- priv->gsw_base = regmap_get_range(priv->ethsys_regmap, 0) + GSW_BASE;
--
-- priv->mt753x_phy_base = (priv->mt753x_smi_addr + 1) &
-- MT753X_SMI_ADDR_MASK;
--
-- /* Turn off PHYs */
-- for (i = 0; i < MT753X_NUM_PHYS; i++) {
-- phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, i);
-- phy_val = priv->mii_read(priv, phy_addr, MII_BMCR);
-- phy_val |= BMCR_PDOWN;
-- priv->mii_write(priv, phy_addr, MII_BMCR, phy_val);
-- }
--
-- switch (priv->phy_interface) {
-- case PHY_INTERFACE_MODE_USXGMII:
-- /* Use CPU bridge instead of actual USXGMII path */
--
-- /* Set GDM1 no drop */
-- mtk_fe_rmw(priv, PSE_NO_DROP_CFG_REG, 0, PSE_NO_DROP_GDM1);
--
-- /* Enable GDM1 to GSW CPU bridge */
-- mtk_gmac_rmw(priv, GMAC_MAC_MISC_REG, 0, BIT(0));
--
-- /* XGMAC force link up */
-- mtk_gmac_rmw(priv, GMAC_XGMAC_STS_REG, 0, P1_XGMAC_FORCE_LINK);
--
-- /* Setup GSW CPU bridge IPG */
-- mtk_gmac_rmw(priv, GMAC_GSW_CFG_REG, GSWTX_IPG_M | GSWRX_IPG_M,
-- (0xB << GSWTX_IPG_S) | (0xB << GSWRX_IPG_S));
-- break;
-- default:
-- printf("Error: MT7988 GSW does not support %s interface\n",
-- phy_string_for_interface(priv->phy_interface));
-- break;
-- }
--
-- pmcr = MT7988_FORCE_MODE |
-- (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) |
-- MAC_MODE | MAC_TX_EN | MAC_RX_EN |
-- BKOFF_EN | BACKPR_EN |
-- FORCE_RX_FC | FORCE_TX_FC |
-- (SPEED_1000M << FORCE_SPD_S) | FORCE_DPX |
-- FORCE_LINK;
--
-- priv->mt753x_pmcr = pmcr;
--
-- /* Keep MAC link down before starting eth */
-- mt753x_reg_write(priv, PMCR_REG(6), FORCE_MODE_LNK);
--
-- /* Turn on PHYs */
-- for (i = 0; i < MT753X_NUM_PHYS; i++) {
-- phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, i);
-- phy_val = priv->mii_read(priv, phy_addr, MII_BMCR);
-- phy_val &= ~BMCR_PDOWN;
-- priv->mii_write(priv, phy_addr, MII_BMCR, phy_val);
-- }
--
-- mt7988_phy_setting(priv);
--
-- return 0;
--}
--
--static int mt753x_switch_init(struct mtk_eth_priv *priv)
--{
-- int ret;
-- int i;
--
-- /* Global reset switch */
-- if (priv->mcm) {
-- reset_assert(&priv->rst_mcm);
-- udelay(1000);
-- reset_deassert(&priv->rst_mcm);
-- mdelay(priv->mt753x_reset_wait_time);
-- } else if (dm_gpio_is_valid(&priv->rst_gpio)) {
-- dm_gpio_set_value(&priv->rst_gpio, 0);
-- udelay(1000);
-- dm_gpio_set_value(&priv->rst_gpio, 1);
-- mdelay(priv->mt753x_reset_wait_time);
-- }
--
-- ret = priv->switch_init(priv);
-- if (ret)
-- return ret;
--
-- /* Set port isolation */
-- for (i = 0; i < MT753X_NUM_PORTS; i++) {
-- /* Set port matrix mode */
-- if (i != 6)
-- mt753x_reg_write(priv, PCR_REG(i),
-- (0x40 << PORT_MATRIX_S));
-- else
-- mt753x_reg_write(priv, PCR_REG(i),
-- (0x3f << PORT_MATRIX_S));
--
-- /* Set port mode to user port */
-- mt753x_reg_write(priv, PVC_REG(i),
-- (0x8100 << STAG_VPID_S) |
-- (VLAN_ATTR_USER << VLAN_ATTR_S));
-- }
--
-- return 0;
--}
--
--static void mtk_xphy_link_adjust(struct mtk_eth_priv *priv)
--{
-- u16 lcl_adv = 0, rmt_adv = 0;
-- u8 flowctrl;
-- u32 mcr;
--
-- mcr = mtk_gmac_read(priv, XGMAC_PORT_MCR(priv->gmac_id));
-- mcr &= ~(XGMAC_FORCE_TX_FC | XGMAC_FORCE_RX_FC);
--
-- if (priv->phydev->duplex) {
-- if (priv->phydev->pause)
-- rmt_adv = LPA_PAUSE_CAP;
-- if (priv->phydev->asym_pause)
-- rmt_adv |= LPA_PAUSE_ASYM;
--
-- if (priv->phydev->advertising & ADVERTISED_Pause)
-- lcl_adv |= ADVERTISE_PAUSE_CAP;
-- if (priv->phydev->advertising & ADVERTISED_Asym_Pause)
-- lcl_adv |= ADVERTISE_PAUSE_ASYM;
--
-- flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
--
-- if (flowctrl & FLOW_CTRL_TX)
-- mcr |= XGMAC_FORCE_TX_FC;
-- if (flowctrl & FLOW_CTRL_RX)
-- mcr |= XGMAC_FORCE_RX_FC;
--
-- debug("rx pause %s, tx pause %s\n",
-- flowctrl & FLOW_CTRL_RX ? "enabled" : "disabled",
-- flowctrl & FLOW_CTRL_TX ? "enabled" : "disabled");
-- }
--
-- mcr &= ~(XGMAC_TRX_DISABLE);
-- mtk_gmac_write(priv, XGMAC_PORT_MCR(priv->gmac_id), mcr);
--}
--
--static void mtk_phy_link_adjust(struct mtk_eth_priv *priv)
--{
-- u16 lcl_adv = 0, rmt_adv = 0;
-- u8 flowctrl;
-- u32 mcr;
--
-- mcr = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) |
-- (MAC_RX_PKT_LEN_1536 << MAC_RX_PKT_LEN_S) |
-- MAC_MODE | FORCE_MODE |
-- MAC_TX_EN | MAC_RX_EN |
-- DEL_RXFIFO_CLR |
-- BKOFF_EN | BACKPR_EN;
--
-- switch (priv->phydev->speed) {
-- case SPEED_10:
-- mcr |= (SPEED_10M << FORCE_SPD_S);
-- break;
-- case SPEED_100:
-- mcr |= (SPEED_100M << FORCE_SPD_S);
-- break;
-- case SPEED_1000:
-- case SPEED_2500:
-- mcr |= (SPEED_1000M << FORCE_SPD_S);
-- break;
-- };
--
-- if (priv->phydev->link)
-- mcr |= FORCE_LINK;
--
-- if (priv->phydev->duplex) {
-- mcr |= FORCE_DPX;
--
-- if (priv->phydev->pause)
-- rmt_adv = LPA_PAUSE_CAP;
-- if (priv->phydev->asym_pause)
-- rmt_adv |= LPA_PAUSE_ASYM;
--
-- if (priv->phydev->advertising & ADVERTISED_Pause)
-- lcl_adv |= ADVERTISE_PAUSE_CAP;
-- if (priv->phydev->advertising & ADVERTISED_Asym_Pause)
-- lcl_adv |= ADVERTISE_PAUSE_ASYM;
--
-- flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
--
-- if (flowctrl & FLOW_CTRL_TX)
-- mcr |= FORCE_TX_FC;
-- if (flowctrl & FLOW_CTRL_RX)
-- mcr |= FORCE_RX_FC;
--
-- debug("rx pause %s, tx pause %s\n",
-- flowctrl & FLOW_CTRL_RX ? "enabled" : "disabled",
-- flowctrl & FLOW_CTRL_TX ? "enabled" : "disabled");
-- }
--
-- mtk_gmac_write(priv, GMAC_PORT_MCR(priv->gmac_id), mcr);
--}
--
--static int mtk_phy_start(struct mtk_eth_priv *priv)
--{
-- struct phy_device *phydev = priv->phydev;
-- int ret;
--
-- ret = phy_startup(phydev);
--
-- if (ret) {
-- debug("Could not initialize PHY %s\n", phydev->dev->name);
-- return ret;
-- }
--
-- if (!phydev->link) {
-- debug("%s: link down.\n", phydev->dev->name);
-- return 0;
-- }
--
-- if (!priv->force_mode) {
-- if (priv->phy_interface == PHY_INTERFACE_MODE_USXGMII ||
-- priv->phy_interface == PHY_INTERFACE_MODE_10GBASER ||
-- priv->phy_interface == PHY_INTERFACE_MODE_XGMII)
-- mtk_xphy_link_adjust(priv);
-- else
-- mtk_phy_link_adjust(priv);
-- }
--
-- debug("Speed: %d, %s duplex%s\n", phydev->speed,
-- (phydev->duplex) ? "full" : "half",
-- (phydev->port == PORT_FIBRE) ? ", fiber mode" : "");
--
-- return 0;
--}
--
--static int mtk_phy_probe(struct udevice *dev)
--{
-- struct mtk_eth_priv *priv = dev_get_priv(dev);
-- struct phy_device *phydev;
--
-- phydev = phy_connect(priv->mdio_bus, priv->phy_addr, dev,
-- priv->phy_interface);
-- if (!phydev)
-- return -ENODEV;
--
-- phydev->supported &= PHY_GBIT_FEATURES;
-- phydev->advertising = phydev->supported;
--
-- priv->phydev = phydev;
-- phy_config(phydev);
--
-- return 0;
--}
--
--static void mtk_sgmii_an_init(struct mtk_eth_priv *priv)
--{
-- /* Set SGMII GEN1 speed(1G) */
-- clrbits_le32(priv->sgmii_base + priv->soc->ana_rgc3, SGMSYS_SPEED_MASK);
--
-- /* Enable SGMII AN */
-- setbits_le32(priv->sgmii_base + SGMSYS_PCS_CONTROL_1,
-- SGMII_AN_ENABLE);
--
-- /* SGMII AN mode setting */
-- writel(SGMII_AN_MODE, priv->sgmii_base + SGMSYS_SGMII_MODE);
--
-- /* SGMII PN SWAP setting */
-- if (priv->pn_swap) {
-- setbits_le32(priv->sgmii_base + SGMSYS_QPHY_WRAP_CTRL,
-- SGMII_PN_SWAP_TX_RX);
-- }
--
-- /* Release PHYA power down state */
-- clrsetbits_le32(priv->sgmii_base + SGMSYS_QPHY_PWR_STATE_CTRL,
-- SGMII_PHYA_PWD, 0);
--}
--
--static void mtk_sgmii_force_init(struct mtk_eth_priv *priv)
--{
-- /* Set SGMII GEN2 speed(2.5G) */
-- clrsetbits_le32(priv->sgmii_base + priv->soc->ana_rgc3,
-- SGMSYS_SPEED_MASK,
-- FIELD_PREP(SGMSYS_SPEED_MASK, SGMSYS_SPEED_2500));
--
-- /* Disable SGMII AN */
-- clrsetbits_le32(priv->sgmii_base + SGMSYS_PCS_CONTROL_1,
-- SGMII_AN_ENABLE, 0);
--
-- /* SGMII force mode setting */
-- writel(SGMII_FORCE_MODE, priv->sgmii_base + SGMSYS_SGMII_MODE);
--
-- /* SGMII PN SWAP setting */
-- if (priv->pn_swap) {
-- setbits_le32(priv->sgmii_base + SGMSYS_QPHY_WRAP_CTRL,
-- SGMII_PN_SWAP_TX_RX);
-- }
--
-- /* Release PHYA power down state */
-- clrsetbits_le32(priv->sgmii_base + SGMSYS_QPHY_PWR_STATE_CTRL,
-- SGMII_PHYA_PWD, 0);
--}
--
--static void mtk_xfi_pll_enable(struct mtk_eth_priv *priv)
--{
-- u32 val = 0;
--
-- /* Add software workaround for USXGMII PLL TCL issue */
-- regmap_write(priv->xfi_pll_regmap, XFI_PLL_ANA_GLB8,
-- RG_XFI_PLL_ANA_SWWA);
--
-- regmap_read(priv->xfi_pll_regmap, XFI_PLL_DIG_GLB8, &val);
-- val |= RG_XFI_PLL_EN;
-- regmap_write(priv->xfi_pll_regmap, XFI_PLL_DIG_GLB8, val);
--}
--
--static void mtk_usxgmii_reset(struct mtk_eth_priv *priv)
--{
-- switch (priv->gmac_id) {
-- case 1:
-- regmap_write(priv->toprgu_regmap, 0xFC, 0x0000A004);
-- regmap_write(priv->toprgu_regmap, 0x18, 0x88F0A004);
-- regmap_write(priv->toprgu_regmap, 0xFC, 0x00000000);
-- regmap_write(priv->toprgu_regmap, 0x18, 0x88F00000);
-- regmap_write(priv->toprgu_regmap, 0x18, 0x00F00000);
-- break;
-- case 2:
-- regmap_write(priv->toprgu_regmap, 0xFC, 0x00005002);
-- regmap_write(priv->toprgu_regmap, 0x18, 0x88F05002);
-- regmap_write(priv->toprgu_regmap, 0xFC, 0x00000000);
-- regmap_write(priv->toprgu_regmap, 0x18, 0x88F00000);
-- regmap_write(priv->toprgu_regmap, 0x18, 0x00F00000);
-- break;
-- }
--
-- mdelay(10);
--}
--
--static void mtk_usxgmii_setup_phya_an_10000(struct mtk_eth_priv *priv)
--{
-- regmap_write(priv->usxgmii_regmap, 0x810, 0x000FFE6D);
-- regmap_write(priv->usxgmii_regmap, 0x818, 0x07B1EC7B);
-- regmap_write(priv->usxgmii_regmap, 0x80C, 0x30000000);
-- ndelay(1020);
-- regmap_write(priv->usxgmii_regmap, 0x80C, 0x10000000);
-- ndelay(1020);
-- regmap_write(priv->usxgmii_regmap, 0x80C, 0x00000000);
--
-- regmap_write(priv->xfi_pextp_regmap, 0x9024, 0x00C9071C);
-- regmap_write(priv->xfi_pextp_regmap, 0x2020, 0xAA8585AA);
-- regmap_write(priv->xfi_pextp_regmap, 0x2030, 0x0C020707);
-- regmap_write(priv->xfi_pextp_regmap, 0x2034, 0x0E050F0F);
-- regmap_write(priv->xfi_pextp_regmap, 0x2040, 0x00140032);
-- regmap_write(priv->xfi_pextp_regmap, 0x50F0, 0x00C014AA);
-- regmap_write(priv->xfi_pextp_regmap, 0x50E0, 0x3777C12B);
-- regmap_write(priv->xfi_pextp_regmap, 0x506C, 0x005F9CFF);
-- regmap_write(priv->xfi_pextp_regmap, 0x5070, 0x9D9DFAFA);
-- regmap_write(priv->xfi_pextp_regmap, 0x5074, 0x27273F3F);
-- regmap_write(priv->xfi_pextp_regmap, 0x5078, 0xA7883C68);
-- regmap_write(priv->xfi_pextp_regmap, 0x507C, 0x11661166);
-- regmap_write(priv->xfi_pextp_regmap, 0x5080, 0x0E000AAF);
-- regmap_write(priv->xfi_pextp_regmap, 0x5084, 0x08080D0D);
-- regmap_write(priv->xfi_pextp_regmap, 0x5088, 0x02030909);
-- regmap_write(priv->xfi_pextp_regmap, 0x50E4, 0x0C0C0000);
-- regmap_write(priv->xfi_pextp_regmap, 0x50E8, 0x04040000);
-- regmap_write(priv->xfi_pextp_regmap, 0x50EC, 0x0F0F0C06);
-- regmap_write(priv->xfi_pextp_regmap, 0x50A8, 0x506E8C8C);
-- regmap_write(priv->xfi_pextp_regmap, 0x6004, 0x18190000);
-- regmap_write(priv->xfi_pextp_regmap, 0x00F8, 0x01423342);
-- regmap_write(priv->xfi_pextp_regmap, 0x00F4, 0x80201F20);
-- regmap_write(priv->xfi_pextp_regmap, 0x0030, 0x00050C00);
-- regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x02002800);
-- ndelay(1020);
-- regmap_write(priv->xfi_pextp_regmap, 0x30B0, 0x00000020);
-- regmap_write(priv->xfi_pextp_regmap, 0x3028, 0x00008A01);
-- regmap_write(priv->xfi_pextp_regmap, 0x302C, 0x0000A884);
-- regmap_write(priv->xfi_pextp_regmap, 0x3024, 0x00083002);
-- regmap_write(priv->xfi_pextp_regmap, 0x3010, 0x00022220);
-- regmap_write(priv->xfi_pextp_regmap, 0x5064, 0x0F020A01);
-- regmap_write(priv->xfi_pextp_regmap, 0x50B4, 0x06100600);
-- regmap_write(priv->xfi_pextp_regmap, 0x3048, 0x40704000);
-- regmap_write(priv->xfi_pextp_regmap, 0x3050, 0xA8000000);
-- regmap_write(priv->xfi_pextp_regmap, 0x3054, 0x000000AA);
-- regmap_write(priv->xfi_pextp_regmap, 0x306C, 0x00000F00);
-- regmap_write(priv->xfi_pextp_regmap, 0xA060, 0x00040000);
-- regmap_write(priv->xfi_pextp_regmap, 0x90D0, 0x00000001);
-- regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0200E800);
-- udelay(150);
-- regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0200C111);
-- ndelay(1020);
-- regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0200C101);
-- udelay(15);
-- regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0202C111);
-- ndelay(1020);
-- regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0202C101);
-- udelay(100);
-- regmap_write(priv->xfi_pextp_regmap, 0x30B0, 0x00000030);
-- regmap_write(priv->xfi_pextp_regmap, 0x00F4, 0x80201F00);
-- regmap_write(priv->xfi_pextp_regmap, 0x3040, 0x30000000);
-- udelay(400);
--}
--
--static void mtk_usxgmii_setup_phya_force_10000(struct mtk_eth_priv *priv)
--{
-- regmap_write(priv->usxgmii_regmap, 0x810, 0x000FFE6C);
-- regmap_write(priv->usxgmii_regmap, 0x818, 0x07B1EC7B);
-- regmap_write(priv->usxgmii_regmap, 0x80C, 0xB0000000);
-- ndelay(1020);
-- regmap_write(priv->usxgmii_regmap, 0x80C, 0x90000000);
-- ndelay(1020);
--
-- regmap_write(priv->xfi_pextp_regmap, 0x9024, 0x00C9071C);
-- regmap_write(priv->xfi_pextp_regmap, 0x2020, 0xAA8585AA);
-- regmap_write(priv->xfi_pextp_regmap, 0x2030, 0x0C020707);
-- regmap_write(priv->xfi_pextp_regmap, 0x2034, 0x0E050F0F);
-- regmap_write(priv->xfi_pextp_regmap, 0x2040, 0x00140032);
-- regmap_write(priv->xfi_pextp_regmap, 0x50F0, 0x00C014AA);
-- regmap_write(priv->xfi_pextp_regmap, 0x50E0, 0x3777C12B);
-- regmap_write(priv->xfi_pextp_regmap, 0x506C, 0x005F9CFF);
-- regmap_write(priv->xfi_pextp_regmap, 0x5070, 0x9D9DFAFA);
-- regmap_write(priv->xfi_pextp_regmap, 0x5074, 0x27273F3F);
-- regmap_write(priv->xfi_pextp_regmap, 0x5078, 0xA7883C68);
-- regmap_write(priv->xfi_pextp_regmap, 0x507C, 0x11661166);
-- regmap_write(priv->xfi_pextp_regmap, 0x5080, 0x0E000AAF);
-- regmap_write(priv->xfi_pextp_regmap, 0x5084, 0x08080D0D);
-- regmap_write(priv->xfi_pextp_regmap, 0x5088, 0x02030909);
-- regmap_write(priv->xfi_pextp_regmap, 0x50E4, 0x0C0C0000);
-- regmap_write(priv->xfi_pextp_regmap, 0x50E8, 0x04040000);
-- regmap_write(priv->xfi_pextp_regmap, 0x50EC, 0x0F0F0C06);
-- regmap_write(priv->xfi_pextp_regmap, 0x50A8, 0x506E8C8C);
-- regmap_write(priv->xfi_pextp_regmap, 0x6004, 0x18190000);
-- regmap_write(priv->xfi_pextp_regmap, 0x00F8, 0x01423342);
-- regmap_write(priv->xfi_pextp_regmap, 0x00F4, 0x80201F20);
-- regmap_write(priv->xfi_pextp_regmap, 0x0030, 0x00050C00);
-- regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x02002800);
-- ndelay(1020);
-- regmap_write(priv->xfi_pextp_regmap, 0x30B0, 0x00000020);
-- regmap_write(priv->xfi_pextp_regmap, 0x3028, 0x00008A01);
-- regmap_write(priv->xfi_pextp_regmap, 0x302C, 0x0000A884);
-- regmap_write(priv->xfi_pextp_regmap, 0x3024, 0x00083002);
-- regmap_write(priv->xfi_pextp_regmap, 0x3010, 0x00022220);
-- regmap_write(priv->xfi_pextp_regmap, 0x5064, 0x0F020A01);
-- regmap_write(priv->xfi_pextp_regmap, 0x50B4, 0x06100600);
-- regmap_write(priv->xfi_pextp_regmap, 0x3048, 0x47684100);
-- regmap_write(priv->xfi_pextp_regmap, 0x3050, 0x00000000);
-- regmap_write(priv->xfi_pextp_regmap, 0x3054, 0x00000000);
-- regmap_write(priv->xfi_pextp_regmap, 0x306C, 0x00000F00);
-- if (priv->gmac_id == 2)
-- regmap_write(priv->xfi_pextp_regmap, 0xA008, 0x0007B400);
-- regmap_write(priv->xfi_pextp_regmap, 0xA060, 0x00040000);
-- regmap_write(priv->xfi_pextp_regmap, 0x90D0, 0x00000001);
-- regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0200E800);
-- udelay(150);
-- regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0200C111);
-- ndelay(1020);
-- regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0200C101);
-- udelay(15);
-- regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0202C111);
-- ndelay(1020);
-- regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0202C101);
-- udelay(100);
-- regmap_write(priv->xfi_pextp_regmap, 0x30B0, 0x00000030);
-- regmap_write(priv->xfi_pextp_regmap, 0x00F4, 0x80201F00);
-- regmap_write(priv->xfi_pextp_regmap, 0x3040, 0x30000000);
-- udelay(400);
--}
--
--static void mtk_usxgmii_an_init(struct mtk_eth_priv *priv)
--{
-- mtk_xfi_pll_enable(priv);
-- mtk_usxgmii_reset(priv);
-- mtk_usxgmii_setup_phya_an_10000(priv);
--}
--
--static void mtk_10gbaser_init(struct mtk_eth_priv *priv)
--{
-- mtk_xfi_pll_enable(priv);
-- mtk_usxgmii_reset(priv);
-- mtk_usxgmii_setup_phya_force_10000(priv);
--}
--
--static int mtk_mac_init(struct mtk_eth_priv *priv)
--{
-- int i, sgmii_sel_mask = 0, ge_mode = 0;
-- u32 mcr;
--
-- if (MTK_HAS_CAPS(priv->soc->caps, MTK_ETH_PATH_MT7629_GMAC2)) {
-- mtk_infra_rmw(priv, MT7629_INFRA_MISC2_REG,
-- INFRA_MISC2_BONDING_OPTION, priv->gmac_id);
-- }
--
-- switch (priv->phy_interface) {
-- case PHY_INTERFACE_MODE_RGMII_RXID:
-- case PHY_INTERFACE_MODE_RGMII:
-- ge_mode = GE_MODE_RGMII;
-- break;
-- case PHY_INTERFACE_MODE_SGMII:
-- case PHY_INTERFACE_MODE_2500BASEX:
-- if (!IS_ENABLED(CONFIG_MTK_ETH_SGMII)) {
-- printf("Error: SGMII is not supported on this platform\n");
-- return -ENOTSUPP;
-- }
--
-- if (MTK_HAS_CAPS(priv->soc->caps, MTK_GMAC2_U3_QPHY)) {
-- mtk_infra_rmw(priv, USB_PHY_SWITCH_REG, QPHY_SEL_MASK,
-- SGMII_QPHY_SEL);
-- }
--
-- if (MTK_HAS_CAPS(priv->soc->caps, MTK_ETH_PATH_MT7622_SGMII))
-- sgmii_sel_mask = SYSCFG1_SGMII_SEL_M;
--
-- mtk_ethsys_rmw(priv, ETHSYS_SYSCFG1_REG, sgmii_sel_mask,
-- SYSCFG1_SGMII_SEL(priv->gmac_id));
--
-- if (priv->phy_interface == PHY_INTERFACE_MODE_SGMII)
-- mtk_sgmii_an_init(priv);
-- else
-- mtk_sgmii_force_init(priv);
--
-- ge_mode = GE_MODE_RGMII;
-- break;
-- case PHY_INTERFACE_MODE_MII:
-- case PHY_INTERFACE_MODE_GMII:
-- ge_mode = GE_MODE_MII;
-- break;
-- case PHY_INTERFACE_MODE_RMII:
-- ge_mode = GE_MODE_RMII;
-- break;
-- default:
-- break;
-- }
--
-- /* set the gmac to the right mode */
-- mtk_ethsys_rmw(priv, ETHSYS_SYSCFG1_REG,
-- SYSCFG1_GE_MODE_M << SYSCFG1_GE_MODE_S(priv->gmac_id),
-- ge_mode << SYSCFG1_GE_MODE_S(priv->gmac_id));
--
-- if (priv->force_mode) {
-- mcr = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) |
-- (MAC_RX_PKT_LEN_1536 << MAC_RX_PKT_LEN_S) |
-- MAC_MODE | FORCE_MODE |
-- MAC_TX_EN | MAC_RX_EN |
-- BKOFF_EN | BACKPR_EN |
-- FORCE_LINK;
--
-- switch (priv->speed) {
-- case SPEED_10:
-- mcr |= SPEED_10M << FORCE_SPD_S;
-- break;
-- case SPEED_100:
-- mcr |= SPEED_100M << FORCE_SPD_S;
-- break;
-- case SPEED_1000:
-- case SPEED_2500:
-- mcr |= SPEED_1000M << FORCE_SPD_S;
-- break;
-- }
--
-- if (priv->duplex)
-- mcr |= FORCE_DPX;
--
-- mtk_gmac_write(priv, GMAC_PORT_MCR(priv->gmac_id), mcr);
-- }
--
-- if (MTK_HAS_CAPS(priv->soc->caps, MTK_GMAC1_TRGMII) &&
-- !MTK_HAS_CAPS(priv->soc->caps, MTK_TRGMII_MT7621_CLK)) {
-- /* Lower Tx Driving for TRGMII path */
-- for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
-- mtk_gmac_write(priv, GMAC_TRGMII_TD_ODT(i),
-- (8 << TD_DM_DRVP_S) |
-- (8 << TD_DM_DRVN_S));
--
-- mtk_gmac_rmw(priv, GMAC_TRGMII_RCK_CTRL, 0,
-- RX_RST | RXC_DQSISEL);
-- mtk_gmac_rmw(priv, GMAC_TRGMII_RCK_CTRL, RX_RST, 0);
-- }
--
-- return 0;
--}
--
--static int mtk_xmac_init(struct mtk_eth_priv *priv)
--{
-- u32 force_link = 0;
--
-- if (!IS_ENABLED(CONFIG_MTK_ETH_XGMII)) {
-- printf("Error: 10Gb interface is not supported on this platform\n");
-- return -ENOTSUPP;
-- }
--
-- switch (priv->phy_interface) {
-- case PHY_INTERFACE_MODE_USXGMII:
-- mtk_usxgmii_an_init(priv);
-- break;
-- case PHY_INTERFACE_MODE_10GBASER:
-- mtk_10gbaser_init(priv);
-- break;
-- default:
-- break;
-- }
--
-- /* Set GMAC to the correct mode */
-- mtk_ethsys_rmw(priv, ETHSYS_SYSCFG1_REG,
-- SYSCFG1_GE_MODE_M << SYSCFG1_GE_MODE_S(priv->gmac_id),
-- 0);
--
-- if ((priv->phy_interface == PHY_INTERFACE_MODE_USXGMII ||
-- priv->phy_interface == PHY_INTERFACE_MODE_10GBASER) &&
-- priv->gmac_id == 1) {
-- mtk_infra_rmw(priv, TOPMISC_NETSYS_PCS_MUX,
-- NETSYS_PCS_MUX_MASK, MUX_G2_USXGMII_SEL);
-- }
--
-- if (priv->phy_interface == PHY_INTERFACE_MODE_XGMII ||
-- priv->gmac_id == 2)
-- force_link = XGMAC_FORCE_LINK(priv->gmac_id);
--
-- mtk_gmac_rmw(priv, XGMAC_STS(priv->gmac_id),
-- XGMAC_FORCE_LINK(priv->gmac_id), force_link);
--
-- /* Force GMAC link down */
-- mtk_gmac_write(priv, GMAC_PORT_MCR(priv->gmac_id), FORCE_MODE);
--
-- return 0;
--}
--
--static void mtk_eth_fifo_init(struct mtk_eth_priv *priv)
--{
-- char *pkt_base = priv->pkt_pool;
-- struct mtk_tx_dma_v2 *txd;
-- struct mtk_rx_dma_v2 *rxd;
-- int i;
--
-- mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG, 0xffff0000, 0);
-- udelay(500);
--
-- memset(priv->tx_ring_noc, 0, NUM_TX_DESC * priv->soc->txd_size);
-- memset(priv->rx_ring_noc, 0, NUM_RX_DESC * priv->soc->rxd_size);
-- memset(priv->pkt_pool, 0xff, TOTAL_PKT_BUF_SIZE);
--
-- flush_dcache_range((ulong)pkt_base,
-- (ulong)(pkt_base + TOTAL_PKT_BUF_SIZE));
--
-- priv->rx_dma_owner_idx0 = 0;
-- priv->tx_cpu_owner_idx0 = 0;
--
-- for (i = 0; i < NUM_TX_DESC; i++) {
-- txd = priv->tx_ring_noc + i * priv->soc->txd_size;
--
-- txd->txd1 = virt_to_phys(pkt_base);
-- txd->txd2 = PDMA_TXD2_DDONE | PDMA_TXD2_LS0;
--
-- if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3))
-- txd->txd5 = PDMA_V2_TXD5_FPORT_SET(priv->gmac_id == 2 ?
-- 15 : priv->gmac_id + 1);
-- else if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2))
-- txd->txd5 = PDMA_V2_TXD5_FPORT_SET(priv->gmac_id + 1);
-- else
-- txd->txd4 = PDMA_V1_TXD4_FPORT_SET(priv->gmac_id + 1);
--
-- pkt_base += PKTSIZE_ALIGN;
-- }
--
-- for (i = 0; i < NUM_RX_DESC; i++) {
-- rxd = priv->rx_ring_noc + i * priv->soc->rxd_size;
--
-- rxd->rxd1 = virt_to_phys(pkt_base);
--
-- if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2) ||
-- MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3))
-- rxd->rxd2 = PDMA_V2_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
-- else
-- rxd->rxd2 = PDMA_V1_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
--
-- pkt_base += PKTSIZE_ALIGN;
-- }
--
-- mtk_pdma_write(priv, TX_BASE_PTR_REG(0),
-- virt_to_phys(priv->tx_ring_noc));
-- mtk_pdma_write(priv, TX_MAX_CNT_REG(0), NUM_TX_DESC);
-- mtk_pdma_write(priv, TX_CTX_IDX_REG(0), priv->tx_cpu_owner_idx0);
--
-- mtk_pdma_write(priv, RX_BASE_PTR_REG(0),
-- virt_to_phys(priv->rx_ring_noc));
-- mtk_pdma_write(priv, RX_MAX_CNT_REG(0), NUM_RX_DESC);
-- mtk_pdma_write(priv, RX_CRX_IDX_REG(0), NUM_RX_DESC - 1);
--
-- mtk_pdma_write(priv, PDMA_RST_IDX_REG, RST_DTX_IDX0 | RST_DRX_IDX0);
--}
--
--static void mtk_eth_mdc_init(struct mtk_eth_priv *priv)
--{
-- u32 divider;
--
-- if (priv->mdc == 0)
-- return;
--
-- divider = min_t(u32, DIV_ROUND_UP(MDC_MAX_FREQ, priv->mdc), MDC_MAX_DIVIDER);
--
-- /* Configure MDC turbo mode */
-- if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3))
-- mtk_gmac_rmw(priv, GMAC_MAC_MISC_REG, 0, MISC_MDC_TURBO);
-- else
-- mtk_gmac_rmw(priv, GMAC_PPSC_REG, 0, MISC_MDC_TURBO);
--
-- /* Configure MDC divider */
-- mtk_gmac_rmw(priv, GMAC_PPSC_REG, PHY_MDC_CFG,
-- FIELD_PREP(PHY_MDC_CFG, divider));
--}
--
--static int mtk_eth_start(struct udevice *dev)
--{
-- struct mtk_eth_priv *priv = dev_get_priv(dev);
-- int i, ret;
--
-- /* Reset FE */
-- reset_assert(&priv->rst_fe);
-- udelay(1000);
-- reset_deassert(&priv->rst_fe);
-- mdelay(10);
--
-- if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2) ||
-- MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3))
-- setbits_le32(priv->fe_base + FE_GLO_MISC_REG, PDMA_VER_V2);
--
-- /* Packets forward to PDMA */
-- mtk_gdma_write(priv, priv->gmac_id, GDMA_IG_CTRL_REG, GDMA_FWD_TO_CPU);
--
-- for (i = 0; i < priv->soc->gdma_count; i++) {
-- if (i == priv->gmac_id)
-- continue;
--
-- mtk_gdma_write(priv, i, GDMA_IG_CTRL_REG, GDMA_FWD_DISCARD);
-- }
--
-- if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3)) {
-- if (priv->sw == SW_MT7988 && priv->gmac_id == 0) {
-- mtk_gdma_write(priv, priv->gmac_id, GDMA_IG_CTRL_REG,
-- GDMA_BRIDGE_TO_CPU);
--
-- mtk_gdma_write(priv, priv->gmac_id, GDMA_EG_CTRL_REG,
-- GDMA_CPU_BRIDGE_EN);
-- } else if ((priv->phy_interface == PHY_INTERFACE_MODE_USXGMII ||
-- priv->phy_interface == PHY_INTERFACE_MODE_10GBASER ||
-- priv->phy_interface == PHY_INTERFACE_MODE_XGMII) &&
-- priv->gmac_id != 0) {
-- mtk_gdma_write(priv, priv->gmac_id, GDMA_EG_CTRL_REG,
-- GDMA_CPU_BRIDGE_EN);
-- }
-- }
--
-- udelay(500);
--
-- mtk_eth_fifo_init(priv);
--
-- if (priv->switch_mac_control)
-- priv->switch_mac_control(priv, true);
--
-- /* Start PHY */
-- if (priv->sw == SW_NONE) {
-- ret = mtk_phy_start(priv);
-- if (ret)
-- return ret;
-- }
--
-- mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG, 0,
-- TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN);
-- udelay(500);
--
-- return 0;
--}
--
--static void mtk_eth_stop(struct udevice *dev)
--{
-- struct mtk_eth_priv *priv = dev_get_priv(dev);
--
-- if (priv->switch_mac_control)
-- priv->switch_mac_control(priv, false);
--
-- mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG,
-- TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN, 0);
-- udelay(500);
--
-- wait_for_bit_le32(priv->fe_base + priv->soc->pdma_base + PDMA_GLO_CFG_REG,
-- RX_DMA_BUSY | TX_DMA_BUSY, 0, 5000, 0);
--}
--
--static int mtk_eth_write_hwaddr(struct udevice *dev)
--{
-- struct eth_pdata *pdata = dev_get_plat(dev);
-- struct mtk_eth_priv *priv = dev_get_priv(dev);
-- unsigned char *mac = pdata->enetaddr;
-- u32 macaddr_lsb, macaddr_msb;
--
-- macaddr_msb = ((u32)mac[0] << 8) | (u32)mac[1];
-- macaddr_lsb = ((u32)mac[2] << 24) | ((u32)mac[3] << 16) |
-- ((u32)mac[4] << 8) | (u32)mac[5];
--
-- mtk_gdma_write(priv, priv->gmac_id, GDMA_MAC_MSB_REG, macaddr_msb);
-- mtk_gdma_write(priv, priv->gmac_id, GDMA_MAC_LSB_REG, macaddr_lsb);
--
-- return 0;
--}
--
--static int mtk_eth_send(struct udevice *dev, void *packet, int length)
--{
-- struct mtk_eth_priv *priv = dev_get_priv(dev);
-- u32 idx = priv->tx_cpu_owner_idx0;
-- struct mtk_tx_dma_v2 *txd;
-- void *pkt_base;
--
-- txd = priv->tx_ring_noc + idx * priv->soc->txd_size;
--
-- if (!(txd->txd2 & PDMA_TXD2_DDONE)) {
-- debug("mtk-eth: TX DMA descriptor ring is full\n");
-- return -EPERM;
-- }
--
-- pkt_base = (void *)phys_to_virt(txd->txd1);
-- memcpy(pkt_base, packet, length);
-- flush_dcache_range((ulong)pkt_base, (ulong)pkt_base +
-- roundup(length, ARCH_DMA_MINALIGN));
--
-- if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2) ||
-- MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3))
-- txd->txd2 = PDMA_TXD2_LS0 | PDMA_V2_TXD2_SDL0_SET(length);
-- else
-- txd->txd2 = PDMA_TXD2_LS0 | PDMA_V1_TXD2_SDL0_SET(length);
--
-- priv->tx_cpu_owner_idx0 = (priv->tx_cpu_owner_idx0 + 1) % NUM_TX_DESC;
-- mtk_pdma_write(priv, TX_CTX_IDX_REG(0), priv->tx_cpu_owner_idx0);
--
-- return 0;
--}
--
--static int mtk_eth_recv(struct udevice *dev, int flags, uchar **packetp)
--{
-- struct mtk_eth_priv *priv = dev_get_priv(dev);
-- u32 idx = priv->rx_dma_owner_idx0;
-- struct mtk_rx_dma_v2 *rxd;
-- uchar *pkt_base;
-- u32 length;
--
-- rxd = priv->rx_ring_noc + idx * priv->soc->rxd_size;
--
-- if (!(rxd->rxd2 & PDMA_RXD2_DDONE)) {
-- debug("mtk-eth: RX DMA descriptor ring is empty\n");
-- return -EAGAIN;
-- }
--
-- if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2) ||
-- MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3))
-- length = PDMA_V2_RXD2_PLEN0_GET(rxd->rxd2);
-- else
-- length = PDMA_V1_RXD2_PLEN0_GET(rxd->rxd2);
--
-- pkt_base = (void *)phys_to_virt(rxd->rxd1);
-- invalidate_dcache_range((ulong)pkt_base, (ulong)pkt_base +
-- roundup(length, ARCH_DMA_MINALIGN));
--
-- if (packetp)
-- *packetp = pkt_base;
--
-- return length;
--}
--
--static int mtk_eth_free_pkt(struct udevice *dev, uchar *packet, int length)
--{
-- struct mtk_eth_priv *priv = dev_get_priv(dev);
-- u32 idx = priv->rx_dma_owner_idx0;
-- struct mtk_rx_dma_v2 *rxd;
--
-- rxd = priv->rx_ring_noc + idx * priv->soc->rxd_size;
--
-- invalidate_dcache_range((ulong)rxd->rxd1,
-- (ulong)rxd->rxd1 + PKTSIZE_ALIGN);
--
-- if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2) ||
-- MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3))
-- rxd->rxd2 = PDMA_V2_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
-- else
-- rxd->rxd2 = PDMA_V1_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
--
-- mtk_pdma_write(priv, RX_CRX_IDX_REG(0), idx);
-- priv->rx_dma_owner_idx0 = (priv->rx_dma_owner_idx0 + 1) % NUM_RX_DESC;
--
-- return 0;
--}
--
--static int mtk_eth_probe(struct udevice *dev)
--{
-- struct eth_pdata *pdata = dev_get_plat(dev);
-- struct mtk_eth_priv *priv = dev_get_priv(dev);
-- ulong iobase = pdata->iobase;
-- int ret;
--
-- /* Frame Engine Register Base */
-- priv->fe_base = (void *)iobase;
--
-- /* GMAC Register Base */
-- priv->gmac_base = (void *)(iobase + GMAC_BASE);
--
-- /* MDIO register */
-- ret = mtk_mdio_register(dev);
-- if (ret)
-- return ret;
--
-- /* Prepare for tx/rx rings */
-- priv->tx_ring_noc = (void *)
-- noncached_alloc(priv->soc->txd_size * NUM_TX_DESC,
-- ARCH_DMA_MINALIGN);
-- priv->rx_ring_noc = (void *)
-- noncached_alloc(priv->soc->rxd_size * NUM_RX_DESC,
-- ARCH_DMA_MINALIGN);
--
-- /* Set MDC divider */
-- mtk_eth_mdc_init(priv);
--
-- /* Set MAC mode */
-- if (priv->phy_interface == PHY_INTERFACE_MODE_USXGMII ||
-- priv->phy_interface == PHY_INTERFACE_MODE_10GBASER ||
-- priv->phy_interface == PHY_INTERFACE_MODE_XGMII)
-- ret = mtk_xmac_init(priv);
-- else
-- ret = mtk_mac_init(priv);
--
-- if (ret)
-- return ret;
--
-- /* Probe phy if switch is not specified */
-- if (priv->sw == SW_NONE)
-- return mtk_phy_probe(dev);
--
-- /* Initialize switch */
-- return mt753x_switch_init(priv);
--}
--
--static int mtk_eth_remove(struct udevice *dev)
--{
-- struct mtk_eth_priv *priv = dev_get_priv(dev);
--
-- /* MDIO unregister */
-- mdio_unregister(priv->mdio_bus);
-- mdio_free(priv->mdio_bus);
--
-- /* Stop possibly started DMA */
-- mtk_eth_stop(dev);
--
-- return 0;
--}
--
--static int mtk_eth_of_to_plat(struct udevice *dev)
--{
-- struct eth_pdata *pdata = dev_get_plat(dev);
-- struct mtk_eth_priv *priv = dev_get_priv(dev);
-- struct ofnode_phandle_args args;
-- struct regmap *regmap;
-- const char *str;
-- ofnode subnode;
-- int ret;
--
-- priv->soc = (const struct mtk_soc_data *)dev_get_driver_data(dev);
-- if (!priv->soc) {
-- dev_err(dev, "missing soc compatible data\n");
-- return -EINVAL;
-- }
--
-- pdata->iobase = (phys_addr_t)dev_remap_addr(dev);
--
-- /* get corresponding ethsys phandle */
-- ret = dev_read_phandle_with_args(dev, "mediatek,ethsys", NULL, 0, 0,
-- &args);
-- if (ret)
-- return ret;
--
-- priv->ethsys_regmap = syscon_node_to_regmap(args.node);
-- if (IS_ERR(priv->ethsys_regmap))
-- return PTR_ERR(priv->ethsys_regmap);
--
-- if (MTK_HAS_CAPS(priv->soc->caps, MTK_INFRA)) {
-- /* get corresponding infracfg phandle */
-- ret = dev_read_phandle_with_args(dev, "mediatek,infracfg",
-- NULL, 0, 0, &args);
--
-- if (ret)
-- return ret;
--
-- priv->infra_regmap = syscon_node_to_regmap(args.node);
-- if (IS_ERR(priv->infra_regmap))
-- return PTR_ERR(priv->infra_regmap);
-- }
--
-- /* Reset controllers */
-- ret = reset_get_by_name(dev, "fe", &priv->rst_fe);
-- if (ret) {
-- printf("error: Unable to get reset ctrl for frame engine\n");
-- return ret;
-- }
--
-- priv->gmac_id = dev_read_u32_default(dev, "mediatek,gmac-id", 0);
--
-- priv->mdc = 0;
-- subnode = ofnode_find_subnode(dev_ofnode(dev), "mdio");
-- if (ofnode_valid(subnode)) {
-- priv->mdc = ofnode_read_u32_default(subnode, "clock-frequency", 2500000);
-- if (priv->mdc > MDC_MAX_FREQ ||
-- priv->mdc < MDC_MAX_FREQ / MDC_MAX_DIVIDER) {
-- printf("error: MDIO clock frequency out of range\n");
-- return -EINVAL;
-- }
-- }
--
-- /* Interface mode is required */
-- pdata->phy_interface = dev_read_phy_mode(dev);
-- priv->phy_interface = pdata->phy_interface;
-- if (pdata->phy_interface == PHY_INTERFACE_MODE_NA) {
-- printf("error: phy-mode is not set\n");
-- return -EINVAL;
-- }
--
-- /* Force mode or autoneg */
-- subnode = ofnode_find_subnode(dev_ofnode(dev), "fixed-link");
-- if (ofnode_valid(subnode)) {
-- priv->force_mode = 1;
-- priv->speed = ofnode_read_u32_default(subnode, "speed", 0);
-- priv->duplex = ofnode_read_bool(subnode, "full-duplex");
--
-- if (priv->speed != SPEED_10 && priv->speed != SPEED_100 &&
-- priv->speed != SPEED_1000 && priv->speed != SPEED_2500 &&
-- priv->speed != SPEED_10000) {
-- printf("error: no valid speed set in fixed-link\n");
-- return -EINVAL;
-- }
-- }
--
-- if ((priv->phy_interface == PHY_INTERFACE_MODE_SGMII ||
-- priv->phy_interface == PHY_INTERFACE_MODE_2500BASEX) &&
-- IS_ENABLED(CONFIG_MTK_ETH_SGMII)) {
-- /* get corresponding sgmii phandle */
-- ret = dev_read_phandle_with_args(dev, "mediatek,sgmiisys",
-- NULL, 0, 0, &args);
-- if (ret)
-- return ret;
--
-- regmap = syscon_node_to_regmap(args.node);
--
-- if (IS_ERR(regmap))
-- return PTR_ERR(regmap);
--
-- priv->sgmii_base = regmap_get_range(regmap, 0);
--
-- if (!priv->sgmii_base) {
-- dev_err(dev, "Unable to find sgmii\n");
-- return -ENODEV;
-- }
--
-- /* Upstream linux use mediatek,pnswap instead of pn_swap */
-- priv->pn_swap = ofnode_read_bool(args.node, "pn_swap") ||
-- ofnode_read_bool(args.node, "mediatek,pnswap");
-- } else if ((priv->phy_interface == PHY_INTERFACE_MODE_USXGMII ||
-- priv->phy_interface == PHY_INTERFACE_MODE_10GBASER) &&
-- IS_ENABLED(CONFIG_MTK_ETH_XGMII)) {
-- /* get corresponding usxgmii phandle */
-- ret = dev_read_phandle_with_args(dev, "mediatek,usxgmiisys",
-- NULL, 0, 0, &args);
-- if (ret)
-- return ret;
--
-- priv->usxgmii_regmap = syscon_node_to_regmap(args.node);
-- if (IS_ERR(priv->usxgmii_regmap))
-- return PTR_ERR(priv->usxgmii_regmap);
--
-- /* get corresponding xfi_pextp phandle */
-- ret = dev_read_phandle_with_args(dev, "mediatek,xfi_pextp",
-- NULL, 0, 0, &args);
-- if (ret)
-- return ret;
--
-- priv->xfi_pextp_regmap = syscon_node_to_regmap(args.node);
-- if (IS_ERR(priv->xfi_pextp_regmap))
-- return PTR_ERR(priv->xfi_pextp_regmap);
--
-- /* get corresponding xfi_pll phandle */
-- ret = dev_read_phandle_with_args(dev, "mediatek,xfi_pll",
-- NULL, 0, 0, &args);
-- if (ret)
-- return ret;
--
-- priv->xfi_pll_regmap = syscon_node_to_regmap(args.node);
-- if (IS_ERR(priv->xfi_pll_regmap))
-- return PTR_ERR(priv->xfi_pll_regmap);
--
-- /* get corresponding toprgu phandle */
-- ret = dev_read_phandle_with_args(dev, "mediatek,toprgu",
-- NULL, 0, 0, &args);
-- if (ret)
-- return ret;
--
-- priv->toprgu_regmap = syscon_node_to_regmap(args.node);
-- if (IS_ERR(priv->toprgu_regmap))
-- return PTR_ERR(priv->toprgu_regmap);
-- }
--
-- /* check for switch first, otherwise phy will be used */
-- priv->sw = SW_NONE;
-- priv->switch_init = NULL;
-- priv->switch_mac_control = NULL;
-- str = dev_read_string(dev, "mediatek,switch");
--
-- if (str) {
-- if (!strcmp(str, "mt7530")) {
-- priv->sw = SW_MT7530;
-- priv->switch_init = mt7530_setup;
-- priv->switch_mac_control = mt7530_mac_control;
-- priv->mt753x_smi_addr = MT753X_DFL_SMI_ADDR;
-- priv->mt753x_reset_wait_time = 1000;
-- } else if (!strcmp(str, "mt7531")) {
-- priv->sw = SW_MT7531;
-- priv->switch_init = mt7531_setup;
-- priv->switch_mac_control = mt7531_mac_control;
-- priv->mt753x_smi_addr = MT753X_DFL_SMI_ADDR;
-- priv->mt753x_reset_wait_time = 200;
-- } else if (!strcmp(str, "mt7988")) {
-- priv->sw = SW_MT7988;
-- priv->switch_init = mt7988_setup;
-- priv->switch_mac_control = mt7988_mac_control;
-- priv->mt753x_smi_addr = MT753X_DFL_SMI_ADDR;
-- priv->mt753x_reset_wait_time = 50;
-- } else {
-- printf("error: unsupported switch\n");
-- return -EINVAL;
-- }
--
-- priv->mcm = dev_read_bool(dev, "mediatek,mcm");
-- if (priv->mcm) {
-- ret = reset_get_by_name(dev, "mcm", &priv->rst_mcm);
-- if (ret) {
-- printf("error: no reset ctrl for mcm\n");
-- return ret;
-- }
-- } else {
-- gpio_request_by_name(dev, "reset-gpios", 0,
-- &priv->rst_gpio, GPIOD_IS_OUT);
-- }
-- } else {
-- ret = dev_read_phandle_with_args(dev, "phy-handle", NULL, 0,
-- 0, &args);
-- if (ret) {
-- printf("error: phy-handle is not specified\n");
-- return ret;
-- }
--
-- priv->phy_addr = ofnode_read_s32_default(args.node, "reg", -1);
-- if (priv->phy_addr < 0) {
-- printf("error: phy address is not specified\n");
-- return ret;
-- }
-- }
--
-- return 0;
--}
--
--static const struct mtk_soc_data mt7988_data = {
-- .caps = MT7988_CAPS,
-- .ana_rgc3 = 0x128,
-- .gdma_count = 3,
-- .pdma_base = PDMA_V3_BASE,
-- .txd_size = sizeof(struct mtk_tx_dma_v2),
-- .rxd_size = sizeof(struct mtk_rx_dma_v2),
--};
--
--static const struct mtk_soc_data mt7986_data = {
-- .caps = MT7986_CAPS,
-- .ana_rgc3 = 0x128,
-- .gdma_count = 2,
-- .pdma_base = PDMA_V2_BASE,
-- .txd_size = sizeof(struct mtk_tx_dma_v2),
-- .rxd_size = sizeof(struct mtk_rx_dma_v2),
--};
--
--static const struct mtk_soc_data mt7981_data = {
-- .caps = MT7981_CAPS,
-- .ana_rgc3 = 0x128,
-- .gdma_count = 2,
-- .pdma_base = PDMA_V2_BASE,
-- .txd_size = sizeof(struct mtk_tx_dma_v2),
-- .rxd_size = sizeof(struct mtk_rx_dma_v2),
--};
--
--static const struct mtk_soc_data mt7629_data = {
-- .caps = MT7629_CAPS,
-- .ana_rgc3 = 0x128,
-- .gdma_count = 2,
-- .pdma_base = PDMA_V1_BASE,
-- .txd_size = sizeof(struct mtk_tx_dma),
-- .rxd_size = sizeof(struct mtk_rx_dma),
--};
--
--static const struct mtk_soc_data mt7623_data = {
-- .caps = MT7623_CAPS,
-- .gdma_count = 2,
-- .pdma_base = PDMA_V1_BASE,
-- .txd_size = sizeof(struct mtk_tx_dma),
-- .rxd_size = sizeof(struct mtk_rx_dma),
--};
--
--static const struct mtk_soc_data mt7622_data = {
-- .caps = MT7622_CAPS,
-- .ana_rgc3 = 0x2028,
-- .gdma_count = 2,
-- .pdma_base = PDMA_V1_BASE,
-- .txd_size = sizeof(struct mtk_tx_dma),
-- .rxd_size = sizeof(struct mtk_rx_dma),
--};
--
--static const struct mtk_soc_data mt7621_data = {
-- .caps = MT7621_CAPS,
-- .gdma_count = 2,
-- .pdma_base = PDMA_V1_BASE,
-- .txd_size = sizeof(struct mtk_tx_dma),
-- .rxd_size = sizeof(struct mtk_rx_dma),
--};
--
--static const struct udevice_id mtk_eth_ids[] = {
-- { .compatible = "mediatek,mt7988-eth", .data = (ulong)&mt7988_data },
-- { .compatible = "mediatek,mt7986-eth", .data = (ulong)&mt7986_data },
-- { .compatible = "mediatek,mt7981-eth", .data = (ulong)&mt7981_data },
-- { .compatible = "mediatek,mt7629-eth", .data = (ulong)&mt7629_data },
-- { .compatible = "mediatek,mt7623-eth", .data = (ulong)&mt7623_data },
-- { .compatible = "mediatek,mt7622-eth", .data = (ulong)&mt7622_data },
-- { .compatible = "mediatek,mt7621-eth", .data = (ulong)&mt7621_data },
-- {}
--};
--
--static const struct eth_ops mtk_eth_ops = {
-- .start = mtk_eth_start,
-- .stop = mtk_eth_stop,
-- .send = mtk_eth_send,
-- .recv = mtk_eth_recv,
-- .free_pkt = mtk_eth_free_pkt,
-- .write_hwaddr = mtk_eth_write_hwaddr,
--};
--
--U_BOOT_DRIVER(mtk_eth) = {
-- .name = "mtk-eth",
-- .id = UCLASS_ETH,
-- .of_match = mtk_eth_ids,
-- .of_to_plat = mtk_eth_of_to_plat,
-- .plat_auto = sizeof(struct eth_pdata),
-- .probe = mtk_eth_probe,
-- .remove = mtk_eth_remove,
-- .ops = &mtk_eth_ops,
-- .priv_auto = sizeof(struct mtk_eth_priv),
-- .flags = DM_FLAG_ALLOC_PRIV_DMA,
--};
---- /dev/null
-+++ b/drivers/net/mtk_eth/mtk_eth.c
-@@ -0,0 +1,1563 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (C) 2025 MediaTek Inc.
-+ *
-+ * Author: Weijie Gao <weijie.gao@mediatek.com>
-+ * Author: Mark Lee <mark-mc.lee@mediatek.com>
-+ */
-+
-+#include <cpu_func.h>
-+#include <dm.h>
-+#include <log.h>
-+#include <malloc.h>
-+#include <miiphy.h>
-+#include <net.h>
-+#include <regmap.h>
-+#include <reset.h>
-+#include <syscon.h>
-+#include <wait_bit.h>
-+#include <asm/cache.h>
-+#include <asm/gpio.h>
-+#include <asm/io.h>
-+#include <dm/device_compat.h>
-+#include <linux/delay.h>
-+#include <linux/err.h>
-+#include <linux/ioport.h>
-+#include <linux/mdio.h>
-+#include <linux/mii.h>
-+#include <linux/printk.h>
-+
-+#include "mtk_eth.h"
-+
-+#define NUM_TX_DESC 32
-+#define NUM_RX_DESC 32
-+#define TX_TOTAL_BUF_SIZE (NUM_TX_DESC * PKTSIZE_ALIGN)
-+#define RX_TOTAL_BUF_SIZE (NUM_RX_DESC * PKTSIZE_ALIGN)
-+#define TOTAL_PKT_BUF_SIZE (TX_TOTAL_BUF_SIZE + RX_TOTAL_BUF_SIZE)
-+
-+#define GDMA_FWD_TO_CPU \
-+ (0x20000000 | \
-+ GDM_ICS_EN | \
-+ GDM_TCS_EN | \
-+ GDM_UCS_EN | \
-+ STRP_CRC | \
-+ (DP_PDMA << MYMAC_DP_S) | \
-+ (DP_PDMA << BC_DP_S) | \
-+ (DP_PDMA << MC_DP_S) | \
-+ (DP_PDMA << UN_DP_S))
-+
-+#define GDMA_BRIDGE_TO_CPU \
-+ (0xC0000000 | \
-+ GDM_ICS_EN | \
-+ GDM_TCS_EN | \
-+ GDM_UCS_EN | \
-+ (DP_PDMA << MYMAC_DP_S) | \
-+ (DP_PDMA << BC_DP_S) | \
-+ (DP_PDMA << MC_DP_S) | \
-+ (DP_PDMA << UN_DP_S))
-+
-+#define GDMA_FWD_DISCARD \
-+ (0x20000000 | \
-+ GDM_ICS_EN | \
-+ GDM_TCS_EN | \
-+ GDM_UCS_EN | \
-+ STRP_CRC | \
-+ (DP_DISCARD << MYMAC_DP_S) | \
-+ (DP_DISCARD << BC_DP_S) | \
-+ (DP_DISCARD << MC_DP_S) | \
-+ (DP_DISCARD << UN_DP_S))
-+
-+struct mtk_eth_priv {
-+ char pkt_pool[TOTAL_PKT_BUF_SIZE] __aligned(ARCH_DMA_MINALIGN);
-+
-+ void *tx_ring_noc;
-+ void *rx_ring_noc;
-+
-+ int rx_dma_owner_idx0;
-+ int tx_cpu_owner_idx0;
-+
-+ void __iomem *fe_base;
-+ void __iomem *gmac_base;
-+ void __iomem *sgmii_base;
-+
-+ struct regmap *ethsys_regmap;
-+
-+ struct regmap *infra_regmap;
-+
-+ struct regmap *usxgmii_regmap;
-+ struct regmap *xfi_pextp_regmap;
-+ struct regmap *xfi_pll_regmap;
-+ struct regmap *toprgu_regmap;
-+
-+ struct mii_dev *mdio_bus;
-+
-+ const struct mtk_soc_data *soc;
-+ int gmac_id;
-+ int force_mode;
-+ int speed;
-+ int duplex;
-+ int mdc;
-+ bool pn_swap;
-+
-+ struct phy_device *phydev;
-+ int phy_interface;
-+ int phy_addr;
-+
-+ struct mtk_eth_switch_priv *swpriv;
-+ const char *swname;
-+
-+ struct gpio_desc rst_gpio;
-+ int mcm;
-+
-+ struct reset_ctl rst_fe;
-+ struct reset_ctl rst_mcm;
-+};
-+
-+static void mtk_pdma_write(struct mtk_eth_priv *priv, u32 reg, u32 val)
-+{
-+ writel(val, priv->fe_base + priv->soc->pdma_base + reg);
-+}
-+
-+static void mtk_pdma_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr,
-+ u32 set)
-+{
-+ clrsetbits_le32(priv->fe_base + priv->soc->pdma_base + reg, clr, set);
-+}
-+
-+static void mtk_gdma_write(struct mtk_eth_priv *priv, int no, u32 reg,
-+ u32 val)
-+{
-+ u32 gdma_base;
-+
-+ if (no == 2)
-+ gdma_base = GDMA3_BASE;
-+ else if (no == 1)
-+ gdma_base = GDMA2_BASE;
-+ else
-+ gdma_base = GDMA1_BASE;
-+
-+ writel(val, priv->fe_base + gdma_base + reg);
-+}
-+
-+void mtk_fe_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, u32 set)
-+{
-+ clrsetbits_le32(priv->fe_base + reg, clr, set);
-+}
-+
-+static u32 mtk_gmac_read(struct mtk_eth_priv *priv, u32 reg)
-+{
-+ return readl(priv->gmac_base + reg);
-+}
-+
-+static void mtk_gmac_write(struct mtk_eth_priv *priv, u32 reg, u32 val)
-+{
-+ writel(val, priv->gmac_base + reg);
-+}
-+
-+void mtk_gmac_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, u32 set)
-+{
-+ clrsetbits_le32(priv->gmac_base + reg, clr, set);
-+}
-+
-+void mtk_ethsys_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, u32 set)
-+{
-+ uint val;
-+
-+ regmap_read(priv->ethsys_regmap, reg, &val);
-+ val &= ~clr;
-+ val |= set;
-+ regmap_write(priv->ethsys_regmap, reg, val);
-+}
-+
-+static void mtk_infra_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr,
-+ u32 set)
-+{
-+ uint val;
-+
-+ regmap_read(priv->infra_regmap, reg, &val);
-+ val &= ~clr;
-+ val |= set;
-+ regmap_write(priv->infra_regmap, reg, val);
-+}
-+
-+/* Direct MDIO clause 22/45 access via SoC */
-+static int mtk_mii_rw(struct mtk_eth_priv *priv, u8 phy, u8 reg, u16 data,
-+ u32 cmd, u32 st)
-+{
-+ int ret;
-+ u32 val;
-+
-+ val = (st << MDIO_ST_S) |
-+ ((cmd << MDIO_CMD_S) & MDIO_CMD_M) |
-+ (((u32)phy << MDIO_PHY_ADDR_S) & MDIO_PHY_ADDR_M) |
-+ (((u32)reg << MDIO_REG_ADDR_S) & MDIO_REG_ADDR_M);
-+
-+ if (cmd == MDIO_CMD_WRITE || cmd == MDIO_CMD_ADDR)
-+ val |= data & MDIO_RW_DATA_M;
-+
-+ mtk_gmac_write(priv, GMAC_PIAC_REG, val | PHY_ACS_ST);
-+
-+ ret = wait_for_bit_le32(priv->gmac_base + GMAC_PIAC_REG,
-+ PHY_ACS_ST, 0, 5000, 0);
-+ if (ret) {
-+ pr_warn("MDIO access timeout\n");
-+ return ret;
-+ }
-+
-+ if (cmd == MDIO_CMD_READ || cmd == MDIO_CMD_READ_C45) {
-+ val = mtk_gmac_read(priv, GMAC_PIAC_REG);
-+ return val & MDIO_RW_DATA_M;
-+ }
-+
-+ return 0;
-+}
-+
-+/* Direct MDIO clause 22 read via SoC */
-+int mtk_mii_read(struct mtk_eth_priv *priv, u8 phy, u8 reg)
-+{
-+ return mtk_mii_rw(priv, phy, reg, 0, MDIO_CMD_READ, MDIO_ST_C22);
-+}
-+
-+/* Direct MDIO clause 22 write via SoC */
-+int mtk_mii_write(struct mtk_eth_priv *priv, u8 phy, u8 reg, u16 data)
-+{
-+ return mtk_mii_rw(priv, phy, reg, data, MDIO_CMD_WRITE, MDIO_ST_C22);
-+}
-+
-+/* Direct MDIO clause 45 read via SoC */
-+int mtk_mmd_read(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg)
-+{
-+ int ret;
-+
-+ ret = mtk_mii_rw(priv, addr, devad, reg, MDIO_CMD_ADDR, MDIO_ST_C45);
-+ if (ret)
-+ return ret;
-+
-+ return mtk_mii_rw(priv, addr, devad, 0, MDIO_CMD_READ_C45,
-+ MDIO_ST_C45);
-+}
-+
-+/* Direct MDIO clause 45 write via SoC */
-+int mtk_mmd_write(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg,
-+ u16 val)
-+{
-+ int ret;
-+
-+ ret = mtk_mii_rw(priv, addr, devad, reg, MDIO_CMD_ADDR, MDIO_ST_C45);
-+ if (ret)
-+ return ret;
-+
-+ return mtk_mii_rw(priv, addr, devad, val, MDIO_CMD_WRITE,
-+ MDIO_ST_C45);
-+}
-+
-+/* Indirect MDIO clause 45 read via MII registers */
-+int mtk_mmd_ind_read(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg)
-+{
-+ int ret;
-+
-+ ret = mtk_mii_write(priv, addr, MII_MMD_ACC_CTL_REG,
-+ (MMD_ADDR << MMD_CMD_S) |
-+ ((devad << MMD_DEVAD_S) & MMD_DEVAD_M));
-+ if (ret)
-+ return ret;
-+
-+ ret = mtk_mii_write(priv, addr, MII_MMD_ADDR_DATA_REG, reg);
-+ if (ret)
-+ return ret;
-+
-+ ret = mtk_mii_write(priv, addr, MII_MMD_ACC_CTL_REG,
-+ (MMD_DATA << MMD_CMD_S) |
-+ ((devad << MMD_DEVAD_S) & MMD_DEVAD_M));
-+ if (ret)
-+ return ret;
-+
-+ return mtk_mii_read(priv, addr, MII_MMD_ADDR_DATA_REG);
-+}
-+
-+/* Indirect MDIO clause 45 write via MII registers */
-+int mtk_mmd_ind_write(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg,
-+ u16 val)
-+{
-+ int ret;
-+
-+ ret = mtk_mii_write(priv, addr, MII_MMD_ACC_CTL_REG,
-+ (MMD_ADDR << MMD_CMD_S) |
-+ ((devad << MMD_DEVAD_S) & MMD_DEVAD_M));
-+ if (ret)
-+ return ret;
-+
-+ ret = mtk_mii_write(priv, addr, MII_MMD_ADDR_DATA_REG, reg);
-+ if (ret)
-+ return ret;
-+
-+ ret = mtk_mii_write(priv, addr, MII_MMD_ACC_CTL_REG,
-+ (MMD_DATA << MMD_CMD_S) |
-+ ((devad << MMD_DEVAD_S) & MMD_DEVAD_M));
-+ if (ret)
-+ return ret;
-+
-+ return mtk_mii_write(priv, addr, MII_MMD_ADDR_DATA_REG, val);
-+}
-+
-+static int mtk_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
-+{
-+ struct mtk_eth_priv *priv = bus->priv;
-+
-+ if (devad < 0)
-+ return mtk_mii_read(priv, addr, reg);
-+
-+ return mtk_mmd_read(priv, addr, devad, reg);
-+}
-+
-+static int mtk_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
-+ u16 val)
-+{
-+ struct mtk_eth_priv *priv = bus->priv;
-+
-+ if (devad < 0)
-+ return mtk_mii_write(priv, addr, reg, val);
-+
-+ return mtk_mmd_write(priv, addr, devad, reg, val);
-+}
-+
-+static int mtk_mdio_register(struct udevice *dev)
-+{
-+ struct mtk_eth_priv *priv = dev_get_priv(dev);
-+ struct mii_dev *mdio_bus = mdio_alloc();
-+ int ret;
-+
-+ if (!mdio_bus)
-+ return -ENOMEM;
-+
-+ mdio_bus->read = mtk_mdio_read;
-+ mdio_bus->write = mtk_mdio_write;
-+ snprintf(mdio_bus->name, sizeof(mdio_bus->name), dev->name);
-+
-+ mdio_bus->priv = (void *)priv;
-+
-+ ret = mdio_register(mdio_bus);
-+
-+ if (ret)
-+ return ret;
-+
-+ priv->mdio_bus = mdio_bus;
-+
-+ return 0;
-+}
-+
-+static int mtk_switch_init(struct mtk_eth_priv *priv)
-+{
-+ struct mtk_eth_switch *swdrvs = ll_entry_start(struct mtk_eth_switch,
-+ mtk_eth_switch);
-+ const u32 n_swdrvs = ll_entry_count(struct mtk_eth_switch,
-+ mtk_eth_switch);
-+ struct mtk_eth_switch *tmp, *swdrv = NULL;
-+ u32 reset_wait_time = 500;
-+ size_t priv_size;
-+ int ret;
-+
-+ if (strcmp(priv->swname, "auto")) {
-+ for (tmp = swdrvs; tmp < swdrvs + n_swdrvs; tmp++) {
-+ if (!strcmp(tmp->name, priv->swname)) {
-+ swdrv = tmp;
-+ break;
-+ }
-+ }
-+ }
-+
-+ if (swdrv)
-+ reset_wait_time = swdrv->reset_wait_time;
-+
-+ /* Global reset switch */
-+ if (priv->mcm) {
-+ reset_assert(&priv->rst_mcm);
-+ udelay(1000);
-+ reset_deassert(&priv->rst_mcm);
-+ mdelay(reset_wait_time);
-+ } else if (dm_gpio_is_valid(&priv->rst_gpio)) {
-+ dm_gpio_set_value(&priv->rst_gpio, 0);
-+ udelay(1000);
-+ dm_gpio_set_value(&priv->rst_gpio, 1);
-+ mdelay(reset_wait_time);
-+ }
-+
-+ if (!swdrv) {
-+ for (tmp = swdrvs; tmp < swdrvs + n_swdrvs; tmp++) {
-+ if (!tmp->detect)
-+ continue;
-+
-+ ret = tmp->detect(priv);
-+ if (!ret) {
-+ swdrv = tmp;
-+ break;
-+ }
-+ }
-+
-+ if (!swdrv) {
-+ printf("Error: unable to detect switch\n");
-+ return -ENODEV;
-+ }
-+ } else {
-+ if (swdrv->detect) {
-+ ret = swdrv->detect(priv);
-+ if (ret) {
-+ printf("Error: switch probing failed\n");
-+ return -ENODEV;
-+ }
-+ }
-+ }
-+
-+ printf("%s\n", swdrv->desc);
-+
-+ priv_size = swdrv->priv_size;
-+ if (priv_size < sizeof(struct mtk_eth_switch_priv))
-+ priv_size = sizeof(struct mtk_eth_switch_priv);
-+
-+ priv->swpriv = calloc(1, priv_size);
-+ if (!priv->swpriv) {
-+ printf("Error: no memory for switch data\n");
-+ return -ENOMEM;
-+ }
-+
-+ priv->swpriv->eth = priv;
-+ priv->swpriv->soc = priv->soc;
-+ priv->swpriv->phy_interface = priv->phy_interface;
-+ priv->swpriv->sw = swdrv;
-+ priv->swpriv->ethsys_base = regmap_get_range(priv->ethsys_regmap, 0);
-+
-+ ret = swdrv->setup(priv->swpriv);
-+ if (ret) {
-+ free(priv->swpriv);
-+ priv->swpriv = NULL;
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static void mtk_xphy_link_adjust(struct mtk_eth_priv *priv)
-+{
-+ u16 lcl_adv = 0, rmt_adv = 0;
-+ u8 flowctrl;
-+ u32 mcr;
-+
-+ mcr = mtk_gmac_read(priv, XGMAC_PORT_MCR(priv->gmac_id));
-+ mcr &= ~(XGMAC_FORCE_TX_FC | XGMAC_FORCE_RX_FC);
-+
-+ if (priv->phydev->duplex) {
-+ if (priv->phydev->pause)
-+ rmt_adv = LPA_PAUSE_CAP;
-+ if (priv->phydev->asym_pause)
-+ rmt_adv |= LPA_PAUSE_ASYM;
-+
-+ if (priv->phydev->advertising & ADVERTISED_Pause)
-+ lcl_adv |= ADVERTISE_PAUSE_CAP;
-+ if (priv->phydev->advertising & ADVERTISED_Asym_Pause)
-+ lcl_adv |= ADVERTISE_PAUSE_ASYM;
-+
-+ flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
-+
-+ if (flowctrl & FLOW_CTRL_TX)
-+ mcr |= XGMAC_FORCE_TX_FC;
-+ if (flowctrl & FLOW_CTRL_RX)
-+ mcr |= XGMAC_FORCE_RX_FC;
-+
-+ debug("rx pause %s, tx pause %s\n",
-+ flowctrl & FLOW_CTRL_RX ? "enabled" : "disabled",
-+ flowctrl & FLOW_CTRL_TX ? "enabled" : "disabled");
-+ }
-+
-+ mcr &= ~(XGMAC_TRX_DISABLE);
-+ mtk_gmac_write(priv, XGMAC_PORT_MCR(priv->gmac_id), mcr);
-+}
-+
-+static void mtk_phy_link_adjust(struct mtk_eth_priv *priv)
-+{
-+ u16 lcl_adv = 0, rmt_adv = 0;
-+ u8 flowctrl;
-+ u32 mcr;
-+
-+ mcr = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) |
-+ (MAC_RX_PKT_LEN_1536 << MAC_RX_PKT_LEN_S) |
-+ MAC_MODE | FORCE_MODE |
-+ MAC_TX_EN | MAC_RX_EN |
-+ DEL_RXFIFO_CLR |
-+ BKOFF_EN | BACKPR_EN;
-+
-+ switch (priv->phydev->speed) {
-+ case SPEED_10:
-+ mcr |= (SPEED_10M << FORCE_SPD_S);
-+ break;
-+ case SPEED_100:
-+ mcr |= (SPEED_100M << FORCE_SPD_S);
-+ break;
-+ case SPEED_1000:
-+ case SPEED_2500:
-+ mcr |= (SPEED_1000M << FORCE_SPD_S);
-+ break;
-+ };
-+
-+ if (priv->phydev->link)
-+ mcr |= FORCE_LINK;
-+
-+ if (priv->phydev->duplex) {
-+ mcr |= FORCE_DPX;
-+
-+ if (priv->phydev->pause)
-+ rmt_adv = LPA_PAUSE_CAP;
-+ if (priv->phydev->asym_pause)
-+ rmt_adv |= LPA_PAUSE_ASYM;
-+
-+ if (priv->phydev->advertising & ADVERTISED_Pause)
-+ lcl_adv |= ADVERTISE_PAUSE_CAP;
-+ if (priv->phydev->advertising & ADVERTISED_Asym_Pause)
-+ lcl_adv |= ADVERTISE_PAUSE_ASYM;
-+
-+ flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
-+
-+ if (flowctrl & FLOW_CTRL_TX)
-+ mcr |= FORCE_TX_FC;
-+ if (flowctrl & FLOW_CTRL_RX)
-+ mcr |= FORCE_RX_FC;
-+
-+ debug("rx pause %s, tx pause %s\n",
-+ flowctrl & FLOW_CTRL_RX ? "enabled" : "disabled",
-+ flowctrl & FLOW_CTRL_TX ? "enabled" : "disabled");
-+ }
-+
-+ mtk_gmac_write(priv, GMAC_PORT_MCR(priv->gmac_id), mcr);
-+}
-+
-+static int mtk_phy_start(struct mtk_eth_priv *priv)
-+{
-+ struct phy_device *phydev = priv->phydev;
-+ int ret;
-+
-+ ret = phy_startup(phydev);
-+
-+ if (ret) {
-+ debug("Could not initialize PHY %s\n", phydev->dev->name);
-+ return ret;
-+ }
-+
-+ if (!phydev->link) {
-+ debug("%s: link down.\n", phydev->dev->name);
-+ return 0;
-+ }
-+
-+ if (!priv->force_mode) {
-+ if (priv->phy_interface == PHY_INTERFACE_MODE_USXGMII ||
-+ priv->phy_interface == PHY_INTERFACE_MODE_10GBASER ||
-+ priv->phy_interface == PHY_INTERFACE_MODE_XGMII)
-+ mtk_xphy_link_adjust(priv);
-+ else
-+ mtk_phy_link_adjust(priv);
-+ }
-+
-+ debug("Speed: %d, %s duplex%s\n", phydev->speed,
-+ (phydev->duplex) ? "full" : "half",
-+ (phydev->port == PORT_FIBRE) ? ", fiber mode" : "");
-+
-+ return 0;
-+}
-+
-+static int mtk_phy_probe(struct udevice *dev)
-+{
-+ struct mtk_eth_priv *priv = dev_get_priv(dev);
-+ struct phy_device *phydev;
-+
-+ phydev = phy_connect(priv->mdio_bus, priv->phy_addr, dev,
-+ priv->phy_interface);
-+ if (!phydev)
-+ return -ENODEV;
-+
-+ phydev->supported &= PHY_GBIT_FEATURES;
-+ phydev->advertising = phydev->supported;
-+
-+ priv->phydev = phydev;
-+ phy_config(phydev);
-+
-+ return 0;
-+}
-+
-+static void mtk_sgmii_an_init(struct mtk_eth_priv *priv)
-+{
-+ /* Set SGMII GEN1 speed(1G) */
-+ clrbits_le32(priv->sgmii_base + priv->soc->ana_rgc3, SGMSYS_SPEED_MASK);
-+
-+ /* Enable SGMII AN */
-+ setbits_le32(priv->sgmii_base + SGMSYS_PCS_CONTROL_1,
-+ SGMII_AN_ENABLE);
-+
-+ /* SGMII AN mode setting */
-+ writel(SGMII_AN_MODE, priv->sgmii_base + SGMSYS_SGMII_MODE);
-+
-+ /* SGMII PN SWAP setting */
-+ if (priv->pn_swap) {
-+ setbits_le32(priv->sgmii_base + SGMSYS_QPHY_WRAP_CTRL,
-+ SGMII_PN_SWAP_TX_RX);
-+ }
-+
-+ /* Release PHYA power down state */
-+ clrsetbits_le32(priv->sgmii_base + SGMSYS_QPHY_PWR_STATE_CTRL,
-+ SGMII_PHYA_PWD, 0);
-+}
-+
-+static void mtk_sgmii_force_init(struct mtk_eth_priv *priv)
-+{
-+ /* Set SGMII GEN2 speed(2.5G) */
-+ clrsetbits_le32(priv->sgmii_base + priv->soc->ana_rgc3,
-+ SGMSYS_SPEED_MASK,
-+ FIELD_PREP(SGMSYS_SPEED_MASK, SGMSYS_SPEED_2500));
-+
-+ /* Disable SGMII AN */
-+ clrsetbits_le32(priv->sgmii_base + SGMSYS_PCS_CONTROL_1,
-+ SGMII_AN_ENABLE, 0);
-+
-+ /* SGMII force mode setting */
-+ writel(SGMII_FORCE_MODE, priv->sgmii_base + SGMSYS_SGMII_MODE);
-+
-+ /* SGMII PN SWAP setting */
-+ if (priv->pn_swap) {
-+ setbits_le32(priv->sgmii_base + SGMSYS_QPHY_WRAP_CTRL,
-+ SGMII_PN_SWAP_TX_RX);
-+ }
-+
-+ /* Release PHYA power down state */
-+ clrsetbits_le32(priv->sgmii_base + SGMSYS_QPHY_PWR_STATE_CTRL,
-+ SGMII_PHYA_PWD, 0);
-+}
-+
-+static void mtk_xfi_pll_enable(struct mtk_eth_priv *priv)
-+{
-+ u32 val = 0;
-+
-+ /* Add software workaround for USXGMII PLL TCL issue */
-+ regmap_write(priv->xfi_pll_regmap, XFI_PLL_ANA_GLB8,
-+ RG_XFI_PLL_ANA_SWWA);
-+
-+ regmap_read(priv->xfi_pll_regmap, XFI_PLL_DIG_GLB8, &val);
-+ val |= RG_XFI_PLL_EN;
-+ regmap_write(priv->xfi_pll_regmap, XFI_PLL_DIG_GLB8, val);
-+}
-+
-+static void mtk_usxgmii_reset(struct mtk_eth_priv *priv)
-+{
-+ switch (priv->gmac_id) {
-+ case 1:
-+ regmap_write(priv->toprgu_regmap, 0xFC, 0x0000A004);
-+ regmap_write(priv->toprgu_regmap, 0x18, 0x88F0A004);
-+ regmap_write(priv->toprgu_regmap, 0xFC, 0x00000000);
-+ regmap_write(priv->toprgu_regmap, 0x18, 0x88F00000);
-+ regmap_write(priv->toprgu_regmap, 0x18, 0x00F00000);
-+ break;
-+ case 2:
-+ regmap_write(priv->toprgu_regmap, 0xFC, 0x00005002);
-+ regmap_write(priv->toprgu_regmap, 0x18, 0x88F05002);
-+ regmap_write(priv->toprgu_regmap, 0xFC, 0x00000000);
-+ regmap_write(priv->toprgu_regmap, 0x18, 0x88F00000);
-+ regmap_write(priv->toprgu_regmap, 0x18, 0x00F00000);
-+ break;
-+ }
-+
-+ mdelay(10);
-+}
-+
-+static void mtk_usxgmii_setup_phya_an_10000(struct mtk_eth_priv *priv)
-+{
-+ regmap_write(priv->usxgmii_regmap, 0x810, 0x000FFE6D);
-+ regmap_write(priv->usxgmii_regmap, 0x818, 0x07B1EC7B);
-+ regmap_write(priv->usxgmii_regmap, 0x80C, 0x30000000);
-+ ndelay(1020);
-+ regmap_write(priv->usxgmii_regmap, 0x80C, 0x10000000);
-+ ndelay(1020);
-+ regmap_write(priv->usxgmii_regmap, 0x80C, 0x00000000);
-+
-+ regmap_write(priv->xfi_pextp_regmap, 0x9024, 0x00C9071C);
-+ regmap_write(priv->xfi_pextp_regmap, 0x2020, 0xAA8585AA);
-+ regmap_write(priv->xfi_pextp_regmap, 0x2030, 0x0C020707);
-+ regmap_write(priv->xfi_pextp_regmap, 0x2034, 0x0E050F0F);
-+ regmap_write(priv->xfi_pextp_regmap, 0x2040, 0x00140032);
-+ regmap_write(priv->xfi_pextp_regmap, 0x50F0, 0x00C014AA);
-+ regmap_write(priv->xfi_pextp_regmap, 0x50E0, 0x3777C12B);
-+ regmap_write(priv->xfi_pextp_regmap, 0x506C, 0x005F9CFF);
-+ regmap_write(priv->xfi_pextp_regmap, 0x5070, 0x9D9DFAFA);
-+ regmap_write(priv->xfi_pextp_regmap, 0x5074, 0x27273F3F);
-+ regmap_write(priv->xfi_pextp_regmap, 0x5078, 0xA7883C68);
-+ regmap_write(priv->xfi_pextp_regmap, 0x507C, 0x11661166);
-+ regmap_write(priv->xfi_pextp_regmap, 0x5080, 0x0E000AAF);
-+ regmap_write(priv->xfi_pextp_regmap, 0x5084, 0x08080D0D);
-+ regmap_write(priv->xfi_pextp_regmap, 0x5088, 0x02030909);
-+ regmap_write(priv->xfi_pextp_regmap, 0x50E4, 0x0C0C0000);
-+ regmap_write(priv->xfi_pextp_regmap, 0x50E8, 0x04040000);
-+ regmap_write(priv->xfi_pextp_regmap, 0x50EC, 0x0F0F0C06);
-+ regmap_write(priv->xfi_pextp_regmap, 0x50A8, 0x506E8C8C);
-+ regmap_write(priv->xfi_pextp_regmap, 0x6004, 0x18190000);
-+ regmap_write(priv->xfi_pextp_regmap, 0x00F8, 0x01423342);
-+ regmap_write(priv->xfi_pextp_regmap, 0x00F4, 0x80201F20);
-+ regmap_write(priv->xfi_pextp_regmap, 0x0030, 0x00050C00);
-+ regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x02002800);
-+ ndelay(1020);
-+ regmap_write(priv->xfi_pextp_regmap, 0x30B0, 0x00000020);
-+ regmap_write(priv->xfi_pextp_regmap, 0x3028, 0x00008A01);
-+ regmap_write(priv->xfi_pextp_regmap, 0x302C, 0x0000A884);
-+ regmap_write(priv->xfi_pextp_regmap, 0x3024, 0x00083002);
-+ regmap_write(priv->xfi_pextp_regmap, 0x3010, 0x00022220);
-+ regmap_write(priv->xfi_pextp_regmap, 0x5064, 0x0F020A01);
-+ regmap_write(priv->xfi_pextp_regmap, 0x50B4, 0x06100600);
-+ regmap_write(priv->xfi_pextp_regmap, 0x3048, 0x40704000);
-+ regmap_write(priv->xfi_pextp_regmap, 0x3050, 0xA8000000);
-+ regmap_write(priv->xfi_pextp_regmap, 0x3054, 0x000000AA);
-+ regmap_write(priv->xfi_pextp_regmap, 0x306C, 0x00000F00);
-+ regmap_write(priv->xfi_pextp_regmap, 0xA060, 0x00040000);
-+ regmap_write(priv->xfi_pextp_regmap, 0x90D0, 0x00000001);
-+ regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0200E800);
-+ udelay(150);
-+ regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0200C111);
-+ ndelay(1020);
-+ regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0200C101);
-+ udelay(15);
-+ regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0202C111);
-+ ndelay(1020);
-+ regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0202C101);
-+ udelay(100);
-+ regmap_write(priv->xfi_pextp_regmap, 0x30B0, 0x00000030);
-+ regmap_write(priv->xfi_pextp_regmap, 0x00F4, 0x80201F00);
-+ regmap_write(priv->xfi_pextp_regmap, 0x3040, 0x30000000);
-+ udelay(400);
-+}
-+
-+static void mtk_usxgmii_setup_phya_force_10000(struct mtk_eth_priv *priv)
-+{
-+ regmap_write(priv->usxgmii_regmap, 0x810, 0x000FFE6C);
-+ regmap_write(priv->usxgmii_regmap, 0x818, 0x07B1EC7B);
-+ regmap_write(priv->usxgmii_regmap, 0x80C, 0xB0000000);
-+ ndelay(1020);
-+ regmap_write(priv->usxgmii_regmap, 0x80C, 0x90000000);
-+ ndelay(1020);
-+
-+ regmap_write(priv->xfi_pextp_regmap, 0x9024, 0x00C9071C);
-+ regmap_write(priv->xfi_pextp_regmap, 0x2020, 0xAA8585AA);
-+ regmap_write(priv->xfi_pextp_regmap, 0x2030, 0x0C020707);
-+ regmap_write(priv->xfi_pextp_regmap, 0x2034, 0x0E050F0F);
-+ regmap_write(priv->xfi_pextp_regmap, 0x2040, 0x00140032);
-+ regmap_write(priv->xfi_pextp_regmap, 0x50F0, 0x00C014AA);
-+ regmap_write(priv->xfi_pextp_regmap, 0x50E0, 0x3777C12B);
-+ regmap_write(priv->xfi_pextp_regmap, 0x506C, 0x005F9CFF);
-+ regmap_write(priv->xfi_pextp_regmap, 0x5070, 0x9D9DFAFA);
-+ regmap_write(priv->xfi_pextp_regmap, 0x5074, 0x27273F3F);
-+ regmap_write(priv->xfi_pextp_regmap, 0x5078, 0xA7883C68);
-+ regmap_write(priv->xfi_pextp_regmap, 0x507C, 0x11661166);
-+ regmap_write(priv->xfi_pextp_regmap, 0x5080, 0x0E000AAF);
-+ regmap_write(priv->xfi_pextp_regmap, 0x5084, 0x08080D0D);
-+ regmap_write(priv->xfi_pextp_regmap, 0x5088, 0x02030909);
-+ regmap_write(priv->xfi_pextp_regmap, 0x50E4, 0x0C0C0000);
-+ regmap_write(priv->xfi_pextp_regmap, 0x50E8, 0x04040000);
-+ regmap_write(priv->xfi_pextp_regmap, 0x50EC, 0x0F0F0C06);
-+ regmap_write(priv->xfi_pextp_regmap, 0x50A8, 0x506E8C8C);
-+ regmap_write(priv->xfi_pextp_regmap, 0x6004, 0x18190000);
-+ regmap_write(priv->xfi_pextp_regmap, 0x00F8, 0x01423342);
-+ regmap_write(priv->xfi_pextp_regmap, 0x00F4, 0x80201F20);
-+ regmap_write(priv->xfi_pextp_regmap, 0x0030, 0x00050C00);
-+ regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x02002800);
-+ ndelay(1020);
-+ regmap_write(priv->xfi_pextp_regmap, 0x30B0, 0x00000020);
-+ regmap_write(priv->xfi_pextp_regmap, 0x3028, 0x00008A01);
-+ regmap_write(priv->xfi_pextp_regmap, 0x302C, 0x0000A884);
-+ regmap_write(priv->xfi_pextp_regmap, 0x3024, 0x00083002);
-+ regmap_write(priv->xfi_pextp_regmap, 0x3010, 0x00022220);
-+ regmap_write(priv->xfi_pextp_regmap, 0x5064, 0x0F020A01);
-+ regmap_write(priv->xfi_pextp_regmap, 0x50B4, 0x06100600);
-+ regmap_write(priv->xfi_pextp_regmap, 0x3048, 0x47684100);
-+ regmap_write(priv->xfi_pextp_regmap, 0x3050, 0x00000000);
-+ regmap_write(priv->xfi_pextp_regmap, 0x3054, 0x00000000);
-+ regmap_write(priv->xfi_pextp_regmap, 0x306C, 0x00000F00);
-+ if (priv->gmac_id == 2)
-+ regmap_write(priv->xfi_pextp_regmap, 0xA008, 0x0007B400);
-+ regmap_write(priv->xfi_pextp_regmap, 0xA060, 0x00040000);
-+ regmap_write(priv->xfi_pextp_regmap, 0x90D0, 0x00000001);
-+ regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0200E800);
-+ udelay(150);
-+ regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0200C111);
-+ ndelay(1020);
-+ regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0200C101);
-+ udelay(15);
-+ regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0202C111);
-+ ndelay(1020);
-+ regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0202C101);
-+ udelay(100);
-+ regmap_write(priv->xfi_pextp_regmap, 0x30B0, 0x00000030);
-+ regmap_write(priv->xfi_pextp_regmap, 0x00F4, 0x80201F00);
-+ regmap_write(priv->xfi_pextp_regmap, 0x3040, 0x30000000);
-+ udelay(400);
-+}
-+
-+static void mtk_usxgmii_an_init(struct mtk_eth_priv *priv)
-+{
-+ mtk_xfi_pll_enable(priv);
-+ mtk_usxgmii_reset(priv);
-+ mtk_usxgmii_setup_phya_an_10000(priv);
-+}
-+
-+static void mtk_10gbaser_init(struct mtk_eth_priv *priv)
-+{
-+ mtk_xfi_pll_enable(priv);
-+ mtk_usxgmii_reset(priv);
-+ mtk_usxgmii_setup_phya_force_10000(priv);
-+}
-+
-+static int mtk_mac_init(struct mtk_eth_priv *priv)
-+{
-+ int i, sgmii_sel_mask = 0, ge_mode = 0;
-+ u32 mcr;
-+
-+ if (MTK_HAS_CAPS(priv->soc->caps, MTK_ETH_PATH_MT7629_GMAC2)) {
-+ mtk_infra_rmw(priv, MT7629_INFRA_MISC2_REG,
-+ INFRA_MISC2_BONDING_OPTION, priv->gmac_id);
-+ }
-+
-+ switch (priv->phy_interface) {
-+ case PHY_INTERFACE_MODE_RGMII_RXID:
-+ case PHY_INTERFACE_MODE_RGMII:
-+ ge_mode = GE_MODE_RGMII;
-+ break;
-+ case PHY_INTERFACE_MODE_SGMII:
-+ case PHY_INTERFACE_MODE_2500BASEX:
-+ if (!IS_ENABLED(CONFIG_MTK_ETH_SGMII)) {
-+ printf("Error: SGMII is not supported on this platform\n");
-+ return -ENOTSUPP;
-+ }
-+
-+ if (MTK_HAS_CAPS(priv->soc->caps, MTK_GMAC2_U3_QPHY)) {
-+ mtk_infra_rmw(priv, USB_PHY_SWITCH_REG, QPHY_SEL_MASK,
-+ SGMII_QPHY_SEL);
-+ }
-+
-+ if (MTK_HAS_CAPS(priv->soc->caps, MTK_ETH_PATH_MT7622_SGMII))
-+ sgmii_sel_mask = SYSCFG1_SGMII_SEL_M;
-+
-+ mtk_ethsys_rmw(priv, ETHSYS_SYSCFG1_REG, sgmii_sel_mask,
-+ SYSCFG1_SGMII_SEL(priv->gmac_id));
-+
-+ if (priv->phy_interface == PHY_INTERFACE_MODE_SGMII)
-+ mtk_sgmii_an_init(priv);
-+ else
-+ mtk_sgmii_force_init(priv);
-+
-+ ge_mode = GE_MODE_RGMII;
-+ break;
-+ case PHY_INTERFACE_MODE_MII:
-+ case PHY_INTERFACE_MODE_GMII:
-+ ge_mode = GE_MODE_MII;
-+ break;
-+ case PHY_INTERFACE_MODE_RMII:
-+ ge_mode = GE_MODE_RMII;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ /* set the gmac to the right mode */
-+ mtk_ethsys_rmw(priv, ETHSYS_SYSCFG1_REG,
-+ SYSCFG1_GE_MODE_M << SYSCFG1_GE_MODE_S(priv->gmac_id),
-+ ge_mode << SYSCFG1_GE_MODE_S(priv->gmac_id));
-+
-+ if (priv->force_mode) {
-+ mcr = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) |
-+ (MAC_RX_PKT_LEN_1536 << MAC_RX_PKT_LEN_S) |
-+ MAC_MODE | FORCE_MODE |
-+ MAC_TX_EN | MAC_RX_EN |
-+ BKOFF_EN | BACKPR_EN |
-+ FORCE_LINK;
-+
-+ switch (priv->speed) {
-+ case SPEED_10:
-+ mcr |= SPEED_10M << FORCE_SPD_S;
-+ break;
-+ case SPEED_100:
-+ mcr |= SPEED_100M << FORCE_SPD_S;
-+ break;
-+ case SPEED_1000:
-+ case SPEED_2500:
-+ mcr |= SPEED_1000M << FORCE_SPD_S;
-+ break;
-+ }
-+
-+ if (priv->duplex)
-+ mcr |= FORCE_DPX;
-+
-+ mtk_gmac_write(priv, GMAC_PORT_MCR(priv->gmac_id), mcr);
-+ }
-+
-+ if (MTK_HAS_CAPS(priv->soc->caps, MTK_GMAC1_TRGMII) &&
-+ !MTK_HAS_CAPS(priv->soc->caps, MTK_TRGMII_MT7621_CLK)) {
-+ /* Lower Tx Driving for TRGMII path */
-+ for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
-+ mtk_gmac_write(priv, GMAC_TRGMII_TD_ODT(i),
-+ (8 << TD_DM_DRVP_S) |
-+ (8 << TD_DM_DRVN_S));
-+
-+ mtk_gmac_rmw(priv, GMAC_TRGMII_RCK_CTRL, 0,
-+ RX_RST | RXC_DQSISEL);
-+ mtk_gmac_rmw(priv, GMAC_TRGMII_RCK_CTRL, RX_RST, 0);
-+ }
-+
-+ return 0;
-+}
-+
-+static int mtk_xmac_init(struct mtk_eth_priv *priv)
-+{
-+ u32 force_link = 0;
-+
-+ if (!IS_ENABLED(CONFIG_MTK_ETH_XGMII)) {
-+ printf("Error: 10Gb interface is not supported on this platform\n");
-+ return -ENOTSUPP;
-+ }
-+
-+ switch (priv->phy_interface) {
-+ case PHY_INTERFACE_MODE_USXGMII:
-+ mtk_usxgmii_an_init(priv);
-+ break;
-+ case PHY_INTERFACE_MODE_10GBASER:
-+ mtk_10gbaser_init(priv);
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ /* Set GMAC to the correct mode */
-+ mtk_ethsys_rmw(priv, ETHSYS_SYSCFG1_REG,
-+ SYSCFG1_GE_MODE_M << SYSCFG1_GE_MODE_S(priv->gmac_id),
-+ 0);
-+
-+ if ((priv->phy_interface == PHY_INTERFACE_MODE_USXGMII ||
-+ priv->phy_interface == PHY_INTERFACE_MODE_10GBASER) &&
-+ priv->gmac_id == 1) {
-+ mtk_infra_rmw(priv, TOPMISC_NETSYS_PCS_MUX,
-+ NETSYS_PCS_MUX_MASK, MUX_G2_USXGMII_SEL);
-+ }
-+
-+ if (priv->phy_interface == PHY_INTERFACE_MODE_XGMII ||
-+ priv->gmac_id == 2)
-+ force_link = XGMAC_FORCE_LINK(priv->gmac_id);
-+
-+ mtk_gmac_rmw(priv, XGMAC_STS(priv->gmac_id),
-+ XGMAC_FORCE_LINK(priv->gmac_id), force_link);
-+
-+ /* Force GMAC link down */
-+ mtk_gmac_write(priv, GMAC_PORT_MCR(priv->gmac_id), FORCE_MODE);
-+
-+ return 0;
-+}
-+
-+static void mtk_eth_fifo_init(struct mtk_eth_priv *priv)
-+{
-+ char *pkt_base = priv->pkt_pool;
-+ struct mtk_tx_dma_v2 *txd;
-+ struct mtk_rx_dma_v2 *rxd;
-+ int i;
-+
-+ mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG, 0xffff0000, 0);
-+ udelay(500);
-+
-+ memset(priv->tx_ring_noc, 0, NUM_TX_DESC * priv->soc->txd_size);
-+ memset(priv->rx_ring_noc, 0, NUM_RX_DESC * priv->soc->rxd_size);
-+ memset(priv->pkt_pool, 0xff, TOTAL_PKT_BUF_SIZE);
-+
-+ flush_dcache_range((ulong)pkt_base,
-+ (ulong)(pkt_base + TOTAL_PKT_BUF_SIZE));
-+
-+ priv->rx_dma_owner_idx0 = 0;
-+ priv->tx_cpu_owner_idx0 = 0;
-+
-+ for (i = 0; i < NUM_TX_DESC; i++) {
-+ txd = priv->tx_ring_noc + i * priv->soc->txd_size;
-+
-+ txd->txd1 = virt_to_phys(pkt_base);
-+ txd->txd2 = PDMA_TXD2_DDONE | PDMA_TXD2_LS0;
-+
-+ if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3))
-+ txd->txd5 = PDMA_V2_TXD5_FPORT_SET(priv->gmac_id == 2 ?
-+ 15 : priv->gmac_id + 1);
-+ else if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2))
-+ txd->txd5 = PDMA_V2_TXD5_FPORT_SET(priv->gmac_id + 1);
-+ else
-+ txd->txd4 = PDMA_V1_TXD4_FPORT_SET(priv->gmac_id + 1);
-+
-+ pkt_base += PKTSIZE_ALIGN;
-+ }
-+
-+ for (i = 0; i < NUM_RX_DESC; i++) {
-+ rxd = priv->rx_ring_noc + i * priv->soc->rxd_size;
-+
-+ rxd->rxd1 = virt_to_phys(pkt_base);
-+
-+ if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2) ||
-+ MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3))
-+ rxd->rxd2 = PDMA_V2_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
-+ else
-+ rxd->rxd2 = PDMA_V1_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
-+
-+ pkt_base += PKTSIZE_ALIGN;
-+ }
-+
-+ mtk_pdma_write(priv, TX_BASE_PTR_REG(0),
-+ virt_to_phys(priv->tx_ring_noc));
-+ mtk_pdma_write(priv, TX_MAX_CNT_REG(0), NUM_TX_DESC);
-+ mtk_pdma_write(priv, TX_CTX_IDX_REG(0), priv->tx_cpu_owner_idx0);
-+
-+ mtk_pdma_write(priv, RX_BASE_PTR_REG(0),
-+ virt_to_phys(priv->rx_ring_noc));
-+ mtk_pdma_write(priv, RX_MAX_CNT_REG(0), NUM_RX_DESC);
-+ mtk_pdma_write(priv, RX_CRX_IDX_REG(0), NUM_RX_DESC - 1);
-+
-+ mtk_pdma_write(priv, PDMA_RST_IDX_REG, RST_DTX_IDX0 | RST_DRX_IDX0);
-+}
-+
-+static void mtk_eth_mdc_init(struct mtk_eth_priv *priv)
-+{
-+ u32 divider;
-+
-+ if (priv->mdc == 0)
-+ return;
-+
-+ divider = min_t(u32, DIV_ROUND_UP(MDC_MAX_FREQ, priv->mdc), MDC_MAX_DIVIDER);
-+
-+ /* Configure MDC turbo mode */
-+ if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3))
-+ mtk_gmac_rmw(priv, GMAC_MAC_MISC_REG, 0, MISC_MDC_TURBO);
-+ else
-+ mtk_gmac_rmw(priv, GMAC_PPSC_REG, 0, MISC_MDC_TURBO);
-+
-+ /* Configure MDC divider */
-+ mtk_gmac_rmw(priv, GMAC_PPSC_REG, PHY_MDC_CFG,
-+ FIELD_PREP(PHY_MDC_CFG, divider));
-+}
-+
-+static int mtk_eth_start(struct udevice *dev)
-+{
-+ struct mtk_eth_priv *priv = dev_get_priv(dev);
-+ int i, ret;
-+
-+ /* Reset FE */
-+ reset_assert(&priv->rst_fe);
-+ udelay(1000);
-+ reset_deassert(&priv->rst_fe);
-+ mdelay(10);
-+
-+ if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2) ||
-+ MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3))
-+ setbits_le32(priv->fe_base + FE_GLO_MISC_REG, PDMA_VER_V2);
-+
-+ /* Packets forward to PDMA */
-+ mtk_gdma_write(priv, priv->gmac_id, GDMA_IG_CTRL_REG, GDMA_FWD_TO_CPU);
-+
-+ for (i = 0; i < priv->soc->gdma_count; i++) {
-+ if (i == priv->gmac_id)
-+ continue;
-+
-+ mtk_gdma_write(priv, i, GDMA_IG_CTRL_REG, GDMA_FWD_DISCARD);
-+ }
-+
-+ if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3)) {
-+ if (priv->swpriv && !strcmp(priv->swpriv->sw->name, "mt7988") &&
-+ priv->gmac_id == 0) {
-+ mtk_gdma_write(priv, priv->gmac_id, GDMA_IG_CTRL_REG,
-+ GDMA_BRIDGE_TO_CPU);
-+
-+ mtk_gdma_write(priv, priv->gmac_id, GDMA_EG_CTRL_REG,
-+ GDMA_CPU_BRIDGE_EN);
-+ } else if ((priv->phy_interface == PHY_INTERFACE_MODE_USXGMII ||
-+ priv->phy_interface == PHY_INTERFACE_MODE_10GBASER ||
-+ priv->phy_interface == PHY_INTERFACE_MODE_XGMII) &&
-+ priv->gmac_id != 0) {
-+ mtk_gdma_write(priv, priv->gmac_id, GDMA_EG_CTRL_REG,
-+ GDMA_CPU_BRIDGE_EN);
-+ }
-+ }
-+
-+ udelay(500);
-+
-+ mtk_eth_fifo_init(priv);
-+
-+ if (priv->swpriv) {
-+ /* Enable communication with switch */
-+ if (priv->swpriv->sw->mac_control)
-+ priv->swpriv->sw->mac_control(priv->swpriv, true);
-+ } else {
-+ /* Start PHY */
-+ ret = mtk_phy_start(priv);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG, 0,
-+ TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN);
-+ udelay(500);
-+
-+ return 0;
-+}
-+
-+static void mtk_eth_stop(struct udevice *dev)
-+{
-+ struct mtk_eth_priv *priv = dev_get_priv(dev);
-+
-+ if (priv->swpriv) {
-+ if (priv->swpriv->sw->mac_control)
-+ priv->swpriv->sw->mac_control(priv->swpriv, false);
-+ }
-+
-+ mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG,
-+ TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN, 0);
-+ udelay(500);
-+
-+ wait_for_bit_le32(priv->fe_base + priv->soc->pdma_base + PDMA_GLO_CFG_REG,
-+ RX_DMA_BUSY | TX_DMA_BUSY, 0, 5000, 0);
-+}
-+
-+static int mtk_eth_write_hwaddr(struct udevice *dev)
-+{
-+ struct eth_pdata *pdata = dev_get_plat(dev);
-+ struct mtk_eth_priv *priv = dev_get_priv(dev);
-+ unsigned char *mac = pdata->enetaddr;
-+ u32 macaddr_lsb, macaddr_msb;
-+
-+ macaddr_msb = ((u32)mac[0] << 8) | (u32)mac[1];
-+ macaddr_lsb = ((u32)mac[2] << 24) | ((u32)mac[3] << 16) |
-+ ((u32)mac[4] << 8) | (u32)mac[5];
-+
-+ mtk_gdma_write(priv, priv->gmac_id, GDMA_MAC_MSB_REG, macaddr_msb);
-+ mtk_gdma_write(priv, priv->gmac_id, GDMA_MAC_LSB_REG, macaddr_lsb);
-+
-+ return 0;
-+}
-+
-+static int mtk_eth_send(struct udevice *dev, void *packet, int length)
-+{
-+ struct mtk_eth_priv *priv = dev_get_priv(dev);
-+ u32 idx = priv->tx_cpu_owner_idx0;
-+ struct mtk_tx_dma_v2 *txd;
-+ void *pkt_base;
-+
-+ txd = priv->tx_ring_noc + idx * priv->soc->txd_size;
-+
-+ if (!(txd->txd2 & PDMA_TXD2_DDONE)) {
-+ debug("mtk-eth: TX DMA descriptor ring is full\n");
-+ return -EPERM;
-+ }
-+
-+ pkt_base = (void *)phys_to_virt(txd->txd1);
-+ memcpy(pkt_base, packet, length);
-+ flush_dcache_range((ulong)pkt_base, (ulong)pkt_base +
-+ roundup(length, ARCH_DMA_MINALIGN));
-+
-+ if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2) ||
-+ MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3))
-+ txd->txd2 = PDMA_TXD2_LS0 | PDMA_V2_TXD2_SDL0_SET(length);
-+ else
-+ txd->txd2 = PDMA_TXD2_LS0 | PDMA_V1_TXD2_SDL0_SET(length);
-+
-+ priv->tx_cpu_owner_idx0 = (priv->tx_cpu_owner_idx0 + 1) % NUM_TX_DESC;
-+ mtk_pdma_write(priv, TX_CTX_IDX_REG(0), priv->tx_cpu_owner_idx0);
-+
-+ return 0;
-+}
-+
-+static int mtk_eth_recv(struct udevice *dev, int flags, uchar **packetp)
-+{
-+ struct mtk_eth_priv *priv = dev_get_priv(dev);
-+ u32 idx = priv->rx_dma_owner_idx0;
-+ struct mtk_rx_dma_v2 *rxd;
-+ uchar *pkt_base;
-+ u32 length;
-+
-+ rxd = priv->rx_ring_noc + idx * priv->soc->rxd_size;
-+
-+ if (!(rxd->rxd2 & PDMA_RXD2_DDONE)) {
-+ debug("mtk-eth: RX DMA descriptor ring is empty\n");
-+ return -EAGAIN;
-+ }
-+
-+ if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2) ||
-+ MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3))
-+ length = PDMA_V2_RXD2_PLEN0_GET(rxd->rxd2);
-+ else
-+ length = PDMA_V1_RXD2_PLEN0_GET(rxd->rxd2);
-+
-+ pkt_base = (void *)phys_to_virt(rxd->rxd1);
-+ invalidate_dcache_range((ulong)pkt_base, (ulong)pkt_base +
-+ roundup(length, ARCH_DMA_MINALIGN));
-+
-+ if (packetp)
-+ *packetp = pkt_base;
-+
-+ return length;
-+}
-+
-+static int mtk_eth_free_pkt(struct udevice *dev, uchar *packet, int length)
-+{
-+ struct mtk_eth_priv *priv = dev_get_priv(dev);
-+ u32 idx = priv->rx_dma_owner_idx0;
-+ struct mtk_rx_dma_v2 *rxd;
-+
-+ rxd = priv->rx_ring_noc + idx * priv->soc->rxd_size;
-+
-+ invalidate_dcache_range((ulong)rxd->rxd1,
-+ (ulong)rxd->rxd1 + PKTSIZE_ALIGN);
-+
-+ if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2) ||
-+ MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3))
-+ rxd->rxd2 = PDMA_V2_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
-+ else
-+ rxd->rxd2 = PDMA_V1_RXD2_PLEN0_SET(PKTSIZE_ALIGN);
-+
-+ mtk_pdma_write(priv, RX_CRX_IDX_REG(0), idx);
-+ priv->rx_dma_owner_idx0 = (priv->rx_dma_owner_idx0 + 1) % NUM_RX_DESC;
-+
-+ return 0;
-+}
-+
-+static int mtk_eth_probe(struct udevice *dev)
-+{
-+ struct eth_pdata *pdata = dev_get_plat(dev);
-+ struct mtk_eth_priv *priv = dev_get_priv(dev);
-+ ulong iobase = pdata->iobase;
-+ int ret;
-+
-+ /* Frame Engine Register Base */
-+ priv->fe_base = (void *)iobase;
-+
-+ /* GMAC Register Base */
-+ priv->gmac_base = (void *)(iobase + GMAC_BASE);
-+
-+ /* MDIO register */
-+ ret = mtk_mdio_register(dev);
-+ if (ret)
-+ return ret;
-+
-+ /* Prepare for tx/rx rings */
-+ priv->tx_ring_noc = (void *)
-+ noncached_alloc(priv->soc->txd_size * NUM_TX_DESC,
-+ ARCH_DMA_MINALIGN);
-+ priv->rx_ring_noc = (void *)
-+ noncached_alloc(priv->soc->rxd_size * NUM_RX_DESC,
-+ ARCH_DMA_MINALIGN);
-+
-+ /* Set MDC divider */
-+ mtk_eth_mdc_init(priv);
-+
-+ /* Set MAC mode */
-+ if (priv->phy_interface == PHY_INTERFACE_MODE_USXGMII ||
-+ priv->phy_interface == PHY_INTERFACE_MODE_10GBASER ||
-+ priv->phy_interface == PHY_INTERFACE_MODE_XGMII)
-+ ret = mtk_xmac_init(priv);
-+ else
-+ ret = mtk_mac_init(priv);
-+
-+ if (ret)
-+ return ret;
-+
-+ /* Probe phy if switch is not specified */
-+ if (!priv->swname)
-+ return mtk_phy_probe(dev);
-+
-+ /* Initialize switch */
-+ return mtk_switch_init(priv);
-+}
-+
-+static int mtk_eth_remove(struct udevice *dev)
-+{
-+ struct mtk_eth_priv *priv = dev_get_priv(dev);
-+
-+ /* MDIO unregister */
-+ mdio_unregister(priv->mdio_bus);
-+ mdio_free(priv->mdio_bus);
-+
-+ /* Stop possibly started DMA */
-+ mtk_eth_stop(dev);
-+
-+ if (priv->swpriv) {
-+ if (priv->swpriv->sw->cleanup)
-+ priv->swpriv->sw->cleanup(priv->swpriv);
-+ free(priv->swpriv);
-+ }
-+
-+ return 0;
-+}
-+
-+static int mtk_eth_of_to_plat(struct udevice *dev)
-+{
-+ struct eth_pdata *pdata = dev_get_plat(dev);
-+ struct mtk_eth_priv *priv = dev_get_priv(dev);
-+ struct ofnode_phandle_args args;
-+ struct regmap *regmap;
-+ ofnode subnode;
-+ int ret;
-+
-+ priv->soc = (const struct mtk_soc_data *)dev_get_driver_data(dev);
-+ if (!priv->soc) {
-+ dev_err(dev, "missing soc compatible data\n");
-+ return -EINVAL;
-+ }
-+
-+ pdata->iobase = (phys_addr_t)dev_remap_addr(dev);
-+
-+ /* get corresponding ethsys phandle */
-+ ret = dev_read_phandle_with_args(dev, "mediatek,ethsys", NULL, 0, 0,
-+ &args);
-+ if (ret)
-+ return ret;
-+
-+ priv->ethsys_regmap = syscon_node_to_regmap(args.node);
-+ if (IS_ERR(priv->ethsys_regmap))
-+ return PTR_ERR(priv->ethsys_regmap);
-+
-+ if (MTK_HAS_CAPS(priv->soc->caps, MTK_INFRA)) {
-+ /* get corresponding infracfg phandle */
-+ ret = dev_read_phandle_with_args(dev, "mediatek,infracfg",
-+ NULL, 0, 0, &args);
-+
-+ if (ret)
-+ return ret;
-+
-+ priv->infra_regmap = syscon_node_to_regmap(args.node);
-+ if (IS_ERR(priv->infra_regmap))
-+ return PTR_ERR(priv->infra_regmap);
-+ }
-+
-+ /* Reset controllers */
-+ ret = reset_get_by_name(dev, "fe", &priv->rst_fe);
-+ if (ret) {
-+ printf("error: Unable to get reset ctrl for frame engine\n");
-+ return ret;
-+ }
-+
-+ priv->gmac_id = dev_read_u32_default(dev, "mediatek,gmac-id", 0);
-+
-+ priv->mdc = 0;
-+ subnode = ofnode_find_subnode(dev_ofnode(dev), "mdio");
-+ if (ofnode_valid(subnode)) {
-+ priv->mdc = ofnode_read_u32_default(subnode, "clock-frequency", 2500000);
-+ if (priv->mdc > MDC_MAX_FREQ ||
-+ priv->mdc < MDC_MAX_FREQ / MDC_MAX_DIVIDER) {
-+ printf("error: MDIO clock frequency out of range\n");
-+ return -EINVAL;
-+ }
-+ }
-+
-+ /* Interface mode is required */
-+ pdata->phy_interface = dev_read_phy_mode(dev);
-+ priv->phy_interface = pdata->phy_interface;
-+ if (pdata->phy_interface == PHY_INTERFACE_MODE_NA) {
-+ printf("error: phy-mode is not set\n");
-+ return -EINVAL;
-+ }
-+
-+ /* Force mode or autoneg */
-+ subnode = ofnode_find_subnode(dev_ofnode(dev), "fixed-link");
-+ if (ofnode_valid(subnode)) {
-+ priv->force_mode = 1;
-+ priv->speed = ofnode_read_u32_default(subnode, "speed", 0);
-+ priv->duplex = ofnode_read_bool(subnode, "full-duplex");
-+
-+ if (priv->speed != SPEED_10 && priv->speed != SPEED_100 &&
-+ priv->speed != SPEED_1000 && priv->speed != SPEED_2500 &&
-+ priv->speed != SPEED_10000) {
-+ printf("error: no valid speed set in fixed-link\n");
-+ return -EINVAL;
-+ }
-+ }
-+
-+ if ((priv->phy_interface == PHY_INTERFACE_MODE_SGMII ||
-+ priv->phy_interface == PHY_INTERFACE_MODE_2500BASEX) &&
-+ IS_ENABLED(CONFIG_MTK_ETH_SGMII)) {
-+ /* get corresponding sgmii phandle */
-+ ret = dev_read_phandle_with_args(dev, "mediatek,sgmiisys",
-+ NULL, 0, 0, &args);
-+ if (ret)
-+ return ret;
-+
-+ regmap = syscon_node_to_regmap(args.node);
-+
-+ if (IS_ERR(regmap))
-+ return PTR_ERR(regmap);
-+
-+ priv->sgmii_base = regmap_get_range(regmap, 0);
-+
-+ if (!priv->sgmii_base) {
-+ dev_err(dev, "Unable to find sgmii\n");
-+ return -ENODEV;
-+ }
-+
-+ /* Upstream linux use mediatek,pnswap instead of pn_swap */
-+ priv->pn_swap = ofnode_read_bool(args.node, "pn_swap") ||
-+ ofnode_read_bool(args.node, "mediatek,pnswap");
-+ } else if ((priv->phy_interface == PHY_INTERFACE_MODE_USXGMII ||
-+ priv->phy_interface == PHY_INTERFACE_MODE_10GBASER) &&
-+ IS_ENABLED(CONFIG_MTK_ETH_XGMII)) {
-+ /* get corresponding usxgmii phandle */
-+ ret = dev_read_phandle_with_args(dev, "mediatek,usxgmiisys",
-+ NULL, 0, 0, &args);
-+ if (ret)
-+ return ret;
-+
-+ priv->usxgmii_regmap = syscon_node_to_regmap(args.node);
-+ if (IS_ERR(priv->usxgmii_regmap))
-+ return PTR_ERR(priv->usxgmii_regmap);
-+
-+ /* get corresponding xfi_pextp phandle */
-+ ret = dev_read_phandle_with_args(dev, "mediatek,xfi_pextp",
-+ NULL, 0, 0, &args);
-+ if (ret)
-+ return ret;
-+
-+ priv->xfi_pextp_regmap = syscon_node_to_regmap(args.node);
-+ if (IS_ERR(priv->xfi_pextp_regmap))
-+ return PTR_ERR(priv->xfi_pextp_regmap);
-+
-+ /* get corresponding xfi_pll phandle */
-+ ret = dev_read_phandle_with_args(dev, "mediatek,xfi_pll",
-+ NULL, 0, 0, &args);
-+ if (ret)
-+ return ret;
-+
-+ priv->xfi_pll_regmap = syscon_node_to_regmap(args.node);
-+ if (IS_ERR(priv->xfi_pll_regmap))
-+ return PTR_ERR(priv->xfi_pll_regmap);
-+
-+ /* get corresponding toprgu phandle */
-+ ret = dev_read_phandle_with_args(dev, "mediatek,toprgu",
-+ NULL, 0, 0, &args);
-+ if (ret)
-+ return ret;
-+
-+ priv->toprgu_regmap = syscon_node_to_regmap(args.node);
-+ if (IS_ERR(priv->toprgu_regmap))
-+ return PTR_ERR(priv->toprgu_regmap);
-+ }
-+
-+ priv->swname = dev_read_string(dev, "mediatek,switch");
-+ if (priv->swname) {
-+ priv->mcm = dev_read_bool(dev, "mediatek,mcm");
-+ if (priv->mcm) {
-+ ret = reset_get_by_name(dev, "mcm", &priv->rst_mcm);
-+ if (ret) {
-+ printf("error: no reset ctrl for mcm\n");
-+ return ret;
-+ }
-+ } else {
-+ gpio_request_by_name(dev, "reset-gpios", 0,
-+ &priv->rst_gpio, GPIOD_IS_OUT);
-+ }
-+ } else {
-+ ret = dev_read_phandle_with_args(dev, "phy-handle", NULL, 0,
-+ 0, &args);
-+ if (ret) {
-+ printf("error: phy-handle is not specified\n");
-+ return ret;
-+ }
-+
-+ priv->phy_addr = ofnode_read_s32_default(args.node, "reg", -1);
-+ if (priv->phy_addr < 0) {
-+ printf("error: phy address is not specified\n");
-+ return ret;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct mtk_soc_data mt7988_data = {
-+ .caps = MT7988_CAPS,
-+ .ana_rgc3 = 0x128,
-+ .gdma_count = 3,
-+ .pdma_base = PDMA_V3_BASE,
-+ .txd_size = sizeof(struct mtk_tx_dma_v2),
-+ .rxd_size = sizeof(struct mtk_rx_dma_v2),
-+};
-+
-+static const struct mtk_soc_data mt7986_data = {
-+ .caps = MT7986_CAPS,
-+ .ana_rgc3 = 0x128,
-+ .gdma_count = 2,
-+ .pdma_base = PDMA_V2_BASE,
-+ .txd_size = sizeof(struct mtk_tx_dma_v2),
-+ .rxd_size = sizeof(struct mtk_rx_dma_v2),
-+};
-+
-+static const struct mtk_soc_data mt7981_data = {
-+ .caps = MT7981_CAPS,
-+ .ana_rgc3 = 0x128,
-+ .gdma_count = 2,
-+ .pdma_base = PDMA_V2_BASE,
-+ .txd_size = sizeof(struct mtk_tx_dma_v2),
-+ .rxd_size = sizeof(struct mtk_rx_dma_v2),
-+};
-+
-+static const struct mtk_soc_data mt7629_data = {
-+ .caps = MT7629_CAPS,
-+ .ana_rgc3 = 0x128,
-+ .gdma_count = 2,
-+ .pdma_base = PDMA_V1_BASE,
-+ .txd_size = sizeof(struct mtk_tx_dma),
-+ .rxd_size = sizeof(struct mtk_rx_dma),
-+};
-+
-+static const struct mtk_soc_data mt7623_data = {
-+ .caps = MT7623_CAPS,
-+ .gdma_count = 2,
-+ .pdma_base = PDMA_V1_BASE,
-+ .txd_size = sizeof(struct mtk_tx_dma),
-+ .rxd_size = sizeof(struct mtk_rx_dma),
-+};
-+
-+static const struct mtk_soc_data mt7622_data = {
-+ .caps = MT7622_CAPS,
-+ .ana_rgc3 = 0x2028,
-+ .gdma_count = 2,
-+ .pdma_base = PDMA_V1_BASE,
-+ .txd_size = sizeof(struct mtk_tx_dma),
-+ .rxd_size = sizeof(struct mtk_rx_dma),
-+};
-+
-+static const struct mtk_soc_data mt7621_data = {
-+ .caps = MT7621_CAPS,
-+ .gdma_count = 2,
-+ .pdma_base = PDMA_V1_BASE,
-+ .txd_size = sizeof(struct mtk_tx_dma),
-+ .rxd_size = sizeof(struct mtk_rx_dma),
-+};
-+
-+static const struct udevice_id mtk_eth_ids[] = {
-+ { .compatible = "mediatek,mt7988-eth", .data = (ulong)&mt7988_data },
-+ { .compatible = "mediatek,mt7986-eth", .data = (ulong)&mt7986_data },
-+ { .compatible = "mediatek,mt7981-eth", .data = (ulong)&mt7981_data },
-+ { .compatible = "mediatek,mt7629-eth", .data = (ulong)&mt7629_data },
-+ { .compatible = "mediatek,mt7623-eth", .data = (ulong)&mt7623_data },
-+ { .compatible = "mediatek,mt7622-eth", .data = (ulong)&mt7622_data },
-+ { .compatible = "mediatek,mt7621-eth", .data = (ulong)&mt7621_data },
-+ {}
-+};
-+
-+static const struct eth_ops mtk_eth_ops = {
-+ .start = mtk_eth_start,
-+ .stop = mtk_eth_stop,
-+ .send = mtk_eth_send,
-+ .recv = mtk_eth_recv,
-+ .free_pkt = mtk_eth_free_pkt,
-+ .write_hwaddr = mtk_eth_write_hwaddr,
-+};
-+
-+U_BOOT_DRIVER(mtk_eth) = {
-+ .name = "mtk-eth",
-+ .id = UCLASS_ETH,
-+ .of_match = mtk_eth_ids,
-+ .of_to_plat = mtk_eth_of_to_plat,
-+ .plat_auto = sizeof(struct eth_pdata),
-+ .probe = mtk_eth_probe,
-+ .remove = mtk_eth_remove,
-+ .ops = &mtk_eth_ops,
-+ .priv_auto = sizeof(struct mtk_eth_priv),
-+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
-+};
---- a/drivers/net/mtk_eth.h
-+++ /dev/null
-@@ -1,600 +0,0 @@
--/* SPDX-License-Identifier: GPL-2.0 */
--/*
-- * Copyright (C) 2018 MediaTek Inc.
-- *
-- * Author: Weijie Gao <weijie.gao@mediatek.com>
-- * Author: Mark Lee <mark-mc.lee@mediatek.com>
-- */
--
--#ifndef _MTK_ETH_H_
--#define _MTK_ETH_H_
--
--#include <linux/bitops.h>
--#include <linux/bitfield.h>
--
--enum mkt_eth_capabilities {
-- MTK_TRGMII_BIT,
-- MTK_TRGMII_MT7621_CLK_BIT,
-- MTK_U3_COPHY_V2_BIT,
-- MTK_INFRA_BIT,
-- MTK_NETSYS_V2_BIT,
-- MTK_NETSYS_V3_BIT,
--
-- /* PATH BITS */
-- MTK_ETH_PATH_GMAC1_TRGMII_BIT,
-- MTK_ETH_PATH_GMAC2_SGMII_BIT,
-- MTK_ETH_PATH_MT7622_SGMII_BIT,
-- MTK_ETH_PATH_MT7629_GMAC2_BIT,
--};
--
--#define MTK_TRGMII BIT(MTK_TRGMII_BIT)
--#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
--#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT)
--#define MTK_INFRA BIT(MTK_INFRA_BIT)
--#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT)
--#define MTK_NETSYS_V3 BIT(MTK_NETSYS_V3_BIT)
--
--/* Supported path present on SoCs */
--#define MTK_ETH_PATH_GMAC1_TRGMII BIT(MTK_ETH_PATH_GMAC1_TRGMII_BIT)
--
--#define MTK_ETH_PATH_GMAC2_SGMII BIT(MTK_ETH_PATH_GMAC2_SGMII_BIT)
--#define MTK_ETH_PATH_MT7622_SGMII BIT(MTK_ETH_PATH_MT7622_SGMII_BIT)
--#define MTK_ETH_PATH_MT7629_GMAC2 BIT(MTK_ETH_PATH_MT7629_GMAC2_BIT)
--
--#define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
--
--#define MTK_GMAC2_U3_QPHY (MTK_ETH_PATH_GMAC2_SGMII | MTK_U3_COPHY_V2 | MTK_INFRA)
--
--#define MTK_HAS_CAPS(caps, _x) (((caps) & (_x)) == (_x))
--
--#define MT7621_CAPS (MTK_GMAC1_TRGMII | MTK_TRGMII_MT7621_CLK)
--
--#define MT7622_CAPS (MTK_ETH_PATH_MT7622_SGMII)
--
--#define MT7623_CAPS (MTK_GMAC1_TRGMII)
--
--#define MT7629_CAPS (MTK_ETH_PATH_MT7629_GMAC2 | MTK_INFRA)
--
--#define MT7981_CAPS (MTK_GMAC2_U3_QPHY | MTK_NETSYS_V2)
--
--#define MT7986_CAPS (MTK_NETSYS_V2)
--
--#define MT7988_CAPS (MTK_NETSYS_V3 | MTK_INFRA)
--
--/* Frame Engine Register Bases */
--#define PDMA_V1_BASE 0x0800
--#define PDMA_V2_BASE 0x6000
--#define PDMA_V3_BASE 0x6800
--#define GDMA1_BASE 0x0500
--#define GDMA2_BASE 0x1500
--#define GDMA3_BASE 0x0540
--#define GMAC_BASE 0x10000
--#define GSW_BASE 0x20000
--
--/* Ethernet subsystem registers */
--
--#define ETHSYS_SYSCFG1_REG 0x14
--#define SYSCFG1_GE_MODE_S(n) (12 + ((n) * 2))
--#define SYSCFG1_GE_MODE_M 0x3
--#define SYSCFG1_SGMII_SEL_M GENMASK(9, 8)
--#define SYSCFG1_SGMII_SEL(gmac) BIT(9 - (gmac))
--
--#define ETHSYS_CLKCFG0_REG 0x2c
--#define ETHSYS_TRGMII_CLK_SEL362_5 BIT(11)
--
--/* Top misc registers */
--#define TOPMISC_NETSYS_PCS_MUX 0x84
--#define NETSYS_PCS_MUX_MASK GENMASK(1, 0)
--#define MUX_G2_USXGMII_SEL BIT(1)
--#define MUX_HSGMII1_G1_SEL BIT(0)
--
--#define USB_PHY_SWITCH_REG 0x218
--#define QPHY_SEL_MASK 0x3
--#define SGMII_QPHY_SEL 0x2
--
--#define MT7629_INFRA_MISC2_REG 0x70c
--#define INFRA_MISC2_BONDING_OPTION GENMASK(15, 0)
--
--/* SYSCFG1_GE_MODE: GE Modes */
--#define GE_MODE_RGMII 0
--#define GE_MODE_MII 1
--#define GE_MODE_MII_PHY 2
--#define GE_MODE_RMII 3
--
--/* SGMII subsystem config registers */
--#define SGMSYS_PCS_CONTROL_1 0x0
--#define SGMII_LINK_STATUS BIT(18)
--#define SGMII_AN_ENABLE BIT(12)
--#define SGMII_AN_RESTART BIT(9)
--
--#define SGMSYS_SGMII_MODE 0x20
--#define SGMII_AN_MODE 0x31120103
--#define SGMII_FORCE_MODE 0x31120019
--
--#define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8
--#define SGMII_PHYA_PWD BIT(4)
--
--#define SGMSYS_QPHY_WRAP_CTRL 0xec
--#define SGMII_PN_SWAP_TX_RX 0x03
--
--#define SGMSYS_GEN2_SPEED 0x2028
--#define SGMSYS_GEN2_SPEED_V2 0x128
--#define SGMSYS_SPEED_MASK GENMASK(3, 2)
--#define SGMSYS_SPEED_2500 1
--
--/* USXGMII subsystem config registers */
--/* Register to control USXGMII XFI PLL digital */
--#define XFI_PLL_DIG_GLB8 0x08
--#define RG_XFI_PLL_EN BIT(31)
--
--/* Register to control USXGMII XFI PLL analog */
--#define XFI_PLL_ANA_GLB8 0x108
--#define RG_XFI_PLL_ANA_SWWA 0x02283248
--
--/* Frame Engine Registers */
--#define PSE_NO_DROP_CFG_REG 0x108
--#define PSE_NO_DROP_GDM1 BIT(1)
--
--#define FE_GLO_MISC_REG 0x124
--#define PDMA_VER_V2 BIT(4)
--
--/* PDMA */
--#define TX_BASE_PTR_REG(n) (0x000 + (n) * 0x10)
--#define TX_MAX_CNT_REG(n) (0x004 + (n) * 0x10)
--#define TX_CTX_IDX_REG(n) (0x008 + (n) * 0x10)
--#define TX_DTX_IDX_REG(n) (0x00c + (n) * 0x10)
--
--#define RX_BASE_PTR_REG(n) (0x100 + (n) * 0x10)
--#define RX_MAX_CNT_REG(n) (0x104 + (n) * 0x10)
--#define RX_CRX_IDX_REG(n) (0x108 + (n) * 0x10)
--#define RX_DRX_IDX_REG(n) (0x10c + (n) * 0x10)
--
--#define PDMA_GLO_CFG_REG 0x204
--#define TX_WB_DDONE BIT(6)
--#define RX_DMA_BUSY BIT(3)
--#define RX_DMA_EN BIT(2)
--#define TX_DMA_BUSY BIT(1)
--#define TX_DMA_EN BIT(0)
--
--#define PDMA_RST_IDX_REG 0x208
--#define RST_DRX_IDX0 BIT(16)
--#define RST_DTX_IDX0 BIT(0)
--
--/* GDMA */
--#define GDMA_IG_CTRL_REG 0x000
--#define GDM_ICS_EN BIT(22)
--#define GDM_TCS_EN BIT(21)
--#define GDM_UCS_EN BIT(20)
--#define STRP_CRC BIT(16)
--#define MYMAC_DP_S 12
--#define MYMAC_DP_M 0xf000
--#define BC_DP_S 8
--#define BC_DP_M 0xf00
--#define MC_DP_S 4
--#define MC_DP_M 0xf0
--#define UN_DP_S 0
--#define UN_DP_M 0x0f
--
--#define GDMA_EG_CTRL_REG 0x004
--#define GDMA_CPU_BRIDGE_EN BIT(31)
--
--#define GDMA_MAC_LSB_REG 0x008
--
--#define GDMA_MAC_MSB_REG 0x00c
--
--/* MYMAC_DP/BC_DP/MC_DP/UN_DP: Destination ports */
--#define DP_PDMA 0
--#define DP_GDMA1 1
--#define DP_GDMA2 2
--#define DP_PPE 4
--#define DP_QDMA 5
--#define DP_DISCARD 7
--
--/* GMAC Registers */
--
--#define GMAC_PPSC_REG 0x0000
--#define PHY_MDC_CFG GENMASK(29, 24)
--#define MDC_TURBO BIT(20)
--#define MDC_MAX_FREQ 25000000
--#define MDC_MAX_DIVIDER 63
--
--#define GMAC_PIAC_REG 0x0004
--#define PHY_ACS_ST BIT(31)
--#define MDIO_REG_ADDR_S 25
--#define MDIO_REG_ADDR_M 0x3e000000
--#define MDIO_PHY_ADDR_S 20
--#define MDIO_PHY_ADDR_M 0x1f00000
--#define MDIO_CMD_S 18
--#define MDIO_CMD_M 0xc0000
--#define MDIO_ST_S 16
--#define MDIO_ST_M 0x30000
--#define MDIO_RW_DATA_S 0
--#define MDIO_RW_DATA_M 0xffff
--
--#define GMAC_XGMAC_STS_REG 0x000c
--#define P1_XGMAC_FORCE_LINK BIT(15)
--
--#define GMAC_MAC_MISC_REG 0x0010
--#define MISC_MDC_TURBO BIT(4)
--
--#define GMAC_GSW_CFG_REG 0x0080
--#define GSWTX_IPG_M 0xF0000
--#define GSWTX_IPG_S 16
--#define GSWRX_IPG_M 0xF
--#define GSWRX_IPG_S 0
--
--/* MDIO_CMD: MDIO commands */
--#define MDIO_CMD_ADDR 0
--#define MDIO_CMD_WRITE 1
--#define MDIO_CMD_READ 2
--#define MDIO_CMD_READ_C45 3
--
--/* MDIO_ST: MDIO start field */
--#define MDIO_ST_C45 0
--#define MDIO_ST_C22 1
--
--#define GMAC_PORT_MCR(p) (0x0100 + (p) * 0x100)
--#define MAC_RX_PKT_LEN_S 24
--#define MAC_RX_PKT_LEN_M 0x3000000
--#define IPG_CFG_S 18
--#define IPG_CFG_M 0xc0000
--#define MAC_MODE BIT(16)
--#define FORCE_MODE BIT(15)
--#define MAC_TX_EN BIT(14)
--#define MAC_RX_EN BIT(13)
--#define DEL_RXFIFO_CLR BIT(12)
--#define BKOFF_EN BIT(9)
--#define BACKPR_EN BIT(8)
--#define FORCE_RX_FC BIT(5)
--#define FORCE_TX_FC BIT(4)
--#define FORCE_SPD_S 2
--#define FORCE_SPD_M 0x0c
--#define FORCE_DPX BIT(1)
--#define FORCE_LINK BIT(0)
--
--/* Values of IPG_CFG */
--#define IPG_96BIT 0
--#define IPG_96BIT_WITH_SHORT_IPG 1
--#define IPG_64BIT 2
--
--/* MAC_RX_PKT_LEN: Max RX packet length */
--#define MAC_RX_PKT_LEN_1518 0
--#define MAC_RX_PKT_LEN_1536 1
--#define MAC_RX_PKT_LEN_1552 2
--#define MAC_RX_PKT_LEN_JUMBO 3
--
--/* FORCE_SPD: Forced link speed */
--#define SPEED_10M 0
--#define SPEED_100M 1
--#define SPEED_1000M 2
--
--#define GMAC_TRGMII_RCK_CTRL 0x300
--#define RX_RST BIT(31)
--#define RXC_DQSISEL BIT(30)
--
--#define GMAC_TRGMII_TD_ODT(n) (0x354 + (n) * 8)
--#define TD_DM_DRVN_S 4
--#define TD_DM_DRVN_M 0xf0
--#define TD_DM_DRVP_S 0
--#define TD_DM_DRVP_M 0x0f
--
--/* XGMAC Status Registers */
--#define XGMAC_STS(x) (((x) == 2) ? 0x001C : 0x000C)
--#define XGMAC_FORCE_LINK(x) (((x) == 1) ? BIT(31) : BIT(15))
--
--/* XGMAC Registers */
--#define XGMAC_PORT_MCR(x) (0x2000 + (((x) - 1) * 0x1000))
--#define XGMAC_TRX_DISABLE 0xf
--#define XGMAC_FORCE_TX_FC BIT(5)
--#define XGMAC_FORCE_RX_FC BIT(4)
--
--/* MT7530 Registers */
--
--#define PCR_REG(p) (0x2004 + (p) * 0x100)
--#define PORT_MATRIX_S 16
--#define PORT_MATRIX_M 0xff0000
--
--#define PVC_REG(p) (0x2010 + (p) * 0x100)
--#define STAG_VPID_S 16
--#define STAG_VPID_M 0xffff0000
--#define VLAN_ATTR_S 6
--#define VLAN_ATTR_M 0xc0
--
--/* VLAN_ATTR: VLAN attributes */
--#define VLAN_ATTR_USER 0
--#define VLAN_ATTR_STACK 1
--#define VLAN_ATTR_TRANSLATION 2
--#define VLAN_ATTR_TRANSPARENT 3
--
--#define PMCR_REG(p) (0x3000 + (p) * 0x100)
--/* XXX: all fields of MT7530 are defined under GMAC_PORT_MCR
-- * MT7531 specific fields are defined below
-- */
--#define FORCE_MODE_EEE1G BIT(25)
--#define FORCE_MODE_EEE100 BIT(26)
--#define FORCE_MODE_TX_FC BIT(27)
--#define FORCE_MODE_RX_FC BIT(28)
--#define FORCE_MODE_DPX BIT(29)
--#define FORCE_MODE_SPD BIT(30)
--#define FORCE_MODE_LNK BIT(31)
--#define MT7531_FORCE_MODE FORCE_MODE_EEE1G | FORCE_MODE_EEE100 |\
-- FORCE_MODE_TX_FC | FORCE_MODE_RX_FC | \
-- FORCE_MODE_DPX | FORCE_MODE_SPD | \
-- FORCE_MODE_LNK
--#define MT7988_FORCE_MODE FORCE_MODE_TX_FC | FORCE_MODE_RX_FC | \
-- FORCE_MODE_DPX | FORCE_MODE_SPD | \
-- FORCE_MODE_LNK
--
--/* MT7531 SGMII Registers */
--#define MT7531_SGMII_REG_BASE 0x5000
--#define MT7531_SGMII_REG_PORT_BASE 0x1000
--#define MT7531_SGMII_REG(p, r) (MT7531_SGMII_REG_BASE + \
-- (p) * MT7531_SGMII_REG_PORT_BASE + (r))
--#define MT7531_PCS_CONTROL_1(p) MT7531_SGMII_REG(((p) - 5), 0x00)
--#define MT7531_SGMII_MODE(p) MT7531_SGMII_REG(((p) - 5), 0x20)
--#define MT7531_QPHY_PWR_STATE_CTRL(p) MT7531_SGMII_REG(((p) - 5), 0xe8)
--#define MT7531_PHYA_CTRL_SIGNAL3(p) MT7531_SGMII_REG(((p) - 5), 0x128)
--/* XXX: all fields of MT7531 SGMII are defined under SGMSYS */
--
--/* MT753x System Control Register */
--#define SYS_CTRL_REG 0x7000
--#define SW_PHY_RST BIT(2)
--#define SW_SYS_RST BIT(1)
--#define SW_REG_RST BIT(0)
--
--/* MT7531 */
--#define MT7531_PHY_IAC 0x701c
--/* XXX: all fields are defined under GMAC_PIAC_REG */
--
--#define MT7531_CLKGEN_CTRL 0x7500
--#define CLK_SKEW_OUT_S 8
--#define CLK_SKEW_OUT_M 0x300
--#define CLK_SKEW_IN_S 6
--#define CLK_SKEW_IN_M 0xc0
--#define RXCLK_NO_DELAY BIT(5)
--#define TXCLK_NO_REVERSE BIT(4)
--#define GP_MODE_S 1
--#define GP_MODE_M 0x06
--#define GP_CLK_EN BIT(0)
--
--/* Values of GP_MODE */
--#define GP_MODE_RGMII 0
--#define GP_MODE_MII 1
--#define GP_MODE_REV_MII 2
--
--/* Values of CLK_SKEW_IN */
--#define CLK_SKEW_IN_NO_CHANGE 0
--#define CLK_SKEW_IN_DELAY_100PPS 1
--#define CLK_SKEW_IN_DELAY_200PPS 2
--#define CLK_SKEW_IN_REVERSE 3
--
--/* Values of CLK_SKEW_OUT */
--#define CLK_SKEW_OUT_NO_CHANGE 0
--#define CLK_SKEW_OUT_DELAY_100PPS 1
--#define CLK_SKEW_OUT_DELAY_200PPS 2
--#define CLK_SKEW_OUT_REVERSE 3
--
--#define HWTRAP_REG 0x7800
--/* MT7530 Modified Hardware Trap Status Registers */
--#define MHWTRAP_REG 0x7804
--#define CHG_TRAP BIT(16)
--#define LOOPDET_DIS BIT(14)
--#define P5_INTF_SEL_S 13
--#define P5_INTF_SEL_M 0x2000
--#define SMI_ADDR_S 11
--#define SMI_ADDR_M 0x1800
--#define XTAL_FSEL_S 9
--#define XTAL_FSEL_M 0x600
--#define P6_INTF_DIS BIT(8)
--#define P5_INTF_MODE_S 7
--#define P5_INTF_MODE_M 0x80
--#define P5_INTF_DIS BIT(6)
--#define C_MDIO_BPS BIT(5)
--#define CHIP_MODE_S 0
--#define CHIP_MODE_M 0x0f
--
--/* P5_INTF_SEL: Interface type of Port5 */
--#define P5_INTF_SEL_GPHY 0
--#define P5_INTF_SEL_GMAC5 1
--
--/* P5_INTF_MODE: Interface mode of Port5 */
--#define P5_INTF_MODE_GMII_MII 0
--#define P5_INTF_MODE_RGMII 1
--
--#define MT7530_P6ECR 0x7830
--#define P6_INTF_MODE_M 0x3
--#define P6_INTF_MODE_S 0
--
--/* P6_INTF_MODE: Interface mode of Port6 */
--#define P6_INTF_MODE_RGMII 0
--#define P6_INTF_MODE_TRGMII 1
--
--#define NUM_TRGMII_CTRL 5
--
--#define MT7530_TRGMII_RD(n) (0x7a10 + (n) * 8)
--#define RD_TAP_S 0
--#define RD_TAP_M 0x7f
--
--#define MT7530_TRGMII_TD_ODT(n) (0x7a54 + (n) * 8)
--/* XXX: all fields are defined under GMAC_TRGMII_TD_ODT */
--
--/* TOP Signals Status Register */
--#define MT7531_TOP_SIG_SR 0x780c
--#define PAD_MCM_SMI_EN BIT(0)
--#define PAD_DUAL_SGMII_EN BIT(1)
--
--/* MT7531 PLLGP Registers */
--#define MT7531_PLLGP_EN 0x7820
--#define EN_COREPLL BIT(2)
--#define SW_CLKSW BIT(1)
--#define SW_PLLGP BIT(0)
--
--#define MT7531_PLLGP_CR0 0x78a8
--#define RG_COREPLL_EN BIT(22)
--#define RG_COREPLL_POSDIV_S 23
--#define RG_COREPLL_POSDIV_M 0x3800000
--#define RG_COREPLL_SDM_PCW_S 1
--#define RG_COREPLL_SDM_PCW_M 0x3ffffe
--#define RG_COREPLL_SDM_PCW_CHG BIT(0)
--
--/* MT7531 RGMII and SGMII PLL clock */
--#define MT7531_ANA_PLLGP_CR2 0x78b0
--#define MT7531_ANA_PLLGP_CR5 0x78bc
--
--/* MT7531 GPIO GROUP IOLB SMT0 Control */
--#define MT7531_SMT0_IOLB 0x7f04
--#define SMT_IOLB_5_SMI_MDC_EN BIT(5)
--
--/* MT7530 GPHY MDIO Indirect Access Registers */
--#define MII_MMD_ACC_CTL_REG 0x0d
--#define MMD_CMD_S 14
--#define MMD_CMD_M 0xc000
--#define MMD_DEVAD_S 0
--#define MMD_DEVAD_M 0x1f
--
--/* MMD_CMD: MMD commands */
--#define MMD_ADDR 0
--#define MMD_DATA 1
--#define MMD_DATA_RW_POST_INC 2
--#define MMD_DATA_W_POST_INC 3
--
--#define MII_MMD_ADDR_DATA_REG 0x0e
--
--/* MT7530 GPHY MDIO MMD Registers */
--#define CORE_PLL_GROUP2 0x401
--#define RG_SYSPLL_EN_NORMAL BIT(15)
--#define RG_SYSPLL_VODEN BIT(14)
--#define RG_SYSPLL_POSDIV_S 5
--#define RG_SYSPLL_POSDIV_M 0x60
--
--#define CORE_PLL_GROUP4 0x403
--#define MT7531_BYPASS_MODE BIT(4)
--#define MT7531_POWER_ON_OFF BIT(5)
--#define RG_SYSPLL_DDSFBK_EN BIT(12)
--#define RG_SYSPLL_BIAS_EN BIT(11)
--#define RG_SYSPLL_BIAS_LPF_EN BIT(10)
--
--#define CORE_PLL_GROUP5 0x404
--#define RG_LCDDS_PCW_NCPO1_S 0
--#define RG_LCDDS_PCW_NCPO1_M 0xffff
--
--#define CORE_PLL_GROUP6 0x405
--#define RG_LCDDS_PCW_NCPO0_S 0
--#define RG_LCDDS_PCW_NCPO0_M 0xffff
--
--#define CORE_PLL_GROUP7 0x406
--#define RG_LCDDS_PWDB BIT(15)
--#define RG_LCDDS_ISO_EN BIT(13)
--#define RG_LCCDS_C_S 4
--#define RG_LCCDS_C_M 0x70
--#define RG_LCDDS_PCW_NCPO_CHG BIT(3)
--
--#define CORE_PLL_GROUP10 0x409
--#define RG_LCDDS_SSC_DELTA_S 0
--#define RG_LCDDS_SSC_DELTA_M 0xfff
--
--#define CORE_PLL_GROUP11 0x40a
--#define RG_LCDDS_SSC_DELTA1_S 0
--#define RG_LCDDS_SSC_DELTA1_M 0xfff
--
--#define CORE_GSWPLL_GRP1 0x40d
--#define RG_GSWPLL_POSDIV_200M_S 12
--#define RG_GSWPLL_POSDIV_200M_M 0x3000
--#define RG_GSWPLL_EN_PRE BIT(11)
--#define RG_GSWPLL_FBKDIV_200M_S 0
--#define RG_GSWPLL_FBKDIV_200M_M 0xff
--
--#define CORE_GSWPLL_GRP2 0x40e
--#define RG_GSWPLL_POSDIV_500M_S 8
--#define RG_GSWPLL_POSDIV_500M_M 0x300
--#define RG_GSWPLL_FBKDIV_500M_S 0
--#define RG_GSWPLL_FBKDIV_500M_M 0xff
--
--#define CORE_TRGMII_GSW_CLK_CG 0x410
--#define REG_GSWCK_EN BIT(0)
--#define REG_TRGMIICK_EN BIT(1)
--
--/* Extend PHY Control Register 3 */
--#define PHY_EXT_REG_14 0x14
--
--/* Fields of PHY_EXT_REG_14 */
--#define PHY_EN_DOWN_SHFIT BIT(4)
--
--/* Extend PHY Control Register 4 */
--#define PHY_EXT_REG_17 0x17
--
--/* Fields of PHY_EXT_REG_17 */
--#define PHY_LINKDOWN_POWER_SAVING_EN BIT(4)
--
--/* PHY RXADC Control Register 7 */
--#define PHY_DEV1E_REG_0C6 0x0c6
--
--/* Fields of PHY_DEV1E_REG_0C6 */
--#define PHY_POWER_SAVING_S 8
--#define PHY_POWER_SAVING_M 0x300
--#define PHY_POWER_SAVING_TX 0x0
--
--/* PDMA descriptors */
--struct mtk_rx_dma {
-- unsigned int rxd1;
-- unsigned int rxd2;
-- unsigned int rxd3;
-- unsigned int rxd4;
--} __packed __aligned(4);
--
--struct mtk_rx_dma_v2 {
-- unsigned int rxd1;
-- unsigned int rxd2;
-- unsigned int rxd3;
-- unsigned int rxd4;
-- unsigned int rxd5;
-- unsigned int rxd6;
-- unsigned int rxd7;
-- unsigned int rxd8;
--} __packed __aligned(4);
--
--struct mtk_tx_dma {
-- unsigned int txd1;
-- unsigned int txd2;
-- unsigned int txd3;
-- unsigned int txd4;
--} __packed __aligned(4);
--
--struct mtk_tx_dma_v2 {
-- unsigned int txd1;
-- unsigned int txd2;
-- unsigned int txd3;
-- unsigned int txd4;
-- unsigned int txd5;
-- unsigned int txd6;
-- unsigned int txd7;
-- unsigned int txd8;
--} __packed __aligned(4);
--
--/* PDMA TXD fields */
--#define PDMA_TXD2_DDONE BIT(31)
--#define PDMA_TXD2_LS0 BIT(30)
--#define PDMA_V1_TXD2_SDL0_M GENMASK(29, 16)
--#define PDMA_V1_TXD2_SDL0_SET(_v) FIELD_PREP(PDMA_V1_TXD2_SDL0_M, (_v))
--#define PDMA_V2_TXD2_SDL0_M GENMASK(23, 8)
--#define PDMA_V2_TXD2_SDL0_SET(_v) FIELD_PREP(PDMA_V2_TXD2_SDL0_M, (_v))
--
--#define PDMA_V1_TXD4_FPORT_M GENMASK(27, 25)
--#define PDMA_V1_TXD4_FPORT_SET(_v) FIELD_PREP(PDMA_V1_TXD4_FPORT_M, (_v))
--#define PDMA_V2_TXD4_FPORT_M GENMASK(27, 24)
--#define PDMA_V2_TXD4_FPORT_SET(_v) FIELD_PREP(PDMA_V2_TXD4_FPORT_M, (_v))
--
--#define PDMA_V2_TXD5_FPORT_M GENMASK(19, 16)
--#define PDMA_V2_TXD5_FPORT_SET(_v) FIELD_PREP(PDMA_V2_TXD5_FPORT_M, (_v))
--
--/* PDMA RXD fields */
--#define PDMA_RXD2_DDONE BIT(31)
--#define PDMA_RXD2_LS0 BIT(30)
--#define PDMA_V1_RXD2_PLEN0_M GENMASK(29, 16)
--#define PDMA_V1_RXD2_PLEN0_GET(_v) FIELD_GET(PDMA_V1_RXD2_PLEN0_M, (_v))
--#define PDMA_V1_RXD2_PLEN0_SET(_v) FIELD_PREP(PDMA_V1_RXD2_PLEN0_M, (_v))
--#define PDMA_V2_RXD2_PLEN0_M GENMASK(23, 8)
--#define PDMA_V2_RXD2_PLEN0_GET(_v) FIELD_GET(PDMA_V2_RXD2_PLEN0_M, (_v))
--#define PDMA_V2_RXD2_PLEN0_SET(_v) FIELD_PREP(PDMA_V2_RXD2_PLEN0_M, (_v))
--
--#endif /* _MTK_ETH_H_ */
---- /dev/null
-+++ b/drivers/net/mtk_eth/mtk_eth.h
-@@ -0,0 +1,429 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * Copyright (C) 2025 MediaTek Inc.
-+ *
-+ * Author: Weijie Gao <weijie.gao@mediatek.com>
-+ * Author: Mark Lee <mark-mc.lee@mediatek.com>
-+ */
-+
-+#ifndef _MTK_ETH_H_
-+#define _MTK_ETH_H_
-+
-+#include <linker_lists.h>
-+#include <linux/bitops.h>
-+#include <linux/bitfield.h>
-+
-+struct mtk_eth_priv;
-+struct mtk_eth_switch_priv;
-+
-+/* struct mtk_soc_data - This is the structure holding all differences
-+ * among various plaforms
-+ * @caps Flags shown the extra capability for the SoC
-+ * @ana_rgc3: The offset for register ANA_RGC3 related to
-+ * sgmiisys syscon
-+ * @gdma_count: Number of GDMAs
-+ * @pdma_base: Register base of PDMA block
-+ * @txd_size: Tx DMA descriptor size.
-+ * @rxd_size: Rx DMA descriptor size.
-+ */
-+struct mtk_soc_data {
-+ u32 caps;
-+ u32 ana_rgc3;
-+ u32 gdma_count;
-+ u32 pdma_base;
-+ u32 txd_size;
-+ u32 rxd_size;
-+};
-+
-+struct mtk_eth_switch {
-+ const char *name;
-+ const char *desc;
-+ size_t priv_size;
-+ u32 reset_wait_time;
-+
-+ int (*detect)(struct mtk_eth_priv *priv);
-+ int (*setup)(struct mtk_eth_switch_priv *priv);
-+ int (*cleanup)(struct mtk_eth_switch_priv *priv);
-+ void (*mac_control)(struct mtk_eth_switch_priv *priv, bool enable);
-+};
-+
-+#define MTK_ETH_SWITCH(__name) \
-+ ll_entry_declare(struct mtk_eth_switch, __name, mtk_eth_switch)
-+
-+struct mtk_eth_switch_priv {
-+ struct mtk_eth_priv *eth;
-+ const struct mtk_eth_switch *sw;
-+ const struct mtk_soc_data *soc;
-+ void *ethsys_base;
-+ int phy_interface;
-+};
-+
-+enum mkt_eth_capabilities {
-+ MTK_TRGMII_BIT,
-+ MTK_TRGMII_MT7621_CLK_BIT,
-+ MTK_U3_COPHY_V2_BIT,
-+ MTK_INFRA_BIT,
-+ MTK_NETSYS_V2_BIT,
-+ MTK_NETSYS_V3_BIT,
-+
-+ /* PATH BITS */
-+ MTK_ETH_PATH_GMAC1_TRGMII_BIT,
-+ MTK_ETH_PATH_GMAC2_SGMII_BIT,
-+ MTK_ETH_PATH_MT7622_SGMII_BIT,
-+ MTK_ETH_PATH_MT7629_GMAC2_BIT,
-+};
-+
-+#define MTK_TRGMII BIT(MTK_TRGMII_BIT)
-+#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
-+#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT)
-+#define MTK_INFRA BIT(MTK_INFRA_BIT)
-+#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT)
-+#define MTK_NETSYS_V3 BIT(MTK_NETSYS_V3_BIT)
-+
-+/* Supported path present on SoCs */
-+#define MTK_ETH_PATH_GMAC1_TRGMII BIT(MTK_ETH_PATH_GMAC1_TRGMII_BIT)
-+#define MTK_ETH_PATH_GMAC2_SGMII BIT(MTK_ETH_PATH_GMAC2_SGMII_BIT)
-+#define MTK_ETH_PATH_MT7622_SGMII BIT(MTK_ETH_PATH_MT7622_SGMII_BIT)
-+#define MTK_ETH_PATH_MT7629_GMAC2 BIT(MTK_ETH_PATH_MT7629_GMAC2_BIT)
-+
-+#define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
-+
-+#define MTK_GMAC2_U3_QPHY (MTK_ETH_PATH_GMAC2_SGMII | MTK_U3_COPHY_V2 | MTK_INFRA)
-+
-+#define MTK_HAS_CAPS(caps, _x) (((caps) & (_x)) == (_x))
-+
-+#define MT7621_CAPS (MTK_GMAC1_TRGMII | MTK_TRGMII_MT7621_CLK)
-+
-+#define MT7622_CAPS (MTK_ETH_PATH_MT7622_SGMII)
-+
-+#define MT7623_CAPS (MTK_GMAC1_TRGMII)
-+
-+#define MT7629_CAPS (MTK_ETH_PATH_MT7629_GMAC2 | MTK_INFRA)
-+
-+#define MT7981_CAPS (MTK_GMAC2_U3_QPHY | MTK_NETSYS_V2)
-+
-+#define MT7986_CAPS (MTK_NETSYS_V2)
-+
-+#define MT7987_CAPS (MTK_NETSYS_V3 | MTK_GMAC2_U3_QPHY | MTK_INFRA)
-+
-+#define MT7988_CAPS (MTK_NETSYS_V3 | MTK_INFRA)
-+
-+/* Frame Engine Register Bases */
-+#define PDMA_V1_BASE 0x0800
-+#define PDMA_V2_BASE 0x6000
-+#define PDMA_V3_BASE 0x6800
-+#define GDMA1_BASE 0x0500
-+#define GDMA2_BASE 0x1500
-+#define GDMA3_BASE 0x0540
-+#define GMAC_BASE 0x10000
-+#define GSW_BASE 0x20000
-+
-+/* Ethernet subsystem registers */
-+#define ETHSYS_SYSCFG1_REG 0x14
-+#define SYSCFG1_GE_MODE_S(n) (12 + ((n) * 2))
-+#define SYSCFG1_GE_MODE_M 0x3
-+#define SYSCFG1_SGMII_SEL_M GENMASK(9, 8)
-+#define SYSCFG1_SGMII_SEL(gmac) BIT(9 - (gmac))
-+
-+#define ETHSYS_CLKCFG0_REG 0x2c
-+#define ETHSYS_TRGMII_CLK_SEL362_5 BIT(11)
-+
-+/* Top misc registers */
-+#define TOPMISC_NETSYS_PCS_MUX 0x84
-+#define NETSYS_PCS_MUX_MASK GENMASK(1, 0)
-+#define MUX_G2_USXGMII_SEL BIT(1)
-+#define MUX_HSGMII1_G1_SEL BIT(0)
-+
-+#define USB_PHY_SWITCH_REG 0x218
-+#define QPHY_SEL_MASK 0x3
-+#define SGMII_QPHY_SEL 0x2
-+
-+#define MT7629_INFRA_MISC2_REG 0x70c
-+#define INFRA_MISC2_BONDING_OPTION GENMASK(15, 0)
-+
-+/* SYSCFG1_GE_MODE: GE Modes */
-+#define GE_MODE_RGMII 0
-+#define GE_MODE_MII 1
-+#define GE_MODE_MII_PHY 2
-+#define GE_MODE_RMII 3
-+
-+/* SGMII subsystem config registers */
-+#define SGMSYS_PCS_CONTROL_1 0x0
-+#define SGMII_LINK_STATUS BIT(18)
-+#define SGMII_AN_ENABLE BIT(12)
-+#define SGMII_AN_RESTART BIT(9)
-+
-+#define SGMSYS_SGMII_MODE 0x20
-+#define SGMII_AN_MODE 0x31120103
-+#define SGMII_FORCE_MODE 0x31120019
-+
-+#define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8
-+#define SGMII_PHYA_PWD BIT(4)
-+
-+#define SGMSYS_QPHY_WRAP_CTRL 0xec
-+#define SGMII_PN_SWAP_TX_RX 0x03
-+
-+#define SGMSYS_GEN2_SPEED 0x2028
-+#define SGMSYS_GEN2_SPEED_V2 0x128
-+#define SGMSYS_SPEED_MASK GENMASK(3, 2)
-+#define SGMSYS_SPEED_2500 1
-+
-+/* USXGMII subsystem config registers */
-+/* Register to control USXGMII XFI PLL digital */
-+#define XFI_PLL_DIG_GLB8 0x08
-+#define RG_XFI_PLL_EN BIT(31)
-+
-+/* Register to control USXGMII XFI PLL analog */
-+#define XFI_PLL_ANA_GLB8 0x108
-+#define RG_XFI_PLL_ANA_SWWA 0x02283248
-+
-+/* Frame Engine Registers */
-+#define PSE_NO_DROP_CFG_REG 0x108
-+#define PSE_NO_DROP_GDM1 BIT(1)
-+
-+#define FE_GLO_MISC_REG 0x124
-+#define PDMA_VER_V2 BIT(4)
-+
-+/* PDMA */
-+#define TX_BASE_PTR_REG(n) (0x000 + (n) * 0x10)
-+#define TX_MAX_CNT_REG(n) (0x004 + (n) * 0x10)
-+#define TX_CTX_IDX_REG(n) (0x008 + (n) * 0x10)
-+#define TX_DTX_IDX_REG(n) (0x00c + (n) * 0x10)
-+
-+#define RX_BASE_PTR_REG(n) (0x100 + (n) * 0x10)
-+#define RX_MAX_CNT_REG(n) (0x104 + (n) * 0x10)
-+#define RX_CRX_IDX_REG(n) (0x108 + (n) * 0x10)
-+#define RX_DRX_IDX_REG(n) (0x10c + (n) * 0x10)
-+
-+#define PDMA_GLO_CFG_REG 0x204
-+#define TX_WB_DDONE BIT(6)
-+#define RX_DMA_BUSY BIT(3)
-+#define RX_DMA_EN BIT(2)
-+#define TX_DMA_BUSY BIT(1)
-+#define TX_DMA_EN BIT(0)
-+
-+#define PDMA_RST_IDX_REG 0x208
-+#define RST_DRX_IDX0 BIT(16)
-+#define RST_DTX_IDX0 BIT(0)
-+
-+/* GDMA */
-+#define GDMA_IG_CTRL_REG 0x000
-+#define GDM_ICS_EN BIT(22)
-+#define GDM_TCS_EN BIT(21)
-+#define GDM_UCS_EN BIT(20)
-+#define STRP_CRC BIT(16)
-+#define MYMAC_DP_S 12
-+#define MYMAC_DP_M 0xf000
-+#define BC_DP_S 8
-+#define BC_DP_M 0xf00
-+#define MC_DP_S 4
-+#define MC_DP_M 0xf0
-+#define UN_DP_S 0
-+#define UN_DP_M 0x0f
-+
-+#define GDMA_EG_CTRL_REG 0x004
-+#define GDMA_CPU_BRIDGE_EN BIT(31)
-+
-+#define GDMA_MAC_LSB_REG 0x008
-+
-+#define GDMA_MAC_MSB_REG 0x00c
-+
-+/* MYMAC_DP/BC_DP/MC_DP/UN_DP: Destination ports */
-+#define DP_PDMA 0
-+#define DP_GDMA1 1
-+#define DP_GDMA2 2
-+#define DP_PPE 4
-+#define DP_QDMA 5
-+#define DP_DISCARD 7
-+
-+/* GMAC Registers */
-+#define GMAC_PPSC_REG 0x0000
-+#define PHY_MDC_CFG GENMASK(29, 24)
-+#define MDC_TURBO BIT(20)
-+#define MDC_MAX_FREQ 25000000
-+#define MDC_MAX_DIVIDER 63
-+
-+#define GMAC_PIAC_REG 0x0004
-+#define PHY_ACS_ST BIT(31)
-+#define MDIO_REG_ADDR_S 25
-+#define MDIO_REG_ADDR_M 0x3e000000
-+#define MDIO_PHY_ADDR_S 20
-+#define MDIO_PHY_ADDR_M 0x1f00000
-+#define MDIO_CMD_S 18
-+#define MDIO_CMD_M 0xc0000
-+#define MDIO_ST_S 16
-+#define MDIO_ST_M 0x30000
-+#define MDIO_RW_DATA_S 0
-+#define MDIO_RW_DATA_M 0xffff
-+
-+#define GMAC_XGMAC_STS_REG 0x000c
-+#define P1_XGMAC_FORCE_LINK BIT(15)
-+
-+#define GMAC_MAC_MISC_REG 0x0010
-+#define MISC_MDC_TURBO BIT(4)
-+
-+#define GMAC_GSW_CFG_REG 0x0080
-+#define GSWTX_IPG_M 0xF0000
-+#define GSWTX_IPG_S 16
-+#define GSWRX_IPG_M 0xF
-+#define GSWRX_IPG_S 0
-+
-+/* MDIO_CMD: MDIO commands */
-+#define MDIO_CMD_ADDR 0
-+#define MDIO_CMD_WRITE 1
-+#define MDIO_CMD_READ 2
-+#define MDIO_CMD_READ_C45 3
-+
-+/* MDIO_ST: MDIO start field */
-+#define MDIO_ST_C45 0
-+#define MDIO_ST_C22 1
-+
-+#define GMAC_PORT_MCR(p) (0x0100 + (p) * 0x100)
-+#define MAC_RX_PKT_LEN_S 24
-+#define MAC_RX_PKT_LEN_M 0x3000000
-+#define IPG_CFG_S 18
-+#define IPG_CFG_M 0xc0000
-+#define MAC_MODE BIT(16)
-+#define FORCE_MODE BIT(15)
-+#define MAC_TX_EN BIT(14)
-+#define MAC_RX_EN BIT(13)
-+#define DEL_RXFIFO_CLR BIT(12)
-+#define BKOFF_EN BIT(9)
-+#define BACKPR_EN BIT(8)
-+#define FORCE_RX_FC BIT(5)
-+#define FORCE_TX_FC BIT(4)
-+#define FORCE_SPD_S 2
-+#define FORCE_SPD_M 0x0c
-+#define FORCE_DPX BIT(1)
-+#define FORCE_LINK BIT(0)
-+
-+/* Values of IPG_CFG */
-+#define IPG_96BIT 0
-+#define IPG_96BIT_WITH_SHORT_IPG 1
-+#define IPG_64BIT 2
-+
-+/* MAC_RX_PKT_LEN: Max RX packet length */
-+#define MAC_RX_PKT_LEN_1518 0
-+#define MAC_RX_PKT_LEN_1536 1
-+#define MAC_RX_PKT_LEN_1552 2
-+#define MAC_RX_PKT_LEN_JUMBO 3
-+
-+/* FORCE_SPD: Forced link speed */
-+#define SPEED_10M 0
-+#define SPEED_100M 1
-+#define SPEED_1000M 2
-+
-+#define GMAC_TRGMII_RCK_CTRL 0x300
-+#define RX_RST BIT(31)
-+#define RXC_DQSISEL BIT(30)
-+
-+#define NUM_TRGMII_CTRL 5
-+
-+#define GMAC_TRGMII_TD_ODT(n) (0x354 + (n) * 8)
-+#define TD_DM_DRVN_S 4
-+#define TD_DM_DRVN_M 0xf0
-+#define TD_DM_DRVP_S 0
-+#define TD_DM_DRVP_M 0x0f
-+
-+/* XGMAC Status Registers */
-+#define XGMAC_STS(x) (((x) == 2) ? 0x001C : 0x000C)
-+#define XGMAC_FORCE_LINK(x) (((x) == 1) ? BIT(31) : BIT(15))
-+
-+/* XGMAC Registers */
-+#define XGMAC_PORT_MCR(x) (0x2000 + (((x) - 1) * 0x1000))
-+#define XGMAC_TRX_DISABLE 0xf
-+#define XGMAC_FORCE_TX_FC BIT(5)
-+#define XGMAC_FORCE_RX_FC BIT(4)
-+
-+/* MDIO Indirect Access Registers */
-+#define MII_MMD_ACC_CTL_REG 0x0d
-+#define MMD_CMD_S 14
-+#define MMD_CMD_M 0xc000
-+#define MMD_DEVAD_S 0
-+#define MMD_DEVAD_M 0x1f
-+
-+/* MMD_CMD: MMD commands */
-+#define MMD_ADDR 0
-+#define MMD_DATA 1
-+#define MMD_DATA_RW_POST_INC 2
-+#define MMD_DATA_W_POST_INC 3
-+
-+#define MII_MMD_ADDR_DATA_REG 0x0e
-+
-+/* PDMA descriptors */
-+struct mtk_rx_dma {
-+ unsigned int rxd1;
-+ unsigned int rxd2;
-+ unsigned int rxd3;
-+ unsigned int rxd4;
-+} __packed __aligned(4);
-+
-+struct mtk_rx_dma_v2 {
-+ unsigned int rxd1;
-+ unsigned int rxd2;
-+ unsigned int rxd3;
-+ unsigned int rxd4;
-+ unsigned int rxd5;
-+ unsigned int rxd6;
-+ unsigned int rxd7;
-+ unsigned int rxd8;
-+} __packed __aligned(4);
-+
-+struct mtk_tx_dma {
-+ unsigned int txd1;
-+ unsigned int txd2;
-+ unsigned int txd3;
-+ unsigned int txd4;
-+} __packed __aligned(4);
-+
-+struct mtk_tx_dma_v2 {
-+ unsigned int txd1;
-+ unsigned int txd2;
-+ unsigned int txd3;
-+ unsigned int txd4;
-+ unsigned int txd5;
-+ unsigned int txd6;
-+ unsigned int txd7;
-+ unsigned int txd8;
-+} __packed __aligned(4);
-+
-+/* PDMA TXD fields */
-+#define PDMA_TXD2_DDONE BIT(31)
-+#define PDMA_TXD2_LS0 BIT(30)
-+#define PDMA_V1_TXD2_SDL0_M GENMASK(29, 16)
-+#define PDMA_V1_TXD2_SDL0_SET(_v) FIELD_PREP(PDMA_V1_TXD2_SDL0_M, (_v))
-+#define PDMA_V2_TXD2_SDL0_M GENMASK(23, 8)
-+#define PDMA_V2_TXD2_SDL0_SET(_v) FIELD_PREP(PDMA_V2_TXD2_SDL0_M, (_v))
-+
-+#define PDMA_V1_TXD4_FPORT_M GENMASK(27, 25)
-+#define PDMA_V1_TXD4_FPORT_SET(_v) FIELD_PREP(PDMA_V1_TXD4_FPORT_M, (_v))
-+#define PDMA_V2_TXD4_FPORT_M GENMASK(27, 24)
-+#define PDMA_V2_TXD4_FPORT_SET(_v) FIELD_PREP(PDMA_V2_TXD4_FPORT_M, (_v))
-+
-+#define PDMA_V2_TXD5_FPORT_M GENMASK(19, 16)
-+#define PDMA_V2_TXD5_FPORT_SET(_v) FIELD_PREP(PDMA_V2_TXD5_FPORT_M, (_v))
-+
-+/* PDMA RXD fields */
-+#define PDMA_RXD2_DDONE BIT(31)
-+#define PDMA_RXD2_LS0 BIT(30)
-+#define PDMA_V1_RXD2_PLEN0_M GENMASK(29, 16)
-+#define PDMA_V1_RXD2_PLEN0_GET(_v) FIELD_GET(PDMA_V1_RXD2_PLEN0_M, (_v))
-+#define PDMA_V1_RXD2_PLEN0_SET(_v) FIELD_PREP(PDMA_V1_RXD2_PLEN0_M, (_v))
-+#define PDMA_V2_RXD2_PLEN0_M GENMASK(23, 8)
-+#define PDMA_V2_RXD2_PLEN0_GET(_v) FIELD_GET(PDMA_V2_RXD2_PLEN0_M, (_v))
-+#define PDMA_V2_RXD2_PLEN0_SET(_v) FIELD_PREP(PDMA_V2_RXD2_PLEN0_M, (_v))
-+
-+void mtk_fe_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, u32 set);
-+void mtk_gmac_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, u32 set);
-+void mtk_ethsys_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, u32 set);
-+
-+int mtk_mii_read(struct mtk_eth_priv *priv, u8 phy, u8 reg);
-+int mtk_mii_write(struct mtk_eth_priv *priv, u8 phy, u8 reg, u16 data);
-+int mtk_mmd_read(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg);
-+int mtk_mmd_write(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg,
-+ u16 val);
-+int mtk_mmd_ind_read(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg);
-+int mtk_mmd_ind_write(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg,
-+ u16 val);
-+
-+#endif /* _MTK_ETH_H_ */