From: Pradeep Kumar Chitrapu Date: Thu, 7 Apr 2022 23:56:54 +0000 (-0700) Subject: Add Transmit Power Envelope element in 6 GHz X-Git-Tag: hostap_2_11~2094 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8128ea76af12ec1b148d6900e18328e12085f821;p=thirdparty%2Fhostap.git Add Transmit Power Envelope element in 6 GHz Add Transmit Power Envelope element for 6 GHz per IEEE Std 802.11ax-2021. Currently, this uses hard coded EIRP/PSD limits which are applicable to 6 GHz operation in United states, Japan, and Korea. Support to extract power limits from kernel data will be added after complete regulatory support is added for the 6 GHz band. Signed-off-by: Pradeep Kumar Chitrapu --- diff --git a/src/ap/beacon.c b/src/ap/beacon.c index 5ab44f64e..24ad61c46 100644 --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -497,9 +497,15 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, 3 + sizeof(struct ieee80211_he_operation) + 3 + sizeof(struct ieee80211_he_mu_edca_parameter_set) + 3 + sizeof(struct ieee80211_spatial_reuse); - if (is_6ghz_op_class(hapd->iconf->op_class)) + if (is_6ghz_op_class(hapd->iconf->op_class)) { buflen += sizeof(struct ieee80211_he_6ghz_oper_info) + 3 + sizeof(struct ieee80211_he_6ghz_band_cap); + /* An additional Transmit Power Envelope element for + * subordinate client */ + if (hapd->iconf->he_6ghz_reg_pwr_type == + HE_6GHZ_INDOOR_AP) + buflen += 4; + } } #endif /* CONFIG_IEEE80211AX */ @@ -1353,6 +1359,15 @@ static u8 * hostapd_gen_fils_discovery(struct hostapd_data *hapd, size_t *len) buf_len = pos - buf; total_len += buf_len; +#ifdef CONFIG_IEEE80211AX + /* Transmit Power Envelope element(s) */ + if (is_6ghz_op_class(hapd->iconf->op_class)) { + total_len += 4; + if (hapd->iconf->he_6ghz_reg_pwr_type == HE_6GHZ_INDOOR_AP) + total_len += 4; + } +#endif /* CONFIG_IEEE80211AX */ + head = os_zalloc(total_len); if (!head) return NULL; @@ -1425,6 +1440,9 @@ static u8 * hostapd_gen_fils_discovery(struct hostapd_data *hapd, size_t *len) pos += buf_len; } + if (is_6ghz_op_class(hapd->iconf->op_class)) + pos = hostapd_eid_txpower_envelope(hapd, pos); + *len = pos - (u8 *) head; wpa_hexdump(MSG_DEBUG, "FILS Discovery frame template", head, pos - (u8 *) head); @@ -1499,9 +1517,15 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, 3 + sizeof(struct ieee80211_he_operation) + 3 + sizeof(struct ieee80211_he_mu_edca_parameter_set) + 3 + sizeof(struct ieee80211_spatial_reuse); - if (is_6ghz_op_class(hapd->iconf->op_class)) + 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); + /* An additional Transmit Power Envelope element for + * subordinate client */ + if (hapd->iconf->he_6ghz_reg_pwr_type == + HE_6GHZ_INDOOR_AP) + tail_len += 4; + } } #endif /* CONFIG_IEEE80211AX */ diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index d2b718974..fa5f04318 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -6904,6 +6904,38 @@ void ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src, } +static u8 * hostapd_add_tpe_info(u8 *eid, u8 tx_pwr_count, + enum max_tx_pwr_interpretation tx_pwr_intrpn, + u8 tx_pwr_cat, u8 tx_pwr) +{ + int i; + + *eid++ = WLAN_EID_TRANSMIT_POWER_ENVELOPE; /* Element ID */ + *eid++ = 2 + tx_pwr_count; /* Length */ + + /* + * Transmit Power Information field + * bits 0-2 : Maximum Transmit Power Count + * bits 3-5 : Maximum Transmit Power Interpretation + * bits 6-7 : Maximum Transmit Power Category + */ + *eid++ = tx_pwr_count | (tx_pwr_intrpn << 3) | (tx_pwr_cat << 6); + + /* Maximum Transmit Power field */ + for (i = 0; i <= tx_pwr_count; i++) + *eid++ = tx_pwr; + + return eid; +} + + +/* + * TODO: Extract power limits from channel data after 6G regulatory + * support. + */ +#define REG_PSD_MAX_TXPOWER_FOR_DEFAULT_CLIENT (-1) /* dBm/MHz */ +#define REG_PSD_MAX_TXPOWER_FOR_SUBORDINATE_CLIENT 5 /* dBm/MHz */ + u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid) { struct hostapd_iface *iface = hapd->iface; @@ -6928,6 +6960,43 @@ u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid) if (i == mode->num_channels) return eid; +#ifdef CONFIG_IEEE80211AX + /* IEEE Std 802.11ax-2021, Annex E.2.7 (6 GHz band in the United + * States): An AP that is an Indoor Access Point per regulatory rules + * shall send at least two Transmit Power Envelope elements in Beacon + * and Probe Response frames as follows: + * - Maximum Transmit Power Category subfield = Default; + * Unit interpretation = Regulatory client EIRP PSD + * - Maximum Transmit Power Category subfield = Subordinate Device; + * Unit interpretation = Regulatory client EIRP PSD + */ + if (is_6ghz_op_class(iconf->op_class)) { + enum max_tx_pwr_interpretation tx_pwr_intrpn; + + /* Same Maximum Transmit Power for all 20 MHz bands */ + tx_pwr_count = 0; + tx_pwr_intrpn = REGULATORY_CLIENT_EIRP_PSD; + + /* Default Transmit Power Envelope for Global Operating Class */ + tx_pwr = REG_PSD_MAX_TXPOWER_FOR_DEFAULT_CLIENT * 2; + eid = hostapd_add_tpe_info(eid, tx_pwr_count, tx_pwr_intrpn, + REG_DEFAULT_CLIENT, tx_pwr); + + /* Indoor Access Point must include an additional TPE for + * subordinate devices */ + if (iconf->he_6ghz_reg_pwr_type == HE_6GHZ_INDOOR_AP) { + /* TODO: Extract PSD limits from channel data */ + tx_pwr = REG_PSD_MAX_TXPOWER_FOR_SUBORDINATE_CLIENT * 2; + eid = hostapd_add_tpe_info(eid, tx_pwr_count, + tx_pwr_intrpn, + REG_SUBORDINATE_CLIENT, + tx_pwr); + } + + return eid; + } +#endif /* CONFIG_IEEE80211AX */ + switch (hostapd_get_oper_chwidth(iconf)) { case CHANWIDTH_USE_HT: if (iconf->secondary_channel == 0) { @@ -7000,19 +7069,9 @@ u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid) else tx_pwr = max_tx_power; - *eid++ = WLAN_EID_TRANSMIT_POWER_ENVELOPE; - *eid++ = 2 + tx_pwr_count; - - /* - * Max Transmit Power count and - * Max Transmit Power units = 0 (EIRP) - */ - *eid++ = tx_pwr_count; - - for (i = 0; i <= tx_pwr_count; i++) - *eid++ = tx_pwr; - - return eid; + return hostapd_add_tpe_info(eid, tx_pwr_count, LOCAL_EIRP, + 0 /* Reserved for bands other than 6 GHz */, + tx_pwr); } diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index db41ba1f2..2c85d3fba 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -1947,6 +1947,26 @@ struct tpc_report { u8 link_margin; } STRUCT_PACKED; +/* + * IEEE Std 802.11ax-2021, Table 9-275a - Maximum Transmit Power + * Interpretation subfield encoding + */ +enum max_tx_pwr_interpretation { + LOCAL_EIRP = 0, + LOCAL_EIRP_PSD = 1, + REGULATORY_CLIENT_EIRP = 2, + REGULATORY_CLIENT_EIRP_PSD = 3, +}; + +/* + * IEEE Std 802.11ax-2021, Table E-13 - Maximum Transmit Power + * Category subfield encoding in the United States + */ +enum reg_6g_client_type { + REG_DEFAULT_CLIENT = 0, + REG_SUBORDINATE_CLIENT = 1, +}; + #define RRM_CAPABILITIES_IE_LEN 5 /* IEEE Std 802.11-2012, 8.5.7.4 - Link Measurement Request frame format */