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

📄 if_ec.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1992, 1993 *	The 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_ec.c	8.1 (Berkeley) 6/11/93 *//* WARNING -- THIS DRIVER DOES NOT WORK YET -- It is merely a sketch */#include "ec.h"#if NEC > 0/* * Intel 82586/3com Etherlink II controller. */#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/syslog.h>#include <sys/ioctl.h>#include <sys/errno.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 ISOextern	char all_es_snpa[], all_is_snpa[], all_l1is_snpa[], all_l2is_snpa[];#endif#include <i386/isa/if_ecreg.h>#if NBPFILTER > 0#include <net/bpf.h>#include <net/bpfdesc.h>#endifint	ecdebug = 1;		/* console error messages */int	ecintr(), ecinit(), ecioctl(), ecstart(), ether_output();int	ecattach(), ecprobe(), ecreset(), ecwatchdog();void	ec_idpattern(), ec_reset_all(), ec_getnmdata(), ecread();struct	mbuf *m_devget();extern	struct ifnet loif;struct	ec_82586params ec_82586defaults =    { 11, 0xc8, ECMINSIZE, 0x2e, 0, 0x60, 0, 2, 0, 0, 0x40};    /* 2e == no source insert *//* * Ethernet software status per interface. * * Each interface is referenced by a network interface structure, * sc_if, which the routing code uses to locate the interface. * This structure contains the output queue for the interface, its address, ... */struct	ec_softc {	struct	arpcom sc_ac;	/* common Ethernet structures */#define	sc_if	sc_ac.ac_if	/* network-visible interface */#define	sc_addr	sc_ac.ac_enaddr	/* hardware Ethernet address */	caddr_t	sc_device;		/* e.g. isa_device */	caddr_t	sc_bpf;			/* for packet filter */	struct	ec_ports *sc_ports;	/* control ports for this unit */	struct	ec_mem *sc_hmem;	/* Host addr for shared memory */	struct	ec_mem *sc_dmem;	/* Device (chip) addr for shared mem */	int	sc_msize;		/* How much memory is mapped? */	int	sc_iflags;		/* copy of sc_if.if_flags for state */	int	sc_rxnum;		/* Last receiver dx we looked at */	int	sc_txnum;		/* Last tranmistter dx we stomped on */	int	sc_txcnt;		/* Number of packets queued for tx*/	int	sc_xint;	/* errors */	int	sc_txbusy;		/* we're confused */	int	sc_uflo;		/* DMA Late */	int	sc_runt;		/* too short */	int	sc_txbad;	int	sc_rxlen;} ec_softc[NEC];#include <i386/isa/isa_device.h>struct	isa_driver ecdriver = {	ecprobe, ecattach, "ec",};#define TIMO 10000 /* used in ec_uprim */ecprobe(id)	register struct	isa_device *id;{	int	unit = id->id_unit, msize = id->id_msize;	struct	ec_ports *reg = (struct ec_ports *)id->id_iobase;	register struct	ec_softc *ec = ec_softc + unit;	u_char	data[6];	ec_reset_all();	bzero((caddr_t)data, sizeof(data));	ec_getnmdata(reg, R_ECID, data);	if (bcmp((caddr_t)data, "*3COM*", sizeof(data)) != 0) {		if (ecdebug) {			printf("ecprobe: ec%d not matched: %s\n",				unit, ether_sprintf(data));		}		return 0;	}	ec_getnmdata(reg, R_ETHER, ec->sc_addr);	ec_getnmdata(reg, R_REV, data);	ec->sc_hmem	= (struct ec_mem *) (id->id_maddr);	ec->sc_dmem	= (struct ec_mem *) (0x10000 - msize);	ec->sc_msize	= msize;	ec->sc_device	= (caddr_t) id;	ec->sc_ports	= reg;	printf("ec%d: hardware address %s, rev info %s\n",		unit, ether_sprintf(ec->sc_addr), ether_sprintf(data));	return 1;}voidec_idpattern(){	int i = 255, n;	register caddr_t p = (caddr_t)0x100;	for (n = 255;  n > 0; n--) {		outb(p, i);		if ((i <<= 1) & 0x100)			i ^= 0xe7;	}}voidec_reset_all(){	register caddr_t p = (caddr_t)0x100;	outb(p, 0);	ec_idpattern();	outb(p, 0);}extern int cpuspeed;#define ECWR(p, e, d)	outb(&(p->e), d)#define ECRD(p, e)	inb(&(p->e))#define SET_CA		ECWR(ec->sc_ports, port_ca, 0)#define UNLATCH_INT	ECWR(ec->sc_ports, port_ic, 0);voidec_getnmdata(p, which, data)register struct ec_ports *p;int which;register u_char *data;{	register int i;	ECWR(p, creg, which);	DELAY(2);	for (i = 0; i < 6; i++) {		DELAY(2);		data[i] = ECRD(p, data[i]);	}}ecreset(unit)	register int unit;{	register struct ec_softc *ec = &ec_softc[unit];	struct ec_ports *p	 = ec->sc_ports;	struct ec_mem	*hmem	 = ec->sc_hmem;	int timo;	ECWR(p, creg, R_LPB);	DELAY(10);	if ((ec->sc_if.if_flags & IFF_RUNNING) == 0)		return 0;	if (ecdebug)		printf("ec%dreset\n", unit);	ec_meminit(ec);	ECWR(p, creg, R_NORST);	DELAY(10);	hmem->iscp.busy = 1;	ECWR(p, port_ca, 0);	DELAY(10);	for (timo = TIMO; hmem->iscp.busy; )		timo--;	if (timo == 0) {		printf("ec(%d)reset: iscp failed\n", unit);		return 0;	}	hmem->scb.command = CU_START;	ECWR(p, port_ca, 0);	DELAY(10);	for (timo = TIMO; (hmem->scb.status & CU_STATE) == CUS_ACTIVE;)		timo--;	if (timo == 0 || (hmem->scb.status & CU_STATE) != CUS_IDLE) {		printf("ec(%d)reset: setup failed\n", unit);		return 0;	}	ECWR(p, port_ic, 0);	DELAY(10);	ECWR(p, creg, R_NORST|R_IEN);	hmem->scb.command = RU_START | (hmem->scb.status & 0xf000);	ECWR(p, port_ca, 0);	DELAY(10);	ec->sc_if.if_timer = 5;	return 0;			/* Keep GCC Happy! */}/* * Interface exists: make available by filling in network interface * record.  System will initialize the interface when it is ready * to accept packets. */ecattach(id)	register struct isa_device *id;{	int	unit = id->id_unit;	struct ec_softc *ec = &ec_softc[unit];	struct ifnet *ifp = &ec->sc_if;	ifp->if_unit = unit;	ifp->if_name = "ec";	ifp->if_mtu = ETHERMTU;	ifp->if_init = ecinit;	ifp->if_init = ecreset;	ifp->if_ioctl = ecioctl;	ifp->if_watchdog = ecwatchdog;	ifp->if_output = ether_output;	ifp->if_start = ecstart;	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;#if NBPFILTER > 0	bpfattach(&ec->sc_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));#endif	if_attach(ifp);	return (1);}#define OFF(e) ((u_short)&(((struct ec_mem *)0)->e))ec_meminit(ec)	register struct ec_softc *ec;{	register struct ec_mem *hmem = ec->sc_hmem;	register int i;	struct ec_rfd *rc = hmem->rcom;	struct ec_transmit *tc = hmem->tcom;	caddr_t cp;	bzero((caddr_t)hmem, ec->sc_msize);	*(struct ec_mem **)		(ec->sc_msize - 4 + (caddr_t)ec->sc_hmem) = ec->sc_dmem;	hmem->iscp.scb_off	= OFF(scb);	hmem->iscp.scb_base	= (caddr_t)ec->sc_dmem;	hmem->scb.rfa_off	= OFF(rcom[0]);	hmem->scb.cbl_off	= OFF(config);	hmem->config.com1	= COM1_CONFIGURE;	bcopy((caddr_t)&ec_82586defaults, (caddr_t)&hmem->config.modes,		sizeof(hmem->config.modes));#if NBPFILTER > 0	if (ec->sc_if.if_flags & IFF_PROMISC)		hmem->config.modes.promisc |= M_PROMISC;#endif	hmem->config.next_off	= OFF(iasetup);	bcopy((caddr_t)ec->sc_addr, (caddr_t)hmem->iasetup.srcaddr, 6);#ifndef ISO	hmem->iasetup.com1	= COM1_IASETUP | COM1_S | COM1_EL;#else	hmem->iasetup.com1	= COM1_IASETUP;	hmem->iasetup.next_off	= OFF(mcsetup);	hmem->mcsetup.com1	= COM1_MCSETUP | COM1_S | COM1_EL;	hmem->mcsetup.count	= 24;	cp = (caddr_t)hmem->txbuf[0];	bcopy((caddr_t)all_es_snpa, cp, 6);	cp += 6;	bcopy((caddr_t)all_is_snpa, cp, 6);	cp += 6;	bcopy((caddr_t)all_l1is_snpa, cp, 6);	cp += 6;	bcopy((caddr_t)all_l2is_snpa, cp, 6);	cp += 6;#endif	for (i = 0; i < NTXBUF; i++) {		tc->tbd_off	= OFF(tcom[i].count);		tc->buffer	= ec->sc_dmem->txbuf[i];		(tc++)->com1	= COM1_TRANSMIT | COM1_S | COM1_EL | COM1_I;	}	for (i = 0; i < NRXBUF; i++) {		rc->next_off	= OFF(rcom[i + 1]);		rc->rbd_off	= OFF(rcom[i].count);		rc->buffer	= ec->sc_dmem->rxbuf[i];		(rc++)->size	= ECMTU | COM1_EL;	}	(--rc)->next_off = OFF(rcom[0]);}/* * Initialization of interface */ecinit(unit)	int unit;{	register struct ifnet *ifp = &ec_softc[unit].sc_if;	register struct ifaddr *ifa;	int s;	/* not yet, if address still unknown */	for (ifa = ifp->if_addrlist;; ifa = ifa->ifa_next)		if (ifa == 0)			return 0;		else if (ifa->ifa_addr && ifa->ifa_addr->sa_family != AF_LINK)			break;	if ((ifp->if_flags & IFF_RUNNING) == 0) {		s = splimp();		ifp->if_flags |= IFF_RUNNING;		ecreset(unit);	        (void) ecstart(ifp);		splx(s);	}	return 0;}/* * Timeout: for now check for a transmit command taking more than 10 seconds. */ecwatchdog(unit)	int unit;{	register struct ec_softc *ec = ec_softc + unit;	if (ec->sc_iflags & IFF_OACTIVE) {		ec->sc_if.if_flags &= ~IFF_RUNNING;		ecinit(unit);	} else if (ec->sc_txcnt > 0)		ec->sc_iflags |= IFF_OACTIVE;	ec->sc_if.if_timer = 5;}ec_txstart(ec)register struct ec_softc *ec;{	struct	ec_mem *hmem = ec->sc_hmem;	int i;	if ((i = ec->sc_txnum - ec->sc_txcnt) < 0) i += NTXBUF;	hmem->scb.cbl_off = OFF(tcom[i]);

⌨️ 快捷键说明

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