Linux Mii management/mdio子系统分析之四 mdio总线及phy驱动模型及其开发流程

发布时间:2024年01月16日

(转载)原文链接:https://blog.csdn.net/u014044624/article/details/123303208


????? 前三篇文章完成了mdio子系统概述、mdio子系统驱动模型概述、mii_bus子模块方法及驱动实现分析,本篇文章我们主要进行mdio总线驱动实现分析、phy驱动实现分析等部分,涉及的内容如下:

一、mdio总线实现及相应方法分析

?

二、phy驱动实现相应方法的分析

?

三、phy驱动开发步骤说明

?

?

一、mdio总线实现及相应方法分析

?

? ? 既然mdio子模块属于总线型驱动,因此mdio子模块也是继承于linux设备-总线-驱动模型,从而实现自己的驱动模型,这在第二篇文章中也已经进行了说明,但第二篇文章主要介绍数据结构间的关联,本篇我们将介绍实现mdio总线、phy驱动等数据结构间关联的方法。下面我们看下mdio总线的定义及相应驱动接口的定义说明。

?

mdio_bus_type定义及说明

如下为mdio_bus_type的定义,mdio总线的实现相对也比较简单,连probe、remove接口都没有实现,而直接由phy_driver->probe/remove接口进行实现,mdio_bus_type主要实现如下两个功能:

  1. 定义dev_atrrs变量,针对所有注册在mdio_bus_type上的phy_device,均会创建该dev_attrs上定义的属性文件,该属性文件的名称为phy_id,该属性文件为只读属性文件,可获取该phy_device的phy id;
  2. 定义了match方法,用于进行phy_device、phy_driver的匹配检测操作。

?

?

?

?

mdio总线的device、driver注册与注销相关方法的实现流程说明

???? 由于mdio_bus_type没有提供probe、remove方法,因此针对mdio_bus_type而言,其device、driver的注册与注销方法的处理流程有些许的不同。针对linux设备-总线-驱动模型而言,其提供了device_register/driver_register、device_unregister/driver_unregister方法,用于进行设备与驱动绑定与解绑操作,从而实现设备的探测与移除操作。如下图为mdio总线实现中device_register/driver_register、device_unregister/driver_unregister接口的处理流程如下图所示。

  1. 针对device_register/driver_register而言,主要涉及将device、driver添加至mdio_bus_type,并进行device与driver的匹配检测,待匹配成功后,则通过driver->probe接口最终调用phy_driver->probe接口(这一点可以理解为面向对象中的多态,而phy_driver为device_driver的子类,即通过父类device_driver->probe方法调用至子类phy_driver->probe方法)。
  2. 针对device_unregister/driver_unregister而言,主要用于将device或driver从mdio_bus_type上移除,并调用driver->remove接口实现移除工作(而driver->remove接口最终调用phy_driver->remove接口(这一点可以理解为面向对象中的多态,而phy_driver为device_driver的子类,即通过父类device_driver->remove方法调用至子类phy_driver->remove方法)

?

?

?

?

?

?

mdio总线的match方法说明

????? mdio总线的match方法为mdio_bus_match,mdio_bus_match的实现流程如下图所示,其主要实现如下三方面的匹配检测功能:

  1. 先进行设备树驱动模型的支持(若系统支持设备树,则先调用该接口进行匹配检测,主要是将phy_driver与phy_device设备树节点的compatible变量进行匹配检测),若匹配则返回匹配成功;
  2. 若a没有匹配成功,则确认phy_driver是否提供了匹配检测方法,若提供匹配检测方法,则再次进行匹配检测,若匹配成功,则返回成功;
  3. 若以上均没有匹配成功,则判断phy_device的phyid与phy_driver支持的phyid进行匹配检测,若匹配成功则返回成功。

?

?

?

?

phy驱动实现相应方法的分析

? ? ? ?在前面我们也说了,可以将phy_driver理解为device_driver的子类,并实现了probe、remove接口,用以实现上一章节所说的多态。若下图所示,即为phy_driver与device_driver关联,针对phy_device与phy_driver而言,也提供了phy_device与phy_driver的注销方法,分别为phy_device_register、phy_drivers_register、phy_driver_unregister(因phy_device的注册是由mii_bus注册时通过调用mdiobus_register时完成phy_device的注册的,因此phy_device的注销也是在mdiobus_unregister中完成了,因此mdio子系统没有额外定义phy_device的注销接口)。

?

?

?

phy_device_register、phy_drivers_register接口分析

?

下图是这两个接口的处理流程图,下面进行详细说明:

针对phy_driver_register,主要完成如下工作:

  1. 设置phy_driver->driver的probe为phy_probe、remove为phy_remove,所依附的总线为mdio_bus_type,从而可将该phy_driver注册至mdio总线上;
  2. 调用driver_register接口,将该phy_driver->driver注册至mdio总线上,而关于driver_register的调用流程已经在上述mdio总线的device、driver注册与注销方法中说明。

针对phy_device_register而言,主要完成工作如下:

  1. 若phy_device已经与mii_bus完成绑定,则返回失败;
  2. 若该phy_device需要进行fixup,则调用phy_scan_fixups进行修正,一般在phy 芯片存在errata时,才进行修正;
  3. 调用device_add将该phy_device->dev注册至mdio总线(在调用phy_device_create创建一个phy_device时,已经设置phy_device->dev.bus为mdio_bus_type,因此在phy_device_register中无需再设置phy_device->dev.bus)

?

?

?

? ? ? 针对phy_device_register、phy_driver_register接口而言,也就是对device_register、driver_register的封装,以便作为mdio子模块的phy_device、phy_driver的注册接口

?

phy_driver_unregister接口分析

该接口就是对driver_unregister的封装,此处不再赘述。

?

?

三、phy驱动开发步骤说明

?

针对phy 驱动而言,主要实现两部分的内容:

  1. 实现probe、remove、suspend、resume接口,用于完成phy_driver的注册与注销,以及针对linux设备-总线-驱动模型的基础;
  2. 实现phy device处理相关的接口config_init、config_aneg、read_status、ack_interrupt、config_intr、did_interrupt、match_phy_device、ts_info、hwtstamp、rxtstamp、txtstamp、set_wol、get_wol。
  3. 其中config_init主要是对phy device进行一些初始化配置;
  4. 而config_aneg、read_status主要用于设置phy device的自适应机制已经获取phy的状态(主要用于获取适配速率、双工模式等),一般这两个接口直接使用genphy_config_aneg、genphy_read_status即可,触发该phy device有特殊的定义;
  5. 而ack_interrupt、config_intr、did_interrupt主要用于phy device的link up/down相关的中断处理,这个与具体的phy device有关,查看相应的芯片手册说明即可;
  6. 而针对ts_info、hwtstamp、rxtstamp、txtstamp、set_wol、get_wol主要是时间戳相关的处理,大多数phy device均不需实现这几个接口。
  7. match_phy_device主要用于实现phy_device与phy_driver的匹配检测,若一个phy_driver支持多个类型的phy_device,则最好实现该接口,若该phy_driver只适配某一个型号的phy_device,则不需要实现该接口,只需要设置支持的phy_id与phy_mask即可。

?

? ? ?以上即是实现phy driver的大体步骤,一般情况下若phy device不是很特殊,完全可以不实现phy driver,而在mdiobus_register时针对没有匹配phy_driver的设备,会将其与genphy_driver进行绑定,而genphy_driver基本上对大多数phy device而言,均可以正常驱动。但若我们仅需要在phy driver的probe接口中进行一些配置(如设置phy device的led mode 等),则完全可以将config_ange、read_status等接口使用genphy_driver中的接口,仅实现probe接口即可。

?

?

? ? ? ? 以上便是本篇文章的主要内容,主要介绍mdio_bus_type的定义;phy_device与phy_driver的注册与注销流程以及phy_driver编写需实现的接口等内容,下一篇文章主要介绍mdio模型实现的phy 状态机,以及phy_device与net_device的绑定与解绑相关的内容。

文章来源:https://blog.csdn.net/weixin_45682654/article/details/135607307
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。