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

📄 if_qu.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* if_qu.c - Motorola MC68EN360 QUICC network interface driver *//* Copyright 1994-1997 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01k,31aug98,fle  doc : replaced simple quotes before 040 with 68 name to avoid                 bolded text problems01j,18jul97,spm  removed incorrect attachment test from driver initialization01i,15jul97,spm  removed driver initialization from ioctl support (SPR #8831)01h,14jul97,vin  fixed SPR# 8919.01g,15may97,map  fixed intr event ack (scce) handling (SPR# 8580).01f,03jan97,vin  modified for BSD44.01f,15may97,map  fixed intr event register ack [SPR# 8580]01e,08jul94,dzb  Added promisc code into quIoctl() code.01d,30jun94,dzb  removed relevant quIoctl() code (SPR #3437).01c,21apr94,dzb  fixed quReset() so doesn't reset all IFF flags (SPR #3239).01b,12nov93,dzb  fixed event race condition in quIntr() (SPR #2632).01a,18sep93,dzb  written.*//*This module implements the Motorola MC68EN360 QUICC Ethernet network interfacedriver.This driver is designed to support the Ethernet mode of a SCC residing on theMC68EN360 processor chip.  It is generic in the sense that it does not carewhich SCC is being used, and it supports up to four individual units per board.To achieve this goal, the driver must be given several target-specificparameters, and some external support routines must be provided.  Theseparameters, and the mechanisms used to communicate them to the driver, aredetailed below.This network interface driver does not include support for trailer protocolsor data chaining.  However, buffer loaning has been implemented in an effort toboost performance. Support for four individual device units was designedinto this driver.This driver maintains cache coherency by allocating bufferspace using the cacheDmaMalloc() routine.  This is provided for boards thatuse the MC68EN360 in 68040 companion mode where it is attached to processorswith data cache space.Due to a lack of suitable hardware, the multiple unit support and 68040companion mode support have not been tested.BOARD LAYOUTThis device is on-chip.  No jumpering diagram is necessary.EXTERNAL INTERFACEThis driver provides the standard external interface; the device unit is attached by the quattach() routine, which uses quInit() to initialize the driver.The only user-callable routine is quattach(), which publishes the `qu'interface and initializes the driver structures.TARGET-SPECIFIC PARAMETERS.iP "base address of MC68EN360 internal memory"This parameter is passed to the driver by quattach().This parameter indicates the address at which the MC68EN360 presentsits internal memory (also known as the dual ported RAM base address).With this address, and the SCC number (see below), the driver is able tocompute the location of the SCC parameter RAM and the SCC register map.This parameter should point to the internal memory of the QUICC chipwhere the SCC physically resides, which may not necessarily be the masterQUICC on the target board..iP "interrupt vector"This parameter is passed to the driver by quattach().This driver configures the MC68EN360 device to generate hardware interruptsfor various events within the device.  Therefore, this driver containsan interrupt handler routine.  This driver will call the VxWorks systemfunction intConnect() to connect its interrupt handler to the interruptvector generated as a result of the MC68EN360 interrupt..iP "SCC number used"This parameter is passed to the driver by quattach().This driver is written to support four individual device units.At the time that this driver was written, Motorola had releasedinformation stating that any of the SCCs on the MC68EN360 may be usedin Ethernet mode.  Thus, the multiple units supported by this drivermay reside on different MC68EN360 chips, or may be on different SCCswithin a single MC68EN360.  This parameter is used to explicitly statewhich SCC is being used (SCC1 is most commonly used, thus this parametermost often equals "1")..iP "number of transmit and receive buffer descriptors"These parameters are passed to the driver by quattach().The number of transmit and receive buffer descriptors (BDs) used isconfigurable by the user upon attaching the driver.  Each bufferdescriptor resides in 8 bytes of the MC68EN360's dual ported RAM space,and each one points to a 1520 byte buffer in regular RAM.  There mustbe a minimum of two transmit and two receive BDs, and there is nomaximum, although over a certain amount will not speed up the driver andwill waste valuable dual ported RAM space.  If this parameter is "NULL"a default value of "32" BDs will be used..iP "offset of transmit and receive buffer descriptors"These parameters are passed to the driver by quattach().These parameters indicate the base location of the transmit and receivebuffer descriptors (BDs).  They are offsets in bytes from the base addressof MC68EN360 internal memory (see above).  Each BD takes up 8 bytes ofdual ported RAM, and it is the user's responsibility to ensure that allspecified BDs will fit within dual ported RAM.  This includes any otherBDs the target board may be using, including other SCCs, SMCs, and theSPI device.  There is no default for these parameters; they must beprovided by the user..iP "base address of buffer pool"This parameter is passed to the driver by quattach().This parameter is used to notify the driver that space for the transmitand receive buffers need not be allocated, but should be taken from acache-coherent private memory space provided by the user at the givenaddress.  The user should be aware that memory used for buffers must be4-byte aligned and non-cacheable.  All the buffers*must* fit in the given memory space; no checking will be performed.This includes all transmit and receive buffers (see above) and anadditional 16 receive loaner buffers, unless the number of receiveBDs is less than 16, in which case that number of loaner buffers will beused.  Each buffer is 1520 bytes.  If this parameter is "NONE", spacefor buffers will be obtained by calling cacheDmaMalloc() in quattach()..LPEXTERNAL SUPPORT REQUIREMENTSThis driver requires three external support functions:.iP "STATUS sys360EnetEnable (int unit, UINT32 regBase)" "" 9 -1This routine is expected to perform any target specific functions requiredto enable the Ethernet controller.  These functions typically includeenabling the Transmit Enable signal (TENA) and connecting the transmitand receive clocks to the SCC.The driver calls this routine, once per unit, from the quInit() routine..iP "void sys360EnetDisable (int unit, UINT32 regBase)"This routine is expected to perform any target specific functions requiredto disable the Ethernet controller.  This usually involves disabling theTransmit Enable (TENA) signal.The driver calls this routine from the quReset() routine each time a unitis disabled..iP "STATUS sys360EnetAddrGet (int unit, u_char * addr)"The driver expects this routine to provide the six byte Ethernethardware address that will be used by this unit.  This routine must copythe six byte address to the space provided by <addr>.  This routine isexpected to return OK on success, or ERROR.The driver calls this routine, once per unit, from the quInit() routine..LPSYSTEM RESOURCE USAGEWhen implemented, this driver requires the following system resources:    - one mutual exclusion semaphore    - one interrupt vector    - 0 bytes in the initialized data section (data)    - 1272 bytes in the uninitialized data section (BSS) The data and BSS sections are quoted for the CPU32 architecture and may varyfor other architectures.  The code size (text) will varies greatly betweenarchitectures, and is therefore not quoted here.If the driver allocates the memory to share with the Ethernet device unit,it does so by calling the cacheDmaMalloc() routine.  For the default caseof 32 transmit buffers, 32 receive buffers, and 16 loaner buffers, the totalsize requested is 121,600 bytes.  If a non-cacheable memory region is providedby the user, the size of this region should be this amount, unless theuser has specified a different number of transmit or receive BDs.This driver can only operate if this memory region is non-cacheable,or if the hardware implements bus snooping.  The driver cannot maintaincache coherency for the device because the buffers are asynchronouslymodified by both the driver and the device, and these fields may share thesame cache line.  Additionally, the MC68EN360 dual ported RAM must bedeclared as non-cacheable memory where applicable (e.g., when attachedto a 68040 processor).SEE ALSO: ifLib,.I "Motorola MC68360 User's Manual"INTERNALFuture optimization: Transmit directly from mbufs/clusters instead of calling                     copy_from_mbufs(). Turn on transmit interrupts to know		     when to call free routine.*//* includes */#include "vxWorks.h"#include "iv.h"#include "taskLib.h"#include "memLib.h"#include "ioctl.h"#include "etherLib.h"#include "net/mbuf.h"#include "net/protosw.h"#include "socket.h"#include "errno.h"#include "net/if.h"#include "net/unixLib.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 "cacheLib.h"#include "stdio.h"#include "intLib.h"#include "logLib.h"#include "netLib.h"#include "drv/netif/netifDev.h"#include "drv/multi/m68360.h"/* defines */#define MAX_UNITS	4	/* max qu units */#define ENET_ADDR_SIZE	0x6	/* size of Ethernet src/dest addresses */#define TX_BD_MIN	2	/* minimum number of Tx buffer descriptors */#define RX_BD_MIN	2	/* minimum number of Rx buffer descriptors */#define TX_BD_DEFAULT	0x20	/* default number of Tx buffer descriptors */#define RX_BD_DEFAULT	0x20	/* default number of Rx buffer descriptors */#define FRAME_MAX	0x05ee	/* maximum frame size */#define FRAME_MAX_AL	0x05f0	/* maximum frame size, 4 byte alligned */#define FRAME_MIN	0x0040	/* minimum frame size */#define L_POOL		0x10	/* number of Rx loaner buffers in pool *//* typedefs */typedef struct mbuf MBUF;typedef struct arpcom IDR;	/* Interface Data Record */typedef struct ifnet IFNET;typedef struct sockaddr SOCK;typedef struct ether_header ETH_HDR; 		typedef struct drv_ctrl	/* DRV_CTRL */    {    IDR		idr;		/* Interface Data Record */    BOOL	attached;	/* indicates unit is attached */    BOOL	initialized;	/* indicates unit is initialized */    BOOL	txStop;		/* emergency stop output */    int		nLoanRxBd;	/* number of receive buffers left to loan */    u_char *	lPool[L_POOL];	/* receive BD loaner pool */    UINT8 *	pRefCnt[L_POOL];/* stack of reference count pointers */    UINT8	refCnt[L_POOL]; /* actual reference count values */    UINT32	regBase;	/* register/DPR base address */    SCC_DEV	ether;		/* ETHERNET SCC device */    } DRV_CTRL;/* globals */IMPORT STATUS sys360EnetEnable  (int unit, UINT32 regBase); /* enable ctrl */IMPORT void   sys360EnetDisable (int unit, UINT32 regBase); /* disable ctrl */IMPORT STATUS sys360EnetAddrGet (int unit, u_char * addr);  /* get enet addr *//* locals */LOCAL DRV_CTRL drvCtrl[MAX_UNITS];	/* array of driver control *//* forward declarations */#ifdef __STDC__LOCAL STATUS    quInit (int unit);#ifdef BSD43_DRIVERLOCAL int       quOutput (IFNET * pIfNet, MBUF * pMbuf, SOCK * pSock);LOCAL void      quStartOutput (int unit);#elseLOCAL void      quStartOutput (DRV_CTRL * pDrvCtrl); #endifLOCAL int       quIoctl (IFNET * pIfNet, int cmd, caddr_t data);LOCAL void      quReset (int unit);LOCAL void      quIntr (int unit);LOCAL void	quTxRestart (DRV_CTRL *	pDrvCtrl);LOCAL void      quHandleInt (DRV_CTRL * pDrvCtrl);LOCAL void      quRecv (DRV_CTRL * pDrvCtrl, SCC_BUF * pRxBd);LOCAL void      quLoanFree (DRV_CTRL * pDrvCtrl, u_char * pRxBuf, UINT8 * pRef);#else  /* __STDC__ */LOCAL STATUS    quInit ();LOCAL int       quOutput ();LOCAL void      quStartOutput ();LOCAL int       quIoctl ();LOCAL void      quReset ();LOCAL void      quIntr ();LOCAL void	quTxRestart ();LOCAL void      quHandleInt ();LOCAL void      quRecv (); LOCAL void      quLoanFree (); #endif  /* __STDC__ *//********************************************************************************* quattach - publish the `qu' network interface and initialize driver structures** The routine publishes the `qu' interface by filling in a network Interface* Data Record (IDR) and adding this record to the system list.** The MC68EN360 shares a region of memory with the driver.  The caller of this* routine can specify the address of a non-cacheable memory region with* <bufBase>, or if this parameter is "NONE" the driver will obtain this* memory region from calls to cacheDmaMalloc().  Non-cacheable memory space* is important for cases where the MC68EN360 is operating in companion mode,* and is attached to a processor with cache memory.** Once non-cacheable memory is obtained, this routine will divide up the* memory between the various buffer descriptors (BDs).  The number* of BDs can be specified by <txBdNum> and <rxBdNum>, or if "NULL", a* default value of 32 BDs will be used.  An additional number of buffers are* reserved as receive loaner buffers.  The number of loaner buffers is the* lesser of <rxBdNum> and a default number of 16.** The user must specify the location of the transmit and receive BDs in* the 68EN360's dual ported RAM.  <txBdBase> and <rxBdBase> give the* offsets from <quAddr> for the base of the BD rings.  Each BD uses 8 bytes.* Care must be taken so that the specified locations for Ethernet BDs* do not conflict with other dual ported RAM structures. ** Up to four individual device units are supported by this driver.  Device* units may reside on different MC68EN360 chips, or may be on different SCCs* within a single MC68EN360.  The <sccNum> parameter is used to explicitly* state which SCC is being used. SCC1 is most commonly used, thus this* parameter most often equals "1".* * Before this routine returns, it calls quReset() to put the Ethernet* controller in a quiescent state, and connects up the interrupt vector* <ivec>.** RETURNS: OK or ERROR.** SEE ALSO: ifLib,* .I "Motorola MC68360 User's Manual"*/STATUS quattach    (    int		unit,		/* unit number */    UINT32	quAddr,		/* base address of QUICC chip internal mem */    int		ivec,		/* interrupt vector */    int		sccNum,		/* SCC number used */    int		txBdNum,	/* number of transmit buffer descriptors */    int		rxBdNum,	/* number of receive buffer descriptors */    UINT32	txBdBase,	/* transmit buffer descriptor offset */    UINT32	rxBdBase,	/* receive buffer descriptor offset */    UINT32	bufBase		/* address of memory pool; NONE = malloc it */    )    {    DRV_CTRL *	pDrvCtrl;    int		counter;    int         scc = sccNum - 1;    int		loanNum = L_POOL;    u_char *	txBuf;    u_char *	rxBuf;    u_char *	loanBuf;         if (unit < 0 || unit >= MAX_UNITS)	/* sanity check the unit number */	 return (ERROR);		      pDrvCtrl = & drvCtrl[unit];        /* ensure single invocation */    if (pDrvCtrl->attached)        return (ERROR);    /* initialize flag(s) */    pDrvCtrl->initialized = FALSE;    /* do a quick check of input parameters */    if ((sccNum < 1) || (sccNum > 4))	return (ERROR);    if (txBdBase == rxBdBase)	return (ERROR);    /* publish the Interface Data Record */#ifdef BSD43_DRIVER    ether_attach (& pDrvCtrl->idr.ac_if, unit, "qu", (FUNCPTR) quInit,                  (FUNCPTR) quIoctl, (FUNCPTR) quOutput, (FUNCPTR) quReset);#else    ether_attach    (                    (IFNET *) & pDrvCtrl->idr,                    unit,                    "qu",                    (FUNCPTR) quInit,                    (FUNCPTR) quIoctl,                    (FUNCPTR) ether_output, /* generic ether_output */                    (FUNCPTR) quReset                    );    pDrvCtrl->idr.ac_if.if_start = (FUNCPTR) quStartOutput;#endif /* BSD43_DRIVER */    /* use default number of buffer descriptors if user did not specify */    if (txBdNum == NULL)	txBdNum = TX_BD_DEFAULT;    if (rxBdNum == NULL)	rxBdNum = RX_BD_DEFAULT;    /* must be at least two transmit and receive buffer descriptors */    txBdNum = max (TX_BD_MIN, txBdNum);    rxBdNum = max (RX_BD_MIN, rxBdNum);    loanNum = min (rxBdNum, loanNum);     /* fill in driver control structure for <unit> */    pDrvCtrl->regBase         = quAddr;    pDrvCtrl->ether.sccNum    = sccNum;    pDrvCtrl->ether.txBdNum   = txBdNum;    pDrvCtrl->ether.rxBdNum   = rxBdNum;    pDrvCtrl->nLoanRxBd       = loanNum;    pDrvCtrl->ether.txBdBase  = (SCC_BUF *) (quAddr + (txBdBase & 0xfff));    pDrvCtrl->ether.rxBdBase  = (SCC_BUF *) (quAddr + (rxBdBase & 0xfff));    pDrvCtrl->ether.txBufSize = FRAME_MAX_AL;    pDrvCtrl->ether.rxBufSize = FRAME_MAX_AL;    /* derive SCC dependent variables */    pDrvCtrl->ether.pScc    = (SCC *) ((UINT32) M360_DPR_SCC1(quAddr) +                                       (scc * 0x100));

⌨️ 快捷键说明

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