前言
@和原子哥一起学习Linux
开发环境:I.MX6Ull开发板
参考内容:正点原子的驱动开发教程,并完成uboot移植部分,使用自己移植的代码。
一、选择网络初始化函数
board_init_r
initr_net->eth_initialize();
判断调用的哪个文件??
查找net里面的makefile即可
二、通用初始化
eth_common_init()
miiphy_init
——》初始化链表:mii_devs
——》初始化全局参数:current_mii
phy_init();——》此处是开启了CONFIG_PHY_SMSC
phy_smsc_init();
——》注册了4个phy驱动等待进行匹配
驱动内容
genphy_config_aneg
——》传入要操作的设备phy_device
genphy_setup_forced
——》如果关闭了自协商(phydev->autoneg),则按指定双工和速率的数值配置phy_write,否则继续向下
genphy_config_advert
——》读取通用寄存器4、9,获得自动协商的能力,并按照phydev->supported的设置配置能力
——》如果能力值和之前不同则进行复位
genphy_restart_aneg——》启用并重启自动协商
genphy_startup
——》传入要操作的设备phy_device
genphy_update_link
——》移植时增加了对于lan8720的软件复位操作;
link状态没变则不处理;如果开启自协商但是没有协商成功,则等待PHY_ANEG_TIMEOUT,
否则更新phydev->link中的值以反映当前链路的值.
genphy_parse_link
——》更新速度和双工。如果启用了自动协商,它将使用链接伙伴所公布的功能和我们所公布的功能的AND。
如果禁用了自动协商,则在控制寄存器中使用适当的位。
genphy_shutdown——》空函数
board_eth_init
路径:一般为board目录下板子的适配文件中
uboot\board\freescale\mx6ull_my_emmc\mx6ull_my_emmc.c
1)setup_iomux_fec
——》芯片IO复用的配置
——》芯片复位,相当于让PHY解引用
fecmxc_initialize_multi
——》参数1:bd_t:board info数据结构定义,保存板子参数。
——》参数2:CONFIG_FEC_ENET_DEV,选择使用的网络设备。
——》参数3:CONFIG_FEC_MXC_PHYADDR,此网络设备链接的phy地址。
——》参数4:IMX_FEC_BASE,此网络设备的寄存器地址。
mx6_enet_fused——》空函数
fec_get_miibus
mdio_alloc——》申请mii_dev的内存-bus
fec_phy_read、fec_phy_write——》注册bus.read,bus.write函数
fec_set_dev_name——》设置名称为FEC%i-bus->name
mdio_register——》将bus注册到mii_devs列表中
fec_mii_setspeed——》设置MII_SPEED
phy_find_by_mask
bus->reset——》跳过,没有注册
get_phy_device_by_mask
——》先查找自己有没有这个设备,没有则开始创建一个phy设备
create_phy_by_mask
——》读取phyId,若读取到,则创建phy设备
get_phy_driver
——》绑定phy驱动,根据读到的phy_id和drv->uid比较(加mark),读取到的phy_id & drv->mask为7c0f0,则绑定的驱动为之前注册的lan8710_driver
phy_probe(dev);——》如果驱动有probe,会调用此函数
fec_probe
——》创建一个网络设备edev,私有内容为fec_priv
fec_alloc_descs
——》申请对齐的内存为tbd_base,rbd_base描述符
——》申请RX buffer,最多FEC_RBD_NUM,与rbd_base联动
——》注册网络设备的调用函数
——》Reset chip
——》对FEC寄存器进行初始配置
——》绑定phy设备,并调用phy驱动的config和函数配置
——》检查mac地址是否有效
网络注册函数
fec_init
fec_set_hwaddr
——》设置mac地址
——》iaddr对应寄存器ENETx_IAUR,用于接收带有单播地址的帧的地址识别过程
——》gaddr对应寄存器ENETx_GAUR,用于接收带有多播地址的帧的地址识别过程
——》paddr对应寄存器ENETx_PAUR,在暂停帧中精确匹配和源地址字段
fec_tbd_init
——》初始化传输任务的缓冲区描述符
fec_rbd_init
——》初始化接收任务的缓冲区描述符
fec_reg_setup
——》通过配置ENETx_EIMR,用于屏蔽中断
——》通过配置ENETx_EIR,用于清除事件
——》通过配置ENETx_RCR,用于设置最大帧长度,和FEC_RCNTRL_RGMII
——》通过配置ENETx_OPD ,用于配置暂停帧的操作码和暂停时间
——》通过配置ENETx_TFWR ,用于传输FIFO写步长
——》通过配置ENETx_RMON_T_DROP ,用于清空保留寄存器
——》通过配置eth->r_fstart ,用于注册接受fifo
——》通过配置ENETx_MRBR,用于设置有效的最大接收缓冲区大小
——》通过配置ENETx_TDSR,用于指向传输缓冲区描述符队列开头的指针指向tbd_base
——》通过配置ENETx_RDSR,用于指向接受缓冲区描述符队列开头的指针指向rbd_base
miiphy_restart_aneg
——》复位phy,设置自协商位
fec_open
——》启动FEC引擎
——》通过配置ENETx_TCR,用于设置全双工
——》通过fec_rbd_clean初始化rbd_base
——》通过flush_dcache_range刷新描述符在RAM中
——》通过配置ENETx_ECR,用于HW endian SWAP
——》通过配置ENETx_TFWR ,用于store and forward mode
——》Enable FEC-Lite controller
——》disable the gasket | wait for the gasket to be disabled
——》configure gasket for RMII, 50 MHz, no loopback, and no echo
——》re-enable the gasket | wait until MII gasket is ready
——》Start up the PHY
——》Enable SmartDMA receive task
fec_send
——》发送一帧
——》检查帧大小,需要大于0小于1500
——》设置传输缓冲区。总是使用第一个缓冲区进行传输,第二个缓冲区将为空,只用于停止DMA引擎。还将包刷新到RAM中以避免缓存问题。
——》现在更新BD的状态
——》刷新数据缓存。这段代码将两个TX描述符都刷新到RAM。
——》读取DMA描述符的最后四个字节DRAM
——》开启SmartDMA传输任务功能 | 等待直到帧被发送。
fec_recv
——》读出一帧
——》检查是否发生了任何关键事件 | 并处理
——》在读取状态之前,必须使数据缓存失效,因为RAM中的数据可能已经被DMA更改了。
——》获取缓冲区地址和大小
——》在缓冲区上使数据缓存失效
——》填充缓冲区并将其传递给上层
——》释放当前缓冲区,重新启动引擎并向前移动到下一个缓冲区
fec_halt
——》停止FEC引擎
fec_set_hwaddr
——》见fec_init的第一个函数