完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
PHY设备驱动分析
MAC和PHY可能是集成在CPU中可能独立,下图介绍典型的MAC集成,PHY独立。两者搭配实现网卡功能。 Mdio设备注册到总线 文件路径:driversnetethernettidavinci_mdio.c device_initcall(davinci_mdio_init); –》 davinci_mdio_init –》platform_driver_register(&davinci_mdio_driver); davinci_mdio_probe –》 mdiobus_regist Phy设备初始化: Linux内核通过mdio总线访问、控制PHY , phy_device的注册不依靠设备树(根据上面驱动的名字在设备树中搜不到),该设备的注册在MDIO驱动中调用mdiobus_register中会注册phy_device 文件路径:driversnetphymdio_bus.c –》 mdiobus_register /* register the mii bus */ –》 device_register –》 mdiobus_scan /这个过程就是根据phy id通过mdio的mdiobus_read去读phy芯片的寄存器来检测改id下的phy设备是否存在,如果存在就把该设备使用phy_device_register注册/ –》 get_phy_device –》 get_phy_id // 读寄存器 –》 phy_device_create // 创建phy设备,创建phy设备时会设置phy的接口,例如PHY_INTERFACE_MODE_GMII,以及从总线上扫描到的设备的信息赋值给phy设备 –》 INIT_DELAYED_WORK(&dev-》state_queue, phy_state_machine); // !!!初始化状态机函数 –》 phy_device_register 在phy_device_create 时会使用mdio_bus_type这个结构体,里面有个匹配函数具体如下 Phy驱动注册: 状态机 phy状态变化主要在phy_state_machine函数,该函数一直在运行(每隔一秒检测一次网络状态),该函数判断不同的网络状态作出不同的动作。其中CHANGELINK是会根据网络连、断来判断是RUNNING还是NOLINK。这样,就知道网络是连接上还是断开。当连接上网络后(注:不断开情况),状态为RUNNING时,之后重新赋值CHANGELINK,到了CHANGELINK又赋值RUNNING,这两种状态之间不断切换。完整代码如下: PHY状态变化规律 上电时状态变化: PHY_READY -》 PHY_UP -》 PHY_AN -》 PHY_RUNNING 拨出网线时状态变化: PHY_RUNNING -》PHY_NOLINK 插上网线时状态变化: PHY_NOLINK -》 PHY_RUNNING 自动协商过程: cpsw_ndo_open-》cpsw_slave_open -》 PHY_UP -》 phy_start_aneg -》 genphy_config_aneg -》 genphy_config_advert -》 genphy_restart_aneg -》 PHY_AN -》 PHY_NOLINK(串口打印Down) -》 phy_aneg_done -》 PHY_RUNNING(串口打印Up) 注:在AN后出现NOLINK状态,我猜是因为自动协商需要时间,此时间大于1秒,然后执行到状态机判断成NOLINK,然后判断是否完成自动协商,然后再到RUNNING状态。 注意: 调用phy_driver_register去注册驱动,这是phy驱动也会形成一个链表,这里之所以不是树而上面的设备成为树,是因为mii可能挂载在pci总线上,当然pci上可能有其它设备,这些设备和phy设备不在一个链表上,而是通过kobject链接管理的,对应的还有一个kset,kset其实是kobject的一个集合,相同的kobject对象会指向同一个kset,如USB鼠标、键盘就属于同一个kset集。上述的总线,设备,以及驱动(假设驱动已经编写好了,驱动中多半会有一个标示符,暂且将其看作为id,这个id指明了其支持的设备)内;假设不支持热插拔,那么启动时,系统就会扫描设备,并串联进设备树,当驱动注册(register时),驱动就会去设备树中,找id号和其对 应的相等的,如果找到,那么这两个就捆绑在一起了,通常为XXX_attcah函数,应用层对该设备的操作就变为调用驱动中对应的read、write、ioctl等。如果支持热插拔,比上面的就复杂了,因为驱动可能先于设备(总线)存在,所以当有新硬件连接时,内核会调用XXX_probe函数去探测,并注册设备,然后去驱动链表中查找驱动,如果找到,则attach。对其操作方法与上述一样。 运行ifconfig eth0 up命令的过程 针对PHY芯片RTL8201F的部分寄存器分析 phy_write(phydev, 0x1f, 00000007); phydev 是phy设备,0x1f是寄存器地址31的十六进制,00000007是第七页 LED定制寄存器,例如0x0088是对LED0和LED1定制,在第19个寄存器使能定制后,定制LED功能就会按照19寄存器的设置,或者后期更新的设置进行工作。 定制的含义就是把使能定制的作为ACT LED使用。 下面这个寄存器由第八章可以知道,改寄存器可以改变网口的speed,测试置1可以实现。 附录:操作LED参考代码(原创咯)和RTL驱动代码 |
|
|
|
只有小组成员才能发言,加入小组>>
4274个成员聚集在这个小组
加入小组3275 浏览 0 评论
航顺(HK)联合电子发烧友推出“近距离体验高性能Cortex-M3,免费申请价值288元评估板
4216 浏览 1 评论
4221 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-10 18:37 , Processed in 0.648930 second(s), Total 76, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号