linux2.6.38内核下的DM9000网卡驱动移植

时间:2021-06-27 12:23:19
 

Linux2.6.38内核已经有自带的DM9000网上驱动,要移植DM9000的网卡驱动我们只要在内核原有的驱动代码上加以改动就可以了。我们先简单分析一下DM9000的驱动代码,DM9000的驱动的源文件目录为:drivers/net/dm9000.c,我们从它的入口函数进行分析:

static int __init

dm9000_init(void)

{

       printk(KERN_INFO "%s Ethernet Driver, V%s\n", CARDNAME, DRV_VERSION);

 

       return platform_driver_register(&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”,跟踪进入dm9000_probe()函数进一步分析。进入dm9000_probe()函数,其它的先不用看,我们能看到一个这样的东西:

       db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

       db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);

       db->irq_res  = platform_get_resource(pdev, IORESOURCE_IRQ, 0);

这是一个平台资源,所以我们要移植DM9000的驱动就得先为它构建一个相应的平台资源。db->addr_res是发送地址时使用的地址,db->data_res是发送数据时使用的地址,db->irq_res是中断号。

开始移植:

       要移植DM9000网卡驱动,要修改的地方不多,主要修改arch/arm/plat-s3c24xx/common-smdk.c和drivers/net/dm9000.c两个文件,在common-smdk.c文件中加入平台设备资源,并添加设备,之后再修改dm9000.c的dm9000_probe()函数,加入相应的硬件操作,再修改dm9000_open()函数的中断注册就OK了,细节如下:

打开common-smdk.c文件:

vi arch/arm/plat-s3c24xx/common-smdk.c

1、包含头文件#include <linux/dm9000.h>

2、添加设备资源,定义下面几个结构体变量

static struct resource s3c_dm9k_resource[] = {

       [0] = {

              .start = S3C2410_CS4 , //发送地址时用到的地址

              .end = S3C2410_CS4 + 3 ,

              .flags = IORESOURCE_MEM ,

       },

       [1] = {

              .start = S3C2410_CS4 + 4 , //发送数据时用到的地址

              .end = S3C2410_CS4 + + 4 + 3 ,

              .flags = IORESOURCE_MEM ,

       },

       [2] = {

              .start = IRQ_EINT7 ,  //中断号

              .end = IRQ_EINT7 ,

              .flags = IORESOURCE_IRQ ,

       },

};

 

static struct dm9000_plat_data s3c_dm9k_platdata = {

       .flags = DM9000_PLATF_16BITONLY ,  //设置数据位宽为16位

};

//平台设备

static struct platform_device s3c_device_dm9k = {

       .name = "dm9000" , //这里的名称必须与dm9000.c文件中驱动名称一样

       .num_resources = ARRAY_SIZE(s3c_dm9k_resource) ,

       .resource = s3c_dm9k_resource ,

       .dev = {

              .platform_data = &s3c_dm9k_platdata ,

       }

};

注意:DM9000的访问基址为0x20000000(BANK4的基址),所以用到的内存址用S3C2410_CS4。

3、添加设备

static struct platform_device __initdata *smdk_devs[] = {

       &s3c_device_nand,

       &smdk_led4,

       &smdk_led5,

       &smdk_led6,

       &smdk_led7,

       &s3c_device_dm9k,   //在这里添加自己定义的平台设备

};

再修改drivers/net/dm9000.c文件中的dm9000_probe()函数和dm9000_open()函数,修改dm9000_probe()函数主要是设置存储器控制器使BANK4可用,修改dm9000_open()主要是修改中断注册。

1、打开dm9000.c文件,加入头文件#include <mach/regs-mem.h>

2、修改dm9000_probe()函数,在函数开头处定义两个变量用来保存寄存器的值,同时更改寄存器的值

unsigned int oldval_bwscon ;

unsigned int oldval_bankcon4 ;

 

oldval_bwscon = *((volatile unsigned int *)S3C2410_BWSCON) ;

 

*((volatile unsigned int *)S3C2410_BWSCON) = (oldval_bwscon & ~(3<<16) | S3C2410_BWSCON_DW4_16 | S3C2410_BWSCON_WS4 | S3C2410_BWSCON_ST4 ;

 

Oldval_bankcon4 = *((volatile unsigned int *)S3C2410_BANKCON4) ;

 

*((volatile unsigned int *)S3C2410_BANKCON4 ) = 0x1f7c ;

3、异常退出时还原寄存器的值,在out:段下面加入以下代码

out:

    *((volatile unsigned int *)S3C2410_BWSCON) = oldval_bwscon ;

    *((volatile unsigned int *)S3C2410_BANKCON4) = oldval_bankcon4 ;

4、修改dm9000_open()函数,为中断注册标识加上升沿

... //部分代码

       if (irqflags == IRQF_TRIGGER_NONE)

              dev_warn(db->dev, "WARNING: no IRQ resource flags set.\n");

       irqflags |= IRQF_SHARED;

       irqflags |= IRQF_TRIGGER_RISING; //加入上升沿

       if (request_irq(dev->irq, dm9000_interrupt, irqflags, dev->name, dev))

              return -EAGAIN;

... //部分代码

5、保存退出

代码修改完之后,make menuconfig选中DM9000网卡驱动编译进内核

Device Drivers --->

       Network device support --->

              [*] Network device support

                     Ethernet (10 or 100Mbit) --->

                            <*> DM9000 support

然后make uImage就OK了,编译好内核后下载到开发板启动,只要能看到跟下面内容类拟的输出就说明网卡驱动移植成功了。

IP-Config: Guessing netmask 255.255.255.0

IP-Config: Complete:

  device=eth0, addr=192.168.7.159, mask=255.255.255.0, gw=255.255.255.255,

  host=192.168.7.159, domain=, nis-domain=(none),

  bootserver=255.255.255.255, rootserver=192.168.7.119, rootpath=