if_ie.c revision 40565
1/*-
2 * Copyright (c) 1992, 1993, University of Vermont and State
3 *  Agricultural College.
4 * Copyright (c) 1992, 1993, Garrett A. Wollman.
5 *
6 * Portions:
7 * Copyright (c) 1990, 1991, William F. Jolitz
8 * Copyright (c) 1990, The Regents of the University of California
9 *
10 * 3Com 3C507 support:
11 * Copyright (c) 1993, 1994, Charles M. Hannum
12 *
13 * EtherExpress 16 support:
14 * Copyright (c) 1993, 1994, 1995, Rodney W. Grimes
15 * Copyright (c) 1997, Aaron C. Smith
16 *
17 * All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
22 * 1. Redistributions of source code must retain the above copyright
23 *    notice, this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright
25 *    notice, this list of conditions and the following disclaimer in the
26 *    documentation and/or other materials provided with the distribution.
27 * 3. All advertising materials mentioning features or use of this software
28 *    must display the following acknowledgement:
29 *	This product includes software developed by the University of
30 *	Vermont and State Agricultural College and Garrett A. Wollman, by
31 *	William F. Jolitz, by the University of California, Berkeley,
32 *	Lawrence Berkeley Laboratory, and their contributors, by
33 *	Charles M. Hannum, by Rodney W. Grimes, and by Aaron C. Smith.
34 * 4. Neither the names of the Universities nor the names of the authors
35 *    may be used to endorse or promote products derived from this software
36 *    without specific prior written permission.
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41 * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR AUTHORS BE LIABLE
42 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
44 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
46 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
47 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * SUCH DAMAGE.
49 *
50 *	$Id: if_ie.c,v 1.56 1998/08/10 17:21:48 bde Exp $
51 */
52
53/*
54 * Intel 82586 Ethernet chip
55 * Register, bit, and structure definitions.
56 *
57 * Written by GAW with reference to the Clarkson Packet Driver code for this
58 * chip written by Russ Nelson and others.
59 *
60 * Intel EtherExpress 16 support from if_ix.c, written by Rodney W. Grimes.
61 */
62
63/*
64 * The i82586 is a very versatile chip, found in many implementations.
65 * Programming this chip is mostly the same, but certain details differ
66 * from card to card.  This driver is written so that different cards
67 * can be automatically detected at run-time.
68 */
69
70/*
71Mode of operation:
72
73We run the 82586 in a standard Ethernet mode.  We keep NFRAMES received
74frame descriptors around for the receiver to use, and NRXBUFS associated
75receive buffer descriptors, both in a circular list.  Whenever a frame is
76received, we rotate both lists as necessary.  (The 586 treats both lists
77as a simple queue.)  We also keep a transmit command around so that packets
78can be sent off quickly.
79
80We configure the adapter in AL-LOC = 1 mode, which means that the
81Ethernet/802.3 MAC header is placed at the beginning of the receive buffer
82rather than being split off into various fields in the RFD.  This also
83means that we must include this header in the transmit buffer as well.
84
85By convention, all transmit commands, and only transmit commands, shall
86have the I (IE_CMD_INTR) bit set in the command.  This way, when an
87interrupt arrives at ieintr(), it is immediately possible to tell
88what precisely caused it.  ANY OTHER command-sending routines should
89run at splimp(), and should post an acknowledgement to every interrupt
90they generate.
91
92The 82586 has a 24-bit address space internally, and the adaptor's memory
93is located at the top of this region.  However, the value we are given in
94configuration is normally the *bottom* of the adaptor RAM.  So, we must go
95through a few gyrations to come up with a kernel virtual address which
96represents the actual beginning of the 586 address space.  First, we
97autosize the RAM by running through several possible sizes and trying to
98initialize the adapter under the assumption that the selected size is
99correct.  Then, knowing the correct RAM size, we set up our pointers in
100ie_softc[unit].  `iomem' represents the computed base of the 586 address
101space.  `iomembot' represents the actual configured base of adapter RAM.
102Finally, `iosize' represents the calculated size of 586 RAM.  Then, when
103laying out commands, we use the interval [iomembot, iomembot + iosize); to
104make 24-pointers, we subtract iomem, and to make 16-pointers, we subtract
105iomem and and with 0xffff.
106
107*/
108
109#include "ie.h"
110#if NIE > 0
111#include "opt_inet.h"
112#include "opt_ipx.h"
113
114#include <sys/param.h>
115#include <sys/systm.h>
116#include <sys/kernel.h>
117#include <sys/malloc.h>
118#include <sys/conf.h>
119#include <sys/mbuf.h>
120#include <sys/socket.h>
121#include <sys/sockio.h>
122#include <sys/syslog.h>
123
124#include <net/if.h>
125#include <net/if_types.h>
126#include <net/if_dl.h>
127
128#include "bpfilter.h"
129
130#ifdef INET
131#include <netinet/in.h>
132#include <netinet/if_ether.h>
133#endif
134
135#ifdef IPX
136#include <netipx/ipx.h>
137#include <netipx/ipx_if.h>
138#endif
139
140#ifdef NS
141#include <netns/ns.h>
142#include <netns/ns_if.h>
143#endif
144
145#include <machine/clock.h>
146#include <machine/md_var.h>
147
148#include <i386/isa/isa_device.h>
149#include <i386/isa/ic/i82586.h>
150#include <i386/isa/icu.h>
151#include <i386/isa/if_iereg.h>
152#include <i386/isa/if_ie507.h>
153#include <i386/isa/if_iee16.h>
154#include <i386/isa/elink.h>
155
156#if NBPFILTER > 0
157#include <net/bpf.h>
158#endif
159
160#ifdef DEBUG
161#define IED_RINT	0x01
162#define IED_TINT	0x02
163#define IED_RNR		0x04
164#define IED_CNA		0x08
165#define IED_READFRAME	0x10
166static int	ie_debug = IED_RNR;
167
168#endif
169
170#define IE_BUF_LEN	ETHER_MAX_LEN	/* length of transmit buffer */
171
172/* Forward declaration */
173struct ie_softc;
174
175static struct mbuf *last_not_for_us;
176
177static int	ieprobe(struct isa_device * dvp);
178static int	ieattach(struct isa_device * dvp);
179static ointhand2_t	ieintr;
180static int	sl_probe(struct isa_device * dvp);
181static int	el_probe(struct isa_device * dvp);
182static int	ni_probe(struct isa_device * dvp);
183static int	ee16_probe(struct isa_device * dvp);
184
185static int	check_ie_present(int unit, caddr_t where, unsigned size);
186static void	ieinit(int unit);
187static void	ie_stop(int unit);
188static int	ieioctl(struct ifnet * ifp, u_long command, caddr_t data);
189static void	iestart(struct ifnet * ifp);
190
191static void	el_reset_586(int unit);
192static void	el_chan_attn(int unit);
193
194static void	sl_reset_586(int unit);
195static void	sl_chan_attn(int unit);
196
197static void	ee16_reset_586(int unit);
198static void	ee16_chan_attn(int unit);
199static __inline void ee16_interrupt_enable(struct ie_softc * ie);
200static void	ee16_eeprom_outbits(struct ie_softc * ie, int edata, int cnt);
201static void	ee16_eeprom_clock(struct ie_softc * ie, int state);
202static u_short	ee16_read_eeprom(struct ie_softc * ie, int location);
203static int	ee16_eeprom_inbits(struct ie_softc * ie);
204static void	ee16_shutdown(int howto, void *sc);
205
206static void	iereset(int unit);
207static void	ie_readframe(int unit, struct ie_softc * ie, int bufno);
208static void	ie_drop_packet_buffer(int unit, struct ie_softc * ie);
209static void	sl_read_ether(int unit, unsigned char addr[6]);
210static void	find_ie_mem_size(int unit);
211static void	chan_attn_timeout(void *rock);
212static int	command_and_wait(int unit, int command,
213				 void volatile * pcmd, int);
214static void	run_tdr(int unit, struct ie_tdr_cmd * cmd);
215static int	ierint(int unit, struct ie_softc * ie);
216static int	ietint(int unit, struct ie_softc * ie);
217static int	iernr(int unit, struct ie_softc * ie);
218static void	start_receiver(int unit);
219static __inline int ieget(int, struct ie_softc *, struct mbuf **,
220			  struct ether_header *, int *);
221static caddr_t	setup_rfa(caddr_t ptr, struct ie_softc * ie);
222static int	mc_setup(int, caddr_t, volatile struct ie_sys_ctl_block *);
223static void	ie_mc_reset(int unit);
224
225#ifdef DEBUG
226static void	print_rbd(volatile struct ie_recv_buf_desc * rbd);
227
228static int	in_ierint = 0;
229static int	in_ietint = 0;
230
231#endif
232
233/*
234 * This tells the autoconf code how to set us up.
235 */
236struct isa_driver iedriver = {
237	ieprobe, ieattach, "ie",
238};
239
240enum ie_hardware {
241	IE_STARLAN10,
242	IE_EN100,
243	IE_SLFIBER,
244	IE_3C507,
245	IE_NI5210,
246	IE_EE16,
247	IE_UNKNOWN
248};
249
250static const char *ie_hardware_names[] = {
251	"StarLAN 10",
252	"EN100",
253	"StarLAN Fiber",
254	"3C507",
255	"NI5210",
256	"EtherExpress 16",
257	"Unknown"
258};
259
260/*
261sizeof(iscp) == 1+1+2+4 == 8
262sizeof(scb) == 2+2+2+2+2+2+2+2 == 16
263NFRAMES * sizeof(rfd) == NFRAMES*(2+2+2+2+6+6+2+2) == NFRAMES*24 == 384
264sizeof(xmit_cmd) == 2+2+2+2+6+2 == 18
265sizeof(transmit buffer) == 1512
266sizeof(transmit buffer desc) == 8
267-----
2681946
269
270NRXBUFS * sizeof(rbd) == NRXBUFS*(2+2+4+2+2) == NRXBUFS*12
271NRXBUFS * IE_RBUF_SIZE == NRXBUFS*256
272
273NRXBUFS should be (16384 - 1946) / (256 + 12) == 14438 / 268 == 53
274
275With NRXBUFS == 48, this leaves us 1574 bytes for another command or
276more buffers.  Another transmit command would be 18+8+1512 == 1538
277---just barely fits!
278
279Obviously all these would have to be reduced for smaller memory sizes.
280With a larger memory, it would be possible to roughly double the number of
281both transmit and receive buffers.
282*/
283
284#define NFRAMES		8	/* number of receive frames */
285#define NRXBUFS		48	/* number of buffers to allocate */
286#define IE_RBUF_SIZE	256	/* size of each buffer, MUST BE POWER OF TWO */
287#define NTXBUFS		2	/* number of transmit commands */
288#define IE_TBUF_SIZE	ETHER_MAX_LEN	/* size of transmit buffer */
289
290/*
291 * Ethernet status, per interface.
292 */
293static struct ie_softc {
294	struct	 arpcom arpcom;
295	void	 (*ie_reset_586) (int);
296	void	 (*ie_chan_attn) (int);
297	enum	 ie_hardware hard_type;
298	int	 hard_vers;
299
300	u_short	 port;		/* i/o base address for this interface */
301	caddr_t	 iomem;		/* memory size */
302	caddr_t	 iomembot;	/* memory base address */
303	unsigned iosize;
304	int	 bus_use;	/* 0 means 16bit, 1 means 8 bit adapter */
305
306	int	 want_mcsetup;
307	int	 promisc;
308	int	 nframes;
309	int	 nrxbufs;
310	int	 ntxbufs;
311	volatile struct ie_int_sys_conf_ptr *iscp;
312	volatile struct ie_sys_ctl_block *scb;
313	volatile struct ie_recv_frame_desc **rframes;	/* nframes worth */
314	volatile struct ie_recv_buf_desc **rbuffs;	/* nrxbufs worth */
315	volatile u_char **cbuffs;			/* nrxbufs worth */
316	int	 rfhead, rftail, rbhead, rbtail;
317
318	volatile struct ie_xmit_cmd **xmit_cmds;	/* ntxbufs worth */
319	volatile struct ie_xmit_buf **xmit_buffs;	/* ntxbufs worth */
320	u_char	 **xmit_cbuffs;				/* ntxbufs worth */
321	int	 xmit_count;
322
323	struct	 ie_en_addr mcast_addrs[MAXMCAST + 1];
324	int	 mcast_count;
325
326	u_short	 irq_encoded;	/* encoded interrupt on IEE16 */
327}	ie_softc[NIE];
328
329#define MK_24(base, ptr) ((caddr_t)((uintptr_t)ptr - (uintptr_t)base))
330#define MK_16(base, ptr) ((u_short)(uintptr_t)MK_24(base, ptr))
331
332#define PORT ie_softc[unit].port
333#define MEM  ie_softc[unit].iomem
334
335int
336ieprobe(struct isa_device *dvp)
337{
338	int	ret;
339
340	ret = sl_probe(dvp);
341	if (!ret)
342		ret = el_probe(dvp);
343	if (!ret)
344		ret = ni_probe(dvp);
345	if (!ret)
346		ret = ee16_probe(dvp);
347
348	return (ret);
349}
350
351static int
352sl_probe(struct isa_device *dvp)
353{
354	int	unit = dvp->id_unit;
355	u_char	c;
356
357	ie_softc[unit].port = dvp->id_iobase;
358	ie_softc[unit].iomembot = dvp->id_maddr;
359	ie_softc[unit].iomem = 0;
360	ie_softc[unit].bus_use = 0;
361
362	c = inb(PORT + IEATT_REVISION);
363	switch (SL_BOARD(c)) {
364	case SL10_BOARD:
365		ie_softc[unit].hard_type = IE_STARLAN10;
366		ie_softc[unit].ie_reset_586 = sl_reset_586;
367		ie_softc[unit].ie_chan_attn = sl_chan_attn;
368		break;
369	case EN100_BOARD:
370		ie_softc[unit].hard_type = IE_EN100;
371		ie_softc[unit].ie_reset_586 = sl_reset_586;
372		ie_softc[unit].ie_chan_attn = sl_chan_attn;
373		break;
374	case SLFIBER_BOARD:
375		ie_softc[unit].hard_type = IE_SLFIBER;
376		ie_softc[unit].ie_reset_586 = sl_reset_586;
377		ie_softc[unit].ie_chan_attn = sl_chan_attn;
378		break;
379
380		/*
381		 * Anything else is not recognized or cannot be used.
382		 */
383	default:
384		return (0);
385	}
386
387	ie_softc[unit].hard_vers = SL_REV(c);
388
389	/*
390	 * Divine memory size on-board the card.  Ususally 16k.
391	 */
392	find_ie_mem_size(unit);
393
394	if (!ie_softc[unit].iosize) {
395		return (0);
396	}
397	dvp->id_msize = ie_softc[unit].iosize;
398
399	switch (ie_softc[unit].hard_type) {
400	case IE_EN100:
401	case IE_STARLAN10:
402	case IE_SLFIBER:
403		sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr);
404		break;
405
406	default:
407		if (bootverbose)
408			printf("ie%d: unknown AT&T board type code %d\n", unit,
409		       	ie_softc[unit].hard_type);
410		return (0);
411	}
412
413	return (1);
414}
415
416
417static int
418el_probe(struct isa_device *dvp)
419{
420	struct ie_softc *sc = &ie_softc[dvp->id_unit];
421	u_char	c;
422	int	i;
423	u_char	signature[] = "*3COM*";
424	int	unit = dvp->id_unit;
425
426	sc->port = dvp->id_iobase;
427	sc->iomembot = dvp->id_maddr;
428	sc->bus_use = 0;
429
430	/* Need this for part of the probe. */
431	sc->ie_reset_586 = el_reset_586;
432	sc->ie_chan_attn = el_chan_attn;
433
434	/* Reset and put card in CONFIG state without changing address. */
435	elink_reset();
436	outb(ELINK_ID_PORT, 0x00);
437	elink_idseq(ELINK_507_POLY);
438	elink_idseq(ELINK_507_POLY);
439	outb(ELINK_ID_PORT, 0xff);
440
441	c = inb(PORT + IE507_MADDR);
442	if (c & 0x20) {
443#ifdef DEBUG
444		printf("ie%d: can't map 3C507 RAM in high memory\n", unit);
445#endif
446		return (0);
447	}
448	/* go to RUN state */
449	outb(ELINK_ID_PORT, 0x00);
450	elink_idseq(ELINK_507_POLY);
451	outb(ELINK_ID_PORT, 0x00);
452
453	outb(PORT + IE507_CTRL, EL_CTRL_NRST);
454
455	for (i = 0; i < 6; i++)
456		if (inb(PORT + i) != signature[i])
457			return (0);
458
459	c = inb(PORT + IE507_IRQ) & 0x0f;
460
461	if (dvp->id_irq != (1 << c)) {
462		printf("ie%d: kernel configured irq %d "
463		       "doesn't match board configured irq %d\n",
464		       unit, ffs(dvp->id_irq) - 1, c);
465		return (0);
466	}
467	c = (inb(PORT + IE507_MADDR) & 0x1c) + 0xc0;
468
469	if (kvtop(dvp->id_maddr) != ((int) c << 12)) {
470		printf("ie%d: kernel configured maddr %lx "
471		       "doesn't match board configured maddr %x\n",
472		       unit, kvtop(dvp->id_maddr), (int) c << 12);
473		return (0);
474	}
475	outb(PORT + IE507_CTRL, EL_CTRL_NORMAL);
476
477	sc->hard_type = IE_3C507;
478	sc->hard_vers = 0;	/* 3C507 has no version number. */
479
480	/*
481	 * Divine memory size on-board the card.
482	 */
483	find_ie_mem_size(unit);
484
485	if (!sc->iosize) {
486		printf("ie%d: can't find shared memory\n", unit);
487		outb(PORT + IE507_CTRL, EL_CTRL_NRST);
488		return (0);
489	}
490	if (!dvp->id_msize)
491		dvp->id_msize = sc->iosize;
492	else if (dvp->id_msize != sc->iosize) {
493		printf("ie%d: kernel configured msize %d "
494		       "doesn't match board configured msize %d\n",
495		       unit, dvp->id_msize, sc->iosize);
496		outb(PORT + IE507_CTRL, EL_CTRL_NRST);
497		return (0);
498	}
499	sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr);
500
501	/* Clear the interrupt latch just in case. */
502	outb(PORT + IE507_ICTRL, 1);
503
504	return (16);
505}
506
507
508static int
509ni_probe(struct isa_device *dvp)
510{
511	int	unit = dvp->id_unit;
512	int	boardtype, c;
513
514	ie_softc[unit].port = dvp->id_iobase;
515	ie_softc[unit].iomembot = dvp->id_maddr;
516	ie_softc[unit].iomem = 0;
517	ie_softc[unit].bus_use = 1;
518
519	boardtype = inb(PORT + IEATT_REVISION);
520	c = inb(PORT + IEATT_REVISION + 1);
521	boardtype = boardtype + (c << 8);
522	switch (boardtype) {
523	case 0x5500:		/* This is the magic cookie for the NI5210 */
524		ie_softc[unit].hard_type = IE_NI5210;
525		ie_softc[unit].ie_reset_586 = sl_reset_586;
526		ie_softc[unit].ie_chan_attn = sl_chan_attn;
527		break;
528
529		/*
530		 * Anything else is not recognized or cannot be used.
531		 */
532	default:
533		return (0);
534	}
535
536	ie_softc[unit].hard_vers = 0;
537
538	/*
539	 * Divine memory size on-board the card.  Either 8 or 16k.
540	 */
541	find_ie_mem_size(unit);
542
543	if (!ie_softc[unit].iosize) {
544		return (0);
545	}
546	if (!dvp->id_msize)
547		dvp->id_msize = ie_softc[unit].iosize;
548	else if (dvp->id_msize != ie_softc[unit].iosize) {
549		printf("ie%d: kernel configured msize %d "
550		       "doesn't match board configured msize %d\n",
551		       unit, dvp->id_msize, ie_softc[unit].iosize);
552		return (0);
553	}
554	sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr);
555
556	return (8);
557
558}
559
560
561static void
562ee16_shutdown(int howto, void *sc)
563{
564	struct	ie_softc *ie = (struct ie_softc *)sc;
565	int	unit = ie - &ie_softc[0];
566
567	ee16_reset_586(unit);
568	outb(PORT + IEE16_ECTRL, IEE16_RESET_ASIC);
569	outb(PORT + IEE16_ECTRL, 0);
570}
571
572
573/* Taken almost exactly from Rod's if_ix.c. */
574
575int
576ee16_probe(struct isa_device *dvp)
577{
578	struct ie_softc *sc = &ie_softc[dvp->id_unit];
579
580	int	i;
581	int	unit = dvp->id_unit;
582	u_short board_id, id_var1, id_var2, checksum = 0;
583	u_short eaddrtemp, irq;
584	u_short pg, adjust, decode, edecode;
585	u_char	bart_config;
586	u_long	bd_maddr;
587
588	short	irq_translate[] = {0, IRQ9, IRQ3, IRQ4, IRQ5, IRQ10, IRQ11, 0};
589	char	irq_encode[] = {0, 0, 0, 2, 3, 4, 0, 0, 0, 1, 5, 6, 0, 0, 0, 0};
590
591	/* Need this for part of the probe. */
592	sc->ie_reset_586 = ee16_reset_586;
593	sc->ie_chan_attn = ee16_chan_attn;
594
595	/* unsure if this is necessary */
596	sc->bus_use = 0;
597
598	/* reset any ee16 at the current iobase */
599	outb(dvp->id_iobase + IEE16_ECTRL, IEE16_RESET_ASIC);
600	outb(dvp->id_iobase + IEE16_ECTRL, 0);
601	DELAY(240);
602
603	/* now look for ee16. */
604	board_id = id_var1 = id_var2 = 0;
605	for (i = 0; i < 4; i++) {
606		id_var1 = inb(dvp->id_iobase + IEE16_ID_PORT);
607		id_var2 = ((id_var1 & 0x03) << 2);
608		board_id |= ((id_var1 >> 4) << id_var2);
609	}
610
611	if (board_id != IEE16_ID) {
612		printf("ie%d: unknown board_id: %x\n", unit, board_id);
613		return (0);
614	}
615	/* need sc->port for ee16_read_eeprom */
616	sc->port = dvp->id_iobase;
617	sc->hard_type = IE_EE16;
618
619	/*
620	 * The shared RAM location on the EE16 is encoded into bits 3-7 of
621	 * EEPROM location 6.  We zero the upper byte, and shift the 5 bits
622	 * right 3.  The resulting number tells us the RAM location.
623	 * Because the EE16 supports either 16k or 32k of shared RAM, we
624	 * only worry about the 32k locations.
625	 *
626	 * NOTE: if a 64k EE16 exists, it should be added to this switch. then
627	 * the ia->ia_msize would need to be set per case statement.
628	 *
629	 * value	msize	location =====	=====	======== 0x03	0x8000
630	 * 0xCC000 0x06	0x8000	0xD0000 0x0C	0x8000	0xD4000 0x18
631	 * 0x8000	0xD8000
632	 *
633	 */
634
635	bd_maddr = 0;
636	i = (ee16_read_eeprom(sc, 6) & 0x00ff) >> 3;
637	switch (i) {
638	case 0x03:
639		bd_maddr = 0xCC000;
640		break;
641	case 0x06:
642		bd_maddr = 0xD0000;
643		break;
644	case 0x0c:
645		bd_maddr = 0xD4000;
646		break;
647	case 0x18:
648		bd_maddr = 0xD8000;
649		break;
650	default:
651		bd_maddr = 0;
652		break;
653	}
654	dvp->id_msize = 0x8000;
655	if (kvtop(dvp->id_maddr) != bd_maddr) {
656		printf("ie%d: kernel configured maddr %lx "
657		       "doesn't match board configured maddr %lx\n",
658		       unit, kvtop(dvp->id_maddr), bd_maddr);
659	}
660	sc->iomembot = dvp->id_maddr;
661	sc->iomem = 0;		/* XXX some probes set this and some don't */
662	sc->iosize = dvp->id_msize;
663
664	/* need to put the 586 in RESET while we access the eeprom. */
665	outb(PORT + IEE16_ECTRL, IEE16_RESET_586);
666
667	/* read the eeprom and checksum it, should == IEE16_ID */
668	for (i = 0; i < 0x40; i++)
669		checksum += ee16_read_eeprom(sc, i);
670
671	if (checksum != IEE16_ID) {
672		printf("ie%d: invalid eeprom checksum: %x\n", unit, checksum);
673		return (0);
674	}
675	/*
676	 * Size and test the memory on the board.  The size of the memory
677	 * can be one of 16k, 32k, 48k or 64k.	It can be located in the
678	 * address range 0xC0000 to 0xEFFFF on 16k boundaries.
679	 *
680	 * If the size does not match the passed in memory allocation size
681	 * issue a warning, but continue with the minimum of the two sizes.
682	 */
683
684	switch (dvp->id_msize) {
685	case 65536:
686	case 32768:		/* XXX Only support 32k and 64k right now */
687		break;
688	case 16384:
689	case 49512:
690	default:
691		printf("ie%d: mapped memory size %d not supported\n", unit,
692		       dvp->id_msize);
693		return (0);
694		break;		/* NOTREACHED */
695	}
696
697	if ((kvtop(dvp->id_maddr) < 0xC0000) ||
698	    (kvtop(dvp->id_maddr) + sc->iosize > 0xF0000)) {
699		printf("ie%d: mapped memory location %p out of range\n", unit,
700		       (void *)dvp->id_maddr);
701		return (0);
702	}
703	pg = (kvtop(dvp->id_maddr) & 0x3C000) >> 14;
704	adjust = IEE16_MCTRL_FMCS16 | (pg & 0x3) << 2;
705	decode = ((1 << (sc->iosize / 16384)) - 1) << pg;
706	edecode = ((~decode >> 4) & 0xF0) | (decode >> 8);
707
708	/* ZZZ This should be checked against eeprom location 6, low byte */
709	outb(PORT + IEE16_MEMDEC, decode & 0xFF);
710	/* ZZZ This should be checked against eeprom location 1, low byte */
711	outb(PORT + IEE16_MCTRL, adjust);
712	/* ZZZ Now if I could find this one I would have it made */
713	outb(PORT + IEE16_MPCTRL, (~decode & 0xFF));
714	/* ZZZ I think this is location 6, high byte */
715	outb(PORT + IEE16_MECTRL, edecode);	/* XXX disable Exxx */
716
717	(void) kvtop(dvp->id_maddr);
718
719	/*
720	 * first prime the stupid bart DRAM controller so that it works,
721	 * then zero out all of memory.
722	 */
723	bzero(sc->iomembot, 32);
724	bzero(sc->iomembot, sc->iosize);
725
726	/*
727	 * Get the encoded interrupt number from the EEPROM, check it
728	 * against the passed in IRQ.  Issue a warning if they do not match.
729	 * Always use the passed in IRQ, not the one in the EEPROM.
730	 */
731	irq = ee16_read_eeprom(sc, IEE16_EEPROM_CONFIG1);
732	irq = (irq & IEE16_EEPROM_IRQ) >> IEE16_EEPROM_IRQ_SHIFT;
733	irq = irq_translate[irq];
734	if (dvp->id_irq > 0) {
735		if (irq != dvp->id_irq) {
736			printf("ie%d: WARNING: board configured "
737			       "at irq %u, using %u\n",
738			       dvp->id_unit, dvp->id_irq, irq);
739			irq = dvp->id_unit;
740		}
741	} else {
742		dvp->id_irq = irq;
743	}
744	sc->irq_encoded = irq_encode[ffs(irq) - 1];
745
746	/*
747	 * Get the hardware ethernet address from the EEPROM and save it in
748	 * the softc for use by the 586 setup code.
749	 */
750	eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_HIGH);
751	sc->arpcom.ac_enaddr[1] = eaddrtemp & 0xFF;
752	sc->arpcom.ac_enaddr[0] = eaddrtemp >> 8;
753	eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_MID);
754	sc->arpcom.ac_enaddr[3] = eaddrtemp & 0xFF;
755	sc->arpcom.ac_enaddr[2] = eaddrtemp >> 8;
756	eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_LOW);
757	sc->arpcom.ac_enaddr[5] = eaddrtemp & 0xFF;
758	sc->arpcom.ac_enaddr[4] = eaddrtemp >> 8;
759
760	/* disable the board interrupts */
761	outb(PORT + IEE16_IRQ, sc->irq_encoded);
762
763	/* enable loopback to keep bad packets off the wire */
764	if (sc->hard_type == IE_EE16) {
765		bart_config = inb(PORT + IEE16_CONFIG);
766		bart_config |= IEE16_BART_LOOPBACK;
767		bart_config |= IEE16_BART_MCS16_TEST;/* inb doesn't get bit! */
768		outb(PORT + IEE16_CONFIG, bart_config);
769		bart_config = inb(PORT + IEE16_CONFIG);
770	}
771	/* take the board out of reset state */
772	outb(PORT + IEE16_ECTRL, 0);
773	DELAY(100);
774
775	if (!check_ie_present(unit, dvp->id_maddr, sc->iosize))
776		return (0);
777
778	return (16);		/* return the number of I/O ports */
779}
780
781/*
782 * Taken almost exactly from Bill's if_is.c, then modified beyond recognition.
783 */
784int
785ieattach(struct isa_device *dvp)
786{
787	int	factor;
788	int	unit = dvp->id_unit;
789	struct ie_softc *ie = &ie_softc[unit];
790	struct ifnet *ifp = &ie->arpcom.ac_if;
791	size_t	allocsize;
792
793	dvp->id_ointr = ieintr;
794
795	/*
796	 * based on the amount of memory we have, allocate our tx and rx
797	 * resources.
798	 */
799	factor = dvp->id_msize / 16384;
800	ie->nframes = factor * NFRAMES;
801	ie->nrxbufs = factor * NRXBUFS;
802	ie->ntxbufs = factor * NTXBUFS;
803
804	/*
805	 * Since all of these guys are arrays of pointers, allocate as one
806	 * big chunk and dole out accordingly.
807	 */
808	allocsize = sizeof(void *) * (ie->nframes
809				      + (ie->nrxbufs * 2)
810				      + (ie->ntxbufs * 3));
811	ie->rframes = (volatile struct ie_recv_frame_desc **) malloc(allocsize,
812								     M_DEVBUF,
813								   M_NOWAIT);
814	if (ie->rframes == NULL)
815		return (0);
816	ie->rbuffs =
817	    (volatile struct ie_recv_buf_desc **)&ie->rframes[ie->nframes];
818	ie->cbuffs = (volatile u_char **)&ie->rbuffs[ie->nrxbufs];
819	ie->xmit_cmds =
820	    (volatile struct ie_xmit_cmd **)&ie->cbuffs[ie->nrxbufs];
821	ie->xmit_buffs =
822	    (volatile struct ie_xmit_buf **)&ie->xmit_cmds[ie->ntxbufs];
823	ie->xmit_cbuffs = (u_char **)&ie->xmit_buffs[ie->ntxbufs];
824
825	ifp->if_softc = ie;
826	ifp->if_unit = unit;
827	ifp->if_name = iedriver.name;
828	ifp->if_mtu = ETHERMTU;
829	printf("ie%d: <%s R%d> address %6D\n", unit,
830	       ie_hardware_names[ie->hard_type],
831	       ie->hard_vers + 1,
832	       ie->arpcom.ac_enaddr, ":");
833
834	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
835	ifp->if_output = ether_output;
836	ifp->if_start = iestart;
837	ifp->if_ioctl = ieioctl;
838	ifp->if_type = IFT_ETHER;
839	ifp->if_addrlen = 6;
840	ifp->if_hdrlen = 14;
841
842	if (ie->hard_type == IE_EE16)
843		at_shutdown(ee16_shutdown, ie, SHUTDOWN_POST_SYNC);
844
845#if NBPFILTER > 0
846	bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
847#endif
848
849	if_attach(ifp);
850	ether_ifattach(ifp);
851	return (1);
852}
853
854/*
855 * What to do upon receipt of an interrupt.
856 */
857static void
858ieintr(int unit)
859{
860	register struct ie_softc *ie = &ie_softc[unit];
861	register u_short status;
862
863	/* Clear the interrupt latch on the 3C507. */
864	if (ie->hard_type == IE_3C507
865	 && (inb(PORT + IE507_CTRL) & EL_CTRL_INTL))
866		outb(PORT + IE507_ICTRL, 1);
867
868	/* disable interrupts on the EE16. */
869	if (ie->hard_type == IE_EE16)
870		outb(PORT + IEE16_IRQ, ie->irq_encoded);
871
872	status = ie->scb->ie_status;
873
874loop:
875
876	/* Don't ack interrupts which we didn't receive */
877	ie_ack(ie->scb, IE_ST_WHENCE & status, unit, ie->ie_chan_attn);
878
879	if (status & (IE_ST_RECV | IE_ST_RNR)) {
880#ifdef DEBUG
881		in_ierint++;
882		if (ie_debug & IED_RINT)
883			printf("ie%d: rint\n", unit);
884#endif
885		ierint(unit, ie);
886#ifdef DEBUG
887		in_ierint--;
888#endif
889	}
890	if (status & IE_ST_DONE) {
891#ifdef DEBUG
892		in_ietint++;
893		if (ie_debug & IED_TINT)
894			printf("ie%d: tint\n", unit);
895#endif
896		ietint(unit, ie);
897#ifdef DEBUG
898		in_ietint--;
899#endif
900	}
901	if (status & IE_ST_RNR) {
902#ifdef DEBUG
903		if (ie_debug & IED_RNR)
904			printf("ie%d: rnr\n", unit);
905#endif
906		iernr(unit, ie);
907	}
908#ifdef DEBUG
909	if ((status & IE_ST_ALLDONE)
910	    && (ie_debug & IED_CNA))
911		printf("ie%d: cna\n", unit);
912#endif
913
914	if ((status = ie->scb->ie_status) & IE_ST_WHENCE)
915		goto loop;
916
917	/* Clear the interrupt latch on the 3C507. */
918	if (ie->hard_type == IE_3C507)
919		outb(PORT + IE507_ICTRL, 1);
920
921	/* enable interrupts on the EE16. */
922	if (ie->hard_type == IE_EE16)
923		outb(PORT + IEE16_IRQ, ie->irq_encoded | IEE16_IRQ_ENABLE);
924
925}
926
927/*
928 * Process a received-frame interrupt.
929 */
930static int
931ierint(int unit, struct ie_softc *ie)
932{
933	int	i, status;
934	static int timesthru = 1024;
935
936	i = ie->rfhead;
937	while (1) {
938		status = ie->rframes[i]->ie_fd_status;
939
940		if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) {
941			ie->arpcom.ac_if.if_ipackets++;
942			if (!--timesthru) {
943				ie->arpcom.ac_if.if_ierrors +=
944				    ie->scb->ie_err_crc +
945				    ie->scb->ie_err_align +
946				    ie->scb->ie_err_resource +
947				    ie->scb->ie_err_overrun;
948				ie->scb->ie_err_crc = 0;
949				ie->scb->ie_err_align = 0;
950				ie->scb->ie_err_resource = 0;
951				ie->scb->ie_err_overrun = 0;
952				timesthru = 1024;
953			}
954			ie_readframe(unit, ie, i);
955		} else {
956			if (status & IE_FD_RNR) {
957				if (!(ie->scb->ie_status & IE_RU_READY)) {
958					ie->rframes[0]->ie_fd_next =
959					    MK_16(MEM, ie->rbuffs[0]);
960					ie->scb->ie_recv_list =
961					    MK_16(MEM, ie->rframes[0]);
962					command_and_wait(unit, IE_RU_START,
963							 0, 0);
964				}
965			}
966			break;
967		}
968		i = (i + 1) % ie->nframes;
969	}
970	return (0);
971}
972
973/*
974 * Process a command-complete interrupt.  These are only generated by
975 * the transmission of frames.	This routine is deceptively simple, since
976 * most of the real work is done by iestart().
977 */
978static int
979ietint(int unit, struct ie_softc *ie)
980{
981	int	status;
982	int	i;
983
984	ie->arpcom.ac_if.if_timer = 0;
985	ie->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
986
987	for (i = 0; i < ie->xmit_count; i++) {
988		status = ie->xmit_cmds[i]->ie_xmit_status;
989
990		if (status & IE_XS_LATECOLL) {
991			printf("ie%d: late collision\n", unit);
992			ie->arpcom.ac_if.if_collisions++;
993			ie->arpcom.ac_if.if_oerrors++;
994		} else if (status & IE_XS_NOCARRIER) {
995			printf("ie%d: no carrier\n", unit);
996			ie->arpcom.ac_if.if_oerrors++;
997		} else if (status & IE_XS_LOSTCTS) {
998			printf("ie%d: lost CTS\n", unit);
999			ie->arpcom.ac_if.if_oerrors++;
1000		} else if (status & IE_XS_UNDERRUN) {
1001			printf("ie%d: DMA underrun\n", unit);
1002			ie->arpcom.ac_if.if_oerrors++;
1003		} else if (status & IE_XS_EXCMAX) {
1004			printf("ie%d: too many collisions\n", unit);
1005			ie->arpcom.ac_if.if_collisions += 16;
1006			ie->arpcom.ac_if.if_oerrors++;
1007		} else {
1008			ie->arpcom.ac_if.if_opackets++;
1009			ie->arpcom.ac_if.if_collisions += status & IE_XS_MAXCOLL;
1010		}
1011	}
1012	ie->xmit_count = 0;
1013
1014	/*
1015	 * If multicast addresses were added or deleted while we were
1016	 * transmitting, ie_mc_reset() set the want_mcsetup flag indicating
1017	 * that we should do it.
1018	 */
1019	if (ie->want_mcsetup) {
1020		mc_setup(unit, (caddr_t) ie->xmit_cbuffs[0], ie->scb);
1021		ie->want_mcsetup = 0;
1022	}
1023	/* Wish I knew why this seems to be necessary... */
1024	ie->xmit_cmds[0]->ie_xmit_status |= IE_STAT_COMPL;
1025
1026	iestart(&ie->arpcom.ac_if);
1027	return (0);		/* shouldn't be necessary */
1028}
1029
1030/*
1031 * Process a receiver-not-ready interrupt.  I believe that we get these
1032 * when there aren't enough buffers to go around.  For now (FIXME), we
1033 * just restart the receiver, and hope everything's ok.
1034 */
1035static int
1036iernr(int unit, struct ie_softc *ie)
1037{
1038#ifdef doesnt_work
1039	setup_rfa((caddr_t) ie->rframes[0], ie);
1040
1041	ie->scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1042	command_and_wait(unit, IE_RU_START, 0, 0);
1043#else
1044	/* This doesn't work either, but it doesn't hang either. */
1045	command_and_wait(unit, IE_RU_DISABLE, 0, 0);	/* just in case */
1046	setup_rfa((caddr_t) ie->rframes[0], ie);	/* ignore cast-qual */
1047
1048	ie->scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1049	command_and_wait(unit, IE_RU_START, 0, 0);	/* was ENABLE */
1050
1051#endif
1052	ie_ack(ie->scb, IE_ST_WHENCE, unit, ie->ie_chan_attn);
1053
1054	ie->arpcom.ac_if.if_ierrors++;
1055	return (0);
1056}
1057
1058/*
1059 * Compare two Ether/802 addresses for equality, inlined and
1060 * unrolled for speed.	I'd love to have an inline assembler
1061 * version of this...
1062 */
1063static __inline int
1064ether_equal(u_char * one, u_char * two)
1065{
1066	if (one[0] != two[0])
1067		return (0);
1068	if (one[1] != two[1])
1069		return (0);
1070	if (one[2] != two[2])
1071		return (0);
1072	if (one[3] != two[3])
1073		return (0);
1074	if (one[4] != two[4])
1075		return (0);
1076	if (one[5] != two[5])
1077		return (0);
1078	return 1;
1079}
1080
1081/*
1082 * Check for a valid address.  to_bpf is filled in with one of the following:
1083 *   0 -> BPF doesn't get this packet
1084 *   1 -> BPF does get this packet
1085 *   2 -> BPF does get this packet, but we don't
1086 * Return value is true if the packet is for us, and false otherwise.
1087 *
1088 * This routine is a mess, but it's also critical that it be as fast
1089 * as possible.	 It could be made cleaner if we can assume that the
1090 * only client which will fiddle with IFF_PROMISC is BPF.  This is
1091 * probably a good assumption, but we do not make it here.  (Yet.)
1092 */
1093static __inline int
1094check_eh(struct ie_softc * ie, struct ether_header * eh, int *to_bpf)
1095{
1096	int	i;
1097
1098	switch (ie->promisc) {
1099	case IFF_ALLMULTI:
1100		/*
1101		 * Receiving all multicasts, but no unicasts except those
1102		 * destined for us.
1103		 */
1104#if NBPFILTER > 0
1105		/* BPF gets this packet if anybody cares */
1106		*to_bpf = (ie->arpcom.ac_if.if_bpf != 0);
1107#endif
1108		if (eh->ether_dhost[0] & 1) {
1109			return (1);
1110		}
1111		if (ether_equal(eh->ether_dhost, ie->arpcom.ac_enaddr))
1112			return (1);
1113		return (0);
1114
1115	case IFF_PROMISC:
1116		/*
1117		 * Receiving all packets.  These need to be passed on to
1118		 * BPF.
1119		 */
1120#if NBPFILTER > 0
1121		*to_bpf = (ie->arpcom.ac_if.if_bpf != 0);
1122#endif
1123		/* If for us, accept and hand up to BPF */
1124		if (ether_equal(eh->ether_dhost, ie->arpcom.ac_enaddr))
1125			return (1);
1126
1127#if NBPFILTER > 0
1128		if (*to_bpf)
1129			*to_bpf = 2;	/* we don't need to see it */
1130#endif
1131
1132		/*
1133		 * Not a multicast, so BPF wants to see it but we don't.
1134		 */
1135		if (!(eh->ether_dhost[0] & 1))
1136			return (1);
1137
1138		/*
1139		 * If it's one of our multicast groups, accept it and pass
1140		 * it up.
1141		 */
1142		for (i = 0; i < ie->mcast_count; i++) {
1143			if (ether_equal(eh->ether_dhost,
1144			    (u_char *)&ie->mcast_addrs[i])) {
1145#if NBPFILTER > 0
1146				if (*to_bpf)
1147					*to_bpf = 1;
1148#endif
1149				return (1);
1150			}
1151		}
1152		return (1);
1153
1154	case IFF_ALLMULTI | IFF_PROMISC:
1155		/*
1156		 * Acting as a multicast router, and BPF running at the same
1157		 * time. Whew!	(Hope this is a fast machine...)
1158		 */
1159#if NBPFILTER > 0
1160		*to_bpf = (ie->arpcom.ac_if.if_bpf != 0);
1161#endif
1162		/* We want to see multicasts. */
1163		if (eh->ether_dhost[0] & 1)
1164			return (1);
1165
1166		/* We want to see our own packets */
1167		if (ether_equal(eh->ether_dhost, ie->arpcom.ac_enaddr))
1168			return (1);
1169
1170		/* Anything else goes to BPF but nothing else. */
1171#if NBPFILTER > 0
1172		if (*to_bpf)
1173			*to_bpf = 2;
1174#endif
1175		return (1);
1176
1177	default:
1178		/*
1179		 * Only accept unicast packets destined for us, or
1180		 * multicasts for groups that we belong to.  For now, we
1181		 * assume that the '586 will only return packets that we
1182		 * asked it for.  This isn't strictly true (it uses hashing
1183		 * for the multicast filter), but it will do in this case,
1184		 * and we want to get out of here as quickly as possible.
1185		 */
1186#if NBPFILTER > 0
1187		*to_bpf = (ie->arpcom.ac_if.if_bpf != 0);
1188#endif
1189		return (1);
1190	}
1191	return (0);
1192}
1193
1194/*
1195 * We want to isolate the bits that have meaning...  This assumes that
1196 * IE_RBUF_SIZE is an even power of two.  If somehow the act_len exceeds
1197 * the size of the buffer, then we are screwed anyway.
1198 */
1199static __inline int
1200ie_buflen(struct ie_softc * ie, int head)
1201{
1202	return (ie->rbuffs[head]->ie_rbd_actual
1203		& (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1)));
1204}
1205
1206static __inline int
1207ie_packet_len(int unit, struct ie_softc * ie)
1208{
1209	int	i;
1210	int	head = ie->rbhead;
1211	int	acc = 0;
1212
1213	do {
1214		if (!(ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
1215#ifdef DEBUG
1216			print_rbd(ie->rbuffs[ie->rbhead]);
1217#endif
1218			log(LOG_ERR,
1219			    "ie%d: receive descriptors out of sync at %d\n",
1220			    unit, ie->rbhead);
1221			iereset(unit);
1222			return (-1);
1223		}
1224		i = ie->rbuffs[head]->ie_rbd_actual & IE_RBD_LAST;
1225
1226		acc += ie_buflen(ie, head);
1227		head = (head + 1) % ie->nrxbufs;
1228	} while (!i);
1229
1230	return (acc);
1231}
1232
1233/*
1234 * Read data off the interface, and turn it into an mbuf chain.
1235 *
1236 * This code is DRAMATICALLY different from the previous version; this
1237 * version tries to allocate the entire mbuf chain up front, given the
1238 * length of the data available.  This enables us to allocate mbuf
1239 * clusters in many situations where before we would have had a long
1240 * chain of partially-full mbufs.  This should help to speed up the
1241 * operation considerably.  (Provided that it works, of course.)
1242 */
1243static __inline int
1244ieget(int unit, struct ie_softc *ie, struct mbuf **mp,
1245      struct ether_header *ehp, int *to_bpf)
1246{
1247	struct	mbuf *m, *top, **mymp;
1248	int	i;
1249	int	offset;
1250	int	totlen, resid;
1251	int	thismboff;
1252	int	head;
1253
1254	totlen = ie_packet_len(unit, ie);
1255	if (totlen <= 0)
1256		return (-1);
1257
1258	i = ie->rbhead;
1259
1260	/*
1261	 * Snarf the Ethernet header.
1262	 */
1263	bcopy((caddr_t) ie->cbuffs[i], (caddr_t) ehp, sizeof *ehp);
1264	/* ignore cast-qual warning here */
1265
1266	/*
1267	 * As quickly as possible, check if this packet is for us. If not,
1268	 * don't waste a single cycle copying the rest of the packet in.
1269	 * This is only a consideration when FILTER is defined; i.e., when
1270	 * we are either running BPF or doing multicasting.
1271	 */
1272	if (!check_eh(ie, ehp, to_bpf)) {
1273		ie_drop_packet_buffer(unit, ie);
1274		ie->arpcom.ac_if.if_ierrors--;	/* just this case, it's not an
1275						 * error
1276						 */
1277		return (-1);
1278	}
1279	totlen -= (offset = sizeof *ehp);
1280
1281	MGETHDR(*mp, M_DONTWAIT, MT_DATA);
1282	if (!*mp) {
1283		ie_drop_packet_buffer(unit, ie);
1284		return (-1);
1285	}
1286	m = *mp;
1287	m->m_pkthdr.rcvif = &ie->arpcom.ac_if;
1288	m->m_len = MHLEN;
1289	resid = m->m_pkthdr.len = totlen;
1290	top = 0;
1291	mymp = &top;
1292
1293	/*
1294	 * This loop goes through and allocates mbufs for all the data we
1295	 * will be copying in.	It does not actually do the copying yet.
1296	 */
1297	do {			/* while(resid > 0) */
1298		/*
1299		 * Try to allocate an mbuf to hold the data that we have.
1300		 * If we already allocated one, just get another one and
1301		 * stick it on the end (eventually).  If we don't already
1302		 * have one, try to allocate an mbuf cluster big enough to
1303		 * hold the whole packet, if we think it's reasonable, or a
1304		 * single mbuf which may or may not be big enough. Got that?
1305		 */
1306		if (top) {
1307			MGET(m, M_DONTWAIT, MT_DATA);
1308			if (!m) {
1309				m_freem(top);
1310				ie_drop_packet_buffer(unit, ie);
1311				return (-1);
1312			}
1313			m->m_len = MLEN;
1314		}
1315		if (resid >= MINCLSIZE) {
1316			MCLGET(m, M_DONTWAIT);
1317			if (m->m_flags & M_EXT)
1318				m->m_len = min(resid, MCLBYTES);
1319		} else {
1320			if (resid < m->m_len) {
1321				if (!top && resid + max_linkhdr <= m->m_len)
1322					m->m_data += max_linkhdr;
1323				m->m_len = resid;
1324			}
1325		}
1326		resid -= m->m_len;
1327		*mymp = m;
1328		mymp = &m->m_next;
1329	} while (resid > 0);
1330
1331	resid = totlen;
1332	m = top;
1333	thismboff = 0;
1334	head = ie->rbhead;
1335
1336	/*
1337	 * Now we take the mbuf chain (hopefully only one mbuf most of the
1338	 * time) and stuff the data into it.  There are no possible failures
1339	 * at or after this point.
1340	 */
1341	while (resid > 0) {	/* while there's stuff left */
1342		int	thislen = ie_buflen(ie, head) - offset;
1343
1344		/*
1345		 * If too much data for the current mbuf, then fill the
1346		 * current one up, go to the next one, and try again.
1347		 */
1348		if (thislen > m->m_len - thismboff) {
1349			int	newlen = m->m_len - thismboff;
1350
1351			bcopy((caddr_t) (ie->cbuffs[head] + offset),
1352			      mtod(m, caddr_t) +thismboff, (unsigned) newlen);
1353			/* ignore cast-qual warning */
1354			m = m->m_next;
1355			thismboff = 0;	/* new mbuf, so no offset */
1356			offset += newlen;	/* we are now this far into
1357						 * the packet */
1358			resid -= newlen;	/* so there is this much left
1359						 * to get */
1360			continue;
1361		}
1362		/*
1363		 * If there is more than enough space in the mbuf to hold
1364		 * the contents of this buffer, copy everything in, advance
1365		 * pointers, and so on.
1366		 */
1367		if (thislen < m->m_len - thismboff) {
1368			bcopy((caddr_t) (ie->cbuffs[head] + offset),
1369			    mtod(m, caddr_t) +thismboff, (unsigned) thislen);
1370			thismboff += thislen;	/* we are this far into the
1371						 * mbuf */
1372			resid -= thislen;	/* and this much is left */
1373			goto nextbuf;
1374		}
1375		/*
1376		 * Otherwise, there is exactly enough space to put this
1377		 * buffer's contents into the current mbuf.  Do the
1378		 * combination of the above actions.
1379		 */
1380		bcopy((caddr_t) (ie->cbuffs[head] + offset),
1381		      mtod(m, caddr_t) + thismboff, (unsigned) thislen);
1382		m = m->m_next;
1383		thismboff = 0;		/* new mbuf, start at the beginning */
1384		resid -= thislen;	/* and we are this far through */
1385
1386		/*
1387		 * Advance all the pointers.  We can get here from either of
1388		 * the last two cases, but never the first.
1389		 */
1390nextbuf:
1391		offset = 0;
1392		ie->rbuffs[head]->ie_rbd_actual = 0;
1393		ie->rbuffs[head]->ie_rbd_length |= IE_RBD_LAST;
1394		ie->rbhead = head = (head + 1) % ie->nrxbufs;
1395		ie->rbuffs[ie->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
1396		ie->rbtail = (ie->rbtail + 1) % ie->nrxbufs;
1397	}
1398
1399	/*
1400	 * Unless something changed strangely while we were doing the copy,
1401	 * we have now copied everything in from the shared memory. This
1402	 * means that we are done.
1403	 */
1404	return (0);
1405}
1406
1407/*
1408 * Read frame NUM from unit UNIT (pre-cached as IE).
1409 *
1410 * This routine reads the RFD at NUM, and copies in the buffers from
1411 * the list of RBD, then rotates the RBD and RFD lists so that the receiver
1412 * doesn't start complaining.  Trailers are DROPPED---there's no point
1413 * in wasting time on confusing code to deal with them.	 Hopefully,
1414 * this machine will never ARP for trailers anyway.
1415 */
1416static void
1417ie_readframe(int unit, struct ie_softc *ie, int	num/* frame number to read */)
1418{
1419	struct ie_recv_frame_desc rfd;
1420	struct mbuf *m = 0;
1421	struct ether_header eh;
1422
1423#if NBPFILTER > 0
1424	int	bpf_gets_it = 0;
1425
1426#endif
1427
1428	bcopy((caddr_t) (ie->rframes[num]), &rfd,
1429	      sizeof(struct ie_recv_frame_desc));
1430
1431	/*
1432	 * Immediately advance the RFD list, since we we have copied ours
1433	 * now.
1434	 */
1435	ie->rframes[num]->ie_fd_status = 0;
1436	ie->rframes[num]->ie_fd_last |= IE_FD_LAST;
1437	ie->rframes[ie->rftail]->ie_fd_last &= ~IE_FD_LAST;
1438	ie->rftail = (ie->rftail + 1) % ie->nframes;
1439	ie->rfhead = (ie->rfhead + 1) % ie->nframes;
1440
1441	if (rfd.ie_fd_status & IE_FD_OK) {
1442#if NBPFILTER > 0
1443		if (ieget(unit, ie, &m, &eh, &bpf_gets_it)) {
1444#else
1445		if (ieget(unit, ie, &m, &eh, (int *)0)) {
1446#endif
1447			ie->arpcom.ac_if.if_ierrors++;	/* this counts as an
1448							 * error */
1449			return;
1450		}
1451	}
1452#ifdef DEBUG
1453	if (ie_debug & IED_READFRAME) {
1454		printf("ie%d: frame from ether %6D type %x\n", unit,
1455		       eh.ether_shost, ":", (unsigned) eh.ether_type);
1456	}
1457	if (ntohs(eh.ether_type) > ETHERTYPE_TRAIL
1458	    && ntohs(eh.ether_type) < (ETHERTYPE_TRAIL + ETHERTYPE_NTRAILER))
1459		printf("received trailer!\n");
1460#endif
1461
1462	if (!m)
1463		return;
1464
1465	if (last_not_for_us) {
1466		m_freem(last_not_for_us);
1467		last_not_for_us = 0;
1468	}
1469#if NBPFILTER > 0
1470	/*
1471	 * Check for a BPF filter; if so, hand it up. Note that we have to
1472	 * stick an extra mbuf up front, because bpf_mtap expects to have
1473	 * the ether header at the front. It doesn't matter that this
1474	 * results in an ill-formatted mbuf chain, since BPF just looks at
1475	 * the data.  (It doesn't try to free the mbuf, tho' it will make a
1476	 * copy for tcpdump.)
1477	 */
1478	if (bpf_gets_it) {
1479		struct mbuf m0;
1480
1481		m0.m_len = sizeof eh;
1482		m0.m_data = (caddr_t)&eh;
1483		m0.m_next = m;
1484
1485		/* Pass it up */
1486		bpf_mtap(&ie->arpcom.ac_if, &m0);
1487	}
1488	/*
1489	 * A signal passed up from the filtering code indicating that the
1490	 * packet is intended for BPF but not for the protocol machinery. We
1491	 * can save a few cycles by not handing it off to them.
1492	 */
1493	if (bpf_gets_it == 2) {
1494		last_not_for_us = m;
1495		return;
1496	}
1497#endif				/* NBPFILTER > 0 */
1498	/*
1499	 * In here there used to be code to check destination addresses upon
1500	 * receipt of a packet.	 We have deleted that code, and replaced it
1501	 * with code to check the address much earlier in the cycle, before
1502	 * copying the data in; this saves us valuable cycles when operating
1503	 * as a multicast router or when using BPF.
1504	 */
1505
1506	/*
1507	 * Finally pass this packet up to higher layers.
1508	 */
1509	ether_input(&ie->arpcom.ac_if, &eh, m);
1510}
1511
1512static void
1513ie_drop_packet_buffer(int unit, struct ie_softc * ie)
1514{
1515	int	i;
1516
1517	do {
1518		/*
1519		 * This means we are somehow out of sync.  So, we reset the
1520		 * adapter.
1521		 */
1522		if (!(ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
1523#ifdef DEBUG
1524			print_rbd(ie->rbuffs[ie->rbhead]);
1525#endif
1526			log(LOG_ERR, "ie%d: receive descriptors out of sync at %d\n",
1527			    unit, ie->rbhead);
1528			iereset(unit);
1529			return;
1530		}
1531		i = ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_LAST;
1532
1533		ie->rbuffs[ie->rbhead]->ie_rbd_length |= IE_RBD_LAST;
1534		ie->rbuffs[ie->rbhead]->ie_rbd_actual = 0;
1535		ie->rbhead = (ie->rbhead + 1) % ie->nrxbufs;
1536		ie->rbuffs[ie->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
1537		ie->rbtail = (ie->rbtail + 1) % ie->nrxbufs;
1538	} while (!i);
1539}
1540
1541
1542/*
1543 * Start transmission on an interface.
1544 */
1545static void
1546iestart(struct ifnet *ifp)
1547{
1548	struct	 ie_softc *ie = ifp->if_softc;
1549	struct	 mbuf *m0, *m;
1550	unsigned char *buffer;
1551	u_short	 len;
1552
1553	/*
1554	 * This is not really volatile, in this routine, but it makes gcc
1555	 * happy.
1556	 */
1557	volatile u_short *bptr = &ie->scb->ie_command_list;
1558
1559	if (!(ifp->if_flags & IFF_RUNNING))
1560		return;
1561	if (ifp->if_flags & IFF_OACTIVE)
1562		return;
1563
1564	do {
1565		IF_DEQUEUE(&ie->arpcom.ac_if.if_snd, m);
1566		if (!m)
1567			break;
1568
1569		buffer = ie->xmit_cbuffs[ie->xmit_count];
1570		len = 0;
1571
1572		for (m0 = m; m && len < IE_BUF_LEN; m = m->m_next) {
1573			bcopy(mtod(m, caddr_t), buffer, m->m_len);
1574			buffer += m->m_len;
1575			len += m->m_len;
1576		}
1577
1578		m_freem(m0);
1579		len = max(len, ETHER_MIN_LEN);
1580
1581#if NBPFILTER > 0
1582		/*
1583		 * See if bpf is listening on this interface, let it see the
1584		 * packet before we commit it to the wire.
1585		 */
1586		if (ie->arpcom.ac_if.if_bpf)
1587			bpf_tap(&ie->arpcom.ac_if,
1588				ie->xmit_cbuffs[ie->xmit_count], len);
1589#endif
1590
1591		ie->xmit_buffs[ie->xmit_count]->ie_xmit_flags =
1592		    IE_XMIT_LAST|len;
1593		ie->xmit_buffs[ie->xmit_count]->ie_xmit_next = 0xffff;
1594		ie->xmit_buffs[ie->xmit_count]->ie_xmit_buf =
1595		    MK_24(ie->iomem, ie->xmit_cbuffs[ie->xmit_count]);
1596
1597		ie->xmit_cmds[ie->xmit_count]->com.ie_cmd_cmd = IE_CMD_XMIT;
1598		ie->xmit_cmds[ie->xmit_count]->ie_xmit_status = 0;
1599		ie->xmit_cmds[ie->xmit_count]->ie_xmit_desc =
1600		    MK_16(ie->iomem, ie->xmit_buffs[ie->xmit_count]);
1601
1602		*bptr = MK_16(ie->iomem, ie->xmit_cmds[ie->xmit_count]);
1603		bptr = &ie->xmit_cmds[ie->xmit_count]->com.ie_cmd_link;
1604		ie->xmit_count++;
1605	} while (ie->xmit_count < ie->ntxbufs);
1606
1607	/*
1608	 * If we queued up anything for transmission, send it.
1609	 */
1610	if (ie->xmit_count) {
1611		ie->xmit_cmds[ie->xmit_count - 1]->com.ie_cmd_cmd |=
1612		    IE_CMD_LAST | IE_CMD_INTR;
1613
1614		/*
1615		 * By passing the command pointer as a null, we tell
1616		 * command_and_wait() to pretend that this isn't an action
1617		 * command.  I wish I understood what was happening here.
1618		 */
1619		command_and_wait(ifp->if_unit, IE_CU_START, 0, 0);
1620		ifp->if_flags |= IFF_OACTIVE;
1621	}
1622	return;
1623}
1624
1625/*
1626 * Check to see if there's an 82586 out there.
1627 */
1628static int
1629check_ie_present(int unit, caddr_t where, unsigned size)
1630{
1631	volatile struct ie_sys_conf_ptr *scp;
1632	volatile struct ie_int_sys_conf_ptr *iscp;
1633	volatile struct ie_sys_ctl_block *scb;
1634	u_long	realbase;
1635	int	s;
1636
1637	s = splimp();
1638
1639	realbase = (uintptr_t) where + size - (1 << 24);
1640
1641	scp = (volatile struct ie_sys_conf_ptr *) (uintptr_t)
1642	      (realbase + IE_SCP_ADDR);
1643	bzero((char *) scp, sizeof *scp);
1644
1645	/*
1646	 * First we put the ISCP at the bottom of memory; this tests to make
1647	 * sure that our idea of the size of memory is the same as the
1648	 * controller's. This is NOT where the ISCP will be in normal
1649	 * operation.
1650	 */
1651	iscp = (volatile struct ie_int_sys_conf_ptr *) where;
1652	bzero((char *)iscp, sizeof *iscp);
1653
1654	scb = (volatile struct ie_sys_ctl_block *) where;
1655	bzero((char *)scb, sizeof *scb);
1656
1657	scp->ie_bus_use = ie_softc[unit].bus_use;	/* 8-bit or 16-bit */
1658	scp->ie_iscp_ptr = (caddr_t) ((volatile caddr_t) iscp -
1659				      (volatile caddr_t) (volatile uintptr_t)
1660				      realbase);
1661
1662	iscp->ie_busy = 1;
1663	iscp->ie_scb_offset = MK_16(realbase, scb) + 256;
1664
1665	(*ie_softc[unit].ie_reset_586) (unit);
1666	(*ie_softc[unit].ie_chan_attn) (unit);
1667
1668	DELAY(100);		/* wait a while... */
1669
1670	if (iscp->ie_busy) {
1671		splx(s);
1672		return (0);
1673	}
1674	/*
1675	 * Now relocate the ISCP to its real home, and reset the controller
1676	 * again.
1677	 */
1678	iscp = (void *) Align((caddr_t) (uintptr_t)
1679			      (realbase + IE_SCP_ADDR -
1680			       sizeof(struct ie_int_sys_conf_ptr)));
1681	bzero((char *) iscp, sizeof *iscp);	/* ignore cast-qual */
1682
1683	scp->ie_iscp_ptr = (caddr_t) ((caddr_t) iscp -
1684				      (caddr_t) (uintptr_t) realbase);
1685	/* ignore cast-qual */
1686
1687	iscp->ie_busy = 1;
1688	iscp->ie_scb_offset = MK_16(realbase, scb);
1689
1690	(*ie_softc[unit].ie_reset_586) (unit);
1691	(*ie_softc[unit].ie_chan_attn) (unit);
1692
1693	DELAY(100);
1694
1695	if (iscp->ie_busy) {
1696		splx(s);
1697		return (0);
1698	}
1699	ie_softc[unit].iosize = size;
1700	ie_softc[unit].iomem = (caddr_t) (uintptr_t) realbase;
1701
1702	ie_softc[unit].iscp = iscp;
1703	ie_softc[unit].scb = scb;
1704
1705	/*
1706	 * Acknowledge any interrupts we may have caused...
1707	 */
1708	ie_ack(scb, IE_ST_WHENCE, unit, ie_softc[unit].ie_chan_attn);
1709	splx(s);
1710
1711	return (1);
1712}
1713
1714/*
1715 * Divine the memory size of ie board UNIT.
1716 * Better hope there's nothing important hiding just below the ie card...
1717 */
1718static void
1719find_ie_mem_size(int unit)
1720{
1721	unsigned size;
1722
1723	ie_softc[unit].iosize = 0;
1724
1725	for (size = 65536; size >= 8192; size -= 8192) {
1726		if (check_ie_present(unit, ie_softc[unit].iomembot, size)) {
1727			return;
1728		}
1729	}
1730
1731	return;
1732}
1733
1734void
1735el_reset_586(int unit)
1736{
1737	outb(PORT + IE507_CTRL, EL_CTRL_RESET);
1738	DELAY(100);
1739	outb(PORT + IE507_CTRL, EL_CTRL_NORMAL);
1740	DELAY(100);
1741}
1742
1743void
1744sl_reset_586(int unit)
1745{
1746	outb(PORT + IEATT_RESET, 0);
1747}
1748
1749void
1750ee16_reset_586(int unit)
1751{
1752	outb(PORT + IEE16_ECTRL, IEE16_RESET_586);
1753	DELAY(100);
1754	outb(PORT + IEE16_ECTRL, 0);
1755	DELAY(100);
1756}
1757
1758void
1759el_chan_attn(int unit)
1760{
1761	outb(PORT + IE507_ATTN, 1);
1762}
1763
1764void
1765sl_chan_attn(int unit)
1766{
1767	outb(PORT + IEATT_ATTN, 0);
1768}
1769
1770void
1771ee16_chan_attn(int unit)
1772{
1773	outb(PORT + IEE16_ATTN, 0);
1774}
1775
1776u_short
1777ee16_read_eeprom(struct ie_softc *sc, int location)
1778{
1779	int	ectrl, edata;
1780
1781	ectrl = inb(sc->port + IEE16_ECTRL);
1782	ectrl &= IEE16_ECTRL_MASK;
1783	ectrl |= IEE16_ECTRL_EECS;
1784	outb(sc->port + IEE16_ECTRL, ectrl);
1785
1786	ee16_eeprom_outbits(sc, IEE16_EEPROM_READ, IEE16_EEPROM_OPSIZE1);
1787	ee16_eeprom_outbits(sc, location, IEE16_EEPROM_ADDR_SIZE);
1788	edata = ee16_eeprom_inbits(sc);
1789	ectrl = inb(sc->port + IEE16_ECTRL);
1790	ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EEDI | IEE16_ECTRL_EECS);
1791	outb(sc->port + IEE16_ECTRL, ectrl);
1792	ee16_eeprom_clock(sc, 1);
1793	ee16_eeprom_clock(sc, 0);
1794	return edata;
1795}
1796
1797void
1798ee16_eeprom_outbits(struct ie_softc *sc, int edata, int count)
1799{
1800	int	ectrl, i;
1801
1802	ectrl = inb(sc->port + IEE16_ECTRL);
1803	ectrl &= ~IEE16_RESET_ASIC;
1804	for (i = count - 1; i >= 0; i--) {
1805		ectrl &= ~IEE16_ECTRL_EEDI;
1806		if (edata & (1 << i)) {
1807			ectrl |= IEE16_ECTRL_EEDI;
1808		}
1809		outb(sc->port + IEE16_ECTRL, ectrl);
1810		DELAY(1);	/* eeprom data must be setup for 0.4 uSec */
1811		ee16_eeprom_clock(sc, 1);
1812		ee16_eeprom_clock(sc, 0);
1813	}
1814	ectrl &= ~IEE16_ECTRL_EEDI;
1815	outb(sc->port + IEE16_ECTRL, ectrl);
1816	DELAY(1);		/* eeprom data must be held for 0.4 uSec */
1817}
1818
1819int
1820ee16_eeprom_inbits(struct ie_softc *sc)
1821{
1822	int	ectrl, edata, i;
1823
1824	ectrl = inb(sc->port + IEE16_ECTRL);
1825	ectrl &= ~IEE16_RESET_ASIC;
1826	for (edata = 0, i = 0; i < 16; i++) {
1827		edata = edata << 1;
1828		ee16_eeprom_clock(sc, 1);
1829		ectrl = inb(sc->port + IEE16_ECTRL);
1830		if (ectrl & IEE16_ECTRL_EEDO) {
1831			edata |= 1;
1832		}
1833		ee16_eeprom_clock(sc, 0);
1834	}
1835	return (edata);
1836}
1837
1838void
1839ee16_eeprom_clock(struct ie_softc *sc, int state)
1840{
1841	int	ectrl;
1842
1843	ectrl = inb(sc->port + IEE16_ECTRL);
1844	ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EESK);
1845	if (state) {
1846		ectrl |= IEE16_ECTRL_EESK;
1847	}
1848	outb(sc->port + IEE16_ECTRL, ectrl);
1849	DELAY(9);		/* EESK must be stable for 8.38 uSec */
1850}
1851
1852static __inline void
1853ee16_interrupt_enable(struct ie_softc *sc)
1854{
1855	DELAY(100);
1856	outb(sc->port + IEE16_IRQ, sc->irq_encoded | IEE16_IRQ_ENABLE);
1857	DELAY(100);
1858}
1859
1860void
1861sl_read_ether(int unit, unsigned char addr[6])
1862{
1863	int	i;
1864
1865	for (i = 0; i < 6; i++)
1866		addr[i] = inb(PORT + i);
1867}
1868
1869
1870static void
1871iereset(int unit)
1872{
1873	int	s = splimp();
1874
1875	if (unit >= NIE) {
1876		splx(s);
1877		return;
1878	}
1879	printf("ie%d: reset\n", unit);
1880	ie_softc[unit].arpcom.ac_if.if_flags &= ~IFF_UP;
1881	ieioctl(&ie_softc[unit].arpcom.ac_if, SIOCSIFFLAGS, 0);
1882
1883	/*
1884	 * Stop i82586 dead in its tracks.
1885	 */
1886	if (command_and_wait(unit, IE_RU_ABORT | IE_CU_ABORT, 0, 0))
1887		printf("ie%d: abort commands timed out\n", unit);
1888
1889	if (command_and_wait(unit, IE_RU_DISABLE | IE_CU_STOP, 0, 0))
1890		printf("ie%d: disable commands timed out\n", unit);
1891
1892#ifdef notdef
1893	if (!check_ie_present(unit, ie_softc[unit].iomembot,
1894			      e_softc[unit].iosize))
1895		panic("ie disappeared!");
1896#endif
1897
1898	ie_softc[unit].arpcom.ac_if.if_flags |= IFF_UP;
1899	ieioctl(&ie_softc[unit].arpcom.ac_if, SIOCSIFFLAGS, 0);
1900
1901	splx(s);
1902	return;
1903}
1904
1905/*
1906 * This is called if we time out.
1907 */
1908static void
1909chan_attn_timeout(void *rock)
1910{
1911	*(int *) rock = 1;
1912}
1913
1914/*
1915 * Send a command to the controller and wait for it to either
1916 * complete or be accepted, depending on the command.  If the
1917 * command pointer is null, then pretend that the command is
1918 * not an action command.  If the command pointer is not null,
1919 * and the command is an action command, wait for
1920 * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK
1921 * to become true.
1922 */
1923static int
1924command_and_wait(int unit, int cmd, volatile void *pcmd, int mask)
1925{
1926	volatile struct ie_cmd_common *cc = pcmd;
1927	volatile int timedout = 0;
1928	struct	 callout_handle ch;
1929
1930	ie_softc[unit].scb->ie_command = (u_short) cmd;
1931
1932	if (IE_ACTION_COMMAND(cmd) && pcmd) {
1933		(*ie_softc[unit].ie_chan_attn) (unit);
1934
1935		/*
1936		 * According to the packet driver, the minimum timeout
1937		 * should be .369 seconds, which we round up to .37.
1938		 */
1939		ch = timeout(chan_attn_timeout, (caddr_t)&timedout,
1940			     37 * hz / 100);
1941		/* ignore cast-qual */
1942
1943		/*
1944		 * Now spin-lock waiting for status.  This is not a very
1945		 * nice thing to do, but I haven't figured out how, or
1946		 * indeed if, we can put the process waiting for action to
1947		 * sleep.  (We may be getting called through some other
1948		 * timeout running in the kernel.)
1949		 */
1950		while (1) {
1951			if ((cc->ie_cmd_status & mask) || timedout)
1952				break;
1953		}
1954
1955		untimeout(chan_attn_timeout, (caddr_t)&timedout, ch);
1956		/* ignore cast-qual */
1957
1958		return (timedout);
1959	} else {
1960
1961		/*
1962		 * Otherwise, just wait for the command to be accepted.
1963		 */
1964		(*ie_softc[unit].ie_chan_attn) (unit);
1965
1966		while (ie_softc[unit].scb->ie_command);	/* spin lock */
1967
1968		return (0);
1969	}
1970}
1971
1972/*
1973 * Run the time-domain reflectometer...
1974 */
1975static void
1976run_tdr(int unit, struct ie_tdr_cmd *cmd)
1977{
1978	int	result;
1979
1980	cmd->com.ie_cmd_status = 0;
1981	cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST;
1982	cmd->com.ie_cmd_link = 0xffff;
1983	cmd->ie_tdr_time = 0;
1984
1985	ie_softc[unit].scb->ie_command_list = MK_16(MEM, cmd);
1986	cmd->ie_tdr_time = 0;
1987
1988	if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL))
1989		result = 0x2000;
1990	else
1991		result = cmd->ie_tdr_time;
1992
1993	ie_ack(ie_softc[unit].scb, IE_ST_WHENCE, unit,
1994	       ie_softc[unit].ie_chan_attn);
1995
1996	if (result & IE_TDR_SUCCESS)
1997		return;
1998
1999	if (result & IE_TDR_XCVR) {
2000		printf("ie%d: transceiver problem\n", unit);
2001	} else if (result & IE_TDR_OPEN) {
2002		printf("ie%d: TDR detected an open %d clocks away\n", unit,
2003		       result & IE_TDR_TIME);
2004	} else if (result & IE_TDR_SHORT) {
2005		printf("ie%d: TDR detected a short %d clocks away\n", unit,
2006		       result & IE_TDR_TIME);
2007	} else {
2008		printf("ie%d: TDR returned unknown status %x\n", unit, result);
2009	}
2010}
2011
2012static void
2013start_receiver(int unit)
2014{
2015	int	s = splimp();
2016
2017	ie_softc[unit].scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
2018	command_and_wait(unit, IE_RU_START, 0, 0);
2019
2020	ie_ack(ie_softc[unit].scb, IE_ST_WHENCE, unit, ie_softc[unit].ie_chan_attn);
2021
2022	splx(s);
2023}
2024
2025/*
2026 * Here is a helper routine for iernr() and ieinit().  This sets up
2027 * the RFA.
2028 */
2029static caddr_t
2030setup_rfa(caddr_t ptr, struct ie_softc * ie)
2031{
2032	volatile struct ie_recv_frame_desc *rfd = (void *) ptr;
2033	volatile struct ie_recv_buf_desc *rbd;
2034	int	i;
2035	int	unit = ie - &ie_softc[0];
2036
2037	/* First lay them out */
2038	for (i = 0; i < ie->nframes; i++) {
2039		ie->rframes[i] = rfd;
2040		bzero((char *) rfd, sizeof *rfd);	/* ignore cast-qual */
2041		rfd++;
2042	}
2043
2044	ptr = (caddr_t) Align((caddr_t) rfd);	/* ignore cast-qual */
2045
2046	/* Now link them together */
2047	for (i = 0; i < ie->nframes; i++) {
2048		ie->rframes[i]->ie_fd_next =
2049		    MK_16(MEM, ie->rframes[(i + 1) % ie->nframes]);
2050	}
2051
2052	/* Finally, set the EOL bit on the last one. */
2053	ie->rframes[ie->nframes - 1]->ie_fd_last |= IE_FD_LAST;
2054
2055	/*
2056	 * Now lay out some buffers for the incoming frames.  Note that we
2057	 * set aside a bit of slop in each buffer, to make sure that we have
2058	 * enough space to hold a single frame in every buffer.
2059	 */
2060	rbd = (void *) ptr;
2061
2062	for (i = 0; i < ie->nrxbufs; i++) {
2063		ie->rbuffs[i] = rbd;
2064		bzero((char *)rbd, sizeof *rbd);
2065		ptr = (caddr_t) Align(ptr + sizeof *rbd);
2066		rbd->ie_rbd_length = IE_RBUF_SIZE;
2067		rbd->ie_rbd_buffer = MK_24(MEM, ptr);
2068		ie->cbuffs[i] = (void *) ptr;
2069		ptr += IE_RBUF_SIZE;
2070		rbd = (void *) ptr;
2071	}
2072
2073	/* Now link them together */
2074	for (i = 0; i < ie->nrxbufs; i++) {
2075		ie->rbuffs[i]->ie_rbd_next =
2076		    MK_16(MEM, ie->rbuffs[(i + 1) % ie->nrxbufs]);
2077	}
2078
2079	/* Tag EOF on the last one */
2080	ie->rbuffs[ie->nrxbufs - 1]->ie_rbd_length |= IE_RBD_LAST;
2081
2082	/*
2083	 * We use the head and tail pointers on receive to keep track of the
2084	 * order in which RFDs and RBDs are used.
2085	 */
2086	ie->rfhead = 0;
2087	ie->rftail = ie->nframes - 1;
2088	ie->rbhead = 0;
2089	ie->rbtail = ie->nrxbufs - 1;
2090
2091	ie->scb->ie_recv_list = MK_16(MEM, ie->rframes[0]);
2092	ie->rframes[0]->ie_fd_buf_desc = MK_16(MEM, ie->rbuffs[0]);
2093
2094	ptr = Align(ptr);
2095	return (ptr);
2096}
2097
2098/*
2099 * Run the multicast setup command.
2100 * Call at splimp().
2101 */
2102static int
2103mc_setup(int unit, caddr_t ptr,
2104	 volatile struct ie_sys_ctl_block * scb)
2105{
2106	struct ie_softc *ie = &ie_softc[unit];
2107	volatile struct ie_mcast_cmd *cmd = (void *) ptr;
2108
2109	cmd->com.ie_cmd_status = 0;
2110	cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST;
2111	cmd->com.ie_cmd_link = 0xffff;
2112
2113	/* ignore cast-qual */
2114	bcopy((caddr_t) ie->mcast_addrs, (caddr_t) cmd->ie_mcast_addrs,
2115	      ie->mcast_count * sizeof *ie->mcast_addrs);
2116
2117	cmd->ie_mcast_bytes = ie->mcast_count * 6;	/* grrr... */
2118
2119	scb->ie_command_list = MK_16(MEM, cmd);
2120	if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
2121	    || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
2122		printf("ie%d: multicast address setup command failed\n", unit);
2123		return (0);
2124	}
2125	return (1);
2126}
2127
2128/*
2129 * This routine takes the environment generated by check_ie_present()
2130 * and adds to it all the other structures we need to operate the adapter.
2131 * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands,
2132 * starting the receiver unit, and clearing interrupts.
2133 *
2134 * THIS ROUTINE MUST BE CALLED AT splimp() OR HIGHER.
2135 */
2136static void
2137ieinit(int unit)
2138{
2139	struct ie_softc *ie = &ie_softc[unit];
2140	volatile struct ie_sys_ctl_block *scb = ie->scb;
2141	caddr_t ptr;
2142	int	i;
2143
2144	ptr = (caddr_t) Align((caddr_t) scb + sizeof *scb);
2145
2146	/*
2147	 * Send the configure command first.
2148	 */
2149	{
2150		volatile struct ie_config_cmd *cmd = (void *) ptr;
2151
2152		ie_setup_config(cmd, ie->promisc,
2153				ie->hard_type == IE_STARLAN10);
2154		cmd->com.ie_cmd_status = 0;
2155		cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST;
2156		cmd->com.ie_cmd_link = 0xffff;
2157
2158		scb->ie_command_list = MK_16(MEM, cmd);
2159
2160		if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
2161		 || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
2162			printf("ie%d: configure command failed\n", unit);
2163			return;
2164		}
2165	}
2166	/*
2167	 * Now send the Individual Address Setup command.
2168	 */
2169	{
2170		volatile struct ie_iasetup_cmd *cmd = (void *) ptr;
2171
2172		cmd->com.ie_cmd_status = 0;
2173		cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST;
2174		cmd->com.ie_cmd_link = 0xffff;
2175
2176		bcopy((char *)ie_softc[unit].arpcom.ac_enaddr,
2177		      (char *)&cmd->ie_address, sizeof cmd->ie_address);
2178		scb->ie_command_list = MK_16(MEM, cmd);
2179		if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
2180		    || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
2181			printf("ie%d: individual address "
2182			       "setup command failed\n", unit);
2183			return;
2184		}
2185	}
2186
2187	/*
2188	 * Now run the time-domain reflectometer.
2189	 */
2190	run_tdr(unit, (void *) ptr);
2191
2192	/*
2193	 * Acknowledge any interrupts we have generated thus far.
2194	 */
2195	ie_ack(ie->scb, IE_ST_WHENCE, unit, ie->ie_chan_attn);
2196
2197	/*
2198	 * Set up the RFA.
2199	 */
2200	ptr = setup_rfa(ptr, ie);
2201
2202	/*
2203	 * Finally, the transmit command and buffer are the last little bit
2204	 * of work.
2205	 */
2206
2207	/* transmit command buffers */
2208	for (i = 0; i < ie->ntxbufs; i++) {
2209		ie->xmit_cmds[i] = (void *) ptr;
2210		ptr += sizeof *ie->xmit_cmds[i];
2211		ptr = Align(ptr);
2212		ie->xmit_buffs[i] = (void *)ptr;
2213		ptr += sizeof *ie->xmit_buffs[i];
2214		ptr = Align(ptr);
2215	}
2216
2217	/* transmit buffers */
2218	for (i = 0; i < ie->ntxbufs - 1; i++) {
2219		ie->xmit_cbuffs[i] = (void *)ptr;
2220		ptr += IE_BUF_LEN;
2221		ptr = Align(ptr);
2222	}
2223	ie->xmit_cbuffs[ie->ntxbufs - 1] = (void *) ptr;
2224
2225	for (i = 1; i < ie->ntxbufs; i++) {
2226		bzero((caddr_t) ie->xmit_cmds[i], sizeof *ie->xmit_cmds[i]);
2227		bzero((caddr_t) ie->xmit_buffs[i], sizeof *ie->xmit_buffs[i]);
2228	}
2229
2230	/*
2231	 * This must be coordinated with iestart() and ietint().
2232	 */
2233	ie->xmit_cmds[0]->ie_xmit_status = IE_STAT_COMPL;
2234
2235	/* take the ee16 out of loopback */
2236	if (ie->hard_type == IE_EE16) {
2237		u_int8_t bart_config;
2238
2239		bart_config = inb(PORT + IEE16_CONFIG);
2240		bart_config &= ~IEE16_BART_LOOPBACK;
2241		/* inb doesn't get bit! */
2242		bart_config |= IEE16_BART_MCS16_TEST;
2243		outb(PORT + IEE16_CONFIG, bart_config);
2244		ee16_interrupt_enable(ie);
2245		ee16_chan_attn(unit);
2246	}
2247	ie->arpcom.ac_if.if_flags |= IFF_RUNNING;	/* tell higher levels
2248							 * we're here */
2249	start_receiver(unit);
2250
2251	return;
2252}
2253
2254static void
2255ie_stop(int unit)
2256{
2257	command_and_wait(unit, IE_RU_DISABLE, 0, 0);
2258}
2259
2260static int
2261ieioctl(struct ifnet *ifp, u_long command, caddr_t data)
2262{
2263	struct ifaddr *ifa = (struct ifaddr *) data;
2264	struct ie_softc *ie = ifp->if_softc;
2265	struct ifreq *ifr = (struct ifreq *) data;
2266	int	s, error = 0;
2267
2268	s = splimp();
2269
2270	switch (command) {
2271	case SIOCSIFADDR:
2272		ifp->if_flags |= IFF_UP;
2273
2274		switch (ifa->ifa_addr->sa_family) {
2275#ifdef INET
2276		case AF_INET:
2277			ieinit(ifp->if_unit);
2278			arp_ifinit((struct arpcom *) ifp, ifa);
2279			break;
2280#endif				/* INET */
2281
2282#ifdef IPX
2283			/*
2284			 * This magic copied from if_is.c; I don't use XNS,
2285			 * so I have no way of telling if this actually
2286			 * works or not.
2287			 */
2288		case AF_IPX:
2289			{
2290				struct ipx_addr *ina =
2291				    &(IA_SIPX(ifa)->sipx_addr);
2292
2293				if (ipx_nullhost(*ina)) {
2294					ina->x_host = *(union ipx_host *) (ie->arpcom.ac_enaddr);
2295				} else {
2296					ifp->if_flags &= ~IFF_RUNNING;
2297					bcopy((caddr_t) ina->x_host.c_host,
2298					      (caddr_t) ie->arpcom.ac_enaddr,
2299					      sizeof ie->arpcom.ac_enaddr);
2300				}
2301
2302				ieinit(ifp->if_unit);
2303			}
2304			break;
2305#endif				/* IPX */
2306
2307#ifdef NS
2308			/*
2309			 * This magic copied from if_is.c; I don't use XNS,
2310			 * so I have no way of telling if this actually
2311			 * works or not.
2312			 */
2313		case AF_NS:
2314			{
2315				struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
2316
2317				if (ns_nullhost(*ina)) {
2318					ina->x_host = *(union ns_host *)(ie->arpcom.ac_enaddr);
2319				} else {
2320					ifp->if_flags &= ~IFF_RUNNING;
2321					bcopy((caddr_t) ina->x_host.c_host,
2322					      (caddr_t) ie->arpcom.ac_enaddr,
2323					      sizeof ie->arpcom.ac_enaddr);
2324				}
2325
2326				ieinit(ifp->if_unit);
2327			}
2328			break;
2329#endif				/* NS */
2330
2331		default:
2332			ieinit(ifp->if_unit);
2333			break;
2334		}
2335		break;
2336
2337	case SIOCSIFFLAGS:
2338		/*
2339		 * Note that this device doesn't have an "all multicast"
2340		 * mode, so we must turn on promiscuous mode and do the
2341		 * filtering manually.
2342		 */
2343		if ((ifp->if_flags & IFF_UP) == 0 &&
2344		    (ifp->if_flags & IFF_RUNNING)) {
2345			ifp->if_flags &= ~IFF_RUNNING;
2346			ie_stop(ifp->if_unit);
2347		} else if ((ifp->if_flags & IFF_UP) &&
2348			   (ifp->if_flags & IFF_RUNNING) == 0) {
2349			ie_softc[ifp->if_unit].promisc =
2350			    ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
2351			ieinit(ifp->if_unit);
2352		} else if (ie_softc[ifp->if_unit].promisc ^
2353			   (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI))) {
2354			ie_softc[ifp->if_unit].promisc =
2355			    ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
2356			ieinit(ifp->if_unit);
2357		}
2358		break;
2359
2360	case SIOCADDMULTI:
2361	case SIOCDELMULTI:
2362		/*
2363		 * Update multicast listeners
2364		 */
2365		/* reset multicast filtering */
2366		ie_mc_reset(ifp->if_unit);
2367		error = 0;
2368		break;
2369
2370	case SIOCSIFMTU:
2371		/*
2372		 * Set the interface MTU.
2373		 */
2374		if (ifr->ifr_mtu > ETHERMTU) {
2375			error = EINVAL;
2376		} else {
2377			ifp->if_mtu = ifr->ifr_mtu;
2378		}
2379		break;
2380
2381	default:
2382		error = EINVAL;
2383	}
2384
2385	splx(s);
2386	return (error);
2387}
2388
2389static void
2390ie_mc_reset(int unit)
2391{
2392	struct ie_softc *ie = &ie_softc[unit];
2393	struct ifmultiaddr *ifma;
2394
2395	/*
2396	 * Step through the list of addresses.
2397	 */
2398	ie->mcast_count = 0;
2399	for (ifma = ie->arpcom.ac_if.if_multiaddrs.lh_first; ifma;
2400	     ifma = ifma->ifma_link.le_next) {
2401		if (ifma->ifma_addr->sa_family != AF_LINK)
2402			continue;
2403
2404		/* XXX - this is broken... */
2405		if (ie->mcast_count >= MAXMCAST) {
2406			ie->arpcom.ac_if.if_flags |= IFF_ALLMULTI;
2407			ieioctl(&ie->arpcom.ac_if, SIOCSIFFLAGS, (void *) 0);
2408			goto setflag;
2409		}
2410		bcopy(LLADDR((struct sockaddr_dl *) ifma->ifma_addr),
2411		      &(ie->mcast_addrs[ie->mcast_count]), 6);
2412		ie->mcast_count++;
2413	}
2414
2415setflag:
2416	ie->want_mcsetup = 1;
2417}
2418
2419
2420#ifdef DEBUG
2421static void
2422print_rbd(volatile struct ie_recv_buf_desc * rbd)
2423{
2424	printf("RBD at %p:\n"
2425	       "actual %04x, next %04x, buffer %p\n"
2426	       "length %04x, mbz %04x\n",
2427	       (void *) rbd,
2428	       rbd->ie_rbd_actual, rbd->ie_rbd_next,
2429	       (void *) rbd->ie_rbd_buffer,
2430	       rbd->ie_rbd_length, rbd->mbz);
2431}
2432
2433#endif				/* DEBUG */
2434#endif				/* NIE > 0 */
2435