Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2633961
  • 博文数量: 333
  • 博客积分: 4817
  • 博客等级: 上校
  • 技术积分: 4413
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-28 10:51
文章分类

全部博文(333)

文章存档

2017年(20)

2016年(57)

2015年(27)

2014年(20)

2013年(21)

2012年(164)

2011年(24)

分类: LINUX

2012-03-06 16:11:51

 
 
     继续分析内核自带的驱动源码,这次目标直指DM9000网卡驱动,2000行的驱动代码~~我们不能被表象所吓倒(虽然比起之前的驱动难度的确更大),根据之前掌握的知识和对网卡硬件的学习,我们还是要有信心去征服它的!

 

下面先给出整个驱动程序的大致框架,以理清我们凌乱的思绪。

 

 

由上图可见,本驱动采取虚拟平台总线驱动,在dm9000_driver驱动下有三个分支,其中.driver和.remove可分在同一类,实现suspend、resume、remove这三个功能。而另一重要分支则在.probe中实现,在内核探测设备的时候,绑定dm9000_netdev_ops和dm9000_ethtod_ops两个功能结构体,其包含的功能函数分别有:

 

①dm9000_netdev_ops:

  1. static const struct net_device_ops dm9000_netdev_ops = {  
  2.     .ndo_open       = dm9000_open,  
  3.     .ndo_stop       = dm9000_stop,  
  4.     .ndo_start_xmit     = dm9000_start_xmit,  
  5.     .ndo_tx_timeout     = dm9000_timeout,  
  6.     .ndo_set_multicast_list = dm9000_hash_table,  
  7.     .ndo_do_ioctl       = dm9000_ioctl,  
  8.     .ndo_change_mtu     = eth_change_mtu,  
  9.     .ndo_validate_addr  = eth_validate_addr,  
  10.     .ndo_set_mac_address    = eth_mac_addr,  
  11. #ifdef CONFIG_NET_POLL_CONTROLLER   
  12.     .ndo_poll_controller    = dm9000_poll_controller,  
  13. #endif   
  14. };  
static const struct net_device_ops dm9000_netdev_ops = { .ndo_open = dm9000_open, .ndo_stop = dm9000_stop, .ndo_start_xmit = dm9000_start_xmit, .ndo_tx_timeout = dm9000_timeout, .ndo_set_multicast_list = dm9000_hash_table, .ndo_do_ioctl = dm9000_ioctl, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = dm9000_poll_controller, #endif };

 

②dm9000_ethtod_ops:

  1. static const struct ethtool_ops dm9000_ethtool_ops = {  
  2.     .get_drvinfo        = dm9000_get_drvinfo,  
  3.     .get_settings       = dm9000_get_settings,  
  4.     .set_settings       = dm9000_set_settings,  
  5.     .get_msglevel       = dm9000_get_msglevel,  
  6.     .set_msglevel       = dm9000_set_msglevel,  
  7.     .nway_reset     = dm9000_nway_reset,  
  8.     .get_link       = dm9000_get_link,  
  9.     .get_wol        = dm9000_get_wol,  
  10.     .set_wol        = dm9000_set_wol,  
  11.     .get_eeprom_len     = dm9000_get_eeprom_len,  
  12.     .get_eeprom     = dm9000_get_eeprom,  
  13.     .set_eeprom     = dm9000_set_eeprom,  
  14.     .get_rx_csum        = dm9000_get_rx_csum,  
  15.     .set_rx_csum        = dm9000_set_rx_csum,  
  16.     .get_tx_csum        = ethtool_op_get_tx_csum,  
  17.     .set_tx_csum        = dm9000_set_tx_csum,  
  18. };  
static const struct ethtool_ops dm9000_ethtool_ops = { .get_drvinfo = dm9000_get_drvinfo, .get_settings = dm9000_get_settings, .set_settings = dm9000_set_settings, .get_msglevel = dm9000_get_msglevel, .set_msglevel = dm9000_set_msglevel, .nway_reset = dm9000_nway_reset, .get_link = dm9000_get_link, .get_wol = dm9000_get_wol, .set_wol = dm9000_set_wol, .get_eeprom_len = dm9000_get_eeprom_len, .get_eeprom = dm9000_get_eeprom, .set_eeprom = dm9000_set_eeprom, .get_rx_csum = dm9000_get_rx_csum, .set_rx_csum = dm9000_set_rx_csum, .get_tx_csum = ethtool_op_get_tx_csum, .set_tx_csum = dm9000_set_tx_csum, };

 

经过上述简单的分析之后,相信大家都对这个驱动程序的框架已经有一个大致的认识了,从篇幅和条理性等方面考虑,我们把分析具体函数的工作留到这个系列后面的博文去写。

 

 

在进入驱动程序分析之前,让我们先了解一下有关硬件连线及其资料(网上摘录)

 

DM9000的引脚和MINI2440的引脚连接

DM9000  MINI2440 功能描述
SD0   DATA0  
数据信号
 |           |
SD15  DATA15  
数据信号
CMD  ADDR2  
识别为地址还是数据
INT   EINT7  
中断
IOR#   nOE   
读命令使能
IOW#  nWE   
写命令使能
AEN   nGCS4  
片选使能

 

可以看出连接了16条数据线,1条地址线,而这唯一的一条地址线用于判断数据线传输的是地址还是数据,所以这16条数据线为数据和地址复用。而片选信号使用的BANK4,则访问0x2000 0000 – 0x27FF FFFF这个范围的地址时会激活片选使能信号nGCS4。而在MINI2440提供的内核中,DM9000的地址IO地址为0x2000 0000,数据IO0x2000 0004。则向地址IO写数据的时候不会激活ADDR2,所以向DM9000传送的数据为地址,而向数据IO写数据的时候会激活ADDR2,所以向DM9000传送的数据为数据

 

补充一点:在u-boot和linux-2.6.32.2内核中,IO地址设置为0x20000300,DA地址设置为0x20000304

 

而DM9000的读写时序、具体操作,请参考以下给出的datasheet~~(本人偷懒不详细给出啦)

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