This switches athn(4) to the new RA Tx rate adaptation module.
Tests on athn(4) PCI devices are welcome.
USB devices don't need to be tested in this case Tx rate adaptation
is taken care of by firmware.

I could only test on AR9285 so far, but the result looks promising.

diff c6a6a64b49f2287751632205d64f594eb6c1ee42 
636e9964c6e5313bb1c75823249d483597a0e93a
blob - 43169fcccf130b28c5b2e0a95e1b7689244e43d5
blob + 2a8e9aacae52a047979890b95c2880a004b2495b
--- sys/dev/cardbus/if_athn_cardbus.c
+++ sys/dev/cardbus/if_athn_cardbus.c
@@ -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>
blob - 3c11b4c004b4dd5fb12e7789f74bfb3e346b7acf
blob + bbe145570c10ef1466c23ae70f626634bd8d354d
--- sys/dev/ic/ar5008.c
+++ sys/dev/ic/ar5008.c
@@ -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,13 +1079,15 @@ 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++;
+       /* 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);
+       }
 
-       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, struc
                /* 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, struc
        }
        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, struc
        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) ||
blob - c2b0d05b3fe2f8b721790c3a0955028c7d36e923
blob + 830f460f211fb2f0c84b482cdada36cdec4cbc4c
--- sys/dev/ic/ar5416.c
+++ sys/dev/ic/ar5416.c
@@ -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>
blob - 14a7f15c8a72ad9d97c59433cfd811f6de4d2214
blob + 0db7b5f5520a3d4e1ebf0039157bbe55ead103a1
--- sys/dev/ic/ar9003.c
+++ sys/dev/ic/ar9003.c
@@ -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>
blob - acb00c62ed242d348010edb679bcc289a0c9cd7f
blob + 91071ffff1e0408b552cb2d60ac4888c4d5edbc6
--- sys/dev/ic/ar9280.c
+++ sys/dev/ic/ar9280.c
@@ -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>
blob - 057ea48e06ba07e29d1d055a29231cab2cef5616
blob + e4aaa701edc2d5bf1d3ec7a219ed097d8278fdd2
--- sys/dev/ic/ar9285.c
+++ sys/dev/ic/ar9285.c
@@ -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>
blob - df89bf7d767b94c6089fee763c21c0dece84f4b9
blob + d46441f4677ed3962867068828b2ff88e56e0d7d
--- sys/dev/ic/ar9287.c
+++ sys/dev/ic/ar9287.c
@@ -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>
blob - 34cead5782df98ee5b8ae5b0ca3d0beefc9b5864
blob + 7fc464067a5b8780137a01091e0b0eba9e443099
--- sys/dev/ic/ar9380.c
+++ sys/dev/ic/ar9380.c
@@ -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>
blob - d20bb5615c20f30c2d7bc1bc4bfc66370dfeb232
blob + f410a488af23f47eb7900394a5e23e27924d033b
--- sys/dev/ic/athn.c
+++ sys/dev/ic/athn.c
@@ -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 ieee802
 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 ieee8021
        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 ieee8021
        }
 }
 
-#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_
 
        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);
blob - c21c69794415adb83a18fc08809ff718d85af409
blob + da86bf73ce43f3278abd049a08e15b73d8a74e33
--- sys/dev/ic/athnvar.h
+++ sys/dev/ic/athnvar.h
@@ -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;
blob - 874f3523b5eff7240135126401c71d3a34395317
blob + b7c75ef72cdd787b4bda3264ba603e86061c1985
--- sys/dev/pci/if_athn_pci.c
+++ sys/dev/pci/if_athn_pci.c
@@ -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>
blob - 771baafcdac926e3752111a37d6963447775c8ab
blob + 3655df8bade95c8e7d42cf9216412470913c08c5
--- sys/dev/usb/if_athn_usb.c
+++ sys/dev/usb/if_athn_usb.c
@@ -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>

Reply via email to