On Tue, Jul 10, 2012 at 05:56:29PM +0200, Stefan Sperling wrote: > Updated version that includes similar fixes for the rt2661 variants. > > This seems to help soekris-based ral APs that get stuck with the OACTIVE > flag set (see the flags line in "ifconfig ral0" output when the AP stops > responding) and then require "ifconfig ral0 down up" to recover. > > It would be great to get some more testing. Thanks!
Anyone want to OK this? We've been testing this with edd's soekris (rt2661 minipci) and two rt2560/rt2661 ralink cardbus cards. > > Index: rt2560.c > =================================================================== > RCS file: /cvs/src/sys/dev/ic/rt2560.c,v > retrieving revision 1.58 > diff -u -p -r1.58 rt2560.c > --- rt2560.c 22 Feb 2011 20:05:03 -0000 1.58 > +++ rt2560.c 10 Jul 2012 15:34:21 -0000 > @@ -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); > @@ -2685,6 +2697,7 @@ rt2560_stop(struct ifnet *ifp, int disab > 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); > > Index: rt2560var.h > =================================================================== > RCS file: /cvs/src/sys/dev/ic/rt2560var.h,v > retrieving revision 1.9 > diff -u -p -r1.9 rt2560var.h > --- rt2560var.h 7 Sep 2010 16:21:42 -0000 1.9 > +++ rt2560var.h 7 Jul 2012 15:58:58 -0000 > @@ -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; > > Index: rt2661.c > =================================================================== > RCS file: /cvs/src/sys/dev/ic/rt2661.c,v > retrieving revision 1.65 > diff -u -p -r1.65 rt2661.c > --- rt2661.c 18 Mar 2011 06:05:21 -0000 1.65 > +++ rt2661.c 10 Jul 2012 15:38:03 -0000 > @@ -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 disab > 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); > > Index: rt2661var.h > =================================================================== > RCS file: /cvs/src/sys/dev/ic/rt2661var.h,v > retrieving revision 1.14 > diff -u -p -r1.14 rt2661var.h > --- rt2661var.h 18 Mar 2011 06:05:21 -0000 1.14 > +++ rt2661var.h 10 Jul 2012 13:17:30 -0000 > @@ -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;