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

📄 mb86960end.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* mb86960End.c - END-style Fujitsu MB86960 Ethernet network interface driver *//* Copyright 1984-1998 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01b,28mar99,jdi  doc: added missing module title and fixed other format                 errors (SPR 26119).01a,27feb99,db  written from templateEnd.c and target/src/drv/netif/if_fn.c*//*DESCRIPTIONThis module implements the Fujitsu MB86960 NICE Ethernet network interfacedriver.This driver is non-generic and has only been run on the Fujitsu SPARCliteEvaluation Board.  It currently supports only unit number zero.The driver must be given several target-specific parameters, and some externalsupport routines must be provided.  These parameters, and the mechanisms usedto communicate them to the driver, are detailed below.BOARD LAYOUTThis device is on-board.  No jumpering diagram is necessary.The MB86960 Network Interface Controller with Encoder/Decoder (NICE) chip isa highly integrated monolithic device which incorporates both networkcontroller, complete with buffer management and Manchester encoder/decoder.TARGET-SPECIFIC PARAMETERSThe format of the parameter string is:    <unit>:<devBaseAddr>:<ivec>.IP <unit>A convenient holdover from the former model.  It is only used in thestring name for the driver..IP <devBaseAddr>The base Address of the chip registers..IP <ivec>This is the interrupt vector number of the hardware interrupt generated bythis ethernet device.  The driver uses intConnect() to attach an interrupthandler to this interrupt.EXTERNAL SUPPORT REQUIREMENTSThis driver requires seven external support functions:.IP sys86960IntEnable().CS    void sysEnetIntEnable (int unit).CEThis routine provides a target-specific interface to enable Ethernet deviceinterrupts for a given device unit. For this driver, value of unit must be 0..IP sys86960IntDisable().CS    void sysEnetIntDisable (int unit).CEThis routine provides a target-specific interface to disable Ethernet deviceinterrupts for a given device unit. For this driver, value of unit must be 0..IP sysEnetAddrGet().CS    STATUS sysEnetAddrGet (int unit, char *enetAdrs).CEThis routine provides a target-specific interface to access a device Ethernetaddress. This routine should provide a six-byte Ethernet address in  the <enetAdrs> parameter and return OK or ERROR.In this driver the macros SYS_OUT_SHORT and SYS_IN_SHORT which callbsp-specific functions to access the chip register.INCLUDES:end.h endLib.h etherMultiLib.hSEE ALSO: muxLib, endLib.I "Writing and Enhanced Network Driver"*//* includes */#include "vxWorks.h"#include "iv.h"#include "memLib.h"#include "intLib.h"#include "stdio.h"#include "stdlib.h"#include "netLib.h"#include "drv/end/mb86960End.h"		/* Common defines. */#include "etherMultiLib.h"		/* multicast stuff. */#include "end.h"			/* Common END structures. */#include "endLib.h"#include "lstLib.h"			/* Needed to maintain protocol list. */#include "logLib.h"#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"/* Endian safe macro - MB86960_SWAP_SHORT */#if (_BYTE_ORDER == _BIG_ENDIAN)#   define MB86960_SWAP_SHORT(x)	(MSB(x) | LSB(x) << 8)#else#   define MB86960_SWAP_SHORT(x)	(x)#endif /* * 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->vector), \			     rtn, (int)arg); \	}#endif/* Macro to disconnect interrupt handler from vector */#ifndef SYS_INT_DISCONNECT#   define SYS_INT_DISCONNECT(pDrvCtrl,rtn,arg,pResult) \	{ \	*pResult = OK; /* HELP: need a real routine */ \	}#endif/* Macro to enable the appropriate interrupt level */#ifndef SYS_INT_ENABLE#   define SYS_INT_ENABLE(pDrvCtrl) \	{ \	IMPORT STATUS sysEnetIntEnable(int); \	sysEnetIntEnable (pDrvCtrl->unit); \	}#endif#ifndef SYS_INT_DISABLE#   define SYS_INT_DISABLE(pDrvCtrl) \	{ \	IMPORT STATUS sysEnetIntDisable(int); \	sysEnetIntDisable (pDrvCtrl->unit); \	}#endif/* Macro to get the ethernet address from the BSP */#ifndef SYS_ENET_ADDR_GET#   define SYS_ENET_ADDR_GET(pDrvCtrl, pRetCode) \	{ \	IMPORT STATUS sysEnetAddrGet(); \        *pRetCode = sysEnetAddrGet (pDrvCtrl->unit, (char *) &pDrvCtrl->enetAddr); \	}#endif/* * Macros to do a short (UINT16) access to the chip. Default * assumes a normal memory mapped device. */#ifndef SYS_OUT_SHORT#   define SYS_OUT_SHORT(addr,value) \	{ \	IMPORT void sysAsiSeth (); \        sysAsiSeth (addr, value); \	}#endif#ifndef SYS_IN_SHORT#   define SYS_IN_SHORT(addr, var) \	{ \	IMPORT u_short sysAsiGeth (); \        var = sysAsiGeth (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)/* * This will only work if there is only a single unit, for multiple * unit device drivers these should be integrated into the MB86960_END_CTRL * structure. */M_CL_CONFIG fnMclBlkCfg = 	/* network mbuf configuration table */    {    /*     no. mBlks		no. clBlks	memArea		memSize    -----------		----------	-------		-------    */    0, 			0, 		NULL, 		0    };CL_DESC fnClDescTbl [] = 	/* network cluster pool configuration table */    {    /*     clusterSize		num		memArea		memSize    -----------		----		-------		-------    */    {MB86960_BUFSIZ,	0,		NULL,		0}      }; int fnClDescTblNumEnt = (NELEMENTS(fnClDescTbl));/* Definitions for the flags field */#define LS_PROMISCUOUS_FLAG     0x1#define LS_MEM_ALLOC_FLAG       0x2#define LS_PAD_USED_FLAG        0x4#define LS_RCV_HANDLING_FLAG    0x8#define LS_POLLING              0x20/***** DEBUG MACROS *****/#define 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_POLL_REDIR	0x10000#define	DRV_DEBUG_LOG_NVRAM	0x20000#ifdef LOCAL#undef LOCAL#endif /* LOCAL */#define LOCAL ;int  mb86960Debug = DRV_DEBUG_OFF;NET_POOL mb86960NetPool;#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6)  \        if (mb86960Debug & FLG)                   \           logMsg(X0, X1, X2, X3, X4, X5, X6);#define DRV_PRINT(FLG,X)                          \	if (mb86960Debug & FLG) printf X;#else /*DRV_DEBUG*/#define DRV_LOG(DBG_SW, X0, X1, X2, X3, X4, X5, X6)#define DRV_PRINT(DBG_SW,X)#endif /*DRV_DEBUG*/#define MB86960_BUFS  100    /* Needs some work *//* forward static functions */LOCAL void	mb86960Reset		(MB86960_END_CTRL * pDrvCtrl);LOCAL void	mb86960Int		(MB86960_END_CTRL * pDrvCtrl);LOCAL void	mb86960HandleRcvInt  	(MB86960_END_CTRL * pDrvCtrl);LOCAL STATUS	mb86960Recv		(MB86960_END_CTRL * pDrvCtrl, 					 MB86960_RX_FRAME * pRxFrame);LOCAL BOOL      mb86960RxMore 		(MB86960_END_CTRL * pDrvCtrl);LOCAL void	mb86960Config		(MB86960_END_CTRL * pDrvCtrl);/* END Specific interfaces. *//* This is the only externally visible interface. */END_OBJ * 	mb86960EndLoad 	(char * initString);LOCAL STATUS	mb86960Start	(MB86960_END_CTRL * pDrvCtrl);LOCAL STATUS	mb86960Stop	(MB86960_END_CTRL * pDrvCtrl);LOCAL STATUS	mb86960Unload   ();LOCAL int	mb86960Ioctl	(MB86960_END_CTRL * pDrvCtrl, int cmd,				 caddr_t data);LOCAL STATUS	mb86960Send	(MB86960_END_CTRL * pDrvCtrl, 				 M_BLK_ID pBuf);LOCAL STATUS    mb89680Transmit (MB86960_END_CTRL * pDrvCtrl, 				 M_BLK_ID pMblk);LOCAL STATUS    mb86960PacketGet (MB86960_END_CTRL  * pDrvCtrl, 				  MB86960_RX_FRAME * pRxFrame);LOCAL BOOL      mb89680RxMore   (MB86960_END_CTRL * pDrvCtrl);			  LOCAL void 	mb86960AddrFilterSet (MB86960_END_CTRL* pDrvCtrl, char * pAddr, 				      BOOL	bSet);LOCAL STATUS	mb86960MCastAddrAdd (MB86960_END_CTRL * pDrvCtrl, 				     char* pAddress);LOCAL STATUS	mb86960MCastAddrDel (MB86960_END_CTRL * pDrvCtrl, 				     char* pAddress);LOCAL STATUS	mb86960MCastAddrGet (MB86960_END_CTRL * pDrvCtrl, 				     MULTI_TABLE* pTable);LOCAL STATUS	mb86960PollSend (MB86960_END_CTRL * pDrvCtrl, M_BLK_ID pBuf);LOCAL STATUS	mb86960PollRcv 	(MB86960_END_CTRL * pDrvCtrl, M_BLK_ID pBuf);LOCAL STATUS	mb86960PollStart (MB86960_END_CTRL * pDrvCtrl);LOCAL STATUS	mb86960PollStop (MB86960_END_CTRL * pDrvCtrl);LOCAL STATUS	mb86960InitParse (MB86960_END_CTRL *, char *);LOCAL STATUS	mb86960MemInit ();LOCAL int 	mb86960HashIndex (char * pEnAddr);LOCAL STATUS    mb86960HdrShow (struct ether_header * pHdr, char * msg);/* * Declare our function table.  This is static across all driver * instances. */LOCAL NET_FUNCS mb86960FuncTable =    {    (FUNCPTR) mb86960Start,	/* Function to start the device. */    (FUNCPTR) mb86960Stop,	/* Function to stop the device. */    (FUNCPTR) mb86960Unload,	/* Unloading function for the driver. */    (FUNCPTR) mb86960Ioctl,		/* Ioctl function for the driver. */    (FUNCPTR) mb86960Send,		/* Send function for the driver. */    (FUNCPTR) mb86960MCastAddrAdd,	/* Multicast address add func. */    (FUNCPTR) mb86960MCastAddrDel,	/* Multicast address delete func. */    (FUNCPTR) mb86960MCastAddrGet,	/* Multicast table retrieve func. */    (FUNCPTR) mb86960PollSend,		/* Polling send function. */    (FUNCPTR) mb86960PollRcv,		/* Polling receive function. */    endEtherAddressForm,        /* Put address info into a packet. */    endEtherPacketDataGet,      /* Get a pointer to packet data. */    endEtherPacketAddrGet       /* Get packet addresses. */    };int overFlowCnt; int dropCnt; /********************************************************************************* mb86960EndLoad - initialize the driver and device** This routine initializes the driver and puts the device to an operational * state.* All of the device specific parameters are passed in via the initString, which* expects a string of the following format:** <unit>:<base_addr>:<int_vector>:<int_level>** 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, "fn") 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 * mb86960EndLoad    (    char * pInitString		/* String to be parsed by the driver. */    )    {    MB86960_END_CTRL * pDrvCtrl;    STATUS retCode;        DRV_LOG (DRV_DEBUG_LOAD, "Loading nice...\n", 1, 2, 3, 4, 5, 6);    if (pInitString == NULL)        return (NULL);    if (pInitString[0] == NULL)        {        bcopy((char *)FN_DEV_NAME, pInitString, FN_DEV_NAME_LEN);        return (0);        }        /* allocate the device structure */	    pDrvCtrl = (MB86960_END_CTRL *) calloc (sizeof(MB86960_END_CTRL), 1);    if (pDrvCtrl == NULL)	goto errorExit;    /* parse the init string, filling in the device structure */    if (mb86960InitParse (pDrvCtrl, pInitString) == ERROR)	goto errorExit;    /* Ask the BSP to provide the ethernet address. */	    SYS_ENET_ADDR_GET(pDrvCtrl, &retCode);    if (retCode == ERROR)	goto errorExit;    /*      * initialize the END and MIB2 parts of the structure     * The M2 element must come from m2Lib.h      * This template is set up for a DIX type ethernet device.     */	    if (END_OBJ_INIT (&pDrvCtrl->end, (DEV_OBJ *)pDrvCtrl, FN_DEV_NAME,        	      pDrvCtrl->unit, &mb86960FuncTable,		      "Fujitsu MB86960 Ethernet Enhanced Network Driver") 		      == ERROR || 		      END_MIB_INIT (&pDrvCtrl->end, M2_ifType_ethernet_csmacd,			  &pDrvCtrl->enetAddr[0], ENET_ADDR_LEN, ETHERMTU,			  MB86960_SPEED) == ERROR)        goto errorExit;    /* Perform memory allocation/distribution */    if (mb86960MemInit (pDrvCtrl) == ERROR)        goto errorExit;    /* (re)initialize and configure the device */	    mb86960Reset (pDrvCtrl);    mb86960Config (pDrvCtrl);    /* set the flags to indicate readiness */    END_OBJ_READY (&pDrvCtrl->end, (IFF_UP | IFF_RUNNING | IFF_NOTRAILERS				    | IFF_BROADCAST | IFF_MULTICAST));    DRV_LOG (DRV_DEBUG_LOAD, "Done loading end...\n", 1, 2, 3, 4, 5, 6);    return (&pDrvCtrl->end);errorExit:    mb86960Unload (pDrvCtrl);    return (NULL);    }/********************************************************************************* mb86960InitParse - parse the initialization string** This routine parses the input string, filling in values in the* driver control structure.** The initialization string format is:   <unit>:<baseAddr>:<ivec>* .IP <unit>* Device unit number, a small integer.  Must always be 0.* .IP <devBaseAddr>* Base address of the device register set.* .IP <ivec>* Interrupt vector number, used with sysIntConnect().** RETURNS: OK or ERROR for invalid arguments.*/STATUS mb86960InitParse    (    MB86960_END_CTRL * pDrvCtrl,	/* device pointer */    char * pInitString			/* information string */    )    {    char *	tok;    char *      pHolder = NULL;         /* Parse the initString */    /* Unit number. */    tok = strtok_r (pInitString, ":", &pHolder);    if (tok == NULL) 	return ERROR;    if ((pDrvCtrl->unit = atoi (tok)) != 0) 	return ERROR;    /* Device Base Address. */    tok = strtok_r (NULL, ":", &pHolder);    if (tok == NULL) 	return ERROR;    pDrvCtrl->devBaseAddr = (char *)strtoul (tok, NULL, 16);    /* Interrupt vector. */        tok = strtok_r (NULL, ":", &pHolder);    if (tok == NULL) 	return ERROR;    pDrvCtrl->vector = atoi (tok);    DRV_LOG (DRV_DEBUG_LOAD, "Processed all arugments\n", 1, 2, 3, 4, 5, 6);    DRV_LOG (DRV_DEBUG_LOAD, "Address %p ivec %d\n",		       (int ) pDrvCtrl->devBaseAddr, (int ) pDrvCtrl->vector, 		       3, 4, 5, 6);    return OK;    }/********************************************************************************* mb86960MemInit - initialize memory for the chip** This routine is highly specific to the device.  ** RETURNS: OK or ERROR.*/STATUS mb86960MemInit    (    MB86960_END_CTRL * pDrvCtrl	/* device to be initialized */    )    {    /*     * This is how we would set up and END netPool using netBufLib(1).     * This code is pretty generic.     */        if ((pDrvCtrl->end.pNetPool = malloc (sizeof(NET_POOL))) == NULL)        return (ERROR);    fnMclBlkCfg.mBlkNum = MB86960_BUFS;     fnClDescTbl[0].clNum = MB86960_BUFS;    fnMclBlkCfg.clBlkNum = fnClDescTbl[0].clNum;    /* Calculate the total memory for all the M-Blks and CL-Blks. */    fnMclBlkCfg.memSize = (fnMclBlkCfg.mBlkNum * (MSIZE + sizeof (long))) +                          (fnMclBlkCfg.clBlkNum * (CL_BLK_SZ + sizeof(long)));    if ((fnMclBlkCfg.memArea = (char *) memalign (sizeof(long),                                                  fnMclBlkCfg.memSize))        == NULL)        return (ERROR);    /* Calculate the memory size of all the clusters. */    fnClDescTbl[0].memSize = (fnClDescTbl[0].clNum * (MB86960_BUFSIZ + 8))        + sizeof(int);    /* Allocate the memory for the clusters from cache safe memory. */    fnClDescTbl[0].memArea =        (char *) memalign (sizeof(long), fnClDescTbl[0].memSize);    if ((int)fnClDescTbl[0].memArea == NULL)

⌨️ 快捷键说明

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