Linux Mii management/mdio子系统分析之三 mii_bus注册、注销及其驱动开发流程

      本篇是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,完成以上操作后,即建立了如下图的数据结构间的关联图。该接口的处理流程如下图所示(该流程图屏蔽了一些合法性判断、返回值判断等信息):

  1. 调用device_register,将该mii_bus的device成员注册至系统的device_kset中,并完成与mdio_bus_class的关联;
  2. 针对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相反,将上述建立的结构体变量之间的关联解除。下图为该接口的流程图。主要分为如下两部分:

  1. 调用device_del,注销该mii_bus;
  2. 针对该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驱动进行分析)。这一类驱动的开发步骤如下:

  1. 创建一个platform_driver驱动,在该驱动的probe接口中执行如下操作:
    1. 根据platform device传递的参数(即mii_bus的id名称),从mdio_bus_class中查找到具体的mii_bus,并获取该变量;
    2. 创建对应的字符设备驱动,并把mii_bus作为该字符设备驱动的私有数据传递,而在该字符设备的read/write/ioctl接口中,即可借助mdiobus_read、mdiobus_write与mii_bus完成与具体的交换芯片的命令交换,实现对交换芯片的配置。

 

 

mii-bus驱动开发步骤说明

 

mii_bus结构体的定义如下,我们实现一个mii_bus驱动也就是实现该结构体类型的变量,并调用上述的mdiobus_register接口,即可完成mii_bus的注册。具体步骤如下:

  1. 需设置该mii_bus的名称与id,而在系统中可根据该id值搜索一个mii_bus;
  2. 完成read、write、reset方法,其中read、write主要用于与该mii_bus下的设备进行命令的交互;而reset方法主要用于对mii_bus的reset,关于这三个方法的实现,驱动开发人员可根据具体mac芯片的手册说明进行相应的开发操作。
  3. phy_mask主要用于设置需要忽略的phy addr,如我们需要忽略对phy addr 0的查找,则将phy_mask设置为0x01即可。
  4. 而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驱动编写步骤等内容,该类驱动的实现也比较简单,只要按上述方法实现即可。

发布了140 篇原创文章 · 获赞 30 · 访问量 45万+

猜你喜欢

转载自blog.csdn.net/lickylin/article/details/104718277