目录
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文件,找到fec1和fec2节点,修改网络节点信息,fec1节点信息修改如下所示:
&fec1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet1>;
phy-mode = "rmii";
phy-handle = <ðphy0>;
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 = <ðphy1>;
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主机,测试结果如下图所示: