📄 gei82543end.c
字号:
/* gei82543End.c - Intel PRO/1000 F/T/XF/XT/MT/MF network adapter END driver *//* Copyright 1984-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01m,23may02,jln support 82545/82546 fiber-based adapter(spr 78084) clean interrupts only when packets can be processed 01l,02may02,jln support 82540/82545/82546 based adapters spr # 76739; stop device only after device has been started spr # 76511 change input argument from vector to unit in SYS_INT_ENABLE and SYS_INT_DISABLE macros01k,22apr02,rcs changed gei82543MemAllFree() to use free for pDrvCtrl->pTxDesCtlBase SPR# 76130 01j,22apr02,rcs removed taskDelay() from gei82543EndPollSend() SPR# 7610201i,14jan02,dat Removing warnings from Diab compiler01h,08nov01,jln coding workaround for TBI compatibility HW bug (spr# 71363), but disable it by default for testing issues. 01g,01sep01,jln clean up documentation01f,10aug01,jln add support for 82544-based adapters spr# 69774; remove copying method for transmitting; add support for jumbo frames spr# 67477 01e,03may01,jln fix memory leak in gei82543EndStop (spr# 67116); added read operation before exit ISR to flush write buffer for PCI bridge; polish TX/RX handling01d,01may01,jln change MACRO(s) GEI_READ_REG, GEI_READ_DESC_WORD, and GEI_READ_DESC_LONG for coding convention01c,19apr01,jln clean up for spr#6532601b,01apr01,jln clean up after code review (partial spr#65326).01a,08jan01,jln created based on templateEnd.c and fei82557End.c END scheme*//*DESCRIPTIONThe gei82543End driver supports Intel PRO1000 T/F/XF/XT/MT/MF adaptorsThese adaptors use Intel 82543GC, 82544GC/EI, or 82540/82545/82546EB Gigabit Ethernet controllers.The 8254x are highly integrated, high-performance LAN controllers for 1000/100/10Mb/s transfer rates. They provide 32/64 bit 33/66Mhz interfaces to the PCI bus with 32/64 bit addressing and are fully compliant with PCI bus specification version 2.2. The 82544, 82545 and 82546 also provide PCI-X interface.The 8254x controllers implement all IEEE 802.3 receive and transmit MAC functions. They provide a Ten-Bit Interface (TBI) as specified in the IEEE 802.3z standard for 1000Mb/s full-duplex operation with 1.25 GHz Ethernet transceivers (SERDES), as well as a GMII interface as specified in IEEE 802.3ab for 10/100/1000 BASE-T transceivers, and also an MII interface as specified in IEEE 802.3u for 10/100 BASE-T transceivers. The 8254x controllers offer auto-negotiation capability for TBI and GMII/MII modes and also support IEEE 802.3x compliant flow control. Although these devices also support other advanced features such as receive and transmit IP/TCP/UDP checksum offloading, jumbo frames, and provide flash support up to 512KB and EEPROM support, this driver does NOT support these features. The 8254x establishes a shared memory communication system with the CPU, which is divided into two parts: the control/status registers and thereceive/transmit descriptors/buffers. The control/status registersare on the 8254x chips and are only accessible with PCI or PCI-X memory cycles, whereas the other structures reside on the host. The buffer size can be programmed between 256 bytes to 16k bytes. This driver uses thereceive buffer size of 2048 bytes for an MTU of 1500. The Intel PRO/1000 F/XF/MF adapters only implement the TBI mode of the8254x controller with built-in SERDESs in the adaptors.The Intel PRO/1000 T adapters based on 82543GC implement the GMII mode with a Gigabit Ethernet Transceiver (PHY) of MARVELL's Alaska 88E1000/88E1000S. However, the PRO/1000 XT/MT adapters based on 82540/82544/82545/82546 use the built-in PHY in controllers.The driver on the current release supports both GMII mode for Intel PRO1000T/XT/MT adapers and TBI mode for Intel PRO1000 F/XF/MF adapters. However,it requires the target-specific initialization code (sys543BoardInit ()) to distinguish these kinds of adapters by PCI device IDs. EXTERNAL INTERFACEThe driver provides the standard external interface, gei82543EndLoad(), whichtakes a string of colon separated parameters. The parameter string is parsed using strtok_r() and each parameter in converted from a string representationto a binary.The format of the parameter string is: "<memBase>:<memSize>:<nRxDes>:<nTxDes>:<flags>:<offset>:<mtu>" TARGET-SPECIFIC PARAMETERS.IP <memBase>This parameter is passed to the driver via gei82543EndLoad().The 8254x is a DMA-type device and typically shares access to some region ofmemory with the CPU. This driver is designed for systems that directly share memory between the CPU and the 8254x.This parameter can be used to specify an explicit memory region for useby the 8254x chip. This should be done on targets that restrict the 8254xto a particular memory region. The constant `NONE' can be used to indicate that there are such memory, in which case the driver will allocate cache safememory for its use using cacheDmaAlloc()..IP <memSize>The memory size parameter specifies the size of the pre-allocated memory region. The driver checks the size of the provided memory region is adequate with respect to the given number of transmit Descriptor and Receive Descriptor..IP <nRxDes>This parameter specifies the number of transmit descriptors to beallocated. If this number is 0, a default value of 24 will be used..IP <nTxDes>This parameter specifies the number of receive descriptors to beallocated. If this parameter is 0, a default of 24 is used..IP <flags>This parameter is provided for user to customize this device driver for theirapplication. GEI_END_SET_TIMER (0x01): a timer will be started to constantly free back the loaned transmit mBlks.GEI_END_SET_RX_PRIORITY (0x02): packet transfer (receive) from device to hostmemory will have higher priority than the packet transfer (transmit) from hostmemory to device in the PCI bus. For end-station application, it is suggestedto set this priority in favor of receive operation to avoid receive overrun.However, for routing applications, it is not necessary to use this priority.This option is only for 82543-based adapters. GEI_END_FREE_RESOURCE_DELAY (0x04): when transmitting larger packets, the driver will hold mblks(s) from the network stack and return them after the driver has completed transmitting the packet, and either the timer has expired or there are no more available descriptors. If this option is not used, the driver will free mblk(s) when ever the packet transmission is done. This optionwill place greater demands on the network pool and should only be used in systems which have sufficient memory to allocate a large network pool. It is not advised for the memory-limited target systems.GEI_END_TBI_COMPATIBILITY (0x200): if this driver enables the workaround for TBI compatibility HW bugs (#define INCLUDE_TBI_COMPATIBLE), user can set this bit to enable a software workaround for the well-known TBI compatibility HW bug in the Intel PRO1000 T adapter. This bug is only occured in the copper-and-82543-based adapter, and the link partner has advertised only 1000Base-T capability. .IP <offset>This parameter is provided for the architectures which need DWORD (4 byte) alignment of the IP header. In that case, the value of OFFSET should be two, otherwise, the default value is zero..LP EXTERNAL SUPPORT REQUIREMENTSThis driver requires one external support function:.CSSTATUS sys82543BoardInit (int unit, ADAPTOR_INFO *pBoard).CEThis routine performs some target-specific initialization such as EEPROM validation and obtaining ETHERNET address and initialization control words (ICWs) from EEPROM. The routine also initializes the adaptor-specific data structure. Some target-specific functions used later in driver operation are hooked up to that structure. It's strongly recommended that users providea delay function with higher timing resolution. This delay function will be used in the PHY's read/write operations if GMII is used. The driver will use taskDelay() by default if user can NOT provide any delay function, and this will probably result in very slow PHY initialization process. The user should also specify the PHY's type of MII or GMII. This routine returns OK, or ERROR if it fails..LPSYSTEM RESOURCE USAGEThe driver uses cacheDmaMalloc() to allocate memory to share with the 8254xGC.The size of this area is affected by the configuration parameters specifiedin the gei82543EndLoad() call. Either the shared memory region must be non-cacheable, or else the hardware must implement bus snooping. The driver cannot maintain cache coherency for the device because fields within the command structures are asynchronously modified by both the driver and the device, and these fields may share the same cache line.SYSTEM TUNING HINTSSignificant performance gains may be had by tuning the system and network stack.This may be especially necessary for achiving gigabit transfer rates. Increasing the network stack's pools are strongly recommended. This driver borrows mblks from the network stack to accerlate packet transmitting. Theoretically, the number borrowed clusters could be the same as the number of the device's transmit descriptors. However, if the network stack has fewer available clusters than available transmit descriptors then this will result in reduced throughput. Therefore, increasing the network stack's number of clusters relative to the number of transmit descriptors will increase bandwidth.Of course this technique will eventually reach a point of diminishing return. There are actually several sizes of clusters available in the network pool.Increasing any or all of these cluster sizes will result in some increase in performance. However, increasing the 2048-byte cluster size will likely have the greatest impact since this size will hold an entire MTU and header.Increasing the number of receive descriptors and clusters may also have positive impact.Increasing the buffer size of sockets can also be beneficial. This cansignificantly improve performance for a target system under higher transfer rates. However, it should be noted that large amounts of unread buffers idling in sockets reduces the resources available to the rest of the stack. This can, in fact, have a negative impact on bandwidth. One method to reduce this effectis to carefully adjust application tasks' priorities and possibly increase number of receive clusters.Callback functions defined in the sysGei82543End.c can be used to dynamically and/or statically change the internal timer registers such as ITR, RADV, and RDTR to reduce RX interrupt rate.INTERNALThis library contains two conditional compilation switchs: DRV_DEBUG and INCLUDE_GEI82543_DEBUG_ROUTINE. If defined, debug routines will be included.And output message can be selected by gei82543GCDebug variable.SEE ALSO: muxLib, endLib.I "RS-82543GC GIGABIT ETHERNET CONTROLLER NETWORKING DEVELOPER'S MANUAL"*//* includes */#include "vxWorks.h"#include "stdlib.h"#include "cacheLib.h"#include "intLib.h"#include "end.h" /* common END structures. */#include "endLib.h"#include "lstLib.h" /* needed to maintain protocol list. */#include "wdLib.h"#include "iv.h"#include "semLib.h"#include "logLib.h"#include "netLib.h"#include "stdio.h"#include "sysLib.h"#include "errno.h"#include "errnoLib.h"#include "memLib.h"#include "iosLib.h"#undef ETHER_MAP_IP_MULTICAST#include "etherMultiLib.h" /* multicast stuff. */#include "net/mbuf.h"#include "net/unixLib.h"#include "net/protosw.h"#include "net/systm.h"#include "net/if_subr.h"#include "net/route.h"#include "sys/socket.h"#include "sys/ioctl.h"#include "sys/times.h"#include "drv/end/gei82543End.h"/* IMPORT */IMPORT STATUS sys82543BoardInit (int, ADAPTOR_INFO *);IMPORT int endMultiLstCnt (END_OBJ* pEnd); /* defines */#undef INCLUDE_TBI_COMPATIBLE/* all 8254x chip registers are 32 bit long*/#if (_BYTE_ORDER == _BIG_ENDIAN)#define GEI_READ_REG(offset,result) \ do { \ UINT32 temp; \ temp = ((*(volatile UINT32 *)(pDrvCtrl->devRegBase + (offset)))); \ result = LONGSWAP(temp); /* swap the data */ \ } while (0)#define GEI_WRITE_REG(offset, value) \ ((*(volatile UINT32 *)(pDrvCtrl->devRegBase + (offset))) = \ (UINT32) LONGSWAP(value))#define GEI_WRITE_DESC_WORD(pDesc, offset, value) \ (*(UINT16 *)((UINT32)pDesc + offset) = \ (MSB(value) | LSB(value)<<8) & 0xffff)#define GEI_WRITE_DESC_LONG(pDesc, offset, value) \ (*(UINT32 *)((UINT32)pDesc + offset) = \ (UINT32) LONGSWAP(value))#define GEI_READ_DESC_WORD(pDesc, offset, result) \ do { \ UINT16 temp; \ temp = *(UINT16 *)((UINT32)pDesc + offset); \ result = (MSB(temp) | (LSB(temp) << 8)) & 0xffff; \ } while (0)#define GEI_READ_DESC_LONG(pDesc, offset, result) \ do { \ UINT32 temp; \ temp = *(UINT32 *)((UINT32)pDesc + offset); \ result = LONGSWAP(temp); /* swap the data */ \ } while (0)#else /* (_BYTE_ORDER == _BIG_ENDIAN) */#define GEI_READ_REG(offset, result) \ result = (*(volatile UINT32 *)(pDrvCtrl->devRegBase + (offset)))#define GEI_WRITE_REG(offset, value) \ ((*(volatile UINT32 *)(pDrvCtrl->devRegBase + (offset))) = \ (UINT32)(value))#define GEI_WRITE_DESC_WORD(pDesc, offset, value) \ (*(UINT16 *)((UINT32)pDesc + offset) = (UINT16)(value & 0xffff))#define GEI_WRITE_DESC_LONG(pDesc, offset, value) \ (*(UINT32 *)((UINT32)pDesc + offset) = (UINT32)value)#define GEI_READ_DESC_WORD(pDesc, offset, result) \ result = ((UINT16)(*(UINT16 *)((UINT32)pDesc + offset)) & 0xffff)#define GEI_READ_DESC_LONG(pDesc, offset, result) \ result = ((UINT32)( *(UINT32 *)((UINT32)pDesc + offset))) #endif /* (_BYTE_ORDER == _BIG_ENDIAN) */#define GEI_WRITE_DESC_BYTE(pDesc, offset, value) \ (*(UINT8 *)((UINT32)pDesc + offset) = (UINT8) (value & 0xff))#define GEI_READ_DESC_BYTE(pDesc, offset) \ ((UINT8)( *(UINT8 *)((UINT32)pDesc + offset)) & 0xff)#define GEI_GET_RX_DESC_ADDR(offset) \ (pDrvCtrl->pRxDescBase + ((offset) * RXDESC_SIZE))#define GEI_GET_TX_DESC_ADDR(offset) \ (pDrvCtrl->pTxDescBase + ((offset) * TXDESC_SIZE))#define GEI_GET_TX_DESC_CTL_ADDR(offset) \ (pDrvCtrl->pTxDesCtlBase + (offset));#define GEI_GET_TX_DESC_TAIL_UPDATE(tmp, num) \ (tmp) = (pDrvCtrl->txDescTail + (num)) % (pDrvCtrl->txDescNum) #define GEI_GET_RX_DESC_TAIL_UPDATE(tmp, num) \ (tmp) = (pDrvCtrl->rxDescTail + (num)) % (pDrvCtrl->rxDescNum)#define ROUND_UP_MULTIPLE(x, y) \ ( ( ( x + ( y - 1 ) ) / y ) * y )/* bus/CPU address translation macros */#define GEI_VIRT_TO_BUS(virtAddr) \ (GEI_PHYS_TO_BUS (((UINT32) GEI_VIRT_TO_PHYS (virtAddr))))#define GEI_BUS_TO_VIRT(busAddr) \ ((GEI_PHYS_TO_VIRT ((UINT32) GEI_BUS_TO_PHYS (busAddr))))#define GEI_PHYS_TO_VIRT(physAddr) \ END_CACHE_PHYS_TO_VIRT ((char *)(physAddr))#define GEI_VIRT_TO_PHYS(virtAddr) \ END_CACHE_VIRT_TO_PHYS ((char *)(virtAddr))#define GEI_PHYS_TO_BUS(physAddr) \ PHYS_TO_BUS_ADDR (pDrvCtrl->unit, (physAddr))#define GEI_BUS_TO_PHYS(busAddr) \ BUS_TO_PHYS_ADDR (pDrvCtrl->unit, (busAddr))/* cache macros */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -