You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

IMX6UL无Bootloader预配置时FEC1的PHY无法被MDIO识别问题

解决IMX6UL双FEC共享MDIO总线时FEC1 PHY识别问题

问题背景

在IMX6UL设备上使用FEC1和FEC2,二者各连接一个PHY,且两个PHY的管理接口共享FEC2子节点下的同一MDIO总线:FEC1的PHY在MDIO总线上地址为0,FEC2的PHY地址为1。

启动时出现以下异常:

  • MDIO搜索无法找到FEC1连接的PHY,日志提示[ 3.701404] mdio_bus 20b4000.ethernet-1: MDIO device at address 0 is missing.
  • 后续出现[ 24.683268] fec 2188000.ethernet eth1: Unable to connect to phy

若通过U-Boot或Barebox等Bootloader在Linux启动前预先配置FEC,系统可正常工作。经排查原因如下:
未通过Bootloader预配置时,FEC2的设备树节点地址低于FEC1,Linux会优先探测FEC2;此时FEC1的pinmux未配置,导致FEC1的复用功能未设置,PHY无时钟;后续探测FEC1时时钟才开启,但MDIO已判定该PHY不可达;重启Linux后,复用功能已配置,FEC1的PHY可被正常识别。

解决方案

方法1:调整设备树节点顺序,让FEC1先初始化

Linux按设备树中节点的先后顺序初始化设备,将&fec1节点放在&fec2节点之前,这样FEC1的pinmux和时钟会先被配置,MDIO扫描时FEC1的PHY已经具备工作时钟。

修改后的设备树节点顺序示例:

&fec1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_enet1>, <&pinctrl_enet1_gpio>;
    phy-mode = "rmii";
    phy-handle = <&ethphy0>;
    phy-supply = <&reg_fec_3v3>;
    status = "okay";
};

&fec2 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_enet2>, 
                <&pinctrl_enet2_mdio>,
                <&pinctrl_enet2_gpio>;
    phy-mode = "rmii";
    phy-supply = <&reg_fec_3v3>;
    phy-handle = <&ethphy1>;
    status = "okay";

    mdio {
        #address-cells = <1>;
        #size-cells = <0>;

        ethphy0: ethernet-phy@0 {
            compatible = "ethernet-phy-ieee802.3-c22";
            reg = <0>;
            max-speed = <100>;
            clocks = <&clks IMX6UL_CLK_ENET_REF>;
            reset-gpios = <&gpio3 9 GPIO_ACTIVE_LOW>;
            reset-assert-us = <200>;
            reset-deassert-us = <1000>;
            reset-names = "phy-reset1";
        };      

        ethphy1: ethernet-phy@1 {
            compatible = "ethernet-phy-ieee802.3-c22";
            reg = <1>;
            max-speed = <100>;
            clocks = <&clks IMX6UL_CLK_ENET2_REF_125M>;
            reset-gpios = <&gpio3 10 GPIO_ACTIVE_LOW>;
            reset-assert-us = <200>;
            reset-deassert-us = <1000>;
            reset-names = "phy-reset2";
        };
    };  
};

注意:将FEC2的pinctrl_enet1_gpio移到FEC1的pinctrl-0中,让FEC1自行管理自身PHY的复位引脚配置。

方法2:显式配置FEC1的时钟,确保初始化时开启

在FEC1节点中添加clocks和clock-names属性,强制内核在初始化FEC1时启用必要的时钟,避免依赖后续初始化流程:

&fec1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_enet1>, <&pinctrl_enet1_gpio>;
    phy-mode = "rmii";
    phy-handle = <&ethphy0>;
    phy-supply = <&reg_fec_3v3>;
    // 显式指定并启用FEC1的参考时钟、IPG时钟和AHB时钟
    clocks = <&clks IMX6UL_CLK_ENET_REF>, <&clks IMX6UL_CLK_ENET1_IPG>, <&clks IMX6UL_CLK_ENET1_AHB>;
    clock-names = "enet_ref", "ipg", "ahb";
    status = "okay";
};

方法3:增加MDIO扫描延迟,给FEC1时钟启动留足时间

在FEC2的MDIO节点中添加mdio-delay-us属性,增加MDIO扫描时的延迟,确保FEC1的时钟有足够时间完成启动:

&fec2 {
    ...
    mdio {
        #address-cells = <1>;
        #size-cells = <0>;
        mdio-delay-us = <100>; // 增加扫描延迟,单位微秒
        ethphy0: ethernet-phy@0 { ... };
        ethphy1: ethernet-phy@1 { ... };
    };
};

附加信息

原设备树片段

&fec1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_enet1>/*,
                <&pinctrl_enet1_mdio>,
                <&pinctrl_enet1_gpio>*/;
                
    phy-mode = "rmii";
    phy-handle = <&ethphy0>;
    phy-supply = <&reg_fec_3v3>;

    status = "okay";
};

&fec2 {

    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_enet2>, 
                <&pinctrl_enet2_mdio>,
                <&pinctrl_enet1_gpio>,
                <&pinctrl_enet2_gpio>;
                
    phy-mode = "rmii";
    phy-supply = <&reg_fec_3v3>;
    phy-handle = <&ethphy1>;

    status = "okay";

    /*
     * The MDIO bus is shared between ENET1 and ENET2. If you only want
     * to enable ENET1, this node must be moved to fec1 node, and the
     * pinctrl-0 of fec1 must contain the IOMUX for the MDIO bus on ENET1
     * (pintrl_enet1_mdio).
     */
    mdio {
        #address-cells = <1>;
        #size-cells = <0>;

        /* mdio address "0" */
        ethphy0: ethernet-phy@0 {
            compatible = "ethernet-phy-ieee802.3-c22";
            reg = <0>;
            max-speed = <100>;
            clocks = <&clks IMX6UL_CLK_ENET_REF>;
            reset-gpios = <&gpio3 9 GPIO_ACTIVE_LOW>;
            reset-assert-us = <200>;
            reset-deassert-us = <1000>;
            reset-names = "phy-reset1";
        };      

        /* mdio address "1" */
        ethphy1: ethernet-phy@1 {
            compatible = "ethernet-phy-ieee802.3-c22";
            reg = <1>;
            max-speed = <100>;
            clocks = <&clks IMX6UL_CLK_ENET2_REF_125M>;
            reset-gpios = <&gpio3 10 GPIO_ACTIVE_LOW>;
            reset-assert-us = <200>;
            reset-deassert-us = <1000>;
            reset-names = "phy-reset2";
        };
    };  
};

&iomuxc {

    pinctrl_enet1: enet1grp {
        fsl,pins = <
            MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN      0x1b0b0
            MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER      0x1b0b0
            MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0
            MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0
            MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
            MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
            MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN      0x1b0b0
            MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1  0x4001b0a8
        >;
    };

    pinctrl_enet2: enet2grp {
        fsl,pins = <
            MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN      0x1b0b0
            MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER      0x1b0b0
            MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
            MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
            MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0a0
            MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0a0
            MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN      0x1b0b0
            MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2      0x4001b0a8
        >;
    };

    pinctrl_enet2_mdio: mdioenet2grp {
        fsl,pins = <
            /* mdio */
            MX6UL_PAD_GPIO1_IO07__ENET2_MDC     0x1b0b0
            MX6UL_PAD_GPIO1_IO06__ENET2_MDIO    0x1b0b0
        >;
    };

    pinctrl_enet1_gpio: enet1gpiogrp {
        fsl,pins = <
            /* PHY reset */     
            MX6UL_PAD_LCD_DATA04__GPIO3_IO09    0x1b0b0 /* ENET1_RESET */
        >;
    };  

    pinctrl_enet2_gpio: enet2gpiogrp {
        fsl,pins = <
            /* PHY reset */
            MX6UL_PAD_LCD_DATA05__GPIO3_IO10    0x1b0b0 /* ENET2_RESET */
        >;
    };
};

启动日志(精简版)

[    0.000000] Booting Linux on physical CPU 0x0
...
[    0.000000] Kernel command line: bootchooser.active=system0 console=ttymxc0,115200n8   systemd.machine_id=61f6da2724f38d0f1c202fb743ec3557 root=/dev/mmcblk0p3 rauc.slot=system0 rootwait
...
[    3.361074] mdio_bus 20b4000.ethernet-1: MDIO device at address 0 is missing.
[    3.383677] fec 20b4000.ethernet eth0: registered PHC device 0
[    3.408859] pps pps1: new PPS source ptp1
[    4.002064] fec 2188000.ethernet eth1: registered PHC device 1
...
[   20.108429] systemd[1]: Started Network Configuration.
[  OK  ] Started Network Configuration.
[   21.529085] Generic PHY 20b4000.ethernet-1:01: attached PHY driver (mii_bus:phy_addr=20b4000.ethernet-1:01, irq=POLL)
[   21.686217] fec 20b4000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[   21.851450] fec 2188000.ethernet eth1: Unable to connect to phy
[   22.000309] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
...

引脚组输出

user@myboard:~# cat /sys/kernel/debug/pinctrl/20e0000.pinctrl/pingroups
registered pin groups:

...

group: enet2grp
pin 59 (MX6UL_PAD_ENET2_RX_EN)
pin 64 (MX6UL_PAD_ENET2_RX_ER)
pin 57 (MX6UL_PAD_ENET2_RX_DATA0)
pin 58 (MX6UL_PAD_ENET2_RX_DATA1)
pin 60 (MX6UL_PAD_ENET2_TX_DATA0)
pin 61 (MX6UL_PAD_ENET2_TX_DATA1)
pin 62 (MX6UL_PAD_ENET2_TX_EN)
pin 63 (MX6UL_PAD_ENET2_TX_CLK)

group: mdioenet2grp
pin 30 (MX6UL_PAD_GPIO1_IO07)
pin 29 (MX6UL_PAD_GPIO1_IO06)

group: enet1gpiogrp
pin 20 (MX6UL_PAD_JTAG_TDI)

group: enet2gpiogrp
pin 22 (MX6UL_PAD_JTAG_TRST_B)

...

group: enet1grp
pin 51 (MX6UL_PAD_ENET1_RX_EN)
pin 56 (MX6UL_PAD_ENET1_RX_ER)
pin 49 (MX6UL_PAD_ENET1_RX_DATA0)
pin 50 (MX6UL_PAD_ENET1_RX_DATA1)
pin 52 (MX6UL_PAD_ENET1_TX_DATA0)
pin 53 (MX6UL_PAD_ENET1_TX_DATA1)
pin 54 (MX6UL_PAD_ENET1_TX_EN)
pin 55 (MX6UL_PAD_ENET1_TX_CLK)

group: mdioenet1grp
pin 30 (MX6UL_PAD_GPIO1_IO07)
pin 29 (MX6UL_PAD_GPIO1_IO06)

...

内容的提问来源于stack exchange,提问作者RScAut

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 20:58:10