if_le.c revision 1.16 1 /* $NetBSD: if_le.c,v 1.16 1995/01/03 15:43:36 gwr Exp $ */
2
3 /*
4 * LANCE Ethernet driver
5 *
6 * Copyright (c) 1995 Gordon W. Ross
7 * Copyright (c) 1994 Charles Hannum.
8 *
9 * Copyright (C) 1993, Paul Richards. This software may be used, modified,
10 * copied, distributed, and sold, in both source and binary form provided
11 * that the above copyright and these terms are retained. Under no
12 * circumstances is the author responsible for the proper functioning
13 * of this software, nor does the author assume any responsibility
14 * for damages incurred with its use.
15 */
16
17 #include "bpfilter.h"
18
19 #include <sys/param.h>
20 #include <sys/systm.h>
21 #include <sys/errno.h>
22 #include <sys/ioctl.h>
23 #include <sys/mbuf.h>
24 #include <sys/socket.h>
25 #include <sys/syslog.h>
26 #include <sys/device.h>
27
28 #include <net/if.h>
29 #include <net/if_dl.h>
30 #include <net/if_types.h>
31 #include <net/netisr.h>
32
33 #ifdef INET
34 #include <netinet/in.h>
35 #include <netinet/in_systm.h>
36 #include <netinet/in_var.h>
37 #include <netinet/ip.h>
38 #include <netinet/if_ether.h>
39 #endif
40
41 #ifdef NS
42 #include <netns/ns.h>
43 #include <netns/ns_if.h>
44 #endif
45
46 #if NBPFILTER > 0
47 #include <net/bpf.h>
48 #include <net/bpfdesc.h>
49 #endif
50
51 #include <machine/autoconf.h>
52 #include <machine/cpu.h>
53
54 /* #define LEDEBUG 1 */
55
56 #include "if_lereg.h"
57 #include "if_le.h"
58 #include "if_le_subr.h"
59
60 #define ETHER_MIN_LEN 64
61 #define ETHER_MAX_LEN 1518
62
63 /*
64 * The lance has only 24 address lines. When it accesses memory,
65 * the high address lines are hard-wired to 0xFF, so we must:
66 * (1) put what we want the LANCE to see above 0xFF000000, and
67 * (2) mask our CPU addresses down to 24 bits for the LANCE.
68 */
69 #define LANCE_ADDR(sc,x) ((u_int)(x) & 0xFFffff)
70
71 #ifdef PACKETSTATS
72 long lexpacketsizes[LEMTU+1];
73 long lerpacketsizes[LEMTU+1];
74 #endif
75
76 /* autoconfiguration driver */
77 void le_attach(struct device *, struct device *, void *);
78
79 struct cfdriver lecd = {
80 NULL, "le", le_md_match, le_attach,
81 DV_IFNET, sizeof(struct le_softc),
82 };
83
84 int leioctl __P((struct ifnet *, u_long, caddr_t));
85 int lestart __P((struct ifnet *));
86 int lewatchdog __P((/* short */));
87 static inline void lewrcsr __P((/* struct le_softc *, u_short, u_short */));
88 static inline u_short lerdcsr __P((/* struct le_softc *, u_short */));
89 void leinit __P((struct le_softc *));
90 void lememinit __P((struct le_softc *));
91 void lereset __P((struct le_softc *));
92 void lestop __P((struct le_softc *));
93 void letint __P((struct le_softc *));
94 void lerint __P((struct le_softc *));
95 void leread __P((struct le_softc *, u_char *, int));
96 struct mbuf *leget __P((u_char *, int, struct ifnet *));
97 void lesetladrf __P((struct arpcom *, u_long *));
98 #ifdef LEDEBUG
99 void recv_print __P((struct le_softc *, int));
100 void xmit_print __P((struct le_softc *, int));
101 #endif
102
103 /*
104 * Inline routines to read and write the LANCE registers.
105 */
106
107 static inline void
108 lewrcsr(sc, regnum, value)
109 struct le_softc *sc;
110 u_short regnum;
111 u_short value;
112 {
113 volatile struct le_regs *regs = sc->sc_regs;
114
115 regs->lereg_addr = regnum;
116 regs->lereg_data = value;
117 }
118
119 static inline u_short
120 lerdcsr(sc, regnum)
121 struct le_softc *sc;
122 u_short regnum;
123 {
124 volatile struct le_regs *regs = sc->sc_regs;
125 u_short value;
126
127 regs->lereg_addr = regnum;
128 value = regs->lereg_data;
129
130 return (value);
131 }
132
133 /*
134 * The probe is done in if_le_subr.c:if_md_match()
135 */
136
137 /*
138 * Interface exists: make available by filling in network interface
139 * record. System will initialize the interface when it is ready
140 * to accept packets. We get the ethernet address here.
141 */
142 void
143 le_attach(parent, self, aux)
144 struct device *parent, *self;
145 void *aux;
146 {
147 struct le_softc *sc = (void *)self;
148 struct confargs *ca = aux;
149 struct ifnet *ifp = &sc->sc_if;
150 int pri;
151 u_int a;
152
153 le_md_attach(parent, self, aux);
154 printf(" hwaddr %s\n", ether_sprintf(sc->sc_enaddr));
155
156 /*
157 * Initialize and attach S/W interface
158 */
159 ifp->if_unit = sc->sc_dev.dv_unit;
160 ifp->if_name = lecd.cd_name;
161 ifp->if_output = ether_output;
162 ifp->if_start = lestart;
163 ifp->if_ioctl = leioctl;
164 ifp->if_watchdog = lewatchdog;
165 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
166 #ifdef IFF_NOTRAILERS
167 /* XXX still compile when the blasted things are gone... */
168 ifp->if_flags |= IFF_NOTRAILERS;
169 #endif
170 if_attach(ifp);
171 ether_ifattach(ifp);
172 #if NBPFILTER > 0
173 bpfattach(&sc->sc_if.if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
174 #endif
175 }
176
177 void
178 lereset(sc)
179 struct le_softc *sc;
180 {
181
182 leinit(sc);
183 }
184
185 int
186 lewatchdog(unit)
187 short unit;
188 {
189 struct le_softc *sc = lecd.cd_devs[unit];
190
191 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
192 ++sc->sc_if.if_oerrors;
193 lereset(sc);
194 }
195
196 /* LANCE initialization block set up. */
197 void
198 lememinit(sc)
199 register struct le_softc *sc;
200 {
201 struct ifnet *ifp = &sc->sc_if;
202 int i;
203 void *mem;
204 u_long a;
205
206 /*
207 * At this point we assume that the memory allocated to the Lance is
208 * quadword aligned. If it isn't then the initialisation is going
209 * fail later on.
210 */
211 mem = sc->sc_mem;
212
213 sc->sc_init = mem;
214 #if NBPFILTER > 0
215 if (ifp->if_flags & IFF_PROMISC)
216 sc->sc_init->mode = LE_NORMAL | LE_PROM;
217 else
218 #endif
219 sc->sc_init->mode = LE_NORMAL;
220
221 /* Set the Ethernet address (have to byte-swap) */
222 for (i = 0; i < 6; i += 2) {
223 sc->sc_init->padr[i] = sc->sc_enaddr[i+1];
224 sc->sc_init->padr[i+1] = sc->sc_enaddr[i];
225 }
226 lesetladrf(&sc->sc_ac, sc->sc_init->ladrf);
227 mem += sizeof(struct init_block);
228
229 sc->sc_rd = mem;
230 a = LANCE_ADDR(sc, mem);
231 sc->sc_init->rdra = a;
232 sc->sc_init->rlen = ((a >> 16) & 0xff) | (RLEN << 13);
233 mem += NRBUF * sizeof(struct mds);
234
235 sc->sc_td = mem;
236 a = LANCE_ADDR(sc, mem);
237 sc->sc_init->tdra = a;
238 sc->sc_init->tlen = ((a >> 16) & 0xff) | (TLEN << 13);
239 mem += NTBUF * sizeof(struct mds);
240
241 /*
242 * Set up receive ring descriptors.
243 */
244 sc->sc_rbuf = mem;
245 for (i = 0; i < NRBUF; i++) {
246 a = LANCE_ADDR(sc, mem);
247 sc->sc_rd[i].addr = a;
248 sc->sc_rd[i].flags = ((a >> 16) & 0xff) | LE_OWN;
249 sc->sc_rd[i].bcnt = -BUFSIZE;
250 sc->sc_rd[i].mcnt = 0;
251 mem += BUFSIZE;
252 }
253
254 /*
255 * Set up transmit ring descriptors.
256 */
257 sc->sc_tbuf = mem;
258 for (i = 0; i < NTBUF; i++) {
259 a = LANCE_ADDR(sc, mem);
260 sc->sc_td[i].addr = a;
261 sc->sc_td[i].flags= ((a >> 16) & 0xff);
262 sc->sc_td[i].bcnt = 0xf000;
263 sc->sc_td[i].mcnt = 0;
264 mem += BUFSIZE;
265 }
266
267 #ifdef DIAGNOSTIC
268 if (mem > (sc->sc_mem + MEMSIZE))
269 panic("lememinit: used 0x%x\n", mem - sc->sc_mem);
270 #endif
271 }
272
273 void
274 lestop(sc)
275 struct le_softc *sc;
276 {
277
278 lewrcsr(sc, 0, LE_STOP);
279 }
280
281 /*
282 * Initialization of interface; set up initialization block
283 * and transmit/receive descriptor rings.
284 */
285 void
286 leinit(sc)
287 register struct le_softc *sc;
288 {
289 struct ifnet *ifp = &sc->sc_if;
290 int s;
291 register int timo;
292 u_long a;
293
294 /* Address not known. */
295 if (!ifp->if_addrlist)
296 return;
297
298 s = splimp();
299
300 /* Don't want to get in a weird state. */
301 lewrcsr(sc, 0, LE_STOP);
302 delay(100);
303
304 sc->sc_last_rd = sc->sc_last_td = sc->sc_no_td = 0;
305
306 /* Set up LANCE init block. */
307 lememinit(sc);
308
309 /* Set byte swapping etc. */
310 lewrcsr(sc, 3, LE_CONF3);
311
312 /* Give LANCE the physical address of its init block. */
313 a = LANCE_ADDR(sc, sc->sc_init);
314 lewrcsr(sc, 1, a);
315 lewrcsr(sc, 2, (a >> 16) & 0xff);
316
317 /* Try to initialize the LANCE. */
318 delay(100);
319 lewrcsr(sc, 0, LE_INIT);
320
321 /* Wait for initialization to finish. */
322 for (timo = 1000; timo; timo--)
323 if (lerdcsr(sc, 0) & LE_IDON)
324 break;
325
326 if (lerdcsr(sc, 0) & LE_IDON) {
327 /* Start the LANCE. */
328 lewrcsr(sc, 0, LE_INEA | LE_STRT | LE_IDON);
329 ifp->if_flags |= IFF_RUNNING;
330 ifp->if_flags &= ~IFF_OACTIVE;
331 lestart(ifp);
332 } else
333 printf("%s: card failed to initialize\n", sc->sc_dev.dv_xname);
334
335 (void) splx(s);
336 }
337
338 /*
339 * Controller interrupt.
340 */
341 int
342 leintr(vsc)
343 void *vsc;
344 {
345 register struct le_softc *sc = vsc;
346 register u_short isr;
347
348 isr = lerdcsr(sc, 0);
349 #ifdef LEDEBUG
350 if (sc->sc_debug)
351 printf("%s: leintr entering with isr=%04x\n",
352 sc->sc_dev.dv_xname, isr);
353 #endif
354 if ((isr & LE_INTR) == 0)
355 return 0;
356
357 do {
358 lewrcsr(sc, 0,
359 isr & (LE_INEA | LE_BABL | LE_MISS | LE_MERR |
360 LE_RINT | LE_TINT | LE_IDON));
361 if (isr & (LE_BABL | LE_CERR | LE_MISS | LE_MERR)) {
362 if (isr & LE_BABL) {
363 printf("%s: babble\n", sc->sc_dev.dv_xname);
364 sc->sc_if.if_oerrors++;
365 }
366 #if 0
367 if (isr & LE_CERR) {
368 printf("%s: collision error\n", sc->sc_dev.dv_xname);
369 sc->sc_if.if_collisions++;
370 }
371 #endif
372 if (isr & LE_MISS) {
373 #if 0
374 printf("%s: missed packet\n", sc->sc_dev.dv_xname);
375 #endif
376 sc->sc_if.if_ierrors++;
377 }
378 if (isr & LE_MERR) {
379 printf("%s: memory error\n", sc->sc_dev.dv_xname);
380 lereset(sc);
381 goto out;
382 }
383 }
384
385 if ((isr & LE_RXON) == 0) {
386 printf("%s: receiver disabled\n", sc->sc_dev.dv_xname);
387 sc->sc_if.if_ierrors++;
388 lereset(sc);
389 goto out;
390 }
391 if ((isr & LE_TXON) == 0) {
392 printf("%s: transmitter disabled\n", sc->sc_dev.dv_xname);
393 sc->sc_if.if_oerrors++;
394 lereset(sc);
395 goto out;
396 }
397
398 if (isr & LE_RINT) {
399 /* Reset watchdog timer. */
400 sc->sc_if.if_timer = 0;
401 lerint(sc);
402 }
403 if (isr & LE_TINT) {
404 /* Reset watchdog timer. */
405 sc->sc_if.if_timer = 0;
406 letint(sc);
407 }
408
409 isr = lerdcsr(sc, 0);
410 } while ((isr & LE_INTR) != 0);
411
412 #ifdef LEDEBUG
413 if (sc->sc_debug)
414 printf("%s: leintr returning with isr=%04x\n",
415 sc->sc_dev.dv_xname, isr);
416 #endif
417
418 out:
419 return 1;
420 }
421
422 #define NEXTTDS \
423 if (++tmd == NTBUF) tmd=0, cdm=sc->sc_td; else ++cdm
424
425 /*
426 * Setup output on interface.
427 * Get another datagram to send off of the interface queue, and map it to the
428 * interface before starting the output.
429 * Called only at splimp or interrupt level.
430 */
431 int
432 lestart(ifp)
433 struct ifnet *ifp;
434 {
435 register struct le_softc *sc = lecd.cd_devs[ifp->if_unit];
436 register int tmd;
437 volatile struct mds *cdm;
438 struct mbuf *m0, *m;
439 u_char *buffer;
440 int len;
441
442 if ((sc->sc_if.if_flags & (IFF_RUNNING | IFF_OACTIVE)) !=
443 IFF_RUNNING)
444 return;
445
446 tmd = sc->sc_last_td;
447 cdm = &sc->sc_td[tmd];
448
449 for (;;) {
450 if (sc->sc_no_td >= NTBUF) {
451 sc->sc_if.if_flags |= IFF_OACTIVE;
452 #ifdef LEDEBUG
453 if (sc->sc_debug)
454 printf("no_td = %d, last_td = %d\n", sc->sc_no_td,
455 sc->sc_last_td);
456 #endif
457 break;
458 }
459
460 #ifdef LEDEBUG
461 if (cdm->flags & LE_OWN) {
462 sc->sc_if.if_flags |= IFF_OACTIVE;
463 printf("missing buffer, no_td = %d, last_td = %d\n",
464 sc->sc_no_td, sc->sc_last_td);
465 }
466 #endif
467
468 IF_DEQUEUE(&sc->sc_if.if_snd, m);
469 if (!m)
470 break;
471
472 ++sc->sc_no_td;
473
474 /*
475 * Copy the mbuf chain into the transmit buffer.
476 */
477 buffer = sc->sc_tbuf + (BUFSIZE * sc->sc_last_td);
478 len = 0;
479 for (m0 = m; m; m = m->m_next) {
480 bcopy(mtod(m, caddr_t), buffer, m->m_len);
481 buffer += m->m_len;
482 len += m->m_len;
483 }
484
485 #ifdef LEDEBUG
486 if (len > ETHER_MAX_LEN)
487 printf("packet length %d\n", len);
488 #endif
489
490 #if NBPFILTER > 0
491 if (sc->sc_if.if_bpf)
492 bpf_mtap(sc->sc_if.if_bpf, m0);
493 #endif
494
495 m_freem(m0);
496 len = max(len, ETHER_MIN_LEN);
497
498 /*
499 * Init transmit registers, and set transmit start flag.
500 */
501 cdm->bcnt = -len;
502 cdm->mcnt = 0;
503 cdm->flags |= LE_OWN | LE_STP | LE_ENP;
504
505 #ifdef LEDEBUG
506 if (sc->sc_debug)
507 xmit_print(sc, sc->sc_last_td);
508 #endif
509
510 lewrcsr(sc, 0, LE_INEA | LE_TDMD);
511
512 NEXTTDS;
513 }
514
515 sc->sc_last_td = tmd;
516 }
517
518 void
519 letint(sc)
520 struct le_softc *sc;
521 {
522 register int tmd = (sc->sc_last_td - sc->sc_no_td + NTBUF) % NTBUF;
523 volatile struct mds *cdm;
524
525 cdm = &sc->sc_td[tmd];
526 if (cdm->flags & LE_OWN) {
527 /* Race condition with loop below. */
528 #ifdef LEDEBUG
529 if (sc->sc_debug)
530 printf("%s: extra tint\n", sc->sc_dev.dv_xname);
531 #endif
532 return;
533 }
534
535 sc->sc_if.if_flags &= ~IFF_OACTIVE;
536
537 do {
538 if (sc->sc_no_td <= 0)
539 break;
540 #ifdef LEDEBUG
541 if (sc->sc_debug)
542 printf("trans cdm = %x\n", cdm);
543 #endif
544 sc->sc_if.if_opackets++;
545 --sc->sc_no_td;
546 if (cdm->mcnt & (LE_TBUFF | LE_UFLO | LE_LCOL | LE_LCAR | LE_RTRY)) {
547 if (cdm->mcnt & LE_TBUFF)
548 printf("%s: transmit buffer error\n", sc->sc_dev.dv_xname);
549 if ((cdm->mcnt & (LE_TBUFF | LE_UFLO)) == LE_UFLO)
550 printf("%s: underflow\n", sc->sc_dev.dv_xname);
551 if (cdm->mcnt & LE_UFLO) {
552 lereset(sc);
553 return;
554 }
555 #if 0
556 if (cdm->mcnt & LE_LCOL) {
557 printf("%s: late collision\n", sc->sc_dev.dv_xname);
558 sc->sc_if.if_collisions++;
559 }
560 if (cdm->mcnt & LE_LCAR)
561 printf("%s: lost carrier\n", sc->sc_dev.dv_xname);
562 if (cdm->mcnt & LE_RTRY) {
563 printf("%s: excessive collisions, tdr %d\n",
564 sc->sc_dev.dv_xname, cdm->flags & 0x1ff);
565 sc->sc_if.if_collisions += 16;
566 }
567 #endif
568 } else if (cdm->flags & LE_ONE)
569 sc->sc_if.if_collisions++;
570 else if (cdm->flags & LE_MORE)
571 /* Real number is unknown. */
572 sc->sc_if.if_collisions += 2;
573 NEXTTDS;
574 } while ((cdm->flags & LE_OWN) == 0);
575
576 lestart(&sc->sc_if);
577 }
578
579 #define NEXTRDS \
580 if (++rmd == NRBUF) rmd=0, cdm=sc->sc_rd; else ++cdm
581
582 /* only called from one place, so may as well integrate */
583 void
584 lerint(sc)
585 struct le_softc *sc;
586 {
587 register int rmd = sc->sc_last_rd;
588 volatile struct mds *cdm;
589
590 cdm = &sc->sc_rd[rmd];
591 if (cdm->flags & LE_OWN) {
592 /* Race condition with loop below. */
593 #ifdef LEDEBUG
594 if (sc->sc_debug)
595 printf("%s: extra rint\n", sc->sc_dev.dv_xname);
596 #endif
597 return;
598 }
599
600 /* Process all buffers with valid data. */
601 do {
602 if (cdm->flags & (LE_FRAM | LE_OFLO | LE_CRC | LE_RBUFF)) {
603 if ((cdm->flags & (LE_FRAM | LE_OFLO | LE_ENP)) == (LE_FRAM | LE_ENP))
604 printf("%s: framing error\n", sc->sc_dev.dv_xname);
605 if ((cdm->flags & (LE_OFLO | LE_ENP)) == LE_OFLO)
606 printf("%s: overflow\n", sc->sc_dev.dv_xname);
607 if ((cdm->flags & (LE_CRC | LE_OFLO | LE_ENP)) == (LE_CRC | LE_ENP))
608 printf("%s: crc mismatch\n", sc->sc_dev.dv_xname);
609 if (cdm->flags & LE_RBUFF)
610 printf("%s: receive buffer error\n", sc->sc_dev.dv_xname);
611 } else if (cdm->flags & (LE_STP | LE_ENP) != (LE_STP | LE_ENP)) {
612 do {
613 cdm->mcnt = 0;
614 cdm->flags |= LE_OWN;
615 NEXTRDS;
616 } while ((cdm->flags & (LE_OWN | LE_ERR | LE_STP | LE_ENP)) == 0);
617 sc->sc_last_rd = rmd;
618 printf("%s: chained buffer\n", sc->sc_dev.dv_xname);
619 if ((cdm->flags & (LE_OWN | LE_ERR | LE_STP | LE_ENP)) != LE_ENP) {
620 lereset(sc);
621 return;
622 }
623 } else {
624 #ifdef LEDEBUG
625 if (sc->sc_debug)
626 recv_print(sc, sc->sc_last_rd);
627 #endif
628 leread(sc, sc->sc_rbuf + (BUFSIZE * rmd),
629 (int)cdm->mcnt);
630 sc->sc_if.if_ipackets++;
631 }
632
633 cdm->bcnt = -BUFSIZE;
634 cdm->mcnt = 0;
635 cdm->flags |= LE_OWN;
636 NEXTRDS;
637 #ifdef LEDEBUG
638 if (sc->sc_debug)
639 printf("sc->sc_last_rd = %x, cdm = %x\n",
640 sc->sc_last_rd, cdm);
641 #endif
642 } while ((cdm->flags & LE_OWN) == 0);
643
644 sc->sc_last_rd = rmd;
645 }
646
647 /*
648 * Pass a packet to the higher levels.
649 */
650 void
651 leread(sc, buf, len)
652 register struct le_softc *sc;
653 u_char *buf;
654 int len;
655 {
656 struct ifnet *ifp;
657 struct mbuf *m;
658 struct ether_header *eh;
659
660 len -= 4;
661 if (len <= 0)
662 return;
663
664 /* Pull packet off interface. */
665 ifp = &sc->sc_if;
666 m = leget(buf, len, ifp);
667 if (m == 0)
668 return;
669
670 /* We assume that the header fit entirely in one mbuf. */
671 eh = mtod(m, struct ether_header *);
672
673 #if NBPFILTER > 0
674 /*
675 * Check if there's a BPF listener on this interface.
676 * If so, hand off the raw packet to BPF.
677 */
678 if (ifp->if_bpf) {
679 bpf_mtap(ifp->if_bpf, m);
680
681 /*
682 * Note that the interface cannot be in promiscuous mode if
683 * there are no BPF listeners. And if we are in promiscuous
684 * mode, we have to check if this packet is really ours.
685 */
686 if ((ifp->if_flags & IFF_PROMISC) &&
687 (eh->ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */
688 bcmp(eh->ether_dhost, sc->sc_enaddr,
689 sizeof(eh->ether_dhost)) != 0) {
690 m_freem(m);
691 return;
692 }
693 }
694 #endif
695
696 /* We assume that the header fit entirely in one mbuf. */
697 m->m_pkthdr.len -= sizeof(*eh);
698 m->m_len -= sizeof(*eh);
699 m->m_data += sizeof(*eh);
700
701 ether_input(ifp, eh, m);
702 }
703
704 /*
705 * Supporting routines
706 */
707
708 /*
709 * Pull data off an interface.
710 * Len is length of data, with local net header stripped.
711 * We copy the data into mbufs. When full cluster sized units are present
712 * we copy into clusters.
713 */
714 struct mbuf *
715 leget(buf, totlen, ifp)
716 u_char *buf;
717 int totlen;
718 struct ifnet *ifp;
719 {
720 struct mbuf *top, **mp, *m;
721 int len;
722
723 MGETHDR(m, M_DONTWAIT, MT_DATA);
724 if (m == 0)
725 return 0;
726 m->m_pkthdr.rcvif = ifp;
727 m->m_pkthdr.len = totlen;
728 len = MHLEN;
729 top = 0;
730 mp = ⊤
731
732 while (totlen > 0) {
733 if (top) {
734 MGET(m, M_DONTWAIT, MT_DATA);
735 if (m == 0) {
736 m_freem(top);
737 return 0;
738 }
739 len = MLEN;
740 }
741 if (totlen >= MINCLSIZE) {
742 MCLGET(m, M_DONTWAIT);
743 if (m->m_flags & M_EXT)
744 len = MCLBYTES;
745 }
746 m->m_len = len = min(totlen, len);
747 bcopy((caddr_t)buf, mtod(m, caddr_t), len);
748 buf += len;
749 totlen -= len;
750 *mp = m;
751 mp = &m->m_next;
752 }
753
754 return top;
755 }
756
757 /*
758 * Process an ioctl request.
759 */
760 int
761 leioctl(ifp, cmd, data)
762 register struct ifnet *ifp;
763 u_long cmd;
764 caddr_t data;
765 {
766 struct le_softc *sc = lecd.cd_devs[ifp->if_unit];
767 struct ifaddr *ifa = (struct ifaddr *)data;
768 struct ifreq *ifr = (struct ifreq *)data;
769 int s, error = 0;
770
771 s = splimp();
772
773 switch (cmd) {
774
775 case SIOCSIFADDR:
776 ifp->if_flags |= IFF_UP;
777
778 switch (ifa->ifa_addr->sa_family) {
779 #ifdef INET
780 case AF_INET:
781 leinit(sc); /* before arpwhohas */
782 /*
783 * See if another station has *our* IP address.
784 * i.e.: There is an address conflict! If a
785 * conflict exists, a message is sent to the
786 * console.
787 */
788 sc->sc_ac.ac_ipaddr = IA_SIN(ifa)->sin_addr;
789 arpwhohas(&sc->sc_ac, &IA_SIN(ifa)->sin_addr);
790 break;
791 #endif
792 #ifdef NS
793 /* XXX - This code is probably wrong. */
794 case AF_NS:
795 {
796 register struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
797
798 if (ns_nullhost(*ina))
799 ina->x_host =
800 *(union ns_host *)(sc->sc_enaddr);
801 else
802 bcopy(ina->x_host.c_host,
803 sc->sc_enaddr,
804 sizeof(sc->sc_enaddr));
805 /* Set new address. */
806 leinit(sc);
807 break;
808 }
809 #endif
810 default:
811 leinit(sc);
812 break;
813 }
814 break;
815
816 case SIOCSIFFLAGS:
817 /*
818 * If interface is marked down and it is running, then stop it
819 */
820 if ((ifp->if_flags & IFF_UP) == 0 &&
821 (ifp->if_flags & IFF_RUNNING) != 0) {
822 /*
823 * If interface is marked down and it is running, then
824 * stop it.
825 */
826 lestop(sc);
827 ifp->if_flags &= ~IFF_RUNNING;
828 } else if ((ifp->if_flags & IFF_UP) != 0 &&
829 (ifp->if_flags & IFF_RUNNING) == 0) {
830 /*
831 * If interface is marked up and it is stopped, then
832 * start it.
833 */
834 leinit(sc);
835 } else {
836 /*
837 * Reset the interface to pick up changes in any other
838 * flags that affect hardware registers.
839 */
840 /*lestop(sc);*/
841 leinit(sc);
842 }
843 #ifdef LEDEBUG
844 if (ifp->if_flags & IFF_DEBUG)
845 sc->sc_debug = 1;
846 else
847 sc->sc_debug = 0;
848 #endif
849 break;
850
851 case SIOCADDMULTI:
852 case SIOCDELMULTI:
853 error = (cmd == SIOCADDMULTI) ?
854 ether_addmulti(ifr, &sc->sc_ac):
855 ether_delmulti(ifr, &sc->sc_ac);
856
857 if (error == ENETRESET) {
858 /*
859 * Multicast list has changed; set the hardware filter
860 * accordingly.
861 */
862 leinit(sc);
863 error = 0;
864 }
865 break;
866
867 default:
868 error = EINVAL;
869 }
870 (void) splx(s);
871 return error;
872 }
873
874 #ifdef LEDEBUG
875 void
876 recv_print(sc, no)
877 struct le_softc *sc;
878 int no;
879 {
880 struct mds *rmd;
881 int i, printed = 0;
882 u_short len;
883
884 rmd = &sc->sc_rd[no];
885 len = rmd->mcnt;
886 printf("%s: receive buffer %d, len = %d\n", sc->sc_dev.dv_xname, no,
887 len);
888 printf("%s: status %x\n", sc->sc_dev.dv_xname, lerdcsr(sc, 0));
889 for (i = 0; i < len; i++) {
890 if (!printed) {
891 printed = 1;
892 printf("%s: data: ", sc->sc_dev.dv_xname);
893 }
894 printf("%x ", *(sc->sc_rbuf + (BUFSIZE*no) + i));
895 }
896 if (printed)
897 printf("\n");
898 }
899
900 void
901 xmit_print(sc, no)
902 struct le_softc *sc;
903 int no;
904 {
905 struct mds *rmd;
906 int i, printed=0;
907 u_short len;
908
909 rmd = &sc->sc_td[no];
910 len = -rmd->bcnt;
911 printf("%s: transmit buffer %d, len = %d\n", sc->sc_dev.dv_xname, no,
912 len);
913 printf("%s: status %x\n", sc->sc_dev.dv_xname, lerdcsr(sc, 0));
914 printf("%s: addr %x, flags %x, bcnt %x, mcnt %x\n",
915 sc->sc_dev.dv_xname, rmd->addr, rmd->flags, rmd->bcnt, rmd->mcnt);
916 for (i = 0; i < len; i++) {
917 if (!printed) {
918 printed = 1;
919 printf("%s: data: ", sc->sc_dev.dv_xname);
920 }
921 printf("%x ", *(sc->sc_tbuf + (BUFSIZE*no) + i));
922 }
923 if (printed)
924 printf("\n");
925 }
926 #endif /* LEDEBUG */
927
928 /*
929 * Set up the logical address filter.
930 */
931 void
932 lesetladrf(ac, af)
933 struct arpcom *ac;
934 u_long *af;
935 {
936 struct ifnet *ifp = &ac->ac_if;
937 struct ether_multi *enm;
938 register u_char *cp, c;
939 register u_long crc;
940 register int i, len;
941 struct ether_multistep step;
942
943 /*
944 * Set up multicast address filter by passing all multicast addresses
945 * through a crc generator, and then using the high order 6 bits as an
946 * index into the 64 bit logical address filter. The high order bit
947 * selects the word, while the rest of the bits select the bit within
948 * the word.
949 */
950
951 if (ifp->if_flags & IFF_PROMISC) {
952 ifp->if_flags |= IFF_ALLMULTI;
953 af[0] = af[1] = 0xffffffff;
954 return;
955 }
956
957 af[0] = af[1] = 0;
958 ETHER_FIRST_MULTI(step, ac, enm);
959 while (enm != NULL) {
960 if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
961 sizeof(enm->enm_addrlo)) != 0) {
962 /*
963 * We must listen to a range of multicast addresses.
964 * For now, just accept all multicasts, rather than
965 * trying to set only those filter bits needed to match
966 * the range. (At this time, the only use of address
967 * ranges is for IP multicast routing, for which the
968 * range is big enough to require all bits set.)
969 */
970 ifp->if_flags |= IFF_ALLMULTI;
971 af[0] = af[1] = 0xffffffff;
972 return;
973 }
974
975 cp = enm->enm_addrlo;
976 crc = 0xffffffff;
977 for (len = sizeof(enm->enm_addrlo); --len >= 0;) {
978 c = *cp++;
979 for (i = 8; --i >= 0;) {
980 if ((crc & 0x01) ^ (c & 0x01)) {
981 crc >>= 1;
982 crc ^= 0x6db88320 | 0x80000000;
983 } else
984 crc >>= 1;
985 c >>= 1;
986 }
987 }
988 /* Just want the 6 most significant bits. */
989 crc >>= 26;
990
991 /* Turn on the corresponding bit in the filter. */
992 af[crc >> 5] |= 1 << ((crc & 0x1f) ^ 0);
993
994 ETHER_NEXT_MULTI(step, enm);
995 }
996 ifp->if_flags &= ~IFF_ALLMULTI;
997 }
998