免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1203 | 回复: 0
打印 上一主题 下一主题

DM9000移植 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-11-08 11:40 |只看该作者 |倒序浏览




在前面移植好内核和文件系统之后,开始考虑网卡的通信了。网上好多关于DM9000驱动的例子,大同小异,但是一律照搬都是不行,最多的只能发现设备,到最后还是ping不通,花费九牛二虎之力,终于还是弄好了。
看到ping通其他主机,真是舒了一口气。

首先,移植驱动要做的这么几个事情
1、 要让系统能检测到设备
2、 初始化它
3、 让驱动找到收发的接口,一般也就是中断/DMA(具体的收发一般都是驱动已经写好了的,不用我们多动脑筋)

要让系统能检测到设备,首先要知道网卡的基地址。以我的板子为例,DM9000的CS接在B_nGCS5上,所以基址是0x28000000,在include/asm-arm/arch-s3c2410/map.h中有详细的定义如下
#define S3C2410_CS0 (0x00000000)
#define S3C2410_CS1 (0x08000000)
#define S3C2410_CS2 (0x10000000)
#define S3C2410_CS3 (0x18000000)
#define S3C2410_CS4 (0x20000000)
#define S3C2410_CS5 (0x28000000)
#define S3C2410_CS6 (0x30000000)
#define S3C2410_CS7 (0x38000000)

我们看到的是8个片选,s3c2440将4G(0x40000000)的地址空间通过8个片选划分为8个区间,我们最常看到的地址比如0x30200000,这是内存地址,因为内存接的CS6,它的地址是以0x3开头的。很明显,DM9000接在CS5上,基址应该就是0x28000000了,可是这里还有一个疑问,为什么会是0x28000300,这个问题我也没弄明白,不过在后来移植CS8900时,我发现CS8900A的手册中有这么一句话:当CS8900复位时,16字节连续的端口被分配在偏移地址300H处,这个地址就是CS8900的I/O基地址。就权且这么用吧,反正我试了,除非加上这个300,否则系统找不到DM9000这个设备(后来的CS8900也如此)。

   
好了,不罗嗦了,先把工作做完。

移植步骤
1. 修改arch/arm/plat-s3c24xx/devs.c,加入dm9000的信息,并使用EXPORT_SYMBOL 宏将platform_device s3c_device_dm9000导出,在smdk2410.c中会用到

//===========================================================================
//     dm9000 ------yangdk

#define    DM9000_BASE 0x28000300
//#define DM9000_IRQ IRQ_EINT3
static struct resource s3c_dm9000_resource[] = {
        [0] = {
              .start = DM9000_BASE,
      .end   = DM9000_BASE+ 0x3,
      .flags = IORESOURCE_MEM
       },
       [1]={
              .start = DM9000_BASE + 0x4,
              .end = DM9000_BASE + 0x4 + 0x7c,
              .flags = IORESOURCE_MEM
       },
        [2] = {
      .start = IRQ_EINT3,
      .end   = IRQ_EINT3,
      .flags = IORESOURCE_IRQ
       }
};

static struct dm9000_plat_data s3c_device_dm9000_platdata = {
   .flags= DM9000_PLATF_16BITONLY,
};

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_device_dm9000_platdata,
       }
};

EXPORT_SYMBOL(s3c_device_dm9000);      
//end of DM9000
//===========================================================================

2.在include/asm-arm/plat-s3c24xx/devs.h 文件中 添加一行
  extern struct platform_device s3c_device_dm9000;  


3.在arch/arm/mach-s3c2410/mach-smdk2410.c中将dm9000加入到要初始化的设备链表里去,内核启动时将会检测设备并加载驱动

static struct platform_device *smdk2410_devices[] __initdata = {
       &s3c_device_usb,
       &s3c_device_lcd,
       &s3c_device_wdt,
       &s3c_device_i2c,
       &s3c_device_iis,
       &s3c_device_dm9000,
};

       4.在arch/arm/mach-s3c2440/mach-smdk2440.c中加入对DM9000的地址映射
       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
              .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
              .length            = SZ_4M,
              .type              = MT_DEVICE,
       },{
              .virtual = S3C2410_ADDR(0x02100300),
              .pfn        = __phys_to_pfn(0x28000300),    //DM9000       -----yangdk
              .length     = SZ_1M,
              .type              = MT_DEVICE,
       }     
};
5. 修改driver/net/dm9000.c
加入几个头文件,后面有用
view plain
copy to clipboard
print
?
#include
#include
#include   
"" regs-gpio.h="">  #include
#include
#include
在probe函数中加入
view plain
copy to clipboard
print
?
unsigned char ne_def_eth_mac_addr[]={0x00,0x12,0x34,0x56,0x80,0x49};//yangdk          unsigned char ne_def_eth_mac_addr[]={0x00,0x12,0x34,0x56,0x80,0x49};//yangdk
然后在大约640行(我的改动比较多,不记得原来的行号了)左右的地方修改
view plain
copy to clipboard
print
?
for (i = 0; i
    //ndev->dev_addr = ior(db, i+DM9000_PAR); //yangdk   
    ndev->dev_addr = ne_def_eth_mac_addr;                  for (i = 0; i dev_addr = ior(db, i+DM9000_PAR);        //yangdk
                        ndev->dev_addr = ne_def_eth_mac_addr;
这是手动修改网卡的MAC地址,在上面的数组中自己随便填入,不要是全0或者全1就行。
到此为止,网卡可以发现了,也能配上IP,但是ping不同其他主机。是初始化的问题,继续
6. 在probe函数中加入这部分代码
view plain
copy to clipboard
print
?
//-----------yangdk------------------------------------------------->   
  
static void *bwscon,*bankcon4,*bankcon5;   
static void *gpfcon,*gpfcon1;   
static void *extint0,*extint01;   
static void *intmsk;   
static void *dsc0,*dsc1;  
#define BWSCON           (0x48000000)  
#define BANKCON4     (0x48000014)  
#define BANKCON5     (0x48000018)  
#define GPFCON           (0x56000060)  //infact: GPGCON=0X56000060  
#define GPFCON1          (0x56000050)  
#define EXTINT0          (0x5600008C)   
#define EXTINT01         (0x56000088)  
#define INTMSK           (0x4A000008)  
#define DSC0    0x560000c4)  
#define DSC1     (0x560000c8)   
  
    bwscon=ioremap_nocache(BWSCON,0x0000004);   
    extint01=ioremap_nocache(EXTINT01,0x0000004);//   
      
    intmsk=ioremap_nocache(INTMSK,0x0000004);   
    dsc1=ioremap_nocache(DSC1,0x0000004);      
  
    writel(readl(bwscon)|0xc0000,bwscon);   
    writel(readl(dsc1)|(0xf
  
    s3c2410_gpio_cfgpin(S3C2410_GPF3, S3C2410_GPF3_EINT3);   
    writel((readl(extint01)&(~(3//eint3 high level   
    writel(readl(intmsk)&(~(1//      
  
  
//  //-----------yangdk------------------------------------------------->
static void *bwscon,*bankcon4,*bankcon5;
static void *gpfcon,*gpfcon1;
static void *extint0,*extint01;
static void *intmsk;
static void *dsc0,*dsc1;
#define BWSCON           (0x48000000)
#define BANKCON4         (0x48000014)
#define BANKCON5         (0x48000018)
#define GPFCON           (0x56000060)  //infact: GPGCON=0X56000060
#define GPFCON1          (0x56000050)
#define EXTINT0          (0x5600008C)  
#define EXTINT01         (0x56000088)
#define INTMSK           (0x4A000008)
#define DSC0        0x560000c4)
#define DSC1         (0x560000c8)
        bwscon=ioremap_nocache(BWSCON,0x0000004);
        extint01=ioremap_nocache(EXTINT01,0x0000004);//
       
        intmsk=ioremap_nocache(INTMSK,0x0000004);
        dsc1=ioremap_nocache(DSC1,0x0000004);       
        writel(readl(bwscon)|0xc0000,bwscon);
        writel(readl(dsc1)|(0xf
这时启动就OK了!
(完)

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/84348/showart_1387402.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP