diff options
author | Stefan Sperling <stsp@cvs.openbsd.org> | 2012-07-13 10:08:16 +0000 |
---|---|---|
committer | Stefan Sperling <stsp@cvs.openbsd.org> | 2012-07-13 10:08:16 +0000 |
commit | e88a6f2d21a7d8b0565da510ebae982d4e31a4be (patch) | |
tree | ee6f02cbda055e32fed3e6e364034fad139f89ec | |
parent | ce3878f3661a55c891f6523fbc959007cf662830 (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.c | 27 | ||||
-rw-r--r-- | sys/dev/ic/rt2560var.h | 4 | ||||
-rw-r--r-- | sys/dev/ic/rt2661.c | 20 | ||||
-rw-r--r-- | sys/dev/ic/rt2661var.h | 4 |
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; |