seeq8005.c revision 1.1
1/* $NetBSD: seeq8005.c,v 1.1 2000/09/18 20:51:15 bjh21 Exp $ */ 2 3/* 4 * Copyright (c) 2000 Ben Harris 5 * Copyright (c) 1995 Mark Brinicombe 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Mark Brinicombe. 19 * 4. The name of the company nor the name of the author may be used to 20 * endorse or promote products derived from this software without specific 21 * prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35/* 36 * SEEQ 8005 device driver 37 */ 38 39/* 40 * Bugs/possible improvements: 41 * - Does not currently support DMA 42 * - Does not currently support multicasts 43 * - Does not transmit multiple packets in one go 44 * - Does not support big-endian hosts 45 * - Does not support 8-bit busses 46 */ 47 48#include "opt_inet.h" 49#include "opt_ns.h" 50 51#include <sys/types.h> 52#include <sys/param.h> 53 54__RCSID("$NetBSD: seeq8005.c,v 1.1 2000/09/18 20:51:15 bjh21 Exp $"); 55 56#include <sys/systm.h> 57#include <sys/endian.h> 58#include <sys/errno.h> 59#include <sys/ioctl.h> 60#include <sys/mbuf.h> 61#include <sys/socket.h> 62#include <sys/syslog.h> 63#include <sys/device.h> 64 65#include <net/if.h> 66#include <net/if_dl.h> 67#include <net/if_types.h> 68#include <net/if_ether.h> 69 70#ifdef INET 71#include <netinet/in.h> 72#include <netinet/in_systm.h> 73#include <netinet/in_var.h> 74#include <netinet/ip.h> 75#include <netinet/if_inarp.h> 76#endif 77 78#ifdef NS 79#include <netns/ns.h> 80#include <netns/ns_if.h> 81#endif 82 83#include "bpfilter.h" 84#if NBPFILTER > 0 85#include <net/bpf.h> 86#include <net/bpfdesc.h> 87#endif 88 89#include <machine/bus.h> 90#include <machine/intr.h> 91 92#include <dev/ic/seeq8005reg.h> 93#include <dev/ic/seeq8005var.h> 94 95#ifndef EA_TIMEOUT 96#define EA_TIMEOUT 60 97#endif 98 99#define EA_TX_BUFFER_SIZE 0x4000 100#define EA_RX_BUFFER_SIZE 0xC000 101 102/*#define EA_TX_DEBUG*/ 103/*#define EA_RX_DEBUG*/ 104/*#define EA_DEBUG*/ 105/*#define EA_PACKET_DEBUG*/ 106 107/* for debugging convenience */ 108#ifdef EA_DEBUG 109#define dprintf(x) printf x 110#else 111#define dprintf(x) 112#endif 113 114/* 115 * prototypes 116 */ 117 118static int ea_init(struct seeq8005_softc *); 119static int ea_ioctl(struct ifnet *, u_long, caddr_t); 120static void ea_start(struct ifnet *); 121static void ea_watchdog(struct ifnet *); 122static void ea_reinit(struct seeq8005_softc *); 123static void ea_chipreset(struct seeq8005_softc *); 124static void ea_ramtest(struct seeq8005_softc *); 125static int ea_stoptx(struct seeq8005_softc *); 126static int ea_stoprx(struct seeq8005_softc *); 127static void ea_stop(struct seeq8005_softc *); 128static void ea_await_fifo_empty(struct seeq8005_softc *); 129static void ea_await_fifo_full(struct seeq8005_softc *); 130static void ea_writebuf(struct seeq8005_softc *, u_char *, u_int, size_t); 131static void ea_readbuf(struct seeq8005_softc *, u_char *, u_int, size_t); 132static void earead(struct seeq8005_softc *, int, int); 133static struct mbuf *eaget(struct seeq8005_softc *, int, int, struct ifnet *); 134static void ea_hardreset(struct seeq8005_softc *); 135static void eagetpackets(struct seeq8005_softc *); 136static void eatxpacket(struct seeq8005_softc *); 137 138 139#ifdef EA_PACKET_DEBUG 140void ea_dump_buffer(struct seeq8005_softc *, int); 141#endif 142 143 144#ifdef EA_PACKET_DEBUG 145/* 146 * Dump the interface buffer 147 */ 148 149void 150ea_dump_buffer(struct seeq8005_softc *sc, u_int offset) 151{ 152 bus_space_tag_t iot = sc->sc_iot; 153 bus_space_handle_t ioh = sc->sc_ioh; 154 u_int addr; 155 int loop; 156 size_t size; 157 int ctrl; 158 int ptr; 159 160 addr = offset; 161 162 do { 163 bus_space_write_2(iot, ioh, EA_8005_COMMAND, 164 sc->sc_command | EA_CMD_FIFO_READ); 165 bus_space_write_2(iot, ioh, EA_8005_CONFIG1, 166 sc->sc_config1 | EA_BUFCODE_LOCAL_MEM); 167 bus_space_write_2(iot, ioh, EA_8005_DMA_ADDR, addr); 168 169 ptr = bus_space_read_2(iot, ioh, EA_8005_BUFWIN); 170 ctrl = bus_space_read_2(iot, ioh, EA_8005_BUFWIN); 171 ptr = ((ptr & 0xff) << 8) | ((ptr >> 8) & 0xff); 172 173 if (ptr == 0) break; 174 size = ptr - addr; 175 176 printf("addr=%04x size=%04x ", addr, size); 177 printf("cmd=%02x st=%02x\n", ctrl & 0xff, ctrl >> 8); 178 179 for (loop = 0; loop < size - 4; loop += 2) 180 printf("%04x ", 181 bus_space_read_2(iot, ioh, EA_8005_BUFWIN)); 182 printf("\n"); 183 addr = ptr; 184 } while (size != 0); 185} 186#endif 187 188/* 189 * Attach chip. 190 */ 191 192void 193seeq8005_attach(struct seeq8005_softc *sc, const u_int8_t *myaddr) 194{ 195 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 196 197 /* Print out some information for the user. */ 198 199 printf(": address %s", ether_sprintf(myaddr)); 200 201 /* Stop the board. */ 202 203 ea_chipreset(sc); 204 ea_stoptx(sc); 205 ea_stoprx(sc); 206 207 /* Initialise ifnet structure. */ 208 209 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); 210 ifp->if_softc = sc; 211 ifp->if_start = ea_start; 212 ifp->if_ioctl = ea_ioctl; 213 ifp->if_watchdog = ea_watchdog; 214 ifp->if_flags = IFF_BROADCAST | IFF_NOTRAILERS; 215 216 /* Now we can attach the interface. */ 217 218 if_attach(ifp); 219 ether_ifattach(ifp, myaddr); 220 221 /* Finally, attach to bpf filter if it is present. */ 222 223#if NBPFILTER > 0 224 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header)); 225#endif 226 227 /* Should test the RAM */ 228 229 ea_ramtest(sc); 230 231 printf("\n"); 232} 233 234 235/* 236 * Test the RAM on the ethernet card. 237 */ 238 239void 240ea_ramtest(struct seeq8005_softc *sc) 241{ 242 bus_space_tag_t iot = sc->sc_iot; 243 bus_space_handle_t ioh = sc->sc_ioh; 244 int loop; 245 u_int sum = 0; 246 char pbuf[9]; 247 248/* dprintf(("ea_ramtest()\n"));*/ 249 250 /* 251 * Test the buffer memory on the board. 252 * Write simple pattens to it and read them back. 253 */ 254 255 /* Set up the whole buffer RAM for writing */ 256 257 bus_space_write_2(iot, ioh, EA_8005_CONFIG1, EA_BUFCODE_TX_EAP); 258 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, (EA_BUFFER_SIZE >> 8) - 1); 259 bus_space_write_2(iot, ioh, EA_8005_TX_PTR, 0x0000); 260 bus_space_write_2(iot, ioh, EA_8005_RX_PTR, EA_BUFFER_SIZE - 2); 261 262 /* Set the write start address and write a pattern */ 263 264 ea_writebuf(sc, NULL, 0x0000, 0); 265 266 for (loop = 0; loop < EA_BUFFER_SIZE; loop += 2) 267 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, loop); 268 269 /* Set the read start address and verify the pattern */ 270 271 ea_readbuf(sc, NULL, 0x0000, 0); 272 273 for (loop = 0; loop < EA_BUFFER_SIZE; loop += 2) 274 if (bus_space_read_2(iot, ioh, EA_8005_BUFWIN) != loop) 275 ++sum; 276 277 if (sum != 0) 278 dprintf(("sum=%d\n", sum)); 279 280 /* Set the write start address and write a pattern */ 281 282 ea_writebuf(sc, NULL, 0x0000, 0); 283 284 for (loop = 0; loop < EA_BUFFER_SIZE; loop += 2) 285 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 286 loop ^ (EA_BUFFER_SIZE - 1)); 287 288 /* Set the read start address and verify the pattern */ 289 290 ea_readbuf(sc, NULL, 0x0000, 0); 291 292 for (loop = 0; loop < EA_BUFFER_SIZE; loop += 2) 293 if (bus_space_read_2(iot, ioh, EA_8005_BUFWIN) != 294 (loop ^ (EA_BUFFER_SIZE - 1))) 295 ++sum; 296 297 if (sum != 0) 298 dprintf(("sum=%d\n", sum)); 299 300 /* Set the write start address and write a pattern */ 301 302 ea_writebuf(sc, NULL, 0x0000, 0); 303 304 for (loop = 0; loop < EA_BUFFER_SIZE; loop += 2) 305 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 0xaa55); 306 307 /* Set the read start address and verify the pattern */ 308 309 ea_readbuf(sc, NULL, 0x0000, 0); 310 311 for (loop = 0; loop < EA_BUFFER_SIZE; loop += 2) 312 if (bus_space_read_2(iot, ioh, EA_8005_BUFWIN) != 0xaa55) 313 ++sum; 314 315 if (sum != 0) 316 dprintf(("sum=%d\n", sum)); 317 318 /* Set the write start address and write a pattern */ 319 320 ea_writebuf(sc, NULL, 0x0000, 0); 321 322 for (loop = 0; loop < EA_BUFFER_SIZE; loop += 2) 323 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 0x55aa); 324 325 /* Set the read start address and verify the pattern */ 326 327 ea_readbuf(sc, NULL, 0x0000, 0); 328 329 for (loop = 0; loop < EA_BUFFER_SIZE; loop += 2) 330 if (bus_space_read_2(iot, ioh, EA_8005_BUFWIN) != 0x55aa) 331 ++sum; 332 333 if (sum != 0) 334 dprintf(("sum=%d\n", sum)); 335 336 /* Report */ 337 338 if (sum == 0) { 339 format_bytes(pbuf, sizeof(pbuf), EA_BUFFER_SIZE); 340 printf(", %s buffer RAM", pbuf); 341 } else 342 printf(", buffer RAM failed self test, %d faults", sum); 343} 344 345 346/* 347 * Stop and reinitialise the interface. 348 */ 349 350static void 351ea_reinit(struct seeq8005_softc *sc) 352{ 353 int s; 354 355 dprintf(("eareinit()\n")); 356 357 /* Stop and reinitialise the interface */ 358 359 s = splnet(); 360 ea_stop(sc); 361 ea_init(sc); 362 splx(s); 363} 364 365 366/* 367 * Stop the tx interface. 368 * 369 * Returns 0 if the tx was already stopped or 1 if it was active 370 */ 371 372static int 373ea_stoptx(struct seeq8005_softc *sc) 374{ 375 bus_space_tag_t iot = sc->sc_iot; 376 bus_space_handle_t ioh = sc->sc_ioh; 377 int timeout; 378 int status; 379 380 dprintf(("ea_stoptx()\n")); 381 382 status = bus_space_read_2(iot, ioh, EA_8005_STATUS); 383 if (!(status & EA_STATUS_TX_ON)) 384 return 0; 385 386 /* Stop any tx and wait for confirmation */ 387 bus_space_write_2(iot, ioh, EA_8005_COMMAND, 388 sc->sc_command | EA_CMD_TX_OFF); 389 390 timeout = 20000; 391 do { 392 status = bus_space_read_2(iot, ioh, EA_8005_STATUS); 393 } while ((status & EA_STATUS_TX_ON) && --timeout > 0); 394 if (timeout == 0) 395 dprintf(("ea_stoptx: timeout waiting for tx termination\n")); 396 397 /* Clear any pending tx interrupt */ 398 bus_space_write_2(iot, ioh, EA_8005_COMMAND, 399 sc->sc_command | EA_CMD_TX_INTACK); 400 return 1; 401} 402 403 404/* 405 * Stop the rx interface. 406 * 407 * Returns 0 if the tx was already stopped or 1 if it was active 408 */ 409 410static int 411ea_stoprx(struct seeq8005_softc *sc) 412{ 413 bus_space_tag_t iot = sc->sc_iot; 414 bus_space_handle_t ioh = sc->sc_ioh; 415 int timeout; 416 int status; 417 418 dprintf(("ea_stoprx()\n")); 419 420 status = bus_space_read_2(iot, ioh, EA_8005_STATUS); 421 if (!(status & EA_STATUS_RX_ON)) 422 return 0; 423 424 /* Stop any rx and wait for confirmation */ 425 426 bus_space_write_2(iot, ioh, EA_8005_COMMAND, 427 sc->sc_command | EA_CMD_RX_OFF); 428 429 timeout = 20000; 430 do { 431 status = bus_space_read_2(iot, ioh, EA_8005_STATUS); 432 } while ((status & EA_STATUS_RX_ON) && --timeout > 0); 433 if (timeout == 0) 434 dprintf(("ea_stoprx: timeout waiting for rx termination\n")); 435 436 /* Clear any pending rx interrupt */ 437 438 bus_space_write_2(iot, ioh, EA_8005_COMMAND, 439 sc->sc_command | EA_CMD_RX_INTACK); 440 return 1; 441} 442 443 444/* 445 * Stop interface. 446 * Stop all IO and shut the interface down 447 */ 448 449static void 450ea_stop(struct seeq8005_softc *sc) 451{ 452 bus_space_tag_t iot = sc->sc_iot; 453 bus_space_handle_t ioh = sc->sc_ioh; 454 455 dprintf(("ea_stop()\n")); 456 457 /* Stop all IO */ 458 ea_stoptx(sc); 459 ea_stoprx(sc); 460 461 /* Disable rx and tx interrupts */ 462 sc->sc_command &= (EA_CMD_RX_INTEN | EA_CMD_TX_INTEN); 463 464 /* Clear any pending interrupts */ 465 bus_space_write_2(iot, ioh, EA_8005_COMMAND, 466 sc->sc_command | EA_CMD_RX_INTACK | 467 EA_CMD_TX_INTACK | EA_CMD_DMA_INTACK | 468 EA_CMD_BW_INTACK); 469 dprintf(("st=%08x", bus_space_read_2(iot, ioh, EA_8005_STATUS))); 470 471 /* Cancel any watchdog timer */ 472 sc->sc_ethercom.ec_if.if_timer = 0; 473} 474 475 476/* 477 * Reset the chip 478 * Following this the software registers are reset 479 */ 480 481static void 482ea_chipreset(struct seeq8005_softc *sc) 483{ 484 bus_space_tag_t iot = sc->sc_iot; 485 bus_space_handle_t ioh = sc->sc_ioh; 486 487 dprintf(("ea_chipreset()\n")); 488 489 /* Reset the controller. Min of 4us delay here */ 490 491 bus_space_write_2(iot, ioh, EA_8005_CONFIG2, EA_CFG2_RESET); 492 delay(100); 493 494 sc->sc_command = 0; 495 sc->sc_config1 = 0; 496 sc->sc_config2 = 0; 497} 498 499 500/* 501 * Do a hardware reset of the board, and upload the ethernet address again in 502 * case the board forgets. 503 */ 504 505static void 506ea_hardreset(struct seeq8005_softc *sc) 507{ 508 bus_space_tag_t iot = sc->sc_iot; 509 bus_space_handle_t ioh = sc->sc_ioh; 510 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 511 int loop; 512 513 dprintf(("ea_hardreset()\n")); 514 515 /* Stop any activity */ 516 ea_stoptx(sc); 517 ea_stoprx(sc); 518 519 ea_chipreset(sc); 520 521 /* Set up defaults for the registers */ 522 523 /* Set the byte order for transfers to/from board RAM. */ 524#if BYTE_ORDER == BIG_ENDIAN 525 sc->sc_config2 = EA_CFG2_BYTESWAP 526#else 527 sc->sc_config2 = 0; 528#endif 529 bus_space_write_2(iot, ioh, EA_8005_CONFIG2, sc->sc_config2); 530 sc->sc_command = 0x00; 531 sc->sc_config1 = EA_CFG1_STATION_ADDR0 | EA_CFG1_DMA_BSIZE_1 | 532 EA_CFG1_DMA_BURST_CONT; 533 bus_space_write_2(iot, ioh, EA_8005_CONFIG1, sc->sc_config1); 534 bus_space_write_2(iot, ioh, EA_8005_COMMAND, sc->sc_command); 535 536 bus_space_write_2(iot, ioh, EA_8005_CONFIG1, EA_BUFCODE_TX_EAP); 537 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 538 (EA_TX_BUFFER_SIZE >> 8) - 1); 539 540 /* Write the station address - the receiver must be off */ 541 bus_space_write_2(iot, ioh, EA_8005_CONFIG1, 542 sc->sc_config1 | EA_BUFCODE_STATION_ADDR0); 543 for (loop = 0; loop < ETHER_ADDR_LEN; ++loop) 544 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 545 LLADDR(ifp->if_sadl)[loop]); 546} 547 548 549/* 550 * If the DMA FIFO's in write mode, wait for it to empty. Needed when 551 * switching the FIFO from write to read. We also use it when changing 552 * the address for writes. 553 */ 554static void 555ea_await_fifo_empty(struct seeq8005_softc *sc) 556{ 557 bus_space_tag_t iot = sc->sc_iot; 558 bus_space_handle_t ioh = sc->sc_ioh; 559 int timeout; 560 561 timeout = 20000; 562 if ((bus_space_read_2(iot, ioh, EA_8005_STATUS) & 563 EA_STATUS_FIFO_DIR) != 0) 564 return; /* FIFO is reading anyway. */ 565 while ((bus_space_read_2(iot, ioh, EA_8005_STATUS) & 566 EA_STATUS_FIFO_EMPTY) == 0 && 567 --timeout > 0) 568 continue; 569} 570 571/* 572 * Wait for the DMA FIFO to fill before reading from it. 573 */ 574static void 575ea_await_fifo_full(struct seeq8005_softc *sc) 576{ 577 bus_space_tag_t iot = sc->sc_iot; 578 bus_space_handle_t ioh = sc->sc_ioh; 579 int timeout; 580 581 timeout = 20000; 582 while ((bus_space_read_2(iot, ioh, EA_8005_STATUS) & 583 EA_STATUS_FIFO_FULL) == 0 && 584 --timeout > 0) 585 continue; 586} 587 588/* 589 * write to the buffer memory on the interface 590 * 591 * The buffer address is set to ADDR. 592 * If len != 0 then data is copied from the address starting at buf 593 * to the interface buffer. 594 * BUF must be usable as a u_int16_t *. 595 * If LEN is odd, it must be safe to overwrite one extra byte. 596 */ 597 598static void 599ea_writebuf(struct seeq8005_softc *sc, u_char *buf, u_int addr, size_t len) 600{ 601 bus_space_tag_t iot = sc->sc_iot; 602 bus_space_handle_t ioh = sc->sc_ioh; 603 604 dprintf(("writebuf: st=%04x\n", 605 bus_space_read_2(iot, ioh, EA_8005_STATUS))); 606 607#ifdef DIAGNOSTIC 608 if (__predict_false(!ALIGNED_POINTER(buf, u_int16_t))) 609 panic("%s: unaligned writebuf", sc->sc_dev.dv_xname); 610#endif 611 if (__predict_false(addr >= EA_BUFFER_SIZE)) 612 panic("%s: writebuf out of range", sc->sc_dev.dv_xname); 613 614 /* Assume that copying too much is safe. */ 615 if (len % 2 != 0) 616 len++; 617 618 ea_await_fifo_empty(sc); 619 620 bus_space_write_2(iot, ioh, EA_8005_CONFIG1, 621 sc->sc_config1 | EA_BUFCODE_LOCAL_MEM); 622 bus_space_write_2(iot, ioh, EA_8005_COMMAND, 623 sc->sc_command | EA_CMD_FIFO_WRITE); 624 bus_space_write_2(iot, ioh, EA_8005_DMA_ADDR, addr); 625 626 if (len > 0) 627 bus_space_write_multi_2(iot, ioh, EA_8005_BUFWIN, 628 (u_int16_t *)buf, len / 2); 629 /* Leave FIFO to empty in the background */ 630} 631 632 633/* 634 * read from the buffer memory on the interface 635 * 636 * The buffer address is set to ADDR. 637 * If len != 0 then data is copied from the interface buffer to the 638 * address starting at buf. 639 * BUF must be usable as a u_int16_t *. 640 * If LEN is odd, it must be safe to overwrite one extra byte. 641 */ 642 643static void 644ea_readbuf(struct seeq8005_softc *sc, u_char *buf, u_int addr, size_t len) 645{ 646 647 bus_space_tag_t iot = sc->sc_iot; 648 bus_space_handle_t ioh = sc->sc_ioh; 649 650 dprintf(("readbuf: st=%04x addr=%04x len=%d\n", 651 bus_space_read_2(iot, ioh, EA_8005_STATUS), addr, len)); 652 653#ifdef DIAGNOSTIC 654 if (!ALIGNED_POINTER(buf, u_int16_t)) 655 panic("%s: unaligned readbuf", sc->sc_dev.dv_xname); 656#endif 657 if (addr >= EA_BUFFER_SIZE) 658 panic("%s: writebuf out of range", sc->sc_dev.dv_xname); 659 660 /* Assume that copying too much is safe. */ 661 if (len % 2 != 0) 662 len++; 663 664 ea_await_fifo_empty(sc); 665 bus_space_write_2(iot, ioh, EA_8005_CONFIG1, 666 sc->sc_config1 | EA_BUFCODE_LOCAL_MEM); 667 668 bus_space_write_2(iot, ioh, EA_8005_DMA_ADDR, addr); 669 bus_space_write_2(iot, ioh, EA_8005_COMMAND, 670 sc->sc_command | EA_CMD_FIFO_READ); 671 672 ea_await_fifo_full(sc); 673 674 if (len > 0) 675 bus_space_read_multi_2(iot, ioh, EA_8005_BUFWIN, 676 (u_int16_t *)buf, len / 2); 677} 678 679 680/* 681 * Initialize interface. 682 * 683 * This should leave the interface in a state for packet reception and 684 * transmission. 685 */ 686 687static int 688ea_init(struct seeq8005_softc *sc) 689{ 690 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 691 bus_space_tag_t iot = sc->sc_iot; 692 bus_space_handle_t ioh = sc->sc_ioh; 693 int s; 694 695 dprintf(("ea_init()\n")); 696 697 s = splnet(); 698 699 /* First, reset the board. */ 700 701 ea_hardreset(sc); 702 703 704 /* Configure rx. */ 705 dprintf(("Configuring rx...\n")); 706 if (ifp->if_flags & IFF_PROMISC) 707 sc->sc_config1 = EA_CFG1_PROMISCUOUS; 708 else 709 sc->sc_config1 = EA_CFG1_BROADCAST; 710 711 sc->sc_config1 |= EA_CFG1_DMA_BSIZE_8 | EA_CFG1_STATION_ADDR0 | 712 EA_CFG1_DMA_BURST_CONT; 713 bus_space_write_2(iot, ioh, EA_8005_CONFIG1, sc->sc_config1); 714 715 716 /* Configure TX. */ 717 dprintf(("Configuring tx...\n")); 718 719 bus_space_write_2(iot, ioh, EA_8005_CONFIG1, 720 sc->sc_config1 | EA_BUFCODE_TX_EAP); 721 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 722 (EA_TX_BUFFER_SIZE >> 8) - 1); 723 bus_space_write_2(iot, ioh, EA_8005_TX_PTR, 0x0000); 724 725 sc->sc_config2 |= EA_CFG2_OUTPUT; 726 bus_space_write_2(iot, ioh, EA_8005_CONFIG2, sc->sc_config2); 727 728 729 /* Place a NULL header at the beginning of the transmit area */ 730 ea_writebuf(sc, NULL, 0x0000, 0); 731 732 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 0x0000); 733 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 0x0000); 734 735 sc->sc_command |= EA_CMD_TX_INTEN; 736 bus_space_write_2(iot, ioh, EA_8005_COMMAND, sc->sc_command); 737 738 739 /* Setup the Rx pointers */ 740 sc->sc_rx_ptr = EA_TX_BUFFER_SIZE; 741 742 bus_space_write_2(iot, ioh, EA_8005_RX_PTR, sc->sc_rx_ptr); 743 bus_space_write_2(iot, ioh, EA_8005_RX_END, sc->sc_rx_ptr >> 8); 744 745 746 /* Place a NULL header at the beginning of the receive area */ 747 ea_writebuf(sc, NULL, sc->sc_rx_ptr, 0); 748 749 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 0x0000); 750 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 0x0000); 751 752 753 /* Turn on Rx */ 754 sc->sc_command |= EA_CMD_RX_INTEN; 755 bus_space_write_2(iot, ioh, EA_8005_COMMAND, 756 sc->sc_command | EA_CMD_RX_ON); 757 758 759 /* Set flags appropriately. */ 760 ifp->if_flags |= IFF_RUNNING; 761 ifp->if_flags &= ~IFF_OACTIVE; 762 763 dprintf(("init: st=%04x\n", 764 bus_space_read_2(iot, ioh, EA_8005_STATUS))); 765 766 767 /* And start output. */ 768 ea_start(ifp); 769 770 splx(s); 771 return 0; 772} 773 774 775/* 776 * Start output on interface. Get datagrams from the queue and output them, 777 * giving the receiver a chance between datagrams. Call only from splnet or 778 * interrupt level! 779 */ 780 781static void 782ea_start(struct ifnet *ifp) 783{ 784 struct seeq8005_softc *sc = ifp->if_softc; 785 int s; 786 787 s = splnet(); 788#ifdef EA_TX_DEBUG 789 dprintf(("ea_start()...\n")); 790#endif 791 792 /* Don't do anything if output is active. */ 793 794 if (ifp->if_flags & IFF_OACTIVE) 795 return; 796 797 /* Mark interface as output active */ 798 799 ifp->if_flags |= IFF_OACTIVE; 800 801 /* tx packets */ 802 803 eatxpacket(sc); 804 splx(s); 805} 806 807 808/* 809 * Transfer a packet to the interface buffer and start transmission 810 * 811 * Called at splnet() 812 */ 813 814void 815eatxpacket(struct seeq8005_softc *sc) 816{ 817 bus_space_tag_t iot = sc->sc_iot; 818 bus_space_handle_t ioh = sc->sc_ioh; 819 struct mbuf *m, *m0; 820 struct ifnet *ifp; 821 int len, nextpacket; 822 u_int8_t hdr[4]; 823 824 ifp = &sc->sc_ethercom.ec_if; 825 826 /* Dequeue the next packet. */ 827 IF_DEQUEUE(&ifp->if_snd, m0); 828 829 /* If there's nothing to send, return. */ 830 if (!m0) { 831 ifp->if_flags &= ~IFF_OACTIVE; 832 sc->sc_config2 |= EA_CFG2_OUTPUT; 833 bus_space_write_2(iot, ioh, EA_8005_CONFIG2, sc->sc_config2); 834#ifdef EA_TX_DEBUG 835 dprintf(("tx finished\n")); 836#endif 837 return; 838 } 839 840#if NBPFILTER > 0 841 /* Give the packet to the bpf, if any. */ 842 if (ifp->if_bpf) 843 bpf_mtap(ifp->if_bpf, m0); 844#endif 845 846#ifdef EA_TX_DEBUG 847 dprintf(("Tx new packet\n")); 848#endif 849 850 sc->sc_config2 &= ~EA_CFG2_OUTPUT; 851 bus_space_write_2(iot, ioh, EA_8005_CONFIG2, sc->sc_config2); 852 853 /* 854 * Copy the frame to the start of the transmit area on the card, 855 * leaving four bytes for the transmit header. 856 */ 857 len = 0; 858 for (m = m0; m; m = m->m_next) { 859 if (m->m_len == 0) 860 continue; 861 ea_writebuf(sc, mtod(m, caddr_t), 4 + len, m->m_len); 862 len += m->m_len; 863 } 864 m_freem(m0); 865 866 867 /* If packet size is odd round up to the next 16 bit boundry */ 868 if (len % 2) 869 ++len; 870 871 len = max(len, ETHER_MIN_LEN); 872 873 if (len > (ETHER_MAX_LEN - ETHER_CRC_LEN)) 874 log(LOG_WARNING, "%s: oversize packet = %d bytes\n", 875 sc->sc_dev.dv_xname, len); 876 877#if 0 /*def EA_TX_DEBUG*/ 878 dprintf(("ea: xfr pkt length=%d...\n", len)); 879 880 dprintf(("%s-->", ether_sprintf(sc->sc_pktbuf+6))); 881 dprintf(("%s\n", ether_sprintf(sc->sc_pktbuf))); 882#endif 883 884/* dprintf(("st=%04x\n", bus_space_read_2(iot, ioh, EA_8005_STATUS)));*/ 885 886 /* Follow it with a NULL packet header */ 887 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 0x0000); 888 bus_space_write_2(iot, ioh, EA_8005_BUFWIN, 0x0000); 889 890 891 /* Write the packet header */ 892 893 nextpacket = len + 4; 894 hdr[0] = (nextpacket >> 8) & 0xff; 895 hdr[1] = nextpacket & 0xff; 896 hdr[2] = EA_PKTHDR_TX | EA_PKTHDR_DATA_FOLLOWS | 897 EA_TXHDR_XMIT_SUCCESS_INT | EA_TXHDR_COLLISION_INT; 898 hdr[3] = 0; /* Status byte -- will be update by hardware. */ 899 ea_writebuf(sc, hdr, 0x0000, 4); 900 901 bus_space_write_2(iot, ioh, EA_8005_TX_PTR, 0x0000); 902 903/* dprintf(("st=%04x\n", bus_space_read_2(iot, ioh, EA_8005_STATUS)));*/ 904 905#ifdef EA_PACKET_DEBUG 906 ea_dump_buffer(sc, 0); 907#endif 908 909 910 /* Now transmit the datagram. */ 911/* dprintf(("st=%04x\n", bus_space_read_2(iot, ioh, EA_8005_STATUS)));*/ 912 bus_space_write_2(iot, ioh, EA_8005_COMMAND, 913 sc->sc_command | EA_CMD_TX_ON); 914#ifdef EA_TX_DEBUG 915 dprintf(("st=%04x\n", bus_space_read_2(iot, ioh, EA_8005_STATUS))); 916 dprintf(("tx: queued\n")); 917#endif 918} 919 920 921/* 922 * Ethernet controller interrupt. 923 */ 924 925int 926seeq8005intr(void *arg) 927{ 928 struct seeq8005_softc *sc = arg; 929 bus_space_tag_t iot = sc->sc_iot; 930 bus_space_handle_t ioh = sc->sc_ioh; 931 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 932 int status, s, handled; 933 u_int8_t txhdr[4]; 934 u_int txstatus; 935 936 handled = 0; 937 dprintf(("eaintr: ")); 938 939 940 /* Get the controller status */ 941 status = bus_space_read_2(iot, ioh, EA_8005_STATUS); 942 dprintf(("st=%04x ", status)); 943 944 945 /* Tx interrupt ? */ 946 if (status & EA_STATUS_TX_INT) { 947 dprintf(("txint ")); 948 handled = 1; 949 950 /* Acknowledge the interrupt */ 951 bus_space_write_2(iot, ioh, EA_8005_COMMAND, 952 sc->sc_command | EA_CMD_TX_INTACK); 953 954 ea_readbuf(sc, txhdr, 0x0000, 4); 955 956#ifdef EA_TX_DEBUG 957 dprintf(("txstatus=%02x %02x %02x %02x\n", 958 txhdr[0], txhdr[1], txhdr[2], txhdr[3])); 959#endif 960 txstatus = txhdr[3]; 961 962 /* 963 * Did it succeed ? Did we collide ? 964 * 965 * The exact proceedure here is not clear. We should get 966 * an interrupt on a sucessfull tx or on a collision. 967 * The done flag is set after successfull tx or 16 collisions 968 * We should thus get a interrupt for each of collision 969 * and the done bit should not be set. However it does appear 970 * to be set at the same time as the collision bit ... 971 * 972 * So we will count collisions and output errors and will 973 * assume that if the done bit is set the packet was 974 * transmitted. Stats may be wrong if 16 collisions occur on 975 * a packet as the done flag should be set but the packet 976 * may not have been transmitted. so the output count might 977 * not require incrementing if the 16 collisions flags is 978 * set. I don;t know abou this until it happens. 979 */ 980 981 if (txstatus & EA_TXHDR_COLLISION) 982 ifp->if_collisions++; 983 else if (txstatus & EA_TXHDR_ERROR_MASK) 984 ifp->if_oerrors++; 985 986#if 0 987 if (txstatus & EA_TXHDR_ERROR_MASK) 988 log(LOG_WARNING, "tx packet error =%02x\n", txstatus); 989#endif 990 991 if (txstatus & EA_PKTHDR_DONE) { 992 ifp->if_opackets++; 993 994 /* Tx next packet */ 995 996 s = splnet(); 997 eatxpacket(sc); 998 splx(s); 999 } 1000 } 1001 1002 1003 /* Rx interrupt ? */ 1004 if (status & EA_STATUS_RX_INT) { 1005 dprintf(("rxint ")); 1006 handled = 1; 1007 1008 /* Acknowledge the interrupt */ 1009 bus_space_write_2(iot, ioh, EA_8005_COMMAND, 1010 sc->sc_command | EA_CMD_RX_INTACK); 1011 1012 /* Install a watchdog timer needed atm to fixed rx lockups */ 1013 ifp->if_timer = EA_TIMEOUT; 1014 1015 /* Processes the received packets */ 1016 eagetpackets(sc); 1017 1018 1019#if 0 1020 /* Make sure the receiver is on */ 1021 if ((status & EA_STATUS_RX_ON) == 0) { 1022 bus_space_write_2(iot, ioh, EA_8005_COMMAND, 1023 sc->sc_command | EA_CMD_RX_ON); 1024 printf("rxintr: rx is off st=%04x\n",status); 1025 } 1026#endif 1027 } 1028 1029#ifdef EA_DEBUG 1030 status = bus_space_read_2(iot, ioh, EA_8005_STATUS); 1031 dprintf(("st=%04x\n", status)); 1032#endif 1033 1034 return handled; 1035} 1036 1037 1038void 1039eagetpackets(struct seeq8005_softc *sc) 1040{ 1041 bus_space_tag_t iot = sc->sc_iot; 1042 bus_space_handle_t ioh = sc->sc_ioh; 1043 u_int addr; 1044 int len; 1045 int ctrl; 1046 int ptr; 1047 int pack; 1048 int status; 1049 u_int8_t rxhdr[4]; 1050 struct ifnet *ifp; 1051 1052 ifp = &sc->sc_ethercom.ec_if; 1053 1054 1055 /* We start from the last rx pointer position */ 1056 addr = sc->sc_rx_ptr; 1057 sc->sc_config2 &= ~EA_CFG2_OUTPUT; 1058 bus_space_write_2(iot, ioh, EA_8005_CONFIG2, sc->sc_config2); 1059 1060 do { 1061 /* Read rx header */ 1062 ea_readbuf(sc, rxhdr, addr, 4); 1063 1064 /* Split the packet header */ 1065 ptr = (rxhdr[0] << 8) | rxhdr[1]; 1066 ctrl = rxhdr[2]; 1067 status = rxhdr[3]; 1068 1069#ifdef EA_RX_DEBUG 1070 dprintf(("addr=%04x ptr=%04x ctrl=%02x status=%02x\n", 1071 addr, ptr, ctrl, status)); 1072#endif 1073 1074 1075 /* Zero packet ptr ? then must be null header so exit */ 1076 if (ptr == 0) break; 1077 1078 1079 /* Get packet length */ 1080 len = (ptr - addr) - 4; 1081 1082 if (len < 0) 1083 len += EA_RX_BUFFER_SIZE; 1084 1085#ifdef EA_RX_DEBUG 1086 dprintf(("len=%04x\n", len)); 1087#endif 1088 1089 1090 /* Has the packet rx completed ? if not then exit */ 1091 if ((status & EA_PKTHDR_DONE) == 0) 1092 break; 1093 1094 /* 1095 * Did we have any errors? then note error and go to 1096 * next packet 1097 */ 1098 if (__predict_false(status & 0x0f)) { 1099 ++ifp->if_ierrors; 1100 log(LOG_WARNING, 1101 "%s: rx packet error (%02x) - dropping packet\n", 1102 sc->sc_dev.dv_xname, status & 0x0f); 1103 sc->sc_config2 |= EA_CFG2_OUTPUT; 1104 bus_space_write_2(iot, ioh, EA_8005_CONFIG2, 1105 sc->sc_config2); 1106 ea_reinit(sc); 1107 return; 1108 } 1109 1110 /* 1111 * Is the packet too big ? - this will probably be trapped 1112 * above as a receive error 1113 */ 1114 if (__predict_false(len > (ETHER_MAX_LEN - ETHER_CRC_LEN))) { 1115 ++ifp->if_ierrors; 1116 log(LOG_WARNING, "%s: rx packet size error len=%d\n", 1117 sc->sc_dev.dv_xname, len); 1118 sc->sc_config2 |= EA_CFG2_OUTPUT; 1119 bus_space_write_2(iot, ioh, EA_8005_CONFIG2, 1120 sc->sc_config2); 1121 ea_reinit(sc); 1122 return; 1123 } 1124 1125 ifp->if_ipackets++; 1126 /* Pass data up to upper levels. */ 1127 earead(sc, addr + 4, len); 1128 1129 addr = ptr; 1130 ++pack; 1131 } while (len != 0); 1132 1133 sc->sc_config2 |= EA_CFG2_OUTPUT; 1134 bus_space_write_2(iot, ioh, EA_8005_CONFIG2, sc->sc_config2); 1135 1136#ifdef EA_RX_DEBUG 1137 dprintf(("new rx ptr=%04x\n", addr)); 1138#endif 1139 1140 1141 /* Store new rx pointer */ 1142 sc->sc_rx_ptr = addr; 1143 bus_space_write_2(iot, ioh, EA_8005_RX_END, sc->sc_rx_ptr >> 8); 1144 1145 /* Make sure the receiver is on */ 1146 bus_space_write_2(iot, ioh, EA_8005_COMMAND, 1147 sc->sc_command | EA_CMD_RX_ON); 1148 1149} 1150 1151 1152/* 1153 * Pass a packet up to the higher levels. 1154 */ 1155 1156static void 1157earead(struct seeq8005_softc *sc, int addr, int len) 1158{ 1159 register struct ether_header *eh; 1160 struct mbuf *m; 1161 struct ifnet *ifp; 1162 1163 ifp = &sc->sc_ethercom.ec_if; 1164 1165 /* Pull packet off interface. */ 1166 m = eaget(sc, addr, len, ifp); 1167 if (m == 0) 1168 return; 1169 eh = mtod(m, struct ether_header *); 1170 1171#ifdef EA_RX_DEBUG 1172 dprintf(("%s-->", ether_sprintf(eh->ether_shost))); 1173 dprintf(("%s\n", ether_sprintf(eh->ether_dhost))); 1174#endif 1175 1176#if NBPFILTER > 0 1177 /* 1178 * Check if there's a BPF listener on this interface. 1179 * If so, hand off the raw packet to bpf. 1180 */ 1181 if (ifp->if_bpf) { 1182 bpf_mtap(ifp->if_bpf, m); 1183 1184 /* 1185 * Note that the interface cannot be in promiscuous mode if 1186 * there are no BPF listeners. And if we are in promiscuous 1187 * mode, we have to check if this packet is really ours. 1188 */ 1189 if ((ifp->if_flags & IFF_PROMISC) && 1190 !ETHER_IS_MULTICAST(eh->ether_dhost) && 1191 bcmp(eh->ether_dhost, LLADDR(ifp->if_sadl), 1192 sizeof(eh->ether_dhost)) != 0) { 1193 m_freem(m); 1194 return; 1195 } 1196 } 1197#endif 1198 1199 (*ifp->if_input)(ifp, m); 1200} 1201 1202/* 1203 * Pull read data off a interface. Len is length of data, with local net 1204 * header stripped. We copy the data into mbufs. When full cluster sized 1205 * units are present we copy into clusters. 1206 */ 1207 1208struct mbuf * 1209eaget(struct seeq8005_softc *sc, int addr, int totlen, struct ifnet *ifp) 1210{ 1211 struct mbuf *top, **mp, *m; 1212 int len; 1213 u_int cp, epkt; 1214 1215 cp = addr; 1216 epkt = cp + totlen; 1217 1218 MGETHDR(m, M_DONTWAIT, MT_DATA); 1219 if (m == 0) 1220 return 0; 1221 m->m_pkthdr.rcvif = ifp; 1222 m->m_pkthdr.len = totlen; 1223 m->m_len = MHLEN; 1224 top = 0; 1225 mp = ⊤ 1226 1227 while (totlen > 0) { 1228 if (top) { 1229 MGET(m, M_DONTWAIT, MT_DATA); 1230 if (m == 0) { 1231 m_freem(top); 1232 return 0; 1233 } 1234 m->m_len = MLEN; 1235 } 1236 len = min(totlen, epkt - cp); 1237 if (len >= MINCLSIZE) { 1238 MCLGET(m, M_DONTWAIT); 1239 if (m->m_flags & M_EXT) 1240 m->m_len = len = min(len, MCLBYTES); 1241 else 1242 len = m->m_len; 1243 } else { 1244 /* 1245 * Place initial small packet/header at end of mbuf. 1246 */ 1247 if (len < m->m_len) { 1248 if (top == 0 && len + max_linkhdr <= m->m_len) 1249 m->m_data += max_linkhdr; 1250 m->m_len = len; 1251 } else 1252 len = m->m_len; 1253 } 1254 if (top == 0) { 1255 /* Make sure the payload is aligned */ 1256 caddr_t newdata = (caddr_t) 1257 ALIGN(m->m_data + sizeof(struct ether_header)) - 1258 sizeof(struct ether_header); 1259 len -= newdata - m->m_data; 1260 m->m_len = len; 1261 m->m_data = newdata; 1262 } 1263 ea_readbuf(sc, mtod(m, u_char *), 1264 cp < EA_BUFFER_SIZE ? cp : cp - EA_RX_BUFFER_SIZE, 1265 len); 1266 cp += len; 1267 *mp = m; 1268 mp = &m->m_next; 1269 totlen -= len; 1270 if (cp == epkt) 1271 cp = addr; 1272 } 1273 1274 return top; 1275} 1276 1277/* 1278 * Process an ioctl request. This code needs some work - it looks pretty ugly. 1279 */ 1280static int 1281ea_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1282{ 1283 struct seeq8005_softc *sc = ifp->if_softc; 1284 struct ifaddr *ifa = (struct ifaddr *)data; 1285/* struct ifreq *ifr = (struct ifreq *)data;*/ 1286 int s, error = 0; 1287 1288 s = splnet(); 1289 1290 switch (cmd) { 1291 1292 case SIOCSIFADDR: 1293 ifp->if_flags |= IFF_UP; 1294 dprintf(("if_flags=%08x\n", ifp->if_flags)); 1295 1296 switch (ifa->ifa_addr->sa_family) { 1297#ifdef INET 1298 case AF_INET: 1299 arp_ifinit(ifp, ifa); 1300 dprintf(("Interface ea is coming up (AF_INET)\n")); 1301 ea_init(sc); 1302 break; 1303#endif 1304#ifdef NS 1305 /* XXX - This code is probably wrong. */ 1306 case AF_NS: 1307 { 1308 register struct ns_addr *ina = &IA_SNS(ifa)->sns_addr; 1309 1310 if (ns_nullhost(*ina)) 1311 ina->x_host = 1312 *(union ns_host *)LLADDR(ifp->if_sadl); 1313 else 1314 bcopy(ina->x_host.c_host, 1315 LLADDR(ifp->if_sadl), ETHER_ADDR_LEN); 1316 /* Set new address. */ 1317 dprintf(("Interface ea is coming up (AF_NS)\n")); 1318 ea_init(sc); 1319 break; 1320 } 1321#endif 1322 default: 1323 dprintf(("Interface ea is coming up (default)\n")); 1324 ea_init(sc); 1325 break; 1326 } 1327 break; 1328 1329 case SIOCSIFFLAGS: 1330 dprintf(("if_flags=%08x\n", ifp->if_flags)); 1331 if ((ifp->if_flags & IFF_UP) == 0 && 1332 (ifp->if_flags & IFF_RUNNING) != 0) { 1333 /* 1334 * If interface is marked down and it is running, then 1335 * stop it. 1336 */ 1337 dprintf(("Interface ea is stopping\n")); 1338 ea_stop(sc); 1339 ifp->if_flags &= ~IFF_RUNNING; 1340 } else if ((ifp->if_flags & IFF_UP) != 0 && 1341 (ifp->if_flags & IFF_RUNNING) == 0) { 1342 /* 1343 * If interface is marked up and it is stopped, then 1344 * start it. 1345 */ 1346 dprintf(("Interface ea is restarting(1)\n")); 1347 ea_init(sc); 1348 } else { 1349 /* 1350 * Some other important flag might have changed, so 1351 * reset. 1352 */ 1353 dprintf(("Interface ea is reinitialising\n")); 1354 ea_reinit(sc); 1355 } 1356 break; 1357 1358 default: 1359 error = EINVAL; 1360 break; 1361 } 1362 1363 splx(s); 1364 return error; 1365} 1366 1367/* 1368 * Device timeout routine. 1369 * 1370 * Ok I am not sure exactly how the device timeout should work.... 1371 * Currently what will happens is that that the device timeout is only 1372 * set when a packet it received. This indicates we are on an active 1373 * network and thus we should expect more packets. If non arrive in 1374 * in the timeout period then we reinitialise as we may have jammed. 1375 * We zero the timeout at this point so that we don't end up with 1376 * an endless stream of timeouts if the network goes down. 1377 */ 1378 1379static void 1380ea_watchdog(struct ifnet *ifp) 1381{ 1382 struct seeq8005_softc *sc = ifp->if_softc; 1383 1384 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname); 1385 ifp->if_oerrors++; 1386 dprintf(("ea_watchdog: ")); 1387 dprintf(("st=%04x\n", 1388 bus_space_read_2(sc->sc_iot, sc->sc_ioh, EA_8005_STATUS))); 1389 1390 /* Kick the interface */ 1391 1392 ea_reinit(sc); 1393 1394/* ifp->if_timer = EA_TIMEOUT;*/ 1395 ifp->if_timer = 0; 1396} 1397 1398/* End of if_ea.c */ 1399