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

📄 if_lnsgi.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* if_lnsgi.c - AMD Am7990 LANCE Ethernet (for SGI) network interface driver *//* Copyright 1984-1997 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01k,15jul97,spm  removed driver initialization from ioctl support (SPR #8831);                 added ARP request to SIOCSIFADDR ioctl handler01j,08apr97,spm  removed compiler warnings, and errors from changes in if_ln.h01i,07apr97,spm  code cleanup, corrected statistics, and upgraded to BSD 4.401h,11aug93,jmm  Changed ioctl.h and socket.h to sys/ioctl.h and sys/socket.h01g,22feb93,jdi  documentation cleanup.01f,09sep92,gae  documentation tweaks.01e,29jul92,rfs  Moved driver specific items here from the header file.01d,22jul92,gae  fixed number of parameters to logMsg().01c,23jun92,ajm  upgraded to 5.1, ansiized.01b,28apr92,ajm  changed lnEnetAddr to lnsgiEnetAddr for board specific driver01a,30mar92,ajm  modified if_ln.c 01x for SGI VIP10, becomes target specific*//*DESCRIPTIONThis module implements theAdvanced Micro Devices Am7990 LANCE Ethernet network interface driver for theSilicon Graphics VIP10 board.  The only user-callable routine is lnsgiattach(),which publishes the `lnsgi' interface and initializes the driver and device.This driver is a special variant of if_ln, designed for the Silicon Graphics (SGI) VIP10 board.BOARD LAYOUTThis device is on-board.  No jumpering diagram is necessary.SEE ALSO: ifLib*/#include "vxWorks.h"#include "iv.h"#include "memLib.h"#include "cacheLib.h"#include "sys/ioctl.h"#include "intLib.h"#include "logLib.h"#include "netLib.h"#include "taskLib.h"#include "etherLib.h"#include "net/mbuf.h"#include "net/protosw.h"#include "net/unixLib.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 "drv/netif/if_ln.h"/***** LOCAL DEFINITIONS *****/#define RMD_SIZ		sizeof(ln_rmd)#define TMD_SIZ		sizeof(ln_tmd)/* Configuration items */#define LN_MIN_FIRST_DATA_CHAIN	96	/* min size of 1st buf in data-chain */#define LN_MAX_MDS		128	/* max number of [r|t]md's for LANCE */#define	LN_BUFSIZE	(ETHERMTU + sizeof (struct ether_header) + 6)#define LN_RMD_RLEN	5	/* ring size as a power of 2 -- 32 RMD's */#define LN_TMD_TLEN	5	/* same for transmit ring    -- 32 TMD's */#define LN_NUM_RESERVES	8	/* have up to 8 reserved RMD's for loans */#define MAX_LN		1	/* max number of LANCE chips on board *//* * If LN_KICKSTART_TX is TRUE the transmitter is kick-started to force a * read of the transmit descriptors, otherwise the internal polling (1.6msec) * will initiate a read of the descriptors.  This should be FALSE is there * is any chance of memory latency or chip accesses detaining the LANCE DMA, * which results in a transmitter UFLO error.  This can be changed with the * global lnKickStartTx below. */#define LN_KICKSTART_TX	FALSE	/* TRUE:  kick-start transmitter,				   FALSE: wait for internal poll *//* The definition of the driver control structure */typedef struct ls_softc    {    struct arpcom  ls_ac;		/* ethernet common part */    ln_ib	  *ib;				/* ptr to Initialization Block */    struct		{        int	r_po2;			/* RMD ring size as a power of 2! */		int	r_size;			/* RMD ring size (power of 2!) */		int	r_index;		/* index into RMD ring */		ln_rmd	*r_ring;		/* RMD ring */		char	*r_bufs;		/* receive buffers base */        } rmd_ring;    struct		{        int	t_po2;			/* TMD ring size as a power of 2! */		int	t_size;			/* TMD ring size (power of 2!) */		int	t_index;		/* index into TMD ring */		int	d_index;		/* index into TMD ring */		ln_tmd	*t_ring;		/* TMD ring */		char	*t_bufs;		/* transmit buffers base */        } tmd_ring;    u_char	ls_flags;		/* misc control flags */    int		ivec;			/* interrupt vector */    int		ilevel;			/* interrupt level */    LN_DEVICE	*devAdrs;		/* device structure address */    char	*memBase;		/* LANCE memory pool base */    int	  	memWidth;		/* width of data port */    int		csr0Errs;		/* count of csr0 errors */    int		bufSize;		/* size of buffer in the LANCE ring */    BOOL	canLoanRmds;		/* can we loan out rmd's as clusters? */    char	*freeBufs[LN_NUM_RESERVES];	/* available reserve buffers */    int		nFree;			/* number of free reserve buffers */    u_char	loanRefCnt[LN_MAX_MDS];	/* reference counts for loaned RMD's */    } DRV_CTRL;#define DRV_CTRL_SIZ	sizeof(DRV_CTRL)/* 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_START_OUTPUT_FLAG	0x10/* Shorthand structure references */#define	ls_if		ls_ac.ac_if		/* network-visible interface */#define	ls_enaddr 	ls_ac.ac_enaddr		/* hardware ethernet address */#define	ls_rpo2		rmd_ring.r_po2#define	ls_rsize	rmd_ring.r_size#define	ls_rindex	rmd_ring.r_index#define	ls_rring	rmd_ring.r_ring#define	ls_tpo2		tmd_ring.t_po2#define	ls_tsize	tmd_ring.t_size#define	ls_tindex	tmd_ring.t_index#define	ls_dindex	tmd_ring.d_index#define	ls_tring	tmd_ring.t_ring#define LN_RMD_GIVE_TO_LANCE(pRmd) 					\    { 									\    pRmd->lnRMD1 &= 0xff; 						\    pRmd->rbuf_mcnt = 0; 						\    pRmd->lnRMD1 |= lnrmd1_OWN;      					\    }/** The following macros let the MIPS architecture allocate and free dymanic* memory from uncached space.  The calls calloc, and cfree do the same* as malloc, and free, they are merely there to aviod macro recursion.*/#define malloc(x)       	K0_TO_K1(calloc((size_t) (x),\					 (size_t) sizeof(char)))#define free(x)         	cfree((void *) (K1_TO_K0((x))))#define	cacheClearEntry(x,y)#define EMAP_ADDR       0xbf920802              /* memory map memory */LOCAL volatile u_short *pEmap = (volatile u_short *) EMAP_ADDR;/* buffer address to emap translation */#define	EMAP_PG_SZ		(4096)#define EMAP_OFFSET(index)      ((index) << 1)#define EMAP_VALUE(buffaddr)    ((u_int)(buffaddr) >> 12)/* lance address to physical translation */#define EMAP_PG(addr)      	(((addr) >> 12) & 0xff)#define EMAP_ENTRY(addr)   	(pEmap[(EMAP_PG(addr))])#define EADDR(addr)        	(((EMAP_ENTRY(addr)) << 12) | \				 ((u_int)(addr) & 0xfff))#define LNADDR(index,addr)	(((index) << 12) | ((u_int)(addr) & 0xfff))/* emap indexes */#define EMAPLEN         256#define IBUF_SZ         2#define RBUF_SZ         64#define TBUF_SZ         64#define RBUF_INDEX      0                       /* location of init block */#define TBUF_INDEX      (RBUF_INDEX + RBUF_SZ)  /* location of rec mbufs */#define IBUF_INDEX      (TBUF_INDEX + TBUF_SZ)  /* location of xmit mbufs *//* imports */IMPORT void sysWbFlush ();IMPORT void sysLanIntEnable (int ilevel);IMPORT unsigned char lnsgiEnetAddr []; /* ethernet address to load into LANCE *//* globals */int lnsgiLogCount = 0;/* locals */LOCAL int lnTsize = LN_TMD_TLEN;	/* deflt xmit ring size as power of 2 */LOCAL int lnRsize = LN_RMD_RLEN;	/* deflt recv ring size as power of 2 */LOCAL struct ls_softc  *ls_softc [MAX_LN];LOCAL u_int RAPOffset = 128;	/* XXX initially 1, calculated in lnReset */LOCAL u_int CSROffset = 0;	/* XXX initially 0, calculated in lnReset *//* forward declarations */static int        lnInit (int unit);static int        lnIoctl (struct ifnet *ifp, int cmd, caddr_t data);#ifdef BSD43_DRIVERstatic int        lnOutput (struct ifnet *ifp, struct mbuf *m0,                             struct sockaddr *dst);#endifstatic void       lnReset(int unit);static ln_rmd    *lnGetFullRMD (struct ls_softc  *ls);static ln_tmd    *lnGetFreeTMD (struct ls_softc  *ls);static STATUS     lnRecv (struct ls_softc *ls, ln_rmd *rmd);static void       lnChipInit (struct ls_softc  *ls);static void       lnChipReset (struct ls_softc *ls);static void       lnConfig (struct ls_softc *ls);static void       lnHandleCsr0Err (struct ls_softc *ls, u_short status);static void       lnHandleRecvInt (struct ls_softc *ls);static void       lnInt (struct ls_softc  *ls);static void       lnRmdFree (struct ls_softc *ls, char *pBuf);#ifdef BSD43_DRIVERstatic void       lnStartOutput (int unit);#elsestatic void       lnStartOutput (DRV_CTRL *ls);#endifstatic void       lnCsrWrite (struct ls_softc *ls, int reg, u_short value);static u_short    lnCsrRead (struct ls_softc *ls, int reg);static void       lnCsrIntWrite (struct ls_softc *ls, int reg, u_short value);static u_short    lnCsrIntRead (struct ls_softc *ls, int reg);/********************************************************************************* lnsgiattach - publish the `lnsgi' network interface and initialize the driver and device** This routine attaches an `lnsgi' Ethernet interface to the network if the* interface exists.  It makes the interface available by filling in* the network interface record.  The system will initialize the interface* when it is ready to accept packets.** The <memAdrs> parameter specifies the location of the interface memory pool;* if NONE, the memory pool will be malloc'ed.** The <memWidth> parameter sets the memory pool's data port width (in bytes);* if NONE, any data width will be used.** BUGS* To zero out LANCE data structures, this routine uses bzero(), which* ignores the <memWidth> specification and uses any size data access to* write to memory.** RETURNS: OK or ERROR.*/STATUS lnsgiattach    (    int	      unit,		/* unit number */    char     *devAdrs,		/* LANCE i/o address */    int	      ivec,		/* interrupt vector */    int	      ilevel,		/* interrupt level */    char     *memAdrs,		/* address of memory pool (-1 = malloc it) */    ULONG     memSize,		/* only used if memory pool is NOT malloc()'d */    int	      memWidth,		/* byte-width of data (-1 = any width)     */    BOOL      usePadding,       /* use padding when accessing RAP? */    int	      bufSize 		/* size of a buffer in the LANCE ring */    )    {    FAST DRV_CTRL * 	ls;    FAST struct ifnet	  *ifp;    FAST unsigned int	   sz;		/* temporary size holder */    char 		  *memPool;	/* start of the LANCE memory pool */    if (bufSize == 0)        bufSize = LN_BUFSIZE;    if ((int) memAdrs != NONE)	/* specified memory pool */	{	/*	 * With a specified memory pool we want to maximize	 * lnRsize and lnTsize	 */	sz = (memSize - (sizeof (ln_rmd) + sizeof (ln_tmd) + sizeof (ln_ib)))	       / ((2 * bufSize) + sizeof (ln_rmd) + sizeof (ln_tmd));	sz >>= 1;		/* adjust for roundoff */	for (lnRsize = 0; sz != 0; lnRsize++, sz >>= 1)	    ;	lnTsize = lnRsize;	/* lnTsize = lnRsize for convenience */	}    /* limit ring sizes to reasonable values */    if (lnRsize < 2)        lnRsize = 2;		/* 4 buffers is reasonable min */    if (lnRsize > 7)        lnRsize = 7;		/* 128 buffers is max for chip */    /* limit ring sizes to reasonable values */    if (lnTsize < 2)        lnTsize = 2;		/* 4 buffers is reasonable min */    if (lnTsize > 7)        lnTsize = 7;		/* 128 buffers is max for chip */    /* calculate the total size of LANCE memory pool.  (basic softc structure     * is just allocated from free memory pool since LANCE never references).     */    sz = ((sizeof (ln_ib))        + (((1 << lnRsize) + 1) * sizeof (ln_rmd)) +	  (bufSize << lnRsize) + (((1 << lnTsize) + 1) * sizeof (ln_tmd)) +	  (bufSize << lnTsize));    sz = sz + 6;			/* allow for alignment adjustment */    if ((int) memAdrs == NONE)	/* if -1 then allocate memPool from free pool */	{	memPool = (char *) malloc (sz);	/* allocate memory */	if ((int)memPool == NULL)	    return (ERROR);		/* bail out if we don't get memory */	}    else	{	if (memSize < sz)	    return (ERROR);	/* bail out if memSize specified is too small */	memPool = memAdrs;	/* set the beginning of pool */	}    /*                        memPool partitioning     *                        --------------------     *     *                                                 LOW MEMORY     *     *   		memPool,ls->ib	|-------------------------------------|     *					|				      |     *					|         (sizeof (ln_ib))	      |     *					|				      |     *   		  ls->ls_rring  |-------------------------------------|     *					|				      |     * 					| ((1 << lnRsize) + 1)*sizeof (ln_rmd)|     *					|				      |     *   	   ls->rmd_ring.r_bufs	|-------------------------------------|     *					|				      |     * 					|       (bufSize << lnRsize)          |     *					|				      |     *  		  ls->ls_tring	|-------------------------------------|     *					|				      |     *					| ((1 << lnTsize) + 1)*sizeof (ln_tmd)|     *					|				      |     *   	   ls->tmd_ring.t_bufs	|-------------------------------------|     *					|				      |     * 					|       (bufSize << lnTsize)          |     *					|				      |     *  			        |-------------------------------------|     *     *                                                HIGH MEMORY     */    /* allocate basic softc structure */    ls = (DRV_CTRL *)malloc (sizeof (DRV_CTRL));    if (ls == NULL)	{	if ((int) memAdrs == NONE)	/* if we malloced memPool */	    (void) free (memPool);	/* free the memPool */	return (ERROR);	}    /* zero out entire softc structure */    bzero ( (char *)ls, sizeof (DRV_CTRL));    /* fill in high byte of memory base (A24:A31) and data port width */    ls->memBase  = (char *)((ULONG)memPool & 0xff000000);    ls->memWidth = memWidth;

⌨️ 快捷键说明

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