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

📄 if_ne.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifndef lintstatic char *sccsid = "@(#)if_ne.c	4.7	(ULTRIX)  2/26/91";#endif lint/************************************************************************ *									* *			Copyright (c) 1984-1989 by			* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University	of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//*----------------------------------------------------------------------- * Modification History: * * 24-Feb-91 jsd *	Allow loopback packets if COPYALL mode is set * * 9-Aug-90 chc (Chran-Ham Chang) *	Fixed the SIOCRPHYSADDR ioctl problem. * * 25-Sep-89 chc (Chran-Ham Chang)  * 	Created this Second Generation Ethernet Controller (SGEC) *	network driver for mipsfairII   * * 08-Mar-90 chc *      reworked on the neinit routine *      fixed the mbuf free problem  * * --------------------------------------------------------------------*//* * Digital SGEC Network Interface */#include "ne.h"#include "packetfilter.h"       /* NPACKETFILTER */#include "../data/if_ne_data.c"extern struct protosw *iftype_to_proto(), *iffamily_to_proto();extern int net_output();extern struct timeval time;int	neprobe(), neattach(), neintr(),nereset();int	neinit(),nestart(),neioctl(),newatch();extern int cpu;u_short nestd[] = { 0 };struct	uba_driver nedriver =	{ neprobe, 0, neattach, 0, nestd, "ne", neinfo };u_char ne_unused_multi[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };u_char ne_multi[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 };#ifdef vax#define svtopte(x) (unsigned long)(&Sysmap[btop((int)x&~VA_SYS)])#define ptetosv(x) (unsigned long)((unsigned)ptob((struct pte *)(x)-&Sysmap[0])|VA_SYS)#define vaddr(y) (char *)(ptetosv((y)->pt_addr)+(y)->offset)#endifint	nedebug = 0;#define NEMCLGET(m) { \	register struct mbuf *p ; \	MGET((m), M_DONTWAIT, MT_DATA); \	if ((m)) { \		MCLGET((m), p); \ 		m->m_len = CLBYTES; \		if (p == 0) { \			m_freem((m)); \		       (m) = (struct mbuf *)NULL; \		 } \	  } \}#define NEALIGN(start,align)	(((int)start&align) ? \				  (caddr_t)((((int)start)&(~align))+ \				  align+1): \				  (caddr_t)(start))/* * Probe the SGEC to see if it's there */neprobe(reg,ui)	caddr_t reg;	struct uba_device *ui;{	int unit = ui->ui_unit;        register struct ne_softc *sc = &ne_softc[unit];	register struct nesw *nesw;     /* ptr to switch struct */	int i,j;	caddr_t ringaddr,mp; 	struct mbuf **mbp;	/* 	 * CPU identifiers 	 */	 switch (cpu) {		case DS_5500:		/* mipsfair 2 */			sc->nesw = nesw = ds5500sw;			sc->ne_narom = (u_char *)PHYS_TO_K1(nesw->ne_phys_narom);			sc->ne_csrs = (NECSRS *)PHYS_TO_K1(nesw->ne_phys_csr);			sc->ne_initcsr = (u_long)( nesw->ne_ipl | nesw->ne_vec | nesw->ne_mode | 0x1fff0003 );			sc->ne_cmdcsr = nesw->ne_burst << NE_BURST_SHIFT | nesw->ne_sigle | NE_CSR6_DC ; 			sc->ntring = nesw->ntdesc;			sc->nrring = nesw->nrdesc;			sc->is_if.if_sysid_type = 111; 			break;		default:			printf("neprobe : cpu type %d unknown",cpu);			return(0);	}	/*	 * reset the SGEC and check the self test result	 */	if(!nesoftreset(sc,unit))		return(0);  /* self test fail */		/* 	 * Initial the CSR0	 */	if(!nesetcsr0(sc,unit))		return(0);  /* csr0 write error */	/*	 * Load the System Base Register for VAX arch.         */#ifdef vax	csrpt->csr7 = (u_long) mfpr(SBR);#endif	/*	 * Allocate contigous, octaword aligned (performance purpose)	 * space for both descriptor rings   	 */	 KM_ALLOC(ringaddr, caddr_t, sizeof(NEDESC) * (sc->ntring +	 sc->nrring + 3), KM_DEVBUF,KM_NOW_CL_CO_CA);	if(ringaddr == 0 ) {		printf(" ne %d: couldn't allocate memory for  descriptor ring\n",unit);		return(0);	}	/* make the OCTAWORD alignment to increase performance */	sc->tring = (NEDESC *)NEALIGN(ringaddr,NE_OCTAWORD); 	sc->tring = (NEDESC *)PHYS_TO_K1(svtophy(sc->tring));	/* chain back the ring */	sc->tring[sc->ntring].ne_bfaddr = svtophy(sc->tring);	sc->tring[sc->ntring].ne_info = NE_CA; 	sc->tring[sc->ntring].ne_own = NE_OWN;	sc->rring = sc->tring + sc->ntring + 1;	sc->rring = (NEDESC *)PHYS_TO_K1(svtophy(sc->rring));	/* chain back the ring */	sc->rring[sc->nrring].ne_bfaddr = svtophy(sc->rring);	sc->rring[sc->nrring].ne_info = NE_CA; 	sc->rring[sc->nrring].ne_own = NE_OWN;					/* 	 * Allocate mbuf pointer for transmit and receive buffer	 *	 *	tmbuf : mbuf pointer which points the transmit	 *		data buffer 	 *	smbuf : mbuf chained point which is passed by	 *		higher network layer	 *	rmbuf : mbuf pointer which points the receive buffer	 */	KM_ALLOC(sc->tmbuf, struct mbuf ** , sizeof(struct mbuf *) * (sc->ntring * 2 + sc->nrring), KM_DEVBUF, KM_NOW_CL_CO_CA);	if(sc->tmbuf == 0 ) {		printf(" ne %d: couldn't allocate memory for buffer pointer\n",unit);		KM_FREE(ringaddr,KM_DEVBUF);		return(0);	}	/* clean the mbuf pointer */	bzero(sc->tmbuf,((sizeof(struct mbuf *) * (sc->ntring *2 + sc->nrring))));	sc->smbuf = sc->tmbuf + sc->ntring ;	sc->rmbuf = sc->smbuf + sc->ntring ;	/* setup buffer must be word aligned */	KM_ALLOC(mp,caddr_t ,SETUPSIZE+1, KM_DEVBUF,KM_NOW_CL_CO_CA);   	if(mp == 0) {		printf(" ne%d: couldn't allocate setup buffer \n",unit);		KM_FREE(ringaddr,KM_DEVBUF);		KM_FREE(sc->tmbuf,KM_DEVBUF);		return(0);	}	sc->ne_setup = (struct ne_setup *)NEALIGN(mp,NE_WORD); 	/*	 * initialize multicast address table 	 */	for (i=0; i<NMULTI; i++) {		sc->muse[i] = 0;		bcopy(ne_multi, &sc->multi[i],MULTISIZE);	}	/* 	 * fill out the station address from narom	 */	 for ( i = j = 0; i < 6 ; i++, j +=4 ) {		sc->ne_setup[0].setup_char[i]=sc->is_addr[i]=sc->ne_narom[j];	}	return(sizeof(struct ne_softc));}/* * Interface exeists: make available by filling in network interface * record.  System will initialize the interface when it is ready * to accept packets. */neattach(ui)	struct	uba_device *ui;{	register struct ne_softc *sc = &ne_softc[ui->ui_unit];	register struct ifnet *ifp = &sc->is_if;	register int i;        register struct sockaddr_in *sin;	register NECSRS *csrpt = sc->ne_csrs;	int delay;	ifp->if_unit = ui->ui_unit;	ifp->if_name = "ne";	ifp->if_mtu = ETHERMTU;	ifp->if_type = IFT_ETHER;	ifp->if_flags |= IFF_BROADCAST | IFF_DYNPROTO | IFF_NOTRAILERS;	((struct arpcom *)ifp)->ac_ipaddr.s_addr = 0;        sin = (struct sockaddr_in *)&ifp->if_addr;	sin->sin_family = AF_INET;	ifp->if_init = neinit;	ifp->if_output = net_output;	ifp->if_start = nestart;	ifp->if_ioctl = neioctl;	ifp->if_timer = 0;	ifp->if_watchdog = newatch;	ifp->if_reset = nereset;	/*	 * Get the SGEC version	 */	sc->ne_rev = csrpt->csr10; 	for (delay = 100000; delay && !(csrpt->csr5 & NE_CSR5_DN); delay--);	if(!delay)		{		printf("ne%d: timeout accessing virtual CSR10 \n",ui->ui_unit);/* XXX */		sc->ne_rev = 3;		}	sc->ne_rev = csrpt->csr10 >> NE_RE_SHIFT ; 	bcopy("DEC SGEC Ethernet Interface", ifp->if_version, 27); 	     ifp->if_version[28] = '\0';  	printf("ne%d: %s, V%d  hardware address: %s \n", ui->ui_unit,           ifp->if_version,sc->ne_rev,ether_sprintf(sc->is_addr)); #if NPACKETFILTER > 0	attachpfilter(&(sc->is_ed));#endif NPACKETFILTER > 0 	if_attach(ifp);}/*  * Initialization of interface, allocate the mbuf for reveive ring, * fill up the setup frame and start the interface   */neinit(unit)	int	unit;{	register struct ne_softc *sc = &ne_softc[unit];	register struct ifnet *ifp = &sc->is_if;	register NEDESC *rp;	register struct mbuf *m;		register s;	NECSRS *csrpt = sc->ne_csrs;	int i,status,delay;	/* address not known */	if (ifp->if_addrlist == (struct ifaddr *)0)		return;	if (ifp->if_flags & IFF_RUNNING)		return;	s = splimp();	if ( ifp->if_flags & IFF_PROMISC ) {		sc->ne_cmdcsr |= NE_AF_PRO ;		csrpt->csr6 &= ~(NE_CSR6_SR | NE_CSR6_ST);	}	else {		sc->ne_cmdcsr &= ~NE_AF_PRO ;       		/* prepare the setup frame */		nesetup( sc , NE_SETUP_IC);	        sc->tring[0].ne_bfaddr = svtophy(sc->ne_setup);        	sc->tring[0].ne_bsize = SETUPSIZE ;        	sc->tring[0].ne_info = NE_DT_TSET | NE_SETUP_IC;        	sc->tring[0].ne_own = NE_OWN;		/* startup the setup packet and wait for interrupt */		csrpt->csr4 = svtophy(sc->tring);		csrpt->csr6 = sc->ne_cmdcsr | NE_CSR6_ST | NE_CSR6_IE ;		csrpt->csr1 = NE_CSR1_PD;		wbflush();			for (delay = 100; delay > 0 && !(csrpt->csr5 & NE_CSR5_TI); delay--)			DELAY(10000);  				if(!delay) {   			printf("ne%d : setup frame transmit timeout \n",unit);				status = EIO;			splx(s);			return (status);			}		else {			if (sc->tring[0].ne_flag & NE_SETUP_SE) {				printf("ne%d : setup frame error \n",unit);				status = EIO;				splx(s);				return (status);			}			sc->setupqueued = 0;		}		/* clear the csr5 */		csrpt->csr5 = csrpt->csr5;		 		wbflush();	}	/* set up the receive buffer */	for ( i=0,rp=sc->rring ; i < sc->nrring; i++,rp++) {		if(!(sc->rmbuf[i])) {			NEMCLGET(m);			} else {			m = sc->rmbuf[i];		}		if(m) {			neinitdesc(rp,m,1);			rp->ne_own = NE_OWN;			sc->rmbuf[i]=m;		} else {			printf("ne%d: couldn't allocate receive buffer\n",unit);			status = EIO;			splx(s);			return (status);			}	}	/* set up the transmit buffer */	for ( i=0,rp=sc->tring ; i < sc->ntring; i++,rp++) {		if(!(sc->tmbuf[i])) {			NEMCLGET(m);		} else {			m = sc->tmbuf[i];		}		if(m) {			neinitdesc(rp,m,0);			sc->tmbuf[i]=m;		} else {			printf("ne%d: couldn't allocate transmit buffer\n",unit);			status = EIO;			splx(s);			return (status);		}	}	sc->nxmit = sc->tindex = sc->otindex = sc->rindex = 0;	/* fill out the descriptor address list */	csrpt->csr3 = svtophy(sc->rring);	csrpt->csr4 = svtophy(sc->tring);	if ( ifp->if_flags & IFF_ALLMULTI )		sc->ne_cmdcsr |= NE_AF_MUL ;	if ((ifp->if_flags & IFF_LOOPBACK)) 			/* if this is a internal loop back */		csrpt->csr6 = sc->ne_cmdcsr | NE_CSR6_SR | NE_CSR6_ST				| NE_CSR6_IE | NE_OM6_EXL ;	else		csrpt->csr6 = sc->ne_cmdcsr | NE_CSR6_SR | NE_CSR6_ST				| NE_CSR6_IE | NE_OM6_NOR ;	/*	 * mark the interface up; place the setup frame in the xmit list	 */	ifp->if_flags |= IFF_UP | IFF_RUNNING;	ifp->if_flags &= ~IFF_OACTIVE;	nestart( unit );	sc->ztime = time.tv_sec;	splx(s);}	/*  * Start output on the interface  */nestart(unit)	int	unit;{	register struct ne_softc *sc = &ne_softc[unit];	register NEDESC *rp;	register int index;	struct mbuf *m,*m0;	int bufaddr,tlen,s;	int nNENXMT=sc->ntring;	NECSRS *csrpt = sc->ne_csrs;	for ( index = sc->tindex; sc->tring[index].ne_own == 0 &&		sc->nxmit < ( nNENXMT - 1 ) ; sc->tindex = index =		++index % nNENXMT ){		rp = &sc->tring[index];		if(sc->setupqueued){			rp->ne_bfaddr = svtophy(sc->ne_setup);			tlen = SETUPSIZE;  			rp->ne_info = NE_DT_TSET;			sc->setupqueued = 0;			if(sc->ne_setup_ic) {				rp->ne_info |= NE_SETUP_IC ;				sc->ne_setup_ic = 0;			}		} else { 			IF_DEQUEUE(&sc->is_if.if_snd, m);			if(m == 0) {

⌨️ 快捷键说明

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