天天看點

mini2440移植之DM9000驅動

1.裝置資源初始化

linux2.6.32.2已經自帶完善的DM9000網卡驅動(drivers/net/dm9000.c),平台裝置。

在mach-mini2440.c中填寫相應結構表

添加驅動所需頭檔案dm9000.h

#include <linux/dm9000.h>

定義DM9000網卡裝置的實體基位址

#define  MACH_MINI2440_DM9K_BASE    (S3C2410_CS4 + 0x300)

填充該平台裝置資源設定

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,
},
};
同時在mini2440 裝置集中添加上面做好的網卡平台裝置
static struct platform_device *mini2440_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
&mini2440_device_eth,
&s3c_device_nand,
};
           

調整DM9000所用的位寬寄存器

打開 linux-2.6.32.2/ drivers/net/dm9000.c,頭檔案處添加2410 相關的配置定義

#include <asm/delay.h>

#include <asm/irq.h>

#include <asm/io.h>

#if defined(CONFIG_ARCH_S3C2410)
#include <mach/regs-mem.h>
#endif
           

#include "dm9000.h"

在dm9000 裝置的初始化函數中添加如下紅色部分,這裡是配置DM9000 所用片選總

線的時序,因為mini2440 目前隻有一個通過總線外擴的裝置,這部分也可以放到mach-mini2440.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;
#endif
           

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

return platform_driver_register(&dm9000_driver);

}

2.關于MAC位址

需要注意的是,本開發闆所用的DM9000 網卡并沒有外接EEPROM 用以存儲MAC 地

址,是以系統中的MAC 位址是一個“軟”位址,也就是可以通過軟體進行修改,可以随意改

為其他值,在static int __devinit dm9000_probe(struct platform_device *pdev)函數中可以看出:

/* try reading the node address from the attached EEPROM */
;嘗試從EEPROM 讀取MAC 位址
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)) {
/* try reading from mac */
mac_src = "chip";
for (i = 0; i < 6; i++)
ndev->dev_addr[i] = ior(db, i+DM9000_PAR);
}
;使用“軟”MAC 位址: 08:90:90:90:90:90
memcpy(ndev->dev_addr, "\x08\x90\x90\x90\x90\x90", 6);
if (!is_valid_ether_addr(ndev->dev_addr))
dev_warn(db->dev, "%s: Invalid ethernet MAC address. Please "
"set using ifconfig\n", ndev->name);
           

繼續閱讀