DM9000网卡驱动详细分析(1)
来源:互联网 发布:淘宝宝贝销量多久清空 编辑:程序博客网 时间:2024/04/27 16:32
linux下DM9000网卡驱动同样是注册成平台驱动(platform driver)的形式.平台驱动在此就不多做介绍了,具体请参考linux驱动分析之framebuffer驱动.重点介绍DM9000网卡的控制.
首先大致介绍一下DM9000的相关情况.这里参考大牛黄刚博客的一段(略有改动).
DM9000的引脚和MINI2440的引脚连接:
DM9000 MINI2440 功能描述
SD0 DATA0 数据信号
| |
SD15 DATA15 数据信号
CMD ADDR2 识别为地址还是数据(为高电平时16位数据线上传输的是数据,为低电平时16位数据线上传输的是地址)
INT EINT7 中断
IOR# nOE 读命令使能
IOW# nWE 写命令使能
AEN nGCS4 片选使能
可以看出DM9000与处理器连接了16根数据线,1根地址线,而这唯一的一根地址线用于判断16根数据线上传输的是地址还是数据,所以这16条数据线为数据和地址复用.而片选信号使用的nGCS4(BANK4),则当处理器访问0x20000000 – 0x27FFFFFF这个范围的地址时会激活片选使能信号nGCS4.由于MINI2440使用的是ADDR2这根地址线,故DM9000的地址IO为0x20000000,数据IO为0x2000 0004.向地址IO写数据的时候不会激活ADDR2,所以向DM9000传送的为地址,而向数据IO写数据的时候会激活ADDR2,所以向DM9000传送的为数据.
以上为DM9000的读写大致情况.下面着重从源代码的角度分析linux下是如何驱动DM9000的.(driver/net/dm9000.c)
static int __init dm9000_init(void)
{
#if defined(CONFIG_ARCH_S3C2410)
unsigned int oldval_bwscon = *(volatile unsigned int *)S3C2410_BWSCON;
unsigned int oldval_bankcon4 = *(volatile unsigned int *)S3C2410_BANKCON4;
*((volatile unsigned int *)S3C2410_BWSCON)=(oldval_bwscon&~(3<<16))|S3C2410_BWSCON_DW4_16|S3C2410_BWSCON_WS4 |
S3C2410_BWSCON_ST4;
*((volatile unsigned int *)S3C2410_BANKCON4) = 0x1f7c;
*(volatile unsigned int *)S3C2410_BWSCON = oldval_bwscon;
*(volatile unsigned int *)S3C2410_BANKCON4 = oldval_bankcon4;
#endif//这一段是FriendARM加上去的,下面会有所分析
printk(KERN_INFO "%s Ethernet Driver, V%s/n", CARDNAME, DRV_VERSION);
return platform_driver_register(&dm9000_driver);
}
static void __exit
dm9000_cleanup(void)
{
platform_driver_unregister(&dm9000_driver);
}
module_init(dm9000_init);
module_exit(dm9000_cleanup);
struct platform_driver dm9000_driver初始化如下:
static struct platform_driver dm9000_driver = {
.driver= {
.name = "dm9000",
.owner = THIS_MODULE,
.pm = &dm9000_drv_pm_ops,
},
.probe = dm9000_probe,
.remove = __devexit_p(dm9000_drv_remove),
};
平台设备驱动注册成功时最终会调用到dm9000_driver的probe成员,在函数dm9000_probe中完成设备资源的申请,注册,dm9000网卡的相关检测(如类型,ID号等),网络设备结构的初始化,注册等工作.下面来重点分析这个函数.
static int __devinit dm9000_probe(struct platform_device *pdev)
{
struct dm9000_plat_data *pdata = pdev->dev.platform_data;
struct board_info *db;/* Point a board information structure */
struct net_device *ndev;
const unsigned char *mac_src;
int ret = 0;
int iosize;
int i;
u32 id_val;
/* Init network device */
ndev = alloc_etherdev(sizeof(struct board_info));
if (!ndev) {
dev_err(&pdev->dev, "could not allocate device./n");
return -ENOMEM;
}
SET_NETDEV_DEV(ndev, &pdev->dev);
dev_dbg(&pdev->dev, "dm9000_probe()/n");
/* setup board info structure */
db = netdev_priv(ndev);
db->dev = &pdev->dev;
db->ndev = ndev;
spin_lock_init(&db->lock);
mutex_init(&db->addr_lock);
INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work);
此函数的参数struct platform_device *pdev是在平台驱动注册的时候传进来的,指向的结构具体为:
static struct resource mini2440_dm9k_resource[] = {
[0] = {
.start = MACH_MINI2440_DM9K_BASE,
.end = MACH_MINI2440_DM9K_BASE + 3,
.flags = IORESOURCE_MEM
},
[1] = {
.start = MACH_MINI2440_DM9K_BASE + 4,
.end = MACH_MINI2440_DM9K_BASE + 7,
.flags = IORESOURCE_MEM
},
[2] = {
.start = IRQ_EINT7,
.end = IRQ_EINT7,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
},
};
/*
* * * The DM9000 has no eeprom, and it's MAC address is set by
* * * the bootloader before starting the kernel.
* * */
static struct dm9000_plat_data mini2440_dm9k_pdata = {
.flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
};
static struct platform_device mini2440_device_eth = {
.name = "dm9000",
.id = -1,
.num_resources = ARRAY_SIZE(mini2440_dm9k_resource),
.resource = mini2440_dm9k_resource,
.dev = {
.platform_data = &mini2440_dm9k_pdata,
},
};
- DM9000网卡驱动详细分析(1)
- DM9000网卡驱动详细分析(2)
- DM9000网卡驱动详细分析(3)
- DM9000网卡驱动分析
- DM9000网卡驱动分析
- DM9000网卡驱动分析
- 【驱动】DM9000网卡驱动分析
- DM9000网卡驱动深度分析
- ARM-Linux驱动--DM9000网卡驱动分析
- 详细透彻的分析DM9000网卡驱动程序(1)
- 详细透彻的分析DM9000网卡驱动程序(1)
- DM9000网卡驱动框架源码分析
- dm9000网卡的linux驱动分析
- Mini2440中的DM9000网卡驱动分析
- dm9000网卡驱动分析(一)
- dm9000网卡驱动分析(二)
- dm9000网卡驱动分析(三)
- dm9000网卡驱动分析(四)
- TD物理层中的FPACH和PRACH的区别和作用
- android获取系统剪贴析的内容(复制/粘贴)
- android 开发 @override 编译错误 解决办法
- Ubuntu安装
- 链表的各种操作
- DM9000网卡驱动详细分析(1)
- android获取当前窗口的宽度和高度
- dproxy的一个BUG
- DM9000网卡驱动详细分析(2)
- Symantec SEP11.0客户端部署!
- Web QQ 原理,ajax方式模拟socket编程
- Class.getResourceAsStream 和 ClassLoader.getResourceAsStream区别
- Android学习笔记(一)
- IHTMLDocument2 对象