diff options
author | Aloka Dixit <quic_alokad@quicinc.com> | 2023-03-13 21:59:16 -0700 |
---|---|---|
committer | Jouni Malinen <j@w1.fi> | 2023-03-17 18:54:50 +0200 |
commit | 7618269ec6fb4b66b31db56b60219cac78b3ad78 (patch) | |
tree | 77fc2d88127485ef044ce56de6de8e8ed021f649 | |
parent | 9102fda31f6e98024253668358ff2ac2df5c3b2f (diff) | |
download | hostap-7618269ec6fb4b66b31db56b60219cac78b3ad78.tar.gz |
EHT: Validate puncturing bitmap
Validate preamble puncturing bitmap.
Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
-rw-r--r-- | src/ap/hw_features.c | 52 | ||||
-rw-r--r-- | src/common/hw_features_common.c | 67 | ||||
-rw-r--r-- | src/common/hw_features_common.h | 1 |
3 files changed, 120 insertions, 0 deletions
diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c index ed5ff41d3..842d9f5ba 100644 --- a/src/ap/hw_features.c +++ b/src/ap/hw_features.c @@ -893,6 +893,55 @@ static int hostapd_is_usable_edmg(struct hostapd_iface *iface) } +static bool hostapd_is_usable_punct_bitmap(struct hostapd_iface *iface) +{ +#ifdef CONFIG_IEEE80211BE + struct hostapd_config *conf = iface->conf; + u8 bw, start_chan; + + if (!conf->punct_bitmap) + return true; + + if (!conf->ieee80211be) { + wpa_printf(MSG_ERROR, + "Currently RU puncturing is supported only if ieee80211be is enabled"); + return false; + } + + if (iface->freq >= 2412 && iface->freq <= 2484) { + wpa_printf(MSG_ERROR, + "RU puncturing not supported in 2.4 GHz"); + return false; + } + + switch (conf->eht_oper_chwidth) { + case 0: + wpa_printf(MSG_ERROR, + "RU puncturing is supported only in 80 MHz and 160 MHz"); + return false; + case 1: + bw = 80; + start_chan = conf->eht_oper_centr_freq_seg0_idx - 6; + break; + case 2: + bw = 160; + start_chan = conf->eht_oper_centr_freq_seg0_idx - 14; + break; + default: + return false; + } + + if (!is_punct_bitmap_valid(bw, (conf->channel - start_chan) / 4, + conf->punct_bitmap)) { + wpa_printf(MSG_ERROR, "Invalid puncturing bitmap"); + return false; + } +#endif /* CONFIG_IEEE80211BE */ + + return true; +} + + static int hostapd_is_usable_chans(struct hostapd_iface *iface) { int secondary_freq; @@ -915,6 +964,9 @@ static int hostapd_is_usable_chans(struct hostapd_iface *iface) if (!hostapd_is_usable_edmg(iface)) return 0; + if (!hostapd_is_usable_punct_bitmap(iface)) + return 0; + if (!iface->conf->secondary_channel) return 1; diff --git a/src/common/hw_features_common.c b/src/common/hw_features_common.c index 6646301df..584c6d275 100644 --- a/src/common/hw_features_common.c +++ b/src/common/hw_features_common.c @@ -876,3 +876,70 @@ int chan_pri_allowed(const struct hostapd_channel_data *chan) return !(chan->flag & HOSTAPD_CHAN_DISABLED) && (chan->allowed_bw & HOSTAPD_CHAN_WIDTH_20); } + + +/* IEEE P802.11be/D3.0, Table 36-30 - Definition of the Punctured Channel + * Information field in the U-SIG for an EHT MU PPDU using non-OFDMA + * transmissions */ +static const u16 punct_bitmap_80[] = { 0xF, 0xE, 0xD, 0xB, 0x7 }; +static const u16 punct_bitmap_160[] = { + 0xFF, 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, + 0x7F, 0xFC, 0xF3, 0xCF, 0x3F +}; +static const u16 punct_bitmap_320[] = { + 0xFFFF, 0xFFFC, 0xFFF3, 0xFFCF, 0xFF3F, 0xFCFF, 0xF3FF, 0xCFFF, + 0x3FFF, 0xFFF0, 0xFF0F, 0xF0FF, 0x0FFF, 0xFFC0, 0xFF30, 0xFCF0, + 0xF3F0, 0xCFF0, 0x3FF0, 0x0FFC, 0x0FF3, 0x0FCF, 0x0F3F, 0x0CFF, + 0x03FF +}; + + +bool is_punct_bitmap_valid(u16 bw, u16 pri_ch_bit_pos, u16 punct_bitmap) +{ + u8 i, count; + u16 bitmap; + const u16 *valid_bitmaps; + + if (!punct_bitmap) /* All channels active */ + return true; + + bitmap = ~punct_bitmap; + + switch (bw) { + case 80: + bitmap &= 0xF; + valid_bitmaps = punct_bitmap_80; + count = ARRAY_SIZE(punct_bitmap_80); + break; + + case 160: + bitmap &= 0xFF; + valid_bitmaps = punct_bitmap_160; + count = ARRAY_SIZE(punct_bitmap_160); + break; + + case 320: + bitmap &= 0xFFFF; + valid_bitmaps = punct_bitmap_320; + count = ARRAY_SIZE(punct_bitmap_320); + break; + + default: + return false; + } + + if (!bitmap) /* No channel active */ + return false; + + if (!(bitmap & BIT(pri_ch_bit_pos))) { + wpa_printf(MSG_DEBUG, "Primary channel cannot be punctured"); + return false; + } + + for (i = 0; i < count; i++) { + if (valid_bitmaps[i] == bitmap) + return true; + } + + return false; +} diff --git a/src/common/hw_features_common.h b/src/common/hw_features_common.h index d8ca16867..82e028238 100644 --- a/src/common/hw_features_common.h +++ b/src/common/hw_features_common.h @@ -54,5 +54,6 @@ u32 num_chan_to_bw(int num_chans); int chan_bw_allowed(const struct hostapd_channel_data *chan, u32 bw, int ht40_plus, int pri); int chan_pri_allowed(const struct hostapd_channel_data *chan); +bool is_punct_bitmap_valid(u16 bw, u16 pri_ch_bit_pos, u16 punct_bitmap); #endif /* HW_FEATURES_COMMON_H */ |