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