- When setting up a packet for transmit, if we the tx ring is over half
full, kick the binary blob to force it to complete any pending tx completions. - In the watchdog routine, only reset the chip if the blob doesn't complete any pending tx completions rather than requiring it to complete all of the pending tx completions. Submitted by: Nathan Whitehorn <nathanw@uchicago.edu> MFC after: 2 weeks
This commit is contained in:
parent
ac895519de
commit
f00d84860a
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user