Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

MFC r253404:

   o TxD ring requires 8 bytes alignment to work so change alignment
     constraint to 8. Previously it may have triggered watchdog
     timeouts.
   o Check whether interrupt is ours or not.
   o Enable interrupts before attemping to transmit queued packets.
     This will slightly improve TX performance.
   o No need to clear IFF_DRV_OACTIVE in a loop. AE_FLAG_TXAVAIL is
     used to know whether there are enough available TxD ring space.
   o Added missing bus_dmamap_sync(9) in ae_rx_intr() and rearranged
     code to avoid unncessary register access.
   o Make sure to clear TxD, TxS, RxD rings in driver initialization.
     Otherwise some data in these rings could be interpreted as
     'updated' which in turn will advance internally maintained
     pointers and can trigger watchdog timeouts.

  PR:	kern/180382
  Approved by:	re (hrs)
  • Loading branch information...
commit e4703cfad1213dc6aa052a2426c720a3cdcde25e 1 parent fc07a03
yongari authored
Showing with 30 additions and 20 deletions.
  1. +30 −20 sys/dev/ae/if_ae.c
View
50 sys/dev/ae/if_ae.c
@@ -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,12 +1790,16 @@ 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);
- /*
- * 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);
+ }
+ }
AE_UNLOCK(sc);
}
@@ -1849,10 +1860,10 @@ ae_tx_intr(ae_softc_t *sc)
ifp->if_oerrors++;
sc->tx_inproc--;
-
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
}
+ 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
Please sign in to comment.
Something went wrong with that request. Please try again.