www.pudn.com > MPC8241BSP.rar > rtl8139Config.c


/************************************************************************ 
* 版权所有 (C)2003, 深圳市中兴通讯股份有限公司。 
*  
* 文件名称: rtl8139Config.c 
* 文件标识:  
* 内容摘要: 提供对8139的各种配置函数 
* 其它说明: 暂无 
                  
* 当前版本: V1.0 
* 作    者: 邹同亮 
* 完成日期: 2003年1月11日 
*  
* 修改记录1:增加了读写8139寄存器和Descriptor的函数,并加了注释 
*    修改日期:2003-5-20 
*    版 本 号: 
*    修 改 人: 
*    修改内容:  
* 修改记录2:… 
************************************************************************/ 
#include "vxWorks.h" 
#include "muxlib.h" 
#include "etherLib.h" 
#include "end.h" 
#include "endLib.h" 
#include "ifLib.h"  
#include "ipProto.h"  
 
#include "rtl8139Config.h"  
#include "rtlcpp.h"  
 
 
IMPORT STATUS ipDetach(int unit, char * pDevice ); 
IMPORT void netPoolShow(NET_POOL_ID pNetPool); 
 
 
/************************************************************************ 
* 函数名称: Set8139DeviceNum 
* 功能描述: 初始化8139对应的资源表入口 
* 输入参数: unit:    	网口的设备号,如rtl0的0   
*			 pciBus:	PCI总线号   
*			 pciDevice:网口PCI设备号 
*			 pciFunc:	网口PCI功能号 
* 输出参数: 无 
* 返 回 值: OK:    加载成功 
            ERROR: 加载不成功             
* 其它说明: 无 
* 修改日期:    版本号     修改人	      修改内容 
* ----------------------------------------------- 
* 2002/12/24    V1.0       汪康宏          创建 
* 2003/03/28    V1.01      邹同亮          设置前先判断是否存在 
************************************************************************/ 
STATUS Set8139DeviceNum(int unit, UINT32  pciBus, UINT32 pciDevice, UINT32  pciFunc) 
{ 
    UINT32 		membaseCsr;  /* 网口内存空间基地址 */ 
    UINT32 		iobaseCsr;	 /* 网口IO空间基地址 */ 
    UINT16	    deviceId;    /* 设备类型号 */ 
    char 		irq;         /* 网口中断向量号 */ 
	 
	/* 填写PCI设备表 */				 
	pRsrc [unit] = rtl81x9PciResrcs + unit;  
				 
	pRsrc [unit]->pciBus    = pciBus; 
	pRsrc [unit]->pciDevice = pciDevice; 
	pRsrc [unit]->pciFunc   = pciFunc; 
				 
	 
    UnitNum++; 
    needScan8139 = 0;     
     
	pciConfigInWord (pciBus, pciDevice, pciFunc, PCI_CFG_DEVICE_ID, &deviceId); 
	if ((RTL_DEVICEID_8129 != deviceId) &&	(RTL_DEVICEID_8139 != deviceId)) 
	{ 
		return(ERROR);		 
	}	 
	 
	pRsrc [unit] = rtl81x9PciResrcs + unit;		 
	 
	 
	/* 获得网口PCI的内存基地址、IO基地址、中断向量号 */	 
	pciConfigInLong (pRsrc[unit]->pciBus,  
		pRsrc[unit]->pciDevice,  
		pRsrc[unit]->pciFunc, 
		PCI_CFG_BASE_ADDRESS_0, &iobaseCsr); 
	 
	pciConfigInLong (pRsrc[unit]->pciBus,  
		pRsrc[unit]->pciDevice,  
		pRsrc[unit]->pciFunc, 
		PCI_CFG_BASE_ADDRESS_1, &membaseCsr); 
	 
	pciConfigInByte (pRsrc[unit]->pciBus,  
		pRsrc[unit]->pciDevice,  
		pRsrc[unit]->pciFunc, 
		PCI_CFG_DEV_INT_LINE, &irq);	 
	 
	membaseCsr   &= PCI_MEMBASE_MASK; 
	iobaseCsr    &= PCI_IOBASE_MASK; 
	 
	/* 填写到资源表 */	 
	pRsrc[unit]->membaseCsr   = membaseCsr; 
	pRsrc[unit]->iobaseCsr    = iobaseCsr; 
	pRsrc[unit]->irq          = irq; 
	pRsrc[unit]->irqvec       = irq;     
	 
	 
	/* 使能内存空间和IO空间映射 */	 
	pciConfigOutWord (	pRsrc[unit]->pciBus,  
		pRsrc[unit]->pciDevice,  
		pRsrc[unit]->pciFunc, 
		PCI_CFG_COMMAND, PCI_CMD_IO_ENABLE | 
		PCI_CMD_MEM_ENABLE | PCI_CMD_MASTER_ENABLE); 
	 
	/* 禁止睡眠模式 */	 
	pciConfigOutWord (pRsrc[unit]->pciBus,  
		pRsrc[unit]->pciDevice,  
		pRsrc[unit]->pciFunc,  
		PCI_CFG_MODE,  
		SLEEP_MODE_DIS);		 
     
    return OK; 
}	 
 
 
/************************************************************************ 
* 函数名称: init8139net 
* 功能描述: 加载8139网口 
* 输入参数: unit:    	网口的设备号,如rtl0的0   
*			 pciBus:	PCI总线号   
*			 pciDevice:网口PCI设备号 
*			 pciFunc:	网口PCI功能号 
*			 clusterNum:网口缓冲区大小,缺省值为2000 
* 输出参数: 无 
* 返 回 值: OK:    加载成功 
            ERROR: 加载不成功             
* 其它说明: 无 
* 修改日期:    版本号     修改人	      修改内容 
* ----------------------------------------------- 
* 2002/12/24    V1.0        邹同亮          创建 
************************************************************************/ 
STATUS  init8139net(int unit,   UINT32  pciBus, UINT32 pciDevice, UINT32  pciFunc, UINT32 clusterNum) 
{ 
    void *pInitC; 
  
 	/* 初始化8139对应的资源表入口 */ 
 	if(Set8139DeviceNum(unit, pciBus, pciDevice, pciFunc) !=OK) 
 	{ 
 		return ERROR; 
 	}   
  	g_ul8139ClusterNum = clusterNum; 
  	 
  	/* 加载8139设备到mux并启动之 */ 
    pInitC = (void *)muxDevLoad(unit, 
                                sysRtlcpEndLoad, 
                                "", 
                                1, NULL); 
    if (pInitC == NULL) 
    { 
        printf("muxLoad failed!\n"); 
        return ERROR; 
    } 
    else 
    { 
         
        if (muxDevStart(pInitC) != OK) 
        { 
            printf("muxDevStart failed!\n"); 
            return ERROR; 
        } 
    }  
	return OK; 
} 
 
	 
/************************************************************************ 
* 函数名称:  Get8139MacAddr 
* 功能描述:  用于获得8139的mac地址 
* 输入参数: unit:    网口的设备号,如rtl0的0             
* 输出参数: pucAddr: 用于传出MAC地址.为6个字节的数组,如0x00,0x01,0xaf,0x04, 
            0xb,0x16 
* 返 回 值: OK:    成功 
            ERROR: 不成功             
* 其它说明: 无 
* 修改日期:    版本号     修改人	      修改内容 
* ----------------------------------------------- 
* 2002/12/24   V1.0        马书宇          创建 
************************************************************************/ 
STATUS Get8139MacAddr(int unit, unsigned char * pucAddr) 
{ 
	END_OBJ  *FindEnd; 
	char NetDevice[5] = "rtl"; 
	 
	FindEnd = endFindByName(NetDevice,unit); 
	if(FindEnd == NULL) 
	{ 
		printf("endFindByName error\n"); 
		return (ERROR); 
	} 
	if((*(FindEnd->pFuncTable->ioctl))(FindEnd->devObject.pDevice, EIOCGADDR, pucAddr) == ERROR) 
	{ 
		printf("GetNetMac error\n"); 
		return (ERROR); 
	} 
	return (OK); 
} 
 
 
/************************************************************************ 
* 函数名称:  Set8139MacAddr 
* 功能描述:  用于动态修改8139的mac地址 
* 输入参数: unit:    网口的设备号,如rtl0的0 
            pucAddr: 用于传入MAC地址.为6个字节的数组,如0x00,0x01,0xaf,0x04, 
             0xb,0x16 
* 输出参数: 无 
* 返 回 值: OK:    成功 
            ERROR: 不成功             
* 其它说明: 修改网口MAC地址之前,必须保存当前掩码和IP地址,卸掉协议栈, 
            修改之后,再装载协议栈,恢复原来地掩码和IP地址 
* 修改日期:    版本号     修改人	      修改内容 
* ----------------------------------------------- 
* 2002/12/24   V1.0        马书宇          创建 
************************************************************************/ 
STATUS Set8139MacAddr(int unit, unsigned char * pucAddr) 
{ 
	END_OBJ *FindEnd; 
	char  IpAddress[40]; 
	int NetMask[2];	 
	char NetDevice[4] = "rtl"; 
	char DeviceName[4] = "rtl"; 
	 
	NetDevice[3] = unit + 0x30; 
	 
	/* 判断网口是否存在 */ 
	FindEnd = endFindByName(DeviceName, unit); 
	if(FindEnd == NULL) 
	{ 
		printf("endFindByName error\n"); 
		return (ERROR); 
	} 
	 
	/* 修改前先保存一些IP层信息,为修改后恢复用 */ 
	if(ifMaskGet(NetDevice, NetMask) == ERROR) 
	{ 
		printf("ifMaskGet error\n"); 
		return (ERROR); 
	} 
	if(ifAddrGet(NetDevice, IpAddress) == ERROR) 
	{ 
		printf("ifAddrGet error\n"); 
		return (ERROR); 
	} 
	if(ipDetach(unit, DeviceName) == ERROR) 
	{ 
		printf("ipDetach error\n"); 
		return (ERROR); 
	}	 
	 
	/* 修改MAC地址 */ 
	if((*(FindEnd->pFuncTable->ioctl))(FindEnd->devObject.pDevice, EIOCSADDR, pucAddr) == ERROR) 
	{ 
		printf("SetNetMac error\n"); 
		return (ERROR); 
	} 
 
	/* 恢复以前的设置 */ 
	if(ipAttach (unit, DeviceName) == ERROR) 
	{ 
		printf("ipAttach error\n"); 
		return (ERROR); 
	} 
	 
	if(ifMaskSet(NetDevice, *NetMask) == ERROR) 
	{ 
		printf("ifMaskSet error\n"); 
		return (ERROR); 
	}	 
 
	if(ifAddrSet(NetDevice, IpAddress) == ERROR) 
	{ 
		printf("ifAddrSet error, errno:%x\n",errno);		 
		/* return (ERROR); */ 
	} 
		 
	return (OK); 
} 
 
/************************************************************************ 
* 函数名称:  Set8139MacWithoutIP 
* 功能描述:  用于动态修改8139的mac地址 
* 输入参数: unit:    网口的设备号,如rtl0的0 
             pucAddr: 用于传入MAC地址.为6个字节的数组,如0x00,0x01,0xaf,0x04, 
             0xb,0x16 
* 输出参数: 无 
* 返 回 值: OK:    成功 
             ERROR: 不成功             
* 其它说明: 用于没有加vxWorks协议栈的网口的MAC地址修改 
* 修改日期:    版本号     修改人	      修改内容 
* ----------------------------------------------- 
* 2003/06/16   V1.0        邹同亮          创建 
************************************************************************/ 
STATUS Set8139MacWithoutIP(int unit, unsigned char * pucAddr) 
{ 
	END_OBJ * FindEnd; 
	char  IpAddress[40]; 
	int NetMask;		 
	char DeviceName[4] = "rtl"; 
	char NetDevice[4] = "rtl"; 
	 
	NetDevice[3] = unit + 0x30; 
	 
	/* 判断网口是否存在 */ 
	FindEnd = endFindByName(DeviceName, unit); 
	if(FindEnd == NULL) 
	{ 
		printf("endFindByName error\n"); 
		return (ERROR); 
	}	 
	 
	/* 修改MAC地址 */ 
	if((*(FindEnd->pFuncTable->ioctl))(FindEnd->devObject.pDevice, EIOCSADDR, pucAddr)==ERROR) 
	{ 
		printf("SetNetMac error\n"); 
		return (ERROR); 
	}		 
	return (OK); 
} 
 
/************************************************************************ 
* 函数名称: writeethead8139 
* 功能描述: 改8139MAC地址 
* 输入参数: unit:    	  网口的设备号,如rtl0的0   
*			 MacAddress[6]: MAC地址   
* 输出参数: 无 
* 返 回 值: OK:    加载成功 
            ERROR: 加载不成功             
* 其它说明: 无 
* 修改日期:    版本号     修改人	      修改内容 
* ----------------------------------------------- 
* 2002/12/24    V1.0       马书宇          创建 
************************************************************************/ 
void WriteetHead8139(int unit,unsigned char MacAddress[6]) 
{ 
	RTL81X9END_DEVICE FakeResources[1];  
	RTL81X9END_DEVICE *FakepReso; 
	 
	unsigned short eeprom[3] = {0}; 
	unsigned char enetAddr[6];	 
	FakepReso     = &FakeResources [0];   
	FakepReso->devAdrs = pRsrc[unit]->membaseCsr; 
	enetAddr[0] = MacAddress[0]; 
	enetAddr[1] = MacAddress[1]; 
	enetAddr[2] = MacAddress[2]; 
	enetAddr[3] = MacAddress[3]; 
	enetAddr[4] = MacAddress[4]; 
	enetAddr[5] = MacAddress[5]; 
	 
	rtl81x9ReadEEPROM(FakepReso, (unsigned char*)eeprom, 0x7, 3, 0);  
	eeprom[0] = ((enetAddr[1]<<8)|enetAddr[0]); 
	eeprom[1] = ((enetAddr[3]<<8)|enetAddr[2]); 
	eeprom[2] = ((enetAddr[5]<<8)|enetAddr[4]); 
	 
	rtl81x9WriteENABLE(FakepReso); 
	rtl81x9WriteEEPROM(FakepReso, (unsigned char*)eeprom, 0x7, 3, 0);  
	rtl81x9WriteDISABLE(FakepReso); 
	/* rtl81x9ReadEEPROM(FakepReso,  (unsigned char*)eeprom, 0x7, 3, 0); */ 
} 
 
 
#if 0 
/************************************************************************ 
* 函数名称: Set8139DeviceNum 
* 功能描述: 把配置文件写到8139带的EEPROM 
* 输入参数: unit:    	网口的设备号,如rtl0的0   
* 输出参数: 无 
* 返 回 值: OK:    加载成功 
            ERROR: 加载不成功             
* 其它说明: 调试用 
* 修改日期:    版本号     修改人	      修改内容 
* ----------------------------------------------- 
* 2002/12/24    V1.0       汪康宏          创建 
 
************************************************************************/ 
void write8139DefaultConfig(int unit) 
{ 
	RTL81X9END_DEVICE FakeResources [1];  
	RTL81X9END_DEVICE *FakepReso;	 
	unsigned char defaultConfig[80]; 
	int i;  
	FILE *ptfp = NULL; 
 
	 
	STATUS iRetVal; 
	ULONG dwFileSize =0; 
			 
	unsigned char * pWrtBuff = defaultConfig; 
	unsigned char rdBuff[80], *pRdBuff; 
 
	pRdBuff = rdBuff; 
	 
	bzero(pWrtBuff, sizeof(defaultConfig)); 
	bzero(rdBuff, sizeof(rdBuff)); 
	 
	ptfp = fopen("/tgtsvr/8139.bit","rb"); 
	 
	if(NULL == ptfp) 
	{ 
		printf("Can not open 8139 EEPROM file!\n"); 
		return; 
	} 
	 
	/* 将文件装载到RAM中 */ 
	iRetVal = fread(rdBuff, 1, 64, ptfp); 
	if(iRetVal != dwFileSize) 
	{	 
		printf("\nfile read error"); 
		fclose(ptfp); 
		return; 
	}	 
 
	fclose(ptfp); 
	 
	for(i=0; i<64; i++) 
	{ 
		pWrtBuff[i+1] = rdBuff[i]; 
		pWrtBuff[i] = rdBuff[i+1]; 
		i++; 
	} 
	 
	FakepReso     = &FakeResources [0];   
	FakepReso->devAdrs = pRsrc[unit]->membaseCsr; 
	 
	rtl81x9WriteENABLE(FakepReso); 
	taskDelay(1); 
	 
	rtl81x9WriteEEPROM(FakepReso, pWrtBuff, 0, 32, 0); 
		 
	rtl81x9WriteDISABLE(FakepReso); 
	 
	bzero(rdBuff, sizeof(rdBuff)); 
	 
	rtl81x9ReadEEPROM(FakepReso, pRdBuff, 0, 32, 0); 
	 
} 
#endif 
 
/************************************************************************ 
* 函数名称: sysChecki8139Loopback 
* 功能描述: 8139的自环测试 
* 输入参数: unit:    网口的设备号,如rtl0的0             
* 输出参数: 无 
* 返 回 值: 0:   成功 
            >0: 各种错误状态             
* 其它说明: 先进入轮循环方式,发10包再接收10包,比较收发数据是否一致 
* 修改日期:    版本号     修改人	      修改内容 
* ----------------------------------------------- 
* 2002/12/24   V1.0       邹同亮          创建 
************************************************************************/ 
ULONG sysChecki8139Loopback(int unit) 
{ 
    USHORT 		wLen; 
    USHORT 		wTmp;     
    USHORT  	wBMCR;   /* 存放老的BMCR寄存器值 */ 
    M_BLK_ID 	pMblk;   /* 发送包Mblk指针 */ 
    M_BLK_ID 	pMblkR;  /* 接收包Mblk指针 */ 
    END_OBJ  	*FindEnd;/* 网口对应的END_OBJ */	 
    CL_BLK_ID	pClBlk;	  
    char		*pCluster; 
    char 		strSPacket[200],strRPacket[200];  /* 发送和接收数据缓冲区 */   
    ULONG	    dwTxConfig; /* 存放老的发送配置寄存器值 */ 
    ULONG	    dwRet, dwRetValue  = 0;  
    RTL81X9END_DEVICE *pDrvCtrl; /* 网口对应的控制块 */ 
    /*     
    int iii; 
    */ 
	 
    wLen = 64 ; 
    if(unit > 100) 
    { 
		printf("8139网口编号不能超过100\n"); 
		return 1; 
    } 
	 
    /* 初始化收发缓冲区 */ 
    for( wTmp = 0 ; wTmp < 12 ; wTmp++ ) 
    { 
        strSPacket[wTmp] = 0xff; 
        strRPacket[wTmp] = 0; 
    } 
	 
    for( wTmp = 12 ; wTmp < 100; wTmp++) 
    { 
        strSPacket[wTmp] = 0; 
        strRPacket[wTmp] = 0; 
    }	     
    strcpy(&strSPacket[12],"This is a Network test frame!"); 
     
    /* 测试前先判断网口是否存在 */ 
    FindEnd = endFindByName("rtl", unit);	 
    if(FindEnd == NULL ) 
    { 
		printf("找不到编号为%d的8139网口\n", unit); 
		return 1;    	 
    } 
    pDrvCtrl = FindEnd->devObject.pDevice; 
    if(pDrvCtrl == NULL ) 
    { 
		printf("pDrvCtrl == NULL\n"); 
		return 1; 
    } 
     
    /* 测试前先配置网口为自环和轮循方式 */ 
    printf("\ni8139 loopback...\n"); 
    rtl81x9Ioctl( pDrvCtrl, EIOCPOLLSTART, NULL);     
    dwTxConfig  = rtl81x9CsrReadLong(pDrvCtrl, RTL_REGS_TX_CONFIG, RTL_WIN_0); 
    wBMCR =  rtl81x9CsrReadWord(pDrvCtrl, RTL_REGS_MII_BMCR, RTL_WIN_0);  
    rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_MII_BMCR, 0x2d00, RTL_WIN_0); /* 配置自环前先禁止网口的自动协商功能 */ 
    rtl81x9CsrWriteLong(pDrvCtrl, RTL_REGS_TX_CONFIG, (dwTxConfig|0x00060000), RTL_WIN_0); /* 设置自环方式 */        
    taskDelay(50); 
     
	/* 清除已接收的数据 */ 
    while(1) 
    { 
		pMblkR = mBlkGet(pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA); 
		if(pMblkR == NULL) 
			break; 
		 
		if(rtl81x9PollReceive( pDrvCtrl , pMblkR ) == OK) 
		{ 
			netMblkClChainFree(pMblkR); 
		}		 
		else 
		{ 
			netMblkFree(pDrvCtrl->end.pNetPool, pMblkR); 
			break; 
		} 
    } 
	 
    	 
    /* 发10包数据 */	 
    wTmp =0; 
    dwRet = 1; 
    do 
    {	 
		 
		pMblk = mBlkGet(pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA); 
		if(pMblk == NULL) 
		{ 
			printf("error!\n i8139 can't alloc mblk !\n");		 
			dwRetValue = 0xfe; 
			goto testEnd; 
		} 
		 
		if((pClBlk = netClBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT)) == NULL) 
		{ 
			netMblkFree(pDrvCtrl->end.pNetPool, pMblk); 
			DRV_LOG(DRV_DEBUG_ERR,"Out of Cluster Blocks!\n", 1, 2, 3, 4,5, 6);			 
			goto testEnd; 
		}   
		 
		pCluster = netClusterGet(pDrvCtrl->end.pNetPool, pDrvCtrl->pClPoolId);     
		if (pClBlk ==	NULL) 
		{		 
			netMblkFree(pDrvCtrl->end.pNetPool, pMblk); 
			netClBlkFree(pDrvCtrl->end.pNetPool, pClBlk); 
			DRV_LOG	(DRV_DEBUG_POLL_TX,	"Get tx	buffer error\n", 1, 2, 3, 4, 5,	6);		 
			goto testEnd;	 
		} 
		 
		 
		netClBlkJoin (pClBlk, pCluster, wLen, NULL, 0, 0, 0); 
		netMblkClJoin (pMblk, pClBlk);				 
		 
		RTL_CACHE_INVALIDATE (pMblk->mBlkHdr.mData,	wLen); 
        memcpy( pMblk->m_data, strSPacket, wLen ); 
        pMblk->m_len = wLen; 
        pMblk->mBlkHdr.mFlags |= M_PKTHDR; 
        pMblk->mBlkPktHdr.len = pMblk->m_len; 
         
        dwRet = rtl81x9PollSend( pDrvCtrl , pMblk );  
        if(dwRet == OK ) 
        { 
			printf("8139 Send Number %d frame correct! \n", wTmp+1);			 
        } 
        else 
        { 
			printf("8139 send Number %d frame incorrect! \n", wTmp+1);			 
        } 
        /* 
        if(  (dwRet = rtl81x9PollSend( pDrvCtrl , pMblk ) ) !=  EAGAIN ) 
        { 
		break; 
        } 
        */ 
        taskDelay(20); 
        wTmp++; 
         
    }while( wTmp < 10 );      
     
    /* 判断接收到的数据是否正确 */ 
    wTmp =0; 
    do 
    { 
		pMblkR = mBlkGet(pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA);	 
		if( pMblkR == NULL ) 
		{ 
			printf("error!\n i8139 can't alloc mblk !\n");		 
			dwRetValue = 0x4; 
			goto testEnd;	 
		} 
		 
		pMblk->mBlkHdr.mLen = 100;  
		 
		dwRet = rtl81x9PollReceive(pDrvCtrl, pMblkR);         
		if( dwRet == OK ) 
		{ 
			netMblkToBufCopy (pMblkR, &strRPacket[0], NULL); 
			netMblkClChainFree(pMblkR);  
			/* 
			printf("receive wLen is 0x%x\n",pMblkR->mBlkHdr.mLen);			 
			for(iii=0;iiimBlkHdr.mLen;iii++) 
			{ 
			if(iii%16==0&&iii!=0) 
			printf("\n"); 
			printf("%02x ",(int)*(pMblkR->mBlkHdr.mData+iii)); 
			}		 
			printf("\n"); 
			*/ 
			if( bcmp( strSPacket, strRPacket, wLen ) == 0 ) 
			{	 
				printf("8139 Recv Number %d frame correct! \n", wTmp+1);			 
				dwRetValue = OK; 
			} 
			else 
			{				 
				printf("8139 Recv Number %d frame incorrect! \n", wTmp+1);			 
				dwRetValue = 2;				 
			} 
		} 
		else 
		{ 
			netMblkFree(pDrvCtrl->end.pNetPool, pMblkR); 
			printf("error!\n 8139 can't received frame !\n"); 
			dwRetValue = 3 ; 
			break; 
		} 
		wTmp++; 
		 
    }while(wTmp < 10); 
     
   	/* 恢复测试前状态并返回测试结果 */ 
testEnd:	 
	rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_TX_CONFIG, dwTxConfig, RTL_WIN_0); 
	rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_MII_BMCR, wBMCR,RTL_WIN_0);	 
	rtl81x9Ioctl( pDrvCtrl, EIOCPOLLSTOP, NULL );	 
	taskDelay(100);	 
    return dwRetValue; 
} 
 
 
/************************************************************************ 
* 函数名称: SetRtl8139State 
* 功能描述: 设置8139的各种状态 
* 输入参数: unit:    网口的设备号,如rtl0的0  
*			 ucState   网口状态,见rtl8139Config.h中的宏定义         
* 输出参数: 无 
* 返 回 值: OK:   成功 
             ERROR:失败 
* 其它说明: 仅供内部测试用 
* 修改日期:    版本号     修改人	      修改内容 
* ----------------------------------------------- 
* 2002/05/21    V1.0       邹同亮          创建 
************************************************************************/ 
STATUS SetRtl8139State(int unit,unsigned char ucState) 
{ 
    RTL81X9END_DEVICE 	*pDrvCtrl = NULL;  
    USHORT  wBMCR =0; 
    ULONG	dwTxConfig =0; 
     
    /* 判断网口是否存在,不存在返回 */ 
    pDrvCtrl = (RTL81X9END_DEVICE *)endFindByName("rtl", unit); 
    if(pDrvCtrl == NULL ) 
    {    	 
    	return ERROR; 
    } 
   
  	rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_INTR_MASK, 0x00, NONE); 
  	dwTxConfig  = rtl81x9CsrReadLong(pDrvCtrl, RTL_REGS_TX_CONFIG, RTL_WIN_0);  	 
  	wBMCR =  rtl81x9CsrReadWord(pDrvCtrl, RTL_REGS_MII_BMCR, RTL_WIN_0); 
  	 
  	/* 检查并配置8139为正常工作状态 */ 
  	if( ucState == RTL8139_STATE_NORM) 
  	{  		 
  		rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_MII_BMCR, wBMCR|0x3000, RTL_WIN_0);  /* 自动协商 */ 
    	rtl81x9CsrWriteLong(pDrvCtrl, RTL_REGS_TX_CONFIG, (dwTxConfig&0xfff9ffff), RTL_WIN_0); /* 非自环 */ 
    	rtl81x9CsrWriteWord	(pDrvCtrl, RTL_REGS_INTR_MASK, RTL_VALID_INTERRUPTS, NONE); 
    	taskDelay(20); 
    	return OK; 
  	} 
  	 
  	rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_MII_BMCR, wBMCR&0xefff, RTL_WIN_0); /* 配置各种状态前先禁止网口的自动协商功能 */ 
  	wBMCR =  rtl81x9CsrReadWord(pDrvCtrl, RTL_REGS_MII_BMCR, RTL_WIN_0); 
  	 
  	/* 检查并配置8139为自环状态 */ 
    if(ucState & RTL8139_STATE_LOOP) 
    {	    	 
    	rtl81x9CsrWriteLong(pDrvCtrl, RTL_REGS_TX_CONFIG, (dwTxConfig|0x00060000), RTL_WIN_0); 
    	taskDelay(20); 
    }     
    /* 检查并配置8139速度为100M */ 
    if(ucState & RTL8139_STATE_100M) 
  	{	  		 
  		/* 100M */ 
    	rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_MII_BMCR, (wBMCR|0x2100), RTL_WIN_0);    	    	    	 
    } 
     
    /* 检查并配置8139速度为10M */ 
    if(ucState & RTL8139_STATE_10M) 
    {    
    	/* 10M */ 
    	rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_MII_BMCR, (wBMCR&0xcfff), RTL_WIN_0);			    	    			 
    }     
     
    taskDelay(10); 
     
    rtl81x9CsrWriteWord	(pDrvCtrl, RTL_REGS_INTR_MASK, RTL_VALID_INTERRUPTS, NONE); 
 
    return OK; 
} 
 
/************************************************************************ 
* 函数名称: Get8139Reg 
* 功能描述: 打印8139的寄存器 
* 输入参数: pDrvCtrl:网口设备控制块指针  
*			 ucBegin:  要打印寄存器开始偏移地址 
*			 ucEnd:    要打印寄存器结束偏移地址 
* 输出参数: 无 
* 返 回 值: 无 
* 其它说明: 仅供内部测试用,供GetRtl8139Info调用 
* 修改日期:    版本号     修改人	      修改内容 
* ----------------------------------------------- 
* 2002/05/21    V1.0       邹同亮          创建 
************************************************************************/ 
void Get8139Reg(RTL81X9END_DEVICE *pDrvCtrl, unsigned char ucBegin, unsigned char ucEnd) 
{    
    if((RTL_REGS_TX_STATUS0 >= ucBegin) && (ucEnd >= RTL_REGS_TX_STATUS0)) 
    	printf("RTL_REGS_TX_STATUS0:      0x%08lx\n",rtl81x9CsrReadLong(pDrvCtrl, RTL_REGS_TX_STATUS0, RTL_WIN_0)); 
    if((RTL_REGS_TX_STATUS1 >= ucBegin) && (ucEnd >= RTL_REGS_TX_STATUS1)) 
    	printf("RTL_REGS_TX_STATUS1:      0x%08lx\n",rtl81x9CsrReadLong(pDrvCtrl, RTL_REGS_TX_STATUS1, RTL_WIN_0)); 
    if((RTL_REGS_TX_START_NOR_0 >= ucBegin) && (ucEnd >= RTL_REGS_TX_START_NOR_0)) 
    	printf("RTL_REGS_TX_START_NOR_0:  0x%08lx\n",rtl81x9CsrReadLong(pDrvCtrl, RTL_REGS_TX_START_NOR_0, RTL_WIN_0)); 
    if((RTL_REGS_TX_START_NOR_1 >= ucBegin) && (ucEnd >= RTL_REGS_TX_START_NOR_1)) 
    	printf("RTL_REGS_TX_START_NOR_1:  0x%08lx\n",rtl81x9CsrReadLong(pDrvCtrl, RTL_REGS_TX_START_NOR_1, RTL_WIN_0)); 
    if((RTL_REGS_TX_START_HIGH_0 >= ucBegin) && (ucEnd >= RTL_REGS_TX_START_HIGH_0)) 
    	printf("RTL_REGS_TX_START_HIGH_0: 0x%08lx\n",rtl81x9CsrReadLong(pDrvCtrl, RTL_REGS_TX_START_HIGH_0, RTL_WIN_0)); 
    if((RTL_REGS_TX_START_HIGH_1 >= ucBegin) && (ucEnd >= RTL_REGS_TX_START_HIGH_1)) 
    	printf("RTL_REGS_TX_START_HIGH_1: 0x%08lx\n",rtl81x9CsrReadLong(pDrvCtrl, RTL_REGS_TX_START_HIGH_1, RTL_WIN_0)); 
    if((RTL_REGS_RX_EARLY_CNT >= ucBegin) && (ucEnd >= RTL_REGS_RX_EARLY_CNT)) 
    	printf("RTL_REGS_RX_EARLY_CNT:    0x%04x\n",rtl81x9CsrReadWord(pDrvCtrl, RTL_REGS_RX_EARLY_CNT, RTL_WIN_0)); 
    if((RTL_REGS_RX_EARLY_STATUS >= ucBegin) && (ucEnd >= RTL_REGS_RX_EARLY_STATUS)) 
    	printf("RTL_REGS_RX_EARLY_STATUS: 0x%02x\n",rtl81x9CsrReadByte(pDrvCtrl, RTL_REGS_RX_EARLY_STATUS, RTL_WIN_0)); 
    if((RTL_REGS_CHIP_CMD >= ucBegin) && (ucEnd >= RTL_REGS_CHIP_CMD)) 
    	printf("RTL_REGS_CHIP_CMD:        0x%02x\n",rtl81x9CsrReadByte(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_WIN_0));     
     
     
    if((RTL_REGS_INTR_MASK >= ucBegin) && (ucEnd >= RTL_REGS_INTR_MASK)) 
    	printf("RTL_REGS_INTR_MASK:       0x%04x\n",rtl81x9CsrReadWord(pDrvCtrl, RTL_REGS_INTR_MASK, RTL_WIN_0)); 
    if((RTL_REGS_INTR_STATUS >= ucBegin) && (ucEnd >= RTL_REGS_INTR_STATUS)) 
    	printf("RTL_REGS_INTR_STATUS:     0x%04x\n",rtl81x9CsrReadWord(pDrvCtrl, RTL_REGS_INTR_STATUS, RTL_WIN_0)); 
    if((RTL_REGS_TX_CONFIG >= ucBegin) && (ucEnd >= RTL_REGS_TX_CONFIG)) 
    	printf("RTL_REGS_TX_CONFIG:       0x%08lx\n",rtl81x9CsrReadLong(pDrvCtrl, RTL_REGS_TX_CONFIG, RTL_WIN_0)); 
    if((RTL_REGS_RX_CONFIG >= ucBegin) && (ucEnd >= RTL_REGS_RX_CONFIG)) 
    	printf("RTL_REGS_RX_CONFIG:       0x%08lx\n",rtl81x9CsrReadLong(pDrvCtrl, RTL_REGS_RX_CONFIG, RTL_WIN_0)); 
    if((RTL_REGS_TIMER >= ucBegin) && (ucEnd >= RTL_REGS_TIMER)) 
    	printf("RTL_REGS_TIMER:           0x%08lx\n",rtl81x9CsrReadLong(pDrvCtrl, RTL_REGS_TIMER, RTL_WIN_0)); 
    if((RTL_REGS_RX_MISSED >= ucBegin) && (ucEnd >= RTL_REGS_RX_MISSED)) 
    	printf("RTL_REGS_RX_MISSED:       0x%08lx\n",rtl81x9CsrReadLong(pDrvCtrl, RTL_REGS_RX_MISSED, RTL_WIN_0)); 
    
    if((RTL_REGS_CFG_9346 >= ucBegin) && (ucEnd >= RTL_REGS_CFG_9346)) 
    	printf("RTL_REGS_CFG_9346:        0x%02x\n",rtl81x9CsrReadByte(pDrvCtrl, RTL_REGS_CFG_9346, RTL_WIN_0)); 
    if((RTL_REGS_CONFIG_0 >= ucBegin) && (ucEnd >= RTL_REGS_CONFIG_0)) 
    	printf("RTL_REGS_CONFIG_0:        0x%02x\n",rtl81x9CsrReadByte(pDrvCtrl, RTL_REGS_CONFIG_0, RTL_WIN_0)); 
    if((RTL_REGS_CONFIG_1 >= ucBegin) && (ucEnd >= RTL_REGS_CONFIG_1)) 
    	printf("RTL_REGS_CONFIG_1:        0x%02x\n",rtl81x9CsrReadByte(pDrvCtrl, RTL_REGS_CONFIG_1, RTL_WIN_0)); 
    if((RTL_REGS_TIMERINT >= ucBegin) && (ucEnd >= RTL_REGS_TIMERINT)) 
    	printf("RTL_REGS_TIMERINT:        0x%08lx\n",rtl81x9CsrReadLong(pDrvCtrl, RTL_REGS_TIMERINT, RTL_WIN_0)); 
    if((RTL_REGS_MSR >= ucBegin) && (ucEnd >= RTL_REGS_MSR)) 
    	printf("RTL_REGS_MSR:             0x%02x\n",rtl81x9CsrReadByte(pDrvCtrl, RTL_REGS_MSR, RTL_WIN_0)); 
    if((RTL_REGS_CONFIG3 >= ucBegin) && (ucEnd >= RTL_REGS_CONFIG3)) 
    	printf("RTL_REGS_CONFIG3:         0x%02x\n",rtl81x9CsrReadByte(pDrvCtrl, RTL_REGS_CONFIG3, RTL_WIN_0)); 
    if((RTL_REGS_MII >= ucBegin) && (ucEnd >= RTL_REGS_MII)) 
    	printf("RTL_REGS_MII:             0x%02x\n",rtl81x9CsrReadByte(pDrvCtrl, RTL_REGS_MII, RTL_WIN_0)); 
    if((RTL_REGS_MULTI_INTR >= ucBegin) && (ucEnd >= RTL_REGS_MULTI_INTR)) 
    	printf("RTL_REGS_MULTI_INTR:      0x%08lx\n",rtl81x9CsrReadLong(pDrvCtrl, RTL_REGS_MULTI_INTR, RTL_WIN_0)); 
        
 
     
    if((RTL_REGS_MII_BMCR >= ucBegin) && (ucEnd >= RTL_REGS_MII_BMCR)) 
    	printf("RTL_REGS_MII_BMCR:        0x%04x\n",rtl81x9CsrReadWord(pDrvCtrl, RTL_REGS_MII_BMCR, RTL_WIN_0)); 
    if((RTL_REGS_MII_BMSR >= ucBegin) && (ucEnd >= RTL_REGS_MII_BMSR)) 
    	printf("RTL_REGS_MII_BMSR:        0x%04x\n",rtl81x9CsrReadWord(pDrvCtrl, RTL_REGS_MII_BMSR, RTL_WIN_0)); 
    if((RTL_REGS_NWAY_ADVERT >= ucBegin) && (ucEnd >= RTL_REGS_NWAY_ADVERT)) 
    	printf("RTL_REGS_NWAY_ADVERT:     0x%04x\n",rtl81x9CsrReadWord(pDrvCtrl, RTL_REGS_NWAY_ADVERT, RTL_WIN_0)); 
    if((RTL_REGS_NWAY_LPAR >= ucBegin) && (ucEnd >= RTL_REGS_NWAY_LPAR)) 
    	printf("RTL_REGS_NWAY_LPAR:       0x%04x\n",rtl81x9CsrReadWord(pDrvCtrl, RTL_REGS_NWAY_LPAR, RTL_WIN_0)); 
    if((RTL_REGS_NWAY_EXPANSION >= ucBegin) && (ucEnd >= RTL_REGS_NWAY_EXPANSION)) 
    	printf("RTL_REGS_NWAY_EXPANSION:  0x%04x\n",rtl81x9CsrReadWord(pDrvCtrl, RTL_REGS_NWAY_EXPANSION, RTL_WIN_0)); 
    if((RTL_REGS_DIS >= ucBegin) && (ucEnd >= RTL_REGS_DIS)) 
    	printf("RTL_REGS_DIS:             0x%04x\n",rtl81x9CsrReadWord(pDrvCtrl, RTL_REGS_DIS, RTL_WIN_0)); 
    if((RTL_REGS_FCSC >= ucBegin) && (ucEnd >= RTL_REGS_FCSC)) 
    	printf("RTL_REGS_FCSC:            0x%04x\n",rtl81x9CsrReadWord(pDrvCtrl, RTL_REGS_FCSC, RTL_WIN_0)); 
    if((RTL_REGS_NWAYTR >= ucBegin) && (ucEnd >= RTL_REGS_NWAYTR)) 
    	printf("RTL_REGS_NWAYTR:          0x%04x\n",rtl81x9CsrReadWord(pDrvCtrl, RTL_REGS_NWAYTR, RTL_WIN_0)); 
    if((RTL_REGS_CSCR >= ucBegin) && (ucEnd >= RTL_REGS_CSCR)) 
    	printf("RTL_REGS_CSCR:            0x%04x\n",rtl81x9CsrReadWord(pDrvCtrl, RTL_REGS_CSCR, RTL_WIN_0)); 
     
    if((RTL_REGS_PARA_78 >= ucBegin) && (ucEnd >= RTL_REGS_PARA_78)) 
    	printf("RTL_REGS_PARA_78:         0x%08lx\n",rtl81x9CsrReadLong(pDrvCtrl, RTL_REGS_PARA_78, RTL_WIN_0)); 
    if((RTL_REGS_PARA_7c >= ucBegin) && (ucEnd >= RTL_REGS_PARA_7c)) 
    	printf("RTL_REGS_PARA_7c:         0x%08lx\n",rtl81x9CsrReadLong(pDrvCtrl, RTL_REGS_PARA_7c, RTL_WIN_0)); 
    if((RTL_REGS_TPPOLL >= ucBegin) && (ucEnd >= RTL_REGS_TPPOLL)) 
    	printf("RTL_REGS_TPPOLL:          0x%02x\n",rtl81x9CsrReadByte(pDrvCtrl, RTL_REGS_TPPOLL, RTL_WIN_0)); 
    if((RTL_REGS_CPCR >= ucBegin) && (ucEnd >= RTL_REGS_CPCR)) 
    	printf("RTL_REGS_CPCR:            0x%04x\n",rtl81x9CsrReadWord(pDrvCtrl, RTL_REGS_CPCR, RTL_WIN_0)); 
    if((RTL_REGS_RDSAR_0 >= ucBegin) && (ucEnd >= RTL_REGS_RDSAR_0)) 
    	printf("RTL_REGS_RDSAR_0:         0x%08lx\n",rtl81x9CsrReadLong(pDrvCtrl, RTL_REGS_RDSAR_0, RTL_WIN_0)); 
    if((RTL_REGS_RDSAR_1 >= ucBegin) && (ucEnd >= RTL_REGS_RDSAR_1)) 
    	printf("RTL_REGS_RDSAR_1:         0x%08lx\n",rtl81x9CsrReadLong(pDrvCtrl, RTL_REGS_RDSAR_1, RTL_WIN_0)); 
    if((RTL_REGS_ETTHR >= ucBegin) && (ucEnd >= RTL_REGS_ETTHR)) 
    	printf("RTL_REGS_ETTHR:           0x%02x\n",rtl81x9CsrReadByte(pDrvCtrl, RTL_REGS_ETTHR, RTL_WIN_0));     
	 
} 
 
/************************************************************************ 
* 函数名称: GetRxTxDescriptor 
* 功能描述: 打印8139的Descriptor值 
* 输入参数: pDrvCtrl:网口设备控制块指针  
* 输出参数: 无 
* 返 回 值: 无 
* 其它说明: 仅供内部测试用,供GetRtl8139Info调用 
* 修改日期:    版本号     修改人	      修改内容 
* ----------------------------------------------- 
* 2002/05/21    V1.0       邹同亮          创建 
************************************************************************/ 
void GetRxTxDescriptor(RTL81X9END_DEVICE *pDrvCtrl) 
{     
    unsigned long dwRxCmd[64]; 
    unsigned long dwTxCmd[64]; 
    int i =0; 
    RTL_RMD *pRmd = (RTL_RMD *)NULL;    
    RTL_TMD *pTmd = (RTL_TMD *)NULL;    
     
    /* 获取 */     
    for (i=0; i<64 ; i++) 
    { 
        pRmd = ( RTL_RMD *)(pDrvCtrl->ptrRxBufSpace + 16*i);  
        dwRxCmd[i] = LONGSWAP(pRmd->cmd_leng);         
    }     
     
    for (i=0; i<64 ; i++) 
    { 
        pTmd = ( RTL_TMD *)(pDrvCtrl->ptrTxBufSpace + 16*i);  
        dwTxCmd[i] = LONGSWAP(pTmd->cmd_leng);      
    }  
     
    /* 打印 */ 
    printf("rmdIndex:%d, tmdIndex:%d, tmdIndexC:%d\n", pDrvCtrl->rmdIndex, pDrvCtrl->tmdIndex, pDrvCtrl->tmdIndexC); 
    printf("RxDesciptor:\n");     
    for (i=0; i<64 ; i++) 
    {         
        if(((i+1)%8) ==0) 
        { 
            printf("%08lx,%08lx,%08lx,%08lx,%08lx,%08lx,%08lx,%08lx\n",dwRxCmd[i-7],dwRxCmd[i-6],dwRxCmd[i-5],dwRxCmd[i-4],dwRxCmd[i-3],dwRxCmd[i-2],dwRxCmd[i-1],dwRxCmd[i]); 
        } 
    } 
     
    printf("TxDesciptor:\n");     
    for (i=0; i<64 ; i++) 
    {         
        if(((i+1)%8) ==0) 
        { 
            printf("%08lx,%08lx,%08lx,%08lx,%08lx,%08lx,%08lx,%08lx\n",dwTxCmd[i-7],dwTxCmd[i-6],dwTxCmd[i-5],dwTxCmd[i-4],dwTxCmd[i-3],dwTxCmd[i-2],dwTxCmd[i-1],dwTxCmd[i]); 
        } 
    }      
 
} 
 
/************************************************************************ 
* 函数名称: Get8139Counter 
* 功能描述: 打印8139的统计值 
* 输入参数: pDrvCtrl:网口设备控制块指针  
* 输出参数: 无 
* 返 回 值: 无 
* 其它说明: 仅供内部测试用,供GetRtl8139Info调用 
* 修改日期:    版本号     修改人	      修改内容 
* ----------------------------------------------- 
* 2002/05/21    V1.0       邹同亮          创建 
************************************************************************/ 
void Get8139Counter(RTL81X9END_DEVICE *pDrvCtrl) 
{     
     
    unsigned long *pCouterBase =NULL;     
	if(pCouterBase == NULL) 
	{ 
        pCouterBase = (unsigned long *)malloc (0x200); 
        pCouterBase = (unsigned long *) ( ( (unsigned long)pCouterBase + 63) & ((unsigned long)~63)); 
	}	 
	 
	rtl81x9CsrWriteLong(pDrvCtrl, RTL_REGS_TX_STATUS0, ((unsigned long)pCouterBase) | 0x8, RTL_WIN_0); 
	rtl81x9CsrWriteLong(pDrvCtrl, RTL_REGS_TX_STATUS1, 0, RTL_WIN_0); 
	 
	while( (rtl81x9CsrReadLong(pDrvCtrl, RTL_REGS_TX_STATUS0, RTL_WIN_0) & 0x8) !=0 ) 
	{ 
		taskDelay(1);		 
	} 
	            
	printf("TxOk      = %ld%ld\n", LONGSWAP(*(pCouterBase +1)), LONGSWAP(*pCouterBase)); 
	printf("RxOk      = %ld%ld\n", LONGSWAP(*(pCouterBase +3)), LONGSWAP(*(pCouterBase +2))); 
	printf("TxErr     = %ld%ld\n", LONGSWAP(*(pCouterBase +5)), LONGSWAP(*(pCouterBase +4))); 
	printf("RxErr     = %ld\n", LONGSWAP(*(pCouterBase +6)));	 
	printf("MissPkt   = %d\n", WORDSWAP(*((unsigned short*)(pCouterBase +7)))); 
	printf("FAE       = %d\n", WORDSWAP(*((unsigned short*)(pCouterBase +7) +1))); 
	printf("Tx1Col    = %ld\n", LONGSWAP(*(pCouterBase +8))); 
	printf("TxMCol    = %ld\n", LONGSWAP(*(pCouterBase +9))); 
	printf("RxOkPhy   = %ld%ld\n", LONGSWAP(*(pCouterBase +11)), LONGSWAP(*(pCouterBase +10))); 
	printf("RxOkBrd   = %ld%ld\n", LONGSWAP(*(pCouterBase +13)), LONGSWAP(*(pCouterBase +12))); 
	printf("RxOkMul   = %ld\n", LONGSWAP(*(pCouterBase +14))); 
	printf("TxAbt     = %d\n", WORDSWAP(*((unsigned short*)(pCouterBase +15)))); 
	printf("TxUndrn   = %d\n", WORDSWAP(*((unsigned short*)(pCouterBase +15) +1))); 
	 
} 
 
/************************************************************************ 
* 函数名称: GetRtl8139Info 
* 功能描述: 打印8139的各种信息 
* 输入参数: unit:    网口的设备号,如rtl0的0  
*			 ucInfo    网口信息类型,见rtl8139Config.h中的宏定义         
* 输出参数: 无 
* 返 回 值: OK:   成功 
             ERROR:失败 
* 其它说明: 仅供内部测试用 
* 修改日期:    版本号     修改人	      修改内容 
* ----------------------------------------------- 
* 2002/05/21    V1.0       邹同亮          创建 
************************************************************************/ 
STATUS GetRtl8139Info(int unit,unsigned char ucInfo) 
{	 
	RTL81X9END_DEVICE *pDrvCtrl = NULL;     
	pDrvCtrl = (RTL81X9END_DEVICE *)endFindByName("rtl", unit); 
    if(pDrvCtrl == NULL ) 
    {    	 
    	return ERROR; 
    } 
     
	/* 打印8139的寄存器 */ 
	if(ucInfo & RTL8139_INFO_REG) 
	{	 
		Get8139Reg(pDrvCtrl, 0x00, 0xff);	 
	} 
	 
	/* 打印8139的GetRxTxDescriptor */ 
	if(ucInfo & RTL8139_INFO_DESCP) 
	{ 
		GetRxTxDescriptor(pDrvCtrl); 
	}	 
	 
	/* 打印8139的统计记数器 */ 
	if(ucInfo & RTL8139_INFO_COUNT) 
	{ 
		Get8139Counter(pDrvCtrl); 
	} 
	 
	/* 打印8139对应设备的缓冲池统计 */ 
	if(ucInfo & RTL8139_INFO_POOL) 
	{ 
    	netPoolShow(pDrvCtrl->end.pNetPool); 
	} 
	 
	return OK; 
}