summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/dc/if_dc.c16
-rw-r--r--sys/dev/dc/if_dcreg.h1
2 files changed, 16 insertions, 1 deletions
diff --git a/sys/dev/dc/if_dc.c b/sys/dev/dc/if_dc.c
index 29125bf..c65eba0 100644
--- a/sys/dev/dc/if_dc.c
+++ b/sys/dev/dc/if_dc.c
@@ -2473,6 +2473,7 @@ dc_list_tx_init(struct dc_softc *sc)
}
cd->dc_tx_prod = cd->dc_tx_cons = cd->dc_tx_cnt = 0;
+ cd->dc_tx_pkts = 0;
bus_dmamap_sync(sc->dc_ltag, sc->dc_lmap,
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
return (0);
@@ -2841,6 +2842,9 @@ dc_txeof(struct dc_softc *sc)
int idx;
u_int32_t ctl, txstat;
+ if (sc->dc_cdata.dc_tx_cnt == 0)
+ return;
+
ifp = sc->dc_ifp;
/*
@@ -2952,6 +2956,13 @@ dc_tick(void *xsc)
ifp = sc->dc_ifp;
mii = device_get_softc(sc->dc_miibus);
+ /*
+ * Reclaim transmitted frames for controllers that do
+ * not generate TX completion interrupt for every frame.
+ */
+ if (sc->dc_flags & DC_TX_USE_TX_INTR)
+ dc_txeof(sc);
+
if (sc->dc_flags & DC_REDUCED_MII_POLL) {
if (sc->dc_flags & DC_21143_NWAY) {
r = CSR_READ_4(sc, DC_10BTSTAT);
@@ -3322,8 +3333,11 @@ dc_encap(struct dc_softc *sc, struct mbuf **m_head)
htole32(DC_TXCTL_FINT);
if (sc->dc_flags & DC_TX_INTR_ALWAYS)
sc->dc_ldata->dc_tx_list[cur].dc_ctl |= htole32(DC_TXCTL_FINT);
- if (sc->dc_flags & DC_TX_USE_TX_INTR && sc->dc_cdata.dc_tx_cnt > 64)
+ if (sc->dc_flags & DC_TX_USE_TX_INTR &&
+ ++sc->dc_cdata.dc_tx_pkts >= 8) {
+ sc->dc_cdata.dc_tx_pkts = 0;
sc->dc_ldata->dc_tx_list[cur].dc_ctl |= htole32(DC_TXCTL_FINT);
+ }
sc->dc_ldata->dc_tx_list[first].dc_status = htole32(DC_TXSTAT_OWN);
bus_dmamap_sync(sc->dc_mtag, sc->dc_cdata.dc_tx_map[idx],
diff --git a/sys/dev/dc/if_dcreg.h b/sys/dev/dc/if_dcreg.h
index 066ea88..81c1b31 100644
--- a/sys/dev/dc/if_dcreg.h
+++ b/sys/dev/dc/if_dcreg.h
@@ -495,6 +495,7 @@ struct dc_chain_data {
bus_dmamap_t dc_tx_map[DC_TX_LIST_CNT];
u_int32_t *dc_sbuf;
u_int8_t dc_pad[DC_MIN_FRAMELEN];
+ int dc_tx_pkts;
int dc_tx_first;
int dc_tx_prod;
int dc_tx_cons;
OpenPOWER on IntegriCloud