Chinaunix首页 | 论坛 | 博客
  • 博客访问: 64021
  • 博文数量: 15
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 107
  • 用 户 组: 普通用户
  • 注册时间: 2013-05-18 21:26
文章分类

全部博文(15)

文章存档

2013年(15)

我的朋友

分类: LINUX

2013-06-02 21:59:47

现象

项目中使用光纤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

   这就实现了“光口/电口 自动切换功能”

阅读(1721) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~