Add support for 40MHz channels to net80211 RA.
authorstsp <stsp@openbsd.org>
Mon, 11 Oct 2021 09:01:05 +0000 (09:01 +0000)
committerstsp <stsp@openbsd.org>
Mon, 11 Oct 2021 09:01:05 +0000 (09:01 +0000)
For the moment we use either the 40MHz rate set or the 20 MHz one,
depending on whether our peer supports 40MHz channels.
If this turns out to be suboptimal we could probe the 40MHz and 20MHz
rate sets separately to detect which one works better.

The same applies to use of the short guard interval (SGI), which is
either always on or off at the moment. Again, probing for this could
be added later if needed.

sys/dev/ic/ar5008.c
sys/dev/pci/if_iwm.c
sys/dev/pci/if_iwn.c
sys/net80211/ieee80211.c
sys/net80211/ieee80211_node.h
sys/net80211/ieee80211_proto.c
sys/net80211/ieee80211_ra.c
sys/net80211/ieee80211_ra.h
sys/net80211/ieee80211_var.h

index fbf2059..e9ff551 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ar5008.c,v 1.68 2021/10/03 20:19:55 kettenis Exp $    */
+/*     $OpenBSD: ar5008.c,v 1.69 2021/10/11 09:01:05 stsp Exp $        */
 
 /*-
  * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
@@ -1150,7 +1150,7 @@ ar5008_tx_process(struct athn_softc *sc, int qid)
        /* Update rate control statistics. */
        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_ra_get_ht_rateset(bf->bf_txmcs, 0 /* chan40 */,
                    ieee80211_node_supports_ht_sgi20(ni));
                unsigned int retries = 0, i;
                int mcs = bf->bf_txmcs;
index 6a14572..77d9c14 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_iwm.c,v 1.374 2021/10/07 08:15:04 stsp Exp $       */
+/*     $OpenBSD: if_iwm.c,v 1.375 2021/10/11 09:01:05 stsp Exp $       */
 
 /*
  * Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@@ -5390,7 +5390,8 @@ iwm_ht_single_rate_control(struct iwm_softc *sc, struct ieee80211_node *ni,
                int mcs = txmcs;
                const struct ieee80211_ht_rateset *rs =
                    ieee80211_ra_get_ht_rateset(txmcs,
-                   ieee80211_node_supports_ht_sgi20(ni));
+                       ieee80211_node_supports_ht_chan40(ni),
+                       ieee80211_ra_use_ht_sgi(ni));
                unsigned int retries = 0, i;
 
                in->lq_rate_mismatch = 0;
index 2870256..aff55ac 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_iwn.c,v 1.249 2021/08/19 06:02:04 stsp Exp $       */
+/*     $OpenBSD: if_iwn.c,v 1.250 2021/10/11 09:01:05 stsp Exp $       */
 
 /*-
  * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -2283,8 +2283,8 @@ iwn_ht_single_rate_control(struct iwn_softc *sc, struct ieee80211_node *ni,
        struct iwn_node *wn = (void *)ni;
        int mcs = rate;
        const struct ieee80211_ht_rateset *rs =
-           ieee80211_ra_get_ht_rateset(rate,
-           ieee80211_node_supports_ht_sgi20(ni));
+           ieee80211_ra_get_ht_rateset(rate, 0 /* chan40 */,
+           ieee80211_ra_use_ht_sgi(ni));
        unsigned int retries = 0, i;
 
        /*
index e313d22..7bb6819 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ieee80211.c,v 1.84 2020/06/08 09:09:58 stsp Exp $     */
+/*     $OpenBSD: ieee80211.c,v 1.85 2021/10/11 09:01:06 stsp Exp $     */
 /*     $NetBSD: ieee80211.c,v 1.19 2004/06/06 05:45:29 dyoung Exp $    */
 
 /*-
@@ -824,28 +824,68 @@ const struct ieee80211_rateset ieee80211_std_rateset_11g =
 
 const struct ieee80211_ht_rateset ieee80211_std_ratesets_11n[] = {
        /* MCS 0-7, 20MHz channel, no SGI */
-       { 8, { 13, 26, 39, 52, 78, 104, 117, 130 }, 0x000000ff, 0, 7, 0},
+       { 8, { 13, 26, 39, 52, 78, 104, 117, 130 },
+           0x000000ff, 0, 7, 0, 0},
 
        /* MCS 0-7, 20MHz channel, SGI */
-       { 8, { 14, 29, 43, 58, 87, 116, 130, 144 }, 0x000000ff, 0, 7, 1 },
+       { 8, { 14, 29, 43, 58, 87, 116, 130, 144 },
+           0x000000ff, 0, 7, 0, 1 },
 
        /* MCS 8-15, 20MHz channel, no SGI */
-       { 8, { 26, 52, 78, 104, 156, 208, 234, 260 }, 0x0000ff00, 8, 15, 0 },
+       { 8, { 26, 52, 78, 104, 156, 208, 234, 260 },
+           0x0000ff00, 8, 15, 0, 0 },
 
        /* MCS 8-15, 20MHz channel, SGI */
-       { 8, { 29, 58, 87, 116, 173, 231, 261, 289 }, 0x0000ff00, 8, 15, 1 },
+       { 8, { 29, 58, 87, 116, 173, 231, 261, 289 },
+           0x0000ff00, 8, 15, 0, 1 },
 
        /* MCS 16-23, 20MHz channel, no SGI */
-       { 8, { 39, 78, 117, 156, 234, 312, 351, 390 }, 0x00ff0000, 16, 23, 0 },
+       { 8, { 39, 78, 117, 156, 234, 312, 351, 390 },
+           0x00ff0000, 16, 23, 0, 0 },
 
        /* MCS 16-23, 20MHz channel, SGI */
-       { 8, { 43, 87, 130, 173, 260, 347, 390, 433 }, 0x00ff0000, 16, 23, 1 },
+       { 8, { 43, 87, 130, 173, 260, 347, 390, 433 },
+           0x00ff0000, 16, 23, 0, 1 },
 
        /* MCS 24-31, 20MHz channel, no SGI */
-       { 8, { 52, 104, 156, 208, 312, 416, 468, 520 }, 0xff000000, 24, 31, 0 },
+       { 8, { 52, 104, 156, 208, 312, 416, 468, 520 },
+           0xff000000, 24, 31, 0, 0 },
 
        /* MCS 24-31, 20MHz channel, SGI */
-       { 8, { 58, 116, 173, 231, 347, 462, 520, 578 }, 0xff000000, 24, 31, 1 },
+       { 8, { 58, 116, 173, 231, 347, 462, 520, 578 },
+           0xff000000, 24, 31, 0, 1 },
+
+       /* MCS 0-7, 40MHz channel, no SGI */
+       { 8, { 27, 54, 81, 108, 162, 216, 243, 270 },
+           0x000000ff, 0, 7, 1, 0 },
+
+       /* MCS 0-7, 40MHz channel, SGI */
+       { 8, { 30, 60, 90, 120, 180, 240, 270, 300 },
+           0x000000ff, 0, 7, 1, 1 },
+
+       /* MCS 8-15, 40MHz channel, no SGI */
+       { 8, { 54, 108, 192, 216, 324, 432, 486, 540 },
+           0x0000ff00, 8, 15, 1, 0 },
+
+       /* MCS 8-15, 40MHz channel, SGI */
+       { 8, { 60, 120, 180, 240, 360, 480, 540, 600 },
+           0x0000ff00, 8, 15, 1, 1 },
+
+       /* MCS 16-23, 40MHz channel, no SGI */
+       { 8, { 81, 162, 243, 324, 486, 648, 729, 810 },
+           0x00ff0000, 16, 23, 1, 0 },
+
+       /* MCS 16-23, 40MHz channel, SGI */
+       { 8, { 90, 180, 270, 360, 540, 720, 810, 900 },
+           0x00ff0000, 16, 23, 1, 1 },
+
+       /* MCS 24-31, 40MHz channel, no SGI */
+       { 8, { 108, 216, 324, 432, 324, 864, 972, 1080 },
+           0xff000000, 24, 31, 1, 0 },
+
+       /* MCS 24-31, 40MHz channel, SGI */
+       { 8, { 120, 240, 360, 480, 520, 960, 1080, 1200 },
+           0xff000000, 24, 31, 1, 1 },
 };
 
 const struct ieee80211_vht_rateset ieee80211_std_ratesets_11ac[] = {
index 4d4b11d..d8fce4c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ieee80211_node.h,v 1.88 2021/04/25 15:32:21 stsp Exp $        */
+/*     $OpenBSD: ieee80211_node.h,v 1.89 2021/10/11 09:01:06 stsp Exp $        */
 /*     $NetBSD: ieee80211_node.h,v 1.9 2004/04/30 22:57:32 dyoung Exp $        */
 
 /*-
@@ -61,7 +61,15 @@ extern const struct ieee80211_rateset ieee80211_std_rateset_11g;
 #define IEEE80211_HT_RATESET_MIMO3_SGI 5
 #define IEEE80211_HT_RATESET_MIMO4     6
 #define IEEE80211_HT_RATESET_MIMO4_SGI 7
-#define IEEE80211_HT_NUM_RATESETS      8
+#define IEEE80211_HT_RATESET_SISO_40   8
+#define IEEE80211_HT_RATESET_SISO_SGI40 9
+#define IEEE80211_HT_RATESET_MIMO2_40  10
+#define IEEE80211_HT_RATESET_MIMO2_SGI40 11
+#define IEEE80211_HT_RATESET_MIMO3_40  12
+#define IEEE80211_HT_RATESET_MIMO3_SGI40 13
+#define IEEE80211_HT_RATESET_MIMO4_40  14
+#define IEEE80211_HT_RATESET_MIMO4_SGI40 15
+#define IEEE80211_HT_NUM_RATESETS      16
 
 /* Maximum number of rates in a HT rateset. */
 #define IEEE80211_HT_RATESET_MAX_NRATES        8
@@ -84,6 +92,7 @@ struct ieee80211_ht_rateset {
        int min_mcs;
        int max_mcs;
 
+       int chan40;
        int sgi;
 };
 
@@ -482,6 +491,15 @@ ieee80211_node_supports_ht_sgi40(struct ieee80211_node *ni)
            (ni->ni_htcaps & IEEE80211_HTCAP_SGI40);
 }
 
+/* Check if the peer can receive frames sent on a 40 MHz channel. */
+static inline int
+ieee80211_node_supports_ht_chan40(struct ieee80211_node *ni)
+{
+       return (ieee80211_node_supports_ht(ni) &&
+           (ni->ni_htcaps & IEEE80211_HTCAP_CBW20_40) &&
+           (ni->ni_htop0 & IEEE80211_HTOP0_CHW));
+}
+
 struct ieee80211com;
 
 typedef void ieee80211_iter_func(void *, struct ieee80211_node *);
index 7e53f9e..41d846d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ieee80211_proto.c,v 1.104 2021/09/23 15:40:41 stsp Exp $      */
+/*     $OpenBSD: ieee80211_proto.c,v 1.105 2021/10/11 09:01:06 stsp Exp $      */
 /*     $NetBSD: ieee80211_proto.c,v 1.8 2004/04/30 23:58:20 dyoung Exp $       */
 
 /*-
@@ -607,7 +607,12 @@ ieee80211_ht_negotiate(struct ieee80211com *ic, struct ieee80211_node *ni)
 
        ni->ni_flags |= IEEE80211_NODE_HT;
 
-       /* Flags IEEE8021_NODE_HT_SGI20/40 are set by drivers if supported. */
+       if (ieee80211_node_supports_ht_sgi20(ni) &&
+           (ic->ic_htcaps & IEEE80211_HTCAP_SGI20))
+               ni->ni_flags |= IEEE80211_NODE_HT_SGI20;
+       if (ieee80211_node_supports_ht_sgi40(ni) &&
+           (ic->ic_htcaps & IEEE80211_HTCAP_SGI40))
+               ni->ni_flags |= IEEE80211_NODE_HT_SGI40;
 }
 
 void
index 8fa9a4f..13d3351 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ieee80211_ra.c,v 1.3 2021/05/03 08:46:28 stsp Exp $   */
+/*     $OpenBSD: ieee80211_ra.c,v 1.4 2021/10/11 09:01:06 stsp Exp $   */
 
 /*
  * Copyright (c) 2021 Christian Ehrhardt <ehrhardt@genua.de>
@@ -112,33 +112,45 @@ ra_fp_sprintf(uint64_t fp)
 #endif /* RA_DEBUG */
 
 const struct ieee80211_ht_rateset *
-ieee80211_ra_get_ht_rateset(int mcs, int sgi20)
+ieee80211_ra_get_ht_rateset(int mcs, int chan40, int sgi)
 {
        const struct ieee80211_ht_rateset *rs;
        int i;
 
        for (i = 0; i < IEEE80211_HT_NUM_RATESETS; i++) {
                rs = &ieee80211_std_ratesets_11n[i];
-               if (sgi20 != rs->sgi)
-                       continue;
-               if (mcs >= rs->min_mcs && mcs <= rs->max_mcs)
+               if (chan40 == rs->chan40 && sgi == rs->sgi &&
+                   mcs >= rs->min_mcs && mcs <= rs->max_mcs)
                        return rs;
        }
 
        panic("MCS %d is not part of any rateset", mcs);
 }
 
+int
+ieee80211_ra_use_ht_sgi(struct ieee80211_node *ni)
+{
+       if ((ni->ni_chan->ic_flags & IEEE80211_CHAN_40MHZ) &&
+           ieee80211_node_supports_ht_chan40(ni)) {
+               if (ni->ni_flags & IEEE80211_NODE_HT_SGI40)
+                       return 1;
+       } else if (ni->ni_flags & IEEE80211_NODE_HT_SGI20)
+               return 1;
+       
+       return 0;
+}
+
 /*
  * Update goodput statistics.
  */
 
 uint64_t
-ieee80211_ra_get_txrate(int mcs, int sgi20)
+ieee80211_ra_get_txrate(int mcs, int chan40, int sgi)
 {
        const struct ieee80211_ht_rateset *rs;
        uint64_t txrate;
 
-       rs = ieee80211_ra_get_ht_rateset(mcs, sgi20);
+       rs = ieee80211_ra_get_ht_rateset(mcs, chan40, sgi);
        txrate = rs->rates[mcs - rs->min_mcs];
        txrate <<= RA_FP_SHIFT; /* convert to fixed-point */
        txrate *= 500; /* convert to kbit/s */
@@ -160,9 +172,9 @@ ieee80211_ra_next_lower_intra_rate(struct ieee80211_ra_node *rn,
 {
        const struct ieee80211_ht_rateset *rs;
        int i, next;
-       int sgi20 = (ni->ni_flags & IEEE80211_NODE_HT_SGI20) ? 1 : 0;
 
-       rs = ieee80211_ra_get_ht_rateset(ni->ni_txmcs, sgi20);
+       rs = ieee80211_ra_get_ht_rateset(ni->ni_txmcs,
+           ieee80211_node_supports_ht_chan40(ni), ieee80211_ra_use_ht_sgi(ni));
        if (ni->ni_txmcs == rs->min_mcs)
                return rs->min_mcs;
 
@@ -185,9 +197,9 @@ ieee80211_ra_next_intra_rate(struct ieee80211_ra_node *rn,
 {
        const struct ieee80211_ht_rateset *rs;
        int i, next;
-       int sgi20 = (ni->ni_flags & IEEE80211_NODE_HT_SGI20) ? 1 : 0;
 
-       rs = ieee80211_ra_get_ht_rateset(ni->ni_txmcs, sgi20);
+       rs = ieee80211_ra_get_ht_rateset(ni->ni_txmcs,
+           ieee80211_node_supports_ht_chan40(ni), ieee80211_ra_use_ht_sgi(ni));
        if (ni->ni_txmcs == rs->max_mcs)
                return rs->max_mcs;
 
@@ -210,33 +222,58 @@ ieee80211_ra_next_rateset(struct ieee80211_ra_node *rn,
 {
        const struct ieee80211_ht_rateset *rs, *rsnext;
        int next;
+       int chan40 = ieee80211_node_supports_ht_chan40(ni);
+       int sgi = ieee80211_ra_use_ht_sgi(ni);
        int mcs = ni->ni_txmcs;
-       int sgi20 = (ni->ni_flags & IEEE80211_NODE_HT_SGI20) ? 1 : 0;
 
-       rs = ieee80211_ra_get_ht_rateset(mcs, sgi20);
+       rs = ieee80211_ra_get_ht_rateset(mcs, chan40, sgi);
        if (rn->probing & IEEE80211_RA_PROBING_UP) {
-               if (rs->max_mcs == 7)   /* MCS 0-7 */
-                       next = sgi20 ? IEEE80211_HT_RATESET_MIMO2_SGI :
-                           IEEE80211_HT_RATESET_MIMO2;
-               else if (rs->max_mcs == 15)     /* MCS 8-15 */
-                       next = sgi20 ? IEEE80211_HT_RATESET_MIMO3_SGI :
-                           IEEE80211_HT_RATESET_MIMO3;
-               else if (rs->max_mcs == 23)     /* MCS 16-23 */
-                       next = sgi20 ? IEEE80211_HT_RATESET_MIMO4_SGI :
-                           IEEE80211_HT_RATESET_MIMO4;
-               else                            /* MCS 24-31 */
+               if (rs->max_mcs == 7) { /* MCS 0-7 */
+                       if (chan40)
+                               next = sgi ? IEEE80211_HT_RATESET_MIMO2_SGI40 :
+                                   IEEE80211_HT_RATESET_MIMO2_40;
+                       else
+                               next = sgi ? IEEE80211_HT_RATESET_MIMO2_SGI :
+                                   IEEE80211_HT_RATESET_MIMO2;
+               } else if (rs->max_mcs == 15) { /* MCS 8-15 */
+                       if (chan40)
+                               next = sgi ? IEEE80211_HT_RATESET_MIMO3_SGI40 :
+                                   IEEE80211_HT_RATESET_MIMO3_40;
+                       else
+                               next = sgi ? IEEE80211_HT_RATESET_MIMO3_SGI :
+                                   IEEE80211_HT_RATESET_MIMO3;
+               } else if (rs->max_mcs == 23) { /* MCS 16-23 */
+                       if (chan40)
+                               next = sgi ? IEEE80211_HT_RATESET_MIMO4_SGI40 :
+                                   IEEE80211_HT_RATESET_MIMO4_40;
+                       else
+                               next = sgi ? IEEE80211_HT_RATESET_MIMO4_SGI :
+                                   IEEE80211_HT_RATESET_MIMO4;
+               } else                          /* MCS 24-31 */
                        return NULL;
        } else if (rn->probing & IEEE80211_RA_PROBING_DOWN) {
-               if (rs->min_mcs == 24)  /* MCS 24-31 */
-                       next = sgi20 ? IEEE80211_HT_RATESET_MIMO3_SGI :
-                           IEEE80211_HT_RATESET_MIMO3;
-               else if (rs->min_mcs == 16)     /* MCS 16-23 */
-                       next = sgi20 ? IEEE80211_HT_RATESET_MIMO2_SGI :
-                           IEEE80211_HT_RATESET_MIMO2;
-               else if (rs->min_mcs == 8)      /* MCS 8-15 */
-                       next = sgi20 ? IEEE80211_HT_RATESET_SISO_SGI :
-                           IEEE80211_HT_RATESET_SISO;
-               else                            /* MCS 0-7 */
+               if (rs->min_mcs == 24) {        /* MCS 24-31 */
+                       if (chan40)
+                               next = sgi ? IEEE80211_HT_RATESET_MIMO3_SGI40 :
+                                   IEEE80211_HT_RATESET_MIMO3_40;
+                       else
+                               next = sgi ? IEEE80211_HT_RATESET_MIMO3_SGI :
+                                   IEEE80211_HT_RATESET_MIMO3;
+               } else if (rs->min_mcs == 16) { /* MCS 16-23 */
+                       if (chan40)
+                               next = sgi ? IEEE80211_HT_RATESET_MIMO2_SGI40 :
+                                   IEEE80211_HT_RATESET_MIMO2_40;
+                       else
+                               next = sgi ? IEEE80211_HT_RATESET_MIMO2_SGI :
+                                   IEEE80211_HT_RATESET_MIMO2;
+               } else if (rs->min_mcs == 8) {  /* MCS 8-15 */
+                       if (chan40)
+                               next = sgi ? IEEE80211_HT_RATESET_SISO_SGI40 :
+                                   IEEE80211_HT_RATESET_SISO_40;
+                       else
+                               next = sgi ? IEEE80211_HT_RATESET_SISO_SGI :
+                                   IEEE80211_HT_RATESET_SISO;
+               } else                          /* MCS 0-7 */
                        return NULL;
        } else
                panic("%s: invalid probing mode %d", __func__, rn->probing);
@@ -276,10 +313,10 @@ ieee80211_ra_probe_next_rateset(struct ieee80211_ra_node *rn,
        const struct ieee80211_ht_rateset *rs;
        struct ieee80211_ra_goodput_stats *g;
        int best_mcs, i;
-       int sgi20 = (ni->ni_flags & IEEE80211_NODE_HT_SGI20) ? 1 : 0;
 
        /* Find most recently measured best MCS from the current rateset. */
-       rs = ieee80211_ra_get_ht_rateset(ni->ni_txmcs, sgi20);
+       rs = ieee80211_ra_get_ht_rateset(ni->ni_txmcs,
+           ieee80211_node_supports_ht_chan40(ni), ieee80211_ra_use_ht_sgi(ni));
        best_mcs = ieee80211_ra_best_mcs_in_rateset(rn, rs);
 
        /* Switch to the next rateset. */
@@ -365,12 +402,13 @@ ieee80211_ra_intra_mode_ra_finished(struct ieee80211_ra_node *rn,
        struct ieee80211_ra_goodput_stats *g = &rn->g[ni->ni_txmcs];
        int next_mcs, best_mcs;
        uint64_t next_rate;
-       int sgi20 = (ni->ni_flags & IEEE80211_NODE_HT_SGI20) ? 1 : 0;
+       int chan40 = ieee80211_node_supports_ht_chan40(ni);
+       int sgi = ieee80211_ra_use_ht_sgi(ni);
 
        rn->probed_rates = (rn->probed_rates | (1 << ni->ni_txmcs));
 
        /* Check if the min/max MCS in this rateset has been probed. */
-       rs = ieee80211_ra_get_ht_rateset(ni->ni_txmcs, sgi20);
+       rs = ieee80211_ra_get_ht_rateset(ni->ni_txmcs, chan40, sgi);
        if (rn->probing & IEEE80211_RA_PROBING_DOWN) {
                if (ni->ni_txmcs == rs->min_mcs ||
                    rn->probed_rates & (1 << rs->min_mcs)) {
@@ -394,7 +432,7 @@ ieee80211_ra_intra_mode_ra_finished(struct ieee80211_ra_node *rn,
                ieee80211_ra_trigger_next_rateset(rn, ni);
                return 1;
        }
-       next_rate = ieee80211_ra_get_txrate(next_mcs, sgi20);
+       next_rate = ieee80211_ra_get_txrate(next_mcs, chan40, sgi);
        if (g->loss == 0 &&
            g->measured >= next_rate + IEEE80211_RA_RATE_THRESHOLD) {
                ieee80211_ra_trigger_next_rateset(rn, ni);
@@ -544,7 +582,7 @@ ieee80211_ra_add_stats_ht(struct ieee80211_ra_node *rn,
 {
        static const uint64_t alpha = RA_FP_1 / 8; /* 1/8 = 0.125 */
        static const uint64_t beta =  RA_FP_1 / 4; /* 1/4 = 0.25 */
-       int s, sgi20;
+       int s;
        struct ieee80211_ra_goodput_stats *g;
        uint64_t sfer, rate, delta;
 
@@ -581,8 +619,9 @@ ieee80211_ra_add_stats_ht(struct ieee80211_ra_node *rn,
        g->nprobe_fail = 0;
        g->nprobe_pkts = 0;
 
-       sgi20 = (ni->ni_flags & IEEE80211_NODE_HT_SGI20) ? 1 : 0;
-       rate = ieee80211_ra_get_txrate(mcs, sgi20);
+       rate = ieee80211_ra_get_txrate(mcs,
+           ieee80211_node_supports_ht_chan40(ni),
+           ieee80211_ra_use_ht_sgi(ni));
 
        g->loss = sfer * 100;
        g->measured = RA_FP_MUL(RA_FP_1 - sfer, rate);
@@ -605,7 +644,8 @@ ieee80211_ra_choose(struct ieee80211_ra_node *rn, struct ieee80211com *ic,
 {
        struct ieee80211_ra_goodput_stats *g = &rn->g[ni->ni_txmcs];
        int s;
-       int sgi20 = (ni->ni_flags & IEEE80211_NODE_HT_SGI20) ? 1 : 0;
+       int chan40 = ieee80211_node_supports_ht_chan40(ni);
+       int sgi = ieee80211_ra_use_ht_sgi(ni);
        const struct ieee80211_ht_rateset *rs, *rsnext;
 
        s = splnet();
@@ -635,7 +675,7 @@ ieee80211_ra_choose(struct ieee80211_ra_node *rn, struct ieee80211com *ic,
                rn->valid_probes = 0;
        }
 
-       rs = ieee80211_ra_get_ht_rateset(ni->ni_txmcs, sgi20);
+       rs = ieee80211_ra_get_ht_rateset(ni->ni_txmcs, chan40, sgi);
        if ((g->measured >> RA_FP_SHIFT) == 0LL ||
            (g->average >= 3 * g->stddeviation &&
            g->measured < g->average - 3 * g->stddeviation)) {
index 8c40b30..663ce47 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ieee80211_ra.h,v 1.1 2021/03/12 16:26:27 stsp Exp $   */
+/*     $OpenBSD: ieee80211_ra.h,v 1.2 2021/10/11 09:01:06 stsp Exp $   */
 
 /*
  * Copyright (c) 2021 Christian Ehrhardt <ehrhardt@genua.de>
@@ -74,6 +74,9 @@ void  ieee80211_ra_add_stats_ht(struct ieee80211_ra_node *,
 void   ieee80211_ra_choose(struct ieee80211_ra_node *,
            struct ieee80211com *, struct ieee80211_node *);
 
-/* Get the HT rateset for a particular HT MCS with SGI20 on/off. */
+/* Get the HT rateset for a particular HT MCS with 40MHz and/or SGI on/off. */
 const struct ieee80211_ht_rateset * ieee80211_ra_get_ht_rateset(int mcs,
-           int sgi20);
+           int chan40, int sgi);
+
+/* Check whether SGI should be used. */
+int ieee80211_ra_use_ht_sgi(struct ieee80211_node *);
index c4c2551..a1b9660 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ieee80211_var.h,v 1.105 2021/09/23 15:13:47 stsp Exp $        */
+/*     $OpenBSD: ieee80211_var.h,v 1.106 2021/10/11 09:01:06 stsp Exp $        */
 /*     $NetBSD: ieee80211_var.h,v 1.7 2004/05/06 03:07:10 dyoung Exp $ */
 
 /*-
@@ -134,6 +134,7 @@ struct ieee80211_channel {
 #define IEEE80211_CHAN_XR      0x1000  /* Extended range OFDM channel */
 #define IEEE80211_CHAN_HT      0x2000  /* 11n/HT channel */
 #define IEEE80211_CHAN_VHT     0x4000  /* 11ac/VHT channel */
+#define IEEE80211_CHAN_40MHZ   0x8000  /* use of 40 MHz is allowed */
 
 /*
  * Useful combinations of channel characteristics.