1 From: Lorenzo Bianconi <lorenzo@kernel.org>
2 Date: Wed, 7 Feb 2024 00:08:18 +0100
3 Subject: [PATCH] hostapd: update TPE IE according to AFC
5 Update Transmit Power Envelope (TPE) IE according to the reply from AFC
6 coordinator on UNII-5 or UNII-7 6GHz bands.
8 Tested-by: Allen Ye <allen.ye@mediatek.com>
13 @@ -977,3 +977,40 @@ void hostap_afc_disable_channels(struct
14 chan->flag |= HOSTAPD_CHAN_DISABLED;
19 +int hostap_afc_get_chan_max_eirp_power(struct hostapd_iface *iface, bool psd,
24 + if (!he_reg_is_sp(iface->conf->he_6ghz_reg_pwr_type))
27 + if (!iface->afc.data_valid)
31 + for (i = 0; i < iface->afc.num_freq_range; i++) {
32 + struct afc_freq_range_elem *f;
34 + f = &iface->afc.freq_range[i];
35 + if (iface->freq >= f->low_freq &&
36 + iface->freq <= f->high_freq) {
37 + *power = 2 * f->max_psd;
42 + for (i = 0; i < iface->afc.num_chan_info; i++) {
43 + struct afc_chan_info_elem *c;
45 + c = &iface->afc.chan_info_list[i];
46 + if (c->chan == iface->conf->channel) {
47 + *power = 2 * c->power;
54 --- a/src/ap/hostapd.h
55 +++ b/src/ap/hostapd.h
56 @@ -732,10 +732,19 @@ struct hostapd_iface {
60 +int hostap_afc_get_chan_max_eirp_power(struct hostapd_iface *iface, bool psd,
62 int hostapd_afc_handle_request(struct hostapd_iface *iface);
63 void hostapd_afc_stop(struct hostapd_iface *iface);
64 void hostap_afc_disable_channels(struct hostapd_iface *iface);
67 +hostap_afc_get_chan_max_eirp_power(struct hostapd_iface *iface, bool psd,
73 static inline int hostapd_afc_handle_request(struct hostapd_iface *iface)
76 --- a/src/ap/ieee802_11.c
77 +++ b/src/ap/ieee802_11.c
78 @@ -7095,42 +7095,53 @@ u8 * hostapd_eid_txpower_envelope(struct
80 if (is_6ghz_op_class(iconf->op_class)) {
81 enum max_tx_pwr_interpretation tx_pwr_intrpn;
82 + int err, max_eirp_psd, max_eirp_power;
84 /* Same Maximum Transmit Power for all 20 MHz bands */
86 tx_pwr_intrpn = REGULATORY_CLIENT_EIRP_PSD;
88 /* Default Transmit Power Envelope for Global Operating Class */
89 - if (hapd->iconf->reg_def_cli_eirp_psd != -1)
90 - tx_pwr = hapd->iconf->reg_def_cli_eirp_psd;
92 - tx_pwr = REG_PSD_MAX_TXPOWER_FOR_DEFAULT_CLIENT * 2;
93 + err = hostap_afc_get_chan_max_eirp_power(iface, true,
96 + if (hapd->iconf->reg_def_cli_eirp_psd != -1)
97 + max_eirp_psd = hapd->iconf->reg_def_cli_eirp_psd;
99 + max_eirp_psd = REG_PSD_MAX_TXPOWER_FOR_DEFAULT_CLIENT * 2;
102 eid = hostapd_add_tpe_info(eid, tx_pwr_count, tx_pwr_intrpn,
103 - REG_DEFAULT_CLIENT, tx_pwr);
104 + REG_DEFAULT_CLIENT, max_eirp_psd);
106 /* Indoor Access Point must include an additional TPE for
107 * subordinate devices */
108 if (he_reg_is_indoor(iconf->he_6ghz_reg_pwr_type)) {
109 - /* TODO: Extract PSD limits from channel data */
110 - if (hapd->iconf->reg_sub_cli_eirp_psd != -1)
111 - tx_pwr = hapd->iconf->reg_sub_cli_eirp_psd;
113 - tx_pwr = REG_PSD_MAX_TXPOWER_FOR_SUBORDINATE_CLIENT * 2;
115 + /* non-AFC connection */
116 + if (hapd->iconf->reg_sub_cli_eirp_psd != -1)
117 + max_eirp_psd = hapd->iconf->reg_sub_cli_eirp_psd;
119 + max_eirp_psd = REG_PSD_MAX_TXPOWER_FOR_SUBORDINATE_CLIENT * 2;
121 eid = hostapd_add_tpe_info(eid, tx_pwr_count,
123 REG_SUBORDINATE_CLIENT,
128 - if (iconf->reg_def_cli_eirp != -1 &&
129 - he_reg_is_sp(iconf->he_6ghz_reg_pwr_type))
130 - eid = hostapd_add_tpe_info(
131 - eid, tx_pwr_count, REGULATORY_CLIENT_EIRP,
132 - REG_DEFAULT_CLIENT,
133 - hapd->iconf->reg_def_cli_eirp);
134 + if (hostap_afc_get_chan_max_eirp_power(iface, false,
135 + &max_eirp_power)) {
136 + max_eirp_power = iconf->reg_def_cli_eirp;
137 + if (max_eirp_power == -1 ||
138 + !he_reg_is_sp(iconf->he_6ghz_reg_pwr_type))
143 + return hostapd_add_tpe_info(eid, tx_pwr_count,
144 + REGULATORY_CLIENT_EIRP,
145 + REG_DEFAULT_CLIENT,
148 #endif /* CONFIG_IEEE80211AX */