移植NXP官方uboot-imx-imx_v2020.04_5.4.70_2.3.0到阿尔法开发板(三)修改网络驱动

1. NXP官方I.MX6ULL EVK开发板和ALIENTEK-ALPHA开发板ENET1和ENET2网络接口对照表

NXP官方i.MX6ULL EVK开发板和ALIENTEK-ALPHA开发板ENET1和ENET2网络PHY芯片引脚连接对照表如下图所示:
在这里插入图片描述
  由上图可知NXP官方i.MX6ULL EVK开发板和ALIENTEK-ALPHA开发板ENET1和ENET2网络PHY芯片的复位引脚不同,其余引脚相同,NXP官方EVK开发板网络PHY芯片复位引脚是通过74LV595扩展而来,而ALIENTEK-ALPHA开发板网络PHY芯片复位引脚连接到I.M6ULL的SNVS_TAMPER7和SNVS_TAMPER8引脚。

2. 修改uboot网络设备节点信息

2.1 屏蔽uboot中SPI4节点信息(74LV595芯片驱动)

打开arch/arm/dts目录下imx6ul-alientek.dtsi文件,屏蔽关于spi4的描述信息,屏蔽的代码如下所示:

/*屏蔽NXP官方I.MX6ULL EVK开发板74LV595相关驱动 20240313*/
	/*
		aliases {
			spi5 = &{/spi4};
		};
	*/
/*屏蔽NXP官方I.MX6ULL EVK开发板74LV595相关驱动 20240313*/
/*
	spi4 {
		compatible = "spi-gpio";
		pinctrl-names = "default";
		pinctrl-0 = <&pinctrl_spi4>;
		status = "okay";
		//pinctrl-assert-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
		//gpio-sck = <&gpio5 11 0>;
		//gpio-mosi = <&gpio5 10 0>;
		//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>;
		};
	};
	*/
/*屏蔽NXP官方74LV595相关控制引脚配置项20240313*/
/*
    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节点信息的描述。

2.2 增加ENET1和ENET2网络PHY芯片复位引脚配置项

  打开arch/arm/dts目录下imx6ul-alientek.dtsi文件,找到iomuxc节点在ENET1和ENET2网络PHY芯片控制引脚配置项pinctrl_enet1
pinctrl_enet2
中增加复位引脚配置项,如下所示:

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
            MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1  0x4001b031
            /*增加ENET1网络PHY芯片的复位使用引脚配置功能*/
            MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07 0X10B0
        >;
    };
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
            MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2  0x4001b031
            /*增加ENET2网络PHY芯片的复位使用引脚配置功能*/
            MX6UL_PAD_SNVS_TAMPER8__GPIO5_IO08 0X10B0
        >;
    };

2.3 修改fec1和fec2节点信息

打开arch/arm/dts目录下imx6ul-alientek.dtsi文件,找到fec1fec2节点,修改网络节点信息,fec1节点信息修改如下所示:

&fec1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_enet1>;
    phy-mode = "rmii";
    phy-handle = <&ethphy0>;
    phy-reset-gpios = <&gpio5 7 GPIO_ACTIVE_LOW>; /*PHY芯片复位引脚电平低电平有效*/
    phy-reset-duration = <200>;                   /*低电平持续时间200ms*/
    status = "okay";
};

fec2节点信息修改如下所示:

&fec2 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_enet2>;
    phy-mode = "rmii";
    phy-handle = <&ethphy1>;
    phy-reset-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>; /*PHY芯片复位引脚电平低电平有效*/
    phy-reset-duration = <200>;                   /*低电平持续时间200ms*/
    status = "okay";

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

        /*修改ENET1网络PHY芯片地址*/
        ethphy0: ethernet-phy@0 {
            reg = <0>;             /*PHY芯片地址*/
            micrel,led-mode = <1>;
            clocks = <&clks IMX6UL_CLK_ENET_REF>;
            smsc,disable-energy-detect;   /*表明PHY芯片是SMSC公司*/
            clock-names = "rmii-ref";
        };

        /*修改ENET2网络PHY芯片地址*/
        ethphy1: ethernet-phy@1 {
            reg = <1>;                   /*PHY芯片地址*/
            micrel,led-mode = <1>;
            clocks = <&clks IMX6UL_CLK_ENET2_REF>;
            smsc,disable-energy-detect;   /*表明PHY芯片是SMSC公司*/
            clock-names = "rmii-ref";
        };
    };
};

phy-reset-gpios:指定phy的复位引脚且为拉低复位
phy-reset-duration:指定复位的持续时间
ethphy0: ethernet-phy@0:这里的0表示的是phy1的地址为0
ethphy1: ethernet-phy@1:这里的1表示的是phy2的地址为1
reg的值同样表示phy的地址。

3. 对LAN8720芯片进行软复位

  LAN8720芯片正常工作需要同时进行硬件复位和软件复位操作,硬件复位操作已在设备树中设置过了,软件复位操作需要在drivers/net/phy/phy.c文件中genphy_update_link()函数中实现。打开drivers/net/phy/phy.c找到函数genphy_update_link,这个函数为PHY驱动函数,此函数用于更新PHY的连接状态和速度。在此函数中增加LAN8720A软件复位操作,修改后的genphy_update_link函数如下所示:

/**
 * genphy_update_link - update link status in @phydev
 * @phydev: target phy_device struct
 *
 * Description: Update the value in phydev->link to reflect the
 *   current link value.  In order to do this, we need to read
 *   the status register twice, keeping the second value.
 */
int genphy_update_link(struct phy_device *phydev)
{
    unsigned int mii_reg;

    static int lan8720_flag = 0;
    int bmcr_reg = 0;
    if (lan8720_flag == 0) {
        bmcr_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
        phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
        while(phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR) & 0X8000) {
            udelay(100);
        }
        phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, bmcr_reg);
        lan8720_flag = 1;
    }

   /*
     * Wait if the link is up, and autonegotiation is in progress
     * (ie - we're capable and it's not done)
     */
mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);

    /*
     * If we already saw the link up, and it hasn't gone down, then
     * we don't need to wait for autoneg again
     */
    if (phydev->link && mii_reg & BMSR_LSTATUS)
        return 0;

    if ((phydev->autoneg == AUTONEG_ENABLE) &&
        !(mii_reg & BMSR_ANEGCOMPLETE)) {
        int i = 0;

        printf("%s Waiting for PHY auto negotiation to complete",
               phydev->dev->name);
        while (!(mii_reg & BMSR_ANEGCOMPLETE)) {
            /*
             * Timeout reached ?
             */
            if (i > (PHY_ANEG_TIMEOUT / 50)) {
                printf(" TIMEOUT !\n");
                phydev->link = 0;
                return -ETIMEDOUT;
            }

            if (ctrlc()) {
                puts("user interrupt!\n");
                phydev->link = 0;
                return -EINTR;
            }

            if ((i++ % 10) == 0)
                printf(".");

            mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
            mdelay(50); /* 50 ms */
        }
        printf(" done\n");
        phydev->link = 1;
    } else {
        /* Read the link a second time to clear the latched state */
        mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);

        if (mii_reg & BMSR_LSTATUS)
            phydev->link = 1;
        else
            phydev->link = 0;
}

    return 0;
}

4. 使能SMSC公司PHY芯片驱动

输入命令“make menuconfig”,打开图形化配置界面,使能SMSC公司PHY芯片驱动,路径如下:
-> Device Drivers
  -> Ethernet PHY(physical media interface)support
    -> Microchip(SMSC) Ethernet PHYs support

在这里插入图片描述
在这里插入图片描述
  上图中选择将“Microchip(SMSC) Ethernet PHYs support”编译到uboot源码中,因此“<>”里面变成了“*”。LAN8720是SMSC公司产品,因此勾选这个就会编译LAN8720驱动,配置完成后点击保存配置按键后推出配置界面,重新编译uboot源码。

5. 测试uboot

5.1 将配置完成uboot重新编译,编译过程如下图所示:

在这里插入图片描述
在这里插入图片描述

5.2 烧写u-boot.bin文件到SD卡

使用正点原子imxdownload软件将编译的u-boot.bin文件烧录到SD卡中,如下图所示:
在这里插入图片描述

5.3 测试uboot

将SD卡插入ALIENTEK-ALPHA开发板SD卡槽,打开SecureCRT 软件,开发板上电,SecureCRT 软件接收到的信息如下图所示:
在这里插入图片描述
uboot中手动设置MAC地址,设置命令如下:
在这里插入图片描述
其中ethaddr是指定eth0的,eth1addr是指定eth1的。
设置ALIENTEK-ALPHA开发板ip地址、网关、掩码、ubuntu的IP地址、保存环境变量,设置完这环境变量后就可以使用ping命令来测试网卡是否驱动成功了。
在这里插入图片描述
使用ping命令ping Ubuntu主机,测试结果如下图所示:
在这里插入图片描述

  • 19
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值