📄 ei82596end.c
字号:
/* ei82596End.c - END style Intel 82596 Ethernet network interface driver *//* Copyright 1989-2000 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02a,11jun00,ham removed reference to etherLib.01z,27jan00,dat fixed use of NULL01y,30nov99,stv freed mBlk chain before returning ERROR (SPR #28492). 01x,11jan99,mem added offset load parameter, changed pNext fields in RFD and TFD to type EI_LINK. Added test for netClusterGet() returning NULL. (SPR 24440)01w,05nov98,dbt fixed error handling in ei82596Recv() routine (SPR #22557).01v,22sep98,dat Lint cleanup.01u,28aug98,n_s Changed watchdog to call ei82596DeviceRestart via netJobAdd. spr #2222401t,17aug98,sut removed SYS_INT_ENABLE and sys596IntAck, which was before SYS_INT_CONNECT [SPR 20284]01s,08dec97,gnn END code review fixes.01r,19oct97,vin moved swapping of loaned buffer before END_RCV_RTN_CALL01q,17oct97,vin removed extra free.01p,09oct97,vin delete unwanted frees in PollSend routine01o,07oct97,vin fixed multicasting, fixed mtu to ETHER_MTU01m,25sep97,gnn SENS beta feedback fixes01l,24sep97,vin added clBlk related calls01k,01sep97,vin fixed the restart logic01j,22aug97,gnn changes due to new buffering scheme01i,12aug97,gnn changes necessitated by MUX/END update.01h,30may97,map Doc updates.01g,02may97,map Fixed bug in multicast address set.01f,30apr97,jag Fixed man page errors.01d,21apr97,map fixed strtok_r() invocation; added intr (dis)enable macros added sys596Init.01c,17apr97,gnn fixed bug in Load/Start sequence.01b,17mar97,map updates for new buffering scheme, and code cleanups.01a,13sep96,map modified if_ei.c to END style.*//*This module implements an Intel 82596 Ethernet network interface driver.This driver is designed to be moderately generic. It operates unmodifiedacross the range of architectures and targets supported by VxWorks. To achieve this, this driver requires some external support routines as well as several target-specific parameters. These parameters (and the mechanisms used to communicate them to the driver) are detailed below.This driver can run with the device configured in eitherbig-endian or little-endian modes. Error recovery code has been added todeal with some of the known errata in the A0 version of the device. Thisdriver supports up to four individual units per CPU.BOARD LAYOUTThis device is on-board. No jumpering diagram is necessary.EXTERNAL INTERFACEThe driver provides one standard external interface, ei82596EndLoad().As input, this routine takes a string of colon-separated parameters.The parameters should be specified in hexadecimal (optionally preceded by "0x" or a minus sign "-"). The parameter string is parsed using strtok_r(), and each parameter is converted from string to binary by a call to:.CS strtoul(parameter, NULL, 16)..CETARGET-SPECIFIC PARAMETERSThe format of the parameter string is: <unit>:<ivec>:<sysbus>:<memBase>:<nTfds>:<nRfds>:<offset>.IP <unit>A convenient holdover from the former model. It is only used in thestring name for the driver..IP <ivec>This is the interrupt vector number of the hardware interrupt generated bythis ethernet device. The driver uses intConnect() to attach an interrupthandler to this interrupt..IP <sysbus>This parameter tells the device about the system bus. To determine the correct value for a target, see .I "Intel 32-bit Local Area Network (LAN) Component User's Manual.".IP <memBase>This parameter specifies the base address of a DMA-able cache-freepre-allocated memory region for use as a memory pool for transmit/receivedescriptors, buffers, and other device control structures.If there is no pre-allocated memory available for the driver, this parametershould be -1 (NONE). In which case, the driver calls cacheDmaAlloc() toallocate cache-safe memory..IP <nTfds>This parameter specifies the number of transmit descriptor/buffers to beallocated. If this parameter is zero or -1 (NULL), a default of 32 is used..IP <nRfds>This parameter specifies the number of receive descriptor/buffers to beallocated. If this parameter is zero or -1 (NULL), a default of 32 is used..IP <offset>Specifies the memory alignment offset..LPEXTERNAL SUPPORT REQUIREMENTSThis driver requires seven external support functions:.IP sys596IntEnable().CS void sys596IntEnable (int unit).CEThis routine provides a target-specific interface to enable Ethernet deviceinterrupts for a given device unit..IP sys596IntDisable().CS void sys596IntDisable (int unit).CEThis routine provides a target-specific interface to disable Ethernet deviceinterrupts for a given device unit..IP sysEnetAddrGet().CS STATUS sysEnetAddrGet (int unit, char *enetAdrs).CEThis routine provides a target-specific interface to access a device Ethernetaddress. This routine should provide a six-byte Ethernet address in the <enetAdrs> parameter and return OK or ERROR..IP sys596Init().CS STATUS sys596Init (int unit).CEThis routine performs any target-specific initialization required before the82596 is initialized. Typically, it is empty. This routine must return OKor ERROR..IP sys596Port().CS void sys596Port (int unit, int cmd, UINT32 addr).CEThis routine provides access to the special port function of the 82596. Itdelivers the command and address arguments to the port of the specified unit.The driver calls this routine primarily during initialization and, under some conditions, during error recovery procedures..IP sys596ChanAtn().CS void sys596ChanAtn (int unit).CEThis routine provides the channel attention signal to the 82596 for thespecified <unit>. The driver calls this routine frequently throughout allphases of operation..IP sys596IntAck().CSvoid sys596IntAck (int unit).CEThis routine must perform any required interrupt acknowledgment or clearing.Typically, this involves an operation to some interrupt control hardware.Note that the INT signal from the 82596 behaves in an "edge-triggered" mode.Therefore, this routine typically clears a latch within the control circuitry.The driver calls this routine from the interrupt handler..LPSYSTEM RESOURCE USAGEThe driver uses cacheDmaMalloc() to allocate memory to share with the 82596.The fixed-size pieces in this area total 160 bytes. The variable-size piecesin this area are affected by the configuration parameters specified in theeiattach() call. The size of one RFD (Receive Frame Descriptor) is 1536bytes. The size of one TFD (Transmit Frame Descriptor) is 1534 bytes. Formore on RFDs and TFDs, see the.I "Intel 82596 User's Manual."The 82596 requires ether that this shared memory region is non-cacheableor that the hardware implements bus snooping. The driver cannot maintaincache coherency for the device. This is because fields within the commandstructures are asynchronously modified by both the driver and the device,and these fields might share the same cache line.TUNING HINTSThe only adjustable parameters are the number of TFDs and RFDs that arecreated at run-time. These parameters are given to the driver when eiattach()is called. There is one TFD and one RFD associated with each transmittedframe and each received frame respectively. For memory-limited applications,decreasing the number of TFDs and RFDs might be a good idea. Increasing thenumber of TFDs provides no performance benefit after a certain point.Increasing the number of RFDs provides more buffering before packets aredropped. This can be useful if there are tasks running at a higher prioritythan the net task.SEE ALSO: ifLib,.I "Intel 82596 User's Manual,".I "Intel 32-bit Local Area Network (LAN) Component User's Manual"*/#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"#include "cacheLib.h"#include "logLib.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 "drv/end/ei82596End.h"#undef ETHER_MAP_IP_MULTICAST#include "etherMultiLib.h"#include "end.h"#include "semLib.h"#define END_MACROS#include "endLib.h"#include "lstLib.h"/* stuff to change in endLib.h */#define END_OBJ_FREE(X) END_OBJECT_UNLOAD(X)/***** LOCAL DEFINITIONS *****//* Driver debug control */#ifdef DRV_DEBUG#define DRV_DEBUG_OFF 0x0000#define DRV_DEBUG_RX 0x0001#define DRV_DEBUG_TX 0x0002#define DRV_DEBUG_POLL (DRV_DEBUG_POLL_RX | DRV_DEBUG_POLL_TX)#define DRV_DEBUG_POLL_RX 0x0004#define DRV_DEBUG_POLL_TX 0x0008#define DRV_DEBUG_LOAD 0x0010#define DRV_DEBUG_IOCTL 0x0020#define DRV_DEBUG_BUF 0x0040#define DRV_DEBUG_INT 0x0800#define DRV_DEBUG_POLL_REDIR 0x10000#define DRV_DEBUG_LOG_NVRAM 0x20000int eiDebug = 0xff;int nLoan=0;IMPORT int nvLogMsg();#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6) \ { \ if ((eiDebug & FLG) && (eiDebug & DRV_DEBUG_LOG_NVRAM)) \ logMsg(X0, X1, X2, X3, X4, X5, X6); \ else if (eiDebug & FLG) \ logMsg(X0, X1, X2, X3, X4, X5, X6); \ }#define DRV_PRINT(FLG,X) \ { \ if (eiDebug & FLG) printf X; \ }#else /*DRV_DEBUG*/#define DRV_LOG(DBG_SW, X0, X1, X2, X3, X4, X5, X6)#define DRV_PRINT(DBG_SW,X)#endif /*DRV_DEBUG*/#define END_FLAGS_ISSET(pEnd, setBits) \ ((pEnd)->flags & (setBits))/* 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 EI_SPEED 10000000 /* bits per sec */#define EADDR_LEN 6 /* ethernet address length */#define DEF_NUM_TFDS 32 /* default number of TFDs */#define DEF_NUM_RFDS 32 /* default number of RFDs */#define EI_PKT_SIZE (ETHERMTU + SIZEOF_ETHERHEADER + EADDR_LEN)#define EI_DEV_NAME "ei"#define EI_DEV_NAME_LEN 3/* driver flags */#define EI_POLLING 0x01 /* polling mode */#define EI_PROMISC 0x02 /* promiscuous mode */#define EI_MCAST 0x04 /* multicast addressing mode */#define EI_MCAST_SOFT 0x08 /* software multicast */#define EI_MEMOWN 0x10 /* device mem allocated by driver */#define END_CTRL_SIZ sizeof(END_CTRL)#define EI_RX_TIMEOUT 3 /* # watchdog runs for receive timeout */#define EI_TX_TIMEOUT 2 /* # watchdog runs for transmit timeout */#define DRV_FLAGS_SET(setBits) \ (pDrvCtrl->flags |= (setBits))#define DRV_FLAGS_CLR(clrBits) \ (pDrvCtrl->flags &= ~(clrBits))#define DRV_FLAGS_GET() \ (pDrvCtrl->flags) #define DRV_FLAGS_ISSET(setBits) \ (pDrvCtrl->flags & (setBits)) /* * 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; /* HELP: need a real routine */ \ }#endif /*SYS_INT_DISCONNECT*/#ifndef SYS_INT_ENABLE#define SYS_INT_ENABLE(pDrvCtrl) \ { \ IMPORT STATUS sys596IntEnable(int); \ \ (void) sys596IntEnable (pDrvCtrl->unit); \ }#endif /*SYS_INT_ENABLE*/#ifndef SYS_INT_DISABLE#define SYS_INT_DISABLE(pDrvCtrl) \ { \ IMPORT void sys596IntDisable(int); \ \ sys596IntDisable(pDrvCtrl->unit); \ }#endif /* SYS_INT_DISABLE */#ifndef DRV_NAME#define DRV_NAME "ei"#define DRV_NAME_LEN 3#endif /* DRV_NAME */#define NET_BUF_FREE(pNetBuf) \ pNetBuf->freeRtn(pNetBuf->pSpare1, pNetBuf->pSpare2)/* The definition of our linked list management structure */typedef struct ei_list /* EI_LIST - 82596 queue head */ { volatile EI_NODE * head; /* header of list */ volatile EI_NODE * tail; /* tail of list */ } EI_LIST;/* The definition of the driver control structure */typedef struct end_ctrl { END_OBJ endObj; /* base class */ int unit; /* unit number */ int ivec; /* interrupt vector */ UINT8 sysbus; /* SCP sysbus value */ char *memBase; /* 82596 memory pool base */ int nTFDs; /* how many TFDs to create */ int nRFDs; /* how many RFDs to create */ INT8 flags; /* driver state */ CACHE_FUNCS cacheFuncs; /* cache descriptor */ SCP *pScp; /* SCP ptr */ ISCP *pIscp; /* ISCP ptr */ SCB *pScb; /* SCB ptr */ CFD *pCfd; /* synchronous command frame */ RFD *rfdPool; /* RFD pool */ TFD *tfdPool; /* TFD pool */ TFD *pPollTfd; /* TFD for polled transmits */ RFD *pFreeRfd; /* first empty RFD in rxQueue */ volatile EI_LIST rxQueue; /* receive queue */ volatile EI_LIST txQueue; /* to be sent queue */ volatile EI_LIST freeQueue; /* free frame descriptors */ volatile EI_LIST cblQueue; /* actual chip transmit queue */ volatile EI_LIST cleanQueue; /* queue of TFDs to cleanup */ WDOG_ID wid; /* watchdog timer for transmit */ int wdInterval; /* watchdog interval in ticks */ long rxLockups; /* receive lockup count */ long txLockups; /* transmit lockup count */ volatile char wdTxTimeout; /* watchdog runs with tx lockup */ volatile char wdRxTimeout; /* watchdog runs with rx lockup */ int resetCount; /* number of chip resets */ BOOL txIdle; /* no pending transmits */ BOOL txCleaning; /* cleaning transmit queue */ BOOL rxHandling; /* handling received packets */ BOOL txBlocked; /* to implement flow control */ CL_POOL_ID pClPoolId; int offset; /* memory offset */ } END_CTRL;/***** GLOBALS *****/#ifdef DRV_DEBUGEND_CTRL *pEndCtrl;#endif /*DRV_DEBUG*//* Function declarations not in any header files */IMPORT STATUS sysEnetAddrGet (int unit, UCHAR addr[]);IMPORT void sys596Init (int unit);IMPORT STATUS sys596IntAck (int unit);IMPORT STATUS sys596IntEnable (int unit);IMPORT void sys596IntDisable (int unit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -