📄 dec21x40end.c
字号:
/* dec21x40End.c - END-style DEC 21x40 PCI Ethernet network interface driver *//* Copyright 1984-1999 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02d,11mar99,tm Added MII/Phy r/w for 2114x link status check (SPR 22196)02c,02mar99,tm txRingClean in ISR to improve small pkt throughput (SPR 23950)02b,01feb99,scb Added support for dec21143. (SPR 22887)02a,30sep98,dbt Adding missing code in poll receive routine.01z,22sep98,dat SPR 22325, system mode transition + lint fixes.01y,07aug98,cn updated documentation about user flags.01w,31jul98,cn removed setting CSR6_FD in xxxMediaSelect [SPR# 21683]. Also moved some indeces setting in xxxStart [SPR#21557].01v,20apr98,map preserve CSR6_PS in xxxChipReset [SPR# 21013]01u,10dec97,kbw man page fiddlings01t,08dec97,gnn END code review fixes.01s,20nov97,gnn fixed spr#9555, configurable TDS and RDS.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, MIB MTU size to ETHER_MTU01n,25sep97,gnn SENS beta feedback fixes01m,24sep97,vin added clBlk related calls01l,02sep97,gnn fixed a race condition in the txRestart handling.01k,25aug97,vin adjusted cluster mem size.01j,22aug97,vin fixed initialization of cluster mem area.01i,22aug97,gnn fixed a bug in polled mode.01h,21aug97,vin added changes for newBuffering API01g,12aug97,gnn changes necessitated by MUX/END update.01f,08aug97,map fixed muxBufInit for user-specified bufpool. added ilevel arg to sysLanIntDisable(). update collision statistics. added more flags to userFlags.01e,10jun97,map renamed funcDec21x40MediaSelect to _func_dec21x40MediaSelect.01d,28may97,kbw general text edit map added DEC SROM support for media configuration.01c,23apr97,map cleaned up; replaced SWAP_SHORT with PCISWAP_SHORT.01b,16apr97,map added support for dec21140.01a,07apr97,map modified if_dc.c to END style.*//*This module implements a DEC 21x40 PCI Ethernet network interface driver andsupports both the 21040, 21140, and 21143 versions of the chip.The DEC 21x40 PCI Ethernet controller is little endian because it interfaceswith a little-endian PCI bus. Although PCI configuration for a device ishandled in the BSP, all other device programming and initialization needs are handled in this module.This driver is designed to be moderately generic. Without modification, it canoperate across the full range of architectures and targets supported by VxWorks.To achieve this, the driver requires a few external support routines as wellas several target-specific parameters. These parameters, and the mechanismsused to communicate them to the driver, are detailed below. If any of theassumptions stated below are not true for your particular hardware, you need to modify the driver before it can operate correctly on your hardware.On the 21040, the driver configures the 10BASE-T interface by default, waits fortwo seconds, and checks the status of the link. If the link status indicatesfailure, AUI interface is configured.On other versions of the 21x40 family, the driver reads media information froma DEC serial ROM and configures the media. To configure the media on targets that do not support a DEC format serial ROM, the driver calls the target-specific media-select routine referenced inthe `_func_dec21x40MediaSelect' hook. The driver supports big-endian or little-endian architectures (as a configurable option). The driver also and contains error recovery code that handles known device errata related to DMA activity.Big-endian processors can be connected to the PCI bus through some controllersthat take care of hardware byte swapping. In such cases, all the registerswhich the chip DMAs 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 operate in little endian mode as it is on the PCIbus. If the cpu board hardware automatically swaps all the accesses to andfrom the PCI bus, then input and output byte stream need not be swapped.BOARD LAYOUTThis device is on-board. No jumpering diagram is necessary.EXTERNAL INTERFACEThe driver provides one standard external interface, dec21x40EndLoad(). As input, this function expects a string of colon-separated parameters. The parameters should be specified as hexadecimal strings (optionally preceded by "0x" or a minus sign "-"). Although the parameter string is parsed using strtok_r(), each parameter is converted from string to binary by a call to:.CS strtoul(parameter, NULL, 16)..CEThe format of the parameter string is:<device_addr>:<PCI_addr>:<ivec>:<ilevel>:<num_rds>:<num_tds>:<mem_base>:<mem_size>:<user_flags>TARGET-SPECIFIC PARAMETERS.IP <device_addr>This is the base address at which the hardware device registers are located..IP <PCI_addr>This parameter defines the main memory address over the PCI bus. It is used totranslate a physical memory address into a PCI-accessible address..IP <ivec>This is the interrupt vector number of the hardware interrupt generated bythis Ethernet device. The driver uses intConnect() to attach an interrupthandler for this interrupt..IP <ilevel>This parameter defines the level of the hardware interrupt..IP <num_rds>The number of receive descriptors to use. This controls how much datathe device can absorb under load. If this is specified as NONE (-1), the default of 32 is used..IP <num_tds>The number of transmit descriptors to use. This controls how much datathe device can absorb under load. If this is specified as NONE (-1) thenthe default of 64 is used..IP <mem_base>This parameter specifies the base address of a DMA-able cache-freepre-allocated memory region for use as a memory pool for transmit/receivedescriptors and buffers.If there is no pre-allocated memory available for the driver, this parametershould be -1 (NONE). In which case, the driver allocates cache safe memoryfor its use using cacheDmaAlloc()..IP <mem_size>The memory size parameter specifies the size of the pre-allocated memoryregion. If memory base is specified as NONE (-1), the driver ignores thisparameter..IP <user_flags>User flags control the run-time characteristics of the Ethernetchip. Most flags specify non default CSR0 and CSR6 bit values. Refer todec21x40End.h for the bit values of the flags and to the device hardwarereference manual for details about device capabilities, CSR6 and CSR0.Device Type: Although the default device type is DEC 21040, specifying the DEC_USR_21140 flag bit turns on DEC 21140 functionality.Ethernet Address: The Ethernet address is retrieved from standard serial ROM on both DEC 21040, and DEC 21140 devices. If the retrieve from ROM fails, the driver calls the sysDec21x40EnetAddrGet() BSP routine. Specifying DEC_USR_XEA flag bit tells the driver should, by default, retrieve the Ethernet address using the sysDec21x40EnetAddrGet() BSP routine.Priority RX processing: The driver programs the chip to process the transmit and receive queues at the same priority. By specifying DEC_USR_BAR_RX,the device is programmed to process receives at a higher priority.TX poll rate: By default, the driver sets the Ethernet chip into a non-polling mode. In this mode, if the transmit engine is idle, it is kick-started every time a packet needs to be transmitted. Alternatively, the chip can be programmed to poll for the next available transmit descriptor if the transmit engine is in idle state. The poll rate is specified by one of DEC_USR_TAP_<xxx> flags.Cache Alignment: The DEC_USR_CAL_<xxx> flags specify the address boundaries for data burst transfers.DMA burst length: The DEC_USR_PBL_<xxx> flags specify the maximum number of long words in a DMA burst.PCI multiple read: The DEC_USR_RML flag specifies that a device supports PCI memory-read-multiple.Full Duplex Mode: When set, the DEC_USR_FD flag allows the device to work in full duplex mode, as long as the PHY used has thiscapability. It is worth noting here that in this operation mode, the dec21x40 chip ignores the Collision and the Carrier Sense signals.MII/Phy Checking: When set, and when a MII interface is being utilizedthe DEC_USR_PHY_CHK flag instructs the driver to wait until the PHY linkstatus has changed to 'up' before continuing. This time period could beas long as six seconds, but in general is on the order of two seconds.If clear, the check will not be performed. This option may be selected ifthe delay is unacceptable, but it is possible that a fast target mayattempt to send packets before the link is up. This will result in'no carrier' errors in packet transmission.Transmit treshold value: The DEC_USR_THR_XXX flags enable the user to choose among different threshold values for the transmit FIFO. Transmission starts when the frame size within the transmit FIFO is larger than the treshold value. This should be selected taking into account the actual operating speed of the PHY. Again, see the device hardware reference manual for details.EXTERNAL SUPPORT REQUIREMENTSThis driver requires three external support functions and provides a hookfunction:.IP sysLanIntEnable().CS void sysLanIntEnable (int level).CEThis routine provides a target-specific interface for enabling Ethernet deviceinterrupts at a specified interrupt level..IP sysLanIntDisable().CS void sysLanIntDisable (void).CEThis routine provides a target-specific interface for disabling Ethernet deviceinterrupts..IP sysDec21x40EnetAddrGet().CS STATUS sysDec21x40EnetAddrGet (int unit, char *enetAdrs).CEThis routine provides a target-specific interface for accessing a deviceEthernet address..IP `_func_dec21x40MediaSelect'.CS FUNCPTR _func_dec21x40MediaSelect.CEIf `_func_dec21x40MediaSelect' is NULL, this driver provides a default media-select routine that reads and sets up physical media using the configuration information from a Version 3 DEC Serial ROM. Any other mediaconfiguration can be supported by initializing `_func_dec21x40MediaSelect',typically in sysHwInit(), to a target-specific media select routine.A media select routine is typically defined as:.ne 8.CS STATUS decMediaSelect ( DEC21X40_DRV_CTRL * pDrvCtrl, /@ driver control @/ UINT * pCsr6Val /@ CSR6 return value @/ ) { ... }.CEThe <pDrvCtrl> parameter is a pointer to the driver control structure that thisroutine can use to access the Ethenet device. The driver control structuremember 'mediaCount', is initialized to 0xff at startup, while the other mediacontrol members ('mediaDefault', 'mediaCurrent', and 'gprModeVal') are initialized to zero. This routine can use these fields in any manner. However, all other driver control structure members should be considered read-only and should not be modified.This routine should reset, initialize, and select an appropriate media. Itshould also write necessary the CSR6 bits (port select, PCS, SCR, and full duplex) to the memory location pointed to by <pCsr6Val>. The driver uses this value to program register CSR6. This routine should return OK or ERROR.SEE ALSO: ifLib, .I "DECchip 21040 Ethernet LAN Controller for PCI,".I "Digital Semiconductor 21140A PCI Fast Ethernet LAN Controller,".I "Using the Digital Semiconductor 21140A with Boot ROM, Serial ROM, and External Register: An Application Note"*//* includes */#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 "errnoLib.h"#include "cacheLib.h"#include "logLib.h"#include "netLib.h"#include "stdio.h"#include "stdlib.h"#include "sysLib.h"#include "etherLib.h"#include "net/systm.h"#include "sys/times.h"#include "net/if_subr.h"#include "drv/end/dec21x40End.h"#undef ETHER_MAP_IP_MULTICAST#include "etherMultiLib.h"#include "end.h"#include "endLib.h"#include "lstLib.h"#include "semLib.h"/* defines */#undef DRV_DEBUG#ifdef DRV_DEBUG#define DRV_DEBUG_OFF 0x0000#define DRV_DEBUG_RX 0x0001#define DRV_DEBUG_TX 0x0002#define DRV_DEBUG_INT 0x0004#define DRV_DEBUG_POLL (DRV_DEBUG_POLL_RX | DRV_DEBUG_POLL_TX)#define DRV_DEBUG_POLL_RX 0x0008#define DRV_DEBUG_POLL_TX 0x0010#define DRV_DEBUG_LOAD 0x0020#define DRV_DEBUG_IOCTL 0x0040#define DRV_DEBUG_MII 0x0080#define DRV_DEBUG_POLL_REDIR 0x10000#define DRV_DEBUG_LOG_NVRAM 0x20000int decDebug = 0x00;int decTxInts=0;int decRxInts=0;int decTxErrors = 0;int decRxErrors = 0;int decTxTpsErrors = 0;int decTxBufErrors = 0;int decTxTjtErrors = 0;int decTxUnfErrors = 0;int decRxBufErrors = 0;int decRxRpsErrors = 0;int decRxWtErrors = 0;int decDescErrors = 0;IMPORT int dataDump();IMPORT int eAdrsDisplay();#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6) \ if (decDebug & FLG) \ logMsg(X0, X1, X2, X3, X4, X5, X6);#define DRV_PRINT(FLG,X) \ if (decDebug & 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))#define END_HADDR(pEnd) \ ((pEnd)->mib2Tbl.ifPhysAddress.phyAddress)#define END_HADDR_LEN(pEnd) \ ((pEnd)->mib2Tbl.ifPhysAddress.addrLength)#define DEC_SPEED_10 10000000 /* 10 Mbps */#define DEC_SPEED_100 100000000 /* 100 Mbps */#define DEC_SPEED_DEF DEC_SPEED_10#define EADDR_LEN 6 /* ethernet address length */#define DEC_PKT_SIZE (ETHERMTU + ENET_HDR_REAL_SIZ + EADDR_LEN)#define DELAY(count) { \ volatile int cx = 0; \ for (cx = 0; cx < (count); cx++); \ }#define LOOPS_PER_NS 4#define NSDELAY(nsec) { \ volatile int nx = 0; \ volatile int loop = (int)((nsec)*LOOPS_PER_NS); \ for (nx = 0; nx < loop; nx++); \ }#define DEC_BUF_ALLOC_ROUTINE \ (FUNCPTR) (DRV_FLAGS_ISSET(DEC_MEMOWN) ? \ cacheDmaMalloc : NULL)#define DEC_BUF_POOL_ADRS \ (char *)(DRV_FLAGS_ISSET(DEC_MEMOWN) ? \ NULL:(pDrvCtrl->txRing + pDrvCtrl->numTds))/* DRV_CTRL flags access macros */#define DRV_FLAGS_SET(setBits) \ (pDrvCtrl->flags |= (setBits))#define DRV_FLAGS_ISSET(setBits) \ (pDrvCtrl->flags & (setBits))#define DRV_FLAGS_CLR(clrBits) \ (pDrvCtrl->flags &= ~(clrBits))#define DRV_FLAGS_GET() \ (pDrvCtrl->flags)/* Cache macros */#define DEC_CACHE_INVALIDATE(address, len) \ CACHE_DRV_INVALIDATE (&pDrvCtrl->cacheFuncs, (address), (len))#define DEC_CACHE_VIRT_TO_PHYS(address) \ CACHE_DRV_VIRT_TO_PHYS (&pDrvCtrl->cacheFuncs, (address))#define DEC_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) \ (((ULONG)(pciAdrs)) - (pDrvCtrl->pciMemBase)) #define MEM_TO_PCI_PHYS(memAdrs) \ (((ULONG)(memAdrs)) + (pDrvCtrl->pciMemBase))#define DEC_VIRT_TO_PCI(vAdrs) \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -