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

📄 cs8900aend.c

📁 sumsung 公司arm9控制器S3c2410x的BSP.
💻 C
📖 第 1 页 / 共 4 页
字号:
/* cs8900aEnd.c - cs8900a Enhanced Network Driver (END) *//*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 cs8900a_OUT_SHORT and cs8900a_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 (*cs8900aIntConnectRtn)(int level, FUNCTPR pFunc, int arg);    IMPORT STATUS (*cs8900aIntDisconnectRtn)(int level, FUNCTPR pFunc, int arg);    IMPORT STATUS (*cs8900aIntEnableRtn) (int level);    IMPORT STATUS (*cs8900aEnetAddrGetRtn)(int unit, char *pResult);    IMPORT STATUS (*cs8900aOutShortRtn)(UINT addr, UINT value);    IMPORT STATUS (*cs8900aInShortRtn)(UINT addr, USHORT *pData);        cs8900aIntConnectRtn = intConnect; /@ must not be NULL @/    cs8900aIntDisconnectRtn = NULL;    cs8900aIntEnableRtn = NULL;    cs8900aEndAddrGetRtn = NULL;    cs8900aOutShortRtn = NULL;    cs8900aInShortRtn = NULL;.CEExcecpt for cs8900aIntConnectRtn and cs8900aIntEnableRtn, 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.  Thiscs8900a 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"#include "string.h"/* addition. */	#include "cs8900a.h"	/* Maximum number of CS8900 chips */	#define MAXUNITS    1	/* read one byte from I/O space */	#ifndef CS_IN_BYTE	#define CS_IN_BYTE(reg,pAddr) (*(pAddr) = *((volatile UCHAR*)(reg)))	#endif /*CS_IN_BYTE*/	/* read a short (16bits) from I/O */	#ifndef CS_IN_WORD	#define CS_IN_WORD(reg,pAddr) (*((volatile USHORT*)(pAddr))) = *((volatile USHORT*)(reg)))	#endif /*CS_IN_WORD*/	/* write a short to I/O space */	#ifndef CS_OUT_WORD	#define CS_OUT_WORD(reg,data) (*((volatile USHORT*)(reg)) = data)	#endif /*CS_OUT_WORD*/	/* enable interrupt level */	#ifndef CS_INT_ENABLE	#define CS_INT_ENABLE(level,pResult) (*pResult = intEnable(level))	#endif /*CS_INT_ENABLE*/	/* connect routine to intr. vector */	#ifndef CS_INT_CONNECT	#define CS_INT_CONNECT(ivec,rtn,arg,pResult) (*pResult = intConnect(ivec,rtn,arg))	#endif /*CS_INT_CONNECT*/IMPORT	int endMultiLstCnt (END_OBJ* pEnd);/* defines */#define	DRV_NAME	"cs"#define DRV_NAME_LEN	(sizeof(DRV_NAME) + 1)#define DRV_DESC	"Cirrus Logic CS8900A END driver"#define DRV_DESC_LEN	(sizeof(DRV_DESC) + 1)#define TASK_CS_INT_PRI	(54)/* Configuration items */#ifndef ETHERMTU#define ETHERMTU (1500)#endif#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/* * Default macro definitions for BSP interface. * These macros can be redefined in a wrapper file, to generate * a new module with an optimized interface. *//* 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 *//* mac address mask */typedef struct struct_mac_address{	USHORT	i_g : 1;	USHORT	u_l : 1;	USHORT	val15_2 : 14;	UINT	val47_16;}STRUCT_MAC_ADDRESS;/* 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. */	USHORT			enetAddr[3];	/* 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 */	/* chip */	USHORT		io_addr;		/* The io base of the cs8900a. */	UINT		mem_addr;		/* The mem base of the cs8900a. */	USHORT		chip_int_num;		/* The cs8900a intrX(0..3) */	USHORT		chip_dma_num;		/* The cs8900a dmaX(0..2) */	UINT		media_type;		/* The media type in software. */	BOOL		in_memory_mode;		/* The flag of mode.(io(false) or memory(true)) */	BOOL		resetting;	UINT		rx_depth;	UINT		max_rx_depth;	UINT		max_tx_depth;	UINT		loan_count;	STRUCT_MAC_ADDRESS *	p_mac_adr;}END_DEVICE;typedef struct self_pkg_buf{	char *	p_char;	int	len;}self_pkg_buf, * p_self_pkg_buf;/* * 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. *//* --------------------------------	no. mBlks	no. clBlks	memArea		memSize *//* network mbuf configuration table	---------	----------	-------		------- */M_CL_CONFIG cs8900aMclBlkConfig = {	0,		0,		NULL,		0};/* ----------------------------------------	clusterSize	num	memArea		memSize   *//* network cluster pool configuration table 	-----------	---	-------		--------- */CL_DESC cs8900aClDescTbl [] = 		{{	0,		0,	NULL,		0	}};int cs8900aClDescTblNumEnt = (NELEMENTS(cs8900aClDescTbl));/* Definitions for the flags field */#define cs8900a_PROMISCUOUS	0x1#define cs8900a_POLLING		0x2#define cs8900a_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	0x20000	int	cs8900aDebug	=	0x00;	int     cs8900aTxInts	=	0;	#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6) if(cs8900aDebug & FLG)logMsg(X0, X1, X2, X3, X4, X5, X6);	#define DRV_PRINT(FLG,X) if(cs8900aDebug & 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	cs8900aReset(END_DEVICE *pDrvCtrl);LOCAL void	cs8900aRecv(END_DEVICE * pDrvCtrl, char * pNewCluster, int len);LOCAL void	cs8900aConfig(END_DEVICE *pDrvCtrl);/* END Specific interfaces. *//* This is the only externally visible interface. */END_OBJ* 	cs8900aLoad(char* initString, void* p_v);LOCAL STATUS	cs8900aStart(END_DEVICE* pDrvCtrl);LOCAL STATUS	cs8900aStop(END_DEVICE* pDrvCtrl);LOCAL int	cs8900aIoctl(END_DEVICE* pDrvCtrl, int cmd, caddr_t data);LOCAL STATUS	cs8900aUnload(END_DEVICE* pDrvCtrl);LOCAL STATUS	cs8900aSend(END_DEVICE* pDrvCtrl, M_BLK_ID pBuf);LOCAL void	cs8900aInt(END_DEVICE* pDrvCtrl);LOCAL STATUS	cs8900aMCastAdd(END_DEVICE* pDrvCtrl, char* pAddress);LOCAL STATUS	cs8900aMCastDel(END_DEVICE* pDrvCtrl, char* pAddress);LOCAL STATUS	cs8900aMCastGet(END_DEVICE* pDrvCtrl, MULTI_TABLE* pTable);LOCAL STATUS	cs8900aPollStart(END_DEVICE* pDrvCtrl);LOCAL STATUS	cs8900aPollStop(END_DEVICE* pDrvCtrl);LOCAL STATUS	cs8900aPollSend(END_DEVICE* pDrvCtrl, M_BLK_ID pBuf);LOCAL STATUS	cs8900aPollRcv(END_DEVICE* pDrvCtrl, M_BLK_ID pBuf);LOCAL void	cs8900aAddrFilterSet(END_DEVICE *pDrvCtrl);LOCAL STATUS	cs8900aMemInit();void cs_pp_w(END_DEVICE* pDrvCtrl, USHORT offset, USHORT value);USHORT cs_pp_r(END_DEVICE* pDrvCtrl, USHORT offset);void cs_chip_generate_interrupt(END_DEVICE * pDrvCtrl);int cs_chip_get_rx_miss_num(END_DEVICE * pDrvCtrl);int cs_chip_get_tx_col_num(END_DEVICE * pDrvCtrl);STATUS cs_chip_int_disable(END_DEVICE * pDrvCtrl);STATUS cs_chip_int_enable(END_DEVICE * pDrvCtrl);STATUS cs_chip_loop_set(END_DEVICE * pDrvCtrl, int val);void cs_chip_rx_frame_drop(END_DEVICE * pDrvCtrl, int num);STATUS cs_chip_select_rx_frame_type(END_DEVICE * pDrvCtrl, USHORT type_mask, int val);STATUS cs_chip_self_reset(END_DEVICE * pDrvCtrl);STATUS cs_chip_set_full_duplex(END_DEVICE * pDrvCtrl, int val);STATUS cs_chip_set_link_dep(END_DEVICE * pDrvCtrl, int val);STATUS cs_chip_set_tx_crc(END_DEVICE * pDrvCtrl, int val);STATUS cs_chip_to_mem_mode(END_DEVICE * pDrvCtrl, int flag);STATUS cs_chip_tx_force_terminate(END_DEVICE * pDrvCtrl, int val);STATUS cs_chip_send_frame(END_DEVICE * pDrvCtrl, USHORT * p_src_buf, int length);STATUS cs_soft_end_init(END_DEVICE * pDrvCtrl);int cs8900a_pin_enable(void);int cs8900a_pin_disable(void);STATUS cs_chip_event_enable(END_DEVICE * pDrvCtrl);STATUS mask32_change_bsp(int* dist32, int num, int len, int src);/* * Declare our function table.  This is static across all device * instances. */LOCAL NET_FUNCS cs8900aFuncTable ={	(FUNCPTR) cs8900aStart,	/* Function to start the device. */	(FUNCPTR) cs8900aStop,		/* Function to stop the device. */	(FUNCPTR) cs8900aUnload,	/* Unloading function for the driver. */	(FUNCPTR) cs8900aIoctl,	/* Ioctl function for the driver. */	(FUNCPTR) cs8900aSend,		/* Send function for the driver. */	(FUNCPTR) cs8900aMCastAdd,	/* Multicast add function for the driver. */	(FUNCPTR) cs8900aMCastDel,	/* Multicast delete function for the driver. */	(FUNCPTR) cs8900aMCastGet,	/* Multicast retrieve function for the driver. */	(FUNCPTR) cs8900aPollSend,	/* Polling send function */	(FUNCPTR) cs8900aPollRcv,	/* Polling receive function */	endEtherAddressForm,		/* put address info into a NET_BUFFER */	endEtherPacketDataGet,		/* get pointer to data in NET_BUFFER */	endEtherPacketAddrGet	  	/* Get packet addresses. */};END_DEVICE *	p_end_device;int display_net_event = 0;/* * cs8900aLoad - 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* cs8900aLoad	(		char* initString,		/* String to be parsed by the driver. */		void* p_v	){	END_DEVICE *pDrvCtrl;	DRV_LOG(DRV_DEBUG_LOAD, "Loading cs8900a...\n", 1, 2, 3, 4, 5, 6);	if(initString == NULL)        {		DRV_LOG(DRV_DEBUG_LOAD, "cs8900aLoad: 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;	cs_soft_end_init(pDrvCtrl);	/*	 * initialize the END and MIB2 parts of the structure	 * The M2 element must come from m2Lib.h	 * This cs8900a is set up for a DIX type ethernet device.	 */	if(	(END_OBJ_INIT(&pDrvCtrl->end, (DEV_OBJ*)pDrvCtrl, DRV_NAME, pDrvCtrl->unit,		&cs8900aFuncTable,DRV_DESC) == ERROR)		||		(END_MIB_INIT (&pDrvCtrl->end, M2_ifType_ethernet_csmacd,		(UCHAR*)&(pDrvCtrl->enetAddr[0]), 6, ETHERMTU,END_SPEED) == ERROR))	{		goto errorExit;	}	/* Perform memory allocation/distribution */	if(cs8900aMemInit(pDrvCtrl) == ERROR) goto errorExit;	/* reset and reconfigure the device */	cs8900aReset(pDrvCtrl);	cs8900aConfig(pDrvCtrl);	/* set the flags to indicate readiness */	END_OBJ_READY(&pDrvCtrl->end, IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST);	DRV_LOG(DRV_DEBUG_LOAD, "Done loading cs8900a...", 1, 2, 3, 4, 5, 6);	p_end_device = pDrvCtrl;	pDrvCtrl->p_mac_adr = (void *)(pDrvCtrl->enetAddr);	return (&(pDrvCtrl->end));errorExit:	if(pDrvCtrl != NULL) free((char *)pDrvCtrl);	p_end_device = NULL;	return NULL;}/* * cs8900aMemInit - initialize memory for the chip * * This routine is highly specific to the device. * * Design choices available:

⌨️ 快捷键说明

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