linux5.10 RTL8211F 百兆设备插入千兆网口识别千兆
环境
内核版本:
5.10
问题描述:
RTL8211F phy 的千兆网口插入百兆设备识别为千兆,使用ethtool工具强制配置成百兆之后可以联通,但是使用百兆网线连接百兆设备,可以正常协商成百兆,4.19和6.1版本的内核都没有这个问题。
分析过程:
根据之前的问题描述,ethtool设置网速之后通讯传输是没有问题,说明问题出在网速协商阶段。
说明在phy芯片的网速协商阶段,读取Link partner能力的函数和对面百兆phy沟通时读取到百兆的phy是千兆的速率。关注点就转到了读取的MII的通用寄存器上。
一般情况下:
读取MII通用寄存器GBSR (1000Base-T Status Register, Address 0x0A)来判断是否千兆。

代码是:
lpagb = phy_read(phydev, MII_STAT1000);
if (lpagb < 0)
return lpagb;
但是只判断该位会把4芯网线协商为千兆全双工,但因为只有4芯,所以通信不成功。
所以还得增加个判断,协商能力寄存器09有一个bit9,是否建议千兆。

增加判断GBCR (1000Base-T Control Register, Address 0x09)的bit 9,也就是内核宏定义上的MII_CTRL1000寄存器,使用ADVERTISE_1000FULL判断。


也就补丁处的代码,判断对面的百兆phy的0寄存器处不建议千兆,然后把自己的速率去掉千兆然后再进行下一步的协商。
解决:
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index e83428c92b33..d4eb8f2253d3 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -2307,6 +2307,9 @@ int genphy_read_lpa(struct phy_device *phydev)
if (lpagb < 0)
return lpagb;
+ if (!(phy_read(phydev, MII_CTRL1000) & ADVERTISE_1000FULL))
+ lpagb = lpagb & ~LPA_1000FULL;
+
if (lpagb & LPA_1000MSFAIL) {
int adv = phy_read(phydev, MII_CTRL1000);
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index e83428c92b33..d4eb8f2253d3 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -2307,6 +2307,9 @@ int genphy_read_lpa(struct phy_device *phydev)
if (lpagb < 0)
return lpagb;
+ if (!(phy_read(phydev, MII_CTRL1000) & ADVERTISE_1000FULL))
+ lpagb = lpagb & ~LPA_1000FULL;
+
if (lpagb & LPA_1000MSFAIL) {
int adv = phy_read(phydev, MII_CTRL1000);
参考:
本文来自博客园,作者:杨旭0324,转载请注明原文链接:https://www.cnblogs.com/allalonewithyou/p/20798096,个人邮箱:yaonie4444@foxmail.com

浙公网安备 33010602011771号