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

📄 if_de.c

📁 open bsd vax module -if function
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1982, 1986, 1989 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)if_de.c	7.12 (Berkeley) 12/16/90 */#include "de.h"#if NDE > 0/* * DEC DEUNA interface * *	Lou Salkind *	New York University * * TODO: *	timeout routine (get statistics) */#include "../include/pte.h"#include "sys/param.h"#include "sys/systm.h"#include "sys/mbuf.h"#include "sys/buf.h"#include "sys/protosw.h"#include "sys/socket.h"#include "sys/vmmac.h"#include "sys/ioctl.h"#include "sys/errno.h"#include "sys/syslog.h"#include "net/if.h"#include "net/netisr.h"#include "net/route.h"#ifdef INET#include "netinet/in.h"#include "netinet/in_systm.h"#include "netinet/in_var.h"#include "netinet/ip.h"#include "netinet/if_ether.h"#endif#ifdef NS#include "netns/ns.h"#include "netns/ns_if.h"#endif#ifdef ISO#include "netiso/iso.h"#include "netiso/iso_var.h"extern char all_es_snpa[], all_is_snpa[];#endif#include "../include/cpu.h"#include "../include/mtpr.h"#include "if_dereg.h"#include "if_uba.h"#include "../uba/ubareg.h"#include "../uba/ubavar.h"#define	NXMT	3	/* number of transmit buffers */#define	NRCV	7	/* number of receive buffers (must be > 1) */int	dedebug = 0;int	deprobe(), deattach(), deintr();struct	uba_device *deinfo[NDE];u_short destd[] = { 0 };struct	uba_driver dedriver =	{ deprobe, 0, deattach, 0, destd, "de", deinfo };int	deinit(),ether_output(),deioctl(),dereset(),destart();/* * Ethernet software status per interface. * * Each interface is referenced by a network interface structure, * ds_if, which the routing code uses to locate the interface. * This structure contains the output queue for the interface, its address, ... * We also have, for each interface, a UBA interface structure, which * contains information about the UNIBUS resources held by the interface: * map registers, buffered data paths, etc.  Information is cached in this * structure for use by the if_uba.c routines in running the interface * efficiently. */struct	de_softc {	struct	arpcom ds_ac;		/* Ethernet common part */#define	ds_if	ds_ac.ac_if		/* network-visible interface */#define	ds_addr	ds_ac.ac_enaddr		/* hardware Ethernet address */	int	ds_flags;#define	DSF_RUNNING	2		/* board is enabled */#define	DSF_SETADDR	4		/* physical address is changed */	int	ds_ubaddr;		/* map info for incore structs */	struct	ifubinfo ds_deuba;	/* unibus resource structure */	struct	ifrw ds_ifr[NRCV];	/* unibus receive maps */	struct	ifxmt ds_ifw[NXMT];	/* unibus xmt maps */	/* the following structures are always mapped in */	struct	de_pcbb ds_pcbb;	/* port control block */	struct	de_ring ds_xrent[NXMT];	/* transmit ring entrys */	struct	de_ring ds_rrent[NRCV];	/* receive ring entrys */	struct	de_udbbuf ds_udbbuf;	/* UNIBUS data buffer */	/* end mapped area */#define	INCORE_BASE(p)	((char *)&(p)->ds_pcbb)#define	RVAL_OFF(n)	((char *)&de_softc[0].n - INCORE_BASE(&de_softc[0]))#define	LVAL_OFF(n)	((char *)de_softc[0].n - INCORE_BASE(&de_softc[0]))#define	PCBB_OFFSET	RVAL_OFF(ds_pcbb)#define	XRENT_OFFSET	LVAL_OFF(ds_xrent)#define	RRENT_OFFSET	LVAL_OFF(ds_rrent)#define	UDBBUF_OFFSET	RVAL_OFF(ds_udbbuf)#define	INCORE_SIZE	RVAL_OFF(ds_xindex)	int	ds_xindex;		/* UNA index into transmit chain */	int	ds_rindex;		/* UNA index into receive chain */	int	ds_xfree;		/* index for next transmit buffer */	int	ds_nxmit;		/* # of transmits in progress */} de_softc[NDE];deprobe(reg)	caddr_t reg;{	register int br, cvec;		/* r11, r10 value-result */	register struct dedevice *addr = (struct dedevice *)reg;	register i;#ifdef lint	br = 0; cvec = br; br = cvec;	i = 0; derint(i); deintr(i);#endif	/*	 * Make sure self-test is finished before we screw with the board.	 * Self-test on a DELUA can take 15 seconds (argh).	 */	for (i = 0;	     i < 160 &&	     (addr->pcsr0 & PCSR0_FATI) == 0 &&	     (addr->pcsr1 & PCSR1_STMASK) == STAT_RESET;	     ++i)		DELAY(100000);	if ((addr->pcsr0 & PCSR0_FATI) != 0 ||	    (addr->pcsr1 & PCSR1_STMASK) != STAT_READY)		return(0);	addr->pcsr0 = 0;	DELAY(100);	addr->pcsr0 = PCSR0_RSET;	while ((addr->pcsr0 & PCSR0_INTR) == 0)		;	/* make board interrupt by executing a GETPCBB command */	addr->pcsr0 = PCSR0_INTE;	addr->pcsr2 = 0;	addr->pcsr3 = 0;	addr->pcsr0 = PCSR0_INTE|CMD_GETPCBB;	DELAY(100000);	return(1);}/* * Interface exists: make available by filling in network interface * record.  System will initialize the interface when it is ready * to accept packets.  We get the ethernet address here. */deattach(ui)	struct uba_device *ui;{	register struct de_softc *ds = &de_softc[ui->ui_unit];	register struct ifnet *ifp = &ds->ds_if;	register struct dedevice *addr = (struct dedevice *)ui->ui_addr;	int csr1;	ifp->if_unit = ui->ui_unit;	ifp->if_name = "de";	ifp->if_mtu = ETHERMTU;	ifp->if_flags = IFF_BROADCAST;	/*	 * What kind of a board is this?	 * The error bits 4-6 in pcsr1 are a device id as long as	 * the high byte is zero.	 */	csr1 = addr->pcsr1;	if (csr1 & 0xff60)		printf("de%d: broken\n", ui->ui_unit);	else if (csr1 & 0x10)		printf("de%d: delua\n", ui->ui_unit);	else		printf("de%d: deuna\n", ui->ui_unit);	/*	 * Reset the board and temporarily map	 * the pcbb buffer onto the Unibus.	 */	addr->pcsr0 = 0;		/* reset INTE */	DELAY(100);	addr->pcsr0 = PCSR0_RSET;	(void)dewait(ui, "reset");	ds->ds_ubaddr = uballoc(ui->ui_ubanum, (char *)&ds->ds_pcbb,		sizeof (struct de_pcbb), 0);	addr->pcsr2 = ds->ds_ubaddr & 0xffff;	addr->pcsr3 = (ds->ds_ubaddr >> 16) & 0x3;	addr->pclow = CMD_GETPCBB;	(void)dewait(ui, "pcbb");	ds->ds_pcbb.pcbb0 = FC_RDPHYAD;	addr->pclow = CMD_GETCMD;	(void)dewait(ui, "read addr ");	ubarelse(ui->ui_ubanum, &ds->ds_ubaddr); 	bcopy((caddr_t)&ds->ds_pcbb.pcbb2, (caddr_t)ds->ds_addr,	    sizeof (ds->ds_addr));	printf("de%d: hardware address %s\n", ui->ui_unit,		ether_sprintf(ds->ds_addr));	ifp->if_init = deinit;	ifp->if_output = ether_output;	ifp->if_ioctl = deioctl;	ifp->if_reset = dereset;	ifp->if_start = destart;	ds->ds_deuba.iff_flags = UBA_CANTWAIT;#ifdef notdef	/* CAN WE USE BDP's ??? */	ds->ds_deuba.iff_flags |= UBA_NEEDBDP;#endif	if_attach(ifp);}/* * Reset of interface after UNIBUS reset. * If interface is on specified uba, reset its state. */dereset(unit, uban)	int unit, uban;{	register struct uba_device *ui;	if (unit >= NDE || (ui = deinfo[unit]) == 0 || ui->ui_alive == 0 ||	    ui->ui_ubanum != uban)		return;	printf(" de%d", unit);	de_softc[unit].ds_if.if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);	de_softc[unit].ds_flags &= ~DSF_RUNNING;	((struct dedevice *)ui->ui_addr)->pcsr0 = PCSR0_RSET;	(void)dewait(ui, "reset");	deinit(unit);}/* * Initialization of interface; clear recorded pending * operations, and reinitialize UNIBUS usage. */deinit(unit)	int unit;{	register struct de_softc *ds = &de_softc[unit];	register struct uba_device *ui = deinfo[unit];	register struct dedevice *addr;	register struct ifrw *ifrw;	register struct ifxmt *ifxp;	struct ifnet *ifp = &ds->ds_if;	int s;	struct de_ring *rp;	int incaddr;	/* not yet, if address still unknown */	if (ifp->if_addrlist == (struct ifaddr *)0)		return;	if (ds->ds_flags & DSF_RUNNING)		return;	if ((ifp->if_flags & IFF_RUNNING) == 0) {		if (if_ubaminit(&ds->ds_deuba, ui->ui_ubanum,		    sizeof (struct ether_header), (int)btoc(ETHERMTU),		    ds->ds_ifr, NRCV, ds->ds_ifw, NXMT) == 0) { 			printf("de%d: can't initialize\n", unit);			ds->ds_if.if_flags &= ~IFF_UP;			return;		}		ds->ds_ubaddr = uballoc(ui->ui_ubanum, INCORE_BASE(ds),			INCORE_SIZE, 0);	}	addr = (struct dedevice *)ui->ui_addr;	/* set the pcbb block address */	incaddr = ds->ds_ubaddr + PCBB_OFFSET;	addr->pcsr2 = incaddr & 0xffff;	addr->pcsr3 = (incaddr >> 16) & 0x3;	addr->pclow = 0;	/* reset INTE */	DELAY(100);	addr->pclow = CMD_GETPCBB;	(void)dewait(ui, "pcbb");	/* set the transmit and receive ring header addresses */	incaddr = ds->ds_ubaddr + UDBBUF_OFFSET;	ds->ds_pcbb.pcbb0 = FC_WTRING;	ds->ds_pcbb.pcbb2 = incaddr & 0xffff;	ds->ds_pcbb.pcbb4 = (incaddr >> 16) & 0x3;	incaddr = ds->ds_ubaddr + XRENT_OFFSET;	ds->ds_udbbuf.b_tdrbl = incaddr & 0xffff;	ds->ds_udbbuf.b_tdrbh = (incaddr >> 16) & 0x3;	ds->ds_udbbuf.b_telen = sizeof (struct de_ring) / sizeof (short);	ds->ds_udbbuf.b_trlen = NXMT;	incaddr = ds->ds_ubaddr + RRENT_OFFSET;	ds->ds_udbbuf.b_rdrbl = incaddr & 0xffff;	ds->ds_udbbuf.b_rdrbh = (incaddr >> 16) & 0x3;	ds->ds_udbbuf.b_relen = sizeof (struct de_ring) / sizeof (short);	ds->ds_udbbuf.b_rrlen = NRCV;	addr->pclow = CMD_GETCMD;	(void)dewait(ui, "wtring");	/* initialize the mode - enable hardware padding */	ds->ds_pcbb.pcbb0 = FC_WTMODE;	/* let hardware do padding - set MTCH bit on broadcast */	ds->ds_pcbb.pcbb2 = MOD_TPAD|MOD_HDX;	addr->pclow = CMD_GETCMD;	(void)dewait(ui, "wtmode");	/* set up the receive and transmit ring entries */	ifxp = &ds->ds_ifw[0];	for (rp = &ds->ds_xrent[0]; rp < &ds->ds_xrent[NXMT]; rp++) {		rp->r_segbl = ifxp->ifw_info & 0xffff;		rp->r_segbh = (ifxp->ifw_info >> 16) & 0x3;		rp->r_flags = 0;		ifxp++;	}	ifrw = &ds->ds_ifr[0];

⌨️ 快捷键说明

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