📄 ln7990end.c
字号:
/* ln7990End.c - END style AMD 7990 LANCE Ethernet network interface driver *//* Copyright 1984-1998 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02t,04mar99,jkf removed "+ 2" when setting pTring. added "+ 1" and "* TMD_SIZ" to lnClDescTbl[0].memArea, ln7990InitMem(), for boards that hand over a memory pool SPR#22628. changed ln7990ScrubTRing() to handle a receive packet. fixed the endMultiLstCnt implicit declaration warning.02s,06oct98,n_s correct error codes in ln7990Int.02r,30sep98,n_s removed check for RINT in PollReceive.02q,23sep98,n_s fixed ln7990Int to limit netJobAdd calls and handle overload cases. spr # 22381.02p,22sep98,n_s fixed ln7990Int to call Restart from task level.02o,21sep98,n_s corrected handling of txSem in ln7990Send ().02n,22sep98,dat SPR 22325, System mode transition.02m,17jul98,db changed "holder" in ln7990InitParse from char ** to char *. fixed references to "holder" in ln7990InitParse(spr #21464).02l,12dec97,kbw made man page edits02k,11dec97,gnn removed IFF_SCAT and IFF_LOAN.02j,08dec97,gnn END code review fixes02i,25nov97,gnn fixed spr#9620 polled mode receive02h,27oct97,vin fixed the offset problem in xxRecv() call.02g,19oct97,vin moved swapping of loaned buffer before END_RCV_RTN_CALL02f,17oct97,vin removed extra free.02e,07oct97,vin MIB MTU size to ETHER_MTU02d,03oct97,gnn added example error upcall code02c,25sep97,gnn fixed SPARC issues and cleaned up memory problems.02b,03sep97,gnn fixed a crashing bug under heavy load02a,31aug97,vin reimplemented txBlocked logic, moved the txBlocked variable into the drvCtrl structure.01z,25aug97,gnn changes due to new netPoolInit routine.01y,22aug97,gnn rewrote and fixed polled mode01x,19aug97,gnn changes due to new buffering scheme.01w,12aug97,gnn changes necessitated by MUX/END update.01v,02jun97,gnn implemented new Memory Width ioctl.01u,20may97,spm corrected memory alignment, added a real lnRestart function 01t,17apr97,gnn added offset load parameter.01s,24feb97,gnn Removed an unecessary step in the interrupt routine. Added code to properly pass back NET_BUFFER fields.01r,05jan97,gnn Turned IFF_SCAT off by default.01q,03feb97,gnn Changed the way in which muxBufAlloc is used. Added speed as an argument to MIB stuff.01p,22jan97,gnn Turned IFF_SCAT off by default.01o,22jan97,gnn Changed code to get the enet address from the BSP.01n,21jan97,gnn Added code to handle send side free routines. Added code to handle scatter/gather interface. Added code to better handle polled mode. Removed code that is common to all ENDs into endLib.c.01m,06jan97,gnn Fixed compilation errors and removed more non-driver stuff.01l,23dec96,dat added macros, added csr3B, enetAddr to init string,01k,02dec96,gnn forgot a break in the Ioctl.01j,27nov96,gnn added MIB 2 Ioctl.01i,19nov96,gnn Added IFF_BROADCAST to the flags.01h,13nov96,dat Restructured to isolate end/mib routines01g,22oct96,gnn Name changes to follow coding standards. static functions changed to LOCAL.01f,22oct96,gnn Removed all netVectors and replaced them with netBuffers. Did a significant code cleanup in preparation for going to a 32bit world with a 24 bit driver.01e,23sep96,gnn Cleanup of code. Changed pointers to look like WRS pointers and the like. Made is so that the ln7990Config routine works correctly to fill in the transmit and receive descriptors' memory fields. This version works with system level debugging or buffer loaning but not with both.01d,28aug96,gnn Fixed argument parsing for pre-allocated memory. Added more log messages to the load sequence.01c,15aug96,gnn Name changes to follow our coding standard.01b,14aug96,gnn Worked the documentation and other stuff over to integrate into the new scheme of network drivers.01a,22apr96,gnn Copied if_ln driver and worked into the END scheme.*//*This module implements the Advanced Micro Devices Am7990 LANCE Ethernet networkinterface driver. The driver can be configured to support big-endian orlittle-endian architectures, and it contains error recovery code to handle known device errata related to DMA activity.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. If any of the assumptions stated below are not true for your particular hardware, this driver might not function correctly with that hardware.BOARD LAYOUTThis device is on-board. No jumpering diagram is necessary.EXTERNAL INTERFACEThe only external interface is the ln7990EndLoad() routine, which expectsthe <initString> parameter as input. This parameter passes in a colon-delimited string of the format:<unit>:<CSR_reg_addr>:<RAP_reg_addr>:<int_vector>:<int_level>:<shmem_addr>:<shmem_size>:<shmem_width>:<offset>:<csr3B>The ln7990EndLoad() 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 <CSR_register_addr>Tells the driver where to find the CSR register..IP <RAP_register_addr>Tells the driver where to find the RAP register..IP <int_vector>Configures the LANCE device to generate hardware interruptsfor various events within the device. Thus, it containsan interrupt handler routine. The driver calls sysIntConnect() to connectits interrupt handler to the interrupt vector generated as a result ofthe LANCE interrupt..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 LANCE 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 <shmem_addr>The LANCE device is a DMA type of device and typically shares access tosome region of memory with the CPU. This driver is designed for systemsthat directly share memory between the CPU and the LANCE. Itassumes that this shared memory is directly available to itwithout any arbitration or timing concerns.This parameter can be used to specify an explicit memory region for useby the LANCE. This should be done on hardware that restricts the LANCEto a particular memory region. The constant NONE can be used to indicatethat there are no memory limitations, in which case, the driverattempts to allocate the shared memory from the system space..IP <shmem_size>Use this parameter to explicitly limit the amount of shared memory (bytes) that this driver uses. Use "NONE" to indicate that there is no specific size limitation. This parameter is used only if a specific memory region is provided to the driver..IP <shmem_width>Some target hardware that restricts the shared memory region to aspecific location also restricts the access width to this region bythe CPU. On such targets, performing an access of an invalid widthcauses a bus error. Use this parameter to specify the number of bytes on which data must be aligned if it is to be used by the driver during access to the shared memory. Use "NONE" to indicate that there are no restrictions. The support for this mechanism is not robust. Thus, its current implementation might not work on all targets requiring these restrictions..IP <offset>Specifies the memory alignment offset..IP <csr3B>Specifies the value that is placed into LANCE control register #3. Thisvalue determines the bus mode of the device and thus allows the support ofbig-endian and little-endian architectures. The default value supportsMotorola-type buses. Normally this value is 0x4. For SPARC CPUs, it isnormally set to 0x7 to add the ACON and BCON control bits. For moreinformation on this register and the bus mode of the LANCE controller, see.I "Advanced Micro Devices Local Area Network Controller Am7990 (LANCE).".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) SYS_OUT_SHORT(pDrvCtrl, reg, data) SYS_IN_SHORT(pDrvCtrl, reg, pData).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 interrupt vector - 68 bytes in the initialized data section (data) /@HELP@/ - 0 bytes of bss /@HELP@/The above data and BSS requirements are for the MC68020 architectureand can vary for other architectures. Code size (text) varies greatly between architectures and is therefore not quoted here.If the driver is not given a specific region of memory using the ln7990EndLoad()routine, then it calls cacheDmaMalloc() to allocate the memory to be sharedwith the LANCE. The size requested is 80,542 bytes. If a memory regionis provided to the driver, the size of this region is adjustable to suituser needs.The LANCE can only be operated if the shared memory region is write-coherentwith the data cache. The driver cannot maintain cache coherency for data that is written by the driver. That is because members within the shared structures are asynchronously modified by both the driver and the device, and these members might share the same cache line.SEE ALSO: muxLib,.I "Advanced Micro Devices Local Area Network Controller Am7990 (LANCE)"*/#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 "etherLib.h"#ifndef DOC /* don't include when building documentation */#include "net/mbuf.h"#endif /* DOC */#include "net/protosw.h"#include "sys/socket.h"#include "errno.h"#include "net/if.h"#include "net/route.h"#include "netinet/in.h"#include "netinet/in_systm.h"#include "netinet/in_var.h"#include "netinet/ip.h"#include "netinet/if_ether.h"#include "net/if_subr.h"#include "m2Lib.h"#include "drv/end/ln7990EndCommon.h" /* Common defines. */#include "drv/end/ln7990End.h" /* device description header */#include "etherMultiLib.h" /* multicast stuff. */#include "end.h" /* Common END structures. */#include "netBufLib.h"#include "muxLib.h"#undef END_MACROS#include "endLib.h"#include "lstLib.h" /* Needed to maintain protocol list. *//***** LOCAL DEFINITIONS *****/#define DELAY(count) { \ volatile int cx = 0; \ for (cx = 0; cx < (count); cx++); \ }/* Configuration items */#define LN_BUFSIZ (ETHERMTU + ENET_HDR_REAL_SIZ + 6)#define LN_RMD_RLEN 5 /* ring size as a power of 2 -- 32 RMD's */#define LN_TMD_TLEN 5 /* same for transmit ring -- 32 TMD's */#define LN_SPEED 10000000/* Naming items */#define LN_DEV_NAME "ln"#define LN_DEV_NAME_LEN 3/* * If LN_KICKSTART_TX is TRUE the transmitter is kick-started to force a * read of the transmit descriptors, otherwise the internal polling (1.6msec) * will initiate a read of the descriptors. This should be FALSE is there * is any chance of memory latency or chip accesses detaining the LANCE DMA, * which results in a transmitter UFLO error. This can be changed with the * global lnKickStartTx below. */#define LN_KICKSTART_TX TRUE/* Cache macros */#define LN_CACHE_INVALIDATE(address, len) \ CACHE_DRV_INVALIDATE (&pDrvCtrl->cacheFuncs, (address), (len))#define LN_CACHE_PHYS_TO_VIRT(address) \ CACHE_DRV_PHYS_TO_VIRT (&pDrvCtrl->cacheFuncs, (address))#define LN_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. */#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 void sysLanIntEnable(); \ sysLanIntEnable (pDrvCtrl->ilevel); \ }#endif /*SYS_INT_ENABLE*/#ifndef SYS_OUT_SHORT#define SYS_OUT_SHORT(pDrvCtrl,addr,value) \ { \ *(USHORT *)addr = value; \ }#endif /*SYS_OUT_SHORT*/#ifndef SYS_IN_SHORT#define SYS_IN_SHORT(pDrvCtrl,addr,pData) \ (*(USHORT *)pData = *(USHORT *)addr)#endif /*SYS_IN_SHORT*/#ifndef SYS_ENET_ADDR_GET#define SYS_ENET_ADDR_GET(pAddress) \ { \ IMPORT unsigned char lnEnetAddr[]; \ bcopy ((char *)lnEnetAddr, (char *)(pAddress), 6); \ }#endif /* SYS_ENET_ADDR_GET *//* 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))typedef struct free_args { void* arg1; void* arg2; } FREE_ARGS; /* The definition of the driver control structure */typedef struct ln_device { END_OBJ end; /* The class we inherit from. */ ln_ib *ib; /* ptr to Initialization Block */ int unit; /* unit number */ int rmdIndex; /* current RMD index */ int rringSize; /* RMD ring size */ int rringLen; /* RMD ring length (bytes) */ ln_rmd* pRring; /* RMD ring start */ int tmdIndex; /* current TMD index */ int tmdIndexC; /* current TMD index */ int tringSize; /* TMD ring size */ int tringLen; /* TMD ring length (bytes) */ ln_tmd* pTring; /* TMD ring start */ int ivec; /* interrupt vector */ int ilevel; /* interrupt level */ u_short* pCsr; /* device register CSR */ u_short* pRap; /* device register RAP */ char* pShMem; /* real ptr to shared memory */ char* memBase; /* LANCE memory pool base */ char* memAdrs; /* LANCE memory pool base */ int memSize; /* LANCE memory pool size */ int memWidth; /* width of data port */ int offset; int csr0Errs; /* count of csr0 errors */ long flags; /* Our local flags. */ UCHAR enetAddr[6]; /* ethernet address */ USHORT csr3B; CACHE_FUNCS cacheFuncs; /* cache function pointers */ BOOL txBlocked; /* transmit flow control */ BOOL txCleaning; FUNCPTR freeRtn[128]; /* Array of free routines. */ struct free_args freeData[128]; /* Array of free arguments */ /* the free routines. */ CL_POOL_ID pClPoolId; END_ERR lastError; /* Last error passed to muxError */ BOOL errorHandling; /* task level error handling */ u_short errorStat; /* error status */ } LN7990END_DEVICE;/* Definitions for the flags field */#define LS_PROMISCUOUS_FLAG 0x1#define LS_MEM_ALLOC_FLAG 0x2#define LS_PAD_USED_FLAG 0x4#define LS_RCV_HANDLING_FLAG 0x8#define LS_POLLING 0x20/* network buffers configuration */M_CL_CONFIG lnMclConfig = /* mBlk configuration table */ { 0, 0, NULL, 0 };CL_DESC lnClDescTbl [] = /* network cluster pool configuration table */ { /* clusterSize num memArea memSize ----------- ---- ------- ------- */ {LN_BUFSIZ, 0, NULL, 0} }; int lnClDescTblNumEnt = (NELEMENTS(lnClDescTbl));/***** DEBUG MACROS *****/#undef DRV_DEBUG#ifdef DRV_DEBUG#define DRV_DEBUG_OFF 0x0000#define DRV_DEBUG_RX 0x0001
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -