Files
wlan-ap/feeds/qca-wifi-7/hostapd/patches/q02-034-ru_puncturing-add-bitmap-to-EHT-operation-element.patch
John Crispin 68cf54d9f7 qca-wifi-7: update to ath12.5.5
Signed-off-by: John Crispin <john@phrozen.org>
2025-02-27 12:45:52 +01:00

315 lines
9.4 KiB
Diff

From 765ef9735ee87ccb8e58df2d7e3cba53851ac8ef Mon Sep 17 00:00:00 2001
From: Muna Sinada <quic_msinada@quicinc.com>
Date: Wed, 2 Mar 2022 15:32:49 -0800
Subject: [PATCH] ru_puncturing: add bitmap to EHT operation element
Add RU puncturing bitmap to the EHT operation element.
Bits set to 1 indicate that the subchannel is punctured, otherwise
active.
Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
---
hostapd/ctrl_iface.c | 36 +++++++++++++
src/ap/hw_features.c | 64 +++++++++++++++++++++++
src/ap/ieee802_11.c | 73 ++++++++++++++++++++++++++
src/ap/ieee802_11.h | 1 +
src/ap/ieee802_11_eht.c | 27 +++++++++-
src/ap/ieee802_11_he.c | 16 ++++++
src/ap/ieee802_11_vht.c | 7 +++
src/common/hw_features_common.c | 92 +++++++++++++++++++++++++++++++++
src/common/hw_features_common.h | 2 +
src/common/ieee802_11_defs.h | 1 +
10 files changed, 318 insertions(+), 1 deletion(-)
--- a/src/ap/hw_features.c
+++ b/src/ap/hw_features.c
@@ -909,6 +909,61 @@ static int hostapd_is_usable_edmg(struct
return 1;
}
+static int hostapd_is_usable_ru_punct_bitmap(struct hostapd_iface *iface)
+{
+ struct hostapd_config *conf = iface->conf;
+ u8 bw, start_chan;
+
+ if (!conf->ru_punct_bitmap) {
+ conf->ru_punct_ofdma = 0;
+ return 1;
+ }
+
+#ifdef CONFIG_IEEE80211BE
+ if (!conf->ieee80211be) {
+ wpa_printf(MSG_ERROR,
+ "Currently RU puncturing is supported only if ieee80211be is enabled");
+ return 0;
+ }
+
+ if (iface->freq >= 2412 && iface->freq <= 2484) {
+ wpa_printf(MSG_ERROR,
+ "RU puncturing not supported in 2.4 GHz");
+ return 0;
+ }
+
+ switch (conf->eht_oper_chwidth) {
+ case 0:
+ wpa_printf(MSG_ERROR,
+ "RU puncturing is supported only in 80 MHz and 160 MHz");
+ return 0;
+ 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 0;
+ }
+
+ if (is_ru_punct_bitmap_valid(bw,
+ (conf->channel - start_chan) / 4,
+ conf->ru_punct_bitmap,
+ conf->ru_punct_ofdma) == false) {
+ wpa_printf(MSG_ERROR, "Invalid RU puncturing bitmap");
+ return 0;
+ }
+
+ return 1;
+#else
+ wpa_printf(MSG_ERROR,
+ "Currently RU puncturing is supported only if ieee80211be is enabled");
+ return 0;
+#endif /* CONFIG_IEEE80211BE */
+}
static bool hostapd_is_usable_punct_bitmap(struct hostapd_iface *iface)
{
@@ -990,6 +1045,9 @@ static int hostapd_is_usable_chans(struc
if (err <= 0)
return err;
+ if (!hostapd_is_usable_ru_punct_bitmap(iface))
+ return 0;
+
if (!hostapd_is_usable_punct_bitmap(iface))
return 0;
--- a/src/ap/ieee802_11.h
+++ b/src/ap/ieee802_11.h
@@ -233,6 +233,7 @@ u16 copy_sta_eht_capab(struct hostapd_da
enum ieee80211_op_mode opmode,
const u8 *he_capab, size_t he_capab_len,
const u8 *eht_capab, size_t eht_capab_len);
+void ru_punct_update_bw(u16 bitmap, u8 pri_chan, enum oper_chan_width *width, u8 *seg0, u8 *seg1);
size_t hostapd_eid_mbssid_len(struct hostapd_data *hapd, u32 frame_type,
u8 *elem_count, const u8 *known_bss,
size_t known_bss_len, size_t *rnr_len);
--- a/src/ap/ieee802_11_eht.c
+++ b/src/ap/ieee802_11_eht.c
@@ -224,6 +224,12 @@ u8 * hostapd_eid_eht_operation(struct ho
else
chwidth = conf->eht_oper_chwidth;
+ if (hapd->iconf->ru_punct_bitmap && !hapd->iface->ru_punct_supp_bw) {
+ hapd->iconf->ru_punct_bitmap = 0;
+ wpa_printf(MSG_ERROR,
+ "Driver does not support RU puncturing. Setting bitmap to 0");
+ }
+
seg0 = hostapd_get_oper_centr_freq_seg0_idx(conf);
if (!seg0)
seg0 = hapd->iconf->channel;
@@ -239,6 +245,12 @@ u8 * hostapd_eid_eht_operation(struct ho
break;
case CONF_OPER_CHWIDTH_160MHZ:
oper->oper_info.control |= EHT_OPER_CHANNEL_WIDTH_160MHZ;
+ if (hapd->iconf->ru_punct_bitmap &&
+ hapd->iface->ru_punct_supp_bw == CONF_OPER_CHWIDTH_320MHZ) {
+ hapd->iconf->ru_punct_bitmap = 0;
+ wpa_printf(MSG_ERROR,
+ "Driver does not support RU puncturing for bandwidths less than 320 MHz. Setting bitmap to 0");
+ }
seg1 = seg0;
if (hapd->iconf->channel < seg0)
seg0 -= 8;
@@ -249,6 +261,7 @@ u8 * hostapd_eid_eht_operation(struct ho
oper->oper_info.control |= EHT_OPER_CHANNEL_WIDTH_80MHZ;
break;
case CONF_OPER_CHWIDTH_USE_HT:
+ hapd->iconf->ru_punct_bitmap = 0;
if ((is_6ghz_op_class(hapd->iconf->op_class) &&
op_class_to_bandwidth(hapd->iconf->op_class) == 40) ||
hapd->iconf->secondary_channel)
@@ -258,6 +271,7 @@ u8 * hostapd_eid_eht_operation(struct ho
break;
default:
+ hapd->iconf->ru_punct_bitmap = 0;
oper->oper_info.control |= EHT_OPER_CHANNEL_WIDTH_20MHZ;
break;
}
@@ -265,6 +279,11 @@ u8 * hostapd_eid_eht_operation(struct ho
oper->oper_info.ccfs0 = seg0;
oper->oper_info.ccfs1 = seg1;
+ if (hapd->iconf->ru_punct_bitmap) {
+ oper->oper_params |= EHT_OPER_DISABLED_SUBCHAN_BITMAP_PRESENT;
+ oper->oper_info.disabled_chan_bitmap = host_to_le16(hapd->iconf->ru_punct_bitmap);
+ }
+
if (hapd->iconf->punct_bitmap) {
oper->oper_params |= EHT_OPER_DISABLED_SUBCHAN_BITMAP_PRESENT;
oper->oper_info.disabled_chan_bitmap =
--- a/src/ap/ieee802_11_he.c
+++ b/src/ap/ieee802_11_he.c
@@ -234,6 +234,22 @@ u8 * hostapd_eid_he_operation(struct hos
}
#endif /* CONFIG_IEEE80211BE */
+ if (hapd->iconf->ru_punct_bitmap) {
+ hapd->iconf->he_oper_chwidth =
+ hostapd_get_oper_chwidth(hapd->iconf);
+ hapd->iconf->he_oper_centr_freq_seg0_idx = seg0;
+ hapd->iconf->he_oper_centr_freq_seg1_idx = seg1;
+
+ punct_update_legacy_bw(hapd->iconf->ru_punct_bitmap,
+ hapd->iconf->channel,
+ &hapd->iconf->he_oper_chwidth,
+ &hapd->iconf->he_oper_centr_freq_seg0_idx,
+ &hapd->iconf->he_oper_centr_freq_seg1_idx);
+
+ seg0 = hapd->iconf->he_oper_centr_freq_seg0_idx;
+ seg1 = hapd->iconf->he_oper_centr_freq_seg1_idx;
+ }
+
if (!seg0)
seg0 = hapd->iconf->channel;
--- a/src/ap/ieee802_11_vht.c
+++ b/src/ap/ieee802_11_vht.c
@@ -110,6 +110,13 @@ u8 * hostapd_eid_vht_operation(struct ho
}
#endif /* CONFIG_IEEE80211BE */
+ if (hapd->iconf->ru_punct_bitmap)
+ punct_update_legacy_bw(hapd->iconf->ru_punct_bitmap,
+ hapd->iconf->channel,
+ &hapd->iconf->vht_oper_chwidth,
+ &hapd->iconf->vht_oper_centr_freq_seg0_idx,
+ &hapd->iconf->vht_oper_centr_freq_seg1_idx);
+
/*
* center freq = 5 GHz + (5 * index)
* So index 42 gives center freq 5.210 GHz
--- a/src/common/hw_features_common.c
+++ b/src/common/hw_features_common.c
@@ -884,6 +884,96 @@ int chan_pri_allowed(const struct hostap
(chan->allowed_bw & HOSTAPD_CHAN_WIDTH_20);
}
+/* IEEE P802.11be/D1.31, December 2021, Table 36-30 5-bit punctured channel
+ * indication for the non-OFDMA case in an EHT MU PPDU
+ */
+static const u16 ru_punct_bitmap_80[] = {0xF, 0xE, 0xD, 0xB, 0x7};
+static const u16 ru_punct_bitmap_160[] = {0xFF, 0xFE, 0xFD, 0xFB, 0xF7, 0xEF,
+ 0xDF, 0xBF, 0x7F, 0xFC, 0xF3, 0xCF,
+ 0x3F};
+static const u16 ru_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_ru_punct_bitmap_valid(u16 bw, u16 pri_ch_bit_pos, u16 ru_punct_bitmap,
+ u8 ru_punct_ofdma)
+{
+ u8 i, non_ofdma_bitmap_count, ofdma_block_count = 1;
+ u16 bitmap;
+ const u16 *non_ofdma_bitmap;
+
+ if (!ru_punct_bitmap) /* All channels active */
+ return true;
+
+ bitmap = ~ru_punct_bitmap;
+
+ switch (bw) {
+ case 80:
+ bitmap &= 0xF;
+ non_ofdma_bitmap = &ru_punct_bitmap_80[0];
+ non_ofdma_bitmap_count = ARRAY_SIZE(ru_punct_bitmap_80);
+ break;
+
+ case 160:
+ bitmap &= 0xFF;
+ non_ofdma_bitmap = &ru_punct_bitmap_160[0];
+ non_ofdma_bitmap_count = ARRAY_SIZE(ru_punct_bitmap_160);
+ break;
+
+ case 320:
+ bitmap &= 0xFFFF;
+ non_ofdma_bitmap = &ru_punct_bitmap_320[0];
+ non_ofdma_bitmap_count = ARRAY_SIZE(ru_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;
+ }
+
+ /* Check for non-OFDMA puncturing patterns */
+ for (i = 0; i < non_ofdma_bitmap_count; i++)
+ if (non_ofdma_bitmap[i] == bitmap)
+ return true;
+
+ if (!ru_punct_ofdma)
+ return false;
+
+ /* Check for OFDMA puncturing patterns */
+ for (i = 0; i < ofdma_block_count; i++) {
+ switch ((bitmap >> (i * 4)) & 0xF) {
+ /* IEEE P802.11be/D1.31, December 2021, 36.3.12.11.2 Preamble
+ * puncturing for PPDUs in an OFDMA transmission
+ */
+ case 0xF:
+ case 0x7:
+ case 0xB:
+ case 0xD:
+ case 0xE:
+ case 0x3:
+ case 0xC:
+ case 0x9:
+ case 0x0:
+ break;
+ default:
+ return false;
+ }
+ }
+
+ return true;
+}
/* 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
--- a/src/common/hw_features_common.h
+++ b/src/common/hw_features_common.h
@@ -57,5 +57,7 @@ int chan_bw_allowed(const struct hostapd
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);
+bool is_ru_punct_bitmap_valid(u16 bw, u16 pri_ch_bit_pos, u16 ru_punct_bitmap,
+ u8 ru_punct_ofdma);
#endif /* HW_FEATURES_COMMON_H */