Switch athn(4) 802.11n Tx rate adaptation from MiRA to RA.
authorstsp <stsp@openbsd.org>
Thu, 15 Apr 2021 18:25:43 +0000 (18:25 +0000)
committerstsp <stsp@openbsd.org>
Thu, 15 Apr 2021 18:25:43 +0000 (18:25 +0000)
Tests:
AR5418: Uwe Werler
AR9280: kn, jmatthew, Lauri Tirkkonen, Scott Bennett, Mikolaj Kucharski
AR9285: kevlo, trondd, myself

ok deraadt@

12 files changed:
sys/dev/cardbus/if_athn_cardbus.c
sys/dev/ic/ar5008.c
sys/dev/ic/ar5416.c
sys/dev/ic/ar9003.c
sys/dev/ic/ar9280.c
sys/dev/ic/ar9285.c
sys/dev/ic/ar9287.c
sys/dev/ic/ar9380.c
sys/dev/ic/athn.c
sys/dev/ic/athnvar.h
sys/dev/pci/if_athn_pci.c
sys/dev/usb/if_athn_usb.c

index 43169fc..91e2d16 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_athn_cardbus.c,v 1.15 2017/01/12 16:32:28 stsp Exp $       */
+/*     $OpenBSD: if_athn_cardbus.c,v 1.16 2021/04/15 18:25:43 stsp Exp $       */
 
 /*-
  * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
@@ -43,7 +43,7 @@
 
 #include <net80211/ieee80211_var.h>
 #include <net80211/ieee80211_amrr.h>
-#include <net80211/ieee80211_mira.h>
+#include <net80211/ieee80211_ra.h>
 #include <net80211/ieee80211_radiotap.h>
 
 #include <dev/ic/athnreg.h>
index 3c11b4c..2b77b0d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ar5008.c,v 1.64 2020/12/12 11:48:52 jan Exp $ */
+/*     $OpenBSD: ar5008.c,v 1.65 2021/04/15 18:25:43 stsp Exp $        */
 
 /*-
  * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
@@ -51,7 +51,7 @@
 
 #include <net80211/ieee80211_var.h>
 #include <net80211/ieee80211_amrr.h>
-#include <net80211/ieee80211_mira.h>
+#include <net80211/ieee80211_ra.h>
 #include <net80211/ieee80211_radiotap.h>
 
 #include <dev/ic/athnreg.h>
@@ -1064,7 +1064,7 @@ ar5008_tx_process(struct athn_softc *sc, int qid)
        struct athn_tx_buf *bf;
        struct ar_tx_desc *ds;
        uint8_t failcnt;
-       int txfail;
+       int txfail = 0, rtscts;
 
        bf = SIMPLEQ_FIRST(&txq->head);
        if (bf == NULL)
@@ -1079,12 +1079,14 @@ ar5008_tx_process(struct athn_softc *sc, int qid)
 
        sc->sc_tx_timer = 0;
 
-       txfail = (ds->ds_status1 & AR_TXS1_EXCESSIVE_RETRIES);
-       if (txfail)
-               ifp->if_oerrors++;
-
-       if (ds->ds_status1 & AR_TXS1_UNDERRUN)
-               athn_inc_tx_trigger_level(sc);
+       /* These status bits are valid if “FRM_XMIT_OK” is clear. */
+       if ((ds->ds_status1 & AR_TXS1_FRM_XMIT_OK) == 0) {
+               txfail = (ds->ds_status1 & AR_TXS1_EXCESSIVE_RETRIES);
+               if (txfail)
+                       ifp->if_oerrors++;
+               if (ds->ds_status1 & AR_TXS1_UNDERRUN)
+                       athn_inc_tx_trigger_level(sc);
+       }
 
        an = (struct athn_node *)bf->bf_ni;
        ni = (struct ieee80211_node *)bf->bf_ni;
@@ -1094,33 +1096,51 @@ ar5008_tx_process(struct athn_softc *sc, int qid)
         * for the final series used.  We must add the number of tries for
         * 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);
-       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;
-       }
+       /* Assume two tries per series, as per AR_TXC2_XMIT_DATA_TRIESx. */
+       failcnt += MS(ds->ds_status9, AR_TXS9_FINAL_IDX) * 2;
+
+       rtscts = (ds->ds_ctl0 & (AR_TXC0_RTS_ENABLE | AR_TXC0_CTS_ENABLE));
 
        /* Update rate control statistics. */
-       if (ni->ni_flags & IEEE80211_NODE_HT) {
-               an->mn.frames++;
-               an->mn.ampdu_size = bf->bf_m->m_pkthdr.len + IEEE80211_CRC_LEN;
-               an->mn.agglen = 1; /* XXX We do not yet support Tx agg. */
-               if (failcnt > 0)
-                       an->mn.retries += failcnt;
-               if (txfail)
-                       an->mn.txfail++;
+       if ((ni->ni_flags & IEEE80211_NODE_HT) && ic->ic_fixed_mcs == -1) {
+               const struct ieee80211_ht_rateset *rs =
+                   ieee80211_ra_get_ht_rateset(bf->bf_txmcs,
+                   ieee80211_node_supports_ht_sgi20(ni));
+               unsigned int retries = 0, i;
+               int mcs = bf->bf_txmcs;
+
+               /* With RTS/CTS each Tx series used the same MCS. */
+               if (rtscts) {
+                       retries = failcnt;
+               } else {
+                       for (i = 0; i < failcnt; i++) {
+                               if (mcs > rs->min_mcs) {
+                                       ieee80211_ra_add_stats_ht(&an->rn,
+                                           ic, ni, mcs, 1, 1);
+                                       if (i % 2) /* two tries per series */
+                                               mcs--;
+                               } else
+                                       retries++;
+                       }
+               }
+
+               if (txfail && retries == 0) {
+                       ieee80211_ra_add_stats_ht(&an->rn, ic, ni,
+                           mcs, 1, 1);
+               } else {
+                       ieee80211_ra_add_stats_ht(&an->rn, ic, ni,
+                           mcs, retries + 1, retries);
+               }
                if (ic->ic_state == IEEE80211_S_RUN) {
 #ifndef IEEE80211_STA_ONLY
                        if (ic->ic_opmode != IEEE80211_M_HOSTAP ||
                            ni->ni_state == IEEE80211_STA_ASSOC)
 #endif
-                               ieee80211_mira_choose(&an->mn, ic, ni);
+                               ieee80211_ra_choose(&an->rn, ic, ni);
                }
-       } else {
+       } else if (ic->ic_fixed_rate == -1) {
                an->amn.amn_txcnt++;
                if (failcnt > 0)
                        an->amn.amn_retrycnt++;
@@ -1492,11 +1512,6 @@ ar5008_tx(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
                /* Use same fixed rate for all tries. */
                ridx[0] = ridx[1] = ridx[2] = ridx[3] =
                    sc->fixed_ridx;
-       } else if ((ni->ni_flags & IEEE80211_NODE_HT) &&
-           ieee80211_mira_is_probing(&an->mn)) {
-               /* Use same fixed rate for all tries. */
-               ridx[0] = ridx[1] = ridx[2] = ridx[3] =
-                   ATHN_RIDX_MCS0 + ni->ni_txmcs;
        } else {
                /* Use fallback table of the node. */
                int txrate;
@@ -1562,6 +1577,7 @@ ar5008_tx(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
        }
        bf->bf_m = m;
        bf->bf_ni = ni;
+       bf->bf_txmcs = ni->ni_txmcs;
        bf->bf_txflags = txflags;
 
        wh = mtod(m, struct ieee80211_frame *);
@@ -1607,16 +1623,12 @@ ar5008_tx(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
        if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
            (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
            IEEE80211_FC0_TYPE_DATA) {
-               int rtsthres = ic->ic_rtsthreshold;
                enum ieee80211_htprot htprot;
 
-               if (ni->ni_flags & IEEE80211_NODE_HT)
-                       rtsthres = ieee80211_mira_get_rts_threshold(&an->mn,
-                           ic, ni, totlen);
                htprot = (ic->ic_bss->ni_htop1 & IEEE80211_HTOP1_PROT_MASK);
 
                /* NB: Group frames are sent using CCK in 802.11b/g. */
-               if (totlen > rtsthres) {
+               if (totlen > ic->ic_rtsthreshold) {
                        ds->ds_ctl0 |= AR_TXC0_RTS_ENABLE;
                } else if (((ic->ic_flags & IEEE80211_F_USEPROT) &&
                    athn_rates[ridx[0]].phy == IEEE80211_T_OFDM) ||
index c2b0d05..972ce24 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ar5416.c,v 1.21 2019/02/01 16:15:07 stsp Exp $        */
+/*     $OpenBSD: ar5416.c,v 1.22 2021/04/15 18:25:43 stsp Exp $        */
 
 /*-
  * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
@@ -51,7 +51,7 @@
 
 #include <net80211/ieee80211_var.h>
 #include <net80211/ieee80211_amrr.h>
-#include <net80211/ieee80211_mira.h>
+#include <net80211/ieee80211_ra.h>
 #include <net80211/ieee80211_radiotap.h>
 
 #include <dev/ic/athnreg.h>
index 14a7f15..caecf1d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ar9003.c,v 1.52 2020/12/12 11:48:52 jan Exp $ */
+/*     $OpenBSD: ar9003.c,v 1.53 2021/04/15 18:25:43 stsp Exp $        */
 
 /*-
  * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -51,7 +51,7 @@
 
 #include <net80211/ieee80211_var.h>
 #include <net80211/ieee80211_amrr.h>
-#include <net80211/ieee80211_mira.h>
+#include <net80211/ieee80211_ra.h>
 #include <net80211/ieee80211_radiotap.h>
 
 #include <dev/ic/athnreg.h>
index acb00c6..60f8eb9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ar9280.c,v 1.27 2019/02/01 16:15:07 stsp Exp $        */
+/*     $OpenBSD: ar9280.c,v 1.28 2021/04/15 18:25:43 stsp Exp $        */
 
 /*-
  * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
@@ -51,7 +51,7 @@
 
 #include <net80211/ieee80211_var.h>
 #include <net80211/ieee80211_amrr.h>
-#include <net80211/ieee80211_mira.h>
+#include <net80211/ieee80211_ra.h>
 #include <net80211/ieee80211_radiotap.h>
 
 #include <dev/ic/athnreg.h>
index 057ea48..20ac9b8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ar9285.c,v 1.28 2019/02/01 16:15:07 stsp Exp $        */
+/*     $OpenBSD: ar9285.c,v 1.29 2021/04/15 18:25:43 stsp Exp $        */
 
 /*-
  * Copyright (c) 2009-2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -52,7 +52,7 @@
 
 #include <net80211/ieee80211_var.h>
 #include <net80211/ieee80211_amrr.h>
-#include <net80211/ieee80211_mira.h>
+#include <net80211/ieee80211_ra.h>
 #include <net80211/ieee80211_radiotap.h>
 
 #include <dev/ic/athnreg.h>
index df89bf7..2503a22 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ar9287.c,v 1.28 2019/03/31 11:00:11 kevlo Exp $       */
+/*     $OpenBSD: ar9287.c,v 1.29 2021/04/15 18:25:43 stsp Exp $        */
 
 /*-
  * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
@@ -51,7 +51,7 @@
 
 #include <net80211/ieee80211_var.h>
 #include <net80211/ieee80211_amrr.h>
-#include <net80211/ieee80211_mira.h>
+#include <net80211/ieee80211_ra.h>
 #include <net80211/ieee80211_radiotap.h>
 
 #include <dev/ic/athnreg.h>
index 34cead5..5e332fc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ar9380.c,v 1.26 2017/08/18 11:00:38 jsg Exp $ */
+/*     $OpenBSD: ar9380.c,v 1.27 2021/04/15 18:25:43 stsp Exp $        */
 
 /*-
  * Copyright (c) 2011 Damien Bergamini <damien.bergamini@free.fr>
@@ -49,7 +49,7 @@
 
 #include <net80211/ieee80211_var.h>
 #include <net80211/ieee80211_amrr.h>
-#include <net80211/ieee80211_mira.h>
+#include <net80211/ieee80211_ra.h>
 #include <net80211/ieee80211_radiotap.h>
 
 #include <dev/ic/athnreg.h>
index 3570b8d..24f8a4d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: athn.c,v 1.110 2021/04/15 18:14:45 stsp Exp $ */
+/*     $OpenBSD: athn.c,v 1.111 2021/04/15 18:25:43 stsp Exp $ */
 
 /*-
  * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
@@ -53,7 +53,7 @@
 
 #include <net80211/ieee80211_var.h>
 #include <net80211/ieee80211_amrr.h>
-#include <net80211/ieee80211_mira.h>
+#include <net80211/ieee80211_ra.h>
 #include <net80211/ieee80211_radiotap.h>
 
 #include <dev/ic/athnreg.h>
@@ -127,11 +127,8 @@ int                athn_hw_reset(struct athn_softc *, struct ieee80211_channel *,
 struct         ieee80211_node *athn_node_alloc(struct ieee80211com *);
 void           athn_newassoc(struct ieee80211com *, struct ieee80211_node *,
                    int);
-void           athn_node_leave(struct ieee80211com *, struct ieee80211_node *);
 int            athn_media_change(struct ifnet *);
 void           athn_next_scan(void *);
-void           athn_iter_mira_delete(void *, struct ieee80211_node *);
-void           athn_delete_mira_nodes(struct athn_softc *);
 int            athn_newstate(struct ieee80211com *, enum ieee80211_state,
                    int);
 void           athn_updateedca(struct ieee80211com *);
@@ -379,9 +376,6 @@ athn_attach(struct athn_softc *sc)
        if_attach(ifp);
        ieee80211_ifattach(ifp);
        ic->ic_node_alloc = athn_node_alloc;
-#ifndef IEEE80211_STA_ONLY
-       ic->ic_node_leave = athn_node_leave;
-#endif
        ic->ic_newassoc = athn_newassoc;
        ic->ic_updateslot = athn_updateslot;
        ic->ic_updateedca = athn_updateedca;
@@ -404,13 +398,10 @@ void
 athn_detach(struct athn_softc *sc)
 {
        struct ifnet *ifp = &sc->sc_ic.ic_if;
-       struct ieee80211com *ic = &sc->sc_ic;
        int qid;
 
        timeout_del(&sc->scan_to);
        timeout_del(&sc->calib_to);
-       if (ic->ic_flags & IEEE80211_F_HTON)
-               athn_delete_mira_nodes(sc);
 
        if (!(sc->flags & ATHN_FLAG_USB)) {
                for (qid = 0; qid < ATHN_QID_COUNT; qid++)
@@ -2479,7 +2470,7 @@ athn_node_alloc(struct ieee80211com *ic)
 
        an = malloc(sizeof(struct athn_node), M_DEVBUF, M_NOWAIT | M_ZERO);
        if (an && (ic->ic_flags & IEEE80211_F_HTON))
-               ieee80211_mira_node_init(&an->mn);
+               ieee80211_ra_node_init(&an->rn);
        return (struct ieee80211_node *)an;
 }
 
@@ -2495,7 +2486,7 @@ athn_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
        if ((ni->ni_flags & IEEE80211_NODE_HT) == 0)
                ieee80211_amrr_node_init(&sc->amrr, &an->amn);
        else if (ic->ic_opmode == IEEE80211_M_STA)
-               ieee80211_mira_node_init(&an->mn);
+               ieee80211_ra_node_init(&an->rn);
 
        /* Start at lowest available bit-rate, AMRR will raise. */
        ni->ni_txrate = 0;
@@ -2552,16 +2543,6 @@ athn_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
        }
 }
 
-#ifndef IEEE80211_STA_ONLY
-void
-athn_node_leave(struct ieee80211com *ic, struct ieee80211_node *ni)
-{
-       struct athn_node *an = (void *)ni;
-       if (ic->ic_flags & IEEE80211_F_HTON)
-               ieee80211_mira_cancel_timeouts(&an->mn);
-}
-#endif
-
 int
 athn_media_change(struct ifnet *ifp)
 {
@@ -2604,26 +2585,6 @@ athn_next_scan(void *arg)
        splx(s);
 }
 
-void
-athn_iter_mira_delete(void *arg, struct ieee80211_node *ni)
-{
-       struct athn_node *an = (struct athn_node *)ni;
-       ieee80211_mira_cancel_timeouts(&an->mn);
-}
-
-/* Delete pending timeouts managed by MiRA. */
-void
-athn_delete_mira_nodes(struct athn_softc *sc)
-{
-       struct ieee80211com *ic = &sc->sc_ic;
-
-       if (ic->ic_opmode == IEEE80211_M_STA) {
-               struct athn_node *an = (struct athn_node *)ic->ic_bss;
-               ieee80211_mira_cancel_timeouts(&an->mn);
-       } else
-               ieee80211_iterate_nodes(ic, athn_iter_mira_delete, sc);
-}
-
 int
 athn_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
 {
@@ -2634,10 +2595,6 @@ athn_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
 
        timeout_del(&sc->calib_to);
 
-       if ((ic->ic_flags & IEEE80211_F_HTON) &&
-           ic->ic_state == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN)
-               athn_delete_mira_nodes(sc);
-
        switch (nstate) {
        case IEEE80211_S_INIT:
                athn_set_led(sc, 0);
index c21c697..db6bdf4 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: athnvar.h,v 1.41 2020/10/11 07:05:28 mpi Exp $        */
+/*     $OpenBSD: athnvar.h,v 1.42 2021/04/15 18:25:43 stsp Exp $       */
 
 /*-
  * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
@@ -79,6 +79,7 @@ struct athn_tx_buf {
 
        struct mbuf                     *bf_m;
        struct ieee80211_node           *bf_ni;
+       int                             bf_txmcs;
        int                             bf_txflags;
 #define ATHN_TXFLAG_PAPRD      (1 << 0)
 #define ATHN_TXFLAG_CAB                (1 << 1) 
@@ -295,7 +296,7 @@ static const uint16_t ar_mcs_ndbps[][2] = {
 struct athn_node {
        struct ieee80211_node           ni;
        struct ieee80211_amrr_node      amn;
-       struct ieee80211_mira_node      mn;
+       struct ieee80211_ra_node        rn;
        uint8_t                         ridx[ATHN_NUM_RATES];
        uint8_t                         fallback[ATHN_NUM_RATES];
        uint8_t                         sta_index;
index 874f352..31cae7a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_athn_pci.c,v 1.20 2019/04/23 01:17:09 kevlo Exp $  */
+/*     $OpenBSD: if_athn_pci.c,v 1.21 2021/04/15 18:25:44 stsp Exp $   */
 
 /*-
  * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
@@ -43,7 +43,7 @@
 
 #include <net80211/ieee80211_var.h>
 #include <net80211/ieee80211_amrr.h>
-#include <net80211/ieee80211_mira.h>
+#include <net80211/ieee80211_ra.h>
 #include <net80211/ieee80211_radiotap.h>
 
 #include <dev/ic/athnreg.h>
index 771baaf..08ffda8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_athn_usb.c,v 1.60 2021/02/25 02:48:20 dlg Exp $    */
+/*     $OpenBSD: if_athn_usb.c,v 1.61 2021/04/15 18:25:44 stsp Exp $   */
 
 /*-
  * Copyright (c) 2011 Damien Bergamini <damien.bergamini@free.fr>
@@ -49,7 +49,7 @@
 
 #include <net80211/ieee80211_var.h>
 #include <net80211/ieee80211_amrr.h>
-#include <net80211/ieee80211_mira.h>
+#include <net80211/ieee80211_ra.h>
 #include <net80211/ieee80211_radiotap.h>
 
 #include <dev/ic/athnreg.h>