一. 简介
本文继续学习 NXP官方Linux内核移植网络驱动的更改。
在学习 uboot 移植的时候就已经说过了,正点原子开发板的网络和 NXP 官方的网络硬件上不同,网络 PHY 芯片由 KSZ8081 换为了 LAN8720A,两个网络 PHY 芯片的复位 IO 也不同。 所以,Linux 内核自带的网络驱动是驱动不起来 I.MX6U-ALPHA 开发板上的网络的,需要做修改。
本文继上一篇文章的学习,文章地址如下:
二. Linux内核移植之网络驱动更改
之前网络驱动更改中,修改网络复位IO和PHY 地址以后,Linux 内核内部通用 PHY驱动已经正常工作。上一篇文章已经可以 ping通 ubuntu系统了。
但是,正点原子视频学习中,左神说网络可能还会存在问题,还需要做网络其他方面的更改。
这里在之前更改的基础上,再进行网络驱动其他方面的更改。具体如下:
4. 修改 fec_main.c 文件
static int fec_probe(struct platform_device *pdev)
{
struct fec_enet_private *fep;
struct fec_platform_data *pdata;
struct net_device *ndev;
int i, irq, ret = 0;
struct resource *r;
const struct of_device_id *of_id;
static int dev_id;
struct device_node *np = pdev->dev.of_node, *phy_node;
int num_tx_qs;
int num_rx_qs;
/* zuozhongkai 2019/2/20 设置MX6UL_PAD_ENET1_TX_CLK和
* MX6UL_PAD_ENET2_TX_CLK这两个IO的复用寄存器的SION位
* 为1。
*/
void __iomem *IMX6U_ENET1_TX_CLK;
void __iomem *IMX6U_ENET2_TX_CLK;
IMX6U_ENET1_TX_CLK = ioremap(0X020E00DC, 4);
writel(0X14, IMX6U_ENET1_TX_CLK);
IMX6U_ENET2_TX_CLK = ioremap(0X020E00FC, 4);
writel(0X14, IMX6U_ENET2_TX_CLK);
...........................................
return 0;
}
第18行 ~ 第 25行,是新添加的代码,如果要在 I.MX6ULL 上使用 LAN8720A 就需要设置 ENET1 和 ENET2 的 TX_CLK 引脚复位寄存器的 SION 位为 1。
参考 IMX6ULL参考手册,TX_CLK寄存器的 SION位如下:
5. 修改 smsc.c 文件
正点原子文档中,左神的说明:
static int smsc_phy_reset(struct phy_device *phydev)
{
int err, phy_reset;
int msec = 1;
struct device_node *np;
int timeout = 50000;
if(phydev->addr == 0) /* FEC1 */
{
np = of_find_node_by_path("/soc/aips-bus@02100000/ethernet@02188000");
if(np == NULL) {
return -EINVAL;
}
}
if(phydev->addr == 1) /* FEC2 */
{
np = of_find_node_by_path("/soc/aips-bus@02000000/ethernet@020b4000");
if(np == NULL) {
return -EINVAL;
}
}
err = of_property_read_u32(np, "phy-reset-duration", &msec);
/* A sane reset duration should not be longer than 1s */
if (!err && msec > 1000)
msec = 1;
phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0);
if (!gpio_is_valid(phy_reset))
// return;
gpio_free(phy_reset);
gpio_direction_output(phy_reset, 0);
gpio_set_value(phy_reset, 0);
msleep(msec);
gpio_set_value(phy_reset, 1);
int rc = phy_read(phydev, MII_LAN83C185_SPECIAL_MODES);
if (rc < 0)
return rc;
/* If the SMSC PHY is in power down mode, then set it
* in all capable mode before using it.
*/
if ((rc & MII_LAN83C185_MODE_MASK) == MII_LAN83C185_MODE_POWERDOWN) {
/* set "all capable" mode and reset the phy */
rc |= MII_LAN83C185_MODE_ALL;
phy_write(phydev, MII_LAN83C185_SPECIAL_MODES, rc);
}
phy_write(phydev, MII_BMCR, BMCR_RESET);
/* wait end of reset (max 500 ms) */
do {
udelay(10);
if (timeout-- == 0)
return -1;
rc = phy_read(phydev, MII_BMCR);
} while (rc & BMCR_RESET);
return 0;
}
6. 配置 Linux 内核,使能 LAN8720 驱动
-> Device Drivers-> Network device support-> PHY Device support and infrastructure-> Drivers for SMSC PHYs
选中 "Driver for SMSC PHYs" 选项,如下:
选择 "Driver for SMSC PHYs" 选项后,进行保存。
三. 网络驱动测试
开发板重新上电后,就会重新下载上面新编译的 zImage与 imx6ull-alientek-nand.dtb设备树文件。
注意:确认 zImage的编译时间是否是最新的!!!
开发板正常启动到根文件系统项,进入根文件系统的根目录下。如下:
Running local boot scripts (/etc/rc.local).
root@ATK-IMX6U:~# icm20608: version magic '4.1.15-g19f085b-dirty SMP preempt mod_unload modversions ARMv7 p2v8 ' should be '4.1.15 SMP preempt mod_unload modversions ARMv6 p2v8 '
root@ATK-IMX6U:~#
1. 查看开发板上的所有网卡,输入 "ifconfig" 命令查看:
root@ATK-IMX6U:~# ifconfig
eth0 Link encap:Ethernet HWaddr 88:9f:ed:ad:10:d1
inet addr:169.254.200.201 Bcast:169.254.255.255 Mask:255.255.0.0
inet6 addr: fe80::8a9f:edff:fead:10d1/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:75 errors:0 dropped:0 overruns:0 frame:0
TX packets:48 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:5817 (5.6 KiB) TX bytes:10902 (10.6 KiB)
eth1 Link encap:Ethernet HWaddr 88:e5:e1:37:af:b5
UP BROADCAST MULTICAST DYNAMIC MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:22 errors:0 dropped:0 overruns:0 frame:0
TX packets:22 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1340 (1.3 KiB) TX bytes:1340 (1.3 KiB)
root@ATK-IMX6U:~# ifconfig eth0 192.168.1.50
root@ATK-IMX6U:~# ifconfig
eth0 Link encap:Ethernet HWaddr 88:9f:ed:ad:10:d1
inet addr:192.168.1.50 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::8a9f:edff:fead:10d1/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:228 errors:0 dropped:0 overruns:0 frame:0
TX packets:224 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:19328 (18.8 KiB) TX bytes:106747 (104.2 KiB)
.................................
3. 使用 “ping” 命令来 ping 一下自己的主机,如果能 ping 通那说明网络驱动修改成功!我的 Ubuntu 主机 IP 地址为 192.168.1.66,操作如下:
root@ATK-IMX6U:~# ping 192.168.1.66
PING 192.168.1.66 (192.168.1.66) 56(84) bytes of data.
64 bytes from 192.168.1.66: icmp_seq=1 ttl=64 time=0.977 ms
64 bytes from 192.168.1.66: icmp_seq=2 ttl=64 time=1.35 ms
64 bytes from 192.168.1.66: icmp_seq=3 ttl=64 time=0.990 ms
64 bytes from 192.168.1.66: icmp_seq=4 ttl=64 time=1.03 ms