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