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