am7990.c revision 1.11 1 /* $NetBSD: am7990.c,v 1.11 1996/03/14 19:05:07 christos Exp $ */
2
3 /*-
4 * Copyright (c) 1995 Charles M. Hannum. All rights reserved.
5 * Copyright (c) 1992, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Ralph Campbell and Rick Macklem.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
39 * @(#)if_le.c 8.2 (Berkeley) 11/16/93
40 */
41
42 #include <sys/ioctl.h>
43 #include <sys/errno.h>
44
45 #ifdef INET
46 #include <netinet/in_systm.h>
47 #include <netinet/in_var.h>
48 #include <netinet/ip.h>
49 #endif
50
51 #ifdef NS
52 #include <netns/ns.h>
53 #include <netns/ns_if.h>
54 #endif
55
56 #if defined(CCITT) && defined(LLC)
57 #include <sys/socketvar.h>
58 #include <netccitt/x25.h>
59 #include <netccitt/pk.h>
60 #include <netccitt/pk_var.h>
61 #include <netccitt/pk_extern.h>
62 #endif
63
64 #if NBPFILTER > 0
65 #include <net/bpf.h>
66 #include <net/bpfdesc.h>
67 #endif
68
69 #ifdef LEDEBUG
70 void recv_print __P((struct le_softc *, int));
71 void xmit_print __P((struct le_softc *, int));
72 #endif
73
74 #define ifp (&sc->sc_arpcom.ac_if)
75
76 void
77 leconfig(sc)
78 struct le_softc *sc;
79 {
80 int mem;
81
82 /* Make sure the chip is stopped. */
83 lestop(sc);
84
85 /* Initialize ifnet structure. */
86 ifp->if_unit = sc->sc_dev.dv_unit;
87 ifp->if_start = lestart;
88 ifp->if_ioctl = leioctl;
89 ifp->if_watchdog = lewatchdog;
90 ifp->if_flags =
91 IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
92 #ifdef LANCE_REVC_BUG
93 ifp->if_flags &= ~IFF_MULTICAST;
94 #endif
95
96 /* Attach the interface. */
97 if_attach(ifp);
98 ether_ifattach(ifp);
99
100 #if NBPFILTER > 0
101 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
102 #endif
103
104 switch (sc->sc_memsize) {
105 case 8192:
106 sc->sc_nrbuf = 4;
107 sc->sc_ntbuf = 1;
108 break;
109 case 16384:
110 sc->sc_nrbuf = 8;
111 sc->sc_ntbuf = 2;
112 break;
113 case 32768:
114 sc->sc_nrbuf = 16;
115 sc->sc_ntbuf = 4;
116 break;
117 case 65536:
118 sc->sc_nrbuf = 32;
119 sc->sc_ntbuf = 8;
120 break;
121 default:
122 panic("leconfig: weird memory size");
123 }
124
125 printf(": address %s\n%s: %d receive buffers, %d transmit buffers\n",
126 ether_sprintf(sc->sc_arpcom.ac_enaddr),
127 sc->sc_dev.dv_xname, sc->sc_nrbuf, sc->sc_ntbuf);
128
129 mem = 0;
130 sc->sc_initaddr = mem;
131 mem += sizeof(struct leinit);
132 sc->sc_rmdaddr = mem;
133 mem += sizeof(struct lermd) * sc->sc_nrbuf;
134 sc->sc_tmdaddr = mem;
135 mem += sizeof(struct letmd) * sc->sc_ntbuf;
136 sc->sc_rbufaddr = mem;
137 mem += LEBLEN * sc->sc_nrbuf;
138 sc->sc_tbufaddr = mem;
139 mem += LEBLEN * sc->sc_ntbuf;
140 #ifdef notyet
141 if (mem > ...)
142 panic(...);
143 #endif
144 }
145
146 void
147 lereset(sc)
148 struct le_softc *sc;
149 {
150 int s;
151
152 s = splimp();
153 leinit(sc);
154 splx(s);
155 }
156
157 void
158 lewatchdog(unit)
159 int unit;
160 {
161 struct le_softc *sc = LE_SOFTC(unit);
162
163 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
164 ++ifp->if_oerrors;
165
166 lereset(sc);
167 }
168
169 /*
170 * Set up the initialization block and the descriptor rings.
171 */
172 void
173 lememinit(sc)
174 register struct le_softc *sc;
175 {
176 u_long a;
177 int bix;
178 struct leinit init;
179 struct lermd rmd;
180 struct letmd tmd;
181
182 #if NBPFILTER > 0
183 if (ifp->if_flags & IFF_PROMISC)
184 init.init_mode = LE_MODE_NORMAL | LE_MODE_PROM;
185 else
186 #endif
187 init.init_mode = LE_MODE_NORMAL;
188 init.init_padr[0] =
189 (sc->sc_arpcom.ac_enaddr[1] << 8) | sc->sc_arpcom.ac_enaddr[0];
190 init.init_padr[1] =
191 (sc->sc_arpcom.ac_enaddr[3] << 8) | sc->sc_arpcom.ac_enaddr[2];
192 init.init_padr[2] =
193 (sc->sc_arpcom.ac_enaddr[5] << 8) | sc->sc_arpcom.ac_enaddr[4];
194 lesetladrf(&sc->sc_arpcom, init.init_ladrf);
195
196 sc->sc_last_rd = 0;
197 sc->sc_first_td = sc->sc_last_td = sc->sc_no_td = 0;
198
199 a = sc->sc_addr + LE_RMDADDR(sc, 0);
200 init.init_rdra = a;
201 init.init_rlen = (a >> 16) | ((ffs(sc->sc_nrbuf) - 1) << 13);
202
203 a = sc->sc_addr + LE_TMDADDR(sc, 0);
204 init.init_tdra = a;
205 init.init_tlen = (a >> 16) | ((ffs(sc->sc_ntbuf) - 1) << 13);
206
207 (*sc->sc_copytodesc)(sc, &init, LE_INITADDR(sc), sizeof(init));
208
209 /*
210 * Set up receive ring descriptors.
211 */
212 for (bix = 0; bix < sc->sc_nrbuf; bix++) {
213 a = sc->sc_addr + LE_RBUFADDR(sc, bix);
214 rmd.rmd0 = a;
215 rmd.rmd1_hadr = a >> 16;
216 rmd.rmd1_bits = LE_R1_OWN;
217 rmd.rmd2 = -LEBLEN | LE_XMD2_ONES;
218 rmd.rmd3 = 0;
219 (*sc->sc_copytodesc)(sc, &rmd, LE_RMDADDR(sc, bix),
220 sizeof(rmd));
221 }
222
223 /*
224 * Set up transmit ring descriptors.
225 */
226 for (bix = 0; bix < sc->sc_ntbuf; bix++) {
227 a = sc->sc_addr + LE_TBUFADDR(sc, bix);
228 tmd.tmd0 = a;
229 tmd.tmd1_hadr = a >> 16;
230 tmd.tmd1_bits = 0;
231 tmd.tmd2 = 0 | LE_XMD2_ONES;
232 tmd.tmd3 = 0;
233 (*sc->sc_copytodesc)(sc, &tmd, LE_TMDADDR(sc, bix),
234 sizeof(tmd));
235 }
236 }
237
238 void
239 lestop(sc)
240 struct le_softc *sc;
241 {
242
243 lewrcsr(sc, LE_CSR0, LE_C0_STOP);
244 }
245
246 /*
247 * Initialization of interface; set up initialization block
248 * and transmit/receive descriptor rings.
249 */
250 void
251 leinit(sc)
252 register struct le_softc *sc;
253 {
254 register int timo;
255 u_long a;
256
257 lewrcsr(sc, LE_CSR0, LE_C0_STOP);
258 LE_DELAY(100);
259
260 /* Set the correct byte swapping mode, etc. */
261 lewrcsr(sc, LE_CSR3, sc->sc_conf3);
262
263 /* Set up LANCE init block. */
264 lememinit(sc);
265
266 /* Give LANCE the physical address of its init block. */
267 a = sc->sc_addr + LE_INITADDR(sc);
268 lewrcsr(sc, LE_CSR1, a);
269 lewrcsr(sc, LE_CSR2, a >> 16);
270
271 /* Try to initialize the LANCE. */
272 LE_DELAY(100);
273 lewrcsr(sc, LE_CSR0, LE_C0_INIT);
274
275 /* Wait for initialization to finish. */
276 for (timo = 100000; timo; timo--)
277 if (lerdcsr(sc, LE_CSR0) & LE_C0_IDON)
278 break;
279
280 if (lerdcsr(sc, LE_CSR0) & LE_C0_IDON) {
281 /* Start the LANCE. */
282 lewrcsr(sc, LE_CSR0, LE_C0_INEA | LE_C0_STRT | LE_C0_IDON);
283 ifp->if_flags |= IFF_RUNNING;
284 ifp->if_flags &= ~IFF_OACTIVE;
285 ifp->if_timer = 0;
286 lestart(ifp);
287 } else
288 printf("%s: card failed to initialize\n", sc->sc_dev.dv_xname);
289 }
290
291 /*
292 * Routine to copy from mbuf chain to transmit buffer in
293 * network buffer memory.
294 */
295 integrate int
296 leput(sc, boff, m)
297 struct le_softc *sc;
298 int boff;
299 register struct mbuf *m;
300 {
301 register struct mbuf *n;
302 register int len, tlen = 0;
303
304 for (; m; m = n) {
305 len = m->m_len;
306 if (len == 0) {
307 MFREE(m, n);
308 continue;
309 }
310 (*sc->sc_copytobuf)(sc, mtod(m, caddr_t), boff, len);
311 boff += len;
312 tlen += len;
313 MFREE(m, n);
314 }
315 if (tlen < LEMINSIZE) {
316 (*sc->sc_zerobuf)(sc, boff, LEMINSIZE - tlen);
317 tlen = LEMINSIZE;
318 }
319 return (tlen);
320 }
321
322 /*
323 * Pull data off an interface.
324 * Len is length of data, with local net header stripped.
325 * We copy the data into mbufs. When full cluster sized units are present
326 * we copy into clusters.
327 */
328 integrate struct mbuf *
329 leget(sc, boff, totlen)
330 struct le_softc *sc;
331 int boff, totlen;
332 {
333 register struct mbuf *m;
334 struct mbuf *top, **mp;
335 int len, pad;
336
337 MGETHDR(m, M_DONTWAIT, MT_DATA);
338 if (m == 0)
339 return (0);
340 m->m_pkthdr.rcvif = ifp;
341 m->m_pkthdr.len = totlen;
342 pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header);
343 m->m_data += pad;
344 len = MHLEN - pad;
345 top = 0;
346 mp = ⊤
347
348 while (totlen > 0) {
349 if (top) {
350 MGET(m, M_DONTWAIT, MT_DATA);
351 if (m == 0) {
352 m_freem(top);
353 return 0;
354 }
355 len = MLEN;
356 }
357 if (top && totlen >= MINCLSIZE) {
358 MCLGET(m, M_DONTWAIT);
359 if (m->m_flags & M_EXT)
360 len = MCLBYTES;
361 }
362 m->m_len = len = min(totlen, len);
363 (*sc->sc_copyfrombuf)(sc, mtod(m, caddr_t), boff, len);
364 boff += len;
365 totlen -= len;
366 *mp = m;
367 mp = &m->m_next;
368 }
369
370 return (top);
371 }
372
373 /*
374 * Pass a packet to the higher levels.
375 */
376 integrate void
377 leread(sc, boff, len)
378 register struct le_softc *sc;
379 int boff, len;
380 {
381 struct mbuf *m;
382 struct ether_header *eh;
383
384 if (len <= sizeof(struct ether_header) ||
385 len > ETHERMTU + sizeof(struct ether_header)) {
386 #ifdef LEDEBUG
387 printf("%s: invalid packet size %d; dropping\n",
388 sc->sc_dev.dv_xname, len);
389 #endif
390 ifp->if_ierrors++;
391 return;
392 }
393
394 /* Pull packet off interface. */
395 m = leget(sc, boff, len);
396 if (m == 0) {
397 ifp->if_ierrors++;
398 return;
399 }
400
401 ifp->if_ipackets++;
402
403 /* We assume that the header fit entirely in one mbuf. */
404 eh = mtod(m, struct ether_header *);
405
406 #if NBPFILTER > 0
407 /*
408 * Check if there's a BPF listener on this interface.
409 * If so, hand off the raw packet to BPF.
410 */
411 if (ifp->if_bpf) {
412 bpf_mtap(ifp->if_bpf, m);
413
414 #ifndef LANCE_REVC_BUG
415 /*
416 * Note that the interface cannot be in promiscuous mode if
417 * there are no BPF listeners. And if we are in promiscuous
418 * mode, we have to check if this packet is really ours.
419 */
420 if ((ifp->if_flags & IFF_PROMISC) != 0 &&
421 (eh->ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */
422 bcmp(eh->ether_dhost, sc->sc_arpcom.ac_enaddr,
423 sizeof(eh->ether_dhost)) != 0) {
424 m_freem(m);
425 return;
426 }
427 #endif
428 }
429 #endif
430
431 #ifdef LANCE_REVC_BUG
432 if (bcmp(eh->ether_dhost, sc->sc_arpcom.ac_enaddr,
433 sizeof(eh->ether_dhost)) != 0 &&
434 bcmp(eh->ether_dhost, etherbroadcastaddr,
435 sizeof(eh->ether_dhost)) != 0) {
436 m_freem(m);
437 return;
438 }
439 #endif
440
441 /* Pass the packet up, with the ether header sort-of removed. */
442 m_adj(m, sizeof(struct ether_header));
443 ether_input(ifp, eh, m);
444 }
445
446 integrate void
447 lerint(sc)
448 struct le_softc *sc;
449 {
450 register int bix;
451 int rp;
452 struct lermd rmd;
453
454 bix = sc->sc_last_rd;
455
456 /* Process all buffers with valid data. */
457 for (;;) {
458 rp = LE_RMDADDR(sc, bix);
459 (*sc->sc_copyfromdesc)(sc, &rmd, rp, sizeof(rmd));
460
461 if (rmd.rmd1_bits & LE_R1_OWN)
462 break;
463
464 if (rmd.rmd1_bits & LE_R1_ERR) {
465 if (rmd.rmd1_bits & LE_R1_ENP) {
466 #ifdef LEDEBUG
467 if ((rmd.rmd1_bits & LE_R1_OFLO) == 0) {
468 if (rmd.rmd1_bits & LE_R1_FRAM)
469 printf("%s: framing error\n",
470 sc->sc_dev.dv_xname);
471 if (rmd.rmd1_bits & LE_R1_CRC)
472 printf("%s: crc mismatch\n",
473 sc->sc_dev.dv_xname);
474 }
475 #endif
476 } else {
477 if (rmd.rmd1_bits & LE_R1_OFLO)
478 printf("%s: overflow\n",
479 sc->sc_dev.dv_xname);
480 }
481 if (rmd.rmd1_bits & LE_R1_BUFF)
482 printf("%s: receive buffer error\n",
483 sc->sc_dev.dv_xname);
484 ifp->if_ierrors++;
485 } else if (rmd.rmd1_bits & (LE_R1_STP | LE_R1_ENP) !=
486 (LE_R1_STP | LE_R1_ENP)) {
487 printf("%s: dropping chained buffer\n",
488 sc->sc_dev.dv_xname);
489 ifp->if_ierrors++;
490 } else {
491 #ifdef LEDEBUG
492 if (sc->sc_debug)
493 recv_print(sc, sc->sc_last_rd);
494 #endif
495 leread(sc, LE_RBUFADDR(sc, bix), (int)rmd.rmd3 - 4);
496 }
497
498 rmd.rmd1_bits = LE_R1_OWN;
499 rmd.rmd2 = -LEBLEN | LE_XMD2_ONES;
500 rmd.rmd3 = 0;
501 (*sc->sc_copytodesc)(sc, &rmd, rp, sizeof(rmd));
502
503 #ifdef LEDEBUG
504 if (sc->sc_debug)
505 printf("sc->sc_last_rd = %x, rmd = %x\n",
506 sc->sc_last_rd, rmd);
507 #endif
508
509 if (++bix == sc->sc_nrbuf)
510 bix = 0;
511 }
512
513 sc->sc_last_rd = bix;
514 }
515
516 integrate void
517 letint(sc)
518 register struct le_softc *sc;
519 {
520 register int bix;
521 struct letmd tmd;
522
523 bix = sc->sc_first_td;
524
525 for (;;) {
526 if (sc->sc_no_td <= 0)
527 break;
528
529 #ifdef LEDEBUG
530 if (sc->sc_debug)
531 printf("trans tmd = %x\n", tmd);
532 #endif
533
534 (*sc->sc_copyfromdesc)(sc, &tmd, LE_TMDADDR(sc, bix),
535 sizeof(tmd));
536
537 if (tmd.tmd1_bits & LE_T1_OWN)
538 break;
539
540 ifp->if_flags &= ~IFF_OACTIVE;
541
542 if (tmd.tmd1_bits & LE_T1_ERR) {
543 if (tmd.tmd3 & LE_T3_BUFF)
544 printf("%s: transmit buffer error\n", sc->sc_dev.dv_xname);
545 else if (tmd.tmd3 & LE_T3_UFLO)
546 printf("%s: underflow\n", sc->sc_dev.dv_xname);
547 if (tmd.tmd3 & (LE_T3_BUFF | LE_T3_UFLO)) {
548 lereset(sc);
549 return;
550 }
551 if (tmd.tmd3 & LE_T3_LCAR)
552 printf("%s: lost carrier\n", sc->sc_dev.dv_xname);
553 if (tmd.tmd3 & LE_T3_LCOL)
554 ifp->if_collisions++;
555 if (tmd.tmd3 & LE_T3_RTRY) {
556 printf("%s: excessive collisions, tdr %d\n",
557 sc->sc_dev.dv_xname, tmd.tmd3 & LE_T3_TDR_MASK);
558 ifp->if_collisions += 16;
559 }
560 ifp->if_oerrors++;
561 } else {
562 if (tmd.tmd1_bits & LE_T1_ONE)
563 ifp->if_collisions++;
564 else if (tmd.tmd1_bits & LE_T1_MORE)
565 /* Real number is unknown. */
566 ifp->if_collisions += 2;
567 ifp->if_opackets++;
568 }
569
570 if (++bix == sc->sc_ntbuf)
571 bix = 0;
572
573 --sc->sc_no_td;
574 }
575
576 sc->sc_first_td = bix;
577
578 lestart(ifp);
579
580 if (sc->sc_no_td == 0)
581 ifp->if_timer = 0;
582 }
583
584 /*
585 * Controller interrupt.
586 */
587 int
588 leintr(arg)
589 register void *arg;
590 {
591 register struct le_softc *sc = arg;
592 register u_int16_t isr;
593
594 isr = lerdcsr(sc, LE_CSR0);
595 #ifdef LEDEBUG
596 if (sc->sc_debug)
597 printf("%s: leintr entering with isr=%04x\n",
598 sc->sc_dev.dv_xname, isr);
599 #endif
600 if ((isr & LE_C0_INTR) == 0)
601 return (0);
602
603 lewrcsr(sc, LE_CSR0,
604 isr & (LE_C0_INEA | LE_C0_BABL | LE_C0_MISS | LE_C0_MERR |
605 LE_C0_RINT | LE_C0_TINT | LE_C0_IDON));
606 if (isr & LE_C0_ERR) {
607 if (isr & LE_C0_BABL) {
608 #ifdef LEDEBUG
609 printf("%s: babble\n", sc->sc_dev.dv_xname);
610 #endif
611 ifp->if_oerrors++;
612 }
613 #if 0
614 if (isr & LE_C0_CERR) {
615 printf("%s: collision error\n", sc->sc_dev.dv_xname);
616 ifp->if_collisions++;
617 }
618 #endif
619 if (isr & LE_C0_MISS) {
620 #ifdef LEDEBUG
621 printf("%s: missed packet\n", sc->sc_dev.dv_xname);
622 #endif
623 ifp->if_ierrors++;
624 }
625 if (isr & LE_C0_MERR) {
626 printf("%s: memory error\n", sc->sc_dev.dv_xname);
627 lereset(sc);
628 return (1);
629 }
630 }
631
632 if ((isr & LE_C0_RXON) == 0) {
633 printf("%s: receiver disabled\n", sc->sc_dev.dv_xname);
634 ifp->if_ierrors++;
635 lereset(sc);
636 return (1);
637 }
638 if ((isr & LE_C0_TXON) == 0) {
639 printf("%s: transmitter disabled\n", sc->sc_dev.dv_xname);
640 ifp->if_oerrors++;
641 lereset(sc);
642 return (1);
643 }
644
645 if (isr & LE_C0_RINT)
646 lerint(sc);
647 if (isr & LE_C0_TINT)
648 letint(sc);
649
650 return (1);
651 }
652
653 #undef ifp
654
655 /*
656 * Setup output on interface.
657 * Get another datagram to send off of the interface queue, and map it to the
658 * interface before starting the output.
659 * Called only at splimp or interrupt level.
660 */
661 void
662 lestart(ifp)
663 register struct ifnet *ifp;
664 {
665 register struct le_softc *sc = LE_SOFTC(ifp->if_unit);
666 register int bix;
667 register struct mbuf *m;
668 struct letmd tmd;
669 int rp;
670 int len;
671
672 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
673 return;
674
675 bix = sc->sc_last_td;
676
677 for (;;) {
678 rp = LE_TMDADDR(sc, bix);
679 (*sc->sc_copyfromdesc)(sc, &tmd, rp, sizeof(tmd));
680
681 if (tmd.tmd1_bits & LE_T1_OWN) {
682 ifp->if_flags |= IFF_OACTIVE;
683 printf("missing buffer, no_td = %d, last_td = %d\n",
684 sc->sc_no_td, sc->sc_last_td);
685 }
686
687 IF_DEQUEUE(&ifp->if_snd, m);
688 if (m == 0)
689 break;
690
691 #if NBPFILTER > 0
692 /*
693 * If BPF is listening on this interface, let it see the packet
694 * before we commit it to the wire.
695 */
696 if (ifp->if_bpf)
697 bpf_mtap(ifp->if_bpf, m);
698 #endif
699
700 /*
701 * Copy the mbuf chain into the transmit buffer.
702 */
703 len = leput(sc, LE_TBUFADDR(sc, bix), m);
704
705 #ifdef LEDEBUG
706 if (len > ETHERMTU + sizeof(struct ether_header))
707 printf("packet length %d\n", len);
708 #endif
709
710 ifp->if_timer = 5;
711
712 /*
713 * Init transmit registers, and set transmit start flag.
714 */
715 tmd.tmd1_bits = LE_T1_OWN | LE_T1_STP | LE_T1_ENP;
716 tmd.tmd2 = -len | LE_XMD2_ONES;
717 tmd.tmd3 = 0;
718
719 (*sc->sc_copytodesc)(sc, &tmd, rp, sizeof(tmd));
720
721 #ifdef LEDEBUG
722 if (sc->sc_debug)
723 xmit_print(sc, sc->sc_last_td);
724 #endif
725
726 lewrcsr(sc, LE_CSR0, LE_C0_INEA | LE_C0_TDMD);
727
728 if (++bix == sc->sc_ntbuf)
729 bix = 0;
730
731 if (++sc->sc_no_td == sc->sc_ntbuf) {
732 ifp->if_flags |= IFF_OACTIVE;
733 break;
734 }
735
736 }
737
738 sc->sc_last_td = bix;
739 }
740
741 /*
742 * Process an ioctl request.
743 */
744 int
745 leioctl(ifp, cmd, data)
746 register struct ifnet *ifp;
747 u_long cmd;
748 caddr_t data;
749 {
750 struct le_softc *sc = LE_SOFTC(ifp->if_unit);
751 struct ifaddr *ifa = (struct ifaddr *)data;
752 struct ifreq *ifr = (struct ifreq *)data;
753 int s, error = 0;
754
755 s = splimp();
756
757 switch (cmd) {
758
759 case SIOCSIFADDR:
760 ifp->if_flags |= IFF_UP;
761
762 switch (ifa->ifa_addr->sa_family) {
763 #ifdef INET
764 case AF_INET:
765 leinit(sc);
766 arp_ifinit(&sc->sc_arpcom, ifa);
767 break;
768 #endif
769 #ifdef NS
770 case AF_NS:
771 {
772 register struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
773
774 if (ns_nullhost(*ina))
775 ina->x_host =
776 *(union ns_host *)(sc->sc_arpcom.ac_enaddr);
777 else
778 bcopy(ina->x_host.c_host,
779 sc->sc_arpcom.ac_enaddr,
780 sizeof(sc->sc_arpcom.ac_enaddr));
781 /* Set new address. */
782 leinit(sc);
783 break;
784 }
785 #endif
786 default:
787 leinit(sc);
788 break;
789 }
790 break;
791
792 #if defined(CCITT) && defined(LLC)
793 case SIOCSIFCONF_X25:
794 ifp->if_flags |= IFF_UP;
795 ifa->ifa_rtrequest = cons_rtrequest; /* XXX */
796 error = x25_llcglue(PRC_IFUP, ifa->ifa_addr);
797 if (error == 0)
798 leinit(sc);
799 break;
800 #endif /* CCITT && LLC */
801
802 case SIOCSIFFLAGS:
803 if ((ifp->if_flags & IFF_UP) == 0 &&
804 (ifp->if_flags & IFF_RUNNING) != 0) {
805 /*
806 * If interface is marked down and it is running, then
807 * stop it.
808 */
809 lestop(sc);
810 ifp->if_flags &= ~IFF_RUNNING;
811 } else if ((ifp->if_flags & IFF_UP) != 0 &&
812 (ifp->if_flags & IFF_RUNNING) == 0) {
813 /*
814 * If interface is marked up and it is stopped, then
815 * start it.
816 */
817 leinit(sc);
818 } else {
819 /*
820 * Reset the interface to pick up changes in any other
821 * flags that affect hardware registers.
822 */
823 /*lestop(sc);*/
824 leinit(sc);
825 }
826 #ifdef LEDEBUG
827 if (ifp->if_flags & IFF_DEBUG)
828 sc->sc_debug = 1;
829 else
830 sc->sc_debug = 0;
831 #endif
832 break;
833
834 case SIOCADDMULTI:
835 case SIOCDELMULTI:
836 error = (cmd == SIOCADDMULTI) ?
837 ether_addmulti(ifr, &sc->sc_arpcom) :
838 ether_delmulti(ifr, &sc->sc_arpcom);
839
840 if (error == ENETRESET) {
841 /*
842 * Multicast list has changed; set the hardware filter
843 * accordingly.
844 */
845 lereset(sc);
846 error = 0;
847 }
848 break;
849
850 default:
851 error = EINVAL;
852 break;
853 }
854
855 splx(s);
856 return (error);
857 }
858
859 #ifdef LEDEBUG
860 void
861 recv_print(sc, no)
862 struct le_softc *sc;
863 int no;
864 {
865 struct lermd rmd;
866 u_int16_t len;
867 struct ether_header eh;
868
869 (*sc->sc_copyfromdesc)(sc, &rmd, LE_RMDADDR(sc, no), sizeof(rmd));
870 len = rmd.rmd3;
871 printf("%s: receive buffer %d, len = %d\n", sc->sc_dev.dv_xname, no,
872 len);
873 printf("%s: status %04x\n", sc->sc_dev.dv_xname, lerdcsr(sc, LE_CSR0));
874 printf("%s: ladr %04x, hadr %02x, flags %02x, bcnt %04x, mcnt %04x\n",
875 sc->sc_dev.dv_xname,
876 rmd.rmd0, rmd.rmd1_hadr, rmd.rmd1_bits, rmd.rmd2, rmd.rmd3);
877 if (len >= sizeof(eh)) {
878 (*sc->sc_copyfrombuf)(sc, &eh, LE_RBUFADDR(sc, no), sizeof(eh));
879 printf("%s: dst %s", ether_sprintf(eh.ether_dhost));
880 printf(" src %s type %04x\n", ether_sprintf(eh.ether_shost),
881 ntohs(eh.ether_type));
882 }
883 }
884
885 void
886 xmit_print(sc, no)
887 struct le_softc *sc;
888 int no;
889 {
890 struct letmd tmd;
891 u_int16_t len;
892 struct ether_header eh;
893
894 (*sc->sc_copyfromdesc)(sc, &tmd, LE_TMDADDR(sc, no), sizeof(tmd));
895 len = -tmd.tmd2;
896 printf("%s: transmit buffer %d, len = %d\n", sc->sc_dev.dv_xname, no,
897 len);
898 printf("%s: status %04x\n", sc->sc_dev.dv_xname, lerdcsr(sc, LE_CSR0));
899 printf("%s: ladr %04x, hadr %02x, flags %02x, bcnt %04x, mcnt %04x\n",
900 sc->sc_dev.dv_xname,
901 tmd.tmd0, tmd.tmd1_hadr, tmd.tmd1_bits, tmd.tmd2, tmd.tmd3);
902 if (len >= sizeof(eh)) {
903 (*sc->sc_copyfrombuf)(sc, &eh, LE_TBUFADDR(sc, no), sizeof(eh));
904 printf("%s: dst %s", ether_sprintf(eh.ether_dhost));
905 printf(" src %s type %04x\n", ether_sprintf(eh.ether_shost),
906 ntohs(eh.ether_type));
907 }
908 }
909 #endif /* LEDEBUG */
910
911 /*
912 * Set up the logical address filter.
913 */
914 void
915 lesetladrf(ac, af)
916 struct arpcom *ac;
917 u_int16_t *af;
918 {
919 struct ifnet *ifp = &ac->ac_if;
920 struct ether_multi *enm;
921 register u_char *cp, c;
922 register u_int32_t crc;
923 register int i, len;
924 struct ether_multistep step;
925
926 /*
927 * Set up multicast address filter by passing all multicast addresses
928 * through a crc generator, and then using the high order 6 bits as an
929 * index into the 64 bit logical address filter. The high order bit
930 * selects the word, while the rest of the bits select the bit within
931 * the word.
932 */
933
934 if (ifp->if_flags & IFF_PROMISC)
935 goto allmulti;
936
937 af[0] = af[1] = af[2] = af[3] = 0x0000;
938 ETHER_FIRST_MULTI(step, ac, enm);
939 while (enm != NULL) {
940 if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
941 sizeof(enm->enm_addrlo)) != 0) {
942 /*
943 * We must listen to a range of multicast addresses.
944 * For now, just accept all multicasts, rather than
945 * trying to set only those filter bits needed to match
946 * the range. (At this time, the only use of address
947 * ranges is for IP multicast routing, for which the
948 * range is big enough to require all bits set.)
949 */
950 goto allmulti;
951 }
952
953 cp = enm->enm_addrlo;
954 crc = 0xffffffff;
955 for (len = sizeof(enm->enm_addrlo); --len >= 0;) {
956 c = *cp++;
957 for (i = 8; --i >= 0;) {
958 if ((crc & 0x01) ^ (c & 0x01)) {
959 crc >>= 1;
960 crc ^= 0xedb88320;
961 } else
962 crc >>= 1;
963 c >>= 1;
964 }
965 }
966 /* Just want the 6 most significant bits. */
967 crc >>= 26;
968
969 /* Set the corresponding bit in the filter. */
970 af[crc >> 4] |= 1 << (crc & 0xf);
971
972 ETHER_NEXT_MULTI(step, enm);
973 }
974 ifp->if_flags &= ~IFF_ALLMULTI;
975 return;
976
977 allmulti:
978 ifp->if_flags |= IFF_ALLMULTI;
979 af[0] = af[1] = af[2] = af[3] = 0xffff;
980 }
981
982
983 /*
984 * Routines for accessing the transmit and receive buffers.
985 * The various CPU and adapter configurations supported by this
986 * driver require three different access methods for buffers
987 * and descriptors:
988 * (1) contig (contiguous data; no padding),
989 * (2) gap2 (two bytes of data followed by two bytes of padding),
990 * (3) gap16 (16 bytes of data followed by 16 bytes of padding).
991 */
992
993 #ifdef LE_NEED_BUF_CONTIG
994 /*
995 * contig: contiguous data with no padding.
996 *
997 * Buffers may have any alignment.
998 */
999
1000 integrate void
1001 copytobuf_contig(sc, from, boff, len)
1002 struct le_softc *sc;
1003 void *from;
1004 int boff, len;
1005 {
1006 volatile caddr_t buf = sc->sc_mem;
1007
1008 /*
1009 * Just call bcopy() to do the work.
1010 */
1011 bcopy(from, buf + boff, len);
1012 }
1013
1014 integrate void
1015 copyfrombuf_contig(sc, to, boff, len)
1016 struct le_softc *sc;
1017 void *to;
1018 int boff, len;
1019 {
1020 volatile caddr_t buf = sc->sc_mem;
1021
1022 /*
1023 * Just call bcopy() to do the work.
1024 */
1025 bcopy(buf + boff, to, len);
1026 }
1027
1028 integrate void
1029 zerobuf_contig(sc, boff, len)
1030 struct le_softc *sc;
1031 int boff, len;
1032 {
1033 volatile caddr_t buf = sc->sc_mem;
1034
1035 /*
1036 * Just let bzero() do the work
1037 */
1038 bzero(buf + boff, len);
1039 }
1040 #endif /* LE_NEED_BUF_CONTIG */
1041
1042 #ifdef LE_NEED_BUF_GAP2
1043 /*
1044 * gap2: two bytes of data followed by two bytes of pad.
1045 *
1046 * Buffers must be 4-byte aligned. The code doesn't worry about
1047 * doing an extra byte.
1048 */
1049
1050 integrate void
1051 copytobuf_gap2(sc, fromv, boff, len)
1052 struct le_softc *sc;
1053 void *fromv;
1054 int boff;
1055 register int len;
1056 {
1057 volatile caddr_t buf = sc->sc_mem;
1058 register caddr_t from = fromv;
1059 register volatile u_int16_t *bptr;
1060 register int xfer;
1061
1062 if (boff & 0x1) {
1063 /* handle unaligned first byte */
1064 bptr = ((volatile u_int16_t *)buf) + (boff - 1);
1065 *bptr = (*from++ << 8) | (*bptr & 0xff);
1066 bptr += 2;
1067 len--;
1068 } else
1069 bptr = ((volatile u_int16_t *)buf) + boff;
1070 while (len > 1) {
1071 *bptr = (from[1] << 8) | (from[0] & 0xff);
1072 bptr += 2;
1073 from += 2;
1074 len -= 2;
1075 }
1076 if (len == 1)
1077 *bptr = (u_int16_t)*from;
1078 }
1079
1080 integrate void
1081 copyfrombuf_gap2(sc, tov, boff, len)
1082 struct le_softc *sc;
1083 void *tov;
1084 int boff, len;
1085 {
1086 volatile caddr_t buf = sc->sc_mem;
1087 register caddr_t to = tov;
1088 register volatile u_int16_t *bptr;
1089 register u_int16_t tmp;
1090 register int xfer;
1091
1092 if (boff & 0x1) {
1093 /* handle unaligned first byte */
1094 bptr = ((volatile u_int16_t *)buf) + (boff - 1);
1095 *to++ = (*bptr >> 8) & 0xff;
1096 bptr += 2;
1097 len--;
1098 } else
1099 bptr = ((volatile u_int16_t *)buf) + boff;
1100 while (len > 1) {
1101 tmp = *bptr;
1102 *to++ = tmp & 0xff;
1103 *to++ = (tmp >> 8) & 0xff;
1104 bptr += 2;
1105 len -= 2;
1106 }
1107 if (len == 1)
1108 *to = *bptr & 0xff;
1109 }
1110
1111 integrate void
1112 zerobuf_gap2(sc, boff, len)
1113 struct le_softc *sc;
1114 int boff, len;
1115 {
1116 volatile caddr_t buf = sc->sc_mem;
1117 register volatile u_int16_t *bptr;
1118
1119 if ((unsigned)boff & 0x1) {
1120 bptr = ((volatile u_int16_t *)buf) + (boff - 1);
1121 *bptr &= 0xff;
1122 bptr += 2;
1123 len--;
1124 } else
1125 bptr = ((volatile u_int16_t *)buf) + boff;
1126 while (len > 0) {
1127 *bptr = 0;
1128 bptr += 2;
1129 len -= 2;
1130 }
1131 }
1132 #endif /* LE_NEED_BUF_GAP2 */
1133
1134 #ifdef LE_NEED_BUF_GAP16
1135 /*
1136 * gap16: 16 bytes of data followed by 16 bytes of pad.
1137 *
1138 * Buffers must be 32-byte aligned.
1139 */
1140
1141 integrate void
1142 copytobuf_gap16(sc, fromv, boff, len)
1143 struct le_softc *sc;
1144 void *fromv;
1145 int boff;
1146 register int len;
1147 {
1148 volatile caddr_t buf = sc->sc_mem;
1149 register caddr_t from = fromv;
1150 register caddr_t bptr;
1151 register int xfer;
1152
1153 bptr = buf + ((boff << 1) & ~0x1f);
1154 boff &= 0xf;
1155 xfer = min(len, 16 - boff);
1156 while (len > 0) {
1157 bcopy(from, bptr + boff, xfer);
1158 from += xfer;
1159 bptr += 32;
1160 boff = 0;
1161 len -= xfer;
1162 xfer = min(len, 16);
1163 }
1164 }
1165
1166 integrate void
1167 copyfrombuf_gap16(sc, tov, boff, len)
1168 struct le_softc *sc;
1169 void *tov;
1170 int boff, len;
1171 {
1172 volatile caddr_t buf = sc->sc_mem;
1173 register caddr_t to = tov;
1174 register caddr_t bptr;
1175 register int xfer;
1176
1177 bptr = buf + ((boff << 1) & ~0x1f);
1178 boff &= 0xf;
1179 xfer = min(len, 16 - boff);
1180 while (len > 0) {
1181 bcopy(bptr + boff, to, xfer);
1182 to += xfer;
1183 bptr += 32;
1184 boff = 0;
1185 len -= xfer;
1186 xfer = min(len, 16);
1187 }
1188 }
1189
1190 integrate void
1191 zerobuf_gap16(sc, boff, len)
1192 struct le_softc *sc;
1193 int boff, len;
1194 {
1195 volatile caddr_t buf = sc->sc_mem;
1196 register caddr_t bptr;
1197 register int xfer;
1198
1199 bptr = buf + ((boff << 1) & ~0x1f);
1200 boff &= 0xf;
1201 xfer = min(len, 16 - boff);
1202 while (len > 0) {
1203 bzero(bptr + boff, xfer);
1204 bptr += 32;
1205 boff = 0;
1206 len -= xfer;
1207 xfer = min(len, 16);
1208 }
1209 }
1210 #endif /* LE_NEED_BUF_GAP16 */
1211