1 /* $OpenBSD: am7990.c,v 1.44 2009/08/10 20:29:54 deraadt Exp $ */ 2 /* $NetBSD: am7990.c,v 1.22 1996/10/13 01:37:19 christos Exp $ */ 3 4 /*- 5 * Copyright (c) 1995 Charles M. Hannum. All rights reserved. 6 * Copyright (c) 1992, 1993 7 * The Regents of the University of California. All rights reserved. 8 * 9 * This code is derived from software contributed to Berkeley by 10 * Ralph Campbell and Rick Macklem. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * @(#)if_le.c 8.2 (Berkeley) 11/16/93 37 */ 38 39 #include "bpfilter.h" 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/mbuf.h> 44 #include <sys/syslog.h> 45 #include <sys/socket.h> 46 #include <sys/device.h> 47 #include <sys/malloc.h> 48 #include <sys/ioctl.h> 49 #include <sys/errno.h> 50 51 #include <net/if.h> 52 #include <net/if_media.h> 53 54 #ifdef INET 55 #include <netinet/in.h> 56 #include <netinet/if_ether.h> 57 #include <netinet/in_systm.h> 58 #include <netinet/in_var.h> 59 #include <netinet/ip.h> 60 #endif 61 62 #if NBPFILTER > 0 63 #include <net/bpf.h> 64 #endif 65 66 #include <dev/ic/am7990reg.h> 67 #include <dev/ic/am7990var.h> 68 69 #ifdef LEDEBUG 70 void am7990_recv_print(struct am7990_softc *, int); 71 void am7990_xmit_print(struct am7990_softc *, int); 72 #endif 73 74 integrate void am7990_rint(struct am7990_softc *); 75 integrate void am7990_tint(struct am7990_softc *); 76 77 integrate int am7990_put(struct am7990_softc *, int, struct mbuf *); 78 integrate struct mbuf *am7990_get(struct am7990_softc *, int, int); 79 integrate void am7990_read(struct am7990_softc *, int, int); 80 81 #define ifp (&sc->sc_arpcom.ac_if) 82 83 #if 0 /* XXX what do we do about this?! --thorpej */ 84 static inline u_int16_t ether_cmp(void *, void *); 85 86 /* 87 * Compare two Ether/802 addresses for equality, inlined and 88 * unrolled for speed. I'd love to have an inline assembler 89 * version of this... XXX: Who wanted that? mycroft? 90 * I wrote one, but the following is just as efficient. 91 * This expands to 10 short m68k instructions! -gwr 92 * Note: use this like bcmp() 93 */ 94 static inline u_short 95 ether_cmp(one, two) 96 void *one, *two; 97 { 98 register u_int16_t *a = (u_short *) one; 99 register u_int16_t *b = (u_short *) two; 100 register u_int16_t diff; 101 102 diff = *a++ - *b++; 103 diff |= *a++ - *b++; 104 diff |= *a++ - *b++; 105 106 return (diff); 107 } 108 109 #define ETHER_CMP ether_cmp 110 #endif /* XXX */ 111 112 #ifndef ETHER_CMP 113 #define ETHER_CMP(a, b) bcmp((a), (b), ETHER_ADDR_LEN) 114 #endif 115 116 /* 117 * am7990 configuration driver. Attachments are provided by 118 * machine-dependent driver front-ends. 119 */ 120 struct cfdriver le_cd = { 121 NULL, "le", DV_IFNET 122 }; 123 124 void 125 am7990_config(sc) 126 struct am7990_softc *sc; 127 { 128 int mem; 129 130 /* Make sure the chip is stopped. */ 131 am7990_stop(sc); 132 133 /* Initialize ifnet structure. */ 134 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); 135 ifp->if_softc = sc; 136 ifp->if_start = am7990_start; 137 ifp->if_ioctl = am7990_ioctl; 138 ifp->if_watchdog = am7990_watchdog; 139 ifp->if_flags = 140 IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST; 141 #ifdef LANCE_REVC_BUG 142 ifp->if_flags &= ~IFF_MULTICAST; 143 #endif 144 ifp->if_baudrate = IF_Mbps(10); 145 IFQ_SET_READY(&ifp->if_snd); 146 147 ifp->if_capabilities = IFCAP_VLAN_MTU; 148 149 /* Attach the interface. */ 150 if_attach(ifp); 151 ether_ifattach(ifp); 152 153 if (sc->sc_memsize > 262144) 154 sc->sc_memsize = 262144; 155 156 switch (sc->sc_memsize) { 157 case 8192: 158 sc->sc_nrbuf = 4; 159 sc->sc_ntbuf = 1; 160 break; 161 case 16384: 162 sc->sc_nrbuf = 8; 163 sc->sc_ntbuf = 2; 164 break; 165 case 32768: 166 sc->sc_nrbuf = 16; 167 sc->sc_ntbuf = 4; 168 break; 169 case 65536: 170 sc->sc_nrbuf = 32; 171 sc->sc_ntbuf = 8; 172 break; 173 case 131072: 174 sc->sc_nrbuf = 64; 175 sc->sc_ntbuf = 16; 176 break; 177 case 262144: 178 sc->sc_nrbuf = 128; 179 sc->sc_ntbuf = 32; 180 break; 181 default: 182 panic("am7990_config: weird memory size %lu", sc->sc_memsize); 183 } 184 185 printf(": address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr)); 186 printf("%s: %d receive buffers, %d transmit buffers\n", 187 sc->sc_dev.dv_xname, sc->sc_nrbuf, sc->sc_ntbuf); 188 189 mem = 0; 190 sc->sc_initaddr = mem; 191 mem += sizeof(struct leinit); 192 sc->sc_rmdaddr = mem; 193 mem += sizeof(struct lermd) * sc->sc_nrbuf; 194 sc->sc_tmdaddr = mem; 195 mem += sizeof(struct letmd) * sc->sc_ntbuf; 196 sc->sc_rbufaddr = mem; 197 mem += ETHER_MAX_DIX_LEN * sc->sc_nrbuf; 198 sc->sc_tbufaddr = mem; 199 mem += ETHER_MAX_DIX_LEN * sc->sc_ntbuf; 200 #ifdef notyet 201 if (mem > ...) 202 panic(...); 203 #endif 204 } 205 206 void 207 am7990_reset(sc) 208 struct am7990_softc *sc; 209 { 210 int s; 211 212 s = splnet(); 213 am7990_init(sc); 214 splx(s); 215 } 216 217 /* 218 * Set up the initialization block and the descriptor rings. 219 */ 220 void 221 am7990_meminit(sc) 222 register struct am7990_softc *sc; 223 { 224 u_long a; 225 int bix; 226 struct leinit init; 227 struct lermd rmd; 228 struct letmd tmd; 229 230 #if NBPFILTER > 0 231 if (ifp->if_flags & IFF_PROMISC) 232 init.init_mode = LE_MODE_NORMAL | LE_MODE_PROM; 233 else 234 #endif 235 init.init_mode = LE_MODE_NORMAL; 236 init.init_padr[0] = 237 (sc->sc_arpcom.ac_enaddr[1] << 8) | sc->sc_arpcom.ac_enaddr[0]; 238 init.init_padr[1] = 239 (sc->sc_arpcom.ac_enaddr[3] << 8) | sc->sc_arpcom.ac_enaddr[2]; 240 init.init_padr[2] = 241 (sc->sc_arpcom.ac_enaddr[5] << 8) | sc->sc_arpcom.ac_enaddr[4]; 242 am7990_setladrf(&sc->sc_arpcom, init.init_ladrf); 243 244 sc->sc_last_rd = 0; 245 sc->sc_first_td = sc->sc_last_td = sc->sc_no_td = 0; 246 247 a = sc->sc_addr + LE_RMDADDR(sc, 0); 248 init.init_rdra = a; 249 init.init_rlen = (a >> 16) | ((ffs(sc->sc_nrbuf) - 1) << 13); 250 251 a = sc->sc_addr + LE_TMDADDR(sc, 0); 252 init.init_tdra = a; 253 init.init_tlen = (a >> 16) | ((ffs(sc->sc_ntbuf) - 1) << 13); 254 255 (*sc->sc_copytodesc)(sc, &init, LE_INITADDR(sc), sizeof(init)); 256 257 /* 258 * Set up receive ring descriptors. 259 */ 260 for (bix = 0; bix < sc->sc_nrbuf; bix++) { 261 a = sc->sc_addr + LE_RBUFADDR(sc, bix); 262 rmd.rmd0 = a; 263 rmd.rmd1_hadr = a >> 16; 264 rmd.rmd1_bits = LE_R1_OWN; 265 rmd.rmd2 = -ETHER_MAX_DIX_LEN | LE_XMD2_ONES; 266 rmd.rmd3 = 0; 267 (*sc->sc_copytodesc)(sc, &rmd, LE_RMDADDR(sc, bix), 268 sizeof(rmd)); 269 } 270 271 /* 272 * Set up transmit ring descriptors. 273 */ 274 for (bix = 0; bix < sc->sc_ntbuf; bix++) { 275 a = sc->sc_addr + LE_TBUFADDR(sc, bix); 276 tmd.tmd0 = a; 277 tmd.tmd1_hadr = a >> 16; 278 tmd.tmd1_bits = 0; 279 tmd.tmd2 = 0 | LE_XMD2_ONES; 280 tmd.tmd3 = 0; 281 (*sc->sc_copytodesc)(sc, &tmd, LE_TMDADDR(sc, bix), 282 sizeof(tmd)); 283 } 284 } 285 286 void 287 am7990_stop(sc) 288 struct am7990_softc *sc; 289 { 290 291 (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_STOP); 292 } 293 294 /* 295 * Initialization of interface; set up initialization block 296 * and transmit/receive descriptor rings. 297 */ 298 void 299 am7990_init(sc) 300 register struct am7990_softc *sc; 301 { 302 register int timo; 303 u_long a; 304 305 (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_STOP); 306 DELAY(100); 307 308 /* Newer LANCE chips have a reset register */ 309 if (sc->sc_hwreset) 310 (*sc->sc_hwreset)(sc); 311 312 /* Set the correct byte swapping mode, etc. */ 313 (*sc->sc_wrcsr)(sc, LE_CSR3, sc->sc_conf3); 314 315 /* Set up LANCE init block. */ 316 am7990_meminit(sc); 317 318 /* Give LANCE the physical address of its init block. */ 319 a = sc->sc_addr + LE_INITADDR(sc); 320 (*sc->sc_wrcsr)(sc, LE_CSR1, a); 321 (*sc->sc_wrcsr)(sc, LE_CSR2, a >> 16); 322 323 /* Try to initialize the LANCE. */ 324 DELAY(100); 325 (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INIT); 326 327 /* Wait for initialization to finish. */ 328 for (timo = 100000; timo; timo--) 329 if ((*sc->sc_rdcsr)(sc, LE_CSR0) & LE_C0_IDON) 330 break; 331 332 if ((*sc->sc_rdcsr)(sc, LE_CSR0) & LE_C0_IDON) { 333 /* Start the LANCE. */ 334 (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA | LE_C0_STRT | 335 LE_C0_IDON); 336 ifp->if_flags |= IFF_RUNNING; 337 ifp->if_flags &= ~IFF_OACTIVE; 338 ifp->if_timer = 0; 339 am7990_start(ifp); 340 } else 341 printf("%s: controller failed to initialize\n", sc->sc_dev.dv_xname); 342 if (sc->sc_hwinit) 343 (*sc->sc_hwinit)(sc); 344 } 345 346 /* 347 * Routine to copy from mbuf chain to transmit buffer in 348 * network buffer memory. 349 */ 350 integrate int 351 am7990_put(sc, boff, m) 352 struct am7990_softc *sc; 353 int boff; 354 register struct mbuf *m; 355 { 356 register struct mbuf *n; 357 register int len, tlen = 0; 358 359 for (; m; m = n) { 360 len = m->m_len; 361 if (len == 0) { 362 MFREE(m, n); 363 continue; 364 } 365 (*sc->sc_copytobuf)(sc, mtod(m, caddr_t), boff, len); 366 boff += len; 367 tlen += len; 368 MFREE(m, n); 369 } 370 if (tlen < LEMINSIZE) { 371 (*sc->sc_zerobuf)(sc, boff, LEMINSIZE - tlen); 372 tlen = LEMINSIZE; 373 } 374 return (tlen); 375 } 376 377 /* 378 * Pull data off an interface. 379 * Len is length of data, with local net header stripped. 380 * We copy the data into mbufs. When full cluster sized units are present 381 * we copy into clusters. 382 */ 383 integrate struct mbuf * 384 am7990_get(sc, boff, totlen) 385 struct am7990_softc *sc; 386 int boff, totlen; 387 { 388 register struct mbuf *m; 389 struct mbuf *top, **mp; 390 int len, pad; 391 392 MGETHDR(m, M_DONTWAIT, MT_DATA); 393 if (m == 0) 394 return (0); 395 m->m_pkthdr.rcvif = ifp; 396 m->m_pkthdr.len = totlen; 397 pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header); 398 m->m_data += pad; 399 len = MHLEN - pad; 400 top = 0; 401 mp = ⊤ 402 403 while (totlen > 0) { 404 if (top) { 405 MGET(m, M_DONTWAIT, MT_DATA); 406 if (m == 0) { 407 m_freem(top); 408 return 0; 409 } 410 len = MLEN; 411 } 412 if (totlen >= MINCLSIZE) { 413 MCLGET(m, M_DONTWAIT); 414 if (m->m_flags & M_EXT) { 415 len = MCLBYTES; 416 if (!top) { 417 m->m_data += pad; 418 len -= pad; 419 } 420 } 421 } 422 m->m_len = len = min(totlen, len); 423 (*sc->sc_copyfrombuf)(sc, mtod(m, caddr_t), boff, len); 424 boff += len; 425 totlen -= len; 426 *mp = m; 427 mp = &m->m_next; 428 } 429 430 return (top); 431 } 432 433 /* 434 * Pass a packet to the higher levels. 435 */ 436 integrate void 437 am7990_read(sc, boff, len) 438 register struct am7990_softc *sc; 439 int boff, len; 440 { 441 struct mbuf *m; 442 #ifdef LANCE_REVC_BUG 443 struct ether_header *eh; 444 #endif 445 446 if (len <= sizeof(struct ether_header) || 447 len > ETHERMTU + ETHER_VLAN_ENCAP_LEN + sizeof(struct ether_header)) { 448 #ifdef LEDEBUG 449 printf("%s: invalid packet size %d; dropping\n", 450 sc->sc_dev.dv_xname, len); 451 #endif 452 ifp->if_ierrors++; 453 return; 454 } 455 456 /* Pull packet off interface. */ 457 m = am7990_get(sc, boff, len); 458 if (m == 0) { 459 ifp->if_ierrors++; 460 return; 461 } 462 463 ifp->if_ipackets++; 464 465 #if NBPFILTER > 0 466 /* 467 * Check if there's a BPF listener on this interface. 468 * If so, hand off the raw packet to BPF. 469 */ 470 if (ifp->if_bpf) 471 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN); 472 #endif 473 474 #ifdef LANCE_REVC_BUG 475 /* 476 * The old LANCE (Rev. C) chips have a bug which causes 477 * garbage to be inserted in front of the received packet. 478 * The work-around is to ignore packets with an invalid 479 * destination address (garbage will usually not match). 480 * Of course, this precludes multicast support... 481 */ 482 eh = mtod(m, struct ether_header *); 483 if (ETHER_CMP(eh->ether_dhost, sc->sc_arpcom.ac_enaddr) && 484 ETHER_CMP(eh->ether_dhost, etherbroadcastaddr)) { 485 m_freem(m); 486 return; 487 } 488 #endif 489 490 /* Pass the packet up. */ 491 ether_input_mbuf(ifp, m); 492 } 493 494 integrate void 495 am7990_rint(sc) 496 struct am7990_softc *sc; 497 { 498 register int bix; 499 int rp; 500 struct lermd rmd; 501 502 bix = sc->sc_last_rd; 503 504 /* Process all buffers with valid data. */ 505 for (;;) { 506 rp = LE_RMDADDR(sc, bix); 507 (*sc->sc_copyfromdesc)(sc, &rmd, rp, sizeof(rmd)); 508 509 if (rmd.rmd1_bits & LE_R1_OWN) 510 break; 511 512 if (rmd.rmd1_bits & LE_R1_ERR) { 513 if (rmd.rmd1_bits & LE_R1_ENP) { 514 #ifdef LEDEBUG 515 if ((rmd.rmd1_bits & LE_R1_OFLO) == 0) { 516 if (rmd.rmd1_bits & LE_R1_FRAM) 517 printf("%s: framing error\n", 518 sc->sc_dev.dv_xname); 519 if (rmd.rmd1_bits & LE_R1_CRC) 520 printf("%s: crc mismatch\n", 521 sc->sc_dev.dv_xname); 522 } 523 #endif 524 } else { 525 if (rmd.rmd1_bits & LE_R1_OFLO) 526 printf("%s: overflow\n", 527 sc->sc_dev.dv_xname); 528 } 529 if (rmd.rmd1_bits & LE_R1_BUFF) 530 printf("%s: receive buffer error\n", 531 sc->sc_dev.dv_xname); 532 ifp->if_ierrors++; 533 } else if ((rmd.rmd1_bits & (LE_R1_STP | LE_R1_ENP)) != 534 (LE_R1_STP | LE_R1_ENP)) { 535 printf("%s: dropping chained buffer\n", 536 sc->sc_dev.dv_xname); 537 ifp->if_ierrors++; 538 } else { 539 #ifdef LEDEBUG1 540 if (sc->sc_debug) 541 am7990_recv_print(sc, sc->sc_last_rd); 542 #endif 543 am7990_read(sc, LE_RBUFADDR(sc, bix), 544 (int)rmd.rmd3 - 4); 545 } 546 547 rmd.rmd1_bits = LE_R1_OWN; 548 rmd.rmd2 = -ETHER_MAX_DIX_LEN | LE_XMD2_ONES; 549 rmd.rmd3 = 0; 550 (*sc->sc_copytodesc)(sc, &rmd, rp, sizeof(rmd)); 551 552 #ifdef LEDEBUG1 553 if (sc->sc_debug) 554 printf("sc->sc_last_rd = %x, rmd: " 555 "ladr %04x, hadr %02x, flags %02x, " 556 "bcnt %04x, mcnt %04x\n", 557 sc->sc_last_rd, 558 rmd.rmd0, rmd.rmd1_hadr, rmd.rmd1_bits, 559 rmd.rmd2, rmd.rmd3); 560 #endif 561 562 if (++bix == sc->sc_nrbuf) 563 bix = 0; 564 } 565 566 sc->sc_last_rd = bix; 567 } 568 569 integrate void 570 am7990_tint(sc) 571 register struct am7990_softc *sc; 572 { 573 register int bix; 574 struct letmd tmd; 575 576 bix = sc->sc_first_td; 577 578 for (;;) { 579 if (sc->sc_no_td <= 0) 580 break; 581 582 (*sc->sc_copyfromdesc)(sc, &tmd, LE_TMDADDR(sc, bix), 583 sizeof(tmd)); 584 585 #ifdef LEDEBUG 586 if (sc->sc_debug) 587 printf("trans tmd: " 588 "ladr %04x, hadr %02x, flags %02x, " 589 "bcnt %04x, mcnt %04x\n", 590 tmd.tmd0, tmd.tmd1_hadr, tmd.tmd1_bits, 591 tmd.tmd2, tmd.tmd3); 592 #endif 593 594 if (tmd.tmd1_bits & LE_T1_OWN) 595 break; 596 597 ifp->if_flags &= ~IFF_OACTIVE; 598 599 if (tmd.tmd1_bits & LE_T1_ERR) { 600 if (tmd.tmd3 & LE_T3_BUFF) 601 printf("%s: transmit buffer error\n", 602 sc->sc_dev.dv_xname); 603 else if (tmd.tmd3 & LE_T3_UFLO) 604 printf("%s: underflow\n", sc->sc_dev.dv_xname); 605 if (tmd.tmd3 & (LE_T3_BUFF | LE_T3_UFLO)) { 606 am7990_reset(sc); 607 return; 608 } 609 if (tmd.tmd3 & LE_T3_LCAR) { 610 if (sc->sc_nocarrier) 611 (*sc->sc_nocarrier)(sc); 612 } 613 if (tmd.tmd3 & LE_T3_LCOL) 614 ifp->if_collisions++; 615 if (tmd.tmd3 & LE_T3_RTRY) { 616 printf("%s: excessive collisions, tdr %d\n", 617 sc->sc_dev.dv_xname, 618 tmd.tmd3 & LE_T3_TDR_MASK); 619 ifp->if_collisions += 16; 620 } 621 ifp->if_oerrors++; 622 } else { 623 if (tmd.tmd1_bits & LE_T1_ONE) 624 ifp->if_collisions++; 625 else if (tmd.tmd1_bits & LE_T1_MORE) 626 /* Real number is unknown. */ 627 ifp->if_collisions += 2; 628 ifp->if_opackets++; 629 } 630 631 if (++bix == sc->sc_ntbuf) 632 bix = 0; 633 634 --sc->sc_no_td; 635 } 636 637 sc->sc_first_td = bix; 638 639 am7990_start(ifp); 640 641 if (sc->sc_no_td == 0) 642 ifp->if_timer = 0; 643 } 644 645 /* 646 * Controller interrupt. 647 */ 648 int 649 am7990_intr(arg) 650 register void *arg; 651 { 652 register struct am7990_softc *sc = arg; 653 register u_int16_t isr; 654 655 isr = (*sc->sc_rdcsr)(sc, LE_CSR0); 656 #ifdef LEDEBUG 657 if (sc->sc_debug){ 658 printf("%s: am7990_intr entering with isr=%04x\n", 659 sc->sc_dev.dv_xname, isr); 660 printf(" isr: 0x%b\n", isr, LE_C0_BITS); 661 } 662 #endif 663 if ((isr & LE_C0_INTR) == 0) 664 return (0); 665 666 /* 667 * After receiving an interrupt, we need to toggle the interrupt 668 * enable bit in order to keep receiving them (some chips works 669 * without this, some do not) 670 */ 671 (*sc->sc_wrcsr)(sc, LE_CSR0, isr & ~LE_C0_INEA); 672 (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA); 673 674 if (isr & LE_C0_ERR) { 675 if (isr & LE_C0_BABL) { 676 #ifdef LEDEBUG 677 printf("%s: babble\n", sc->sc_dev.dv_xname); 678 #endif 679 ifp->if_oerrors++; 680 } 681 #if 0 682 if (isr & LE_C0_CERR) { 683 printf("%s: collision error\n", sc->sc_dev.dv_xname); 684 ifp->if_collisions++; 685 } 686 #endif 687 if (isr & LE_C0_MISS) { 688 #ifdef LEDEBUG 689 printf("%s: missed packet\n", sc->sc_dev.dv_xname); 690 #endif 691 ifp->if_ierrors++; 692 } 693 if (isr & LE_C0_MERR) { 694 printf("%s: memory error\n", sc->sc_dev.dv_xname); 695 am7990_reset(sc); 696 return (1); 697 } 698 } 699 700 if ((isr & LE_C0_RXON) == 0) { 701 printf("%s: receiver disabled\n", sc->sc_dev.dv_xname); 702 ifp->if_ierrors++; 703 am7990_reset(sc); 704 return (1); 705 } 706 if ((isr & LE_C0_TXON) == 0) { 707 printf("%s: transmitter disabled\n", sc->sc_dev.dv_xname); 708 ifp->if_oerrors++; 709 am7990_reset(sc); 710 return (1); 711 } 712 713 if (isr & LE_C0_RINT) 714 am7990_rint(sc); 715 if (isr & LE_C0_TINT) 716 am7990_tint(sc); 717 718 return (1); 719 } 720 721 #undef ifp 722 723 void 724 am7990_watchdog(ifp) 725 struct ifnet *ifp; 726 { 727 struct am7990_softc *sc = ifp->if_softc; 728 729 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname); 730 ++ifp->if_oerrors; 731 732 am7990_reset(sc); 733 } 734 735 /* 736 * Setup output on interface. 737 * Get another datagram to send off of the interface queue, and map it to the 738 * interface before starting the output. 739 * Called only at splnet or interrupt level. 740 */ 741 void 742 am7990_start(ifp) 743 register struct ifnet *ifp; 744 { 745 register struct am7990_softc *sc = ifp->if_softc; 746 register int bix; 747 register struct mbuf *m; 748 struct letmd tmd; 749 int rp; 750 int len; 751 752 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 753 return; 754 755 bix = sc->sc_last_td; 756 757 for (;;) { 758 rp = LE_TMDADDR(sc, bix); 759 (*sc->sc_copyfromdesc)(sc, &tmd, rp, sizeof(tmd)); 760 761 if (tmd.tmd1_bits & LE_T1_OWN) { 762 ifp->if_flags |= IFF_OACTIVE; 763 printf("missing buffer, no_td = %d, last_td = %d\n", 764 sc->sc_no_td, sc->sc_last_td); 765 } 766 767 IFQ_DEQUEUE(&ifp->if_snd, m); 768 if (m == 0) 769 break; 770 771 #if NBPFILTER > 0 772 /* 773 * If BPF is listening on this interface, let it see the packet 774 * before we commit it to the wire. 775 */ 776 if (ifp->if_bpf) 777 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT); 778 #endif 779 780 /* 781 * Copy the mbuf chain into the transmit buffer. 782 */ 783 len = am7990_put(sc, LE_TBUFADDR(sc, bix), m); 784 785 #ifdef LEDEBUG 786 if (len > ETHERMTU + sizeof(struct ether_header)) 787 printf("packet length %d\n", len); 788 #endif 789 790 ifp->if_timer = 5; 791 792 /* 793 * Init transmit registers, and set transmit start flag. 794 */ 795 tmd.tmd1_bits = LE_T1_OWN | LE_T1_STP | LE_T1_ENP; 796 tmd.tmd2 = -len | LE_XMD2_ONES; 797 tmd.tmd3 = 0; 798 799 (*sc->sc_copytodesc)(sc, &tmd, rp, sizeof(tmd)); 800 801 #ifdef LEDEBUG 802 if (sc->sc_debug) 803 am7990_xmit_print(sc, sc->sc_last_td); 804 #endif 805 806 (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA | LE_C0_TDMD); 807 808 if (++bix == sc->sc_ntbuf) 809 bix = 0; 810 811 if (++sc->sc_no_td == sc->sc_ntbuf) { 812 #ifdef LEDEBUG 813 printf("\nequal!\n"); 814 #endif 815 ifp->if_flags |= IFF_OACTIVE; 816 break; 817 } 818 819 } 820 821 sc->sc_last_td = bix; 822 } 823 824 /* 825 * Process an ioctl request. 826 */ 827 int 828 am7990_ioctl(ifp, cmd, data) 829 register struct ifnet *ifp; 830 u_long cmd; 831 caddr_t data; 832 { 833 register struct am7990_softc *sc = ifp->if_softc; 834 struct ifaddr *ifa = (struct ifaddr *)data; 835 struct ifreq *ifr = (struct ifreq *)data; 836 int s, error = 0; 837 838 s = splnet(); 839 840 switch (cmd) { 841 case SIOCSIFADDR: 842 ifp->if_flags |= IFF_UP; 843 844 switch (ifa->ifa_addr->sa_family) { 845 #ifdef INET 846 case AF_INET: 847 am7990_init(sc); 848 arp_ifinit(&sc->sc_arpcom, ifa); 849 break; 850 #endif 851 default: 852 am7990_init(sc); 853 break; 854 } 855 break; 856 857 case SIOCSIFFLAGS: 858 if ((ifp->if_flags & IFF_UP) == 0 && 859 (ifp->if_flags & IFF_RUNNING) != 0) { 860 /* 861 * If interface is marked down and it is running, then 862 * stop it. 863 */ 864 am7990_stop(sc); 865 ifp->if_flags &= ~IFF_RUNNING; 866 } else if ((ifp->if_flags & IFF_UP) != 0 && 867 (ifp->if_flags & IFF_RUNNING) == 0) { 868 /* 869 * If interface is marked up and it is stopped, then 870 * start it. 871 */ 872 am7990_init(sc); 873 } else { 874 /* 875 * Reset the interface to pick up changes in any other 876 * flags that affect hardware registers. 877 */ 878 /*am7990_stop(sc);*/ 879 am7990_init(sc); 880 } 881 #ifdef LEDEBUG 882 if (ifp->if_flags & IFF_DEBUG) 883 sc->sc_debug = 1; 884 else 885 sc->sc_debug = 0; 886 #endif 887 break; 888 889 case SIOCGIFMEDIA: 890 case SIOCSIFMEDIA: 891 if (sc->sc_hasifmedia) 892 error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifmedia, cmd); 893 else 894 error = EINVAL; 895 break; 896 897 default: 898 error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data); 899 } 900 901 if (error == ENETRESET) { 902 if (ifp->if_flags & IFF_RUNNING) 903 am7990_reset(sc); 904 error = 0; 905 } 906 907 splx(s); 908 return (error); 909 } 910 911 #ifdef LEDEBUG 912 void 913 am7990_recv_print(sc, no) 914 struct am7990_softc *sc; 915 int no; 916 { 917 struct lermd rmd; 918 u_int16_t len; 919 struct ether_header eh; 920 921 (*sc->sc_copyfromdesc)(sc, &rmd, LE_RMDADDR(sc, no), sizeof(rmd)); 922 len = rmd.rmd3; 923 printf("%s: receive buffer %d, len = %d\n", sc->sc_dev.dv_xname, no, 924 len); 925 printf("%s: status %04x\n", sc->sc_dev.dv_xname, 926 (*sc->sc_rdcsr)(sc, LE_CSR0)); 927 printf("%s: ladr %04x, hadr %02x, flags %02x, bcnt %04x, mcnt %04x\n", 928 sc->sc_dev.dv_xname, 929 rmd.rmd0, rmd.rmd1_hadr, rmd.rmd1_bits, rmd.rmd2, rmd.rmd3); 930 if (len >= sizeof(eh)) { 931 (*sc->sc_copyfrombuf)(sc, &eh, LE_RBUFADDR(sc, no), sizeof(eh)); 932 printf("%s: dst %s", sc->sc_dev.dv_xname, 933 ether_sprintf(eh.ether_dhost)); 934 printf(" src %s type %04x\n", ether_sprintf(eh.ether_shost), 935 ntohs(eh.ether_type)); 936 } 937 } 938 939 void 940 am7990_xmit_print(sc, no) 941 struct am7990_softc *sc; 942 int no; 943 { 944 struct letmd tmd; 945 u_int16_t len; 946 struct ether_header eh; 947 948 (*sc->sc_copyfromdesc)(sc, &tmd, LE_TMDADDR(sc, no), sizeof(tmd)); 949 len = -tmd.tmd2; 950 printf("%s: transmit buffer %d, len = %d\n", sc->sc_dev.dv_xname, no, 951 len); 952 printf("%s: status %04x\n", sc->sc_dev.dv_xname, 953 (*sc->sc_rdcsr)(sc, LE_CSR0)); 954 printf("%s: ladr %04x, hadr %02x, flags %02x, bcnt %04x, mcnt %04x\n", 955 sc->sc_dev.dv_xname, 956 tmd.tmd0, tmd.tmd1_hadr, tmd.tmd1_bits, tmd.tmd2, tmd.tmd3); 957 if (len >= sizeof(eh)) { 958 (*sc->sc_copyfrombuf)(sc, &eh, LE_TBUFADDR(sc, no), sizeof(eh)); 959 printf("%s: dst %s", sc->sc_dev.dv_xname, 960 ether_sprintf(eh.ether_dhost)); 961 printf(" src %s type %04x\n", ether_sprintf(eh.ether_shost), 962 ntohs(eh.ether_type)); 963 } 964 } 965 #endif /* LEDEBUG */ 966 967 /* 968 * Set up the logical address filter. 969 */ 970 void 971 am7990_setladrf(ac, af) 972 struct arpcom *ac; 973 u_int16_t *af; 974 { 975 struct ifnet *ifp = &ac->ac_if; 976 struct ether_multi *enm; 977 register u_int32_t crc; 978 struct ether_multistep step; 979 980 /* 981 * Set up multicast address filter by passing all multicast addresses 982 * through a crc generator, and then using the high order 6 bits as an 983 * index into the 64 bit logical address filter. The high order bit 984 * selects the word, while the rest of the bits select the bit within 985 * the word. 986 */ 987 988 if (ifp->if_flags & IFF_PROMISC) 989 goto allmulti; 990 991 af[0] = af[1] = af[2] = af[3] = 0x0000; 992 ETHER_FIRST_MULTI(step, ac, enm); 993 while (enm != NULL) { 994 if (ETHER_CMP(enm->enm_addrlo, enm->enm_addrhi)) { 995 /* 996 * We must listen to a range of multicast addresses. 997 * For now, just accept all multicasts, rather than 998 * trying to set only those filter bits needed to match 999 * the range. (At this time, the only use of address 1000 * ranges is for IP multicast routing, for which the 1001 * range is big enough to require all bits set.) 1002 */ 1003 goto allmulti; 1004 } 1005 1006 crc = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN) >> 26; 1007 1008 /* Set the corresponding bit in the filter. */ 1009 af[crc >> 4] |= 1 << (crc & 0xf); 1010 1011 ETHER_NEXT_MULTI(step, enm); 1012 } 1013 ifp->if_flags &= ~IFF_ALLMULTI; 1014 return; 1015 1016 allmulti: 1017 ifp->if_flags |= IFF_ALLMULTI; 1018 af[0] = af[1] = af[2] = af[3] = 0xffff; 1019 } 1020 1021 1022 /* 1023 * Routines for accessing the transmit and receive buffers. 1024 * The various CPU and adapter configurations supported by this 1025 * driver require three different access methods for buffers 1026 * and descriptors: 1027 * (1) contig (contiguous data; no padding), 1028 * (2) gap2 (two bytes of data followed by two bytes of padding), 1029 * (3) gap16 (16 bytes of data followed by 16 bytes of padding). 1030 */ 1031 1032 /* 1033 * contig: contiguous data with no padding. 1034 * 1035 * Buffers may have any alignment. 1036 */ 1037 1038 void 1039 am7990_copytobuf_contig(sc, from, boff, len) 1040 struct am7990_softc *sc; 1041 void *from; 1042 int boff, len; 1043 { 1044 volatile caddr_t buf = sc->sc_mem; 1045 1046 /* 1047 * Just call bcopy() to do the work. 1048 */ 1049 bcopy(from, buf + boff, len); 1050 } 1051 1052 void 1053 am7990_copyfrombuf_contig(sc, to, boff, len) 1054 struct am7990_softc *sc; 1055 void *to; 1056 int boff, len; 1057 { 1058 volatile caddr_t buf = sc->sc_mem; 1059 1060 /* 1061 * Just call bcopy() to do the work. 1062 */ 1063 bcopy(buf + boff, to, len); 1064 } 1065 1066 void 1067 am7990_zerobuf_contig(sc, boff, len) 1068 struct am7990_softc *sc; 1069 int boff, len; 1070 { 1071 volatile caddr_t buf = sc->sc_mem; 1072 1073 /* 1074 * Just let bzero() do the work 1075 */ 1076 bzero(buf + boff, len); 1077 } 1078 1079 #if 0 1080 /* 1081 * Examples only; duplicate these and tweak (if necessary) in 1082 * machine-specific front-ends. 1083 */ 1084 1085 /* 1086 * gap2: two bytes of data followed by two bytes of pad. 1087 * 1088 * Buffers must be 4-byte aligned. The code doesn't worry about 1089 * doing an extra byte. 1090 */ 1091 1092 void 1093 am7990_copytobuf_gap2(sc, fromv, boff, len) 1094 struct am7990_softc *sc; 1095 void *fromv; 1096 int boff; 1097 register int len; 1098 { 1099 volatile caddr_t buf = sc->sc_mem; 1100 register caddr_t from = fromv; 1101 register volatile u_int16_t *bptr; 1102 1103 if (boff & 0x1) { 1104 /* handle unaligned first byte */ 1105 bptr = ((volatile u_int16_t *)buf) + (boff - 1); 1106 *bptr = (*from++ << 8) | (*bptr & 0xff); 1107 bptr += 2; 1108 len--; 1109 } else 1110 bptr = ((volatile u_int16_t *)buf) + boff; 1111 while (len > 1) { 1112 *bptr = (from[1] << 8) | (from[0] & 0xff); 1113 bptr += 2; 1114 from += 2; 1115 len -= 2; 1116 } 1117 if (len == 1) 1118 *bptr = (u_int16_t)*from; 1119 } 1120 1121 void 1122 am7990_copyfrombuf_gap2(sc, tov, boff, len) 1123 struct am7990_softc *sc; 1124 void *tov; 1125 int boff, len; 1126 { 1127 volatile caddr_t buf = sc->sc_mem; 1128 register caddr_t to = tov; 1129 register volatile u_int16_t *bptr; 1130 register u_int16_t tmp; 1131 1132 if (boff & 0x1) { 1133 /* handle unaligned first byte */ 1134 bptr = ((volatile u_int16_t *)buf) + (boff - 1); 1135 *to++ = (*bptr >> 8) & 0xff; 1136 bptr += 2; 1137 len--; 1138 } else 1139 bptr = ((volatile u_int16_t *)buf) + boff; 1140 while (len > 1) { 1141 tmp = *bptr; 1142 *to++ = tmp & 0xff; 1143 *to++ = (tmp >> 8) & 0xff; 1144 bptr += 2; 1145 len -= 2; 1146 } 1147 if (len == 1) 1148 *to = *bptr & 0xff; 1149 } 1150 1151 void 1152 am7990_zerobuf_gap2(sc, boff, len) 1153 struct am7990_softc *sc; 1154 int boff, len; 1155 { 1156 volatile caddr_t buf = sc->sc_mem; 1157 register volatile u_int16_t *bptr; 1158 1159 if ((unsigned)boff & 0x1) { 1160 bptr = ((volatile u_int16_t *)buf) + (boff - 1); 1161 *bptr &= 0xff; 1162 bptr += 2; 1163 len--; 1164 } else 1165 bptr = ((volatile u_int16_t *)buf) + boff; 1166 while (len > 0) { 1167 *bptr = 0; 1168 bptr += 2; 1169 len -= 2; 1170 } 1171 } 1172 1173 /* 1174 * gap16: 16 bytes of data followed by 16 bytes of pad. 1175 * 1176 * Buffers must be 32-byte aligned. 1177 */ 1178 1179 void 1180 am7990_copytobuf_gap16(sc, fromv, boff, len) 1181 struct am7990_softc *sc; 1182 void *fromv; 1183 int boff; 1184 register int len; 1185 { 1186 volatile caddr_t buf = sc->sc_mem; 1187 register caddr_t from = fromv; 1188 register caddr_t bptr; 1189 register int xfer; 1190 1191 bptr = buf + ((boff << 1) & ~0x1f); 1192 boff &= 0xf; 1193 xfer = min(len, 16 - boff); 1194 while (len > 0) { 1195 bcopy(from, bptr + boff, xfer); 1196 from += xfer; 1197 bptr += 32; 1198 boff = 0; 1199 len -= xfer; 1200 xfer = min(len, 16); 1201 } 1202 } 1203 1204 void 1205 am7990_copyfrombuf_gap16(sc, tov, boff, len) 1206 struct am7990_softc *sc; 1207 void *tov; 1208 int boff, len; 1209 { 1210 volatile caddr_t buf = sc->sc_mem; 1211 register caddr_t to = tov; 1212 register caddr_t bptr; 1213 register int xfer; 1214 1215 bptr = buf + ((boff << 1) & ~0x1f); 1216 boff &= 0xf; 1217 xfer = min(len, 16 - boff); 1218 while (len > 0) { 1219 bcopy(bptr + boff, to, xfer); 1220 to += xfer; 1221 bptr += 32; 1222 boff = 0; 1223 len -= xfer; 1224 xfer = min(len, 16); 1225 } 1226 } 1227 1228 void 1229 am7990_zerobuf_gap16(sc, boff, len) 1230 struct am7990_softc *sc; 1231 int boff, len; 1232 { 1233 volatile caddr_t buf = sc->sc_mem; 1234 register caddr_t bptr; 1235 register int xfer; 1236 1237 bptr = buf + ((boff << 1) & ~0x1f); 1238 boff &= 0xf; 1239 xfer = min(len, 16 - boff); 1240 while (len > 0) { 1241 bzero(bptr + boff, xfer); 1242 bptr += 32; 1243 boff = 0; 1244 len -= xfer; 1245 xfer = min(len, 16); 1246 } 1247 } 1248 #endif /* Example only */ 1249