111122-1257
Vxworks-dm9000驱动移植
前言
本次移植时基于公司自己的开发板:cpu:ppc8377,cpu自带2个网卡,然后扩展一个dm9000网卡,这次移植就是使用vxwroks6.6来移植dm9000.
Vxworks5.5和vxworks6.6对网络驱动有两种不同的模型,5.5下标准模型是end模型,而6.6下标准的是vxbus模型,但是vxworks6.6下可以兼容5.5的end模型,本次移植已经分别已经实现,故下面先对6.6下的end移植介绍,然后再对vxbus移植作介绍,因为本次移植没有改变太多的东西(因为vxbus下涉及很多东西,而这次成功移植的vxbus只是使用了里面很少的一部分),同时提交2个包,一个是end的target-111117-1738.rar,一个是vxbus的target-111121-1602.rar。
Vxworks-dm9000驱动移植 .............................................................................................. 1 前言 .................................................................................................................................... 1 一.Dm9000-vxwork6.6-end模型移植 ........................................................................... 2
1.概述 ......................................................................................................................... 2
1.1End模型 ....................................................................................................... 2 1.2.驱动层的内存缓冲池 .................................................................................. 2 2.涉及的代码 ............................................................................................................. 3
2-1:添加资源文件,config.h和configNet.h ................................................... 3
2-1-1.config.h ............................................................................................. 3 2-1-2. configNet.h ...................................................................................... 3 2-1-3 ........................................................................................................... 3 2-2.入口函数DM9000EndLoad(char* initString, void *pArg)分析和移植 ............................................................................................................................ 3
2-2-1.初始化网卡名 .................................................................................. 3 2-2-2.网卡资源calloc和资源结构体 ....................................................... 4 2-2-3.基地址,资源部分初始化 .............................................................. 5 2-2-4.map_op-->地址映射 ........................................................................ 5 2-2-5.网卡rest ........................................................................................... 6 2-2-6.注册函数结构体 .............................................................................. 7 2-2-7.网卡内存分配 .................................................................................. 8 2-2-8.网卡资源配置 .................................................................................. 8 2-2-9.最后,使end设备准备好 .............................................................. 9 2-2-10.ior,iow,phy_read,phy_write ............................................................ 9 2-2-11.endload总结 ................................................................................. 10 2-3 dm9000FuncTable ...................................................................................... 11 2-4.dm9000Start ............................................................................................ 11 2-5.dm9000Ioctl ............................................................................................ 12 2.6. dm9000Send .............................................................................................. 12 2-7.dm9000int .................................................................................................. 16
1
111122-1257
2-8. dm9000McastAdd dm9000MCastDel dm9000McastGet dm9000PollSend dm9000PollRcv等解析 ................................................................................... 22
二.Dm9000-vxwork6.6-vxbus模型移植 ..................................................................... 24
1. 前言: ................................................................................................................. 24 2.涉及代码 ............................................................................................................... 25
2-1.usrAppinit.c的void usrAppInit(void)函数 ........................................... 25 2.2. ethRegister ................................................................................................. 25 2.3.ethDevPlbRegistration ............................................................................ 25 2.4. ethInstInit,ethInstInit2, ........................................................................ 26 2.5. ethInstConnect ........................................................................................... 27 2.6. ethMuxConnect ......................................................................................... 27 2.7.vxbus的 end_device ................................................................................. 28 2.8. DM9000EndLoad ...................................................................................... 29 2.9.vxbus操作时使用vxbus独有特性探索之hwconf.c .............................. 29
三.移植过程中配到的困难 .......................................................................................... 30
一.Dm9000-vxwork6.6-end模型移植
1.概述 1.1End模型
End模型是比较成熟的模型,VxWorks网络协议栈增加一层MUX层。MUX层是VxWorks方便在网络接口硬件上实现多种协议而增加的一层。它主要用于管理底层的多种硬件的设备驱动,向上层不同协议提供统一的接口,降低了上层协议与底层物理硬件的藕合,使得网络驱动和上层协议彼此保持独立,既方便在现有硬件基础上实现新的上层协议,也利于用新的硬件支持原有的上层协议。
MUX与END的交互是通过提供一套可供底层调用接口服务来实现的,实现END驱动必须遵循这套接口关系。所以我们只要在驱动中实现对应的接口函数,我们的移植工作就成功了。
1.2.驱动层的内存缓冲池
缓冲池数据结构网络设备驱动与上层协议进行数据交换需要相应的内存缓冲,并且管理这些缓冲也需要相应的函数。VxWorks提供了netBufLib函数库用于创建和管理网络设备用到的内存缓冲池,网络设备驱动可以直接使用也可以在此基础上设计自己特定的内存缓冲池。数据以簇的形式保存,数据结构mBlks(内存块)和clBlks(簇块)形成的数据链结构则用于指定各个簇。
在clBlk之上是mBlk结构。该结构存储一个到clBlk的连接,也可以存储一个到另一个mBlk的连接。通过mBlk的连接,可以引用任意数量的数据。
下面的修改中会介绍对mblk等缓冲池的操作,这个地方是移植的重点,也是难点。对网卡
2
111122-1257
驱动的修改部分,主要为如下几个方面:开始的map_op(对硬件的初始化),endload,start,ioctl(基本不用动),send,dm9000int, reciveint,而send中断时只是在中断函数中对计数器进行减一操作。还有send/recive是对mblk的处理。而对poll等多播还有后面的函数基本上无需修改,直接使用普通的send和Rec即可。
2.涉及的代码
2-1:添加资源文件,config.h和configNet.h
2-1-1.config.h
在config.h中添加加上如下定义: #define INCLUDE_DM9000_END 2-1-2. configNet.h
在configNet.h中对结构体数组endDevTbl[] 仿照原先的定义,添加对dm9000网卡的定义,如下:
#ifdef INCLUDE_DM9000_END
{ 0, DM9000_LOAD_FUNC,DM9000_LOAD_STRING,1,NULL,FALSE}, #endif 2-1-3
在本文件的前面添加对应的宏定义 #ifdef INCLUDE_DM9000_END
#define DM9000_LOAD_FUNC DM9000EndLoad //定义装载函数
#define DM9000_LOAD_STRING \ //定义装载函数的参数,这个任意,因为后面没有用到
#define DM9000_BUFF_LOAD 1 //这个固定,不需要改动
IMPORT END_OBJ *DM9000_LOAD_FUNC (char *,void *); //把转载函数给声明出去 #endif
注意事项:这个地方定义一定要留意,如果没有写好的话,程序是进不去驱动的。
2-2.入口函数DM9000EndLoad(char* initString, void *pArg)分析和移植
2-2-1.初始化网卡名
if (initString == NULL){
DRV_LOG (DRV_DEBUG_LOAD, \ return (NULL); }
if (initString[0] == '\\0'){
DRV_LOG (DRV_DEBUG_LOAD, \
bcopy((char *)DM9000_DEV_NAME, initString, DM9000_DEV_NAME_LEN);
3
111122-1257
return (NULL); }
这段代码主要为设置网卡名字,上层会调用2次,程序开头把DM9000_DEV_NAME定义为: #define DM9000_DEV_NAME \ 2-2-2.网卡资源calloc和资源结构体
pDrvCtrl = (END_DEVICE *)calloc(sizeof (END_DEVICE), 1); DrvCtrl = pDrvCtrl; if (pDrvCtrl == NULL) {
DRV_LOG (DRV_DEBUG_LOAD, \printf(\goto errorExit; }
memset( (void*)pDrvCtrl, 0, sizeof( END_DEVICE ) );
上面这段代码主要是进行dm9000设备的资源申请处理,本次移植使用的资源结构体如下: typedef struct end_device {
END_OBJ end; /* The class we inherit from. */ END_ERR err; UINT IOBase;
int unit; /* unit number */ int ivec; /* interrupt vector */ int ilevel; /* interrupt level */ long flags; /* Our local flags. */ UCHAR enetAddr[6]; /* ethernet address */
CACHE_FUNCS cacheFuncs; /* cache function pointers */ CL_POOL_ID pClPoolId; /* cluster pool */
BOOL rxHandling; /* rcv task is scheduled */
UCHAR io_mode; /* 0:word, 2:byte */ char tx_pkt_cnt;
char device_wait_reset; UWORD queue_pkt_len;
UCHAR reg0; /* registers saved */ UCHAR nic_type; /* NIC type */
UCHAR op_mode; /* PHY operation mode */
UCHAR mcastFilter[8]; /* multicast filter */ UCHAR dummyBytes[3]; /* dummyBytes, for 32-bit align */ UCHAR txBuf[ETHERMTU + EH_SIZE + 6 + 64 ]; unsigned int io_addr; /这下面的2个参数是我加上去的,为了后面对寄存器操作方便 unsigned int io_data; } END_DEVICE;
这个资源结构体比较简单不过多介绍,下面在函数中会提到
4
111122-1257
2-2-3.基地址,资源部分初始化
(pDrvCtrl->flags) = 0;
(pDrvCtrl->op_mode) = DM9000_MEDIA_MODE; //设置phy的模式,为8,下面会涉及对phy的初始化
pDrvCtrl->ivec=17;
pDrvCtrl->ilevel=17; //这两个是中断号,设为一致,有一个没有用到 pDrvCtrl->unit=0; //这个为eth0后面的0 //下面的是网卡寄存器的基地址和数据地址
pDrvCtrl->io_addr=(unsigned int)(DM9000A_MAC_BASE);
pDrvCtrl->io_data=(unsigned int)(DM9000A_MAC_BASE + 0x00 + 0x4);
2-2-4.map_op-->地址映射
dm9000ConfigInit(pDrvCtrl);这个函数调用其实是map_op,其中涉及对io的映射等,特别是对mpc8377的pOr,pbr的初始化,还有mpc8377自己的UPMA,最后会把源码放在文档目录下,可以参看,初始化代码列为如下,不过多解释: static void ethAddrMap( ) { volatile unsigned int *pOr, *pBr; volatile unsigned int *pWbar3, *pWar3; volatile unsigned int *pBcr, *pCrr; /* map br3 register, and set the value */ pBr = ( volatile unsigned int *)(SYSTEM_CONFIG_BASE_ADDR + REG_BR3); *pBr = DM9000A_MAC_BASE | BR_DEFAULT; taskDelay(10); /* map or3 register, and set the value */ pOr = ( volatile unsigned int *)(SYSTEM_CONFIG_BASE_ADDR + REG_OR3); *pOr = OR_DEFAULT; //*pOr = 0xf0000106; taskDelay(10);
pWbar3=(volatile unsigned int *)(IMMR_BASE_ADDR + LBLAWBAR3_OFFSET_ADDR); *pWbar3 = DM9000A_MAC_BASE; /* 0xd3000000 */ taskDelay(10); pWar3=( volatile unsigned int *)(IMMR_BASE_ADDR + LBLAWAR3_OFFSET_ADDR); *pWar3 = 0x8000001b; /* enable, 256MB */ taskDelay(10); pBcr = ( volatile unsigned int *)(IMMR_BASE_ADDR + REG_LBCR); *pBcr = LBCR_DEFAULT;
5