(转载)原文链接:https://blog.csdn.net/u014044624/article/details/123303174
本篇是mii management/mdio模块分析的第三篇文章,本章我们主要介绍mii-bus的注册与注销接口。在前面的介绍中也已经说过,我们可以将mii-bus理解为mdio总线的控制器的抽象,就像spi-master、i2c-adapter一样。
本篇文章主要涉及如下两部分:
mii-bus的注册与注销接口
mii-bus提供的方法说明
mii-bus驱动开发步骤说明
mii-bus的注册与注销接口
mii_bus主要提供了mdiobus_register、mdiobus_unregister。下面我们对这两个接口进行分析说明。在分析这两个接口之前,我们还是把上一篇文章中的mii_bus、device、mdio_bus_class等结构体之间的关联图贴在这儿,以便我们可以更好的理解mdiobus_register、mdiobus_unregister。
mdiobus_register接口分析
该接口主要用于向系统中注册一个mii_bus device,并将该device注册至mdio_bus_class,完成以上操作后,即建立了如下图的数据结构间的关联图。该接口的处理流程如下图所示(该流程图屏蔽了一些合法性判断、返回值判断等信息):
- 调用device_register,将该mii_bus的device成员注册至系统的device_kset中,并完成与mdio_bus_class的关联;
- 针对phy address范围为[0-31],且mii_bus未设置忽略该phyid检测,则调用mdio_scan去搜索该phy addr下是否挂载了phy device(通过mii_bus->read接口,获取phy id),若获取到phy_id,则调用phy_device_register,将扫描到的phy_device注册至mdio_bus_type中(phy_device的注册我们在下一篇文章中介绍)。
通过以上两步,即完成了上述图片中mdio_bus_class、device_kset、mii_bus之间的关联,以及phy_device、mii_bus、phy_driver的关联。
mdiobus_unregister接口分析
该接口实现的功能刚发与mdiobus_registre相反,将上述建立的结构体变量之间的关联解除。下图为该接口的流程图。主要分为如下两部分:
- 调用device_del,注销该mii_bus;
- 针对该mii_bus所扫描到的phy_device,均调用device_unregister进行注销。
以上即为mii_bus的注册与注销方法,我们需要注意的一点是:
在进行mii_bus的注册中,会扫描该mdio总线上挂载的每一个phy设备,若存在则将该设备注册至mdio_bus_type上。这是与spi_master、i2c_adapter所不同的,在spi_master、i2c_adapter中需要驱动开发人员在板级文件或者设备树配置文件上显示完成spi device、i2c device的注册,而phy_device的注册与注销由mii_bus自动完成搜索及注册与注销操作,不需要驱动人员参与。
mii-bus提供的方法说明
与spi-master、i2c-adapter一样,mii-bus也提供了mdio-bus的访问方法,通过mii-bus提供的访问方法,即可访问该mdio总线上挂接的phy设备。系统主要提供了mdio bus read、write方法,名称分别为mdiobus_read、mdiobus_write,这两个接口主要是调用具体mii_bus的read/write方法,实现对phy device的读写控制命令。
那我们在做哪些驱动开发时,会用到这两个接口吗?比如我们的soc芯片通过mdio/mdc引脚连接了一个交换芯片,我们需要对该交换芯片进行配置,则可直接借助mdiobus_read/mdiobus_write实现与该交换芯片的命令交换(目前针对这一类驱动,linux系统提供了dsa驱动模块,在linux3.10时该模块仅作为Marvell相关交换芯片驱动使用,而在linux 5.2中已经有众多交换芯片驱动厂家支持了,后面我们在单独对dsa驱动进行分析)。这一类驱动的开发步骤如下:
- 创建一个platform_driver驱动,在该驱动的probe接口中执行如下操作:
- 根据platform device传递的参数(即mii_bus的id名称),从mdio_bus_class中查找到具体的mii_bus,并获取该变量;
- 创建对应的字符设备驱动,并把mii_bus作为该字符设备驱动的私有数据传递,而在该字符设备的read/write/ioctl接口中,即可借助mdiobus_read、mdiobus_write与mii_bus完成与具体的交换芯片的命令交换,实现对交换芯片的配置。
mii-bus驱动开发步骤说明
mii_bus结构体的定义如下,我们实现一个mii_bus驱动也就是实现该结构体类型的变量,并调用上述的mdiobus_register接口,即可完成mii_bus的注册。具体步骤如下:
- 需设置该mii_bus的名称与id,而在系统中可根据该id值搜索一个mii_bus;
- 完成read、write、reset方法,其中read、write主要用于与该mii_bus下的设备进行命令的交互;而reset方法主要用于对mii_bus的reset,关于这三个方法的实现,驱动开发人员可根据具体mac芯片的手册说明进行相应的开发操作。
- phy_mask主要用于设置需要忽略的phy addr,如我们需要忽略对phy addr 0的查找,则将phy_mask设置为0x01即可。
- 而irq主要指向一个数组,该数组中存储了每一个phy addr对应的irq,主要用于为每一个 phy addr对应的中断,该中断主要用于link up/down,针对该部分内容主要涉及到phy state machine,我们在后续章节中会详述该部分(大部分的mii_bus一般不提供该irq,但phy state machine提供了phy_poll机制,即是没有该irq,也可以进行phy link up/down,类似于mmc子模块中mmc card的poll机制)。
针对一个mii_bus类型的变量,只需要实现上述4步,然后再调用mdiobus_register接口,即可将该mii_bus注
册至系统中。
以上便是本篇文章的主要内容,主要涉及mii_bus的注册与注销、mii_bus驱动编写步骤等内容,该类驱动的实现也比较简单,只要按上述方法实现即可。