summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbeck <beck@openbsd.org>2004-05-01 00:03:59 +0000
committerbeck <beck@openbsd.org>2004-05-01 00:03:59 +0000
commit8b40c9aa504a01218a5b7117dbb55d8251f63d5d (patch)
tree1ede0cce99680bfb7321d5f239e1898dfede7cd1
parentrbootd privsep uid/gid (diff)
downloadwireguard-openbsd-8b40c9aa504a01218a5b7117dbb55d8251f63d5d.tar.xz
wireguard-openbsd-8b40c9aa504a01218a5b7117dbb55d8251f63d5d.zip
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@
-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);