if_vx.c revision 331722
1/*- 2 * Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Herb Peyerl. 16 * 4. The name of Herb Peyerl may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * 31 */ 32 33#include <sys/cdefs.h> 34__FBSDID("$FreeBSD: stable/11/sys/dev/vx/if_vx.c 331722 2018-03-29 02:50:57Z eadler $"); 35 36/* 37 * Created from if_ep.c driver by Fred Gray (fgray@rice.edu) to support 38 * the 3c590 family. 39 */ 40 41/* 42 * Modified from the FreeBSD 1.1.5.1 version by: 43 * Andres Vega Garcia 44 * INRIA - Sophia Antipolis, France 45 * avega@sophia.inria.fr 46 */ 47 48/* 49 * Promiscuous mode added and interrupt logic slightly changed 50 * to reduce the number of adapter failures. Transceiver select 51 * logic changed to use value from EEPROM. Autoconfiguration 52 * features added. 53 * Done by: 54 * Serge Babkin 55 * Chelindbank (Chelyabinsk, Russia) 56 * babkin@hq.icb.chel.su 57 */ 58 59 60#include <sys/param.h> 61#include <sys/systm.h> 62#include <sys/sockio.h> 63#include <sys/kernel.h> 64#include <sys/malloc.h> 65#include <sys/mbuf.h> 66#include <sys/socket.h> 67 68#include <net/if.h> 69#include <net/if_var.h> 70 71#include <net/ethernet.h> 72#include <net/if_dl.h> 73#include <net/if_types.h> 74 75#include <machine/bus.h> 76 77#include <sys/bus.h> 78 79#include <net/bpf.h> 80 81#include <dev/vx/if_vxreg.h> 82#include <dev/vx/if_vxvar.h> 83 84#define ETHER_MAX_LEN 1518 85#define ETHER_ADDR_LEN 6 86#define ETHER_ALIGN 2 87 88static struct connector_entry { 89 int bit; 90 char *name; 91} conn_tab[VX_CONNECTORS] = { 92 93#define CONNECTOR_UTP 0 94 { 95 0x08, "utp" 96 }, 97#define CONNECTOR_AUI 1 98 { 99 0x20, "aui" 100 }, 101/* dummy */ 102 { 103 0, "???" 104 }, 105#define CONNECTOR_BNC 3 106 { 107 0x10, "bnc" 108 }, 109#define CONNECTOR_TX 4 110 { 111 0x02, "tx" 112 }, 113#define CONNECTOR_FX 5 114 { 115 0x04, "fx" 116 }, 117#define CONNECTOR_MII 6 118 { 119 0x40, "mii" 120 }, 121 { 122 0, "???" 123 } 124}; 125 126static void vx_txstat(struct vx_softc *); 127static int vx_status(struct vx_softc *); 128static void vx_init(void *); 129static void vx_init_locked(struct vx_softc *); 130static int vx_ioctl(struct ifnet *, u_long, caddr_t); 131static void vx_start(struct ifnet *); 132static void vx_start_locked(struct ifnet *); 133static void vx_watchdog(void *); 134static void vx_reset(struct vx_softc *); 135static void vx_read(struct vx_softc *); 136static struct mbuf *vx_get(struct vx_softc *, u_int); 137static void vx_mbuf_fill(void *); 138static void vx_mbuf_empty(struct vx_softc *); 139static void vx_setfilter(struct vx_softc *); 140static void vx_getlink(struct vx_softc *); 141static void vx_setlink(struct vx_softc *); 142 143int 144vx_attach(device_t dev) 145{ 146 struct vx_softc *sc = device_get_softc(dev); 147 struct ifnet *ifp; 148 int i; 149 u_char eaddr[6]; 150 151 ifp = sc->vx_ifp = if_alloc(IFT_ETHER); 152 if (ifp == NULL) { 153 device_printf(dev, "can not if_alloc()\n"); 154 return 0; 155 } 156 if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 157 158 mtx_init(&sc->vx_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 159 MTX_DEF); 160 callout_init_mtx(&sc->vx_callout, &sc->vx_mtx, 0); 161 callout_init_mtx(&sc->vx_watchdog, &sc->vx_mtx, 0); 162 GO_WINDOW(0); 163 CSR_WRITE_2(sc, VX_COMMAND, GLOBAL_RESET); 164 VX_BUSY_WAIT; 165 166 vx_getlink(sc); 167 168 /* 169 * Read the station address from the eeprom 170 */ 171 GO_WINDOW(0); 172 for (i = 0; i < 3; i++) { 173 int x; 174 175 if (vx_busy_eeprom(sc)) { 176 mtx_destroy(&sc->vx_mtx); 177 if_free(ifp); 178 return 0; 179 } 180 CSR_WRITE_2(sc, VX_W0_EEPROM_COMMAND, EEPROM_CMD_RD 181 | (EEPROM_OEM_ADDR0 + i)); 182 if (vx_busy_eeprom(sc)) { 183 mtx_destroy(&sc->vx_mtx); 184 if_free(ifp); 185 return 0; 186 } 187 x = CSR_READ_2(sc, VX_W0_EEPROM_DATA); 188 eaddr[(i << 1)] = x >> 8; 189 eaddr[(i << 1) + 1] = x; 190 } 191 192 ifp->if_snd.ifq_maxlen = ifqmaxlen; 193 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 194 ifp->if_start = vx_start; 195 ifp->if_ioctl = vx_ioctl; 196 ifp->if_init = vx_init; 197 ifp->if_softc = sc; 198 199 ether_ifattach(ifp, eaddr); 200 201 sc->vx_tx_start_thresh = 20; /* probably a good starting point. */ 202 203 VX_LOCK(sc); 204 vx_stop(sc); 205 VX_UNLOCK(sc); 206 207 return 1; 208} 209 210/* 211 * The order in here seems important. Otherwise we may not receive 212 * interrupts. ?! 213 */ 214static void 215vx_init(void *xsc) 216{ 217 struct vx_softc *sc = (struct vx_softc *)xsc; 218 219 VX_LOCK(sc); 220 vx_init_locked(sc); 221 VX_UNLOCK(sc); 222} 223 224static void 225vx_init_locked(struct vx_softc *sc) 226{ 227 struct ifnet *ifp = sc->vx_ifp; 228 int i; 229 230 VX_LOCK_ASSERT(sc); 231 232 VX_BUSY_WAIT; 233 234 GO_WINDOW(2); 235 236 for (i = 0; i < 6; i++) /* Reload the ether_addr. */ 237 CSR_WRITE_1(sc, VX_W2_ADDR_0 + i, IF_LLADDR(sc->vx_ifp)[i]); 238 239 CSR_WRITE_2(sc, VX_COMMAND, RX_RESET); 240 VX_BUSY_WAIT; 241 CSR_WRITE_2(sc, VX_COMMAND, TX_RESET); 242 VX_BUSY_WAIT; 243 244 GO_WINDOW(1); /* Window 1 is operating window */ 245 for (i = 0; i < 31; i++) 246 CSR_READ_1(sc, VX_W1_TX_STATUS); 247 248 CSR_WRITE_2(sc, VX_COMMAND, SET_RD_0_MASK | S_CARD_FAILURE | 249 S_RX_COMPLETE | S_TX_COMPLETE | S_TX_AVAIL); 250 CSR_WRITE_2(sc, VX_COMMAND, SET_INTR_MASK | S_CARD_FAILURE | 251 S_RX_COMPLETE | S_TX_COMPLETE | S_TX_AVAIL); 252 253 /* 254 * Attempt to get rid of any stray interrupts that occurred during 255 * configuration. On the i386 this isn't possible because one may 256 * already be queued. However, a single stray interrupt is 257 * unimportant. 258 */ 259 CSR_WRITE_2(sc, VX_COMMAND, ACK_INTR | 0xff); 260 261 vx_setfilter(sc); 262 vx_setlink(sc); 263 264 CSR_WRITE_2(sc, VX_COMMAND, RX_ENABLE); 265 CSR_WRITE_2(sc, VX_COMMAND, TX_ENABLE); 266 267 vx_mbuf_fill(sc); 268 269 /* Interface is now `running', with no output active. */ 270 ifp->if_drv_flags |= IFF_DRV_RUNNING; 271 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 272 callout_reset(&sc->vx_watchdog, hz, vx_watchdog, sc); 273 274 /* Attempt to start output, if any. */ 275 vx_start_locked(ifp); 276} 277 278static void 279vx_setfilter(struct vx_softc *sc) 280{ 281 struct ifnet *ifp = sc->vx_ifp; 282 283 VX_LOCK_ASSERT(sc); 284 GO_WINDOW(1); /* Window 1 is operating window */ 285 CSR_WRITE_2(sc, VX_COMMAND, SET_RX_FILTER | 286 FIL_INDIVIDUAL | FIL_BRDCST | FIL_MULTICAST | 287 ((ifp->if_flags & IFF_PROMISC) ? FIL_PROMISC : 0)); 288} 289 290static void 291vx_getlink(struct vx_softc *sc) 292{ 293 int n, k; 294 295 GO_WINDOW(3); 296 sc->vx_connectors = CSR_READ_2(sc, VX_W3_RESET_OPT) & 0x7f; 297 for (n = 0, k = 0; k < VX_CONNECTORS; k++) { 298 if (sc->vx_connectors & conn_tab[k].bit) { 299 if (n > 0) 300 printf("/"); 301 printf("%s", conn_tab[k].name); 302 n++; 303 } 304 } 305 if (sc->vx_connectors == 0) { 306 printf("no connectors!\n"); 307 return; 308 } 309 GO_WINDOW(3); 310 sc->vx_connector = 311 (CSR_READ_4(sc, VX_W3_INTERNAL_CFG) & INTERNAL_CONNECTOR_MASK) 312 >> INTERNAL_CONNECTOR_BITS; 313 if (sc->vx_connector & 0x10) { 314 sc->vx_connector &= 0x0f; 315 printf("[*%s*]", conn_tab[(int)sc->vx_connector].name); 316 printf(": disable 'auto select' with DOS util!\n"); 317 } else { 318 printf("[*%s*]\n", conn_tab[(int)sc->vx_connector].name); 319 } 320} 321 322static void 323vx_setlink(struct vx_softc *sc) 324{ 325 struct ifnet *ifp = sc->vx_ifp; 326 int i, j, k; 327 char *reason, *warning; 328 static int prev_flags; 329 static signed char prev_conn = -1; 330 331 VX_LOCK_ASSERT(sc); 332 if (prev_conn == -1) 333 prev_conn = sc->vx_connector; 334 335 /* 336 * S.B. 337 * 338 * Now behavior was slightly changed: 339 * 340 * if any of flags link[0-2] is used and its connector is 341 * physically present the following connectors are used: 342 * 343 * link0 - AUI * highest precedence 344 * link1 - BNC 345 * link2 - UTP * lowest precedence 346 * 347 * If none of them is specified then 348 * connector specified in the EEPROM is used 349 * (if present on card or UTP if not). 350 */ 351 i = sc->vx_connector; /* default in EEPROM */ 352 reason = "default"; 353 warning = NULL; 354 355 if (ifp->if_flags & IFF_LINK0) { 356 if (sc->vx_connectors & conn_tab[CONNECTOR_AUI].bit) { 357 i = CONNECTOR_AUI; 358 reason = "link0"; 359 } else { 360 warning = "aui not present! (link0)"; 361 } 362 } else if (ifp->if_flags & IFF_LINK1) { 363 if (sc->vx_connectors & conn_tab[CONNECTOR_BNC].bit) { 364 i = CONNECTOR_BNC; 365 reason = "link1"; 366 } else { 367 warning = "bnc not present! (link1)"; 368 } 369 } else if (ifp->if_flags & IFF_LINK2) { 370 if (sc->vx_connectors & conn_tab[CONNECTOR_UTP].bit) { 371 i = CONNECTOR_UTP; 372 reason = "link2"; 373 } else { 374 warning = "utp not present! (link2)"; 375 } 376 } else if ((sc->vx_connectors & conn_tab[(int)sc->vx_connector].bit) == 0) { 377 warning = "strange connector type in EEPROM."; 378 reason = "forced"; 379 i = CONNECTOR_UTP; 380 } 381 /* Avoid unnecessary message. */ 382 k = (prev_flags ^ ifp->if_flags) & (IFF_LINK0 | IFF_LINK1 | IFF_LINK2); 383 if ((k != 0) || (prev_conn != i)) { 384 if (warning != NULL) 385 if_printf(ifp, "warning: %s\n", warning); 386 if_printf(ifp, "selected %s. (%s)\n", conn_tab[i].name, reason); 387 } 388 /* Set the selected connector. */ 389 GO_WINDOW(3); 390 j = CSR_READ_4(sc, VX_W3_INTERNAL_CFG) & ~INTERNAL_CONNECTOR_MASK; 391 CSR_WRITE_4(sc, VX_W3_INTERNAL_CFG, j | (i << INTERNAL_CONNECTOR_BITS)); 392 393 /* First, disable all. */ 394 CSR_WRITE_2(sc, VX_COMMAND, STOP_TRANSCEIVER); 395 DELAY(800); 396 GO_WINDOW(4); 397 CSR_WRITE_2(sc, VX_W4_MEDIA_TYPE, 0); 398 399 /* Second, enable the selected one. */ 400 switch (i) { 401 case CONNECTOR_UTP: 402 GO_WINDOW(4); 403 CSR_WRITE_2(sc, VX_W4_MEDIA_TYPE, ENABLE_UTP); 404 break; 405 case CONNECTOR_BNC: 406 CSR_WRITE_2(sc, VX_COMMAND, START_TRANSCEIVER); 407 DELAY(800); 408 break; 409 case CONNECTOR_TX: 410 case CONNECTOR_FX: 411 GO_WINDOW(4); 412 CSR_WRITE_2(sc, VX_W4_MEDIA_TYPE, LINKBEAT_ENABLE); 413 break; 414 default: /* AUI and MII fall here */ 415 break; 416 } 417 GO_WINDOW(1); 418 419 prev_flags = ifp->if_flags; 420 prev_conn = i; 421} 422 423static void 424vx_start(struct ifnet *ifp) 425{ 426 struct vx_softc *sc = ifp->if_softc; 427 428 VX_LOCK(sc); 429 vx_start_locked(ifp); 430 VX_UNLOCK(sc); 431} 432 433static void 434vx_start_locked(struct ifnet *ifp) 435{ 436 struct vx_softc *sc = ifp->if_softc; 437 struct mbuf *m; 438 int len, pad; 439 440 VX_LOCK_ASSERT(sc); 441 442 /* Don't transmit if interface is busy or not running */ 443 if ((sc->vx_ifp->if_drv_flags & 444 (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != IFF_DRV_RUNNING) 445 return; 446 447startagain: 448 /* Sneak a peek at the next packet */ 449 m = ifp->if_snd.ifq_head; 450 if (m == NULL) { 451 return; 452 } 453 /* We need to use m->m_pkthdr.len, so require the header */ 454 M_ASSERTPKTHDR(m); 455 len = m->m_pkthdr.len; 456 457 pad = (4 - len) & 3; 458 459 /* 460 * The 3c509 automatically pads short packets to minimum ethernet 461 * length, but we drop packets that are too large. Perhaps we should 462 * truncate them instead? 463 */ 464 if (len + pad > ETHER_MAX_LEN) { 465 /* packet is obviously too large: toss it */ 466 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 467 IF_DEQUEUE(&ifp->if_snd, m); 468 m_freem(m); 469 goto readcheck; 470 } 471 VX_BUSY_WAIT; 472 if (CSR_READ_2(sc, VX_W1_FREE_TX) < len + pad + 4) { 473 CSR_WRITE_2(sc, VX_COMMAND, 474 SET_TX_AVAIL_THRESH | ((len + pad + 4) >> 2)); 475 /* not enough room in FIFO - make sure */ 476 if (CSR_READ_2(sc, VX_W1_FREE_TX) < len + pad + 4) { 477 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 478 sc->vx_timer = 1; 479 return; 480 } 481 } 482 CSR_WRITE_2(sc, VX_COMMAND, SET_TX_AVAIL_THRESH | (8188 >> 2)); 483 IF_DEQUEUE(&ifp->if_snd, m); 484 if (m == NULL) /* not really needed */ 485 return; 486 487 VX_BUSY_WAIT; 488 CSR_WRITE_2(sc, VX_COMMAND, SET_TX_START_THRESH | 489 ((len / 4 + sc->vx_tx_start_thresh) >> 2)); 490 491 BPF_MTAP(sc->vx_ifp, m); 492 493 /* 494 * Do the output at splhigh() so that an interrupt from another device 495 * won't cause a FIFO underrun. 496 * 497 * XXX: Can't enforce that anymore. 498 */ 499 500 CSR_WRITE_4(sc, VX_W1_TX_PIO_WR_1, len | TX_INDICATE); 501 502 while (m) { 503 if (m->m_len > 3) 504 bus_space_write_multi_4(sc->vx_bst, sc->vx_bsh, 505 VX_W1_TX_PIO_WR_1, (u_int32_t *)mtod(m, caddr_t), 506 m->m_len / 4); 507 if (m->m_len & 3) 508 bus_space_write_multi_1(sc->vx_bst, sc->vx_bsh, 509 VX_W1_TX_PIO_WR_1, 510 mtod(m, caddr_t) + (m->m_len & ~3), m->m_len & 3); 511 m = m_free(m); 512 } 513 while (pad--) 514 CSR_WRITE_1(sc, VX_W1_TX_PIO_WR_1, 0); /* Padding */ 515 516 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); 517 sc->vx_timer = 1; 518 519readcheck: 520 if ((CSR_READ_2(sc, VX_W1_RX_STATUS) & ERR_INCOMPLETE) == 0) { 521 /* We received a complete packet. */ 522 523 if ((CSR_READ_2(sc, VX_STATUS) & S_INTR_LATCH) == 0) { 524 /* 525 * No interrupt, read the packet and continue 526 * Is this supposed to happen? Is my motherboard 527 * completely busted? 528 */ 529 vx_read(sc); 530 } else 531 /* 532 * Got an interrupt, return so that it gets 533 * serviced. 534 */ 535 return; 536 } else { 537 /* Check if we are stuck and reset [see XXX comment] */ 538 if (vx_status(sc)) { 539 if (ifp->if_flags & IFF_DEBUG) 540 if_printf(ifp, "adapter reset\n"); 541 vx_reset(sc); 542 } 543 } 544 545 goto startagain; 546} 547 548/* 549 * XXX: The 3c509 card can get in a mode where both the fifo status bit 550 * FIFOS_RX_OVERRUN and the status bit ERR_INCOMPLETE are set 551 * We detect this situation and we reset the adapter. 552 * It happens at times when there is a lot of broadcast traffic 553 * on the cable (once in a blue moon). 554 */ 555static int 556vx_status(struct vx_softc *sc) 557{ 558 struct ifnet *ifp; 559 int fifost; 560 561 VX_LOCK_ASSERT(sc); 562 563 /* 564 * Check the FIFO status and act accordingly 565 */ 566 GO_WINDOW(4); 567 fifost = CSR_READ_2(sc, VX_W4_FIFO_DIAG); 568 GO_WINDOW(1); 569 570 ifp = sc->vx_ifp; 571 if (fifost & FIFOS_RX_UNDERRUN) { 572 if (ifp->if_flags & IFF_DEBUG) 573 if_printf(ifp, "RX underrun\n"); 574 vx_reset(sc); 575 return 0; 576 } 577 if (fifost & FIFOS_RX_STATUS_OVERRUN) { 578 if (ifp->if_flags & IFF_DEBUG) 579 if_printf(ifp, "RX Status overrun\n"); 580 return 1; 581 } 582 if (fifost & FIFOS_RX_OVERRUN) { 583 if (ifp->if_flags & IFF_DEBUG) 584 if_printf(ifp, "RX overrun\n"); 585 return 1; 586 } 587 if (fifost & FIFOS_TX_OVERRUN) { 588 if (ifp->if_flags & IFF_DEBUG) 589 if_printf(ifp, "TX overrun\n"); 590 vx_reset(sc); 591 return 0; 592 } 593 return 0; 594} 595 596static void 597vx_txstat(struct vx_softc *sc) 598{ 599 struct ifnet *ifp; 600 int i; 601 602 VX_LOCK_ASSERT(sc); 603 604 /* 605 * We need to read+write TX_STATUS until we get a 0 status 606 * in order to turn off the interrupt flag. 607 */ 608 ifp = sc->vx_ifp; 609 while ((i = CSR_READ_1(sc, VX_W1_TX_STATUS)) & TXS_COMPLETE) { 610 CSR_WRITE_1(sc, VX_W1_TX_STATUS, 0x0); 611 612 if (i & TXS_JABBER) { 613 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 614 if (ifp->if_flags & IFF_DEBUG) 615 if_printf(ifp, "jabber (%x)\n", i); 616 vx_reset(sc); 617 } else if (i & TXS_UNDERRUN) { 618 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 619 if (ifp->if_flags & IFF_DEBUG) 620 if_printf(ifp, "fifo underrun (%x) @%d\n", i, 621 sc->vx_tx_start_thresh); 622 if (sc->vx_tx_succ_ok < 100) 623 sc->vx_tx_start_thresh = 624 min(ETHER_MAX_LEN, 625 sc->vx_tx_start_thresh + 20); 626 sc->vx_tx_succ_ok = 0; 627 vx_reset(sc); 628 } else if (i & TXS_MAX_COLLISION) { 629 if_inc_counter(ifp, IFCOUNTER_COLLISIONS, 1); 630 CSR_WRITE_2(sc, VX_COMMAND, TX_ENABLE); 631 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 632 } else 633 sc->vx_tx_succ_ok = (sc->vx_tx_succ_ok + 1) & 127; 634 } 635} 636 637void 638vx_intr(void *voidsc) 639{ 640 short status; 641 struct vx_softc *sc = voidsc; 642 struct ifnet *ifp = sc->vx_ifp; 643 644 VX_LOCK(sc); 645 for (;;) { 646 CSR_WRITE_2(sc, VX_COMMAND, C_INTR_LATCH); 647 648 status = CSR_READ_2(sc, VX_STATUS); 649 650 if ((status & (S_TX_COMPLETE | S_TX_AVAIL | 651 S_RX_COMPLETE | S_CARD_FAILURE)) == 0) 652 break; 653 654 /* 655 * Acknowledge any interrupts. It's important that we do this 656 * first, since there would otherwise be a race condition. 657 * Due to the i386 interrupt queueing, we may get spurious 658 * interrupts occasionally. 659 */ 660 CSR_WRITE_2(sc, VX_COMMAND, ACK_INTR | status); 661 662 if (status & S_RX_COMPLETE) 663 vx_read(sc); 664 if (status & S_TX_AVAIL) { 665 sc->vx_timer = 0; 666 sc->vx_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 667 vx_start_locked(sc->vx_ifp); 668 } 669 if (status & S_CARD_FAILURE) { 670 if_printf(ifp, "adapter failure (%x)\n", status); 671 sc->vx_timer = 0; 672 vx_reset(sc); 673 break; 674 } 675 if (status & S_TX_COMPLETE) { 676 sc->vx_timer = 0; 677 vx_txstat(sc); 678 vx_start_locked(ifp); 679 } 680 } 681 VX_UNLOCK(sc); 682 683 /* no more interrupts */ 684 return; 685} 686 687static void 688vx_read(struct vx_softc *sc) 689{ 690 struct ifnet *ifp = sc->vx_ifp; 691 struct mbuf *m; 692 struct ether_header *eh; 693 u_int len; 694 695 VX_LOCK_ASSERT(sc); 696 len = CSR_READ_2(sc, VX_W1_RX_STATUS); 697again: 698 699 if (ifp->if_flags & IFF_DEBUG) { 700 int err = len & ERR_MASK; 701 char *s = NULL; 702 703 if (len & ERR_INCOMPLETE) 704 s = "incomplete packet"; 705 else if (err == ERR_OVERRUN) 706 s = "packet overrun"; 707 else if (err == ERR_RUNT) 708 s = "runt packet"; 709 else if (err == ERR_ALIGNMENT) 710 s = "bad alignment"; 711 else if (err == ERR_CRC) 712 s = "bad crc"; 713 else if (err == ERR_OVERSIZE) 714 s = "oversized packet"; 715 else if (err == ERR_DRIBBLE) 716 s = "dribble bits"; 717 718 if (s) 719 if_printf(ifp, "%s\n", s); 720 } 721 if (len & ERR_INCOMPLETE) 722 return; 723 724 if (len & ERR_RX) { 725 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 726 goto abort; 727 } 728 len &= RX_BYTES_MASK; /* Lower 11 bits = RX bytes. */ 729 730 /* Pull packet off interface. */ 731 m = vx_get(sc, len); 732 if (m == NULL) { 733 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 734 goto abort; 735 } 736 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); 737 738 { 739 struct mbuf *m0; 740 741 m0 = m_devget(mtod(m, char *), m->m_pkthdr.len, ETHER_ALIGN, 742 ifp, NULL); 743 if (m0 == NULL) { 744 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 745 goto abort; 746 } 747 m_freem(m); 748 m = m0; 749 } 750 751 /* We assume the header fit entirely in one mbuf. */ 752 eh = mtod(m, struct ether_header *); 753 754 /* 755 * XXX: Some cards seem to be in promiscuous mode all the time. 756 * we need to make sure we only get our own stuff always. 757 * bleah! 758 */ 759 760 if (!(ifp->if_flags & IFF_PROMISC) 761 && (eh->ether_dhost[0] & 1) == 0 /* !mcast and !bcast */ 762 && bcmp(eh->ether_dhost, IF_LLADDR(sc->vx_ifp), 763 ETHER_ADDR_LEN) != 0) { 764 m_freem(m); 765 return; 766 } 767 VX_UNLOCK(sc); 768 (*ifp->if_input)(ifp, m); 769 VX_LOCK(sc); 770 771 /* 772 * In periods of high traffic we can actually receive enough 773 * packets so that the fifo overrun bit will be set at this point, 774 * even though we just read a packet. In this case we 775 * are not going to receive any more interrupts. We check for 776 * this condition and read again until the fifo is not full. 777 * We could simplify this test by not using vx_status(), but 778 * rechecking the RX_STATUS register directly. This test could 779 * result in unnecessary looping in cases where there is a new 780 * packet but the fifo is not full, but it will not fix the 781 * stuck behavior. 782 * 783 * Even with this improvement, we still get packet overrun errors 784 * which are hurting performance. Maybe when I get some more time 785 * I'll modify vx_read() so that it can handle RX_EARLY interrupts. 786 */ 787 if (vx_status(sc)) { 788 len = CSR_READ_2(sc, VX_W1_RX_STATUS); 789 /* Check if we are stuck and reset [see XXX comment] */ 790 if (len & ERR_INCOMPLETE) { 791 if (ifp->if_flags & IFF_DEBUG) 792 if_printf(ifp, "adapter reset\n"); 793 vx_reset(sc); 794 return; 795 } 796 goto again; 797 } 798 return; 799 800abort: 801 CSR_WRITE_2(sc, VX_COMMAND, RX_DISCARD_TOP_PACK); 802} 803 804static struct mbuf * 805vx_get(struct vx_softc *sc, u_int totlen) 806{ 807 struct ifnet *ifp = sc->vx_ifp; 808 struct mbuf *top, **mp, *m; 809 int len; 810 811 VX_LOCK_ASSERT(sc); 812 m = sc->vx_mb[sc->vx_next_mb]; 813 sc->vx_mb[sc->vx_next_mb] = NULL; 814 if (m == NULL) { 815 MGETHDR(m, M_NOWAIT, MT_DATA); 816 if (m == NULL) 817 return NULL; 818 } else { 819 /* If the queue is no longer full, refill. */ 820 if (sc->vx_last_mb == sc->vx_next_mb && 821 sc->vx_buffill_pending == 0) { 822 callout_reset(&sc->vx_callout, hz / 100, vx_mbuf_fill, 823 sc); 824 sc->vx_buffill_pending = 1; 825 } 826 /* Convert one of our saved mbuf's. */ 827 sc->vx_next_mb = (sc->vx_next_mb + 1) % MAX_MBS; 828 m->m_data = m->m_pktdat; 829 m->m_flags = M_PKTHDR; 830 bzero(&m->m_pkthdr, sizeof(m->m_pkthdr)); 831 } 832 m->m_pkthdr.rcvif = ifp; 833 m->m_pkthdr.len = totlen; 834 len = MHLEN; 835 top = NULL; 836 mp = ⊤ 837 838 /* 839 * We read the packet at splhigh() so that an interrupt from another 840 * device doesn't cause the card's buffer to overflow while we're 841 * reading it. We may still lose packets at other times. 842 * 843 * XXX: Can't enforce this anymore. 844 */ 845 846 /* 847 * Since we don't set allowLargePackets bit in MacControl register, 848 * we can assume that totlen <= 1500bytes. 849 * The while loop will be performed iff we have a packet with 850 * MLEN < m_len < MINCLSIZE. 851 */ 852 while (totlen > 0) { 853 if (top) { 854 m = sc->vx_mb[sc->vx_next_mb]; 855 sc->vx_mb[sc->vx_next_mb] = NULL; 856 if (m == NULL) { 857 MGET(m, M_NOWAIT, MT_DATA); 858 if (m == NULL) { 859 m_freem(top); 860 return NULL; 861 } 862 } else { 863 sc->vx_next_mb = (sc->vx_next_mb + 1) % MAX_MBS; 864 } 865 len = MLEN; 866 } 867 if (totlen >= MINCLSIZE) { 868 if (MCLGET(m, M_NOWAIT)) 869 len = MCLBYTES; 870 } 871 len = min(totlen, len); 872 if (len > 3) 873 bus_space_read_multi_4(sc->vx_bst, sc->vx_bsh, 874 VX_W1_RX_PIO_RD_1, mtod(m, u_int32_t *), len / 4); 875 if (len & 3) { 876 bus_space_read_multi_1(sc->vx_bst, sc->vx_bsh, 877 VX_W1_RX_PIO_RD_1, mtod(m, u_int8_t *) + (len & ~3), 878 len & 3); 879 } 880 m->m_len = len; 881 totlen -= len; 882 *mp = m; 883 mp = &m->m_next; 884 } 885 886 CSR_WRITE_2(sc, VX_COMMAND, RX_DISCARD_TOP_PACK); 887 888 return top; 889} 890 891 892static int 893vx_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 894{ 895 struct vx_softc *sc = ifp->if_softc; 896 struct ifreq *ifr = (struct ifreq *) data; 897 int error = 0; 898 899 switch (cmd) { 900 case SIOCSIFFLAGS: 901 VX_LOCK(sc); 902 if ((ifp->if_flags & IFF_UP) == 0 && 903 (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) { 904 /* 905 * If interface is marked up and it is stopped, then 906 * start it. 907 */ 908 vx_stop(sc); 909 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 910 } else if ((ifp->if_flags & IFF_UP) != 0 && 911 (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { 912 /* 913 * If interface is marked up and it is stopped, then 914 * start it. 915 */ 916 vx_init_locked(sc); 917 } else { 918 /* 919 * deal with flags changes: 920 * IFF_MULTICAST, IFF_PROMISC, 921 * IFF_LINK0, IFF_LINK1, 922 */ 923 vx_setfilter(sc); 924 vx_setlink(sc); 925 } 926 VX_UNLOCK(sc); 927 break; 928 929 case SIOCSIFMTU: 930 /* 931 * Set the interface MTU. 932 */ 933 VX_LOCK(sc); 934 if (ifr->ifr_mtu > ETHERMTU) { 935 error = EINVAL; 936 } else { 937 ifp->if_mtu = ifr->ifr_mtu; 938 } 939 VX_UNLOCK(sc); 940 break; 941 942 case SIOCADDMULTI: 943 case SIOCDELMULTI: 944 /* 945 * Multicast list has changed; set the hardware filter 946 * accordingly. 947 */ 948 VX_LOCK(sc); 949 vx_reset(sc); 950 VX_UNLOCK(sc); 951 error = 0; 952 break; 953 954 955 default: 956 error = ether_ioctl(ifp, cmd, data); 957 break; 958 } 959 960 return (error); 961} 962 963static void 964vx_reset(struct vx_softc *sc) 965{ 966 967 VX_LOCK_ASSERT(sc); 968 vx_stop(sc); 969 vx_init_locked(sc); 970} 971 972static void 973vx_watchdog(void *arg) 974{ 975 struct vx_softc *sc; 976 struct ifnet *ifp; 977 978 sc = arg; 979 VX_LOCK_ASSERT(sc); 980 callout_reset(&sc->vx_watchdog, hz, vx_watchdog, sc); 981 if (sc->vx_timer == 0 || --sc->vx_timer > 0) 982 return; 983 984 ifp = sc->vx_ifp; 985 if (ifp->if_flags & IFF_DEBUG) 986 if_printf(ifp, "device timeout\n"); 987 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 988 vx_start_locked(ifp); 989 vx_intr(sc); 990} 991 992void 993vx_stop(struct vx_softc *sc) 994{ 995 996 VX_LOCK_ASSERT(sc); 997 sc->vx_timer = 0; 998 callout_stop(&sc->vx_watchdog); 999 1000 CSR_WRITE_2(sc, VX_COMMAND, RX_DISABLE); 1001 CSR_WRITE_2(sc, VX_COMMAND, RX_DISCARD_TOP_PACK); 1002 VX_BUSY_WAIT; 1003 CSR_WRITE_2(sc, VX_COMMAND, TX_DISABLE); 1004 CSR_WRITE_2(sc, VX_COMMAND, STOP_TRANSCEIVER); 1005 DELAY(800); 1006 CSR_WRITE_2(sc, VX_COMMAND, RX_RESET); 1007 VX_BUSY_WAIT; 1008 CSR_WRITE_2(sc, VX_COMMAND, TX_RESET); 1009 VX_BUSY_WAIT; 1010 CSR_WRITE_2(sc, VX_COMMAND, C_INTR_LATCH); 1011 CSR_WRITE_2(sc, VX_COMMAND, SET_RD_0_MASK); 1012 CSR_WRITE_2(sc, VX_COMMAND, SET_INTR_MASK); 1013 CSR_WRITE_2(sc, VX_COMMAND, SET_RX_FILTER); 1014 1015 vx_mbuf_empty(sc); 1016} 1017 1018int 1019vx_busy_eeprom(struct vx_softc *sc) 1020{ 1021 int j, i = 100; 1022 1023 while (i--) { 1024 j = CSR_READ_2(sc, VX_W0_EEPROM_COMMAND); 1025 if (j & EEPROM_BUSY) 1026 DELAY(100); 1027 else 1028 break; 1029 } 1030 if (!i) { 1031 if_printf(sc->vx_ifp, "eeprom failed to come ready\n"); 1032 return (1); 1033 } 1034 return (0); 1035} 1036 1037static void 1038vx_mbuf_fill(void *sp) 1039{ 1040 struct vx_softc *sc = (struct vx_softc *)sp; 1041 int i; 1042 1043 VX_LOCK_ASSERT(sc); 1044 i = sc->vx_last_mb; 1045 do { 1046 if (sc->vx_mb[i] == NULL) 1047 MGET(sc->vx_mb[i], M_NOWAIT, MT_DATA); 1048 if (sc->vx_mb[i] == NULL) 1049 break; 1050 i = (i + 1) % MAX_MBS; 1051 } while (i != sc->vx_next_mb); 1052 sc->vx_last_mb = i; 1053 /* If the queue was not filled, try again. */ 1054 if (sc->vx_last_mb != sc->vx_next_mb) { 1055 callout_reset(&sc->vx_callout, hz / 100, vx_mbuf_fill, sc); 1056 sc->vx_buffill_pending = 1; 1057 } else { 1058 sc->vx_buffill_pending = 0; 1059 } 1060} 1061 1062static void 1063vx_mbuf_empty(struct vx_softc *sc) 1064{ 1065 int i; 1066 1067 VX_LOCK_ASSERT(sc); 1068 for (i = 0; i < MAX_MBS; i++) { 1069 if (sc->vx_mb[i]) { 1070 m_freem(sc->vx_mb[i]); 1071 sc->vx_mb[i] = NULL; 1072 } 1073 } 1074 sc->vx_last_mb = sc->vx_next_mb = 0; 1075 if (sc->vx_buffill_pending != 0) 1076 callout_stop(&sc->vx_callout); 1077} 1078