📄 templateend.c
字号:
/* templateEnd.c - template Enhanced Network Driver (END) *//* Copyright 1984-2001 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--------------------01y,14jun02,dat Fixing diab warnings01x,15may02,dat Update comments about polled entry points01w,03nov01,dat buffer/cache updates01v,24sep01,pai merge from sustaining branch to Veloce (SPR# 70553).01u,06jun01,pai templateLoad corrected for two-pass algorithm (SPR# 67836)01t,09mar01,dat 64473, MuxLib was free'ing the END_OBJ structure. Fixed the load function for driver name response.01s,29sep00,dat removing PHYS_TO_VIRT translation01r,20sep00,dat SPR 32058, allow for alternate intConnect rtn01q,28aug00,stv corrected the handling of EIOCSFLAGS ioctl (SPR# 29423).01p,02aug00,stv removed netMblkClChainFree() in Pollsend routine (SPR# 32885).01o,11jun00,ham removed reference to etherLib.01n,27jan00,dat fixed use of NULL01m,12dec00,pai fixed SYS_ENET_ADDR_GET and SYS_INT_ENABLE definitions (SPR #62969).01l,12dec00,pai fixed various build errors (SPR #62962).01k,12dec00,pai merged in changes from HIT August Drivers Release.01j,12oct99,dat SPR 28492, fixed templateSend.01i,29mar99,dat documentation, SPR 26119. fixed .bS/.bE usage01h,28feb99,pul changed the prototype for END NET functions, to have END_OBJ reference as the first argument rather than device object, fix for SPR#2428501g,17feb99,dat documentation, removed beta warning01f,29sep98,dat Fixed problem in PollRx relating to SPR 22325.01e,28sep98,dat SPR 22325, system mode transition, plus fixed warnings and template is now compilable (SPR 22204).01d,17jul98,db changed "holder" in templateParse from char** to char *. fixed references to "holder" in templateParse(spr #21464).01c,15oct97,gnn revised to reflect the latest API changes.01b,05may97,dat added TODO's for documentation and macros.01a,04feb97,gnn written.*//*DESCRIPTIONTODO - Describe the chip being used completely, even if it provides morefeatures than ethernet.TODO - Describe the device's full ethernet capabilities, even if this driverdoesn't or can't utilize all of them. Describe the features that the driverdoes implement and any restrictions on their use.TODO - Describe all macros that can be used to customize this driver. Allaccesses to chip registers should be done through redefineable macros.In this example driver the macros TEMPLATE_OUT_SHORT and TEMPLATE_IN_SHORTare sample macros to read/write data to a mock device. If a devicecommunicates through formatted control blocks in shared memory, theaccesses to those control blocks should also be through redefinablemacros.TODO - The following information describes the procedure an end user wouldfollow to integrate this new END device into a new BSP. The procedure needs to be well documented.This driver is easily customized for a BSP by modifying global pointersto routines. The routine pointers are declared below. The code belowindicates the default values for each routine as well. By modifyingthese global pointer values, the BSP can change the behaviour of the driver..CS IMPORT STATUS (*templateIntConnectRtn) \ (int level, FUNCTPR pFunc, int arg); IMPORT STATUS (*templateIntDisconnectRtn) \ (int level, FUNCTPR pFunc, int arg); IMPORT STATUS (*templateIntEnableRtn) (int level); IMPORT STATUS (*templateEnetAddrGetRtn)(int unit, char *pResult); IMPORT STATUS (*templateOutShortRtn)(UINT addr, UINT value); IMPORT STATUS (*templateInShortRtn)(UINT addr, USHORT *pData); templateIntConnectRtn = intConnect; /@ must not be NULL @/ templateIntDisconnectRtn = NULL; templateIntEnableRtn = NULL; templateEndAddrGetRtn = NULL; templateOutShortRtn = NULL; templateInShortRtn = NULL;.CEExcecpt for templateIntConnectRtn and templateIntEnableRtn, a NULL valuewill result in the driver taking a default action. For the int disconnectfunction the default action is to do nothing at all. For the short in and outroutines, the default is to assume memory mapped device registers and toaccess them directly. The default ethernet address get routineprovides an invalid ethernet address of all zeros (0:0:0:0:0:0).If the BSP is willing to accept these default values no action at allis needed. To change the default value, the BSP should create an appropriateroutine and set the address into the global value before first use. Thiswould normally be done at function sysHwInit2() time.For Tornado 3.0 you need to pay attention to virtual physical addresstranslations which are important. Use the cache lib macros to toproper VIRT_TO_PHYS translation as part of generating the physical DMAaddress for the device. Avoid the use of PHYS_TO_VIRT translation asit can be very time consuming. If at all possible, the driver shouldcache the virtual address of each data buffer used for DMA.Prior to VxWorks AE 1.1, the muxLib function muxDevUnload() did a freeof the actual END_OBJ structure that was malloc'd during the driverload routine. Starting with VxWorks AE 1.1, this behaviour can bechanged. If the second argument to END_OBJ_INIT points to the END_OBJthen muxLib will free it during muxDevUnload. If not, then muxDevUnloadwill not free the allocated space. Under this situation, it is assumedthat the driver unload routine has free'd the space itself. This preservesbackward compatibility with older drivers that always specified the secondargument to END_OBJ_INIT() as a pointer to the END_OBJ structure. Thistemplate has been changed to use the new behaviour instead.INCLUDES:end.h endLib.h etherMultiLib.hSEE ALSO: muxLib, endLib.I "Writing and 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 "iv.h"#include "semLib.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 "netinet/if_ether.h"#include "sys/socket.h"#include "sys/ioctl.h"#include "sys/times.h"IMPORT int endMultiLstCnt (END_OBJ* pEnd);/* defines */#define DRV_NAME "template"#define DRV_NAME_LEN (sizeof(DRV_NAME) + 1)/* Configuration items */#define END_BUFSIZ (ETHERMTU + SIZEOF_ETHERHEADER + 6)#define EH_SIZE (14)#define END_SPEED_10M 10000000 /* 10Mbs */#define END_SPEED_100M 100000000 /* 100Mbs */#define END_SPEED END_SPEED_10M/* Cache macros */#define END_CACHE_INVALIDATE(address, len) \ CACHE_DRV_INVALIDATE (pDrvCtrl->pCacheFuncs, (address), (len))#define END_CACHE_VIRT_TO_PHYS(address) \ CACHE_DRV_VIRT_TO_PHYS (pDrvCtrl->pCacheFuncs, (address))/* * 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 FUNCPTR templateIntConnectRtn = intConnect;# define SYS_INT_CONNECT(pDrvCtrl,rtn,arg,pResult) \ do { \ *pResult = (*templateIntConnectRtn) ((VOIDFUNCPTR *) \ INUM_TO_IVEC (pDrvCtrl->ivec), rtn, (int)arg); \ } while (0)#endif/* Macro to disconnect interrupt handler from vector */#ifndef SYS_INT_DISCONNECT STATUS (*templateIntDisconnectRtn) \ (int level, FUNCPTR rtn, int arg) = NULL;# define SYS_INT_DISCONNECT(pDrvCtrl,rtn,arg,pResult) \ do { \ if (templateIntDisconnectRtn != NULL) \ *pResult = (*templateIntDisconnectRtn)(pDrvCtrl->ivec, \ rtn, (int)arg); \ else \ *pResult = ERROR; \ } while (0)#endif/* Macro to enable the appropriate interrupt level */#ifndef SYS_INT_ENABLE STATUS (*templateIntEnableRtn)(int level) = NULL;# define SYS_INT_ENABLE(pDrvCtrl) \ do { \ if (templateIntEnableRtn != NULL) \ (*templateIntEnableRtn) (pDrvCtrl->ilevel); \ } while (0)#endif/* Macro to get the ethernet address from the BSP */#ifndef SYS_ENET_ADDR_GET STATUS (*templateEnetAddrGetRtn)(int unit, char * pResult) = NULL;# define SYS_ENET_ADDR_GET(pDevice) \ do { \ if (templateEnetAddrGetRtn == NULL) \ bzero ((char *)&pDevice->enetAddr, 6); \ else \ (*templateEnetAddrGetRtn)(pDevice->unit, \ (char *)&pDevice->enetAddr); \ } while (0)#endif/* * Macros to do a short (UINT16) access to the chip. Default * assumes a normal memory mapped device. */#ifndef TEMPLATE_OUT_SHORT STATUS (*templateOutShortRtn)(UINT addr, UINT value) = NULL;# define TEMPLATE_OUT_SHORT(pDrvCtrl,addr,value) \ do { \ if (templateOutShortRtn == NULL) \ (*(USHORT *)addr = value) \ else \ (*templateOutShortRtn)((UINT)addr, (UINT)value) \ } while (0)#endif#ifndef TEMPLATE_IN_SHORT STATUS (*templateInShortRtn)(UINT addr, USHORT *pData) = NULL;# define TEMPLATE_IN_SHORT(pDrvCtrl,addr,pData) \ do { \ if (templateInShortRtn == NULL) \ (*pData = *addr) \ else \ (*templateInShortRtn)((UINT)addr, pData) \ } while (0)#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 */typedef struct { int len; char * pData; /* data virtual address */ char * pPhys; /* dma physical address */ } PKT; /* A dummy DMA data packet */#define TEMPLATE_PKT_LEN_GET(pPkt) (((PKT *)pPkt)->len)#define TEMPLATE_PKT_VIRT_GET(pPkt) (((PKT *)pPkt)->pData)typedef struct rfd { PKT * pPkt; struct rfd * next; } RFD; /* dummy rx frame descriptor */typedef struct free_args { void* arg1; void* arg2; } FREE_ARGS;/* The definition of the driver control structure */typedef struct end_device { END_OBJ end; /* The class we inherit from. */ int unit; /* unit number */ int ivec; /* interrupt vector */ int ilevel; /* interrupt level */ char* pShMem; /* real ptr to shared memory */ long flags; /* Our local flags. */ UCHAR enetAddr[6]; /* ethernet address */ CACHE_FUNCS* pCacheFuncs; /* cache function pointers */ FUNCPTR freeRtn[128]; /* Array of free routines. */ struct free_args freeData[128]; /* Array of free arguments */ /* the free routines. */ CL_POOL_ID pClPoolId; /* cluster pool */ BOOL rxHandling; /* rcv task is scheduled */ } END_DEVICE;/* * This will only work if there is only a single unit, for multiple * unit device drivers these should be integrated into the END_DEVICE * structure. */M_CL_CONFIG templateMclBlkConfig = /* network mbuf configuration table */ { /* no. mBlks no. clBlks memArea memSize ----------- ---------- ------- ------- */ 0, 0, NULL, 0 };CL_DESC templateClDescTbl [] = /* network cluster pool configuration table */ { /* clusterSize num memArea memSize ----------- ---- ------- ------- */ {ETHERMTU + EH_SIZE + 2, 0, NULL, 0} };int templateClDescTblNumEnt = (NELEMENTS(templateClDescTbl));/* Definitions for the flags field */#define TEMPLATE_PROMISCUOUS 0x1#define TEMPLATE_POLLING 0x2/* Status register bits, returned by templateStatusRead() */#define TEMPLATE_RINT 0x1 /* Rx interrupt pending */#define TEMPLATE_TINT 0x2 /* Tx interrupt pending */#define TEMPLATE_RXON 0x4 /* Rx on (enabled) */#define TEMPLATE_VALID_INT 0x3 /* Any valid interrupt pending */#define TEMPLATE_MIN_FBUF (1536) /* min first buffer size *//* DEBUG MACROS */#ifdef DEBUG# define LOGMSG(x,a,b,c,d,e,f) \ if (endDebug) \ { \ logMsg (x,a,b,c,d,e,f); \ }#else# define LOGMSG(x,a,b,c,d,e,f)#endif /* ENDDEBUG */#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_POLL_REDIR 0x10000#define DRV_DEBUG_LOG_NVRAM 0x20000int templateDebug = 0x00;int templateTxInts=0;#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6) \ if (templateDebug & FLG) \ logMsg(X0, X1, X2, X3, X4, X5, X6);#define DRV_PRINT(FLG,X) \ if (templateDebug & 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*//* LOCALS *//* forward static functions */LOCAL void templateReset (END_DEVICE *pDrvCtrl);LOCAL void templateInt (END_DEVICE *pDrvCtrl);LOCAL void templateHandleRcvInt (END_DEVICE *pDrvCtrl);LOCAL STATUS templateRecv (END_DEVICE *pDrvCtrl, PKT* pData);LOCAL void templateConfig (END_DEVICE *pDrvCtrl);LOCAL UINT templateStatusRead (END_DEVICE *pDrvCtrl);/* END Specific interfaces. *//* This is the only externally visible interface. */END_OBJ* templateLoad (char* initString);LOCAL STATUS templateStart (END_DEVICE* pDrvCtrl);LOCAL STATUS templateStop (END_DEVICE* pDrvCtrl);LOCAL int templateIoctl (END_DEVICE* pDrvCtrl, int cmd, caddr_t data);LOCAL STATUS templateUnload (END_DEVICE* pDrvCtrl);LOCAL STATUS templateSend (END_DEVICE* pDrvCtrl, M_BLK_ID pBuf);LOCAL STATUS templateMCastAdd (END_DEVICE* pDrvCtrl, char* pAddress);LOCAL STATUS templateMCastDel (END_DEVICE* pDrvCtrl, char* pAddress);LOCAL STATUS templateMCastGet (END_DEVICE* pDrvCtrl, MULTI_TABLE* pTable);LOCAL STATUS templatePollStart (END_DEVICE* pDrvCtrl);LOCAL STATUS templatePollStop (END_DEVICE* pDrvCtrl);LOCAL STATUS templatePollSend (END_DEVICE* pDrvCtrl, M_BLK_ID pBuf);LOCAL STATUS templatePollRcv (END_DEVICE* pDrvCtrl, M_BLK_ID pBuf);LOCAL void templateAddrFilterSet(END_DEVICE *pDrvCtrl);LOCAL STATUS templateParse ();LOCAL STATUS templateMemInit ();/* * Declare our function table. This is static across all device * instances. */LOCAL NET_FUNCS templateFuncTable = { (FUNCPTR) templateStart, /* Function to start the device. */ (FUNCPTR) templateStop, /* Function to stop the device. */ (FUNCPTR) templateUnload, /* Unloading function for the driver. */ (FUNCPTR) templateIoctl, /* Ioctl function for the driver. */ (FUNCPTR) templateSend, /* Send function for the driver. */ (FUNCPTR) templateMCastAdd, /* Multicast add function for the */ /* driver. */ (FUNCPTR) templateMCastDel, /* Multicast delete function for */ /* the driver. */ (FUNCPTR) templateMCastGet, /* Multicast retrieve function for */ /* the driver. */ (FUNCPTR) templatePollSend, /* Polling send function */ (FUNCPTR) templatePollRcv, /* Polling receive function */ endEtherAddressForm, /* put address info into a NET_BUFFER */ endEtherPacketDataGet, /* get pointer to data in NET_BUFFER */ endEtherPacketAddrGet /* Get packet addresses. */ };/********************************************************************************* templateLoad - 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 the initString.** The string contains the target specific parameters like this:** "register addr:int vector:int level:shmem addr:shmem size:shmem width"** 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 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 empty.*/END_OBJ* templateLoad ( char* initString /* String to be parsed by the driver. */ ) { END_DEVICE *pDrvCtrl; DRV_LOG (DRV_DEBUG_LOAD, "Loading template...\n", 1, 2, 3, 4, 5, 6); if (initString == NULL) { DRV_LOG (DRV_DEBUG_LOAD, "templateLoad: NULL initStr\r\n", 0,0,0,0,0,0); return NULL; } if (initString[0] == EOS) { bcopy ((char *)DRV_NAME, initString, DRV_NAME_LEN); return NULL; } /* else initString is not blank, pass two ... */ /* allocate the device structure */ pDrvCtrl = (END_DEVICE *)calloc (sizeof (END_DEVICE), 1); if (pDrvCtrl == NULL) goto errorExit; /* parse the init string, filling in the device structure */ if (templateParse (pDrvCtrl, initString) == ERROR) goto errorExit; /* Ask the BSP for the ethernet address. */ SYS_ENET_ADDR_GET(pDrvCtrl); /* 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, NULL, "template", pDrvCtrl->unit, &templateFuncTable,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -