您的位置:首页 > 运维架构 > Linux

Linux-2.6.32.67内核裁剪与移植之DM9000网卡驱动移植(3)

2015-08-28 18:57 701 查看
                                  Linux-2.6.32.67内核裁剪与移植之DM9000网卡驱动移植

                                                                                           作者:赵凯

                                                                                           QQ: 1205958201

  

修改arch/arm/mach-s3c2440/mach-smdk2440.c的182行,Platform_device结构体中加入:

static struct platform_device *smdk2440_devices[] __initdata = {

    &s3c_device_usb,

    &s3c_device_lcd,

    &s3c_device_wdt,

    &s3c_device_i2c0,

    &s3c_device_iis,

   &s3c_device_dm9000,

};

修改arch/arm/plat-s3c24xx/devs.c在第38行之后加入:

#include <linux/dm9000.h>
     /*DM9000*/
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_EINT18, /*use eint18 GPG10*/
    .end = IRQ_EINT18,
    .flags = IORESOURCE_IRQ,
}
};
static struct dm9000_plat_data s3c_dm9000_platdata = {
    .flags = DM9000_PLATF_16BITONLY,
};
extern struct platform_device s3c_device_dm9000 = {
    .name = "dm9000",
    .id = 0,
    .num_resources = ARRAY_SIZE(s3c_dm9000_resource),
    .resource = s3c_dm9000_resource,
    .dev = {
    .platform_data = &s3c_dm9000_platdata,
}
};
EXPORT_SYMBOL(s3c_device_dm9000);
在arch/arm/plat-s3c/include/plat/devs.h中加入一行:
extern struct platform_device s3c_device_dm9000;
 
修改dm9000.c源码,在drivers/net/dm9000.c中
1. 添加头文件,在第43行加入:

#if defined(CONFIG_ARCH_S3C2410)

#include <mach/regs-mem.h>

#endif
2. 指定注册时的中断触发方式,在第1085行加入:
static int
dm9000_open(struct net_device *dev)
{
    board_info_t *db = netdev_priv(dev);
    unsigned long irqflags = db->irq_res->flags & IRQF_TRIGGER_MASK;
 
    if (netif_msg_ifup(db))
       dev_dbg(db->dev, "enabling %s\n", dev->name);
 
    /* If there is no IRQ type specified, default to something that
     * may work, and tell the user that this is a problem */
 
    if (irqflags == IRQF_TRIGGER_NONE)
       dev_warn(db->dev, "WARNING: no IRQ resource flags set.\n");
 
    irqflags |= IRQF_SHARED;
    #if defined (CONFIG_ARCH_S3C2410)
if(request_irq(dev->irq,&dm9000_interrupt,IRQF_SHARED|IRQF_TRIGGER_RISING,dev->name,dev))
    #else
    if(request_irq(dev->irq,&dm9000_interrupt,IRQF_SHARED,dev->name,dev))
    #endif
    //if (request_irq(dev->irq, &dm9000_interrupt, irqflags, dev->name, dev))
       return -EAGAIN;
 
    /* Initialize DM9000 board */
    dm9000_reset(db);
    dm9000_init_dm9000(dev);
 
    /* Init driver variable */
    db->dbug_cnt = 0;
 
    mii_check_media(&db->mii, netif_msg_link(db), 1);
    netif_start_queue(dev);
   
    dm9000_schedule_poll(db);
    return 0;
}
3. 设置BANK4,设置MAC地址,在1292行,dm9000_probe函数中加入:
dm9000_probe(struct platform_device *pdev)
{
   struct dm9000_plat_data *pdata = pdev->dev.platform_data;
   struct board_info *db;   /* Point a board information structure */
   struct net_device *ndev;
   const unsigned char *mac_src;
   int ret = 0;
   int iosize;
   int i;
   u32 id_val;
   #if defined(CONFIG_ARCH_S3C2410)
   unsigned int oldval_bwscon = *(volatile unsigned int *)S3C2410_BWSCON;
   unsigned int oldval_bankcon4 = *(volatile unsigned int*)S3C2410_BANKCON4;
   #endif
/* Init network device */
    ndev = alloc_etherdev(sizeof(struct board_info));
    if (!ndev) {
       dev_err(&pdev->dev, "could not allocate device.\n");
       return -ENOMEM;
    }
。。。。。。
在1305行加入:
SET_NETDEV_DEV(ndev, &pdev->dev);
    dev_dbg(&pdev->dev, "dm9000_probe()\n");
    #if defined(CONFIG_ARCH_S3C2410)
    *((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
 
    /* setup board info structure */
    db = netdev_priv(ndev);
在1469行之后加入:
 
db->mii.mdio_read    = dm9000_phy_read;
    db->mii.mdio_write   = dm9000_phy_write;
#if defined(CONFIG_ARCH_S3C2410)
printk("Now use the default MAC address: 08:90:90:90:90:90 ");
mac_src = "www.txmcu.com";
ndev->dev_addr[0] = 0x08;
ndev->dev_addr[1] = 0x90;
ndev->dev_addr[2] = 0x90;
ndev->dev_addr[3] = 0x90;
ndev->dev_addr[4] = 0x90;
ndev->dev_addr[5] = 0x90;
#else
    mac_src = "eeprom";
 
    /* try reading the node address from the attached 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)) {
       /* try reading from mac */
      
       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
    platform_set_drvdata(pdev, ndev);
    ret = register_netdev(ndev);
 
    if (ret == 0)
       printk(KERN_INFO "%s: dm9000%c at %p,%p IRQ %d MAC: %pM (%s)\n",
              ndev->name, dm9000_type_to_char(db->type),
              db->io_addr, db->io_data, ndev->irq,
              ndev->dev_addr, mac_src);
    return 0;
 
out:
#if defined(CONFIG_ARCH_S3C2410)
*(volatile unsigned int *)S3C2410_BWSCON = oldval_bwscon;
*(volatile unsigned int *)S3C2410_BANKCON4 = oldval_bankcon4;
#endif
    dev_err(db->dev, "not found (%d).\n", ret);
 
    dm9000_release_board(pdev, db);
    free_netdev(ndev);
 
    return ret;
}
最后是配置内核,支持网卡:
Device Drivers --->

[*] Network device support --->

[*] Ethernet(10 or 100 Mbit) --->

<*> DM9000 support

(4)DM9000 maximum debug level

生成uImage,下载到开发板中:
tftp 0x32000000 uImage;nand erase 0 400000

nand write.jffs2 0x32000000 0 $filesize
这个时候开发板启动内核时候,开发板无法ping通虚拟机。
[root@ZK2440 /]# ping 192.168.1.8
PING 192.168.1.8 (192.168.1.8): 56 data bytes
ping: sendto: Network is unreachable
利用ifconfig查看环境变量发现没有配置网络。
先使用ifconfig命令配置一下网络(重启会失效)
ifconfig eth0 192.168.1.6 netmask 255.255.255.0 up
然后ping主机出现错误:
[root@ZK2440 /]# ping 192.168.1.9
PING 192.168.1.9 (192.168.1.9): 56 data bytes
------------[ cut here ]------------
WARNING: at net/sched/sch_generic.c:261 dev_watchdog+0x148/0x234()
NETDEV WATCHDOG: eth0 (dm9000): transmit queue 0 timed out
Modules linked in:
[<c00509a8>] (unwind_backtrace+0x0/0xdc) from [<c006c5b0>] (warn_slowpath_common+0x48/0x7c)
[<c006c5b0>] (warn_slowpath_common+0x48/0x7c) from [<c006c620>] (warn_slowpath_fmt+0x28/0x38)
[<c006c620>] (warn_slowpath_fmt+0x28/0x38) from [<c02b6a84>] (dev_watchdog+0x148/0x234)
[<c02b6a84>] (dev_watchdog+0x148/0x234) from [<c0075c6c>] (run_timer_softirq+0x160/0x1f4)
[<c0075c6c>] (run_timer_softirq+0x160/0x1f4) from [<c0071444>] (__do_softirq+0x98/0x150)
[<c0071444>] (__do_softirq+0x98/0x150) from [<c004a06c>] (asm_do_IRQ+0x6c/0x88)
[<c004a06c>] (asm_do_IRQ+0x6c/0x88) from [<c004aaa4>] (__irq_svc+0x24/0xa0)
Exception stack(0xc041df78 to 0xc041dfc0)
仔细检查开发板原理图与网卡相关的部分,发现DM9000的第100管脚接的是EINT7,这时候需要修改arch/arm/plat-s3c24xx/devs.c中的一个地方,将
[2] = {
    .start = IRQ_EINT18, /*use eint18 GPG10*/
    .end = IRQ_EINT18,
    .flags = IORESOURCE_IRQ,
}
改为:
[2] = {
    .start = IRQ_EINT7, /*use eint18 GPG10*/
    .end = IRQ_EINT7,
    .flags = IORESOURCE_IRQ,
}
重新生成uImage,下载到开发板中,设置开发板中的ip,网关等,然后ping主机,结果如下:
[root@ZK2440 /]# ping 192.168.1.8
PING 192.168.1.8 (192.168.1.8): 56 data bytes
64 bytes from 192.168.1.8: seq=0 ttl=64 time=6.210 ms
64 bytes from 192.168.1.8: seq=1 ttl=64 time=1.277 ms
64 bytes from 192.168.1.8: seq=2 ttl=64 time=1.340 ms
64 bytes from 192.168.1.8: seq=3 ttl=64 time=1.320 ms
64 bytes from 192.168.1.8: seq=4 ttl=64 time=1.375 ms
64 bytes from 192.168.1.8: seq=5 ttl=64 time=1.361 ms
64 bytes from 192.168.1.8: seq=6 ttl=64 time=1.270 ms
64 bytes from 192.168.1.8: seq=7 ttl=64 time=1.326 ms
64 bytes from 192.168.1.8: seq=8 ttl=64 time=1.354 ms
64 bytes from 192.168.1.8: seq=9 ttl=64 time=1.326 ms
64 bytes from 192.168.1.8: seq=10 ttl=64 time=1.363 ms
64 bytes from 192.168.1.8: seq=11 ttl=64 time=1.070 ms
64 bytes from 192.168.1.8: seq=12 ttl=64 time=1.255 ms
^C
--- 192.168.1.8 ping statistics ---
13 packets transmitted, 13 packets received, 0% packet loss
round-trip min/avg/max = 1.070/1.680/6.210 ms
同时,虚拟机ping开发板的情况如下:
 
[root@localhost linux-2.6.32.67]# ping 192.168.1.6
PING 192.168.1.6 (192.168.1.6) 56(84) bytes of data.
64 bytes from 192.168.1.6: icmp_seq=1 ttl=64 time=1.06 ms
64 bytes from 192.168.1.6: icmp_seq=2 ttl=64 time=1.13 ms
64 bytes from 192.168.1.6: icmp_seq=3 ttl=64 time=1.42 ms
64 bytes from 192.168.1.6: icmp_seq=4 ttl=64 time=1.08 ms
64 bytes from 192.168.1.6: icmp_seq=5 ttl=64 time=1.09 ms
64 bytes from 192.168.1.6: icmp_seq=6 ttl=64 time=1.04 ms
^C
--- 192.168.1.6 ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5647ms
rtt min/avg/max/mdev = 1.046/1.141/1.426/0.136 ms
表明DM9000移植成功。同时为了开发板上电内核保存设置的ip信息。修改etc/init.d/rcS文件,加入如下内容:
ifconfig eth0 192.168.1.6 netmask 255.255.255.0 up
然后开发板重启,利用ifconfig命令查看设置如下:
eth0      Link encap:Ethernet  HWaddr 08:90:90:90:90:90 
          inet addr:192.168.1.6  Bcast:192.168.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:192 (192.0 B)  TX bytes:0 (0.0 B)
          Interrupt:51 Base address:0xe000
说明设置成功。
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息