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

📄 rtl81x9.c

📁 在Tornado环境下实现的8139网卡芯片的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
 /* rtl81x9End.c - RealTek RTL81x9 Fast Ethernet interface header *//* Copyright 1984-2000 Wind River Systems, Inc. *//*modification history--------------------01c,28jan00,dgy  Updated comments that refered to the wrong files.01b,28jan00,dgy  Changed ryl81x9CsrReadByte to use the correct SYS_IN				 macro.01a,29oct99,dgy  created*//* 				Theory of OperationI. Board CompatibilityThis device driver is designed for the RealTek RTL81x9, the RealTek FastEthernet controllers for PCI.  This chip is used on a few clone boards.II. Board-specific settingsPCI bus devices are configured by the system at boot time, so no jumpersneed to be set on the board.  The system BIOS will assign thePCI INTA signal to a (preferably otherwise unused) system IRQ line.III. Driver operationIIIa. Rx Ring buffersThe receive unit uses a single linear ring buffer rather than the more common (and more efficient) descriptor-based architecture.  Incoming framesare sequentially stored into the Rx region, and the host copies them intomBlks.IIIb. Tx operationThe RTL81x9 uses a fixed set of four Tx descriptors in register space.EXTERNAL INTERFACEThe only external interface is the rtl81x9EndLoad() routine, which expectsthe <initString> parameter as input.  This parameter passes in a colon-delimited string of the format:<unit>:<devMemAddr>:<devIoAddr>:<pciMemBase:<vecNum>:<intLvl>:<memAdrs>:<memSize>:<memWidth>:<flags>:<buffMultiplier>The el3c90xEndLoad() function uses strtok() to parse the string.TARGET-SPECIFIC PARAMETERS.IP <unit>A convenient holdover from the former model.  This parameter is used onlyin the string name for the driver..IP <devMemAddr>This parameter in the memory base address of the device registers in thememory map of the CPU. It indicates to the driver where to find theregister set. < This parameter should be equal to NONE if the devicedoes not support memory mapped registers..IP <devIoAddr>This parameter in the IO base address of the device registers in theIO map of some CPUs. It indicates to the driver where to find the RDPregister. If both <devIoAddr> and <devMemAddr> are given then the devicechooses <devMemAddr> which is a memory mapped register base address.This parameter should be equal to NONE if the device does not support IO mapped registers.. <pciMemBase>This parameter is the base address of the CPU memory as seen from thePCI bus. This parameter is zero for most intel architectures..IP <vecNum>This parameter is the vector associated with the device interrupt.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 <intLvl>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 sysRtl81x9IntEnable() is called toperform any board-specific operations required to allow the servicing of aNIC interrupt.  For a description of sysRtl81x9IntEnable(), see "ExternalSupport Requirements" below..IP <memAdrs>This parameter gives the driver the memory address to carve out itsbuffers and data structures. If this parameter is specified to beNONE then the driver allocates cache coherent memory for buffersand descriptors from the system pool.The 3C90x NIC 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 NIC.  Itassumes that this shared memory is directly available to itwithout any arbitration or timing concerns..IP <memSize>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 <memWidth>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 <flags>This is parameter is used for future use, currently its value should bezero.EXTERNAL SUPPORT REQUIREMENTSThis driver requires several external support functions, defined as macros:.CS    SYS_INT_CONNECT(pDrvCtrl, routine, arg)    SYS_INT_DISCONNECT (pDrvCtrl, routine, arg)    SYS_INT_ENABLE(pDrvCtrl)    SYS_INT_DISABLE(pDrvCtrl)    SYS_OUT_BYTE(pDrvCtrl, reg, data)    SYS_IN_BYTE(pDrvCtrl, reg, data)    SYS_OUT_WORD(pDrvCtrl, reg, data)    SYS_IN_WORD(pDrvCtrl, reg, data)    SYS_OUT_LONG(pDrvCtrl, reg, data)    SYS_IN_LONG(pDrvCtrl, reg, data)    SYS_DELAY (delay)    sysEl3c90xIntEnable(pDrvCtrl->intLevel)     sysEl3c90xIntDisable(pDrvCtrl->intLevel)    sysDelay (delay).CEThere are default values in the source code for these macros.  They presumememory mapped accesses to the device registers and the normal intConnect(),and intEnable() BSP functions.  The first argument to each is the devicecontroller structure. Thus, each has access back to all the device-specificinformation.  Having the pointer in the macro facilitates the addition of new features to this driver.The macros SYS_INT_CONNECT, SYS_INT_DISCONNECT, SYS_INT_ENABLE andSYS_INT_DISABLE allow the driver to be customized for BSPs that use specialversions of these routines.The macro SYS_INT_CONNECT is used to connect the interrupt handler tothe appropriate vector.  By default it is the routine intConnect().The macro SYS_INT_DISCONNECT is used to disconnect the interrupt handler priorto unloading the module.  By default this is a dummy routine thatreturns OK.The macro SYS_INT_ENABLE is used to enable the interrupt level for theend device.  It is called once during initialization.  It calls anexternal board level routine sysRtl81x9IntEnable(). The macro SYS_INT_DISABLE is used to disable the interrupt level for theend device.  It is called during stop.  It calls anexternal board level routine sysRtl81x9IntDisable().The macro SYS_DELAY is used for a delay loop. It calls an external boardlevel routine sysDelay(delay). The granularity of delay is one microsecond.SYSTEM RESOURCE USAGEWhen implemented, this driver requires the following system resources:    - one mutual exclusion semaphore    - one interrupt vector    - 24072 bytes in text for a I80486 target    - 112 bytes in the initialized data section (data)    - 0 bytes in the uninitialized data section (BSS)The driver allocates clusters of size 1536 bytes for receive frames andand transmit frames. There are 16 descriptors in the upload ringand 16 descriptors in the download ring. The buffer multiplier by defaultis 2, which means that the total number of clusters allocated by defaultare 64 ((upload descriptors + download descriptors)*2). There are as manyclBlks as the number of clusters. The number of mBlks allocated are twicethe number of clBlks. By default there are 64 clusters, 64 clBlks and 128mBlks allocated in the pool for the device. Depending on the load of thesystem increase the number of clusters allocated by incrementing the buffermultiplier.INCLUDES:end.h endLib.h etherMultiLib.h rtl81x9End.hSEE ALSO: muxLib, endLib, netBufLib.pG "Writing and Enhanced Network Driver"*/#define END_MACROS#include "vxWorks.h"#include "wdLib.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 "semLib.h"#include "cacheLib.h"#include "sys/ioctl.h"#include "etherLib.h"#include "ioLib.h"#define CPU_PENTIUM /* for the bug of OS in Pentium */#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 "m2Lib.h"#include "etherMultiLib.h"		/* multicast stuff. */#include "end.h"			/* Common END structures. */#include "netBufLib.h"#include "muxLib.h"#include "endLib.h"#include "lstLib.h"			/* Needed to maintain protocol list. *//***** LOCAL DEFINITIONS *****/#include "rtl81x9.h"/*#define DRV_DEBUG*/ 	/* vicADD */		#ifdef	DRV_DEBUG	/*int	rtl81x9Debug = (DRV_DEBUG_ALL & (~DRV_DEBUG_POLL));  Turn it off initially.  vicadd*/	int	rtl81x9Debug = 0 ;#endif /* DRV_DEBUG *//* network buffers configuration */M_CL_CONFIG rtlMclConfig = 	/* mBlk configuration table */    {    0, 0, NULL, 0    };CL_DESC rtlClDesc [] = 	/* network cluster pool configuration table */    {    /*     clusterSize	num		memArea		memSize    -----------	----		-------		-------    */    {RTL_BUFSIZ,		0,	NULL,		0}    }; int rtlClDescNumEnt = (NELEMENTS(rtlClDesc));#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)/* * Default macro definitions for BSP interface. * For X86 arch, the intConnect/Disconnect defaults are pciIntConnect and * pciIntDisconnect.  For all others it is just intConnect and a dummy * disconnect function. * HELP: This needs to be fixed by porting pciIntLib to all architectures. */#if CPU_FAMILY == I80X86#ifndef SYS_INT_CONNECT#define SYS_INT_CONNECT(pDrvCtrl,rtn,arg,pResult)                       \    {                                                                   \    IMPORT STATUS pciIntConnect();                                      \    *pResult = pciIntConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (pDrvCtrl->ivec),\			     (rtn), (int)(arg));                        \    }#endif	/* SYS_INT_CONNECT */#ifndef SYS_INT_DISCONNECT#define SYS_INT_DISCONNECT(pDrvCtrl,rtn,arg,pResult)                    \    {                                                                   \    IMPORT STATUS pciIntDisconnect();                                      \    *pResult = pciIntDisconnect ((VOIDFUNCPTR *)INUM_TO_IVEC (pDrvCtrl->ivec),\			     (rtn));		                        \    }#endif /* SYS_INT_DISCONNECT */#else /* CPU_FAMILY == I80X86 */#ifndef SYS_INT_CONNECT#define SYS_INT_CONNECT(pDrvCtrl,rtn,arg,pResult)                       \    {                                                                   \    IMPORT STATUS intConnect();                                      \    *pResult = pciIntConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (pDrvCtrl->ivec),\			     (rtn), (int)(arg));                        \    }#endif /*SYS_INT_CONNECT*/#ifndef SYS_INT_DISCONNECT#define SYS_INT_DISCONNECT(pDrvCtrl,rtn,arg,pResult)                    \    {                                                                   \    *pResult = OK;							\    }#endif /*SYS_INT_DISCONNECT*/#endif /* CPU_FAMILY == I80X86 *//* Macro to enable the appropriate interrupt level */#ifndef SYS_INT_ENABLE#define SYS_INT_ENABLE(pDrvCtrl) \    { \    IMPORT STATUS sysRtl81x9IntEnable(); \    sysRtl81x9IntEnable ((pDrvCtrl)->ilevel); \    }#endif /* SYS_INT_ENABLE*//* Macro to disable the appropriate interrupt level */#ifndef SYS_INT_DISABLE#define SYS_INT_DISABLE(pDrvCtrl) \    { \    IMPORT void sysRtl81x9IntDisable (); \    sysRtl81x9IntDisable ((pDrvCtrl)->ilevel); \    }#endif#ifndef SYS_OUT_LONG#define SYS_OUT_LONG(pDrvCtrl,addr,value) \    { \    *((ULONG *)(addr)) = PCI_SWAP((value)); \    }#endif /* SYS_OUT_LONG */#ifndef SYS_IN_LONG#define SYS_IN_LONG(pDrvCtrl,addr,data) \    { \    ((data) = PCI_SWAP(*((ULONG *)(addr)))); \    }#endif /* SYS_IN_LONG */#ifndef SYS_OUT_SHORT#define SYS_OUT_SHORT(pDrvCtrl,addr,value) \    { \    *((USHORT *)(addr)) = PCI_WORD_SWAP((value)); \    }#endif /* SYS_OUT_SHORT*/#ifndef SYS_IN_SHORT#define SYS_IN_SHORT(pDrvCtrl,addr,data) \    { \    ((data) = PCI_WORD_SWAP(*((USHORT *)(addr)))); \    }      #endif /* SYS_IN_SHORT*/#ifndef SYS_OUT_BYTE#define SYS_OUT_BYTE(pDrvCtrl,addr,value) \    { \    *((UCHAR *)(addr)) = (value); \    }#endif /* SYS_OUT_BYTE */#ifndef SYS_IN_BYTE#define SYS_IN_BYTE(pDrvCtrl,addr,data) \    { \    ((data) = *((UCHAR *)(addr))); \    }#endif /* SYS_IN_BYTE */#ifndef SYS_OUT_SHORT_CSR#define SYS_OUT_SHORT_CSR(pDrvCtrl,addr,value) \    { \    *(USHORT *)addr = value; \    }#endif /*SYS_OUT_SHORT_CSR*/#ifndef SYS_IN_SHORT_CSR#define SYS_IN_SHORT_CSR(pDrvCtrl,addr,pData) \    (*(USHORT *)pData = *(USHORT *)addr)#endif /*SYS_IN_SHORT_CSR*/#define SYS_DELAY(count)	{                                               \			volatile int cx = 0;                            \			for (cx = 0; cx < (count); cx++);               \			}#ifndef SYS_ENET_ADDR_GET#define SYS_ENET_ADDR_GET(pDrvCtrl, pAddress) \    { \    IMPORT STATUS sysRtl81x9EnetAddrGet (RTL81X9END_DEVICE *pDrvCtrl, \                                     char * enetAdrs); \    sysRtl81x9EnetAddrGet (pDrvCtrl, pAddress); \    }#endif /* SYS_ENET_ADDR_GET *//* Cache macros */#define RTL_CACHE_INVALIDATE(address, len) \        CACHE_DRV_INVALIDATE (&pDrvCtrl->cacheFuncs, (address), (len))#define RTL_CACHE_VIRT_TO_PHYS(address) \        CACHE_DRV_VIRT_TO_PHYS (&pDrvCtrl->cacheFuncs, (address))/* * MII access routines are provided for the 8129, which * doesn't have a built-in PHY. For the 8139, we fake things * up by diverting rl_phy_readreg()/rl_phy_writereg() to the * direct access PHY registers.

⌨️ 快捷键说明

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