summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/Kconfig6
-rw-r--r--drivers/net/calxedaxgmac.c2
-rw-r--r--drivers/net/dwc_eth_qos_adi.c2
-rw-r--r--drivers/net/dwc_eth_xgmac.c2
-rw-r--r--drivers/net/fsl-mc/mc.c45
-rw-r--r--drivers/net/fsl_enetc.c57
-rw-r--r--drivers/net/fsl_enetc.h1
-rw-r--r--drivers/net/fsl_enetc_xpcs_phy.c970
-rw-r--r--drivers/net/macb.c94
-rw-r--r--drivers/net/macb.h2
-rw-r--r--drivers/net/phy/Kconfig4
-rw-r--r--drivers/net/phy/adin.c13
-rw-r--r--drivers/net/phy/airoha/Kconfig1
-rw-r--r--drivers/net/phy/airoha/air_en8811.c60
-rw-r--r--drivers/net/phy/aquantia.c2
-rw-r--r--drivers/net/phy/dp83867.c16
-rw-r--r--drivers/net/phy/mscc.c11
-rw-r--r--drivers/net/qe/dm_qe_uec_phy.c2
-rw-r--r--drivers/net/sandbox.c2
-rw-r--r--drivers/net/sni_netsec.c2
-rw-r--r--drivers/net/ti/cpsw.c188
-rw-r--r--drivers/net/xilinx_axi_emac.c20
-rw-r--r--drivers/net/zynq_gem.c61
23 files changed, 1405 insertions, 158 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index ed07e286676..666618681df 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -339,7 +339,7 @@ config ESSEDMA
config ETH_SANDBOX
depends on SANDBOX
- depends on NET || NET_LWIP
+ depends on NET
default y
bool "Sandbox: Mocked Ethernet driver"
help
@@ -350,7 +350,7 @@ config ETH_SANDBOX
config ETH_SANDBOX_RAW
depends on SANDBOX
- depends on NET
+ depends on NET_LEGACY
default y
bool "Sandbox: Bridge to Linux Raw Sockets"
help
@@ -476,7 +476,7 @@ config FTMAC100
config FTGMAC100
bool "Ftgmac100 Ethernet Support"
select PHYLIB
- depends on NET
+ depends on NET_LEGACY
help
This driver supports the Faraday's FTGMAC100 Gigabit SoC
Ethernet controller that can be found on Aspeed SoCs (which
diff --git a/drivers/net/calxedaxgmac.c b/drivers/net/calxedaxgmac.c
index ebb399457fb..92990fa6d47 100644
--- a/drivers/net/calxedaxgmac.c
+++ b/drivers/net/calxedaxgmac.c
@@ -597,7 +597,7 @@ static const struct udevice_id xgmac_eth_ids[] = {
{ }
};
-U_BOOT_DRIVER(eth_xgmac) = {
+U_BOOT_DRIVER(calxeda_hb_xgmac) = {
.name = "eth_xgmac",
.id = UCLASS_ETH,
.of_match = xgmac_eth_ids,
diff --git a/drivers/net/dwc_eth_qos_adi.c b/drivers/net/dwc_eth_qos_adi.c
index b578225eaad..37db8525b48 100644
--- a/drivers/net/dwc_eth_qos_adi.c
+++ b/drivers/net/dwc_eth_qos_adi.c
@@ -15,7 +15,7 @@
#include <reset.h>
#include <linux/io.h>
-#include <asm/arch-adi/sc5xx/sc5xx.h>
+#include <asm/arch/sc5xx.h>
#include "dwc_eth_qos.h"
diff --git a/drivers/net/dwc_eth_xgmac.c b/drivers/net/dwc_eth_xgmac.c
index 2ab5ec5f0d9..311b57011c3 100644
--- a/drivers/net/dwc_eth_xgmac.c
+++ b/drivers/net/dwc_eth_xgmac.c
@@ -1206,7 +1206,7 @@ static const struct udevice_id xgmac_ids[] = {
{ }
};
-U_BOOT_DRIVER(eth_xgmac) = {
+U_BOOT_DRIVER(dwc_eth_xgmac) = {
.name = "eth_xgmac",
.id = UCLASS_ETH,
.of_match = of_match_ptr(xgmac_ids),
diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c
index c8ed702f50a..e28f8d96ed7 100644
--- a/drivers/net/fsl-mc/mc.c
+++ b/drivers/net/fsl-mc/mc.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2014 Freescale Semiconductor, Inc.
- * Copyright 2017-2018, 2020-2021 NXP
+ * Copyright 2017-2018, 2020-2021, 2025 NXP
*/
#include <config.h>
#include <command.h>
@@ -72,6 +72,7 @@ static u64 mc_lazy_dpl_addr;
static u32 dpsparser_obj_id;
static u16 dpsparser_handle;
static char *mc_err_msg_apply_spb[] = MC_ERROR_MSG_APPLY_SPB;
+static bool wait_for_dpl;
#ifdef DEBUG
void dump_ram_words(const char *title, void *addr)
@@ -653,7 +654,7 @@ static int load_mc_aiop_img(u64 aiop_fw_addr)
}
#endif
-static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr)
+static int wait_for_mc(u32 *final_reg_gsr)
{
u32 reg_gsr;
u32 mc_fw_boot_status;
@@ -792,7 +793,7 @@ int mc_init(u64 mc_fw_addr, u64 mc_dpc_addr)
* Deassert reset and release MC core 0 to run
*/
out_le32(&mc_ccsr_regs->reg_gcr1, GCR1_P1_DE_RST | GCR1_M_ALL_DE_RST);
- error = wait_for_mc(true, &reg_gsr);
+ error = wait_for_mc(&reg_gsr);
if (error != 0)
goto out;
@@ -855,13 +856,20 @@ int mc_apply_dpl(u64 mc_dpl_addr)
* Tell the MC to deploy the DPL:
*/
out_le32(&mc_ccsr_regs->reg_gsr, 0x0);
- printf("fsl-mc: Deploying data path layout ... ");
- error = wait_for_mc(false, &reg_gsr);
- if (!error)
- mc_dpl_applied = 0;
+ /* Wait for the MC firmware to finish processing the DPL */
+ if (wait_for_dpl) {
+ printf("fsl-mc: Deploying data path layout ... ");
+ error = wait_for_mc(&reg_gsr);
+ if (error)
+ return error;
+ } else {
+ printf("fsl-mc: Started the DPL deploy process\n");
+ }
- return error;
+ mc_dpl_applied = 0;
+
+ return 0;
}
int get_mc_boot_status(void)
@@ -1995,6 +2003,11 @@ static int do_fsl_mc(struct cmd_tbl *cmdtp, int flag, int argc,
* later from announce_and_cleanup().
*/
mc_lazy_dpl_addr = mc_dpl_addr;
+
+ wait_for_dpl = true;
+ if (argc >= 5 && strcmp(argv[4], "nowait") == 0)
+ wait_for_dpl = false;
+
break;
}
@@ -2023,6 +2036,10 @@ static int do_fsl_mc(struct cmd_tbl *cmdtp, int flag, int argc,
mc_apply_addr = simple_strtoull(argv[3], NULL, 16);
+ wait_for_dpl = true;
+ if (argc >= 5 && strcmp(argv[4], "nowait") == 0)
+ wait_for_dpl = false;
+
/* The user wants DPL applied now */
if (!fsl_mc_ldpaa_exit(NULL))
err = mc_apply_dpl(mc_apply_addr);
@@ -2070,12 +2087,12 @@ static int do_fsl_mc(struct cmd_tbl *cmdtp, int flag, int argc,
U_BOOT_CMD(
fsl_mc, CONFIG_SYS_MAXARGS, 1, do_fsl_mc,
"DPAA2 command to manage Management Complex (MC)",
- "start mc [FW_addr] [DPC_addr] - Start Management Complex\n"
- "fsl_mc apply DPL [DPL_addr] - Apply DPL file\n"
- "fsl_mc lazyapply DPL [DPL_addr] - Apply DPL file on exit\n"
- "fsl_mc apply spb [spb_addr] - Apply SPB Soft Parser Blob\n"
- "fsl_mc start aiop [FW_addr] - Start AIOP\n"
- "fsl_mc dump_log - Dump MC Log\n"
+ "fsl_mc start mc <fw_addr> <DPC_addr> - Start the Management Complex firmware\n"
+ "fsl_mc apply dpl <dpl_addr> [nowait] - Apply the DPL (Data Path Layout) file\n"
+ "fsl_mc lazyapply dpl <DPL_addr> [nowait] - Apply the DPL (Data Path Layout) file on exit\n"
+ "fsl_mc apply spb <spb_addr> - Apply the SPB Soft Parser Blob\n"
+ "fsl_mc start aiop <fw_addr> - Start AIOP\n"
+ "fsl_mc dump_log - Dump the MC Log\n"
);
void mc_env_boot(void)
diff --git a/drivers/net/fsl_enetc.c b/drivers/net/fsl_enetc.c
index a4ba27904bc..206f1a381bb 100644
--- a/drivers/net/fsl_enetc.c
+++ b/drivers/net/fsl_enetc.c
@@ -8,6 +8,7 @@
#include <clk.h>
#include <cpu_func.h>
#include <dm.h>
+#include <dm/device_compat.h>
#include <errno.h>
#include <fdt_support.h>
#include <malloc.h>
@@ -20,14 +21,21 @@
#include <linux/bug.h>
#include <linux/delay.h>
#include <linux/build_bug.h>
+#include <linux/bitfield.h>
+#include <power/regulator.h>
+#include "fsl_enetc.h"
#ifdef CONFIG_ARCH_IMX9
#include <asm/mach-imx/sys_proto.h>
#include <cpu_func.h>
+#include "fsl_enetc_xpcs_phy.c"
+#else
+static inline int xpcs_phy_usxgmii_pma_config(struct udevice *dev)
+{
+ return 0;
+}
#endif
-#include "fsl_enetc.h"
-
#define ENETC_DRIVER_NAME "enetc_eth"
/*
@@ -454,19 +462,23 @@ static void enetc_setup_mac_iface(struct udevice *dev,
/* set up serdes for SXGMII */
static int enetc_init_sxgmii(struct udevice *dev)
{
- struct enetc_priv *priv = dev_get_priv(dev);
-
if (!enetc_has_imdio(dev))
return 0;
- /* Dev ability - SXGMII */
- enetc_mdio_write(&priv->imdio, ENETC_PCS_PHY_ADDR, ENETC_PCS_DEVAD_REPL,
- ENETC_PCS_DEV_ABILITY, ENETC_PCS_DEV_ABILITY_SXGMII);
+ if (enetc_is_imx95(dev)) {
+ xpcs_phy_usxgmii_pma_config(dev);
+ } else {
+ struct enetc_priv *priv = dev_get_priv(dev);
+
+ /* Dev ability - SXGMII */
+ enetc_mdio_write(&priv->imdio, ENETC_PCS_PHY_ADDR, ENETC_PCS_DEVAD_REPL,
+ ENETC_PCS_DEV_ABILITY, ENETC_PCS_DEV_ABILITY_SXGMII);
- /* Restart PCS AN */
- enetc_mdio_write(&priv->imdio, ENETC_PCS_PHY_ADDR, ENETC_PCS_DEVAD_REPL,
- ENETC_PCS_CR,
- ENETC_PCS_CR_RST | ENETC_PCS_CR_RESET_AN);
+ /* Restart PCS AN */
+ enetc_mdio_write(&priv->imdio, ENETC_PCS_PHY_ADDR, ENETC_PCS_DEVAD_REPL,
+ ENETC_PCS_CR,
+ ENETC_PCS_CR_RST | ENETC_PCS_CR_RESET_AN);
+ }
return 0;
}
@@ -523,6 +535,10 @@ static int enetc_config_phy(struct udevice *dev)
return -ENODEV;
supported = PHY_GBIT_FEATURES | SUPPORTED_2500baseX_Full;
+
+ if (enetc_is_imx95(dev))
+ supported |= PHY_10G_FEATURES;
+
priv->phy->supported &= supported;
priv->phy->advertising &= supported;
@@ -537,12 +553,31 @@ static int enetc_probe(struct udevice *dev)
{
struct enetc_priv *priv = dev_get_priv(dev);
int res;
+ struct udevice *supply = NULL;
if (ofnode_valid(dev_ofnode(dev)) && !ofnode_is_enabled(dev_ofnode(dev))) {
enetc_dbg(dev, "interface disabled\n");
return -ENODEV;
}
+ if (CONFIG_IS_ENABLED(DM_REGULATOR)) {
+ res = device_get_supply_regulator(dev, "serdes-supply",
+ &supply);
+ if (res && res != -ENOENT) {
+ printf("%s: device_get_supply_regulator failed: %d\n",
+ __func__, res);
+ return res;
+ }
+
+ if (supply) {
+ res = regulator_set_enable_if_allowed(supply, true);
+ if (res) {
+ printf("%s: Error enabling phy supply\n", dev->name);
+ return res;
+ }
+ }
+ }
+
priv->enetc_txbd = memalign(ENETC_BD_ALIGN,
sizeof(struct enetc_tx_bd) * ENETC_BD_CNT);
priv->enetc_rxbd = memalign(ENETC_BD_ALIGN,
diff --git a/drivers/net/fsl_enetc.h b/drivers/net/fsl_enetc.h
index 804df853bf5..6d868e82f8c 100644
--- a/drivers/net/fsl_enetc.h
+++ b/drivers/net/fsl_enetc.h
@@ -205,6 +205,7 @@ struct enetc_data {
/* PCS / internal SoC PHY ID, it defaults to 0 on all interfaces */
#define ENETC_PCS_PHY_ADDR 0
+#define ENETC_NON_PCS_PHY_ADDR 16
/* PCS registers */
#define ENETC_PCS_CR 0x00
diff --git a/drivers/net/fsl_enetc_xpcs_phy.c b/drivers/net/fsl_enetc_xpcs_phy.c
new file mode 100644
index 00000000000..4039690223d
--- /dev/null
+++ b/drivers/net/fsl_enetc_xpcs_phy.c
@@ -0,0 +1,970 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2024 NXP
+ */
+
+#define XPCS_PHY_GLOBAL 0x0
+#define XPCS_PHY_MPLLA 0x1
+#define XPCS_PHY_MPLLB 0x2
+#define XPCS_PHY_LANE 0x3
+#define XPCS_PHY_MAC_ADAPTER 0x1f
+
+#define XPCS_PHY_REG(x) (((x) & 0x1fffe) >> 1)
+
+/* MAC ADAPTER */
+#define MAC_ADAPTER_LOCK_PHY 0x200
+#define MAC_ADAPTER_LOCK_MPLLA 0x204
+#define MAC_ADAPTER_LOCK_MPLLB 0x208
+#define MAC_ADAPTER_LOCK_ROM 0x20c
+#define MAC_ADAPTER_LOCK_RAM 0x210
+#define MAC_ADAPTER_LOCK_EVENT 0x214
+
+#define MAC_ADAPTER_LOCK_LOCK BIT(7)
+
+/* PMA */
+#define PMA_RX_LSTS 0x10040
+#define PMA_RX_LSTS_RX_VALID_0 BIT(12)
+#define PMA_MP_12G_16G_25G_TX_GENCTRL0 0x10060
+#define PMA_TX_GENCTRL0_TX_RST_0 BIT(8)
+#define PMA_TX_GENCTRL0_TX_DT_EN_0 BIT(12)
+#define PMA_MP_12G_16G_25G_TX_GENCTRL1 0x10062
+#define PMA_TX_GENCTRL1_VBOOST_EN_0 BIT(4)
+#define PMA_TX_GENCTRL1_VBOOST_LVL_MASK GENMASK(10, 8)
+#define PMA_TX_GENCTRL1_VBOOST_LVL(x) (((x) << 8) & GENMASK(10, 8))
+#define PMA_TX_GENCTRL1_TX_CLK_RDY_0 BIT(12)
+#define PMA_MP_12G_16G_TX_GENCTRL2 0x10064
+#define PMA_TX_GENCTRL2_TX_REQ_0 BIT(0)
+#define PMA_TX_GENCTRL2_TX0_WIDTH_MASK GENMASK(9, 8)
+#define PMA_TX_GENCTRL2_TX0_WIDTH(x) (((x) << 8) & GENMASK(9, 8))
+#define PMA_MP_12G_16G_25G_TX_BOOST_CTRL 0x10066
+#define PMA_TX_BOOST_CTRL_TX0_IBOOST_MASK GENMASK(3, 0)
+#define PMA_TX_BOOST_CTRL_TX0_IBOOST(x) ((x) & GENMASK(3, 0))
+#define PMA_MP_12G_16G_25G_TX_RATE_CTRL 0x10068
+#define PMA_TX_RATE_CTRL_TX0_RATE_MASK GENMASK(2, 0)
+#define PMA_TX_RATE_CTRL_TX0_RATE(x) ((x) & GENMASK(2, 0))
+#define PMA_MP_12G_16G_25G_TX_POWER_STATE_CTRL 0x1006A
+#define PMA_POWER_STATE_CTRL_TX0_PSTATE_MASK GENMASK(1, 0)
+#define PMA_POWER_STATE_CTRL_TX0_PSTATE(x) ((x) & GENMASK(1, 0))
+#define PMA_POWER_STATE_CTRL_TX_DISABLE_0 BIT(8)
+#define PMA_MP_12G_16G_25G_TX_EQ_CTRL0 0x1006C
+#define PMA_TX_EQ_CTRL0_TX_EQ_PRE_MASK GENMASK(5, 0)
+#define PMA_TX_EQ_CTRL0_TX_EQ_PRE(x) ((x) & GENMASK(5, 0))
+#define PMA_TX_EQ_CTRL0_TX_EQ_MAIN_MASK GENMASK(13, 8)
+#define PMA_TX_EQ_CTRL0_TX_EQ_MAIN(x) (((x) << 8) & GENMASK(13, 8))
+#define PMA_MP_12G_16G_25G_TX_EQ_CTRL1 0x1006E
+#define PMA_TX_EQ_CTRL1_TX_EQ_POST_MASK GENMASK(5, 0)
+#define PMA_TX_EQ_CTRL1_TX_EQ_POST(x) ((x) & GENMASK(5, 0))
+#define PMA_MP_16G_25G_TX_MISC_CTRL0 0x1007C
+#define PMA_TX_MISC_CTRL0_TX0_MISC_MASK GENMASK(7, 0)
+#define PMA_TX_MISC_CTRL0_TX0_MISC(x) ((x) & GENMASK(7, 0))
+#define PMA_MP_12G_16G_25G_RX_GENCTRL0 0x100A0
+#define PMA_RX_GENCTRL0_RX_DT_EN_0 BIT(8)
+#define PMA_MP_12G_16G_25G_RX_GENCTRL1 0x100A2
+#define PMA_RX_GENCTRL1_RX_RST_0 BIT(4)
+#define PMA_RX_GENCTRL1_RX_TERM_ACDC_0 BIT(8)
+#define PMA_RX_GENCTRL1_RX_DIV16P5_CLK_EN_0 BIT(12)
+#define PMA_MP_12G_16G_RX_GENCTRL2 0x100A4
+#define PMA_RX_GENCTRL2_RX_REQ_0 BIT(0)
+#define PMA_RX_GENCTRL2_RX0_WIDTH_MASK GENMASK(9, 8)
+#define PMA_RX_GENCTRL2_RX0_WIDTH(x) (((x) << 8) & GENMASK(9, 8))
+#define PMA_MP_12G_16G_RX_GENCTRL3 0x100A6
+#define PMA_RX_GENCTRL3_LOS_TRSHLD_0_MASK GENMASK(2, 0)
+#define PMA_RX_GENCTRL3_LOS_TRSHLD_0(x) ((x) & GENMASK(2, 0))
+#define PMA_RX_GENCTRL3_LOS_LFPS_EN_0 BIT(12)
+#define PMA_MP_12G_16G_25G_RX_RATE_CTRL 0x100A8
+#define PMA_RX_RATE_CTRL_RX0_RATE_MASK GENMASK(1, 0)
+#define PMA_RX_RATE_CTRL_RX0_RATE(x) ((x) & GENMASK(1, 0))
+#define PMA_MP_12G_16G_25G_RX_POWER_STATE_CTRL 0x100AA
+#define PMA_RX_POWER_STATE_CTRL_RX0_PSTATE_MASK GENMASK(1, 0)
+#define PMA_RX_POWER_STATE_CTRL_RX0_PSTATE(x) ((x) & GENMASK(1, 0))
+#define PMA_RX_POWER_STATE_CTRL_RX_DISABLE_0 BIT(8)
+#define PMA_MP_12G_16G_25G_RX_CDR_CTRL 0x100AC
+#define PMA_RX_CDR_CTRL_CDR_SSC_EN_0 BIT(4)
+#define PMA_MP_12G_16G_25G_RX_ATTN_CTRL 0x100AE
+#define PMA_RX_ATTN_CTRL_RX0_EQ_ATT_LVL_MASK GENMASK(2, 0)
+#define PMA_RX_ATTN_CTRL_RX0_EQ_ATT_LVL(x) ((x) & GENMASK(2, 0))
+#define PMA_MP_16G_25G_RX_EQ_CTRL0 0x100B0
+#define PMA_RX_EQ_CTRL0_CTLE_BOOST_0_MASK GENMASK(4, 0)
+#define PMA_RX_EQ_CTRL0_CTLE_BOOST_0(x) ((x) & GENMASK(4, 0))
+#define PMA_RX_EQ_CTRL0_CTLE_POLE_0_MASK GENMASK(6, 5)
+#define PMA_RX_EQ_CTRL0_CTLE_POLE_0(x) (((x) << 5) & GENMASK(6, 5))
+#define PMA_RX_EQ_CTRL0_VGA2_GAIN_0_MASK GENMASK(10, 8)
+#define PMA_RX_EQ_CTRL0_VGA2_GAIN_0(x) (((x) << 8) & GENMASK(10, 8))
+#define PMA_RX_EQ_CTRL0_VGA1_GAIN_0_MASK GENMASK(14, 12)
+#define PMA_RX_EQ_CTRL0_VGA1_GAIN_0(x) (((x) << 12) & GENMASK(14, 12))
+#define PMA_MP_12G_16G_25G_RX_EQ_CTRL4 0x100B8
+#define PMA_RX_EQ_CTRL4_CONT_ADAPT_0 BIT(0)
+#define PMA_RX_EQ_CTRL4_RX_AD_REQ BIT(12)
+#define PMA_MP_16G_25G_RX_EQ_CTRL5 0x100BA
+#define PMA_RX_EQ_CTRL5_RX_ADPT_SEL_0 BIT(0)
+#define PMA_RX_EQ_CTRL5_RX0_ADPT_MODE_MASK GENMASK(5, 4)
+#define PMA_RX_EQ_CTRL5_RX0_ADPT_MODE(x) (((x) << 4) & GENMASK(5, 4))
+#define PMA_MP_12G_16G_25G_DFE_TAP_CTRL0 0x100BC
+#define PMA_DFE_TAP_CTRL0_DFE_TAP1_0_MASK GENMASK(7, 0)
+#define PMA_DFE_TAP_CTRL0_DFE_TAP1_0(x) ((x) & GENMASK(7, 0))
+#define PMA_MP_16G_RX_CDR_CTRL1 0x100C8
+#define PMA_RX_CDR_CTRL1_VCO_TEMP_COMP_EN_0 BIT(0)
+#define PMA_RX_CDR_CTRL1_VCO_STEP_CTRL_0 BIT(4)
+#define PMA_RX_CDR_CTRL1_VCO_FRQBAND_0_MASK GENMASK(9, 8)
+#define PMA_RX_CDR_CTRL1_VCO_FRQBAND_0(x) (((x) << 8) & GENMASK(9, 8))
+#define PMA_MP_16G_25G_RX_PPM_CTRL0 0x100CA
+#define PMA_RX_PPM_CTRL0_RX0_CDR_PPM_MAX_MASK GENMASK(4, 0)
+#define PMA_RX_PPM_CTRL0_RX0_CDR_PPM_MAX(x) ((x) & GENMASK(4, 0))
+#define PMA_MP_16G_25G_RX_GENCTRL4 0x100D0
+#define PMA_RX_GENCTRL4_RX_DFE_BYP_0 BIT(8)
+#define PMA_MP_16G_25G_RX_MISC_CTRL0 0x100D2
+#define PMA_RX_MISC_CTRL0_RX0_MISC_MASK GENMASK(7, 0)
+#define PMA_RX_MISC_CTRL0_RX0_MISC(x) ((x) & GENMASK(7, 0))
+#define PMA_MP_16G_25G_RX_IQ_CTRL0 0x100D6
+#define PMA_RX_IQ_CTRL0_RX0_MARGIN_IQ_MASK GENMASK(6, 0)
+#define PMA_RX_IQ_CTRL0_RX0_MARGIN_IQ(x) ((x) & GENMASK(6, 0))
+#define PMA_RX_IQ_CTRL0_RX0_DELTA_IQ_MASK GENMASK(11, 8)
+#define PMA_RX_IQ_CTRL0_RX0_DELTA_IQ(x) (((x) << 8) & GENMASK(11, 8))
+#define PMA_MP_12G_16G_25G_MPLL_CMN_CTRL 0x100E0
+#define PMA_MPLL_CMN_CTRL_MPLL_EN_0 BIT(0)
+#define PMA_MPLL_CMN_CTRL_MPLLB_SEL_0 BIT(4)
+#define PMA_MP_12G_16G_MPLLA_CTRL0 0x100E2
+#define PMA_MPLLA_CTRL0_MPLLA_MULTIPLIER_MASK GENMASK(7, 0)
+#define PMA_MPLLA_CTRL0_MPLLA_MULTIPLIER(x) ((x) & GENMASK(7, 0))
+#define PMA_MP_16G_MPLLA_CTRL1 0x100E4
+#define PMA_MPLLA_CTRL1_MPLLA_SSC_EN BIT(0)
+#define PMA_MPLLA_CTRL1_MPLLA_SSC_CLK_SEL BIT(4)
+#define PMA_MPLLA_CTRL1_MPLLA_FRACN_CTRL_MASK GENMASK(15, 5)
+#define PMA_MPLLA_CTRL1_MPLLA_FRACN_CTRL(x) (((x) << 5) & GENMASK(15, 5))
+#define PMA_MP_12G_16G_MPLLA_CTRL2 0x100E6
+#define PMA_MPLLA_CTRL2_MPLLA_DIV_MULT_MASK GENMASK(6, 0)
+#define PMA_MPLLA_CTRL2_MPLLA_DIV_MULT(x) ((x) & GENMASK(6, 0))
+#define PMA_MPLLA_CTRL2_MPLLA_DIV_CLK_EN BIT(7)
+#define PMA_MPLLA_CTRL2_MPLLA_DIV8_CLK_EN BIT(8)
+#define PMA_MPLLA_CTRL2_MPLLA_DIV10_CLK_EN BIT(9)
+#define PMA_MPLLA_CTRL2_MPLLA_DIV16P5_CLK_EN BIT(10)
+#define PMA_MPLLA_CTRL2_MPLLA_TX_CLK_DIV_MASK GENMASK(12, 11)
+#define PMA_MPLLA_CTRL2_MPLLA_TX_CLK_DIV(x) (((x) << 11) & GENMASK(12, 11))
+#define PMA_MP_16G_MPLLA_CTRL3 0x100EE
+#define PMA_MPLLA_CTRL3_MPLLA_BANDWIDTH_MASK GENMASK(15, 0)
+#define PMA_MPLLA_CTRL3_MPLLA_BANDWIDTH(x) ((x) & GENMASK(15, 0))
+#define PMA_MP_16G_MPLLA_CTRL4 0x100F2
+#define PMA_MPLLA_CTRL4_MPLLA_SSC_FRQ_CNT_INT_MASK GENMASK(11, 0)
+#define PMA_MPLLA_CTRL4_MPLLA_SSC_FRQ_CNT_INT(x) ((x) & GENMASK(11, 0))
+#define PMA_MP_16G_MPLLA_CTRL5 0x100F4
+#define PMA_MPLLA_CTRL5_MPLLA_SSC_FRQ_CNT_PK_MASK GENMASK(7, 0)
+#define PMA_MPLLA_CTRL5_MPLLA_SSC_FRQ_CNT_PK(x) ((x) & GENMASK(7, 0))
+#define PMA_MPLLA_CTRL5_MPLLA_SSC_SPD_EN BIT(8)
+#define PMA_MP_12G_16G_25G_MISC_CTRL0 0x10120
+#define PMA_MISC_CTRL0_RX_VREF_CTRL_MASK GENMASK(12, 8)
+#define PMA_MISC_CTRL0_RX_VREF_CTRL(x) (((x) << 8) & GENMASK(12, 8))
+#define PMA_MP_12G_16G_25G_REF_CLK_CTRL 0x10122
+#define PMA_REF_CLK_CTRL_REF_CLK_DIV2 BIT(2)
+#define PMA_REF_CLK_CTRL_REF_RANGE_MASK GENMASK(5, 3)
+#define PMA_REF_CLK_CTRL_REF_RANGE(x) (((x) << 3) & GENMASK(5, 3))
+#define PMA_REF_CLK_CTRL_REF_MPLLA_DIV2 BIT(6)
+#define PMA_MP_12G_16G_25G_VCO_CAL_LD0 0x10124
+#define PMA_VCO_CAL_LD0_VCO_LD_VAL_0_MASK GENMASK(12, 0)
+#define PMA_VCO_CAL_LD0_VCO_LD_VAL_0(x) ((x) & GENMASK(12, 0))
+#define PMA_MP_16G_25G_VCO_CAL_REF0 0x1012C
+#define PMA_VCO_CAL_REF0_VCO_REF_LD_0_MASK GENMASK(6, 0)
+#define PMA_VCO_CAL_REF0_VCO_REF_LD_0(x) ((x) & GENMASK(6, 0))
+#define PMA_MP_12G_16G_25G_MISC_STS 0x10130
+#define PMA_MISC_STS_RX_ADPT_ACK BIT(12)
+#define PMA_MP_12G_16G_25G_SRAM 0x10136
+#define PMA_SRAM_INIT_DN BIT(0)
+#define PMA_SRAM_EXT_LD_DN BIT(1)
+#define PMA_MP_16G_25G_MISC_CTRL2 0x10138
+#define PMA_MISC_CTRL2_SUP_MISC_MASK GENMASK(7, 0)
+#define PMA_MISC_CTRL2_SUP_MISC(x) ((x) & GENMASK(7, 0))
+
+/* PCS */
+#define PCS_CTRL1 0x0
+#define PCS_CTRL1_RESET BIT(15)
+#define PCS_CTRL2 0xE
+#define PCS_CTRL2_PCS_TYPE_SEL_MASK GENMASK(3, 0)
+#define PCS_CTRL2_PCS_TYPE_SEL(x) ((x) & GENMASK(3, 0))
+#define PCS_DIG_CTRL1 0x10000
+#define PCS_DIG_CTRL1_USXG_EN BIT(9)
+#define PCS_DIG_CTRL1_USRA_RST BIT(10)
+#define PCS_DIG_CTRL1_VR_RST BIT(15)
+#define PCS_DEBUG_CTRL 0x1000A
+#define PCS_DEBUG_CTRL_SUPRESS_LOS_DET BIT(4)
+#define PCS_DEBUG_CTRL_RX_DT_EN_CTL BIT(6)
+#define PCS_DEBUG_CTRL_TX_PMBL_CTL BIT(8)
+#define PCS_KR_CTRL1 0x1000E
+#define PCS_KR_CTRL1_USXG_MODE_MASK GENMASK(12, 10)
+#define PCS_KR_CTRL1_USXG_MODE(x) (((x) << 10) & GENMASK(12, 10))
+
+/* VS MII MMD */
+#define MII_CTRL 0x0
+#define MII_CTRL_SS5 BIT(5)
+#define MII_CTRL_SS6 BIT(6)
+#define MII_CTRL_AN_ENABLE BIT(12)
+#define MII_CTRL_SS13 BIT(13)
+#define MII_DIG_CTRL1 0x10000
+#define MII_DIG_CTRL1_CL37_TMR_OVR_RIDE BIT(3)
+#define MII_AN_CTRL 0x10002
+#define MII_AN_CTRL_MII_AN_INTR_EN BIT(0)
+#define MII_AN_CTRL_TX_CONFIG BIT(3)
+#define MII_AN_INTR_STS 0x10004
+#define MII_AN_INTR_STS_CL37_ANCMPLT_INTR BIT(0)
+#define MII_LINK_TIMER_CTRL 0x10014
+#define MII_LINK_TIMER_CTRL_CL37_LINK_TIME_MASK GENMASK(15, 0)
+#define MII_LINK_TIMER_CTRL_CL37_LINK_TIME(x) ((x) & GENMASK(15, 0))
+
+/* E16 MEM MAP */
+#define IDCODE_LO 0x0
+#define IDCODE_HI 0x4
+#define GLOBAL_CTRL_EX_0 0x114
+#define GLOBAL_CTRL_EX_0_PHY_SRAM_BYPASS BIT(0)
+#define L0_RX_VCO_OVRD_OUT_0 0x20c
+#define L0_RX_VCO_OVRD_OUT_0_RX_ANA_CDR_FREQ_TUNE_MASK GENMASK(12, 3)
+#define L0_RX_VCO_OVRD_OUT_0_RX_ANA_CDR_FREQ_TUNE(x) (((x) << 3) & GENMASK(12, 3))
+#define L0_RX_VCO_OVRD_OUT_0_RX_CDR_FREQ_TUNE_OVRD_EN BIT(15)
+#define L0_RX_VCO_OVRD_OUT_2 0x214
+#define L0_RX_VCO_OVRD_OUT_2_RX_ANA_CDR_FREQ_TUNE_CLK BIT(0)
+
+static int enetc_mdio_read(struct mii_dev *bus, int addr, int devad, int reg);
+static int enetc_mdio_write(struct mii_dev *bus, int addr, int devad, int reg, u16 val);
+
+int xpcs_read(struct udevice *dev, int devaddr, u32 reg)
+{
+ struct enetc_priv *priv = dev_get_priv(dev);
+
+ return enetc_mdio_read(&priv->imdio, ENETC_PCS_PHY_ADDR, devaddr, reg);
+}
+
+int xpcs_write(struct udevice *dev, int devaddr, u32 reg, u16 val)
+{
+ struct enetc_priv *priv = dev_get_priv(dev);
+
+ return enetc_mdio_write(&priv->imdio, ENETC_PCS_PHY_ADDR, devaddr, reg, val);
+}
+
+int xpcs_phy_read(struct udevice *dev, int devaddr, u32 reg)
+{
+ struct enetc_priv *priv = dev_get_priv(dev);
+
+ return enetc_mdio_read(&priv->imdio, ENETC_NON_PCS_PHY_ADDR, devaddr, reg);
+}
+
+int xpcs_phy_write(struct udevice *dev, int devaddr, u32 reg, u16 val)
+{
+ struct enetc_priv *priv = dev_get_priv(dev);
+
+ return enetc_mdio_write(&priv->imdio, ENETC_NON_PCS_PHY_ADDR, devaddr, reg, val);
+}
+
+int xpcs_phy_read_pma(struct udevice *dev, u32 reg)
+{
+ return xpcs_read(dev, MDIO_MMD_PMAPMD, XPCS_PHY_REG(reg));
+}
+
+int xpcs_phy_write_pma(struct udevice *dev, int reg, u16 val)
+{
+ return xpcs_write(dev, MDIO_MMD_PMAPMD, XPCS_PHY_REG(reg), val);
+}
+
+int xpcs_phy_usxgmii_init_seq_2(struct udevice *dev)
+{
+ ulong begin;
+ u16 val;
+
+ /* Seq 2.1 Keep preamble data */
+ val = xpcs_read(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_DEBUG_CTRL));
+ val |= PCS_DEBUG_CTRL_TX_PMBL_CTL;
+ xpcs_write(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_DEBUG_CTRL), val);
+
+ /* Seq 2.2 Power up MPLLA to P1 state */
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_POWER_STATE_CTRL);
+ val = u16_replace_bits(val, 2, PMA_POWER_STATE_CTRL_TX0_PSTATE_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_POWER_STATE_CTRL, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_MPLL_CMN_CTRL);
+ val |= PMA_MPLL_CMN_CTRL_MPLL_EN_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_MPLL_CMN_CTRL, val);
+
+ /* Seq 2.3 Assert request of transmitand receive */
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2);
+ val |= PMA_TX_GENCTRL2_TX_REQ_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2);
+ val |= PMA_RX_GENCTRL2_RX_REQ_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2, val);
+
+ /* Seq 2.4 Poll for acknowledge */
+ begin = get_timer(0);
+ do {
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2);
+ if (get_timer(begin) > 500) {
+ dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+ goto timeout;
+ }
+ mdelay(10);
+ } while (val & PMA_TX_GENCTRL2_TX_REQ_0);
+
+ begin = get_timer(0);
+ do {
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2);
+ if (get_timer(begin) > 500) {
+ dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+ goto timeout;
+ }
+ mdelay(10);
+ } while (val & PMA_RX_GENCTRL2_RX_REQ_0);
+
+ /* Seq 2.5 Turn transmit to P0 state */
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_POWER_STATE_CTRL);
+ val = u16_replace_bits(val, 0, PMA_POWER_STATE_CTRL_TX0_PSTATE_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_POWER_STATE_CTRL, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL0);
+ val &= ~PMA_TX_GENCTRL0_TX_RST_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL0, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_POWER_STATE_CTRL);
+ val &= ~PMA_POWER_STATE_CTRL_TX_DISABLE_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_POWER_STATE_CTRL, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_MPLL_CMN_CTRL);
+ val |= PMA_MPLL_CMN_CTRL_MPLL_EN_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_MPLL_CMN_CTRL, val);
+
+ /* Seq 2.6 Turn receive to P0 state */
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL1);
+ val &= ~PMA_RX_GENCTRL1_RX_RST_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL1, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_POWER_STATE_CTRL);
+ val &= ~PMA_RX_POWER_STATE_CTRL_RX0_PSTATE_MASK;
+ val &= ~PMA_RX_POWER_STATE_CTRL_RX_DISABLE_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_POWER_STATE_CTRL, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_POWER_STATE_CTRL);
+ val &= ~PMA_RX_POWER_STATE_CTRL_RX0_PSTATE_MASK;
+ val &= ~PMA_RX_POWER_STATE_CTRL_RX_DISABLE_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_POWER_STATE_CTRL, val);
+
+ /* Seq 2.7 Enable transmitter output driver in the PHY */
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL0);
+ val |= PMA_TX_GENCTRL0_TX_DT_EN_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL0, val);
+
+ /* Seq 2.8 Enable receiver data output from PHY */
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL0);
+ val |= PMA_RX_GENCTRL0_RX_DT_EN_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL0, val);
+
+ /* Seq 2.9 Assert request of transmit and receive */
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2);
+ val |= PMA_TX_GENCTRL2_TX_REQ_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2);
+ val |= PMA_RX_GENCTRL2_RX_REQ_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2, val);
+
+ /* Seq 2.10 Poll for acknowledge */
+ begin = get_timer(0);
+ do {
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2);
+ if (get_timer(begin) > 500) {
+ dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+ goto timeout;
+ }
+ mdelay(10);
+ schedule();
+ } while (val & PMA_TX_GENCTRL2_TX_REQ_0);
+
+ begin = get_timer(0);
+ do {
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2);
+ if (get_timer(begin) > 500) {
+ dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+ goto timeout;
+ }
+ mdelay(10);
+ schedule();
+ } while (val & PMA_RX_GENCTRL2_RX_REQ_0);
+
+ return 0;
+
+timeout:
+ return -ETIMEDOUT;
+}
+
+void xpcs_phy_reg_lock(struct udevice *dev)
+{
+ u16 val;
+ ulong begin;
+
+ if (xpcs_phy_read(dev, XPCS_PHY_MAC_ADAPTER, XPCS_PHY_REG(MAC_ADAPTER_LOCK_PHY)) & MAC_ADAPTER_LOCK_LOCK)
+ return;
+
+ xpcs_phy_write(dev, XPCS_PHY_MAC_ADAPTER, XPCS_PHY_REG(MAC_ADAPTER_LOCK_PHY), MAC_ADAPTER_LOCK_LOCK);
+ xpcs_phy_write(dev, XPCS_PHY_MAC_ADAPTER, XPCS_PHY_REG(MAC_ADAPTER_LOCK_MPLLA), MAC_ADAPTER_LOCK_LOCK);
+ xpcs_phy_write(dev, XPCS_PHY_MAC_ADAPTER, XPCS_PHY_REG(MAC_ADAPTER_LOCK_MPLLB), MAC_ADAPTER_LOCK_LOCK);
+ xpcs_phy_write(dev, XPCS_PHY_MAC_ADAPTER, XPCS_PHY_REG(MAC_ADAPTER_LOCK_ROM), MAC_ADAPTER_LOCK_LOCK);
+ xpcs_phy_write(dev, XPCS_PHY_MAC_ADAPTER, XPCS_PHY_REG(MAC_ADAPTER_LOCK_RAM), MAC_ADAPTER_LOCK_LOCK);
+
+ begin = get_timer(0);
+ do {
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_SRAM);
+ if (get_timer(begin) > 500) {
+ dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+ goto timeout;
+ }
+ mdelay(10);
+ } while (!(val & PMA_SRAM_INIT_DN));
+
+ /* Work around */
+ // xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_SRAM, PMA_SRAM_EXT_LD_DN);
+ xpcs_phy_write(dev, XPCS_PHY_GLOBAL, XPCS_PHY_REG(GLOBAL_CTRL_EX_0), GLOBAL_CTRL_EX_0_PHY_SRAM_BYPASS);
+
+ begin = get_timer(0);
+ do {
+ val = xpcs_read(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_CTRL1));
+ if (get_timer(begin) > 500) {
+ dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+ goto timeout;
+ }
+ mdelay(10);
+ } while (val & PCS_CTRL1_RESET);
+
+ mdelay(1);
+
+timeout:
+ return;
+}
+
+int xpcs_phy_usxgmii_pma_config(struct udevice *dev)
+{
+ ulong begin;
+ u16 val;
+
+ xpcs_phy_reg_lock(dev);
+
+ /* 1.6 Turn off C37 auto-negotiation */
+ val = xpcs_read(dev, MDIO_MMD_VEND2, XPCS_PHY_REG(MII_CTRL));
+ val &= ~MII_CTRL_AN_ENABLE;
+ xpcs_write(dev, MDIO_MMD_VEND2, XPCS_PHY_REG(MII_CTRL), val);
+
+ /* 1.7 Assert tx_reset and rx_reset*/
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL0);
+ val |= PMA_TX_GENCTRL0_TX_RST_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL0, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL1);
+ val |= PMA_RX_GENCTRL1_RX_RST_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL1, val);
+
+ /* 1.8 Wait for more than 1us */
+ udelay(5);
+
+ /* 1.9 Deassert tx_reset and rx_reset*/
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL0);
+ val &= ~PMA_TX_GENCTRL0_TX_RST_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL0, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL1);
+ val &= ~PMA_RX_GENCTRL1_RX_RST_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL1, val);
+
+ /* 1.10 Power down MPLLA */
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_POWER_STATE_CTRL);
+ val = u16_replace_bits(val, 3, PMA_POWER_STATE_CTRL_TX0_PSTATE_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_POWER_STATE_CTRL, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_MPLL_CMN_CTRL);
+ val &= ~PMA_MPLL_CMN_CTRL_MPLL_EN_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_MPLL_CMN_CTRL, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL0);
+ val &= ~PMA_TX_GENCTRL0_TX_DT_EN_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL0, val);
+
+ /* 1.11 Change RX0 power state to P2 */
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL0);
+ val &= ~PMA_RX_GENCTRL0_RX_DT_EN_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL0, val);
+
+ /* TODO: check if it is needed */
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_POWER_STATE_CTRL);
+ val = u16_replace_bits(val, 1, PMA_RX_POWER_STATE_CTRL_RX0_PSTATE_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_POWER_STATE_CTRL, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_POWER_STATE_CTRL);
+ val = u16_replace_bits(val, 3, PMA_RX_POWER_STATE_CTRL_RX0_PSTATE_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_POWER_STATE_CTRL, val);
+
+ /* 1.12 Assert request of transmit and receive */
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2);
+ val |= PMA_TX_GENCTRL2_TX_REQ_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2);
+ val |= PMA_RX_GENCTRL2_RX_REQ_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2, val);
+
+ /* 1.13 Poll for acknlowledge */
+ begin = get_timer(0);
+ do {
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2);
+ if (get_timer(begin) > 500) {
+ dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+ goto timeout;
+ }
+ mdelay(10);
+ } while (val & PMA_TX_GENCTRL2_TX_REQ_0);
+
+ begin = get_timer(0);
+ do {
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2);
+ if (get_timer(begin) > 500) {
+ dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+ goto timeout;
+ }
+ mdelay(10);
+ } while (val & PMA_RX_GENCTRL2_RX_REQ_0);
+
+ /* 2 Config MPLL for 10G XGMII */
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_REF_CLK_CTRL);
+ val = u16_replace_bits(val, 6, PMA_REF_CLK_CTRL_REF_RANGE_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_REF_CLK_CTRL, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_REF_CLK_CTRL);
+ val &= ~PMA_REF_CLK_CTRL_REF_CLK_DIV2;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_REF_CLK_CTRL, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_REF_CLK_CTRL);
+ val |= PMA_REF_CLK_CTRL_REF_MPLLA_DIV2;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_REF_CLK_CTRL, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2);
+ val &= ~PMA_MPLLA_CTRL2_MPLLA_DIV8_CLK_EN;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2);
+ val |= PMA_MPLLA_CTRL2_MPLLA_DIV10_CLK_EN;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2);
+ val |= PMA_MPLLA_CTRL2_MPLLA_DIV16P5_CLK_EN;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2);
+ val &= ~PMA_MPLLA_CTRL2_MPLLA_TX_CLK_DIV_MASK;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2);
+ val |= PMA_MPLLA_CTRL2_MPLLA_DIV_CLK_EN;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2);
+ val = u16_replace_bits(val, 5, PMA_MPLLA_CTRL2_MPLLA_DIV_MULT_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_16G_MPLLA_CTRL1);
+ val &= ~PMA_MPLLA_CTRL1_MPLLA_SSC_EN;
+ xpcs_phy_write_pma(dev, PMA_MP_16G_MPLLA_CTRL1, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_16G_MPLLA_CTRL1);
+ val &= ~PMA_MPLLA_CTRL1_MPLLA_SSC_CLK_SEL;
+ xpcs_phy_write_pma(dev, PMA_MP_16G_MPLLA_CTRL1, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_16G_MPLLA_CTRL5);
+ val &= ~PMA_MPLLA_CTRL5_MPLLA_SSC_FRQ_CNT_PK_MASK;
+ xpcs_phy_write_pma(dev, PMA_MP_16G_MPLLA_CTRL5, val);
+
+ xpcs_phy_write_pma(dev, PMA_MP_16G_MPLLA_CTRL4, 0);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_16G_MPLLA_CTRL5);
+ val &= ~PMA_MPLLA_CTRL5_MPLLA_SSC_SPD_EN;
+ xpcs_phy_write_pma(dev, PMA_MP_16G_MPLLA_CTRL5, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_16G_MPLLA_CTRL1);
+ val &= ~PMA_MPLLA_CTRL1_MPLLA_FRACN_CTRL_MASK;
+ xpcs_phy_write_pma(dev, PMA_MP_16G_MPLLA_CTRL1, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL0);
+ val = u16_replace_bits(val, 33, PMA_MPLLA_CTRL0_MPLLA_MULTIPLIER_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL0, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL1);
+ val = u16_replace_bits(val, 5, PMA_TX_GENCTRL1_VBOOST_LVL_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL1, val);
+
+ val = PMA_MPLLA_CTRL3_MPLLA_BANDWIDTH(0xA016);
+ xpcs_phy_write_pma(dev, PMA_MP_16G_MPLLA_CTRL3, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_MISC_CTRL0);
+ val = u16_replace_bits(val, 0x11, PMA_MISC_CTRL0_RX_VREF_CTRL_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_MISC_CTRL0, val);
+
+ val = PMA_MISC_CTRL2_SUP_MISC(1);
+ xpcs_phy_write_pma(dev, PMA_MP_16G_25G_MISC_CTRL2, val);
+
+ val = PMA_VCO_CAL_REF0_VCO_REF_LD_0(0x29);
+ xpcs_phy_write_pma(dev, PMA_MP_16G_25G_VCO_CAL_REF0, val);
+
+ val = PMA_VCO_CAL_LD0_VCO_LD_VAL_0(0x549);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_VCO_CAL_LD0, val);
+
+ val = PMA_RX_PPM_CTRL0_RX0_CDR_PPM_MAX(0x12);
+ xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_PPM_CTRL0, val);
+
+ /* 3 Configure LANE0 for 10G XGMII */
+ xpcs_phy_write_pma(dev, PMA_MP_16G_25G_TX_MISC_CTRL0, 0x0);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_RATE_CTRL, 0x0);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_MPLL_CMN_CTRL);
+ val &= ~PMA_MPLL_CMN_CTRL_MPLLB_SEL_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_MPLL_CMN_CTRL, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2);
+ val = u16_replace_bits(val, 3, PMA_TX_GENCTRL2_TX0_WIDTH_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL1);
+ val |= PMA_TX_GENCTRL1_VBOOST_EN_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL1, val);
+
+ val = PMA_TX_BOOST_CTRL_TX0_IBOOST(0xf);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_BOOST_CTRL, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_EQ_CTRL0);
+ val = u16_replace_bits(val, 0, PMA_TX_EQ_CTRL0_TX_EQ_PRE_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_EQ_CTRL0, val);
+
+ val = PMA_TX_EQ_CTRL1_TX_EQ_POST(0x20);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_EQ_CTRL1, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_EQ_CTRL0);
+ val = u16_replace_bits(val, 0x20, PMA_TX_EQ_CTRL0_TX_EQ_MAIN_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_EQ_CTRL0, val);
+
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_RATE_CTRL, 0x0);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL0);
+ val = u16_replace_bits(val, 0x2, PMA_RX_EQ_CTRL0_CTLE_POLE_0_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL0, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL0);
+ val = u16_replace_bits(val, 0x10, PMA_RX_EQ_CTRL0_CTLE_BOOST_0_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL0, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_RX_GENCTRL3);
+ val = u16_replace_bits(val, 0x7, PMA_RX_GENCTRL3_LOS_TRSHLD_0_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_RX_GENCTRL3, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_16G_RX_CDR_CTRL1);
+ val |= PMA_RX_CDR_CTRL1_VCO_STEP_CTRL_0;
+ xpcs_phy_write_pma(dev, PMA_MP_16G_RX_CDR_CTRL1, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_16G_RX_CDR_CTRL1);
+ val |= PMA_RX_CDR_CTRL1_VCO_TEMP_COMP_EN_0;
+ xpcs_phy_write_pma(dev, PMA_MP_16G_RX_CDR_CTRL1, val);
+
+ val = PMA_RX_MISC_CTRL0_RX0_MISC(0x12);
+ xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_MISC_CTRL0, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2);
+ val = u16_replace_bits(val, 0x3, PMA_RX_GENCTRL2_RX0_WIDTH_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL1);
+ val |= PMA_RX_GENCTRL1_RX_DIV16P5_CLK_EN_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL1, val);
+
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_CDR_CTRL, 0x0);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_RX_GENCTRL3);
+ val &= ~PMA_RX_GENCTRL3_LOS_LFPS_EN_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_RX_GENCTRL3, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_16G_25G_RX_GENCTRL4);
+ val &= ~PMA_RX_GENCTRL4_RX_DFE_BYP_0;
+ xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_GENCTRL4, val);
+
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_ATTN_CTRL, 0x0);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL0);
+ val = u16_replace_bits(val, 0x5, PMA_RX_EQ_CTRL0_VGA1_GAIN_0_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL0, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL0);
+ val = u16_replace_bits(val, 0x5, PMA_RX_EQ_CTRL0_VGA2_GAIN_0_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL0, val);
+
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_DFE_TAP_CTRL0, 0x0);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_16G_RX_CDR_CTRL1);
+ val = u16_replace_bits(val, 0x1, PMA_RX_CDR_CTRL1_VCO_FRQBAND_0_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_16G_RX_CDR_CTRL1, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL1);
+ val |= PMA_RX_GENCTRL1_RX_TERM_ACDC_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL1, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_16G_25G_RX_IQ_CTRL0);
+ val = u16_replace_bits(val, 0x0, PMA_RX_IQ_CTRL0_RX0_DELTA_IQ_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_IQ_CTRL0, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL5);
+ val &= ~PMA_RX_EQ_CTRL5_RX_ADPT_SEL_0;
+ xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL5, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL5);
+ val = u16_replace_bits(val, 0x3, PMA_RX_EQ_CTRL5_RX0_ADPT_MODE_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL5, val);
+
+ /* 4 Configure XPCS for 10G XGMII */
+ xpcs_write(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_CTRL2), 0x0);
+
+ val = xpcs_read(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_DIG_CTRL1));
+ val |= PCS_DIG_CTRL1_USXG_EN;
+ xpcs_write(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_DIG_CTRL1), val);
+
+ val = xpcs_read(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_KR_CTRL1));
+ val = u16_replace_bits(val, 0x0, PCS_KR_CTRL1_USXG_MODE_MASK);
+ xpcs_write(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_KR_CTRL1), val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL0);
+ val = u16_replace_bits(val, 0x21, PMA_MPLLA_CTRL0_MPLLA_MULTIPLIER_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL0, val);
+
+ val = PMA_MPLLA_CTRL3_MPLLA_BANDWIDTH(0xA016);
+ xpcs_phy_write_pma(dev, PMA_MP_16G_MPLLA_CTRL3, val);
+
+ val = PMA_VCO_CAL_LD0_VCO_LD_VAL_0(0x549);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_VCO_CAL_LD0, val);
+
+ val = PMA_VCO_CAL_REF0_VCO_REF_LD_0(0x29);
+ xpcs_phy_write_pma(dev, PMA_MP_16G_25G_VCO_CAL_REF0, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_EQ_CTRL4);
+ val |= PMA_RX_EQ_CTRL4_CONT_ADAPT_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_EQ_CTRL4, val);
+
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_RATE_CTRL, 0x0);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_RATE_CTRL, 0x0);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2);
+ val = u16_replace_bits(val, 0x3, PMA_TX_GENCTRL2_TX0_WIDTH_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_TX_GENCTRL2, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2);
+ val = u16_replace_bits(val, 0x3, PMA_RX_GENCTRL2_RX0_WIDTH_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2);
+ val |= PMA_MPLLA_CTRL2_MPLLA_DIV16P5_CLK_EN;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2);
+ val |= PMA_MPLLA_CTRL2_MPLLA_DIV10_CLK_EN;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2);
+ val &= ~PMA_MPLLA_CTRL2_MPLLA_DIV8_CLK_EN;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_MPLLA_CTRL2, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL1);
+ val |= PMA_TX_GENCTRL1_VBOOST_EN_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL1, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL0);
+ val = u16_replace_bits(val, 0x10, PMA_RX_EQ_CTRL0_CTLE_BOOST_0_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL0, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_16G_RX_CDR_CTRL1);
+ val |= PMA_RX_CDR_CTRL1_VCO_STEP_CTRL_0;
+ xpcs_phy_write_pma(dev, PMA_MP_16G_RX_CDR_CTRL1, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_16G_RX_CDR_CTRL1);
+ val |= PMA_RX_CDR_CTRL1_VCO_TEMP_COMP_EN_0;
+ xpcs_phy_write_pma(dev, PMA_MP_16G_RX_CDR_CTRL1, val);
+
+ val = PMA_RX_MISC_CTRL0_RX0_MISC(0x12);
+ xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_MISC_CTRL0, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_16G_25G_RX_GENCTRL4);
+ val &= ~PMA_RX_GENCTRL4_RX_DFE_BYP_0;
+ xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_GENCTRL4, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_16G_RX_CDR_CTRL1);
+ val = u16_replace_bits(val, 0x1, PMA_RX_CDR_CTRL1_VCO_FRQBAND_0_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_16G_RX_CDR_CTRL1, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_16G_25G_RX_IQ_CTRL0);
+ val = u16_replace_bits(val, 0x0, PMA_RX_IQ_CTRL0_RX0_DELTA_IQ_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_IQ_CTRL0, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL5);
+ val = u16_replace_bits(val, 0x3, PMA_RX_EQ_CTRL5_RX0_ADPT_MODE_MASK);
+ xpcs_phy_write_pma(dev, PMA_MP_16G_25G_RX_EQ_CTRL5, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL1);
+ val &= ~PMA_TX_GENCTRL1_TX_CLK_RDY_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL1, val);
+
+ /* 5 Assert soft reset */
+ val = xpcs_read(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_DIG_CTRL1));
+ val |= PCS_DIG_CTRL1_VR_RST;
+ xpcs_write(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_DIG_CTRL1), val);
+
+ /* 6 Poll for SRAM initialization done */
+ begin = get_timer(0);
+ do {
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_SRAM);
+ if (get_timer(begin) > 500) {
+ dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+ goto timeout;
+ }
+ mdelay(10);
+ } while (!(val & PMA_SRAM_INIT_DN));
+
+ /* 7 Assert SRAM external loading done */
+ /* Workaround */
+ // xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_SRAM, PMA_SRAM_EXT_LD_DN);
+ xpcs_phy_write(dev, XPCS_PHY_GLOBAL, XPCS_PHY_REG(GLOBAL_CTRL_EX_0), GLOBAL_CTRL_EX_0_PHY_SRAM_BYPASS);
+
+ /* 8 Poll for vendor-specific soft reset */
+ begin = get_timer(0);
+ do {
+ val = xpcs_read(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_DIG_CTRL1));
+ if (get_timer(begin) > 500) {
+ dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+ goto timeout;
+ }
+ mdelay(10);
+ } while (val & PCS_DIG_CTRL1_VR_RST);
+
+ /* 9 Turn receive to P0 state */
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL1);
+ val &= ~PMA_RX_GENCTRL1_RX_RST_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL1, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_POWER_STATE_CTRL);
+ val &= ~PMA_RX_POWER_STATE_CTRL_RX_DISABLE_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_POWER_STATE_CTRL, val);
+
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_POWER_STATE_CTRL);
+ val &= ~PMA_RX_POWER_STATE_CTRL_RX0_PSTATE_MASK;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_POWER_STATE_CTRL, val);
+
+ /* 10 Enable receiver data output from PHY */
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL0);
+ val |= PMA_RX_GENCTRL0_RX_DT_EN_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_GENCTRL0, val);
+
+ /* 11 Assert request of receive */
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2);
+ val |= PMA_RX_GENCTRL2_RX_REQ_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2, val);
+
+ /* 11.1 Poll for acknowledge */
+ begin = get_timer(0);
+ do {
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_RX_GENCTRL2);
+ if (get_timer(begin) > 500) {
+ dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+ goto timeout;
+ }
+ mdelay(10);
+ } while (val & PMA_RX_GENCTRL2_RX_REQ_0);
+
+ /* 12 Assert TX0 clock is active and stable */
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL1);
+ val |= PMA_TX_GENCTRL1_TX_CLK_RDY_0;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_TX_GENCTRL1, val);
+
+ /*
+ * 13.1 Configure XPCS to consider Loss-of-Signal indicated by the
+ * PHY while evaluating the receive link status
+ */
+ val = xpcs_read(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_DEBUG_CTRL));
+ val |= PCS_DEBUG_CTRL_SUPRESS_LOS_DET;
+ xpcs_write(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_DEBUG_CTRL), val);
+ /*
+ * 13.2 Configure XPCS to deassert "receiver data enable" on
+ * detecting of Loss-of-Signal
+ */
+ val = xpcs_read(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_DEBUG_CTRL));
+ val |= PCS_DEBUG_CTRL_RX_DT_EN_CTL;
+ xpcs_write(dev, MDIO_MMD_PCS, XPCS_PHY_REG(PCS_DEBUG_CTRL), val);
+
+ /* 14 Poll for DPLL lock status for Lane 0 */
+ begin = get_timer(0);
+ do {
+ val = xpcs_phy_read_pma(dev, PMA_RX_LSTS);
+ if (get_timer(begin) > 500) {
+ dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+ goto timeout;
+ }
+ mdelay(10);
+ } while (!(val & PMA_RX_LSTS_RX_VALID_0));
+
+ /* 15 Assert request of receive adaptation */
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_EQ_CTRL4);
+ val |= PMA_RX_EQ_CTRL4_RX_AD_REQ;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_EQ_CTRL4, val);
+
+ /* 16 Poll for acknowledge */
+ begin = get_timer(0);
+ do {
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_MISC_STS);
+ if (get_timer(begin) > 500) {
+ dev_err(dev, "Polling timeout, line: %d\n", __LINE__);
+ goto timeout;
+ }
+ mdelay(10);
+ } while (!(val & PMA_MISC_STS_RX_ADPT_ACK));
+
+ /* 17 Deassert request of receive adaptation */
+ val = xpcs_phy_read_pma(dev, PMA_MP_12G_16G_25G_RX_EQ_CTRL4);
+ val &= ~PMA_RX_EQ_CTRL4_RX_AD_REQ;
+ xpcs_phy_write_pma(dev, PMA_MP_12G_16G_25G_RX_EQ_CTRL4, val);
+
+ /* 18 Set the value of Config_Reg to 0 for Clause 37 autonegotiation. */
+ val = xpcs_read(dev, MDIO_MMD_VEND2, XPCS_PHY_REG(MII_AN_CTRL));
+ val &= ~MII_AN_CTRL_TX_CONFIG;
+ xpcs_write(dev, MDIO_MMD_VEND2, XPCS_PHY_REG(MII_AN_CTRL), val);
+
+ /* 19 Select XGMII speed */
+ val = xpcs_read(dev, MDIO_MMD_VEND2, XPCS_PHY_REG(MII_CTRL));
+ val &= ~MII_CTRL_SS5;
+ val |= MII_CTRL_SS6 | MII_CTRL_SS13;
+ xpcs_write(dev, MDIO_MMD_VEND2, XPCS_PHY_REG(MII_CTRL), val);
+
+ val = xpcs_phy_usxgmii_init_seq_2(dev);
+ if (val)
+ return val;
+
+ return 0;
+
+timeout:
+ return -ETIMEDOUT;
+}
+
+u32 xpcs_phy_get_id(struct udevice *dev)
+{
+ int ret;
+ u32 id;
+
+ /* First, search C73 PCS using PCS MMD */
+ ret = xpcs_phy_read(dev, XPCS_PHY_GLOBAL, XPCS_PHY_REG(IDCODE_HI));
+ if (ret < 0)
+ return 0xffffffff;
+
+ id = ret << 16;
+
+ ret = xpcs_phy_read(dev, XPCS_PHY_GLOBAL, XPCS_PHY_REG(IDCODE_LO));
+ if (ret < 0)
+ return 0xffffffff;
+
+ /* If Device IDs are not all zeros or all ones,
+ * we found C73 AN-type device
+ */
+ if ((id | ret) && (id | ret) != 0xffffffff)
+ return id | ret;
+
+ return 0xffffffff;
+}
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index cbf5f605518..bea1dfed892 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -38,9 +38,13 @@
#include <linux/mii.h>
#include <asm/io.h>
#include <linux/dma-mapping.h>
-#include <asm/arch/clk.h>
#include <linux/errno.h>
+/* Without CLK, we rely on the arch definition */
+#if !defined(CONFIG_CLK)
+#include <asm/arch/clk.h>
+#endif
+
#include "macb.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -768,18 +772,40 @@ static int macb_phy_init(struct udevice *dev, const char *name)
lpa);
} else {
/* if macb port is a fixed link */
- /* TODO : manage gigabit capable processors */
+ const char *human_readable_speed;
+
speed = macb->speed;
duplex = macb->duplex;
+ switch (speed) {
+ case 2:
+ human_readable_speed = "1000";
+ break;
+ case 1:
+ human_readable_speed = "100";
+ break;
+ case 0:
+ human_readable_speed = "10";
+ break;
+ default:
+ printf("%s: speed %d not supported\n", name, speed);
+ return -EINVAL;
+ }
printf("%s: link up, %sMbps %s-duplex\n",
name,
- speed ? "100" : "10",
+ human_readable_speed,
duplex ? "full" : "half");
}
ncfgr = macb_readl(macb, NCFGR);
ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD) | GEM_BIT(GBE));
- if (speed) {
+ if (speed == 2) {
+ if (!gem_is_gigabit_capable(macb)) {
+ printf("%s: is not gigabit Ethernet capable\n", name);
+ return -EINVAL;
+ }
+ ncfgr |= GEM_BIT(GBE);
+ ret = macb_linkspd_cb(dev, _1000BASET);
+ } else if (speed == 1) {
ncfgr |= MACB_BIT(SPD);
ret = macb_linkspd_cb(dev, _100BASET);
} else {
@@ -923,26 +949,39 @@ static int _macb_init(struct udevice *dev, const char *name)
/* Check the multi queue and initialize the queue for tx */
gmac_init_multi_queues(macb);
- /*
- * When the GMAC IP with GE feature, this bit is used to
- * select interface between RGMII and GMII.
- * When the GMAC IP without GE feature, this bit is used
- * to select interface between RMII and MII.
+ /* This driver uses the user I/O to select the PHY features,
+ * but some GEM instances come with a fixed configuration and
+ * no USERIO.
*/
- if (macb->phy_interface == PHY_INTERFACE_MODE_RGMII ||
- macb->phy_interface == PHY_INTERFACE_MODE_RGMII_ID ||
- macb->phy_interface == PHY_INTERFACE_MODE_RGMII_RXID ||
- macb->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID)
- val = macb->config->usrio->rgmii;
- else if (macb->phy_interface == PHY_INTERFACE_MODE_RMII)
- val = macb->config->usrio->rmii;
- else if (macb->phy_interface == PHY_INTERFACE_MODE_MII)
- val = macb->config->usrio->mii;
+ if (gem_readl(macb, DCFG1) & GEM_BIT(USERIO)) {
+ /*
+ * When the GMAC IP with GE feature, this bit is used to
+ * select interface between RGMII and GMII.
+ * When he GMAC IP without GE feature, this bit is used
+ * to select interface between RMII and MII.
+ */
+ switch (macb->phy_interface) {
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ val = macb->config->usrio->rgmii;
+ break;
+ case PHY_INTERFACE_MODE_RMII:
+ val = macb->config->usrio->rmii;
+ break;
+ case PHY_INTERFACE_MODE_MII:
+ val = macb->config->usrio->mii;
+ break;
+ default:
+ break;
+ }
- if (macb->config->caps & MACB_CAPS_USRIO_HAS_CLKEN)
- val |= macb->config->usrio->clken;
+ if (macb->config->caps & MACB_CAPS_USRIO_HAS_CLKEN)
+ val |= macb->config->usrio->clken;
- gem_writel(macb, USRIO, val);
+ gem_writel(macb, USRIO, val);
+ }
if (macb->phy_interface == PHY_INTERFACE_MODE_SGMII) {
unsigned int ncfgr = macb_readl(macb, NCFGR);
@@ -1003,9 +1042,14 @@ static int _macb_write_hwaddr(struct macb_device *macb, unsigned char *enetaddr)
/* set hardware address */
hwaddr_bottom = enetaddr[0] | enetaddr[1] << 8 |
enetaddr[2] << 16 | enetaddr[3] << 24;
- macb_writel(macb, SA1B, hwaddr_bottom);
hwaddr_top = enetaddr[4] | enetaddr[5] << 8;
- macb_writel(macb, SA1T, hwaddr_top);
+ if (macb_is_gem(macb)) {
+ gem_writel(macb, SA1B, hwaddr_bottom);
+ gem_writel(macb, SA1T, hwaddr_top);
+ } else {
+ macb_writel(macb, SA1B, hwaddr_bottom);
+ macb_writel(macb, SA1T, hwaddr_top);
+ }
return 0;
}
@@ -1307,7 +1351,9 @@ static int macb_eth_of_to_plat(struct udevice *dev)
macb->phy_addr = PHY_MAX_ADDR + 1;
macb->duplex = fdtdec_get_bool(blob, fl_node, "full-duplex");
speed_fdt = fdtdec_get_int(blob, fl_node, "speed", 0);
- if (speed_fdt == 100) {
+ if (speed_fdt == 1000) {
+ macb->speed = 2;
+ } else if (speed_fdt == 100) {
macb->speed = 1;
} else if (speed_fdt == 10) {
macb->speed = 0;
diff --git a/drivers/net/macb.h b/drivers/net/macb.h
index 0eb90574618..002d5bd31b2 100644
--- a/drivers/net/macb.h
+++ b/drivers/net/macb.h
@@ -443,6 +443,8 @@
#define MACB_REV_SIZE 16
/* Bitfields in DCFG1. */
+#define GEM_USERIO_OFFSET 9
+#define GEM_USERIO_SIZE 1
#define GEM_IRQCOR_OFFSET 23
#define GEM_IRQCOR_SIZE 1
#define GEM_DBWDEF_OFFSET 25
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 5d2277a4602..0025c895f12 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -7,7 +7,7 @@ config MV88E6352_SWITCH
menuconfig PHYLIB
bool "Ethernet PHY (physical media interface) support"
- depends on NET || NET_LWIP
+ depends on NET
help
Enable Ethernet PHY (physical media interface) support.
@@ -381,7 +381,7 @@ config PHY_FIXED
config PHY_NCSI
bool "NC-SI based PHY"
- depends on NET
+ depends on NET_LEGACY
endif #PHYLIB
diff --git a/drivers/net/phy/adin.c b/drivers/net/phy/adin.c
index ce448810ff6..4d42e56dada 100644
--- a/drivers/net/phy/adin.c
+++ b/drivers/net/phy/adin.c
@@ -10,6 +10,7 @@
#include <linux/bitops.h>
#include <linux/bitfield.h>
+#define PHY_ID_ADIN1200 0x0283bc20
#define PHY_ID_ADIN1300 0x0283bc30
#define ADIN1300_EXT_REG_PTR 0x10
#define ADIN1300_EXT_REG_DATA 0x11
@@ -263,6 +264,18 @@ static int adin1300_config(struct phy_device *phydev)
return genphy_config(phydev);
}
+U_BOOT_PHY_DRIVER(ADIN1200) = {
+ .name = "ADIN1200",
+ .uid = PHY_ID_ADIN1200,
+ .mask = 0xffffffff,
+ .features = PHY_BASIC_FEATURES,
+ .config = adin1300_config,
+ .startup = genphy_startup,
+ .shutdown = genphy_shutdown,
+ .readext = adin_extread,
+ .writeext = adin_extwrite,
+};
+
U_BOOT_PHY_DRIVER(ADIN1300) = {
.name = "ADIN1300",
.uid = PHY_ID_ADIN1300,
diff --git a/drivers/net/phy/airoha/Kconfig b/drivers/net/phy/airoha/Kconfig
index da8747939e3..4139df343ad 100644
--- a/drivers/net/phy/airoha/Kconfig
+++ b/drivers/net/phy/airoha/Kconfig
@@ -7,6 +7,7 @@ config PHY_AIROHA_EN8811
depends on PHY_AIROHA
depends on SUPPORTS_FW_LOADER
select FW_LOADER
+ select PHY_COMMON_PROPS
help
AIROHA EN8811H supported.
AIROHA AN8811HB supported.
diff --git a/drivers/net/phy/airoha/air_en8811.c b/drivers/net/phy/airoha/air_en8811.c
index 0b974472732..32f06dd6dfa 100644
--- a/drivers/net/phy/airoha/air_en8811.c
+++ b/drivers/net/phy/airoha/air_en8811.c
@@ -23,6 +23,7 @@
#include <linux/compat.h>
#include <dm/device_compat.h>
#include <u-boot/crc.h>
+#include <linux/phy/phy-common-props.h>
/* MII Registers */
#define AIR_AUX_CTRL_STATUS 0x1d
@@ -1046,11 +1047,50 @@ static int air_leds_init(struct phy_device *phydev, int num, u16 dur, int mode)
return 0;
}
-static int en8811h_config(struct phy_device *phydev)
+static int en8811h_config_serdes_polarity(struct phy_device *phydev)
{
- struct en8811h_priv *priv = phydev->priv;
ofnode node = phy_get_ofnode(phydev);
+ unsigned int pol, default_pol;
u32 pbus_value = 0;
+ int ret;
+
+ if (!ofnode_valid(node))
+ return 0;
+
+ default_pol = PHY_POL_NORMAL;
+ if (ofnode_read_bool(node, "airoha,pnswap-rx"))
+ default_pol = PHY_POL_INVERT;
+
+ ret = phy_get_rx_polarity(node,
+ phy_string_for_interface(phydev->interface),
+ BIT(PHY_POL_NORMAL) | BIT(PHY_POL_INVERT),
+ default_pol, &pol);
+ if (ret)
+ return ret;
+ if (pol == PHY_POL_INVERT)
+ pbus_value |= EN8811H_POLARITY_RX_REVERSE;
+
+ default_pol = PHY_POL_NORMAL;
+ if (ofnode_read_bool(node, "airoha,pnswap-tx"))
+ default_pol = PHY_POL_INVERT;
+
+ ret = phy_get_tx_polarity(node,
+ phy_string_for_interface(phydev->interface),
+ BIT(PHY_POL_NORMAL) | BIT(PHY_POL_INVERT),
+ default_pol, &pol);
+ if (ret)
+ return ret;
+ if (pol == PHY_POL_NORMAL)
+ pbus_value |= EN8811H_POLARITY_TX_NORMAL;
+
+ return air_buckpbus_reg_modify(phydev, EN8811H_POLARITY,
+ EN8811H_POLARITY_RX_REVERSE |
+ EN8811H_POLARITY_TX_NORMAL, pbus_value);
+}
+
+static int en8811h_config(struct phy_device *phydev)
+{
+ struct en8811h_priv *priv = phydev->priv;
int ret = 0;
/* If restart happened in .probe(), no need to restart now */
@@ -1081,20 +1121,8 @@ static int en8811h_config(struct phy_device *phydev)
if (ret < 0)
return ret;
- /* Serdes polarity */
- pbus_value = 0;
- if (ofnode_read_bool(node, "airoha,pnswap-rx"))
- pbus_value |= EN8811H_POLARITY_RX_REVERSE;
- else
- pbus_value &= ~EN8811H_POLARITY_RX_REVERSE;
- if (ofnode_read_bool(node, "airoha,pnswap-tx"))
- pbus_value &= ~EN8811H_POLARITY_TX_NORMAL;
- else
- pbus_value |= EN8811H_POLARITY_TX_NORMAL;
- ret = air_buckpbus_reg_modify(phydev, EN8811H_POLARITY,
- EN8811H_POLARITY_RX_REVERSE |
- EN8811H_POLARITY_TX_NORMAL,
- pbus_value);
+ /* Configure Serdes polarity from device tree */
+ ret = en8811h_config_serdes_polarity(phydev);
if (ret < 0)
return ret;
diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
index 10b87dfb8ab..83da3e1cc77 100644
--- a/drivers/net/phy/aquantia.c
+++ b/drivers/net/phy/aquantia.c
@@ -400,7 +400,7 @@ int aquantia_config(struct phy_device *phydev)
int interface = phydev->interface;
u32 val, id, rstatus, fault;
u32 reg_val1 = 0;
- int num_retries = 5;
+ int num_retries = 200;
int usx_an = 0;
/*
diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c
index 7ce03b59b6a..ebed61de133 100644
--- a/drivers/net/phy/dp83867.c
+++ b/drivers/net/phy/dp83867.c
@@ -203,32 +203,24 @@ static int dp83867_of_init(struct phy_device *phydev)
"Should be 'rgmii-id' to use internal delays\n");
}
- /* RX delay *must* be specified if internal delay of RX is used. */
+ dp83867->rx_id_delay = DP83867_RGMIIDCTL_2_00_NS;
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
ret = ofnode_read_u32(node, "ti,rx-internal-delay",
&dp83867->rx_id_delay);
- if (ret) {
- pr_debug("ti,rx-internal-delay must be specified\n");
- return ret;
- }
- if (dp83867->rx_id_delay > DP83867_RGMII_RX_CLK_DELAY_MAX) {
+ if (!ret && dp83867->rx_id_delay > DP83867_RGMII_RX_CLK_DELAY_MAX) {
pr_debug("ti,rx-internal-delay value of %u out of range\n",
dp83867->rx_id_delay);
return -EINVAL;
}
}
- /* TX delay *must* be specified if internal delay of RX is used. */
+ dp83867->tx_id_delay = DP83867_RGMIIDCTL_2_00_NS;
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
ret = ofnode_read_u32(node, "ti,tx-internal-delay",
&dp83867->tx_id_delay);
- if (ret) {
- debug("ti,tx-internal-delay must be specified\n");
- return ret;
- }
- if (dp83867->tx_id_delay > DP83867_RGMII_TX_CLK_DELAY_MAX) {
+ if (!ret && dp83867->tx_id_delay > DP83867_RGMII_TX_CLK_DELAY_MAX) {
pr_debug("ti,tx-internal-delay value of %u out of range\n",
dp83867->tx_id_delay);
return -EINVAL;
diff --git a/drivers/net/phy/mscc.c b/drivers/net/phy/mscc.c
index a65e81dff0c..d96970949bc 100644
--- a/drivers/net/phy/mscc.c
+++ b/drivers/net/phy/mscc.c
@@ -23,6 +23,7 @@
#define PHY_ID_VSC8502 0x00070630
#define PHY_ID_VSC8540 0x00070760
#define PHY_ID_VSC8541 0x00070770
+#define PHY_ID_VSC8572 0x000704d0
#define PHY_ID_VSC8574 0x000704a0
#define PHY_ID_VSC8584 0x000707c0
@@ -1612,6 +1613,16 @@ U_BOOT_PHY_DRIVER(vsc8541) = {
.shutdown = &genphy_shutdown,
};
+U_BOOT_PHY_DRIVER(vsc8572) = {
+ .name = "Microsemi VSC8572",
+ .uid = PHY_ID_VSC8572,
+ .mask = 0x000ffff0,
+ .features = PHY_GBIT_FEATURES,
+ .config = &vsc8574_config,
+ .startup = &mscc_startup,
+ .shutdown = &genphy_shutdown,
+};
+
U_BOOT_PHY_DRIVER(vsc8574) = {
.name = "Microsemi VSC8574",
.uid = PHY_ID_VSC8574,
diff --git a/drivers/net/qe/dm_qe_uec_phy.c b/drivers/net/qe/dm_qe_uec_phy.c
index 8c0168be859..107c7686b3b 100644
--- a/drivers/net/qe/dm_qe_uec_phy.c
+++ b/drivers/net/qe/dm_qe_uec_phy.c
@@ -152,7 +152,7 @@ static const struct udevice_id qe_uec_mdio_ids[] = {
{ }
};
-U_BOOT_DRIVER(mvmdio) = {
+U_BOOT_DRIVER(qe_uec_mdio) = {
.name = "qe_uec_mdio",
.id = UCLASS_MDIO,
.of_match = qe_uec_mdio_ids,
diff --git a/drivers/net/sandbox.c b/drivers/net/sandbox.c
index 0ea50c484c0..e1daeb6c1e6 100644
--- a/drivers/net/sandbox.c
+++ b/drivers/net/sandbox.c
@@ -15,7 +15,7 @@
/*
* Structure definitions for network protocols. Since this file is used for
- * both NET and NET_LWIP, and given that the two network stacks do have
+ * both NET_LEGACY and NET_LWIP, and given that the two network stacks do have
* conflicting types (for instance struct icmp_hdr), it is on purpose that the
* structures are defined locally with minimal dependencies -- <asm/types.h> is
* included for the bit types and that's it.
diff --git a/drivers/net/sni_netsec.c b/drivers/net/sni_netsec.c
index 71afe78fd28..b74a5c27cae 100644
--- a/drivers/net/sni_netsec.c
+++ b/drivers/net/sni_netsec.c
@@ -1138,7 +1138,7 @@ static const struct udevice_id netsec_ids[] = {
{}
};
-U_BOOT_DRIVER(ave) = {
+U_BOOT_DRIVER(synquacer_netsec) = {
.name = "synquacer_netsec",
.id = UCLASS_ETH,
.of_match = netsec_ids,
diff --git a/drivers/net/ti/cpsw.c b/drivers/net/ti/cpsw.c
index d7746f454ba..7a7cb83bd98 100644
--- a/drivers/net/ti/cpsw.c
+++ b/drivers/net/ti/cpsw.c
@@ -33,6 +33,7 @@
#define PKT_MAX (1500 + 14 + 4 + 4)
#define CLEAR_BIT 1
#define GIGABITEN BIT(7)
+#define GMII_EN BIT(5)
#define FULLDUPLEXEN BIT(0)
#define MIIEN BIT(15)
#define CTL_EXT_EN BIT(18)
@@ -216,6 +217,10 @@ struct cpsw_priv {
u32 phy_mask;
};
+struct cpsw_driver_data {
+ void (*gmii_sel)(struct cpsw_priv *priv, phy_interface_t phy_mode);
+};
+
static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
{
int idx;
@@ -1064,9 +1069,17 @@ static void cpsw_gmii_sel_dra7xx(struct cpsw_priv *priv,
writel(reg, priv->data->gmii_sel);
}
-static void cpsw_phy_sel(struct cpsw_priv *priv, const char *compat,
- phy_interface_t phy_mode)
+static void cpsw_phy_sel(struct cpsw_priv *priv, phy_interface_t phy_mode)
{
+ const char *compat = priv->data->phy_sel_compat;
+ const struct cpsw_driver_data *drv_data =
+ (const struct cpsw_driver_data *)dev_get_driver_data(priv->dev);
+
+ if (drv_data && drv_data->gmii_sel) {
+ drv_data->gmii_sel(priv, phy_mode);
+ return;
+ }
+
if (!strcmp(compat, "ti,am3352-cpsw-phy-sel"))
cpsw_gmii_sel_am3352(priv, phy_mode);
if (!strcmp(compat, "ti,am43xx-cpsw-phy-sel"))
@@ -1084,8 +1097,7 @@ static int cpsw_eth_probe(struct udevice *dev)
priv->data = pdata->priv_pdata;
ti_cm_get_macid(dev, priv->data, pdata->enetaddr);
/* Select phy interface in control module */
- cpsw_phy_sel(priv, priv->data->phy_sel_compat,
- pdata->phy_interface);
+ cpsw_phy_sel(priv, pdata->phy_interface);
return _cpsw_register(priv);
}
@@ -1122,33 +1134,13 @@ static void cpsw_eth_of_parse_slave(struct cpsw_platform_data *data,
"max-speed", 0);
}
-static int cpsw_eth_of_to_plat(struct udevice *dev)
+static int cpsw_eth_of_to_plat_legacy(struct udevice *dev,
+ struct cpsw_platform_data *data)
{
- struct eth_pdata *pdata = dev_get_plat(dev);
- struct cpsw_platform_data *data;
- struct gpio_desc *mode_gpios;
int slave_index = 0;
- int num_mode_gpios;
ofnode subnode;
int ret;
- data = calloc(1, sizeof(struct cpsw_platform_data));
- if (!data)
- return -ENOMEM;
-
- pdata->priv_pdata = data;
- pdata->iobase = dev_read_addr(dev);
- data->version = CPSW_CTRL_VERSION_2;
- data->bd_ram_ofs = CPSW_BD_OFFSET;
- data->ale_reg_ofs = CPSW_ALE_OFFSET;
- data->cpdma_reg_ofs = CPSW_CPDMA_OFFSET;
- data->mdio_div = CPSW_MDIO_DIV;
- data->host_port_reg_ofs = CPSW_HOST_PORT_OFFSET,
-
- pdata->phy_interface = -1;
-
- data->cpsw_base = pdata->iobase;
-
ret = dev_read_s32(dev, "cpdma_channels", &data->channels);
if (ret) {
printf("error: cpdma_channels not found in dt\n");
@@ -1177,21 +1169,10 @@ static int cpsw_eth_of_to_plat(struct udevice *dev)
ret = dev_read_u32(dev, "mac_control", &data->mac_control);
if (ret) {
- printf("error: ale_entries not found in dt\n");
+ printf("error: mac_control not found in dt\n");
return ret;
}
- num_mode_gpios = gpio_get_list_count(dev, "mode-gpios");
- if (num_mode_gpios > 0) {
- mode_gpios = malloc(sizeof(struct gpio_desc) *
- num_mode_gpios);
- gpio_request_list_by_name(dev, "mode-gpios", mode_gpios,
- num_mode_gpios, GPIOD_IS_OUT);
- free(mode_gpios);
- }
-
- data->active_slave = dev_read_u32_default(dev, "active_slave", 0);
-
ofnode_for_each_subnode(subnode, dev_ofnode(dev)) {
const char *name;
@@ -1222,16 +1203,118 @@ static int cpsw_eth_of_to_plat(struct udevice *dev)
if (ofnode_read_bool(subnode, "rmii-clock-ext"))
data->rmii_clock_external = true;
+ }
+ }
- data->phy_sel_compat = ofnode_read_string(subnode,
- "compatible");
- if (!data->phy_sel_compat) {
- pr_err("Not able to get gmii_sel compatible\n");
- return -ENOENT;
- }
+ return 0;
+}
+
+static int cpsw_eth_of_to_plat_switch(struct udevice *dev,
+ struct cpsw_platform_data *data)
+{
+ ofnode eth_ports_node, subnode;
+ int ret;
+
+ data->channels = 8;
+ data->ale_entries = 1024;
+ data->mac_control = GMII_EN;
+
+ eth_ports_node = ofnode_find_subnode(dev_ofnode(dev), "ethernet-ports");
+ data->slaves = ofnode_get_child_count(eth_ports_node);
+ if (!data->slaves) {
+ pr_err("cpsw: No ethernet-ports defined\n");
+ return -EINVAL;
+ }
+
+ data->slave_data = malloc(sizeof(struct cpsw_slave_data) * data->slaves);
+ if (!data->slave_data)
+ return -ENOMEM;
+
+ ofnode_for_each_subnode(subnode, eth_ports_node) {
+ struct ofnode_phandle_args args;
+ u32 port_id;
+
+ ret = ofnode_read_u32(subnode, "reg", &port_id);
+ if (ret || !port_id || port_id > data->slaves) {
+ pr_err("cpsw: invalid or missing reg in port node\n");
+ return -EINVAL;
+ }
+
+ cpsw_eth_of_parse_slave(data, port_id - 1, subnode);
+
+ if (!data->gmii_sel) {
+ ret = ofnode_parse_phandle_with_args(subnode, "phys", "#phy-cells",
+ 0, 0, &args);
+ if (!ret)
+ data->gmii_sel = ofnode_get_addr(args.node);
+ }
+ }
+
+ if (!data->gmii_sel) {
+ pr_err("No port specified phys correctly\n");
+ return -ENOENT;
+ }
+
+ ofnode_for_each_subnode(subnode, dev_ofnode(dev)) {
+ const char *name = ofnode_get_name(subnode);
+
+ if (strncmp(name, "mdio", 4))
+ continue;
+
+ data->mdio_base = ofnode_get_addr(subnode);
+ if (data->mdio_base == FDT_ADDR_T_NONE) {
+ pr_err("Not able to get MDIO address space\n");
+ return -ENOENT;
}
}
+ return 0;
+}
+
+static int cpsw_eth_of_to_plat(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_plat(dev);
+ struct cpsw_platform_data *data;
+ struct gpio_desc *mode_gpios;
+ int num_mode_gpios;
+ int ret;
+ bool switch_dt_bindings =
+ ofnode_valid(ofnode_find_subnode(dev_ofnode(dev), "ethernet-ports"));
+
+ data = calloc(1, sizeof(struct cpsw_platform_data));
+ if (!data)
+ return -ENOMEM;
+
+ pdata->priv_pdata = data;
+ pdata->iobase = dev_read_addr(dev);
+ data->version = CPSW_CTRL_VERSION_2;
+ data->bd_ram_ofs = CPSW_BD_OFFSET;
+ data->ale_reg_ofs = CPSW_ALE_OFFSET;
+ data->cpdma_reg_ofs = CPSW_CPDMA_OFFSET;
+ data->mdio_div = CPSW_MDIO_DIV;
+ data->host_port_reg_ofs = CPSW_HOST_PORT_OFFSET;
+
+ pdata->phy_interface = -1;
+
+ data->cpsw_base = pdata->iobase;
+
+ num_mode_gpios = gpio_get_list_count(dev, "mode-gpios");
+ if (num_mode_gpios > 0) {
+ mode_gpios = malloc(sizeof(struct gpio_desc) * num_mode_gpios);
+ gpio_request_list_by_name(dev, "mode-gpios", mode_gpios,
+ num_mode_gpios, GPIOD_IS_OUT);
+ free(mode_gpios);
+ }
+
+ data->active_slave = dev_read_u32_default(dev, "active_slave", 0);
+
+ if (switch_dt_bindings)
+ ret = cpsw_eth_of_to_plat_switch(dev, data);
+ else
+ ret = cpsw_eth_of_to_plat_legacy(dev, data);
+ if (ret)
+ return ret;
+
data->slave_data[0].slave_reg_ofs = CPSW_SLAVE0_OFFSET;
data->slave_data[0].sliver_reg_ofs = CPSW_SLIVER0_OFFSET;
@@ -1253,9 +1336,22 @@ static int cpsw_eth_of_to_plat(struct udevice *dev)
return 0;
}
+static const struct cpsw_driver_data cpsw_data_am3352 = {
+ .gmii_sel = cpsw_gmii_sel_am3352,
+};
+
+static const struct cpsw_driver_data cpsw_data_dra7xx = {
+ .gmii_sel = cpsw_gmii_sel_dra7xx,
+};
+
static const struct udevice_id cpsw_eth_ids[] = {
- { .compatible = "ti,cpsw" },
- { .compatible = "ti,am335x-cpsw" },
+ { .compatible = "ti,cpsw", .data = (ulong)&cpsw_data_am3352 },
+ { .compatible = "ti,am335x-cpsw", .data = (ulong)&cpsw_data_am3352 },
+ { .compatible = "ti,am4372-cpsw", .data = (ulong)&cpsw_data_am3352 },
+ { .compatible = "ti,dra7-cpsw", .data = (ulong)&cpsw_data_dra7xx },
+ { .compatible = "ti,am335x-cpsw-switch", .data = (ulong)&cpsw_data_am3352 },
+ { .compatible = "ti,am4372-cpsw-switch", .data = (ulong)&cpsw_data_am3352 },
+ { .compatible = "ti,dra7-cpsw-switch", .data = (ulong)&cpsw_data_dra7xx },
{ }
};
#endif
diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c
index e9cc5db52d2..1ea81fe1830 100644
--- a/drivers/net/xilinx_axi_emac.c
+++ b/drivers/net/xilinx_axi_emac.c
@@ -28,6 +28,10 @@
#define XAE_EMMC_LINKSPD_100 0x40000000 /* Link Speed mask for 100 Mbit */
#define XAE_EMMC_LINKSPD_1000 0x80000000 /* Link Speed mask for 1000 Mbit */
+/* Reset and Address Filter (RAF) Register bit definitions */
+#define XAE_RAF_MCSTREJ_MASK 0x00000002 /* Reject rx multicast dst addr */
+#define XAE_RAF_BCSTREJ_MASK 0x00000004 /* Reject rx broadcast dst addr */
+
/* Interrupt Status/Enable/Mask Registers bit definitions */
#define XAE_INT_RXRJECT_MASK 0x00000008 /* Rx frame rejected */
#define XAE_INT_MGTRDY_MASK 0x00000080 /* MGT clock Lock */
@@ -153,7 +157,8 @@ static struct axidma_bd tx_bd __attribute((aligned(DMAALIGN)));
static struct axidma_bd rx_bd __attribute((aligned(DMAALIGN)));
struct axi_regs {
- u32 reserved[3];
+ u32 raf; /* 0x0: Reset and Address Filter */
+ u32 reserved[2];
u32 is; /* 0xC: Interrupt status */
u32 reserved2;
u32 ie; /* 0x14: Interrupt enable */
@@ -528,6 +533,19 @@ static int axi_ethernet_init(struct axidma_priv *priv)
/* Set default MDIO divisor */
writel(XAE_MDIO_DIV_DFT | XAE_MDIO_MC_MDIOEN_MASK, &regs->mdio_mc);
+ /*
+ * Reject broadcast and multicast frames at MAC level to reduce
+ * unnecessary traffic processing. Multicast rejection is only
+ * enabled when IPv6 is not configured because IPv6 Neighbor
+ * Discovery and DHCPv6 rely on multicast.
+ */
+ if (!IS_ENABLED(CONFIG_IPV6))
+ writel(readl(&regs->raf) | XAE_RAF_MCSTREJ_MASK |
+ XAE_RAF_BCSTREJ_MASK, &regs->raf);
+ else
+ writel(readl(&regs->raf) | XAE_RAF_BCSTREJ_MASK,
+ &regs->raf);
+
debug("axiemac: InitHw done\n");
return 0;
}
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index a50d5aee03f..f570ae9ee73 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -69,10 +69,13 @@
#define ZYNQ_GEM_NWCFG_SGMII_ENBL 0x08000000 /* SGMII Enable */
#define ZYNQ_GEM_NWCFG_PCS_SEL 0x00000800 /* PCS select */
+#define ZYNQ_GEM_DBUS_WIDTH_MASK (3 << 21) /* bits 22:21 */
#ifdef CONFIG_ARM64
# define ZYNQ_GEM_DBUS_WIDTH (1 << 21) /* 64 bit bus */
+# define ZYNQ_GEM_DBUS_WIDTH_128 (2 << 21) /* 128 bit bus */
#else
# define ZYNQ_GEM_DBUS_WIDTH (0 << 21) /* 32 bit bus */
+# define ZYNQ_GEM_DBUS_WIDTH_128 (0 << 21) /* 32 bit bus */
#endif
#define ZYNQ_GEM_NWCFG_INIT (ZYNQ_GEM_DBUS_WIDTH | \
@@ -134,6 +137,7 @@
#define ZYNQ_GEM_FREQUENCY_10 2500000UL
#define ZYNQ_GEM_FREQUENCY_100 25000000UL
#define ZYNQ_GEM_FREQUENCY_1000 125000000UL
+#define ZYNQ_GEM_FREQUENCY_10000 150000000UL
#define RXCLK_EN BIT(0)
@@ -470,28 +474,6 @@ static int zynq_gem_init(struct udevice *dev)
for (i = 0; i < STAT_SIZE; i++)
readl(&regs->stat[i]);
- /* Setup RxBD space */
- memset(priv->rx_bd, 0, RX_BUF * sizeof(struct emac_bd));
-
- for (i = 0; i < RX_BUF; i++) {
- priv->rx_bd[i].status = 0xF0000000;
- priv->rx_bd[i].addr =
- (lower_32_bits((ulong)(priv->rxbuffers)
- + (i * PKTSIZE_ALIGN)));
-#if defined(CONFIG_PHYS_64BIT)
- priv->rx_bd[i].addr_hi =
- (upper_32_bits((ulong)(priv->rxbuffers)
- + (i * PKTSIZE_ALIGN)));
-#endif
- }
- /* WRAP bit to last BD */
- priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
- /* Write RxBDs to IP */
- writel(lower_32_bits((ulong)priv->rx_bd), &regs->rxqbase);
-#if defined(CONFIG_PHYS_64BIT)
- writel(upper_32_bits((ulong)priv->rx_bd), &regs->upper_rxqbase);
-#endif
-
/* Setup for DMA Configuration register */
writel(ZYNQ_GEM_DMACR_INIT, &regs->dmacr);
@@ -520,6 +502,35 @@ static int zynq_gem_init(struct udevice *dev)
priv->init++;
}
+ /*
+ * Reinitialize RX BDs on every init. The 10GBE USX block asserts
+ * RX_SYNC_RESET during setup which resets the GEM RX DMA pointer
+ * back to rxqbase, so BDs and rxqbase must be refreshed each time
+ * to keep the hardware and driver ring indices in sync.
+ */
+ priv->rxbd_current = 0;
+ priv->rx_first_buf = 0;
+ memset(priv->rx_bd, 0, RX_BUF * sizeof(struct emac_bd));
+ for (i = 0; i < RX_BUF; i++) {
+ priv->rx_bd[i].status = 0xF0000000;
+ priv->rx_bd[i].addr =
+ (lower_32_bits((ulong)(priv->rxbuffers)
+ + (i * PKTSIZE_ALIGN)));
+#if defined(CONFIG_PHYS_64BIT)
+ priv->rx_bd[i].addr_hi =
+ (upper_32_bits((ulong)(priv->rxbuffers)
+ + (i * PKTSIZE_ALIGN)));
+#endif
+ }
+ /* WRAP bit to last BD */
+ priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
+
+ /* Write RxBDs to IP */
+ writel(lower_32_bits((ulong)priv->rx_bd), &regs->rxqbase);
+#if defined(CONFIG_PHYS_64BIT)
+ writel(upper_32_bits((ulong)priv->rx_bd), &regs->upper_rxqbase);
+#endif
+
ret = phy_startup(priv->phydev);
if (ret)
return ret;
@@ -532,6 +543,8 @@ static int zynq_gem_init(struct udevice *dev)
nwconfig = ZYNQ_GEM_NWCFG_INIT;
if (device_is_compatible(dev, "amd,versal2-10gbe")) {
+ nwconfig &= ~ZYNQ_GEM_DBUS_WIDTH_MASK;
+ nwconfig |= ZYNQ_GEM_DBUS_WIDTH_128;
if (priv->interface == PHY_INTERFACE_MODE_10GBASER) {
ctrl = readl(&regs->nwcfg);
ctrl |= PCSSEL;
@@ -602,6 +615,9 @@ static int zynq_gem_init(struct udevice *dev)
}
switch (priv->phydev->speed) {
+ case SPEED_10000:
+ clk_rate = ZYNQ_GEM_FREQUENCY_10000;
+ break;
case SPEED_1000:
nwconfig |= ZYNQ_GEM_NWCFG_SPEED1000;
clk_rate = ZYNQ_GEM_FREQUENCY_1000;
@@ -615,6 +631,7 @@ static int zynq_gem_init(struct udevice *dev)
break;
}
nwcfg = readl(&regs->nwcfg);
+ nwcfg &= ~(ZYNQ_GEM_NWCFG_SPEED100 | ZYNQ_GEM_NWCFG_SPEED1000);
nwcfg |= nwconfig;
if (nwcfg)
writel(nwcfg, &regs->nwcfg);