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