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

📄 if_qe.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifndef lintstatic char *sccsid = "@(#)if_qe.c	4.5	(ULTRIX)	2/26/91";#endif lint/************************************************************************ *									* *			Copyright (c) 1985-89 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 * * 16-Nov-89 - chc *      Added code to print out the station address at the system boot time. * * 14-Nov-89 - chc *	Fixed the unaligned access problem for the 802.2 LLC transmit *	frame. * * 27-Oct-89 - Uttam Shikarpur *	Added: *		1) Ability to report back the type of network interface *		   we are running on. *		2) Counters to  keep track of the multicast pack., bytes sent. * * 20-OCT-89 - chc *	Added code to fixed the mapping register release problem *	Changed the mapping register information mask ( form 21 to *	22 )  * * 31-Aug-89 - chc *      Added code to restart the qe under the non-existant memory *      condition *      Modified the code in order to support MIPS processor * * 3-May-89 Uttam Shikarpur *      Add support for Ethernet packet filter *      Moved common read code to ../net/ether_read.c * * 06-Mar-89 - Lea Gottfredsen * 	Correct decnet counters not to include sizeof ethernet header * * 05-Dec-88 - robin *	Changed the code that used the output of qballoc because the *	format of the way map registers is coded in the return value *	changed. * * 29-Jun-88 - Fred L. Templin *	Added code to the qeoutput() routine to prevent qeoutput from *	running if the interface has not yet been marked as "IFF_UP" *	and "IFF_RUNNING". * * 15-Jan-88 - lp *	Reworked how softc gets allocated. Also fixed driver to use new *	larger mbufs. * * 26-Feb-87  -- jsd *	Check return of iftype_to_proto so that we don't jump to 0. *	Also, restored Ed Ferris DECnet fix from 04-Jan-87 that got zapped * * 06-Jan-87  -- robin *	changed the way transmit and receive rings are mapped.  The *	old method used a loop and called the allocation routine in each *	iteration, this wasted a map register (fire wall) on each call. *	the new way makes one allocation call and the divides the mapped *	area up, this saves the wasted fire walls (except one). * * 04-Jan-87 -- ejf *	Fix to DECnet receive bytes/packets counters. * * 02-Sept-86 -- ejf *	Fixed problem where qe driver was not properly handling packets *	with an odd number of bytes less than the minimum packet size. *	Also, added code in interrupt routine to validate transmit list *	if it became invalid while there were still outstanding transmit *	buffers. * * 13-Jun-86   -- jaw 	fix to uba reset and drivers. * * 19-May-86 -- Chase *	Added code to free up mbufs left in the transmit ring after a *	lockup.  Failure to do this may cause systems under a heavy *	network load to run out of mbufs. * * 06-May-86  -- larry *	increase QETIMO to 1 second which implies 3 seconds till a qerestart. *	clear RESET bit in qeprobe and qerestart so the LQA will work. * * 15-Apr-86  -- afd *	Rename "unused_multi" to "qunused_multi" for extending Generic *	kernel to MicroVAXen. * * 18-mar-86  -- jaw     br/cvec changed to NOT use registers. * * 12 March 86 -- Jeff Chase *	Modified to handle the new MCLGET macro *	Changed if_qe_data.c to use more receive buffers *	Added a flag to poke with adb to log qe_restarts on console * * 19 Oct 85 -- rjl *	Changed the watch dog timer from 30 seconds to 3.  VMS is using * 	less than 1 second in their's. Also turned the printf into an *	mprintf. * *  09/16/85 -- Larry Cohen * 		Add 43bsd alpha tape changes for subnet routing		 * *  1 Aug 85 -- rjl *	Panic on a non-existent memory interrupt and the case where a packet *	was chained.  The first should never happen because non-existant  *	memory interrupts cause a bus reset. The second should never happen *	because we hang 2k input buffers on the device. * *  1 Aug 85 -- rich *      Fixed the broadcast loopback code to handle Clusters without *      wedging the system. * *  27 Feb. 85 -- ejf *	Return default hardware address on ioctl request. * *  12 Feb. 85 -- ejf *	Added internal extended loopback capability. * *  27 Dec. 84 -- rjl *	Fixed bug that caused every other transmit descriptor to be used *	instead of every descriptor. * *  21 Dec. 84 -- rjl *	Added watchdog timer to mask hardware bug that causes device lockup. * *  18 Dec. 84 -- rjl *	Reworked driver to use q-bus mapping routines.  MicroVAX-I now does *	copying instead of m-buf shuffleing. *	A number of deficencies in the hardware/firmware were compensated *	for. See comments in qestart and qerint. * *  14 Nov. 84 -- jf *	Added usage counts for multicast addresses. *	Updated general protocol support to allow access to the Ethernet *	header. * *  04 Oct. 84 -- jf *	Added support for new ioctls to add and delete multicast addresses *	and set the physical address.  *	Add support for general protocols. * *  14 Aug. 84 -- rjl *	Integrated Shannon changes. (allow arp above 1024 and ? ) * *  13 Feb. 84 -- rjl * *	Initial version of driver. derived from IL driver. *  * --------------------------------------------------------------------- */#include "qe.h"#if	NQE > 0 || defined(BINARY)/* * Digital Q-BUS to NI Adapter */#include "packetfilter.h"       /* NPACKETFILTER */#include "../data/if_qe_data.c"extern struct protosw *iftype_to_proto(), *iffamily_to_proto();extern int net_output();extern struct timeval time;extern timeout();int	qeprobe(), qeattach(), qeint(), qewatch();int	qeinit(),qestart(),qeioctl(),qereset(),qewatch();struct mbuf *qeget();u_short qestd[] = { 0 };struct	uba_driver qedriver =	{ qeprobe, 0, qeattach, 0, qestd, "qe", qeinfo };u_char qunused_multi[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };u_char qe_multi[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; #define OMASK 0x1ff#define REGMASK 0x1fff#define NREGMASK 0x1ff#define QBAI_MR(i) ((int)((i) >> 9) & REGMASK)#define QBAI_NMR(i) ((int)((i) >> 22) & NREGMASK)#define QE_TIMEO	(1 * hz)#define	QEUNIT(x)	minor(x)static int mask = 0x1fffff;		/* address mask		*/int qewatchrun = 0;			/* watchdog running	*/int qe_show_restarts = 0;		/* restart diagnosis	*/ 	int qe_runt = 0;/* * The deqna shouldn't recieve more than ETHERMTU + sizeof(struct ether_header) * but will actually take in up to 2048 bytes. To guard against the receiver * chaining buffers (which we aren't prepared to handle) we allocate 2kb  * size buffers. */#define MAXPACKETSIZE 2048		/* Should really be ETHERMTU	*//* * Probe the QNA to see if it's there */qeprobe(reg)	caddr_t reg;{#ifdef vax	register struct qedevice *addr = (struct qedevice *)reg;#endif vax#ifdef mips	volatile struct qedevice *addr = (struct qedevice *)reg;#endif mips	register struct qe_ring *rp; 	register struct qe_ring *prp; 	/* physical rp 		*/	register int i, j, ncl;	register struct qe_softc *sc;	struct uba_hd *uh = uba_hd;	/* only one bus so no index here */	int unit;	KM_ALLOC(sc,struct qe_softc *,sizeof(struct qe_softc),KM_DEVBUF,KM_CLEAR|KM_CONTIG|KM_CALL);	qe_softc[nNQE] = sc;	unit = nNQE++;	/*	 * Set the address mask for the particular cpu	 */	if( uba_hd[numuba].uba_type&UBAUVI )		mask = 0x3fffff;	else		mask = 0x1fffff;	/*	 * The QNA interrupts on i/o operations. To do an I/O operation 	 * we have to setup the interface by transmitting a setup  packet.	 */	addr->qe_csr = QE_RESET;	addr->qe_vector = (uba_hd[numuba].uh_lastiv -= 4);	/*	 * Map the communications area and the setup packet.	 */	sc->setupaddr =		qballoc(0, sc->setup_pkt, sizeof(sc->setup_pkt), 0);	sc->rringaddr = (struct qe_ring *)		qballoc(0, sc->rring, sizeof(struct qe_ring)*(nNTOT+2),0);	prp = (struct qe_ring *)((int)sc->rringaddr & mask);        addr->qe_csr &= ~QE_RESET;	/*	 * The QNA will loop the setup packet back to the receive ring	 * for verification, therefore we initialize the first 	 * receive & transmit ring descriptors and link the setup packet	 * to them.	 */	qeinitdesc( sc->tring, sc->setupaddr & mask, sizeof(sc->setup_pkt));	qeinitdesc( sc->rring, sc->setupaddr & mask, sizeof(sc->setup_pkt));	rp = (struct qe_ring *)sc->tring;	rp->qe_setup = 1;	rp->qe_eomsg = 1;	rp->qe_flag = rp->qe_status1 = QE_NOTYET;	rp->qe_valid = 1;	rp = (struct qe_ring *)sc->rring;	rp->qe_flag = rp->qe_status1 = QE_NOTYET;	rp->qe_valid = 1;	/*	 * Get the addr off of the interface and place it into the setup	 * packet. This code looks strange due to the fact that the address	 * is placed in the setup packet in col. major order. 	 */	for( i = 0 ; i < 6 ; i++ )		sc->setup_pkt[i][1] = (u_char)addr->qe_sta_addr[i];	qesetup( sc );	/*	 * Start the interface and wait for the packet.	 */	j = cvec;	addr->qe_csr = QE_INT_ENABLE | QE_XMIT_INT | QE_RCV_INT;	addr->qe_rcvlist_lo = (short)prp;	addr->qe_rcvlist_hi = (short)((int)prp >> 16);	prp += nNRCV+1;	addr->qe_xmtlist_lo = (short)prp;	addr->qe_xmtlist_hi = (short)((int)prp >> 16);	DELAY(10000);	/*	 * All done with the bus resources. If it's a uVAX-I they weren't	 * really allocated otherwise deallocated them.	 */	if((uba_hd[numuba].uba_type&UBAUVI) == 0 ) {		qbarelse(0, &sc->setupaddr);		qbarelse(0, &sc->rringaddr);	}	if( cvec == j ) 		return 0;		/* didn't interrupt	*/	/*	 * Allocate page size buffers now. If we wait until the network	 * is setup they have already fragmented. By doing it here in	 * conjunction with always coping on uVAX-I processors we obtain	 * physically contigous buffers for dma transfers.	 */	ncl = clrnd((int)btoc(MAXPACKETSIZE) + CLSIZE) / CLSIZE;	KM_ALLOC(sc->buffers, char *, nNTOT*ncl*CLBYTES, KM_DEVBUF, KM_NOWAIT|KM_CONTIG|KM_CALL);	if(sc->buffers == NULL)		panic("noncontig alloc in qe");	return( sizeof(struct qedevice) );} /* * Interface exists: make available by filling in network interface * record.  System will initialize the interface when it is ready * to accept packets. */qeattach(ui)	struct uba_device *ui;{	register struct qe_softc *sc = qe_softc[ui->ui_unit];	register struct ifnet *ifp = &sc->is_if;#ifdef vax	register struct qedevice *addr = (struct qedevice *)ui->ui_addr;#endif vax#ifdef mips	volatile  struct qedevice *addr = (struct qedevice *)ui->ui_addr;#endif mips	register int i;	struct sockaddr_in *sin;	int nb;	ifp->if_unit = ui->ui_unit;	ifp->if_name = "qe";	ifp->if_mtu = ETHERMTU;	ifp->if_type = IFT_ETHER;	ifp->if_flags |= IFF_BROADCAST | IFF_DYNPROTO;	((struct arpcom *)ifp)->ac_ipaddr.s_addr = 0;	/*	 * Read the address from the prom and save it.	 */	for( i=0 ; i<6 ; i++ )		sc->setup_pkt[i][1] = sc->is_addr[i] = (u_char)addr->qe_sta_addr[i];	/*	 * Save the vector for initialization at reset time.	 */	sc->qe_intvec = addr->qe_vector;	sin = (struct sockaddr_in *)&ifp->if_addr;	sin->sin_family = AF_INET;	ifp->if_init = qeinit;	ifp->if_output = net_output;	ifp->if_start = qestart;	ifp->if_ioctl = qeioctl;	ifp->if_reset = qereset;	addr->qe_vector |= 1;		if(addr->qe_vector & 01) {		ifp->if_sysid_type = 37;		if(addr->qe_vector & 0x8000) {			bcopy("DEC DELQA Ethernet Interface Normal Mode", ifp->if_version, 40);			nb = 40;		} else {			bcopy("DEC DELQA Ethernet Interface DEQNA-lock Mode", ifp->if_version, 44);			nb = 44;		}	} else {		ifp->if_sysid_type = 5;		bcopy("DEC DEQNA Ethernet Interface", ifp->if_version, 28);		nb = 28;	}	ifp->if_version[nb] = '\0';        printf("qe%d: %s, hardware address %s\n", ui->ui_unit,		ifp->if_version,                ether_sprintf(sc->is_addr));	addr->qe_vector &= ~1;#if NPACKETFILTER > 0	/* Tell the packet filter we are here */	attachpfilter(&(sc->qe_ed));#endif NPACKETFILTER	if_attach(ifp);#ifdef mips	ifp->if_snd.ifq_maxlen = 1000;#endif mips}/* * Reset of interface after UNIBUS reset. * If interface is on specified uba, reset its state. */qereset(unit, uban)	int unit, uban;{	register struct uba_device *ui;	if (unit >= nNQE || (ui = qeinfo[unit]) == 0 || ui->ui_alive == 0 ||		ui->ui_ubanum != uban)		return;	printf(" qe%d", unit);	qeinit(unit);} /* * Initialization of interface.  */qeinit(unit)	int unit;{

⌨️ 快捷键说明

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