dp83932.c revision 1.1
1/* $NetBSD: dp83932.c,v 1.1 2001/07/05 14:37:41 thorpej Exp $ */ 2 3/*- 4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39/* 40 * Device driver for the National Semiconductor DP83932 41 * Systems-Oriented Network Interface Controller (SONIC). 42 */ 43 44#include "bpfilter.h" 45 46#include <sys/param.h> 47#include <sys/systm.h> 48#include <sys/mbuf.h> 49#include <sys/malloc.h> 50#include <sys/kernel.h> 51#include <sys/socket.h> 52#include <sys/ioctl.h> 53#include <sys/errno.h> 54#include <sys/device.h> 55 56#include <uvm/uvm_extern.h> 57 58#include <net/if.h> 59#include <net/if_dl.h> 60#include <net/if_ether.h> 61 62#if NBPFILTER > 0 63#include <net/bpf.h> 64#endif 65 66#include <machine/bus.h> 67#include <machine/intr.h> 68 69#include <dev/ic/dp83932reg.h> 70#include <dev/ic/dp83932var.h> 71 72void sonic_start(struct ifnet *); 73void sonic_watchdog(struct ifnet *); 74int sonic_ioctl(struct ifnet *, u_long, caddr_t); 75int sonic_init(struct ifnet *); 76void sonic_stop(struct ifnet *, int); 77 78void sonic_shutdown(void *); 79 80void sonic_reset(struct sonic_softc *); 81void sonic_rxdrain(struct sonic_softc *); 82int sonic_add_rxbuf(struct sonic_softc *, int); 83void sonic_set_filter(struct sonic_softc *); 84 85uint16_t sonic_txintr(struct sonic_softc *); 86void sonic_rxintr(struct sonic_softc *); 87 88int sonic_copy_small = 0; 89 90/* 91 * sonic_attach: 92 * 93 * Attach a SONIC interface to the system. 94 */ 95void 96sonic_attach(struct sonic_softc *sc, const uint8_t *enaddr) 97{ 98 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 99 int i, rseg, error; 100 bus_dma_segment_t seg; 101 size_t cdatasize; 102 103 /* 104 * Allocate the control data structures, and create and load the 105 * DMA map for it. 106 */ 107 if (sc->sc_32bit) 108 cdatasize = sizeof(struct sonic_control_data32); 109 else 110 cdatasize = sizeof(struct sonic_control_data16); 111 112 if ((error = bus_dmamem_alloc(sc->sc_dmat, cdatasize, 113 PAGE_SIZE, (64 * 1024), &seg, 1, &rseg, 114 BUS_DMA_NOWAIT)) != 0) { 115 printf("%s: unable to allocate control data, error = %d\n", 116 sc->sc_dev.dv_xname, error); 117 goto fail_0; 118 } 119 120 if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, 121 cdatasize, (caddr_t *) &sc->sc_cdata16, 122 BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) { 123 printf("%s: unable to map control data, error = %d\n", 124 sc->sc_dev.dv_xname, error); 125 goto fail_1; 126 } 127 128 if ((error = bus_dmamap_create(sc->sc_dmat, 129 cdatasize, 1, cdatasize, 0, BUS_DMA_NOWAIT, 130 &sc->sc_cddmamap)) != 0) { 131 printf("%s: unable to create control data DMA map, " 132 "error = %d\n", sc->sc_dev.dv_xname, error); 133 goto fail_2; 134 } 135 136 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap, 137 sc->sc_cdata16, cdatasize, NULL, BUS_DMA_NOWAIT)) != 0) { 138 printf("%s: unable to load control data DMA map, error = %d\n", 139 sc->sc_dev.dv_xname, error); 140 goto fail_3; 141 } 142 143 /* 144 * Create the transmit buffer DMA maps. 145 */ 146 for (i = 0; i < SONIC_NTXDESC; i++) { 147 if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 148 SONIC_NTXFRAGS, MCLBYTES, 0, BUS_DMA_NOWAIT, 149 &sc->sc_txsoft[i].ds_dmamap)) != 0) { 150 printf("%s: unable to create tx DMA map %d, " 151 "error = %d\n", sc->sc_dev.dv_xname, i, error); 152 goto fail_4; 153 } 154 } 155 156 /* 157 * Create the receive buffer DMA maps. 158 */ 159 for (i = 0; i < SONIC_NRXDESC; i++) { 160 if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, 161 MCLBYTES, 0, BUS_DMA_NOWAIT, 162 &sc->sc_rxsoft[i].ds_dmamap)) != 0) { 163 printf("%s: unable to create rx DMA map %d, " 164 "error = %d\n", sc->sc_dev.dv_xname, i, error); 165 goto fail_5; 166 } 167 sc->sc_rxsoft[i].ds_mbuf = NULL; 168 } 169 170 /* 171 * Reset the chip to a known state. 172 */ 173 sonic_reset(sc); 174 175 printf("%s: Ethernet address %s\n", sc->sc_dev.dv_xname, 176 ether_sprintf(enaddr)); 177 178 strcpy(ifp->if_xname, sc->sc_dev.dv_xname); 179 ifp->if_softc = sc; 180 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 181 ifp->if_ioctl = sonic_ioctl; 182 ifp->if_start = sonic_start; 183 ifp->if_watchdog = sonic_watchdog; 184 ifp->if_init = sonic_init; 185 ifp->if_stop = sonic_stop; 186 IFQ_SET_READY(&ifp->if_snd); 187 188 /* 189 * Attach the interface. 190 */ 191 if_attach(ifp); 192 ether_ifattach(ifp, enaddr); 193 194 /* 195 * Make sure the interface is shutdown during reboot. 196 */ 197 sc->sc_sdhook = shutdownhook_establish(sonic_shutdown, sc); 198 if (sc->sc_sdhook == NULL) 199 printf("%s: WARNING: unable to establish shutdown hook\n", 200 sc->sc_dev.dv_xname); 201 return; 202 203 /* 204 * Free any resources we've allocated during the failed attach 205 * attempt. Do this in reverse order and fall through. 206 */ 207 fail_5: 208 for (i = 0; i < SONIC_NRXDESC; i++) { 209 if (sc->sc_rxsoft[i].ds_dmamap != NULL) 210 bus_dmamap_destroy(sc->sc_dmat, 211 sc->sc_rxsoft[i].ds_dmamap); 212 } 213 fail_4: 214 for (i = 0; i < SONIC_NTXDESC; i++) { 215 if (sc->sc_txsoft[i].ds_dmamap != NULL) 216 bus_dmamap_destroy(sc->sc_dmat, 217 sc->sc_txsoft[i].ds_dmamap); 218 } 219 bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap); 220 fail_3: 221 bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap); 222 fail_2: 223 bus_dmamem_unmap(sc->sc_dmat, (caddr_t) sc->sc_cdata16, cdatasize); 224 fail_1: 225 bus_dmamem_free(sc->sc_dmat, &seg, rseg); 226 fail_0: 227 return; 228} 229 230/* 231 * sonic_shutdown: 232 * 233 * Make sure the interface is stopped at reboot. 234 */ 235void 236sonic_shutdown(void *arg) 237{ 238 struct sonic_softc *sc = arg; 239 240 sonic_stop(&sc->sc_ethercom.ec_if, 1); 241} 242 243/* 244 * sonic_start: [ifnet interface function] 245 * 246 * Start packet transmission on the interface. 247 */ 248void 249sonic_start(struct ifnet *ifp) 250{ 251 struct sonic_softc *sc = ifp->if_softc; 252 struct mbuf *m0, *m; 253 struct sonic_tda16 *tda16; 254 struct sonic_tda32 *tda32; 255 struct sonic_descsoft *ds; 256 bus_dmamap_t dmamap; 257 int error, olasttx, nexttx, opending, seg, totlen, olseg; 258 259 if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING) 260 return; 261 262 /* 263 * Remember the previous txpending and the current "last txdesc 264 * used" index. 265 */ 266 opending = sc->sc_txpending; 267 olasttx = sc->sc_txlast; 268 269 /* 270 * Loop through the send queue, setting up transmit descriptors 271 * until we drain the queue, or use up all available transmit 272 * descriptors. Leave one at the end for sanity's sake. 273 */ 274 while (sc->sc_txpending < (SONIC_NTXDESC - 1)) { 275 /* 276 * Grab a packet off the queue. 277 */ 278 IFQ_POLL(&ifp->if_snd, m0); 279 if (m0 == NULL) 280 break; 281 m = NULL; 282 283 /* 284 * Get the next available transmit descriptor. 285 */ 286 nexttx = SONIC_NEXTTX(sc->sc_txlast); 287 ds = &sc->sc_txsoft[nexttx]; 288 dmamap = ds->ds_dmamap; 289 290 /* 291 * Load the DMA map. If this fails, the packet either 292 * didn't fit in the allotted number of frags, or we were 293 * short on resources. In this case, we'll copy and try 294 * again. 295 */ 296 if (bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0, 297 BUS_DMA_NOWAIT) != 0) { 298 MGETHDR(m, M_DONTWAIT, MT_DATA); 299 if (m == NULL) { 300 printf("%s: unable to allocate Tx mbuf\n", 301 sc->sc_dev.dv_xname); 302 break; 303 } 304 if (m0->m_pkthdr.len > MHLEN) { 305 MCLGET(m, M_DONTWAIT); 306 if ((m->m_flags & M_EXT) == 0) { 307 printf("%s: unable to allocate Tx " 308 "cluster\n", sc->sc_dev.dv_xname); 309 m_freem(m); 310 break; 311 } 312 } 313 m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t)); 314 m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len; 315 error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, 316 m, BUS_DMA_NOWAIT); 317 if (error) { 318 printf("%s: unable to load Tx buffer, " 319 "error = %d\n", sc->sc_dev.dv_xname, error); 320 m_freem(m); 321 break; 322 } 323 } 324 IFQ_DEQUEUE(&ifp->if_snd, m0); 325 if (m != NULL) { 326 m_freem(m0); 327 m0 = m; 328 } 329 330 /* 331 * WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET. 332 */ 333 334 /* Sync the DMA map. */ 335 bus_dmamap_sync(sc->sc_dmat, dmamap, 0, dmamap->dm_mapsize, 336 BUS_DMASYNC_PREWRITE); 337 338 /* 339 * Store a pointer to the packet so we can free it later. 340 */ 341 ds->ds_mbuf = m0; 342 343 /* 344 * Initialize the transmit descriptor. 345 */ 346 totlen = 0; 347 if (sc->sc_32bit) { 348 tda32 = &sc->sc_tda32[nexttx]; 349 for (seg = 0; seg < dmamap->dm_nsegs; seg++) { 350 tda32->tda_frags[seg].frag_ptr1 = 351 htosonic32(sc, 352 (dmamap->dm_segs[seg].ds_addr >> 16) & 353 0xffff); 354 tda32->tda_frags[seg].frag_ptr0 = 355 htosonic32(sc, 356 dmamap->dm_segs[seg].ds_addr & 0xffff); 357 tda32->tda_frags[seg].frag_size = 358 htosonic32(sc, dmamap->dm_segs[seg].ds_len); 359 totlen += dmamap->dm_segs[seg].ds_len; 360 } 361 362 /* 363 * Pad the packet out if it's less than the 364 * minimum Ethernet frame size. 365 */ 366 if (totlen < (ETHER_MIN_LEN - ETHER_CRC_LEN)) { 367 tda32->tda_frags[seg - 1].frag_size = 368 htosonic32(sc, 369 dmamap->dm_segs[seg - 1].ds_len + 370 ((ETHER_MIN_LEN - ETHER_CRC_LEN) - totlen)); 371 totlen = ETHER_MIN_LEN - ETHER_CRC_LEN; 372 } 373 374 tda32->tda_status = 0; 375 tda32->tda_pktconfig = 0; 376 tda32->tda_pktsize = htosonic32(sc, totlen); 377 tda32->tda_fragcnt = htosonic32(sc, seg); 378 379 /* Link it up. */ 380 tda32->tda_frags[seg].frag_ptr0 = 381 htosonic32(sc, SONIC_CDTXADDR(sc, 382 SONIC_NEXTTX(nexttx)) & 0xffff); 383 } else { 384 tda16 = &sc->sc_tda16[nexttx]; 385 for (seg = 0; seg < dmamap->dm_nsegs; seg++) { 386 tda16->tda_frags[seg].frag_ptr1 = 387 htosonic16(sc, 388 (dmamap->dm_segs[seg].ds_addr >> 16) & 389 0xffff); 390 tda16->tda_frags[seg].frag_ptr0 = 391 htosonic16(sc, 392 dmamap->dm_segs[seg].ds_addr & 0xffff); 393 tda16->tda_frags[seg].frag_size = 394 htosonic16(sc, dmamap->dm_segs[seg].ds_len); 395 totlen += dmamap->dm_segs[seg].ds_len; 396 } 397 398 /* 399 * Pad the packet out if it's less than the 400 * minimum Ethernet frame size. 401 */ 402 if (totlen < (ETHER_MIN_LEN - ETHER_CRC_LEN)) { 403 tda16->tda_frags[seg - 1].frag_size = 404 htosonic16(sc, 405 dmamap->dm_segs[seg - 1].ds_len + 406 ((ETHER_MIN_LEN - ETHER_CRC_LEN) - totlen)); 407 totlen = ETHER_MIN_LEN - ETHER_CRC_LEN; 408 } 409 410 tda16->tda_status = 0; 411 tda16->tda_pktconfig = 0; 412 tda16->tda_pktsize = htosonic16(sc, totlen); 413 tda16->tda_fragcnt = htosonic16(sc, seg); 414 415 /* Link it up. */ 416 tda16->tda_frags[seg].frag_ptr0 = 417 htosonic16(sc, SONIC_CDTXADDR(sc, 418 SONIC_NEXTTX(nexttx)) & 0xffff); 419 } 420 421 /* Sync the Tx descriptor. */ 422 SONIC_CDTXSYNC(sc, nexttx, 423 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 424 425 /* Advance the Tx pointer. */ 426 sc->sc_txpending++; 427 sc->sc_txlast = nexttx; 428 429#if NBPFILTER > 0 430 /* 431 * Pass the packet to any BPF listeners. 432 */ 433 if (ifp->if_bpf) 434 bpf_mtap(ifp->if_bpf, m0); 435#endif 436 } 437 438 if (sc->sc_txpending == (SONIC_NTXDESC - 1)) { 439 /* No more slots left; notify upper layer. */ 440 ifp->if_flags |= IFF_OACTIVE; 441 } 442 443 if (sc->sc_txpending != opending) { 444 /* 445 * We enqueued packets. If the transmitter was idle, 446 * reset the txdirty pointer. 447 */ 448 if (opending == 0) 449 sc->sc_txdirty = SONIC_NEXTTX(olasttx); 450 451 /* 452 * Stop the SONIC on the last packet we've set up, 453 * and clear end-of-list on the descriptor previous 454 * to our new chain. 455 * 456 * NOTE: our `seg' variable should still be valid! 457 */ 458 if (sc->sc_32bit) { 459 olseg = 460 sonic32toh(sc, sc->sc_tda32[olasttx].tda_fragcnt); 461 sc->sc_tda32[sc->sc_txlast].tda_frags[seg].frag_ptr0 |= 462 htosonic32(sc, TDA_LINK_EOL); 463 SONIC_CDTXSYNC(sc, sc->sc_txlast, 464 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 465 sc->sc_tda32[olasttx].tda_frags[olseg].frag_ptr0 &= 466 htosonic32(sc, ~TDA_LINK_EOL); 467 SONIC_CDTXSYNC(sc, olasttx, 468 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 469 } else { 470 olseg = 471 sonic16toh(sc, sc->sc_tda16[olasttx].tda_fragcnt); 472 sc->sc_tda16[sc->sc_txlast].tda_frags[seg].frag_ptr0 |= 473 htosonic16(sc, TDA_LINK_EOL); 474 SONIC_CDTXSYNC(sc, sc->sc_txlast, 475 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 476 sc->sc_tda16[olasttx].tda_frags[olseg].frag_ptr0 &= 477 htosonic16(sc, ~TDA_LINK_EOL); 478 SONIC_CDTXSYNC(sc, olasttx, 479 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 480 } 481 482 /* Start the transmitter. */ 483 CSR_WRITE(sc, SONIC_CR, CR_TXP); 484 485 /* Set a watchdog timer in case the chip flakes out. */ 486 ifp->if_timer = 5; 487 } 488} 489 490/* 491 * sonic_watchdog: [ifnet interface function] 492 * 493 * Watchdog timer handler. 494 */ 495void 496sonic_watchdog(struct ifnet *ifp) 497{ 498 struct sonic_softc *sc = ifp->if_softc; 499 500 printf("%s: device timeout\n", sc->sc_dev.dv_xname); 501 ifp->if_oerrors++; 502 503 (void) sonic_init(ifp); 504} 505 506/* 507 * sonic_ioctl: [ifnet interface function] 508 * 509 * Handle control requests from the operator. 510 */ 511int 512sonic_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 513{ 514 int s, error; 515 516 s = splnet(); 517 518 switch (cmd) { 519 default: 520 error = ether_ioctl(ifp, cmd, data); 521 if (error == ENETRESET) { 522 /* 523 * Multicast list has changed; set the hardware 524 * filter accordingly. 525 */ 526 (void) sonic_init(ifp); 527 error = 0; 528 } 529 break; 530 } 531 532 splx(s); 533 return (error); 534} 535 536/* 537 * sonic_intr: 538 * 539 * Interrupt service routine. 540 */ 541int 542sonic_intr(void *arg) 543{ 544 struct sonic_softc *sc = arg; 545 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 546 uint16_t isr; 547 int handled = 0, wantinit; 548 549 for (wantinit = 0; wantinit == 0;) { 550 isr = CSR_READ(sc, SONIC_ISR) & sc->sc_imr; 551 if (isr == 0) 552 break; 553 CSR_WRITE(sc, SONIC_ISR, isr); /* ACK */ 554 555 handled = 1; 556 557 if (isr & IMR_PRX) 558 sonic_rxintr(sc); 559 560 if (isr & (IMR_PTX|IMR_TXER)) { 561 if (sonic_txintr(sc) & TCR_FU) { 562 printf("%s: transmit FIFO underrun\n", 563 sc->sc_dev.dv_xname); 564 wantinit = 1; 565 } 566 } 567 568 if (isr & (IMR_RFO|IMR_RBA|IMR_RBE|IMR_RDE)) { 569#define PRINTERR(bit, str) \ 570 if (isr & (bit)) \ 571 printf("%s: %s\n", sc->sc_dev.dv_xname, str) 572 PRINTERR(IMR_RFO, "receive FIFO overrun"); 573 PRINTERR(IMR_RBA, "receive buffer exceeded"); 574 PRINTERR(IMR_RBE, "receive buffers exhausted"); 575 PRINTERR(IMR_RDE, "receive descriptors exhausted"); 576 wantinit = 1; 577 } 578 } 579 580 if (handled) { 581 if (wantinit) 582 (void) sonic_init(ifp); 583 sonic_start(ifp); 584 } 585 586 return (handled); 587} 588 589/* 590 * sonic_txintr: 591 * 592 * Helper; handle transmit complete interrupts. 593 */ 594uint16_t 595sonic_txintr(struct sonic_softc *sc) 596{ 597 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 598 struct sonic_descsoft *ds; 599 struct sonic_tda32 *tda32; 600 struct sonic_tda16 *tda16; 601 uint16_t status, totstat = 0; 602 int i; 603 604 ifp->if_flags &= ~IFF_OACTIVE; 605 606 for (i = sc->sc_txdirty; sc->sc_txpending != 0; 607 i = SONIC_NEXTTX(i), sc->sc_txpending--) { 608 ds = &sc->sc_txsoft[i]; 609 610 SONIC_CDTXSYNC(sc, i, 611 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 612 613 if (sc->sc_32bit) { 614 tda32 = &sc->sc_tda32[i]; 615 status = sonic32toh(sc, tda32->tda_status); 616 } else { 617 tda16 = &sc->sc_tda16[i]; 618 status = sonic16toh(sc, tda16->tda_status); 619 } 620 621 if ((status & ~(TCR_EXDIS|TCR_CRCI|TCR_POWC|TCR_PINT)) == 0) 622 break; 623 624 totstat |= status; 625 626 bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0, 627 ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE); 628 bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap); 629 m_freem(ds->ds_mbuf); 630 ds->ds_mbuf = NULL; 631 632 /* 633 * Check for errors and collisions. 634 */ 635 if (status & TCR_PTX) 636 ifp->if_opackets++; 637 else 638 ifp->if_oerrors++; 639 ifp->if_collisions += TDA_STATUS_NCOL(status); 640 } 641 642 /* Update the dirty transmit buffer pointer. */ 643 sc->sc_txdirty = i; 644 645 /* 646 * Cancel the watchdog timer if there are no pending 647 * transmissions. 648 */ 649 if (sc->sc_txpending == 0) 650 ifp->if_timer = 0; 651 652 return (totstat); 653} 654 655/* 656 * sonic_rxintr: 657 * 658 * Helper; handle receive interrupts. 659 */ 660void 661sonic_rxintr(struct sonic_softc *sc) 662{ 663 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 664 struct sonic_descsoft *ds; 665 struct sonic_rda32 *rda32; 666 struct sonic_rda16 *rda16; 667 struct mbuf *m; 668 int i, len; 669 uint16_t status, bytecount, ptr0, ptr1, seqno; 670 671 for (i = sc->sc_rxptr;; i = SONIC_NEXTRX(i)) { 672 ds = &sc->sc_rxsoft[i]; 673 674 SONIC_CDRXSYNC(sc, i, 675 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 676 677 if (sc->sc_32bit) { 678 rda32 = &sc->sc_rda32[i]; 679 if (rda32->rda_inuse != 0) 680 break; 681 status = sonic32toh(sc, rda32->rda_status); 682 bytecount = sonic32toh(sc, rda32->rda_bytecount); 683 ptr0 = sonic32toh(sc, rda32->rda_pkt_ptr0); 684 ptr1 = sonic32toh(sc, rda32->rda_pkt_ptr1); 685 seqno = sonic32toh(sc, rda32->rda_seqno); 686 } else { 687 rda16 = &sc->sc_rda16[i]; 688 if (rda16->rda_inuse != 0) 689 break; 690 status = sonic16toh(sc, rda16->rda_status); 691 bytecount = sonic16toh(sc, rda16->rda_bytecount); 692 ptr0 = sonic16toh(sc, rda16->rda_pkt_ptr0); 693 ptr1 = sonic16toh(sc, rda16->rda_pkt_ptr1); 694 seqno = sonic16toh(sc, rda16->rda_seqno); 695 } 696 697 /* 698 * Make absolutely sure this is the only packet 699 * in this receive buffer. Our entire Rx buffer 700 * management scheme depends on this, and if the 701 * SONIC didn't follow our rule, it means we've 702 * misconfigured it. 703 */ 704 KASSERT(status & RCR_LPKT); 705 706 /* 707 * Make sure the packet arrived OK. If an error occurred, 708 * update stats and reset the descriptor. The buffer will 709 * be reused the next time the descriptor comes up in the 710 * ring. 711 */ 712 if ((status & RCR_PRX) == 0) { 713 if (status & RCR_FAER) 714 printf("%s: Rx frame alignment error\n", 715 sc->sc_dev.dv_xname); 716 else if (status & RCR_CRCR) 717 printf("%s: Rx CRC error\n", 718 sc->sc_dev.dv_xname); 719 ifp->if_ierrors++; 720 SONIC_INIT_RXDESC(sc, i); 721 continue; 722 } 723 724 bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0, 725 ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD); 726 727 /* 728 * The SONIC includes the CRC with every packet. 729 */ 730 len = bytecount; 731 732 /* 733 * Ok, if the chip is in 32-bit mode, then receive 734 * buffers must be aligned to 32-bit boundaries, 735 * which means the payload is misaligned. In this 736 * case, we must allocate a new mbuf, and copy the 737 * packet into it, scooted forward 2 bytes to ensure 738 * proper alignment. 739 * 740 * Note, in 16-bit mode, we can configure the SONIC 741 * to do what we want, and we have. 742 */ 743#ifndef __NO_STRICT_ALIGNMENT 744 if (sc->sc_32bit) { 745 MGETHDR(m, M_DONTWAIT, MT_DATA); 746 if (m == NULL) 747 goto dropit; 748 if (len > (MHLEN - 2)) { 749 MCLGET(m, M_DONTWAIT); 750 if ((m->m_flags & M_EXT) == 0) 751 goto dropit; 752 } 753 m->m_data += 2; 754 /* 755 * Note that we use a cluster for incoming frames, 756 * so the buffer is virtually contiguous. 757 */ 758 memcpy(mtod(m, caddr_t), mtod(ds->ds_mbuf, caddr_t), 759 len); 760 SONIC_INIT_RXDESC(sc, i); 761 bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0, 762 ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD); 763 } else 764#endif /* ! __NO_STRICT_ALIGNMENT */ 765 /* 766 * If the packet is small enough to fit in a single 767 * header mbuf, allocate one and copy the data into 768 * it. This greatly reduces memory consumption when 769 * we receive lots of small packets. 770 */ 771 if (sonic_copy_small != 0 && len <= (MHLEN - 2)) { 772 MGETHDR(m, M_DONTWAIT, MT_DATA); 773 if (m == NULL) 774 goto dropit; 775 m->m_data += 2; 776 /* 777 * Note that we use a cluster for incoming frames, 778 * so the buffer is virtually contiguous. 779 */ 780 memcpy(mtod(m, caddr_t), mtod(ds->ds_mbuf, caddr_t), 781 len); 782 SONIC_INIT_RXDESC(sc, i); 783 bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0, 784 ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD); 785 } else { 786 m = ds->ds_mbuf; 787 if (sonic_add_rxbuf(sc, i) != 0) { 788 dropit: 789 ifp->if_ierrors++; 790 SONIC_INIT_RXDESC(sc, i); 791 bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0, 792 ds->ds_dmamap->dm_mapsize, 793 BUS_DMASYNC_PREREAD); 794 continue; 795 } 796 } 797 798 ifp->if_ipackets++; 799 m->m_flags |= M_HASFCS; 800 m->m_pkthdr.rcvif = ifp; 801 m->m_pkthdr.len = m->m_len = len; 802 803#if NBPFILTER > 0 804 /* 805 * Pass this up to any BPF listeners. 806 */ 807 if (ifp->if_bpf) 808 bpf_mtap(ifp->if_bpf, m); 809#endif /* NBPFILTER > 0 */ 810 811 /* Pass it on. */ 812 (*ifp->if_input)(ifp, m); 813 } 814 815 /* Update the receive pointer. */ 816 sc->sc_rxptr = i; 817 CSR_WRITE(sc, SONIC_RWR, SONIC_CDRRADDR(sc, SONIC_PREVRX(i))); 818} 819 820/* 821 * sonic_reset: 822 * 823 * Perform a soft reset on the SONIC. 824 */ 825void 826sonic_reset(struct sonic_softc *sc) 827{ 828 829 CSR_WRITE(sc, SONIC_CR, 0); /* ensure RST is clear */ 830 CSR_WRITE(sc, SONIC_CR, CR_RST); 831 delay(1000); 832 CSR_WRITE(sc, SONIC_CR, 0); 833 delay(1000); 834} 835 836/* 837 * sonic_init: [ifnet interface function] 838 * 839 * Initialize the interface. Must be called at splnet(). 840 */ 841int 842sonic_init(struct ifnet *ifp) 843{ 844 struct sonic_softc *sc = ifp->if_softc; 845 struct sonic_descsoft *ds; 846 int i, error = 0; 847 uint16_t reg; 848 849 /* 850 * Cancel any pending I/O. 851 */ 852 sonic_stop(ifp, 0); 853 854 /* 855 * Reset the SONIC to a known state. 856 */ 857 sonic_reset(sc); 858 859 /* 860 * Bring the SONIC into reset state, and program the DCR. 861 * 862 * Note: We don't bother optimizing the transmit and receive 863 * thresholds, here. We just use the most conservative values: 864 * 865 * - Rx: 4 bytes (RFT0,RFT0 == 0,0) 866 * - Tx: 28 bytes (TFT0,TFT1 == 1,1) 867 */ 868 reg = sc->sc_dcr | DCR_TFT0 | DCR_TFT1; 869 if (sc->sc_32bit) 870 reg |= DCR_DW; 871 CSR_WRITE(sc, SONIC_CR, CR_RST); 872 CSR_WRITE(sc, SONIC_DCR, reg); 873 CSR_WRITE(sc, SONIC_DCR2, sc->sc_dcr2); 874 CSR_WRITE(sc, SONIC_CR, 0); 875 876 /* 877 * Initialize the transmit descriptors. 878 */ 879 if (sc->sc_32bit) { 880 for (i = 0; i < SONIC_NTXDESC; i++) { 881 memset(&sc->sc_tda32[i], 0, sizeof(struct sonic_tda32)); 882 SONIC_CDTXSYNC(sc, i, 883 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 884 } 885 } else { 886 for (i = 0; i < SONIC_NTXDESC; i++) { 887 memset(&sc->sc_tda16[i], 0, sizeof(struct sonic_tda16)); 888 SONIC_CDTXSYNC(sc, i, 889 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 890 } 891 } 892 sc->sc_txpending = 0; 893 sc->sc_txdirty = 0; 894 sc->sc_txlast = SONIC_NTXDESC - 1; 895 896 /* 897 * Initialize the receive descriptor ring. 898 */ 899 for (i = 0; i < SONIC_NRXDESC; i++) { 900 ds = &sc->sc_rxsoft[i]; 901 if (ds->ds_mbuf == NULL) { 902 if ((error = sonic_add_rxbuf(sc, i)) != 0) { 903 printf("%s: unable to allocate or map Rx " 904 "buffer %d, error = %d\n", 905 sc->sc_dev.dv_xname, i, error); 906 /* 907 * XXX Should attempt to run with fewer receive 908 * XXX buffers instead of just failing. 909 */ 910 sonic_rxdrain(sc); 911 goto out; 912 } 913 } 914 } 915 sc->sc_rxptr = 0; 916 917 /* Give the transmit ring to the SONIC. */ 918 CSR_WRITE(sc, SONIC_UTDAR, (SONIC_CDTXADDR(sc, 0) >> 16) & 0xffff); 919 CSR_WRITE(sc, SONIC_CTDAR, SONIC_CDTXADDR(sc, 0) & 0xffff); 920 921 /* Give the receive descriptor ring to the SONIC. */ 922 CSR_WRITE(sc, SONIC_URDAR, (SONIC_CDRXADDR(sc, 0) >> 16) & 0xffff); 923 CSR_WRITE(sc, SONIC_CRDAR, SONIC_CDRXADDR(sc, 0) & 0xffff); 924 925 /* Give the receive buffer ring to the SONIC. */ 926 CSR_WRITE(sc, SONIC_URRAR, (SONIC_CDRRADDR(sc, 0) >> 16) & 0xffff); 927 CSR_WRITE(sc, SONIC_RSAR, SONIC_CDRRADDR(sc, 0) & 0xffff); 928 if (sc->sc_32bit) 929 CSR_WRITE(sc, SONIC_REAR, 930 (SONIC_CDRRADDR(sc, SONIC_NRXDESC - 1) + 931 sizeof(struct sonic_rra32)) & 0xffff); 932 else 933 CSR_WRITE(sc, SONIC_REAR, 934 (SONIC_CDRRADDR(sc, SONIC_NRXDESC - 1) + 935 sizeof(struct sonic_rra16)) & 0xffff); 936 CSR_WRITE(sc, SONIC_RRR, SONIC_CDRRADDR(sc, 0) & 0xffff); 937 CSR_WRITE(sc, SONIC_RWR, SONIC_CDRRADDR(sc, SONIC_NRXDESC - 1)); 938 939 /* 940 * Set the End-Of-Buffer counter such that only one packet 941 * will be placed into each buffer we provide. Note we are 942 * following the recommendation of section 3.4.4 of the manual 943 * here, and have "lengthened" the receive buffers accordingly. 944 */ 945 if (sc->sc_32bit) 946 CSR_WRITE(sc, SONIC_EOBC, (ETHER_MAX_LEN + 2) / 2); 947 else 948 CSR_WRITE(sc, SONIC_EOBC, (ETHER_MAX_LEN / 2)); 949 950 /* Reset the receive sequence counter. */ 951 CSR_WRITE(sc, SONIC_RSC, 0); 952 953 /* Clear the tally registers. */ 954 CSR_WRITE(sc, SONIC_CRCETC, 0xffff); 955 CSR_WRITE(sc, SONIC_FAET, 0xffff); 956 CSR_WRITE(sc, SONIC_MPT, 0xffff); 957 958 /* Set the receive filter. */ 959 sonic_set_filter(sc); 960 961 /* 962 * Set the interrupt mask register. 963 */ 964 sc->sc_imr = IMR_RFO | IMR_RBA | IMR_RBE | IMR_RDE | 965 IMR_TXER | IMR_PTX | IMR_PRX; 966 CSR_WRITE(sc, SONIC_IMR, sc->sc_imr); 967 968 /* 969 * Start the receive process in motion. Note, we don't 970 * start the transmit process until we actually try to 971 * transmit packets. 972 */ 973 CSR_WRITE(sc, SONIC_CR, CR_RXEN | CR_RRRA); 974 975 /* 976 * ...all done! 977 */ 978 ifp->if_flags |= IFF_RUNNING; 979 ifp->if_flags &= ~IFF_OACTIVE; 980 981 out: 982 if (error) 983 printf("%s: interface not running\n", sc->sc_dev.dv_xname); 984 return (error); 985} 986 987/* 988 * sonic_rxdrain: 989 * 990 * Drain the receive queue. 991 */ 992void 993sonic_rxdrain(struct sonic_softc *sc) 994{ 995 struct sonic_descsoft *ds; 996 int i; 997 998 for (i = 0; i < SONIC_NRXDESC; i++) { 999 ds = &sc->sc_rxsoft[i]; 1000 if (ds->ds_mbuf != NULL) { 1001 bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap); 1002 m_freem(ds->ds_mbuf); 1003 ds->ds_mbuf = NULL; 1004 } 1005 } 1006} 1007 1008/* 1009 * sonic_stop: [ifnet interface function] 1010 * 1011 * Stop transmission on the interface. 1012 */ 1013void 1014sonic_stop(struct ifnet *ifp, int disable) 1015{ 1016 struct sonic_softc *sc = ifp->if_softc; 1017 struct sonic_descsoft *ds; 1018 int i; 1019 1020 /* 1021 * Disable interrupts. 1022 */ 1023 CSR_WRITE(sc, SONIC_IMR, 0); 1024 1025 /* 1026 * Stop the transmitter, receiver, and timer. 1027 */ 1028 CSR_WRITE(sc, SONIC_CR, CR_HTX|CR_RXDIS|CR_STP); 1029 for (i = 0; i < 1000; i++) { 1030 if ((CSR_READ(sc, SONIC_CR) & (CR_TXP|CR_RXEN|CR_ST)) == 0) 1031 break; 1032 delay(2); 1033 } 1034 if ((CSR_READ(sc, SONIC_CR) & (CR_TXP|CR_RXEN|CR_ST)) != 0) 1035 printf("%s: SONIC failed to stop\n", sc->sc_dev.dv_xname); 1036 1037 /* 1038 * Release any queued transmit buffers. 1039 */ 1040 for (i = 0; i < SONIC_NTXDESC; i++) { 1041 ds = &sc->sc_txsoft[i]; 1042 if (ds->ds_mbuf != NULL) { 1043 bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap); 1044 m_freem(ds->ds_mbuf); 1045 ds->ds_mbuf = NULL; 1046 } 1047 } 1048 1049 if (disable) 1050 sonic_rxdrain(sc); 1051 1052 /* 1053 * Mark the interface down and cancel the watchdog timer. 1054 */ 1055 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1056 ifp->if_timer = 0; 1057} 1058 1059/* 1060 * sonic_add_rxbuf: 1061 * 1062 * Add a receive buffer to the indicated descriptor. 1063 */ 1064int 1065sonic_add_rxbuf(struct sonic_softc *sc, int idx) 1066{ 1067 struct sonic_descsoft *ds = &sc->sc_rxsoft[idx]; 1068 struct mbuf *m; 1069 int error; 1070 1071 MGETHDR(m, M_DONTWAIT, MT_DATA); 1072 if (m == NULL) 1073 return (ENOBUFS); 1074 1075 MCLGET(m, M_DONTWAIT); 1076 if ((m->m_flags & M_EXT) == 0) { 1077 m_freem(m); 1078 return (ENOBUFS); 1079 } 1080 1081 if (ds->ds_mbuf != NULL) 1082 bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap); 1083 1084 ds->ds_mbuf = m; 1085 1086 error = bus_dmamap_load(sc->sc_dmat, ds->ds_dmamap, 1087 m->m_ext.ext_buf, m->m_ext.ext_size, NULL, BUS_DMA_NOWAIT); 1088 if (error) { 1089 printf("%s: can't load rx DMA map %d, error = %d\n", 1090 sc->sc_dev.dv_xname, idx, error); 1091 panic("sonic_add_rxbuf"); /* XXX */ 1092 } 1093 1094 bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0, 1095 ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD); 1096 1097 SONIC_INIT_RXDESC(sc, idx); 1098 1099 return (0); 1100} 1101 1102static void 1103sonic_set_camentry(struct sonic_softc *sc, int entry, const uint8_t *enaddr) 1104{ 1105 1106 if (sc->sc_32bit) { 1107 struct sonic_cda32 *cda = &sc->sc_cda32[entry]; 1108 1109 cda->cda_entry = htosonic32(sc, entry); 1110 cda->cda_addr0 = htosonic32(sc, enaddr[0] | (enaddr[1] << 8)); 1111 cda->cda_addr1 = htosonic32(sc, enaddr[2] | (enaddr[3] << 8)); 1112 cda->cda_addr2 = htosonic32(sc, enaddr[4] | (enaddr[5] << 8)); 1113 } else { 1114 struct sonic_cda16 *cda = &sc->sc_cda16[entry]; 1115 1116 cda->cda_entry = htosonic16(sc, entry); 1117 cda->cda_addr0 = htosonic16(sc, enaddr[0] | (enaddr[1] << 8)); 1118 cda->cda_addr1 = htosonic16(sc, enaddr[2] | (enaddr[3] << 8)); 1119 cda->cda_addr2 = htosonic16(sc, enaddr[4] | (enaddr[5] << 8)); 1120 } 1121} 1122 1123/* 1124 * sonic_set_filter: 1125 * 1126 * Set the SONIC receive filter. 1127 */ 1128void 1129sonic_set_filter(struct sonic_softc *sc) 1130{ 1131 struct ethercom *ec = &sc->sc_ethercom; 1132 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1133 struct ether_multi *enm; 1134 struct ether_multistep step; 1135 int i, entry = 0; 1136 uint16_t camvalid = 0; 1137 uint16_t rcr = 0; 1138 1139 if (ifp->if_flags & IFF_BROADCAST) 1140 rcr |= RCR_BRD; 1141 1142 if (ifp->if_flags & IFF_PROMISC) { 1143 rcr |= RCR_PRO; 1144 goto allmulti; 1145 } 1146 1147 /* Put our station address in the first CAM slot. */ 1148 sonic_set_camentry(sc, entry, LLADDR(ifp->if_sadl)); 1149 camvalid |= (1U << entry); 1150 entry++; 1151 1152 /* Add the multicast addresses to the CAM. */ 1153 ETHER_FIRST_MULTI(step, ec, enm); 1154 while (enm != NULL) { 1155 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { 1156 /* 1157 * We must listen to a range of multicast addresses. 1158 * The only way to do this on the SONIC is to enable 1159 * reception of all multicast packets. 1160 */ 1161 goto allmulti; 1162 } 1163 1164 if (entry == 16) { 1165 /* 1166 * Out of CAM slots. Have to enable reception 1167 * of all multicast addresses. 1168 */ 1169 goto allmulti; 1170 } 1171 1172 sonic_set_camentry(sc, entry, enm->enm_addrlo); 1173 camvalid |= (1U << entry); 1174 entry++; 1175 1176 ETHER_NEXT_MULTI(step, enm); 1177 } 1178 1179 ifp->if_flags &= ~IFF_ALLMULTI; 1180 goto setit; 1181 1182 allmulti: 1183 /* Use only the first CAM slot (station address). */ 1184 camvalid = 0x0001; 1185 entry = 1; 1186 rcr |= RCR_AMC; 1187 1188 setit: 1189 /* Load the CAM. */ 1190 SONIC_CDCAMSYNC(sc, BUS_DMASYNC_PREWRITE); 1191 CSR_WRITE(sc, SONIC_CDP, SONIC_CDCAMADDR(sc) & 0xffff); 1192 CSR_WRITE(sc, SONIC_CDC, entry); 1193 CSR_WRITE(sc, SONIC_CR, CR_LCAM); 1194 for (i = 0; i < 10000; i++) { 1195 if ((CSR_READ(sc, SONIC_CR) & CR_LCAM) == 0) 1196 break; 1197 delay(2); 1198 } 1199 if (CSR_READ(sc, SONIC_CR) & CR_LCAM) 1200 printf("%s: CAM load failed\n", sc->sc_dev.dv_xname); 1201 SONIC_CDCAMSYNC(sc, BUS_DMASYNC_POSTWRITE); 1202 1203 /* Set the CAM enable resgiter. */ 1204 CSR_WRITE(sc, SONIC_CER, camvalid); 1205 1206 /* Set the receive control register. */ 1207 CSR_WRITE(sc, SONIC_RCR, rcr); 1208} 1209