📄 fei82557end.c
字号:
/* fei82557End.c - END style Intel 82557 Ethernet network interface driver *//* Copyright 1989-2000 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01w,02aug00,stv removed netMblkClChainFree() in Pollsend routine (SPR# 32885).01v,19jun00,jgn SPR 32016, improve interrupt handling + add multiplier to increase number of rx buffers available for loaning01u,11jun00,ham removed reference to etherLib.01t,06jun00,jgn fixed CPU to PCI trans. for base address regs (SPR 31811)01s,29feb00,stv Fixed the bug which stalls transmission under heavy load (SPR# 30361). (merge from T2)01r,02jun00,jgn fixed initialisation for cases where CPU adrs != PCI adrs01q,11apr00,jgn added support for aligning packet data (offset parameter)01p,27jan00,dat fixed use of NULL, removed warnings01o,05jan00,stv removed private/funcBindP.h (SPR# 29875). 01n,01dec99,stv freed mBlk chain before returning ERROR (SPR #28492).01m,14oct99,stv Fixed the bug of failing to release the transmit semaphore (SPR #29094).01l,08sep99,jmb avoid virtual address translations of *_NOT_USED.01k,11mar99,cn added support for shared PCI interrupts (SPR# 24379). Also corrected a potential memory leak in xxxRecv.01j,09mar99,cn moved callout to adapter init routine before xxxMemInit(), and corrected usage of xxxSCBCommand() (SPR# 25242).01i,22sep98,dat removed lint warnings.01h,21jul98,cn added support for multi-device configuration. Also made chip-access macros redefineable and moved them to the header file.01g,16apr98,cn added globals feiEndIntConnect and feiEndIntDisconnect and modified SYS_INT_CONNECT and SYS_INT_DISCONNECT accordingly. Changed state to scbStatus in fei82557Action().01f,23mar98,cn fixed compiling problem when building for big-endian machines01e,11mar98,cn checked-in 01d,05mar98,cn more code clean-up after code review, added support for MULTIALL01c,23feb98,cn code clean-up01b,18feb98,cn changed all the once called LINK macros to normal01a,07nov97,cn created from ../netif/if_fei.c, version 01k*//*DESCRIPTIONThis module implements an Intel 82557 Ethernet network interface driver.This is a fast Ethernet PCI bus controller, IEEE 802.3 10Base-T and 100Base-T compatible. It also features a glueless 32-bit PCI bus master interface, fully compliant with PCI Spec version 2.1. An interface to MII compliant physical layer devices is built-in to the card. The 82557Ethernet PCI bus controller also includes Flash support up to 1 MByteand EEPROM support, altough these features are not dealt with in this driver.The 82557 establishes a shared memory communication system with the CPU,which is divided into three parts: the Control/Status Registers (CSR),the Command Block List (CBL) and the Receive Frame Area (RFA). The CSRis on chip and is either accessible with I/O or memory cycles, whereas theother structures reside on the host.The CSR is the main means of communication between the device and thehost, meaning that the host issues commands through these registerswhile the chip posts status changes in it, occurred as a result of thosecommands. Pointers to both the CBL and RFA are also stored in the CSR.The CBL consists of a linked list of frame descriptors through which individual action commands can be performed. These may be transmit commands as well as non-transmit commands, e.g. Configure or Multicastsetup commands. While the CBL list may function in two different modes,only the simplified memory mode is implemented in the driver.The RFA is a linked list of receive frame descriptors. Only support forthe simplified memory mode is granted. In this model, the data buffer immediately follows the related frame descriptor.The driver is designed to be moderately generic, operating unmodifiedacross the range of architectures and targets supported by VxWorks. To achieve this, this 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 detailed below.BOARD LAYOUTThis device is on-board. No jumpering diagram is necessary.EXTERNAL INTERFACEThe driver provides the standard external interface, fei82557EndLoad(), whichtakes a string of colon separated parameters. The parameters should bespecified in hexadecimal, optionally preceeded by "0x" or a minus sign "-".The parameter string is parsed using strtok_r() and each parameter isconverted from a string representation to binary by a call tostrtoul(parameter, NULL, 16).The format of the parameter string is: "<memBase>:<memSize>:<nTfds>:<nRfds>:<flags>:<offset>"In addition, the two global variables 'feiEndIntConnect' and 'feiEndIntDisconnect' specify respectively the interrupt connect routine and the interrupt disconnect routine to be used depending on the BSP. The former defaults to intConnect() and the user can override this to use any other interrupt connect routine (say pciIntConnect()) in sysHwInit() or any device specific initialization routine called in sysHwInit(). Likewise, the latter is set by default to NULL, but it may be overridden in the BSP in the same way. TARGET-SPECIFIC PARAMETERS.IP <memBase>This parameter is passed to the driver via fei82557EndLoad().The Intel 82557 device is a DMA-type device and typically sharesaccess to some region of memory with the CPU. This driver is designedfor systems that directly share memory between the CPU and the 82557.This parameter can be used to specify an explicit memory region for useby the 82557. This should be done on targets that restrict the 82557to a particular memory region. The constant `NONE' can be used to indicate that there are no memory limitations, in which case the driver will allocate cache safe memory for its use using cacheDmaAlloc()..IP <memSize>The memory size parameter specifies the size of the pre-allocated memoryregion. If memory base is specified as NONE (-1), the driver ignores thisparameter. Otherwise, the driver checks the size of the provoded memory region is adequate with respect to the given number of Command FrameDescriptor and Receive Frame Descriptor..IP <nTfds>This parameter specifies the number of transmit descriptor/buffers to beallocated. If this parameter is less than two, a default of 32 is used..IP <nRfds>This parameter specifies the number of receive descriptor/buffers to beallocated. If this parameter is less than two, a default of 32 is used.In addition, four times as many loaning buffers are created. These buffersare loaned up to the network stack. When loaning buffers are exhausted,the system begins discarding incoming packets. Specifying 32 buffers resultsin 32 frame descriptors, 32 reserved buffers and 128 loaning buffers beingcreated from the system heap..IP <flags>User flags may control the run-time characteristics of the Ethernetchip. Not implemented..IP <offset>Offset used to align IP header on word boundary for CPUs that need long wordaligned access to the IP packet (this will normally be zero or two). This field isoptional, the default value is zero..LP EXTERNAL SUPPORT REQUIREMENTSThis driver requires one external support function:.CSSTATUS sys557Init (int unit, FEI_BOARD_INFO *pBoard).CEThis routine performs any target-specific initializationrequired before the 82557 device is initialized by the driver.The driver calls this routine every time it wants to [re]initializethe device. This routine returns OK, or ERROR if it fails..LPSYSTEM RESOURCE USAGEThe driver uses cacheDmaMalloc() to allocate memory to share with the 82557.The size of this area is affected by the configuration parameters specifiedin the fei82557EndLoad() call. Either the shared memory region must be non-cacheable, or elsethe hardware must implement bus snooping. The driver cannot maintaincache coherency for the device because fields within the commandstructures are asynchronously modified by both the driver and the device,and these fields may share the same cache line.TUNING HINTSThe only adjustable parameters are the number of TFDs and RFDs that will becreated at run-time. These parameters are given to the driver when fei82557EndLoad() is called. There is one TFD and one RFD associated with each transmitted frame and each received frame respectively. For memory-limited applications, decreasing the number of TFDs and RFDs may be desirable. Increasing the number of TFDs will provide no performance benefit after a certain point. Increasing the number of RFDs will provide more buffering before packets are dropped. This can be useful if there are tasks running at a higher priority than the net task.ALIGNMENTSome architectures do not support unaligned access to 32-bit data items. Onthese architectures (eg PowerPC and ARM), it will be necessary to adjust theoffset parameter in the load string to realign the packet. Failure to do sowill result in received packets being absorbed by the network stack, althoughtransmit functions should work OK.SEE ALSO: ifLib,.I "Intel 82557 User's Manual,".I "Intel 32-bit Local Area Network (LAN) Component User's Manual"*/#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 "iosLib.h"#include "errnoLib.h"#include "vxLib.h" /* from if_fei.c */#include "private/funcBindP.h"#include "cacheLib.h"#include "logLib.h"#include "netLib.h"#include "stdio.h"#include "stdlib.h"#include "sysLib.h"#include "taskLib.h"#include "net/systm.h"#include "sys/times.h"#include "net/if_subr.h"#include "drv/end/fei82557End.h"#include "drv/pci/pciIntLib.h"#undef ETHER_MAP_IP_MULTICAST#include "etherMultiLib.h"#include "end.h"#include "semLib.h"#define END_MACROS#include "endLib.h"#include "lstLib.h"/* defines *//* Driver debug control */#undef DRV_DEBUG557/* Driver debug control */#ifdef DRV_DEBUG557#define DRV_DEBUG_OFF 0x0000#define DRV_DEBUG_RX 0x0001#define DRV_DEBUG_TX 0x0002#define DRV_DEBUG_POLL (DRV_DEBUG_POLL_RX | DRV_DEBUG_POLL_TX)#define DRV_DEBUG_POLL_RX 0x0004#define DRV_DEBUG_POLL_TX 0x0008#define DRV_DEBUG_LOAD 0x0010#define DRV_DEBUG_IOCTL 0x0020#define DRV_DEBUG_INT 0x0040#define DRV_DEBUG_START 0x0080#define DRV_DEBUG_DUMP 0x0100#define DRV_DEBUG_ALL 0xffffint fei82557Debug = DRV_DEBUG_LOAD;#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6) \ do { \ if (fei82557Debug & FLG) \ if (_func_logMsg != NULL) \ _func_logMsg (X0, (int)X1, (int)X2, (int)X3, (int)X4, \ (int)X5, (int)X6); \ } while (0)#define DRV_PRINT(FLG, X) \ do { \ if (fei82557Debug & FLG) \ printf X; \ } while (0)#else /* DRV_DEBUG557 */#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6)#define DRV_PRINT(FLG, X)#endif /* DRV_DEBUG557 *//* general macros for reading/writing from/to specified locations */#if (_BYTE_ORDER == _BIG_ENDIAN) #define FEI_SWAP_LONG(x) LONGSWAP(x)#define FEI_SWAP_WORD(x) (MSB(x) | LSB(x) << 8) #else #define FEI_SWAP_LONG(x) (x)#define FEI_SWAP_WORD(x) (x) #endif /* _BYTE_ORDER == _BIG_ENDIAN *//* Cache and PCI-bus related macros */#define FEI_VIRT_TO_SYS(virtAddr) \ (FEI_LOCAL_TO_SYS (((UINT32) FEI_VIRT_TO_PHYS (virtAddr))))#define FEI_SYS_TO_VIRT(sysAddr) \ ((FEI_PHYS_TO_VIRT ((UINT32) FEI_SYS_TO_LOCAL (sysAddr))))#define FEI_PHYS_TO_VIRT(physAddr) \ CACHE_DRV_PHYS_TO_VIRT (&pDrvCtrl->cacheFuncs, (char *)(physAddr))#define FEI_VIRT_TO_PHYS(virtAddr) \ CACHE_DRV_VIRT_TO_PHYS (&pDrvCtrl->cacheFuncs, (char *)(virtAddr))#define FEI_LOCAL_TO_SYS(physAddr) \ LOCAL_TO_SYS_ADDR (pDrvCtrl->unit, (physAddr))#define FEI_SYS_TO_LOCAL(sysAddr) \ SYS_TO_LOCAL_ADDR (pDrvCtrl->unit, (sysAddr))#define FEI_CACHE_INVALIDATE(address, len) \ CACHE_DRV_INVALIDATE (&pDrvCtrl->cacheFuncs, (address), (len))/* driver flags */#define FEI_OWN_MEM 0x01 /* internally provided memory */#define FEI_INV_NCFD 0x02 /* invalid nCFDs provided */#define FEI_INV_NRFD 0x04 /* invalid nRFDs provided */#define FEI_POLLING 0x08 /* polling mode */#define FEI_PROMISC 0x20 /* promiscuous mode */#define FEI_MCAST 0x40 /* multicast addressing mode */#define FEI_MCASTALL 0x80 /* all multicast addressing mode */#define FEI_MEMOWN 0x10 /* device mem allocated by driver */ #define FEI_FLAG_CLEAR(clearBits) \ (pDrvCtrl->flags &= ~(clearBits))#define FEI_FLAG_SET(setBits) \ (pDrvCtrl->flags |= (setBits))#define FEI_FLAG_GET() \ (pDrvCtrl->flags)#define FEI_FLAG_ISSET(setBits) \ (pDrvCtrl->flags & (setBits))/* shortcuts */#define END_FLAGS_ISSET(setBits) \ ((&pDrvCtrl->endObj)->flags & (setBits))#define FEI_VECTOR(pDrvCtrl) \ ((pDrvCtrl)->board.vector)#define FEI_INT_ENABLE(pDrvCtrl) \ ((int)(pDrvCtrl)->board.intEnable)#define FEI_INT_DISABLE(pDrvCtrl) \ ((int)(pDrvCtrl)->board.intDisable)#define FEI_INT_ACK(pDrvCtrl) \ ((int)(pDrvCtrl)->board.intAck)#define CL_OVERHEAD 4 /* prepended cluster header */#define CL_RFD_SIZE (RFD_SIZE + CL_OVERHEAD) #define FEI_SAFE_MEM(pDrvCtrl) \ ((pDrvCtrl)->memSize)#define FEI_RFD_MEM(pDrvCtrl) \ (CL_RFD_SIZE * (pDrvCtrl)->nRFDs)#define FEI_CFD_MEM(pDrvCtrl) \ (CFD_SIZE * (pDrvCtrl)->nCFDs)#define FEI_HADDR(pEnd) \ ((pEnd)->mib2Tbl.ifPhysAddress.phyAddress)#define FEI_HADDR_LEN(pEnd) \ ((pEnd)->mib2Tbl.ifPhysAddress.addrLength)/* Control Status Register definitions, some of them came from if_fei.h */#define CSR_STAT_OFFSET SCB_STATUS /* CSR status byte */#define CSR_ACK_OFFSET 0x01 /* CSR acknowledge byte */#define CSR_COMM_OFFSET SCB_CMD /* CSR command byte */#define CSR_INT_OFFSET 0x03 /* CSR Interrupt byte */#define CSR_GP_OFFSET SCB_POINTER /* CSR General Pointer */#define CSR_PORT_OFFSET SCB_PORT /* CSR PORT Register */#define CSR_FLASH_OFFSET SCB_FLASH /* CSR FLASH Register */#define CSR_EEPROM_OFFSET SCB_EEPROM /* CSR EEPROM Register */#define CSR_MDI_OFFSET SCB_MDI /* CSR MDI Register */#define CSR_RXBC_OFFSET SCB_EARLYRX /* CSR early RCV Byte Count *//* Control Status Registers read/write macros *//* Control Status Registers write macros */#define CSR_BYTE_WR(offset, value) \ FEI_BYTE_WR (((UINT32) (pDrvCtrl->pCSR) + (offset)), (value))#define CSR_WORD_WR(offset, value) \ FEI_WORD_WR (((UINT32) (pDrvCtrl->pCSR) + (offset)), (value))#define CSR_LONG_WR(offset, value) \ FEI_LONG_WR (((UINT32) (pDrvCtrl->pCSR) + (offset)), (value))/* this is a special case, as the device will read it as an address */#define CSR_GP_WR(value) \ do { \ volatile UINT32 temp = FEI_VIRT_TO_SYS (value); \ \ CSR_LONG_WR (CSR_GP_OFFSET, (temp)); \ } while (0)/* Control Status Registers read macros */#define CSR_BYTE_RD(offset, value) \ FEI_BYTE_RD ((UINT32 *) ((UINT32) (pDrvCtrl->pCSR) + (offset)), \ (value))#define CSR_WORD_RD(offset, value) \ FEI_WORD_RD ((UINT32 *) ((UINT32) (pDrvCtrl->pCSR) + (offset)), \ (value))#define CSR_LONG_RD(offset, value) \ FEI_LONG_RD ((UINT32 *) ((UINT32) (pDrvCtrl->pCSR) + (offset)), \ (value))/* this is a special case, as the CPU will read it as an address */#define CSR_GP_RD(value) \ do { \ volatile UINT32 tempVal; \ \ CSR_LONG_RD (CSR_GP_OFFSET), (tempVal)) \ \ value = FEI_SYS_TO_VIRT (((UINT32) (tempVal))); \ } while (0)/* FD rings available */ #define CFD_FREE 0x01 /* CFD free ring */#define CFD_USED 0x02 /* CFD used ring */#define RFD_FREE 0x04 /* RFD free ring */ #define CFD_COMM_WORD 0x01 /* CFD command word */#define CFD_STAT_WORD 0x02 /* CFD status word */#define RFD_COMM_WORD 0x04 /* RFD command word */#define RFD_STAT_WORD 0x08 /* RFD status word */ #define CFD_ACTION 0x01 /* generic action command */#define CFD_TX 0x02 /* transmit command *//* frame descriptors macros: these are generic among RFDs and CFDs */#define FD_FLAG_ISSET(fdStat, bits) \ (((UINT16) (fdStat)) & ((UINT16) (bits)))/* get the pointer to the appropriate frame descriptor ring */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -