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