📄 elt3c509end.c
字号:
/* elt3c509End.c - END network interface driver for 3COM 3C509*//* Copyright 1984-2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01j,17jun02,dmh increased delay loop in elt3c509EepromRead SPR# 7883001i,28aug00,stv corrected the handling of EIOCSFLAGS ioctl (SPR# 29423).01h,02aug00,jkf Added statistics definitions to this file, SPR#26952.01g,11jun00,ham removed reference to etherLib.01f,27jan00,dat fixed use of NULL, removed warnings01e,01dec99,stv freed mBlk chain before returning ERROR (SPR #28492).01d,29mar99,dat SPR 26119, documentation, usage of .bS/.bE01c,10mar99,sbs added checking for non-zero value of nRxFrames.01b,06dec98,ms_ remove comment about "assumptions stated below", which we thinkis leftover from the template lance driver.01a,28sep98,snk written by mBedded Innovations Inc.*//*DESCRIPTIONThis module implements the 3COM 3C509 EtherLink III Ethernet network interface driver.This driver is designed to be moderately generic. Thus, it operates unmodified across the range of architectures and targets supported by VxWorks. To achieve this, the driver load routine requires an input string consisting of several target-specific values. The driver also requires some external support routines. These target-specific values and the external support routines are described below. BOARD LAYOUTThis device is on-board. No jumpering diagram is necessary.EXTERNAL INTERFACEThe only external interface is the elt3c509Load() routine, which expectsthe <initString> parameter as input. This parameter passes in a colon-delimited string of the format:<unit>:<port>:<intVector>:<intLevel>:<attachementType>:<nRxFrames>The elt3c509Load() 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 <intVector>Configures the ELT device to generate hardware interruptsfor various events within the device. Thus, it containsan interrupt handler routine. The driver calls intConnect() to connectits interrupt handler to the interrupt vector generated as a result ofthe ELT interrupt..IP <intLevel>This parameter is passed to an external support routine, sysEltIntEnable(),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 ELT 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 <attachmentType>This parameter is used to select the transceiver hardware attachment. This is then used by the elt3c509BoardInit() routine to activate the selected attachment. elt3c509BoardInit() is called as a part of the driver'sinitialization..IP <nRxFrames>This parameter is used as number of receive frames by the driver.EXTERNAL 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) SYS_INT_DISABLE(pDrvCtrl) SYS_OUT_BYTE(pDrvCtrl, reg, data) SYS_IN_BYTE(pDrvCtrl, reg, data) SYS_OUT_WORD(pDrvCtrl, reg, data) SYS_IN_WORD(pDrvCtrl, reg, data) SYS_OUT_WORD_STRING(pDrvCtrl, reg, pData, len) SYS_IN_WORD_STRING(pDrvCtrl, reg, pData, len) sysEltIntEnable(pDrvCtrl->intLevel) sysEltIntDisable(pDrvCtrl->intLevel) .CEThere are default values in the source code for these macros. They presumeIO-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.The macros SYS_INT_CONNECT, SYS_INT_DISCONNECT, and SYS_INT_ENABLE allowthe driver to be customized for BSPs that use special versions of theseroutines.The macro SYS_INT_CONNECT is used to connect the interrupt handler tothe appropriate vector. By default it is the routine intConnect().The macro SYS_INT_DISCONNECT is used to disconnect the interrupt handler priorto unloading the module. By default this is a dummy routine thatreturns OK.The macro SYS_INT_ENABLE is used to enable the interrupt level for theend device. It is called once during initialization. It calls anexternal board level routine sysEltIntEnable(). The macro SYS_INT_DISABLE is used to disable the interrupt level for theend device. It is called during stop. It calls anexternal board level routine sysEltIntDisable(). SYSTEM RESOURCE USAGEWhen implemented, this driver requires the following system resources: - one interrupt vector - 9720 bytes of text - 88 bytes in the initialized data section (data) - 0 bytes of bssThe driver requires 1520 bytes of preallocation for Transmit Buffer and 1520*nRxFrames of receive buffers. The default value of nRxFrames is 64therefore total pre-allocation is (64 + 1)*1520.TUNING HINTSnRxFrames parameter can be used for tuning no of receive frames to be usedfor handling packet receive. More no. of these could help receiving more loaning in case of massive reception.INTERNALThis driver is END compliant. It supports Multicasting and Poll mode Send andReceive capabilities. The initialization calls elt3c509BoardInit(), which initializes the ELT3C509 chip, and elt3c509MemInit() routine which initializesmemory allocation for Tx and Rx functionality. One mblk chain is allocated for storing Tx frame and nRxFrame(64) mblk chainss are allocated for Rx frames.When a receive interrupt is received, netJobAdd() is called to scheduleelt3c509HandlePktsRcv() routine for handling reception of the packets. This routine empties the FIFO in a mblk chain and loops for more packets.The cluster is then passed up to the Receive routine of the upper layer.To transmit a packet, contents of mblk are copied into the TxFrame which isused to fill the FIFO of the chip. Transmit complete interrupt is used to check for status of the transmission.When Polling mode is enabled, both for Tx and Rx together, elt3c509PollRcv()routine gets the packet out of the FIFO, copies into the mblk. For Tx in Poll mode, elt3c509PollSend(0 routine is called by the upper layer, the datais copied into the TxFrame from the mblk and sent out. The interrupt is disabled for transmit complete.Multicast addresses are handled by setting/resetting the RX_F_MULTICAST bitin the chip. When an address is added, the bit is set. When an address is removed and the address list is empty, the bit is reset.INCLUDES:end.h endLib.h etherMultiLib.h elt3c509End.hSEE ALSO: muxLib, endLib.I "Writing an Enhanced Network Driver"*//* includes */#include "vxWorks.h"#include "wdLib.h"#include "stdlib.h"#include "taskLib.h"#include "logLib.h"#include "intLib.h"#include "netLib.h"#include "stdio.h"#include "stdlib.h"#include "sysLib.h"#include "iv.h"#include "memLib.h"#include "semLib.h"#include "cacheLib.h"#include "sys/ioctl.h"#include "etherMultiLib.h" /* multicast stuff. */#include "end.h" /* Common END structures. */#include "endLib.h"#include "lstLib.h" /* Needed to maintain protocol list. */#include "netBufLib.h"#include "muxLib.h"#include "m2Lib.h"#include "drv/end/elt3c509End.h"/* statistic macro's */#define collisions elt3c509Stats[0]#define crcs elt3c509Stats[1]#define aligns elt3c509Stats[2]#define rxnobuffers elt3c509Stats[3]#define rxoverruns elt3c509Stats[4]#define disabled elt3c509Stats[5]#define deferring elt3c509Stats[6]#define txunderruns elt3c509Stats[7]#define aborts elt3c509Stats[8]#define outofwindow elt3c509Stats[9]#define heartbeats elt3c509Stats[10]#define badPacket elt3c509Stats[11]#define shortPacket elt3c509Stats[12]#define txnoerror elt3c509Stats[13]#define rxnoerror elt3c509Stats[14]#define txerror elt3c509Stats[15]#define rxerror elt3c509Stats[16]#define overwrite elt3c509Stats[17]#define wrapped elt3c509Stats[18]#define interrupts elt3c509Stats[19]#define elt3c509_reset elt3c509Stats[20]#define strayint elt3c509Stats[21]#define multcollisions elt3c509Stats[22]#define latecollisions elt3c509Stats[23]#define nocarriers elt3c509Stats[24]#define jabbers elt3c509Stats[25]#define txoverruns elt3c509Stats[26]#define rxunderruns elt3c509Stats[27]#define rxearly elt3c509Stats[28]#ifdef ELT_TIMING #define timerUpdates elt3c509Stats[29]#define timerOverflow elt3c509Stats[30]#define timerInvalid elt3c509Stats[31]#define maxRxLatency elt3c509Stats[32]#define minRxLatency elt3c509Stats[33]#define maxIntLatency elt3c509Stats[34]#define taskQRxOuts elt3c509Stats[35]#define maxRxTaskQ elt3c509Stats[36] #define taskQTxOuts elt3c509Stats[37] #define maxTxTaskQ elt3c509Stats[38] #endif /* ELT_TIMING */ /* Cache macros */#define ELT3C509_CACHE_INVALIDATE(address, len) \ CACHE_DRV_INVALIDATE (&pDrvCtrl->cacheFuncs, (address), (len))#define ELT3C509_CACHE_PHYS_TO_VIRT(address) \ CACHE_DRV_PHYS_TO_VIRT (&pDrvCtrl->cacheFuncs, (address))#define ELT3C509_CACHE_VIRT_TO_PHYS(address) \ CACHE_DRV_VIRT_TO_PHYS (&pDrvCtrl->cacheFuncs, (address))/* * Default macro definitions for BSP interface. * These macros can be redefined in a wrapper file, to generate * a new module with an optimized interface. *//* Macro to connect interrupt handler to vector */#ifndef SYS_INT_CONNECT# define SYS_INT_CONNECT(pDrvCtrl,rtn,arg,pResult) \ { \ *pResult = intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (pDrvCtrl->ivec), \ rtn, (int)arg); \ }#endif/* Macro to disconnect interrupt handler from vector */#ifndef SYS_INT_DISCONNECT# define SYS_INT_DISCONNECT(pDrvCtrl,rtn,arg,pResult) \ { \ *pResult = OK; \ }#endif/* Macro to enable the appropriate interrupt level */#ifndef SYS_INT_ENABLE# define SYS_INT_ENABLE(pDrvCtrl) \ { \ IMPORT void sysEltIntEnable(); \ sysEltIntEnable (pDrvCtrl->intLevel); \ }#endif/* Macro to disable the appropriate interrupt level */#ifndef SYS_INT_DISABLE# define SYS_INT_DISABLE(pDrvCtrl) \ { \ IMPORT void sysEltIntDisable (); \ sysEltIntDisable (pDrvCtrl->intLevel); \ }#endif/* * Macros to do a byte access to the chip. Uses * sysOutByte() and sysInByte(). */#ifndef SYS_OUT_BYTE# define SYS_OUT_BYTE(pDrvCtrl,addr,value) \ { \ sysOutByte((addr), (value)); \ }#endif#ifndef SYS_IN_BYTE# define SYS_IN_BYTE(pDrvCtrl,addr,data) \ { \ (data) = sysInByte((addr)); \ }#endif /* * Macros to do a word access to the chip. Uses * sysOutWord() and sysInWord(). */#ifndef SYS_OUT_WORD# define SYS_OUT_WORD(pDrvCtrl,addr,value) \ { \ sysOutWord((addr), (value)); \ }#endif#ifndef SYS_IN_WORD# define SYS_IN_WORD(pDrvCtrl,addr,data) \ { \ (data) = sysInWord((addr)); \ }#endif #ifndef SYS_IN_WORD_STRING#define SYS_IN_WORD_STRING(pDrvCtrl, reg, pData, len) \ { \ sysInWordString ((reg), (pData),(len)); \ }#endif#ifndef SYS_OUT_WORD_STRING#define SYS_OUT_WORD_STRING(pDrvCtrl, reg, pData, len) \ { \ sysOutWordString ((reg),(pData), (len)); \ }#endif /* 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 VOID_TO_DRVCTRL(pVoid,pDrvCtrl) ((pDrvCtrl)=(ELT3C509_DEVICE *)(pVoid))/* externs */IMPORT int endMultiLstCnt (END_OBJ *);M_CL_CONFIG elt3c509MclConfig = /* network mbuf configuration table */ { /* no. mBlks no. clBlks memArea memSize ----------- ---------- ------- ------- */ 0, 0, NULL, 0 };CL_DESC elt3c509ClDescTbl [] = /* network cluster pool configuration table */ { /* clusterSize num memArea memSize ----------- ---- ------- ------- */ {ELT3C509_BUFSIZ, 0, NULL, 0} }; int elt3c509ClDescTblNumEnt = (NELEMENTS(elt3c509ClDescTbl));/* DEBUG MACROS */#undef DRV_DEBUG#ifdef DRV_DEBUGint elt3c509Debug = 0x0f; /* Turn it off initially. */NET_POOL * pEltPool;#define ENDLOGMSG(x) \ if (elt3c509Debug) \ { \ logMsg x; \ }#else#define ENDLOGMSG(x)#endif /* DRV_DEBUG *//* forward static functions */ STATUS elt3c509Parse (ELT3C509_DEVICE *, char *);LOCAL STATUS elt3c509Start (void * pEnd);LOCAL STATUS elt3c509Stop (void * pEnd);LOCAL STATUS elt3c509Unload (void * pEnd);LOCAL int elt3c509Ioctl (void * pEnd, int cmd, caddr_t data);LOCAL STATUS elt3c509Send (void * pEnd, M_BLK_ID pBuf);LOCAL STATUS elt3c509MCastAdd (void * pEnd, char * pAddress);LOCAL STATUS elt3c509MCastDel (void * pEnd, char * pAddress);LOCAL STATUS elt3c509MCastGet (void * pEnd, MULTI_TABLE * pTable);LOCAL STATUS elt3c509PollSend (void * pEnd, M_BLK_ID pBuf);LOCAL STATUS elt3c509PollRcv (void * pEnd, M_BLK_ID pBuf);LOCAL void elt3c509Reset (ELT3C509_DEVICE * pDrvCtrl);LOCAL void elt3c509Int (ELT3C509_DEVICE * pDrvCtrl);LOCAL void elt3c509HandlePktsRcv (ELT3C509_DEVICE * pDrvCtrl);LOCAL STATUS elt3c509BoardInit (ELT3C509_DEVICE * pDrvCtrl);LOCAL void elt3c509Config (ELT3C509_DEVICE * pDrvCtrl);LOCAL STATUS elt3c509PollStart (ELT3C509_DEVICE * pDrvCtrl);LOCAL STATUS elt3c509PollStop (ELT3C509_DEVICE * pDrvCtrl);LOCAL STATUS elt3c509MemInit (ELT3C509_DEVICE * pDrvCtrl);LOCAL void elt3c509IntDisable (ELT3C509_DEVICE * pDrvCtrl);LOCAL void elt3c509IntEnable (ELT3C509_DEVICE * pDrvCtrl);LOCAL void elt3c509RxStart (ELT3C509_DEVICE * pDrvCtrl);LOCAL void elt3c509TxStart (ELT3C509_DEVICE * pDrvCtrl);LOCAL STATUS elt3c509Activate (ELT3C509_DEVICE * pDrvCtrl);LOCAL void elt3c509IdCommand (int idPort);LOCAL UINT16 elt3c509IdEepromRead (int address);LOCAL int elt3c509EepromRead (int port, int offset);LOCAL void elt3c509IntMaskSet (ELT3C509_DEVICE * pDrvCtrl, int maskBits);LOCAL void elt3c509StatFlush (ELT3C509_DEVICE * pDrvCtrl);/* LOCALS *//* * Declare our function table. This is static across all driver * instances.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -