diff options
author | Bob Beck <beck@cvs.openbsd.org> | 2004-05-01 00:04:00 +0000 |
---|---|---|
committer | Bob Beck <beck@cvs.openbsd.org> | 2004-05-01 00:04:00 +0000 |
commit | a771f6c2c23265815bd9620f5261e53800a544c6 (patch) | |
tree | 7116f0ae360deeed7d7772b86e8e479b411592c5 /sys/dev/ic | |
parent | 98afcebbb4412cef3580991c5209cfab035f61c7 (diff) |
Fix nasty bug where driver would not correctly catch and handle an rnr
condition when it was due to the the recieve buffers being exhausted with
no packet transmits during that time. Symptom was that the fxp would
simply stop interrupting for the next 15 seconds until the watchdog kicked
in and reset the chip due to 15 seconds of inactivity, making the fxp very
poorly behaved when hammered on hard.
ok deraadt@
Diffstat (limited to 'sys/dev/ic')
-rw-r--r-- | sys/dev/ic/fxp.c | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/sys/dev/ic/fxp.c b/sys/dev/ic/fxp.c index d1176e6bc19..739bf581a46 100644 --- a/sys/dev/ic/fxp.c +++ b/sys/dev/ic/fxp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fxp.c,v 1.49 2004/04/26 03:00:44 mcbride Exp $ */ +/* $OpenBSD: fxp.c,v 1.50 2004/05/01 00:03:59 beck Exp $ */ /* $NetBSD: if_fxp.c,v 1.2 1997/06/05 02:01:55 thorpej Exp $ */ /* @@ -738,8 +738,10 @@ fxp_intr(arg) struct fxp_softc *sc = arg; struct ifnet *ifp = &sc->sc_arpcom.ac_if; u_int8_t statack; - int claimed = 0, rnr; - + bus_dmamap_t rxmap; + int claimed = 0; + int rnr = 0; + /* * If the interface isn't running, don't try to * service the interrupt.. just ack it and bail. @@ -755,8 +757,7 @@ fxp_intr(arg) while ((statack = CSR_READ_1(sc, FXP_CSR_SCB_STATACK)) != 0) { claimed = 1; - rnr = 0; - + rnr = (statack & FXP_SCB_STATACK_RNR) ? 1 : 0; /* * First ACK all the interrupts in this pass. */ @@ -807,7 +808,6 @@ fxp_intr(arg) */ if (statack & (FXP_SCB_STATACK_FR | FXP_SCB_STATACK_RNR)) { struct mbuf *m; - bus_dmamap_t rxmap; u_int8_t *rfap; rcvloop: m = sc->rfa_headm; @@ -859,15 +859,16 @@ rcvloop: } goto rcvloop; } - if (rnr) { - rxmap = *((bus_dmamap_t *) - sc->rfa_headm->m_ext.ext_buf); - fxp_scb_wait(sc); - CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, + } + if (rnr) { + rxmap = *((bus_dmamap_t *) + sc->rfa_headm->m_ext.ext_buf); + fxp_scb_wait(sc); + CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, rxmap->dm_segs[0].ds_addr + RFA_ALIGNMENT_FUDGE); - fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START); - } + fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START); + } } return (claimed); |