xref: /netbsd-src/sys/dev/isa/if_el.c (revision 2a399c6883d870daece976daec6ffa7bb7f934ce)
1 /*	$NetBSD: if_el.c,v 1.50 1997/11/30 15:31:25 drochner Exp $	*/
2 
3 /*
4  * Copyright (c) 1994, Matthew E. Kimmel.  Permission is hereby granted
5  * to use, copy, modify and distribute this software provided that both
6  * the copyright notice and this permission notice appear in all copies
7  * of the software, derivative works or modified versions, and any
8  * portions thereof.
9  */
10 
11 /*
12  * 3COM Etherlink 3C501 device driver
13  */
14 
15 /*
16  * Bugs/possible improvements:
17  *	- Does not currently support DMA
18  *	- Does not currently support multicasts
19  */
20 
21 #include "bpfilter.h"
22 #include "rnd.h"
23 
24 #include <sys/param.h>
25 #include <sys/systm.h>
26 #include <sys/errno.h>
27 #include <sys/ioctl.h>
28 #include <sys/mbuf.h>
29 #include <sys/socket.h>
30 #include <sys/syslog.h>
31 #include <sys/device.h>
32 #if NRND > 0
33 #include <sys/rnd.h>
34 #endif
35 
36 #include <net/if.h>
37 #include <net/if_dl.h>
38 #include <net/if_types.h>
39 
40 #include <net/if_ether.h>
41 
42 #ifdef INET
43 #include <netinet/in.h>
44 #include <netinet/in_systm.h>
45 #include <netinet/in_var.h>
46 #include <netinet/ip.h>
47 #include <netinet/if_inarp.h>
48 #endif
49 
50 #ifdef NS
51 #include <netns/ns.h>
52 #include <netns/ns_if.h>
53 #endif
54 
55 #if NBPFILTER > 0
56 #include <net/bpf.h>
57 #include <net/bpfdesc.h>
58 #endif
59 
60 #include <machine/cpu.h>
61 #include <machine/intr.h>
62 #include <machine/bus.h>
63 
64 #include <dev/isa/isavar.h>
65 #include <dev/isa/if_elreg.h>
66 
67 #define ETHER_MIN_LEN	64
68 #define ETHER_MAX_LEN	1518
69 #define	ETHER_ADDR_LEN	6
70 
71 /* for debugging convenience */
72 #ifdef EL_DEBUG
73 #define DPRINTF(x) printf x
74 #else
75 #define DPRINTF(x)
76 #endif
77 
78 /*
79  * per-line info and status
80  */
81 struct el_softc {
82 	struct device sc_dev;
83 	void *sc_ih;
84 
85 	struct ethercom sc_ethercom;	/* ethernet common */
86 	bus_space_tag_t sc_iot;		/* bus space identifier */
87 	bus_space_handle_t sc_ioh;	/* i/o handle */
88 
89 #if NRND > 0
90 	rndsource_element_t rnd_source;
91 #endif
92 };
93 
94 /*
95  * prototypes
96  */
97 int elintr __P((void *));
98 void elinit __P((struct el_softc *));
99 int elioctl __P((struct ifnet *, u_long, caddr_t));
100 void elstart __P((struct ifnet *));
101 void elwatchdog __P((struct ifnet *));
102 void elreset __P((struct el_softc *));
103 void elstop __P((struct el_softc *));
104 static int el_xmit __P((struct el_softc *));
105 void elread __P((struct el_softc *, int));
106 struct mbuf *elget __P((struct el_softc *sc, int));
107 static inline void el_hardreset __P((struct el_softc *));
108 
109 #ifdef __BROKEN_INDIRECT_CONFIG
110 int elprobe __P((struct device *, void *, void *));
111 #else
112 int elprobe __P((struct device *, struct cfdata *, void *));
113 #endif
114 void elattach __P((struct device *, struct device *, void *));
115 
116 struct cfattach el_ca = {
117 	sizeof(struct el_softc), elprobe, elattach
118 };
119 
120 struct cfdriver el_cd = {
121 	NULL, "el", DV_IFNET
122 };
123 
124 /*
125  * Probe routine.
126  *
127  * See if the card is there and at the right place.
128  * (XXX - cgd -- needs help)
129  */
130 int
131 elprobe(parent, match, aux)
132 	struct device *parent;
133 #ifdef __BROKEN_INDIRECT_CONFIG
134 	void *match;
135 #else
136 	struct cfdata *match;
137 #endif
138 	void *aux;
139 {
140 	struct isa_attach_args *ia = aux;
141 	bus_space_tag_t iot = ia->ia_iot;
142 	bus_space_handle_t ioh;
143 	int iobase = ia->ia_iobase;
144 	u_int8_t station_addr[ETHER_ADDR_LEN];
145 	u_int8_t i;
146 	int rval;
147 
148 	rval = 0;
149 
150 	/* First check the base. */
151 	if (iobase < 0x200 || iobase > 0x3f0)
152 		return 0;
153 
154 	/* Map i/o space. */
155 	if (bus_space_map(iot, iobase, 16, 0, &ioh))
156 		return 0;
157 
158 	/*
159 	 * Now attempt to grab the station address from the PROM and see if it
160 	 * contains the 3com vendor code.
161 	 */
162 	DPRINTF(("Probing 3c501 at 0x%x...\n", iobase));
163 
164 	/* Reset the board. */
165 	DPRINTF(("Resetting board...\n"));
166 	bus_space_write_1(iot, ioh, EL_AC, EL_AC_RESET);
167 	delay(5);
168 	bus_space_write_1(iot, ioh, EL_AC, 0);
169 
170 	/* Now read the address. */
171 	DPRINTF(("Reading station address...\n"));
172 	for (i = 0; i < ETHER_ADDR_LEN; i++) {
173 		bus_space_write_1(iot, ioh, EL_GPBL, i);
174 		station_addr[i] = bus_space_read_1(iot, ioh, EL_EAW);
175 	}
176 	DPRINTF(("Address is %s\n", ether_sprintf(station_addr)));
177 
178 	/*
179 	 * If the vendor code is ok, return a 1.  We'll assume that whoever
180 	 * configured this system is right about the IRQ.
181 	 */
182 	if (station_addr[0] != 0x02 || station_addr[1] != 0x60 ||
183 	    station_addr[2] != 0x8c) {
184 		DPRINTF(("Bad vendor code.\n"));
185 		goto out;
186 	}
187 	DPRINTF(("Vendor code ok.\n"));
188 
189 	ia->ia_iosize = 16;
190 	ia->ia_msize = 0;
191 	rval = 1;
192 
193  out:
194 	bus_space_unmap(iot, ioh, 16);
195 	return rval;
196 }
197 
198 /*
199  * Attach the interface to the kernel data structures.  By the time this is
200  * called, we know that the card exists at the given I/O address.  We still
201  * assume that the IRQ given is correct.
202  */
203 void
204 elattach(parent, self, aux)
205 	struct device *parent, *self;
206 	void *aux;
207 {
208 	struct el_softc *sc = (void *)self;
209 	struct isa_attach_args *ia = aux;
210 	bus_space_tag_t iot = ia->ia_iot;
211 	bus_space_handle_t ioh;
212 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
213 	u_int8_t myaddr[ETHER_ADDR_LEN];
214 	u_int8_t i;
215 
216 	printf("\n");
217 
218 	DPRINTF(("Attaching %s...\n", sc->sc_dev.dv_xname));
219 
220 	/* Map i/o space. */
221 	if (bus_space_map(iot, ia->ia_iobase, ia->ia_iosize, 0, &ioh)) {
222 		printf("%s: can't map i/o space\n", self->dv_xname);
223 		return;
224 	}
225 
226 	sc->sc_iot = iot;
227 	sc->sc_ioh = ioh;
228 
229 	/* Reset the board. */
230 	bus_space_write_1(iot, ioh, EL_AC, EL_AC_RESET);
231 	delay(5);
232 	bus_space_write_1(iot, ioh, EL_AC, 0);
233 
234 	/* Now read the address. */
235 	for (i = 0; i < ETHER_ADDR_LEN; i++) {
236 		bus_space_write_1(iot, ioh, EL_GPBL, i);
237 		myaddr[i] = bus_space_read_1(iot, ioh, EL_EAW);
238 	}
239 
240 	/* Stop the board. */
241 	elstop(sc);
242 
243 	/* Initialize ifnet structure. */
244 	bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
245 	ifp->if_softc = sc;
246 	ifp->if_start = elstart;
247 	ifp->if_ioctl = elioctl;
248 	ifp->if_watchdog = elwatchdog;
249 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS;
250 
251 	/* Now we can attach the interface. */
252 	DPRINTF(("Attaching interface...\n"));
253 	if_attach(ifp);
254 	ether_ifattach(ifp, myaddr);
255 
256 	/* Print out some information for the user. */
257 	printf("%s: address %s\n", self->dv_xname, ether_sprintf(myaddr));
258 
259 	/* Finally, attach to bpf filter if it is present. */
260 #if NBPFILTER > 0
261 	DPRINTF(("Attaching to BPF...\n"));
262 	bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
263 #endif
264 
265 	sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
266 	    IPL_NET, elintr, sc);
267 
268 #if NRND > 0
269 	DPRINTF(("Attaching to random...\n"));
270 	rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname, RND_TYPE_NET);
271 #endif
272 
273 	DPRINTF(("elattach() finished.\n"));
274 }
275 
276 /*
277  * Reset interface.
278  */
279 void
280 elreset(sc)
281 	struct el_softc *sc;
282 {
283 	int s;
284 
285 	DPRINTF(("elreset()\n"));
286 	s = splnet();
287 	elstop(sc);
288 	elinit(sc);
289 	splx(s);
290 }
291 
292 /*
293  * Stop interface.
294  */
295 void
296 elstop(sc)
297 	struct el_softc *sc;
298 {
299 
300 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, EL_AC, 0);
301 }
302 
303 /*
304  * Do a hardware reset of the board, and upload the ethernet address again in
305  * case the board forgets.
306  */
307 static inline void
308 el_hardreset(sc)
309 	struct el_softc *sc;
310 {
311 	bus_space_tag_t iot = sc->sc_iot;
312 	bus_space_handle_t ioh = sc->sc_ioh;
313 	int i;
314 
315 	bus_space_write_1(iot, ioh, EL_AC, EL_AC_RESET);
316 	delay(5);
317 	bus_space_write_1(iot, ioh, EL_AC, 0);
318 
319 	for (i = 0; i < ETHER_ADDR_LEN; i++)
320 		bus_space_write_1(iot, ioh, i,
321 		    LLADDR(sc->sc_ethercom.ec_if.if_sadl)[i]);
322 }
323 
324 /*
325  * Initialize interface.
326  */
327 void
328 elinit(sc)
329 	struct el_softc *sc;
330 {
331 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
332 	bus_space_tag_t iot = sc->sc_iot;
333 	bus_space_handle_t ioh = sc->sc_ioh;
334 
335 	/* First, reset the board. */
336 	el_hardreset(sc);
337 
338 	/* Configure rx. */
339 	DPRINTF(("Configuring rx...\n"));
340 	if (ifp->if_flags & IFF_PROMISC)
341 		bus_space_write_1(iot, ioh, EL_RXC,
342 		    EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB |
343 		    EL_RXC_DOFLOW | EL_RXC_PROMISC);
344 	else
345 		bus_space_write_1(iot, ioh, EL_RXC,
346 		    EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB |
347 		    EL_RXC_DOFLOW | EL_RXC_ABROAD);
348 	bus_space_write_1(iot, ioh, EL_RBC, 0);
349 
350 	/* Configure TX. */
351 	DPRINTF(("Configuring tx...\n"));
352 	bus_space_write_1(iot, ioh, EL_TXC, 0);
353 
354 	/* Start reception. */
355 	DPRINTF(("Starting reception...\n"));
356 	bus_space_write_1(iot, ioh, EL_AC, EL_AC_IRQE | EL_AC_RX);
357 
358 	/* Set flags appropriately. */
359 	ifp->if_flags |= IFF_RUNNING;
360 	ifp->if_flags &= ~IFF_OACTIVE;
361 
362 	/* And start output. */
363 	elstart(ifp);
364 }
365 
366 /*
367  * Start output on interface.  Get datagrams from the queue and output them,
368  * giving the receiver a chance between datagrams.  Call only from splnet or
369  * interrupt level!
370  */
371 void
372 elstart(ifp)
373 	struct ifnet *ifp;
374 {
375 	struct el_softc *sc = ifp->if_softc;
376 	bus_space_tag_t iot = sc->sc_iot;
377 	bus_space_handle_t ioh = sc->sc_ioh;
378 	struct mbuf *m, *m0;
379 	int s, i, off, retries;
380 
381 	DPRINTF(("elstart()...\n"));
382 	s = splnet();
383 
384 	/* Don't do anything if output is active. */
385 	if ((ifp->if_flags & IFF_OACTIVE) != 0) {
386 		splx(s);
387 		return;
388 	}
389 
390 	ifp->if_flags |= IFF_OACTIVE;
391 
392 	/*
393 	 * The main loop.  They warned me against endless loops, but would I
394 	 * listen?  NOOO....
395 	 */
396 	for (;;) {
397 		/* Dequeue the next datagram. */
398 		IF_DEQUEUE(&ifp->if_snd, m0);
399 
400 		/* If there's nothing to send, return. */
401 		if (m0 == 0)
402 			break;
403 
404 #if NBPFILTER > 0
405 		/* Give the packet to the bpf, if any. */
406 		if (ifp->if_bpf)
407 			bpf_mtap(ifp->if_bpf, m0);
408 #endif
409 
410 		/* Disable the receiver. */
411 		bus_space_write_1(iot, ioh, EL_AC, EL_AC_HOST);
412 		bus_space_write_1(iot, ioh, EL_RBC, 0);
413 
414 		/* Transfer datagram to board. */
415 		DPRINTF(("el: xfr pkt length=%d...\n", m0->m_pkthdr.len));
416 		off = EL_BUFSIZ - max(m0->m_pkthdr.len, ETHER_MIN_LEN);
417 #ifdef DIAGNOSTIC
418 		if ((off & 0xffff) != off)
419 			printf("%s: bogus off 0x%x\n",
420 			    sc->sc_dev.dv_xname, off);
421 #endif
422 		bus_space_write_1(iot, ioh, EL_GPBL, off & 0xff);
423 		bus_space_write_1(iot, ioh, EL_GPBH, (off >> 8) & 0xff);
424 
425 		/* Copy the datagram to the buffer. */
426 		for (m = m0; m != 0; m = m->m_next)
427 			bus_space_write_multi_1(iot, ioh, EL_BUF,
428 			    mtod(m, u_int8_t *), m->m_len);
429 
430 		m_freem(m0);
431 
432 		/* Now transmit the datagram. */
433 		retries = 0;
434 		for (;;) {
435 			bus_space_write_1(iot, ioh, EL_GPBL, off & 0xff);
436 			bus_space_write_1(iot, ioh, EL_GPBH, (off >> 8) & 0xff);
437 			if (el_xmit(sc)) {
438 				ifp->if_oerrors++;
439 				break;
440 			}
441 			/* Check out status. */
442 			i = bus_space_read_1(iot, ioh, EL_TXS);
443 			DPRINTF(("tx status=0x%x\n", i));
444 			if ((i & EL_TXS_READY) == 0) {
445 				DPRINTF(("el: err txs=%x\n", i));
446 				if (i & (EL_TXS_COLL | EL_TXS_COLL16)) {
447 					ifp->if_collisions++;
448 					if ((i & EL_TXC_DCOLL16) == 0 &&
449 					    retries < 15) {
450 						retries++;
451 						bus_space_write_1(iot, ioh,
452 						    EL_AC, EL_AC_HOST);
453 					}
454 				} else {
455 					ifp->if_oerrors++;
456 					break;
457 				}
458 			} else {
459 				ifp->if_opackets++;
460 				break;
461 			}
462 		}
463 
464 		/*
465 		 * Now give the card a chance to receive.
466 		 * Gotta love 3c501s...
467 		 */
468 		(void)bus_space_read_1(iot, ioh, EL_AS);
469 		bus_space_write_1(iot, ioh, EL_AC, EL_AC_IRQE | EL_AC_RX);
470 		splx(s);
471 		/* Interrupt here. */
472 		s = splnet();
473 	}
474 
475 	(void)bus_space_read_1(iot, ioh, EL_AS);
476 	bus_space_write_1(iot, ioh, EL_AC, EL_AC_IRQE | EL_AC_RX);
477 	ifp->if_flags &= ~IFF_OACTIVE;
478 	splx(s);
479 }
480 
481 /*
482  * This function actually attempts to transmit a datagram downloaded to the
483  * board.  Call at splnet or interrupt, after downloading data!  Returns 0 on
484  * success, non-0 on failure.
485  */
486 static int
487 el_xmit(sc)
488 	struct el_softc *sc;
489 {
490 	bus_space_tag_t iot = sc->sc_iot;
491 	bus_space_handle_t ioh = sc->sc_ioh;
492 	int i;
493 
494 	/*
495 	 * XXX
496 	 * This busy-waits for the tx completion.  Can we get an interrupt
497 	 * instead?
498 	 */
499 
500 	DPRINTF(("el: xmit..."));
501 	bus_space_write_1(iot, ioh, EL_AC, EL_AC_TXFRX);
502 	i = 20000;
503 	while ((bus_space_read_1(iot, ioh, EL_AS) & EL_AS_TXBUSY) && (i > 0))
504 		i--;
505 	if (i == 0) {
506 		DPRINTF(("tx not ready\n"));
507 		return -1;
508 	}
509 	DPRINTF(("%d cycles.\n", 20000 - i));
510 	return 0;
511 }
512 
513 /*
514  * Controller interrupt.
515  */
516 int
517 elintr(arg)
518 	void *arg;
519 {
520 	register struct el_softc *sc = arg;
521 	bus_space_tag_t iot = sc->sc_iot;
522 	bus_space_handle_t ioh = sc->sc_ioh;
523 	u_int8_t rxstat;
524 	int len;
525 
526 	DPRINTF(("elintr: "));
527 
528 	/* Check board status. */
529 	if ((bus_space_read_1(iot, ioh, EL_AS) & EL_AS_RXBUSY) != 0) {
530 		(void)bus_space_read_1(iot, ioh, EL_RXC);
531 		bus_space_write_1(iot, ioh, EL_AC, EL_AC_IRQE | EL_AC_RX);
532 		return 0;
533 	}
534 
535 	for (;;) {
536 		rxstat = bus_space_read_1(iot, ioh, EL_RXS);
537 		if (rxstat & EL_RXS_STALE)
538 			break;
539 
540 		/* If there's an overflow, reinit the board. */
541 		if ((rxstat & EL_RXS_NOFLOW) == 0) {
542 			DPRINTF(("overflow.\n"));
543 			el_hardreset(sc);
544 			/* Put board back into receive mode. */
545 			if (sc->sc_ethercom.ec_if.if_flags & IFF_PROMISC)
546 				bus_space_write_1(iot, ioh, EL_RXC,
547 				    EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB |
548 				    EL_RXC_DOFLOW | EL_RXC_PROMISC);
549 			else
550 				bus_space_write_1(iot, ioh, EL_RXC,
551 				    EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB |
552 				    EL_RXC_DOFLOW | EL_RXC_ABROAD);
553 			(void)bus_space_read_1(iot, ioh, EL_AS);
554 			bus_space_write_1(iot, ioh, EL_RBC, 0);
555 			break;
556 		}
557 
558 		/* Incoming packet. */
559 		len = bus_space_read_1(iot, ioh, EL_RBL);
560 		len |= bus_space_read_1(iot, ioh, EL_RBH) << 8;
561 		DPRINTF(("receive len=%d rxstat=%x ", len, rxstat));
562 		bus_space_write_1(iot, ioh, EL_AC, EL_AC_HOST);
563 
564 		/* Pass data up to upper levels. */
565 		elread(sc, len);
566 
567 		/* Is there another packet? */
568 		if ((bus_space_read_1(iot, ioh, EL_AS) & EL_AS_RXBUSY) != 0)
569 			break;
570 
571 #if NRND > 0
572 		rnd_add_uint32(&sc->rnd_source, rxstat);
573 #endif
574 
575 		DPRINTF(("<rescan> "));
576 	}
577 
578 	(void)bus_space_read_1(iot, ioh, EL_RXC);
579 	bus_space_write_1(iot, ioh, EL_AC, EL_AC_IRQE | EL_AC_RX);
580 	return 1;
581 }
582 
583 /*
584  * Pass a packet to the higher levels.
585  */
586 void
587 elread(sc, len)
588 	register struct el_softc *sc;
589 	int len;
590 {
591 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
592 	struct mbuf *m;
593 	struct ether_header *eh;
594 
595 	if (len <= sizeof(struct ether_header) ||
596 	    len > ETHER_MAX_LEN) {
597 		printf("%s: invalid packet size %d; dropping\n",
598 		    sc->sc_dev.dv_xname, len);
599 		ifp->if_ierrors++;
600 		return;
601 	}
602 
603 	/* Pull packet off interface. */
604 	m = elget(sc, len);
605 	if (m == 0) {
606 		ifp->if_ierrors++;
607 		return;
608 	}
609 
610 	ifp->if_ipackets++;
611 
612 	/* We assume that the header fit entirely in one mbuf. */
613 	eh = mtod(m, struct ether_header *);
614 
615 #if NBPFILTER > 0
616 	/*
617 	 * Check if there's a BPF listener on this interface.
618 	 * If so, hand off the raw packet to BPF.
619 	 */
620 	if (ifp->if_bpf) {
621 		bpf_mtap(ifp->if_bpf, m);
622 
623 		/*
624 		 * Note that the interface cannot be in promiscuous mode if
625 		 * there are no BPF listeners.  And if we are in promiscuous
626 		 * mode, we have to check if this packet is really ours.
627 		 */
628 		if ((ifp->if_flags & IFF_PROMISC) &&
629 		    (eh->ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */
630 		    bcmp(eh->ether_dhost, LLADDR(ifp->if_sadl),
631 			    sizeof(eh->ether_dhost)) != 0) {
632 			m_freem(m);
633 			return;
634 		}
635 	}
636 #endif
637 
638 	/* We assume that the header fit entirely in one mbuf. */
639 	m_adj(m, sizeof(struct ether_header));
640 	ether_input(ifp, eh, m);
641 }
642 
643 /*
644  * Pull read data off a interface.  Len is length of data, with local net
645  * header stripped.  We copy the data into mbufs.  When full cluster sized
646  * units are present we copy into clusters.
647  */
648 struct mbuf *
649 elget(sc, totlen)
650 	struct el_softc *sc;
651 	int totlen;
652 {
653 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
654 	bus_space_tag_t iot = sc->sc_iot;
655 	bus_space_handle_t ioh = sc->sc_ioh;
656 	struct mbuf *top, **mp, *m;
657 	int len;
658 
659 	MGETHDR(m, M_DONTWAIT, MT_DATA);
660 	if (m == 0)
661 		return 0;
662 	m->m_pkthdr.rcvif = ifp;
663 	m->m_pkthdr.len = totlen;
664 	len = MHLEN;
665 	top = 0;
666 	mp = &top;
667 
668 	bus_space_write_1(iot, ioh, EL_GPBL, 0);
669 	bus_space_write_1(iot, ioh, EL_GPBH, 0);
670 
671 	while (totlen > 0) {
672 		if (top) {
673 			MGET(m, M_DONTWAIT, MT_DATA);
674 			if (m == 0) {
675 				m_freem(top);
676 				return 0;
677 			}
678 			len = MLEN;
679 		}
680 		if (totlen >= MINCLSIZE) {
681 			MCLGET(m, M_DONTWAIT);
682 			if ((m->m_flags & M_EXT) == 0) {
683 				m_free(m);
684 				m_freem(top);
685 				return 0;
686 			}
687 			len = MCLBYTES;
688 		}
689 		m->m_len = len = min(totlen, len);
690 		bus_space_read_multi_1(iot, ioh, EL_BUF, mtod(m, u_int8_t *), len);
691 		totlen -= len;
692 		*mp = m;
693 		mp = &m->m_next;
694 	}
695 
696 	bus_space_write_1(iot, ioh, EL_RBC, 0);
697 	bus_space_write_1(iot, ioh, EL_AC, EL_AC_RX);
698 
699 	return top;
700 }
701 
702 /*
703  * Process an ioctl request. This code needs some work - it looks pretty ugly.
704  */
705 int
706 elioctl(ifp, cmd, data)
707 	register struct ifnet *ifp;
708 	u_long cmd;
709 	caddr_t data;
710 {
711 	struct el_softc *sc = ifp->if_softc;
712 	struct ifaddr *ifa = (struct ifaddr *)data;
713 	int s, error = 0;
714 
715 	s = splnet();
716 
717 	switch (cmd) {
718 
719 	case SIOCSIFADDR:
720 		ifp->if_flags |= IFF_UP;
721 
722 		switch (ifa->ifa_addr->sa_family) {
723 #ifdef INET
724 		case AF_INET:
725 			elinit(sc);
726 			arp_ifinit(ifp, ifa);
727 			break;
728 #endif
729 #ifdef NS
730 		/* XXX - This code is probably wrong. */
731 		case AF_NS:
732 		    {
733 			register struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
734 
735 			if (ns_nullhost(*ina))
736 				ina->x_host =
737 				    *(union ns_host *)LLADDR(ifp->if_sadl);
738 			else
739 				bcopy(ina->x_host.c_host, LLADDR(ifp->if_sadl),
740 				    ETHER_ADDR_LEN);
741 			/* Set new address. */
742 			elinit(sc);
743 			break;
744 		    }
745 #endif
746 		default:
747 			elinit(sc);
748 			break;
749 		}
750 		break;
751 
752 	case SIOCSIFFLAGS:
753 		if ((ifp->if_flags & IFF_UP) == 0 &&
754 		    (ifp->if_flags & IFF_RUNNING) != 0) {
755 			/*
756 			 * If interface is marked down and it is running, then
757 			 * stop it.
758 			 */
759 			elstop(sc);
760 			ifp->if_flags &= ~IFF_RUNNING;
761 		} else if ((ifp->if_flags & IFF_UP) != 0 &&
762 		    	   (ifp->if_flags & IFF_RUNNING) == 0) {
763 			/*
764 			 * If interface is marked up and it is stopped, then
765 			 * start it.
766 			 */
767 			elinit(sc);
768 		} else {
769 			/*
770 			 * Some other important flag might have changed, so
771 			 * reset.
772 			 */
773 			elreset(sc);
774 		}
775 		break;
776 
777 	default:
778 		error = EINVAL;
779 		break;
780 	}
781 
782 	splx(s);
783 	return error;
784 }
785 
786 /*
787  * Device timeout routine.
788  */
789 void
790 elwatchdog(ifp)
791 	struct ifnet *ifp;
792 {
793 	struct el_softc *sc = ifp->if_softc;
794 
795 	log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
796 	sc->sc_ethercom.ec_if.if_oerrors++;
797 
798 	elreset(sc);
799 }
800