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

📄 ultraend.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* ultraEnd.c - SMC Ultra Elite END network interface driver *//* Copyright 1984-1999 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01b,09mar99,sbs  changed SYS_INT_ENABLE and SYS_INT_DISABLE to use                 device specific BSP routines. 01a,06jan99,dra	 written.*//*DESCRIPTIONThis module implements the SMC Elite Ultra Ethernt network interface driver.This driver supports single transmission and multiple reception.  TheCurrent register is a write pointer to the ring.  The Bound registeris a read pointer from the ring.  This driver gets the Currentregister at the interrupt level and sets the Bound register at thetask level.  The interrupt is only masked during configuration or inpolled mode.CONFIGURATIONThe W1 jumper should be set in the position of "Software Configuration".The defined I/O address in config.h must match the one stored in EEROM. The RAM address, the RAM size, and the IRQ level are defined in config.h. IRQ levels 2,3,5,7,10,11,15 are supported.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_IN_BYTE(pDrvCtrl, reg, pData)    SYS_OUT_BYTE(pDrvCtrl, reg, pData).CEThese macros allow the driver to be customized for BSPs that usespecial versions 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 sysUltraIntEnable().The macro SYS_INT_DISABLE is used to disable the interrupt level for theend device.  It is called once during shutdown. It calls anexternal board level routine sysUltraIntDisable().The macros SYS_IN_BYTE and SYS_OUT_BYTE are used for accessing theultra device.  The default macros map these operations ontosysInByte() and sysOutByte().INCLUDES:end.h endLib.h etherMultiLib.hSEE ALSO: muxLib, endLib.I "Writing an Enhanced Network Driver"*//* 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 "etherLib.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/ultraEnd.h"/* defines *//* Configuration items */#define ULTRA_SPEED_10M		10000000	/* 10Mbs */#define ULTRA_SPEED		ULTRA_SPEED_10M/* Definitions for the flags field */#define ULTRA_POLLING			0x01#define ULTRA_TX_IN_PROGRESS		0x02#define ULTRA_TX_BLOCKED		0x04#define ULTRA_RCV_HANDLING_FLAG		0x08/* Debug macros */#undef DRV_DEBUG#ifdef	DRV_DEBUG#define DRV_DEBUG_OFF		0x0000#define DRV_DEBUG_RX		0x0001#define	DRV_DEBUG_TX		0x0002#define DRV_DEBUG_INT		0x0004#define	DRV_DEBUG_POLL		(DRV_DEBUG_POLL_RX | DRV_DEBUG_POLL_TX)#define	DRV_DEBUG_POLL_RX	0x0008#define	DRV_DEBUG_POLL_TX	0x0010#define	DRV_DEBUG_LOAD		0x0020#define	DRV_DEBUG_IOCTL		0x0040#define	DRV_DEBUG_ERR		0x0080#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6)		\    do								\        {							\	if (ultraDebug & (FLG))					\	    logMsg (X0, X1, X2, X3, X4, X5, X6);		\	}							\    while (0)#define DRV_PRINT(FLG, X)					\    do								\        {							\	if (ultraDebug & (FLG))					\	    printf X;						\	}							\    while (0)#else /* DRV_DEBUG */#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6)	do {} while (0)#define DRV_PRINT(FLG, X)				do {} while (0)#endif /* DRV_DEBUG *//* Cache macros */#define ULTRA_CACHE_INVALIDATE(address, len) \        CACHE_DRV_INVALIDATE (&pDrvCtrl->cacheFuncs, (address), (len))/* * Default macro definitions for BSP interface.  These macros can be * redefined in a wrapper file, to generate a new module with an * optimized interface. *//* Macro to connect interrupt handler to vector */#ifndef SYS_INT_CONNECT#define SYS_INT_CONNECT(pDrvCtrl,rtn,arg,pResult) \    { \    IMPORT STATUS sysIntConnect(); \    *(pResult) = intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC ((pDrvCtrl)->ivec), \			   rtn, (int)(arg)); \    }#endif/* Macro to disconnect interrupt handler from vector */LOCAL VOID dummyIsr (void) { };#ifndef SYS_INT_DISCONNECT#define SYS_INT_DISCONNECT(pDrvCtrl,rtn,arg,pResult) \    { \    IMPORT STATUS intConnect(); \    *(pResult) = intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC ((pDrvCtrl)->ivec), \			     dummyIsr, (int)(arg)); \    }#endif/* Macro to enable the appropriate interrupt level */#ifndef SYS_INT_ENABLE#define SYS_INT_ENABLE(pDrvCtrl) \	{ \        IMPORT void sysUltraIntEnable(); \	sysUltraIntEnable ((pDrvCtrl)->intLevel); \	}#endif/* Macro to disable the appropriate interrupt level */#ifndef SYS_INT_DISABLE#define SYS_INT_DISABLE(pDrvCtrl) \	{ \        IMPORT void sysUltraIntDisable(); \	sysUltraIntDisable ((pDrvCtrl)->intLevel); \	}#endif/* * Macros to do a byte access to the chip.  Default assumes an * I/O mapped device accessed in the x86 fashion. */#ifndef SYS_OUT_BYTE#define SYS_OUT_BYTE(pDrvCtrl, addr, value) \	 (sysOutByte ((pDrvCtrl)->ioAddr+(addr), value))#endif#ifndef SYS_IN_BYTE#define SYS_IN_BYTE(pDrvCtrl, addr, pData) \	 (*(pData) = sysInByte ((pDrvCtrl)->ioAddr+(addr)))#endif/* A shortcut for getting the hardware address from the MIB II stuff. */#define END_HADDR(pEnd)	\		((pEnd)->mib2Tbl.ifPhysAddress.phyAddress)#define END_HADDR_LEN(pEnd) \		((pEnd)->mib2Tbl.ifPhysAddress.addrLength)/* typedefs *//* The definition of the driver control structure */typedef struct ultra_device    {    END_OBJ     endObj;			/* The class we inherit from. */    END_ERR	lastError;		/* Last error passed to muxError */    int		unit;			/* unit number */    int         ivec;                   /* interrupt vector */    int         ilevel;			/* interrupt level */    int		ioAddr;			/* address of ultra's shared memory */    int		memAddr;		/* address of ultra's shared memory */    int		memSize;		/* size of ultra's shared memory */    int		config;			/* device config (TP, BNC) */    int		offset;			/* packet data offset */    UINT	transmitPage[2];	/* start of TX packets */    UINT	transmitCnt;		/* number of TX packets sent */    UCHAR	current;		/* location of current RX packet */    UCHAR	nextPacket;		/* location of next RX packet */    UCHAR	istat;			/* current interrupt status */    UCHAR	tstat;			/* current TX status */    UCHAR	rstat;			/* current RX status */    UCHAR	uppByteCnt;		/* last upper byte count */    UCHAR	intLevel;		/* interrupt level from table */    ULONG	flags;			/* Our local flags. */    UCHAR	enetAddr[6];		/* ethernet address */    UCHAR	mcastFilter[8];		/* multicast address mask */    CACHE_FUNCS cacheFuncs;             /* cache function pointers */    CL_POOL_ID	clPoolId;		/* cluster pool */    } ULTRA_DEVICE;/* globals */#ifdef	DRV_DEBUGint ultraDebug = 0x00;#endif	/* DRV_DEBUG *//* locals */LOCAL IRQ_TABLE irqTable [] =     {    { 2, 0x15},    { 2, 0x15},    { 2, 0x15},    { 3, 0x19},    { 3, 0x19},    { 5, 0x1d},    { 5, 0x1d},    { 7, 0x51},    { 7, 0x51},    { 7, 0x51},    {10, 0x55},    {11, 0x59},    {11, 0x59},    {11, 0x59},    {11, 0x59},    {15, 0x5d}    };/* forward declarations */IMPORT	int endMultiLstCnt (END_OBJ* pEnd);LOCAL void	ultraInt	(ULTRA_DEVICE *pDrvCtrl);LOCAL STATUS	ultraRecv	(ULTRA_DEVICE *pDrvCtrl);LOCAL void	ultraConfig	(ULTRA_DEVICE *pDrvCtrl);LOCAL int	ultraPacketGet  (ULTRA_DEVICE *pDrvCtrl, UCHAR *pDst);LOCAL void	ultraAddrFilterSet (ULTRA_DEVICE *pDrvCtrl);LOCAL void	ultraHandleRcvInt  (ULTRA_DEVICE *pDrvCtrl);LOCAL STATUS	ultraParse	(ULTRA_DEVICE* pDrvCtrl, char* initString);LOCAL STATUS	ultraMemInit	(ULTRA_DEVICE* pDrvCtrl, int clNum);LOCAL STATUS	ultraPollStart	(ULTRA_DEVICE* pDrvCtrl);LOCAL STATUS	ultraPollStop	(ULTRA_DEVICE* pDrvCtrl);LOCAL void	ultraReset	(ULTRA_DEVICE* pDrvCtrl);/* Ultra Specific interfaces. */LOCAL STATUS	ultraStart	(void* pObj);LOCAL STATUS	ultraStop	(void* pObj);LOCAL STATUS	ultraUnload	(void* pObj);LOCAL int	ultraIoctl	(void* pObj, int cmd, caddr_t data);LOCAL STATUS	ultraSend	(void* pObj, M_BLK_ID pBuf);			  LOCAL STATUS	ultraMCastAdd	(void* pObj, char* pAddress);LOCAL STATUS	ultraMCastDel	(void* pObj, char* pAddress);LOCAL STATUS	ultraMCastGet	(void* pObj, MULTI_TABLE* pTable);LOCAL STATUS	ultraPollSend	(void* pObj, M_BLK_ID pBuf);LOCAL STATUS	ultraPollRcv	(void* pObj, M_BLK_ID pBuf);/* This is the only externally visible interface. */END_OBJ* 	ultraLoad	(char* initString);/* * Declare our function table.  This is static across all driver * instances. */LOCAL NET_FUNCS ultraFuncTable =    {    ultraStart,			/* Function to start the device. */    ultraStop,			/* Function to stop the device. */    ultraUnload,		/* Unloading function for the driver. */    ultraIoctl,			/* Ioctl function for the driver. */    ultraSend,			/* Send function for the driver. */    ultraMCastAdd,		/* Multicast add function for the driver */    ultraMCastDel,		/* Multicast delete function for the driver */    ultraMCastGet,		/* Multicast get function for the driver */    ultraPollSend,		/* Polling send function */    ultraPollRcv,		/* Polling receive function */    endEtherAddressForm,	/* put address info into a NET_BUFFER */    endEtherPacketDataGet, 	/* get pointer to data in NET_BUFFER */    endEtherPacketAddrGet 	/* Get packet addresses. */    };/********************************************************************************* ultraLoad - initialize the driver and device** This routine initializes the driver and the device to the operational state.* All of the device-specific parameters are passed in <initString>, which* expects a string of the following format:** <unit>:<ioAddr>:<memAddr>:<vecNum>:<intLvl>:<config>:<offset>"** This routine can be called in two modes. If it is called with an empty but* allocated string, it places the name of this device (that is, "ultra") into * the <initString> and returns 0.** If the string is allocated and not empty, the routine attempts to load* the driver using the values specified in the string.** RETURNS: An END object pointer, or NULL on error, or 0 and the name of the* device if the <initString> was NULL.*/END_OBJ* ultraLoad    (    char *	initString	/* String to be parsed by the driver. */    )    {    ULTRA_DEVICE *	pDrvCtrl;        if (initString == NULL)        return (NULL);        if (initString[0] == NULL)        {        bcopy ((char *)DEV_NAME, initString, DEV_NAME_LEN);        return (NULL);        }        DRV_LOG (DRV_DEBUG_LOAD, "ultraLoad: loading\n",	     (int) DEV_NAME, 2, 3, 4, 5, 6);    /* allocate the device structure */                pDrvCtrl = (ULTRA_DEVICE *)calloc (sizeof (ULTRA_DEVICE), 1);    if (pDrvCtrl == NULL)	goto errorExit;    /* parse the init string, filling in the device structure */    if (ultraParse (pDrvCtrl, initString) == ERROR)	{	logMsg ("ultraLoad: bad initialization string\n",		1, 2, 3, 4, 5, 6);	goto errorExit;	}    DRV_LOG (DRV_DEBUG_LOAD,	     "ultraLoad: unit=%d ivec=%x ilevel=%x ioAddr=%x memAddr=%x config=%x\n",	     pDrvCtrl->unit,	     pDrvCtrl->ivec, pDrvCtrl->ilevel,	     pDrvCtrl->ioAddr,  pDrvCtrl->memAddr,	     pDrvCtrl->config);    /* Setup the rest of pDrvCtrl */    pDrvCtrl->intLevel		= irqTable [pDrvCtrl->ilevel].irq;    pDrvCtrl->transmitPage[0]	= ULTRA_TSTART0;    pDrvCtrl->transmitPage[1]	= ULTRA_TSTART1;    pDrvCtrl->transmitCnt	= 0;    pDrvCtrl->memSize		= ULTRA_RAMSIZE;    pDrvCtrl->cacheFuncs	= cacheDmaFuncs;    /* Reset the device */    ultraReset (pDrvCtrl);    /* Get ethernet address from card */    SYS_OUT_BYTE (pDrvCtrl, LAN_CMD, CMD_PS0 | CMD_STP);    SYS_IN_BYTE (pDrvCtrl, CTRL_LAN0, &pDrvCtrl->enetAddr[0]);    SYS_IN_BYTE (pDrvCtrl, CTRL_LAN1, &pDrvCtrl->enetAddr[1]);    SYS_IN_BYTE (pDrvCtrl, CTRL_LAN2, &pDrvCtrl->enetAddr[2]);    SYS_IN_BYTE (pDrvCtrl, CTRL_LAN3, &pDrvCtrl->enetAddr[3]);    SYS_IN_BYTE (pDrvCtrl, CTRL_LAN4, &pDrvCtrl->enetAddr[4]);    SYS_IN_BYTE (pDrvCtrl, CTRL_LAN5, &pDrvCtrl->enetAddr[5]);    SYS_OUT_BYTE (pDrvCtrl, LAN_CMD, CMD_STP);    /* initialize the END and MIB2 parts of the structure */    if (END_OBJ_INIT (&pDrvCtrl->endObj, (DEV_OBJ *)pDrvCtrl, "ultra",                      pDrvCtrl->unit, &ultraFuncTable,                      "SMC Ultra Elite Enhanced Network Driver.") == ERROR)	goto errorExit;    if (END_MIB_INIT (&pDrvCtrl->endObj, M2_ifType_ethernet_csmacd,                      &pDrvCtrl->enetAddr[0], 6, ETHERMTU,		      ULTRA_SPEED) == ERROR)	goto errorExit;    /* Perform memory allocation */    if (ultraMemInit (pDrvCtrl, 128) == ERROR)	{#if (CPU_FAMILY==I80X86)	/* Probably the bootrom case, try to get by with fewer clusters. */	if (ultraMemInit (pDrvCtrl, 8) == ERROR)	    goto errorExit;#else /* (CPU_FAMILY==I80X86) */	goto errorExit;#endif /* (CPU_FAMILY==I80X86) */	}    /* Reconfigure the device */    ultraConfig (pDrvCtrl);    DRV_LOG (DRV_DEBUG_LOAD, "ultraLoad: done\n",	     1, 2, 3, 4, 5, 6);    /* Set the flags to indicate readiness */    END_OBJ_READY (&pDrvCtrl->endObj,		    IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST		    | IFF_MULTICAST | IFF_SIMPLEX);        return (&pDrvCtrl->endObj);errorExit:    DRV_LOG (DRV_DEBUG_LOAD, "ultraLoad: errorExit\n",	     1, 2, 3, 4, 5, 6);

⌨️ 快捷键说明

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