PHY自协商
1. 自协商定义
自动协商模式是端口根据另一端设备的连接速度和双工模式,自动把它的速度调节到最高的公共水平,即线路两端能具有的最快速度和双工模式。
自协商功能允许一个网络设备能够将自己所支持的工作模式信息传达给网络上的对端,并接受对方可能传递过来的相应信息,从而解决双工和10M/100M速率自协商问题。自协商功能完全由物理层芯片设计实现,因此并不使用专用数据包或带来任何高层协议开销。
自协商功能的基本机制是:每个网络设备在上电、管理命令发出、或是用户干预时发出FLP(快速连接脉冲),协商信息封装在这些FLP序列中。FLT中包含有时钟/数字序列,将这些数据从中提取出来就可以得到对端设备支持的工作模式,以及一些用于协商握手机制的其他信息。
总结一句话:自协商是PHY与PHY之间的通信协商,与MAC无直接关系!
2. 自协商过程
如果两端都支持自协商,则都会接收到对方的FLP,并且把FLP中的信息解码出来,得到对方的连接能力,并且把对端的自协商能力值记录在自协商对端能力寄存器中(Auto-Negotiation Link Partner Ability Register , PHY标准寄存器地址5 ),同时把状态寄存器(PHY标准寄存器地址1)的自协商完成bit(bit5)置成1,在自协商未完成的情况下,这个bit一直为0。然后各自根据自己和对方的最大连接能力,选择最好的连接方式Link。比如,如果双方都即支持10M也支持100M,则速率按照100M连接;双方都即支持全双工也支持半双工,则按照全双工连接。
以太网的自动协商功能是由PHY硬件自己完成的,不需要我们的内核去做什么指导工作,只要设置相应寄存器启动自动协商后,我们就可以读相关的寄存器来得到现在协商成啥了。
以太网端口两端的工作模式必须协商一致,否则就会出现流量一大速度变慢,或者甚至出现接口掉线的问题。如果此时网络出现故障,不通、或者速度很慢,请检查接口是否协商为100M位以上的速度,以及全双工工作模式。如果没有,且端口为up的状态,可以尝试将强制将一端网络设定位100M位、全双工的工作模式,以调试网络是否恢复正常。但是若之后两端拔插网线,或者其他原因导致端口重新协商,则有可能仍会导致协商不匹配。
3. 普通链接脉冲和快速链接脉冲
OSI模型定义了7层网络模型,以太网MAC层对应OSI模型中的第二层-数据链路层,以太网PHY对应OSI模型中的第一层-物理层。对于以太网而言,物理层的主要功能是将在网线或者光纤中传输的原始数据(电压,电流等)转化为可被接收且符合协议的数字信号,其为数据链路层提供物理连接。
自协商协议的主要内容包括:双工模式,运行速率等。自动协商功能完全由物理层PHY芯片实现,无需额外数据包和高层协议开销。根据广播通信速率10M或者100M的不同,自动协商功能提供两种模式NLP(Figure 6)和FLP(Figure 2)。
3.1 10Base-TE自动协商模式(10M)
使用单独10Base-TE广播自动协商模式时, PHY芯片会通过Figure 1中TXD_P, TXD_N和RXD_P,RXD_N发送NLP(Normal Link Pulse)普通链路脉冲,每个脉冲间隔16ms。
3.2 100Base-TX自动协商模式(100M)
使用100Bast-TX自动协商模式时, PHY芯片会通过Figure 1中TXD_P, TXD_N和RXD_P,RXD_N发送FLP(Fast Link Pulse)快速链路脉冲。
4. 代码逻辑
以stmmac为例
//初始化PHY状态机
stmmac_dvr_probestmmac_mdio_registerof_mdiobus_registerof_mdiobus_register_phyphy_device_create INIT_DELAYED_WORK(&dev->state_queue,phy_state_machine)
//启动状态机
#define PHY_STATE_TIME HZ //Linux核心每隔固定周期会发出timer interrupt (IRQ 0),HZ是用来定义每一秒有几次timer interrupts。举例来说,HZ为1000,代表每秒有1000次timer interrupts。
stmmac_openphylink_startphy_startphy_start_machinephy_trigger_machinephy_queue_state_machine(phydev,PHY_STATE_TIME) //每隔1秒启动一次状态机mod_delayed_work(system_power_efficient_wq, &phydev->state_queue, jiffies);void phy_state_machine(struct work_struct *work)
{struct delayed_work *dwork = to_delayed_work(work);struct phy_device *phydev =container_of(dwork, struct phy_device, state_queue);bool needs_aneg = false, do_suspend = false;enum phy_state old_state;int err = 0;mutex_lock(&phydev->lock);old_state = phydev->state;switch (phydev->state) {case PHY_DOWN:case PHY_READY:break;case PHY_UP:needs_aneg = true;break;case PHY_NOLINK:case PHY_RUNNING:err = phy_check_link_status(phydev);break;case PHY_HALTED:if (phydev->link) {phydev->link = 0;phy_link_down(phydev, true);}do_suspend = true;break;}mutex_unlock(&phydev->lock);if (needs_aneg)err = phy_start_aneg(phydev);else if (do_suspend)phy_suspend(phydev);if (err < 0)phy_error(phydev);if (old_state != phydev->state) {phydev_dbg(phydev, "PHY state change %s -> %s\n",phy_state_to_str(old_state),phy_state_to_str(phydev->state));if (phydev->drv && phydev->drv->link_change_notify)phydev->drv->link_change_notify(phydev);}mutex_unlock(&phydev->lock);
}
当phy状态变为PHY_UP时,状态机会配置、启动自协商功能,然后调用phy_check_link_status获取自协商的结果。
int phy_start_aneg(struct phy_device *phydev)
{int err;if (!phydev->drv)return -EIO;mutex_lock(&phydev->lock);if (AUTONEG_DISABLE == phydev->autoneg) //如果PHY不支持自适应,从setting总取出合适的speed和duplex进行配置phy_sanitize_settings(phydev);err = phy_config_aneg(phydev);if (err < 0)goto out_unlock;if (phy_is_started(phydev))//如果phy->state==PHY_UPerr = phy_check_link_status(phydev);
out_unlock:mutex_unlock(&phydev->lock);return err;
} static int phy_config_aneg(struct phy_device *phydev)
{if (phydev->drv->config_aneg) //如果PHY driver提供了config_aneg回调则调用回调return phydev->drv->config_aneg(phydev);if (phydev->is_c45 && !(phydev->c45_ids.devices_in_package & BIT(0))) //如果指定了C45则调用下面函数return genphy_c45_config_aneg(phydev);return genphy_config_aneg(phydev); //如果上面两条都不满足,则用这个函数
}
通常phy driver里会提供read_status回调函数,在这个回调函数中会读取PHY的speed和duplex等等信息并将结果返回给调用者;
在phy_check_link_status中调用phy driver里提供的read_status回调函数获取phy speed,然后调用phy_link_change将获取到的phy speed赋值给pl->phy_state将phy最新状态通知到MAC。
当phy状态变为PHY_RUNNING时,needs_aneg不会被赋值为ture,不会再启动自协商并获取PHY状态了,但是PHY_RUNNING时会一直调用phy_check_link_status获取PHY状态并通知给MAC。
5. 特别注意
需要特别注意的是,千兆phy必须打开自协商使能方可运行。强制千兆只能通过关闭十兆百兆广播能力的方式实现,这是802.3协议中规定的。
协议规定千兆无法像十兆百兆一样强制的原因通过查找资料和测试猜测如下:
1、千兆协商的过程需要确定两端phy的主从关系
2、无法像十百兆的协商一样通过不同的广播码确认对方的速率
相关文章:

PHY自协商
1. 自协商定义 自动协商模式是端口根据另一端设备的连接速度和双工模式,自动把它的速度调节到最高的公共水平,即线路两端能具有的最快速度和双工模式。 自协商功能允许一个网络设备能够将自己所支持的工作模式信息传达给网络上的对端,并接受对…...

【大数据离线开发】8.2 Hive的安装和配置
8.3 Hive的安装和配置 安装模式: 嵌入模式 :不需要使用MySQL,需要Hive自带的一个关系型数据库:Derby本地模式、远程模式 ----> 需要MySQL数据库的支持 安装 hive 安装包 1、解压tar -zxvf apache-hive-2.3.0-bin.tar.gz -C…...

Capture Modules:车载网络报文捕获模块
(以下所有图片均来源于Technica官网) Technica Engineering的新一代硬件设备,即Capture Modules,提供了五种变体以涵盖不同带宽的车载以太网(100BASE-T1和1000BASE-T1)以及常见的IVN技术(CAN、C…...

数据结构与算法系列之时间与空间复杂度
这里写目录标题算法的复杂度大O的渐进表示法实例分析空间复杂度每日一题算法的复杂度 衡量一个算法的好坏,一般 是从时间和空间两个维度来衡量的, 即时间复杂度和空间复杂度。 时间复杂度主要衡量一个算法的运行快慢, 空间复杂度主要衡量一个…...

Python代码使用PyQt5制作界面并封装
目录参考链接续:https://blog.csdn.net/yulinxx/article/details/93344163 若要对此程序进行封装,加个界面,然后制作成 EXE, 使用 PyQt5 制作界面,PyInstaller 进行封装成 EXE 可参考: Python制作小软件…...

【Node.js】MySQL数据库的第三方模块(mysql)
mysql安装操作MySQL数据库的第三方模块(mysql)通过第三方模块(mysql2)连接到MySQL数据库mysql插入数据mysql插入数据的便捷方式mysql更新数据mysql更新数据的便捷方式mysql删除数据安装操作MySQL数据库的第三方模块(my…...

Docker中安装并配置单机版redis
1、使用docker安装redis 搜索Reis镜像,这里展示的是官方最新的镜像docker search redis 使用官方dockerhub搜索redis 2、选用常用的redis5.0作为安装的版本docker pull redis:5.0 3、运行redis容器的两种方式 3.1 不映射外部配置文件直接运行redis5.0镜像docker …...

模拟微信聊天-课后程序(JAVA基础案例教程-黑马程序员编著-第八章-课后作业)
【案例9-1】 模拟微信聊天 【案例介绍】 1.案例描述 在如今,微信聊天已经人们生活中必不可少的重要组成部分,人们的交流很多都是通过微信来进行的。本案例要求:将多线程与UDP通信相关知识结合,模拟实现微信聊天小程序。通过监…...

html2canvas将页面dom元素内容渲染成图片保存至本地
html2canvas:https://html2canvas.hertzen.com/configuration/ github:https://github.com/niklasvh/html2canvas 效果 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compa…...

前端进阶JS运行原理
JS运行原理 深入了解V8引擎原理 浏览器内核是由两部分组成的,以webkit为例: WebCore:负责HTML解析、布局、渲染等等相关的工作;JavaScriptCore:解析、执行JavaScript代码; 官方对V8引擎的定义࿱…...

Python识别二维码的两种方法(cv2)
在学习Python处理二维码的过程中,我们看到的大多是“用python生成酷炫二维码”、“用Python制作动图二维码”之类的文章。而关于使用Python批量识别二维码的教程,并不多见。所以今天我会给大家分享两种批量识别二维码的Python技巧!pyzbar PI…...

用一个例子告诉你 怎样使用Spark中RDD的算子
目录 1. 前言 1.1 操作分类 1.2 语法知识 2. transformations 2.1 map 2.2 mapPartitions 2.3 flatMap 2.4 glom 2.5 groupBy 2.6 filter 2.7 sample 2.8 distinct 2.9 coalesce 2.10 repartition 2.11 sortBy 2.12 partitionBy 2.13 reduceByKey 2.14 gro…...

什么是跨域? 出现原因及解决方法
目录一、什么是跨域二、为什么有跨域问题?三、解决跨域问题的方案1.Jsonp2.nginx3.CORS3.1 什么是cors3.2 原理四、GateWay网关中实现跨域步骤一、什么是跨域 跨域:浏览器对于javascript的同源策略的限制 。 同源政策的目的,是为了保证用户…...

低代码系统能够解决哪些痛点?
低代码系统能够解决哪些痛点?如果用4句话去归纳,低代码开发可以解决以下问题—— 为企业提供更高的灵活性,用户可以突破代码的限制自主开发业务应用;通过减少对专业软件开发人员的依赖,公司可以快速响应市场上的新业务…...

华为OD机试题,用 Java 解【两数之和绝对值最小】问题
最近更新的博客 华为OD机试题,用 Java 解【停车场车辆统计】问题华为OD机试题,用 Java 解【字符串变换最小字符串】问题华为OD机试题,用 Java 解【计算最大乘积】问题华为OD机试题,用 Java 解【DNA 序列】问题华为OD机试 - 组成最大数(Java) | 机试题算法思路 【2023】使…...

AcWing算法提高课-3.1.1热浪
宣传一下算法提高课整理 <— CSDN个人主页:更好的阅读体验 <— 题目传送门点这里 题目描述 德克萨斯纯朴的民众们这个夏天正在遭受巨大的热浪!!! 他们的德克萨斯长角牛吃起来不错,可是它们并不是很擅长生产富…...

华为OD机试题【最差产品奖】用 C++ 编码,速通 (2023.Q1)
最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧文章目录 最近更新的博客使用说明最差产…...
NFT市场大战:Blur市场地位可持续吗?
在战胜无数虚张声势的挑战者之后,OpenSea终于迎来了一个实力雄厚的竞争对手,已威胁到它的市场主导地位。opensea是什么?参考《NFT,区块链的产物之一,了解NFT交易平台Opensea》 继成功的空投之后,Blur并没有…...

初识CSS
1.CSS语法形式CSS基本语法规则就是:选择器若干属性声明由选择器选择一个元素,其中的属性声明就作用于该元素.比如:<body><p>这是一个段落</p><!-- style可以放在代码的任意地方 --><style>p{/* 将字体颜色设置为红色 */color: red;}</style&g…...
kubernetes(k8s)知识总结(第3期)
1. PV 与 PVC PV 是持久卷(Persistent Volume)的首字母缩写。通常情况下,可以事先在 k8s 集群创建 PV 对象: apiVersion: v1 kind: PersistentVolume metadata:name: nfs spec:storageClassName: manualcapacity:storage: 1Giac…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...

基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...

Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...

【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...