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

📄 templatenetif.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* tempNetif.c - template ethernet network interface driver *//* Copyright 1989-1997 Wind River Systems, Inc. *//*TODO -	Remove the template modification history and begin a new history	starting with version 01a and growing the history upward with	each revision.modification history--------------------01d,24sep97,dat  documentation cleanup, added TEMPLATE_NETIF_{READ | WRITE}01c,25aug97,dat  removed IFNET references01b,08aug97,dat  fixed compilation bugs01a,30jul97,dat  written (from if_ei.c, ver 03h)*//*.SH TODOReplace the documentation for this template driver with documentationfor the driver being written.  Begin with an overview of the complete device.  Indicate if the new driveronly implements a sub-section of the whole device or not.Describe all of the operating modes of the device, and indicate whichones this driver implements.Document the device initialization steps to be used in the BSP to createand initialize the device.  Document all the macros thatcan be used to customize the driver to a particular hardware environment.Document anything that will help the user to understand how this deviceworks and interacts with this driver.This template assumes the device uses some type of transmit frame descriptor(tfd) and a similar receive frame descriptor (rfd).  There is an array orlist for each.  There are dummy declarations for a TFD and an RFD structure.INTERRUPTSThis driver requires the BSP to perform the intConnect function.  The BSPshould connect the templateInt() function using a single argument 'unit'to the appropriate vector.  This driver will use the TEMPLATE_INT_ENABLE()and TEMPLATE_INT_DISABLE() macros to enable and disable interrupts. Themacro TEMPLATE_INT_INIT() is used to initialize the interrupt system duringdriver initialization time.  The macro TEMPLATE_INT_ACK() is used toperform interrupt acknowledge functions external to the driver.HARDWARE The macros TEMPLATE_NETIF_READ() and TEMPLATE_NETIF_WRITE() are used forall accesses to actual chip.  These macros can be redefined to createcustom modules for special situations.NOTES:This template driver was abstracted from the Intel 82596 driver, if_ei.c.It is a fairly common device that has its own DMA controller built in.Transmit data is assigned to a TFD (transmit frame descriptor) and the TFDis linked to a command list that the device monitors.  Similar incomingpackets are in RFDs (receive frame descriptors).  An interrupt occurs whenthere are RFDs ready with incoming data.  The RFD is then unlinked from thereceive queue and processed.  When the incoming data is no longer needed thebuffer and RFD and returned to the free pool of RFDs, for reuse.WARNINGS:Do not use printf statements within code executed by netTask. A deadlockis possible when the shell is redirected to the network.  Use logMsg()instead. (SPR 8954)SEE ALSO: ifLib*/#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/if.h"#include "net/route.h"#include "iosLib.h"#include "errnoLib.h"#include "cacheLib.h"#include "logLib.h"#include "netLib.h"#include "stdio.h"#include "stdlib.h"#include "sysLib.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 "etherLib.h"#include "net/systm.h"#include "sys/times.h"#include "net/if_subr.h"/* local definitions */#define EH_SIZE		14#define MAX_UNITS       4                   /* maximum units to support */#define MAX_RFDS_LOANED 8                   /* max RFDs that can be loaned *//* Typedefs for external structures that are not typedef'd in their .h files */typedef struct mbuf MBUF;typedef struct arpcom IDR;                  /* Interface Data Record wrapper */typedef struct ifnet IFNET;                 /* real Interface Data Record */typedef struct sockaddr SOCK;typedef struct rfd { /* TODO - This is a dummy RFD structure */    ETH_HDR* pEnetHdr;    int status;    int count;    int reserved;    int actualCnt;    int refCnt;    char * enetData;    int bufSize;    } RFD;typedef RFD	TFD;	/* TODO - This is a dummy TFD structure *//* The definition of the driver control structure */typedef struct drv_ctrl	/* TODO - This is a dummy driver control structure */    {    IDR			idr;		/* interface data record */    BOOL		attached;	/* indicates attach() called */    volatile UCHAR *	pCsr;		/* Control status register */    char *		memBase;	/* memory pool base */    volatile BOOL	rcvHandling;	/* flag, indicates netTask active */    volatile BOOL	txCleaning;	/* flag, indicates netTask active */    volatile BOOL	txIdle;		/* flag, indicates idle transmitter */    volatile int	nLoanRfds;	/* number of loanable RFDs left */    CACHE_FUNCS		cacheFuncs;	/* cache descriptor */    int			intLevel;	/* interrupt level # */    } DRV_CTRL;#define DRV_CTRL_SIZ  sizeof(DRV_CTRL)/* hardware abstraction macros */#ifndef TEMPLATE_NETIF_READ#define TEMPLATE_NETIF_READ(pDrvCtrl, reg, result) \	((result) = (*(pDrvCtrl->reg)))#endif /* TEMPLATE_NETIF_READ */#ifndef TEMPLATE_NETIF_WRITE#define TEMPLATE_NETIF_WRITE(pDrvCtrl, reg, data) \	((*(pDrvCtrl->reg)) = (data))#endif /* TEMPLATE_NETIF_WRITE *//* Dummy declarations of bits in the CSR register */#define TEMPLATE_CSR_RX_PEND	0x1#define TEMPLATE_CSR_TX_PEND	0x2#define TEMPLATE_CSR_RFD_READY	0x4/* Dummy declarations of CSR commands */#define TEMPLATE_CMD_RESET	0x1#define TEMPLATE_CMD_TX_START	0x2#define TEMPLATE_CMD_RX_START	0x4/* declarations for default macro definitions */IMPORT	STATUS sysIntEnable (int);IMPORT	STATUS sysIntDisable (int);IMPORT	STATUS sysIntAck (int);IMPORT	STATUS sysTemplateAddrGet (int, void *);#ifndef TEMPLATE_INT_ENABLE		/* enable this interrupt */#define TEMPLATE_INT_ENABLE(pDrv) \	sysIntEnable (pDrv->intLevel);#endif TEMPLATE_INT_ENABLE#ifndef TEMPLATE_INT_DISABLE		/* disable this interrupt */#define TEMPLATE_INT_DISABLE(pDrv) \	sysIntEnable (pDrv->intLevel);#endif TEMPLATE_INT_DISABLE#ifndef TEMPLATE_INT_INIT		/* initialize interrupts */#define TEMPLATE_INT_INIT(pDrv) \	/* do nothing */#endif TEMPLATE_INT_INIT#ifndef TEMPLATE_INT_ACK		/* acknowledge interrupt */#define TEMPLATE_INT_ACK(pDrv) \	sysIntAck (pDrv->intLevel);#endif TEMPLATE_INT_ACK#ifndef TEMPLATE_ENET_GET		/* get ethernet MAC address */#define TEMPLATE_ENET_GET(pDrvCtrl, pResult) \	*pResult = sysTemplateAddrGet (pDrvCtrl->idr.ac_if.if_unit, \				(char *)pDrvCtrl->idr.ac_enaddr);#endif TEMPLATE_ENET_GET/* local data */LOCAL DRV_CTRL drvCtrl [MAX_UNITS]; 	/* array of driver control structs *//* forward function declarations */IMPORT STATUS	templateAttach (int unit, UCHAR* pCsr, int iLevel,				char* memBase, int nTfds, int nRfds);IMPORT void	templateInt (int unit);LOCAL STATUS	templateInit (int unit);LOCAL void	templateReset (int unit);LOCAL int	templateIoctl (IDR *pIDR, int cmd, caddr_t data);LOCAL int	templateOutput (IDR *pIDR, MBUF *pMbuf, SOCK *pDestAddr);LOCAL void	templateTxStart (int unit);LOCAL void	templateHandleRecv (DRV_CTRL *pDrvCtrl);LOCAL STATUS	templateReceive (DRV_CTRL *pDrvCtrl, RFD *pRfd);LOCAL void	templateLoanFree (DRV_CTRL *pDrvCtrl, RFD *pRfd);LOCAL void	templateRxStart (DRV_CTRL *pDrvCtrl);LOCAL void	templateTfdSend (DRV_CTRL *pDrvCtrl, TFD *pTfd);LOCAL void	templateTfdStart (DRV_CTRL *pDrvCtrl);LOCAL void	templateRfdReturn (DRV_CTRL *pDrvCtrl, RFD *pRfd);LOCAL RFD	*templateRfdGet (DRV_CTRL *pDrvCtrl);LOCAL BOOL	templateRfdReady (DRV_CTRL *pDrvCtrl);LOCAL STATUS	templateDeviceStart (int unit);/********************************************************************************* templateAttach - publish the network interface and initialize the device** This routine publishes the `template' interface by filling in a network* interface record and adding this record to the system list.  This routine* also initializes the driver and the device to the operational state.** The <memBase> parameter is used to inform the driver about the shared* memory region.  If this parameter is set to the constant "NONE," then this* routine will attempt to allocate the shared memory from the system.  Any* other value for this parameter is interpreted by this routine as the address* of the shared memory region to be used.** If the caller provides the shared memory region, then the driver assumes* that this region does not require cache coherency operations, nor does it* require conversions between virtual and physical addresses.** If the caller indicates that this routine must allocate the shared memory* region, then this routine will use cacheDmaMalloc() to obtain* some  non-cacheable memory.  The attributes of this memory will be checked,* and if the memory is not both read and write coherent, this routine will* abort and return ERROR.** RETURNS: OK or ERROR if arguments are invalid or a hardware fault is detected.** SEE ALSO: ifLib*/STATUS templateAttach    (    int         unit,       /* unit number */    UCHAR *	pCsr,	    /* ptr to CSR */    int         iLevel,     /* interrupt level */    char *      memBase,    /* address of memory pool or NONE */    int         nTfds,      /* no. of transmit frames (0 = default) */    int         nRfds       /* no. of receive frames (0 = default) */    )    {    DRV_CTRL    *pDrvCtrl;    UINT        size;		/* temporary size holder */    int		temp;    static char *errMsg1 = "\nattach: could not obtain memory\n";    /* Sanity checks */    if (unit < 0|| unit >= MAX_UNITS     || pCsr == NULL)        return (ERROR);    /* Ensure single invocation per system life */    pDrvCtrl = & drvCtrl [unit];    if (pDrvCtrl->attached)        return (OK);    /* Publish the interface record */    ether_attach    (                    &pDrvCtrl->idr.ac_if,                    unit,                    "template",                    (FUNCPTR) NULL,                    (FUNCPTR) templateIoctl,                    (FUNCPTR) templateOutput,                    (FUNCPTR) templateReset                    );    size = 1024 * 16; /* TODO - calculate the total size of memory pool */    /*     * 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     * and will not require the use of the special cache routines.     * If the caller did not provide an area, then we must obtain it from     * the system, using the cache savvy allocation routine.     */    switch ((int) memBase)        {        case NONE :                            /* we must obtain it */	    /*	     * TODO - if driver needs coherent memory, test for it and	     * report error if not coherent.	     */	    /* allocate memory */            pDrvCtrl->memBase = cacheDmaMalloc (size);            if (pDrvCtrl->memBase == NULL)    /* no memory available */                {                printf (errMsg1);                goto error;                }            pDrvCtrl->cacheFuncs = cacheDmaFuncs;            break;        default :                               /* the user provided an area */            pDrvCtrl->memBase = memBase;        /* use the provided address */            pDrvCtrl->cacheFuncs = cacheNullFuncs;            break;        }    /* TODO - Save device specific parameters */    pDrvCtrl->intLevel = iLevel;    pDrvCtrl->pCsr = pCsr;    /*     * TODO - If needed, carve up the shared memory region into     * specific sections.     */    /* get our enet (MAC) addr */    TEMPLATE_ENET_GET (pDrvCtrl, &temp);    if (temp == ERROR)	{	errnoSet (S_iosLib_INVALID_ETHERNET_ADDRESS);        goto error;	}    /* NOTE: The BSP will connect the ISR to the interrupt vector */    /* reset chip, set flags to indicate device is active */    if (templateInit (unit) == ERROR)        goto error;    pDrvCtrl->attached = TRUE;    pDrvCtrl->idr.ac_if.if_flags |= (IFF_UP | IFF_RUNNING | IFF_NOTRAILERS);    return (OK);error:    /* TODO - Release allocated objects/memory */    return (ERROR);    }/********************************************************************************* templateInit - Initialize the interface.** Initialization of interface; clear recorded pending operations.* Called by templateAttach().** RETURNS: OK or ERROR if a hardware failure is detected.*/LOCAL STATUS templateInit     (    int unit			/* unit number */    )    {    DRV_CTRL    *pDrvCtrl = & drvCtrl [unit];    pDrvCtrl->rcvHandling   = FALSE;  /* netTask not running our receive job */    pDrvCtrl->txCleaning    = FALSE;  /* netTask not running our clean job */    pDrvCtrl->txIdle        = TRUE;         /* transmitter idle */    /* Perform device initialization */    TEMPLATE_INT_DISABLE (pDrvCtrl);    TEMPLATE_INT_INIT (pDrvCtrl);	/* board specific initialization */    /* TODO - configure chip, set up MAC address, etc */    /* TODO - setup TX and RX buffer lists/queues */    /* TODO - Setup free RFD list, and loan count */    pDrvCtrl->nLoanRfds = MAX_RFDS_LOANED;    /* Clear and enable interrupts */    TEMPLATE_INT_ACK (pDrvCtrl);	/* to clear any pending interrupts */    TEMPLATE_INT_ENABLE (pDrvCtrl);    /* Start the device */    if (templateDeviceStart (unit) == ERROR)        return (ERROR);    return (OK);    }/********************************************************************************* templateReset - reset the ei interface** Mark interface as inactive and reset the chip.  Called from the interface* layer as needed to shut down the device.** RETURNS: N/A.*/LOCAL void templateReset    (    int unit    )    {    DRV_CTRL *pDrvCtrl;    pDrvCtrl = & drvCtrl [unit];    pDrvCtrl->idr.ac_if.if_flags = 0;    TEMPLATE_INT_DISABLE (pDrvCtrl);    /* TODO - reset the device */    TEMPLATE_NETIF_WRITE(pDrvCtrl, pCsr, TEMPLATE_CMD_RESET);    }/********************************************************************************* templateIoctl - interface ioctl procedure** Process an interface ioctl request.** RETURNS: 0 (OK) always.*/LOCAL int templateIoctl    (    IDR     *pIDR,    int     cmd,    caddr_t data    )    {    DRV_CTRL *	pDrvCtrl = & drvCtrl [pIDR->ac_if.if_unit];    int		retVal = OK;    int		s;    s = splimp ();    switch (cmd)        {        case SIOCSIFADDR:            retVal = set_if_addr (&pIDR->ac_if, data, pDrvCtrl->idr.ac_enaddr);            break;        case SIOCSIFFLAGS:            /* Flags are set outside this module. No additional work to do. */            break;        default:            retVal = EINVAL;        }    splx (s);    return (retVal);    }/********************************************************************************

⌨️ 快捷键说明

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