diff --git a/sys/arch/i386/isa/if_ne.c b/sys/arch/i386/isa/if_ne.c deleted file mode 100644 index 2e090e76b2dd..000000000000 --- a/sys/arch/i386/isa/if_ne.c +++ /dev/null @@ -1,968 +0,0 @@ -/*- - * Copyright (c) 1990, 1991 William F. Jolitz. - * Copyright (c) 1990 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. - * - * from: @(#)if_ne.c 7.4 (Berkeley) 5/21/91 - * $Id: if_ne.c,v 1.16 1994/01/24 00:17:32 deraadt Exp $ - */ - -/* - * NE2000/NE1000 Ethernet driver - * - * Parts inspired from Tim Tucker's if_wd driver for the wd8003, - * insight on the ne2000 gained from Robert Clements PC/FTP driver. - * - * Corrected for NE1000 by Andrew A. Chernov - */ - -#include "ne.h" -#if NNE > 0 - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#ifdef INET -#include -#include -#include -#include -#include -#endif - -#ifdef NS -#include -#include -#endif - -#include "bpfilter.h" -#if NBPFILTER > 0 -#include -#include -#include -#endif - -#include - -#include -#include -#include - -int neprobe(), neattach(), neintr(); -int nestart(),neinit(), ether_output(), neioctl(); - -struct isa_driver nedriver = { - neprobe, neattach, "ne", -}; - -struct mbuf *neget(); - -#define ETHER_MIN_LEN 64 -#define ETHER_MAX_LEN 1536 - -/* - * Ethernet software status per interface. - * - * Each interface is referenced by a network interface structure, - * ns_if, which the routing code uses to locate the interface. - * This structure contains the output queue for the interface, its address, ... - */ -struct ne_softc { - struct arpcom ns_ac; /* Ethernet common part */ -#define ns_if ns_ac.ac_if /* network-visible interface */ -#define ns_addrp ns_ac.ac_enaddr /* hardware Ethernet address */ - int ns_flags; -#define DSF_LOCK 1 /* block re-entering enstart */ - int ns_oactive ; - int ns_mask ; - int ns_ba; /* byte addr in buffer ram of inc pkt */ - int ns_cur; /* current page being filled */ - struct prhdr ns_ph; /* hardware header of incoming packet*/ - struct ether_header ns_eh; /* header of incoming packet */ - u_char ns_pb[2048 /*ETHERMTU+sizeof(long)*/]; - short ns_txstart; /* transmitter buffer start */ - u_short ns_rxend; /* recevier buffer end */ - short ns_port; /* i/o port base */ - short ns_mode; /* word/byte mode */ - caddr_t ns_bpf; /* BPF frob */ -} ne_softc[NNE] ; -#define ENBUFSIZE (sizeof(struct ether_header) + ETHERMTU + 2 + ETHER_MIN_LEN) - -#define PAT(n) (0xa55a + 37*(n)) - -u_char boarddata[16]; - -neprobe(dvp) - struct isa_device *dvp; -{ - int val, i, s, sum, bytemode = 1, pat; - register struct ne_softc *ns = &ne_softc[dvp->id_unit]; - register nec; - -#ifdef lint - neintr(0); -#endif - - nec = ns->ns_port = dvp->id_iobase; - s = splimp(); - - if (bytemode) { - /* Byte Transfers, Burst Mode Select, Fifo at 8 bytes */ - ns->ns_mode = DSDC_BMS|DSDC_FT1; - ns->ns_txstart = TBUF8; - ns->ns_rxend = RBUFEND8; - } else { -word: - /* Word Transfers, Burst Mode Select, Fifo at 8 bytes */ - ns->ns_mode = DSDC_WTS|DSDC_BMS|DSDC_FT1; - ns->ns_txstart = TBUF16; - ns->ns_rxend = RBUFEND16; - bytemode = 0; - } - - /* Reset the bastard */ - val = inb(nec + ne_reset); - DELAY(200); - outb(nec + ne_reset, val); - DELAY(200); - - outb(nec + ds_cmd, DSCM_STOP|DSCM_NODMA); - - i = 10000; - while ((inb(nec + ds0_isr) & DSIS_RESET) == 0 && i-- > 0); - if (i < 0) return (0); - - outb(nec + ds0_isr, 0xff); - outb(nec + ds0_dcr, ns->ns_mode); - outb(nec + ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_STOP); - DELAY(1000); - - /* Check cmd reg and fail if not right */ - if ((i = inb(nec + ds_cmd)) != (DSCM_NODMA|DSCM_PG0|DSCM_STOP)) - return(0); - - outb(nec + ds0_tcr, 0); - outb(nec + ds0_rcr, DSRC_MON); - outb(nec + ds0_pstart, (ns->ns_txstart+PKTSZ)/DS_PGSIZE); - outb(nec + ds0_pstop, ns->ns_rxend/DS_PGSIZE); - outb(nec + ds0_bnry, ns->ns_rxend/DS_PGSIZE); - outb(nec + ds0_imr, 0); - outb(nec + ds0_isr, 0); - outb(nec + ds_cmd, DSCM_NODMA|DSCM_PG1|DSCM_STOP); - outb(nec + ds1_curr, (ns->ns_txstart+PKTSZ)/DS_PGSIZE); - outb(nec + ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_STOP); - - -#ifdef NEDEBUG -#define RCON 37 - { int i, rom; - - rom=1; - printf("ne ram "); - - for (i = 0; i < 0xfff0; i+=4) { - pat = PAT(i); - neput(ns, &pat,i,4); - nefetch(ns, &pat,i,4); - if (pat == PAT(i)) { - if (rom) { - rom=0; - printf(" %x", i); - } - } else { - if (!rom) { - rom=1; - printf("..%x ", i); - } - } - pat=0; - neput(ns, &pat,i,4); - } - printf("\n"); - } -#endif - - /* - * detect difference between units - * solely by where the RAM is decoded. - */ - pat = PAT(0); - neput(ns, &pat, ns->ns_txstart, 4); - nefetch(ns, &pat, ns->ns_txstart, 4); - if (pat != PAT(0)) { - if (bytemode) - goto word; - else return (0); - } - - - /* Extract board address */ - nefetch (ns, (caddr_t)boarddata, 0, sizeof(boarddata)); - - for(i=0; i < 6; i++) - ns->ns_addrp[i] = boarddata[i*(2-bytemode)]; - splx(s); - return (16); -} - -/* - * Fetch from onboard ROM/RAM - */ -nefetch (ns, up, ad, len) struct ne_softc *ns; caddr_t up; { - u_char cmd; - register nec = ns->ns_port; - int counter = 100000; - - cmd = inb (nec + ds_cmd); - outb (nec + ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_START); - - /* Setup remote dma */ - outb (nec + ds0_isr, DSIS_RDC); - - if ((ns->ns_mode & DSDC_WTS) && len&1) - len++; /* roundup to words */ - - outb (nec+ds0_rbcr0, len); - outb (nec+ds0_rbcr1, len>>8); - outb (nec+ds0_rsar0, ad); - outb (nec+ds0_rsar1, ad>>8); - - /* Execute & extract from card */ - outb (nec+ds_cmd, DSCM_RREAD|DSCM_PG0|DSCM_START); - - if (ns->ns_mode & DSDC_WTS) - insw (nec+ne_data, up, len/2); - else - insb (nec+ne_data, up, len); - - /* Wait till done, then shutdown feature */ - while ((inb (nec+ds0_isr) & DSIS_RDC) == 0 && counter-- > 0) - ; - outb (nec+ds0_isr, DSIS_RDC); - outb (nec+ds_cmd, cmd); -} - -/* - * Put to onboard RAM - */ -neput (ns, up, ad, len) struct ne_softc *ns; caddr_t up; { - u_char cmd; - register nec = ns->ns_port; - int counter = 100000; - - cmd = inb(nec+ds_cmd); - outb (nec+ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_START); - - /* Setup for remote dma */ - outb (nec+ds0_isr, DSIS_RDC); - - if ((ns->ns_mode & DSDC_WTS) && len&1) - len++; /* roundup to words */ - - outb (nec+ds0_rbcr0, len); - outb (nec+ds0_rbcr1, len>>8); - outb (nec+ds0_rsar0, ad); - outb (nec+ds0_rsar1, ad>>8); - - /* Execute & stuff to card */ - outb (nec+ds_cmd, DSCM_RWRITE|DSCM_PG0|DSCM_START); - if (ns->ns_mode & DSDC_WTS) - outsw (nec+ne_data, up, len/2); - else - outsb (nec+ne_data, up, len); - - /* Wait till done, then shutdown feature */ - while ((inb (nec+ds0_isr) & DSIS_RDC) == 0 && counter-- > 0) - ; - outb (nec+ds0_isr, DSIS_RDC); - outb (nec+ds_cmd, cmd); -} - -/* - * Reset of interface. - */ -nereset(unit, uban) - int unit, uban; -{ - if (unit >= NNE) - return; - printf("ne%d: reset\n", unit); - ne_softc[unit].ns_flags &= ~DSF_LOCK; - neinit(unit); -} - -/* - * 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. - */ -neattach(dvp) - struct isa_device *dvp; -{ - int unit = dvp->id_unit; - register struct ne_softc *ns = &ne_softc[unit]; - register struct ifnet *ifp = &ns->ns_if; - - ifp->if_unit = unit; - ifp->if_name = nedriver.name ; - ifp->if_mtu = ETHERMTU; - printf ("ne%d: ne%s ethernet address %s\n", unit, - (ns->ns_mode & DSDC_WTS) ? "2000" : "1000", - ether_sprintf(ns->ns_addrp)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS; - ifp->if_init = neinit; - ifp->if_output = ether_output; - ifp->if_start = nestart; - ifp->if_ioctl = neioctl; - ifp->if_reset = nereset; - ifp->if_watchdog = 0; - if_attach(ifp); - -#if NBPFILTER > 0 - bpfattach(&ns->ns_bpf, ifp, DLT_EN10MB, - sizeof(struct ether_header)); -#endif -} - -/* - * Initialization of interface; set up initialization block - * and transmit/receive descriptor rings. - */ -neinit(unit) - int unit; -{ - register struct ne_softc *ns = &ne_softc[unit]; - struct ifnet *ifp = &ns->ns_if; - int s; - int i; char *cp; - register nec = ns->ns_port; - - if (ifp->if_addrlist == (struct ifaddr *)0) return; - if (ifp->if_flags & IFF_RUNNING) return; - - s = splimp(); - - /* set physical address on ethernet */ - outb (nec+ds_cmd, DSCM_NODMA|DSCM_PG1|DSCM_STOP); - for (i=0 ; i < 6 ; i++) outb(nec+ds1_par0+i,ns->ns_addrp[i]); - - /* clr logical address hash filter for now */ - for (i=0 ; i < 8 ; i++) outb(nec+ds1_mar0+i,0xff); - - /* init regs */ - outb (nec+ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_STOP); - outb (nec+ds0_rbcr0, 0); - outb (nec+ds0_rbcr1, 0); - outb (nec+ds0_imr, 0); - outb (nec+ds0_isr, 0xff); - - /* Word Transfer select, Burst Mode Select, Fifo at 8 bytes */ - outb(nec+ds0_dcr, ns->ns_mode); - - outb(nec+ds0_tcr, 0); - outb (nec+ds0_rcr, DSRC_MON); - outb (nec+ds0_tpsr, 0); - outb(nec+ds0_pstart, (ns->ns_txstart+PKTSZ)/DS_PGSIZE); - outb(nec+ds0_pstop, ns->ns_rxend/DS_PGSIZE); - outb(nec+ds0_bnry, (ns->ns_txstart+PKTSZ)/DS_PGSIZE); - outb (nec+ds_cmd, DSCM_NODMA|DSCM_PG1|DSCM_STOP); - outb(nec+ds1_curr, (ns->ns_txstart+PKTSZ)/DS_PGSIZE); - ns->ns_cur = (ns->ns_txstart+PKTSZ)/DS_PGSIZE; - outb (nec+ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_START); -#if NBPFILTER > 0 - if (ns->ns_if.if_flags & IFF_PROMISC) - outb (nec+ds0_rcr, DSRC_AB | DSRC_PRO | DSRC_AR | DSRC_SEP); - else -#endif - outb (nec+ds0_rcr, DSRC_AB); - outb(nec+ds0_dcr, ns->ns_mode); - outb (nec+ds0_imr, 0xff); - - ns->ns_if.if_flags |= IFF_RUNNING; - ns->ns_flags &= ~DSF_LOCK; - ns->ns_oactive = 0; ns->ns_mask = ~0; - nestart(ifp); - splx(s); -} - -/* - * Setup output on interface. - * Get another datagram to send off of the interface queue, - * and map it to the interface before starting the output. - * called only at splimp or interrupt level. - * XXX: Needs BPF hook. - */ -nestart(ifp) - struct ifnet *ifp; -{ - register struct ne_softc *ns = &ne_softc[ifp->if_unit]; - struct mbuf *m0, *m; - int len, i, t; - register nec = ns->ns_port; - u_char cmd; - u_short word; - int counter; - - if (ns->ns_flags & DSF_LOCK) - return; - - if ((ns->ns_if.if_flags & IFF_RUNNING) == 0) - return; - - /* - * The DS8390 has only one transmit buffer, if it is busy we - * must wait until the transmit interrupt completes. - */ - outb(nec+ds_cmd,DSCM_NODMA|DSCM_START); - - if (inb(nec+ds_cmd) & DSCM_TRANS) - return; - - IF_DEQUEUE(&ns->ns_if.if_snd, m); - - if (m == 0) - return; - - ns->ns_flags |= DSF_LOCK; /* prevent entering nestart */ - - /* - * Copy the mbuf chain into the transmit buffer - */ - - i = 0; - len = m->m_pkthdr.len; - - /* next code derived from neput() */ - - if ((ns->ns_mode & DSDC_WTS) && t&1) - t++; /* roundup to words */ - - cmd = inb(nec+ds_cmd); - outb (nec+ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_START); - - /* Setup for remote dma */ - outb (nec+ds0_isr, DSIS_RDC); - - outb (nec+ds0_rbcr0, t); - outb (nec+ds0_rbcr1, t>>8); - outb (nec+ds0_rsar0, ns->ns_txstart); - outb (nec+ds0_rsar1, ns->ns_txstart>>8); - - /* Execute & stuff to card */ - outb (nec+ds_cmd, DSCM_RWRITE|DSCM_PG0|DSCM_START); - - if (ns->ns_mode & DSDC_WTS) { /* Word Mode */ - while (m != 0) { - if (m->m_len > 1) - outsw(nec+ne_data, m->m_data, m->m_len / 2); - if (m->m_len & 1) { - word = (u_char) *(mtod(m, caddr_t) + m->m_len - 1); - if ((m = m->m_next) != 0) { - word |= *mtod(m, caddr_t) << 8; - m->m_len--; - m->m_data++; - } - outsw(nec+ne_data, (caddr_t)&word, 1); - } else - m = m->m_next; - } - } - else { /* Byte Mode */ - while (m != 0) { - if (m->m_len > 0) - outsb(nec+ne_data, mtod(m, caddr_t), m->m_len); - m = m->m_next; - } - } - - m_freem(m0); - - counter = 100000; - /* Wait till done, then shutdown feature */ - while ((inb (nec+ds0_isr) & DSIS_RDC) == 0 && counter-- > 0) - ; - outb (nec+ds0_isr, DSIS_RDC); - outb (nec+ds_cmd, cmd); - - /* - * Init transmit length registers, and set transmit start flag. - */ - - if (len < ETHER_MIN_LEN) len = ETHER_MIN_LEN; - outb(nec+ds0_tbcr0,len&0xff); - outb(nec+ds0_tbcr1,(len>>8)&0xff); - outb(nec+ds0_tpsr, ns->ns_txstart/DS_PGSIZE); - outb(nec+ds_cmd, DSCM_TRANS|DSCM_NODMA|DSCM_START); -} - -/* buffer successor/predecessor in ring? */ -#define succ(n) (((n)+1 >= ns->ns_rxend/DS_PGSIZE) ? (ns->ns_txstart+PKTSZ)/DS_PGSIZE : (n)+1) -#define pred(n) (((n)-1 < (ns->ns_txstart+PKTSZ)/DS_PGSIZE) ? ns->ns_rxend/DS_PGSIZE-1 : (n)-1) - -/* - * Controller interrupt. - */ -neintr(unit) -{ - register struct ne_softc *ns = &ne_softc[unit]; - u_char cmd,isr; - register nec = ns->ns_port; - - /* Save cmd, clear interrupt */ - cmd = inb (nec+ds_cmd); -loop: - isr = inb (nec+ds0_isr); - outb(nec+ds_cmd,DSCM_NODMA|DSCM_START); - outb(nec+ds0_isr, isr); - - /* Receiver error */ - if (isr & DSIS_RXE) { - /* need to read these registers to clear status */ - (void) inb(nec+ ds0_rsr); - (void) inb(nec+ 0xD); - (void) inb(nec + 0xE); - (void) inb(nec + 0xF); - ns->ns_if.if_ierrors++; - } - - /* We received something; rummage thru tiny ring buffer */ - if (isr & (DSIS_RX|DSIS_RXE|DSIS_ROVRN)) { - u_char pend,lastfree; - - outb(nec+ds_cmd, DSCM_START|DSCM_NODMA|DSCM_PG1); - pend = inb(nec+ds1_curr); - outb(nec+ds_cmd, DSCM_START|DSCM_NODMA|DSCM_PG0); - lastfree = inb(nec+ds0_bnry); - - /* Have we wrapped? */ - if (lastfree >= ns->ns_rxend/DS_PGSIZE) - lastfree = (ns->ns_txstart+PKTSZ)/DS_PGSIZE; - if (pend < lastfree && ns->ns_cur < pend) - lastfree = ns->ns_cur; - else if (ns->ns_cur > lastfree) - lastfree = ns->ns_cur; - - /* Something in the buffer? */ - while (pend != lastfree) { - u_char nxt; - - /* Extract header from microcephalic board */ - nefetch(ns, &ns->ns_ph,lastfree*DS_PGSIZE, - sizeof(ns->ns_ph)); - ns->ns_ba = lastfree*DS_PGSIZE+sizeof(ns->ns_ph); - - /* Incipient paranoia */ - if (ns->ns_ph.pr_status == DSRS_RPC || - /* for dequna's */ - ns->ns_ph.pr_status == 0x21) - nerecv (ns); -#ifdef NEDEBUG - else { - printf("cur %x pnd %x lfr %x ", - ns->ns_cur, pend, lastfree); - printf("nxt %x len %x ", ns->ns_ph.pr_nxtpg, - (ns->ns_ph.pr_sz1<<8)+ ns->ns_ph.pr_sz0); - printf("Bogus Sts %x\n", ns->ns_ph.pr_status); - } -#endif - - nxt = ns->ns_ph.pr_nxtpg ; - - /* Sanity check */ - if ( nxt >= (ns->ns_txstart+PKTSZ)/DS_PGSIZE - && nxt <= ns->ns_rxend/DS_PGSIZE && nxt <= pend) - ns->ns_cur = nxt; - else ns->ns_cur = nxt = pend; - - /* Set the boundaries */ - lastfree = nxt; - outb(nec+ds0_bnry, pred(nxt)); - outb(nec+ds_cmd, DSCM_START|DSCM_NODMA|DSCM_PG1); - pend = inb(nec+ds1_curr); - outb(nec+ds_cmd, DSCM_START|DSCM_NODMA|DSCM_PG0); - } - outb(nec+ds_cmd, DSCM_START|DSCM_NODMA); - } - - /* Transmit error */ - if (isr & DSIS_TXE) { - ns->ns_flags &= ~DSF_LOCK; - /* Need to read these registers to clear status */ - ns->ns_if.if_collisions += inb(nec+ds0_tbcr0); - ns->ns_if.if_oerrors++; - } - - /* Packet Transmitted */ - if (isr & DSIS_TX) { - ns->ns_flags &= ~DSF_LOCK; - ++ns->ns_if.if_opackets; - ns->ns_if.if_collisions += inb(nec+ds0_tbcr0); - } - - /* Receiver ovverun? */ - if (isr & DSIS_ROVRN) { - log(LOG_ERR, "ne%d: ring buffer overflow; isr=%x\n", - ns-ne_softc, isr/*, DSIS_BITS*/); - outb(nec+ds0_rbcr0, 0); - outb(nec+ds0_rbcr1, 0); - outb(nec+ds0_tcr, DSTC_LB0); - outb(nec+ds0_rcr, DSRC_MON); - outb(nec+ds_cmd, DSCM_START|DSCM_NODMA); - outb(nec+ds0_rcr, DSRC_AB); - outb(nec+ds0_tcr, 0); - } - - /* Any more to send? */ - outb (nec+ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_START); - nestart(&ns->ns_if); - outb (nec+ds_cmd, cmd); - outb (nec+ds0_imr, 0xff); - - /* Still more to do? */ - isr = inb (nec+ds0_isr); - if(isr) goto loop; -} - -/* - * Ethernet interface receiver interface. - * If input error just drop packet. - * Otherwise examine packet to determine type. If can't determine length - * from type, then have to drop packet. Othewise decapsulate - * packet based on type and pass to type specific higher-level - * input routine. - */ -nerecv(ns) - register struct ne_softc *ns; -{ - int len,i; - - ns->ns_if.if_ipackets++; - len = ns->ns_ph.pr_sz0 + (ns->ns_ph.pr_sz1<<8); - if(len < ETHER_MIN_LEN || len > ETHER_MAX_LEN) - return; - - /* this need not be so torturous - one/two bcopys at most into mbufs */ - nefetch(ns, ns->ns_pb, ns->ns_ba, min(len,DS_PGSIZE-sizeof(ns->ns_ph))); - if (len > DS_PGSIZE-sizeof(ns->ns_ph)) { - int l = len - (DS_PGSIZE-sizeof(ns->ns_ph)), b ; - u_char *p = ns->ns_pb + (DS_PGSIZE-sizeof(ns->ns_ph)); - - if (++ns->ns_cur >= ns->ns_rxend/DS_PGSIZE) - ns->ns_cur = (ns->ns_txstart+PKTSZ)/DS_PGSIZE; - b = ns->ns_cur*DS_PGSIZE; - - while (l >= DS_PGSIZE) { - nefetch(ns, p, b, DS_PGSIZE); - p += DS_PGSIZE; l -= DS_PGSIZE; - if (++ns->ns_cur >= ns->ns_rxend/DS_PGSIZE) - ns->ns_cur = (ns->ns_txstart+PKTSZ)/DS_PGSIZE; - b = ns->ns_cur*DS_PGSIZE; - } - if (l > 0) - nefetch(ns, p, b, l); - } - /* don't forget checksum! */ - len -= sizeof(long) + sizeof(struct ether_header); - - neread(ns,(caddr_t)(ns->ns_pb), len); -} - -/* - * Pass a packet to the higher levels. - * We deal with the trailer protocol here. - */ -neread(ns, buf, len) - register struct ne_softc *ns; - char *buf; - int len; -{ - register struct ether_header *eh; - struct mbuf *m; - int off, resid; - register struct ifqueue *inq; - u_short etype; - - /* - * Deal with trailer protocol: if type is trailer type - * get true type from first 16-bit word past data. - * Remember that type was trailer by setting off. - */ - eh = (struct ether_header *)buf; - etype = ntohs((u_short)eh->ether_type); -#define nedataaddr(eh, off, type) ((type)(((caddr_t)((eh)+1)+(off)))) - if (etype >= ETHERTYPE_TRAIL && - etype < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) { - off = (etype - ETHERTYPE_TRAIL) * 512; - if (off >= ETHERMTU) return; /* sanity */ - eh->ether_type = *nedataaddr(eh, off, u_short *); - resid = ntohs(*nedataaddr(eh, off+2, u_short *)); - if (off + resid > len) return; /* sanity */ - len = off + resid; - } else off = 0; - - if (len <= 0) return; - - /* - * Pull packet off interface. Off is nonzero if packet - * has trailing header; neget will then force this header - * information to be at the front, but we still have to drop - * the type and length which are at the front of any trailer data. - */ - m = neget(buf, len, off, &ns->ns_if); - if (m == 0) return; - -#if NBPFILTER > 0 - /* - * Check if there's a bpf filter listening on this interface. - * If so, hand off the raw packet to bpf. - */ - if (ns->ns_bpf) { - bpf_mtap(ns->ns_bpf, m); - } - - /* - * Note that the interface cannot be in promiscuous mode if - * there are no bpf listeners. And if we are in promiscuous - * mode, we have to check if this packet is really ours. - * - * XXX This test does not support multicasts. - */ - if ((ns->ns_if.if_flags & IFF_PROMISC) && - bcmp(eh->ether_dhost, ns->ns_addrp, - sizeof(eh->ether_dhost)) != 0 && - bcmp(eh->ether_dhost, etherbroadcastaddr, - sizeof(eh->ether_dhost)) != 0) { - - m_freem(m); - return; - } -#endif - - /* - * Drop packet header and save fixed up ether_type. - */ -#if NBPFILTER > 0 - m_adj(m, sizeof(struct ether_header)); -#endif - ether_input(&ns->ns_if, eh, m); -} - -/* - * Supporting routines - */ - -/* - * Pull read data off a interface. - * Len is length of data, with local net header stripped. - * Off is non-zero if a trailer protocol was used, and - * gives the offset of the trailer information. - * We copy the trailer information and then all the normal - * data into mbufs. When full cluster sized units are present - * we copy into clusters. - */ -struct mbuf * -neget(buf, totlen, off, ifp) - caddr_t buf; - int totlen, off; - struct ifnet *ifp; -{ - struct mbuf *top, *last, *m; - int len; - register caddr_t cp; - - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == 0) - return (0); - top = last = m; - -#if NBPFILTER > 0 - /* - * Copy the ethernet header first. - * XXX: This assumes that ether_header fits inside the mbuf. - */ - /* - * XXX: This line is to avoid `nfs_rcv odd length!' spewage. - */ - m->m_data += (MHLEN - sizeof(struct ether_header)) & 3; - bcopy(buf, mtod(m, caddr_t), sizeof(struct ether_header)); - m->m_len = sizeof(struct ether_header); - m->m_pkthdr.len = totlen + sizeof(struct ether_header); -#else - m->m_len = 0; - m->m_pkthdr.len = totlen; -#endif - m->m_pkthdr.rcvif = ifp; - - buf += sizeof(struct ether_header); - cp = buf; - - if (off) { - cp += off + 2 * sizeof(u_short); - totlen -= off + 2 * sizeof(u_short); - } - - copy: - while (totlen > 0) { - len = min(totlen, M_TRAILINGSPACE(m)); - if (!len) { - MGET(m, M_DONTWAIT, MT_DATA); - if (m == 0) { - m_freem(top); - return (0); - } - if (totlen >= MINCLSIZE) { - MCLGET(m, M_DONTWAIT); - if (m == 0) { - m_freem(top); - return (0); - } - } - m->m_len = 0; - last->m_next = m; - last = m; - len = min(totlen, M_TRAILINGSPACE(m)); - } - - bcopy(cp, mtod(m, caddr_t) + m->m_len, len); - m->m_len += len; - totlen -= len; - cp += len; - } - - if (off) { - totlen = off; - cp = buf; - off = 0; - goto copy; - } - - return (top); -} - -/* - * Process an ioctl request. - */ -neioctl(ifp, cmd, data) - register struct ifnet *ifp; - int cmd; - caddr_t data; -{ - register struct ifaddr *ifa = (struct ifaddr *)data; - struct ne_softc *ns = &ne_softc[ifp->if_unit]; - struct ifreq *ifr = (struct ifreq *)data; - int s = splimp(), error = 0; - - - switch (cmd) { - - case SIOCSIFADDR: - ifp->if_flags |= IFF_UP; - - switch (ifa->ifa_addr->sa_family) { -#ifdef INET - case AF_INET: - neinit(ifp->if_unit); /* before arpwhohas */ - ((struct arpcom *)ifp)->ac_ipaddr = - IA_SIN(ifa)->sin_addr; - arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr); - break; -#endif -#ifdef NS - case AF_NS: - { - register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); - - if (ns_nullhost(*ina)) - ina->x_host = *(union ns_host *)(ns->ns_addrp); - else { - /* - * The manual says we can't change the address - * while the receiver is armed, - * so reset everything - */ - ifp->if_flags &= ~IFF_RUNNING; - bcopy((caddr_t)ina->x_host.c_host, - (caddr_t)ns->ns_addrp, sizeof(ns->ns_addrp)); - } - neinit(ifp->if_unit); /* does ne_setaddr() */ - break; - } -#endif - default: - neinit(ifp->if_unit); - break; - } - break; - - case SIOCSIFFLAGS: - if ((ifp->if_flags & IFF_UP) == 0 && - ifp->if_flags & IFF_RUNNING) { - ifp->if_flags &= ~IFF_RUNNING; - outb(ns->ns_port + ds_cmd, DSCM_STOP|DSCM_NODMA); - } else if (ifp->if_flags & IFF_UP && - (ifp->if_flags & IFF_RUNNING) == 0) { - neinit(ifp->if_unit); - break; - } -#if NBPFILTER > 0 - if (ns->ns_if.if_flags & IFF_PROMISC) - outb (ns->ns_port+ds0_rcr, DSRC_AB | DSRC_PRO | - DSRC_AR | DSRC_SEP); - else -#endif - outb (ns->ns_port+ds0_rcr, DSRC_AB); - break; - -#ifdef notdef - case SIOCGHWADDR: - bcopy((caddr_t)ns->ns_addr, (caddr_t) &ifr->ifr_data, - sizeof(ns->ns_addr)); - break; -#endif - - default: - error = EINVAL; - } - splx(s); - return (error); -} -#endif diff --git a/sys/arch/i386/isa/if_nereg.h b/sys/arch/i386/isa/if_nereg.h deleted file mode 100644 index 72c618ce62ca..000000000000 --- a/sys/arch/i386/isa/if_nereg.h +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * Copyright (c) 1991 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. - * - * from: @(#)if_nereg.h 7.1 (Berkeley) 5/9/91 - * $Id: if_nereg.h,v 1.2 1993/05/22 08:01:24 cgd Exp $ - */ - -/* - * NE1000/2000 Ethernet Card registers - */ - -/* This card uses a DS8390 Ethernet controller in at the beginning of - its i/o space */ -#include "ic/ds8390.h" - -#define ne_data 0x10 /* Data Transfer port */ -#define ne_reset 0x1f /* Card Reset port */ - -#define PKTSZ 3*512 /* Size of transmit buffer */ - -/* Span of memory on an NE2000 */ -#define TBUF16 (16*1024) /* Starting location of Transmit Buffer */ -#define RBUFEND16 (32*1024) /* Ending location of Receive Buffer */ - -/* Span of memory on an NE1000 */ -#define TBUF8 (8*1024) /* Starting location of Transmit Buffer */ -#define RBUFEND8 (16*1024) /* Ending location of Receive Buffer */