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