Linux Mii management/mdio子系统分析之五 PHY状态机分析及其与net_device的关联

news2024/11/15 8:28:30

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


      前面几章基本上完成了mdio模块驱动模型的分析,本篇文章主要讲述phy device的状态机以及phy device与net_device的关联。Phy device主要是对phy的抽象,而net_device主要是对mac的抽象,而mdio总线以及mii_bus主要用于对phy设备的控制(包括设置phy设备的工作模式、速率模式、是否为自适应、phy的link状态等),而net_device需要根据phy的工作模式、速率模式、phy的link状态进行状态的同步,因此需要将net_device与phy device进行绑定与解绑。本章主要分为两个方面:

一、phy_device与net_device的绑定与解绑

 

二、phy device的状态机

 

 

一、phy_device与net_device的绑定与解绑操作。

 

什么时候实现phy_devicenet_device的绑定与解绑操作?

我们从现有各厂家的net_device驱动可以看到,大致存在两种模式:

  1. 在net_device的probe接口中,根据传递的mdio_bus_id、phy_id,查找phy_device并完成net_device与phy_device的关联;在net_device的remove接口中,完成net_device与phy_device的解绑操作;
  2. 在net_device->netdev_ops->ndo_open接口中,据传递的mdio_bus_id、phy_id,查找phy_device并完成net_device与phy_device的关联;在nnet_device->netdev_ops->ndo_stop中,完成net_device与phy_device的解绑操作(即应用层执行ifconfig xxx up/down操作时调用ndo_open/ndo_stop)。

 

关于phy_device与net_device的绑定与解绑主要涉及如下几个函数phy_connect、phy_disconnect

下面我们分析下这两个接口的主要工呢

 

phy_connect分析

该接口主要用来进行一个net_device类型的变量与phy_device类型的变量的关联、设置phy_device的状态为PHY_READY,并启动phy_device的状态机,详细处理流程如下图所示

  1. 确认phy_device是否存在(根据传递的phy_device_id,在mdio_bus_type中查找phy_deviec);
  2. 若phy_device存在,则进行net_device与phy_device的相互关联(phy_device->attached_dev、net_device->phydev),并调用phy_driver->config_init完成对phy device的初始化;
  3. 启动phy_device的状态机对应的延迟队列。

 

 

 

phy_disconnect分析

 

phy_disconnect的操作刚好与phy_connect接口的操作相反,主要提供的功能如下:

  1. 若phy_device支持中断,则调用phy_stop_interrupts关闭中断,并free该中断;
  2. 调用phy_stop_machine接口,关闭该phy_device的状态机对应的延迟队列;
  3. 解除net_device与phy_device关联,若该phy_device是与genphy_driver绑定,则调用device_release_driver解除它们之间的绑定关系。

 

 

 

 

phy_device irq相关说明

     在上面的介绍中,我们提到了phy_device的中断,针对phy_device的中断而言,当两个phy之间的link up/down的变化后(两个phy完成速率协商或者连接断开时),则会触发该中断,从而触发phy_device的状态机的转变(状态转换至PHY_RUNNING/PHY_NOLINK)。

       那若phy_device不支持中断模式呢?那就使用PHY_POLL模式,在该模式下则当phy_device处于PHY_RUNNING状态时,则将phy_device状态自动切换至PHY_CHANGELINK状态,而在PHY_CHANGELINK状态下通过对phy_device的状态寄存器,确定phy_device处于link up/down状态。这类似于之前介绍的MMC部分的mmc card的在位检测模式(若支持中断则通过中断方式通知mmc card的在位与否;若不支持中断,则进行周期1s的延迟队列的调度进行轮询检测)。但与mmc模块不同的是,针对phy_device的状态机对应的延迟队列而言,不管其phy_device是否支持link up/down中断,其状态机对应延迟队列均为周期1s执行(不支持中断则由phy_device的状态机自动切换phy的状态进行检测,支持中断则由中断处理函数中进行状态的切换)。

如下即为执行完phy_connect操作后,针对支持phy_device中断处理接口(phy_interrupt)以及其底半部处理接口(phy_change)与phy_state_machine之间的关联。

 

 

phy device的状态机

 

         在调用phy_connect完成net_device与phy_device的关联后,则启动phy_device的状态机流转对应的延迟队列调度接口,进行phy_device的状态流转操作。如下图为phy_device的状态流程图,下面详细说明下各状态的流转说明:

  1. 当调用phy_device_create创建一个phy_device或者调用phy_remove移除phy_device时,即将phy_device的状态设置为PHY_DOWN;
  2. PHY_START状态,目前在linux3.10的内核中,没有将phy_device的状态切换至PHY_START步骤,因此先跳过;
  3. 当调用phy_connect完成phy_device与net_device的绑定后,即将phy_device的状态设置为PHY_READY状态;或者在phy_device_register、phy_driver_register时完成phy_device与phy_driver的绑定后,也会将其状态设置为PHY_READY。
  4. 当系统调用phy_start接口,且其状态为PHY_READY时,则将其状态流转至PHY_UP状态(一般在net_device->net_ops->ndo_start中,完成phy_connect调用后,则调用phy_start将phy状态流转至PHY_UP);
  5. 在PHY_UP状态时,若该phy_device设置了自适应,则自动将其状态流转至PHY_AN;若该PHY_DEVICE设置为FORCE状态,则自动将其状态流转至PHY_FORCING;
  6. 在PHY_AN状态下,根据读取的phy_device的状态寄存器,若linkup,则将其状态流转至PHY_RUNNING;否则将其状态流转至PHY_NOLINK;
  7. 在PHY_NOLINK状态下,根据读取的phy_device的状态寄存器,若linkup,则将其状态流转至PHY_RUNNING;
  8. 在PHY_FORCING状态下,若读取phy_device的状态寄存器,为linkup,则将其状态流转至PHY_RUNNING;
  9. PHY_RUNNING状态下,若phy_device不支持中断,则将其状态设置为PHY_CHANGELINK,进行phy_device linkup状态的轮询检测;
  10. 在PHY_CHANGELINK状态下,根据读取的phy_device的状态寄存器,若linkup,则将其状态流转至PHY_RUNNING;否则则将其状态设置为PHY_NOLINK;
  11. 当各驱动模块调用phy_stop接口后,则phy_device的状态跳转至PHY_HALTED状态(无条件跳转,一般在net_device->netdev_ops->ndo_stop中会调用phy_stop);
  12. 仅在phy_device处于PHY_HALTED状态时,方才会流转至该PHY_RESUMING状态,该状态可跳转至PHY_AN、PHY_NOLINK、PHY_RUNNING。

 

 

 

以上即为phy_device的状态,当phy_device处于PHY_RUNNING状态时(此时调用netif_carrier_on设置net_device状态),说明两端的phy协商成功,可进行数据通信。以上phy_device的状态流转由接口phy_state_machine实现,该接口的流程图如下:

主要说明如下:

  1. 当phy_device处于PHY_UP状态时,则phy_device状态机处理接口,设置needs_aneg为1,调用phy_start_ange接口,进入PHY_AN状态或PHY_FORCING状态,进行phy_device的状态的协商;
  2. 在PHY_AN状态时,则phy_state_machine判断是否需要将状态跳转至PHY_RUNNING或PHY_NOLINK;
  3. 在PHY_RUNNING状态时,若phy_device不支持中断,则将其状态跳转至PHY_CHANNGELINK状态,由phy_state_machine接口来轮询判断phy_device的状态是否跳转至PHY_RUNNING/PHY_NOLINK;

而像PHY_DOWN、PHY_START、PHY_READY、PHY_UP、PHY_HALTED、

PHY_RESUMING这几个状态,一般由外部模块调用相应的接口进行跳转,而非phy_state_machine自动流转。
 

 

针对net_device也有相应的状态定义,如下图所示主要涉及如下几个状态

enum netdev_state_t {undefined

__LINK_STATE_START,

__LINK_STATE_PRESENT,

__LINK_STATE_NOCARRIER,

__LINK_STATE_LINKWATCH_PENDING,

__LINK_STATE_DORMANT,

};

 

  1. 当net_device注册至系统时,即设置__LINK_STATE_PRESENT;
  2. 当执行ifconfig xxx up,启用一个net_device时,则将其状态设置为__LINK_STATE_START(记住此时并不代表phy已完成协商且处于linkup状态),并在调用net_device->netdev_ops->ndo_open时,设置__LINK_STATE_NOCARRIER;
  3. 当调用phy_connect完成phy_device与net_device的绑定以及启动phy_device的状态机后,且phy_device跳转至PHY_RUNNING的同时,清除__LINK_STATE_NOCARRIER位,此时方才表明可进行数据通信。

 

 

      以上即是本次的主要内容,主要涉及phy_device与net_device之间的关联建立以及phy_device的状态机流转相关的内容。当phy_device处于PHY_RUNNING状态时,则将net_device的状态设置为carrier_on,即可进行mac层及mac层以上的数据通信工作。

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

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

相关文章

CCPC 2023 北京市赛 G.【模板】线段树(线段树区间合并20次多项式)

题目 思路来源 lyw 题解 洛谷高仿题目P4247 (aix)(aix)(aix)注意到当x有超过20项时,20个2相乘,对2的20次方取模就为0 所以,维护0次项到19次项乘积的和,向上合并时,是两个多项式卷积,这里暴力相乘即可 …

AI教我学编程之C#类的基本概念(2)

前言 AI教我学编程之C#类的基本概念(2) 已经更新,欢迎道友们前往阅读,本节我们继续学习C#类的基本概念 目录 上节回顾 质疑 对话AI 特殊情况 发问 解释 数据/函数成员 类和程序–实现一个简单的程序 实现尝试 声明类 类的成员…

如何判断售卖的医疗器械产品是二类还是三类

售卖医疗器械需关注产品本身是否为一、二、三类医疗器械。第一类医疗器械为一般项目的经营范围无需取得备案或许可证即可销售。第二类医疗器械产品需办理第二类医疗器械的备案方可销售。第三类医疗器械需取得医疗器械经营许可证且许可证上的经营范围需与销售的产品对应方可销售…

漏洞复现-Yearning front 任意文件读取漏洞(附漏洞检测脚本)

免责声明 文章中涉及的漏洞均已修复,敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…

关于 Error: Cannot find module ‘webpack/lib/RuleSet‘ 的详细解决方法(亲测有效)- 以及删除脚手架的方法

对于出现的这个错误,之前我也尝试了网上的多种解决方案,最终经过测试后,是通过将原来的 vue/cli 版本降级到 4.5.15 版本,最后再重新安装 node_modules 包 才得以解决。 下面是我将介绍怎么安装 4.5.15 版本的脚手架等。 &#x…

运筹说 第65期 | 动态规划的基本概念和基本原理

20世纪50年代初,美国数学家R. Bellman 等人在解决多阶段决策优化问题时提出了一种高效的求解方法——动态规划(Dynamic Programming),该方法基于多阶段决策优化问题的特点,把多阶段问题转换为一系列互相联系的单阶段问…

【经典算法】有趣的算法之---遗传算法梳理

every blog every motto: You can do more than you think. 0. 前言 遗传算法是一种基于自然选择和遗传机制的优化算法,因此它通常被用于求解各种最优化问题,例如函数优化、特征选择、图像处理等。 一言以蔽之: 将数学中的优化问题&#xf…

人机协同中存在一个独特的时空体系

一、在人机协同中存在一个独特的时空体系 在人机这个独特的时空体系中,人和机器之间的时间和空间的交织和共同作用。 在时间维度上,人机协同体系中的人和机器具有不同的时间节奏和速度。人类有限的生命周期和有时候需要休息的需求使得他们的工作时间和生…

(2023版)斯坦福CS231n学习笔记:DL与CV教程 (3) | 正则化与最优化

前言 📚 笔记专栏:斯坦福CS231N:面向视觉识别的卷积神经网络(23)🔗 课程链接:https://www.bilibili.com/video/BV1xV411R7i5💻 CS231n: 深度学习计算机视觉(2017&#xf…

Android 12+ MQTT适配

最终的解决方案是下载源码去改。我用的是已经修改好了的库,如果包名要自己的, 要注意: 1. compileSdk 34 和 targetSdk 34 改成33(Android12)或者34(Android13)。 2. 下载的 module 导入。 …

【设计模式之美】重构(三)之解耦方法论:如何通过封装、抽象、模块化、中间层等解耦代码?

文章目录 一. “解耦”概述二. 如何给代码“解耦”?1. 封装与抽象2. 中间层2.1. 引入中间层能**简化模块或类之间的依赖关系**。2.2. 引入中间层可以起到过渡的作用,能够让开发和重构同步进行,不互相干扰。 3. 模块化4. 其他设计思想和原则4.…

QT属性动画

时间记录:2024/1/15 一、介绍 属性动画类为QPropertyAnimation,类似于CSS的keyframes关键帧 二、分类及使用步骤 1.几何动画 (1)创建QPropertyAnimation对象 (2)setPropertyName方法设置属性名称&#…

谷歌验证码|某爬虫问答社区登录参数分析

关注它,不迷路。 本文章中所有内容仅供学习交流,不可用于任何商业用途和非法用途,否则后果自负,如有侵权,请联系作者立即删除! 1.目标地址 aHR0cHM6Ly9iYnMubmlnaHR0ZWFtLmNuL21lbWJlci5waHA/bW9kPW…

高通平台开发系列讲解(PCIE篇)MHI (Modem Host Interface)驱动详解

文章目录 一、MHI驱动代码二、MHI读数据流程三、MHI写数据流程沉淀、分享、成长,让自己和他人都能有所收获!😄 📢MHI (Modem Host Interface)我们通过名字顾名思义知道,它是Modem与Host的桥梁。 MHI 可以很容易地适应任何外围总线,但它主要用于基于 PCIe 的设备。 MHI(…

ElasticSearch降本增效常见的方法 | 京东云技术团队

Elasticsearch在db_ranking 的排名不断上升,其在存储领域已经蔚然成风且占有非常重要的地位。 随着Elasticsearch越来越受欢迎,企业花费在ES建设上的成本自然也不少。那如何减少ES的成本呢?今天我们就特地来聊聊ES降本增效的常见方法&#x…

Odrive 学习系列三:在odrive工程中添加SEGGER RTT 日志输出功能

一、背景: 对于嵌入式来讲,有个日志输出真真真真的太重要啦! SEGGER JLink自带的RTT日志输出对于老嵌入式而言更是开发利器。 Odrive本身的工程是不带这个功能的,尽管使用stlink可以查阅寄存器等,但感觉还是差了点意思。因此在本系列第二节的基础上,希望能给Odrive工程添…

Notepad++编译运行C/C++程序

首先需要先下载一个C语言编译器-MinGW(免费的) 官网:http://www.mingw.org/(加载太慢) 我选择MinGW - Minimalist GNU for Windows download | SourceForge.net这个网址下载的 注意安装地址,后续配置环境…

unique()函数

这篇博客是本人在学习算法中遇到的一个常用的函数&#xff0c;记录分享给大家 注意 &#xff1a;unique&#xff08;&#xff09;函数是删除相邻的重复元素&#xff0c;并且返回的是去重范围后的第一个元素的地址&#xff0c;左闭右开 #include <bits/stdc.h> using na…

CAN-位填充

位填充定义&#xff08;Bit Stuffing&#xff09; 当CAN节点发送 逻辑电平&#xff08;显性dominant或隐性recessive&#xff09;为持续相同的5位时&#xff0c;它必须添加一位反向电平。 CAN接收 节点会自动删除这个新增的额外电平位。 位填充作用 1---位填充是为了防止突发…

Codeforces Round 114 (Div. 1) C. Wizards and Numbers(思维题 辗转相除+博弈 巴什博弈)

题目 t(t<1e4)组询问&#xff0c;每次询问(a,b)&#xff08;0<a,b<1e18&#xff09;&#xff0c; 不妨a<b&#xff08;a>b时需要交换两个数考虑&#xff09; ①令b减去a的k次方&#xff08;k>1&#xff09;&#xff0c;要求减完之后b非负 ②令bb%a 当a和…