1 /* $NetBSD: if_temac.c,v 1.2 2007/03/04 05:59:46 christos Exp $ */ 2 3 /* 4 * Copyright (c) 2006 Jachym Holecek 5 * All rights reserved. 6 * 7 * Written for DFC Design, s.r.o. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Driver for Xilinx LocalLink TEMAC as wired on the GSRD platform. 34 * 35 * TODO: 36 * - Optimize 37 * - Checksum offload 38 * - Address filters 39 * - Support jumbo frames 40 */ 41 42 #include <sys/cdefs.h> 43 __KERNEL_RCSID(0, "$NetBSD: if_temac.c,v 1.2 2007/03/04 05:59:46 christos Exp $"); 44 45 #include "bpfilter.h" 46 47 #include <sys/param.h> 48 #include <sys/systm.h> 49 #include <sys/mbuf.h> 50 #include <sys/kernel.h> 51 #include <sys/socket.h> 52 #include <sys/ioctl.h> 53 #include <sys/device.h> 54 55 #include <uvm/uvm_extern.h> 56 57 #include <net/if.h> 58 #include <net/if_dl.h> 59 #include <net/if_media.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 68 #include <evbppc/virtex/idcr.h> 69 #include <evbppc/virtex/dev/xcvbusvar.h> 70 #include <evbppc/virtex/dev/cdmacreg.h> 71 #include <evbppc/virtex/dev/temacreg.h> 72 #include <evbppc/virtex/dev/temacvar.h> 73 74 #include <dev/mii/miivar.h> 75 76 77 /* This is outside of TEMAC's DCR window, we have to hardcode it... */ 78 #define DCR_ETH_BASE 0x0030 79 80 #define TEMAC_REGDEBUG 0 81 #define TEMAC_RXDEBUG 0 82 #define TEMAC_TXDEBUG 0 83 84 #if TEMAC_RXDEBUG > 0 || TEMAC_TXDEBUG > 0 85 #define TEMAC_DEBUG 1 86 #else 87 #define TEMAC_DEBUG 0 88 #endif 89 90 #if TEMAC_REGDEBUG > 0 91 #define TRACEREG(arg) printf arg 92 #else 93 #define TRACEREG(arg) /* nop */ 94 #endif 95 96 /* DMA control chains take up one (16KB) page. */ 97 #define TEMAC_NTXDESC 256 98 #define TEMAC_NRXDESC 256 99 100 #define TEMAC_TXQLEN 64 /* Software Tx queue length */ 101 #define TEMAC_NTXSEG 16 /* Maximum Tx segments per packet */ 102 103 #define TEMAC_NRXSEG 1 /* Maximum Rx segments per packet */ 104 #define TEMAC_RXPERIOD 1 /* Interrupt every N descriptors. */ 105 #define TEMAC_RXTIMO_HZ 100 /* Rx reaper frequency */ 106 107 /* Next Tx descriptor and descriptor's offset WRT sc_cdaddr. */ 108 #define TEMAC_TXSINC(n, i) (((n) + TEMAC_TXQLEN + (i)) % TEMAC_TXQLEN) 109 #define TEMAC_TXINC(n, i) (((n) + TEMAC_NTXDESC + (i)) % TEMAC_NTXDESC) 110 111 #define TEMAC_TXSNEXT(n) TEMAC_TXSINC((n), 1) 112 #define TEMAC_TXNEXT(n) TEMAC_TXINC((n), 1) 113 #define TEMAC_TXDOFF(n) (offsetof(struct temac_control, cd_txdesc) + \ 114 (n) * sizeof(struct cdmac_descr)) 115 116 /* Next Rx descriptor and descriptor's offset WRT sc_cdaddr. */ 117 #define TEMAC_RXINC(n, i) (((n) + TEMAC_NRXDESC + (i)) % TEMAC_NRXDESC) 118 #define TEMAC_RXNEXT(n) TEMAC_RXINC((n), 1) 119 #define TEMAC_RXDOFF(n) (offsetof(struct temac_control, cd_rxdesc) + \ 120 (n) * sizeof(struct cdmac_descr)) 121 #define TEMAC_ISINTR(i) (((i) % TEMAC_RXPERIOD) == 0) 122 #define TEMAC_ISLAST(i) ((i) == (TEMAC_NRXDESC - 1)) 123 124 125 struct temac_control { 126 struct cdmac_descr cd_txdesc[TEMAC_NTXDESC]; 127 struct cdmac_descr cd_rxdesc[TEMAC_NRXDESC]; 128 }; 129 130 struct temac_txsoft { 131 bus_dmamap_t txs_dmap; 132 struct mbuf *txs_mbuf; 133 int txs_last; 134 }; 135 136 struct temac_rxsoft { 137 bus_dmamap_t rxs_dmap; 138 struct mbuf *rxs_mbuf; 139 }; 140 141 struct temac_softc { 142 struct device sc_dev; 143 struct ethercom sc_ec; 144 #define sc_if sc_ec.ec_if 145 146 /* Peripheral registers */ 147 bus_space_tag_t sc_iot; 148 bus_space_handle_t sc_ioh; 149 150 /* CDMAC channel registers */ 151 bus_space_tag_t sc_dma_rxt; 152 bus_space_handle_t sc_dma_rxh; /* Rx channel */ 153 bus_space_handle_t sc_dma_rsh; /* Rx status */ 154 155 bus_space_tag_t sc_dma_txt; 156 bus_space_handle_t sc_dma_txh; /* Tx channel */ 157 bus_space_handle_t sc_dma_tsh; /* Tx status */ 158 159 struct temac_txsoft sc_txsoft[TEMAC_TXQLEN]; 160 struct temac_rxsoft sc_rxsoft[TEMAC_NRXDESC]; 161 162 struct callout sc_rx_timo; 163 struct callout sc_mii_tick; 164 struct mii_data sc_mii; 165 166 bus_dmamap_t sc_control_dmap; 167 #define sc_cdaddr sc_control_dmap->dm_segs[0].ds_addr 168 169 struct temac_control *sc_control_data; 170 #define sc_rxdescs sc_control_data->cd_rxdesc 171 #define sc_txdescs sc_control_data->cd_txdesc 172 173 int sc_txbusy; 174 175 int sc_txfree; 176 int sc_txcur; 177 int sc_txreap; 178 179 int sc_rxreap; 180 181 int sc_txsfree; 182 int sc_txscur; 183 int sc_txsreap; 184 185 int sc_dead; /* Rx/Tx DMA error (fatal) */ 186 int sc_rx_drained; 187 188 int sc_rx_chan; 189 int sc_tx_chan; 190 191 void *sc_sdhook; 192 void *sc_rx_ih; 193 void *sc_tx_ih; 194 195 bus_dma_tag_t sc_dmat; 196 }; 197 198 /* Device interface. */ 199 static void temac_attach(struct device *, struct device *, void *); 200 201 /* Ifnet interface. */ 202 static int temac_init(struct ifnet *); 203 static int temac_ioctl(struct ifnet *, u_long, void *); 204 static void temac_start(struct ifnet *); 205 static void temac_stop(struct ifnet *, int); 206 207 /* Media management. */ 208 static int temac_mediachange(struct ifnet *); 209 static void temac_mediastatus(struct ifnet *, struct ifmediareq *); 210 static int temac_mii_readreg(struct device *, int, int); 211 static void temac_mii_statchg(struct device *); 212 static void temac_mii_tick(void *); 213 static void temac_mii_writereg(struct device *, int, int, int); 214 215 /* Indirect hooks. */ 216 static void temac_shutdown(void *); 217 static void temac_rx_intr(void *); 218 static void temac_tx_intr(void *); 219 220 /* Tools. */ 221 static inline void temac_rxcdsync(struct temac_softc *, int, int, int); 222 static inline void temac_txcdsync(struct temac_softc *, int, int, int); 223 static void temac_txreap(struct temac_softc *); 224 static void temac_rxreap(struct temac_softc *); 225 static int temac_rxalloc(struct temac_softc *, int, int); 226 static void temac_rxtimo(void *); 227 static void temac_rxdrain(struct temac_softc *); 228 static void temac_reset(struct temac_softc *); 229 static void temac_txkick(struct temac_softc *); 230 231 /* Register access. */ 232 static inline void gmi_write_8(uint32_t, uint32_t, uint32_t); 233 static inline void gmi_write_4(uint32_t, uint32_t); 234 static inline void gmi_read_8(uint32_t, uint32_t *, uint32_t *); 235 static inline uint32_t gmi_read_4(uint32_t); 236 static inline void hif_wait_stat(uint32_t); 237 238 #define cdmac_rx_stat(sc) \ 239 bus_space_read_4((sc)->sc_dma_rxt, (sc)->sc_dma_rsh, 0 /* XXX hack */) 240 241 #define cdmac_rx_reset(sc) \ 242 bus_space_write_4((sc)->sc_dma_rxt, (sc)->sc_dma_rsh, 0, CDMAC_STAT_RESET) 243 244 #define cdmac_rx_start(sc, val) \ 245 bus_space_write_4((sc)->sc_dma_rxt, (sc)->sc_dma_rxh, CDMAC_CURDESC, (val)) 246 247 #define cdmac_tx_stat(sc) \ 248 bus_space_read_4((sc)->sc_dma_txt, (sc)->sc_dma_tsh, 0 /* XXX hack */) 249 250 #define cdmac_tx_reset(sc) \ 251 bus_space_write_4((sc)->sc_dma_txt, (sc)->sc_dma_tsh, 0, CDMAC_STAT_RESET) 252 253 #define cdmac_tx_start(sc, val) \ 254 bus_space_write_4((sc)->sc_dma_txt, (sc)->sc_dma_txh, CDMAC_CURDESC, (val)) 255 256 257 CFATTACH_DECL(temac, sizeof(struct temac_softc), 258 xcvbus_child_match, temac_attach, NULL, NULL); 259 260 261 /* 262 * Private bus utilities. 263 */ 264 static inline void 265 hif_wait_stat(uint32_t mask) 266 { 267 int i = 0; 268 269 while (mask != (mfidcr(IDCR_HIF_STAT) & mask)) { 270 if (i++ > 100) { 271 printf("%s: timeout waiting for 0x%08x\n", 272 __func__, mask); 273 break; 274 } 275 delay(5); 276 } 277 278 TRACEREG(("%s: stat %#08x loops %d\n", __func__, mask, i)); 279 } 280 281 static inline void 282 gmi_write_4(uint32_t addr, uint32_t lo) 283 { 284 mtidcr(IDCR_HIF_ARG0, lo); 285 mtidcr(IDCR_HIF_CTRL, (addr & HIF_CTRL_GMIADDR) | HIF_CTRL_WRITE); 286 hif_wait_stat(HIF_STAT_GMIWR); 287 288 TRACEREG(("%s: %#08x <- %#08x\n", __func__, addr, lo)); 289 } 290 291 static inline void 292 gmi_write_8(uint32_t addr, uint32_t lo, uint32_t hi) 293 { 294 mtidcr(IDCR_HIF_ARG1, hi); 295 gmi_write_4(addr, lo); 296 } 297 298 static inline void 299 gmi_read_8(uint32_t addr, uint32_t *lo, uint32_t *hi) 300 { 301 *lo = gmi_read_4(addr); 302 *hi = mfidcr(IDCR_HIF_ARG1); 303 } 304 305 static inline uint32_t 306 gmi_read_4(uint32_t addr) 307 { 308 uint32_t res; 309 310 mtidcr(IDCR_HIF_CTRL, addr & HIF_CTRL_GMIADDR); 311 hif_wait_stat(HIF_STAT_GMIRR); 312 313 res = mfidcr(IDCR_HIF_ARG0); 314 TRACEREG(("%s: %#08x -> %#08x\n", __func__, addr, res)); 315 return (res); 316 } 317 318 /* 319 * Generic device. 320 */ 321 static void 322 temac_attach(struct device *parent, struct device *self, void *aux) 323 { 324 struct xcvbus_attach_args *vaa = aux; 325 struct ll_dmac *rx = vaa->vaa_rx_dmac; 326 struct ll_dmac *tx = vaa->vaa_tx_dmac; 327 struct temac_softc *sc = (struct temac_softc *)self; 328 struct ifnet *ifp = &sc->sc_if; 329 struct mii_data *mii = &sc->sc_mii; 330 uint8_t enaddr[ETHER_ADDR_LEN]; 331 bus_dma_segment_t seg; 332 int error, nseg, i; 333 334 printf(": TEMAC\n"); /* XXX will be LL_TEMAC, PLB_TEMAC */ 335 336 KASSERT(rx); 337 KASSERT(tx); 338 339 sc->sc_dmat = vaa->vaa_dmat; 340 sc->sc_dead = 0; 341 sc->sc_rx_drained = 1; 342 sc->sc_txbusy = 0; 343 sc->sc_iot = vaa->vaa_iot; 344 sc->sc_dma_rxt = rx->dmac_iot; 345 sc->sc_dma_txt = tx->dmac_iot; 346 347 /* 348 * Map HIF and receive/transmit dmac registers. 349 */ 350 if ((error = bus_space_map(vaa->vaa_iot, vaa->vaa_addr, TEMAC_SIZE, 0, 351 &sc->sc_ioh)) != 0) { 352 printf("%s: could not map registers\n", device_xname(self)); 353 goto fail_0; 354 } 355 356 if ((error = bus_space_map(sc->sc_dma_rxt, rx->dmac_ctrl_addr, 357 CDMAC_CTRL_SIZE, 0, &sc->sc_dma_rxh)) != 0) { 358 printf("%s: could not map Rx control registers\n", 359 device_xname(self)); 360 goto fail_0; 361 } 362 if ((error = bus_space_map(sc->sc_dma_rxt, rx->dmac_stat_addr, 363 CDMAC_STAT_SIZE, 0, &sc->sc_dma_rsh)) != 0) { 364 printf("%s: could not map Rx status register\n", 365 device_xname(self)); 366 goto fail_0; 367 } 368 369 if ((error = bus_space_map(sc->sc_dma_txt, tx->dmac_ctrl_addr, 370 CDMAC_CTRL_SIZE, 0, &sc->sc_dma_txh)) != 0) { 371 printf("%s: could not map Tx control registers\n", 372 device_xname(self)); 373 goto fail_0; 374 } 375 if ((error = bus_space_map(sc->sc_dma_txt, tx->dmac_stat_addr, 376 CDMAC_STAT_SIZE, 0, &sc->sc_dma_tsh)) != 0) { 377 printf("%s: could not map Tx status register\n", 378 device_xname(self)); 379 goto fail_0; 380 } 381 382 /* 383 * Allocate and initialize DMA control chains. 384 */ 385 if ((error = bus_dmamem_alloc(sc->sc_dmat, 386 sizeof(struct temac_control), 8, 0, &seg, 1, &nseg, 0)) != 0) { 387 printf("%s: could not allocate control data\n", 388 sc->sc_dev.dv_xname); 389 goto fail_0; 390 } 391 392 if ((error = bus_dmamem_map(sc->sc_dmat, &seg, nseg, 393 sizeof(struct temac_control), 394 (void **)&sc->sc_control_data, BUS_DMA_COHERENT)) != 0) { 395 printf("%s: could not map control data\n", 396 sc->sc_dev.dv_xname); 397 goto fail_1; 398 } 399 400 if ((error = bus_dmamap_create(sc->sc_dmat, 401 sizeof(struct temac_control), 1, 402 sizeof(struct temac_control), 0, 0, &sc->sc_control_dmap)) != 0) { 403 printf("%s: could not create control data DMA map\n", 404 sc->sc_dev.dv_xname); 405 goto fail_2; 406 } 407 408 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_control_dmap, 409 sc->sc_control_data, sizeof(struct temac_control), NULL, 0)) != 0) { 410 printf("%s: could not load control data DMA map\n", 411 sc->sc_dev.dv_xname); 412 goto fail_3; 413 } 414 415 /* 416 * Link descriptor chains. 417 */ 418 memset(sc->sc_control_data, 0, sizeof(struct temac_control)); 419 420 for (i = 0; i < TEMAC_NTXDESC; i++) { 421 sc->sc_txdescs[i].desc_next = sc->sc_cdaddr + 422 TEMAC_TXDOFF(TEMAC_TXNEXT(i)); 423 sc->sc_txdescs[i].desc_stat = CDMAC_STAT_DONE; 424 } 425 for (i = 0; i < TEMAC_NRXDESC; i++) { 426 sc->sc_rxdescs[i].desc_next = sc->sc_cdaddr + 427 TEMAC_RXDOFF(TEMAC_RXNEXT(i)); 428 sc->sc_txdescs[i].desc_stat = CDMAC_STAT_DONE; 429 } 430 431 bus_dmamap_sync(sc->sc_dmat, sc->sc_control_dmap, 0, 432 sizeof(struct temac_control), 433 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 434 435 /* 436 * Initialize software state for transmit/receive jobs. 437 */ 438 for (i = 0; i < TEMAC_TXQLEN; i++) { 439 if ((error = bus_dmamap_create(sc->sc_dmat, 440 ETHER_MAX_LEN_JUMBO, TEMAC_NTXSEG, ETHER_MAX_LEN_JUMBO, 441 0, 0, &sc->sc_txsoft[i].txs_dmap)) != 0) { 442 printf("%s: could not create Tx DMA map %d\n", 443 sc->sc_dev.dv_xname, i); 444 goto fail_4; 445 } 446 sc->sc_txsoft[i].txs_mbuf = NULL; 447 sc->sc_txsoft[i].txs_last = 0; 448 } 449 450 for (i = 0; i < TEMAC_NRXDESC; i++) { 451 if ((error = bus_dmamap_create(sc->sc_dmat, 452 MCLBYTES, TEMAC_NRXSEG, MCLBYTES, 0, 0, 453 &sc->sc_rxsoft[i].rxs_dmap)) != 0) { 454 printf("%s: could not create Rx DMA map %d\n", 455 sc->sc_dev.dv_xname, i); 456 goto fail_5; 457 } 458 sc->sc_rxsoft[i].rxs_mbuf = NULL; 459 } 460 461 /* 462 * Setup transfer interrupt handlers. 463 */ 464 error = ENOMEM; 465 466 sc->sc_rx_ih = ll_dmac_intr_establish(rx->dmac_chan, 467 temac_rx_intr, sc); 468 if (sc->sc_rx_ih == NULL) { 469 printf("%s: could not establish Rx interrupt\n", 470 device_xname(self)); 471 goto fail_5; 472 } 473 474 sc->sc_tx_ih = ll_dmac_intr_establish(tx->dmac_chan, 475 temac_tx_intr, sc); 476 if (sc->sc_tx_ih == NULL) { 477 printf("%s: could not establish Tx interrupt\n", 478 device_xname(self)); 479 goto fail_6; 480 } 481 482 /* XXXFreza: faked, should read unicast address filter. */ 483 enaddr[0] = 0x00; 484 enaddr[1] = 0x11; 485 enaddr[2] = 0x17; 486 enaddr[3] = 0xff; 487 enaddr[4] = 0xff; 488 enaddr[5] = 0x01; 489 490 /* 491 * Initialize the TEMAC. 492 */ 493 temac_reset(sc); 494 495 /* Configure MDIO link. */ 496 gmi_write_4(TEMAC_GMI_MGMTCF, GMI_MGMT_CLKDIV_100MHz | GMI_MGMT_MDIO); 497 498 /* Initialize PHY. */ 499 mii->mii_ifp = ifp; 500 mii->mii_readreg = temac_mii_readreg; 501 mii->mii_writereg = temac_mii_writereg; 502 mii->mii_statchg = temac_mii_statchg; 503 ifmedia_init(&mii->mii_media, 0, temac_mediachange, 504 temac_mediastatus); 505 506 mii_attach(&sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY, 507 MII_OFFSET_ANY, 0); 508 if (LIST_FIRST(&mii->mii_phys) == NULL) { 509 ifmedia_add(&mii->mii_media, IFM_ETHER|IFM_NONE, 0, NULL); 510 ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_NONE); 511 } else { 512 ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_AUTO); 513 } 514 515 /* Hold PHY in reset. */ 516 bus_space_write_4(sc->sc_iot, sc->sc_ioh, TEMAC_RESET, TEMAC_RESET_PHY); 517 518 /* Reset EMAC. */ 519 bus_space_write_4(sc->sc_iot, sc->sc_ioh, TEMAC_RESET, 520 TEMAC_RESET_EMAC); 521 delay(10000); 522 523 /* Reset peripheral, awakes PHY and EMAC. */ 524 bus_space_write_4(sc->sc_iot, sc->sc_ioh, TEMAC_RESET, 525 TEMAC_RESET_PERIPH); 526 delay(40000); 527 528 /* (Re-)Configure MDIO link. */ 529 gmi_write_4(TEMAC_GMI_MGMTCF, GMI_MGMT_CLKDIV_100MHz | GMI_MGMT_MDIO); 530 531 /* 532 * Hook up with network stack. 533 */ 534 strcpy(ifp->if_xname, sc->sc_dev.dv_xname); 535 ifp->if_softc = sc; 536 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 537 ifp->if_ioctl = temac_ioctl; 538 ifp->if_start = temac_start; 539 ifp->if_init = temac_init; 540 ifp->if_stop = temac_stop; 541 ifp->if_watchdog = NULL; 542 IFQ_SET_READY(&ifp->if_snd); 543 IFQ_SET_MAXLEN(&ifp->if_snd, TEMAC_TXQLEN); 544 545 sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU; 546 547 if_attach(ifp); 548 ether_ifattach(ifp, enaddr); 549 550 sc->sc_sdhook = shutdownhook_establish(temac_shutdown, sc); 551 if (sc->sc_sdhook == NULL) 552 printf("%s: WARNING: unable to establish shutdown hook\n", 553 device_xname(self)); 554 555 callout_setfunc(&sc->sc_mii_tick, temac_mii_tick, sc); 556 callout_setfunc(&sc->sc_rx_timo, temac_rxtimo, sc); 557 558 return ; 559 560 fail_6: 561 ll_dmac_intr_disestablish(rx->dmac_chan, sc->sc_rx_ih); 562 i = TEMAC_NRXDESC; 563 fail_5: 564 for (--i; i >= 0; i--) 565 bus_dmamap_destroy(sc->sc_dmat, sc->sc_rxsoft[i].rxs_dmap); 566 i = TEMAC_TXQLEN; 567 fail_4: 568 for (--i; i >= 0; i--) 569 bus_dmamap_destroy(sc->sc_dmat, sc->sc_txsoft[i].txs_dmap); 570 fail_3: 571 bus_dmamap_destroy(sc->sc_dmat, sc->sc_control_dmap); 572 fail_2: 573 bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_control_data, 574 sizeof(struct temac_control)); 575 fail_1: 576 bus_dmamem_free(sc->sc_dmat, &seg, nseg); 577 fail_0: 578 printf("%s: error = %d\n", device_xname(self), error); 579 } 580 581 /* 582 * Network device. 583 */ 584 static int 585 temac_init(struct ifnet *ifp) 586 { 587 struct temac_softc *sc = (struct temac_softc *)ifp->if_softc; 588 uint32_t rcr, tcr; 589 int i, error; 590 591 /* Reset DMA channels. */ 592 cdmac_tx_reset(sc); 593 cdmac_rx_reset(sc); 594 595 /* Set current media. */ 596 mii_mediachg(&sc->sc_mii); 597 callout_schedule(&sc->sc_mii_tick, hz); 598 599 /* Enable EMAC engine. */ 600 rcr = (gmi_read_4(TEMAC_GMI_RXCF1) | GMI_RX_ENABLE) & 601 ~(GMI_RX_JUMBO | GMI_RX_FCS); 602 gmi_write_4(TEMAC_GMI_RXCF1, rcr); 603 604 tcr = (gmi_read_4(TEMAC_GMI_TXCF) | GMI_TX_ENABLE) & 605 ~(GMI_TX_JUMBO | GMI_TX_FCS); 606 gmi_write_4(TEMAC_GMI_TXCF, tcr); 607 608 /* XXXFreza: Force promiscuous mode, for now. */ 609 gmi_write_4(TEMAC_GMI_AFM, GMI_AFM_PROMISC); 610 ifp->if_flags |= IFF_PROMISC; 611 612 /* Rx/Tx queues are drained -- either from attach() or stop(). */ 613 sc->sc_txsfree = TEMAC_TXQLEN; 614 sc->sc_txsreap = 0; 615 sc->sc_txscur = 0; 616 617 sc->sc_txfree = TEMAC_NTXDESC; 618 sc->sc_txreap = 0; 619 sc->sc_txcur = 0; 620 621 sc->sc_rxreap = 0; 622 623 /* Allocate and map receive buffers. */ 624 if (sc->sc_rx_drained) { 625 for (i = 0; i < TEMAC_NRXDESC; i++) { 626 if ((error = temac_rxalloc(sc, i, 1)) != 0) { 627 printf("%s: failed to allocate Rx " 628 "descriptor %d\n", 629 sc->sc_dev.dv_xname, i); 630 631 temac_rxdrain(sc); 632 return (error); 633 } 634 } 635 sc->sc_rx_drained = 0; 636 637 temac_rxcdsync(sc, 0, TEMAC_NRXDESC, 638 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 639 cdmac_rx_start(sc, sc->sc_cdaddr + TEMAC_RXDOFF(0)); 640 } 641 642 ifp->if_flags |= IFF_RUNNING; 643 ifp->if_flags &= ~IFF_OACTIVE; 644 645 return (0); 646 } 647 648 static int 649 temac_ioctl(struct ifnet *ifp, u_long cmd, void *data) 650 { 651 struct temac_softc *sc = (struct temac_softc *)ifp->if_softc; 652 struct ifreq *ifr = (struct ifreq *)data; 653 int s, ret; 654 655 s = splnet(); 656 if (sc->sc_dead) { 657 ret = EIO; 658 } else 659 switch (cmd) { 660 case SIOCSIFMEDIA: 661 case SIOCGIFMEDIA: 662 ret = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, 663 cmd); 664 break; 665 666 default: 667 ret = ether_ioctl(ifp, cmd, data); 668 break; 669 } 670 671 splx(s); 672 return (ret); 673 } 674 675 static void 676 temac_start(struct ifnet *ifp) 677 { 678 struct temac_softc *sc = (struct temac_softc *)ifp->if_softc; 679 struct temac_txsoft *txs; 680 struct mbuf *m; 681 bus_dmamap_t dmap; 682 int error, head, nsegs, i; 683 684 nsegs = 0; 685 head = sc->sc_txcur; 686 txs = NULL; /* gcc */ 687 688 if (sc->sc_dead) 689 return; 690 691 KASSERT(sc->sc_txfree >= 0); 692 KASSERT(sc->sc_txsfree >= 0); 693 694 /* 695 * Push mbufs into descriptor chain until we drain the interface 696 * queue or run out of descriptors. We'll mark the first segment 697 * as "done" in hope that we might put CDMAC interrupt above IPL_NET 698 * and have it start jobs & mark packets for GC preemtively for 699 * us -- creativity due to limitations in CDMAC transfer engine 700 * (it really consumes lists, not circular queues, AFAICS). 701 * 702 * We schedule one interrupt per Tx batch. 703 */ 704 while (1) { 705 IFQ_POLL(&ifp->if_snd, m); 706 if (m == NULL) 707 break; 708 709 if (sc->sc_txsfree == 0) { 710 ifp->if_flags |= IFF_OACTIVE; 711 break; 712 } 713 714 txs = &sc->sc_txsoft[sc->sc_txscur]; 715 dmap = txs->txs_dmap; 716 717 if (txs->txs_mbuf != NULL) 718 printf("FOO\n"); 719 if (txs->txs_last) 720 printf("BAR\n"); 721 722 if ((error = bus_dmamap_load_mbuf(sc->sc_dmat, dmap, m, 723 BUS_DMA_WRITE | BUS_DMA_NOWAIT)) != 0) { 724 if (error == EFBIG) { 725 printf("%s: Tx consumes too many segments, " 726 "dropped\n", sc->sc_dev.dv_xname); 727 IFQ_DEQUEUE(&ifp->if_snd, m); 728 m_freem(m); 729 continue; 730 } else { 731 printf("%s: Tx stall due to resource " 732 "shortage\n", sc->sc_dev.dv_xname); 733 break; 734 } 735 } 736 737 /* 738 * If we're short on DMA descriptors, notify upper layers 739 * and leave this packet for later. 740 */ 741 if (dmap->dm_nsegs > sc->sc_txfree) { 742 bus_dmamap_unload(sc->sc_dmat, dmap); 743 ifp->if_flags |= IFF_OACTIVE; 744 break; 745 } 746 747 IFQ_DEQUEUE(&ifp->if_snd, m); 748 749 bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize, 750 BUS_DMASYNC_PREWRITE); 751 txs->txs_mbuf = m; 752 753 /* 754 * Map the packet into descriptor chain. XXX We'll want 755 * to fill checksum offload commands here. 756 * 757 * We would be in a race if we weren't blocking CDMAC intr 758 * at this point -- we need to be locked against txreap() 759 * because of dmasync ops. 760 */ 761 762 temac_txcdsync(sc, sc->sc_txcur, dmap->dm_nsegs, 763 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 764 765 for (i = 0; i < dmap->dm_nsegs; i++) { 766 sc->sc_txdescs[sc->sc_txcur].desc_addr = 767 dmap->dm_segs[i].ds_addr; 768 sc->sc_txdescs[sc->sc_txcur].desc_size = 769 dmap->dm_segs[i].ds_len; 770 sc->sc_txdescs[sc->sc_txcur].desc_stat = 771 (i == 0 ? CDMAC_STAT_SOP : 0) | 772 (i == (dmap->dm_nsegs - 1) ? CDMAC_STAT_EOP : 0); 773 774 sc->sc_txcur = TEMAC_TXNEXT(sc->sc_txcur); 775 } 776 777 sc->sc_txfree -= dmap->dm_nsegs; 778 nsegs += dmap->dm_nsegs; 779 780 sc->sc_txscur = TEMAC_TXSNEXT(sc->sc_txscur); 781 sc->sc_txsfree--; 782 } 783 784 /* Get data running if we queued any. */ 785 if (nsegs > 0) { 786 int tail = TEMAC_TXINC(sc->sc_txcur, -1); 787 788 /* Mark the last packet in this job. */ 789 txs->txs_last = 1; 790 791 /* Mark the last descriptor in this job. */ 792 sc->sc_txdescs[tail].desc_stat |= CDMAC_STAT_STOP | 793 CDMAC_STAT_INTR; 794 temac_txcdsync(sc, head, nsegs, 795 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 796 797 temac_txkick(sc); 798 #if TEMAC_TXDEBUG > 0 799 printf("%s: start: txcur %03d -> %03d, nseg %03d\n", 800 sc->sc_dev.dv_xname, head, sc->sc_txcur, nsegs); 801 #endif 802 } 803 } 804 805 static void 806 temac_stop(struct ifnet *ifp, int disable) 807 { 808 struct temac_softc *sc = (struct temac_softc *)ifp->if_softc; 809 struct temac_txsoft *txs; 810 int i; 811 812 #if TEMAC_DEBUG > 0 813 printf("%s: stop\n", device_xname(&sc->sc_dev)); 814 #endif 815 816 /* Down the MII. */ 817 callout_stop(&sc->sc_mii_tick); 818 mii_down(&sc->sc_mii); 819 820 /* Stop the engine. */ 821 temac_reset(sc); 822 823 /* Drain buffers queues (unconditionally). */ 824 temac_rxdrain(sc); 825 826 for (i = 0; i < TEMAC_TXQLEN; i++) { 827 txs = &sc->sc_txsoft[i]; 828 829 if (txs->txs_mbuf != NULL) { 830 bus_dmamap_unload(sc->sc_dmat, txs->txs_dmap); 831 m_freem(txs->txs_mbuf); 832 txs->txs_mbuf = NULL; 833 txs->txs_last = 0; 834 } 835 } 836 sc->sc_txbusy = 0; 837 838 /* Acknowledge we're down. */ 839 ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE); 840 } 841 842 /* 843 * Media management. 844 */ 845 static int 846 temac_mediachange(struct ifnet *ifp) 847 { 848 struct temac_softc *sc = (struct temac_softc *)ifp->if_softc; 849 850 if (ifp->if_flags & IFF_UP) 851 mii_mediachg(&sc->sc_mii); 852 return (0); 853 } 854 855 static void 856 temac_mediastatus(struct ifnet *ifp, struct ifmediareq *imr) 857 { 858 struct temac_softc *sc = (struct temac_softc *)ifp->if_softc; 859 860 mii_pollstat(&sc->sc_mii); 861 862 imr->ifm_status = sc->sc_mii.mii_media_status; 863 imr->ifm_active = sc->sc_mii.mii_media_active; 864 } 865 866 static int 867 temac_mii_readreg(struct device *self, int phy, int reg) 868 { 869 mtidcr(IDCR_HIF_ARG0, (phy << 5) | reg); 870 mtidcr(IDCR_HIF_CTRL, TEMAC_GMI_MII_ADDR); 871 hif_wait_stat(HIF_STAT_MIIRR); 872 873 return (int)mfidcr(IDCR_HIF_ARG0); 874 } 875 876 static void 877 temac_mii_writereg(struct device *self, int phy, int reg, int val) 878 { 879 mtidcr(IDCR_HIF_ARG0, val); 880 mtidcr(IDCR_HIF_CTRL, TEMAC_GMI_MII_WRVAL | HIF_CTRL_WRITE); 881 mtidcr(IDCR_HIF_ARG0, (phy << 5) | reg); 882 mtidcr(IDCR_HIF_CTRL, TEMAC_GMI_MII_ADDR | HIF_CTRL_WRITE); 883 hif_wait_stat(HIF_STAT_MIIWR); 884 } 885 886 static void 887 temac_mii_statchg(struct device *self) 888 { 889 struct temac_softc *sc = (struct temac_softc *)self; 890 uint32_t rcf, tcf, mmc; 891 892 /* Full/half duplex link. */ 893 rcf = gmi_read_4(TEMAC_GMI_RXCF1); 894 tcf = gmi_read_4(TEMAC_GMI_TXCF); 895 896 if (sc->sc_mii.mii_media_active & IFM_FDX) { 897 gmi_write_4(TEMAC_GMI_RXCF1, rcf & ~GMI_RX_HDX); 898 gmi_write_4(TEMAC_GMI_TXCF, tcf & ~GMI_TX_HDX); 899 } else { 900 gmi_write_4(TEMAC_GMI_RXCF1, rcf | GMI_RX_HDX); 901 gmi_write_4(TEMAC_GMI_TXCF, tcf | GMI_TX_HDX); 902 } 903 904 /* Link speed. */ 905 mmc = gmi_read_4(TEMAC_GMI_MMC) & ~GMI_MMC_SPEED_MASK; 906 907 switch (IFM_SUBTYPE(sc->sc_mii.mii_media_active)) { 908 case IFM_10_T: 909 /* 910 * XXXFreza: the GMAC is not happy with 10Mbit ethernet, 911 * although the documentation claims it's supported. Maybe 912 * it's just my equipment... 913 */ 914 mmc |= GMI_MMC_SPEED_10; 915 break; 916 case IFM_100_TX: 917 mmc |= GMI_MMC_SPEED_100; 918 break; 919 case IFM_1000_T: 920 mmc |= GMI_MMC_SPEED_1000; 921 break; 922 } 923 924 gmi_write_4(TEMAC_GMI_MMC, mmc); 925 } 926 927 static void 928 temac_mii_tick(void *arg) 929 { 930 struct temac_softc *sc = (struct temac_softc *)arg; 931 int s; 932 933 if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0) 934 return ; 935 936 s = splnet(); 937 mii_tick(&sc->sc_mii); 938 splx(s); 939 940 callout_schedule(&sc->sc_mii_tick, hz); 941 } 942 943 /* 944 * External hooks. 945 */ 946 static void 947 temac_shutdown(void *arg) 948 { 949 struct temac_softc *sc = (struct temac_softc *)arg; 950 951 temac_reset(sc); 952 } 953 954 static void 955 temac_tx_intr(void *arg) 956 { 957 struct temac_softc *sc = (struct temac_softc *)arg; 958 uint32_t stat; 959 960 /* XXX: We may need to splnet() here if cdmac(4) changes. */ 961 962 if ((stat = cdmac_tx_stat(sc)) & CDMAC_STAT_ERROR) { 963 printf("%s: transmit DMA is toast (%#08x), halted!\n", 964 sc->sc_dev.dv_xname, stat); 965 966 /* XXXFreza: how to signal this upstream? */ 967 temac_stop(&sc->sc_if, 1); 968 sc->sc_dead = 1; 969 } 970 971 #if TEMAC_DEBUG > 0 972 printf("%s: tx intr 0x%08x\n", device_xname(&sc->sc_dev), stat); 973 #endif 974 temac_txreap(sc); 975 } 976 977 static void 978 temac_rx_intr(void *arg) 979 { 980 struct temac_softc *sc = (struct temac_softc *)arg; 981 uint32_t stat; 982 983 /* XXX: We may need to splnet() here if cdmac(4) changes. */ 984 985 if ((stat = cdmac_rx_stat(sc)) & CDMAC_STAT_ERROR) { 986 printf("%s: receive DMA is toast (%#08x), halted!\n", 987 sc->sc_dev.dv_xname, stat); 988 989 /* XXXFreza: how to signal this upstream? */ 990 temac_stop(&sc->sc_if, 1); 991 sc->sc_dead = 1; 992 } 993 994 #if TEMAC_DEBUG > 0 995 printf("%s: rx intr 0x%08x\n", device_xname(&sc->sc_dev), stat); 996 #endif 997 temac_rxreap(sc); 998 } 999 1000 /* 1001 * Utils. 1002 */ 1003 static inline void 1004 temac_txcdsync(struct temac_softc *sc, int first, int cnt, int flag) 1005 { 1006 if ((first + cnt) > TEMAC_NTXDESC) { 1007 bus_dmamap_sync(sc->sc_dmat, sc->sc_control_dmap, 1008 TEMAC_TXDOFF(first), 1009 sizeof(struct cdmac_descr) * (TEMAC_NTXDESC - first), 1010 flag); 1011 cnt = (first + cnt) % TEMAC_NTXDESC; 1012 first = 0; 1013 } 1014 1015 bus_dmamap_sync(sc->sc_dmat, sc->sc_control_dmap, 1016 TEMAC_TXDOFF(first), 1017 sizeof(struct cdmac_descr) * cnt, 1018 flag); 1019 } 1020 1021 static inline void 1022 temac_rxcdsync(struct temac_softc *sc, int first, int cnt, int flag) 1023 { 1024 if ((first + cnt) > TEMAC_NRXDESC) { 1025 bus_dmamap_sync(sc->sc_dmat, sc->sc_control_dmap, 1026 TEMAC_RXDOFF(first), 1027 sizeof(struct cdmac_descr) * (TEMAC_NRXDESC - first), 1028 flag); 1029 cnt = (first + cnt) % TEMAC_NRXDESC; 1030 first = 0; 1031 } 1032 1033 bus_dmamap_sync(sc->sc_dmat, sc->sc_control_dmap, 1034 TEMAC_RXDOFF(first), 1035 sizeof(struct cdmac_descr) * cnt, 1036 flag); 1037 } 1038 1039 static void 1040 temac_txreap(struct temac_softc *sc) 1041 { 1042 struct temac_txsoft *txs; 1043 bus_dmamap_t dmap; 1044 int sent = 0; 1045 1046 /* 1047 * Transmit interrupts happen on the last descriptor of Tx jobs. 1048 * Hence, every time we're called (and we assume txintr is our 1049 * only caller!), we reap packets upto and including the one 1050 * marked as last-in-batch. 1051 * 1052 * XXX we rely on that we make EXACTLY one batch per intr, no more 1053 */ 1054 while (sc->sc_txsfree != TEMAC_TXQLEN) { 1055 txs = &sc->sc_txsoft[sc->sc_txsreap]; 1056 dmap = txs->txs_dmap; 1057 1058 sc->sc_txreap = TEMAC_TXINC(sc->sc_txreap, dmap->dm_nsegs); 1059 sc->sc_txfree += dmap->dm_nsegs; 1060 1061 bus_dmamap_unload(sc->sc_dmat, txs->txs_dmap); 1062 m_freem(txs->txs_mbuf); 1063 txs->txs_mbuf = NULL; 1064 1065 sc->sc_if.if_opackets++; 1066 sent = 1; 1067 1068 sc->sc_txsreap = TEMAC_TXSNEXT(sc->sc_txsreap); 1069 sc->sc_txsfree++; 1070 1071 if (txs->txs_last) { 1072 txs->txs_last = 0; 1073 sc->sc_txbusy = 0; /* channel stopped now */ 1074 1075 temac_txkick(sc); 1076 break; 1077 } 1078 } 1079 1080 if (sent && (sc->sc_if.if_flags & IFF_OACTIVE)) 1081 sc->sc_if.if_flags &= ~IFF_OACTIVE; 1082 } 1083 1084 static int 1085 temac_rxalloc(struct temac_softc *sc, int which, int verbose) 1086 { 1087 struct temac_rxsoft *rxs; 1088 struct mbuf *m; 1089 uint32_t stat; 1090 int error; 1091 1092 rxs = &sc->sc_rxsoft[which]; 1093 1094 /* The mbuf itself is not our problem, just clear DMA related stuff. */ 1095 if (rxs->rxs_mbuf != NULL) { 1096 bus_dmamap_unload(sc->sc_dmat, rxs->rxs_dmap); 1097 rxs->rxs_mbuf = NULL; 1098 } 1099 1100 /* 1101 * We would like to store mbuf and dmap in application specific 1102 * fields of the descriptor, but that doesn't work for Rx. Shame 1103 * on Xilinx for this (and for the useless timer architecture). 1104 * 1105 * Hence each descriptor needs its own soft state. We may want 1106 * to merge multiple rxs's into a monster mbuf when we support 1107 * jumbo frames though. Also, we use single set of indexing 1108 * variables for both sc_rxdescs[] and sc_rxsoft[]. 1109 */ 1110 MGETHDR(m, M_DONTWAIT, MT_DATA); 1111 if (m == NULL) { 1112 if (verbose) 1113 printf("%s: out of Rx header mbufs\n", 1114 sc->sc_dev.dv_xname); 1115 return (ENOBUFS); 1116 } 1117 MCLAIM(m, &sc->sc_ec.ec_rx_mowner); 1118 1119 MCLGET(m, M_DONTWAIT); 1120 if ((m->m_flags & M_EXT) == 0) { 1121 if (verbose) 1122 printf("%s: out of Rx cluster mbufs\n", 1123 sc->sc_dev.dv_xname); 1124 m_freem(m); 1125 return (ENOBUFS); 1126 } 1127 1128 rxs->rxs_mbuf = m; 1129 m->m_pkthdr.len = m->m_len = MCLBYTES; 1130 1131 /* Make sure the payload after ethernet header is 4-aligned. */ 1132 m_adj(m, 2); 1133 1134 error = bus_dmamap_load_mbuf(sc->sc_dmat, rxs->rxs_dmap, m, 1135 BUS_DMA_NOWAIT); 1136 if (error) { 1137 if (verbose) 1138 printf("%s: could not map Rx descriptor %d, " 1139 "error = %d\n", sc->sc_dev.dv_xname, which, error); 1140 1141 rxs->rxs_mbuf = NULL; 1142 m_freem(m); 1143 1144 return (error); 1145 } 1146 1147 stat = \ 1148 (TEMAC_ISINTR(which) ? CDMAC_STAT_INTR : 0) | 1149 (TEMAC_ISLAST(which) ? CDMAC_STAT_STOP : 0); 1150 1151 bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmap, 0, 1152 rxs->rxs_dmap->dm_mapsize, BUS_DMASYNC_PREREAD); 1153 1154 /* Descriptor post-sync, if needed, left to the caller. */ 1155 1156 sc->sc_rxdescs[which].desc_addr = rxs->rxs_dmap->dm_segs[0].ds_addr; 1157 sc->sc_rxdescs[which].desc_size = rxs->rxs_dmap->dm_segs[0].ds_len; 1158 sc->sc_rxdescs[which].desc_stat = stat; 1159 1160 /* Descriptor pre-sync, if needed, left to the caller. */ 1161 1162 return (0); 1163 } 1164 1165 static void 1166 temac_rxreap(struct temac_softc *sc) 1167 { 1168 struct ifnet *ifp = &sc->sc_if; 1169 uint32_t stat, rxstat, rxsize; 1170 struct mbuf *m; 1171 int nseg, head, tail; 1172 1173 head = sc->sc_rxreap; 1174 tail = 0; /* gcc */ 1175 nseg = 0; 1176 1177 /* 1178 * Collect finished entries on the Rx list, kick DMA if we hit 1179 * the end. DMA will always stop on the last descriptor in chain, 1180 * so it will never hit a reap-in-progress descriptor. 1181 */ 1182 while (1) { 1183 /* Maybe we previously failed to refresh this one? */ 1184 if (sc->sc_rxsoft[sc->sc_rxreap].rxs_mbuf == NULL) { 1185 if (temac_rxalloc(sc, sc->sc_rxreap, 0) != 0) 1186 break; 1187 1188 sc->sc_rxreap = TEMAC_RXNEXT(sc->sc_rxreap); 1189 continue; 1190 } 1191 temac_rxcdsync(sc, sc->sc_rxreap, 1, 1192 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1193 1194 stat = sc->sc_rxdescs[sc->sc_rxreap].desc_stat; 1195 m = NULL; 1196 1197 if ((stat & CDMAC_STAT_DONE) == 0) 1198 break; 1199 1200 /* Count any decriptor we've collected, regardless of status. */ 1201 nseg ++; 1202 1203 /* XXXFreza: This won't work for jumbo frames. */ 1204 1205 if ((stat & (CDMAC_STAT_EOP | CDMAC_STAT_SOP)) != 1206 (CDMAC_STAT_EOP | CDMAC_STAT_SOP)) { 1207 printf("%s: Rx packet doesn't fit in " 1208 "one descriptor, stat = %#08x\n", 1209 sc->sc_dev.dv_xname, stat); 1210 goto badframe; 1211 } 1212 1213 /* Dissect TEMAC footer if this is end of packet. */ 1214 rxstat = sc->sc_rxdescs[sc->sc_rxreap].desc_rxstat; 1215 rxsize = sc->sc_rxdescs[sc->sc_rxreap].desc_rxsize & 1216 RXSIZE_MASK; 1217 1218 if ((rxstat & RXSTAT_GOOD) == 0 || 1219 (rxstat & RXSTAT_SICK) != 0) { 1220 printf("%s: corrupt Rx packet, rxstat = %#08x\n", 1221 sc->sc_dev.dv_xname, rxstat); 1222 goto badframe; 1223 } 1224 1225 /* We are now bound to succeed. */ 1226 bus_dmamap_sync(sc->sc_dmat, 1227 sc->sc_rxsoft[sc->sc_rxreap].rxs_dmap, 0, 1228 sc->sc_rxsoft[sc->sc_rxreap].rxs_dmap->dm_mapsize, 1229 BUS_DMASYNC_POSTREAD); 1230 1231 m = sc->sc_rxsoft[sc->sc_rxreap].rxs_mbuf; 1232 m->m_pkthdr.rcvif = ifp; 1233 m->m_pkthdr.len = m->m_len = rxsize; 1234 1235 badframe: 1236 /* Get ready for more work. */ 1237 tail = sc->sc_rxreap; 1238 sc->sc_rxreap = TEMAC_RXNEXT(sc->sc_rxreap); 1239 1240 /* On failures we reuse the descriptor and go ahead. */ 1241 if (m == NULL) { 1242 sc->sc_rxdescs[tail].desc_stat = 1243 (TEMAC_ISINTR(tail) ? CDMAC_STAT_INTR : 0) | 1244 (TEMAC_ISLAST(tail) ? CDMAC_STAT_STOP : 0); 1245 1246 ifp->if_ierrors++; 1247 continue; 1248 } 1249 1250 #if NBPFILTER > 0 1251 if (ifp->if_bpf != NULL) 1252 bpf_mtap(ifp->if_bpf, m); 1253 #endif 1254 1255 ifp->if_ipackets++; 1256 (ifp->if_input)(ifp, m); 1257 1258 /* Refresh descriptor, bail out if we're out of buffers. */ 1259 if (temac_rxalloc(sc, tail, 1) != 0) { 1260 sc->sc_rxreap = TEMAC_RXINC(sc->sc_rxreap, -1); 1261 printf("%s: Rx give up for now\n", sc->sc_dev.dv_xname); 1262 break; 1263 } 1264 } 1265 1266 /* We may now have a contiguous ready-to-go chunk of descriptors. */ 1267 if (nseg > 0) { 1268 #if TEMAC_RXDEBUG > 0 1269 printf("%s: rxreap: rxreap %03d -> %03d, nseg %03d\n", 1270 sc->sc_dev.dv_xname, head, sc->sc_rxreap, nseg); 1271 #endif 1272 temac_rxcdsync(sc, head, nseg, 1273 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 1274 1275 if (TEMAC_ISLAST(tail)) 1276 cdmac_rx_start(sc, sc->sc_cdaddr + TEMAC_RXDOFF(0)); 1277 } 1278 1279 /* Ensure maximum Rx latency is kept under control. */ 1280 callout_schedule(&sc->sc_rx_timo, hz / TEMAC_RXTIMO_HZ); 1281 } 1282 1283 static void 1284 temac_rxtimo(void *arg) 1285 { 1286 struct temac_softc *sc = (struct temac_softc *)arg; 1287 int s; 1288 1289 /* We run TEMAC_RXTIMO_HZ times/sec to ensure Rx doesn't stall. */ 1290 s = splnet(); 1291 temac_rxreap(sc); 1292 splx(s); 1293 } 1294 1295 static void 1296 temac_reset(struct temac_softc *sc) 1297 { 1298 uint32_t rcr, tcr; 1299 1300 /* Kill CDMAC channels. */ 1301 cdmac_tx_reset(sc); 1302 cdmac_rx_reset(sc); 1303 1304 /* Disable receiver. */ 1305 rcr = gmi_read_4(TEMAC_GMI_RXCF1) & ~GMI_RX_ENABLE; 1306 gmi_write_4(TEMAC_GMI_RXCF1, rcr); 1307 1308 /* Disable transmitter. */ 1309 tcr = gmi_read_4(TEMAC_GMI_TXCF) & ~GMI_TX_ENABLE; 1310 gmi_write_4(TEMAC_GMI_TXCF, tcr); 1311 } 1312 1313 static void 1314 temac_rxdrain(struct temac_softc *sc) 1315 { 1316 struct temac_rxsoft *rxs; 1317 int i; 1318 1319 for (i = 0; i < TEMAC_NRXDESC; i++) { 1320 rxs = &sc->sc_rxsoft[i]; 1321 1322 if (rxs->rxs_mbuf != NULL) { 1323 bus_dmamap_unload(sc->sc_dmat, rxs->rxs_dmap); 1324 m_freem(rxs->rxs_mbuf); 1325 rxs->rxs_mbuf = NULL; 1326 } 1327 } 1328 1329 sc->sc_rx_drained = 1; 1330 } 1331 1332 static void 1333 temac_txkick(struct temac_softc *sc) 1334 { 1335 if (sc->sc_txsoft[sc->sc_txsreap].txs_mbuf != NULL && 1336 sc->sc_txbusy == 0) { 1337 cdmac_tx_start(sc, sc->sc_cdaddr + TEMAC_TXDOFF(sc->sc_txreap)); 1338 sc->sc_txbusy = 1; 1339 } 1340 } 1341