mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-19 18:31:33 +00:00
311 lines
12 KiB
Diff
311 lines
12 KiB
Diff
From 710e19ab3a32cb29f833de594b07c7a2639b88b9 Mon Sep 17 00:00:00 2001
|
|
From: Aloka Dixit <quic_alokad@quicinc.com>
|
|
Date: Wed, 22 Dec 2021 14:16:01 -0800
|
|
Subject: [PATCH] ru_puncturing: additions to channel switch command
|
|
|
|
Parse the command to retrive the RU puncturing bitmap and if OFDMA
|
|
patterns shouldbe considered.
|
|
|
|
Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
|
|
---
|
|
hostapd/ctrl_iface.c | 37 ++++++++++++++++++++++++++++++
|
|
src/ap/ctrl_iface_ap.c | 3 +++
|
|
src/ap/drv_callbacks.c | 14 +++++++----
|
|
src/ap/hostapd.c | 4 ++++
|
|
src/ap/hostapd.h | 1 +
|
|
src/drivers/driver.h | 2 ++
|
|
src/drivers/driver_nl80211.c | 6 +++--
|
|
src/drivers/driver_nl80211_event.c | 11 +++++++++
|
|
wpa_supplicant/ap.c | 2 +-
|
|
9 files changed, 73 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
|
|
index b758c600166f..124ec9b4b8a5 100644
|
|
--- a/hostapd/ctrl_iface.c
|
|
+++ b/hostapd/ctrl_iface.c
|
|
@@ -33,6 +33,7 @@
|
|
#include "common/version.h"
|
|
#include "common/ieee802_11_defs.h"
|
|
#include "common/ctrl_iface_common.h"
|
|
+#include "common/hw_features_common.h"
|
|
#ifdef CONFIG_DPP
|
|
#include "common/dpp.h"
|
|
#endif /* CONFIG_DPP */
|
|
@@ -2637,6 +2638,7 @@ static int hostapd_ctrl_register_frame(struct hostapd_data *hapd,
|
|
static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params)
|
|
{
|
|
int idx, bw, bw_idx[] = { 20, 40, 80, 160 };
|
|
+ u32 start_freq;
|
|
|
|
if (is_6ghz_freq(params->freq)) {
|
|
/* Verify if HE was enabled by user or not. 6 GHz does not
|
|
@@ -2669,11 +2671,17 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params)
|
|
|
|
if (params->center_freq2 || params->sec_channel_offset)
|
|
return -1;
|
|
+
|
|
+ if (params->ru_punct_bitmap)
|
|
+ return -1;
|
|
break;
|
|
case 40:
|
|
if (params->center_freq2 || !params->sec_channel_offset)
|
|
return -1;
|
|
|
|
+ if (params->ru_punct_bitmap)
|
|
+ return -1;
|
|
+
|
|
if (!params->center_freq1)
|
|
break;
|
|
switch (params->sec_channel_offset) {
|
|
@@ -2708,6 +2716,9 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params)
|
|
return -1;
|
|
}
|
|
|
|
+ if (params->center_freq2 && params->ru_punct_bitmap)
|
|
+ return -1;
|
|
+
|
|
/* Adjacent and overlapped are not allowed for 80+80 */
|
|
if (params->center_freq2 &&
|
|
params->center_freq1 - params->center_freq2 <= 80 &&
|
|
@@ -2742,6 +2753,32 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params)
|
|
return -1;
|
|
}
|
|
|
|
+ if (!params->ru_punct_bitmap) {
|
|
+ params->ru_punct_ofdma = 0;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ if (!params->eht_enabled) {
|
|
+ wpa_printf(MSG_ERROR,
|
|
+ "Currently RU puncturing is supported only if EHT is enabled");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (params->freq >= 2412 && params->freq <= 2484) {
|
|
+ wpa_printf(MSG_ERROR,
|
|
+ "RU puncturing not supported in 2.4 GHz");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ start_freq = params->center_freq1 - (params->bandwidth / 2);
|
|
+ if (is_ru_punct_bitmap_valid(params->bandwidth,
|
|
+ (params->freq - start_freq) / 20,
|
|
+ params->ru_punct_bitmap,
|
|
+ params->ru_punct_ofdma) == false) {
|
|
+ wpa_printf(MSG_ERROR, "Invalid RU puncturing bitmap");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
return 0;
|
|
}
|
|
#endif /* NEED_AP_MLME */
|
|
diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
|
|
index f01cac247293..62db2730bd6f 100644
|
|
--- a/src/ap/ctrl_iface_ap.c
|
|
+++ b/src/ap/ctrl_iface_ap.c
|
|
@@ -1266,10 +1266,13 @@ int hostapd_parse_csa_settings(const char *pos,
|
|
SET_CSA_SETTING(center_freq2);
|
|
SET_CSA_SETTING(bandwidth);
|
|
SET_CSA_SETTING(sec_channel_offset);
|
|
+ SET_CSA_SETTING(ru_punct_bitmap);
|
|
settings->freq_params.ht_enabled = !!os_strstr(pos, " ht");
|
|
settings->freq_params.vht_enabled = !!os_strstr(pos, " vht");
|
|
settings->freq_params.he_enabled = !!os_strstr(pos, " he");
|
|
settings->freq_params.eht_enabled = !!os_strstr(pos, " eht");
|
|
+ settings->freq_params.ru_punct_ofdma = !!os_strstr(pos,
|
|
+ " ru_punct_ofdma");
|
|
settings->block_tx = !!os_strstr(pos, " blocktx");
|
|
#undef SET_CSA_SETTING
|
|
|
|
diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
|
|
index a02d4a9faad5..85636fe111d0 100644
|
|
--- a/src/ap/drv_callbacks.c
|
|
+++ b/src/ap/drv_callbacks.c
|
|
@@ -872,6 +872,7 @@ void hostapd_event_sta_opmode_changed(struct hostapd_data *hapd, const u8 *addr,
|
|
|
|
void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
|
|
int offset, int width, int cf1, int cf2,
|
|
+ u16 ru_punct_bitmap, u8 ru_punct_ofdma,
|
|
int finished)
|
|
{
|
|
#ifdef NEED_AP_MLME
|
|
@@ -881,12 +882,13 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
|
|
|
|
hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
|
|
HOSTAPD_LEVEL_INFO,
|
|
- "driver %s channel switch: freq=%d, ht=%d, vht_ch=0x%x, he_ch=0x%x, eht_ch=0x%x, offset=%d, width=%d (%s), cf1=%d, cf2=%d",
|
|
+ "driver %s channel switch: freq=%d, ht=%d, vht_ch=0x%x, he_ch=0x%x, eht_ch=0x%x, offset=%d, width=%d (%s), cf1=%d, cf2=%d, ru_punct_bitmap=0x%x, ru_punct_ofdma=%u",
|
|
finished ? "had" : "starting",
|
|
freq, ht, hapd->iconf->ch_switch_vht_config,
|
|
hapd->iconf->ch_switch_he_config,
|
|
hapd->iconf->ch_switch_eht_config, offset,
|
|
- width, channel_width_to_string(width), cf1, cf2);
|
|
+ width, channel_width_to_string(width), cf1, cf2,
|
|
+ ru_punct_bitmap, ru_punct_ofdma);
|
|
|
|
if (!hapd->iface->current_mode) {
|
|
hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
|
|
@@ -985,6 +987,8 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
|
|
hostapd_set_oper_centr_freq_seg0_idx(hapd->iconf, seg0_idx);
|
|
hostapd_set_oper_centr_freq_seg1_idx(hapd->iconf, seg1_idx);
|
|
hapd->iconf->op_class = op_class;
|
|
+ hapd->iconf->ru_punct_bitmap = ru_punct_bitmap;
|
|
+ hapd->iconf->ru_punct_ofdma = ru_punct_ofdma;
|
|
if (hapd->iconf->ieee80211ac) {
|
|
hapd->iconf->vht_capab &= ~VHT_CAP_SUPP_CHAN_WIDTH_MASK;
|
|
if (chwidth == CHANWIDTH_160MHZ)
|
|
@@ -999,11 +1003,11 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
|
|
hapd->iface->num_hw_features);
|
|
|
|
wpa_msg(hapd->msg_ctx, MSG_INFO,
|
|
- "%sfreq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d dfs=%d",
|
|
+ "%sfreq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d dfs=%d ru_punct_bitmap=0x%x ru_punct_ofdma=%u",
|
|
finished ? WPA_EVENT_CHANNEL_SWITCH :
|
|
WPA_EVENT_CHANNEL_SWITCH_STARTED,
|
|
freq, ht, offset, channel_width_to_string(width),
|
|
- cf1, cf2, is_dfs);
|
|
+ cf1, cf2, is_dfs, ru_punct_bitmap, ru_punct_ofdma);
|
|
if (!finished)
|
|
return;
|
|
|
|
@@ -2088,6 +2092,8 @@ void hostapd_wpa_event(void *ctx, enum wpa_event_type event,
|
|
data->ch_switch.ch_width,
|
|
data->ch_switch.cf1,
|
|
data->ch_switch.cf2,
|
|
+ data->ch_switch.ru_punct_bitmap,
|
|
+ data->ch_switch.ru_punct_ofdma,
|
|
event == EVENT_CH_SWITCH);
|
|
break;
|
|
case EVENT_CONNECT_FAILED_REASON:
|
|
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
|
|
index becb726c760b..176ad60aacb1 100644
|
|
--- a/src/ap/hostapd.c
|
|
+++ b/src/ap/hostapd.c
|
|
@@ -3577,6 +3577,8 @@ static int hostapd_change_config_freq(struct hostapd_data *hapd,
|
|
conf->ieee80211n = params->ht_enabled;
|
|
conf->ieee80211ac = params->vht_enabled;
|
|
conf->secondary_channel = params->sec_channel_offset;
|
|
+ conf->ru_punct_bitmap = params->ru_punct_bitmap;
|
|
+ conf->ru_punct_ofdma= params->ru_punct_ofdma;
|
|
ieee80211_freq_to_chan(params->center_freq1,
|
|
&seg0);
|
|
ieee80211_freq_to_chan(params->center_freq2,
|
|
@@ -3790,6 +3792,8 @@ hostapd_switch_channel_fallback(struct hostapd_iface *iface,
|
|
hostapd_set_oper_centr_freq_seg0_idx(iface->conf, seg0_idx);
|
|
hostapd_set_oper_centr_freq_seg1_idx(iface->conf, seg1_idx);
|
|
hostapd_set_oper_chwidth(iface->conf, bw);
|
|
+ iface->conf->ru_punct_bitmap = freq_params->ru_punct_bitmap;
|
|
+ iface->conf->ru_punct_ofdma = freq_params->ru_punct_ofdma;
|
|
|
|
/*
|
|
* Resetting operating class to avoid referring previous values
|
|
diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
|
|
index 6cdd2c4e77d5..3841f1b4eb4b 100644
|
|
--- a/src/ap/hostapd.h
|
|
+++ b/src/ap/hostapd.h
|
|
@@ -701,6 +701,7 @@ int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da,
|
|
int ssi_signal);
|
|
void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
|
|
int offset, int width, int cf1, int cf2,
|
|
+ u16 ru_punct_bitmap, u8 ru_punct_ofdma,
|
|
int finished);
|
|
struct survey_results;
|
|
void hostapd_event_get_survey(struct hostapd_iface *iface,
|
|
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
|
|
index 2bed341a60e2..6900d9d39979 100644
|
|
--- a/src/drivers/driver.h
|
|
+++ b/src/drivers/driver.h
|
|
@@ -6086,6 +6086,8 @@ union wpa_event_data {
|
|
enum chan_width ch_width;
|
|
int cf1;
|
|
int cf2;
|
|
+ u16 ru_punct_bitmap;
|
|
+ u8 ru_punct_ofdma;
|
|
} ch_switch;
|
|
|
|
/**
|
|
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
|
|
index 3fbd4eedf0f6..ae8cba4acd5c 100644
|
|
--- a/src/drivers/driver_nl80211.c
|
|
+++ b/src/drivers/driver_nl80211.c
|
|
@@ -9996,7 +9996,7 @@ static int nl80211_switch_channel(void *priv, struct csa_settings *settings)
|
|
int i;
|
|
|
|
wpa_printf(MSG_DEBUG,
|
|
- "nl80211: Channel switch request (cs_count=%u block_tx=%u freq=%d channel=%d sec_channel_offset=%d width=%d cf1=%d cf2=%d%s%s%s)",
|
|
+ "nl80211: Channel switch request (cs_count=%u block_tx=%u freq=%d channel=%d sec_channel_offset=%d width=%d cf1=%d cf2=%d%s%s%s puncturing bitmap=0x%04x, ru_punct_ofdma=%u)",
|
|
settings->cs_count, settings->block_tx,
|
|
settings->freq_params.freq,
|
|
settings->freq_params.channel,
|
|
@@ -10006,7 +10006,9 @@ static int nl80211_switch_channel(void *priv, struct csa_settings *settings)
|
|
settings->freq_params.center_freq2,
|
|
settings->freq_params.ht_enabled ? " ht" : "",
|
|
settings->freq_params.vht_enabled ? " vht" : "",
|
|
- settings->freq_params.he_enabled ? " he" : "");
|
|
+ settings->freq_params.he_enabled ? " he" : "",
|
|
+ settings->freq_params.ru_punct_bitmap,
|
|
+ settings->freq_params.ru_punct_ofdma);
|
|
|
|
if (!(drv->capa.flags & WPA_DRIVER_FLAGS_AP_CSA)) {
|
|
wpa_printf(MSG_DEBUG, "nl80211: Driver does not support channel switch command");
|
|
diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
|
|
index 640b64c9f95c..c0b0efc90d03 100644
|
|
--- a/src/drivers/driver_nl80211_event.c
|
|
+++ b/src/drivers/driver_nl80211_event.c
|
|
@@ -692,6 +692,8 @@ static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
|
|
struct nlattr *ifindex, struct nlattr *freq,
|
|
struct nlattr *type, struct nlattr *bw,
|
|
struct nlattr *cf1, struct nlattr *cf2,
|
|
+ struct nlattr *ru_punct_bitmap,
|
|
+ struct nlattr *ru_punct_ofdma,
|
|
int finished)
|
|
{
|
|
struct i802_bss *bss;
|
|
@@ -753,6 +755,11 @@ static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
|
|
data.ch_switch.cf1 = nla_get_u32(cf1);
|
|
if (cf2)
|
|
data.ch_switch.cf2 = nla_get_u32(cf2);
|
|
+ if (ru_punct_bitmap) {
|
|
+ data.ch_switch.ru_punct_bitmap = nla_get_u16(ru_punct_bitmap);
|
|
+ if (ru_punct_ofdma)
|
|
+ data.ch_switch.ru_punct_ofdma = nla_get_flag(ru_punct_ofdma);
|
|
+ }
|
|
|
|
if (finished)
|
|
bss->freq = data.ch_switch.freq;
|
|
@@ -3110,6 +3117,8 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
|
|
tb[NL80211_ATTR_CHANNEL_WIDTH],
|
|
tb[NL80211_ATTR_CENTER_FREQ1],
|
|
tb[NL80211_ATTR_CENTER_FREQ2],
|
|
+ tb[NL80211_ATTR_RU_PUNCT_BITMAP],
|
|
+ tb[NL80211_ATTR_RU_PUNCT_SUPP_HE],
|
|
0);
|
|
break;
|
|
case NL80211_CMD_CH_SWITCH_NOTIFY:
|
|
@@ -3120,6 +3129,8 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
|
|
tb[NL80211_ATTR_CHANNEL_WIDTH],
|
|
tb[NL80211_ATTR_CENTER_FREQ1],
|
|
tb[NL80211_ATTR_CENTER_FREQ2],
|
|
+ tb[NL80211_ATTR_RU_PUNCT_BITMAP],
|
|
+ tb[NL80211_ATTR_RU_PUNCT_SUPP_HE],
|
|
1);
|
|
break;
|
|
case NL80211_CMD_DISCONNECT:
|
|
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
|
|
index a9d995af7719..4bf2af6a5143 100644
|
|
--- a/wpa_supplicant/ap.c
|
|
+++ b/wpa_supplicant/ap.c
|
|
@@ -1643,7 +1643,7 @@ void wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht,
|
|
if (wpa_s->current_ssid)
|
|
wpa_s->current_ssid->frequency = freq;
|
|
hostapd_event_ch_switch(iface->bss[0], freq, ht,
|
|
- offset, width, cf1, cf2, finished);
|
|
+ offset, width, cf1, cf2, 0, 0, finished);
|
|
}
|
|
|
|
|
|
--
|
|
2.31.1
|
|
|