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