📄 if_ln.c
字号:
/* if_ln.c - AMD Am7990 LANCE Ethernet network interface driver *//* Copyright 1984-1997 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02x,15jul97,spm added ARP request to SIOCSIFADDR ioctl handler02w,10jun97,spm removed frame check sequence from length of incoming packets02v,04jun97,spm corrected errors introduced during merge from Sirocco tree02u,19may97,spm eliminated all compiler warnings02t,15may97,spm included changes from versions 02r and 02s of Sirocco tree02s,23jan97,vin upgraded to BSD4402s,06feb96,dat added check for inactive interrupt, at end of lnInt. Added a real lnRestart function.02r,11nov94,vin incorporated the etherOutputHook routine.02r,15jun94,dzb [re]implemented buffer loaning, multiple unit support.02q,11aug93,jmm Changed ioctl.h and socket.h to sys/ioctl.h and sys/socket.h02p,19feb93,jdi documentation cleanup.02o,13oct92,rfs Added documentation.02n,02oct92,rfs ANSI warnings go away.02m,02oct92,rfs Made multiple attach calls per unit return OK.02l,09sep92,gae documentation tweaks.02k,02aug92,rfs Merged with cache changes from previous version, added virtual address conversion and write pipe flushing. Removed code that appeared to handle chained incoming packets, but in fact could not do so. Receive buffers must always be large enough to hold a complete packet. Removed promiscuous support. Moved all startup code to the attach routine. Eliminated the init() routine and provided stub for a restart routine that will handle the fatal errors. Removed support for buffer loaning, as it was wrong as well. Revised the ioctl() routine, which was also wrong. Moved driver control structure(s) to bss and changed name used for pointer. Overhauled the transmit routines to discontinue the obsolete usage of the output queue. Added the transmit semaphore. Many other misc.02j,31jul92,dave Changed to new cacheLib.02i,30jul92,rfs Changed the way collisions are counted.02h,29jul92,rfs Typedef'd and renamed the driver control structure and, changed all references to it.02g,29jul92,rfs Moved driver specific items here from the header file.02f,17jul92,jwt added missing cache funtion pointers for "default" case.02e,13jul92,rdc now uses cacheMalloc.02d,12jul92,jcf cacheMalloc() call uses malloc() for 68k 'til cacheMc68kLib.02c,06jul92,jwt removed SPARC sysCacheSet() function calls due to 02c; forced conversion of &cacheFuncs to pointer for macros; cleaned up some typos and compiler warning messages. 02jul92,rfs Added cache coherency support. Added blank lines between functions.02b,26may92,rrr the tree shuffle -changed includes to have absolute path from h/02a,27apr92,jwt converted CPU==SPARC to CPU_FAMILY==SPARC.01z,09oct91,jpb rewrote to fix error handling for transmitter errors, should no longer hang. channel all chip accesses through new functions lnCsrRead and lnCsrWrite, and minimize chip accesses including eliminating transmitter kick-start in lnStartOutput if selected with lnKickStartTx == FALSE. modified to adapt to the LANCE chip alignment which eliminated the need for the RAP padding flags. fixed infinite loop on initialization failure to timeout. cleaned up some ansification remnants.01y,04oct91,rrr passed through the ansification filter -changed functions to ansi style -changed includes to have absolute path from h/ -changed VOID to void -changed copyright notice01x,02oct91,jwt restored lnCSR_3B global variable for Radstone Apex driver.01w,25jul91,jwt removed bit fields (added masks) for portability, correctness.01v,06mar91,hvh aligned buffers for SPARC optimizations.01u,20feb91,jwt added sysCacheSet() call for DMA and caching support.01t,10apr91,jdi documentation cleanup; doc review by elh.01s,20sep90,dab made lnInit() return int.01r,10aug90,dnw added forward declarations of void routines. added include of if_subr.h.01q,11jul90,hjb removed references to ipintr().01p,26jun90,hjb copy_from_mbufs() & m_freem() fix; changed params to bulid_cluster().01o,11may90,yao added missing modification history (01n) for the last checkin.01n,09may90,yao typecasted malloc to (char *).01m,07may90,hjb new RMD loans implementation to avoid hangups.01l,19apr90,hjb deleted param.h, added LN_RMD_GIVE_TO_LANCE, deleted lnHandleXmitInt and ln_bcopy, added lnRmdFree to support cluster-callback optimization, speed-ups in lnInt(), use of LS_ flags, de-linted, modifications to receive routines, added lnLoansPrint() debug routine.01k,18mar90,hjb reduction of redundant code and addition of cluster support. added input error checking in RINT handling code to reduce unnecessary netJobAdd's. recoded the Tadpole padding check. added crude LANCE data chaining support.01j,08nov89,dab added check for Tadpole cpu to enable padding of CSR structure.01i,07aug89,gae changed iv68k.h to iv.h.01h,28jun89,hjb fixed a bug in lnIoctl() -- SIOCSIFFLAGS handling was buggy.01g,13jun89,hjb changed mtu to ETHERMTU (from 1000). check lnLogCount before doing modulo operation to make sure it's not zero.01f,12jun89,hjb added a missing splx (s) in lnRecv ().01e,24may89,jcf reduced netJobAdd () calls by handling more receive packets +dnw at task level, and calling ipintr directly from lnRecv.01d,14feb89,jcf changed copy from/to interface to use appropriate data width. changed lnattach to optionally take address of memory pool. added macros ItoK(), KtoI(), etc. removed superfluous lnConfig() call from lnattach(). +dnw improved error reporting and recovery.01c,07sep88,gae added global variable lnLogCount so that dropped interrupts are not normally reported.01b,09aug88,gae made lnattach have usual number of parameters. Lint.01a,28apr88,dfm written based on other drivers (if_xx) & LANCE documentation.*//*This module implements the Advanced Micro Devices Am7990 LANCE Ethernet networkinterface driver.This driver is designed to be moderately generic, operating unmodifiedacross the range of architectures and targets supported by VxWorks. Toachieve this, the driver must be given several target-specific parameters,and some external support routines must be provided. These parameters,and the mechanisms used to communicate them to the driver, are detailedbelow. If any of the assumptions stated below are not true for yourparticular hardware, this driver will probably not function correctly withit.This driver supports only one LANCE unit per CPU. The driver can beconfigured to support big-endian or little-endian architectures. Itcontains error recovery code to handle known device errata related to DMAactivity.BOARD LAYOUTThis device is on-board. No jumpering diagram is necessary.EXTERNAL INTERFACEThis driver provides the standard external interface with the followingexceptions. All initialization is performed within the attach routine;there is no separate initialization routine. Therefore, in the global interfacestructure, the function pointer to the initialization routine is NULL.The only user-callable routine is lnattach(), which publishes the `ln'interface and initializes the driver and device.TARGET-SPECIFIC PARAMETERS.iP "bus mode"This parameter is a global variable that can be modified at run-time.The LANCE control register #3 determines the bus mode of the device,allowing the support of big-endian and little-endian architectures.This parameter, defined as "u_short lnCSR_3B", is the value that willbe placed into LANCE control register #3. The default value supportsMotorola-type buses. For information about changing this parameter, see the manual.I "Advanced Micro Devices Local Area Network Controller Am7990 (LANCE).".iP "base address of device registers"This parameter is passed to the driver by lnattach(). It indicates to the driver where to find the RDP register.The LANCE presents two registers to the external interface, the RDP (registerdata port) and RAP (register address port) registers. This driver assumes that these two registers occupy two unique addresses in a memory spacethat is directly accessible by the CPU executing this driver. The driverassumes that the RDP register is mapped at a lower address than the RAPregister; the RDP register is therefore considered the "base address.".iP "interrupt vector"This parameter is passed to the driver by lnattach().This driver configures the LANCE device to generate hardware interruptsfor various events within the device; thus it containsan interrupt handler routine. The driver calls intConnect() to connect its interrupt handler to the interrupt vector generated as a result of the LANCE interrupt..iP "interrupt level"This parameter is passed to the driver by lnattach().Some targets use additional interrupt controller devices to help organizeand service the various interrupt sources. This driver avoids allboard-specific knowledge of such devices. During the driver'sinitialization, the external routine sysLanIntEnable() is called toperform any board-specific operations required to allow the servicing of aLANCE interrupt. For a description of sysLanIntEnable(), see "ExternalSupport Requirements" below.This parameter is passed to the external routine..iP "shared memory address"This parameter is passed to the driver by lnattach().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 driver attempts to allocate the shared memory from the system space..iP "shared memory size"This parameter is passed to the driver by lnattach().This parameter can be used to explicitly limit the amount of sharedmemory (bytes) this driver will use. The constant NONE can be used toindicate no specific size limitation. This parameter is used only ifa specific memory region is provided to the driver..iP "shared memory width"This parameter is passed to the driver by lnattach().Some target hardware that restricts the shared memory region to aspecific location also restricts the access width to this region bythe CPU. On these targets, performing an access of an invalid widthwill cause a bus error.This parameter can be used to specify the number of bytes of accesswidth to be used by the driver during access to the shared memory.The constant NONE can be used to indicate no restrictions.Current internal support for this mechanism is not robust; implementation may not work on all targets requiring these restrictions..iP "Ethernet address"This parameter is obtained directly from a global memory location.During initialization, the driver needs to know the Ethernet address forthe LANCE device. The driver assumes that this address is available ina global, six-byte character array, lnEnetAddr[]. This array istypically created and stuffed by the BSP code..LPEXTERNAL SUPPORT REQUIREMENTSThis driver requires one external support function:.iP "void sysLanIntEnable (int level)" "" 9 -1This routine provides a target-specific enable of the interrupt forthe LANCE device. Typically, this involves interrupt controller hardware,either internal or external to the CPU.This routine is called once, from the lnattach() routine..LPSYSTEM RESOURCE USAGEWhen implemented, this driver requires the following system resources: - one mutual exclusion semaphore - one interrupt vector - 24 bytes in the initialized data section (data) - 208 bytes in the uninitialized data section (BSS)The above data and BSS requirements are for the MC68020 architecture and may vary for other architectures. Code size (text) varies greatly betweenarchitectures and is therefore not quoted here.If the driver is not given a specific region of memory via the lnattach()routine, then it calls cacheDmaMalloc() to allocate the memory to be shared with 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 coherencyfor the device for data that is written by the driver because fieldswithin the shared structures are asynchronously modified by both the driverand the device, and these fields may share the same cache line.SEE ALSO: ifLib, .I "Advanced Micro Devices Local Area Network Controller Am7990 (LANCE)"*//* includes */#include "vxWorks.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 "cacheLib.h"#include "sys/ioctl.h"#include "etherLib.h"#include "net/mbuf.h"#include "net/protosw.h"#include "net/unixLib.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 "semLib.h"#include "drv/netif/if_ln.h" /* device description header *//* defines */#define LN_BUFSIZ (ETHERMTU + SIZEOF_ETHERHEADER + 6)#define LN_RMD_RLEN 5 /* default Rx ring size as a power of 2 (32) */#define LN_TMD_TLEN 5 /* default Tx ring size as a power of 2 (32) */#define LN_L_POOL 0x10 /* number of Rx loaner buffers in pool */#define MAX_UNITS 4 /* maximum units supported *//* * 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 if 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))/* typedefs for external structures that are not typedef'd in their .h files */typedef struct mbuf MBUF;typedef struct arpcom IDR; /* Interface Data Record wrapper */typedef struct ifnet IFNET; /* real Interface Data Record */typedef struct sockaddr SOCK;#ifndef BSD43_DRIVERtypedef struct ether_header ETH_HDR; #endif /* BSD43_DRIVER *//* the definition of the driver control structure */typedef struct drv_ctrl { IDR idr; /* Interface Data Record */ char * pMemPool; /* start of LANCE memory pool */ BOOL attached; /* indicates unit is attached */ int rmdIndex; /* current RMD index */ int rringSize; /* RMD ring size */ int rringLen; /* RMD ring length (bytes) */ ln_rmd * rring; /* RMD ring start */ char * rBufBase; /* Rx buffer base address */ int tmdIndex; /* current TMD index */ int tmdIndexC; /* current TMD index */ int tringSize; /* TMD ring size */ int tringLen; /* TMD ring length (bytes) */ ln_tmd * tring; /* TMD ring start */ char * tBufBase; /* Tx buffer base address */ SEM_ID TxSem; /* transmitter semaphore */ u_char flags; /* misc control flags */ int ivec; /* interrupt vector */ int ilevel; /* interrupt level */ LN_DEVICE * devAdrs; /* device structure address */ int memWidth; /* width of data port */ CACHE_FUNCS cacheFuncs; /* cache function pointers */ int nLoanRx; /* number of Rx buffers left to loan */ char * lPool[LN_L_POOL]; /* receive loaner pool ptrs */ UINT8 * pRefCnt[LN_L_POOL]; /* stack of reference count pointers */ UINT8 refCnt[LN_L_POOL]; /* actual reference count values */ } DRV_CTRL;#define DRV_CTRL_SIZ sizeof(DRV_CTRL)#define DC_SIZ sizeof(LN_DC_BUF)#ifdef BSD43_DRIVER#define ENET_HDR_SIZ sizeof(ETH_HDR)#endif /* BSD43_DRIVER */#define RMD_SIZ sizeof(ln_rmd)#define TMD_SIZ sizeof(ln_tmd)#define IB_SIZ sizeof(ln_ib)/* definitions for the flags field */#define LN_PROMISCUOUS_FLAG 0x1#define LN_RX_HANDLING_FLAG 0x2/* globals */IMPORT void sysLanIntEnable ();#ifdef BSD43_DRIVERIMPORT BOOL arpresolve ();#endif /* BSD43_DRIVER */IMPORT unsigned char lnEnetAddr []; /* Ethernet addr to load into lance */u_short lnCSR_3B = lncsr3_BSWP ; /* allows ext setting of bus modes */BOOL lnKickStartTx = LN_KICKSTART_TX;/* locals */LOCAL DRV_CTRL drvCtrl [MAX_UNITS]; /* array of driver control structures */LOCAL int lnTsize = LN_TMD_TLEN; /* deflt xmit ring size as power of 2 */LOCAL int lnRsize = LN_RMD_RLEN; /* deflt recv ring size as power of 2 */LOCAL int lnLPool = LN_L_POOL;/* initial word offsets from LANCE base address to access these registers */LOCAL u_int CSROffset = 0;LOCAL u_int RAPOffset = 1;/* forward declarations */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -