现象:
项目中使用光纤SFP模块:
TSEC(MAC) 《----GMII----》 bcm5461(PHY) 《---SerDes---》SFP(Media)
bcm5461配成fiber模式,网口死活不通,测试发现MAC上收到的包全是FCS错误。
郁闷的调试了N久,发现原来是内核的bug
原因:
内核代码中,CPU每隔一秒就检查PHY的状态。 函数 phy_timer()
若PHY协商成千兆,则把MAC配置成GMII;否则,把MAC配置成MII 函数 adjust_link()
问题就出在CPU对PHY的协商状态的判定。 函数 genphy_read_status()
对PHY协商后速度的判定,内核是通检查bcm5461的MII_STAT1000(地址0x0a)寄存器,即1000BASE-T status寄存器来判定的。这在copper模式下是对的。
但若bcm5461配置成fibber模式,1000BASE-T status Reg里面是垃圾值。内核此时还检查它,内核会以为PHY协商成了10兆模式,接着就会在adjust_link()中将MAC设成MII,所以 MAC---PHY 就会有FCS错误。
解决:
修改函数genphy_read_status()
首先判断bcm是否处于fiber模式
若处于fiber模式,PHY的协商速度写死为 SPEED_1000,并修改bcm5461的fiber模式相关寄存器
若处于copper模式,走内核原始流程就ok
这就实现了“光口/电口 自动切换功能”
阅读(437) | 评论(0) | 转发(0) |