summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryongari <yongari@FreeBSD.org>2009-12-23 19:38:22 +0000
committeryongari <yongari@FreeBSD.org>2009-12-23 19:38:22 +0000
commitf417257f2a0c3ff8d545586df6f3dd69f77525c8 (patch)
tree274300ae2f11cfed3c3f30f2dd4edee0684d6f90
parent415876f659103a3255c7fee0b026d9d126f9c546 (diff)
downloadFreeBSD-src-f417257f2a0c3ff8d545586df6f3dd69f77525c8.zip
FreeBSD-src-f417257f2a0c3ff8d545586df6f3dd69f77525c8.tar.gz
We don't need to generate DMA complete interrupt for every
transmitted frames. So request interrupt for every 16th frames. Due to the limitation of hardware we can't suppress the interrupt as driver should have to check TX status register. The TX status register can store up to 31 TX status so driver can't send more than 31 frames without reading TX status register. With this change controller would not generate TX completion interrupt for every frame, so reclaim transmitted frames in ste_tick().
-rw-r--r--sys/dev/ste/if_ste.c13
-rw-r--r--sys/dev/ste/if_stereg.h6
2 files changed, 18 insertions, 1 deletions
diff --git a/sys/dev/ste/if_ste.c b/sys/dev/ste/if_ste.c
index 75f7fab..8c8b121 100644
--- a/sys/dev/ste/if_ste.c
+++ b/sys/dev/ste/if_ste.c
@@ -877,6 +877,13 @@ ste_tick(void *arg)
*/
if ((sc->ste_flags & STE_FLAG_LINK) == 0)
ste_miibus_statchg(sc->ste_dev);
+ /*
+ * Because we are not generating Tx completion
+ * interrupt for every frame, reclaim transmitted
+ * buffers here.
+ */
+ ste_txeof(sc);
+ ste_txeoc(sc);
ste_stats_update(sc);
ste_watchdog(sc);
callout_reset(&sc->ste_callout, hz, ste_tick, sc);
@@ -1953,7 +1960,11 @@ ste_encap(struct ste_softc *sc, struct mbuf **m_head, struct ste_chain *txc)
* Tx descriptors here. Otherwise we race with controller.
*/
desc->ste_next = 0;
- desc->ste_ctl = htole32(STE_TXCTL_ALIGN_DIS | STE_TXCTL_DMAINTR);
+ if ((sc->ste_cdata.ste_tx_prod % STE_TX_INTR_FRAMES) == 0)
+ desc->ste_ctl = htole32(STE_TXCTL_ALIGN_DIS |
+ STE_TXCTL_DMAINTR);
+ else
+ desc->ste_ctl = htole32(STE_TXCTL_ALIGN_DIS);
txc->ste_mbuf = *m_head;
STE_INC(sc->ste_cdata.ste_tx_prod, STE_TX_LIST_CNT);
sc->ste_cdata.ste_tx_cnt++;
diff --git a/sys/dev/ste/if_stereg.h b/sys/dev/ste/if_stereg.h
index b5b4239..db0d2e7 100644
--- a/sys/dev/ste/if_stereg.h
+++ b/sys/dev/ste/if_stereg.h
@@ -494,6 +494,12 @@ struct ste_desc_onefrag {
#define STE_ADDR_LO(x) ((uint64_t)(x) & 0xFFFFFFFF)
#define STE_ADDR_HI(x) ((uint64_t)(x) >> 32)
+/*
+ * Since Tx status can hold up to 31 status bytes we should
+ * check Tx status before controller fills it up. Otherwise
+ * Tx MAC stalls.
+ */
+#define STE_TX_INTR_FRAMES 16
#define STE_TX_TIMEOUT 5
#define STE_TIMEOUT 1000
#define STE_MIN_FRAMELEN 60
OpenPOWER on IntegriCloud