📄 ne2000end.c
字号:
/* ne2000End.c - NE2000 END network interface driver */#include "copyright_wrs.h"#include "vxWorks.h"#include "endLib.h" /* Common END structures. */#include "etherMultiLib.h"#include "netLib.h"#include "cacheLib.h"#include "lstLib.h" /* Needed to maintain protocol list. */#include "iv.h"#include "stdlib.h"#include "sysLib.h"#include "intLib.h"#include "taskLib.h"#include "ne2000End.h" #include "s3c2410x.h"#include "wrSbcArm9.h"#define NE2000_ALL_INTS (IM_OVWE | IM_TXEE | IM_RXEE | IM_PTXE | IM_PRXE)/*#define NE2000_ALL_INTS (IM_PTXE | IM_PRXE)*/#define CRC32_POLYNOMIAL 0x04c11db7/* Configuration items */#define END_SPEED 10000000#define NE2000_DEV_NAME "ene"#define NE2000_DEV_NAME_LEN 4#ifndef SYS_INT_CONNECT#define SYS_INT_CONNECT(pDrvCtrl,rtn,arg,pResult) \ { \ IMPORT STATUS intConnect(); \ *pResult = intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (pDrvCtrl->ivec), \ rtn, (int)arg); \ }#endif#ifndef SYS_INT_DISCONNECT#define SYS_INT_DISCONNECT(pDrvCtrl,rtn,arg,pResult) \ { \ *pResult = OK; /* HELP: need a real routine */ \ }#endif#ifndef SYS_INT_ENABLE#define SYS_INT_ENABLE(pDrvCtrl) \ { \ IMPORT STATUS intEnable(); \ intEnable (pDrvCtrl->ilevel); \ }#endif#ifndef SYS_ENET_ADDR_GET#define SYS_ENET_ADDR_GET(pDevice) \ ne2000EnetAddrGet(pDevice)#endif#if (CPU_FAMILY == I80X86)#ifndef SYS_OUT_CHAR#define SYS_OUT_CHAR(pDrvCtrl,addr,value) \ sysOutByte((pDrvCtrl)->base + (int) (addr),(char) (value))#endif#ifndef SYS_IN_CHAR#define SYS_IN_CHAR(pDrvCtrl,addr,pData) \ (*(pData) = (UCHAR) sysInByte((pDrvCtrl)->base + (int) (addr)))#endif#ifndef SYS_IN_WORD_STRING#define SYS_IN_WORD_STRING(pDrvCtrl,addr,pData,len) \ (sysInWordString ((pDrvCtrl)->base + (int) (addr), (short *)(pData), \ (len)))#endif#ifndef SYS_OUT_WORD_STRING#define SYS_OUT_WORD_STRING(pDrvCtrl,addr,pData,len) \ (sysOutWordString ((pDrvCtrl)->base + (int) (addr), (short *)(pData), \ (len)))#endif#else /* #if (CPU_FAMILY == I80X86) */#ifndef SYS_OUT_CHAR#define SYS_OUT_CHAR(pDrvCtrl,addr,value) \ sysOutByte((pDrvCtrl)->base + (UINT) (addr), (value))#endif#ifndef SYS_IN_CHAR#define SYS_IN_CHAR(pDrvCtrl,addr,pData) \ (*(pData) = (UCHAR) sysInByte((pDrvCtrl)->base + (UINT) (addr)))#endif#ifndef SYS_IN_WORD_STRING#define SYS_IN_WORD_STRING(pDrvCtrl,addr,pData,len) \ (sysInWordString ((pDrvCtrl)->base + (UINT) (addr), \ (UINT16 *)(pData), (len)))#endif#ifndef SYS_OUT_WORD_STRING#define SYS_OUT_WORD_STRING(pDrvCtrl,addr,pData,len) \ (sysOutWordString ((pDrvCtrl)->base + (UINT) (addr), \ (UINT16 *) (pData), (len)))#endif#endif /* #if (CPU_FAMILY == I80X86) *//* A shortcut for getting the hardware address from the MIB II stuff. */#define END_HADDR(pEnd) \ ((pEnd)->mib2Tbl.ifPhysAddress.phyAddress)#define END_HADDR_LEN(pEnd) \ ((pEnd)->mib2Tbl.ifPhysAddress.addrLength)/* Statistics we gather from the NE2000 */typedef struct { UINT collisions; UINT crcs; UINT aligns; UINT missed; UINT overruns; UINT disabled; UINT deferring; UINT underruns; UINT aborts; UINT outofwindow; UINT heartbeats; UINT badPacket; UINT shortPacket; UINT tnoerror; UINT rnoerror; UINT terror; UINT rerror; UINT overwrite; UINT wrapped; UINT interrupts; UINT reset; UINT strayint; UINT jabber; } NE2000_STAT;typedef struct ne2000_device { END_OBJ endObj; END_ERR lastError; int lastIntError; int unit; int ivec; int ilevel; int byteAccess; int usePromEnetAddr; ULONG base; int offset; #ifdef _USE_SND_DMA_ char packetBuf [SAVE_SND_NUM][NE2000_BUFSIZ]; /* long-aligned */ int packetLen[SAVE_SND_NUM]; #else char packetBuf[NE2000_BUFSIZ]; #endif volatile long flags; volatile UCHAR current; volatile ULONG imask; volatile NE2000_STAT stats; UCHAR enetAddr[6]; UCHAR mcastFilter[8]; UCHAR nextPacket; CL_POOL_ID clPoolId; int configRegA; int configRegB; #ifdef _USE_SND_DMA_ int useHead; int bufCount; int freeHead; #endif #ifdef _USE_RECV_DMA_ char recvMapBuf[RECV_PAGE_NUM][RECV_PAGE_SIZE]; int nextMapPage; #endif } NE2000END_DEVICE;NE2000END_DEVICE *gpDeviceCtrl = NULL;struct macinfo{ char ipadrinfo[50]; char netmaskinfo[50]; char gatewayinfo[50]; ULONG netmaskshowinfo; UCHAR macshowinfo[6]; int dhcpflag; int bootpflag;};struct macinfo MAC_INFO;/* Definitions for the flags field */#define END_PROMISCUOUS_FLAG 0x01#define END_RECV_HANDLING_FLAG 0x02#define END_TX_IN_PROGRESS 0x04#define END_TX_BLOCKED 0x08#define END_POLLING 0x10#define END_OVERWRITE 0x20#define END_OVERWRITE2 0x40/***** DEBUG MACROS *****/#undef DEBUG#ifdef DEBUG# include "stdio.h"# include "logLib.h" int endDebug = 1;# define ENDLOGMSG(x) \ do { \ if (endDebug) \ logMsg x; \ } while (0)#else# define ENDLOGMSG(x)#endif /* ENDDEBUG *//***** LOCALS *****//* imports */IMPORT char ne2000EnetAddr[];IMPORT int endMultiLstCnt (END_OBJ *);LOCAL void ne2000Int (NE2000END_DEVICE* pDrvCtrl);LOCAL void ne2000HandleRcvInt (NE2000END_DEVICE* pDrvCtrl);LOCAL void ne2000Config (NE2000END_DEVICE* pDrvCtrl, int intEnable);LOCAL void ne2000OverwriteRecover (NE2000END_DEVICE* pDrvCtrl, UCHAR cmdStatus);LOCAL int ne2000PacketGet (NE2000END_DEVICE* pDrvCtrl, char *pData);LOCAL void ne2000AddrFilterSet (NE2000END_DEVICE* pDrvCtrl);LOCAL UINT32 ne2000CrcWork (UINT8 inChar, UINT32 inCrc);LOCAL void ne2000EnetAddrGet (NE2000END_DEVICE* pDrvCtrl);LOCAL UCHAR ne2000GetCurr (NE2000END_DEVICE* pDrvCtrl);LOCAL void ne2000DataIn (NE2000END_DEVICE* pDrvCtrl, int eneAddress, int len, char* pData);LOCAL void ne2000DataOut (NE2000END_DEVICE* pDrvCtrl, char* pData, int len, int eneAddress);LOCAL STATUS ne2000Parse (NE2000END_DEVICE* pDrvCtrl, char* initString);LOCAL STATUS ne2000MemInit (NE2000END_DEVICE* pDrvCtrl);LOCAL STATUS ne2000PollStart (NE2000END_DEVICE* pDrvCtrl);LOCAL STATUS ne2000PollStop (NE2000END_DEVICE* pDrvCtrl);/* END Specific interfaces. *//* This is the only externally visible interface. */END_OBJ * ne2000EndLoad (char* initString, void *pBSP);LOCAL STATUS ne2000Start (void* pCookie);LOCAL STATUS ne2000Stop (void* pCookie);LOCAL STATUS ne2000Unload (void *pCookie);LOCAL int ne2000Ioctl (void *pCookie, int cmd, caddr_t data);LOCAL STATUS ne2000Send (void *pCookie, M_BLK_ID pBuf);LOCAL STATUS ne2000MCastAdd (void *pCookie, char* pAddress);LOCAL STATUS ne2000MCastDel (void *pCookie, char* pAddress);LOCAL STATUS ne2000MCastGet (void *pCookie, MULTI_TABLE* pTable);LOCAL STATUS ne2000PollSend (void *pCookie, M_BLK_ID pBuf);LOCAL STATUS ne2000PollRecv (void *pCookie, M_BLK_ID pBuf);#define U32 unsigned intvoid ne2000DmaInit();#ifdef _USE_SND_DMA_void ne2000DmaSendInt();void ne2000DmaSend(NE2000END_DEVICE* pDrvCtrl ,int eneAddress);#elsevoid ne2000DmaSendInt();void ne2000DmaSend(NE2000END_DEVICE* pDev , char *srcBuf , int sndLen);#endif#ifdef _USE_RECV_DMA_void ne2000DmaRecvInt();void ne2000DmaRecv(NE2000END_DEVICE *pDrvCtrl,int eneAddress,int len);#endifvoid ne2000OpenRecvIntLog();LOCAL NET_FUNCS ne2000FuncTable = { (FUNCPTR) ne2000Start, (FUNCPTR) ne2000Stop, (FUNCPTR) ne2000Unload, (FUNCPTR) ne2000Ioctl, (FUNCPTR) ne2000Send, (FUNCPTR) ne2000MCastAdd, (FUNCPTR) ne2000MCastDel, (FUNCPTR) ne2000MCastGet, (FUNCPTR) ne2000PollSend, (FUNCPTR) ne2000PollRecv, endEtherAddressForm, (FUNCPTR) endEtherPacketDataGet, (FUNCPTR) endEtherPacketAddrGet };int dmaReadyFlag =TRUE;int recvIntLog = FALSE;/********************************************************************************* RETURNS: An END object pointer or NULL on error.*/END_OBJ* ne2000EndLoad ( char* initString, void* pBSP ) { NE2000END_DEVICE *pDrvCtrl; int level; UCHAR regVal;#ifdef DEBUG printf ("ne2000EndLoad(%s)\n", initString); printf ("\tinitString '%s'\n", initString ? initString : ""); printf ("\tpBSP '%s'\n", pBSP ? pBSP : "");#endif if (initString == NULL) return (NULL); if (initString[0] == '\0') { bcopy((char *)NE2000_DEV_NAME, initString, NE2000_DEV_NAME_LEN); return (NULL); } pDrvCtrl = (NE2000END_DEVICE *) calloc (sizeof(NE2000END_DEVICE), 1); if (pDrvCtrl == NULL) goto errorExit; if (ne2000Parse (pDrvCtrl, initString) == ERROR) goto errorExit; if (pDrvCtrl->configRegA != 0) { level = intLock (); SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_PAGE0); SYS_IN_CHAR (pDrvCtrl, ENE_RBCR0, ®Val); SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR0, pDrvCtrl->configRegA); intUnlock (level); } if (pDrvCtrl->configRegB != 0) { level = intLock (); SYS_IN_CHAR (pDrvCtrl, ENE_RBCR1, ®Val); SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR1, pDrvCtrl->configRegB); intUnlock (level); } SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_NODMA | CMD_PAGE0 | CMD_STOP); if (pDrvCtrl->byteAccess) SYS_OUT_CHAR (pDrvCtrl, ENE_DCON, DCON_BSIZE1 | DCON_BUS_8 | DCON_LOOPBK_OFF); else SYS_OUT_CHAR (pDrvCtrl, ENE_DCON, DCON_BSIZE1 | DCON_BUS16 | DCON_LOOPBK_OFF); SYS_ENET_ADDR_GET (pDrvCtrl); if (END_OBJ_INIT (&pDrvCtrl->endObj, (DEV_OBJ *)pDrvCtrl, NE2000_DEV_NAME, pDrvCtrl->unit, &ne2000FuncTable, "ne2000 Enhanced Network Driver") == ERROR) goto errorExit; if (END_MIB_INIT (&pDrvCtrl->endObj, M2_ifType_ethernet_csmacd, &pDrvCtrl->enetAddr[0], 6, ETHERMTU, END_SPEED) == ERROR) goto errorExit; if (ne2000MemInit (pDrvCtrl) == ERROR) goto errorExit; END_OBJ_READY (&pDrvCtrl->endObj, IFF_NOTRAILERS | IFF_MULTICAST | IFF_BROADCAST); #ifdef _USE_SND_DMA_ pDrvCtrl->useHead = 0x5a; pDrvCtrl->freeHead = 0; pDrvCtrl->bufCount = SAVE_SND_NUM; #endif gpDeviceCtrl = pDrvCtrl; return (&pDrvCtrl->endObj);errorExit: if (pDrvCtrl != NULL) free ((char *)pDrvCtrl); return (NULL); }/******************************************************************************* RETURNS: OK or ERROR for invalid arguments.*/LOCAL STATUS ne2000Parse ( NE2000END_DEVICE * pDrvCtrl, char * initString ) { char* tok; char* holder = NULL; tok = strtok_r (initString, ":", &holder); if (tok == NULL) return (ERROR); pDrvCtrl->unit = atoi (tok); tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return (ERROR); pDrvCtrl->base = strtoul (tok, NULL, 16); tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return (ERROR); pDrvCtrl->ivec = strtoul (tok, NULL, 16); tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return (ERROR); pDrvCtrl->ilevel = strtoul (tok, NULL, 16); tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return (ERROR); pDrvCtrl->byteAccess = atoi (tok); tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return (ERROR); pDrvCtrl->usePromEnetAddr = atoi (tok); tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return (ERROR); pDrvCtrl->offset = strtoul (tok, NULL, 16); pDrvCtrl->configRegA = 0; tok = strtok_r (NULL, ":", &holder); if (tok != NULL) pDrvCtrl->configRegA = strtoul (tok, NULL, 16); pDrvCtrl->configRegB = 0; tok = strtok_r (NULL, ":", &holder); if (tok != NULL) pDrvCtrl->configRegB = strtoul (tok, NULL, 16); return (OK); }/******************************************************************************** RETURNS: OK or ERROR.*/LOCAL STATUS ne2000MemInit ( NE2000END_DEVICE * pDrvCtrl ) { M_CL_CONFIG eneMclBlkConfig; CL_DESC clDesc; /* cluster description */ bzero ((char *)&eneMclBlkConfig, sizeof(eneMclBlkConfig)); bzero ((char *)&clDesc, sizeof(clDesc)); clDesc.clNum = 128; clDesc.clSize = NE2000_BUFSIZ; /* allow for alignment */ clDesc.memSize = ((clDesc.clNum * (clDesc.clSize + 8)) + 4); eneMclBlkConfig.mBlkNum = 64 * 4; eneMclBlkConfig.clBlkNum = clDesc.clNum; eneMclBlkConfig.memSize = (eneMclBlkConfig.mBlkNum * (MSIZE + sizeof (long))) + (eneMclBlkConfig.clBlkNum * (CL_BLK_SZ + sizeof (long))); eneMclBlkConfig.memArea = (char *) memalign(sizeof (long), eneMclBlkConfig.memSize); if (eneMclBlkConfig.memArea == NULL) return (ERROR); clDesc.memArea = (char *) malloc (clDesc.memSize); if (clDesc.memArea == NULL) return (ERROR); pDrvCtrl->endObj.pNetPool = (NET_POOL_ID) malloc (sizeof(NET_POOL)); if (pDrvCtrl->endObj.pNetPool == NULL) return (ERROR); if (netPoolInit (pDrvCtrl->endObj.pNetPool, &eneMclBlkConfig, &clDesc, 1, NULL) == ERROR) return (ERROR); pDrvCtrl->clPoolId = clPoolIdGet (pDrvCtrl->endObj.pNetPool, NE2000_BUFSIZ, FALSE); return (OK); }/********************************************************************************/LOCAL int ne2000Ioctl ( void* pCookie, int cmd, caddr_t data ) { int error = 0; long value; NE2000END_DEVICE* pDrvCtrl = (NE2000END_DEVICE *) pCookie; ENDLOGMSG (("into ne2000Ioctl.\n", 0, 0, 0, 0, 0, 0)); switch ((UINT) cmd) { case EIOCSADDR: if (data == NULL) return (EINVAL); bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->endObj), END_HADDR_LEN(&pDrvCtrl->endObj)); ENDLOGMSG (("ne2000Ioctl set phy addr.\n", 0, 0, 0, 0, 0, 0)); break; case EIOCGADDR: if (data == NULL) return (EINVAL); bcopy ((char *)END_HADDR(&pDrvCtrl->endObj), (char *)data,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -