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

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


(https://blog.csdn.net/u014044624/article/details/130674908)

     前面几章我们介绍了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。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/629989.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue3__Provide / Inject (依赖注入)和mixins

一、 Provide提供和Inject 注入 Provide提供 <script setup> import { provide } from vueprovide(/* 注入名 */ message, /* 值 */ hello!) </script> 例如父组件中提供方法 <template> <div class"home">dfhualsf<div><button…

Qt优秀开源项目之二十一:遇见QSkinny,一个轻量级Qt UI库

目录 一.QSkinny简介 二.工作原理 三.编译 一.QSkinny简介 QSkinny库基于Qt Graphic View和Qt/Quick中少量的核心类。它提供了一组轻量级控件&#xff0c;可以在C或QML中使用这些控件。QSkinny默认是启用硬件加速的&#xff0c;非常适合嵌入式设备&#xff0c;目前已经应用于…

Python之assert断言介绍

python自动化测试中寻找元素并进行操作&#xff0c;如果在元素好找的情况下&#xff0c;相信大家都可以较熟练地编写用例脚本了&#xff0c;但光进行操作可能还不够&#xff0c;有时候也需要对预期结果进行判断。 常用 这里介绍几个常用断言的使用方法&#xff0c;可以一定程度…

Vue3组件库开发 之Button(1)

需求分析&#xff1a; Button 组件大部分关注样式&#xff0c;没有交互 根本分析可以得到具体的属性列表&#xff1a; type:不同的样式(Default,Primary,Danger,Info,Success,Warning) plain:样式的不同展现模式boolean round:圆角boolean circle:圆形按钮&#xff0c;适合图标…

React入门 - 07(说一说 JSX 中的语法细节)

本章内容 目录 1、js 表达式2、列表渲染3、条件渲染4、className5、jsx 中的样式处理6、dangeouslySetInnerHTML7、htmlFor8、使用 jsx 的注意事项 上一节内容我们完成了一个简单的TodoList案例。到现在为止我们已经知道怎么在 JSX中使用 “js 表达式”和”列表渲染“了&#…

蓝桥杯 最长递增

输入 7 5 2 4 1 3 7 2 输出 3 思路 这个思路也很简单&#xff0c;后面大于前面&#xff0c;长度加一。当后面不大于前面的时候&#xff0c;就是一个新的递增序列了&#xff0c;递增序列的长度最小为1。 代码 #include <iostream> using namespace std; int main() {in…

Nginx初体验

文章目录 定义正向代理 & 反向代理安装与尝试 之前没怎么用过代理服务器Nginx&#xff0c;主要也是因为没有架构知识&#xff0c;根本不会去部署相关的机器。但是最近公司内部在调试的时候&#xff0c;经常用本机去充当Ngnix代理服务器&#xff0c;由于对这块知识掌握得还不…

leetcode—搜索二维矩阵II

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,2…

【计算机网络】网络层——详解IP协议

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【网络编程】 本专栏旨在分享学习计算机网络的一点学习心得&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 &#x1f431;一、I…

第29集《佛法修学概要》

丁三、声闻乘 分二&#xff1a;戊一、释义&#xff1b;戊二、四谛法&#xff1b;戊三、结示 请大家打开讲义第八十二页。我们看丁三&#xff0c;声闻乘。 在祖师大德的判教当中&#xff0c;把我们整个大乘的成佛之道分成了三个部分&#xff1a;第一个是安乐道&#xff0c;第…

【链路层】点对点协议 PPP

目录 1、PPP协议的特点 2、PPP协议的组成和帧格式 3、PPP协议的工作状态 目前使用得最广泛的数据链路层协议是点对点协议PPP(Point-to-Point Protocol)。 1、PPP协议的特点 我们知道&#xff0c;互联网用户通常都要连接到某个 ISP 才能接入到互联网。PPP 协议就是用户计算机…

全罐喂养是什么意思?适合猫咪全罐喂养的猫罐头推荐

猫咪全罐喂养的风一直挺大的&#xff0c;但是有好多养猫人一直不知道全罐喂养是什么意思&#xff0c;作为铲龄6年的宠物店店长&#xff0c;从早几年就开始全罐喂养了&#xff0c;对各个品牌的猫罐头也都很熟悉。 作为铲屎官&#xff0c;我们都想要给我猫猫吃的更好&#xff0c…

[足式机器人]Part2 Dr. CAN学习笔记-Advanced控制理论 Ch04-16 Robust Controller非线性鲁棒控制器

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-Advanced控制理论 Ch04-16 Robust Controller非线性鲁棒控制器 1. Slide Control 滑膜控制2 High Gain High Frequency3. 三种鲁棒控制器的比较如何分析控制器 Robust Control : tp achieve rob…

鸿蒙开发笔记(九):渲染控制,if/else,ForEach,LazyForEach

ArkUI通过自定义组件的build()函数和builder装饰器中的声明式UI描述语句构建相应的UI。在声明式描述语句中开发者除了使用系统组件外&#xff0c;还可以使用渲染控制语句来辅助UI的构建&#xff0c;这些渲染控制语句包括控制组件是否显示的条件渲染语句&#xff0c;基于数组数据…

【代码随想录05】242.有效的字母异位词 349. 两个数组的交集 202. 快乐数 1. 两数之和

目录 242.有效的字母异位词题目描述做题思路参考代码 349. 两个数组的交集题目描述做题思路参考代码 202. 快乐数题目描述做题思路参考代码 1.两数之和题目描述参考代码 242.有效的字母异位词 题目描述 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字…

父组件中 arr.push改变数组,但是子组件监听不到 arr 的变化

目录 一、问题 二、解决方法 三、总结 tiips:如嫌繁琐&#xff0c;直接移步总结即可&#xff01; 一、问题 1.真是奇怪呀&#xff0c;一般来说通过 push方法改变 数组&#xff0c;是一定会有响应式的&#xff0c;那就可以监听到变化。但是我今天却遇到了一件奇怪的事情。在…

k8s创建资源对象过程

我们都知道&#xff0c;K8S中一切皆资源&#xff0c;在使用K8S时&#xff0c;所有的pod或者controller都是通过yaml文件进行创建的。 那么接下来&#xff0c;就和大家一起看一下K8S是如何创建资源的。 创建资源对象的过程 Deployment是一种常见的资源对象。在Kubernetes系统…

高精度算法笔记·····························

目录 加法 减法 乘法 除法 高精度加法的步骤&#xff1a; 1.高精度数字利用字符串读入 2.把字符串翻转存入两个整型数组A、B 3.从低位到高位&#xff0c;逐位求和&#xff0c;进位&#xff0c;存余 4.把数组C从高位到低位依次输出 1.2为准备 vector<int> A, B, …

考研机试题收获——高精度进制转换

代码的第一遍真的很重要&#xff0c;在第一次打的时候尽量把问题思考全面&#xff0c;不要漏打少打&#xff0c;尽量不要留bug给之后de。 一、基础方面 一、处理输出的结束问题 scanf和cin默认都不会读取空格 ①scanf()&#xff1a;如果从文件中读取数据&#xff0c;当scanf()…

小红书达人投放策略分析,品牌方必看

小红书已经成为品牌营销的重要战场&#xff0c;达人投放作为小红书营销的核心环节&#xff0c;其策略的精准与否直接关系到营销效果的好坏。本文伯乐网络传媒将对小红书达人投放的重要性、投放策略以及监测与优化进行深入探讨&#xff0c;以期为品牌提供更具实操性的营销建议。…