📄 if_es.c
字号:
/* if_es.c - ETHERSTAR ethernet network interface for the DLAN *//* Copyright 1984-1998 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01i,06oct98,jmp doc: cleanup.01h,19aug98,fle doc : added routine description for esattach01g,15jul97,spm removed driver initialization from ioctl support (SPR #8831)01f,19may97,spm eliminated all compiler warnings01e,15may97,spm reverted to bcopy routines for mbufs in BSD 4.401d,07apr97,spm code cleanup, corrected statistics, and upgraded to BSD 4.401c,26may93,ccc updated for 5.1.01b,03aug92,dyn modified by Dynatem to support their new version.01a,01apr91,ccc written based on other drivers (if_xx) & ESTAR documentation.*//*DESCRIPTIONThe only user callable routine is: esattach (unit, devAdrs, ivec, ilevel, memAdrs, memSize, memWidth)To enable the use of the Dynatem DLAN board the following needs to beadded to the target's config.h file:.CS/@ Device controller I/O addresses: @/ #define INCLUDE_ES #define INT_VEC_ES 0xc0 /@ interrupt vector @/ #define INT_LVL_ES 5 /@ VMEbus interrupt level @/ #define IO_ADRS_ES ((char *) 0x70008000) /@ short I/O address @/.CE LANCE defines .CS #define ES_POOL_ADRS NONE /@ malloc the pool @/ #define ES_POOL_SIZE NONE /@ pool will be default size @/ #define ES_DATA_WIDTH NONE /@ all data widths supported @/ #define ES_PADDING FALSE /@ no padding for RAP @/ #define ES_RING_BUF_SIZE 0 /@ use the default size @/ #define INCLUDE_IF_USR #define IF_USR_NAME "es" #define IF_USR_ATTACH esattach #define IF_USR_ARG1 IO_ADRS_ES #define IF_USR_ARG2 INT_VEC_ES #define IF_USR_ARG3 INT_LVL_ES #define IF_USR_ARG4 ES_POOL_ADRS #define IF_USR_ARG5 ES_POOL_SIZE #define IF_USR_ARG6 ES_DATA_WIDTH #define IF_USR_ARG7 ES_PADDING #define IF_USR_ARG8 ES_RING_BUF_SIZE.CEThe following needs to be added to sysLib.c under global definitions:.CS char esEnetAddr [6];.CESEE ALSO: ifLib*/#include "vxWorks.h"#include "stdlib.h"#include "netLib.h"#include "iv.h"#include "memLib.h"#include "ioctl.h"#include "etherLib.h"#include "logLib.h"#include "intLib.h"#include "sysLib.h"#ifndef DOC /* don't include when building documentation */#include "net/mbuf.h"#endif /* DOC */#include "net/protosw.h"#include "net/unixLib.h"#include "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_es.h"struct dlanptr { u_char *dlcr0; u_char *dlcr1; u_char *dlcr2; u_char *dlcr3; u_char *dlcr4; u_char *dlcr5; u_char *dlcr6; u_char *dlcr7; u_char *dlcr8; u_char *dlcr9; u_char *dlcr10; u_char *dlcr11; u_char *dlcr12; u_char *dlcr13; u_char *dlcr14; u_char *dlcr15;} dlan;IMPORT VOID ether_attach ();#define MAX_ES 1 /* max number of ESTAR chips on board */#define ItoKval(p,type,base) ((type)((ULONG)(p) + (ULONG)(base)))#define ItoK(p,type,base) ((p) = ItoKval(p,type,base))#define ES_RMD_GIVE_TO_ESTAR(pRmd) \ { \ pRmd->rbuf_rmd1 &= 0xff; \ pRmd->rbuf_mcnt = 0; \ pRmd->es_rmd1.es_rmd1b |= esrmd1_OWN; \ }IMPORT unsigned char esEnetAddr []; /* ethernet address to load into lance *//* globals */int esLogCount = 0;int dbg_read = 0;int dbg_output = 0;int recIndex = 0;u_short newdlan;/* locals */LOCAL int esTsize = ES_TMD_TLEN; /* deflt xmit ring size as power of 2 */LOCAL int esRsize = ES_RMD_RLEN; /* deflt recv ring size as power of 2 */LOCAL struct ls_softc *ls_softc [MAX_ES];/* forward declarations */LOCAL VOID esInt ();LOCAL VOID esHandleRecvInt ();LOCAL int esInit ();#ifdef BSD43_DRIVERLOCAL int esOutput ();#endifLOCAL int esIoctl ();LOCAL VOID esReset ();#ifdef BSD43_DRIVERLOCAL VOID esStartOutput ();#elseLOCAL VOID esStartOutput (struct ls_softc *ls);#endifLOCAL es_tmd *esGetFreeTMD ();LOCAL es_rmd *esGetFullRMD ();LOCAL VOID esRmdFree ();LOCAL VOID esConfig ();LOCAL VOID esChipReset ();LOCAL VOID esChipInit ();LOCAL STATUS esRecv ();LOCAL u_short esReadBmpr0 ();/********************************************************************************* esattach - attaches an EtherStar target** Interface exists: make available by filling in network interface* record. System will initialize the interface when it is ready* to accept packets.* The memory pool will be malloced if NONE is specified. The memWidth* determines the data port width (in bytes) of the memory pool.** BUGS:* Currently uses bzero to zero lance data structures, which ignores the* specification of memWidth and may use any size data access to write to memory.**/STATUS esattach ( int unit, /* unit number */ char *devAdrs, /* ESTAR 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 malloced */ int memWidth, /* byte-width of data (-1 == any width) */ BOOL usePadding, /* use padding when accessing RAP? */ int bufSize /* size of a buffer in the ESTAR ring */ ) { FAST struct ls_softc *ls; FAST struct ifnet *ifp; FAST unsigned int sz; /* temporary size holder */ FAST ES_DEVICE *dv; char *memPool; /* start of the ESTAR memory pool */ if (bufSize == 0) bufSize = ES_BUFSIZE; if ((int) memAdrs != NONE) /* specified memory pool */ { /* * With a specified memory pool we want to maximize * esRsize and esTsize */ sz = (memSize - (sizeof (es_rmd) + sizeof (es_tmd) + sizeof (es_ib))) / ((2 * bufSize) + sizeof (es_rmd) + sizeof (es_tmd)); sz >>= 1; /* adjust for roundoff */ for (esRsize = 0; sz != 0; esRsize++, sz >>= 1) ; esTsize = esRsize; /* esTsize = esRsize for convenience */ } /* limit ring sizes to reasonable values */ if (esRsize < 2) esRsize = 2; /* 4 buffers is reasonable min */ if (esRsize > 7) esRsize = 7; /* 128 buffers is max for chip */ /* limit ring sizes to reasonable values */ if (esTsize < 2) esTsize = 2; /* 4 buffers is reasonable min */ if (esTsize > 7) esTsize = 7; /* 128 buffers is max for chip */ /* calculate the total size of ESTAR memory pool. (basic softc structure * is just allocated from free memory pool since ESTAR never references). */ sz = ((sizeof (es_ib)) + (((1 << esRsize) + 1) * sizeof (es_rmd)) + (bufSize << esRsize) + (((1 << esTsize) + 1) * sizeof (es_tmd)) + (bufSize << esTsize)); 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 (es_ib)) | * | | * ls->ls_rring |-------------------------------------| * | | * | ((1 << esRsize) + 1)*sizeof (es_rmd)| * | | * ls->rmd_ring.r_bufs |-------------------------------------| * | | * | (bufSize << esRsize) | * | | * ls->ls_tring |-------------------------------------| * | | * | ((1 << esTsize) + 1)*sizeof (es_tmd)| * | | * ls->tmd_ring.t_bufs |-------------------------------------| * | | * | (bufSize << esTsize) | * | | * |-------------------------------------| * * HIGH MEMORY */ /* allocate basic softc structure */ ls = (struct ls_softc *)malloc (sizeof (struct ls_softc)); 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 (struct ls_softc)); /* fill in high byte of memory base (A24:A31) and data port width */ ls->memBase = (char *) ((ULONG)memPool & 0xff000000); ls->memWidth = memWidth; if ((int) memAdrs == NONE) ls->ls_flags |= LS_MEM_ALLOC_FLAG; if (usePadding == TRUE) /* Is CSR padding necessary? */ ls->ls_flags |= LS_PAD_USED_FLAG; else ls->ls_flags &= ~LS_PAD_USED_FLAG; ls->bufSize = bufSize; /* if memWidth is NONE (we can copy any byte size/boundaries) and * bufSize is big enough to hold the biggest ethernet frame * we can loan out rmds. On systems that cannot afford to have * big enough RMD's, ESTAR will use data-chaining on receive * buffers. Our current implementation of RMD loans does not work * with receive side data-chains. */ if (ls->memWidth == NONE && ls->bufSize == ES_BUFSIZE) { int ix; char *pBuf; ls->canLoanRmds = TRUE; ls->nFree = ES_NUM_RESERVES; if ((pBuf = (char *) malloc ((u_int) (ES_NUM_RESERVES * bufSize))) == NULL) { (void) free (memPool); (void) free ((char *) ls); return (ERROR); } for (ix = 0; ix < ES_NUM_RESERVES; ix++) ls->freeBufs [ix] = (char *) ((int) pBuf + (bufSize * ix)); } else ls->canLoanRmds = FALSE; /* allocate initialization block */ ls->ib = (es_ib *)memPool; sz = sizeof (es_ib); /* size of initialization block */ bzero ((char *)ls->ib, (int) sz); /* zero out entire ib */ /* allocate receive message descriptor (RMD) ring structure */ ls->ls_rpo2 = esRsize; /* remember for esConfig */ ls->ls_rsize = (1 << esRsize); /* receive msg descriptor ring size */ /* leave room to adjust low three bits */ ls->ls_rring = (es_rmd *) ((int)ls->ib + sz); /* of pointer to be 000 */ sz = ((1 << esRsize) + 1) * sizeof (es_rmd); bzero ((char *)ls->ls_rring, (int)sz); /* zero out entire RMD ring */ /* allocate receive buffer space */ ls->rmd_ring.r_bufs = (char *)((int)ls->ls_rring + sz); sz = (bufSize << esRsize); /* room for all the receive buffers */ bzero (ls->rmd_ring.r_bufs, (int)sz);/* zero out entire rbuf area */ /* allocate transmit message descriptor (TMD) ring structure */ ls->ls_tpo2 = esTsize; /* remember for esConfig */ ls->ls_tsize = (1 << esTsize); /* transmit msg descriptor ring size */ ls->ls_tring = (es_tmd *) ((int)ls->rmd_ring.r_bufs + sz); sz = ((1 << esTsize) + 1) * sizeof (es_tmd); bzero ((char *)ls->ls_tring, (int)sz); /* zero out entire TMD ring */ /* allocate transmit buffer space */ ls->tmd_ring.t_bufs = (char *)((int)ls->ls_tring + sz); sz = (bufSize << esTsize); /* room for all the transmit buffers */ bzero (ls->tmd_ring.t_bufs, (int)sz); /* zero out entire tbuf area */ ls_softc [unit] = ls; /* remember address for this unit */ /* initialize device structure */ ls->ivec = ivec; /* interrupt vector */ ls->ilevel = ilevel; /* interrupt level */ ls->devAdrs = (ES_DEVICE *)devAdrs; /* ESTAR i/o address */ /* copy the enet address into the softc */ dv = ls->devAdrs; esEnetAddr[0] = dv->ROM_IDf; esEnetAddr[1] = dv->ROM_IDe; esEnetAddr[2] = dv->ROM_IDd; esEnetAddr[3] = dv->ROM_IDc; esEnetAddr[4] = dv->ROM_IDb; esEnetAddr[5] = dv->ROM_IDa; if (esEnetAddr[3]) { newdlan = TRUE; dlan.dlcr0 = &(dv->dlcr0); dlan.dlcr1 = &(dv->dlcr1); dlan.dlcr2 = &(dv->dlcr2); dlan.dlcr3 = &(dv->dlcr3); dlan.dlcr4 = &(dv->dlcr4); dlan.dlcr5 = &(dv->dlcr5); dlan.dlcr6 = &(dv->dlcr6); dlan.dlcr7 = &(dv->dlcr7); dlan.dlcr8 = &(dv->dlcr8); dlan.dlcr9 = &(dv->dlcr9); dlan.dlcr10 = &(dv->dlcr10); dlan.dlcr11 = &(dv->dlcr11); dlan.dlcr12 = &(dv->dlcr12); dlan.dlcr13 = &(dv->dlcr13); dlan.dlcr14 = &(dv->dlcr14); dlan.dlcr15 = &(dv->dlcr15); } else { newdlan = FALSE; dlan.dlcr0 = &(dv->dlcr1); dlan.dlcr1 = &(dv->dlcr0); dlan.dlcr2 = &(dv->dlcr3); dlan.dlcr3 = &(dv->dlcr2); dlan.dlcr4 = &(dv->dlcr5); dlan.dlcr5 = &(dv->dlcr4); dlan.dlcr6 = &(dv->dlcr7); dlan.dlcr7 = &(dv->dlcr6); dlan.dlcr8 = &(dv->dlcr9); dlan.dlcr9 = &(dv->dlcr8); dlan.dlcr10 = &(dv->dlcr11); dlan.dlcr11 = &(dv->dlcr10); dlan.dlcr12 = &(dv->dlcr13); dlan.dlcr13 = &(dv->dlcr12); dlan.dlcr14 = &(dv->dlcr15); dlan.dlcr15 = &(dv->dlcr14); } bcopy ((char *) esEnetAddr, (char *)ls->ls_enaddr, sizeof (ls->ls_enaddr)); ifp = &ls->ls_if; /* attach and enable the ESTAR interrupt service routine to vector */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -