Chinaunix首页 | 论坛 | 博客
  • 博客访问: 215992
  • 博文数量: 63
  • 博客积分: 3010
  • 博客等级: 中校
  • 技术积分: 620
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-05 14:36
文章存档

2010年(8)

2009年(55)

我的朋友

分类: LINUX

2009-09-30 10:34:26

linux2.6.24 S3c2410 移植AX88796网卡驱动 解决了延时太长问题(原创)
 
 
前两天在Ubuntu下建立了开发环境,移植的是最小的内核。昨天移植了AX88796网卡的驱动,是按网上的资料移植的,结果移植完了出现的问题是网络延时太长,大概在1000ms,有时还ping不通。经过上网查资料,终于解决了这个问题。
原因如下:AX88796中断方式是上升沿中断,而网上所有的资料里面设的是下降沿中断,

static void uptech_ax_init(void)
{
    u32 bwscon;
    bwscon = __raw_readl(S3C2410_BWSCON);
    bwscon &= ~(S3C2410_BWSCON_WS2|S3C2410_BWSCON_ST2|S3C2410_BWSCON_DW2_32);
    bwscon |= (S3C2410_BWSCON_ST2|S3C2410_BWSCON_DW2_16);
    __raw_writel(bwscon, S3C2410_BWSCON);
    __raw_writel(S3C2410_BANKCON_Tacs4|S3C2410_BANKCON_Tcos4|S3C2410_BANKCON_Tacc14|S3C2410_BANKCON_Tcoh4|S3C2410_BANKCON_Tcah4|S3C2410_BANKCON_Tacp6| S3C2410_BANKCON_PMCnorm, S3C2410_BANKCON2);
    set_irq_type(IRQ_EINT2,IRQT_FALLING//改为IRQT_RISING);
    s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_EINT2);
    s3c2410_gpio_pullup(S3C2410_GPF2, 0);
    printk(KERN_INFO "Board init for AX88796 finished!\n");
}

 

我参考的完整文本如下:

linux内核中已经提供了AX88796的驱动,需要我们配置一下。
 
首先,在arch/arm/mach-s3c2410/mach-smdk.c中添加如下内容:

static struct ax_plat_data ax88796_platdata = {
    .wordlength = 2,
    .dcr_val = 0x1,
    .rcr_val = 0x40,
    .flags = AXFLG_MAC_FROMDEV,

};
static struct resource ax88796_res[] = {
    [0] = {
        .start = 0x10000200,
        .end = 0x1000021f,
        .flags = IORESOURCE_MEM,
    },
    [1] = {
        .start = IRQ_EINT2,
        .end = IRQ_EINT2,
        .flags = IORESOURCE_IRQ,
    }
};
struct platform_device ax88796_dev = {
    .name = "ax88796",
    .id = -1,
    .num_resources = ARRAY_SIZE(ax88796_res),
    .resource = ax88796_res,
    .dev = {
    .platform_data = &ax88796_platdata,
    }
};

注意resource中的start和end一定不能错,特别提醒注意end。因为在一般的驱动中,只要start对了,end多点都无所谓,但是在这个驱动中,end必须正确,因为在驱动中需要用到这个end的准确值!我调这个驱动花的主要时间就在这个地方。

platdata中的flags这样设置表示我们从器件中的Physical Address register 读取mac地址,前提是我们的Bootloader对网卡进行了初始化。即在Bootloader中可以设置好设备的mac地址,然后内核驱动就只需要读出这个mac地址就可以了。

然后在drviers/net/ax88796.c中增加下面一个函数:

 

static void uptech_ax_init(void)
{
    u32 bwscon;
    bwscon = __raw_readl(S3C2410_BWSCON);
    bwscon &= ~(S3C2410_BWSCON_WS2|S3C2410_BWSCON_ST2|S3C2410_BWSCON_DW2_32);
    bwscon |= (S3C2410_BWSCON_ST2|S3C2410_BWSCON_DW2_16);
    __raw_writel(bwscon, S3C2410_BWSCON);
    __raw_writel(S3C2410_BANKCON_Tacs4|S3C2410_BANKCON_Tcos4|S3C2410_BANKCON_Tacc14|S3C2410_BANKCON_Tcoh4|S3C2410_BANKCON_Tcah4|S3C2410_BANKCON_Tacp6| S3C2410_BANKCON_PMCnorm, S3C2410_BANKCON2);
    set_irq_type(IRQ_EINT2,IRQT_FALLING);
    s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_EINT2);
    s3c2410_gpio_pullup(S3C2410_GPF2, 0);
    printk(KERN_INFO "Board init for AX88796 finished!\n");
}

然后在axdrv_init函数的开始处调用上面的函数。

这个函数主要是对2410芯片的BANK2和网卡芯片使用的中断进行设置。设置BANK2为16位方式,设置网卡使用的EINT2为下降沿触发中断。如果中断设置不正确,就会出现一些奇怪的错误。我最开始设置的就是低电平触发,结果出现下面的错误:

setting eth0 ....irq 18: nobody cared (try booting with the "irqpoll" option)
[<c0028de8>] (dump_stack+0x0/0x14) from [<c005f4a4>] (__report_bad_irq+0x38/0x94)
[<c005f46c>] (__report_bad_irq+0x0/0x94) from [<c005f718>] (note_interrupt+0x218/0x26c)
 r4:00000000
[<c005f500>] (note_interrupt+0x0/0x26c) from [<c00602a8>] (handle_edge_irq+0x120/0x144)
[<c0060188>] (handle_edge_irq+0x0/0x144) from [<c0024044>] (asm_do_IRQ+0x44/0x5c)
 r6:c02e0020 r5:00000012 r4:c02b14cc
[<c0024000>] (asm_do_IRQ+0x0/0x5c) from [<c0024a44>] (__irq_svc+0x24/0xa0)
Exception stack(0xc3f1bdb0 to 0xc3f1bdf8)
bda0: 00000000 f4000008 00000001 00000000
bdc0: c02b14cc 40000013 00000012 c3e11520 00000000 00000000 c3c40000 c3f1be18
bde0: c3f1bdd4 c3f1bdf8 c005fd50 c005f240 a0000013 ffffffff
 r7:c3e11520 r6:00000004 r5:f4000000 r4:ffffffff

..........................................................

最后,就是在make menuconfig的时候,选上ASIX AX88796 NE2000 clone support就可以了。至于ASIX AX88796 external 93CX6 eeprom support选不选都无所谓,因为在我们上面的platdata的flags中就没有支持eeprom。

阅读(955) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~