xref: /NextBSD/sys/dev/ie/if_ie.c (revision 287e3b14e9552995def1802ec9c5034f4adf28ec)
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  * MAINTAINER: Matthew N. Dodd <winter@jurai.net>
51  */
52 
53 #include <sys/cdefs.h>
54 __FBSDID("$FreeBSD$");
55 
56 /*
57  * Intel 82586 Ethernet chip
58  * Register, bit, and structure definitions.
59  *
60  * Written by GAW with reference to the Clarkson Packet Driver code for this
61  * chip written by Russ Nelson and others.
62  *
63  * Intel EtherExpress 16 support from if_ix.c, written by Rodney W. Grimes.
64  */
65 
66 /*
67  * The i82586 is a very versatile chip, found in many implementations.
68  * Programming this chip is mostly the same, but certain details differ
69  * from card to card.  This driver is written so that different cards
70  * can be automatically detected at run-time.
71  */
72 
73 /*
74  * Mode of operation:
75  *
76  * We run the 82586 in a standard Ethernet mode.  We keep NFRAMES
77  * received frame descriptors around for the receiver to use, and
78  * NRXBUFS associated receive buffer descriptors, both in a circular
79  * list.  Whenever a frame is received, we rotate both lists as
80  * necessary.  (The 586 treats both lists as a simple queue.)  We also
81  * keep a transmit command around so that packets can be sent off
82  * quickly.
83  *
84  * We configure the adapter in AL-LOC = 1 mode, which means that the
85  * Ethernet/802.3 MAC header is placed at the beginning of the receive
86  * buffer rather than being split off into various fields in the RFD.
87  * This also means that we must include this header in the transmit
88  * buffer as well.
89  *
90  * By convention, all transmit commands, and only transmit commands,
91  * shall have the I (IE_CMD_INTR) bit set in the command.  This way,
92  * when an interrupt arrives at ieintr(), it is immediately possible
93  * to tell what precisely caused it.  ANY OTHER command-sending routines
94  * should run at splimp(), and should post an acknowledgement to every
95  * interrupt they generate.
96  *
97  * The 82586 has a 24-bit address space internally, and the adaptor's
98  * memory is located at the top of this region.  However, the value
99  * we are given in configuration is normally the *bottom* of the adaptor
100  * RAM.  So, we must go through a few gyrations to come up with a
101  * kernel virtual address which represents the actual beginning of the
102  * 586 address space.  First, we autosize the RAM by running through
103  * several possible sizes and trying to initialize the adapter under
104  * the assumption that the selected size is correct.  Then, knowing
105  * the correct RAM size, we set up our pointers in the softc `iomem'
106  * represents the computed base of the 586 address space.  `iomembot'
107  * represents the actual configured base of adapter RAM.  Finally,
108  * `iosize' represents the calculated size of 586 RAM.  Then, when
109  * laying out commands, we use the interval [iomembot, iomembot +
110  * iosize); to make 24-pointers, we subtract iomem, and to make
111  * 16-pointers, we subtract iomem and and with 0xffff.
112  */
113 
114 #include <sys/param.h>
115 #include <sys/systm.h>
116 #include <sys/eventhandler.h>
117 #include <sys/kernel.h>
118 #include <sys/malloc.h>
119 #include <sys/mbuf.h>
120 #include <sys/socket.h>
121 #include <sys/sockio.h>
122 #include <sys/syslog.h>
123 
124 #include <sys/module.h>
125 #include <sys/bus.h>
126 
127 #include <machine/bus.h>
128 #include <machine/resource.h>
129 #include <sys/rman.h>
130 
131 #include <net/ethernet.h>
132 #include <net/if.h>
133 #include <net/if_var.h>
134 #include <net/if_types.h>
135 #include <net/if_dl.h>
136 
137 #include <netinet/in.h>
138 #include <netinet/if_ether.h>
139 
140 #include <dev/ic/i82586.h>
141 #include <dev/ie/if_ievar.h>
142 #include <dev/ie/if_iereg.h>
143 #include <dev/ie/if_ie507.h>
144 #include <dev/ie/if_iee16.h>
145 #include <i386/isa/elink.h>
146 
147 #include <net/bpf.h>
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
155 static int	ie_debug = IED_RNR;
156 
157 #endif
158 
159 #define IE_BUF_LEN	ETHER_MAX_LEN	/* length of transmit buffer */
160 
161 /* XXX this driver uses `volatile' and `caddr_t' to a fault. */
162 typedef	volatile char *v_caddr_t;	/* core address, pointer to volatile */
163 
164 /* Forward declaration */
165 struct ie_softc;
166 
167 static void	ieinit			(void *);
168 static void	ieinit_locked		(struct ie_softc *);
169 static void	ie_stop			(struct ie_softc *);
170 static int	ieioctl			(struct ifnet *, u_long, caddr_t);
171 static void	iestart			(struct ifnet *);
172 static void	iestart_locked		(struct ifnet *);
173 
174 static __inline void
175 		ee16_interrupt_enable	(struct ie_softc *);
176 
177 static __inline void
178 		ie_ack			(struct ie_softc *, u_int);
179 static void	iereset			(struct ie_softc *);
180 static void	ie_readframe		(struct ie_softc *, int);
181 static void	ie_drop_packet_buffer	(struct ie_softc *);
182 static int	command_and_wait	(struct ie_softc *,
183 					 int, void volatile *, int);
184 static void	run_tdr			(struct ie_softc *,
185 					 volatile struct ie_tdr_cmd *);
186 static int	ierint			(struct ie_softc *);
187 static int	ietint			(struct ie_softc *);
188 static int	iernr			(struct ie_softc *);
189 static void	start_receiver		(struct ie_softc *);
190 static __inline int
191 		ieget			(struct ie_softc *, struct mbuf **);
192 static v_caddr_t setup_rfa		(struct ie_softc *, v_caddr_t);
193 static int	mc_setup		(struct ie_softc *);
194 static void	ie_mc_reset		(struct ie_softc *);
195 
196 #ifdef DEBUG
197 static void	print_rbd		(volatile struct ie_recv_buf_desc * rbd);
198 static int	in_ierint = 0;
199 static int	in_ietint = 0;
200 #endif
201 
202 static const char *ie_hardware_names[] = {
203 	"None",
204 	"StarLAN 10",
205 	"EN100",
206 	"StarLAN Fiber",
207 	"3C507",
208 	"NI5210",
209 	"EtherExpress 16",
210 	"Unknown"
211 };
212 
213 /*
214  * sizeof(iscp) == 1+1+2+4 == 8
215  * sizeof(scb) == 2+2+2+2+2+2+2+2 == 16
216  * NFRAMES * sizeof(rfd) == NFRAMES*(2+2+2+2+6+6+2+2) == NFRAMES*24 == 384
217  * sizeof(xmit_cmd) == 2+2+2+2+6+2 == 18
218  * sizeof(transmit buffer) == 1512
219  * sizeof(transmit buffer desc) == 8
220  * -----
221  * 1946
222  *
223  * NRXBUFS * sizeof(rbd) == NRXBUFS*(2+2+4+2+2) == NRXBUFS*12
224  * NRXBUFS * IE_RBUF_SIZE == NRXBUFS*256
225  *
226  * NRXBUFS should be (16384 - 1946) / (256 + 12) == 14438 / 268 == 53
227  *
228  * With NRXBUFS == 48, this leaves us 1574 bytes for another command or
229  * more buffers.  Another transmit command would be 18+8+1512 == 1538
230  * ---just barely fits!
231  *
232  * Obviously all these would have to be reduced for smaller memory sizes.
233  * With a larger memory, it would be possible to roughly double the number
234  * of both transmit and receive buffers.
235  */
236 
237 #define	NFRAMES		4	/* number of receive frames */
238 #define	NRXBUFS		24	/* number of buffers to allocate */
239 #define	IE_RBUF_SIZE	256	/* size of each buffer, MUST BE POWER OF TWO */
240 #define	NTXBUFS		1	/* number of transmit commands */
241 #define	IE_TBUF_SIZE	ETHER_MAX_LEN	/* size of transmit buffer */
242 
243 #define MK_24(base, ptr) ((caddr_t)((uintptr_t)ptr - (uintptr_t)base))
244 #define MK_16(base, ptr) ((u_short)(uintptr_t)MK_24(base, ptr))
245 
246 void
ee16_shutdown(struct ie_softc * sc)247 ee16_shutdown(struct ie_softc *sc)
248 {
249 
250 	ee16_reset_586(sc);
251 	outb(PORT(sc) + IEE16_ECTRL, IEE16_RESET_ASIC);
252 	outb(PORT(sc) + IEE16_ECTRL, 0);
253 }
254 
255 /*
256  * Taken almost exactly from Bill's if_is.c, then modified beyond recognition.
257  */
258 int
ie_attach(device_t dev)259 ie_attach(device_t dev)
260 {
261 	struct ie_softc *       sc;
262 	struct ifnet *          ifp;
263 	size_t                  allocsize;
264 	int                     error, factor;
265 
266 	sc = device_get_softc(dev);
267 	ifp = sc->ifp = if_alloc(IFT_ETHER);
268 	if (ifp == NULL) {
269 		device_printf(sc->dev, "can not if_alloc()\n");
270 		return (ENOSPC);
271 	}
272 
273 	sc->dev = dev;
274 	mtx_init(&sc->lock, device_get_nameunit(dev), MTX_NETWORK_LOCK,
275 	    MTX_DEF);
276 
277 	/*
278 	 * based on the amount of memory we have, allocate our tx and rx
279 	 * resources.
280 	 */
281 	factor = rman_get_size(sc->mem_res) / 8192;
282 	sc->nframes = factor * NFRAMES;
283 	sc->nrxbufs = factor * NRXBUFS;
284 	sc->ntxbufs = factor * NTXBUFS;
285 
286 	/*
287 	 * Since all of these guys are arrays of pointers, allocate as one
288 	 * big chunk and dole out accordingly.
289 	 */
290 	allocsize = sizeof(void *) * (sc->nframes
291 				      + (sc->nrxbufs * 2)
292 				      + (sc->ntxbufs * 3));
293 	sc->rframes = (volatile struct ie_recv_frame_desc **) malloc(allocsize,
294 								     M_DEVBUF,
295 								   M_NOWAIT);
296 	if (sc->rframes == NULL) {
297 		mtx_destroy(&sc->lock);
298 		return (ENXIO);
299 	}
300 	sc->rbuffs =
301 	    (volatile struct ie_recv_buf_desc **)&sc->rframes[sc->nframes];
302 	sc->cbuffs = (volatile u_char **)&sc->rbuffs[sc->nrxbufs];
303 	sc->xmit_cmds =
304 	    (volatile struct ie_xmit_cmd **)&sc->cbuffs[sc->nrxbufs];
305 	sc->xmit_buffs =
306 	    (volatile struct ie_xmit_buf **)&sc->xmit_cmds[sc->ntxbufs];
307 	sc->xmit_cbuffs = (volatile u_char **)&sc->xmit_buffs[sc->ntxbufs];
308 
309 	if (bootverbose)
310 		device_printf(sc->dev, "hardware type %s, revision %d\n",
311 			ie_hardware_names[sc->hard_type], sc->hard_vers + 1);
312 
313 	ifp->if_softc = sc;
314 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
315 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
316 	ifp->if_start = iestart;
317 	ifp->if_ioctl = ieioctl;
318 	ifp->if_init = ieinit;
319 	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
320 
321 	ether_ifattach(ifp, sc->enaddr);
322 
323 	error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
324 				NULL, ie_intr, sc, &sc->irq_ih);
325 	if (error) {
326 		device_printf(dev, "Unable to register interrupt handler\n");
327 		mtx_destroy(&sc->lock);
328 		return (error);
329 	}
330 
331 	return (0);
332 }
333 
334 static __inline void
ie_ack(struct ie_softc * sc,u_int mask)335 ie_ack(struct ie_softc *sc, u_int mask)
336 {
337 
338 	sc->scb->ie_command = sc->scb->ie_status & mask;
339 	(*sc->ie_chan_attn) (sc);
340 }
341 
342 /*
343  * What to do upon receipt of an interrupt.
344  */
345 void
ie_intr(void * xsc)346 ie_intr(void *xsc)
347 {
348 	struct ie_softc *sc = (struct ie_softc *)xsc;
349 	u_short status;
350 
351 	IE_LOCK(sc);
352 
353 	/* Clear the interrupt latch on the 3C507. */
354 	if (sc->hard_type == IE_3C507
355 	 && (inb(PORT(sc) + IE507_CTRL) & EL_CTRL_INTL))
356 		outb(PORT(sc) + IE507_ICTRL, 1);
357 
358 	/* disable interrupts on the EE16. */
359 	if (sc->hard_type == IE_EE16)
360 		outb(PORT(sc) + IEE16_IRQ, sc->irq_encoded);
361 
362 	status = sc->scb->ie_status;
363 
364 loop:
365 
366 	/* Don't ack interrupts which we didn't receive */
367 	ie_ack(sc, IE_ST_WHENCE & status);
368 
369 	if (status & (IE_ST_RECV | IE_ST_RNR)) {
370 #ifdef DEBUG
371 		in_ierint++;
372 		if (ie_debug & IED_RINT)
373 			if_printf(sc->ifp, "rint\n");
374 #endif
375 		ierint(sc);
376 #ifdef DEBUG
377 		in_ierint--;
378 #endif
379 	}
380 	if (status & IE_ST_DONE) {
381 #ifdef DEBUG
382 		in_ietint++;
383 		if (ie_debug & IED_TINT)
384 			if_printf(sc->ifp, "tint\n");
385 #endif
386 		ietint(sc);
387 #ifdef DEBUG
388 		in_ietint--;
389 #endif
390 	}
391 	if (status & IE_ST_RNR) {
392 #ifdef DEBUG
393 		if (ie_debug & IED_RNR)
394 			if_printf(sc->ifp, "rnr\n");
395 #endif
396 		iernr(sc);
397 	}
398 #ifdef DEBUG
399 	if ((status & IE_ST_ALLDONE) && (ie_debug & IED_CNA))
400 		if_printf(sc->ifp, "cna\n");
401 #endif
402 
403 	if ((status = sc->scb->ie_status) & IE_ST_WHENCE)
404 		goto loop;
405 
406 	/* Clear the interrupt latch on the 3C507. */
407 	if (sc->hard_type == IE_3C507)
408 		outb(PORT(sc) + IE507_ICTRL, 1);
409 
410 	/* enable interrupts on the EE16. */
411 	if (sc->hard_type == IE_EE16)
412 		outb(PORT(sc) + IEE16_IRQ, sc->irq_encoded | IEE16_IRQ_ENABLE);
413 	IE_UNLOCK(sc);
414 }
415 
416 /*
417  * Process a received-frame interrupt.
418  */
419 static int
ierint(struct ie_softc * sc)420 ierint(struct ie_softc *sc)
421 {
422 	int	i, status;
423 	static int timesthru = 1024;
424 
425 	i = sc->rfhead;
426 	while (1) {
427 		status = sc->rframes[i]->ie_fd_status;
428 
429 		if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) {
430 			if_inc_counter(sc->ifp, IFCOUNTER_IPACKETS, 1);
431 			if (!--timesthru) {
432 				if_inc_counter(sc->ifp, IFCOUNTER_IERRORS,
433 				    sc->scb->ie_err_crc +
434 				    sc->scb->ie_err_align +
435 				    sc->scb->ie_err_resource +
436 				    sc->scb->ie_err_overrun);
437 				sc->scb->ie_err_crc = 0;
438 				sc->scb->ie_err_align = 0;
439 				sc->scb->ie_err_resource = 0;
440 				sc->scb->ie_err_overrun = 0;
441 				timesthru = 1024;
442 			}
443 			ie_readframe(sc, i);
444 		} else {
445 			if (status & IE_FD_RNR) {
446 				if (!(sc->scb->ie_status & IE_RU_READY)) {
447 					sc->rframes[0]->ie_fd_next =
448 					    MK_16(MEM(sc), sc->rbuffs[0]);
449 					sc->scb->ie_recv_list =
450 					    MK_16(MEM(sc), sc->rframes[0]);
451 					command_and_wait(sc, IE_RU_START, 0, 0);
452 				}
453 			}
454 			break;
455 		}
456 		i = (i + 1) % sc->nframes;
457 	}
458 	return (0);
459 }
460 
461 /*
462  * Process a command-complete interrupt.  These are only generated by
463  * the transmission of frames.	This routine is deceptively simple, since
464  * most of the real work is done by iestart().
465  */
466 static int
ietint(struct ie_softc * sc)467 ietint(struct ie_softc *sc)
468 {
469 	struct ifnet *ifp = sc->ifp;
470 	int	status;
471 	int	i;
472 
473 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
474 
475 	for (i = 0; i < sc->xmit_count; i++) {
476 		status = sc->xmit_cmds[i]->ie_xmit_status;
477 
478 		if (status & IE_XS_LATECOLL) {
479 			if_printf(ifp, "late collision\n");
480 			if_inc_counter(ifp, IFCOUNTER_COLLISIONS, 1);
481 			if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
482 		} else if (status & IE_XS_NOCARRIER) {
483 			if_printf(ifp, "no carrier\n");
484 			if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
485 		} else if (status & IE_XS_LOSTCTS) {
486 			if_printf(ifp, "lost CTS\n");
487 			if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
488 		} else if (status & IE_XS_UNDERRUN) {
489 			if_printf(ifp, "DMA underrun\n");
490 			if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
491 		} else if (status & IE_XS_EXCMAX) {
492 			if_printf(ifp, "too many collisions\n");
493 			if_inc_counter(ifp, IFCOUNTER_COLLISIONS, 16);
494 			if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
495 		} else {
496 			if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
497 			if_inc_counter(ifp, IFCOUNTER_COLLISIONS, status & IE_XS_MAXCOLL);
498 		}
499 	}
500 	sc->xmit_count = 0;
501 
502 	/*
503 	 * If multicast addresses were added or deleted while we were
504 	 * transmitting, ie_mc_reset() set the want_mcsetup flag indicating
505 	 * that we should do it.
506 	 */
507 	if (sc->want_mcsetup) {
508 		mc_setup(sc);
509 		sc->want_mcsetup = 0;
510 	}
511 	/* Wish I knew why this seems to be necessary... */
512 	sc->xmit_cmds[0]->ie_xmit_status |= IE_STAT_COMPL;
513 
514 	iestart_locked(ifp);
515 	return (0);		/* shouldn't be necessary */
516 }
517 
518 /*
519  * Process a receiver-not-ready interrupt.  I believe that we get these
520  * when there aren't enough buffers to go around.  For now (FIXME), we
521  * just restart the receiver, and hope everything's ok.
522  */
523 static int
iernr(struct ie_softc * sc)524 iernr(struct ie_softc *sc)
525 {
526 #ifdef doesnt_work
527 	setup_rfa(sc, (v_caddr_t) sc->rframes[0]);
528 
529 	sc->scb->ie_recv_list = MK_16(MEM(sc), sc->rframes[0]);
530 	command_and_wait(sc, IE_RU_START, 0, 0);
531 #else
532 	/* This doesn't work either, but it doesn't hang either. */
533 	command_and_wait(sc, IE_RU_DISABLE, 0, 0);	/* just in case */
534 	setup_rfa(sc, (v_caddr_t) sc->rframes[0]);	/* ignore cast-qual */
535 
536 	sc->scb->ie_recv_list = MK_16(MEM(sc), sc->rframes[0]);
537 	command_and_wait(sc, IE_RU_START, 0, 0);	/* was ENABLE */
538 
539 #endif
540 	ie_ack(sc, IE_ST_WHENCE);
541 
542 	if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
543 	return (0);
544 }
545 
546 /*
547  * Compare two Ether/802 addresses for equality, inlined and
548  * unrolled for speed.	I'd love to have an inline assembler
549  * version of this...
550  */
551 static __inline int
ether_equal(u_char * one,u_char * two)552 ether_equal(u_char * one, u_char * two)
553 {
554 	if (one[0] != two[0])
555 		return (0);
556 	if (one[1] != two[1])
557 		return (0);
558 	if (one[2] != two[2])
559 		return (0);
560 	if (one[3] != two[3])
561 		return (0);
562 	if (one[4] != two[4])
563 		return (0);
564 	if (one[5] != two[5])
565 		return (0);
566 	return 1;
567 }
568 
569 /*
570  * Determine quickly whether we should bother reading in this packet.
571  * This depends on whether BPF and/or bridging is enabled, whether we
572  * are receiving multicast address, and whether promiscuous mode is enabled.
573  * We assume that if IFF_PROMISC is set, then *somebody* wants to see
574  * all incoming packets.
575  */
576 static __inline int
check_eh(struct ie_softc * sc,struct ether_header * eh)577 check_eh(struct ie_softc *sc, struct ether_header *eh)
578 {
579 	/* Optimize the common case: normal operation. We've received
580 	   either a unicast with our dest or a multicast packet. */
581 	if (sc->promisc == 0) {
582 		int i;
583 
584 		/* If not multicast, it's definitely for us */
585 		if ((eh->ether_dhost[0] & 1) == 0)
586 			return (1);
587 
588 		/* Accept broadcasts (loose but fast check) */
589 		if (eh->ether_dhost[0] == 0xff)
590 			return (1);
591 
592 		/* Compare against our multicast addresses */
593 		for (i = 0; i < sc->mcast_count; i++) {
594 			if (ether_equal(eh->ether_dhost,
595 			    (u_char *)&sc->mcast_addrs[i]))
596 				return (1);
597 		}
598 		return (0);
599 	}
600 
601 	/* Always accept packets when in promiscuous mode */
602 	if ((sc->promisc & IFF_PROMISC) != 0)
603 		return (1);
604 
605 	/* Always accept packets directed at us */
606 	if (ether_equal(eh->ether_dhost, IF_LLADDR(sc->ifp)))
607 		return (1);
608 
609 	/* Must have IFF_ALLMULTI but not IFF_PROMISC set. The chip is
610 	   actually in promiscuous mode, so discard unicast packets. */
611 	return((eh->ether_dhost[0] & 1) != 0);
612 }
613 
614 /*
615  * We want to isolate the bits that have meaning...  This assumes that
616  * IE_RBUF_SIZE is an even power of two.  If somehow the act_len exceeds
617  * the size of the buffer, then we are screwed anyway.
618  */
619 static __inline int
ie_buflen(struct ie_softc * sc,int head)620 ie_buflen(struct ie_softc *sc, int head)
621 {
622 	return (sc->rbuffs[head]->ie_rbd_actual
623 		& (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1)));
624 }
625 
626 static __inline int
ie_packet_len(struct ie_softc * sc)627 ie_packet_len(struct ie_softc *sc)
628 {
629 	int	i;
630 	int	head = sc->rbhead;
631 	int	acc = 0;
632 
633 	do {
634 		if (!(sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
635 #ifdef DEBUG
636 			print_rbd(sc->rbuffs[sc->rbhead]);
637 #endif
638 			log(LOG_ERR,
639 			    "%s: receive descriptors out of sync at %d\n",
640 			    sc->ifp->if_xname, sc->rbhead);
641 			iereset(sc);
642 			return (-1);
643 		}
644 		i = sc->rbuffs[head]->ie_rbd_actual & IE_RBD_LAST;
645 
646 		acc += ie_buflen(sc, head);
647 		head = (head + 1) % sc->nrxbufs;
648 	} while (!i);
649 
650 	return (acc);
651 }
652 
653 /*
654  * Read data off the interface, and turn it into an mbuf chain.
655  *
656  * This code is DRAMATICALLY different from the previous version; this
657  * version tries to allocate the entire mbuf chain up front, given the
658  * length of the data available.  This enables us to allocate mbuf
659  * clusters in many situations where before we would have had a long
660  * chain of partially-full mbufs.  This should help to speed up the
661  * operation considerably.  (Provided that it works, of course.)
662  */
663 static __inline int
ieget(struct ie_softc * sc,struct mbuf ** mp)664 ieget(struct ie_softc *sc, struct mbuf **mp)
665 {
666 	struct	ether_header eh;
667 	struct	mbuf *m, *top, **mymp;
668 	int	offset;
669 	int	totlen, resid;
670 	int	thismboff;
671 	int	head;
672 
673 	totlen = ie_packet_len(sc);
674 	if (totlen <= 0)
675 		return (-1);
676 
677 	/*
678 	 * Snarf the Ethernet header.
679 	 */
680 	bcopy(sc->cbuffs[sc->rbhead], &eh, sizeof(struct ether_header));
681 	/* ignore cast-qual warning here */
682 
683 	/*
684 	 * As quickly as possible, check if this packet is for us. If not,
685 	 * don't waste a single cycle copying the rest of the packet in.
686 	 * This is only a consideration when FILTER is defined; i.e., when
687 	 * we are either running BPF or doing multicasting.
688 	 */
689 	if (!check_eh(sc, &eh)) {
690 		ie_drop_packet_buffer(sc);
691 		return (-1);
692 	}
693 
694 	MGETHDR(m, M_NOWAIT, MT_DATA);
695 	if (!m) {
696 		ie_drop_packet_buffer(sc);
697 		return (-1);
698 	}
699 
700 	*mp = m;
701 	m->m_pkthdr.rcvif = sc->ifp;
702 	m->m_len = MHLEN;
703 	resid = m->m_pkthdr.len = totlen;
704 	top = 0;
705 
706 	mymp = &top;
707 
708 	/*
709 	 * This loop goes through and allocates mbufs for all the data we
710 	 * will be copying in.	It does not actually do the copying yet.
711 	 */
712 	do {			/* while(resid > 0) */
713 		/*
714 		 * Try to allocate an mbuf to hold the data that we have.
715 		 * If we already allocated one, just get another one and
716 		 * stick it on the end (eventually).  If we don't already
717 		 * have one, try to allocate an mbuf cluster big enough to
718 		 * hold the whole packet, if we think it's reasonable, or a
719 		 * single mbuf which may or may not be big enough. Got that?
720 		 */
721 		if (top) {
722 			MGET(m, M_NOWAIT, MT_DATA);
723 			if (!m) {
724 				m_freem(top);
725 				ie_drop_packet_buffer(sc);
726 				return (-1);
727 			}
728 			m->m_len = MLEN;
729 		}
730 		if (resid >= MINCLSIZE) {
731 			if (MCLGET(m, M_NOWAIT))
732 				m->m_len = min(resid, MCLBYTES);
733 		} else {
734 			if (resid < m->m_len) {
735 				if (!top && resid + max_linkhdr <= m->m_len)
736 					m->m_data += max_linkhdr;
737 				m->m_len = resid;
738 			}
739 		}
740 		resid -= m->m_len;
741 		*mymp = m;
742 		mymp = &m->m_next;
743 	} while (resid > 0);
744 
745 	resid = totlen;					/* remaining data */
746 	offset = 0;					/* packet offset */
747 	thismboff = 0;					/* offset in m */
748 
749 	m = top;					/* current mbuf */
750 	head = sc->rbhead;				/* current rx buffer */
751 
752 	/*
753 	 * Now we take the mbuf chain (hopefully only one mbuf most of the
754 	 * time) and stuff the data into it.  There are no possible failures
755 	 * at or after this point.
756 	 */
757 	while (resid > 0) {	/* while there's stuff left */
758 		int	thislen = ie_buflen(sc, head) - offset;
759 
760 		/*
761 		 * If too much data for the current mbuf, then fill the
762 		 * current one up, go to the next one, and try again.
763 		 */
764 		if (thislen > m->m_len - thismboff) {
765 			int	newlen = m->m_len - thismboff;
766 
767 			bcopy((v_caddr_t) (sc->cbuffs[head] + offset),
768 			      mtod(m, caddr_t) +thismboff, (unsigned) newlen);
769 			/* ignore cast-qual warning */
770 			m = m->m_next;
771 			thismboff = 0;		/* new mbuf, so no offset */
772 			offset += newlen;	/* we are now this far into
773 						 * the packet */
774 			resid -= newlen;	/* so there is this much left
775 						 * to get */
776 			continue;
777 		}
778 		/*
779 		 * If there is more than enough space in the mbuf to hold
780 		 * the contents of this buffer, copy everything in, advance
781 		 * pointers, and so on.
782 		 */
783 		if (thislen < m->m_len - thismboff) {
784 			bcopy((v_caddr_t) (sc->cbuffs[head] + offset),
785 			    mtod(m, caddr_t) +thismboff, (unsigned) thislen);
786 			thismboff += thislen;	/* we are this far into the
787 						 * mbuf */
788 			resid -= thislen;	/* and this much is left */
789 			goto nextbuf;
790 		}
791 		/*
792 		 * Otherwise, there is exactly enough space to put this
793 		 * buffer's contents into the current mbuf.  Do the
794 		 * combination of the above actions.
795 		 */
796 		bcopy((v_caddr_t) (sc->cbuffs[head] + offset),
797 		      mtod(m, caddr_t) + thismboff, (unsigned) thislen);
798 		m = m->m_next;
799 		thismboff = 0;		/* new mbuf, start at the beginning */
800 		resid -= thislen;	/* and we are this far through */
801 
802 		/*
803 		 * Advance all the pointers.  We can get here from either of
804 		 * the last two cases, but never the first.
805 		 */
806 nextbuf:
807 		offset = 0;
808 		sc->rbuffs[head]->ie_rbd_actual = 0;
809 		sc->rbuffs[head]->ie_rbd_length |= IE_RBD_LAST;
810 		sc->rbhead = head = (head + 1) % sc->nrxbufs;
811 		sc->rbuffs[sc->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
812 		sc->rbtail = (sc->rbtail + 1) % sc->nrxbufs;
813 	}
814 
815 	/*
816 	 * Unless something changed strangely while we were doing the copy,
817 	 * we have now copied everything in from the shared memory. This
818 	 * means that we are done.
819 	 */
820 	return (0);
821 }
822 
823 /*
824  * Read frame NUM from unit UNIT (pre-cached as IE).
825  *
826  * This routine reads the RFD at NUM, and copies in the buffers from
827  * the list of RBD, then rotates the RBD and RFD lists so that the receiver
828  * doesn't start complaining.  Trailers are DROPPED---there's no point
829  * in wasting time on confusing code to deal with them.	 Hopefully,
830  * this machine will never ARP for trailers anyway.
831  */
832 static void
ie_readframe(struct ie_softc * sc,int num)833 ie_readframe(struct ie_softc *sc, int	num/* frame number to read */)
834 {
835 	struct ifnet *ifp = sc->ifp;
836 	struct ie_recv_frame_desc rfd;
837 	struct mbuf *m = 0;
838 #ifdef DEBUG
839 	struct ether_header *eh;
840 #endif
841 
842 	bcopy((v_caddr_t) (sc->rframes[num]), &rfd,
843 	      sizeof(struct ie_recv_frame_desc));
844 
845 	/*
846 	 * Immediately advance the RFD list, since we we have copied ours
847 	 * now.
848 	 */
849 	sc->rframes[num]->ie_fd_status = 0;
850 	sc->rframes[num]->ie_fd_last |= IE_FD_LAST;
851 	sc->rframes[sc->rftail]->ie_fd_last &= ~IE_FD_LAST;
852 	sc->rftail = (sc->rftail + 1) % sc->nframes;
853 	sc->rfhead = (sc->rfhead + 1) % sc->nframes;
854 
855 	if (rfd.ie_fd_status & IE_FD_OK) {
856 		if (ieget(sc, &m)) {
857 			if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);	/* this counts as an
858 							 * error */
859 			return;
860 		}
861 	}
862 #ifdef DEBUG
863 	eh = mtod(m, struct ether_header *);
864 	if (ie_debug & IED_READFRAME) {
865 		if_printf(ifp, "frame from ether %6D type %x\n",
866 		       eh->ether_shost, ":", (unsigned) eh->ether_type);
867 	}
868 	if (ntohs(eh->ether_type) > ETHERTYPE_TRAIL
869 	    && ntohs(eh->ether_type) < (ETHERTYPE_TRAIL + ETHERTYPE_NTRAILER))
870 		printf("received trailer!\n");
871 #endif
872 
873 	if (!m)
874 		return;
875 
876 	/*
877 	 * Finally pass this packet up to higher layers.
878 	 */
879 	IE_UNLOCK(sc);
880 	(*ifp->if_input)(ifp, m);
881 	IE_LOCK(sc);
882 }
883 
884 static void
ie_drop_packet_buffer(struct ie_softc * sc)885 ie_drop_packet_buffer(struct ie_softc *sc)
886 {
887 	int	i;
888 
889 	do {
890 		/*
891 		 * This means we are somehow out of sync.  So, we reset the
892 		 * adapter.
893 		 */
894 		if (!(sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
895 #ifdef DEBUG
896 			print_rbd(sc->rbuffs[sc->rbhead]);
897 #endif
898 			log(LOG_ERR, "%s: receive descriptors out of sync at %d\n",
899 			    sc->ifp->if_xname, sc->rbhead);
900 			iereset(sc);
901 			return;
902 		}
903 		i = sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_LAST;
904 
905 		sc->rbuffs[sc->rbhead]->ie_rbd_length |= IE_RBD_LAST;
906 		sc->rbuffs[sc->rbhead]->ie_rbd_actual = 0;
907 		sc->rbhead = (sc->rbhead + 1) % sc->nrxbufs;
908 		sc->rbuffs[sc->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
909 		sc->rbtail = (sc->rbtail + 1) % sc->nrxbufs;
910 	} while (!i);
911 }
912 
913 
914 /*
915  * Start transmission on an interface.
916  */
917 static void
iestart(struct ifnet * ifp)918 iestart(struct ifnet *ifp)
919 {
920 	struct	 ie_softc *sc = ifp->if_softc;
921 
922 	IE_LOCK(sc);
923 	iestart_locked(ifp);
924 	IE_UNLOCK(sc);
925 }
926 
927 static void
iestart_locked(struct ifnet * ifp)928 iestart_locked(struct ifnet *ifp)
929 {
930 	struct	 ie_softc *sc = ifp->if_softc;
931 	struct	 mbuf *m0, *m;
932 	volatile unsigned char *buffer;
933 	u_short	 len;
934 
935 	/*
936 	 * This is not really volatile, in this routine, but it makes gcc
937 	 * happy.
938 	 */
939 	volatile u_short *bptr = &sc->scb->ie_command_list;
940 
941 	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
942 		return;
943 	if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
944 		return;
945 
946 	do {
947 		IF_DEQUEUE(&sc->ifp->if_snd, m);
948 		if (!m)
949 			break;
950 
951 		BPF_MTAP(ifp, m);
952 
953 		buffer = sc->xmit_cbuffs[sc->xmit_count];
954 		len = 0;
955 
956 		for (m0 = m; m && len < IE_BUF_LEN; m = m->m_next) {
957 			bcopy(mtod(m, caddr_t), buffer, m->m_len);
958 			buffer += m->m_len;
959 			len += m->m_len;
960 		}
961 
962 		m_freem(m0);
963 		len = max(len, ETHER_MIN_LEN);
964 
965 		sc->xmit_buffs[sc->xmit_count]->ie_xmit_flags =
966 		    IE_XMIT_LAST|len;
967 		sc->xmit_buffs[sc->xmit_count]->ie_xmit_next = 0xffff;
968 		sc->xmit_buffs[sc->xmit_count]->ie_xmit_buf =
969 		    MK_24(sc->iomem, sc->xmit_cbuffs[sc->xmit_count]);
970 
971 		sc->xmit_cmds[sc->xmit_count]->com.ie_cmd_cmd = IE_CMD_XMIT;
972 		sc->xmit_cmds[sc->xmit_count]->ie_xmit_status = 0;
973 		sc->xmit_cmds[sc->xmit_count]->ie_xmit_desc =
974 		    MK_16(sc->iomem, sc->xmit_buffs[sc->xmit_count]);
975 
976 		*bptr = MK_16(sc->iomem, sc->xmit_cmds[sc->xmit_count]);
977 		bptr = &sc->xmit_cmds[sc->xmit_count]->com.ie_cmd_link;
978 		sc->xmit_count++;
979 	} while (sc->xmit_count < sc->ntxbufs);
980 
981 	/*
982 	 * If we queued up anything for transmission, send it.
983 	 */
984 	if (sc->xmit_count) {
985 		sc->xmit_cmds[sc->xmit_count - 1]->com.ie_cmd_cmd |=
986 		    IE_CMD_LAST | IE_CMD_INTR;
987 
988 		/*
989 		 * By passing the command pointer as a null, we tell
990 		 * command_and_wait() to pretend that this isn't an action
991 		 * command.  I wish I understood what was happening here.
992 		 */
993 		command_and_wait(sc, IE_CU_START, 0, 0);
994 		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
995 	}
996 	return;
997 }
998 
999 /*
1000  * Check to see if there's an 82586 out there.
1001  */
1002 int
check_ie_present(struct ie_softc * sc)1003 check_ie_present(struct ie_softc *sc)
1004 {
1005 	volatile struct ie_sys_conf_ptr *scp;
1006 	volatile struct ie_int_sys_conf_ptr *iscp;
1007 	volatile struct ie_sys_ctl_block *scb;
1008 	u_long	realbase;
1009 
1010 	realbase = (uintptr_t) sc->iomembot + sc->iosize  - (1 << 24);
1011 
1012 	scp = (volatile struct ie_sys_conf_ptr *) (uintptr_t)
1013 	      (realbase + IE_SCP_ADDR);
1014 	bzero((volatile char *) scp, sizeof *scp);
1015 
1016 	/*
1017 	 * First we put the ISCP at the bottom of memory; this tests to make
1018 	 * sure that our idea of the size of memory is the same as the
1019 	 * controller's. This is NOT where the ISCP will be in normal
1020 	 * operation.
1021 	 */
1022 	iscp = (volatile struct ie_int_sys_conf_ptr *) sc->iomembot;
1023 	bzero((volatile char *)iscp, sizeof *iscp);
1024 
1025 	scb = (volatile struct ie_sys_ctl_block *) sc->iomembot;
1026 	bzero((volatile char *)scb, sizeof *scb);
1027 
1028 	scp->ie_bus_use = sc->bus_use;	/* 8-bit or 16-bit */
1029 	scp->ie_iscp_ptr = (caddr_t) (uintptr_t)
1030 	    ((volatile char *) iscp - (volatile char *) (uintptr_t) realbase);
1031 
1032 	iscp->ie_busy = 1;
1033 	iscp->ie_scb_offset = MK_16(realbase, scb) + 256;
1034 
1035 	(*sc->ie_reset_586) (sc);
1036 	(*sc->ie_chan_attn) (sc);
1037 
1038 	DELAY(100);		/* wait a while... */
1039 
1040 	if (iscp->ie_busy) {
1041 		return (0);
1042 	}
1043 	/*
1044 	 * Now relocate the ISCP to its real home, and reset the controller
1045 	 * again.
1046 	 */
1047 	iscp = (void *) Align((caddr_t) (uintptr_t)
1048 			      (realbase + IE_SCP_ADDR -
1049 			       sizeof(struct ie_int_sys_conf_ptr)));
1050 	bzero((volatile char *) iscp, sizeof *iscp);	/* ignore cast-qual */
1051 
1052 	scp->ie_iscp_ptr = (caddr_t) (uintptr_t)
1053 	    ((volatile char *) iscp - (volatile char *) (uintptr_t) realbase);
1054 
1055 	iscp->ie_busy = 1;
1056 	iscp->ie_scb_offset = MK_16(realbase, scb);
1057 
1058 	(*sc->ie_reset_586) (sc);
1059 	(*sc->ie_chan_attn) (sc);
1060 
1061 	DELAY(100);
1062 
1063 	if (iscp->ie_busy) {
1064 		return (0);
1065 	}
1066 	sc->iomem = (caddr_t) (uintptr_t) realbase;
1067 
1068 	sc->iscp = iscp;
1069 	sc->scb = scb;
1070 
1071 	/*
1072 	 * Acknowledge any interrupts we may have caused...
1073 	 */
1074 	ie_ack(sc, IE_ST_WHENCE);
1075 
1076 	return (1);
1077 }
1078 
1079 void
el_reset_586(struct ie_softc * sc)1080 el_reset_586(struct ie_softc *sc)
1081 {
1082 	outb(PORT(sc) + IE507_CTRL, EL_CTRL_RESET);
1083 	DELAY(100);
1084 	outb(PORT(sc) + IE507_CTRL, EL_CTRL_NORMAL);
1085 	DELAY(100);
1086 }
1087 
1088 void
sl_reset_586(struct ie_softc * sc)1089 sl_reset_586(struct ie_softc *sc)
1090 {
1091 	outb(PORT(sc) + IEATT_RESET, 0);
1092 }
1093 
1094 void
ee16_reset_586(struct ie_softc * sc)1095 ee16_reset_586(struct ie_softc *sc)
1096 {
1097 	outb(PORT(sc) + IEE16_ECTRL, IEE16_RESET_586);
1098 	DELAY(100);
1099 	outb(PORT(sc) + IEE16_ECTRL, 0);
1100 	DELAY(100);
1101 }
1102 
1103 void
el_chan_attn(struct ie_softc * sc)1104 el_chan_attn(struct ie_softc *sc)
1105 {
1106 	outb(PORT(sc) + IE507_ATTN, 1);
1107 }
1108 
1109 void
sl_chan_attn(struct ie_softc * sc)1110 sl_chan_attn(struct ie_softc *sc)
1111 {
1112 	outb(PORT(sc) + IEATT_ATTN, 0);
1113 }
1114 
1115 void
ee16_chan_attn(struct ie_softc * sc)1116 ee16_chan_attn(struct ie_softc *sc)
1117 {
1118 	outb(PORT(sc) + IEE16_ATTN, 0);
1119 }
1120 
1121 static __inline void
ee16_interrupt_enable(struct ie_softc * sc)1122 ee16_interrupt_enable(struct ie_softc *sc)
1123 {
1124 	DELAY(100);
1125 	outb(sc->port + IEE16_IRQ, sc->irq_encoded | IEE16_IRQ_ENABLE);
1126 	DELAY(100);
1127 }
1128 
1129 void
sl_read_ether(struct ie_softc * sc,unsigned char * addr)1130 sl_read_ether(struct ie_softc *sc, unsigned char *addr)
1131 {
1132 	int	i;
1133 
1134 	for (i = 0; i < 6; i++)
1135 		addr[i] = inb(PORT(sc) + i);
1136 }
1137 
1138 static void
iereset(struct ie_softc * sc)1139 iereset(struct ie_softc *sc)
1140 {
1141 	struct ifnet *ifp = sc->ifp;
1142 
1143 	if_printf(ifp, "reset\n");
1144 	ie_stop(sc);
1145 
1146 	/*
1147 	 * Stop i82586 dead in its tracks.
1148 	 */
1149 	if (command_and_wait(sc, IE_RU_ABORT | IE_CU_ABORT, 0, 0))
1150 		if_printf(ifp, "abort commands timed out\n");
1151 
1152 	if (command_and_wait(sc, IE_RU_DISABLE | IE_CU_STOP, 0, 0))
1153 		if_printf(ifp, "disable commands timed out\n");
1154 
1155 #ifdef notdef
1156 	if (!check_ie_present(sc))
1157 		panic("ie disappeared!");
1158 #endif
1159 
1160 	if (ifp->if_flags & IFF_UP)
1161 		ieinit_locked(sc);
1162 
1163 	return;
1164 }
1165 
1166 /*
1167  * Send a command to the controller and wait for it to either
1168  * complete or be accepted, depending on the command.  If the
1169  * command pointer is null, then pretend that the command is
1170  * not an action command.  If the command pointer is not null,
1171  * and the command is an action command, wait for
1172  * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK
1173  * to become true.
1174  */
1175 static int
command_and_wait(struct ie_softc * sc,int cmd,volatile void * pcmd,int mask)1176 command_and_wait(struct ie_softc *sc, int cmd, volatile void *pcmd, int mask)
1177 {
1178 	volatile struct ie_cmd_common *cc = pcmd;
1179 	int i;
1180 
1181 	sc->scb->ie_command = (u_short) cmd;
1182 
1183 	if (IE_ACTION_COMMAND(cmd) && pcmd) {
1184 		(*sc->ie_chan_attn) (sc);
1185 
1186 		/*
1187 		 * Now spin-lock waiting for status.  This is not a very
1188 		 * nice thing to do, but I haven't figured out how, or
1189 		 * indeed if, we can put the process waiting for action to
1190 		 * sleep.  (We may be getting called through some other
1191 		 * timeout running in the kernel.)
1192 		 *
1193 		 * According to the packet driver, the minimum timeout
1194 		 * should be .369 seconds, which we round up to .37.
1195 		 */
1196 		for (i = 0; i < 370; i++) {
1197 			if (cc->ie_cmd_status & mask)
1198 				return (0);
1199 			DELAY(1000);
1200 		}
1201 
1202 		return (1);
1203 	} else {
1204 
1205 		/*
1206 		 * Otherwise, just wait for the command to be accepted.
1207 		 */
1208 		(*sc->ie_chan_attn) (sc);
1209 
1210 		while (sc->scb->ie_command);	/* spin lock */
1211 
1212 		return (0);
1213 	}
1214 }
1215 
1216 /*
1217  * Run the time-domain reflectometer...
1218  */
1219 static void
run_tdr(struct ie_softc * sc,volatile struct ie_tdr_cmd * cmd)1220 run_tdr(struct ie_softc *sc, volatile struct ie_tdr_cmd *cmd)
1221 {
1222 	int	result;
1223 
1224 	cmd->com.ie_cmd_status = 0;
1225 	cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST;
1226 	cmd->com.ie_cmd_link = 0xffff;
1227 	cmd->ie_tdr_time = 0;
1228 
1229 	sc->scb->ie_command_list = MK_16(MEM(sc), cmd);
1230 	cmd->ie_tdr_time = 0;
1231 
1232 	if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL))
1233 		result = 0x2000;
1234 	else
1235 		result = cmd->ie_tdr_time;
1236 
1237 	ie_ack(sc, IE_ST_WHENCE);
1238 
1239 	if (result & IE_TDR_SUCCESS)
1240 		return;
1241 
1242 	if (result & IE_TDR_XCVR) {
1243 		if_printf(sc->ifp, "transceiver problem\n");
1244 	} else if (result & IE_TDR_OPEN) {
1245 		if_printf(sc->ifp, "TDR detected an open %d clocks away\n",
1246 		       result & IE_TDR_TIME);
1247 	} else if (result & IE_TDR_SHORT) {
1248 		if_printf(sc->ifp, "TDR detected a short %d clocks away\n",
1249 		       result & IE_TDR_TIME);
1250 	} else {
1251 		if_printf(sc->ifp, "TDR returned unknown status %x\n", result);
1252 	}
1253 }
1254 
1255 static void
start_receiver(struct ie_softc * sc)1256 start_receiver(struct ie_softc *sc)
1257 {
1258 
1259 	sc->scb->ie_recv_list = MK_16(MEM(sc), sc->rframes[0]);
1260 	command_and_wait(sc, IE_RU_START, 0, 0);
1261 
1262 	ie_ack(sc, IE_ST_WHENCE);
1263 }
1264 
1265 /*
1266  * Here is a helper routine for iernr() and ieinit().  This sets up
1267  * the RFA.
1268  */
1269 static v_caddr_t
setup_rfa(struct ie_softc * sc,v_caddr_t ptr)1270 setup_rfa(struct ie_softc *sc, v_caddr_t ptr)
1271 {
1272 	volatile struct ie_recv_frame_desc *rfd = (volatile void *)ptr;
1273 	volatile struct ie_recv_buf_desc *rbd;
1274 	int	i;
1275 
1276 	/* First lay them out */
1277 	for (i = 0; i < sc->nframes; i++) {
1278 		sc->rframes[i] = rfd;
1279 		bzero((volatile char *) rfd, sizeof *rfd);	/* ignore cast-qual */
1280 		rfd++;
1281 	}
1282 
1283 	ptr = Alignvol(rfd);		/* ignore cast-qual */
1284 
1285 	/* Now link them together */
1286 	for (i = 0; i < sc->nframes; i++) {
1287 		sc->rframes[i]->ie_fd_next =
1288 		    MK_16(MEM(sc), sc->rframes[(i + 1) % sc->nframes]);
1289 	}
1290 
1291 	/* Finally, set the EOL bit on the last one. */
1292 	sc->rframes[sc->nframes - 1]->ie_fd_last |= IE_FD_LAST;
1293 
1294 	/*
1295 	 * Now lay out some buffers for the incoming frames.  Note that we
1296 	 * set aside a bit of slop in each buffer, to make sure that we have
1297 	 * enough space to hold a single frame in every buffer.
1298 	 */
1299 	rbd = (volatile void *) ptr;
1300 
1301 	for (i = 0; i < sc->nrxbufs; i++) {
1302 		sc->rbuffs[i] = rbd;
1303 		bzero((volatile char *)rbd, sizeof *rbd);
1304 		ptr = Alignvol(ptr + sizeof *rbd);
1305 		rbd->ie_rbd_length = IE_RBUF_SIZE;
1306 		rbd->ie_rbd_buffer = MK_24(MEM(sc), ptr);
1307 		sc->cbuffs[i] = (volatile void *) ptr;
1308 		ptr += IE_RBUF_SIZE;
1309 		rbd = (volatile void *) ptr;
1310 	}
1311 
1312 	/* Now link them together */
1313 	for (i = 0; i < sc->nrxbufs; i++) {
1314 		sc->rbuffs[i]->ie_rbd_next =
1315 		    MK_16(MEM(sc), sc->rbuffs[(i + 1) % sc->nrxbufs]);
1316 	}
1317 
1318 	/* Tag EOF on the last one */
1319 	sc->rbuffs[sc->nrxbufs - 1]->ie_rbd_length |= IE_RBD_LAST;
1320 
1321 	/*
1322 	 * We use the head and tail pointers on receive to keep track of the
1323 	 * order in which RFDs and RBDs are used.
1324 	 */
1325 	sc->rfhead = 0;
1326 	sc->rftail = sc->nframes - 1;
1327 	sc->rbhead = 0;
1328 	sc->rbtail = sc->nrxbufs - 1;
1329 
1330 	sc->scb->ie_recv_list = MK_16(MEM(sc), sc->rframes[0]);
1331 	sc->rframes[0]->ie_fd_buf_desc = MK_16(MEM(sc), sc->rbuffs[0]);
1332 
1333 	ptr = Alignvol(ptr);
1334 	return (ptr);
1335 }
1336 
1337 /*
1338  * Run the multicast setup command.
1339  */
1340 static int
mc_setup(struct ie_softc * sc)1341 mc_setup(struct ie_softc *sc)
1342 {
1343 	volatile struct ie_mcast_cmd *cmd = (volatile void *)sc->xmit_cbuffs[0];
1344 
1345 	cmd->com.ie_cmd_status = 0;
1346 	cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST;
1347 	cmd->com.ie_cmd_link = 0xffff;
1348 
1349 	/* ignore cast-qual */
1350 	bcopy((v_caddr_t) sc->mcast_addrs, (v_caddr_t) cmd->ie_mcast_addrs,
1351 	      sc->mcast_count * sizeof *sc->mcast_addrs);
1352 
1353 	cmd->ie_mcast_bytes = sc->mcast_count * 6;	/* grrr... */
1354 
1355 	sc->scb->ie_command_list = MK_16(MEM(sc), cmd);
1356 	if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL)
1357 	    || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
1358 		if_printf(sc->ifp, "multicast address setup command failed\n");
1359 		return (0);
1360 	}
1361 	return (1);
1362 }
1363 
1364 /*
1365  * This routine takes the environment generated by check_ie_present()
1366  * and adds to it all the other structures we need to operate the adapter.
1367  * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands,
1368  * starting the receiver unit, and clearing interrupts.
1369  */
1370 static void
ieinit(xsc)1371 ieinit(xsc)
1372 	void *xsc;
1373 {
1374 	struct ie_softc *sc = xsc;
1375 
1376 	IE_LOCK(sc);
1377 	ieinit_locked(sc);
1378 	IE_UNLOCK(sc);
1379 }
1380 
1381 static void
ieinit_locked(struct ie_softc * sc)1382 ieinit_locked(struct ie_softc *sc)
1383 {
1384 	struct ifnet *ifp = sc->ifp;
1385 	volatile struct ie_sys_ctl_block *scb = sc->scb;
1386 	caddr_t ptr;
1387 	int	i;
1388 
1389 	ptr = Alignvol((volatile char *) scb + sizeof *scb);
1390 
1391 	/*
1392 	 * Send the configure command first.
1393 	 */
1394 	{
1395 		volatile struct ie_config_cmd *cmd = (volatile void *) ptr;
1396 
1397 		ie_setup_config(cmd, sc->promisc,
1398 				sc->hard_type == IE_STARLAN10);
1399 		cmd->com.ie_cmd_status = 0;
1400 		cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST;
1401 		cmd->com.ie_cmd_link = 0xffff;
1402 
1403 		scb->ie_command_list = MK_16(MEM(sc), cmd);
1404 
1405 		if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL)
1406 		 || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
1407 			if_printf(ifp, "configure command failed\n");
1408 			return;
1409 		}
1410 	}
1411 	/*
1412 	 * Now send the Individual Address Setup command.
1413 	 */
1414 	{
1415 		volatile struct ie_iasetup_cmd *cmd = (volatile void *) ptr;
1416 
1417 		cmd->com.ie_cmd_status = 0;
1418 		cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST;
1419 		cmd->com.ie_cmd_link = 0xffff;
1420 
1421 		bcopy((volatile char *)IF_LLADDR(ifp),
1422 		      (volatile char *)&cmd->ie_address, sizeof cmd->ie_address);
1423 		scb->ie_command_list = MK_16(MEM(sc), cmd);
1424 		if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL)
1425 		    || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
1426 			if_printf(ifp, "individual address "
1427 			       "setup command failed\n");
1428 			return;
1429 		}
1430 	}
1431 
1432 	/*
1433 	 * Now run the time-domain reflectometer.
1434 	 */
1435 	run_tdr(sc, (volatile void *) ptr);
1436 
1437 	/*
1438 	 * Acknowledge any interrupts we have generated thus far.
1439 	 */
1440 	ie_ack(sc, IE_ST_WHENCE);
1441 
1442 	/*
1443 	 * Set up the RFA.
1444 	 */
1445 	ptr = setup_rfa(sc, ptr);
1446 
1447 	/*
1448 	 * Finally, the transmit command and buffer are the last little bit
1449 	 * of work.
1450 	 */
1451 
1452 	/* transmit command buffers */
1453 	for (i = 0; i < sc->ntxbufs; i++) {
1454 		sc->xmit_cmds[i] = (volatile void *) ptr;
1455 		ptr += sizeof *sc->xmit_cmds[i];
1456 		ptr = Alignvol(ptr);
1457 		sc->xmit_buffs[i] = (volatile void *)ptr;
1458 		ptr += sizeof *sc->xmit_buffs[i];
1459 		ptr = Alignvol(ptr);
1460 	}
1461 
1462 	/* transmit buffers */
1463 	for (i = 0; i < sc->ntxbufs - 1; i++) {
1464 		sc->xmit_cbuffs[i] = (volatile void *)ptr;
1465 		ptr += IE_BUF_LEN;
1466 		ptr = Alignvol(ptr);
1467 	}
1468 	sc->xmit_cbuffs[sc->ntxbufs - 1] = (volatile void *) ptr;
1469 
1470 	for (i = 1; i < sc->ntxbufs; i++) {
1471 		bzero((v_caddr_t) sc->xmit_cmds[i], sizeof *sc->xmit_cmds[i]);
1472 		bzero((v_caddr_t) sc->xmit_buffs[i], sizeof *sc->xmit_buffs[i]);
1473 	}
1474 
1475 	/*
1476 	 * This must be coordinated with iestart() and ietint().
1477 	 */
1478 	sc->xmit_cmds[0]->ie_xmit_status = IE_STAT_COMPL;
1479 
1480 	/* take the ee16 out of loopback */
1481 	if (sc->hard_type == IE_EE16) {
1482 		u_int8_t bart_config;
1483 
1484 		bart_config = inb(PORT(sc) + IEE16_CONFIG);
1485 		bart_config &= ~IEE16_BART_LOOPBACK;
1486 		/* inb doesn't get bit! */
1487 		bart_config |= IEE16_BART_MCS16_TEST;
1488 		outb(PORT(sc) + IEE16_CONFIG, bart_config);
1489 		ee16_interrupt_enable(sc);
1490 		ee16_chan_attn(sc);
1491 	}
1492 	ifp->if_drv_flags |= IFF_DRV_RUNNING;	/* tell higher levels
1493 							 * we're here */
1494 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1495 
1496 	start_receiver(sc);
1497 
1498 	return;
1499 }
1500 
1501 static void
ie_stop(struct ie_softc * sc)1502 ie_stop(struct ie_softc *sc)
1503 {
1504 	struct ifnet *ifp = sc->ifp;
1505 
1506 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
1507 	command_and_wait(sc, IE_RU_DISABLE, 0, 0);
1508 }
1509 
1510 static int
ieioctl(struct ifnet * ifp,u_long command,caddr_t data)1511 ieioctl(struct ifnet *ifp, u_long command, caddr_t data)
1512 {
1513 	int	error = 0;
1514 	struct	 ie_softc *sc = ifp->if_softc;
1515 
1516 	switch (command) {
1517 	case SIOCSIFFLAGS:
1518 		/*
1519 		 * Note that this device doesn't have an "all multicast"
1520 		 * mode, so we must turn on promiscuous mode and do the
1521 		 * filtering manually.
1522 		 */
1523 		IE_LOCK(sc);
1524 		if ((ifp->if_flags & IFF_UP) == 0 &&
1525 		    (ifp->if_drv_flags & IFF_DRV_RUNNING)) {
1526 			ie_stop(sc);
1527 		} else if ((ifp->if_flags & IFF_UP) &&
1528 			   (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
1529 			sc->promisc =
1530 			    ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
1531 			ieinit_locked(sc);
1532 		} else if (sc->promisc ^
1533 			   (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI))) {
1534 			sc->promisc =
1535 			    ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
1536 			ieinit_locked(sc);
1537 		}
1538 		IE_UNLOCK(sc);
1539 		break;
1540 
1541 	case SIOCADDMULTI:
1542 	case SIOCDELMULTI:
1543 		/*
1544 		 * Update multicast listeners
1545 		 */
1546 		/* reset multicast filtering */
1547 		IE_LOCK(sc);
1548 		ie_mc_reset(sc);
1549 		IE_UNLOCK(sc);
1550 		error = 0;
1551 		break;
1552 
1553 	default:
1554 		error = ether_ioctl(ifp, command, data);
1555 		break;
1556 	}
1557 
1558 	return (error);
1559 }
1560 
1561 static void
ie_mc_reset(struct ie_softc * sc)1562 ie_mc_reset(struct ie_softc *sc)
1563 {
1564 	struct ifmultiaddr *ifma;
1565 
1566 	/*
1567 	 * Step through the list of addresses.
1568 	 */
1569 	sc->mcast_count = 0;
1570 	if_maddr_rlock(sc->ifp);
1571 	TAILQ_FOREACH(ifma, &sc->ifp->if_multiaddrs, ifma_link) {
1572 		if (ifma->ifma_addr->sa_family != AF_LINK)
1573 			continue;
1574 
1575 		/* XXX - this is broken... */
1576 		if (sc->mcast_count >= MAXMCAST) {
1577 			sc->ifp->if_flags |= IFF_ALLMULTI;
1578 			if (sc->ifp->if_flags & IFF_UP)
1579 				ieinit_locked(sc);
1580 			goto setflag;
1581 		}
1582 		bcopy(LLADDR((struct sockaddr_dl *) ifma->ifma_addr),
1583 		      &(sc->mcast_addrs[sc->mcast_count]), 6);
1584 		sc->mcast_count++;
1585 	}
1586 	if_maddr_runlock(sc->ifp);
1587 
1588 setflag:
1589 	sc->want_mcsetup = 1;
1590 }
1591 
1592 
1593 #ifdef DEBUG
1594 static void
print_rbd(volatile struct ie_recv_buf_desc * rbd)1595 print_rbd(volatile struct ie_recv_buf_desc * rbd)
1596 {
1597 	printf("RBD at %p:\n"
1598 	       "actual %04x, next %04x, buffer %p\n"
1599 	       "length %04x, mbz %04x\n",
1600 	       (volatile void *) rbd,
1601 	       rbd->ie_rbd_actual, rbd->ie_rbd_next,
1602 	       (void *) rbd->ie_rbd_buffer,
1603 	       rbd->ie_rbd_length, rbd->mbz);
1604 }
1605 
1606 #endif				/* DEBUG */
1607 
1608 int
ie_alloc_resources(device_t dev)1609 ie_alloc_resources (device_t dev)
1610 {
1611 	struct ie_softc *       sc;
1612 	int                     error;
1613 
1614 	error = 0;
1615 	sc = device_get_softc(dev);
1616 
1617 	sc->io_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->io_rid,
1618 					    RF_ACTIVE);
1619 	if (!sc->io_res) {
1620 		device_printf(dev, "No I/O space?!\n");
1621 		error = ENOMEM;
1622 		goto bad;
1623 	}
1624 	sc->io_bt = rman_get_bustag(sc->io_res);
1625 	sc->io_bh = rman_get_bushandle(sc->io_res);
1626 
1627 	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid,
1628 					     RF_ACTIVE);
1629 	if (!sc->mem_res) {
1630                 device_printf(dev, "No Memory!\n");
1631 		error = ENOMEM;
1632 		goto bad;
1633 	}
1634 	sc->mem_bt = rman_get_bustag(sc->mem_res);
1635 	sc->mem_bh = rman_get_bushandle(sc->mem_res);
1636 
1637 	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
1638 					     RF_ACTIVE);
1639 	if (!sc->irq_res) {
1640 		device_printf(dev, "No IRQ!\n");
1641 		error = ENOMEM;
1642 		goto bad;
1643 	}
1644 
1645 	sc->port = rman_get_start(sc->io_res);  /* XXX hack */
1646 	sc->iomembot = rman_get_virtual(sc->mem_res);
1647 	sc->iosize = rman_get_size(sc->mem_res);
1648 
1649 	return (0);
1650 bad:
1651 	return (error);
1652 }
1653 
1654 void
ie_release_resources(device_t dev)1655 ie_release_resources (device_t dev)
1656 {
1657 	struct ie_softc *       sc;
1658 
1659 	sc = device_get_softc(dev);
1660 
1661 	if (sc->irq_ih)
1662 		bus_teardown_intr(dev, sc->irq_res, sc->irq_ih);
1663 	if (sc->rframes)
1664 		free(sc->rframes, M_DEVBUF);
1665 	if (sc->io_res)
1666 		bus_release_resource(dev, SYS_RES_IOPORT,
1667 				     sc->io_rid, sc->io_res);
1668 	if (sc->irq_res)
1669 		bus_release_resource(dev, SYS_RES_IRQ,
1670 				     sc->irq_rid, sc->irq_res);
1671 	if (sc->mem_res)
1672 		bus_release_resource(dev, SYS_RES_MEMORY,
1673 				     sc->mem_rid, sc->mem_res);
1674 	if (sc->ifp)
1675 		if_free(sc->ifp);
1676 
1677 	return;
1678 }
1679 
1680 int
ie_detach(device_t dev)1681 ie_detach (device_t dev)
1682 {
1683 	struct ie_softc *	sc;
1684 	struct ifnet *		ifp;
1685 
1686 	sc = device_get_softc(dev);
1687 	ifp = sc->ifp;
1688 
1689 	IE_LOCK(sc);
1690 	if (sc->hard_type == IE_EE16)
1691 		ee16_shutdown(sc);
1692 
1693 	ie_stop(sc);
1694 	IE_UNLOCK(sc);
1695 	ether_ifdetach(ifp);
1696 	ie_release_resources(dev);
1697 	mtx_destroy(&sc->lock);
1698 
1699 	return (0);
1700 }
1701