From a17ca92d148721653e76a34e8226a537bfd7cc61 Mon Sep 17 00:00:00 2001 From: kirill Date: Sun, 29 Mar 2026 21:16:21 +0000 Subject: [PATCH] sys/net80211: support of 160Mhz window at 5Ghz OK: kn@, phessler@, stsp@ --- sys/net80211/ieee80211.h | 8 +++- sys/net80211/ieee80211_node.c | 74 +++++++++++++++++++++++++++++------ sys/net80211/ieee80211_node.h | 8 +++- 3 files changed, 75 insertions(+), 15 deletions(-) diff --git a/sys/net80211/ieee80211.h b/sys/net80211/ieee80211.h index 29109c3adbc..b63916f3378 100644 --- a/sys/net80211/ieee80211.h +++ b/sys/net80211/ieee80211.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211.h,v 1.65 2026/03/19 16:50:32 chris Exp $ */ +/* $OpenBSD: ieee80211.h,v 1.66 2026/03/29 21:16:21 kirill Exp $ */ /* $NetBSD: ieee80211.h,v 1.6 2004/04/30 23:51:53 dyoung Exp $ */ /*- @@ -720,7 +720,8 @@ enum { #define IEEE80211_HTOP1_NONGF_STA 0x0004 /* Bit 3 is reserved. */ #define IEEE80211_HTOP1_OBSS_NONHT_STA 0x0010 -/* Bits 5-15 are reserved. */ +#define IEEE80211_HTOP1_CCFS2_SHIFT 5 +#define IEEE80211_HTOP1_CCFS2_MASK 0x1fe0 /* Bytes 4-5. */ /* Bits 0-5 are reserved. */ #define IEEE80211_HTOP2_DUALBEACON 0x0040 @@ -776,6 +777,8 @@ enum { #define IEEE80211_VHTCAP_LINK_ADAPT_MRQ_MFB 3 #define IEEE80211_VHTCAP_RX_ANT_PATTERN 0x10000000 #define IEEE80211_VHTCAP_TX_ANT_PATTERN 0x20000000 +#define IEEE80211_VHTCAP_EXT_NSS_BW_SHIFT 30 +#define IEEE80211_VHTCAP_EXT_NSS_BW_MASK 0xc0000000 /* * VHT-MCS and NSS map (see 802.11ac-2013 8.4.2.160.3, Figure 8-401bs). @@ -792,6 +795,7 @@ enum { #define IEEE80211_VHT_MAX_LGI_MBIT_S_MASK 0x1fff #define IEEE80211_VHT_MAX_LGI_MBIT_S_SHIFT 0 +#define IEEE80211_VHT_EXT_NSS_BW_CAPABLE (1 << 13) /* The highest number of spatial streams supported by VHT. */ #define IEEE80211_VHT_NUM_SS 8 diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c index a557c5c2997..9d3e419ea95 100644 --- a/sys/net80211/ieee80211_node.c +++ b/sys/net80211/ieee80211_node.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_node.c,v 1.212 2026/03/26 12:15:01 kirill Exp $ */ +/* $OpenBSD: ieee80211_node.c,v 1.213 2026/03/29 21:16:21 kirill Exp $ */ /* $NetBSD: ieee80211_node.c,v 1.14 2004/05/09 09:18:47 dyoung Exp $ */ /*- @@ -2536,7 +2536,7 @@ ieee80211_setup_htop(struct ieee80211_node *ni, const uint8_t *data, if (!ieee80211_40mhz_center_freq_valid(data[0], data[1])) ni->ni_htop0 &= ~IEEE80211_HTOP0_SCO_MASK; ni->ni_htop1 = (data[2] | (data[3] << 8)); - ni->ni_htop2 = (data[3] | (data[4] << 8)); + ni->ni_htop2 = (data[4] | (data[5] << 8)); /* * According to 802.11-2012 Table 8-130 the Basic MCS set is @@ -2565,8 +2565,7 @@ ieee80211_setup_vhtcaps(struct ieee80211_node *ni, const uint8_t *data, ni->ni_vht_rx_max_lgi_mbit_s = ((data[6] | (data[7] << 8)) & IEEE80211_VHT_MAX_LGI_MBIT_S_MASK); ni->ni_vht_txmcs = (data[8] | (data[9] << 8)); - ni->ni_vht_tx_max_lgi_mbit_s = ((data[10] | (data[11] << 8)) & - IEEE80211_VHT_MAX_LGI_MBIT_S_MASK); + ni->ni_vht_tx_max_lgi_mbit_s = (data[10] | (data[11] << 8)); ni->ni_flags |= IEEE80211_NODE_VHTCAP; } @@ -2603,8 +2602,8 @@ int ieee80211_setup_vhtop(struct ieee80211_node *ni, const uint8_t *data, uint8_t len, int isprobe) { - uint8_t sco; - int have_40mhz; + uint8_t sco, ccfs0, ccfs1, ccfs2, supp_chwidth, ext_nss_bw_supp; + int have_40mhz, width, ccf1; if (len != 5) return 0; @@ -2621,14 +2620,67 @@ ieee80211_setup_vhtop(struct ieee80211_node *ni, const uint8_t *data, sco == IEEE80211_HTOP0_SCO_SCB); if (have_40mhz && ieee80211_80mhz_center_freq_valid(data[1])) { - ni->ni_vht_chan_width = data[0]; - ni->ni_vht_chan_center_freq_idx0 = data[1]; - - /* Only used in non-consecutive 80-80 160MHz configs. */ + width = data[0]; + ccfs0 = data[1]; if (data[2] && ieee80211_80mhz_center_freq_valid(data[2])) - ni->ni_vht_chan_center_freq_idx1 = data[2]; + ccfs1 = data[2]; else + ccfs1 = 0; + ccfs2 = (ni->ni_htop1 & IEEE80211_HTOP1_CCFS2_MASK) >> + IEEE80211_HTOP1_CCFS2_SHIFT; + if (!ieee80211_80mhz_center_freq_valid(ccfs2)) + ccfs2 = 0; + + supp_chwidth = (ni->ni_vhtcaps & IEEE80211_VHTCAP_CHAN_WIDTH_MASK) >> + IEEE80211_VHTCAP_CHAN_WIDTH_SHIFT; + ext_nss_bw_supp = + (ni->ni_vhtcaps & IEEE80211_VHTCAP_EXT_NSS_BW_MASK) >> + IEEE80211_VHTCAP_EXT_NSS_BW_SHIFT; + + /* See 802.11-2024 Table 9-314 */ + switch ((supp_chwidth << 4) | ext_nss_bw_supp) { + case 0x01: + case 0x02: + case 0x03: + ccf1 = ccfs2; + break; + case 0x10: + ccf1 = ccfs1; + break; + case 0x11: + case 0x12: + if (ccfs1 != 0) + ccf1 = ccfs1; + else + ccf1 = ccfs2; + break; + case 0x13: + case 0x20: + case 0x23: + ccf1 = ccfs1; + break; + default: + ccf1 = 0; + break; + } + + ni->ni_vht_chan_center_freq_idx0 = ccfs0; + ni->ni_vht_chan_center_freq_idx1 = ccfs1; + + if (width == IEEE80211_VHTOP0_CHAN_WIDTH_80 && ccf1 != 0) { + int diff; + + diff = abs(ccf1 - ccfs0); + if (diff == 8) { + ni->ni_vht_chan_center_freq_idx0 = ccf1; + ni->ni_vht_chan_center_freq_idx1 = 0; + width = IEEE80211_VHTOP0_CHAN_WIDTH_160; + } + } else if (width == IEEE80211_VHTOP0_CHAN_WIDTH_160) { ni->ni_vht_chan_center_freq_idx1 = 0; + } + + ni->ni_vht_chan_width = width; } else { ni->ni_vht_chan_width = IEEE80211_VHTOP0_CHAN_WIDTH_HT; ni->ni_vht_chan_center_freq_idx0 = 0; diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h index 411e9d1c188..8efdfdc1aa7 100644 --- a/sys/net80211/ieee80211_node.h +++ b/sys/net80211/ieee80211_node.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_node.h,v 1.100 2026/03/26 12:15:01 kirill Exp $ */ +/* $OpenBSD: ieee80211_node.h,v 1.101 2026/03/29 21:16:21 kirill Exp $ */ /* $NetBSD: ieee80211_node.h,v 1.9 2004/04/30 22:57:32 dyoung Exp $ */ /*- @@ -609,7 +609,11 @@ ieee80211_node_supports_vht_chan160(struct ieee80211_node *ni) cap_chan_width = (ni->ni_vhtcaps & IEEE80211_VHTCAP_CHAN_WIDTH_MASK) >> IEEE80211_VHTCAP_CHAN_WIDTH_SHIFT; - if (cap_chan_width != IEEE80211_VHTCAP_CHAN_WIDTH_160) + if (cap_chan_width != IEEE80211_VHTCAP_CHAN_WIDTH_160 && + cap_chan_width != IEEE80211_VHTCAP_CHAN_WIDTH_160_8080 && + ((ni->ni_vhtcaps & IEEE80211_VHTCAP_EXT_NSS_BW_MASK) == 0 || + (ni->ni_vht_tx_max_lgi_mbit_s & + IEEE80211_VHT_EXT_NSS_BW_CAPABLE) == 0)) return 0; op_chan_width = (ni->ni_vht_chan_width &