summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAloka Dixit <quic_alokad@quicinc.com>2023-03-13 21:59:16 -0700
committerJouni Malinen <j@w1.fi>2023-03-17 18:54:50 +0200
commit7618269ec6fb4b66b31db56b60219cac78b3ad78 (patch)
tree77fc2d88127485ef044ce56de6de8e8ed021f649
parent9102fda31f6e98024253668358ff2ac2df5c3b2f (diff)
downloadhostap-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.c52
-rw-r--r--src/common/hw_features_common.c67
-rw-r--r--src/common/hw_features_common.h1
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 */