summaryrefslogtreecommitdiff
path: root/sys/dev/nve
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2006-05-18 23:19:44 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2006-05-18 23:19:44 +0000
commitf00d84860acfc53919e73130cc7679a4d70ac755 (patch)
tree2e3900cafd857e7974c6d5eb8555ab87d47d1c32 /sys/dev/nve
parentac895519de31f30f7f477a9a6fd5a9ad94776e59 (diff)
Notes
Diffstat (limited to 'sys/dev/nve')
-rw-r--r--sys/dev/nve/if_nve.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/sys/dev/nve/if_nve.c b/sys/dev/nve/if_nve.c
index 73b9aead81f9..2f26a9887458 100644
--- a/sys/dev/nve/if_nve.c
+++ b/sys/dev/nve/if_nve.c
@@ -872,6 +872,17 @@ nve_ifstart_locked(struct ifnet *ifp)
if (m0 == NULL)
return;
+ /*
+ * On nForce4, the chip doesn't interrupt on transmit,
+ * so try to flush transmitted packets from the queue
+ * if it's getting large (see note in nve_watchdog).
+ */
+ if (sc->pending_txs > TX_RING_SIZE/2) {
+ sc->hwapi->pfnDisableInterrupts(sc->hwapi->pADCX);
+ sc->hwapi->pfnHandleInterrupt(sc->hwapi->pADCX);
+ sc->hwapi->pfnEnableInterrupts(sc->hwapi->pADCX);
+ }
+
/* Map MBUF for DMA access */
error = bus_dmamap_load_mbuf(sc->mtag, buf->map, m0,
nve_dmamap_tx_cb, desc, BUS_DMA_NOWAIT);
@@ -1275,6 +1286,7 @@ static void
nve_watchdog(struct ifnet *ifp)
{
struct nve_softc *sc = ifp->if_softc;
+ int pending_txs_start;
NVE_LOCK(sc);
@@ -1283,14 +1295,16 @@ nve_watchdog(struct ifnet *ifp)
* Thus, sometimes the watchdog timer will go off when the
* tx engine is fine, but the tx completions are just deferred.
* Try kicking the driver blob to clear out any pending tx
- * completions. If that clears up all the pending tx
+ * completions. If that clears up any of the pending tx
* operations, then just return without printing the warning
- * message or resetting the adapter.
+ * message or resetting the adapter, as we can then conclude
+ * the chip hasn't actually crashed (it's still sending packets).
*/
+ pending_txs_start = sc->pending_txs;
sc->hwapi->pfnDisableInterrupts(sc->hwapi->pADCX);
sc->hwapi->pfnHandleInterrupt(sc->hwapi->pADCX);
sc->hwapi->pfnEnableInterrupts(sc->hwapi->pADCX);
- if (sc->pending_txs == 0) {
+ if (sc->pending_txs < pending_txs_start) {
NVE_UNLOCK(sc);
return;
}