2010年做网卡开发遇到的问题, 现在就放到这里了。

问题现象

两个节点ping不同,上层显示socket失去连接,建立连接,再失去连接…socket是个54错误, 错误宏是ECONNRESET=connection reset by peer.

问题分析

ping直接走的是网卡驱动层, kernel是VxWorks,一般不会出问题, 用ifShow查看没有发现error。ping包是icmp协议, 添加抓包代码, 发现是节点B收不到ping包。

先查下节点B是不是有接收错误. 在rx中, 添加错误打印(用logMsg, printf太多会打死), 查看发现bug出来时是大量的netGetCluster错误。再查下driver, 发现有dump error函数, 用这个函数查到bug时有 rx overrun error, 手册解释就是内部的FIFO溢出。再看下数据流向,先到网卡FIFO, 然后再送到system(host) memory。手册提到了82557 mem有3部分:CBL + RFA就驻留在system memory + CSR(on chip).

这个system mem就是VxWorks 82557 END memory pool, 它的初始化是 fei82557InitMem, 它的memsize的计算方法:rfd num(nRFDs) * rfd size + rfd loan * rfd size + cfd size(nCFDs) * cfd num(代码里有, rfd和cfd size都是1536byte)。FIFO溢出,很有可能就是system mem较小(这只是推断,手册应该提到FIFO的包是如何上送到system, 估计是rx控制单元先查看system pool是否有空间,有就上送,没就不上送,这样一来,就可能是memory pool size小了:),使得FIFO的包没有及时上送到system mem导致。

手册也提到了rfd过小可以捕获到:

Software can determine the current RU status by reading the SCB status word in the CSR (bits 5:2).
No Resources Due to No More RFDs (0010).

添加测试代码果然有, 也验证了之前的猜测。

问题解决

后面改大RFD, CFD的number,就是initString中,一般在sysFei82557 or configNet.h中。改大后正常。

公开手册是8255X_OpenSDM.pdf。