1 /* $NetBSD: am7990.c,v 1.69 2007/08/26 22:36:35 dyoung 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 __KERNEL_RCSID(0, "$NetBSD: am7990.c,v 1.69 2007/08/26 22:36:35 dyoung Exp $"); 76 77 #include "bpfilter.h" 78 #include "rnd.h" 79 80 #include <sys/param.h> 81 #include <sys/systm.h> 82 #include <sys/mbuf.h> 83 #include <sys/syslog.h> 84 #include <sys/socket.h> 85 #include <sys/device.h> 86 #include <sys/malloc.h> 87 #include <sys/ioctl.h> 88 #include <sys/errno.h> 89 #if NRND > 0 90 #include <sys/rnd.h> 91 #endif 92 93 #include <net/if.h> 94 #include <net/if_dl.h> 95 #include <net/if_ether.h> 96 #include <net/if_media.h> 97 98 #if NBPFILTER > 0 99 #include <net/bpf.h> 100 #include <net/bpfdesc.h> 101 #endif 102 103 #include <dev/ic/lancereg.h> 104 #include <dev/ic/lancevar.h> 105 #include <dev/ic/am7990reg.h> 106 #include <dev/ic/am7990var.h> 107 108 static void am7990_meminit(struct lance_softc *); 109 static void am7990_start(struct ifnet *); 110 111 #if defined(_KERNEL_OPT) 112 #include "opt_ddb.h" 113 #endif 114 115 #ifdef LEDEBUG 116 static void am7990_recv_print(struct lance_softc *, int); 117 static void am7990_xmit_print(struct lance_softc *, int); 118 #endif 119 120 #define ifp (&sc->sc_ethercom.ec_if) 121 122 void 123 am7990_config(struct am7990_softc *sc) 124 { 125 int mem, i; 126 127 sc->lsc.sc_meminit = am7990_meminit; 128 sc->lsc.sc_start = am7990_start; 129 130 lance_config(&sc->lsc); 131 132 mem = 0; 133 sc->lsc.sc_initaddr = mem; 134 mem += sizeof(struct leinit); 135 sc->lsc.sc_rmdaddr = mem; 136 mem += sizeof(struct lermd) * sc->lsc.sc_nrbuf; 137 sc->lsc.sc_tmdaddr = mem; 138 mem += sizeof(struct letmd) * sc->lsc.sc_ntbuf; 139 for (i = 0; i < sc->lsc.sc_nrbuf; i++, mem += LEBLEN) 140 sc->lsc.sc_rbufaddr[i] = mem; 141 for (i = 0; i < sc->lsc.sc_ntbuf; i++, mem += LEBLEN) 142 sc->lsc.sc_tbufaddr[i] = mem; 143 #ifdef notyet 144 if (mem > ...) 145 panic(...); 146 #endif 147 } 148 149 /* 150 * Set up the initialization block and the descriptor rings. 151 */ 152 static void 153 am7990_meminit(struct lance_softc *sc) 154 { 155 u_long a; 156 int bix; 157 struct leinit init; 158 struct lermd rmd; 159 struct letmd tmd; 160 u_int8_t *myaddr; 161 162 #if NBPFILTER > 0 163 if (ifp->if_flags & IFF_PROMISC) 164 init.init_mode = LE_MODE_NORMAL | LE_MODE_PROM; 165 else 166 #endif 167 init.init_mode = LE_MODE_NORMAL; 168 if (sc->sc_initmodemedia == 1) 169 init.init_mode |= LE_MODE_PSEL0; 170 171 /* 172 * Update our private copy of the Ethernet address. 173 * We NEED the copy so we can ensure its alignment! 174 */ 175 memcpy(sc->sc_enaddr, CLLADDR(ifp->if_sadl), ETHER_ADDR_LEN); 176 myaddr = sc->sc_enaddr; 177 178 init.init_padr[0] = (myaddr[1] << 8) | myaddr[0]; 179 init.init_padr[1] = (myaddr[3] << 8) | myaddr[2]; 180 init.init_padr[2] = (myaddr[5] << 8) | myaddr[4]; 181 lance_setladrf(&sc->sc_ethercom, init.init_ladrf); 182 183 sc->sc_last_rd = 0; 184 sc->sc_first_td = sc->sc_last_td = sc->sc_no_td = 0; 185 186 a = sc->sc_addr + LE_RMDADDR(sc, 0); 187 init.init_rdra = a; 188 init.init_rlen = (a >> 16) | ((ffs(sc->sc_nrbuf) - 1) << 13); 189 190 a = sc->sc_addr + LE_TMDADDR(sc, 0); 191 init.init_tdra = a; 192 init.init_tlen = (a >> 16) | ((ffs(sc->sc_ntbuf) - 1) << 13); 193 194 (*sc->sc_copytodesc)(sc, &init, LE_INITADDR(sc), sizeof(init)); 195 196 /* 197 * Set up receive ring descriptors. 198 */ 199 for (bix = 0; bix < sc->sc_nrbuf; bix++) { 200 a = sc->sc_addr + LE_RBUFADDR(sc, bix); 201 rmd.rmd0 = a; 202 rmd.rmd1_hadr = a >> 16; 203 rmd.rmd1_bits = LE_R1_OWN; 204 rmd.rmd2 = -LEBLEN | LE_XMD2_ONES; 205 rmd.rmd3 = 0; 206 (*sc->sc_copytodesc)(sc, &rmd, LE_RMDADDR(sc, bix), 207 sizeof(rmd)); 208 } 209 210 /* 211 * Set up transmit ring descriptors. 212 */ 213 for (bix = 0; bix < sc->sc_ntbuf; bix++) { 214 a = sc->sc_addr + LE_TBUFADDR(sc, bix); 215 tmd.tmd0 = a; 216 tmd.tmd1_hadr = a >> 16; 217 tmd.tmd1_bits = 0; 218 tmd.tmd2 = 0 | LE_XMD2_ONES; 219 tmd.tmd3 = 0; 220 (*sc->sc_copytodesc)(sc, &tmd, LE_TMDADDR(sc, bix), 221 sizeof(tmd)); 222 } 223 } 224 225 static void 226 am7990_rint(struct lance_softc *sc) 227 { 228 int bix; 229 int rp; 230 struct lermd rmd; 231 232 bix = sc->sc_last_rd; 233 234 /* Process all buffers with valid data. */ 235 for (;;) { 236 rp = LE_RMDADDR(sc, bix); 237 (*sc->sc_copyfromdesc)(sc, &rmd, rp, sizeof(rmd)); 238 239 if (rmd.rmd1_bits & LE_R1_OWN) 240 break; 241 242 if (rmd.rmd1_bits & LE_R1_ERR) { 243 if (rmd.rmd1_bits & LE_R1_ENP) { 244 #ifdef LEDEBUG 245 if ((rmd.rmd1_bits & LE_R1_OFLO) == 0) { 246 if (rmd.rmd1_bits & LE_R1_FRAM) 247 printf("%s: framing error\n", 248 sc->sc_dev.dv_xname); 249 if (rmd.rmd1_bits & LE_R1_CRC) 250 printf("%s: crc mismatch\n", 251 sc->sc_dev.dv_xname); 252 } 253 #endif 254 } else { 255 if (rmd.rmd1_bits & LE_R1_OFLO) 256 printf("%s: overflow\n", 257 sc->sc_dev.dv_xname); 258 } 259 if (rmd.rmd1_bits & LE_R1_BUFF) 260 printf("%s: receive buffer error\n", 261 sc->sc_dev.dv_xname); 262 ifp->if_ierrors++; 263 } else if ((rmd.rmd1_bits & (LE_R1_STP | LE_R1_ENP)) != 264 (LE_R1_STP | LE_R1_ENP)) { 265 printf("%s: dropping chained buffer\n", 266 sc->sc_dev.dv_xname); 267 ifp->if_ierrors++; 268 } else { 269 #ifdef LEDEBUG 270 if (sc->sc_debug > 1) 271 am7990_recv_print(sc, sc->sc_last_rd); 272 #endif 273 lance_read(sc, LE_RBUFADDR(sc, bix), 274 (int)rmd.rmd3 - 4); 275 } 276 277 rmd.rmd1_bits = LE_R1_OWN; 278 rmd.rmd2 = -LEBLEN | LE_XMD2_ONES; 279 rmd.rmd3 = 0; 280 (*sc->sc_copytodesc)(sc, &rmd, rp, sizeof(rmd)); 281 282 #ifdef LEDEBUG 283 if (sc->sc_debug) 284 printf("sc->sc_last_rd = %x, rmd: " 285 "ladr %04x, hadr %02x, flags %02x, " 286 "bcnt %04x, mcnt %04x\n", 287 sc->sc_last_rd, 288 rmd.rmd0, rmd.rmd1_hadr, rmd.rmd1_bits, 289 rmd.rmd2, rmd.rmd3); 290 #endif 291 292 if (++bix == sc->sc_nrbuf) 293 bix = 0; 294 } 295 296 sc->sc_last_rd = bix; 297 } 298 299 static void 300 am7990_tint(struct lance_softc *sc) 301 { 302 int bix; 303 struct letmd tmd; 304 305 bix = sc->sc_first_td; 306 307 for (;;) { 308 if (sc->sc_no_td <= 0) 309 break; 310 311 (*sc->sc_copyfromdesc)(sc, &tmd, LE_TMDADDR(sc, bix), 312 sizeof(tmd)); 313 314 #ifdef LEDEBUG 315 if (sc->sc_debug) 316 printf("trans tmd: " 317 "ladr %04x, hadr %02x, flags %02x, " 318 "bcnt %04x, mcnt %04x\n", 319 tmd.tmd0, tmd.tmd1_hadr, tmd.tmd1_bits, 320 tmd.tmd2, tmd.tmd3); 321 #endif 322 323 if (tmd.tmd1_bits & LE_T1_OWN) 324 break; 325 326 ifp->if_flags &= ~IFF_OACTIVE; 327 328 if (tmd.tmd1_bits & LE_T1_ERR) { 329 if (tmd.tmd3 & LE_T3_BUFF) 330 printf("%s: transmit buffer error\n", 331 sc->sc_dev.dv_xname); 332 else if (tmd.tmd3 & LE_T3_UFLO) 333 printf("%s: underflow\n", sc->sc_dev.dv_xname); 334 if (tmd.tmd3 & (LE_T3_BUFF | LE_T3_UFLO)) { 335 lance_reset(sc); 336 return; 337 } 338 if (tmd.tmd3 & LE_T3_LCAR) { 339 sc->sc_havecarrier = 0; 340 if (sc->sc_nocarrier) 341 (*sc->sc_nocarrier)(sc); 342 else 343 printf("%s: lost carrier\n", 344 sc->sc_dev.dv_xname); 345 } 346 if (tmd.tmd3 & LE_T3_LCOL) 347 ifp->if_collisions++; 348 if (tmd.tmd3 & LE_T3_RTRY) { 349 #ifdef LEDEBUG 350 printf("%s: excessive collisions, tdr %d\n", 351 sc->sc_dev.dv_xname, 352 tmd.tmd3 & LE_T3_TDR_MASK); 353 #endif 354 ifp->if_collisions += 16; 355 } 356 ifp->if_oerrors++; 357 } else { 358 if (tmd.tmd1_bits & LE_T1_ONE) 359 ifp->if_collisions++; 360 else if (tmd.tmd1_bits & LE_T1_MORE) 361 /* Real number is unknown. */ 362 ifp->if_collisions += 2; 363 ifp->if_opackets++; 364 } 365 366 if (++bix == sc->sc_ntbuf) 367 bix = 0; 368 369 --sc->sc_no_td; 370 } 371 372 sc->sc_first_td = bix; 373 374 am7990_start(ifp); 375 376 if (sc->sc_no_td == 0) 377 ifp->if_timer = 0; 378 } 379 380 /* 381 * Controller interrupt. 382 */ 383 int 384 am7990_intr(void *arg) 385 { 386 struct lance_softc *sc = arg; 387 u_int16_t isr; 388 389 isr = (*sc->sc_rdcsr)(sc, LE_CSR0) | sc->sc_saved_csr0; 390 sc->sc_saved_csr0 = 0; 391 #if defined(LEDEBUG) && LEDEBUG > 1 392 if (sc->sc_debug) 393 printf("%s: am7990_intr entering with isr=%04x\n", 394 sc->sc_dev.dv_xname, isr); 395 #endif 396 if ((isr & LE_C0_INTR) == 0) 397 return (0); 398 399 #ifdef __vax__ 400 /* 401 * DEC needs this write order to the registers, don't know 402 * the results on other arch's. Ragge 991029 403 */ 404 isr &= ~LE_C0_INEA; 405 (*sc->sc_wrcsr)(sc, LE_CSR0, isr); 406 (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA); 407 #else 408 (*sc->sc_wrcsr)(sc, LE_CSR0, 409 isr & (LE_C0_INEA | LE_C0_BABL | LE_C0_MISS | LE_C0_MERR | 410 LE_C0_RINT | LE_C0_TINT | LE_C0_IDON)); 411 #endif 412 if (isr & LE_C0_ERR) { 413 if (isr & LE_C0_BABL) { 414 #ifdef LEDEBUG 415 printf("%s: babble\n", sc->sc_dev.dv_xname); 416 #endif 417 ifp->if_oerrors++; 418 } 419 #if 0 420 if (isr & LE_C0_CERR) { 421 printf("%s: collision error\n", sc->sc_dev.dv_xname); 422 ifp->if_collisions++; 423 } 424 #endif 425 if (isr & LE_C0_MISS) { 426 #ifdef LEDEBUG 427 printf("%s: missed packet\n", sc->sc_dev.dv_xname); 428 #endif 429 ifp->if_ierrors++; 430 } 431 if (isr & LE_C0_MERR) { 432 printf("%s: memory error\n", sc->sc_dev.dv_xname); 433 lance_reset(sc); 434 return (1); 435 } 436 } 437 438 if ((isr & LE_C0_RXON) == 0) { 439 printf("%s: receiver disabled\n", sc->sc_dev.dv_xname); 440 ifp->if_ierrors++; 441 lance_reset(sc); 442 return (1); 443 } 444 if ((isr & LE_C0_TXON) == 0) { 445 printf("%s: transmitter disabled\n", sc->sc_dev.dv_xname); 446 ifp->if_oerrors++; 447 lance_reset(sc); 448 return (1); 449 } 450 451 /* 452 * Pretend we have carrier; if we don't this will be cleared 453 * shortly. 454 */ 455 sc->sc_havecarrier = 1; 456 457 if (isr & LE_C0_RINT) 458 am7990_rint(sc); 459 if (isr & LE_C0_TINT) 460 am7990_tint(sc); 461 462 #if NRND > 0 463 rnd_add_uint32(&sc->rnd_source, isr); 464 #endif 465 466 return (1); 467 } 468 469 #undef ifp 470 471 /* 472 * Setup output on interface. 473 * Get another datagram to send off of the interface queue, and map it to the 474 * interface before starting the output. 475 * Called only at splnet or interrupt level. 476 */ 477 static void 478 am7990_start(struct ifnet *ifp) 479 { 480 struct lance_softc *sc = ifp->if_softc; 481 int bix; 482 struct mbuf *m; 483 struct letmd tmd; 484 int rp; 485 int len; 486 487 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 488 return; 489 490 bix = sc->sc_last_td; 491 492 for (;;) { 493 rp = LE_TMDADDR(sc, bix); 494 (*sc->sc_copyfromdesc)(sc, &tmd, rp, sizeof(tmd)); 495 496 if (tmd.tmd1_bits & LE_T1_OWN) { 497 ifp->if_flags |= IFF_OACTIVE; 498 printf("missing buffer, no_td = %d, last_td = %d\n", 499 sc->sc_no_td, sc->sc_last_td); 500 } 501 502 IFQ_DEQUEUE(&ifp->if_snd, m); 503 if (m == 0) 504 break; 505 506 #if NBPFILTER > 0 507 /* 508 * If BPF is listening on this interface, let it see the packet 509 * before we commit it to the wire. 510 */ 511 if (ifp->if_bpf) 512 bpf_mtap(ifp->if_bpf, m); 513 #endif 514 515 /* 516 * Copy the mbuf chain into the transmit buffer. 517 */ 518 len = lance_put(sc, LE_TBUFADDR(sc, bix), m); 519 520 #ifdef LEDEBUG 521 if (len > ETHERMTU + sizeof(struct ether_header)) 522 printf("packet length %d\n", len); 523 #endif 524 525 ifp->if_timer = 5; 526 527 /* 528 * Init transmit registers, and set transmit start flag. 529 */ 530 tmd.tmd1_bits = LE_T1_OWN | LE_T1_STP | LE_T1_ENP; 531 tmd.tmd2 = -len | LE_XMD2_ONES; 532 tmd.tmd3 = 0; 533 534 (*sc->sc_copytodesc)(sc, &tmd, rp, sizeof(tmd)); 535 536 #ifdef LEDEBUG 537 if (sc->sc_debug > 1) 538 am7990_xmit_print(sc, sc->sc_last_td); 539 #endif 540 541 (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA | LE_C0_TDMD); 542 543 if (++bix == sc->sc_ntbuf) 544 bix = 0; 545 546 if (++sc->sc_no_td == sc->sc_ntbuf) { 547 ifp->if_flags |= IFF_OACTIVE; 548 break; 549 } 550 551 } 552 553 sc->sc_last_td = bix; 554 } 555 556 #ifdef LEDEBUG 557 static void 558 am7990_recv_print(struct lance_softc *sc, int no) 559 { 560 struct lermd rmd; 561 u_int16_t len; 562 struct ether_header eh; 563 564 (*sc->sc_copyfromdesc)(sc, &rmd, LE_RMDADDR(sc, no), sizeof(rmd)); 565 len = rmd.rmd3; 566 printf("%s: receive buffer %d, len = %d\n", sc->sc_dev.dv_xname, no, 567 len); 568 printf("%s: status %04x\n", sc->sc_dev.dv_xname, 569 (*sc->sc_rdcsr)(sc, LE_CSR0)); 570 printf("%s: ladr %04x, hadr %02x, flags %02x, bcnt %04x, mcnt %04x\n", 571 sc->sc_dev.dv_xname, 572 rmd.rmd0, rmd.rmd1_hadr, rmd.rmd1_bits, rmd.rmd2, rmd.rmd3); 573 if (len >= sizeof(eh)) { 574 (*sc->sc_copyfrombuf)(sc, &eh, LE_RBUFADDR(sc, no), sizeof(eh)); 575 printf("%s: dst %s", sc->sc_dev.dv_xname, 576 ether_sprintf(eh.ether_dhost)); 577 printf(" src %s type %04x\n", ether_sprintf(eh.ether_shost), 578 ntohs(eh.ether_type)); 579 } 580 } 581 582 static void 583 am7990_xmit_print(struct lance_softc *sc, int no) 584 { 585 struct letmd tmd; 586 u_int16_t len; 587 struct ether_header eh; 588 589 (*sc->sc_copyfromdesc)(sc, &tmd, LE_TMDADDR(sc, no), sizeof(tmd)); 590 len = -tmd.tmd2; 591 printf("%s: transmit buffer %d, len = %d\n", sc->sc_dev.dv_xname, no, 592 len); 593 printf("%s: status %04x\n", sc->sc_dev.dv_xname, 594 (*sc->sc_rdcsr)(sc, LE_CSR0)); 595 printf("%s: ladr %04x, hadr %02x, flags %02x, bcnt %04x, mcnt %04x\n", 596 sc->sc_dev.dv_xname, 597 tmd.tmd0, tmd.tmd1_hadr, tmd.tmd1_bits, tmd.tmd2, tmd.tmd3); 598 if (len >= sizeof(eh)) { 599 (*sc->sc_copyfrombuf)(sc, &eh, LE_TBUFADDR(sc, no), sizeof(eh)); 600 printf("%s: dst %s", sc->sc_dev.dv_xname, 601 ether_sprintf(eh.ether_dhost)); 602 printf(" src %s type %04x\n", ether_sprintf(eh.ether_shost), 603 ntohs(eh.ether_type)); 604 } 605 } 606 #endif /* LEDEBUG */ 607