📄 ns83902end.c
字号:
/* ns83902End.c - National Semiconductor DP83902A ST-NIC */ /* Copyright 1998-2002 Wind River Systems, Inc. *//* Copyright 1998-2000 Hitachi ULSI Systems Co.,LTD.,All Rights Reserved *//*modification history--------------------01l,03feb03,m_h refgen problems01k,15jan03,m_h Unsupported by IPv601j,24apr02,h_k changed dummy read to read from pDrvCtrl->ioPort (SPR #74019).01i,25mar02,h_k changed overrun handling to be done in ISR and transmit buffer taking from a static data (SPR #74019).01h,14jan02,dat Removing warnings from Diab compiler01g,10oct01,dat SPR 70829, driver used fp register - fixed., removed warnings, fixed casts for netClFree, fixed macros01f,03oct00,zl ns83902Send() frees the Mblk chain in non-polled mode only.01e,23may00,zl minor code cleanup.01d,29apr00,zl redone TX interrupts, register read/write.01c,21apr00,zl call netMblkClChainFree only if TX succeeds, use TX interrupts instead of polling.01b,10apr00,zl renamed file to ns83902End.c01a,20sep99,zl written based on nicMsEnd.c and nicEvbEnd.c*//*This module implements the National Semiconductor dp83902A ST-NIC Ethernetnetwork interface driver.This driver is moderately generic. The driver must be given several target-specific parameters. These parameters, and the mechanisms used to communicate them to the driver, are detailed below.The driver supports big-endian or little-endian architectures.EXTERNAL INTERFACEThe only external interface is the ns83902EndLoad() routine, which expectsthe <initString> parameter as input. This parameter passes in a colon-delimited string of the format: "<baseAdrs>:<intVec>:<intLvl>:<dmaPort>:<bufSize>:<options>"The ns83902EndLoad() function uses strtok() to parse the string.TARGET-SPECIFIC PARAMETERS.IP "unit"A convenient holdover from the former model. This parameter is used onlyin the string name for the driver..IP "baseAdrs"Base address at which the NIC hardware device registers are located..IP "vecNum"This is the interrupt vector number of the hardware interrupt generated bythis Ethernet device..IP "intLvl"This parameter defines the level of the hardware interrupt..IP "dmaPort"Address of the DMA port used to transfer data to the host CPU..IP "bufSize"Size of the NIC buffer memory in bytes..IP "options"Target specific options: bit0 - wide (0: byte, 1: word) bit1 - register interval (0: 1byte, 1: 2 bytes)EXTERNAL SUPPORT REQUIREMENTSThis driver requires four external support functions, and provides a hookfunction:.iP "void sysLanIntEnable (int level)" "" 9 -1This routine provides a target-specific interface for enabling Ethernet deviceinterrupts at a specified interrupt level..iP "void sysLanIntDisable (void)" "" 9 -1This routine provides a target-specific interface for disabling Ethernet deviceinterrupts..iP "STATUS sysEnetAddrGet (int unit, char *enetAdrs)" "" 9 -1This routine provides a target-specific interface for accessing a deviceEthernet address..iP "sysNs83902DelayCount" "" 9 -1This variable is used to introduce at least a 4 bus cycle (BSCK) delay betweensuccessive NIC chip selects.SYSTEM RESOURCE USAGEThis driver requires the following system resources: - one mutual exclusion semaphore - one interrupt vectorSEE ALSO: muxLib,.I "DP83902A ST-NIC Serial Interface Controller for Twisted Pair"*//* configurations */#undef NS83902_INSTRUMENT /* instrument the driver */#undef NS83902_DEBUG /* log debug messages *//* includes */#include "vxWorks.h"#include "iv.h"#include "vme.h"#include "net/mbuf.h"#include "lstLib.h"#include "semLib.h"#include "sys/times.h"#include "net/unixLib.h"#include "net/protosw.h"#include "sys/socket.h"#include "sys/ioctl.h"#include "errno.h"#include "memLib.h"#include "intLib.h"#include "net/route.h"#include "iosLib.h"#include "errnoLib.h"#include "logLib.h"#include "cacheLib.h"#include "netLib.h"#include "stdio.h"#include "stdlib.h"#include "sysLib.h"#include "etherLib.h"#include "net/systm.h"#include "net/if_subr.h"#ifdef WR_IPV6#include "adv_net.h"#endif /*WR_IPV6*/#include "drv/end/ns83902End.h"#undef ETHER_MAP_IP_MULTICAST#include "etherMultiLib.h"#include "end.h"#include "endLib.h"/* defines */#define NS83902_DEV_NAME "nic"#define NS83902_DEV_NAME_LEN 4#define NS83902_EADR_LEN 6#define NS83902_SPEED 10000000 /* 10Mbps or 100Mbps */#define NS83902_CRC_POLY 0x04c11db7#define IMR_DISABLE 0#define IMR_ENABLE (IMR_PRXE | IMR_OVWE | IMR_PTXE | IMR_TXEE)#define IMR_RX_DISABLE (IMR_OVWE | IMR_PTXE | IMR_TXEE)/* debug macros */#ifdef NS83902_DEBUG#ifdef LOCAL#undef LOCAL#define LOCAL#endif#define NS83902_DEBUG_OFF 0x0000#define NS83902_DEBUG_RX 0x0001#define NS83902_DEBUG_TX 0x0002#define NS83902_DEBUG_INT 0x0004#define NS83902_DEBUG_POLL (NS83902_DEBUG_POLL_RX | NS83902_DEBUG_POLL_TX)#define NS83902_DEBUG_POLL_RX 0x0008#define NS83902_DEBUG_POLL_TX 0x0010#define NS83902_DEBUG_LOAD 0x0020#define NS83902_DEBUG_IOCTL 0x0040#define NS83902_DEBUG_POLL_REDIR 0x10000#define NS83902_DEBUG_LOG_NVRAM 0x20000#define NS83902_DEBUG_MB 0x40000#define NS83902_DEBUG_TMP 0x80000int ns83902Debug = NS83902_DEBUG_OFF;NET_POOL ns83902NetPool; /* global for easy access of end.pNetPool */void * ns83902EndDevice; /* global for easy access of the device */CL_POOL_ID ns83902ClPoolId; /* global for easy access to cluster pool */SEM_ID ns83902DmaSemId; /* global for easy access to sem ID */#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6) \ if (ns83902Debug & FLG) \ logMsg(X0, X1, X2, X3, X4, X5, X6);#else /* NS83902_DEBUG */#define DRV_LOG(DBG_SW, X0, X1, X2, X3, X4, X5, X6)#endif /* NS83902_DEBUG *//* * Default macro definitions for BSP interface. * These macros can be redefined in a wrapper file, to generate * a new module with an optimized interface. */#ifndef SYS_INT_CONNECT#define SYS_INT_CONNECT(pDrvCtrl,rtn,arg,pResult) \ do { \ *pResult = intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (pDrvCtrl->ivec),\ rtn, (int)arg); \ } while (0)#endif /* SYS_INT_CONNECT */#ifndef SYS_INT_DISCONNECT#define SYS_INT_DISCONNECT(pDrvCtrl,rtn,arg,pResult) \ do { \ *pResult = OK; \ } while (0)#endif /* SYS_INT_DISCONNECT */#ifndef SYS_INT_ENABLE#define SYS_INT_ENABLE(pDrvCtrl) \ do { \ IMPORT void sysLanIntEnable(int); \ sysLanIntEnable (pDrvCtrl->ilevel); \ } while (0)#endif /* SYS_INT_ENABLE */#ifndef SYS_INT_DISABLE#define SYS_INT_DISABLE(pDrvCtrl) \ do { \ IMPORT STATUS sysLanIntDisable(int); \ sysLanIntDisable(pDrvCtrl->ilevel); \ } while (0)#endif /*SYS_INT_DISABLE*/#ifndef SYS_ENET_ADDR_GET#define SYS_ENET_ADDR_GET(pDrvCtrl, pAddress) \ do { \ IMPORT STATUS sysEnetAddrGet (int, char*); \ sysEnetAddrGet (pDrvCtrl->unit, pAddress); \ } while (0)#endif /* SYS_ENET_ADDR_GET */#ifndef SYS_NS83902_DELAY#define SYS_NS83902_DELAY() \ do { \ IMPORT UINT32 sysNs83902DelayCount; \ volatile UINT32 cx = 0; \ for (cx = 0; cx < sysNs83902DelayCount; cx++) \ /* spin */ ; \ } while (0)#endif /* SYS_NS83902_DELAY */#ifndef SYS_MS_DELAY#define SYS_MS_DELAY(delay) \ do { \ IMPORT void sysMsDelay (UINT); \ sysMsDelay (delay); \ } while (0)#endif /* SYS_MS_DELAY */#ifndef SYS_IN_SHORT#define SYS_IN_SHORT(pDrvCtrl,addr,data) \ do { \ ((data) = *((volatile USHORT *)(addr))); \ } while (0)#endif /* SYS_IN_SHORT*/#ifndef SYS_OUT_SHORT#define SYS_OUT_SHORT(pDrvCtrl,addr,value) \ do { \ *((volatile USHORT *)(addr)) = (value); \ } while (0)#endif /* SYS_OUT_SHORT */#ifndef SYS_IN_BYTE#define SYS_IN_BYTE(pDrvCtrl, addr, data) \ do { \ ((data) = *((volatile UCHAR *)(addr))); \ } while (0)#endif /* SYS_IN_BYTE */#ifndef SYS_OUT_BYTE#define SYS_OUT_BYTE(pDrvCtrl, addr, value) \ do { \ *((volatile UCHAR *)(addr)) = (value); \ } while (0)#endif /* SYS_OUT_BYTE *//* Setting/Getting on-chip registers */#define NS83902_CR_GET(pDrvCtrl, value) \ do { \ SYS_IN_BYTE ((pDrvCtrl), \ ((pDrvCtrl)->pNic + \ (NS83902_CR) * (pDrvCtrl)->regInterval), \ (value)); \ SYS_NS83902_DELAY(); \ } while (0)#define NS83902_CR_SET(pDrvCtrl, value) \ do { \ SYS_OUT_BYTE ((pDrvCtrl), \ ((pDrvCtrl)->pNic + \ (NS83902_CR) * (pDrvCtrl)->regInterval), \ (value)); \ SYS_NS83902_DELAY(); \ } while (0)#define NS83902_REG_GET(pDrvCtrl, reg, value, page) \ (value = ns83902RegRead (pDrvCtrl, reg, page))#define NS83902_REG_SET(pDrvCtrl, reg, value, page) \ (ns83902RegSet (pDrvCtrl, reg, value, page))/* Macros for dealing with flags */#define DRV_FLAGS_SET(setBits) \ (pDrvCtrl->flags |= (setBits))#define DRV_FLAGS_ISSET(setBits) \ (pDrvCtrl->flags & (setBits))#define DRV_FLAGS_CLR(clrBits) \ (pDrvCtrl->flags &= ~(clrBits))#define DRV_FLAGS_GET() \ (pDrvCtrl->flags)#define NS83902_IS_IN_POLL_MODE() \ ((DRV_FLAGS_GET() & NS83902_FLAG_POLL) == NS83902_FLAG_POLL)#define NS83902_SEM_TAKE(pDrvCtrl, timeout) \ semTake ((pDrvCtrl)->endObj.txSem, timeout)#define NS83902_SEM_GIVE(pDrvCtrl) \ semGive((pDrvCtrl)->endObj.txSem)/* 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)#define END_FLAGS_ISSET(pEnd, setBits) \ ((pEnd)->flags & (setBits))/* * Macros for read and write descriptors. * */#define NS83902_RX_BUF_SZ sizeof(NS83902_RX_FRAME)#define NS83902_RX_HDR_SZ sizeof(NS83902_RX_HDR)#define NS83902_ETH_CRC_LEN 4/* typedefs */typedef struct rx_hdr {#if (_BYTE_ORDER == _BIG_ENDIAN) UINT8 nextRxPage; /* page next pkt starts at */ UINT8 status; /* status of packet */#else UINT8 status; /* status of packet */ UINT8 nextRxPage; /* page next pkt starts at */#endif UINT16 count; /* frame length */ } NS83902_RX_HDR;typedef struct rx_frame { UINT16 pad1; NS83902_RX_HDR rxHdr; /* receive status header */ ENET_HDR enetHdr; /* ethernet header */ UINT8 data[ETHERMTU]; /* frame data */ } NS83902_RX_FRAME;typedef char* NS83902_CLUSTER;typedef struct ns83902_end_device /* driver control structure */ { END_OBJ endObj; /* The class we inherit from. */ END_ERR lastError; /* Last error passed to muxError */ int unit; /* unit number */ int rringSize; /* RMD ring size */ UCHAR enetAddr[NS83902_EADR_LEN]; /* ethernet address */ char* pNic; /* address of NIC chip */ char* ioPort; /* port address of remote DMA */ NS83902_CLUSTER pCluster; /* Rx frame memory */ CL_POOL_ID pClPoolId; /* cluster pool */ int regInterval; /* address diff of adjacent regs */ BOOL wide; /* I/O port is 16 bit (when TRUE) */ int ivec; /* interrupt vector */ int ilevel; /* interrupt level */ UINT8 regPage; /* current register page */ UINT8 txStartPage; /* ptr to Tx start buffer */ UINT8 rxStartPage; /* ptr to Rx start buffer */ UINT8 rxStopPage; /* ptr to Rx stop buffer */ UINT8 nextPage; /* ptr to next page */ NS83902_DRV_FLAG flags; /* device specific flags */ BOOL rxHandling; /* rcv task is scheduled */ BOOL txBlocked; /* to implement flow control */ BOOL rxOvw; /* overwrite warning */ BOOL txResend; /* resend need at overwrite */ } NS83902_END_DEVICE;/* network buffers configuration */M_CL_CONFIG ns83902MclBlkConfig = /* network mbuf configuration table */ { /* no. mBlks no. clBlks memArea memSize --------- ---------- ------- ------- */ 0, 0, NULL, 0 };CL_DESC ns83902ClDescTbl [] = /* cluster pool configuration table */ { /* clSize num memArea memSize ------ ---- ------- ------- */ {0, 0, NULL, 0} }; int ns83902ClDescTblNumEnt = (NELEMENTS(ns83902ClDescTbl));/* globals */#ifdef NS83902_INSTRUMENTUINT32 ns83902TxTimeout = 0; /* number of transmit time-out */UINT32 ns83902TxError = 0; /* number of transmit errors */UINT32 ns83902RestartNb = 0; /* number of restart due to ring overflow */UINT32 ns83902InitNb = 0; /* number of time device is re-initialized */UINT32 ns83902TxNb = 0; /* number of transmitted packets */UINT32 ns83902IntNb = 0; /* number of receive interrupt */UINT32 ns83902Len = 0; /* lenght of the current received packet */UINT32 ns83902HdrStat = 0; /* status byte of the current received packet */UINT32 ns83902NextPage = 0; /* page pointer to the next received packet */UINT32 ns83902CurrentPage = 0; /* start page of the current packet */#endif/* forward declarations */LOCAL void ns83902MARSet (NS83902_END_DEVICE* pDrvCtrl, UINT8 index, BOOL bSet);LOCAL STATUS ns83902AddrFilterSet (NS83902_END_DEVICE *pDrvCtrl, char* pAddr, BOOL bSet);LOCAL int ns83902HashIndex (char* eAddr);LOCAL void ns83902Int (NS83902_END_DEVICE* pDrvCtrl);LOCAL void ns83902Restart (NS83902_END_DEVICE *pDrvCtrl, UINT8 cr);LOCAL void ns83902HandleInt (NS83902_END_DEVICE *pDrvCtrl);LOCAL void ns83902Recv (NS83902_END_DEVICE *pDrvCtrl, NS83902_CLUSTER pCluster);LOCAL NS83902_CLUSTER ns83902ReadFrame (NS83902_END_DEVICE* pDrvCtrl);LOCAL void ns83902Config (NS83902_END_DEVICE* pDrvCtrl);LOCAL STATUS ns83902PktBufRead (NS83902_END_DEVICE *pDrvCtrl, UINT32 ns83902BufAddr, UINT32 len, char *pData);LOCAL STATUS ns83902Transmit (NS83902_END_DEVICE *pDrvCtrl, M_BLK* pMblk);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -