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