The athn driver disables multi-rate retries if RTS is used.
This is done because of a hardware limitation (see comment in ar5008_tx()).
So all attemps to send the frame will use the same data rate.

If RTS is not used, the driver will configure the hardware to switch
to a lower rate after 2 failed attempts, and to a lower rate again after
another 2 failures, and so, until this "rate series" is over.

With RTS enabled a transmit failure is equivally likely with each attempt.
A failure of an earlier attempt followed by successful transmission with
the same transmit rate does not necessarily imply that the rate is bad.
The code which counts transmit failures assumes otherwise and treats
transmit failures with RTS the same way as without RTS.

The diff below fixes this problem.

Index: ar5008.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/ar5008.c,v
retrieving revision 1.41
diff -u -p -r1.41 ar5008.c
--- ar5008.c    30 Jan 2017 10:57:00 -0000      1.41
+++ ar5008.c    31 Jan 2017 16:59:32 -0000
@@ -997,11 +997,17 @@ ar5008_tx_process(struct athn_softc *sc,
        /*
         * NB: the data fail count contains the number of un-acked tries
         * for the final series used.  We must add the number of tries for
-        * each series that was fully processed.
+        * each series that was fully processed to punish transmit rates in
+        * the earlier series which did not perform well.
+        * If RTS/CTS was used, each series used the same transmit rate.
+        * Ignore the series count in this case, since each series had
+        * the same chance of success.
         */
        failcnt  = MS(ds->ds_status1, AR_TXS1_DATA_FAIL_CNT);
-       /* NB: Assume two tries per series. */
-       failcnt += MS(ds->ds_status9, AR_TXS9_FINAL_IDX) * 2;
+       if (!(ds->ds_ctl0 & (AR_TXC0_RTS_ENABLE | AR_TXC0_CTS_ENABLE))) {
+               /* NB: Assume two tries per series. */
+               failcnt += MS(ds->ds_status9, AR_TXS9_FINAL_IDX) * 2;
+       }
 
        /* Update rate control statistics. */
        if (ni->ni_flags & IEEE80211_NODE_HT) {

Reply via email to