From d2dd70ac0a5fe22ca102dd594dce32a1fe581c76 Mon Sep 17 00:00:00 2001 From: stsp Date: Thu, 15 Apr 2021 18:25:43 +0000 Subject: [PATCH] Switch athn(4) 802.11n Tx rate adaptation from MiRA to RA. Tests: AR5418: Uwe Werler AR9280: kn, jmatthew, Lauri Tirkkonen, Scott Bennett, Mikolaj Kucharski AR9285: kevlo, trondd, myself ok deraadt@ --- sys/dev/cardbus/if_athn_cardbus.c | 4 +- sys/dev/ic/ar5008.c | 84 ++++++++++++++++++------------- sys/dev/ic/ar5416.c | 4 +- sys/dev/ic/ar9003.c | 4 +- sys/dev/ic/ar9280.c | 4 +- sys/dev/ic/ar9285.c | 4 +- sys/dev/ic/ar9287.c | 4 +- sys/dev/ic/ar9380.c | 4 +- sys/dev/ic/athn.c | 51 ++----------------- sys/dev/ic/athnvar.h | 5 +- sys/dev/pci/if_athn_pci.c | 4 +- sys/dev/usb/if_athn_usb.c | 4 +- 12 files changed, 73 insertions(+), 103 deletions(-) diff --git a/sys/dev/cardbus/if_athn_cardbus.c b/sys/dev/cardbus/if_athn_cardbus.c index 43169fcccf1..91e2d16d61a 100644 --- a/sys/dev/cardbus/if_athn_cardbus.c +++ b/sys/dev/cardbus/if_athn_cardbus.c @@ -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 @@ -43,7 +43,7 @@ #include #include -#include +#include #include #include diff --git a/sys/dev/ic/ar5008.c b/sys/dev/ic/ar5008.c index 3c11b4c004b..2b77b0d686d 100644 --- a/sys/dev/ic/ar5008.c +++ b/sys/dev/ic/ar5008.c @@ -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 @@ -51,7 +51,7 @@ #include #include -#include +#include #include #include @@ -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) || diff --git a/sys/dev/ic/ar5416.c b/sys/dev/ic/ar5416.c index c2b0d05b3fe..972ce2418c7 100644 --- a/sys/dev/ic/ar5416.c +++ b/sys/dev/ic/ar5416.c @@ -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 @@ -51,7 +51,7 @@ #include #include -#include +#include #include #include diff --git a/sys/dev/ic/ar9003.c b/sys/dev/ic/ar9003.c index 14a7f15c8a7..caecf1dfcbb 100644 --- a/sys/dev/ic/ar9003.c +++ b/sys/dev/ic/ar9003.c @@ -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 @@ -51,7 +51,7 @@ #include #include -#include +#include #include #include diff --git a/sys/dev/ic/ar9280.c b/sys/dev/ic/ar9280.c index acb00c62ed2..60f8eb9ad02 100644 --- a/sys/dev/ic/ar9280.c +++ b/sys/dev/ic/ar9280.c @@ -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 @@ -51,7 +51,7 @@ #include #include -#include +#include #include #include diff --git a/sys/dev/ic/ar9285.c b/sys/dev/ic/ar9285.c index 057ea48e06b..20ac9b8b159 100644 --- a/sys/dev/ic/ar9285.c +++ b/sys/dev/ic/ar9285.c @@ -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 @@ -52,7 +52,7 @@ #include #include -#include +#include #include #include diff --git a/sys/dev/ic/ar9287.c b/sys/dev/ic/ar9287.c index df89bf7d767..2503a22220e 100644 --- a/sys/dev/ic/ar9287.c +++ b/sys/dev/ic/ar9287.c @@ -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 @@ -51,7 +51,7 @@ #include #include -#include +#include #include #include diff --git a/sys/dev/ic/ar9380.c b/sys/dev/ic/ar9380.c index 34cead5782d..5e332fce483 100644 --- a/sys/dev/ic/ar9380.c +++ b/sys/dev/ic/ar9380.c @@ -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 @@ -49,7 +49,7 @@ #include #include -#include +#include #include #include diff --git a/sys/dev/ic/athn.c b/sys/dev/ic/athn.c index 3570b8d389a..24f8a4db31a 100644 --- a/sys/dev/ic/athn.c +++ b/sys/dev/ic/athn.c @@ -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 @@ -53,7 +53,7 @@ #include #include -#include +#include #include #include @@ -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); diff --git a/sys/dev/ic/athnvar.h b/sys/dev/ic/athnvar.h index c21c6979441..db6bdf44304 100644 --- a/sys/dev/ic/athnvar.h +++ b/sys/dev/ic/athnvar.h @@ -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 @@ -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; diff --git a/sys/dev/pci/if_athn_pci.c b/sys/dev/pci/if_athn_pci.c index 874f3523b5e..31cae7acacf 100644 --- a/sys/dev/pci/if_athn_pci.c +++ b/sys/dev/pci/if_athn_pci.c @@ -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 @@ -43,7 +43,7 @@ #include #include -#include +#include #include #include diff --git a/sys/dev/usb/if_athn_usb.c b/sys/dev/usb/if_athn_usb.c index 771baafcdac..08ffda8c9aa 100644 --- a/sys/dev/usb/if_athn_usb.c +++ b/sys/dev/usb/if_athn_usb.c @@ -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 @@ -49,7 +49,7 @@ #include #include -#include +#include #include #include -- 2.20.1