2008年11月26日星期三

cs8900在2440 linux2.6.27

driver/net/cs89x0.c

1.修改ioaddr和irq,接CS3,addr24选择io或memory方式,irq是EINT9,GPG1,写网卡MAC地址
#include "../../arch/arm/mach-s3c2410/include/mach/map.h"
#include "../../arch/arm/mach-s3c2410/include/mach/regs-mem.h"
#include "../../arch/arm/mach-s3c2410/include/mach/regs-gpio.h"
#include "../../arch/arm/mach-s3c2410/include/mach/regs-irq.h"
static unsigned int netcard_portlist[] __used __initdata = { S3C24XX_VA_CS8900_CS3 + 0x300, 0};
static unsigned int cs8900_irq_map[] = {IRQ_EINT9,0,0,0};

2.添加2440硬件初始化函数
static void cs89x0_hw_setup(struct net_device *dev)
{
unsigned int regval = 0;

//CS3, 16 bit bus width
__raw_writel(0x2211d110,S3C2410_BWSCON);
__raw_writel(0x1f7c,S3C2410_BANKCON3);

//EINT[9]
regval = __raw_readl(S3C2410_GPGCON);
regval &= ~(3<<2);
regval |= 2 <<2;
__raw_writel(regval, S3C2410_GPGCON);

//irq mode
regval = __raw_readl(S3C2410_EXTINT1);
regval &= ~(7<<4);
regval |= 4 <<4;
__raw_writel(regval, S3C2410_EXTINT1);

//irq MASK
regval = __raw_readl(S3C2410_EINTMASK);
regval &= ~(1<<9);
__raw_writel(regval, S3C2410_EINTMASK);

//mac addr
dev->dev_addr[0] = 0x00;
dev->dev_addr[1] = 0x00;
dev->dev_addr[2] = 0xc0;
dev->dev_addr[3] = 0xff;
dev->dev_addr[4] = 0xee;
dev->dev_addr[5] = 0x08;

printk("[cs89x0_probe] S3C2410_BWSCON = %x\r\n", __raw_readl(S3C2410_BWSCON));
printk("[cs89x0_probe] S3C2410_BANKCON3 = %x\r\n", __raw_readl(S3C2410_BANKCON3));
printk("[cs89x0_probe] S3C2410_GPGCON = %x\r\n", __raw_readl(S3C2410_GPGCON));
printk("[cs89x0_probe] S3C2410_EXTINT1 = %x\r\n", __raw_readl(S3C2410_EXTINT1));
printk("[cs89x0_probe] S3C2410_EINTMASK = %x\r\n", __raw_readl(S3C2410_EINTMASK));
printk("[cs89x0_probe] MAC ADDR: %x-%x-%x-%x-%x-%x\r\n",
dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);

}

3.在cs89x0_probe里调用cs89x0_hw_setup函数

cs89x0_hw_setup(dev);

if (net_debug)
printk("cs89x0:cs89x0_probe(0x%x)\n", io);

4.修改readword,writeword函数,portno不需要左移(我现在怎么看着不需要了啊,好像else里的也没有左移)

static u16
readword(unsigned long base_addr, int portno)
{
return __raw_readw(base_addr+portno);
}

static void
writeword(unsigned long base_addr, int portno,u16 value)
{
__raw_writew(value,base_addr+portno);
}

5.设置网口RJ45,省去boot启动时带参数
lp->force = g_cs89x0_media__force;
改成
lp->force=FORCE_RJ45;

6.注释掉irq_map的安全检查
#if 0
if (((1 <<>irq) & lp->irq_map) == 0) {
printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
dev->name, dev->irq, lp->irq_map);
ret = -EAGAIN;
goto bad_out;
}
#endif

7.2440初始化时增加分配cs8900的io port,修改mach-smdk2440.c

static struct map_desc smdk2440_iodesc[] __initdata = {
/* ISA IO Space map (memory space selected by A24) */

{
.virtual = (u32)S3C24XX_VA_ISA_WORD,
.pfn = __phys_to_pfn(S3C2410_CS2),
.length = 0x10000,
.type = MT_DEVICE,
}, {
.virtual = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
.pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
.length = SZ_4M,
.type = MT_DEVICE,
}, {
.virtual = (u32)S3C24XX_VA_ISA_BYTE,
.pfn = __phys_to_pfn(S3C2410_CS2),
.length = 0x10000,
.type = MT_DEVICE,
}, {
.virtual = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
.pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
.length = SZ_4M,
.type = MT_DEVICE,
}, { //zhourr
.virtual = (u32)S3C24XX_VA_CS8900_CS3,
.pfn = __phys_to_pfn(S3C2410_CS3 + (1<<24)),
.length = SZ_1M,
.type = MT_DEVICE,
}
};

8.在arch/arm/mach-s3c2410/include/mach/map.h增加宏定义,跟别的不冲突就行了
#define S3C24XX_VA_CS8900_CS3 S3C2410_ADDR(0x04000000)

没有评论: