From: stsp Date: Mon, 11 Oct 2021 09:01:05 +0000 (+0000) Subject: Add support for 40MHz channels to net80211 RA. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=ca785ca0de2f9df4538828467cfca4ae523641c6;p=openbsd Add support for 40MHz channels to net80211 RA. 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. --- diff --git a/sys/dev/ic/ar5008.c b/sys/dev/ic/ar5008.c index fbf2059a157..e9ff551127c 100644 --- a/sys/dev/ic/ar5008.c +++ b/sys/dev/ic/ar5008.c @@ -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 @@ -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; diff --git a/sys/dev/pci/if_iwm.c b/sys/dev/pci/if_iwm.c index 6a145720d30..77d9c141cb9 100644 --- a/sys/dev/pci/if_iwm.c +++ b/sys/dev/pci/if_iwm.c @@ -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 @@ -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; diff --git a/sys/dev/pci/if_iwn.c b/sys/dev/pci/if_iwn.c index 2870256d837..aff55acd0f1 100644 --- a/sys/dev/pci/if_iwn.c +++ b/sys/dev/pci/if_iwn.c @@ -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 @@ -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; /* diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c index e313d22d1a6..7bb68194dd7 100644 --- a/sys/net80211/ieee80211.c +++ b/sys/net80211/ieee80211.c @@ -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[] = { diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h index 4d4b11d89a3..d8fce4ca1f5 100644 --- a/sys/net80211/ieee80211_node.h +++ b/sys/net80211/ieee80211_node.h @@ -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 *); diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c index 7e53f9eb8e1..41d846d591d 100644 --- a/sys/net80211/ieee80211_proto.c +++ b/sys/net80211/ieee80211_proto.c @@ -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 diff --git a/sys/net80211/ieee80211_ra.c b/sys/net80211/ieee80211_ra.c index 8fa9a4f54c7..13d3351f6fd 100644 --- a/sys/net80211/ieee80211_ra.c +++ b/sys/net80211/ieee80211_ra.c @@ -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 @@ -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)) { diff --git a/sys/net80211/ieee80211_ra.h b/sys/net80211/ieee80211_ra.h index 8c40b304598..663ce470c38 100644 --- a/sys/net80211/ieee80211_ra.h +++ b/sys/net80211/ieee80211_ra.h @@ -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 @@ -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 *); diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h index c4c25512cef..a1b9660670f 100644 --- a/sys/net80211/ieee80211_var.h +++ b/sys/net80211/ieee80211_var.h @@ -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.