📄 nicevbend.c
字号:
/* nicEvbEnd.c - National Semiconductor ST-NIC Chip network interface driver *//* Copyright 1984-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01j,16may02,wap Release dmaSem before passing packets up the stack (SPR #77005)01i,02aug00,stv removed netMblkClChainFree() in Pollsend routine (SPR# 32885).01h,11jun00,ham removed reference to etherLib.01g,01dec99,stv freed mBlk chain before returning ERROR (SPR #28492).01f,10feb98,sut added poll mode support01e,09feb98,sut added multicast support01d,08feb98,sut got working01c,25jan98,sut working with initMem01b,21jan98,sut investcating descritor01a,20jan99,sut from netif/if_nicEvb.c*//*This module implements the National Semiconductor 83902A ST-NIC Ethernetnetwork interface driver.This driver is non-generic and is for use on the IBM EVB403 board. The driver must be given several target-specific parameters. Theseparameters, and the mechanisms used to communicate them to the driver, aredetailed below.BOARD LAYOUTThis device is on-board. No jumpering diagram is necessary.EXTERNAL INTERFACEThe only external interface is the nicEvbEndLoad() routine, which expectsthe <initString> parameter as input. This parameter passes in a colon-delimited string of the format:<unit>:<nic_addr>:<int_vector>:<int_level>The nicEvbEndLoad() 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 <nic_addr>Base address for NIC chip.IP <int_vector>Configures the NIC device to generate hardware interrupts for various eventswithin the device. Thus, it contains an interrupt handler routine. The drivercalls sysIntConnect() to connect its interrupt handler to the interrupt vector..IP <int_level>This parameter is passed to an external support routine, sysLanIntEnable(),which is described below in "External Support Requirements." This routine is called during as part of driver's initialization. It handles any board-specific operations required to allow the servicing of a NIC interrupt on targets that use additional interrupt controller devices to help organize and service the various interrupt sources. This parameter makes it possible for this driver to avoid all board-specific knowledge of such devices. .iP "device restart/reset delay"The global variable nicRestartDelay (UINT32), defined in this file, should be initialized in the BSP sysHwInit() routine. nicRestartDelay is used only with PowerPC platform and is equal to the number of time base increments which makes for 1.6 msec. This corresponds to the delay necessary to respect when restarting or resetting the device..LPEXTERNAL SUPPORT REQUIREMENTSThis driver requires several external support functions, defined as macros:.CS SYS_INT_CONNECT(pDrvCtrl, routine, arg) SYS_INT_DISCONNECT (pDrvCtrl, routine, arg) SYS_INT_ENABLE(pDrvCtrl).CEThere are default values in the source code for these macros. They presumememory-mapped accesses to the device registers and the normal intConnect(),and intEnable() BSP functions. The first argument to each is the devicecontroller structure. Thus, each has access back to all the device-specificinformation. Having the pointer in the macro facilitates the addition of new features to this driver.SYSTEM RESOURCE USAGEWhen implemented, this driver requires the following system resources: - one mutual exclusion semaphore - one interrupt vectorSEE ALSO: muxLib*//* configurations */#define NIC_INSTRUMENT /* instrument the driver */#undef DRV_DEBUG /* log debug messages */#if (CPU_FAMILY == PPC)#define NIC_USE_PPCTIMEBASE#else /* CPU_FAMILY == PPC */#undef NIC_USE_PPCTIMEBASE#endif /* CPU_FAMILY == PPC *//* * NIC_FASTER, if defined, improved the driver throuput, however the driver * seems to be less reliable. Left undefined for now. */#undef NIC_FASTER /* improve throuput but less stable *//* includes */#include "vxWorks.h"#include "wdLib.h"#include "iv.h"#include "vme.h"#include "net/mbuf.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"#ifdef DRV_DEBUG#include "logLib.h"#endif#include "cacheLib.h"#include "netLib.h"#include "stdio.h"#include "stdlib.h"#include "sysLib.h"#include "net/systm.h"#include "sys/times.h"#include "net/if_subr.h"#include "netinet/if_ether.h"#include "drv/end/nicEvbEnd.h"#undef ETHER_MAP_IP_MULTICAST#include "etherMultiLib.h"#include "end.h"#include "endLib.h"#include "lstLib.h"#include "semLib.h"/* defines */#define NIC_EVB_DEV_NAME "nicEvb"#define NIC_EVB_DEV_NAME_LEN 7#define NIC_EVB_EADR_LEN 6#define NIC_EVB_SPEED 10000000 /* HELP */#define NIC_TRANS_TIMEOUT 400 /* times to poll for end of Tx */#define NIC_CRC_POLY 0x04c11db7/* debug macros */#ifdef DRV_DEBUG#define DRV_DEBUG_OFF 0x0000#define DRV_DEBUG_RX 0x0001#define DRV_DEBUG_TX 0x0002#define DRV_DEBUG_INT 0x0004#define DRV_DEBUG_POLL (DRV_DEBUG_POLL_RX | DRV_DEBUG_POLL_TX)#define DRV_DEBUG_POLL_RX 0x0008#define DRV_DEBUG_POLL_TX 0x0010#define DRV_DEBUG_LOAD 0x0020#define DRV_DEBUG_IOCTL 0x0040#define DRV_DEBUG_POLL_REDIR 0x10000#define DRV_DEBUG_LOG_NVRAM 0x20000#define DRV_DEBUG_MB 0x40000#ifdef LOCAL#undef LOCAL#define LOCALNET_POOL nicNetPool;#endif/* int nicEvbDebug = DRV_DEBUG_LOAD | DRV_DEBUG_TX | DRV_DEBUG_RX; */int nicEvbDebug = DRV_DEBUG_POLL;#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6) \ if (nicEvbDebug & FLG) \ logMsg(X0, X1, X2, X3, X4, X5, X6);#define DRV_PRINT(FLG, X0, X1, X2, X3, X4, X5, X6) \ if (nicEvbDebug & FLG) \ printf(X0, X1, X2, X3, X4, X5, X6);#else /*DRV_DEBUG*/#define DRV_LOG(DBG_SW, X0, X1, X2, X3, X4, X5, X6)#define DRV_PRINT(DBG_SW,X)#endif /*DRV_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) \ {\ IMPORT STATUS sysIntConnect(); \ *pResult = intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (pDrvCtrl->ivec), \ rtn, (int)arg); \ }#endif /*SYS_INT_CONNECT*/#ifndef SYS_INT_DISCONNECT#define SYS_INT_DISCONNECT(pDrvCtrl,rtn,arg,pResult) \ { \ *pResult = OK; \ }#endif /*SYS_INT_DISCONNECT*/#ifndef SYS_INT_ENABLE#define SYS_INT_ENABLE(ivec) \ { \ IMPORT void sysLanIntEnable(); \ sysLanIntEnable (ivec); \ }#endif /*SYS_INT_ENABLE*/#ifndef SYS_ENET_ADDR_GET#define SYS_ENET_ADDR_GET(pDrvCtrl, pAddress) \ { \ IMPORT sysEnetAddrGet (int, char*);\ nicEvbEnetAddrGet (pDrvCtrl, pAddress); \ }#endif /* SYS_ENET_ADDR_GET */#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 NIC_IS_IN_POLL_MODE()\ ((DRV_FLAGS_GET() & NIC_FLAG_POLL) == NIC_FLAG_POLL)/* 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))/* typedefs */typedef struct rx_hdr { UINT8 status; /* status of packet */ UINT8 nextRxPage; /* page next pkt starts at */ UINT8 cntL; /* low byte of frame length */ UINT8 cntH; /* high byte of frame length */ } NIC_RX_HDR;#define NIC_RX_HDR_SZ sizeof(NIC_RX_HDR)typedef struct rx_frame { UINT16 pad1; NIC_RX_HDR rxHdr; /* receive status header */ struct ether_header enetHdr; /* ethernet header */ UINT8 data [ETHERMTU];/* frame data */ UINT32 fcs; /* frame check sequence */ UINT8 refCnt; /* loaner reference count */ UINT8 pad2; } NIC_RX_FRAME;/* * Macros for read and write descriptors. * */#define NIC_FRAME_DATA_ADDR_GET(pFrame) \ pFrame = ((char *)(pFrame) + sizeof(UINT16) + sizeof(NIC_RX_HDR_SZ));#define NIC_RBR_LEN ((PSTOP - PSTART) + 1)#define NIC_BUF_SZ sizeof(NIC_RX_FRAME)#define NIC_ETH_CRC_LEN 4typedef char* NIC_CLUSTER;typedef struct nic_end_device /* driver control structure */ { END_OBJ end; /* The class we inherit from. */ int unit; /* unit number */ int rmdIndex; /* current RMD index */ int rringSize; /* RMD ring size */ int rringLen; /* RMD ring length (bytes) */ UCHAR enetAddr[NIC_EVB_EADR_LEN]; /* ethernet address */ BOOL txBlocked; /* transmit flow control */ BOOL txCleaning; NIC_DEVICE* pNic; /* address of NIC chip */ int ivec; /* interrupt vector */ int ilevel; /* interrupt level */ SEM_ID dmaSem; /* exclusive use of remote DMA */ UINT8 nextPkt; /* NIC buf page for next pkt */ NIC_CLUSTER pRxCluster; /* Rx frame memory */ CL_POOL_ID pClPoolId; NIC_DRV_FLAG flags; /* device specific flags */ } NICEVB_END_DEVICE;/* globals */UINT32 nicEvbRestartDelay = 30000;/* number of time base ticks to wait for */ /* when resetting the chip */UINT32 nicIntNb = 0; /* number of receive interrupt */UINT32 nicTxTimeout = 0; /* number of transmit time-out */#ifdef NIC_INSTRUMENTUINT32 nicRestartNb = 0; /* number of restart due to ring overflow */UINT32 nicLen = 0; /* lenght of the current received packet */UINT32 nicHdrStat = 0; /* status byte of the current received packet */UINT32 nicNextPage = 0; /* page pointer to the next received packet */UINT32 nicCurrentPage = 0; /* start page of the current packet */UINT32 nicTxNb = 0; /* number of transmitted packets */UINT32 nicInitNb = 0; /* number of time device is re-initialized */#endif/* locals *//* forward declarations */LOCAL int nicEvbMblkDataLenGet (M_BLK* pMblk);LOCAL void nicEvbEnetAddrGet (NICEVB_END_DEVICE* pDrvCtrl, char* pAddress);LOCAL void nicEvbMARSet (NICEVB_END_DEVICE* pDrvCtrl, UINT8 index, BOOL bSet);LOCAL void nicEvbAddrFilterSet (NICEVB_END_DEVICE *pDrvCtrl, char* pAddr, BOOL bSet);LOCAL int nicEvbHashIndex (char* eAddr);LOCAL void nicEvbReset (NICEVB_END_DEVICE* pDrvCtrl);LOCAL void nicEvbInt (NICEVB_END_DEVICE* pDrvCtrl);LOCAL void nicEvbRestart (NICEVB_END_DEVICE *pDrvCtrl, UINT8 cr);LOCAL void nicEvbHandleInt (NICEVB_END_DEVICE *pDrvCtrl);LOCAL BOOL nicEvbRead (NICEVB_END_DEVICE *pDrvCtrl);LOCAL NIC_CLUSTER nicEvbReadFrame (NICEVB_END_DEVICE* pDrvCtrl);LOCAL STATUS nicEvbToStack (NICEVB_END_DEVICE* pDrvCtrl, NIC_CLUSTER pCluster);LOCAL void nicEvbConfig (NICEVB_END_DEVICE* pDrvCtrl);LOCAL STATUS nicEvbPktBufRead (NICEVB_END_DEVICE *pDrvCtrl, UINT32 nicBufAddr, UINT32 len, char *pData);LOCAL void nicEvbWriteCr (NIC_DEVICE *pNic, UINT8 value);LOCAL void nicEvbWriteReg (NIC_DEVICE *pNic, volatile UINT8 *pReg, UINT8 value, UINT8 page);LOCAL UINT8 nicEvbReadReg (NIC_DEVICE *pNic, volatile UINT8 *pReg, char page);LOCAL STATUS nicEvbTransmit (NICEVB_END_DEVICE *pDrvCtrl, M_BLK* pMblk, BOOL waitFlag);LOCAL void nicEvbWritePort (UINT8 value);LOCAL STATUS nicEvbReceive (NICEVB_END_DEVICE *pDrvCtrl, UINT32 nicBufAddr, char *pData, int len);LOCAL UINT8 nicEvbReadPort (void);LOCAL void nicLoanFree (NICEVB_END_DEVICE *pDrvCtrl, NIC_RX_FRAME *pRx);LOCAL BOOL nicEvbPagePtrUpdate (NICEVB_END_DEVICE * pDrvCtrl, NIC_CLUSTER pRxCluster);LOCAL void nicEvbResetDelay (void);LOCAL STATUS nicEvbInitParse (NICEVB_END_DEVICE* pDrvCtrl, char * initString);LOCAL STATUS nicEvbInitMem (NICEVB_END_DEVICE* pDrvCtrl);/* END Specific interfaces. */END_OBJ * nicEvbEndLoad (char *initString);LOCAL STATUS nicEvbUnload (NICEVB_END_DEVICE* pDrvCtrl);LOCAL STATUS nicEvbStart (NICEVB_END_DEVICE* pDrvCtrl);LOCAL STATUS nicEvbStop (NICEVB_END_DEVICE* pDrvCtrl);LOCAL int nicEvbIoctl (NICEVB_END_DEVICE* pDrvCtrl, int cmd, caddr_t data);LOCAL STATUS nicEvbSend (NICEVB_END_DEVICE* pDrvCtrl, M_BLK *pMblk);LOCAL STATUS nicEvbMCastAddrAdd (NICEVB_END_DEVICE *pDrvCtrl, char* pAddress);LOCAL STATUS nicEvbMCastAddrDel (NICEVB_END_DEVICE *pDrvCtrl, char* pAddress);LOCAL STATUS nicEvbMCastAddrGet (NICEVB_END_DEVICE *pDrvCtrl, MULTI_TABLE *pTable);LOCAL STATUS nicEvbPollSend (NICEVB_END_DEVICE *pDrvCtrl, M_BLK *pMblk);LOCAL STATUS nicEvbPollReceive (NICEVB_END_DEVICE *pDrvCtrl, M_BLK *pMblk);LOCAL STATUS nicEvbPollStart (NICEVB_END_DEVICE *pDrvCtrl);LOCAL STATUS nicEvbPollStop (NICEVB_END_DEVICE *pDrvCtrl);/* * Declare our function table. This is static across all driver * instances. */LOCAL NET_FUNCS nicEvbFuncTable = { (FUNCPTR)nicEvbStart, /* Function to start the device. */ (FUNCPTR)nicEvbStop, /* Function to stop the device. */ (FUNCPTR)nicEvbUnload, /* Unloading function for the driver. */ (FUNCPTR)nicEvbIoctl, /* Ioctl function for the driver. */ (FUNCPTR)nicEvbSend, /* Send function for the driver. */ (FUNCPTR)nicEvbMCastAddrAdd, /* Multicast address add */ (FUNCPTR)nicEvbMCastAddrDel, /* Multicast address delete */ (FUNCPTR)nicEvbMCastAddrGet, /* Multicast table retrieve */ (FUNCPTR)nicEvbPollSend, /* Polling send function for the driver. */ (FUNCPTR)nicEvbPollReceive, /* Polling receive function for the driver. */ endEtherAddressForm, /* Put address info into a packet. */ endEtherPacketDataGet, /* Get a pointer to packet data. */ endEtherPacketAddrGet /* Get packet addresses. */ };/******************************************************************************** nicEndLoad - initialize the driver and device** This routine initializes the driver and the device to the operational state.* All of the device-specific parameters are passed in <initString>, which* expects a string of the following format:** <unit>:<base_addr>:<int_vector>:<int_level>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -