1 /* $NetBSD: am7990.c,v 1.68 2005/12/11 12:21:25 christos 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. Neither the name of the University nor the names of its contributors 56 * may be used to endorse or promote products derived from this software 57 * without specific prior written permission. 58 * 59 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 60 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 61 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 62 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 63 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 64 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 65 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 69 * SUCH DAMAGE. 70 * 71 * @(#)if_le.c 8.2 (Berkeley) 11/16/93 72 */ 73 74 #include <sys/cdefs.h> 75 __FBSDID("$FreeBSD$"); 76 77 #include <sys/param.h> 78 #include <sys/bus.h> 79 #include <sys/endian.h> 80 #include <sys/lock.h> 81 #include <sys/mbuf.h> 82 #include <sys/mutex.h> 83 #include <sys/socket.h> 84 85 #include <net/bpf.h> 86 #include <net/ethernet.h> 87 #include <net/if.h> 88 #include <net/if_arp.h> 89 #include <net/if_dl.h> 90 #include <net/if_media.h> 91 #include <net/if_var.h> 92 93 #include <dev/le/lancereg.h> 94 #include <dev/le/lancevar.h> 95 #include <dev/le/am7990reg.h> 96 #include <dev/le/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 lance_detach(&sc->lsc); 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->sc_ifp; 154 struct leinit init; 155 struct lermd rmd; 156 struct letmd tmd; 157 u_long a; 158 int bix; 159 160 LE_LOCK_ASSERT(sc, MA_OWNED); 161 162 if (ifp->if_flags & IFF_PROMISC) 163 init.init_mode = LE_MODE_NORMAL | LE_MODE_PROM; 164 else 165 init.init_mode = LE_MODE_NORMAL; 166 167 init.init_padr[0] = (sc->sc_enaddr[1] << 8) | sc->sc_enaddr[0]; 168 init.init_padr[1] = (sc->sc_enaddr[3] << 8) | sc->sc_enaddr[2]; 169 init.init_padr[2] = (sc->sc_enaddr[5] << 8) | sc->sc_enaddr[4]; 170 lance_setladrf(sc, init.init_ladrf); 171 172 sc->sc_last_rd = 0; 173 sc->sc_first_td = sc->sc_last_td = sc->sc_no_td = 0; 174 175 a = sc->sc_addr + LE_RMDADDR(sc, 0); 176 init.init_rdra = a; 177 init.init_rlen = (a >> 16) | ((ffs(sc->sc_nrbuf) - 1) << 13); 178 179 a = sc->sc_addr + LE_TMDADDR(sc, 0); 180 init.init_tdra = a; 181 init.init_tlen = (a >> 16) | ((ffs(sc->sc_ntbuf) - 1) << 13); 182 183 (*sc->sc_copytodesc)(sc, &init, LE_INITADDR(sc), sizeof(init)); 184 185 /* 186 * Set up receive ring descriptors. 187 */ 188 for (bix = 0; bix < sc->sc_nrbuf; bix++) { 189 a = sc->sc_addr + LE_RBUFADDR(sc, bix); 190 rmd.rmd0 = a; 191 rmd.rmd1_hadr = a >> 16; 192 rmd.rmd1_bits = LE_R1_OWN; 193 rmd.rmd2 = -LEBLEN | LE_XMD2_ONES; 194 rmd.rmd3 = 0; 195 (*sc->sc_copytodesc)(sc, &rmd, LE_RMDADDR(sc, bix), 196 sizeof(rmd)); 197 } 198 199 /* 200 * Set up transmit ring descriptors. 201 */ 202 for (bix = 0; bix < sc->sc_ntbuf; bix++) { 203 a = sc->sc_addr + LE_TBUFADDR(sc, bix); 204 tmd.tmd0 = a; 205 tmd.tmd1_hadr = a >> 16; 206 tmd.tmd1_bits = 0; 207 tmd.tmd2 = LE_XMD2_ONES; 208 tmd.tmd3 = 0; 209 (*sc->sc_copytodesc)(sc, &tmd, LE_TMDADDR(sc, bix), 210 sizeof(tmd)); 211 } 212 } 213 214 static void 215 am7990_rint(struct lance_softc *sc) 216 { 217 struct ifnet *ifp = sc->sc_ifp; 218 struct lermd rmd; 219 int bix, rp; 220 221 bix = sc->sc_last_rd; 222 223 /* Process all buffers with valid data. */ 224 for (;;) { 225 rp = LE_RMDADDR(sc, bix); 226 (*sc->sc_copyfromdesc)(sc, &rmd, rp, sizeof(rmd)); 227 228 if (rmd.rmd1_bits & LE_R1_OWN) 229 break; 230 231 if (rmd.rmd1_bits & LE_R1_ERR) { 232 if (rmd.rmd1_bits & LE_R1_ENP) { 233 #ifdef LEDEBUG 234 if ((rmd.rmd1_bits & LE_R1_OFLO) == 0) { 235 if (rmd.rmd1_bits & LE_R1_FRAM) 236 if_printf(ifp, 237 "framing error\n"); 238 if (rmd.rmd1_bits & LE_R1_CRC) 239 if_printf(ifp, 240 "crc mismatch\n"); 241 } 242 #endif 243 } else { 244 if (rmd.rmd1_bits & LE_R1_OFLO) 245 if_printf(ifp, "overflow\n"); 246 } 247 if (rmd.rmd1_bits & LE_R1_BUFF) 248 if_printf(ifp, "receive buffer error\n"); 249 ifp->if_ierrors++; 250 } else if ((rmd.rmd1_bits & (LE_R1_STP | LE_R1_ENP)) != 251 (LE_R1_STP | LE_R1_ENP)) { 252 if_printf(ifp, "dropping chained buffer\n"); 253 ifp->if_ierrors++; 254 } else { 255 #ifdef LEDEBUG 256 if (sc->sc_flags & LE_DEBUG) 257 am7990_recv_print(sc, sc->sc_last_rd); 258 #endif 259 lance_read(sc, LE_RBUFADDR(sc, bix), 260 (int)rmd.rmd3 - ETHER_CRC_LEN); 261 } 262 263 rmd.rmd1_bits = LE_R1_OWN; 264 rmd.rmd2 = -LEBLEN | LE_XMD2_ONES; 265 rmd.rmd3 = 0; 266 (*sc->sc_copytodesc)(sc, &rmd, rp, sizeof(rmd)); 267 268 #ifdef LEDEBUG 269 if (sc->sc_flags & LE_DEBUG) 270 if_printf(ifp, "sc->sc_last_rd = %x, rmd: " 271 "ladr %04x, hadr %02x, flags %02x, " 272 "bcnt %04x, mcnt %04x\n", 273 sc->sc_last_rd, rmd.rmd0, rmd.rmd1_hadr, 274 rmd.rmd1_bits, rmd.rmd2, rmd.rmd3); 275 #endif 276 277 if (++bix == sc->sc_nrbuf) 278 bix = 0; 279 } 280 281 sc->sc_last_rd = bix; 282 } 283 284 static void 285 am7990_tint(struct lance_softc *sc) 286 { 287 struct ifnet *ifp = sc->sc_ifp; 288 struct letmd tmd; 289 int bix; 290 291 bix = sc->sc_first_td; 292 293 for (;;) { 294 if (sc->sc_no_td <= 0) 295 break; 296 297 (*sc->sc_copyfromdesc)(sc, &tmd, LE_TMDADDR(sc, bix), 298 sizeof(tmd)); 299 300 #ifdef LEDEBUG 301 if (sc->sc_flags & LE_DEBUG) 302 if_printf(ifp, "trans tmd: " 303 "ladr %04x, hadr %02x, flags %02x, " 304 "bcnt %04x, mcnt %04x\n", 305 tmd.tmd0, tmd.tmd1_hadr, tmd.tmd1_bits, 306 tmd.tmd2, tmd.tmd3); 307 #endif 308 309 if (tmd.tmd1_bits & LE_T1_OWN) 310 break; 311 312 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 313 314 if (tmd.tmd1_bits & LE_T1_ERR) { 315 if (tmd.tmd3 & LE_T3_BUFF) 316 if_printf(ifp, "transmit buffer error\n"); 317 else if (tmd.tmd3 & LE_T3_UFLO) 318 if_printf(ifp, "underflow\n"); 319 if (tmd.tmd3 & (LE_T3_BUFF | LE_T3_UFLO)) { 320 lance_init_locked(sc); 321 return; 322 } 323 if (tmd.tmd3 & LE_T3_LCAR) { 324 if (sc->sc_flags & LE_CARRIER) 325 if_link_state_change(ifp, 326 LINK_STATE_DOWN); 327 sc->sc_flags &= ~LE_CARRIER; 328 if (sc->sc_nocarrier) 329 (*sc->sc_nocarrier)(sc); 330 else 331 if_printf(ifp, "lost carrier\n"); 332 } 333 if (tmd.tmd3 & LE_T3_LCOL) 334 ifp->if_collisions++; 335 if (tmd.tmd3 & LE_T3_RTRY) { 336 #ifdef LEDEBUG 337 if_printf(ifp, "excessive collisions, tdr %d\n", 338 tmd.tmd3 & LE_T3_TDR_MASK); 339 #endif 340 ifp->if_collisions += 16; 341 } 342 ifp->if_oerrors++; 343 } else { 344 if (tmd.tmd1_bits & LE_T1_ONE) 345 ifp->if_collisions++; 346 else if (tmd.tmd1_bits & LE_T1_MORE) 347 /* Real number is unknown. */ 348 ifp->if_collisions += 2; 349 ifp->if_opackets++; 350 } 351 352 if (++bix == sc->sc_ntbuf) 353 bix = 0; 354 355 --sc->sc_no_td; 356 } 357 358 sc->sc_first_td = bix; 359 360 ifp->if_timer = sc->sc_no_td > 0 ? 5 : 0; 361 } 362 363 /* 364 * Controller interrupt 365 */ 366 void 367 am7990_intr(void *arg) 368 { 369 struct lance_softc *sc = arg; 370 struct ifnet *ifp = sc->sc_ifp; 371 uint16_t isr; 372 373 LE_LOCK(sc); 374 375 if (sc->sc_hwintr && (*sc->sc_hwintr)(sc) == -1) { 376 ifp->if_ierrors++; 377 lance_init_locked(sc); 378 LE_UNLOCK(sc); 379 return; 380 } 381 382 isr = (*sc->sc_rdcsr)(sc, LE_CSR0); 383 #if defined(LEDEBUG) && LEDEBUG > 1 384 if (sc->sc_flags & LE_DEBUG) 385 if_printf(ifp, "%s: entering with isr=%04x\n", __func__, isr); 386 #endif 387 if ((isr & LE_C0_INTR) == 0) { 388 LE_UNLOCK(sc); 389 return; 390 } 391 392 /* 393 * Clear interrupt source flags and turn off interrupts. If we 394 * don't clear these flags before processing their sources we 395 * could completely miss some interrupt events as the the NIC 396 * can change these flags while we're in this handler. We turn 397 * of interrupts while processing them so we don't get another 398 * one while we still process the previous one in ifp->if_input() 399 * with the driver lock dropped. 400 */ 401 (*sc->sc_wrcsr)(sc, LE_CSR0, isr & ~(LE_C0_INEA | LE_C0_TDMD | 402 LE_C0_STOP | LE_C0_STRT | LE_C0_INIT)); 403 404 if (isr & LE_C0_ERR) { 405 if (isr & LE_C0_BABL) { 406 #ifdef LEDEBUG 407 if_printf(ifp, "babble\n"); 408 #endif 409 ifp->if_oerrors++; 410 } 411 #if 0 412 if (isr & LE_C0_CERR) { 413 if_printf(ifp, "collision error\n"); 414 ifp->if_collisions++; 415 } 416 #endif 417 if (isr & LE_C0_MISS) { 418 #ifdef LEDEBUG 419 if_printf(ifp, "missed packet\n"); 420 #endif 421 ifp->if_ierrors++; 422 } 423 if (isr & LE_C0_MERR) { 424 if_printf(ifp, "memory error\n"); 425 lance_init_locked(sc); 426 LE_UNLOCK(sc); 427 return; 428 } 429 } 430 431 if ((isr & LE_C0_RXON) == 0) { 432 if_printf(ifp, "receiver disabled\n"); 433 ifp->if_ierrors++; 434 lance_init_locked(sc); 435 LE_UNLOCK(sc); 436 return; 437 } 438 if ((isr & LE_C0_TXON) == 0) { 439 if_printf(ifp, "transmitter disabled\n"); 440 ifp->if_oerrors++; 441 lance_init_locked(sc); 442 LE_UNLOCK(sc); 443 return; 444 } 445 446 /* 447 * Pretend we have carrier; if we don't this will be cleared shortly. 448 */ 449 if (!(sc->sc_flags & LE_CARRIER)) 450 if_link_state_change(ifp, LINK_STATE_UP); 451 sc->sc_flags |= LE_CARRIER; 452 453 if (isr & LE_C0_RINT) 454 am7990_rint(sc); 455 if (isr & LE_C0_TINT) 456 am7990_tint(sc); 457 458 /* Enable interrupts again. */ 459 (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA); 460 461 if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) 462 am7990_start_locked(sc); 463 464 LE_UNLOCK(sc); 465 } 466 467 /* 468 * Set up output on interface. 469 * Get another datagram to send off of the interface queue, and map it to the 470 * interface before starting the output. 471 */ 472 static void 473 am7990_start_locked(struct lance_softc *sc) 474 { 475 struct ifnet *ifp = sc->sc_ifp; 476 struct letmd tmd; 477 struct mbuf *m; 478 int bix, enq, len, rp; 479 480 LE_LOCK_ASSERT(sc, MA_OWNED); 481 482 if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != 483 IFF_DRV_RUNNING) 484 return; 485 486 bix = sc->sc_last_td; 487 enq = 0; 488 489 for (; sc->sc_no_td < sc->sc_ntbuf && 490 !IFQ_DRV_IS_EMPTY(&ifp->if_snd);) { 491 rp = LE_TMDADDR(sc, bix); 492 (*sc->sc_copyfromdesc)(sc, &tmd, rp, sizeof(tmd)); 493 494 if (tmd.tmd1_bits & LE_T1_OWN) { 495 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 496 if_printf(ifp, 497 "missing buffer, no_td = %d, last_td = %d\n", 498 sc->sc_no_td, sc->sc_last_td); 499 } 500 501 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 502 if (m == 0) 503 break; 504 505 /* 506 * If BPF is listening on this interface, let it see the packet 507 * before we commit it to the wire. 508 */ 509 BPF_MTAP(ifp, m); 510 511 /* 512 * Copy the mbuf chain into the transmit buffer. 513 */ 514 len = lance_put(sc, LE_TBUFADDR(sc, bix), m); 515 516 #ifdef LEDEBUG 517 if (len > ETHERMTU + ETHER_HDR_LEN) 518 if_printf(ifp, "packet length %d\n", len); 519 #endif 520 521 /* 522 * Init transmit registers, and set transmit start flag. 523 */ 524 tmd.tmd1_bits = LE_T1_OWN | LE_T1_STP | LE_T1_ENP; 525 tmd.tmd2 = -len | LE_XMD2_ONES; 526 tmd.tmd3 = 0; 527 528 (*sc->sc_copytodesc)(sc, &tmd, rp, sizeof(tmd)); 529 530 #ifdef LEDEBUG 531 if (sc->sc_flags & LE_DEBUG) 532 am7990_xmit_print(sc, sc->sc_last_td); 533 #endif 534 535 (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA | LE_C0_TDMD); 536 enq++; 537 538 if (++bix == sc->sc_ntbuf) 539 bix = 0; 540 541 if (++sc->sc_no_td == sc->sc_ntbuf) { 542 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 543 break; 544 } 545 } 546 547 sc->sc_last_td = bix; 548 549 if (enq > 0) 550 ifp->if_timer = 5; 551 } 552 553 #ifdef LEDEBUG 554 static void 555 am7990_recv_print(struct lance_softc *sc, int no) 556 { 557 struct ifnet *ifp = sc->sc_ifp; 558 struct ether_header eh; 559 struct lermd rmd; 560 uint16_t len; 561 562 (*sc->sc_copyfromdesc)(sc, &rmd, LE_RMDADDR(sc, no), sizeof(rmd)); 563 len = rmd.rmd3; 564 if_printf(ifp, "receive buffer %d, len = %d\n", no, len); 565 if_printf(ifp, "status %04x\n", (*sc->sc_rdcsr)(sc, LE_CSR0)); 566 if_printf(ifp, 567 "ladr %04x, hadr %02x, flags %02x, bcnt %04x, mcnt %04x\n", 568 rmd.rmd0, rmd.rmd1_hadr, rmd.rmd1_bits, rmd.rmd2, rmd.rmd3); 569 if (len - ETHER_CRC_LEN >= sizeof(eh)) { 570 (*sc->sc_copyfrombuf)(sc, &eh, LE_RBUFADDR(sc, no), sizeof(eh)); 571 if_printf(ifp, "dst %s", ether_sprintf(eh.ether_dhost)); 572 printf(" src %s type %04x\n", ether_sprintf(eh.ether_shost), 573 ntohs(eh.ether_type)); 574 } 575 } 576 577 static void 578 am7990_xmit_print(struct lance_softc *sc, int no) 579 { 580 struct ifnet *ifp = sc->sc_ifp; 581 struct ether_header eh; 582 struct letmd tmd; 583 uint16_t len; 584 585 (*sc->sc_copyfromdesc)(sc, &tmd, LE_TMDADDR(sc, no), sizeof(tmd)); 586 len = -tmd.tmd2; 587 if_printf(ifp, "transmit buffer %d, len = %d\n", no, len); 588 if_printf(ifp, "status %04x\n", (*sc->sc_rdcsr)(sc, LE_CSR0)); 589 if_printf(ifp, 590 "ladr %04x, hadr %02x, flags %02x, bcnt %04x, mcnt %04x\n", 591 tmd.tmd0, tmd.tmd1_hadr, tmd.tmd1_bits, tmd.tmd2, tmd.tmd3); 592 if (len >= sizeof(eh)) { 593 (*sc->sc_copyfrombuf)(sc, &eh, LE_TBUFADDR(sc, no), sizeof(eh)); 594 if_printf(ifp, "dst %s", ether_sprintf(eh.ether_dhost)); 595 printf(" src %s type %04x\n", ether_sprintf(eh.ether_shost), 596 ntohs(eh.ether_type)); 597 } 598 } 599 #endif /* LEDEBUG */ 600