summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
authorBob Beck <beck@cvs.openbsd.org>2004-05-01 00:04:00 +0000
committerBob Beck <beck@cvs.openbsd.org>2004-05-01 00:04:00 +0000
commita771f6c2c23265815bd9620f5261e53800a544c6 (patch)
tree7116f0ae360deeed7d7772b86e8e479b411592c5 /sys/dev/ic
parent98afcebbb4412cef3580991c5209cfab035f61c7 (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.c27
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);