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

📄 ks8695end.c

📁 kedin bsp for vxWorks
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ks8695End.c - ks8695 Enhanced Network Driver (END) for KS8695/P BSP *//* * Author: LIQUN RUAN (RLQ) * 09/18/2003 * Created based on WindRiver's templateEnd.c for Micrel Semiconductor's KS8695/P SOHO router chip * *//* Copyright 1984-2001 Wind River Systems, Inc. *//*TODO -	Remove the ks8695 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  ks8695EndLoad 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 KS8695_SYS_ENET_ADDR_GET and KS8695_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 ks8695EndSend.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 ks8695 is now compilable (SPR 22204).01d,17jul98,db   changed "holder" in ks8695EndParse from char** to char *.		 fixed references to "holder" in ks8695EndParse(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 KS8695_OUT_SHORT and KS8695_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 (*ks8695IntConnectRtn) \            (int level, FUNCTPR pFunc, int arg);    IMPORT STATUS (*ks8695IntDisconnectRtn) \            (int level, FUNCTPR pFunc, int arg);    IMPORT STATUS (*ks8695IntEnableRtn) (int level);    IMPORT STATUS (*ks8695EnetAddrGetRtn)(int unit, char *pResult);    IMPORT STATUS (*ks8695OutShortRtn)(UINT addr, UINT value);    IMPORT STATUS (*ks8695InShortRtn)(UINT addr, USHORT *pData);        ks8695IntConnectRtn = intConnect; /@ must not be NULL @/    ks8695IntDisconnectRtn = NULL;    ks8695IntEnableRtn = NULL;    ks8695EndAddrGetRtn = NULL;    ks8695OutShortRtn = NULL;    ks8695InShortRtn = NULL;.CEExcecpt for ks8695IntConnectRtn and ks8695IntEnableRtn, 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.  Thisks8695 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"#include "tickLib.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"#include "wdLib.h"#include "ks8695End.h"		/* KS8695/P specific defines. */IMPORT	int endMultiLstCnt (END_OBJ* pEnd);IMPORT POOL_FUNC	*_pEndNetPoolFuncTbl; /* defines */#define	DEBUG#define	DEBUG_THIS#define PACKET_DUMP/*#define	NO_RX*/			/* no rx, for debug only */#define	USE_PERF_COUNTER#define	TEST_RX#define	KS8695_DRV_NAME		"ks"	/* max 8 bytes */#define KS8695_DRV_NAME_LEN	(strlen(KS8695_DRV_NAME) + 1)char ks8695_driver_version[] = "1.0.0";char ks8695_copyright[] = "Copyright (c) 2003 Micrel Semiconductor Corp.";#define	STAT_NET(x)			(pDrvCtrl->stats.x)/*#define	NO_TASK_DELAY*/#ifndef	NO_TASK_DELAY#define	SW_WRITE_DELAY()	taskDelay(4)	/* enough delay for cpu 166/125 MHz */#else#define	SW_WRITE_DELAY()	delayEx(400000)#endif/* Configuration items */#define END_BUFSIZ      	(ETHERMTU + SIZEOF_ETHERHEADER + 6)#define END_SPEED_10M		10000000	/* 10Mbs full duplex */#define END_SPEED_100M		100000000	/* 100Mbs full duplex, default */#define END_SPEED_10M_H		10000000	/* 10Mbs half duplex */#define END_SPEED_100M_H	100000000	/* 100Mbs half duplex */#define END_SPEED       	END_SPEED_100M/* * 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 KS8695_SYS_INT_CONNECT    FUNCPTR	ks8695IntConnectRtn = intConnect;#   define KS8695_SYS_INT_CONNECT(pDrvCtrl,rtn,arg,pResult) \	do { \	*pResult = (*ks8695IntConnectRtn) ((VOIDFUNCPTR *) \			INUM_TO_IVEC (pDrvCtrl->ivec), rtn, (int)arg); \	} while (0)#endif/* Macro to disconnect interrupt handler from vector */#ifndef KS8695_SYS_INT_DISCONNECT    STATUS	(*ks8695IntDisconnectRtn) \			(int level, FUNCPTR rtn, int arg) = NULL;#   define KS8695_SYS_INT_DISCONNECT(pDrvCtrl,rtn,arg,pResult) \	do { \	if (ks8695IntDisconnectRtn != NULL) \	    *pResult = (*ks8695IntDisconnectRtn)(pDrvCtrl->ivec, \					rtn, (int)arg); \	else \	    *pResult = ERROR; \	} while (0)#endif/* Macro to enable the appropriate interrupt level */#undef KS8695_SYS_INT_ENABLE#ifndef KS8695_SYS_INT_ENABLE    STATUS	(*ks8695IntEnableRtn)(int level) = intEnable;#   define KS8695_SYS_INT_ENABLE(pDrvCtrl) \	do { \	    if (ks8695IntEnableRtn != NULL) \		(*ks8695IntEnableRtn)(pDrvCtrl->ilevel); \	} while (0)#endif #undef KS8695_SYS_INT_DISABLE#ifndef KS8695_SYS_INT_DISABLE    STATUS	(*ks8695IntDisableRtn)(int level) = intDisable;#   define KS8695_SYS_INT_DISABLE(pDrvCtrl) \	do { \	    if (ks8695IntDisableRtn != NULL) \		(*ks8695IntDisableRtn) (pDrvCtrl->ilevel); \	} while (0)#endif/* Macro to get the ethernet address from the BSP */#ifndef KS8695_SYS_ENET_ADDR_GET    STATUS (*ks8695EnetAddrGetRtn)(int unit, char * pResult) = NULL;#   define KS8695_SYS_ENET_ADDR_GET(pDevice) \	do { \	if (ks8695EnetAddrGetRtn == NULL) \	    bzero ((char *)&pDevice->enetAddr, 6); \	else \	    (*ks8695EnetAddrGetRtn)(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 KS8695_OUT_SHORT    STATUS (*ks8695OutShortRtn)(UINT addr, UINT value) = NULL;#   define KS8695_OUT_SHORT(pDrvCtrl,addr,value) \	do { \	    if (ks8695OutShortRtn == NULL) \		(*(USHORT *)addr = value) \	    else \		(*ks8695OutShortRtn)((UINT)addr, (UINT)value) \	} while (0)#endif#ifndef KS8695_IN_SHORT    STATUS (*ks8695InShortRtn)(UINT addr, USHORT *pData) = NULL;#   define KS8695_IN_SHORT(pDrvCtrl,addr,pData) \	do { \	    if (ks8695InShortRtn == NULL) \		(*pData = *addr) \	    else \		(*ks8695InShortRtn)((UINT)addr, pData) \	} while (0)#endif/* A shortcut for getting the hardware address from the MIB II stuff. */#define KS8695_END_HADDR(pEnd)	\		((pEnd)->mib2Tbl.ifPhysAddress.phyAddress)#define KS8695_END_HADDR_LEN(pEnd) \		((pEnd)->mib2Tbl.ifPhysAddress.addrLength)/* Cache and PCI-bus related macros */#define KS8695_VIRT_TO_PHYS(virtAddr)					    \		CACHE_DRV_VIRT_TO_PHYS (&pDrvCtrl->cacheDmaFuncs, (char *)(virtAddr))#define KS8695_LOCAL_TO_SYS(physAddr)					    \		LOCAL_TO_SYS_ADDR (pDrvCtrl->unit, (physAddr))#define KS8695_SYS_TO_VIRT(physAddr)                                           \        (KS8695_SYS_TO_LOCAL (((UINT32) KS8695_PHYS_TO_VIRT (physAddr))))#define KS8695_PHYS_TO_VIRT(physAddr)                                          \        CACHE_DRV_PHYS_TO_VIRT (&pDrvCtrl->cacheDmaFuncs, (char *)(physAddr))#define KS8695_SYS_TO_LOCAL(virtAddr)                                          \        SYS_TO_LOCAL_ADDR (pDrvCtrl->unit, (virtAddr))#define KS8695_CACHE_INVALIDATE(address, len)				\        CACHE_DRV_INVALIDATE (&pDrvCtrl->cacheFuncs, (address), (len))#define KS8695_CACHE_FLUSH(address, len)				    \        CACHE_DRV_FLUSH (&pDrvCtrl->cacheFuncs, (address), (len))#define KS8695_VIRT_TO_SYS(virtAddr)					    \		KS8695_LOCAL_TO_SYS(((UINT32)KS8695_VIRT_TOPHYS(virtAddr)))#define KS8695_CACHE_VIRT_TO_PHYS(address)					\		((UINT32)CACHE_DRV_VIRT_TO_PHYS(&pDrvCtrl->cacheFuncs, (address)))#define KS8695_CACHE_DMA_VIRT_TO_PHYS(address)					\		((UINT32)CACHE_DMA_VIRT_TO_PHYS(&pDrvCtrl->cacheFuncs, (address)))#define KS8695_FLAGS_ISSET(pEnd, bits)	((pEnd)->flags & (bits))/*** END MACROS ***/	/* Should be in endlib.h in my opinion */#define KS8695_M2_INUCAST(pEnd)			(pEnd)->mib2Tbl.ifInUcastPkts++#define KS8695_M2_INNUCAST(pEnd)		(pEnd)->mib2Tbl.ifInNUcastPkts++#define KS8695_M2_INERRORS(pEnd)		(pEnd)->mib2Tbl.ifInErrors++#define KS8695_M2_INDISCARDS(pEnd)		(pEnd)->mib2Tbl.ifInDiscards++#define KS8695_M2_INOCTETS(pEnd,bytes)	(pEnd)->mib2Tbl.ifInOctets += bytes#define KS8695_M2_OUTUCAST(pEnd)		(pEnd)->mib2Tbl.ifOutUcastPkts++#define KS8695_M2_OUTNUCAST(pEnd)		(pEnd)->mib2Tbl.ifOutNUcastPkts++#define KS8695_M2_OUTDISCARDS(pEnd)		pEnd)->mib2Tbl.ifOutDiscards++#define KS8695_M2_OUTERRORS(pEnd)		(pEnd)->mib2Tbl.ifOutErrors++#define KS8695_M2_OUTOCTETS(pEnd,bytes)	(pEnd)->mib2Tbl.ifOutOctets += bytes/* 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 cacheFuncs;		/* cache function pointers */    CACHE_FUNCS	cacheDmaFuncs;	/* cache descriptor */    FUNCPTR     freeRtn[128];	/* Array of free routines. */					    CL_POOL_ID	pClPoolId;		/* cluster pool */    BOOL	rxHandling;			/* rcv task is scheduled */    BOOL	txHandling;			/* rcv task is scheduled */    BOOL	linkHandling;		/* WAN link task is scheduled */	/* added KS8695/P specific member variables here */    volatile KS8695_STAT stats;	/* KS8695/P stats */	DMA_INFO	stDMAInfo;		/* DMA information */	UINT32	rev;				/* revision number */    struct ks8695_buffer *pTxMblk;    struct ks8695_buffer *pRxMblk;    INT32 nRxDesc;				/* number of Rx descriptors */    INT32 nRxDescNextAvail;		/* next available Rx descriptor */    INT32 nRxDescNextToFill;	/* next Rx desc to fill new buffer to */    RXDESC *pRxDescriptors;    volatile INT32 RxDescEmpty;	/* atomic flag for empty Rx descriptor  */	INT32	nRxDescTotal;		/* total number fo Rx descriptors */	INT32	nTxDesc;			/* number of Tx descriptors */    INT32 nTxDescNextAvail;		/* next available Tx descriptor */    INT32 nTxDescUsed;			/* used Tx descriptor */    volatile INT32 nTransmitCount;	/* number of packets to transmit */    INT32 nTxProcessedCount;	/* number of packets to transmitted */	INT32	nTxDescTotal;		/* total number fo Tx descriptors */    INT32 nTransmitCoalescing;	/* Tx packets coalescing count */    volatile INT32 nTxDescAvail;	int	offset;					/* packet offset, should be 0 or 2 */	WDOG_ID	watchdog;			/* watch dog id */	int	nWatchdogDelay;		/* watch dog delay period */} END_DEVICE, *PEND_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 ks8695MclBlkConfig = 	/* network mbuf configuration table */    {    /*    no. mBlks		no. clBlks	memArea		memSize    -----------		----------	-------		-------    */    0, 			0, 		NULL, 		0    };CL_DESC ks8695ClDescTbl [] = 	/* network cluster pool configuration table */    {    /*    clusterSize			num	memArea		memSize    -----------			----	-------		-------    */    {ETHERMTU + ENET_HEADER_SIZE + 2,	0,	NULL,		0}    };int ks8695ClDescTblNumEnt = (NELEMENTS(ks8695ClDescTbl));/* Definitions for the flags field */#define KS8695_PROMISCUOUS	0x1#define KS8695_POLLING		0x2#define KS8695_MIN_FBUF		(1536)	/* min data 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		0x00000000#define DRV_DEBUG_RX		0x00000001#define	DRV_DEBUG_TX		0x00000002#define DRV_DEBUG_INT		0x00000004#define	DRV_DEBUG_POLL		(DRV_DEBUG_POLL_RX | DRV_DEBUG_POLL_TX)#define	DRV_DEBUG_POLL_RX	0x00000008#define	DRV_DEBUG_POLL_TX	0x00000010#define	DRV_DEBUG_LOAD		0x00000020#define	DRV_DEBUG_IOCTL		0x00000040#define DRV_DEBUG_POLL_REDIR	0x00010000#define	DRV_DEBUG_LOG_NVRAM	0x00020000#define	DRV_DEBUG_LOG_PHY	0x00040000#define	DRV_DEBUG_LOG_TIMER	0x00080000#define	DRV_DEBUG_LOG_TASK	0x00100000UINT32	ks8695Debug = 0x00000000;#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6)		\	if (ks8695Debug & FLG)                              \            logMsg(X0, X1, X2, X3, X4, X5, X6);#define DRV_PRINT(FLG,X)                                \	if (ks8695Debug & 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 */LOCAL void swResetSNMPInfo(PEND_DEVICE pDrvCtrl);LOCAL void macStartRx(PEND_DEVICE pDrvCtrl, BOOLEAN bStart);LOCAL void macStartTx(PEND_DEVICE pDrvCtrl, BOOLEAN bStart);LOCAL void macEnableInterrupt(PEND_DEVICE pDrvCtrl, BOOLEAN bEnable);LOCAL void swCreateLookUpTable(PEND_DEVICE pDrvCtrl);LOCAL void swAutoNegoStart(PEND_DEVICE pDrvCtrl, UINT uPort);LOCAL void ks8695_power_saving(int bSaving);LOCAL void swAutoNegoAdvertisement(PEND_DEVICE pDrvCtrl, UINT uPort);LOCAL void swAutoNegoAdvertisement(PEND_DEVICE pDrvCtrl, UINT uPort);LOCAL void ks8695IntLink(PEND_DEVICE pDrvCtrl);LOCAL void ks8695IntLinkTask(PEND_DEVICE pDrvCtrl);LOCAL void ks8695Int(PEND_DEVICE pDrvCtrl);LOCAL void macConfigureFlow(PEND_DEVICE pDrvCtrl, uint8_t bFlowCtrl);LOCAL int  hook_irqs(PEND_DEVICE pDrvCtrl, int req);LOCAL int  AllocateTxDescriptors(PEND_DEVICE pDrvCtrl);LOCAL int  AllocateRxDescriptors(PEND_DEVICE pDrvCtrl);LOCAL void FreeTxDescriptors(PEND_DEVICE pDrvCtrl);LOCAL void FreeRxDescriptors(PEND_DEVICE pDrvCtrl);LOCAL void CleanTxRing(PEND_DEVICE pDrvCtrl);LOCAL void CleanRxRing(PEND_DEVICE pDrvCtrl);LOCAL void InitTxRing(PEND_DEVICE pDrvCtrl);LOCAL void InitRxRing(PEND_DEVICE pDrvCtrl);LOCAL M_BLK_ID getBufferBlock(PEND_DEVICE pDrvCtrl, UCHAR **pCluster, M_BLK_ID pSrcMblk);LOCAL void ReceiveBufferFill(PEND_DEVICE pDrvCtrl);LOCAL void ReceiveBufferFillEx(PEND_DEVICE pDrvCtrl);LOCAL void swDetectPhyConnection(PEND_DEVICE pDrvCtrl, UINT uPort);LOCAL void SetDefaults(PEND_DEVICE pDrvCtrl);LOCAL void printStr(char *str);

⌨️ 快捷键说明

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