网站建设需要的东西,河南建设河南勘察设计协会网站,wordpress文章阅读量插件,长沙网站seo优化公司1. 自协商定义 自动协商模式是端口根据另一端设备的连接速度和双工模式#xff0c;自动把它的速度调节到最高的公共水平#xff0c;即线路两端能具有的最快速度和双工模式。 自协商功能允许一个网络设备能够将自己所支持的工作模式信息传达给网络上的对端#xff0c;并接受对…1. 自协商定义 自动协商模式是端口根据另一端设备的连接速度和双工模式自动把它的速度调节到最高的公共水平即线路两端能具有的最快速度和双工模式。 自协商功能允许一个网络设备能够将自己所支持的工作模式信息传达给网络上的对端并接受对方可能传递过来的相应信息从而解决双工和10M/100M速率自协商问题。自协商功能完全由物理层芯片设计实现因此并不使用专用数据包或带来任何高层协议开销。 自协商功能的基本机制是每个网络设备在上电、管理命令发出、或是用户干预时发出FLP快速连接脉冲协商信息封装在这些FLP序列中。FLT中包含有时钟/数字序列将这些数据从中提取出来就可以得到对端设备支持的工作模式以及一些用于协商握手机制的其他信息。 总结一句话自协商是PHY与PHY之间的通信协商与MAC无直接关系 2. 自协商过程 如果两端都支持自协商则都会接收到对方的FLP并且把FLP中的信息解码出来得到对方的连接能力并且把对端的自协商能力值记录在自协商对端能力寄存器中Auto-Negotiation Link Partner Ability Register PHY标准寄存器地址5 同时把状态寄存器PHY标准寄存器地址1的自协商完成bitbit5置成1在自协商未完成的情况下这个bit一直为0。然后各自根据自己和对方的最大连接能力选择最好的连接方式Link。比如如果双方都即支持10M也支持100M则速率按照100M连接双方都即支持全双工也支持半双工则按照全双工连接。 以太网的自动协商功能是由PHY硬件自己完成的不需要我们的内核去做什么指导工作只要设置相应寄存器启动自动协商后我们就可以读相关的寄存器来得到现在协商成啥了。 以太网端口两端的工作模式必须协商一致否则就会出现流量一大速度变慢或者甚至出现接口掉线的问题。如果此时网络出现故障不通、或者速度很慢请检查接口是否协商为100M位以上的速度以及全双工工作模式。如果没有且端口为up的状态可以尝试将强制将一端网络设定位100M位、全双工的工作模式以调试网络是否恢复正常。但是若之后两端拔插网线或者其他原因导致端口重新协商则有可能仍会导致协商不匹配。 3. 普通链接脉冲和快速链接脉冲 OSI模型定义了7层网络模型以太网MAC层对应OSI模型中的第二层-数据链路层以太网PHY对应OSI模型中的第一层-物理层。对于以太网而言物理层的主要功能是将在网线或者光纤中传输的原始数据电压电流等转化为可被接收且符合协议的数字信号其为数据链路层提供物理连接。 自协商协议的主要内容包括双工模式运行速率等。自动协商功能完全由物理层PHY芯片实现无需额外数据包和高层协议开销。根据广播通信速率10M或者100M的不同自动协商功能提供两种模式NLPFigure 6和FLPFigure 2。 3.1 10Base-TE自动协商模式10M 使用单独10Base-TE广播自动协商模式时 PHY芯片会通过Figure 1中TXD_P, TXD_N和RXD_PRXD_N发送NLPNormal Link Pulse普通链路脉冲每个脉冲间隔16ms。 3.2 100Base-TX自动协商模式100M 使用100Bast-TX自动协商模式时 PHY芯片会通过Figure 1中TXD_P, TXD_N和RXD_PRXD_N发送FLPFast 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-statePHY_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、无法像十百兆的协商一样通过不同的广播码确认对方的速率