DM9000网卡驱动的移植。2.6.31.5中自带的dm9000.c可以满足TQ2440开发板上的DM9000网卡的要求,因此可以以2.6.31.5自带的dm9000为基础进行移植。下面是具体的移植步骤:
1) 添加网卡驱动的平台数据信息,包括:网卡的资源(地址资源、数据资源以及中断号等)、数据位数、网卡名称等。编辑文件arch/arm/plat-s3c24xx/devs.c,具体添加内容如下:
在文件开头添加:
38行: #include<linux/dm90000.h>//在引用头文件处添加dm9000.h头文件,该文件包含S3C2410_CS4等定义
在最后添加:
static struct resource s3c_dm9000_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 dm9k_plat_data = {
.flags = DM9000_PLATF_16BITONLY,
}; struct platform_device s3c_device_dm9k = {
.name = "dm9000", //这里的name一定要和drivers/net/dm9000.c中的dm9000_driver.driver.name一致,否则系统会找不到网卡驱动
.id = -1,
.num_resources = ARRAY_SIZE(s3c_dm9000_resource),
.resource = s3c_dm9000_resource,
.dev = {
.platform_data = &dm9k_plat_data,
} };
EXPORT_SYMBOL(s3c_device_dm9k);
2) 导出s3c_device_dm9k变量。编辑arch/arm/plat-s3c/include/plat/devs.h文件,具体添加内容如下:
extern struct platform_device s3c_device_dm9k;
3) 添加s3c_device_dm9k到平台设备数组。编辑arch/arm/mach-s3c2440/mach-smdk2440.c文件,具体添加内容如下:
152 static struct platform_device *smdk2440_devices[] __initdata =
153 {
154 &s3c_device_usb,
155 &s3c_device_lcd,
156 &s3c_device_wdt,
157 &s3c_device_i2c0,
158 &s3c_device_iis,
159 &s3c_device_rtc,
160 &s3c_device_dm9k, //添加dm9000到平台设备数组
161 }
4)修改/drivers/net/dm9000.c文件。由于在common-smdk.c中设置了dm9000使用的系统资源是CS4,因此需要根据dm9000的芯片手册来设置BWSCON和BANKCON4寄存器。另外由于dm9000网卡中断信号为上升沿,因此需要在网卡注册中断前设置中断信号为上升沿有效。具体修改内容如下:
(1)添加处理s3c2440寄存器头文件
41 #if defined(CONFIG_ARCH_S3C2410)
42 #include <mach/regs-mem.h>
43 #endif
添加后如下所示:

(2) dm9000_open()函数中添加对中断类型的处理
1014 #ifdef CONFIG_ARCH_S3C2410
1015 irqflags = IRQF_SHARED | IRQF_TRIGGER_RISING;
1016 #else
1017 if (irqflags == IRQF_TRIGGER_NONE)
1018 dev_warn(db->dev, "WARNING: no IRQ resource flags set.\n");
1019 irqflags |= IRQF_SHARED;
1010 #endif
添加后如下图所示:

(3)dm9000_probe()函数中添加对BWSCON和BANKCON4寄存器的处理,具体的数值请查阅s3c2440A芯片手册
1212行开始:
#if defined(CONFIG_ARCH_S3C2410)
unsigned int oldval_bwscon;
unsigned int oldval_bankcon4;
#endif
ndev = alloc_etherdev(sizeof(struct board_info));
SET_NETDEV_DEV(ndev, &pdev->dev);
1226行开始
#if defined(CONFIG_ARCH_S3C2410)
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; //16bits data && WAIT enable && Using UB/LB
oldval_bankcon4 = *((volatile unsigned int *)S3C2410_BANKCON4);
*((volatile unsigned int *)S3C2410_BANKCON4) = 0x1f7c; //config time seq
#endif
dev_dbg(&pdev->dev, "dm9000_probe()\n");
添加后如下图所示:

out:
dev_err(db->dev, "not found (%d).\n", ret);
#if defined(CONFIG_ARCH_S3C2410)
*((volatile unsigned int *)S3C2410_BWSCON) = oldval_bwscon;
*((volatile unsigned int *)S3C2410_BANKCON4) = oldval_bankcon4;
#endif
dm9000_release_board(pdev, db);
free_netdev(ndev);
添加后如下图所示:

由于s3c2440不能很好的从eeprom中读取网卡的MAC地址,因此需要在probe函数中手动设置网卡的MAC地址,即:在设置网卡MAC地址出屏蔽掉原来代码,手动添加自己的MAC
#ifdef CONFIG_ARCH_S3C2410
mac_src = "handy";
ndev->dev_addr[0] = 0x01;
ndev->dev_addr[1] = 0x23;
ndev->dev_addr[2] = 0x45;
ndev->dev_addr[3] = 0x67;
ndev->dev_addr[4] = 0x89;
ndev->dev_addr[5] = 0xab;
#else
mac_src = "eeprom";
for (i = 0; i < 6; i += 2)
dm9000_read_eeprom(db, i / 2, ndev->dev_addr+i);
if (!is_valid_ether_addr(ndev->dev_addr) && pdata != NULL) {
mac_src = "platform data";
memcpy(ndev->dev_addr, pdata->dev_addr, 6);
}
if (!is_valid_ether_addr(ndev->dev_addr)) {
mac_src = "chip";
for (i = 0; i < 6; i++)
ndev->dev_addr[i] = ior(db, i+DM9000_PAR);
}
if (!is_valid_ether_addr(ndev->dev_addr))
dev_warn(db->dev, "%s: Invalid ethernet MAC address.
Please " "set using ifconfig\n", ndev->name);
#endif
添加后如下所示:

5)编译并配置内核
[*] Networking support --->
Networking options --->
<*> Unix domain sockets
[*] TCP/IP networking
[*] IP:kernel level autoconfiguration
[*] IP:DHCP support
[*] Devices Drivers --->
[*] Network device support --->
[*] Ethernet(10 or 100Mbit) --->
<*> DM9000 support
6)DM9000网卡的配置
1.修改文件系统的“/etc/init.d/rcS”,添加如下所示内容:
ifconfig lo 127.0.0.1 //设置本地回环设备IP地址
net_set& //调用网络配置文件
2.在文件系统的/sbin目录下新建一个可执行文件“net_set”,其内容如下:
#!/bin/sh
echo Try to bring eth0 interface up ...>/dev/tq2440_serial0
if [ -f /etc/net.conf ];then
source /etc/net.conf
ifconfig eth0 down
ifconfig eth0 hw ether $MAC
echo ifconfig eth0 hw ether $MAC > /dev/tq2440_serial0
ifconfig eth0 $IPADDR netmask $NETMASK up
echo ifconfig eth0 $IPADDR netmask $NETMASK up >
/dev/tq2440_serial0
route add default gw $GATEWAY
echo add default gw $GATEWAY > /dev/tq2440_serial0
else
ifconfig eth0 hw ether 10:23:45:67:89:ab
ifconfig eth0 192.168.1.6 netmask 255.255.255.0 up
route add default gw 192.128.1.2
echo ifconfig eth0 hw ether 10:23:45:67:89:ab >
/dev/tq2440_serial0
echo ifconfig eth0 192.168.1.6 netmask 255.255.255.0 up>
/dev/tq2440_serial0
echo route add default gw 192.128.1.2 >/dev/tq2440_serial0
fi
echo Done > /dev/tq2440_serial0
3.然后在文件系统的/etc目录下新建“net.conf”文件用于存放网络配置信息
IPADDR=192.168.1.6
NETMASK=255.255.255.0
GATEWAY=192.168.1.2
MAC=10:23:45:67:89:ab
当要修改网卡的IP地址时,只需要修改“/etc/net.conf”文件的内容后,执行一下net_set命令即可
然后,重新制作根文件系统,烧到开发板,出现如下信息:
