imx6ull-u-boot网络移植
修改网口配置信息
主要修改设备树的信息,设备树位于:arch/arm/dts/imx6ul-14x14-evk.dtsi
硬件电路图
修改fec2信息
未修改前的信息如下:
修改网口1器件的ID信息,网口1使用的ID是0
&fec2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet2>;
phy-mode = "rmii";
phy-handle = <ðphy1>;
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,所以我们需要去注释掉他,位置如下图所示:
修改如下:
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 {
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 = <ðphy0>;
/* 设置复位有效电平和持续时间 */
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 = <ðphy1>;
/* 设置复位有效电平和持续时间 */
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修改配置
重新编译烧录验证
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函数代码,位置如下:
修改结果如下:
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
u-boot卡死网络解决方式
#u-boot启动时卡死的位置
eth1: ethernet@20b4000 [PRIME]Get shared mii bus on ethernet@2188000
解决方法:
在./drivers/net/phy/phy.c文件的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;
}