am7990.c revision 1.64 1 /* $NetBSD: am7990.c,v 1.64 2001/11/13 13:14:34 lukem Exp $ */
2
3 /*-
4 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
9 * Simulation Facility, NASA Ames Research Center.
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 NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 /*-
41 * Copyright (c) 1992, 1993
42 * The Regents of the University of California. All rights reserved.
43 *
44 * This code is derived from software contributed to Berkeley by
45 * Ralph Campbell and Rick Macklem.
46 *
47 * Redistribution and use in source and binary forms, with or without
48 * modification, are permitted provided that the following conditions
49 * are met:
50 * 1. Redistributions of source code must retain the above copyright
51 * notice, this list of conditions and the following disclaimer.
52 * 2. Redistributions in binary form must reproduce the above copyright
53 * notice, this list of conditions and the following disclaimer in the
54 * documentation and/or other materials provided with the distribution.
55 * 3. All advertising materials mentioning features or use of this software
56 * must display the following acknowledgement:
57 * This product includes software developed by the University of
58 * California, Berkeley and its contributors.
59 * 4. Neither the name of the University nor the names of its contributors
60 * may be used to endorse or promote products derived from this software
61 * without specific prior written permission.
62 *
63 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
64 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
65 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
66 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
67 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
68 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
69 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
70 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
71 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
72 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
73 * SUCH DAMAGE.
74 *
75 * @(#)if_le.c 8.2 (Berkeley) 11/16/93
76 */
77
78 #include <sys/cdefs.h>
79 __KERNEL_RCSID(0, "$NetBSD: am7990.c,v 1.64 2001/11/13 13:14:34 lukem Exp $");
80
81 #include "bpfilter.h"
82 #include "rnd.h"
83
84 #include <sys/param.h>
85 #include <sys/systm.h>
86 #include <sys/mbuf.h>
87 #include <sys/syslog.h>
88 #include <sys/socket.h>
89 #include <sys/device.h>
90 #include <sys/malloc.h>
91 #include <sys/ioctl.h>
92 #include <sys/errno.h>
93 #if NRND > 0
94 #include <sys/rnd.h>
95 #endif
96
97 #include <net/if.h>
98 #include <net/if_dl.h>
99 #include <net/if_ether.h>
100 #include <net/if_media.h>
101
102 #if NBPFILTER > 0
103 #include <net/bpf.h>
104 #include <net/bpfdesc.h>
105 #endif
106
107 #include <dev/ic/lancereg.h>
108 #include <dev/ic/lancevar.h>
109 #include <dev/ic/am7990reg.h>
110 #include <dev/ic/am7990var.h>
111
112 void am7990_meminit __P((struct lance_softc *));
113 void am7990_start __P((struct ifnet *));
114
115 #if defined(_KERNEL_OPT)
116 #include "opt_ddb.h"
117 #endif
118
119 #ifdef DDB
120 #define integrate
121 #define hide
122 #else
123 #define integrate static __inline
124 #define hide static
125 #endif
126
127 integrate void am7990_rint __P((struct lance_softc *));
128 integrate void am7990_tint __P((struct lance_softc *));
129
130 #ifdef LEDEBUG
131 void am7990_recv_print __P((struct lance_softc *, int));
132 void am7990_xmit_print __P((struct lance_softc *, int));
133 #endif
134
135 #define ifp (&sc->sc_ethercom.ec_if)
136
137 void
138 am7990_config(sc)
139 struct am7990_softc *sc;
140 {
141 int mem, i;
142
143 sc->lsc.sc_meminit = am7990_meminit;
144 sc->lsc.sc_start = am7990_start;
145
146 lance_config(&sc->lsc);
147
148 mem = 0;
149 sc->lsc.sc_initaddr = mem;
150 mem += sizeof(struct leinit);
151 sc->lsc.sc_rmdaddr = mem;
152 mem += sizeof(struct lermd) * sc->lsc.sc_nrbuf;
153 sc->lsc.sc_tmdaddr = mem;
154 mem += sizeof(struct letmd) * sc->lsc.sc_ntbuf;
155 for (i = 0; i < sc->lsc.sc_nrbuf; i++, mem += LEBLEN)
156 sc->lsc.sc_rbufaddr[i] = mem;
157 for (i = 0; i < sc->lsc.sc_ntbuf; i++, mem += LEBLEN)
158 sc->lsc.sc_tbufaddr[i] = mem;
159 #ifdef notyet
160 if (mem > ...)
161 panic(...);
162 #endif
163 }
164
165 /*
166 * Set up the initialization block and the descriptor rings.
167 */
168 void
169 am7990_meminit(sc)
170 struct lance_softc *sc;
171 {
172 u_long a;
173 int bix;
174 struct leinit init;
175 struct lermd rmd;
176 struct letmd tmd;
177 u_int8_t *myaddr;
178
179 #if NBPFILTER > 0
180 if (ifp->if_flags & IFF_PROMISC)
181 init.init_mode = LE_MODE_NORMAL | LE_MODE_PROM;
182 else
183 #endif
184 init.init_mode = LE_MODE_NORMAL;
185 if (sc->sc_initmodemedia == 1)
186 init.init_mode |= LE_MODE_PSEL0;
187
188 /*
189 * Update our private copy of the Ethernet address.
190 * We NEED the copy so we can ensure its alignment!
191 */
192 memcpy(sc->sc_enaddr, LLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
193 myaddr = sc->sc_enaddr;
194
195 init.init_padr[0] = (myaddr[1] << 8) | myaddr[0];
196 init.init_padr[1] = (myaddr[3] << 8) | myaddr[2];
197 init.init_padr[2] = (myaddr[5] << 8) | myaddr[4];
198 lance_setladrf(&sc->sc_ethercom, init.init_ladrf);
199
200 sc->sc_last_rd = 0;
201 sc->sc_first_td = sc->sc_last_td = sc->sc_no_td = 0;
202
203 a = sc->sc_addr + LE_RMDADDR(sc, 0);
204 init.init_rdra = a;
205 init.init_rlen = (a >> 16) | ((ffs(sc->sc_nrbuf) - 1) << 13);
206
207 a = sc->sc_addr + LE_TMDADDR(sc, 0);
208 init.init_tdra = a;
209 init.init_tlen = (a >> 16) | ((ffs(sc->sc_ntbuf) - 1) << 13);
210
211 (*sc->sc_copytodesc)(sc, &init, LE_INITADDR(sc), sizeof(init));
212
213 /*
214 * Set up receive ring descriptors.
215 */
216 for (bix = 0; bix < sc->sc_nrbuf; bix++) {
217 a = sc->sc_addr + LE_RBUFADDR(sc, bix);
218 rmd.rmd0 = a;
219 rmd.rmd1_hadr = a >> 16;
220 rmd.rmd1_bits = LE_R1_OWN;
221 rmd.rmd2 = -LEBLEN | LE_XMD2_ONES;
222 rmd.rmd3 = 0;
223 (*sc->sc_copytodesc)(sc, &rmd, LE_RMDADDR(sc, bix),
224 sizeof(rmd));
225 }
226
227 /*
228 * Set up transmit ring descriptors.
229 */
230 for (bix = 0; bix < sc->sc_ntbuf; bix++) {
231 a = sc->sc_addr + LE_TBUFADDR(sc, bix);
232 tmd.tmd0 = a;
233 tmd.tmd1_hadr = a >> 16;
234 tmd.tmd1_bits = 0;
235 tmd.tmd2 = 0 | LE_XMD2_ONES;
236 tmd.tmd3 = 0;
237 (*sc->sc_copytodesc)(sc, &tmd, LE_TMDADDR(sc, bix),
238 sizeof(tmd));
239 }
240 }
241
242 integrate void
243 am7990_rint(sc)
244 struct lance_softc *sc;
245 {
246 int bix;
247 int rp;
248 struct lermd rmd;
249
250 bix = sc->sc_last_rd;
251
252 /* Process all buffers with valid data. */
253 for (;;) {
254 rp = LE_RMDADDR(sc, bix);
255 (*sc->sc_copyfromdesc)(sc, &rmd, rp, sizeof(rmd));
256
257 if (rmd.rmd1_bits & LE_R1_OWN)
258 break;
259
260 if (rmd.rmd1_bits & LE_R1_ERR) {
261 if (rmd.rmd1_bits & LE_R1_ENP) {
262 #ifdef LEDEBUG
263 if ((rmd.rmd1_bits & LE_R1_OFLO) == 0) {
264 if (rmd.rmd1_bits & LE_R1_FRAM)
265 printf("%s: framing error\n",
266 sc->sc_dev.dv_xname);
267 if (rmd.rmd1_bits & LE_R1_CRC)
268 printf("%s: crc mismatch\n",
269 sc->sc_dev.dv_xname);
270 }
271 #endif
272 } else {
273 if (rmd.rmd1_bits & LE_R1_OFLO)
274 printf("%s: overflow\n",
275 sc->sc_dev.dv_xname);
276 }
277 if (rmd.rmd1_bits & LE_R1_BUFF)
278 printf("%s: receive buffer error\n",
279 sc->sc_dev.dv_xname);
280 ifp->if_ierrors++;
281 } else if ((rmd.rmd1_bits & (LE_R1_STP | LE_R1_ENP)) !=
282 (LE_R1_STP | LE_R1_ENP)) {
283 printf("%s: dropping chained buffer\n",
284 sc->sc_dev.dv_xname);
285 ifp->if_ierrors++;
286 } else {
287 #ifdef LEDEBUG
288 if (sc->sc_debug > 1)
289 am7990_recv_print(sc, sc->sc_last_rd);
290 #endif
291 lance_read(sc, LE_RBUFADDR(sc, bix),
292 (int)rmd.rmd3 - 4);
293 }
294
295 rmd.rmd1_bits = LE_R1_OWN;
296 rmd.rmd2 = -LEBLEN | LE_XMD2_ONES;
297 rmd.rmd3 = 0;
298 (*sc->sc_copytodesc)(sc, &rmd, rp, sizeof(rmd));
299
300 #ifdef LEDEBUG
301 if (sc->sc_debug)
302 printf("sc->sc_last_rd = %x, rmd: "
303 "ladr %04x, hadr %02x, flags %02x, "
304 "bcnt %04x, mcnt %04x\n",
305 sc->sc_last_rd,
306 rmd.rmd0, rmd.rmd1_hadr, rmd.rmd1_bits,
307 rmd.rmd2, rmd.rmd3);
308 #endif
309
310 if (++bix == sc->sc_nrbuf)
311 bix = 0;
312 }
313
314 sc->sc_last_rd = bix;
315 }
316
317 integrate void
318 am7990_tint(sc)
319 struct lance_softc *sc;
320 {
321 int bix;
322 struct letmd tmd;
323
324 bix = sc->sc_first_td;
325
326 for (;;) {
327 if (sc->sc_no_td <= 0)
328 break;
329
330 (*sc->sc_copyfromdesc)(sc, &tmd, LE_TMDADDR(sc, bix),
331 sizeof(tmd));
332
333 #ifdef LEDEBUG
334 if (sc->sc_debug)
335 printf("trans tmd: "
336 "ladr %04x, hadr %02x, flags %02x, "
337 "bcnt %04x, mcnt %04x\n",
338 tmd.tmd0, tmd.tmd1_hadr, tmd.tmd1_bits,
339 tmd.tmd2, tmd.tmd3);
340 #endif
341
342 if (tmd.tmd1_bits & LE_T1_OWN)
343 break;
344
345 ifp->if_flags &= ~IFF_OACTIVE;
346
347 if (tmd.tmd1_bits & LE_T1_ERR) {
348 if (tmd.tmd3 & LE_T3_BUFF)
349 printf("%s: transmit buffer error\n",
350 sc->sc_dev.dv_xname);
351 else if (tmd.tmd3 & LE_T3_UFLO)
352 printf("%s: underflow\n", sc->sc_dev.dv_xname);
353 if (tmd.tmd3 & (LE_T3_BUFF | LE_T3_UFLO)) {
354 lance_reset(sc);
355 return;
356 }
357 if (tmd.tmd3 & LE_T3_LCAR) {
358 sc->sc_havecarrier = 0;
359 if (sc->sc_nocarrier)
360 (*sc->sc_nocarrier)(sc);
361 else
362 printf("%s: lost carrier\n",
363 sc->sc_dev.dv_xname);
364 }
365 if (tmd.tmd3 & LE_T3_LCOL)
366 ifp->if_collisions++;
367 if (tmd.tmd3 & LE_T3_RTRY) {
368 #ifdef LEDEBUG
369 printf("%s: excessive collisions, tdr %d\n",
370 sc->sc_dev.dv_xname,
371 tmd.tmd3 & LE_T3_TDR_MASK);
372 #endif
373 ifp->if_collisions += 16;
374 }
375 ifp->if_oerrors++;
376 } else {
377 if (tmd.tmd1_bits & LE_T1_ONE)
378 ifp->if_collisions++;
379 else if (tmd.tmd1_bits & LE_T1_MORE)
380 /* Real number is unknown. */
381 ifp->if_collisions += 2;
382 ifp->if_opackets++;
383 }
384
385 if (++bix == sc->sc_ntbuf)
386 bix = 0;
387
388 --sc->sc_no_td;
389 }
390
391 sc->sc_first_td = bix;
392
393 am7990_start(ifp);
394
395 if (sc->sc_no_td == 0)
396 ifp->if_timer = 0;
397 }
398
399 /*
400 * Controller interrupt.
401 */
402 int
403 am7990_intr(arg)
404 void *arg;
405 {
406 struct lance_softc *sc = arg;
407 u_int16_t isr;
408
409 isr = (*sc->sc_rdcsr)(sc, LE_CSR0) | sc->sc_saved_csr0;
410 sc->sc_saved_csr0 = 0;
411 #if defined(LEDEBUG) && LEDEBUG > 1
412 if (sc->sc_debug)
413 printf("%s: am7990_intr entering with isr=%04x\n",
414 sc->sc_dev.dv_xname, isr);
415 #endif
416 if ((isr & LE_C0_INTR) == 0)
417 return (0);
418
419 #ifdef __vax__
420 /*
421 * DEC needs this write order to the registers, don't know
422 * the results on other arch's. Ragge 991029
423 */
424 isr &= ~LE_C0_INEA;
425 (*sc->sc_wrcsr)(sc, LE_CSR0, isr);
426 (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA);
427 #else
428 (*sc->sc_wrcsr)(sc, LE_CSR0,
429 isr & (LE_C0_INEA | LE_C0_BABL | LE_C0_MISS | LE_C0_MERR |
430 LE_C0_RINT | LE_C0_TINT | LE_C0_IDON));
431 #endif
432 if (isr & LE_C0_ERR) {
433 if (isr & LE_C0_BABL) {
434 #ifdef LEDEBUG
435 printf("%s: babble\n", sc->sc_dev.dv_xname);
436 #endif
437 ifp->if_oerrors++;
438 }
439 #if 0
440 if (isr & LE_C0_CERR) {
441 printf("%s: collision error\n", sc->sc_dev.dv_xname);
442 ifp->if_collisions++;
443 }
444 #endif
445 if (isr & LE_C0_MISS) {
446 #ifdef LEDEBUG
447 printf("%s: missed packet\n", sc->sc_dev.dv_xname);
448 #endif
449 ifp->if_ierrors++;
450 }
451 if (isr & LE_C0_MERR) {
452 printf("%s: memory error\n", sc->sc_dev.dv_xname);
453 lance_reset(sc);
454 return (1);
455 }
456 }
457
458 if ((isr & LE_C0_RXON) == 0) {
459 printf("%s: receiver disabled\n", sc->sc_dev.dv_xname);
460 ifp->if_ierrors++;
461 lance_reset(sc);
462 return (1);
463 }
464 if ((isr & LE_C0_TXON) == 0) {
465 printf("%s: transmitter disabled\n", sc->sc_dev.dv_xname);
466 ifp->if_oerrors++;
467 lance_reset(sc);
468 return (1);
469 }
470
471 /*
472 * Pretend we have carrier; if we don't this will be cleared
473 * shortly.
474 */
475 sc->sc_havecarrier = 1;
476
477 if (isr & LE_C0_RINT)
478 am7990_rint(sc);
479 if (isr & LE_C0_TINT)
480 am7990_tint(sc);
481
482 #if NRND > 0
483 rnd_add_uint32(&sc->rnd_source, isr);
484 #endif
485
486 return (1);
487 }
488
489 #undef ifp
490
491 /*
492 * Setup output on interface.
493 * Get another datagram to send off of the interface queue, and map it to the
494 * interface before starting the output.
495 * Called only at splnet or interrupt level.
496 */
497 void
498 am7990_start(ifp)
499 struct ifnet *ifp;
500 {
501 struct lance_softc *sc = ifp->if_softc;
502 int bix;
503 struct mbuf *m;
504 struct letmd tmd;
505 int rp;
506 int len;
507
508 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
509 return;
510
511 bix = sc->sc_last_td;
512
513 for (;;) {
514 rp = LE_TMDADDR(sc, bix);
515 (*sc->sc_copyfromdesc)(sc, &tmd, rp, sizeof(tmd));
516
517 if (tmd.tmd1_bits & LE_T1_OWN) {
518 ifp->if_flags |= IFF_OACTIVE;
519 printf("missing buffer, no_td = %d, last_td = %d\n",
520 sc->sc_no_td, sc->sc_last_td);
521 }
522
523 IFQ_DEQUEUE(&ifp->if_snd, m);
524 if (m == 0)
525 break;
526
527 #if NBPFILTER > 0
528 /*
529 * If BPF is listening on this interface, let it see the packet
530 * before we commit it to the wire.
531 */
532 if (ifp->if_bpf)
533 bpf_mtap(ifp->if_bpf, m);
534 #endif
535
536 /*
537 * Copy the mbuf chain into the transmit buffer.
538 */
539 len = lance_put(sc, LE_TBUFADDR(sc, bix), m);
540
541 #ifdef LEDEBUG
542 if (len > ETHERMTU + sizeof(struct ether_header))
543 printf("packet length %d\n", len);
544 #endif
545
546 ifp->if_timer = 5;
547
548 /*
549 * Init transmit registers, and set transmit start flag.
550 */
551 tmd.tmd1_bits = LE_T1_OWN | LE_T1_STP | LE_T1_ENP;
552 tmd.tmd2 = -len | LE_XMD2_ONES;
553 tmd.tmd3 = 0;
554
555 (*sc->sc_copytodesc)(sc, &tmd, rp, sizeof(tmd));
556
557 #ifdef LEDEBUG
558 if (sc->sc_debug > 1)
559 am7990_xmit_print(sc, sc->sc_last_td);
560 #endif
561
562 (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA | LE_C0_TDMD);
563
564 if (++bix == sc->sc_ntbuf)
565 bix = 0;
566
567 if (++sc->sc_no_td == sc->sc_ntbuf) {
568 ifp->if_flags |= IFF_OACTIVE;
569 break;
570 }
571
572 }
573
574 sc->sc_last_td = bix;
575 }
576
577 #ifdef LEDEBUG
578 void
579 am7990_recv_print(sc, no)
580 struct lance_softc *sc;
581 int no;
582 {
583 struct lermd rmd;
584 u_int16_t len;
585 struct ether_header eh;
586
587 (*sc->sc_copyfromdesc)(sc, &rmd, LE_RMDADDR(sc, no), sizeof(rmd));
588 len = rmd.rmd3;
589 printf("%s: receive buffer %d, len = %d\n", sc->sc_dev.dv_xname, no,
590 len);
591 printf("%s: status %04x\n", sc->sc_dev.dv_xname,
592 (*sc->sc_rdcsr)(sc, LE_CSR0));
593 printf("%s: ladr %04x, hadr %02x, flags %02x, bcnt %04x, mcnt %04x\n",
594 sc->sc_dev.dv_xname,
595 rmd.rmd0, rmd.rmd1_hadr, rmd.rmd1_bits, rmd.rmd2, rmd.rmd3);
596 if (len >= sizeof(eh)) {
597 (*sc->sc_copyfrombuf)(sc, &eh, LE_RBUFADDR(sc, no), sizeof(eh));
598 printf("%s: dst %s", sc->sc_dev.dv_xname,
599 ether_sprintf(eh.ether_dhost));
600 printf(" src %s type %04x\n", ether_sprintf(eh.ether_shost),
601 ntohs(eh.ether_type));
602 }
603 }
604
605 void
606 am7990_xmit_print(sc, no)
607 struct lance_softc *sc;
608 int no;
609 {
610 struct letmd tmd;
611 u_int16_t len;
612 struct ether_header eh;
613
614 (*sc->sc_copyfromdesc)(sc, &tmd, LE_TMDADDR(sc, no), sizeof(tmd));
615 len = -tmd.tmd2;
616 printf("%s: transmit buffer %d, len = %d\n", sc->sc_dev.dv_xname, no,
617 len);
618 printf("%s: status %04x\n", sc->sc_dev.dv_xname,
619 (*sc->sc_rdcsr)(sc, LE_CSR0));
620 printf("%s: ladr %04x, hadr %02x, flags %02x, bcnt %04x, mcnt %04x\n",
621 sc->sc_dev.dv_xname,
622 tmd.tmd0, tmd.tmd1_hadr, tmd.tmd1_bits, tmd.tmd2, tmd.tmd3);
623 if (len >= sizeof(eh)) {
624 (*sc->sc_copyfrombuf)(sc, &eh, LE_TBUFADDR(sc, no), sizeof(eh));
625 printf("%s: dst %s", sc->sc_dev.dv_xname,
626 ether_sprintf(eh.ether_dhost));
627 printf(" src %s type %04x\n", ether_sprintf(eh.ether_shost),
628 ntohs(eh.ether_type));
629 }
630 }
631 #endif /* LEDEBUG */
632