ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

Linux Mii management/mdio子系统分析之六 fixed-mii_bus分析(mac2mac分析)

2020-03-08 18:04:07  阅读:748  来源: 互联网

标签:Mii mii management bus 接口 phy device fixed


     前面几章我们介绍了MDIO模块的大部分内容,针对mii_bus、mdio_bus、phy_device、phy_driver相关的注册、注销均进行了介绍。基本上把mdio模块的内容介绍完了,而本篇介绍的内容,主要是针对虚拟mii_bus实现,并将虚拟phy_device注册至该mii_bus上。(本次分析内容基于LINUX3.10的内核)

 

那fixed-mii_bus起到什么作用呢?其应用场景如下(示意图如下):

  1. 两个cpu间的mac通过rgmii/sgmii等直接相连(不需要phy device),这两块核心板存在于一块单板上,无须使用phy芯片。
  2. cpu与fpga间的mac通过rgmii/sgmii等直接相连(不需要phy device),这两块核心板存在于一块单板上,无须使用phy芯片。

 

 

 

      针对这两种应用场景,均没有使用phy芯片,但mac的驱动程序为保持通用性还是需要进行mii_bus注册以及net-device与phy-device的connect。因此mdio模块设计了一个虚拟的mii_bus(命名为fixed-mii_bus),用于mac芯片无需连接phy芯片的情况。针对上述情况而言,因两个mac间直接通过数据总线(rgmii/sgmii/qsgmii等)相连,因此需要手动配置mac芯片的模式(全双工)、速率(千兆/百兆/万兆等)。

 

fixed_mii_bus相关的数据结构说明

主要定义了struct fixed_mdio_bus、struct fixed_phy两个结构体。其中struct fixed_mdio_bus中包含了

struct mii_bus类型的成员;而struct fixed_phy包含了struct phydev类型的成员。

struct fixed_mdio_bus

该结构体表征一个虚拟mii_bus,并包含了fixed相关的信息,其中:

  1. 链表头phys用于将所有注册至fixed_mii_bus上的逻辑phy device链接在一起;
  2. irqs表示每一个虚拟phy对应的中断(基本上很少有使用该变量的,在mii_bus介绍章节中也说了,该中断可实现对phy devic link up/down的中断触发。在此处基本用不到)

struct fixed_mdio_bus {

int irqs[PHY_MAX_ADDR];

struct mii_bus *mii_bus;

struct list_head phys;

};

 

struct fixed_phy

该结构体表征一个虚拟phy设备,其中:

  1. id表示phy的addr,范围[0-31];
  2. regs表示该虚拟phy设备的寄存器值(因是一个虚拟phy,因此该虚拟phy的寄存器值由fxied_phy_status中的值决定)
  3. status中定义了该虚拟phy设备的各状态值,主要包括link状态、speed、duplex、pause、asym_pause等,而regs中的值即根据该变量中的内容进行设置;
  4. link_update接口用于更新虚拟phy的link状态。该接口类似于struct phydev中的adjust_link。它们之间的区别是:
    1. adjust_link接口根据phy device的link状态,对net_device的link状态进行更新;
    2. link_update接口则是根据net_device的link状态,对虚拟phy设备的link 状态进行更新。

  针对该接口指针,基本上不需要使用,若需要使用,则在创建虚拟phy设备时,赋值即可。

  1. node主要用于将该结构体链接至fixed_mdio_bus的的phys链表上。

 

struct fixed_phy {

int id;

u16 regs[MII_REGS_NUM];

struct phy_device *phydev;

struct fixed_phy_status status;

int (*link_update)(struct net_device *, struct fixed_phy_status *);

struct list_head node;

};

 

struct fixed_phy_status {

int link;

int speed;

int duplex;

int pause;

int asym_pause;

};

 

 

 

fixed_mii_bus的实现流程

 

在《LINUX MDIO模块分析(三)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机制)。

 

而fixed_mii_bus的实现流程也大致如此。下面我们借助mii_bus的实现流程来分析fixed_mii_bus。

  1. fixed_mii_bus的名称为fixed-0;
  2. 提供了read、write方法(比不需要实现reset方法,其实write方法也没有实现,因为挂载在该mii_bus上的均为虚拟phy设备,不需要进行设置操作)。read接口的功能为根据phy addr在fixed_mii_bus的phys链表中找到对应的虚拟phy设备,并根据该虚拟phy设备的struct fixed_phy_status类型的成员,更新其寄存器的值,并返回。
  3. fixed_mii_bus在初始化时,并没有设置需要忽略的phy addr;
  4. 将struct fixed_mdio_bus类型的全局变量platform_fmb中的irq数组赋值给platform_fmb.mii_bus->irq。
  5. 调用mdiobus_register完成fixed_mii_bus的注册。

     fixed_mii_bus基本上严格按照我们上一篇文章中介绍的流程创建的mii_bus。而针对虚拟phy设备而言,需要各模块自行进行虚拟设备的添加,因此fixed_mii_bus模块提供了添加接口fixed_phy_add(在3.10的内核中,仅提供了该接口,这限制了fixed_mii_bus的虚拟phy设备的添加时机,后面详述。而在linux4.x以上的内核增加了接口fixed_phy_register)。

 

fixed_mdio_bus_init接口分析

该接口主要实现上述所说的fixed_mii_bus的实现流程:

  1. 为fixed_mii_bus申请对应的mii_bus,并设置其read、write、irq变量;
  2. 调用mdiobus_register接口,注册fixed_mii_bus。此处我们也多说一下:
    1. mdiobus_register接口我们在之前已经介绍过程,其会为phy addr范围为[0-31]的phy设备,调用mdiobus_scan进行phy device的搜索,若搜索到即为该虚拟phy设备创建phy_device,并注册到mdio_bus中(在搜索phy device时,即会调用fixed_mii_bus的read接口,若虚拟phy设备已添加到fixed_mii_bus中,则返回的phyid即为该虚拟phy设备的addr值,因此即会调用phy_device_create接口创建phy device,并注册至mdio_bus中。因此若在fixed_mdio_bus_init调用之前,未将虚拟phy设备添加至fixed_mii_bus上,则进行mdiobus_register时,搜索不到该虚拟phy设备)。

 

 

 

 

 

fixed_mdio_read接口分析

      该接口用于获取一个虚拟phy设备的寄存器值,而针对虚拟phy设备,其各寄存器的值即根据fixed_phy的struct fixed_phy_status 类型的成员变量status进行设置(即根据在虚拟phy设备的添加时,会通过struct fixed_phy_status 类型的变量,设置该虚拟phy设备的工作模式等信息)。该接口的实现流程图如下,主要功能为:

  1. 根据输入的phy addr,查找该phy addr对应的虚拟设备是否已添加至fixed_mii_bus,若没有则返回失败;否则进入步骤b;
  2. 若查找的fixed_phy提供link_update接口,则调用该接口更新该fixed_phy->status变量中各成员的值;
  3. 调用fixed_phy_update_regs接口,根据fixed_phy->status更新该fixed_phy各寄存器的值;
  4. 返回该fixed_phy对应寄存器的值。

 

 

 

fixed_phy_add接口分析

该接口主要将一个fixed_phy添加至fixed_mii_bus中,该接口的实现流程如下所示。主要功能:

  1. 申请struct fixed_phy类型大小的内存空间;
  2. 若申请成功,则设置该fixed_phy的status成员,并更新其regs值;
  3. 将该fixed_phy添加至fixed_mii_bus的成员phys链表中。

 

       该接口主要是将一个fixed_phy添加至fixed_mii_bus的成员phys中,并没有为之创建对应的phy_device。而针对fixed_mii_bus上的成员phys链表上的fixed_phy链表成员,仅在fixed_mdio_bus_init中注册fixed_mii_bus时,通过mdiobus_register时,完成将该链表上的所有链表成员,均为其注册对应的phy_device至mdio_bus上。因此若各驱动模块想通过fixed_phy_add接口添加一个fixed_phy,则必须保证其在接口fixed_mdio_bus_init调用之前被调用到,否则该添加操作不起作用(因没有创建对应的phy_device)。而在linux3.10中,仅提供了这一个接口进行fixed_phy的添加。这也是这个接口的缺陷,即必须保证调用该接口(fixed_phy_add)的代码片段在fixed_mdio_bus_init执行之前调用。

 

 

fixed_phy_register接口分析

     上面分析fixed_phy_add接口的调用有所限制,必须保证其在fixed_mdio_bus_init执行之前调用。因此在 linux4.x的内核中,增加了接口fixed_phy_register,该接口弥补了fixed_phy_add的不足。接口fixed_phy_register在调用fixed_phy_add之后,调用phy_register,实现phy_device的注册,弥补了fixed_phy_add的不足。该接口的实现流程图如下:

  1. 获取一个可用的phy addr,若获取不到返回失败;
  2. 调用fixed_phy_add将该fixed_phy添加至fixed_mii_bus;
  3. 调用phy_register将该phy_device注册至mdio_bus上。

 

 

 

        在linux3.10及之前的版本,并没有提供该接口,若要使用则可以自己添加该接口。以上基本上完成了fixed_mii_bus模块相关接口的介绍,下面我们主要介绍如何使用fixed_mii_bus的接口。

 

Mac2mac驱动程序修改流程

上面介绍了fixed_mii_bus模块的接口,下面我们说明一下如何修改一个mac的驱动,实现对fixed_phy的支持。我们从两方面说明(支持设备树、不支持设备树)

 

不支持设备树模式的修改流程

  1. 在mac驱动对应的platform driver的probe接口中,调用fixed_phy_register,完成fixed_phy的注册;
  2. 在该net_device的ndo_open接口中,调用phy_connect接口进行phy_device、net_device的绑定时,可根据"fixed-0:phy_addr",在mdio_bus上查找对应的phy_device,从而完成phy_device与net_device的绑定。

 

 

 

支持设备树模式的修改流程

 

  1. 在mac驱动对应的platform driver的probe接口中,通过获取设备树中针对phy-device的定义(如定义了fixed-link,则说明使用fixed_phy,则调用fixed_phy_register,完成fixed_phy的注册;在4.x的内核提供了接口of_phy_register_fixed_link进行fixed_phy的注册);
  2. 在在该net_device的ndo_open接口中,调用phy_connect接口进行phy_device、net_device的绑定时,可根据"fixed-0:phy_addr",在mdio_bus上查找对应的phy_device,从而完成phy_device与net_device的绑定。

 

通过进行以上的修改,即可让mac驱动支持fixed-phy的支持。

 

     本章完成了fixed-phy的分析,也基本上完成了mdio子系统的介绍,我们分析了mii_bus相关的实现流程以及具体mii_bus驱动的实现步骤;也分析了phy_device、phy_driver、mdio_bus的实现流程,以及net_device与phy_device的绑定(phy_connect);介绍了phy_device的状态机流转相关的内容;fixed_mii_bus与fixed_phy的实现以及如何修改mac驱动支持fixed_phy。

标签:Mii,mii,management,bus,接口,phy,device,fixed
来源: https://blog.csdn.net/lickylin/article/details/104718463

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有