网卡设备驱动之移植dm9000c网卡驱动

本文深入解析DM9000C网卡驱动的移植过程,涵盖基地址、中断号的设置,以及内存接口芯片的时序调整。通过分析厂家驱动,指导如何针对不同开发板进行差异性修改。

DM9000C 确定相异性

差异性 和 寄存器设置:
在这里插入图片描述
DM9000C 并不能使用内核提供的驱动,所以要从厂家提供的 DM9000C 的驱动上移植:

一,分析厂家提供的 DM9000C 网卡驱动程序:
在这里插入图片描述
若定义了宏“MODULE”才会使用到初始化“init_module”函数。

1,入口函数:
在这里插入图片描述
2,dmfe_probe1 函数:设置 硬件 。
在这里插入图片描述
网卡接口与内存接口一样,所以只需要去读某个地址即可。地址就表示网卡的某些寄存
器。对里面寄存器的操作只有厂家才知道。所以网卡驱动程序厂家一般都会提供一个
demo。各个开发板的“iobase”基地址肯定不一样。中断引脚可能也不一样。
在这里插入图片描述
3,int dmfe_open(struct net_device *dev)

在这里插入图片描述
下面是自已修改过的代码:
在这里插入图片描述
对于 2440 来说可以配置此中断是“上升沿”触发还是“下降沿”触发。
在入口函数“int __init dm9000c_init(void)”中有修改过的:
在这里插入图片描述

1,具体开发板的基地址:下面显示物理基地址是“0x20000000”,接着 ioremap。 2,也设置了中断号,此开发板的中断号是“IRQ_EINT7”
以上便为简单的厂家 DM9000C 驱动程序的分析。

二,从厂家提供的驱动程序上修改移植:

移植:找出差异性来修改。
DM9000 是一个内存接口的芯片,两个同样接有 DM9000 的开发板,最小差异:基地址、位
宽和中断引脚。
1,用什么地址访问此网卡芯片:
看片选引脚–nGCS4。
地址线和数据线上挂有网卡芯片、内存和 NORFLASH。如何访问一个网卡设备而不被其他
诸如“内存”或“NORFLASH”影响,则是将每个设备选中再访问。
让“nGCS4”片选信号为低电平。
看 2440 芯片手册“MEMORY CONTROLLER”一章:
在这里插入图片描述

只要 CPU 发出的物理地址是“0x2000_0000 - 0x2800_0000”之间时,引脚
“(nGCS4)”就会变成低电平。
(1). 接上板子上的外设,怎么确定它的地址?

  1. CPU 发出一个地址 A
  2. 存储控制器根据地址 A 的范围,决定让 nGCS0~nGCS7 中的哪个引脚输出低电平,假设是
    nGCS3
  3. 接在 nGCS3 的芯片就被选中
  4. 访问这个被选中的芯片的哪个地址呢?由地址线 A26~A0 决定。
    A26~A0 有 27 条地址线,寻址芯片是 128M

修改源代码:
在这里插入图片描述
Ioremap 0x20000000 ,是因为基地址就是 0x20000000 。
让片选引脚是低电平,CPU 发出来的地址必须是位于“0x2000_0000 - 0x2800_0000”之
间。所以上面就把基地址设置为“0x2000_0000”。
2,入口函数 与 出口函数:
原来的入口与出口函数在一个“#ifden”下面:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
移植修改:
去掉 #ifden 。。。#endif ; 将 init_module()改为“dm9000c_init()”入口
函数。
将出口函数“cleanup_module()”改成“dm9000c_exit()”,再加上修饰函数。如
下:

3,查看入口函数中的“probe”函数:
找到设置结构体的函数。
int __init dm9000c_init(void)
–>dmfe_dev = dmfe_probe();
–>struct net_device *dev = alloc_etherdev(sizeof(struct board_info)); 分配结构体
–>dmfe_probe1(dev); 设置
–>register_netdev(dev); 注册
int __init dmfe_probe1(struct net_device *dev)
–>outb(DM9KS_VID_L, iobase); 往iobase地址处写入一个值“DM9KS_VID_L”。DM9000C的索引寄存器
(cmd引脚为0)
id_val = inb(iobase + 4); 从iobase+4处读出某个值。读DM9000C的数据寄存器(cmd引脚为1)
outb(DM9KS_VID_H, iobase);
id_val |= inb(iobase + 4) << 8;
outb(DM9KS_PID_L, iobase);
id_val |= inb(iobase + 4) << 16;
outb(DM9KS_PID_H, iobase);
id_val |= inb(iobase + 4) << 24;
上面要设置“iobase”,这样就能outb(),和inb()能访问。

1,差异性:基地址。要设置 iobase :
当只要 CPU 发出的物理地址是“0x2000_0000 - 0x2800_0000”之间时,引脚“(nGCS4)”
就会变成低电平。所以基地址根据这个物理地址“0x2000_0000 - 0x2800_0000”设置而
来。
在这里插入图片描述
在这里插入图片描述
最后要看宏“MST_ETH_PHYS”。
下面修改“基地址”:在“入口函数”中设置。
在这里插入图片描述
大小的设置有些随意性,就是看用到了多少地址。这里用的不是很多,就直接把大小设置
民了 1M。因为 iobase 定义的是 int 型,ioremap()后要强制转换下,不然编译时会
有一个警告:

2.关于芯片版本
在这里插入图片描述
若芯片版本不是“0x1A”等“chip_info”条件不满足时就返回一个错误。实际中的开
发板网卡不适合这个条件,但注释掉也能使用此驱动,所以这里直接注释去。
//if((db->chip_revision!=0x1A) || ((chip_info&(1<<5))!=0) ||
((chip_info&(1<<2))!=1)) return -ENODEV;
在实际的移植中,因为此句的条件判断而返回时,在不同的地址加打印语句来判断的出错
的地方而发现此句要修改。

3,中断号:
网卡芯片接收到数据后,会产生一个中断(网卡芯片里面也会有内存,因为它接收到数据
后是先放在自已的内存里,然后再产生一个中断)。在“中断服务程序”里再将此缓存的
数据从网卡芯片里拿出来构造成一个“skb_buff”,然后才提交上去(网络 7 层模型的
其他层)。发送时也是从“skb_buff”里拿出数据交给网卡芯片。网卡芯片硬件就会再
把数据从 skb_buff 中取出发送出去,发送完成后就会产生一个中断。
在这里插入图片描述
在这里插入图片描述
4,dev->open = &dmfe_open; 里面有使用中断。
–>if (request_irq(dev->irq,&dmfe_interrupt, IRQF_TRIGGER_RISING,dev->name,dev)) return -
EAGAIN;
在这里插入图片描述
对于 2440 来说,中断可以设置成“上升沿触发”或“下降沿触发”。可以参考以前“按键
中断”驱动中的代码
在这里插入图片描述
以上设置了差异性的部分:iobase 基地址,中断号。

在完成基地址,中断号的设置后,直接在厂家驱动的基础上编译驱动成功。
在这里插入图片描述

编译通过。但这个驱动程序还是有一个缺点,就是各信号间时序的设置。但这里没有设置
前,也能使用,是因为 UBOOT 中设置好了。要是想写一个不依赖于 UBOOT 的网卡驱动程
序,就得自已设置

在这里插入图片描述

网卡是内存一样的接口,地址信号,读写脉冲,这些信号的读写时序会有要求。
CPU 发指令给内存控制器,再由“内存控制器”负责发读写、地址等信号给网卡芯片,这
些信号间的时间要设置。所以还要设置一项“MEMORY CONTROLLER”。
在这里插入图片描述
在这里插入图片描述
等待信号:
当 CPU 访问网卡芯片时,若此时 DM9000 还没准备就绪,这时网卡就可以给 CPU 发出一
个等待信号(nWAIT).从原理图上看 DM9000 没有“nWAIT”等待信号。
在这里插入图片描述
③,BUS WIDTH & WAIT CONTROL REGISTER (BWSCON):
总线位宽 和 等待寄存器。BWSCON 寄存器主要用来设置外接存储器的总线宽度和等待状
态。
a.STx:启动/禁止 SDRAM 的数据掩码引脚,对于 SDRAM,此位为 0;对于 SRAM,此位为 1。
b.WSx:是否使用存储器的 WAIT 信号,通常设为 0 c.DWx:使用两位来设置存储器的位宽:00-8 位,01-16 位,10-32 位,11-保留。
d.比较特殊的是 BANK0 对应的 4 位,它们由硬件跳线决定,只读。
在这里插入图片描述
DW4 的描述为 BANK4 的带宽,DM9000 接了 16 条地址线,呢么带宽就是 16,这里选 01
WS4 的描述为是否为 BANK4 使用等待状态,DM9000 没有接 WAIT 引脚,所以可以不管这个字段
ST4 的描述为是否为 BANK4 使用 UB/LB(写高/低字节使能),DM9000 没有接 nWBE[3:0]这 4 个
引脚,所以也不管这个字段.

设置位宽 DW4 bit[17:16]:
看原理图上 DM9000 使用了多少条数据线。看上面的 DM9000 原理图,数据线是“LDATA0
~ 15”一共 16 条 即 16 位。
设置等待 WS4 bit[18]:不等待.
设置功能引脚 ST4 bit[19]:这个不很了解,就直接按默认写“0”。
在这里插入图片描述

DM9000C 设置时序

位宽&等待状态寄存器 BWSCON(BUS WIDTH&WAIT STATUS CONTROL REGISTER),每四
位控制一个 memory bank,根据 S3C2440 手册,涉及 dm9000 的 4 个引脚是 16~19。默认值
是 0x000000。

  1. ST4[19]:SRAM 是否使用 UB/LB(upper byte/lower byte)。 0:不使用 UB/LB;1:使用 UB/LB。
  2. WS4[18]:WAIT 状态。
    0:禁止 WAIT;1:使能 WAIT。
  3. DW4[16:17]:数据总线宽度。
    00:8 位;01:16 位;10:32 位;11:保留。

接着,BANK4 控制寄存器 BANKCON4(BANK CONTROL REGISTER),用于控制 BANK4 外接设备的
访问时序。默认值是 0x0700。

设置 BANK4 寄存器

  1. Tacs[14:13]:地址建立时间。
    00:0 时钟周期;01:1 时钟周期;10:2 时钟周期;11:4 时钟周期。
  2. Tcos[12:11]:
    片选建立时间。00:0 时钟周期;01:1 时钟周期;10:2 时钟周期;11:4 时钟周期。
  3. Tacc[10:8]:地址周期。
    000:1 时钟周期;001:2 时钟周期;… 111:14 时钟周期。
  4. Tcoh[7:6]:片选保持时间。
    00:0 时钟周期;01:1 时钟周期;10:2 时钟周期;11:4 时钟周期。
  5. Tcah[5:4]:地址保持时间。
    00:0 时钟周期;01:1 时钟周期;10:2 时钟周期;11:4 时钟周期。
  6. Tcap[3:2]:页模式存取周期。
    00:2 时钟周期;01:3 时钟周期;10:4 时钟周期;11:6 时钟周期。
  7. PMC[1:0]:页模式配置。
    00:1 data;01:4 data;10:8 data;11:16 data。
    最后,在 arch/arm/mach-s3c2410/include/mach/regs-mem.h 中,
    #define S3C2410_BWSCON_DW4_16 (1<<16)
    #define S3C2410_BWSCON_WS4 (1<<18)
    #define S3C2410_BWSCON_ST4 (1<<19)
    理解了寄存器 BWSCON 和 BANKCON4 的含义之后,上述代码的作用就很明显了。

看“时间参数”:

在这里插入图片描述
这些值如何设置,只能看 DM9000 的芯片手册。若不想看,则可以使用上面 bit[0-14]
中每个位域的最大值。如 PMC bit[1:0]就使用“11=16data”这个值。用起来之后,
你想让 DM9000 的访问速度更快时,就得去看 DM9000 的芯片手册来修改上面的值。
设置这个时间值的过程,先找到寄存器的位域定义,再找到 2440 上这些时间的时序
图,按照时序图知道它们的关系。然后再找到 DM9000 的芯片手册看芯片上的规定读写时
序,两两时序对比计算,得出这些寄存器位域值的设置结果。

2440,PROGRAMMABLE ACCESS CYCLE
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值