文章目录
一、网络简介
💦I.MX6UL/ULL 内部有个以太网 MAC 外设,也就是 ENET,需要外接一个 PHY 芯片来实现网络通信功能,也就是内部 MAC+外部 PHY 芯片的方案。
💦大家可能听过 DM9000 这个网络芯片,在一些没有内部 MAC 的 CPU 中,比如三星的 2440,4412 等,就会采用 DM9000 来实现联网功能。DM9000 提供了一个类似 SRAM 的访问接口,主控 CPU 通过这个接口即可与DM9000 进行通信,DM9000 就是一个 MAC+PHY 芯片。这个方案就相当于外部 MAC+外部PHY。
💦I.MX6U 这样的内部 MAC+PHY 芯片与 DM9000 方案比有什么优势吗?、
💦优势就是通信效率和速度,一般 SOC 内部的 MAC 是带有一个专用 DMA 的,专门用于处理网络数据包,采用 SRAM 来读写 DM9000 的速度是压根就没法和内部 MAC+外部 PHY 芯片的速度比。
💦I.MX6UL/ULL 有两个网络接口 ENET1 和 ENET2, I.MX6U-ALPHA 开发板提供了这两个网络接口,其中 ENET1 和 ENET2 都使用 LAN8720A 作为 PHY 芯片。
💦NXP 官方的I.MX6ULL EVK 开发板使用 KSZ8081 这颗 PHY 芯片,LAN8720A 相比 KSZ8081 具有体积小、外围器件少、价格便宜等优点。所以需要修改网络驱动来适配LAN8720A 。
💦ENET1原理图如下:
💦LAN8720A 状态判断
I.MX6ULL 会读取 LAN8720 内部寄存器来判断当前的物理链接状态、连接速度(10M 还是 100M)和双工状态(半双工还是全双工)。
💦通讯方式
I.MX6ULL 通过 MDIO接口来读取 PHY 芯片的内部寄存器,MDIO 接口有两个引脚,ENET_MDC 和 ENET_MDIO,ENET_MDC 提供时钟,ENET_MDIO 进行数据传输。一个 MDIO 接口可以管理 32 个 PHY 芯片,同一个 MDIO 接口下的这些 PHY 使用不同的器件地址来做区分,MIDO 接口通过不同的器件地址即可访问到相应的 PHY 芯片。
💦I.MX6U-ALPHA 开发板 ENET1 上连接的 LAN8720A器件地址为 0X0,所示我们要修改 ENET1 网络驱动的话重点就三点:
①、ENET1 复位引脚初始化。
②、LAN8720A 的器件 ID。
③、LAN8720 驱动
💦ENET2原理图如下:
💦关于 ENET2 网络驱动的修改也注意一下三点:
①、ENET2 的复位引脚,ENET2 的复位引脚 ENET2_RST 接到了I.MX6ULL 的SNVS_TAMPER8 上。
②、ENET2 所使用的 PHY 芯片器件地址,PHY 器件地址为 0X1。
③、LAN8720 驱动,ENET1 和 ENET2 都使用的 LAN8720,所以驱动肯定是一样的。
二、修改PHY芯片地址
💦修改 uboot 中的 ENET1 和 ENET2 的 PHY 地址和驱动,打开 mx6ull_alientek_emmc.h这个文件,找到如下代码:
💦未修改时如下:
💦修改后如下:
三、删除 uboot 中 74LV595 的驱动代码
💦原因:75LV595是官方用来控制PHY复位的芯片,在开发板上,是使用IO直接控制的,所以将跟75LV595芯片相关的代码删除。
1.删除宏定义,添加ENET1和ENET2复位引脚,宏定义
💦ENET1 的复位引脚连接到 SNVS_TAMPER7 上,对应 GPIO5_IO07,ENET2 的复位引脚连接到 SNVS_TAMPER8 上,对应 GPIO5_IO08。
2.删除内容如下
💦是 74LV595 的 IO 配置参数结构体,将其删除掉。
💦在mx6ull_alientek_emmc.c 中找到函数 iox74lv_init
💦iox74lv_init 函数是 74LV595 的初始化函数,iox74lv_set 函数用于控制 74LV595 的 IO 输出电平,将这两个函数全部删除掉!
💦在 mx6ull_alientek_emmc.c 中找到 board_init 函数,此函数是板子初始化函数,会被board_init_r 调用,board_init 函数内容如下:
💦board_init 会调用 imx_iomux_v3_setup_multiple_pads 和 iox74lv_init 这两个函数来初始化74lv595 的 GPIO,将这两行删除掉。
四、添加 I.MX6U-ALPHA 开发板网络复位引脚驱动
💦结构体数组 fec1_pads 和 fec2_pads 是 ENET1 和 ENET2 这两个网口的 IO 配置参数,在这两个数组中添加两个网口的复位 IO 配置参数
💦函数 setup_iomux_fec 就是根据 fec1_pads 和 fec2_pads 这两个网络 IO 配置数组来初始化I.MX6ULL 的网络 IO。我们需要在其中添加网络复位 IO 的初始化代码,并且复位一下 PHY 芯片,修改后的 setup_iomux_fec 函数如下:
💦修改 drivers/net/phy/phy.c 文件中的函数 genphy_update_link
uboot 中的 LAN8720A 驱动有点问题,打开文件drivers/net/phy/phy.c,找到函数 genphy_update_link,这是个通用 PHY 驱动函数,此函数用于更新 PHY 的连接状态和速度。使用 LAN8720A 的时候需要在此函数中添加一些代码,修改后的函数 genphy_update_link 如下所示:
💦读取LAN8720A 的 BMCR 寄存器(寄存器地址为 0),此寄存器为 LAN8720A 的配置寄存器,这里先读取此寄存器的默认值并保存起来。向寄存器 BMCR 寄存器写入 BMCR_RESET(值为0X8000),因为 BMCR 的 bit15 是软件复位控制位,复位完成以后此位会自动清零。等待 LAN8720A 软件复位完成,也就是判断 BMCR的 bit15 位是否为 1,为 1 的话表示还没有复位完成。重新向 BMCR 寄存器写入以前的值, 一开始读出的那个值。