diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 7c15ff570..b84107472 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -3685,6 +3685,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, conf->reg_def_cli_eirp_psd = atoi(pos); } else if (os_strcmp(buf, "reg_sub_cli_eirp_psd") == 0) { conf->reg_sub_cli_eirp_psd = atoi(pos); + } else if (os_strcmp(buf, "reg_def_cli_eirp") == 0) { + conf->reg_def_cli_eirp = atoi(pos); } 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) { diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c index a86887930..f53aeae94 100644 --- a/src/ap/ap_config.c +++ b/src/ap/ap_config.c @@ -284,6 +284,7 @@ struct hostapd_config * hostapd_config_defaults(void) conf->he_6ghz_reg_pwr_type = HE_REG_INFO_6GHZ_AP_TYPE_VLP; conf->reg_def_cli_eirp_psd = -1; conf->reg_sub_cli_eirp_psd = -1; + conf->reg_def_cli_eirp = -1; #endif /* CONFIG_IEEE80211AX */ /* The third octet of the country string uses an ASCII space character diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index f145425b7..b5bb2201e 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -1153,6 +1153,15 @@ struct hostapd_config { int reg_def_cli_eirp_psd; int reg_sub_cli_eirp_psd; + /* + * This value should be used when regulatory client EIRP PSD values + * advertised by an AP that is an SP AP or an indoor SP AP are + * insufficient to ensure that regulatory client limits on total EIRP + * are always met for all transmission bandwidths within the bandwidth + * of the AP’s BSS. + */ + int reg_def_cli_eirp; + bool require_he; #endif /* CONFIG_IEEE80211AX */ diff --git a/src/ap/beacon.c b/src/ap/beacon.c index eb7ef6f19..f0ab013d4 100644 --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -624,6 +624,16 @@ static size_t hostapd_probe_resp_elems_len(struct hostapd_data *hapd, hapd->iconf->he_6ghz_reg_pwr_type == HE_REG_INFO_6GHZ_AP_TYPE_INDOOR_SP) buflen += 4; + + /* An additional Transmit Power Envelope element for + * default client with unit interpretation of regulatory + * client EIRP */ + if (hapd->iconf->reg_def_cli_eirp != -1 && + (hapd->iconf->he_6ghz_reg_pwr_type == + HE_REG_INFO_6GHZ_AP_TYPE_SP || + hapd->iconf->he_6ghz_reg_pwr_type == + HE_REG_INFO_6GHZ_AP_TYPE_INDOOR_SP)) + buflen += 4; } } #endif /* CONFIG_IEEE80211AX */ @@ -1937,6 +1947,16 @@ static u8 * hostapd_gen_fils_discovery(struct hostapd_data *hapd, size_t *len) hapd->iconf->he_6ghz_reg_pwr_type == HE_REG_INFO_6GHZ_AP_TYPE_INDOOR_SP) total_len += 4; + + /* An additional Transmit Power Envelope element for + * default client with unit interpretation of regulatory + * client EIRP */ + if (hapd->iconf->reg_def_cli_eirp != -1 && + (hapd->iconf->he_6ghz_reg_pwr_type == + HE_REG_INFO_6GHZ_AP_TYPE_SP || + hapd->iconf->he_6ghz_reg_pwr_type == + HE_REG_INFO_6GHZ_AP_TYPE_INDOOR_SP)) + total_len += 4; } #endif /* CONFIG_IEEE80211AX */ @@ -2104,6 +2124,16 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, hapd->iconf->he_6ghz_reg_pwr_type == HE_REG_INFO_6GHZ_AP_TYPE_INDOOR_SP) tail_len += 4; + + /* An additional Transmit Power Envelope element for + * default client with unit interpretation of regulatory + * client EIRP */ + if (hapd->iconf->reg_def_cli_eirp != -1 && + (hapd->iconf->he_6ghz_reg_pwr_type == + HE_REG_INFO_6GHZ_AP_TYPE_SP || + hapd->iconf->he_6ghz_reg_pwr_type == + HE_REG_INFO_6GHZ_AP_TYPE_INDOOR_SP)) + tail_len += 4; } } #endif /* CONFIG_IEEE80211AX */ diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 8eae9efc7..8f61766a7 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -7092,6 +7092,16 @@ u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid) tx_pwr); } + if (iconf->reg_def_cli_eirp != -1 && + (iconf->he_6ghz_reg_pwr_type == + HE_REG_INFO_6GHZ_AP_TYPE_SP || + iconf->he_6ghz_reg_pwr_type == + HE_REG_INFO_6GHZ_AP_TYPE_INDOOR_SP)) + eid = hostapd_add_tpe_info( + eid, tx_pwr_count, REGULATORY_CLIENT_EIRP, + REG_DEFAULT_CLIENT, + hapd->iconf->reg_def_cli_eirp); + return eid; } #endif /* CONFIG_IEEE80211AX */