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_probe
	stmmac_mdio_register
		of_mdiobus_register
			of_mdiobus_register_phy
				phy_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_open
	phylink_start
		phy_start
			phy_start_machine
				phy_trigger_machine
					phy_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_UP
		err = 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、无法像十百兆的协商一样通过不同的广播码确认对方的速率

  • 5
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PHY以太网自动协商原理是指通过物理层传输介质适配器(PHY)之间的通信,自动协商和确定以太网的最佳传输速率、双工模式和帧长度等参数。 PHY以太网自动协商原理的步骤如下: 1. 连接建立:当两个网络设备(如交换机或路由器)通过以太网电缆连接时,它们的PHY适配器会开始自动协商。 2. 基本能力交换:连接建立后,PHY适配器会互相发送基本能力集信息,其中包括支持的最高速率、支持的双工模式(全双工或半双工)和最大帧长度等。 3. 速率协商PHY适配器会根据收到的基本能力集信息,选择两者都支持的最高速率。这意味着若其中一方适配器只支持较低速率,将会降低双方的传输速率以保持一致。 4. 双工模式协商:根据双方PHY适配器的基本能力集信息,双方会自动协商最佳的双工模式。如果两者都支持全双工模式,它们将采用全双工模式进行通信,否则将选择半双工模式。 5. 帧长度协商PHY适配器还会协商最大可接收的帧长度。这是为了避免MTU(最大传输单元)不匹配,导致数据包分片的问题。 通过PHY以太网自动协商原理,网络设备能够自动确定最佳的传输速率、双工模式和帧长度等参数,以优化以太网的性能和可靠性。这确保了网络设备之间的协同工作,提高了数据传输的效率。此外,PHY适配器还能在网络中发现并适应其他设备的能力,从而实现更好的兼容性和互操作性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值