您好,NXP团队,
我正在使用i.MX93 SoM ,外接LAN8720A PHY,运行在 RMII 模式下。
以太网接口初始化失败,并报告以下错误:
imx-dwmac 428a0000.ethernet eth1:
PHY [stmmac-1:00] 驱动程序 [SMSC LAN8710/LAN8720]
imx-dwmac 428a0000.ethernet:
DMA重置失败
stmmac_hw_setup:DMA 引擎初始化失败
__stmmac_open:硬件设置失败
dmsg 响应
oot@myd-lmx9x:~# dmesg | grep -i eth
[ 0.000000] OF:保留内存:已初始化节点 ethosu_region@B0000000,兼容 ID shared-dma-pool
[ 0.000000] psci:从 DT 探测管道方法。
[ 0.953397] fec 42890000.ethernet:无效的 MAC 地址:00:00:00:00:00:00
[ 0.960228] fec 42890000.ethernet:使用随机 MAC 地址:b2:da:68:e1:93:b7
[ 0.970863] hns3:适用于 Hip08 系列的海思以太网网络驱动程序 - 版本
[ 1.008422] igb:Intel(R) 千兆以太网网络驱动程序
[ 1.071474] usbcore:已注册新的接口驱动程序 kaweth
[ 1.082559] usbcore:已注册新的接口驱动程序 cdc_ether
[ 1.646174] optee:探测管道方法。
[ 1.744525] 蓝牙:BNEP(以太网仿真)版本 1.3
[ 2.560730] fec 42890000.ethernet eth0:已注册 PHC 设备 0
[ 2.567579] imx-dwmac 428a0000.ethernet:未找到 IRQ eth_lpi
[ 2.573824] imx-dwmac 428a0000.ethernet:用户 ID:0x10,Synopsys ID:0x52
[ 2.580662] imx-dwmac 428a0000.ethernet:DWMAC4/5
[ 2.585448] imx-dwmac 428a0000.ethernet:DMA 硬件功能寄存器支持
[ 2.592568] imx-dwmac 428a0000.ethernet:支持 RX 校验和卸载引擎
[ 2.599692] imx-dwmac 428a0000.ethernet:支持插入 TX 校验和
[ 2.606382] imx-dwmac 428a0000.ethernet:支持局域网唤醒
[ 2.612538] imx-dwmac 428a0000.ethernet:通过硬件看门狗定时器启用接收缓解
[ 2.620184] imx-dwmac 428a0000.ethernet:已启用 L3L4 流 TC(条目=8)
[ 2.626958] imx-dwmac 428a0000.ethernet:已启用 RFS 流 TC(条目数=10)
[ 2.633749] imx-dwmac 428a0000.ethernet:启用硬件TC(条目数=256,最大关闭次数=256)
[ 2.641316] imx-dwmac 428a0000.ethernet:使用 32/32 位 DMA 主机/设备宽度
[ 5.034969] systemd[1]: /lib/systemd/system/proftpd.service:8:标准输出类型 syslog 已过时,将自动更新为 journal。请更新您的单元文件,并考虑完全移除该设置。
[ 9.808139] SMSC LAN8710/LAN8720 42890000.ethernet-1:00:phy_poll_reset 失败:-110
[ 9.872078] fec 42890000.ethernet eth0:无法连接到物理层
[ 9.879398] imx-dwmac 428a0000.ethernet eth1: 注册 MEM_TYPE_PAGE_POOL RxQ-0
[ 10.892065] imx-dwmac 428a0000.ethernet eth1: __stmmac_open: 无法连接到 PHY(错误:-110)
[ 10.900872] imx-dwmac 428a0000.ethernet eth1: 注册 MEM_TYPE_PAGE_POOL RxQ-0
[ 11.904042] imx-dwmac 428a0000.ethernet eth1: __stmmac_open: 无法连接到 PHY(错误:-110)
[ 12.838630] SMSC LAN8710/LAN8720 42890000.ethernet-1:00:phy_poll_reset 失败:-110
[ 12.896039] fec 42890000.ethernet eth0:无法连接到物理层
[ 12.899637] imx-dwmac 428a0000.ethernet eth1: 注册 MEM_TYPE_PAGE_POOL RxQ-0
[ 13.904038] imx-dwmac 428a0000.ethernet eth1: __stmmac_open: 无法连接到 PHY(错误:-110)
[ 289.712584] imx-dwmac 428a0000.ethernet eth1: 注册 MEM_TYPE_PAGE_POOL RxQ-0
[ 290.740032] imx-dwmac 428a0000.ethernet eth1: __stmmac_open: 无法连接到 PHY(错误:-110)
[ 322.123525] imx-dwmac 428a0000.ethernet eth1: 注册 MEM_TYPE_PAGE_POOL RxQ-0
[ 323.104042] imx-dwmac 428a0000.ethernet eth1: __stmmac_open: 无法连接到 PHY(错误:-110)
[ 655.579526] imx-dwmac 428a0000.ethernet eth1: 注册 MEM_TYPE_PAGE_POOL RxQ-0
[ 656.612033] imx-dwmac 428a0000.ethernet eth1: __stmmac_open: 无法连接到 PHY(错误:-110)
步骤 1 — 隔离 EQoS
暂时禁用 FEC:
&fec {
status = "disabled";
};
然后启动并检查:
dmesg | grep -Ei "dwmac|stmmac|eqos|mdio|phy|LAN87"
你想查看 EQoS/stmmac MDIO 总线下的 PHY,而不是 42890000.ethernet 下的 PHY。
步骤 2 — 手动验证 MDIO
如果您有mdio-tool或phytool:
phytool 读取 eth1/0/2
phytool 读取 eth1/0/3
LAN8720A PHY ID 应该可读。如果读取超时或返回全部 0xffff/0x0000,则这是硬件/MDIO/RESET/时钟,而不是 IP 协议栈。
步骤 3 — 验证时钟树
cat /sys/kernel/debug/clk/clk_summary | grep -Ei "enet|qos"
同时测量引脚上的 RMII 参考时钟。NXP RMII 线程专门记录了生成预期 50 MHz 时钟和使用 <100000000>、<50000000> 进行 DTS 更新的必要性。
步骤 4 — 检查驱动程序补丁状态
grep -n "RMII_RESET_SPEED\|imx_dwmac_mx93_reset\|fix_soc_reset" \
drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
如果缺失,请应用/移植 i.MX93 RMII DMA RESET 补丁。上游补丁说明它解决了 i.MX93 复位逻辑的问题,需要在 RMII 模式下配置正确的接口速度才能完成复位。( https://www.spinics.net/lists/netdev/msg894184.html )
这是一个棘手的问题——遗憾的是,我们的任何一份文件中还没有对此进行描述。
EQOS 以太网 MAC 是来自第三方的 IP,并且也被 ST Microelectronics 的芯片所采用。这就是为什么你会在 ST 平台的文件夹中找到 i.MX 的代码的原因。EQOS IP 中的 DMA RESET 似乎存在问题或曾经存在问题,但我无法确切地查明问题出在哪里。对于 i.MX 93,我发现忽略此检查可以解决问题,因此请注释掉跳转到“err_stop_resets”的代码:
/drivers/net/dwc_eth_qos.c in function eqos_start
if (ret) {
- pr_err("EQOS_DMA_MODE_SWR stuck\n");
- goto err_stop_resets;
+ pr_err("EQOS_DMA_MODE_SWR stuck indicated, but continue anyway\n");
+ //goto err_stop_resets;
如果您在 EQOS RMII 接口的 TD2 引脚上看到 50 MHz 参考时钟,并且您已将 SION 位配置为将时钟从 TD2 焊盘反馈到 EQOS MAC,那么应该就没问题了。
FEC 应该不会对源文件进行任何更改,只需要对设备树进行必要的调整即可。
我会查找设备树和 board_init 函数所需的配置,稍后在这里发布。
问候,
伯恩哈德。
以下是需要对适用于 i.MX 93(或在某种程度上也适用于 i.MX 91)网络接口的标准 NXP 电路板支持包进行更改的内容。
这些是 u-boot 的更改(来自 NXP git hub),如果您使用主线 u-boot,您可能会看到它略有不同,但原理是相同的。您可能在网上找到的任何设备树参数,例如“ snps,ext-refclk; ”都绝对属于“谨慎使用来自网络的代码”这一范畴。
u-boot 代码或 Linux 内核中可能根本没有评估此类参数(或者可能只在较旧的平台上评估),因此,如果您想确定,请开始搜索此参数并检查它是否已被考虑在内。
可能是这样的:在正确的 DTB 设置下,两个网络接口在 Linux 中都能正常工作,但在 u-boot 命令提示符下只有 FEC 接口工作。为此,请查看以下应用于imx93_evkimx93_evk.c和dwc_eth_qos.c的更改。
uboot-imx/arch/arm/dts/imx93-11x11-evk.dts:
&fec {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_fec>;
phy-mode = "rmii";
phy-handle = <ðphy2>;
fsl,magic-packet;
status = "okay";
mdio {
#address-cells = <1>;
#size-cells = <0>;
clock-frequency = <5000000>;
ethphy2: ethernet-phy@2 {
reg = <0>; /* adapt to MDIO PHY address on your board */
eee-broken-1000t;
};
};
};
&eqos {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_eqos>;
phy-mode = "rmii";
phy-handle = <ðphy1>;
status = "okay";
mdio {
compatible = "snps,dwmac-mdio";
#address-cells = <1>;
#size-cells = <0>;
clock-frequency = <5000000>;
ethphy1: ethernet-phy@1 {
reg = <1>; /* adapt to MDIO PHY address on your board */
eee-broken-1000t;
};
};
};
pinctrl_eqos: eqosgrp { /* for 10/100 board, drive strength settings tbd */
fsl,pins = <
MX93_PAD_ENET1_MDC__ENET_QOS_MDC 0x0000017E
MX93_PAD_ENET1_MDIO__ENET_QOS_MDIO 0x0000017E
MX93_PAD_ENET1_RD0__ENET_QOS_RGMII_RD0 0x0000017E
MX93_PAD_ENET1_RD1__ENET_QOS_RGMII_RD1 0x0000017E
MX93_PAD_ENET1_RXC__ENET_QOS_RX_ER 0x0000017E
MX93_PAD_ENET1_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x0000017E
MX93_PAD_ENET1_TD0__ENET_QOS_RGMII_TD0 0x0000017E
MX93_PAD_ENET1_TD1__ENET_QOS_RGMII_TD1 0x0000017E
MX93_PAD_ENET1_TD2__CCM_ENET_QOS_CLOCK_GENERATE_REF_CLK 0x0000017E
MX93_PAD_ENET1_TXC__GPIO4_IO07 0x0000011E
MX93_PAD_ENET1_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x0000057E
>;
};
pinctrl_fec: fecgrp { /* for 10/100 board, drive strength settings tbd */
fsl,pins = <
MX93_PAD_ENET2_MDC__ENET1_MDC 0x0000011E
MX93_PAD_ENET2_MDIO__ENET1_MDIO 0x0000011E
MX93_PAD_ENET2_RD0__ENET1_RGMII_RD0 0x0000011E
MX93_PAD_ENET2_RD1__ENET1_RGMII_RD1 0x0000011E
MX93_PAD_ENET2_RXC__ENET1_RGMII_RXC 0x0000011E
MX93_PAD_ENET2_RX_CTL__ENET1_RGMII_RX_CTL 0x0000011E
MX93_PAD_ENET2_TD0__ENET1_RGMII_TD0 0x0000011E
MX93_PAD_ENET2_TD1__ENET1_RGMII_TD1 0x0000011E
MX93_PAD_ENET2_TD2__ENET1_TX_CLK 0x0000011E
MX93_PAD_ENET2_TXC__GPIO4_IO21 0x0000011E
MX93_PAD_ENET2_TX_CTL__ENET1_RGMII_TX_CTL 0x0000051E
>;
};
uboot-imx/arch/arm/dts/imx93.dtsi:
fec: ethernet@42890000 {
compatible = "fsl,imx93-fec", "fsl,imx8mq-fec", "fsl,imx6sx-fec";
reg = <0x42890000 0x10000>;
interrupts = ,
,
,
;
clocks = <&clk IMX93_CLK_ENET1_GATE>,
<&clk IMX93_CLK_ENET1_GATE>,
<&clk IMX93_CLK_ENET_TIMER1>,
<&clk IMX93_CLK_ENET_REF>,
<&clk IMX93_CLK_ENET_REF_PHY>;
clock-names = "ipg", "ahb", "ptp",
"enet_clk_ref", "enet_out";
assigned-clocks = <&clk IMX93_CLK_ENET_TIMER1>,
<&clk IMX93_CLK_ENET_REF>,
<&clk IMX93_CLK_ENET_REF_PHY>;
assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>,
<&clk IMX93_CLK_SYS_PLL_PFD0_DIV2>,
<&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>;
assigned-clock-rates = <100000000>, <250000000>, <50000000>;
fsl,num-tx-queues = <3>;
fsl,num-rx-queues = <3>;
fsl,stop-mode = <&wakeupmix_gpr 0x0c 1>;
status = "disabled";
};
eqos: ethernet@428a0000 {
compatible = "nxp,imx93-dwmac-eqos", "snps,dwmac-5.10a";
reg = <0x428a0000 0x10000>;
interrupts = ,
;
interrupt-names = "macirq", "eth_wake_irq";
clocks = <&clk IMX93_CLK_ENET_QOS_GATE>,
<&clk IMX93_CLK_ENET_QOS_GATE>,
<&clk IMX93_CLK_ENET_TIMER2>,
<&clk IMX93_CLK_ENET>,
<&clk IMX93_CLK_ENET_QOS_GATE>;
clock-names = "stmmaceth", "pclk", "ptp_ref", "tx", "mem";
assigned-clocks = <&clk IMX93_CLK_ENET_TIMER2>,
<&clk IMX93_CLK_ENET>;
assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>,
<&clk IMX93_CLK_SYS_PLL_PFD0_DIV2>;
assigned-clock-rates = <100000000>, <250000000>;
intf_mode = <&wakeupmix_gpr 0x28>;
snps,clk-csr = <0>;
status = "disabled";
};
uboot-imx/arch/arm/dts/imx93-11x11-evk-u-boot.dtsi:
&fec {
/* adapt GPIOx y to the actual pin used on your board */
phy-reset-gpios = <&gpiox y GPIO_ACTIVE_LOW>;
phy-reset-duration = <15>;
phy-reset-post-delay = <100>;
};
ðphy1 {
/* adapt GPIOx y to the actual pin used on your board */
phy-reset-gpios = <&gpiox y GPIO_ACTIVE_LOW>;
reset-assert-us = <15000>;
reset-deassert-us = <100000>;
};
imx93_11x11_evk_defconfig 中需要考虑的事项:
CONFIG_USE_ETHPRIME=y
CONFIG_ETHPRIME="eth1"
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_DWC_ETH_QOS=y
CONFIG_DWC_ETH_QOS_IMX=y
CONFIG_FEC_MXC=y
CONFIG_MII=y
uboot-imx/drivers/net/dwc_eth_qos.c 中的函数 eqos_start(struct udevice *dev):
if (ret) {
pr_err("EQOS_DMA_MODE_SWR stuck indicated, continue anyway.\n");
/* ignore this error, comment the goto instruction out */
/* goto err_stop_resets; */
}
uboot-imx/board/freescale/imx93_evkimx93_evk.c:
static int setup_fec(void)
{
/*
There are PHYs which also work with a 25 MHz input clock,
configurable with a pin strapping or over MDIO, so the parameter
could also be ENET_25MHZ)
*/
return set_clk_enet(ENET_50MHZ);
}
static int setup_eqos(void)
{
struct blk_ctrl_wakeupmix_regs *bctrl = (struct blk_ctrl_wakeupmix_regs *)BLK_CTRL_WAKEUPMIX_BASE_ADDR;
u32 *IOMUXC_SW_MUX_CTL_PAD_ENET_TD2 = (u32 *)(IOMUXC_BASE_ADDR + 0xA4);
#define IOMUXC_SW_MUX_CTL_PAD_ENET_TD2_SION (1<<4)
clrbits_le32(&bctrl->enet_clk_sel,
BCTRL_ENET_CLK_SEL_ENET1_TX_CLK_SEL);
clrbits_le32(&bctrl->enet_clk_sel,
BCTRL_ENET_CLK_SEL_ENET_QOS_CLK_TX_CLK_SEL);
/* set INTF as RMII, enable RMII TX clock */
clrsetbits_le32(&bctrl->eqos_gpr,
BCTRL_GPR_ENET_QOS_INTF_MODE_MASK,
BCTRL_GPR_ENET_QOS_INTF_SEL_RMII | BCTRL_GPR_ENET_QOS_CLK_GEN_EN);
setbits_le32(&IOMUXC_SW_MUX_CTL_PAD_ENET_TD2,
IOMUXC_SW_MUX_CTL_PAD_ENET_TD2_SION);
/*
There are PHYs which also work with a 25 MHz input clock,
configurable with a pin strapping or over MDIO, so the parameter
could also be ENET_25MHZ)
*/
return set_clk_eqos(ENET_50MHZ);
}
int board_init(void)
{
#ifdef CONFIG_USB_TCPC
setup_typec();
#endif
if (IS_ENABLED(CONFIG_FEC_MXC))
setup_fec();
if (IS_ENABLED(CONFIG_DWC_ETH_QOS))
setup_eqos();
board_gpio_init();
return 0;
}
问候,
伯恩哈德。