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

📄 if_ln.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifndef lintstatic char *sccsid = "@(#)if_ln.c	4.14      (ULTRIX)  4/11/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: * * 04/11/91	Randall Brown *	Before stopping the lance on 3min, disable DMA on I/O ASIC * * 02/24/91	jsd *	Allow loopback packets if COPYALL mode is set * * 01/21/91	Randall Brown *	Moved code for cpyin4x4 and cpyout4x4 into if_ln_copy.s for *	performance improvement. * * 01/01/91	Chran-Ham Chang *	Change the code to allow the driver promisc mode to be disabled *	after enabling it. * * 12/06/90	Randall Brown *	Fixed a bug in the 4x4() routines dealing with small mbufs not on 8 *	boundarys.  The routines would return an incorrect lrbptr. * * 10/15/90	Randall Brown *	Fixed a bug in probe routine for 3min's with large memory configs. *	Changed a svtolance32 to svtophy. * * 8/31/90	Lea Gottfredsen *	Turned on cacheing for 3min, added clean_dcache calls, and added *	DMA memory read error interrupt check in lnintr * * 08/19/90	Fred L. Templin *	Fixed setting of "IFF_UP" and "IFF_RUNNING" bits. * * 7/11/90	Lea Gottfredsen * 	Added 3min support: 3max-like version and DMA version with funky *	4 word read/writes with skips in between. * * 03/26/90     Paul Grist *      Added support to lnprobe for mipsmate -- DS_5100. * * 12/19/89     Chran-Ham Chang *	Added code to fixed the panic problem when the incoming packet does  *	not turn on the start packet bit.  *  * 11/16/89     Chran-Ham Chang *      Added code to print out the station address at the system boot time. * * 11/15/89	Chran-Ham Chang *	Fixed the unaligned access problem for the 802.2 LLC transmit *      frame.  * * 11/14/89	Chran-Ham Chang *	Fixed 3MAX probing problem. * * 10/27/89	Uttam Shikarpur *	Added: *		1) Ability to report back the type of network interface. *		2) Counters to  keep track of the multicast pack., bytes sent. * * 9/22/89      Chran-Ham Chang *      Fixed collisions counters problem. Merged 3MAX version to the *      pool. * * 9/11/89      afd *      Bug fixes from testing on KMAX.  Set up to really run on 3MAX. * * 31/8/89      Chran-Ham Chang *      Added code to check the mbuf return from lnget(). In addition, *      Added code to restart the LANCE, if the STP bit not found for *      the first incoming packet. * * 8/7/89       Lea Gottfredsen *      Added 3max support. *      An interim version with 3max disguised *      as a PMAX in order to test a specially configured PMAX that *      has a 3max IO module. *      Also, changed multi unit handling in lnprobe, removed next. * * 7/17/89	Chran-Ham Chang *	Merged se DMA receiver architecture into ln driver. *      Changed ifnet name from se to ln. *	 * 6/29/89	Lea Gottfredsen *	Merged packet filter and SMP back into this new  * 	lance driver. Merge of pu and isis pools. Multi-unit support. * * 5/2/89       Lea Gottfredsen *      Added lnsw structure to provide ease of multi architecture *      implementation and readablity. *	Mipsfair support. * * The following comments are a subset of the ones found in the two * old versions of if_ln.c and if_se.c * * 6/2/89 Uttam Shikarpur *      Add support for Ethernet packet filter * * 9/21/88 U. Sinkewicz *      Added locks for SMP. * * 6/8/88       lp *      PMAX * * 04-01-88     Fred L. Templin *      Several changes from initial version. Now up and running with *      Mayfair II. * * 01-04-88     templin (Fred L. Templin) *      Created the if_ln.c module. This module is based on *      a modified version of if_se.c * *  6-May-88 - 10-Feb-8	   Fred Templin *	Several enhancements, performance improvements and bug fixes * *  15-Feb-88 fred (Fred Canter) *      Changes for VAX420 (CVAXstar/PVAX) support. * *  18-Jun-86  jsd (John Dustin) *      Created this VAXstar network controller driver. *      For Ethernet Lance chip implementation. *      Derived from if_qe.c. * * --------------------------------------------------------------------- */#include "ln.h"#if     NLN > 0 || defined(BINARY)/* * Digital LANCE Network Interface */#include "packetfilter.h"       /* NPACKETFILTER */#include "../data/if_ln_data.c"extern struct protosw *iftype_to_proto(), *iffamily_to_proto();extern struct timeval time;extern int net_output();#ifdef vaxextern struct nexus nexus[];#elsevolatile unsigned long *rdpptr;char *nexus;#endifextern int cpu;extern struct lnsw mayfairsw[], ffoxsw[], vaxstarsw[];typedef volatile unsigned char * pvoluchar;int	lndebug = 0;		/* debug flag, range 0->4 */int	lnprobe(), lnattach(), lnintr();int	lninit(), lnstart(), lnioctl(), lnwatch();struct	mbuf *lnget(), *lnget_dma();u_short lnstd[] = { 0 };struct	uba_driver lndriver =	{ lnprobe, 0, lnattach, 0, lnstd, "ln", lninfo };u_char ln_sunused_multi[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };unsigned long ln_crc_table[16];	/* crc initialization table */unsigned int ln_poly = 0xedb88320;	/* polynomial initialization */#define LRBADDR(start,off)	(((int)(start))&0x01 ? \				  (caddr_t)((int)(start)+(off*2)+ \				  (off%2)): \				  ((caddr_t)((int)(start)+(off*2)- \				  (off%2))))/* * Probe the Lance to see if it's there */lnprobe(reg,ui)	caddr_t reg;	struct uba_device *ui;   /* Only for MIPS machine */{	static int unit=0; 	/* Walk thru softc's only for VAX */		register struct ln_softc *sc;	register struct lnsw *lnsw;	/* ptr to switch struct */	register struct ln_initb *initb; /* LRB initb ptr */	int prp;	 	/* physical addr ring pointer */	int pi;			/* physical addr init block */	int i, j, oldcvec,index;	unsigned int tmp, x;	unsigned short flag;	char buf[TC_ROMNAMLEN + 1];	KM_ALLOC(sc,struct ln_softc *, sizeof(struct ln_softc),KM_DEVBUF, KM_CLEAR);	if (!sc)		return(0);			/*	 * CPU identifiers are found in cpuconf.h	 */	switch (cpu) {		case VAX_3400:			/* mayfair II */			ln_softc[unit] = sc;			sc->lnsw = lnsw = mayfairsw;			sc->rdpaddr = (struct lnreg *)(&((struct ni_regs *)reg)->ni_rdp);			sc->rapaddr = (struct lnreg *)(&((struct ni_regs *)reg)->ni_rap);			sc->ln_narom = (u_long *)(((struct ni_regs *)reg)->ni_sar);			sc->ln_lrb = (u_char *)(((struct ni_regs *)reg)->ni_nilrb);			sc->is_if.if_sysid_type = 60;			flag = (LN_IDON | LN_INIT);			break;		case DS_5400:			/* mipsfair */			unit = ui->ui_unit;			ln_softc[unit] = sc;			sc->lnsw = lnsw = ds5400sw;			sc->rdpaddr = (struct lnreg *)PHYS_TO_K1(lnsw->ln_phys_rdp);			sc->rapaddr = (struct lnreg *)PHYS_TO_K1(lnsw->ln_phys_rap);			sc->ln_narom = (u_long *)PHYS_TO_K1(lnsw->ln_phys_narom);			sc->ln_lrb = (pvoluchar)PHYS_TO_K1(lnsw->ln_phys_lrb);			sc->is_if.if_sysid_type = 94;			flag = (LN_IDON | LN_INIT);			break;		case DS_5000:			/* 3max */		case DS_5000_100:		/* 3min */			unit = ui->ui_unit;			ln_softc[unit] = sc;			sc->is_if.if_sysid_type = (cpu == DS_5000_100 ? 118 : 94);			tc_addr_to_name(reg, buf);			if (!strcmp(buf,"PMAD-AA ")) {  /* 3max like */				sc->lnsw = lnsw = ds5000sw;				sc->rdpaddr = (struct lnreg *)((u_long)reg + lnsw->ln_phys_rdp);				sc->rapaddr = (struct lnreg *)((u_long)reg + lnsw->ln_phys_rap);				sc->ln_narom = (u_long *)((u_long)reg + lnsw->ln_phys_narom);				sc->ln_lrb = (pvoluchar)((u_long)reg + lnsw->ln_phys_lrb);				flag = (LN_IDON | LN_INIT);			  } else {	/* PMAD_BA, DMA version  */				sc->lnsw = lnsw = ds3minsw;				sc->rdpaddr = (struct lnreg *)PHYS_TO_K1(lnsw->ln_phys_rdp);				sc->rapaddr = (struct lnreg *)PHYS_TO_K1(lnsw->ln_phys_rap);				sc->ln_narom = (u_long *)PHYS_TO_K1(lnsw->ln_phys_narom);				sc->ssraddr = (u_long *)PHYS_TO_K1(lnsw->ln_phys_ssr);				sc->siraddr = (u_long *)PHYS_TO_K1(lnsw->ln_phys_sir);				sc->ldpaddr = (u_long *)PHYS_TO_K1(lnsw->ln_phys_ldp);				KM_ALLOC(sc->ln_lrb,pvoluchar,LN_LRB_SIZE, KM_DEVBUF, KM_CLEAR);				if (!sc->ln_lrb) return(0);				while (svtophy(sc->ln_lrb) & 0xffff)				    sc->ln_lrb++;	/* 64K align */				/* enable IOASIC to do lance DMA */   				*(u_int *)(sc->ssraddr) |= BIT16SET;				/* next is really svtoioasic */				*(sc->ldpaddr) = (((svtophy(sc->ln_lrb)) & LDPBITS) << 3 );				flag = (LN_IDON | LN_INIT);				}			break;		case DS_3100:		/* pmax */ 	        case DS_5100:		/* mipsmate */			unit = ui->ui_unit;			ln_softc[unit] = sc;			sc->lnsw = lnsw = pmaxsw;			sc->rdpaddr = (struct lnreg *)PHYS_TO_K1(lnsw->ln_phys_rdp);			sc->rapaddr = (struct lnreg *)PHYS_TO_K1(lnsw->ln_phys_rap);			sc->ln_narom = (u_long *)PHYS_TO_K1(lnsw->ln_phys_narom);			sc->ln_lrb = (pvoluchar)PHYS_TO_K1(lnsw->ln_phys_lrb);			flag = (LN_IDON | LN_INIT);			sc->is_if.if_sysid_type = (cpu == DS_3100 ? 67 : 94);			break;		case VAX_60:			/* firefox */			ln_softc[unit] = sc;			sc->lnsw = lnsw = ffoxsw;			sc->rdpaddr = (struct lnreg *)(&((struct ni_regs *)reg)->ni_rdp);			sc->rapaddr = (struct lnreg *)(&((struct ni_regs *)reg)->ni_rap);			sc->ln_narom = (u_long *)(((struct ni_regs *)reg)->ni_sar);			sc->ln_lrb = (u_char *)(((struct ni_regs *)reg)->ni_nilrb);			flag = (LN_IDON | LN_INIT);			sc->is_if.if_sysid_type = 39;			break;#ifdef vax		case VAXSTAR:			/* vs2000 */ 		case C_VAXSTAR:			/* pvax  */ 			ln_softc[unit] = sc;			sc->lnsw = lnsw = vaxstarsw;			sc->rdpaddr = (struct lnreg *)(&(((struct nb1_regs *)qmem)->nb_ni_rdp));			sc->rapaddr = (struct lnreg *)(&(((struct nb1_regs *)qmem)->nb_ni_rap));			sc->ln_narom = (u_long *)(((struct nb_regs *)nexus)->nb_narom);			sc->ln_lrb = (u_char *)( &ln_lrb[unit][0] );				flag = (LN_IDON | LN_INIT | LN_INEA);			sc->is_if.if_sysid_type = 39;			/* system network interrupt */			((struct nb_regs *)nexus)->nb_int_msk |= LN_INT_NP ;				break;#endif vax		default: 			printf("lnprobe : cpu type %d unknown\n", cpu );			return(0);	}	unit++; 		/* for VAX architecture multiple units */   	sc->ln_rap = LN_CSR0;	sc->ln_rdp = LN_STOP;	/*	 * start lrb_offset to point to first byte of the local RAM	 * buffer. lnalloc bumps pointer as chunks of the buffer are	 * allocated.	 */	sc->lrb_offset = 0;	/*	 * Initialize some per unit counters	 */	sc->callno = 0;	lnshowmulti = 0;		lnbablcnt=0;		lnmisscnt=0;		lnmerrcnt=0;	lnrestarts=0;		/*	 * Allocate contiguous, quadword aligned (required)	 * space for both descriptor rings. "lnalloc" takes into account	 * the "alignment factor" for LRB sizing.	 */	for (i=0; i<nLNNRCV; i++) {		sc->rring[i] = lnsw->ln_alloc(sc,sizeof(struct ln_ring), (i==0?LN_QUAD_ALIGN : 0));		if (sc->rring[i] == NULL) {		printf("ln%d: lnalloc: cannot alloc memory for recv descriptor rings\n", unit-1);		return(0);		}	}	for (i=0; i<nLNNXMT; i++) {		sc->tring[i] = lnsw->ln_alloc(sc,sizeof(struct ln_ring), (i==0 ? LN_QUAD_ALIGN : 0));		if (sc->tring[i] == NULL) {		printf("ln%d: lnalloc: cannot alloc memory for xmit descriptor rings\n", unit-1);		return(0);		}	}	/*	 * Allocate local RAM buffer memory for the init block	 */	sc->initbaddr = lnsw->ln_alloc(sc, sizeof(struct ln_initb), LN_WORD_ALIGN);	if (sc->initbaddr == NULL) {		printf("ln%d: lnalloc: cannot alloc memory for init block\n", unit-1);		return(0);	}	/* 	 * Initialize multicast address array. Number of active entries	 * is driven by number of "ADDMULTI" operations. (1, initailly).	 */	for (i=0; i<nLNMULTI; i++) {		sc->muse[i] = 0;		bcopy(ln_sunused_multi,&sc->multi[i],MULTISIZE);	}	sc->nmulti = 0;	/*	 * Initialize Lance chip with init block, ln_initb	 *	  ln_mode;			mode word	  ln_sta_addr;			station address	  ln_multi_mask;		multicast address mask	  ln_rcvlist_lo, ln_rcvlist_hi;	rcv descriptor addr	  ln_rcvlen;			rcv length	  ln_xmtlist_lo, ln_xmtlist_hi;	xmt descriptor addr	  ln_xmtlen;			xmt length	 */	initb = &sc->ln_initb;	initb->ln_mode = 0;	/* normal operation (mode==0) */	/*	 * fill out station address from the narom	 */	for (i = j = 0; i < 3; i++, j += 2) {		initb->ln_sta_addr[i] = 	   	(short)((sc->ln_narom[j]>>lnsw->ln_na_align)&0xff);		initb->ln_sta_addr[i] |= 	   	(short)(((sc->ln_narom[j+1]>>lnsw->ln_na_align)&0xff)<<8);	}	/*	 * fill out multicast address mask	 */	for (i = 0; i < 4; i++) {		initb->ln_multi_mask[i] = 0x0000;	}	/*	 * initialize the multicast address CRC table,	 * using initb as a dummy variable.	 */	for (index=0; !(unit-1) && index<16; index++) {			tmp = index;			for (j=0; j<4; j++) {			    x = (tmp & 0x01);			    tmp = (tmp >> 1);	/* logical shift right 1 bit */			    if (x == 1)				tmp = (tmp ^ ln_poly);	/* XOR */			}			ln_crc_table[index] = tmp;		}		/*	 * Convert VAX Virtual to LANCE relative	 */	prp = lnsw->ln_svtolance(sc->rring[0]);	initb->ln_rcvlist_lo = (short)prp & 0xffff;	initb->ln_rcvlist_hi = 		  (char)(((int)prp >> 16) & 0xff);	initb->ln_rcvlen = RLEN; /* Also clears rcvresv */	prp = lnsw->ln_svtolance(sc->tring[0]);	initb->ln_xmtlist_lo = (short)prp & 0xffff;	initb->ln_xmtlist_hi =		  (char)(((int)prp >> 16) & 0xff);	initb->ln_xmtlen = TLEN; /* Also clears xmtresv */	lnsw->ln_cpyout(initb,sc->initbaddr,sizeof(struct ln_initb),0);	/*	 * get physical address of init block for Lance	 */	/* set-up CSR 1 */	sc->ln_rap = LN_CSR1;	pi = lnsw->ln_svtolance(sc->initbaddr);	sc->ln_rdp = (short)(pi & 0xffff);	/* set-up CSR 2 */	sc->ln_rap = LN_CSR2;	sc->ln_rdp = (short)(((int)pi>>16) & 0xff);	/* hi 8 bits */	sc->ln_rap = LN_CSR0;	/*	 * clear IDON by writing 1, and start INIT sequence	 */	sc->ln_rdp = flag ;	/* wait for init done */	j=0;	while (j++ < 100) {		if ((sc->ln_rdp & LN_IDON) != 0)			break;		DELAY(10000);	}	/* make sure got out okay */	if ((sc->ln_rdp & LN_IDON) == 0) {		if (sc->ln_rdp & LN_ERR) {			printf("ln%d: initialization error, csr = %04x\n",unit-1,(sc->ln_rdp & 0xffff));		} else {			printf("ln%d: cannot initialize Lance\n",unit-1);		}		return(0);		/* didn't interrupt */

⌨️ 快捷键说明

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