summaryrefslogtreecommitdiff
path: root/sys/dev/ic/re.c
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2008-11-07 18:12:23 +0000
committerBrad Smith <brad@cvs.openbsd.org>2008-11-07 18:12:23 +0000
commit5654aca76d77a9076184cfdef233e02795f315eb (patch)
tree70868d0236e3312c34df8536d7fa810e7f593a3b /sys/dev/ic/re.c
parent01d4d3704e8725aff3a9ae216ba003e48f58ebc4 (diff)
Try recollecting RX/TX descriptors if we are going to switch back to TX/RX
interrupts. There seems to be a race between turning on TX/RX interrupt and asserting TX/RX interrupt by the hardware. From Sephe@DragonFly
Diffstat (limited to 'sys/dev/ic/re.c')
-rw-r--r--sys/dev/ic/re.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/sys/dev/ic/re.c b/sys/dev/ic/re.c
index 5a4cd7b5d28..e444f0efa0e 100644
--- a/sys/dev/ic/re.c
+++ b/sys/dev/ic/re.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: re.c,v 1.96 2008/10/16 19:18:03 naddy Exp $ */
+/* $OpenBSD: re.c,v 1.97 2008/11/07 18:12:22 brad Exp $ */
/* $FreeBSD: if_re.c,v 1.31 2004/09/04 07:54:05 ru Exp $ */
/*
* Copyright (c) 1997, 1998-2003
@@ -1627,12 +1627,30 @@ re_intr(void *arg)
if (sc->rl_imtype == RL_IMTYPE_SIM) {
if ((sc->rl_flags & RL_FLAG_TIMERINTR)) {
- if ((tx | rx) == 0)
+ if ((tx | rx) == 0) {
+ /*
+ * Nothing needs to be processed, fallback
+ * to use TX/RX interrupts.
+ */
re_setup_intr(sc, 1, RL_IMTYPE_NONE);
- else
+
+ /*
+ * Recollect, mainly to avoid the possible
+ * race introduced by changing interrupt
+ * masks.
+ */
+ re_rxeof(sc);
+ tx = re_txeof(sc);
+ } else
CSR_WRITE_4(sc, RL_TIMERCNT, 1); /* reload */
- } else if (tx | rx)
+ } else if (tx | rx) {
+ /*
+ * Assume that using simulated interrupt moderation
+ * (hardware timer based) could reduce the interrupt
+ * rate.
+ */
re_setup_intr(sc, 1, RL_IMTYPE_SIM);
+ }
}
if (tx && !IFQ_IS_EMPTY(&ifp->if_snd))