summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Sperling <stsp@cvs.openbsd.org>2012-07-13 10:08:16 +0000
committerStefan Sperling <stsp@cvs.openbsd.org>2012-07-13 10:08:16 +0000
commite88a6f2d21a7d8b0565da510ebae982d4e31a4be (patch)
treeee6f02cbda055e32fed3e6e364034fad139f89ec
parentce3878f3661a55c891f6523fbc959007cf662830 (diff)
Keep separate OACTIVE flags to mark full management/data tx queues,
and set the interface's IFF_OACTIVE flag if either queue is full and clear it only if both queues have free slots. Before this change both queues were setting/clearing the same flag with no regard for the other queue's state. Also, don't reset the tx watchdog counter if either queue still has frames queued when we exit the frame-processing loop in the per-queue interrupt handlers. Both changes originally from sephe@dragonfly. Tested by myself and edd on a slow busy soekris which before this change required occasional 'ifconfig ral0 down up' to recover.
-rw-r--r--sys/dev/ic/rt2560.c27
-rw-r--r--sys/dev/ic/rt2560var.h4
-rw-r--r--sys/dev/ic/rt2661.c20
-rw-r--r--sys/dev/ic/rt2661var.h4
4 files changed, 42 insertions, 13 deletions
diff --git a/sys/dev/ic/rt2560.c b/sys/dev/ic/rt2560.c
index 957704f0f08..1ea7070029a 100644
--- a/sys/dev/ic/rt2560.c
+++ b/sys/dev/ic/rt2560.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rt2560.c,v 1.59 2012/07/13 07:48:31 stsp Exp $ */
+/* $OpenBSD: rt2560.c,v 1.60 2012/07/13 10:08:15 stsp Exp $ */
/*-
* Copyright (c) 2005, 2006
@@ -995,9 +995,14 @@ rt2560_tx_intr(struct rt2560_softc *sc)
sc->txq.next = (sc->txq.next + 1) % RT2560_TX_RING_COUNT;
}
- sc->sc_tx_timer = 0;
- ifp->if_flags &= ~IFF_OACTIVE;
- rt2560_start(ifp);
+ if (sc->txq.queued == 0 && sc->prioq.queued == 0)
+ sc->sc_tx_timer = 0;
+ if (sc->txq.queued < RT2560_TX_RING_COUNT - 1) {
+ sc->sc_flags &= ~RT2560_DATA_OACTIVE;
+ if (!(sc->sc_flags & (RT2560_DATA_OACTIVE|RT2560_PRIO_OACTIVE)))
+ ifp->if_flags &= ~IFF_OACTIVE;
+ rt2560_start(ifp);
+ }
}
void
@@ -1061,9 +1066,14 @@ rt2560_prio_intr(struct rt2560_softc *sc)
sc->prioq.next = (sc->prioq.next + 1) % RT2560_PRIO_RING_COUNT;
}
- sc->sc_tx_timer = 0;
- ifp->if_flags &= ~IFF_OACTIVE;
- rt2560_start(ifp);
+ if (sc->txq.queued == 0 && sc->prioq.queued == 0)
+ sc->sc_tx_timer = 0;
+ if (sc->prioq.queued < RT2560_PRIO_RING_COUNT) {
+ sc->sc_flags &= ~RT2560_PRIO_OACTIVE;
+ if (!(sc->sc_flags & (RT2560_DATA_OACTIVE|RT2560_PRIO_OACTIVE)))
+ ifp->if_flags &= ~IFF_OACTIVE;
+ rt2560_start(ifp);
+ }
}
/*
@@ -1931,6 +1941,7 @@ rt2560_start(struct ifnet *ifp)
if (m0 != NULL) {
if (sc->prioq.queued >= RT2560_PRIO_RING_COUNT) {
ifp->if_flags |= IFF_OACTIVE;
+ sc->sc_flags |= RT2560_PRIO_OACTIVE;
break;
}
IF_DEQUEUE(&ic->ic_mgtq, m0);
@@ -1952,6 +1963,7 @@ rt2560_start(struct ifnet *ifp)
break;
if (sc->txq.queued >= RT2560_TX_RING_COUNT - 1) {
ifp->if_flags |= IFF_OACTIVE;
+ sc->sc_flags |= RT2560_DATA_OACTIVE;
break;
}
IFQ_DEQUEUE(&ifp->if_snd, m0);
@@ -2696,6 +2708,7 @@ rt2560_stop(struct ifnet *ifp, int disable)
struct ieee80211com *ic = &sc->sc_ic;
sc->sc_tx_timer = 0;
+ sc->sc_flags &= ~(RT2560_PRIO_OACTIVE|RT2560_DATA_OACTIVE);
ifp->if_timer = 0;
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
diff --git a/sys/dev/ic/rt2560var.h b/sys/dev/ic/rt2560var.h
index 6d5eff452c5..54490b0a965 100644
--- a/sys/dev/ic/rt2560var.h
+++ b/sys/dev/ic/rt2560var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rt2560var.h,v 1.9 2010/09/07 16:21:42 deraadt Exp $ */
+/* $OpenBSD: rt2560var.h,v 1.10 2012/07/13 10:08:15 stsp Exp $ */
/*-
* Copyright (c) 2005, 2006
@@ -116,6 +116,8 @@ struct rt2560_softc {
#define RT2560_ENABLED (1 << 0)
#define RT2560_UPDATE_SLOT (1 << 1)
#define RT2560_SET_SLOTTIME (1 << 2)
+#define RT2560_PRIO_OACTIVE (1 << 3)
+#define RT2560_DATA_OACTIVE (1 << 4)
int sc_tx_timer;
diff --git a/sys/dev/ic/rt2661.c b/sys/dev/ic/rt2661.c
index dae4cda832e..7221371a8c0 100644
--- a/sys/dev/ic/rt2661.c
+++ b/sys/dev/ic/rt2661.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rt2661.c,v 1.65 2011/03/18 06:05:21 deraadt Exp $ */
+/* $OpenBSD: rt2661.c,v 1.66 2012/07/13 10:08:15 stsp Exp $ */
/*-
* Copyright (c) 2006
@@ -986,9 +986,18 @@ rt2661_tx_intr(struct rt2661_softc *sc)
txq->stat = 0;
}
- sc->sc_tx_timer = 0;
- ifp->if_flags &= ~IFF_OACTIVE;
- rt2661_start(ifp);
+ if (sc->mgtq.queued == 0 && sc->txq[0].queued == 0)
+ sc->sc_tx_timer = 0;
+ if (sc->mgtq.queued < RT2661_MGT_RING_COUNT &&
+ sc->txq[0].queued < RT2661_TX_RING_COUNT - 1) {
+ if (sc->mgtq.queued < RT2661_MGT_RING_COUNT)
+ sc->sc_flags &= ~RT2661_MGT_OACTIVE;
+ if (sc->txq[0].queued < RT2661_TX_RING_COUNT - 1)
+ sc->sc_flags &= ~RT2661_DATA_OACTIVE;
+ if (!(sc->sc_flags & (RT2661_MGT_OACTIVE|RT2661_DATA_OACTIVE)))
+ ifp->if_flags &= ~IFF_OACTIVE;
+ rt2661_start(ifp);
+ }
}
void
@@ -1805,6 +1814,7 @@ rt2661_start(struct ifnet *ifp)
if (m0 != NULL) {
if (sc->mgtq.queued >= RT2661_MGT_RING_COUNT) {
ifp->if_flags |= IFF_OACTIVE;
+ sc->sc_flags |= RT2661_MGT_OACTIVE;
break;
}
IF_DEQUEUE(&ic->ic_mgtq, m0);
@@ -1827,6 +1837,7 @@ rt2661_start(struct ifnet *ifp)
if (sc->txq[0].queued >= RT2661_TX_RING_COUNT - 1) {
/* there is no place left in this ring */
ifp->if_flags |= IFF_OACTIVE;
+ sc->sc_flags |= RT2661_DATA_OACTIVE;
break;
}
IFQ_DEQUEUE(&ifp->if_snd, m0);
@@ -2602,6 +2613,7 @@ rt2661_stop(struct ifnet *ifp, int disable)
int ac;
sc->sc_tx_timer = 0;
+ sc->sc_flags &= ~(RT2661_MGT_OACTIVE|RT2661_DATA_OACTIVE);
ifp->if_timer = 0;
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
diff --git a/sys/dev/ic/rt2661var.h b/sys/dev/ic/rt2661var.h
index e2d061202f6..f95d6207d89 100644
--- a/sys/dev/ic/rt2661var.h
+++ b/sys/dev/ic/rt2661var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rt2661var.h,v 1.14 2011/03/18 06:05:21 deraadt Exp $ */
+/* $OpenBSD: rt2661var.h,v 1.15 2012/07/13 10:08:15 stsp Exp $ */
/*-
* Copyright (c) 2006
@@ -111,6 +111,8 @@ struct rt2661_softc {
#define RT2661_UPDATE_SLOT (1 << 1)
#define RT2661_SET_SLOTTIME (1 << 2)
#define RT2661_FWLOADED (1 << 3)
+#define RT2661_MGT_OACTIVE (1 << 4)
+#define RT2661_DATA_OACTIVE (1 << 5)
int sc_tx_timer;