imx6ull-u-boot网络移植

修改网口配置信息

主要修改设备树的信息,设备树位于:arch/arm/dts/imx6ul-14x14-evk.dtsi

硬件电路图

网口原理图

修改fec2信息

未修改前的信息如下:
fec2原本

修改网口1器件的ID信息,网口1使用的ID是0

 &fec2 {
     pinctrl-names = "default";
     pinctrl-0 = <&pinctrl_enet2>;
     phy-mode = "rmii";
     phy-handle = <&ethphy1>;
     status = "okay";
 
     mdio {
         #address-cells = <1>;
         #size-cells = <0>;
        /* 网口1的设备ID是0设置为@0 */
        ethphy0: ethernet-phy@0 {
            /* reg的值要修改为0 */
            reg = <0>;
            micrel,led-mode = <1>;
            clocks = <&clks IMX6UL_CLK_ENET_REF>;
            clock-names = "rmii-ref";
        };

        ethphy1: ethernet-phy@1 {
            reg = <1>;
            micrel,led-mode = <1>;
            clocks = <&clks IMX6UL_CLK_ENET2_REF>;
            clock-names = "rmii-ref";
        };
    };
};

IO信息修改

注释掉SPI4的引脚信息

从上面的原理图可知网口1使用的复位引脚是GPIO5_IO07,网口2使用的复位引脚是GPIO5_IO08,在官网的u-boot里面这两个引脚被用于SPI4,所以我们需要去注释掉他,位置如下图所示:
SPI4设备树位置

修改如下:

pinctrl_spi4: spi4grp {
         fsl,pins = <
             MX6UL_PAD_BOOT_MODE0__GPIO5_IO10    0x70a1
             MX6UL_PAD_BOOT_MODE1__GPIO5_IO11    0x70a1
             /* 直接注释掉 */
             /* MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07   0x70a1
             MX6UL_PAD_SNVS_TAMPER8__GPIO5_IO08  0x80000000 */
         >;
};

还需要把SPI4修改的设备树信息进行修改,位置如下:
SPI4设备树的信息

修改如下:

spi4 {
    compatible = "spi-gpio";
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_spi4>;
    status = "okay";
    /* 注释掉GPIO5_IO08相关的信息 */
    /* pinctrl-assert-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>; */
    gpio-sck = <&gpio5 11 0>;
    gpio-mosi = <&gpio5 10 0>;
    /* 注释掉GPIO5_IO07相关的信息 */
    /* cs-gpios = <&gpio5 7 0>; */
    num-chipselects = <1>;
    #address-cells = <1>;
    #size-cells = <0>;

    gpio_spi: gpio@0 {
        compatible = "fairchild,74hc595";
        gpio-controller;
        #gpio-cells = <2>;
        reg = <0>;
        registers-number = <1>;
        registers-default = /bits/ 8 <0x57>;
        spi-max-frequency = <100000>;
    };
};

修改网口TX时钟的电器属性值

修改的位置如下:
网口时钟引脚的电器属性值
需要把0x4001b031修改为:0x4001b009
修改结果如下:

     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_EN__ENET1_TX_EN  0x1b0b0
             MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
             MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
             /* 0x4001b031修改为0x4001b009 */
             MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1  0x4001b009
         >;
     };

     pinctrl_enet2: enet2grp {
         fsl,pins = <
             MX6UL_PAD_GPIO1_IO07__ENET2_MDC     0x1b0b0
             MX6UL_PAD_GPIO1_IO06__ENET2_MDIO    0x1b0b0
             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_EN__ENET2_TX_EN  0x1b0b0
             MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
             MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
             /* 0x4001b031修改为0x4001b009 */
             MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2  0x4001b009
         >;
     };

增加网口复位引脚的信息

引脚复位信息增加在下面的位置,如下:

网口复位引脚信息
下面是相关代码段,可以直接复制:

     pinctrl_enet1_reset: enet1resetgrp {
         fsl,pins = <
             MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x10B0
         >;
     };
     pinctrl_enet2_reset: enet2resetgrp {
         fsl,pins = <
             MX6UL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x10B0
         >;
     };

为网口的信息增加pinctrl信息

需要修改的位置如下:
网口设备树的信息

修改后的信息如下:

&fec1 {
    pinctrl-names = "default";
    /* 增加pinctrl_enet1_reset */
    pinctrl-0 = <&pinctrl_enet1 &pinctrl_enet1_reset>;
    phy-mode = "rmii";
    phy-handle = <&ethphy0>;
    /* 设置复位有效电平和持续时间 */
    phy-reset-gpios = <&gpio5 7 GPIO_ACTIVE_LOW>;
    phy-rest-duration = <200>;
    status = "okay";
};
&fec2 {
    pinctrl-names = "default";
    /* 增加pinctrl_enet2_reset */
    pinctrl-0 = <&pinctrl_enet2 &pinctrl_enet2_reset>;
    phy-mode = "rmii";
    phy-handle = <&ethphy1>;
    /* 设置复位有效电平和持续时间 */
    phy-reset-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
    phy-rest-duration = <200>;
    status = "okay";
    mdio {
        #address-cells = <1>;
        #size-cells = <0>;
        ethphy0: ethernet-phy@0 {
            reg = <0>;
            /* 增加当前的PHY为smsc */
            smsc,led-mode = <1>;
            clocks = <&clks IMX6UL_CLK_ENET_REF>;
            clock-names = "rmii-ref";

        };
        ethphy1: ethernet-phy@1 {
            reg = <1>;
            /* 增加当前的PHY为smsc */
            smsc,led-mode = <1>;
            clocks = <&clks IMX6UL_CLK_ENET2_REF>;
            clock-names = "rmii-ref";
        };
    };
};

增加SMSC系列的芯片的支持

make menuconfig

#-> Networking support 
#   -> Search (SMSC) 
#       -> Ethernet PHY (physical media interface) support
#           -> Microchip(SMSC) Ethernet PHYs support

选择Microchip(SMSC) Ethernet PHYs support修改配置
menuconfig_SMSC

重新编译烧录验证

export CROSS_COMPILE=arm-buildroot-linux-gnueabihf-
export ARCH=arm
make -j4
#烧录
sudo dd iflag=dsync oflag=dsync if=u-boot-dtb.imx bs=1k of=/dev/sdb seek=1

在板子上进行验证如下

在板子上启动可能会出现如下错误信息,这个信息是没有配置网口的地址导致的,下面进行配置即可:

Net:   Could not get PHY for FEC1: addr 1

Error: ethernet@20b4000 address not set.

Error: ethernet@20b4000 address not set.

Error: ethernet@20b4000 address not set.
Could not get PHY for FEC0: addr 0

Error: ethernet@20b4000 address not set.

Error: ethernet@20b4000 address not set.
Could not get PHY for FEC0: addr 0
No ethernet found.

u-boot默认使用网口2,我使用路由器与板子相连,板子的网关地址为192.168.2.1,先配置网络信息如下:

setenv ipaddr 192.168.2.230
setenv ethaddr 00:04:9f:04:d2:35
setenv eth1addr 00:04:9f:04:d2:36
setenv gatewayip 192.168.2.1
setenv netmask 255.255.255.0
saveenv

进行ping路由器

结果如下:

ping 192.168.2.1
Get shared mii bus on ethernet@2188000
ethernet@20b4000 Waiting for PHY auto negotiation to complete.... done
Using ethernet@20b4000 device

ARP Retry count exceeded; starting again
ping failed; host 192.168.2.1 is not alive

是由于PHY复位失败,所以需要修改drivers/net/phy/phy.c的genphy_config_aneg函数代码,位置如下:
genphy_config_aneg位置
修改结果如下:

int genphy_config_aneg(struct phy_device *phydev)
{
    int result;
    /* 新增加这条复位代码 */
    phy_reset(phydev);
    if (phydev->autoneg != AUTONEG_ENABLE)
        return genphy_setup_forced(phydev);

    result = genphy_config_advert(phydev);

    if (result < 0) /* error */
        return result;

    if (result == 0) {
        /*
         * Advertisment hasn't changed, but maybe aneg was never on to
         * begin with?  Or maybe phy was isolated?
         */
        int ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);

        if (ctl < 0)
            return ctl;

        if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE))
            result = 1; /* do restart aneg */
    }

    /*
     * Only restart aneg if we are advertising something different
     * than we were before.
     */
    if (result > 0)
        result = genphy_restart_aneg(phydev);

    return result;
}

重新执行上面的编译和烧录工作,最后得到的正确结果

ping 192.168.2.1
Get shared mii bus on ethernet@2188000
ethernet@20b4000 Waiting for PHY auto negotiation to complete.................................... done
Using ethernet@20b4000 device
host 192.168.2.1 is alive

其它

自动配置ethaddr地址

如果未配置ethaddr地址时使用随机数作为ethaddr地址

make menuconfig

# 选择的位置
#->Networking support
#   ->Random ethaddr if unset

动获取MAC地址

u-boot卡死网络解决方式

#u-boot启动时卡死的位置
eth1: ethernet@20b4000 [PRIME]Get shared mii bus on ethernet@2188000

解决方法:
在./drivers/net/phy/phy.c文件的phy_connect函数增加一个延迟函数。
函数所在位置如下:

phy_connect位置

修改如下:

#ifdef CONFIG_DM_ETH
struct phy_device *phy_connect(struct mii_dev *bus, int addr,
                   struct udevice *dev,
                   phy_interface_t interface)
#else
struct phy_device *phy_connect(struct mii_dev *bus, int addr,
                   struct eth_device *dev,
                   phy_interface_t interface)
#endif
{
    struct phy_device *phydev = NULL;
    uint mask = (addr >= 0) ? (1 << addr) : 0xffffffff;
    /* 增加一个延迟 */
    mdelay(100);

#ifdef CONFIG_PHY_FIXED
    phydev = phy_connect_fixed(bus, dev, interface);
#endif

#ifdef CONFIG_PHY_NCSI
    if (!phydev)
        phydev = phy_device_create(bus, 0, PHY_NCSI_ID, false, interface);
#endif

#ifdef CONFIG_PHY_XILINX_GMII2RGMII
    if (!phydev)
        phydev = phy_connect_gmii2rgmii(bus, dev, interface);
#endif

    if (!phydev)
        phydev = phy_find_by_mask(bus, mask, interface);

    if (phydev)
        phy_connect_dev(phydev, dev);
    else
        printf("Could not get PHY for %s: addr %d\n", bus->name, addr);
    return phydev;
}

posted @ 2024-05-14 20:16  其实我只是懒  阅读(152)  评论(0编辑  收藏  举报