⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 if_lnpci.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* if_lnPci.c - AMD Am79C970 PCnet-PCI Ethernet network interface driver *//* Copyright 1984-1997 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01g,28apr99,dat  Merge from 2_0_001h,26aug98,sut  Renamed lnCSR_3B to lnPciCSR_3B DOC required01g,15jul97,spm  added ARP request to SIOCSIFADDR ioctl handler01f,19may97,spm  removed compiler warnings and unused function lnBcrRead()01e,15may97,spm  reverted to bcopy routines for mbufs in BSD 4.401d,13may97,map  made ethernet addr copy, and ether packet type endian safe;                 reinit BCNT for Rx descriptors  [SPR# 8431]01c,28apr97,map  added lnRestart functionality [SPR# 8223]01b,01apr97,spm  code cleanup, corrected statistics, and upgraded to BSD 4.401a,11jan95,vin	 written from 02q of if_ln.c with minimal clean up.*//*This module implements the Advanced Micro Devices Am79C970 PCnet-PCIEthernet 32 bit network interface driver.The PCnet-PCI ethernet controller is inherently little endian becausethe chip is designed to operate on a PCI bus which is a little endianbus. The software interface to the driver is divided into three parts.The first part is the PCI configuration registers and their set up. This part is done at the BSP level in the various BSPs which use thisdriver. The second and third part are dealt in the driver. The secondpart of the interface comprises of the I/O control registers and theirprogramming. The third part of the interface comprises of the descriptorsand the buffers. 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. Big endian processors can be connected to the PCI bus through some controllerswhich take care of hardware byte swapping. In such cases all the registers which the chip DMA s to have to be swapped and written to, so that when thehardware swaps the accesses, the chip would see them correctly. The chip stillhas to be programmed to operated in little endian mode as it is on the PCI bus.If the cpu board hardware automatically swaps all the accesses to and from thePCI bus, then input and output byte stream need not be swapped. 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 lnPciattach(), which publishes the `lnPci'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_long lnPciCSR_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 Am79C970 (PCnet-PCI).".iP "base address of device registers"This parameter is passed to the driver by lnPciattach().  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 lnPciattach().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 lnPciattach().Some targets use additional interrupt controller devices to help organize andservice the various interrupt sources.  This driver avoids all board-specificknowledge of such devices.  During the driver's initialization, the externalroutine sysLanIntEnable() is called to perform any board-specific operationsrequired to turn on LANCE interrupt generation. A similar routine,sysLanIntDisable(), is called by the driver before a LANCE reset to performboard-specific operations required to turn off LANCE interrupt generation.For a description of sysLanIntEnable(), and sysLanIntDisable(), see "ExternalSupport Requirements" below.This parameter is passed to the external routine..iP "shared memory address"This parameter is passed to the driver by lnPciattach().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 lnPciattach().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 lnPciattach().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 "shared memory buffer size"This parameter is passed to the driver by lnPciattach().The driver and LANCE device exchange network data in buffers.  Thisparameter permits the size of these individual buffers to be limited.A value of zero indicates that the default buffer size should be used.The default buffer size is large enough to hold a maximum-size Ethernetpacket.Use of this parameter should be rare.  Network performancewill be affected, since the target will no longer be able to receiveall valid packet sizes..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 for the LANCEdevice.  Typically, this involves programming an interrupt controllerhardware, either internal or external to the CPU.This routine is called during chip initialization, at startup and each LANCEdevice reset..iP "void sysLanIntDisable (int level)" "" 9 -1This routine provides a target-specific disable of the interrupt for the LANCEdevice.  Typically, this involves programming an interrupt controllerhardware, either internal or external to the CPU.This routine is called before a LANCE device reset..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 lnPciattach()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 PCnet-PCI Ethernet Controller for PCI."*/#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"#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 "semLib.h"#include "drv/netif/if_lnPci.h"		/* device description header *//***** LOCAL DEFINITIONS *****//* descriptor size */#define RMD_SIZ  sizeof(ln_rmd)#define TMD_SIZ  sizeof(ln_tmd)/* Configuration items */#define LN_MIN_FIRST_DATA_CHAIN 96      /* min size of 1st buf in data-chain */#define LN_MAX_MDS              128     /* max number of [r|t]md's for LANCE */#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 MAX_UNITS       1       /* 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 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_VIRT_TO_PHYS(address) \        CACHE_DRV_VIRT_TO_PHYS (&pDrvCtrl->cacheFuncs, (address))#define LN_CACHE_PHYS_TO_VIRT(address) \        CACHE_DRV_PHYS_TO_VIRT (&pDrvCtrl->cacheFuncs, (address))/* memory to PCI address translation macros */#define PCI_TO_MEM_PHYS(pciAdrs) \	((pciAdrs) - (pDrvCtrl->pciMemBase))	#define MEM_TO_PCI_PHYS(memAdrs) \	((memAdrs) + (pDrvCtrl->pciMemBase))/* 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;#ifdef BSD43_DRIVER/* The Ethernet header */typedef struct enet_hdr    {    char dst [6];    char src [6];    u_short type;    } ENET_HDR;#define ENET_HDR_SIZ        sizeof(ENET_HDR)#endif            /* BSD43_DRIVER */#define ENET_HDR_REAL_SIZ   14/* The definition of the driver control structure */typedef struct drv_ctrl    {    IDR         idr;                /* Interface Data Record */    ln_ib       *ib;                 /* ptr to Initialization Block */    struct        {        int     r_po2;                  /* RMD ring size as a power of 2! */        int     r_size;                 /* RMD ring size (power of 2!) */        int     r_index;                /* index into RMD ring */        ln_rmd  *r_ring;                /* RMD ring */        char    *r_bufs;                /* receive buffers base */        } rmd_ring;    struct        {        int     t_po2;                  /* TMD ring size as a power of 2! */        int     t_size;                 /* TMD ring size (power of 2!) */        int     t_index;                /* index into TMD ring */        int     d_index;                /* index into TMD ring */        ln_tmd  *t_ring;                /* TMD ring */        char    *t_bufs;                /* transmit buffers base */        } tmd_ring;    BOOL        attached;               /* indicates unit is attached */    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 */    char        *memBase;               /* LANCE memory pool base */    int         memWidth;               /* width of data port */    ULONG	pciMemBase;		/* memory base as seen from PCI*/    int         bufSize;                /* size of buffer in the LANCE ring */    CACHE_FUNCS cacheFuncs;             /* cache function pointers */    } DRV_CTRL;#define DRV_CTRL_SIZ    sizeof(DRV_CTRL)/* 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_START_OUTPUT_FLAG    0x10/* Shorthand structure references */#define rpo2         rmd_ring.r_po2#define rsize        rmd_ring.r_size#define rindex       rmd_ring.r_index#define rring        rmd_ring.r_ring#define tpo2         tmd_ring.t_po2#define tsize        tmd_ring.t_size#define tindex       tmd_ring.t_index#define dindex       tmd_ring.d_index#define tring        tmd_ring.t_ring/***** GLOBALS *****/IMPORT unsigned char lnEnetAddr []; /* Ethernet address to load into lance */ULONG lnPciCSR_3B = 0 ;    /* allows external setting of bus modes */void panic ();void ether_attach ();void sysLanIntEnable (int ilevel);void sysLanIntDisable (int ilevel);BOOL arpresolve ();/***** LOCALS *****/static int lnTsize = LN_TMD_TLEN;    /* deflt xmit ring size as power of 2 */static int lnRsize = LN_RMD_RLEN;    /* deflt recv ring size as power of 2 */static BOOL lnKickStartTx = LN_KICKSTART_TX;/* The array of driver control structures */static DRV_CTRL  drvCtrl [MAX_UNITS];/* initial word offsets from LANCE base address to access these registers */static u_int CSROffset = 0;static u_int RAPOffset = 1;static u_int BDPOffset = 3;/* forward static functions */static void 	lnReset (int unit);static void 	lnInt (DRV_CTRL *pDrvCtrl);static void 	lnHandleRecvInt (DRV_CTRL *pDrvCtrl);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -