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

📄 if_fei.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* if_fei.c - Intel 82557 Ethernet network interface driver *//* Copyright 1998 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01q,28apr99,dat  Merge from 2_0_001s,09mar99,cn   added support for shared PCI interrupts (SPR# 24379).01r,14dec98,n_s  fixed feiInit to properly set promiscuous mode. spr 24000.01q,16oct98,cn   changed default to be BSD44_DRIVER, as 01o did not do it.		 Suppressed warning in feiIoctl() (SPR# 21880).01p,30sep98,cn   moved call to I82557_INT_DISABLE after sys557Init() 		 (SPR# 21879). Also suppressed some warnings (SPR# 21880).01o,16apr98,dat  changed default to be BSD44_DRIVER01n,14apr98,sbs  added global variable feiIntConnect.                 changed SYS_PCI_INT_CONNECT to SYS_INT_CONNECT.                 added documentation on how to use feiIntConnect.01m,18mar98,dat  changed default to be BSD43_DRIVER. fixed compatibility01l,12mar98,sbs  changed intConnect() to SYS_PCI_INT_CONNECT.01k,15jul97,spm  removed driver initialization from ioctl support (SPR #8831)01j,25apr97,gnn  added multicast by turning on promiscous mode.01i,03mar97,myz  fixed spr 766301h,07apr97,spm  code cleanup, corrected statistics, and upgraded to BSD 4.401h,10dec96,jdi  doc: correct statement about # of external support functions.01g,20nov96,myz  doc: removed the document for the sys557Intxxx functions01f,20nov96,myz  correct the DOC problem in feiDumpPrint and feiErrCounterDump01e,20nov96,jdi  doc: mangen fixes and general cleanup.01d,20nov96,hdn  removed CSR_ADDR_GET() and ENET_ADDR_GET().01c,25oct96,myz  added system memory interface and MDI control 01b,10oct96,dzb  clean-up and bug fixes.01a,31aug96,dzb  written, based on v03g of src/drv/netif/if_ei.c.*//*This module implements the Intel 82557 Ethernet network interface driver.This driver is designed to be moderately generic, operating unmodifiedacross the entire range of architectures and targets supported by VxWorks.This driver must be given several target-specific parameters, and someexternal support routines must be provided.  These parameters, and themechanisms used to communicate them to the driver, are detailed below.This driver supports up to four individual units.EXTERNAL INTERFACEThe user-callable routine is feiattach(), which publishes the `fei'interface and performs some initialization.After calling feiattach() to publish the interface, an initializationroutine must be called to bring the device up to an operational state.The initialization routine is not a user-callable routine; upper layerscall it when the interface flag is set to `UP', or when the interface'sIP address is set.There is a global variable 'feiIntConnect' which specifies the interruptconnect routine to be used depending on the BSP. This is by default set 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().TARGET-SPECIFIC PARAMETERS.iP "shared memory address"This parameter is passed to the driver via feiattach().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 indicatethat there are no memory limitations, in which case the driverattempts to allocate the shared memory from the system space..iP "number of Command, Receive, and Loanable-Receive Frame Descriptors"These parameters are passed to the driver via feiattach().The Intel 82557 accesses frame descriptors (and their associated buffers)in memory for each frame transmitted or received.  The number of framedescriptors can be configured at run-time using these parameters..iP "Ethernet address"This parameter is obtained by a call to an external support routine..LPEXTERNAL SUPPORT REQUIREMENTSThis driver requires the following external support function:.CS    STATUS sys557Init (int unit, 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.SYSTEM 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 feiattach() call.  The size of one RFD (Receive Frame Descriptor) isis the same as one CFD (Command Frame Descriptor): 1536 bytes.  For moreinformation about RFDs and CFDs, see the.I "Intel 82557 User's Manual."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.Additionally, this version of the driver does not handle virtual-to-physicalor physical-to-virtual memory mapping.TUNING HINTSThe only adjustable parameters are the number of Frame Descriptors that will becreated at run-time.  These parameters are given to the driver when feiattach()is called.  There is one CFD and one RFD associated with each transmittedframe and each received frame, respectively.  For memory-limited applications,decreasing the number of CFDs and RFDs may be desirable.  Increasing the numberof CFDs will provide no performance benefit after a certain point.Increasing the number of RFDs will provide more buffering before packets aredropped.  This can be useful if there are tasks running at a higher prioritythan the net task.SEE ALSO: ifLib,.I "Intel 82557 User's Manual"*/#include "vxWorks.h"#include "wdLib.h"#include "sockLib.h"#include "memLib.h"#include "intLib.h"#include "iosLib.h"#include "errnoLib.h"#include "cacheLib.h"#include "netLib.h"#include "stdio.h"#include "stdlib.h"#include "string.h"#include "ioctl.h"#include "net/if.h"#include "netinet/in.h"#include "netinet/in_var.h"#include "net/unixLib.h"#include "net/if_subr.h"#include "iv.h"#include "sysLib.h"#include "etherLib.h"#include "vxLib.h"#include "logLib.h"#include "taskLib.h"#include "drv/netif/netifDev.h"#include "drv/netif/if_fei.h"#include "drv/pci/pciIntLib.h"/* defines *//* Change default to BSD44_DRIVER */ #ifndef BSD43_DRIVER#ifndef BSD44_DRIVER#   define BSD44_DRIVER#endif /* BSD44_DRIVER */#endif /* BSD43_DRIVER */#undef	FEI_DEBUG			/* turns on debug output */#ifdef  FEI_DEBUG#undef  LOCAL#define LOCALLOCAL BOOL feiDebug = 1;#endif  /* FEI_DEBUG */#define FEI_ACTION_TMO	1		/* action command timeout in seconds */#define FEI_SCB_TMO	1		/* SCB command timeout in seconds */#define FEI_INIT_TMO	1		/* 557 init timeout in seconds */#define FEI_TX_RESTART_TMO      1       /* tx restart watchdog timeout */#define TCB_TX_THRESH	0x10		/* Tx threshold value */#define BOARD_INT_ENABLE(unit) if ((int)pDrvCtrl->board.intEnable) \	(*pDrvCtrl->board.intEnable)(unit)#define BOARD_INT_DISABLE(unit) if ((int)pDrvCtrl->board.intDisable) \	(*pDrvCtrl->board.intDisable)(unit)#define BOARD_INT_ACK(unit) if ((int)pDrvCtrl->board.intAck) \	(*pDrvCtrl->board.intAck)(unit)#define LOCAL_TO_SYS_ADDR(unit,localAddr) ((int)pDrvCtrl->board.sysLocalToBus? \	(*pDrvCtrl->board.sysLocalToBus)(unit,localAddr):localAddr)#define SYS_TO_LOCAL_ADDR(unit,sysAddr) ((int)pDrvCtrl->board.sysBusToLocal? \        (*pDrvCtrl->board.sysBusToLocal)(unit,sysAddr):sysAddr)#define SYS_INT_CONNECT(vector, routine, parameter) (feiIntConnect \        ((VOIDFUNCPTR *) vector, routine, (int) parameter)) #define I82557_INT_ENABLE pDrvCtrl->pCSR->scbCommand = 0#define I82557_INT_DISABLE  pDrvCtrl->pCSR->scbCommand = SCB_C_M/* typedefs */typedef struct mbuf MBUF;typedef struct arpcom IDR;typedef struct ifnet IFNET;typedef struct sockaddr SOCK;typedef struct drv_ctrl			/* DRV_CTRL */    {    IDR			idr;		/* interface data record */    BOOL		attached;	/* interface has been attached */    CSR *		pCSR;		/* Control/Status Register ptr */    CFD *		pCFD;		/* current Command Frame Descriptor */    RFD *		pRFD;		/* current Receive Frame Descriptor */    RFD *		pRFDL;		/* first loanable RFD */     WDOG_ID             txRestart;      /* tx restart watchdog */    BOOL		rxHandle;	/* rx handler scheduled */    BOOL                txStall;        /* tx handler stalled - no CFDs */    /* Board specific routines to manupalate this device */    BOARD_INFO board;    } DRV_CTRL;/* globals */FUNCPTR feiIntConnect = (FUNCPTR) intConnect; IMPORT STATUS	sys557Init (int unit, BOARD_INFO *pBoard);/* locals */LOCAL DRV_CTRL	drvCtrl [FEI_MAX_UNITS];LOCAL int	feiClkRate = 0;/* forward declarations */LOCAL STATUS	feiInit (int unit);LOCAL void	feiReset (int unit);LOCAL int	feiIoctl (IFNET *pIfNet, int cmd, caddr_t data);#ifdef BSD43_DRIVERLOCAL int	feiOutput (IDR *pIDR, MBUF *pMbuf, SOCK *pDestAddr);LOCAL void	feiTxStartup (int unit);#elseLOCAL void	feiTxStartup (DRV_CTRL *pDrvCtrl);#endifLOCAL void      feiTxRestart (int unit);LOCAL void	feiInt (DRV_CTRL *pDrvCtrl);LOCAL void	feiHandleRecvInt (DRV_CTRL *pDrvCtrl);LOCAL STATUS	feiReceive (DRV_CTRL *pDrvCtrl, RFD *pRfd);LOCAL void	feiLoanFree (DRV_CTRL *pDrvCtrl, RFD *pRfd);LOCAL STATUS	feiNOP (int unit);LOCAL STATUS	feiDiag (int unit);LOCAL STATUS	feiConfig (int unit);LOCAL STATUS	feiIASetup (int unit);LOCAL UINT16	feiAction (int unit, UINT16 action);LOCAL STATUS	feiSCBCommand (DRV_CTRL *pDrvCtrl, UINT8 cmd, BOOL addrValid,		    UINT32 *addr);#ifdef  FEI_DEBUGLOCAL STATUS feiErrCounterDump ( int unit, UINT32 *memAddr);LOCAL STATUS feiDumpPrint (int unit);#endif /* FEI_DEBUG */static int feiMDIWrite ( int unit, int regAddr, int phyAddr, UINT16 writeData);static int feiMDIRead ( int unit, int regAddr, int phyAddr, UINT16 *retVal);static int feiPhyInit (int unit);static int feiMDIPhyConfig ( int unit, int phyAddr);static int feiMDIPhyLinkSet ( int unit, int phyAddr);/********************************************************************************* feiattach - publish the `fei' network interface** This routine publishes the `fei' interface by filling in a network interface* record and adding the record to the system list.** The 82557 shares a region of main memory with the CPU.  The caller of this* routine can specify the address of this shared memory region through the* <memBase> parameter; if <memBase> is set to the constant `NONE', the* driver will allocate the shared memory region.** If the caller provides the shared memory region, the driver assumes* that this region does not require cache coherency operations.** If the caller indicates that feiattach() must allocate the shared memory* region, feiattach() will use cacheDmaMalloc() to obtain a block* of non-cacheable memory.  The attributes of this memory will be checked,* and if the memory is not both read and write coherent, feiattach() will* abort and return ERROR.** A default number of 32 command (transmit) and 32 receive frames can be* selected by passing zero in the parameters <nCFD> and <nRFD>, respectively.* If <nCFD> or <nRFD> is used to select the number of frames, the values* should be greater than two.** A default number of 8 loanable receive frames can be selected by passing* zero in the parameters <nRFDLoan>, else set <nRFDLoan> to the desired* number of loanable receive frames.  If <nRFDLoan> is set to -1, no* loanable receive frames will be allocated/used.** RETURNS: OK, or ERROR if the driver could not be published and initialized.** SEE ALSO: ifLib,* .I "Intel 82557 User's Manual"*/STATUS feiattach    (    int		unit,		/* unit number */    char *	memBase,	/* address of shared memory (NONE = malloc) */    int         nCFD,           /* command frames (0 = default) */    int         nRFD,           /* receive frames (0 = default) */    int         nRFDLoan        /* loanable rx frames (0 = default, -1 = 0) */    )    {    DRV_CTRL *	pDrvCtrl;		/* driver control structure pointer */    WDOG_ID     txWd = NULL;            /* tx restart watchdog */    CFD *	pCFD;			/* pointer to CFDs */    RFD *	pRFD;			/* pointer to RFDs */    UINT32	size;			/* temporary size holder */    UINT32	sizeCFD = ROUND_UP (sizeof (CFD), 4);    UINT32	sizeRFD = ROUND_UP (sizeof (RFD), 4);    int		ix;			/* counter */    char 	bucket[2];    BOOL        memAlloc = FALSE;    /* sanity check the unit number */    if (unit < 0 || unit >= FEI_MAX_UNITS)        return (ERROR);    pDrvCtrl = &drvCtrl [unit];    if (pDrvCtrl->attached)		/* already attached ? */        return (ERROR);    /* initialize the default parameter for the Physical medium layer control*/    /* user has his chance to override in the BSP, just be CAREFUL */    pDrvCtrl->board.phyAddr  = 1;    pDrvCtrl->board.phySpeed = PHY_AUTO_SPEED;    pDrvCtrl->board.phyDpx   = PHY_AUTO_DPX;    pDrvCtrl->board.others   = 0;    pDrvCtrl->board.tcbTxThresh = TCB_TX_THRESH;        /* callout to perform adapter init */    if (sys557Init (unit, &pDrvCtrl->board) == ERROR)        return (ERROR);    /* get CSR address from PCI config space base register */    if ((int)(pDrvCtrl->pCSR = (CSR *)pDrvCtrl->board.baseAddr) == NULL)        return (ERROR);    /* probe for memory-mapped CSR */    if (vxMemProbe ((char *) &pDrvCtrl->pCSR->scbStatus, VX_READ, 2,	&bucket[0]) != OK)        {        printf ("feiattach(): need MMU mapping for address 0x%x\n", (UINT32)	    pDrvCtrl->pCSR);	return (ERROR);	}    I82557_INT_DISABLE;     /* initialize the Physical medium layer */    if (feiPhyInit(unit) != OK)	{	printf("LINK FAILS, Check line connection\n");	}    if (feiClkRate == 0)	feiClkRate = sysClkRateGet ();    /* determine number of Command and Receive Frame descriptors to use */    nCFD     = nCFD ? nCFD : FEI_CFD_DEF;    nRFD     = nRFD ? nRFD : FEI_RFD_DEF;    nRFDLoan = nRFDLoan ? nRFDLoan : FEI_RFD_LOAN;    if (nRFDLoan == -1)        nRFDLoan = 0;    /* publish the interface record */#ifdef BSD43_DRIVER    ether_attach ((IFNET *) & pDrvCtrl->idr, unit, "fei", (FUNCPTR) feiInit,        (FUNCPTR) feiIoctl, (FUNCPTR) feiOutput, (FUNCPTR) feiReset);#else    ether_attach (                 (IFNET *) & pDrvCtrl->idr,                  unit,                  "fei",                  (FUNCPTR) feiInit,                 (FUNCPTR) feiIoctl,                  (FUNCPTR) ether_output,                 (FUNCPTR) feiReset                 );    pDrvCtrl->idr.ac_if.if_start = (FUNCPTR)feiTxStartup;#endif    /* calculate the total size of 82557 memory pool */    size = (sizeRFD * (nRFD + nRFDLoan)) + (sizeCFD * nCFD);    /*     * Establish the memory area that we will share with the device.  If     * the caller has provided an area, then we assume it is non-cacheable.     * If the caller did not provide an area, then we must obtain it from     * the system, using the cache savvy allocation routine.     */    if (memBase == (char *) NONE)	/* allocate on our own */	{        /* this driver doesn't handle incoherent caches */        if (!CACHE_DMA_IS_WRITE_COHERENT () || !CACHE_DMA_IS_READ_COHERENT ())            {            printf ("feiattach: shared memory not cache coherent\n");            goto error;            }        if ((memBase = cacheDmaMalloc (size)) == NULL)            {            printf ("feiattach: could not obtain memory\n");            goto error;            }        memAlloc = TRUE;        }    bzero (memBase, size);              /* zero out entire region */    /* carve up the shared-memory region */    /*     * N.B.     * We are setting up the CFD list as a ring of TxCBs, tied off with a     * CFD_C_SUSP as frames are copied into the data buffers.  The     * susp/resume model is used because the links to the next CFDs do     * not change -- it is a fixed ring.  Also note that if a CFD is needed     * for anything else (e.g., DIAG, NOP, DUMP, CONFIG, or IASETUP comands),     * then the commands will use the current CFD in the list.  After the     * command is complete, it will be set back to a TxCB by feiAction().     */    /* First ready CFD pointer */    pDrvCtrl->pCFD = pCFD = (CFD *) memBase;    /* initialize the CFD ring */    for (ix = 0; ix < nCFD; ix++, pCFD++)	{	pCFD->cfdStatus = CFD_S_COMPLETE | CFD_S_OK;          /* System bus address to link field */	LINK_WR (&pCFD->link,             LOCAL_TO_SYS_ADDR(unit,((UINT32) pCFD + sizeCFD)) );	/* Previous CFD pointer */        pCFD->pPrev = (CFD *) ((UINT32) pCFD - sizeCFD);	LINK_WR (&pCFD->cfdTcb.pTBD, 0xffffffff); /* no TBDs used */	pCFD->cfdTcb.txThresh = pDrvCtrl->board.tcbTxThresh;	pCFD->cfdTcb.tbdNum = 0;	}    pCFD--;    LINK_WR (&pCFD->link, LOCAL_TO_SYS_ADDR(unit,(UINT32)pDrvCtrl->pCFD) )        ; /* tie end of CFD ring, use system bus address */

⌨️ 快捷键说明

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