blob: 42ff1d2d322725e3f808a4998d199e58a21bd834 [file] [log] [blame]
developer617abbd2024-04-23 14:50:01 +08001From b2078261e779c949218974a054dc52f3dc5493c7 Mon Sep 17 00:00:00 2001
2From: Evelyn Tsai <evelyn.tsai@mediatek.com>
3Date: Wed, 20 Mar 2024 07:20:01 +0800
4Subject: [PATCH 026/104] backport: hostapd: update TPE IE according to AFC
5
6Update Transmit Power Envelope (TPE) IE according to the reply from AFC
7coordinator on UNII-5 or UNII-7 6GHz bands.
8
9Tested-by: Allen Ye <allen.ye@mediatek.com>
10Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
11---
12 src/ap/hostapd.c | 39 +++++++++++++++++++++++++++++++++++++
13 src/ap/hostapd.h | 2 ++
14 src/ap/ieee802_11.c | 47 ++++++++++++++++++++++++++++-----------------
15 3 files changed, 70 insertions(+), 18 deletions(-)
16
17diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
18index 916ac00c4..b899c9831 100644
19--- a/src/ap/hostapd.c
20+++ b/src/ap/hostapd.c
21@@ -4904,6 +4904,45 @@ u16 hostapd_get_punct_bitmap(struct hostapd_data *hapd)
22 }
23
24
25+int hostap_afc_get_chan_max_eirp_power(struct hostapd_iface *iface, bool psd,
26+ int *power)
27+{
28+#ifdef CONFIG_AFC
29+ int i;
30+
31+ if (!he_reg_is_sp(iface->conf->he_6ghz_reg_pwr_type))
32+ return -EINVAL;
33+
34+ if (!iface->afc.data_valid)
35+ return -EINVAL;
36+
37+ if (psd) {
38+ for (i = 0; i < iface->afc.num_freq_range; i++) {
39+ struct afc_freq_range_elem *f;
40+
41+ f = &iface->afc.freq_range[i];
42+ if (iface->freq >= f->low_freq &&
43+ iface->freq <= f->high_freq) {
44+ *power = 2 * f->max_psd;
45+ return 0;
46+ }
47+ }
48+ } else {
49+ for (i = 0; i < iface->afc.num_chan_info; i++) {
50+ struct afc_chan_info_elem *c;
51+
52+ c = &iface->afc.chan_info_list[i];
53+ if (c->chan == iface->conf->channel) {
54+ *power = 2 * c->power;
55+ return 0;
56+ }
57+ }
58+ }
59+#endif /* CONFIG_AFC */
60+ return -EINVAL;
61+}
62+
63+
64 void hostap_afc_disable_channels(struct hostapd_iface *iface)
65 {
66 #ifdef CONFIG_AFC
67diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
68index 18bcb82d9..594866fbb 100644
69--- a/src/ap/hostapd.h
70+++ b/src/ap/hostapd.h
71@@ -729,6 +729,8 @@ struct hostapd_iface {
72 };
73
74 /* hostapd.c */
75+int hostap_afc_get_chan_max_eirp_power(struct hostapd_iface *iface, bool psd,
76+ int *power);
77 void hostap_afc_disable_channels(struct hostapd_iface *iface);
78 int hostapd_afc_handle_request(struct hostapd_iface *iface);
79
80diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
81index 9a23c7240..179af5e28 100644
82--- a/src/ap/ieee802_11.c
83+++ b/src/ap/ieee802_11.c
84@@ -7047,42 +7047,53 @@ u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid)
85 */
86 if (is_6ghz_op_class(iconf->op_class)) {
87 enum max_tx_pwr_interpretation tx_pwr_intrpn;
88+ int err, max_eirp_psd, max_eirp_power;
89
90 /* Same Maximum Transmit Power for all 20 MHz bands */
91 tx_pwr_count = 0;
92 tx_pwr_intrpn = REGULATORY_CLIENT_EIRP_PSD;
93
94 /* Default Transmit Power Envelope for Global Operating Class */
95- if (hapd->iconf->reg_def_cli_eirp_psd != -1)
96- tx_pwr = hapd->iconf->reg_def_cli_eirp_psd;
97- else
98- tx_pwr = REG_PSD_MAX_TXPOWER_FOR_DEFAULT_CLIENT * 2;
99+ err = hostap_afc_get_chan_max_eirp_power(iface, true,
100+ &max_eirp_psd);
101+ if (err < 0) {
102+ if (hapd->iconf->reg_def_cli_eirp_psd != -1)
103+ max_eirp_psd = hapd->iconf->reg_def_cli_eirp_psd;
104+ else
105+ max_eirp_psd = REG_PSD_MAX_TXPOWER_FOR_DEFAULT_CLIENT * 2;
106+ }
107
108 eid = hostapd_add_tpe_info(eid, tx_pwr_count, tx_pwr_intrpn,
109- REG_DEFAULT_CLIENT, tx_pwr);
110+ REG_DEFAULT_CLIENT, max_eirp_psd);
111
112 /* Indoor Access Point must include an additional TPE for
113 * subordinate devices */
114 if (he_reg_is_indoor(iconf->he_6ghz_reg_pwr_type)) {
115- /* TODO: Extract PSD limits from channel data */
116- if (hapd->iconf->reg_sub_cli_eirp_psd != -1)
117- tx_pwr = hapd->iconf->reg_sub_cli_eirp_psd;
118- else
119- tx_pwr = REG_PSD_MAX_TXPOWER_FOR_SUBORDINATE_CLIENT * 2;
120+ if (err < 0) {
121+ /* non-AFC connection */
122+ if (hapd->iconf->reg_sub_cli_eirp_psd != -1)
123+ max_eirp_psd = hapd->iconf->reg_sub_cli_eirp_psd;
124+ else
125+ max_eirp_psd = REG_PSD_MAX_TXPOWER_FOR_SUBORDINATE_CLIENT * 2;
126+ }
127 eid = hostapd_add_tpe_info(eid, tx_pwr_count,
128 tx_pwr_intrpn,
129 REG_SUBORDINATE_CLIENT,
130- tx_pwr);
131+ max_eirp_psd);
132 }
133
134- if (iconf->reg_def_cli_eirp != -1 &&
135- he_reg_is_sp(iconf->he_6ghz_reg_pwr_type))
136- eid = hostapd_add_tpe_info(
137- eid, tx_pwr_count, REGULATORY_CLIENT_EIRP,
138- REG_DEFAULT_CLIENT,
139- hapd->iconf->reg_def_cli_eirp);
140+ if (hostap_afc_get_chan_max_eirp_power(iface, false,
141+ &max_eirp_power)) {
142+ max_eirp_power = iconf->reg_def_cli_eirp;
143+ if (max_eirp_power == -1 ||
144+ !he_reg_is_sp(iconf->he_6ghz_reg_pwr_type))
145+ return eid;
146+ }
147
148- return eid;
149+ return hostapd_add_tpe_info(eid, tx_pwr_count,
150+ REGULATORY_CLIENT_EIRP,
151+ REG_DEFAULT_CLIENT,
152+ max_eirp_power);
153 }
154 #endif /* CONFIG_IEEE80211AX */
155
156--
1572.39.2
158