summaryrefslogtreecommitdiffstats
path: root/sys/pci/if_rl.c
diff options
context:
space:
mode:
authorru <ru@FreeBSD.org>2004-04-03 00:42:33 +0000
committerru <ru@FreeBSD.org>2004-04-03 00:42:33 +0000
commit2c8925549a16b6426bfad4ce95dc3948f602350a (patch)
treed9b7926011453a4021437eebf50c19e27a0cdae9 /sys/pci/if_rl.c
parent5964f2843d1f069368b2309432aa54f76ead3a41 (diff)
downloadFreeBSD-src-2c8925549a16b6426bfad4ce95dc3948f602350a.zip
FreeBSD-src-2c8925549a16b6426bfad4ce95dc3948f602350a.tar.gz
Fixed a few bugs in the rl(4) driver:
Under polling(4), we counted non-existent output packets and wasted CPU cycles, corrected. (PR kern/64975.) The fix in revision 1.71 to correct resetting of the watchdog timer was wrong. In rl(4), the TX list does not have a gap between the consumer and producer, so the "empty TX list" test was wrong, corrected. Also, resetting the timer to five each time we know there is still some TX work to do was a bad idea -- under polling(4), if the chip goes out to lunch, this results in the watchdog routine to _never_ be called. Instead, let the timer downgrade to zero and fire the watchdog, then reset it to five when it is zero AND there is some TX work left. (Most other network drivers need this fix too.) MFC after: 3 days
Diffstat (limited to 'sys/pci/if_rl.c')
-rw-r--r--sys/pci/if_rl.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/sys/pci/if_rl.c b/sys/pci/if_rl.c
index b70166a..10a8850 100644
--- a/sys/pci/if_rl.c
+++ b/sys/pci/if_rl.c
@@ -1359,6 +1359,8 @@ rl_txeof(sc)
* frames that have been uploaded.
*/
do {
+ if (RL_LAST_TXMBUF(sc) == NULL)
+ break;
txstat = CSR_READ_4(sc, RL_LAST_TXSTAT(sc));
if (!(txstat & (RL_TXSTAT_TX_OK|
RL_TXSTAT_TX_UNDERRUN|RL_TXSTAT_TXABRT)))
@@ -1366,12 +1368,10 @@ rl_txeof(sc)
ifp->if_collisions += (txstat & RL_TXSTAT_COLLCNT) >> 24;
- if (RL_LAST_TXMBUF(sc) != NULL) {
- bus_dmamap_unload(sc->rl_tag, RL_LAST_DMAMAP(sc));
- bus_dmamap_destroy(sc->rl_tag, RL_LAST_DMAMAP(sc));
- m_freem(RL_LAST_TXMBUF(sc));
- RL_LAST_TXMBUF(sc) = NULL;
- }
+ bus_dmamap_unload(sc->rl_tag, RL_LAST_DMAMAP(sc));
+ bus_dmamap_destroy(sc->rl_tag, RL_LAST_DMAMAP(sc));
+ m_freem(RL_LAST_TXMBUF(sc));
+ RL_LAST_TXMBUF(sc) = NULL;
if (txstat & RL_TXSTAT_TX_OK)
ifp->if_opackets++;
else {
@@ -1396,8 +1396,10 @@ rl_txeof(sc)
ifp->if_flags &= ~IFF_OACTIVE;
} while (sc->rl_cdata.last_tx != sc->rl_cdata.cur_tx);
- ifp->if_timer =
- (sc->rl_cdata.last_tx == sc->rl_cdata.cur_tx) ? 0 : 5;
+ if (RL_LAST_TXMBUF(sc) == NULL)
+ ifp->if_timer = 0;
+ else if (ifp->if_timer == 0)
+ ifp->if_timer = 5;
return;
}
OpenPOWER on IntegriCloud