diff options
author | Stefan Sperling <stsp@cvs.openbsd.org> | 2016-03-21 21:16:02 +0000 |
---|---|---|
committer | Stefan Sperling <stsp@cvs.openbsd.org> | 2016-03-21 21:16:02 +0000 |
commit | 7bfccd5dc21f89e48758c6d815a7bef7d8495ab2 (patch) | |
tree | d34a84cc4d5940e25709f1377c63cd57e4f7078c /sys | |
parent | 482800e4edbfdfee0c22e1dd827a1776ee0640aa (diff) |
Fix watchdog timeouts and dropped frames under load with RT2860 ral(4).
On full tx ring, ring->cur wraps to an active tx descriptor. Passing
that wrapped value to the card was observed to cause general flakiness.
Fix prevents the wrap at the cost of reducing usable tx descriptors by one.
Patch by Richard Procter via bugs@
Tested by Richard on RT2860 and by me on RT3090 and RT2700.
ok mpi@ dlg@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/ic/rt2860.c | 10 | ||||
-rw-r--r-- | sys/dev/ic/rt2860var.h | 5 |
2 files changed, 8 insertions, 7 deletions
diff --git a/sys/dev/ic/rt2860.c b/sys/dev/ic/rt2860.c index d1524ac3241..a0512627a89 100644 --- a/sys/dev/ic/rt2860.c +++ b/sys/dev/ic/rt2860.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rt2860.c,v 1.87 2016/01/05 18:41:15 stsp Exp $ */ +/* $OpenBSD: rt2860.c,v 1.88 2016/03/21 21:16:01 stsp Exp $ */ /*- * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr> @@ -1171,7 +1171,7 @@ rt2860_tx_intr(struct rt2860_softc *sc, int qid) } sc->sc_tx_timer = 0; - if (ring->queued < RT2860_TX_RING_COUNT) + if (ring->queued < RT2860_TX_RING_MAX) sc->qfullmsk &= ~(1 << qid); ifq_clr_oactive(&ifp->if_snd); rt2860_start(ifp); @@ -1618,7 +1618,7 @@ rt2860_tx(struct rt2860_softc *sc, struct mbuf *m, struct ieee80211_node *ni) /* determine how many TXDs are required */ ntxds = 1 + (data->map->dm_nsegs / 2); - if (ring->queued + ntxds >= RT2860_TX_RING_COUNT) { + if (ring->queued + ntxds >= RT2860_TX_RING_MAX) { /* not enough free TXDs, force mbuf defrag */ bus_dmamap_unload(sc->sc_dmat, data->map); error = EFBIG; @@ -1656,7 +1656,7 @@ rt2860_tx(struct rt2860_softc *sc, struct mbuf *m, struct ieee80211_node *ni) /* determine how many TXDs are now required */ ntxds = 1 + (data->map->dm_nsegs / 2); - if (ring->queued + ntxds >= RT2860_TX_RING_COUNT) { + if (ring->queued + ntxds >= RT2860_TX_RING_MAX) { /* this is a hopeless case, drop the mbuf! */ bus_dmamap_unload(sc->sc_dmat, data->map); m_freem(m); @@ -1714,7 +1714,7 @@ rt2860_tx(struct rt2860_softc *sc, struct mbuf *m, struct ieee80211_node *ni) ring->cur = (ring->cur + 1) % RT2860_TX_RING_COUNT; ring->queued += ntxds; - if (ring->queued >= RT2860_TX_RING_COUNT) + if (ring->queued >= RT2860_TX_RING_MAX) sc->qfullmsk |= 1 << qid; /* kick Tx */ diff --git a/sys/dev/ic/rt2860var.h b/sys/dev/ic/rt2860var.h index 76161291541..39b9a7a4460 100644 --- a/sys/dev/ic/rt2860var.h +++ b/sys/dev/ic/rt2860var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rt2860var.h,v 1.21 2013/12/06 21:03:03 deraadt Exp $ */ +/* $OpenBSD: rt2860var.h,v 1.22 2016/03/21 21:16:01 stsp Exp $ */ /*- * Copyright (c) 2007 @@ -17,8 +17,9 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RT2860_TX_RING_COUNT 64 #define RT2860_RX_RING_COUNT 128 +#define RT2860_TX_RING_COUNT 64 +#define RT2860_TX_RING_MAX (RT2860_TX_RING_COUNT - 1) #define RT2860_TX_POOL_COUNT (RT2860_TX_RING_COUNT * 2) #define RT2860_MAX_SCATTER ((RT2860_TX_RING_COUNT * 2) - 1) |