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