Home | History | Annotate | Line # | Download | only in dev
if_ie.c revision 1.51
      1 /*	$NetBSD: if_ie.c,v 1.51 2008/06/28 12:13:38 tsutsui Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 1993, 1994, 1995 Charles M. Hannum.
      5  * Copyright (c) 1992, 1993, University of Vermont and State
      6  *  Agricultural College.
      7  * Copyright (c) 1992, 1993, Garrett A. Wollman.
      8  *
      9  * Portions:
     10  * Copyright (c) 1994, 1995, Rafal K. Boni
     11  * Copyright (c) 1990, 1991, William F. Jolitz
     12  * Copyright (c) 1990, The Regents of the University of California
     13  *
     14  * All rights reserved.
     15  *
     16  * Redistribution and use in source and binary forms, with or without
     17  * modification, are permitted provided that the following conditions
     18  * are met:
     19  * 1. Redistributions of source code must retain the above copyright
     20  *    notice, this list of conditions and the following disclaimer.
     21  * 2. Redistributions in binary form must reproduce the above copyright
     22  *    notice, this list of conditions and the following disclaimer in the
     23  *    documentation and/or other materials provided with the distribution.
     24  * 3. All advertising materials mentioning features or use of this software
     25  *    must display the following acknowledgement:
     26  *	This product includes software developed by Charles M. Hannum, by the
     27  *	University of Vermont and State Agricultural College and Garrett A.
     28  *	Wollman, by William F. Jolitz, and by the University of California,
     29  *	Berkeley, Lawrence Berkeley Laboratory, and its contributors.
     30  * 4. Neither the names of the Universities nor the names of the authors
     31  *    may be used to endorse or promote products derived from this software
     32  *    without specific prior written permission.
     33  *
     34  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     35  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     36  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     37  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR AUTHORS BE LIABLE
     38  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     39  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     40  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     41  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     42  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     43  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     44  * SUCH DAMAGE.
     45  */
     46 
     47 /*
     48  * Intel 82586 Ethernet chip
     49  * Register, bit, and structure definitions.
     50  *
     51  * Original StarLAN driver written by Garrett Wollman with reference to the
     52  * Clarkson Packet Driver code for this chip written by Russ Nelson and others.
     53  *
     54  * BPF support code taken from hpdev/if_le.c, supplied with tcpdump.
     55  *
     56  * 3C507 support is loosely based on code donated to NetBSD by Rafal Boni.
     57  *
     58  * Majorly cleaned up and 3C507 code merged by Charles Hannum.
     59  *
     60  * Converted to SUN ie driver by Charles D. Cranor,
     61  *		October 1994, January 1995.
     62  * This sun version based on i386 version 1.30.
     63  * [ see sys/dev/isa/if_ie.c ]
     64  */
     65 
     66 /*
     67  * The i82586 is a very painful chip, found in sun3's, sun-4/100's
     68  * sun-4/200's, and VME based suns.  The byte order is all wrong for a
     69  * SUN, making life difficult.  Programming this chip is mostly the same,
     70  * but certain details differ from system to system.  This driver is
     71  * written so that different "ie" interfaces can be controled by the same
     72  * driver.
     73  */
     74 
     75 /*
     76    Mode of operation:
     77 
     78    We run the 82586 in a standard Ethernet mode.  We keep NFRAMES
     79    received frame descriptors around for the receiver to use, and
     80    NRXBUF associated receive buffer descriptors, both in a circular
     81    list.  Whenever a frame is received, we rotate both lists as
     82    necessary.  (The 586 treats both lists as a simple queue.)  We also
     83    keep a transmit command around so that packets can be sent off
     84    quickly.
     85 
     86    We configure the adapter in AL-LOC = 1 mode, which means that the
     87    Ethernet/802.3 MAC header is placed at the beginning of the receive
     88    buffer rather than being split off into various fields in the RFD.
     89    This also means that we must include this header in the transmit
     90    buffer as well.
     91 
     92    By convention, all transmit commands, and only transmit commands,
     93    shall have the I (IE_CMD_INTR) bit set in the command.  This way,
     94    when an interrupt arrives at ieintr(), it is immediately possible
     95    to tell what precisely caused it.  ANY OTHER command-sending
     96    routines should run at splnet(), and should post an acknowledgement
     97    to every interrupt they generate.
     98 */
     99 
    100 #include <sys/cdefs.h>
    101 __KERNEL_RCSID(0, "$NetBSD: if_ie.c,v 1.51 2008/06/28 12:13:38 tsutsui Exp $");
    102 
    103 #include "opt_inet.h"
    104 #include "opt_ns.h"
    105 #include "bpfilter.h"
    106 
    107 #include <sys/param.h>
    108 #include <sys/systm.h>
    109 #include <sys/mbuf.h>
    110 #include <sys/buf.h>
    111 #include <sys/protosw.h>
    112 #include <sys/socket.h>
    113 #include <sys/ioctl.h>
    114 #include <sys/errno.h>
    115 #include <sys/syslog.h>
    116 #include <sys/device.h>
    117 
    118 #include <net/if.h>
    119 #include <net/if_types.h>
    120 #include <net/if_dl.h>
    121 #include <net/if_ether.h>
    122 
    123 #if NBPFILTER > 0
    124 #include <net/bpf.h>
    125 #include <net/bpfdesc.h>
    126 #endif
    127 
    128 #ifdef INET
    129 #include <netinet/in.h>
    130 #include <netinet/in_systm.h>
    131 #include <netinet/in_var.h>
    132 #include <netinet/ip.h>
    133 #include <netinet/if_inarp.h>
    134 #endif
    135 
    136 #ifdef NS
    137 #include <netns/ns.h>
    138 #include <netns/ns_if.h>
    139 #endif
    140 
    141 #include <uvm/uvm_extern.h>
    142 
    143 #include <machine/autoconf.h>
    144 #include <machine/cpu.h>
    145 #include <machine/pmap.h>
    146 
    147 /*
    148  * ugly byte-order hack for SUNs
    149  */
    150 
    151 #define XSWAP(y)	( (((y) & 0xff00) >> 8) | (((y) & 0xff) << 8) )
    152 #define SWAP(x)		((u_short)(XSWAP((u_short)(x))))
    153 
    154 #include "i82586.h"
    155 #include "if_iereg.h"
    156 #include "if_ievar.h"
    157 
    158 /* #define	IEDEBUG	XXX */
    159 
    160 /*
    161  * IED: ie debug flags
    162  */
    163 
    164 #define	IED_RINT	0x01
    165 #define	IED_TINT	0x02
    166 #define	IED_RNR		0x04
    167 #define	IED_CNA		0x08
    168 #define	IED_READFRAME	0x10
    169 #define	IED_ENQ		0x20
    170 #define	IED_XMIT	0x40
    171 #define	IED_ALL		0x7f
    172 
    173 #ifdef	IEDEBUG
    174 #define	inline	/* not */
    175 void print_rbd(volatile struct ie_recv_buf_desc *);
    176 int     in_ierint = 0;
    177 int     in_ietint = 0;
    178 int     ie_debug_flags = 0;
    179 #endif
    180 
    181 /* XXX - Skip TDR for now - it always complains... */
    182 int 	ie_run_tdr = 0;
    183 
    184 static void iewatchdog(struct ifnet *);
    185 static int ieinit(struct ie_softc *);
    186 static int ieioctl(struct ifnet *, u_long, void *);
    187 static void iestart(struct ifnet *);
    188 static void iereset(struct ie_softc *);
    189 static int ie_setupram(struct ie_softc *);
    190 
    191 static int cmd_and_wait(struct ie_softc *, int, void *, int);
    192 
    193 static void ie_drop_packet_buffer(struct ie_softc *);
    194 static void ie_readframe(struct ie_softc *, int);
    195 static inline void ie_setup_config(struct ie_config_cmd *, int, int);
    196 
    197 static void ierint(struct ie_softc *);
    198 static void iestop(struct ie_softc *);
    199 static void ietint(struct ie_softc *);
    200 static void iexmit(struct ie_softc *);
    201 
    202 static int mc_setup(struct ie_softc *, void *);
    203 static void mc_reset(struct ie_softc *);
    204 static void run_tdr(struct ie_softc *, struct ie_tdr_cmd *);
    205 static void iememinit(struct ie_softc *);
    206 
    207 static inline uint8_t *Align(char *);
    208 static inline u_int Swap32(u_int);
    209 static inline u_int vtop24(struct ie_softc *, void *);
    210 static inline uint16_t vtop16sw(struct ie_softc *, void *);
    211 
    212 static inline void ie_ack(struct ie_softc *, u_int);
    213 static inline u_short ether_cmp(u_char *, uint8_t *);
    214 static inline int check_eh(struct ie_softc *, struct ether_header *, int *);
    215 static inline int ie_buflen(struct ie_softc *, int);
    216 static inline int ie_packet_len(struct ie_softc *);
    217 static inline struct mbuf * ieget(struct ie_softc *, int *);
    218 
    219 
    220 /*
    221  * Here are a few useful functions.  We could have done these as macros,
    222  * but since we have the inline facility, it makes sense to use that
    223  * instead.
    224  */
    225 
    226 /* KVA to 24 bit device address */
    227 static inline u_int
    228 vtop24(struct ie_softc *sc, void *ptr)
    229 {
    230 	u_int pa;
    231 
    232 	pa = (vaddr_t)ptr - (vaddr_t)sc->sc_iobase;
    233 #ifdef	IEDEBUG
    234 	if (pa & ~0xffFFff)
    235 		panic("ie:vtop24");
    236 #endif
    237 	return pa;
    238 }
    239 
    240 /* KVA to 16 bit offset, swapped */
    241 static inline u_short
    242 vtop16sw(struct ie_softc *sc, void *ptr)
    243 {
    244 	u_int pa;
    245 
    246 	pa = (vaddr_t)ptr - (vaddr_t)sc->sc_maddr;
    247 #ifdef	IEDEBUG
    248 	if (pa & ~0xFFff)
    249 		panic("ie:vtop16");
    250 #endif
    251 
    252 	return SWAP(pa);
    253 }
    254 
    255 static inline u_int
    256 Swap32(u_int x)
    257 {
    258 	u_int y;
    259 
    260 	y = x & 0xFF;
    261 	y <<= 8; x >>= 8;
    262 	y |= x & 0xFF;
    263 	y <<= 8; x >>= 8;
    264 	y |= x & 0xFF;
    265 	y <<= 8; x >>= 8;
    266 	y |= x & 0xFF;
    267 
    268 	return y;
    269 }
    270 
    271 static inline uint8_t *
    272 Align(char *ptr)
    273 {
    274 	u_long  l = (u_long)ptr;
    275 
    276 	l = (l + 3) & ~3L;
    277 	return (uint8_t *)l;
    278 }
    279 
    280 
    281 static inline void
    282 ie_ack(struct ie_softc *sc, u_int mask)
    283 {
    284 	volatile struct ie_sys_ctl_block *scb = sc->scb;
    285 
    286 	cmd_and_wait(sc, scb->ie_status & mask, 0, 0);
    287 }
    288 
    289 
    290 /*
    291  * Taken almost exactly from Bill's if_is.c,
    292  * then modified beyond recognition...
    293  */
    294 void
    295 ie_attach(struct ie_softc *sc)
    296 {
    297 	struct ifnet *ifp = &sc->sc_if;
    298 
    299 	/* MD code has done its part before calling this. */
    300 	printf(": macaddr %s\n", ether_sprintf(sc->sc_addr));
    301 
    302 	/*
    303 	 * Compute number of transmit and receive buffers.
    304 	 * Tx buffers take 1536 bytes, and fixed in number.
    305 	 * Rx buffers are 512 bytes each, variable number.
    306 	 * Need at least 1 frame for each 3 rx buffers.
    307 	 * The ratio 3bufs:2frames is a compromise.
    308 	 */
    309 	sc->ntxbuf = NTXBUF;	/* XXX - Fix me... */
    310 	switch (sc->sc_msize) {
    311 	case 16384:
    312 		sc->nframes = 8 * 4;
    313 		sc->nrxbuf  = 8 * 6;
    314 		break;
    315 	case 32768:
    316 		sc->nframes = 16 * 4;
    317 		sc->nrxbuf  = 16 * 6;
    318 		break;
    319 	case 65536:
    320 		sc->nframes = 32 * 4;
    321 		sc->nrxbuf  = 32 * 6;
    322 		break;
    323 	default:
    324 		sc->nframes = 0;
    325 	}
    326 	if (sc->nframes > MXFRAMES)
    327 		sc->nframes = MXFRAMES;
    328 	if (sc->nrxbuf > MXRXBUF)
    329 		sc->nrxbuf = MXRXBUF;
    330 
    331 #ifdef	IEDEBUG
    332 	aprint_debug_dev(sc->sc_dev,
    333 	    "%dK memory, %d tx frames, %d rx frames, %d rx bufs\n",
    334 	    (sc->sc_msize >> 10), sc->ntxbuf, sc->nframes, sc->nrxbuf);
    335 #endif
    336 
    337 	if ((sc->nframes <= 0) || (sc->nrxbuf <= 0))
    338 		panic("%s: weird memory size", __func__);
    339 
    340 	/*
    341 	 * Setup RAM for transmit/receive
    342 	 */
    343 	if (ie_setupram(sc) == 0) {
    344 		aprint_error(": RAM CONFIG FAILED!\n");
    345 		/* XXX should reclaim resources? */
    346 		return;
    347 	}
    348 
    349 	/*
    350 	 * Initialize and attach S/W interface
    351 	 */
    352 	strcpy(ifp->if_xname, device_xname(sc->sc_dev));
    353 	ifp->if_softc = sc;
    354 	ifp->if_start = iestart;
    355 	ifp->if_ioctl = ieioctl;
    356 	ifp->if_watchdog = iewatchdog;
    357 	ifp->if_flags =
    358 	    IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
    359 
    360 	/* Attach the interface. */
    361 	if_attach(ifp);
    362 	ether_ifattach(ifp, sc->sc_addr);
    363 }
    364 
    365 /*
    366  * Setup IE's ram space.
    367  */
    368 static int
    369 ie_setupram(struct ie_softc *sc)
    370 {
    371 	volatile struct ie_sys_conf_ptr *scp;
    372 	volatile struct ie_int_sys_conf_ptr *iscp;
    373 	volatile struct ie_sys_ctl_block *scb;
    374 	int off;
    375 
    376 	/*
    377 	 * Allocate from end of buffer space for
    378 	 * ISCP, SCB, and other small stuff.
    379 	 */
    380 	off = sc->buf_area_sz;
    381 	off &= ~3;
    382 
    383 	/* SCP (address already chosen). */
    384 	scp = sc->scp;
    385 	(sc->sc_memset)(__UNVOLATILE(scp), 0, sizeof(*scp));
    386 
    387 	/* ISCP */
    388 	off -= sizeof(*iscp);
    389 	iscp = (volatile void *)(sc->buf_area + off);
    390 	(sc->sc_memset)(__UNVOLATILE(iscp), 0, sizeof(*iscp));
    391 	sc->iscp = iscp;
    392 
    393 	/* SCB */
    394 	off -= sizeof(*scb);
    395 	scb  = (volatile void *)(sc->buf_area + off);
    396 	(sc->sc_memset)(__UNVOLATILE(scb), 0, sizeof(*scb));
    397 	sc->scb = scb;
    398 
    399 	/* Remainder is for buffers, etc. */
    400 	sc->buf_area_sz = off;
    401 
    402 	/*
    403 	 * Now fill in the structures we just allocated.
    404 	 */
    405 
    406 	/* SCP: main thing is 24-bit ptr to ISCP */
    407 	scp->ie_bus_use = 0;	/* 16-bit */
    408 	scp->ie_iscp_ptr = Swap32(vtop24(sc, __UNVOLATILE(iscp)));
    409 
    410 	/* ISCP */
    411 	iscp->ie_busy = 1;	/* ie_busy == char */
    412 	iscp->ie_scb_offset = vtop16sw(sc, __UNVOLATILE(scb));
    413 	iscp->ie_base = Swap32(vtop24(sc, sc->sc_maddr));
    414 
    415 	/* SCB */
    416 	scb->ie_command_list = SWAP(0xffff);
    417 	scb->ie_recv_list    = SWAP(0xffff);
    418 
    419 	/* Other stuff is done in ieinit() */
    420 	(sc->reset_586)(sc);
    421 	(sc->chan_attn)(sc);
    422 
    423 	delay(100);		/* wait a while... */
    424 
    425 	if (iscp->ie_busy) {
    426 		return 0;
    427 	}
    428 	/*
    429 	 * Acknowledge any interrupts we may have caused...
    430 	 */
    431 	ie_ack(sc, IE_ST_WHENCE);
    432 
    433 	return 1;
    434 }
    435 
    436 /*
    437  * Device timeout/watchdog routine.  Entered if the device neglects to
    438  * generate an interrupt after a transmit has been started on it.
    439  */
    440 static void
    441 iewatchdog(struct ifnet *ifp)
    442 {
    443 	struct ie_softc *sc = ifp->if_softc;
    444 
    445 	log(LOG_ERR, "%s: device timeout\n", device_xname(sc->sc_dev));
    446 	++ifp->if_oerrors;
    447 	iereset(sc);
    448 }
    449 
    450 /*
    451  * What to do upon receipt of an interrupt.
    452  */
    453 int
    454 ie_intr(void *arg)
    455 {
    456 	struct ie_softc *sc = arg;
    457 	uint16_t status;
    458 	int loopcnt;
    459 
    460 	/*
    461 	 * check for parity error
    462 	 */
    463 	if (sc->hard_type == IE_VME) {
    464 		volatile struct ievme *iev =
    465 		    (volatile struct ievme *)sc->sc_reg;
    466 
    467 		if (iev->status & IEVME_PERR) {
    468 			printf("%s: parity error (ctrl 0x%x @ 0x%02x%04x)\n",
    469 			    device_xname(sc->sc_dev), iev->pectrl,
    470 			    iev->pectrl & IEVME_HADDR, iev->peaddr);
    471 			iev->pectrl = iev->pectrl | IEVME_PARACK;
    472 		}
    473 	}
    474 
    475 	status = sc->scb->ie_status;
    476 	if ((status & IE_ST_WHENCE) == 0)
    477 		return 0;
    478 
    479 	loopcnt = sc->nframes;
    480  loop:
    481 	/* Ack interrupts FIRST in case we receive more during the ISR. */
    482 	ie_ack(sc, IE_ST_WHENCE & status);
    483 
    484 	if (status & (IE_ST_RECV | IE_ST_RNR)) {
    485 #ifdef IEDEBUG
    486 		in_ierint++;
    487 		if (sc->sc_debug & IED_RINT)
    488 			printf("%s: rint\n", device_xname(sc->sc_dev));
    489 #endif
    490 		ierint(sc);
    491 #ifdef IEDEBUG
    492 		in_ierint--;
    493 #endif
    494 	}
    495 
    496 	if (status & IE_ST_DONE) {
    497 #ifdef IEDEBUG
    498 		in_ietint++;
    499 		if (sc->sc_debug & IED_TINT)
    500 			printf("%s: tint\n", device_xname(sc->sc_dev));
    501 #endif
    502 		ietint(sc);
    503 #ifdef IEDEBUG
    504 		in_ietint--;
    505 #endif
    506 	}
    507 
    508 	/*
    509 	 * Receiver not ready (RNR) just means it has
    510 	 * run out of resources (buffers or frames).
    511 	 * One can easily cause this with (i.e.) spray.
    512 	 * This is not a serious error, so be silent.
    513 	 */
    514 	if (status & IE_ST_RNR) {
    515 #ifdef IEDEBUG
    516 		printf("%s: receiver not ready\n", device_xname(sc->sc_dev));
    517 #endif
    518 		sc->sc_if.if_ierrors++;
    519 		iereset(sc);
    520 	}
    521 
    522 #ifdef IEDEBUG
    523 	if ((status & IE_ST_ALLDONE) && (sc->sc_debug & IED_CNA))
    524 		printf("%s: cna\n", device_xname(sc->sc_dev));
    525 #endif
    526 
    527 	status = sc->scb->ie_status;
    528 	if (status & IE_ST_WHENCE) {
    529 		/* It still wants service... */
    530 		if (--loopcnt > 0)
    531 			goto loop;
    532 		/* ... but we've been here long enough. */
    533 		log(LOG_ERR, "%s: interrupt stuck?\n",
    534 		    device_xname(sc->sc_dev));
    535 		iereset(sc);
    536 	}
    537 	return 1;
    538 }
    539 
    540 /*
    541  * Process a received-frame interrupt.
    542  */
    543 void
    544 ierint(struct ie_softc *sc)
    545 {
    546 	volatile struct ie_sys_ctl_block *scb = sc->scb;
    547 	int i, status;
    548 	static int timesthru = 1024;
    549 
    550 	i = sc->rfhead;
    551 	for (;;) {
    552 		status = sc->rframes[i]->ie_fd_status;
    553 
    554 		if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) {
    555 			if (!--timesthru) {
    556 				sc->sc_if.if_ierrors +=
    557 				    SWAP(scb->ie_err_crc) +
    558 				    SWAP(scb->ie_err_align) +
    559 				    SWAP(scb->ie_err_resource) +
    560 				    SWAP(scb->ie_err_overrun);
    561 				scb->ie_err_crc = 0;
    562 				scb->ie_err_align = 0;
    563 				scb->ie_err_resource = 0;
    564 				scb->ie_err_overrun = 0;
    565 				timesthru = 1024;
    566 			}
    567 			ie_readframe(sc, i);
    568 		} else {
    569 			if ((status & IE_FD_RNR) != 0 &&
    570 			    (scb->ie_status & IE_RU_READY) == 0) {
    571 				sc->rframes[0]->ie_fd_buf_desc = vtop16sw(sc,
    572 				    __UNVOLATILE(sc->rbuffs[0]));
    573 				scb->ie_recv_list = vtop16sw(sc,
    574 				    __UNVOLATILE(sc->rframes[0]));
    575 				cmd_and_wait(sc, IE_RU_START, 0, 0);
    576 			}
    577 			break;
    578 		}
    579 		i = (i + 1) % sc->nframes;
    580 	}
    581 }
    582 
    583 /*
    584  * Process a command-complete interrupt.  These are only generated by the
    585  * transmission of frames.  This routine is deceptively simple, since most
    586  * of the real work is done by iestart().
    587  */
    588 void
    589 ietint(struct ie_softc *sc)
    590 {
    591 	struct ifnet *ifp;
    592 	int status;
    593 
    594 	ifp = &sc->sc_if;
    595 
    596 	ifp->if_timer = 0;
    597 	ifp->if_flags &= ~IFF_OACTIVE;
    598 
    599 	status = sc->xmit_cmds[sc->xctail]->ie_xmit_status;
    600 
    601 	if (!(status & IE_STAT_COMPL) || (status & IE_STAT_BUSY))
    602 		printf("%s: command still busy!\n", __func__);
    603 
    604 	if (status & IE_STAT_OK) {
    605 		ifp->if_opackets++;
    606 		ifp->if_collisions +=
    607 		  SWAP(status & IE_XS_MAXCOLL);
    608 	} else {
    609 		ifp->if_oerrors++;
    610 		/*
    611 		 * XXX
    612 		 * Check SQE and DEFERRED?
    613 		 * What if more than one bit is set?
    614 		 */
    615 		if (status & IE_STAT_ABORT)
    616 			printf("%s: send aborted\n", device_xname(sc->sc_dev));
    617 		if (status & IE_XS_LATECOLL)
    618 			printf("%s: late collision\n",
    619 			    device_xname(sc->sc_dev));
    620 		if (status & IE_XS_NOCARRIER)
    621 			printf("%s: no carrier\n", device_xname(sc->sc_dev));
    622 		if (status & IE_XS_LOSTCTS)
    623 			printf("%s: lost CTS\n", device_xname(sc->sc_dev));
    624 		if (status & IE_XS_UNDERRUN)
    625 			printf("%s: DMA underrun\n", device_xname(sc->sc_dev));
    626 		if (status & IE_XS_EXCMAX) {
    627 			/* Do not print this one (too noisy). */
    628 			ifp->if_collisions += 16;
    629 		}
    630 	}
    631 
    632 	/*
    633 	 * If multicast addresses were added or deleted while we
    634 	 * were transmitting, mc_reset() set the want_mcsetup flag
    635 	 * indicating that we should do it.
    636 	 */
    637 	if (sc->want_mcsetup) {
    638 		mc_setup(sc, (void *)sc->xmit_cbuffs[sc->xctail]);
    639 		sc->want_mcsetup = 0;
    640 	}
    641 
    642 	/* Done with the buffer. */
    643 	sc->xmit_busy--;
    644 	sc->xctail = (sc->xctail + 1) % NTXBUF;
    645 
    646 	/* Start the next packet, if any, transmitting. */
    647 	if (sc->xmit_busy > 0)
    648 		iexmit(sc);
    649 
    650 	iestart(ifp);
    651 }
    652 
    653 /*
    654  * Compare two Ether/802 addresses for equality, inlined and
    655  * unrolled for speed.  I'd love to have an inline assembler
    656  * version of this...   XXX: Who wanted that? mycroft?
    657  * I wrote one, but the following is just as efficient.
    658  * This expands to 10 short m68k instructions! -gwr
    659  * Note: use this like bcmp()
    660  */
    661 static inline uint16_t
    662 ether_cmp(uint8_t *one, uint8_t *two)
    663 {
    664 	uint16_t *a = (uint16_t *)one;
    665 	uint16_t *b = (uint16_t *)two;
    666 	uint16_t diff;
    667 
    668 	diff  = *a++ - *b++;
    669 	diff |= *a++ - *b++;
    670 	diff |= *a++ - *b++;
    671 
    672 	return diff;
    673 }
    674 #define	ether_equal !ether_cmp
    675 
    676 /*
    677  * Check for a valid address.  to_bpf is filled in with one of the following:
    678  *   0 -> BPF doesn't get this packet
    679  *   1 -> BPF does get this packet
    680  *   2 -> BPF does get this packet, but we don't
    681  * Return value is true if the packet is for us, and false otherwise.
    682  *
    683  * This routine is a mess, but it's also critical that it be as fast
    684  * as possible.  It could be made cleaner if we can assume that the
    685  * only client which will fiddle with IFF_PROMISC is BPF.  This is
    686  * probably a good assumption, but we do not make it here.  (Yet.)
    687  */
    688 static inline int
    689 check_eh(struct ie_softc *sc, struct ether_header *eh, int *to_bpf)
    690 {
    691 #if NBPFILTER > 0
    692 	struct ifnet *ifp;
    693 
    694 	ifp = &sc->sc_if;
    695 	*to_bpf = (ifp->if_bpf != 0);
    696 #endif
    697 
    698 	/*
    699 	 * This is all handled at a higher level now.
    700 	 */
    701 	return 1;
    702 }
    703 
    704 /*
    705  * We want to isolate the bits that have meaning...  This assumes that
    706  * IE_RBUF_SIZE is an even power of two.  If somehow the act_len exceeds
    707  * the size of the buffer, then we are screwed anyway.
    708  */
    709 static inline int
    710 ie_buflen(struct ie_softc *sc, int head)
    711 {
    712 	int len;
    713 
    714 	len = SWAP(sc->rbuffs[head]->ie_rbd_actual);
    715 	len &= (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1));
    716 	return len;
    717 }
    718 
    719 static inline int
    720 ie_packet_len(struct ie_softc *sc)
    721 {
    722 	int i;
    723 	int head = sc->rbhead;
    724 	int acc = 0;
    725 
    726 	do {
    727 		if ((sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)
    728 		    == 0) {
    729 #ifdef IEDEBUG
    730 			print_rbd(sc->rbuffs[sc->rbhead]);
    731 #endif
    732 			log(LOG_ERR,
    733 			    "%s: receive descriptors out of sync at %d\n",
    734 			    device_xname(sc->sc_dev), sc->rbhead);
    735 			iereset(sc);
    736 			return -1;
    737 		}
    738 
    739 		i = sc->rbuffs[head]->ie_rbd_actual & IE_RBD_LAST;
    740 
    741 		acc += ie_buflen(sc, head);
    742 		head = (head + 1) % sc->nrxbuf;
    743 	} while (i == 0);
    744 
    745 	return acc;
    746 }
    747 
    748 /*
    749  * Setup all necessary artifacts for an XMIT command, and then pass the XMIT
    750  * command to the chip to be executed.  On the way, if we have a BPF listener
    751  * also give him a copy.
    752  */
    753 static void
    754 iexmit(struct ie_softc *sc)
    755 {
    756 	struct ifnet *ifp;
    757 
    758 	ifp = &sc->sc_if;
    759 
    760 #ifdef IEDEBUG
    761 	if (sc->sc_debug & IED_XMIT)
    762 		printf("%s: xmit buffer %d\n", device_xname(sc->sc_dev),
    763 		    sc->xctail);
    764 #endif
    765 
    766 #if NBPFILTER > 0
    767 	/*
    768 	 * If BPF is listening on this interface, let it see the packet before
    769 	 * we push it on the wire.
    770 	 */
    771 	if (ifp->if_bpf)
    772 		bpf_tap(ifp->if_bpf,
    773 		    sc->xmit_cbuffs[sc->xctail],
    774 		    SWAP(sc->xmit_buffs[sc->xctail]->ie_xmit_flags));
    775 #endif
    776 
    777 	sc->xmit_buffs[sc->xctail]->ie_xmit_flags |= IE_XMIT_LAST;
    778 	sc->xmit_buffs[sc->xctail]->ie_xmit_next = SWAP(0xffff);
    779 	sc->xmit_buffs[sc->xctail]->ie_xmit_buf =
    780 	    Swap32(vtop24(sc, sc->xmit_cbuffs[sc->xctail]));
    781 
    782 	sc->xmit_cmds[sc->xctail]->com.ie_cmd_link = SWAP(0xffff);
    783 	sc->xmit_cmds[sc->xctail]->com.ie_cmd_cmd =
    784 	    IE_CMD_XMIT | IE_CMD_INTR | IE_CMD_LAST;
    785 
    786 	sc->xmit_cmds[sc->xctail]->ie_xmit_status = SWAP(0);
    787 	sc->xmit_cmds[sc->xctail]->ie_xmit_desc =
    788 	    vtop16sw(sc, __UNVOLATILE(sc->xmit_buffs[sc->xctail]));
    789 
    790 	sc->scb->ie_command_list =
    791 	    vtop16sw(sc, __UNVOLATILE(sc->xmit_cmds[sc->xctail]));
    792 	cmd_and_wait(sc, IE_CU_START, 0, 0);
    793 
    794 	ifp->if_timer = 5;
    795 }
    796 
    797 /*
    798  * Read data off the interface, and turn it into an mbuf chain.
    799  *
    800  * This code is DRAMATICALLY different from the previous version; this
    801  * version tries to allocate the entire mbuf chain up front, given the
    802  * length of the data available.  This enables us to allocate mbuf
    803  * clusters in many situations where before we would have had a long
    804  * chain of partially-full mbufs.  This should help to speed up the
    805  * operation considerably.  (Provided that it works, of course.)
    806  */
    807 static inline struct mbuf *
    808 ieget(struct ie_softc *sc, int *to_bpf)
    809 {
    810 	struct mbuf *top, **mp, *m;
    811 	int len, totlen, resid;
    812 	int thisrboff, thismboff;
    813 	int head;
    814 	struct ether_header eh;
    815 
    816 	totlen = ie_packet_len(sc);
    817 	if (totlen <= 0)
    818 		return 0;
    819 
    820 	head = sc->rbhead;
    821 
    822 	/*
    823 	 * Snarf the Ethernet header.
    824 	 */
    825 	(sc->sc_memcpy)((void *)&eh, (void *)sc->cbuffs[head],
    826 	    sizeof(struct ether_header));
    827 
    828 	/*
    829 	 * As quickly as possible, check if this packet is for us.
    830 	 * If not, don't waste a single cycle copying the rest of the
    831 	 * packet in.
    832 	 * This is only a consideration when FILTER is defined; i.e., when
    833 	 * we are either running BPF or doing multicasting.
    834 	 */
    835 	if (check_eh(sc, &eh, to_bpf) == 0) {
    836 		/* just this case, it's not an error */
    837 		sc->sc_if.if_ierrors--;
    838 		return 0;
    839 	}
    840 
    841 	resid = totlen;
    842 
    843 	MGETHDR(m, M_DONTWAIT, MT_DATA);
    844 	if (m == 0)
    845 		return 0;
    846 
    847 	m->m_pkthdr.rcvif = &sc->sc_if;
    848 	m->m_pkthdr.len = totlen;
    849 	len = MHLEN;
    850 	top = 0;
    851 	mp = &top;
    852 
    853 	/*
    854 	 * This loop goes through and allocates mbufs for all the data we will
    855 	 * be copying in.  It does not actually do the copying yet.
    856 	 */
    857 	while (totlen > 0) {
    858 		if (top) {
    859 			MGET(m, M_DONTWAIT, MT_DATA);
    860 			if (m == 0) {
    861 				m_freem(top);
    862 				return 0;
    863 			}
    864 			len = MLEN;
    865 		}
    866 		if (totlen >= MINCLSIZE) {
    867 			MCLGET(m, M_DONTWAIT);
    868 			if (m->m_flags & M_EXT)
    869 				len = MCLBYTES;
    870 		}
    871 
    872 		if (mp == &top) {
    873 			char *newdata = (char *)
    874 			    ALIGN(m->m_data + sizeof(struct ether_header)) -
    875 			    sizeof(struct ether_header);
    876 			len -= newdata - m->m_data;
    877 			m->m_data = newdata;
    878 		}
    879 
    880 		m->m_len = len = min(totlen, len);
    881 
    882 		totlen -= len;
    883 		*mp = m;
    884 		mp = &m->m_next;
    885 	}
    886 
    887 	m = top;
    888 	thismboff = 0;
    889 
    890 	/*
    891 	 * Copy the Ethernet header into the mbuf chain.
    892 	 */
    893 	memcpy(mtod(m, void *), &eh, sizeof(struct ether_header));
    894 	thismboff = sizeof(struct ether_header);
    895 	thisrboff = sizeof(struct ether_header);
    896 	resid -= sizeof(struct ether_header);
    897 
    898 	/*
    899 	 * Now we take the mbuf chain (hopefully only one mbuf most of the
    900 	 * time) and stuff the data into it.  There are no possible failures
    901 	 * at or after this point.
    902 	 */
    903 	while (resid > 0) {
    904 		int thisrblen = ie_buflen(sc, head) - thisrboff;
    905 		int thismblen = m->m_len - thismboff;
    906 
    907 		len = min(thisrblen, thismblen);
    908 		(sc->sc_memcpy)(mtod(m, char *) + thismboff,
    909 		    (void *)(sc->cbuffs[head] + thisrboff),
    910 		    (u_int)len);
    911 		resid -= len;
    912 
    913 		if (len == thismblen) {
    914 			m = m->m_next;
    915 			thismboff = 0;
    916 		} else
    917 			thismboff += len;
    918 
    919 		if (len == thisrblen) {
    920 			head = (head + 1) % sc->nrxbuf;
    921 			thisrboff = 0;
    922 		} else
    923 			thisrboff += len;
    924 	}
    925 
    926 	/*
    927 	 * Unless something changed strangely while we were doing the copy,
    928 	 * we have now copied everything in from the shared memory.
    929 	 * This means that we are done.
    930 	 */
    931 	return top;
    932 }
    933 
    934 /*
    935  * Read frame NUM from unit UNIT (pre-cached as IE).
    936  *
    937  * This routine reads the RFD at NUM, and copies in the buffers from
    938  * the list of RBD, then rotates the RBD and RFD lists so that the receiver
    939  * doesn't start complaining.  Trailers are DROPPED---there's no point
    940  * in wasting time on confusing code to deal with them.  Hopefully,
    941  * this machine will never ARP for trailers anyway.
    942  */
    943 static void
    944 ie_readframe(struct ie_softc *sc, int num)
    945 {
    946 	int status;
    947 	struct mbuf *m = 0;
    948 #if NBPFILTER > 0
    949 	int bpf_gets_it = 0;
    950 #endif
    951 
    952 	status = sc->rframes[num]->ie_fd_status;
    953 
    954 	/* Advance the RFD list, since we're done with this descriptor. */
    955 	sc->rframes[num]->ie_fd_status = SWAP(0);
    956 	sc->rframes[num]->ie_fd_last |= IE_FD_LAST;
    957 	sc->rframes[sc->rftail]->ie_fd_last &= ~IE_FD_LAST;
    958 	sc->rftail = (sc->rftail + 1) % sc->nframes;
    959 	sc->rfhead = (sc->rfhead + 1) % sc->nframes;
    960 
    961 	if (status & IE_FD_OK) {
    962 #if NBPFILTER > 0
    963 		m = ieget(sc, &bpf_gets_it);
    964 #else
    965 		m = ieget(sc, NULL);
    966 #endif
    967 		ie_drop_packet_buffer(sc);
    968 	}
    969 	if (m == 0) {
    970 		sc->sc_if.if_ierrors++;
    971 		return;
    972 	}
    973 
    974 #ifdef IEDEBUG
    975 	if (sc->sc_debug & IED_READFRAME) {
    976 		struct ether_header *eh = mtod(m, struct ether_header *);
    977 
    978 		printf("%s: frame from ether %s type 0x%x\n",
    979 		    device_xname(sc->sc_dev),
    980 		    ether_sprintf(eh->ether_shost), (u_int)eh->ether_type);
    981 	}
    982 #endif
    983 
    984 #if NBPFILTER > 0
    985 	/*
    986 	 * Check for a BPF filter; if so, hand it up.
    987 	 * Note that we have to stick an extra mbuf up front, because
    988 	 * bpf_mtap expects to have the ether header at the front.
    989 	 * It doesn't matter that this results in an ill-formatted mbuf chain,
    990 	 * since BPF just looks at the data.  (It doesn't try to free the mbuf,
    991 	 * tho' it will make a copy for tcpdump.)
    992 	 */
    993 	if (bpf_gets_it) {
    994 		/* Pass it up. */
    995 		bpf_mtap(sc->sc_if.if_bpf, m);
    996 
    997 		/*
    998 		 * A signal passed up from the filtering code indicating that
    999 		 * the packet is intended for BPF but not for the protocol
   1000 		 * machinery.  We can save a few cycles by not handing it off
   1001 		 * to them.
   1002 		 */
   1003 		if (bpf_gets_it == 2) {
   1004 			m_freem(m);
   1005 			return;
   1006 		}
   1007 	}
   1008 #endif	/* NBPFILTER > 0 */
   1009 
   1010 	/*
   1011 	 * In here there used to be code to check destination addresses upon
   1012 	 * receipt of a packet.  We have deleted that code, and replaced it
   1013 	 * with code to check the address much earlier in the cycle, before
   1014 	 * copying the data in; this saves us valuable cycles when operating
   1015 	 * as a multicast router or when using BPF.
   1016 	 */
   1017 
   1018 	/*
   1019 	 * Finally pass this packet up to higher layers.
   1020 	 */
   1021 	(*sc->sc_if.if_input)(&sc->sc_if, m);
   1022 	sc->sc_if.if_ipackets++;
   1023 }
   1024 
   1025 static void
   1026 ie_drop_packet_buffer(struct ie_softc *sc)
   1027 {
   1028 	int i;
   1029 
   1030 	do {
   1031 		/*
   1032 		 * This means we are somehow out of sync.  So, we reset the
   1033 		 * adapter.
   1034 		 */
   1035 		if ((sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)
   1036 		    == 0) {
   1037 #ifdef IEDEBUG
   1038 			print_rbd(sc->rbuffs[sc->rbhead]);
   1039 #endif
   1040 			log(LOG_ERR,
   1041 			    "%s: receive descriptors out of sync at %d\n",
   1042 			    device_xname(sc->sc_dev), sc->rbhead);
   1043 			iereset(sc);
   1044 			return;
   1045 		}
   1046 
   1047 		i = sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_LAST;
   1048 
   1049 		sc->rbuffs[sc->rbhead]->ie_rbd_length |= IE_RBD_LAST;
   1050 		sc->rbuffs[sc->rbhead]->ie_rbd_actual = SWAP(0);
   1051 		sc->rbhead = (sc->rbhead + 1) % sc->nrxbuf;
   1052 		sc->rbuffs[sc->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
   1053 		sc->rbtail = (sc->rbtail + 1) % sc->nrxbuf;
   1054 	} while (i == 0);
   1055 }
   1056 
   1057 /*
   1058  * Start transmission on an interface.
   1059  */
   1060 static void
   1061 iestart(struct ifnet *ifp)
   1062 {
   1063 	struct ie_softc *sc = ifp->if_softc;
   1064 	struct mbuf *m0, *m;
   1065 	uint8_t *buffer;
   1066 	uint16_t len;
   1067 
   1068 	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
   1069 		return;
   1070 
   1071 	for (;;) {
   1072 		if (sc->xmit_busy == sc->ntxbuf) {
   1073 			ifp->if_flags |= IFF_OACTIVE;
   1074 			break;
   1075 		}
   1076 
   1077 		IF_DEQUEUE(&ifp->if_snd, m0);
   1078 		if (m0 == 0)
   1079 			break;
   1080 
   1081 		/* We need to use m->m_pkthdr.len, so require the header */
   1082 		if ((m0->m_flags & M_PKTHDR) == 0)
   1083 			panic("%s: no header mbuf", __func__);
   1084 
   1085 #if NBPFILTER > 0
   1086 		/* Tap off here if there is a BPF listener. */
   1087 		if (ifp->if_bpf)
   1088 			bpf_mtap(ifp->if_bpf, m0);
   1089 #endif
   1090 
   1091 #ifdef IEDEBUG
   1092 		if (sc->sc_debug & IED_ENQ)
   1093 			printf("%s: fill buffer %d\n", device_xname(sc->sc_dev),
   1094 			    sc->xchead);
   1095 #endif
   1096 
   1097 		buffer = sc->xmit_cbuffs[sc->xchead];
   1098 		for (m = m0; m != 0; m = m->m_next) {
   1099 			(sc->sc_memcpy)(buffer, mtod(m, void *), m->m_len);
   1100 			buffer += m->m_len;
   1101 		}
   1102 		if (m0->m_pkthdr.len < ETHER_MIN_LEN - ETHER_CRC_LEN) {
   1103 			sc->sc_memset(buffer, 0,
   1104 			    ETHER_MIN_LEN - ETHER_CRC_LEN - m0->m_pkthdr.len);
   1105 			len = ETHER_MIN_LEN - ETHER_CRC_LEN;
   1106 		} else
   1107 			len = m0->m_pkthdr.len;
   1108 
   1109 		m_freem(m0);
   1110 		sc->xmit_buffs[sc->xchead]->ie_xmit_flags = SWAP(len);
   1111 
   1112 		/* Start the first packet transmitting. */
   1113 		if (sc->xmit_busy == 0)
   1114 			iexmit(sc);
   1115 
   1116 		sc->xchead = (sc->xchead + 1) % sc->ntxbuf;
   1117 		sc->xmit_busy++;
   1118 	}
   1119 }
   1120 
   1121 static void
   1122 iereset(struct ie_softc *sc)
   1123 {
   1124 	int s;
   1125 
   1126 	s = splnet();
   1127 
   1128 	/* No message here.  The caller does that. */
   1129 	iestop(sc);
   1130 
   1131 	/*
   1132 	 * Stop i82586 dead in its tracks.
   1133 	 */
   1134 	if (cmd_and_wait(sc, IE_RU_ABORT | IE_CU_ABORT, 0, 0))
   1135 		printf("%s: abort commands timed out\n",
   1136 		    device_xname(sc->sc_dev));
   1137 
   1138 	if (cmd_and_wait(sc, IE_RU_DISABLE | IE_CU_STOP, 0, 0))
   1139 		printf("%s: disable commands timed out\n",
   1140 		    device_xname(sc->sc_dev));
   1141 
   1142 	ieinit(sc);
   1143 
   1144 	splx(s);
   1145 }
   1146 
   1147 /*
   1148  * Send a command to the controller and wait for it to either
   1149  * complete or be accepted, depending on the command.  If the
   1150  * command pointer is null, then pretend that the command is
   1151  * not an action command.  If the command pointer is not null,
   1152  * and the command is an action command, wait for
   1153  * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK
   1154  * to become true.
   1155  */
   1156 static int
   1157 cmd_and_wait(struct ie_softc *sc, int cmd, void *pcmd, int mask)
   1158 {
   1159 	volatile struct ie_cmd_common *cc = pcmd;
   1160 	volatile struct ie_sys_ctl_block *scb = sc->scb;
   1161 	int tmo;
   1162 
   1163 	scb->ie_command = (uint16_t)cmd;
   1164 	(sc->chan_attn)(sc);
   1165 
   1166 	/* Wait for the command to be accepted by the CU. */
   1167 	tmo = 10;
   1168 	while (scb->ie_command && --tmo)
   1169 		delay(10);
   1170 	if (scb->ie_command) {
   1171 #ifdef	IEDEBUG
   1172 		printf("%s: cmd_and_wait, CU stuck (1)\n",
   1173 		    device_xname(sc->sc_dev));
   1174 #endif
   1175 		return -1;	/* timed out */
   1176 	}
   1177 
   1178 	/*
   1179 	 * If asked, also wait for it to finish.
   1180 	 */
   1181 	if (IE_ACTION_COMMAND(cmd) && pcmd) {
   1182 
   1183 		/*
   1184 		 * According to the packet driver, the minimum timeout should
   1185 		 * be .369 seconds, which we round up to .4.
   1186 		 */
   1187 		tmo = 36900;
   1188 
   1189 		/*
   1190 		 * Now spin-lock waiting for status.  This is not a very nice
   1191 		 * thing to do, but I haven't figured out how, or indeed if, we
   1192 		 * can put the process waiting for action to sleep.  (We may
   1193 		 * be getting called through some other timeout running in the
   1194 		 * kernel.)
   1195 		 */
   1196 		while (((cc->ie_cmd_status & mask) == 0) && --tmo)
   1197 			delay(10);
   1198 
   1199 		if ((cc->ie_cmd_status & mask) == 0) {
   1200 #ifdef	IEDEBUG
   1201 			printf("%s: cmd_and_wait, CU stuck (2)\n",
   1202 			    device_xname(sc->sc_dev));
   1203 #endif
   1204 			return -1;	/* timed out */
   1205 		}
   1206 	}
   1207 	return 0;
   1208 }
   1209 
   1210 /*
   1211  * Run the time-domain reflectometer.
   1212  */
   1213 static void
   1214 run_tdr(struct ie_softc *sc, struct ie_tdr_cmd *cmd)
   1215 {
   1216 	int result;
   1217 
   1218 	cmd->com.ie_cmd_status = SWAP(0);
   1219 	cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST;
   1220 	cmd->com.ie_cmd_link = SWAP(0xffff);
   1221 
   1222 	sc->scb->ie_command_list = vtop16sw(sc, cmd);
   1223 	cmd->ie_tdr_time = SWAP(0);
   1224 
   1225 	if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
   1226 	    (cmd->com.ie_cmd_status & IE_STAT_OK) == 0)
   1227 		result = 0x10000;	/* impossible value */
   1228 	else
   1229 		result = cmd->ie_tdr_time;
   1230 
   1231 	ie_ack(sc, IE_ST_WHENCE);
   1232 
   1233 	if (result & IE_TDR_SUCCESS)
   1234 		return;
   1235 
   1236 	if (result & 0x10000) {
   1237 		printf("%s: TDR command failed\n", device_xname(sc->sc_dev));
   1238 	} else if (result & IE_TDR_XCVR) {
   1239 		printf("%s: transceiver problem\n", device_xname(sc->sc_dev));
   1240 	} else if (result & IE_TDR_OPEN) {
   1241 		printf("%s: TDR detected an open %d clocks away\n",
   1242 		    device_xname(sc->sc_dev), SWAP(result & IE_TDR_TIME));
   1243 	} else if (result & IE_TDR_SHORT) {
   1244 		printf("%s: TDR detected a short %d clocks away\n",
   1245 		    device_xname(sc->sc_dev), SWAP(result & IE_TDR_TIME));
   1246 	} else {
   1247 		printf("%s: TDR returned unknown status 0x%x\n",
   1248 		    device_xname(sc->sc_dev), result);
   1249 	}
   1250 }
   1251 
   1252 /*
   1253  * iememinit: set up the buffers
   1254  *
   1255  * we have a block of KVA at sc->buf_area which is of size sc->buf_area_sz.
   1256  * this is to be used for the buffers.  the chip indexs its control data
   1257  * structures with 16 bit offsets, and it indexes actual buffers with
   1258  * 24 bit addresses.   so we should allocate control buffers first so that
   1259  * we don't overflow the 16 bit offset field.   The number of transmit
   1260  * buffers is fixed at compile time.
   1261  *
   1262  * note: this function was written to be easy to understand, rather than
   1263  *       highly efficient (it isn't in the critical path).
   1264  *
   1265  * The memory layout is: tbufs, rbufs, (gap), control blocks
   1266  * [tbuf0, tbuf1] [rbuf0,...rbufN] gap [rframes] [tframes]
   1267  * XXX - This needs review...
   1268  */
   1269 static void
   1270 iememinit(struct ie_softc *sc)
   1271 {
   1272 	uint8_t *ptr;
   1273 	int i;
   1274 	uint16_t nxt;
   1275 
   1276 	/* First, zero all the memory. */
   1277 	ptr = sc->buf_area;
   1278 	(sc->sc_memset)(ptr, 0, sc->buf_area_sz);
   1279 
   1280 	/* Allocate tx/rx buffers. */
   1281 	for (i = 0; i < NTXBUF; i++) {
   1282 		sc->xmit_cbuffs[i] = ptr;
   1283 		ptr += IE_TBUF_SIZE;
   1284 	}
   1285 	for (i = 0; i < sc->nrxbuf; i++) {
   1286 		sc->cbuffs[i] = ptr;
   1287 		ptr += IE_RBUF_SIZE;
   1288 	}
   1289 
   1290 	/* Small pad (Don't trust the chip...) */
   1291 	ptr += 16;
   1292 
   1293 	/* Allocate and fill in xmit buffer descriptors. */
   1294 	for (i = 0; i < NTXBUF; i++) {
   1295 		sc->xmit_buffs[i] = (volatile void *)ptr;
   1296 		ptr = Align(ptr + sizeof(*sc->xmit_buffs[i]));
   1297 		sc->xmit_buffs[i]->ie_xmit_buf =
   1298 		    Swap32(vtop24(sc, sc->xmit_cbuffs[i]));
   1299 		sc->xmit_buffs[i]->ie_xmit_next = SWAP(0xffff);
   1300 	}
   1301 
   1302 	/* Allocate and fill in recv buffer descriptors. */
   1303 	for (i = 0; i < sc->nrxbuf; i++) {
   1304 		sc->rbuffs[i] = (volatile void *)ptr;
   1305 		ptr = Align(ptr + sizeof(*sc->rbuffs[i]));
   1306 		sc->rbuffs[i]->ie_rbd_buffer =
   1307 		    Swap32(vtop24(sc, sc->cbuffs[i]));
   1308 		sc->rbuffs[i]->ie_rbd_length = SWAP(IE_RBUF_SIZE);
   1309 	}
   1310 
   1311 	/* link together recv bufs and set EOL on last */
   1312 	i = sc->nrxbuf - 1;
   1313 	sc->rbuffs[i]->ie_rbd_length |= IE_RBD_LAST;
   1314 	nxt = vtop16sw(sc, __UNVOLATILE(sc->rbuffs[0]));
   1315 	do {
   1316 		sc->rbuffs[i]->ie_rbd_next = nxt;
   1317 		nxt = vtop16sw(sc, __UNVOLATILE(sc->rbuffs[i]));
   1318 	} while (--i >= 0);
   1319 
   1320 	/* Allocate transmit commands. */
   1321 	for (i = 0; i < NTXBUF; i++) {
   1322 		sc->xmit_cmds[i] = (volatile void *)ptr;
   1323 		ptr = Align(ptr + sizeof(*sc->xmit_cmds[i]));
   1324 		sc->xmit_cmds[i]->com.ie_cmd_link = SWAP(0xffff);
   1325 	}
   1326 
   1327 	/* Allocate receive frames. */
   1328 	for (i = 0; i < sc->nframes; i++) {
   1329 		sc->rframes[i] = (volatile void *)ptr;
   1330 		ptr = Align(ptr + sizeof(*sc->rframes[i]));
   1331 	}
   1332 
   1333 	/* Link together recv frames and set EOL on last */
   1334 	i = sc->nframes - 1;
   1335 	sc->rframes[i]->ie_fd_last |= IE_FD_LAST;
   1336 	nxt = vtop16sw(sc, __UNVOLATILE(sc->rframes[0]));
   1337 	do {
   1338 		sc->rframes[i]->ie_fd_next = nxt;
   1339 		nxt = vtop16sw(sc, __UNVOLATILE(sc->rframes[i]));
   1340 	} while (--i >= 0);
   1341 
   1342 
   1343 	/* Pointers to last packet sent and next available transmit buffer. */
   1344 	sc->xchead = sc->xctail = 0;
   1345 
   1346 	/* Clear transmit-busy flag. */
   1347 	sc->xmit_busy = 0;
   1348 
   1349 	/*
   1350 	 * Set the head and tail pointers on receive to keep track of
   1351 	 * the order in which RFDs and RBDs are used.   link the
   1352 	 * recv frames and buffer into the scb.
   1353 	 */
   1354 	sc->rfhead = 0;
   1355 	sc->rftail = sc->nframes - 1;
   1356 	sc->rbhead = 0;
   1357 	sc->rbtail = sc->nrxbuf - 1;
   1358 
   1359 	sc->scb->ie_recv_list =
   1360 	    vtop16sw(sc, __UNVOLATILE(sc->rframes[0]));
   1361 	sc->rframes[0]->ie_fd_buf_desc =
   1362 	    vtop16sw(sc, __UNVOLATILE(sc->rbuffs[0]));
   1363 
   1364 	i = (ptr - sc->buf_area);
   1365 #ifdef IEDEBUG
   1366 	printf("IE_DEBUG: used %d of %d bytes\n", i, sc->buf_area_sz);
   1367 #endif
   1368 	if (i > sc->buf_area_sz)
   1369 		panic("ie: iememinit, out of space");
   1370 }
   1371 
   1372 /*
   1373  * Run the multicast setup command.
   1374  * Called at splnet().
   1375  */
   1376 static int
   1377 mc_setup(struct ie_softc *sc, void *ptr)
   1378 {
   1379 	struct ie_mcast_cmd *cmd = ptr;	/* XXX - Was volatile */
   1380 
   1381 	cmd->com.ie_cmd_status = SWAP(0);
   1382 	cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST;
   1383 	cmd->com.ie_cmd_link = SWAP(0xffff);
   1384 
   1385 	(sc->sc_memcpy)((void *)cmd->ie_mcast_addrs,
   1386 	    (void *)sc->mcast_addrs,
   1387 	    sc->mcast_count * sizeof *sc->mcast_addrs);
   1388 
   1389 	cmd->ie_mcast_bytes =
   1390 	    SWAP(sc->mcast_count * ETHER_ADDR_LEN);	/* grrr... */
   1391 
   1392 	sc->scb->ie_command_list = vtop16sw(sc, cmd);
   1393 	if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
   1394 	    (cmd->com.ie_cmd_status & IE_STAT_OK) == 0) {
   1395 		printf("%s: multicast address setup command failed\n",
   1396 		    device_xname(sc->sc_dev));
   1397 		return 0;
   1398 	}
   1399 	return 1;
   1400 }
   1401 
   1402 static inline void
   1403 ie_setup_config(struct ie_config_cmd *cmd, int promiscuous, int manchester)
   1404 {
   1405 
   1406 	/*
   1407 	 * these are all char's so no need to byte-swap
   1408 	 */
   1409 	cmd->ie_config_count = 0x0c;
   1410 	cmd->ie_fifo = 8;
   1411 	cmd->ie_save_bad = 0x40;
   1412 	cmd->ie_addr_len = 0x2e;
   1413 	cmd->ie_priority = 0;
   1414 	cmd->ie_ifs = 0x60;
   1415 	cmd->ie_slot_low = 0;
   1416 	cmd->ie_slot_high = 0xf2;
   1417 	cmd->ie_promisc = promiscuous | manchester << 2;
   1418 	cmd->ie_crs_cdt = 0;
   1419 	cmd->ie_min_len = 64;
   1420 	cmd->ie_junk = 0xff;
   1421 }
   1422 
   1423 /*
   1424  * This routine inits the ie.
   1425  * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands,
   1426  * starting the receiver unit, and clearing interrupts.
   1427  *
   1428  * THIS ROUTINE MUST BE CALLED AT splnet() OR HIGHER.
   1429  */
   1430 static int
   1431 ieinit(struct ie_softc *sc)
   1432 {
   1433 	volatile struct ie_sys_ctl_block *scb = sc->scb;
   1434 	void *ptr;
   1435 	struct ifnet *ifp;
   1436 
   1437 	ifp = &sc->sc_if;
   1438 	ptr = sc->buf_area;	/* XXX - Use scb instead? */
   1439 
   1440 	/*
   1441 	 * Send the configure command first.
   1442 	 */
   1443 	{
   1444 		struct ie_config_cmd *cmd = ptr;	/* XXX - Was volatile */
   1445 
   1446 		scb->ie_command_list = vtop16sw(sc, cmd);
   1447 		cmd->com.ie_cmd_status = SWAP(0);
   1448 		cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST;
   1449 		cmd->com.ie_cmd_link = SWAP(0xffff);
   1450 
   1451 		ie_setup_config(cmd, (sc->promisc != 0), 0);
   1452 
   1453 		if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
   1454 		    (cmd->com.ie_cmd_status & IE_STAT_OK) == 0) {
   1455 			printf("%s: configure command failed\n",
   1456 			    device_xname(sc->sc_dev));
   1457 			return 0;
   1458 		}
   1459 	}
   1460 
   1461 	/*
   1462 	 * Now send the Individual Address Setup command.
   1463 	 */
   1464 	{
   1465 		struct ie_iasetup_cmd *cmd = ptr;	/* XXX - Was volatile */
   1466 
   1467 		scb->ie_command_list = vtop16sw(sc, cmd);
   1468 		cmd->com.ie_cmd_status = SWAP(0);
   1469 		cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST;
   1470 		cmd->com.ie_cmd_link = SWAP(0xffff);
   1471 
   1472 		(sc->sc_memcpy)((void *)&cmd->ie_address,
   1473 		    CLLADDR(ifp->if_sadl), sizeof(cmd->ie_address));
   1474 
   1475 		if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
   1476 		    (cmd->com.ie_cmd_status & IE_STAT_OK) == 0) {
   1477 			printf("%s: individual address setup command failed\n",
   1478 			    device_xname(sc->sc_dev));
   1479 			return 0;
   1480 		}
   1481 	}
   1482 
   1483 	/*
   1484 	 * Now run the time-domain reflectometer.
   1485 	 */
   1486 	if (ie_run_tdr)
   1487 		run_tdr(sc, ptr);
   1488 
   1489 	/*
   1490 	 * Acknowledge any interrupts we have generated thus far.
   1491 	 */
   1492 	ie_ack(sc, IE_ST_WHENCE);
   1493 
   1494 	/*
   1495 	 * Set up the transmit and recv buffers.
   1496 	 */
   1497 	iememinit(sc);
   1498 
   1499 	/* tell higher levels that we are here */
   1500 	ifp->if_flags |= IFF_RUNNING;
   1501 	ifp->if_flags &= ~IFF_OACTIVE;
   1502 
   1503 	sc->scb->ie_recv_list =
   1504 	    vtop16sw(sc, __UNVOLATILE(sc->rframes[0]));
   1505 	cmd_and_wait(sc, IE_RU_START, 0, 0);
   1506 
   1507 	ie_ack(sc, IE_ST_WHENCE);
   1508 
   1509 	if (sc->run_586)
   1510 		(sc->run_586)(sc);
   1511 
   1512 	return 0;
   1513 }
   1514 
   1515 static void
   1516 iestop(struct ie_softc *sc)
   1517 {
   1518 
   1519 	cmd_and_wait(sc, IE_RU_DISABLE, 0, 0);
   1520 }
   1521 
   1522 static int
   1523 ieioctl(struct ifnet *ifp, u_long cmd, void *data)
   1524 {
   1525 	struct ie_softc *sc = ifp->if_softc;
   1526 	struct ifaddr *ifa = (struct ifaddr *)data;
   1527 	int s, error = 0;
   1528 
   1529 	s = splnet();
   1530 
   1531 	switch (cmd) {
   1532 
   1533 	case SIOCSIFADDR:
   1534 		ifp->if_flags |= IFF_UP;
   1535 
   1536 		switch (ifa->ifa_addr->sa_family) {
   1537 #ifdef INET
   1538 		case AF_INET:
   1539 			ieinit(sc);
   1540 			arp_ifinit(ifp, ifa);
   1541 			break;
   1542 #endif
   1543 #ifdef NS
   1544 		/* XXX - This code is probably wrong. */
   1545 		case AF_NS:
   1546 		    {
   1547 			struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
   1548 
   1549 			if (ns_nullhost(*ina))
   1550 				ina->x_host =
   1551 				    *(union ns_host *)LLADDR(ifp->if_sadl);
   1552 			else
   1553 				memcpy(LLADDR(ifp->if_sadl),
   1554 				    ina->x_host.c_host, ETHER_ADDR_LEN);
   1555 			/* Set new address. */
   1556 			ieinit(sc);
   1557 			break;
   1558 		    }
   1559 #endif /* NS */
   1560 		default:
   1561 			ieinit(sc);
   1562 			break;
   1563 		}
   1564 		break;
   1565 
   1566 	case SIOCSIFFLAGS:
   1567 		sc->promisc = ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
   1568 
   1569 		if ((ifp->if_flags & IFF_UP) == 0 &&
   1570 		    (ifp->if_flags & IFF_RUNNING) != 0) {
   1571 			/*
   1572 			 * If interface is marked down and it is running, then
   1573 			 * stop it.
   1574 			 */
   1575 			iestop(sc);
   1576 			ifp->if_flags &= ~IFF_RUNNING;
   1577 		} else if ((ifp->if_flags & IFF_UP) != 0 &&
   1578 			(ifp->if_flags & IFF_RUNNING) == 0) {
   1579 			/*
   1580 			 * If interface is marked up and it is stopped, then
   1581 			 * start it.
   1582 			 */
   1583 			ieinit(sc);
   1584 		} else {
   1585 			/*
   1586 			 * Reset the interface to pick up changes in any other
   1587 			 * flags that affect hardware registers.
   1588 			 */
   1589 			iestop(sc);
   1590 			ieinit(sc);
   1591 		}
   1592 #ifdef IEDEBUG
   1593 		if (ifp->if_flags & IFF_DEBUG)
   1594 			sc->sc_debug = IED_ALL;
   1595 		else
   1596 			sc->sc_debug = ie_debug_flags;
   1597 #endif
   1598 		break;
   1599 
   1600 	case SIOCADDMULTI:
   1601 	case SIOCDELMULTI:
   1602 		if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) {
   1603 			/*
   1604 			 * Multicast list has changed; set the hardware filter
   1605 			 * accordingly.
   1606 			 */
   1607 			if (ifp->if_flags & IFF_RUNNING)
   1608 				mc_reset(sc);
   1609 			error = 0;
   1610 		}
   1611 		break;
   1612 
   1613 	default:
   1614 		error = EINVAL;
   1615 	}
   1616 	splx(s);
   1617 	return error;
   1618 }
   1619 
   1620 static void
   1621 mc_reset(struct ie_softc *sc)
   1622 {
   1623 	struct ether_multi *enm;
   1624 	struct ether_multistep step;
   1625 	struct ifnet *ifp;
   1626 
   1627 	ifp = &sc->sc_if;
   1628 
   1629 	/*
   1630 	 * Step through the list of addresses.
   1631 	 */
   1632 	sc->mcast_count = 0;
   1633 	ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm);
   1634 	while (enm) {
   1635 		if (sc->mcast_count >= MAXMCAST ||
   1636 		    ether_cmp(enm->enm_addrlo, enm->enm_addrhi) != 0) {
   1637 			ifp->if_flags |= IFF_ALLMULTI;
   1638 			ieioctl(ifp, SIOCSIFFLAGS, NULL);
   1639 			goto setflag;
   1640 		}
   1641 		memcpy(&sc->mcast_addrs[sc->mcast_count], enm->enm_addrlo,
   1642 		    ETHER_ADDR_LEN);
   1643 		sc->mcast_count++;
   1644 		ETHER_NEXT_MULTI(step, enm);
   1645 	}
   1646 setflag:
   1647 	sc->want_mcsetup = 1;
   1648 }
   1649 
   1650 #ifdef IEDEBUG
   1651 void
   1652 print_rbd(volatile struct ie_recv_buf_desc *rbd)
   1653 {
   1654 
   1655 	printf("RBD at %08lx:\nactual %04x, next %04x, buffer %08x\n"
   1656 	    "length %04x, mbz %04x\n", (u_long)rbd, rbd->ie_rbd_actual,
   1657 	    rbd->ie_rbd_next, rbd->ie_rbd_buffer, rbd->ie_rbd_length,
   1658 	    rbd->mbz);
   1659 }
   1660 #endif
   1661