Chinaunix首页 | 论坛 | 博客
  • 博客访问: 819024
  • 博文数量: 264
  • 博客积分: 592
  • 博客等级: 中士
  • 技术积分: 1574
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-24 22:02
文章分类

全部博文(264)

文章存档

2019年(2)

2018年(1)

2017年(1)

2016年(4)

2015年(14)

2014年(57)

2013年(88)

2012年(97)

分类: LINUX

2013-05-25 12:11:49

现象

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

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

阅读(432) | 评论(0) | 转发(0) |
0

上一篇:gdb相关

下一篇:内核驱动框架

给主人留下些什么吧!~~