Files
wlan-ap/feeds/ipq807x_v5.4/hostapd/patches/n00-001-hostapd-add-support-for-6GHz-operation.patch
John Crispin 3b6582117b ipq807x: add ath12 / v5.4 support
Signed-off-by: John Crispin <john@phrozen.org>
2023-04-10 14:25:48 +02:00

565 lines
20 KiB
Diff

From 404211da041eef5ddfc52515048b04c70ef8579c Mon Sep 17 00:00:00 2001
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
Date: Thu, 21 Oct 2021 12:51:38 +0530
Subject: [PATCH] hostapd: add support for 6GHz operation
6 GHz gives users ability to select the AP mode from LPI, SP and
VLP modes. This mode needs to be passed on to the cfg80211
for further processing during AP bring up. Also, the regulatory
rules received by hostapd contains psd values for 6G rules.
Hostapd needs to store these values in order to later advertise
it in the tx power element in the beacon.
This patch adds the support to send the user configured 6g power
type during set_channel command and as well to get and store the
psd values from reg rules which will be later on used in tpe
advertisement during beacon formation.
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
---
src/ap/ap_drv_ops.c | 9 ++++++---
src/ap/beacon.c | 9 +++++++--
src/ap/dfs.c | 6 ++++--
src/ap/hostapd.c | 2 +-
src/ap/ieee802_11.c | 13 ++++++++++++-
src/ap/ieee802_11_he.c | 10 ++++++++--
src/common/hw_features_common.c | 4 +++-
src/common/hw_features_common.h | 2 +-
src/common/ieee802_11_defs.h | 14 ++++++++++++++
src/drivers/driver.h | 20 +++++++++++++++++++-
src/drivers/driver_hostap.c | 3 ++-
src/drivers/driver_nl80211.c | 15 ++++++++++++++-
src/drivers/driver_nl80211.h | 2 +-
src/drivers/driver_nl80211_capa.c | 28 +++++++++++++++++++++++-----
src/drivers/driver_nl80211_event.c | 2 +-
src/drivers/nl80211_copy.h | 19 +++++++++++++++++++
wpa_supplicant/driver_i.h | 2 +-
wpa_supplicant/mesh.c | 2 +-
wpa_supplicant/wpa_supplicant.c | 2 +-
19 files changed, 138 insertions(+), 26 deletions(-)
--- a/src/ap/ap_drv_ops.c
+++ b/src/ap/ap_drv_ops.c
@@ -563,7 +563,8 @@ int hostapd_set_freq(struct hostapd_data
center_segment0, center_segment1,
cmode ? cmode->vht_capab : 0,
cmode ?
- &cmode->he_capab[IEEE80211_MODE_AP] : NULL))
+ &cmode->he_capab[IEEE80211_MODE_AP] : NULL,
+ hapd->iconf->he_6ghz_reg_pwr_type))
return -1;
if (hapd->driver == NULL)
@@ -636,7 +637,8 @@ hostapd_get_hw_feature_data(struct hosta
hapd->driver->get_hw_feature_data == NULL)
return NULL;
return hapd->driver->get_hw_feature_data(hapd->drv_priv, num_modes,
- flags, dfs_domain);
+ flags, dfs_domain,
+ hapd->iconf->he_6ghz_reg_pwr_type);
}
@@ -836,7 +838,8 @@ int hostapd_start_dfs_cac(struct hostapd
oper_chwidth, center_segment0,
center_segment1,
cmode->vht_capab,
- &cmode->he_capab[IEEE80211_MODE_AP])) {
+ &cmode->he_capab[IEEE80211_MODE_AP],
+ hapd->iconf->he_6ghz_reg_pwr_type)) {
wpa_printf(MSG_ERROR, "Can't set freq params");
return -1;
}
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -1571,7 +1571,11 @@ int ieee802_11_build_ap_params(struct ho
if (is_6ghz_op_class(hapd->iconf->op_class)) {
tail_len += sizeof(struct ieee80211_he_6ghz_oper_info) +
3 + sizeof(struct ieee80211_he_6ghz_band_cap);
- /* Additional TX Power envelope for subordinate client */
+ /* Additional TX Power envelope for subordinate client
+ * Currently as per the spec, only AP LP mode should send
+ * the tpe for subordinate client. SP mode should not and
+ * no standard set yet for VLP mode.
+ */
if (hostapd_get_he_6ghz_reg_pwr_type(hapd->iconf) ==
AP_TYPE_6GHZ_INDOOR_AP)
tail_len += 4;
@@ -2012,7 +2016,8 @@ static int __ieee802_11_set_beacon(struc
hostapd_get_oper_centr_freq_seg0_idx(iconf),
hostapd_get_oper_centr_freq_seg1_idx(iconf),
cmode->vht_capab,
- &cmode->he_capab[IEEE80211_MODE_AP]) == 0)
+ &cmode->he_capab[IEEE80211_MODE_AP],
+ iconf->he_6ghz_reg_pwr_type) == 0)
params.freq = &freq;
res = hostapd_drv_set_ap(hapd, &params);
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
@@ -1086,7 +1086,8 @@ static int hostapd_dfs_testmode_set_beac
vht_oper_centr_freq_seg0_idx,
vht_oper_centr_freq_seg1_idx,
iface->current_mode->vht_capab,
- &iface->current_mode->he_capab[IEEE80211_MODE_AP]);
+ &iface->current_mode->he_capab[IEEE80211_MODE_AP],
+ hapd->iconf->he_6ghz_reg_pwr_type);
if (err) {
wpa_printf(MSG_ERROR, "DFS failed to calculate CSA freq params");
@@ -1227,7 +1228,8 @@ static int hostapd_dfs_start_channel_swi
oper_centr_freq_seg0_idx,
oper_centr_freq_seg1_idx,
cmode->vht_capab,
- &cmode->he_capab[ieee80211_mode]);
+ &cmode->he_capab[ieee80211_mode],
+ iface->conf->he_6ghz_reg_pwr_type);
if (err) {
wpa_printf(MSG_ERROR, "DFS failed to calculate CSA freq params");
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -3503,7 +3503,7 @@ static int hostapd_change_config_freq(st
hostapd_get_oper_centr_freq_seg1_idx(conf),
conf->vht_capab,
mode ? &mode->he_capab[IEEE80211_MODE_AP] :
- NULL))
+ NULL, hapd->iconf->he_6ghz_reg_pwr_type))
return -1;
switch (params->bandwidth) {
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -6927,6 +6927,8 @@ u8 * hostapd_eid_txpower_envelope(struct
int dfs, i;
u8 channel, tx_pwr_count, local_pwr_constraint;
u8 tx_pwr, tx_pwr_intrpn, tx_pwr_cat, ap_type;
+ s8 psd;
+
int max_tx_power;
if (!mode)
@@ -6963,15 +6965,24 @@ u8 * hostapd_eid_txpower_envelope(struct
*/
if (ap_type == AP_TYPE_6GHZ_INDOOR_AP) {
tx_pwr_cat = REG_SUBORDINATE_CLIENT;
- /* TODO: extract psd limits from channel data */
+ psd = mode->psd_values[NL80211_REG_SUBORDINATE_CLIENT_LPI + ap_type];
+#ifdef REG_DOM_SUPPORT_TX_POWER
+ tx_pwr = psd * 2;
+#else
tx_pwr = (hostapd_get_6g_tx_power(hapd, ap_type, tx_pwr_cat) * 2);
+#endif /* REG_DOM_SUPPORT_TX_POWER */
eid = hostapd_add_tpe_info(eid, tx_pwr_count, tx_pwr_intrpn,
tx_pwr_cat, tx_pwr);
}
/* Default Tx Power envelope for Global Operating class */
tx_pwr_cat = REG_DEFAULT_CLIENT;
+ psd = mode->psd_values[NL80211_REG_REGULAR_CLIENT_LPI + ap_type];
+#ifdef REG_DOM_SUPPORT_TX_POWER
+ tx_pwr = psd * 2;
+#else
tx_pwr = (hostapd_get_6g_tx_power(hapd, ap_type, tx_pwr_cat) * 2);
+#endif /* REG_DOM_SUPPORT_TX_POWER */
eid = hostapd_add_tpe_info(eid, tx_pwr_count, tx_pwr_intrpn, tx_pwr_cat, tx_pwr);
return eid;
--- a/src/ap/ieee802_11_he.c
+++ b/src/ap/ieee802_11_he.c
@@ -235,10 +235,16 @@ u8 * hostapd_eid_he_operation(struct hos
* - 1 (Standard Power Access Point)
* - Reserved in 5GHz and 2Ghz bands
*/
+
+ u8 ap_type = hostapd_get_he_6ghz_reg_pwr_type(hapd->iconf);
+
if (seg1)
- *pos++ = 3;
+ *pos++ = 3 | (IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO &
+ (ap_type << IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO_LSB));
else
- *pos++ = center_idx_to_bw_6ghz(seg0);
+ *pos++ = center_idx_to_bw_6ghz(seg0) |
+ (IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO &
+ (ap_type << IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO_LSB));
/* Channel Center Freq Seg0/Seg1 */
if (hapd->iconf->he_oper_chwidth == 2) {
--- a/src/common/hw_features_common.c
+++ b/src/common/hw_features_common.c
@@ -403,7 +403,7 @@ int hostapd_set_freq_params(struct hosta
int sec_channel_offset,
int oper_chwidth, int center_segment0,
int center_segment1, u32 vht_caps,
- struct he_capabilities *he_cap)
+ struct he_capabilities *he_cap, u8 reg_6g_pwr_mode)
{
if (!he_cap)
he_enabled = 0;
@@ -486,6 +486,8 @@ int hostapd_set_freq_params(struct hosta
data->ht_enabled = 0;
data->vht_enabled = 0;
+ /* Append 6G reg power info */
+ data->he_6ghz_reg_pwr_type = reg_6g_pwr_mode;
return 0;
}
--- a/src/common/hw_features_common.h
+++ b/src/common/hw_features_common.h
@@ -44,7 +44,7 @@ int hostapd_set_freq_params(struct hosta
int sec_channel_offset,
int oper_chwidth, int center_segment0,
int center_segment1, u32 vht_caps,
- struct he_capabilities *he_caps);
+ struct he_capabilities *he_caps, u8 reg_6g_pwr_mode);
void set_disable_ht40(struct ieee80211_ht_capabilities *htcaps,
int disabled);
int ieee80211ac_cap_check(u32 hw, u32 conf);
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -1963,6 +1963,17 @@ enum reg_6g_client_type {
/* same Max Tx Pwr for all 20MHz bands */
#define DEFAULT_MAX_TX_POWER_COUNT_6G 0
+
+/*
+ * REG_DOM_SUPPORT_TX_POWER - regulatory domain
+ * supports tx power values or not.
+ *
+ * If this macro is undefined, tx-power macros will be used to
+ * get the tx-power, otherwise psd values from regulatory domain
+ * will be taken
+ */
+#define REG_DOM_SUPPORT_TX_POWER 1
+
/*
* These tx-power macros are present till the 6G regdomains are defined to
* support tx-power values for various client types.
@@ -2350,6 +2361,9 @@ struct ieee80211_spatial_reuse {
#define HE_OPERATION_BSS_COLOR_OFFSET 24
#define HE_OPERATION_BSS_COLOR_MAX 64
+#define IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO 0x38
+#define IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO_LSB 3
+
/* Spatial Reuse defines */
#define SPATIAL_REUSE_SRP_DISALLOWED BIT(0)
#define SPATIAL_REUSE_NON_SRG_OBSS_PD_SR_DISALLOWED BIT(1)
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -299,6 +299,12 @@ struct hostapd_hw_modes {
* for IEEE 802.11ay EDMG configuration.
*/
struct ieee80211_edmg_config edmg;
+
+ /**
+ * This array is used to store the psd value of each power mode
+ * supported in 6G band.
+ */
+ s8 psd_values[NL80211_REG_NUM_POWER_MODES];
};
@@ -777,6 +783,17 @@ struct hostapd_freq_params {
* for IEEE 802.11ay EDMG configuration.
*/
struct ieee80211_edmg_config edmg;
+
+ /**
+ * he_6ghz_reg_pwr_type - 6G regulatory power mode
+ * Since many operation related to channel for 6G depends on the
+ * power mode, this parameter is added here.
+ *
+ * 0 - LPI_AP
+ * 1 - SP_AP
+ * 2 - VLP_AP
+ */
+ u8 he_6ghz_reg_pwr_type;
};
/**
@@ -2938,12 +2955,13 @@ struct wpa_driver_ops {
* @num_modes: Variable for returning the number of returned modes
* flags: Variable for returning hardware feature flags
* @dfs: Variable for returning DFS region (HOSTAPD_DFS_REGION_*)
+ * @pwr_mode: Variable required for processing the support data for 6G
* Returns: Pointer to allocated hardware data on success or %NULL on
* failure. Caller is responsible for freeing this.
*/
struct hostapd_hw_modes * (*get_hw_feature_data)(void *priv,
u16 *num_modes,
- u16 *flags, u8 *dfs);
+ u16 *flags, u8 *dfs, u8 pwr_mode);
/**
* send_mlme - Send management frame from MLME
--- a/src/drivers/driver_hostap.c
+++ b/src/drivers/driver_hostap.c
@@ -1099,7 +1099,8 @@ static int hostap_sta_disassoc(void *pri
static struct hostapd_hw_modes * hostap_get_hw_feature_data(void *priv,
u16 *num_modes,
- u16 *flags, u8 *dfs)
+ u16 *flags, u8 *dfs,
+ u8 pwr_mode)
{
struct hostapd_hw_modes *mode;
int i, clen, rlen;
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -5038,6 +5038,19 @@ static int nl80211_set_channel(struct i8
return -1;
}
+#ifdef CONFIG_IEEE80211AX
+ if (freq->freq && is_6ghz_freq(freq->freq)) {
+ wpa_printf(MSG_DEBUG, "%s: 6g_reg_pwr_mode=%d",
+ __func__, freq->he_6ghz_reg_pwr_type);
+ if (nla_put_u8(msg, NL80211_ATTR_6G_REG_POWER_MODE,
+ freq->he_6ghz_reg_pwr_type)) {
+ wpa_printf(MSG_ERROR,
+ "%s: Failed to put 6g_reg_pwr_mode", __func__);
+ nlmsg_free(msg);
+ return -1;
+ }
+ }
+#endif /* CONFIG_IEEE80211AX */
ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
if (ret == 0) {
bss->freq = freq->freq;
@@ -8303,7 +8316,7 @@ static int wpa_driver_nl80211_send_actio
int i;
modes = nl80211_get_hw_feature_data(bss, &num_modes,
- &flags, &dfs_domain);
+ &flags, &dfs_domain, 0);
if (dfs_domain != HOSTAPD_DFS_REGION_ETSI &&
ieee80211_is_dfs(bss->freq, modes, num_modes))
offchanok = 0;
--- a/src/drivers/driver_nl80211.h
+++ b/src/drivers/driver_nl80211.h
@@ -285,7 +285,7 @@ int nl80211_send_monitor(struct wpa_driv
int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv);
struct hostapd_hw_modes *
nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags,
- u8 *dfs_domain);
+ u8 *dfs_domain, u8 pwr_mode);
int process_global_event(struct nl_msg *msg, void *arg);
int process_bss_event(struct nl_msg *msg, void *arg);
--- a/src/drivers/driver_nl80211_capa.c
+++ b/src/drivers/driver_nl80211_capa.c
@@ -1454,6 +1454,7 @@ struct phy_info_arg {
int last_mode, last_chan_idx;
int failed;
u8 dfs_domain;
+ u8 pwr_mode;
};
static void phy_info_ht_capa(struct hostapd_hw_modes *mode, struct nlattr *capa,
@@ -2102,7 +2103,9 @@ static void nl80211_set_ht40_mode_sec(st
static void nl80211_reg_rule_max_eirp(u32 start, u32 end, u32 max_eirp,
- struct phy_info_arg *results)
+ struct phy_info_arg *results,
+ u8 config_pwr_mode, u8 pwr_mode,
+ s8 psd)
{
u16 m;
@@ -2112,10 +2115,16 @@ static void nl80211_reg_rule_max_eirp(u3
for (c = 0; c < mode->num_channels; c++) {
struct hostapd_channel_data *chan = &mode->channels[c];
+
+ if (is_6ghz_freq(chan->freq) && config_pwr_mode != pwr_mode)
+ continue;
+
if ((u32) chan->freq - 10 >= start &&
(u32) chan->freq + 10 <= end)
chan->max_tx_power = max_eirp;
}
+ /* Update the psd rules */
+ mode->psd_values[pwr_mode] = psd;
}
}
@@ -2288,6 +2297,7 @@ static int nl80211_get_reg(struct nl_msg
[NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
};
+ u8 config_pwr_mode = results->pwr_mode;
nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
if (!tb_msg[NL80211_ATTR_REG_ALPHA2] ||
@@ -2312,6 +2322,8 @@ static int nl80211_get_reg(struct nl_msg
nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
{
u32 start, end, max_eirp = 0, max_bw = 0, flags = 0;
+ u8 pwr_mode = 0;
+ s8 psd = 0;
nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
nla_data(nl_rule), nla_len(nl_rule), reg_policy);
if (tb_rule[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
@@ -2325,9 +2337,13 @@ static int nl80211_get_reg(struct nl_msg
max_bw = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
if (tb_rule[NL80211_ATTR_REG_RULE_FLAGS])
flags = nla_get_u32(tb_rule[NL80211_ATTR_REG_RULE_FLAGS]);
+ if (tb_rule[NL80211_ATTR_REG_POWER_MODE])
+ pwr_mode = nla_get_u8(tb_rule[NL80211_ATTR_REG_POWER_MODE]);
+ if (tb_rule[NL80211_ATTR_POWER_RULE_PSD])
+ psd = (s8) nla_get_u8(tb_rule[NL80211_ATTR_POWER_RULE_PSD]);
- wpa_printf(MSG_DEBUG, "nl80211: %u-%u @ %u MHz %u mBm%s%s%s%s%s%s%s%s",
- start, end, max_bw, max_eirp,
+ wpa_printf(MSG_DEBUG, "nl80211: %u-%u @ %u MHz %u mBm pwr_mode: %u psd: %d%s%s%s%s%s%s%s%s",
+ start, end, max_bw, max_eirp, pwr_mode, psd,
flags & NL80211_RRF_NO_OFDM ? " (no OFDM)" : "",
flags & NL80211_RRF_NO_CCK ? " (no CCK)" : "",
flags & NL80211_RRF_NO_INDOOR ? " (no indoor)" : "",
@@ -2341,7 +2357,8 @@ static int nl80211_get_reg(struct nl_msg
nl80211_reg_rule_ht40(start, end, results);
if (tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP])
nl80211_reg_rule_max_eirp(start, end, max_eirp,
- results);
+ results, config_pwr_mode,
+ pwr_mode, psd);
}
nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
@@ -2441,7 +2458,7 @@ static void nl80211_dump_chan_list(struc
struct hostapd_hw_modes *
nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags,
- u8 *dfs_domain)
+ u8 *dfs_domain, u8 pwr_mode)
{
u32 feat;
struct i802_bss *bss = priv;
@@ -2454,6 +2471,7 @@ nl80211_get_hw_feature_data(void *priv,
.last_mode = -1,
.failed = 0,
.dfs_domain = 0,
+ .pwr_mode = pwr_mode
};
*num_modes = 0;
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -1919,7 +1919,7 @@ static unsigned int chan_to_freq(struct
int i;
modes = nl80211_get_hw_feature_data(drv->first_bss, &num_modes,
- &flags, &dfs_domain);
+ &flags, &dfs_domain, 0);
if (!modes) {
wpa_printf(MSG_DEBUG,
"nl80211: Fetching hardware mode failed");
--- a/src/drivers/nl80211_copy.h
+++ b/src/drivers/nl80211_copy.h
@@ -3127,6 +3127,8 @@ enum nl80211_attrs {
NL80211_ATTR_BEACON_TX_MODE,
+ NL80211_ATTR_6G_REG_POWER_MODE,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -3791,6 +3797,20 @@ enum nl80211_band_attr {
#define NL80211_BAND_ATTR_HT_CAPA NL80211_BAND_ATTR_HT_CAPA
+enum nl80211_regulatory_power_modes {
+ NL80211_REG_AP_LPI,
+ NL80211_REG_AP_SP,
+ NL80211_REG_AP_VLP,
+ NL80211_REG_REGULAR_CLIENT_LPI,
+ NL80211_REG_REGULAR_CLIENT_SP,
+ NL80211_REG_REGULAR_CLIENT_VLP,
+ NL80211_REG_SUBORDINATE_CLIENT_LPI,
+ NL80211_REG_SUBORDINATE_CLIENT_SP,
+ NL80211_REG_SUBORDINATE_CLIENT_VLP,
+
+ NL80211_REG_NUM_POWER_MODES,
+};
+
/**
* enum nl80211_wmm_rule - regulatory wmm rule
*
@@ -4015,6 +4035,9 @@ enum nl80211_reg_type {
* a given frequency range. The value is in mBm (100 * dBm).
* @NL80211_ATTR_DFS_CAC_TIME: DFS CAC time in milliseconds.
* If not present or 0 default CAC time will be used.
+ * @NL80211_ATTR_POWER_RULE_PSD: power spectral density (in dBm).
+ * This could be negative.
+ * @NL80211_ATTR_REG_POWER_MODE: the regulatory power mode for 6G rules
* @NL80211_REG_RULE_ATTR_MAX: highest regulatory rule attribute number
* currently defined
* @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use
@@ -4032,6 +4055,10 @@ enum nl80211_reg_rule_attr {
NL80211_ATTR_DFS_CAC_TIME,
+ NL80211_ATTR_POWER_RULE_PSD,
+
+ NL80211_ATTR_REG_POWER_MODE,
+
/* keep last */
__NL80211_REG_RULE_ATTR_AFTER_LAST,
NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -305,7 +305,7 @@ wpa_drv_get_hw_feature_data(struct wpa_s
if (wpa_s->driver->get_hw_feature_data)
return wpa_s->driver->get_hw_feature_data(wpa_s->drv_priv,
num_modes, flags,
- dfs_domain);
+ dfs_domain, 0);
return NULL;
}
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
@@ -231,7 +231,7 @@ static int wpas_mesh_update_freq_params(
hostapd_get_oper_centr_freq_seg0_idx(ifmsh->conf),
hostapd_get_oper_centr_freq_seg1_idx(ifmsh->conf),
ifmsh->conf->vht_capab,
- he_capab)) {
+ he_capab, ifmsh->conf->he_6ghz_reg_pwr_type)) {
wpa_printf(MSG_ERROR, "Error updating mesh frequency params");
wpa_supplicant_mesh_deinit(wpa_s, true);
return -1;
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -2788,7 +2788,7 @@ skip_to_6ghz:
vht_freq.vht_enabled, vht_freq.he_enabled,
freq->sec_channel_offset,
chwidth, seg0, seg1, vht_caps,
- &mode->he_capab[ieee80211_mode]) != 0)
+ &mode->he_capab[ieee80211_mode], 0) != 0)
return;
*freq = vht_freq;
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -3510,6 +3510,15 @@ static int hostapd_config_fill(struct ho
}
} else if (os_strcmp(buf, "he_6ghz_reg_pwr_type") == 0) {
conf->he_6ghz_reg_pwr_type = atoi(pos);
+ if (conf->he_6ghz_reg_pwr_type > AP_TYPE_6GHZ_VERY_LOW_POWER_AP ||
+ conf->he_6ghz_reg_pwr_type < AP_TYPE_6GHZ_INDOOR_AP) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: Invalid 6ghz regulatory power type('%s') "
+ "[min: %d and max: %d]",
+ line, pos, AP_TYPE_6GHZ_INDOOR_AP,
+ AP_TYPE_6GHZ_VERY_LOW_POWER_AP);
+ return 1;
+ }
} else if (os_strcmp(buf, "he_oper_chwidth") == 0) {
conf->he_oper_chwidth = atoi(pos);
} else if (os_strcmp(buf, "he_oper_centr_freq_seg0_idx") == 0) {