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