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

📄 if_il.c

📁 open bsd vax module -if function
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1982, 1986 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_il.c	7.8 (Berkeley) 12/16/90 */#include "il.h"#if NIL > 0/* * Interlan Ethernet Communications Controller interface */#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#include "../include/cpu.h"#include "../include/mtpr.h"#include "if_il.h"#include "if_ilreg.h"#include "if_uba.h"#include "../uba/ubareg.h"#include "../uba/ubavar.h"int	ilprobe(), ilattach(), ilrint(), ilcint();struct	uba_device *ilinfo[NIL];u_short ilstd[] = { 0 };struct	uba_driver ildriver =	{ ilprobe, 0, ilattach, 0, ilstd, "il", ilinfo };#define	ILUNIT(x)	minor(x)int	ilinit(),iloutput(),ilioctl(),ilreset(),ilwatch(),ilstart();int	ildebug = 0;/* * Ethernet software status per interface. * * Each interface is referenced by a network interface structure, * is_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 ether_addr {	u_char	addr[6];};struct	il_softc {	struct	arpcom is_ac;		/* Ethernet common part */#define	is_if	is_ac.ac_if		/* network-visible interface */#define	is_addr	is_ac.ac_enaddr		/* hardware Ethernet address */	struct	ifuba is_ifuba;		/* UNIBUS resources */	int	is_flags;#define	ILF_RCVPENDING	0x2		/* start rcv in ilcint */#define	ILF_STATPENDING	0x4		/* stat cmd pending */#define	ILF_RUNNING	0x8		/* board is running */#define	ILF_SETADDR	0x10		/* physical address is changed */	short	is_lastcmd;		/* can't read csr, so must save it */	short	is_scaninterval;	/* interval of stat collection */#define	ILWATCHINTERVAL	60		/* once every 60 seconds */	union {	    struct	il_stats isu_stats;	/* holds on-board statistics */	    struct	ether_addr isu_maddrs[63];	/* multicast addrs */	}	is_isu;#define is_stats	is_isu.isu_stats#define is_maddrs	is_isu.isu_maddrs	struct	il_stats is_sum;	/* summation over time */	int	is_ubaddr;		/* mapping registers of is_stats */} il_softc[NIL];ilprobe(reg)	caddr_t reg;{	register int br, cvec;		/* r11, r10 value-result */	register struct ildevice *addr = (struct ildevice *)reg;	register i;#ifdef lint	br = 0; cvec = br; br = cvec;	i = 0; ilrint(i); ilcint(i); ilwatch(i);#endif	addr->il_csr = ILC_OFFLINE|IL_CIE;	DELAY(100000);	i = addr->il_csr;		/* clear CDONE */	if (cvec > 0 && cvec != 0x200)		cvec -= 4;	return (1);}/* * Interface exists: make available by filling in network interface * record.  System will initialize the interface when it is ready * to accept packets.  A STATUS command is done to get the ethernet * address and other interesting data. */ilattach(ui)	struct uba_device *ui;{	register struct il_softc *is = &il_softc[ui->ui_unit];	register struct ifnet *ifp = &is->is_if;	register struct ildevice *addr = (struct ildevice *)ui->ui_addr;	ifp->if_unit = ui->ui_unit;	ifp->if_name = "il";	ifp->if_mtu = ETHERMTU;	ifp->if_flags = IFF_BROADCAST;	/*	 * Reset the board and map the statistics	 * buffer onto the Unibus.	 */	addr->il_csr = ILC_RESET;	(void)ilwait(ui, "reset");		is->is_ubaddr = uballoc(ui->ui_ubanum, (caddr_t)&is->is_stats,	    sizeof (struct il_stats), 0);	addr->il_bar = is->is_ubaddr & 0xffff;	addr->il_bcr = sizeof (struct il_stats);	addr->il_csr = ((is->is_ubaddr >> 2) & IL_EUA)|ILC_STAT;	(void)ilwait(ui, "status");	ubarelse(ui->ui_ubanum, &is->is_ubaddr);	if (ildebug)		printf("il%d: module=%s firmware=%s\n", ui->ui_unit,			is->is_stats.ils_module, is->is_stats.ils_firmware); 	bcopy((caddr_t)is->is_stats.ils_addr, (caddr_t)is->is_addr, 	    sizeof (is->is_addr));	printf("il%d: hardware address %s\n", ui->ui_unit,		ether_sprintf(is->is_addr));	ifp->if_init = ilinit;	ifp->if_output = ether_output;	ifp->if_ioctl = ilioctl;	ifp->if_reset = ilreset;	ifp->if_start = ilstart;	is->is_ifuba.ifu_flags = UBA_CANTWAIT;	if_attach(ifp);}ilwait(ui, op)	struct uba_device *ui;	char *op;{	register struct ildevice *addr = (struct ildevice *)ui->ui_addr;	while ((addr->il_csr&IL_CDONE) == 0)		;	if (addr->il_csr&IL_STATUS) {		printf("il%d: %s failed, csr=%b\n", ui->ui_unit, op,			addr->il_csr, IL_BITS);		return (-1);	}	return (0);}/* * Reset of interface after UNIBUS reset. * If interface is on specified uba, reset its state. */ilreset(unit, uban)	int unit, uban;{	register struct uba_device *ui;	if (unit >= NIL || (ui = ilinfo[unit]) == 0 || ui->ui_alive == 0 ||	    ui->ui_ubanum != uban)		return;	printf(" il%d", unit);	il_softc[unit].is_if.if_flags &= ~IFF_RUNNING;	il_softc[unit].is_flags &= ~ILF_RUNNING;	ilinit(unit);}/* * Initialization of interface; clear recorded pending * operations, and reinitialize UNIBUS usage. */ilinit(unit)	int unit;{	register struct il_softc *is = &il_softc[unit];	register struct uba_device *ui = ilinfo[unit];	register struct ildevice *addr;	register struct ifnet *ifp = &is->is_if;	int s;	/* not yet, if address still unknown */	if (ifp->if_addrlist == (struct ifaddr *)0)		return;	if (is->is_flags & ILF_RUNNING)		return;	if ((ifp->if_flags & IFF_RUNNING) == 0) {		if (if_ubainit(&is->is_ifuba, ui->ui_ubanum,		    sizeof (struct il_rheader), (int)btoc(ETHERMTU)) == 0) { 			printf("il%d: can't initialize\n", unit);			is->is_if.if_flags &= ~IFF_UP;			return;		}		is->is_ubaddr = uballoc(ui->ui_ubanum, (caddr_t)&is->is_isu,		    sizeof (is->is_isu), 0);	}	ifp->if_watchdog = ilwatch;	is->is_scaninterval = ILWATCHINTERVAL;	ifp->if_timer = is->is_scaninterval;	addr = (struct ildevice *)ui->ui_addr;	/*	 * Turn off source address insertion (it's faster this way),	 * and set board online.  Former doesn't work if board is	 * already online (happens on ubareset), so we put it offline	 * first.	 */	s = splimp();	addr->il_csr = ILC_RESET;	if (ilwait(ui, "hardware diag")) { 		is->is_if.if_flags &= ~IFF_UP; 		splx(s); 		return; 	}	addr->il_csr = ILC_CISA;	while ((addr->il_csr & IL_CDONE) == 0)		;	/*	 * If we must reprogram this board's physical ethernet	 * address (as for secondary XNS interfaces), we do so	 * before putting it on line, and starting receive requests.	 * If you try this on an older 1010 board, it will total	 * wedge the board.	 */	if (is->is_flags & ILF_SETADDR) {		bcopy((caddr_t)is->is_addr, (caddr_t)&is->is_isu,							sizeof is->is_addr);		addr->il_bar = is->is_ubaddr & 0xffff;		addr->il_bcr = sizeof is->is_addr;		addr->il_csr = ((is->is_ubaddr >> 2) & IL_EUA)|ILC_LDPA;		if (ilwait(ui, "setaddr"))			return;		addr->il_bar = is->is_ubaddr & 0xffff;		addr->il_bcr = sizeof (struct il_stats);		addr->il_csr = ((is->is_ubaddr >> 2) & IL_EUA)|ILC_STAT;		if (ilwait(ui, "verifying setaddr"))			return;		if (bcmp((caddr_t)is->is_stats.ils_addr, (caddr_t)is->is_addr,						sizeof (is->is_addr)) != 0) {			printf("il%d: setaddr didn't work\n", ui->ui_unit);			return;		}	}#ifdef MULTICAST	if (is->is_if.if_flags & IFF_PROMISC) {		addr->il_csr = ILC_PRMSC;		if (ilwait(ui, "all multi"))			return;	} else if (is->is_if.if_flags & IFF_ALLMULTI) {	too_many_multis:		addr->il_csr = ILC_ALLMC;		if (ilwait(ui, "all multi"))			return;	else {		int i;		register struct ether_addr *ep = is->is_maddrs;		struct ether_multi *enm;		struct ether_multistep step;		/*		 * Step through our list of multicast addresses.  If we have		 * too many multicast addresses, or if we have to listen to		 * a range of multicast addresses, turn on reception of all		 * multicasts.		 */		i = 0;		ETHER_FIRST_MULTI(step, &is->is_ac, enm);		while (enm != NULL) {			if (++i > 63 && k != 0) {				break;			}			*ep++ = *(struct ether_addr *)enm->enm_addrlo;			ETHER_NEXT_MULTI(step, enm);		}		if (i = 0) {			/* no multicasts! */		} else if (i <= 63) {			addr->il_bar = is->is_ubaddr & 0xffff;			addr->il_bcr = i * sizeof (struct ether_addr);			addr->il_csr = ((is->is_ubaddr >> 2) & IL_EUA)|						LC_LDGRPS;			if (ilwait(ui, "load multi"))				return;		} else {

⌨️ 快捷键说明

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