EHT: Validate puncturing bitmap

Validate preamble puncturing bitmap.

Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
This commit is contained in:
Aloka Dixit 2023-03-13 21:59:16 -07:00 committed by Jouni Malinen
parent 9102fda31f
commit 7618269ec6
3 changed files with 120 additions and 0 deletions

View file

@ -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;

View file

@ -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;
}

View file

@ -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 */