The ral(4) driver, at least for rt2560 hardware, has a problem with RTS.
When running an AP with this device I see TCP download rates for iwn and
iwm clients stuck below 200KB/s, even though on the air ral(4) sends data
frames at its max rate of 54Mbit/s. Disabling RTS for long frames in the
driver makes TCP download rates go up to 1.5MB/s.
I've been trying to figure out what's wrong, but haven't gotten anywhere yet.
Other drivers and devices benefit from RTS, including athn(4) based APs.
So I think disabling RTS for long frames in just this driver is the best
workaround for now.
Note that RTS may still be enabled for other reasons, such as 11b clients
joining the AP. Tough luck, this problem is not new. It is just more exposed
ever since we enabled RTS for long frames by default.
I've also disabled debug messages for Tx failures, and added a comment
to explain why this driver needs 2 free slots on its Tx ring.
OK?
Index: dev/ic/rt2560.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/rt2560.c,v
retrieving revision 1.80
diff -u -p -r1.80 rt2560.c
--- dev/ic/rt2560.c 13 Apr 2016 10:49:26 -0000 1.80
+++ dev/ic/rt2560.c 6 Oct 2016 11:36:49 -0000
@@ -266,6 +266,9 @@ rt2560_attach(void *xsc, int id)
ic->ic_newassoc = rt2560_newassoc;
ic->ic_updateslot = rt2560_updateslot;
+ /* XXX RTS causes throughput problems -- where is the bug? */
+ ic->ic_rtsthreshold = IEEE80211_RTS_MAX;
+
/* override state transition machine */
sc->sc_newstate = ic->ic_newstate;
ic->ic_newstate = rt2560_newstate;
@@ -959,9 +962,10 @@ rt2560_tx_intr(struct rt2560_softc *sc)
case RT2560_TX_FAIL_INVALID:
case RT2560_TX_FAIL_OTHER:
default:
- printf("%s: sending data frame failed 0x%08x\n",
- sc->sc_dev.dv_xname, letoh32(desc->flags));
+ DPRINTF(("%s: sending data frame failed 0x%08x\n",
+ sc->sc_dev.dv_xname, letoh32(desc->flags)));
ifp->if_oerrors++;
+ break;
}
/* descriptor is no longer valid */
@@ -1031,8 +1035,9 @@ rt2560_prio_intr(struct rt2560_softc *sc
case RT2560_TX_FAIL_INVALID:
case RT2560_TX_FAIL_OTHER:
default:
- printf("%s: sending mgt frame failed 0x%08x\n",
- sc->sc_dev.dv_xname, letoh32(desc->flags));
+ DPRINTF(("%s: sending mgt frame failed 0x%08x\n",
+ sc->sc_dev.dv_xname, letoh32(desc->flags)));
+ break;
}
/* descriptor is no longer valid */
@@ -1945,6 +1950,8 @@ rt2560_start(struct ifnet *ifp)
break;
} else {
+ /* Because RTS/CTS requires an extra frame we need
+ * space for 2 frames on the regular Tx queue. */
if (sc->txq.queued >= RT2560_TX_RING_COUNT - 1) {
ifq_set_oactive(&ifp->if_snd);
sc->sc_flags |= RT2560_DATA_OACTIVE;