Index: sys/dev/ae/if_ae.c =================================================================== --- sys/dev/ae/if_ae.c (revision 253344) +++ sys/dev/ae/if_ae.c (working copy) @@ -585,6 +585,9 @@ ae_init_locked(ae_softc_t *sc) val = eaddr[0] << 8 | eaddr[1]; AE_WRITE_4(sc, AE_EADDR1_REG, val); + bzero(sc->rxd_base_dma, AE_RXD_COUNT_DEFAULT * 1536 + 120); + bzero(sc->txd_base, AE_TXD_BUFSIZE_DEFAULT); + bzero(sc->txs_base, AE_TXS_COUNT_DEFAULT * 4); /* * Set ring buffers base addresses. */ @@ -1115,7 +1118,7 @@ ae_alloc_rings(ae_softc_t *sc) * Create DMA tag for TxD. */ error = bus_dma_tag_create(sc->dma_parent_tag, - 4, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, + 8, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, AE_TXD_BUFSIZE_DEFAULT, 1, AE_TXD_BUFSIZE_DEFAULT, 0, NULL, NULL, &sc->dma_txd_tag); @@ -1128,7 +1131,7 @@ ae_alloc_rings(ae_softc_t *sc) * Create DMA tag for TxS. */ error = bus_dma_tag_create(sc->dma_parent_tag, - 4, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, + 8, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, AE_TXS_COUNT_DEFAULT * 4, 1, AE_TXS_COUNT_DEFAULT * 4, 0, NULL, NULL, &sc->dma_txs_tag); @@ -1761,6 +1764,10 @@ ae_int_task(void *arg, int pending) ifp = sc->ifp; val = AE_READ_4(sc, AE_ISR_REG); /* Read interrupt status. */ + if (val == 0) { + AE_UNLOCK(sc); + return; + } /* * Clear interrupts and disable them. @@ -1783,13 +1790,17 @@ ae_int_task(void *arg, int pending) ae_tx_intr(sc); if ((val & AE_ISR_RX_EVENT) != 0) ae_rx_intr(sc); + /* + * Re-enable interrupts. + */ + AE_WRITE_4(sc, AE_ISR_REG, 0); + + if ((sc->flags & AE_FLAG_TXAVAIL) != 0) { + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + ae_start_locked(ifp); + } } - /* - * Re-enable interrupts. - */ - AE_WRITE_4(sc, AE_ISR_REG, 0); - AE_UNLOCK(sc); } @@ -1849,10 +1860,10 @@ ae_tx_intr(ae_softc_t *sc) ifp->if_oerrors++; sc->tx_inproc--; + } + if ((sc->flags & AE_FLAG_TXAVAIL) != 0) ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - } - if (sc->tx_inproc < 0) { if_printf(ifp, "Received stray Tx interrupt(s).\n"); sc->tx_inproc = 0; @@ -1860,11 +1871,6 @@ ae_tx_intr(ae_softc_t *sc) if (sc->tx_inproc == 0) sc->wd_timer = 0; /* Unarm watchdog. */ - - if ((sc->flags & AE_FLAG_TXAVAIL) != 0) { - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - ae_start_locked(ifp); - } /* * Syncronize DMA buffers. @@ -1923,7 +1929,7 @@ ae_rx_intr(ae_softc_t *sc) ae_rxd_t *rxd; struct ifnet *ifp; uint16_t flags; - int error; + int count, error; KASSERT(sc != NULL, ("[ae, %d]: sc is NULL!", __LINE__)); @@ -1937,7 +1943,7 @@ ae_rx_intr(ae_softc_t *sc) bus_dmamap_sync(sc->dma_rxd_tag, sc->dma_rxd_map, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - for (;;) { + for (count = 0;; count++) { rxd = (ae_rxd_t *)(sc->rxd_base + sc->rxd_cur); flags = le16toh(rxd->flags); if ((flags & AE_RXD_UPDATE) == 0) @@ -1964,10 +1970,14 @@ ae_rx_intr(ae_softc_t *sc) } } - /* - * Update Rx index. - */ - AE_WRITE_2(sc, AE_MB_RXD_IDX_REG, sc->rxd_cur); + if (count > 0) { + bus_dmamap_sync(sc->dma_rxd_tag, sc->dma_rxd_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + /* + * Update Rx index. + */ + AE_WRITE_2(sc, AE_MB_RXD_IDX_REG, sc->rxd_cur); + } } static void