Chinaunix首页 | 论坛 | 博客
  • 博客访问: 198909
  • 博文数量: 60
  • 博客积分: 3269
  • 博客等级: 中校
  • 技术积分: 648
  • 用 户 组: 普通用户
  • 注册时间: 2005-09-21 10:48
文章存档

2012年(6)

2011年(6)

2010年(30)

2009年(8)

2007年(6)

2005年(4)

我的朋友

分类: LINUX

2005-09-23 17:39:41

ARCA GT2000 网卡内核驱动BUG引起的路由网络故障解决

我部设计了一款基于GT2000的防火墙,由其自带的网卡连接交换机芯片扩展8个RJ45口,其中,ARCAnet设备在系统中是eth0。问题如下:

问题:在连接一段时间后,ARCAnet-switch-8RJ45一线就不通了,但同一设备的其它网卡线路均运行正常。

# ARCA GT2000 网卡内核驱动BUG引起的路由网络故障解决

# 系统硬件平台

# ARCA gt2000/ 16M flash/ 128M DIMM SDRAM
#
# 20050823 由 LG 完成

# 其中关于代码和解决部分的技术支持由我的朋友“罗开辉”强力贡献,特此感谢,纪念!

# 我部设计了一款基于GT2000的防火墙,由其自带的网卡连接交换机芯片扩展8个RJ45口,其中,ARCAnet设备在系统中是eth0。问题如下:

# 问题:在连接一段时间后,ARCAnet-switch-8RJ45一线就不通了,但同一设备的其它网卡线路均运行正常。

故障检查:
1、交换部分,在断路后,连接到交换机的机器间通信正常,交换芯片温度低。
2、ARCAnet,断路后通过其他线路登陆防火墙检查,网络设备和系统均运行正常,没有数据错误和其他异常。
3、使用telnet登陆,ifconfig可以正确列出eth0设备的信息,可以正常ping通eth0,但却不能ping通与其连接的子网机器。
4、使用ifconfig eth0 down后,再将其 UP,此线路就又通了,再次出现此情况时重复此办法都可以恢复线路
5、网络中没有重复的MAC地址

6、在故障出现时系统打印内核信息“NETDEV WATCHDOG: eth0 transmit time out”
7、更换其他设计的硬件设备,故障依旧,排除芯片损坏。

http://leadgenius.cublog.cn/

故障分析:
基于以上信息,可以确定应用系统没有问题,怀疑是网卡电路设计有问题或者是网络设备驱动程序有BUG,
但是一个芯片的设计一般不会出现这种问题,周边电路也是模板电路,设计错误不大可能。
比较明确的信息是故障6的内核信息,确定由内核开始检查。

故障解决:
检查内核相关代码,发现:
上层协议发包超时时会调用设备驱动代码中注册的timeout_process函数,该函数定义如下
static void timeout_process(struct net_device *dev)
{
 struct _t_mac_info * mac_info_p = (struct _t_mac_info *)dev->priv; 
 writel(1, mac_info_p->reg_base+DMA_TPD); // 停止硬件IO
 mac_info_p->stats.tx_errors ++;
 netif_wake_queue(dev); // 通知系统继续传输,???
 DBPRINTK("[EXIT ----%s ] ",__FUNCTION__);
 return;
}
很明显该函数中对于此的处理仅仅是记录下了出错计数,并唤醒了传输队列,但若此时是由于真正的硬件故障则如此处理则并不能解决问题,
而我们此时也只有将其恢复初始状态,这一办法可行.因此我们添加一个函数来复位设备
static void arca_eth_clean(struct net_device *dev);

第一步:
在drivers/net/arca-ethc.h中添加函数声明如下
static void arca_eth_clean(struct net_device *dev);

第二步:
在drivers/net/arca-ethc.c中添加函数定义
static void arca_eth_clean(struct net_device *dev)
{
 int i;
 struct _t_mac_info * mac_info_p = (struct _t_mac_info *)dev->priv;
 netif_stop_queue(dev);
 stop_eth(mac_info_p->reg_base);
 synchronize_irq ();
 DBPRINTK("[%s ----  %d] clean device",__FUNCTION__,__LINE__);
 if (mac_info_p -> init_process != NULL)
  (* mac_info_p->init_process)(dev);
 dev->trans_start = jiffies;
 mac_info_p->mac_state = MAC_ACTIVE;
 driver_info.full_count = 0;
 netif_start_queue(dev);
 DBPRINTK("OK Now "); 

}
代码功能:设备复位
详细解释:
1.终止协议栈队列向该设备发送数据包
2.向设备寄存器写入控制字,禁止其读写
3.等待其它设备中断完成
4.从新写各个寄存器,对设备初始化
5.向设备寄存器写入控制字,开启读写
6.通知协议栈可以向该设备发送数据包

第三步:在该文件的timeout_process(1032行)函数中的
writel(1, mac_info_p->reg_base+DMA_TPD);后面添加
arca_eth_clean(dev);
修改后代码如下
static void timeout_process(struct net_device *dev)
{
 struct _t_mac_info * mac_info_p = (struct _t_mac_info *)dev->priv; 
 writel(1, mac_info_p->reg_base+DMA_TPD);
 arca_eth_clean(dev);
 mac_info_p->stats.tx_errors ++;
 netif_wake_queue(dev);
 DBPRINTK("[EXIT ----%s ] ",__FUNCTION__);
 return;
}

重编译内核后,测试系统,问题解决。是ARCA的网卡本身不稳定么?

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