19f4e7dbe26219b090a276e2b5747c51faab2196
[openwrt/staging/wigyori.git] /
1 From abdd0985a36189ef2cc0e393b027276e86137ace Mon Sep 17 00:00:00 2001
2 From: Aditya Kumar Singh <quic_adisi@quicinc.com>
3 Date: Tue, 11 Apr 2023 20:08:49 +0200
4 Subject: [PATCH] ath11k: remove intersection support for regulatory rules
5
6 Currently, regulatory rules from new country settings is intersected with
7 rules from default country settings(during initialisation) in order to prevent
8 users to bypass their default country settings such as power limits, channel
9 flags, etc.
10
11 However, the country setting in the BDF will take higher higher precendence
12 and FW will protect it. Therefore, there is no need to handle intersection
13 on the driver side now.
14
15 Remove regulatory rules intersection logic support.
16
17 Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
18 ---
19 drivers/net/wireless/ath/ath11k/reg.c | 168 +++-----------------------
20 drivers/net/wireless/ath/ath11k/reg.h | 2 +-
21 drivers/net/wireless/ath/ath11k/wmi.c | 24 +---
22 3 files changed, 16 insertions(+), 178 deletions(-)
23
24 --- a/drivers/net/wireless/ath/ath11k/reg.c
25 +++ b/drivers/net/wireless/ath/ath11k/reg.c
26 @@ -363,134 +363,6 @@ static u32 ath11k_map_fw_phy_flags(u32 p
27 return flags;
28 }
29
30 -static bool
31 -ath11k_reg_can_intersect(struct ieee80211_reg_rule *rule1,
32 - struct ieee80211_reg_rule *rule2)
33 -{
34 - u32 start_freq1, end_freq1;
35 - u32 start_freq2, end_freq2;
36 -
37 - start_freq1 = rule1->freq_range.start_freq_khz;
38 - start_freq2 = rule2->freq_range.start_freq_khz;
39 -
40 - end_freq1 = rule1->freq_range.end_freq_khz;
41 - end_freq2 = rule2->freq_range.end_freq_khz;
42 -
43 - if ((start_freq1 >= start_freq2 &&
44 - start_freq1 < end_freq2) ||
45 - (start_freq2 > start_freq1 &&
46 - start_freq2 < end_freq1))
47 - return true;
48 -
49 - /* TODO: Should we restrict intersection feasibility
50 - * based on min bandwidth of the intersected region also,
51 - * say the intersected rule should have a min bandwidth
52 - * of 20MHz?
53 - */
54 -
55 - return false;
56 -}
57 -
58 -static void ath11k_reg_intersect_rules(struct ieee80211_reg_rule *rule1,
59 - struct ieee80211_reg_rule *rule2,
60 - struct ieee80211_reg_rule *new_rule)
61 -{
62 - u32 start_freq1, end_freq1;
63 - u32 start_freq2, end_freq2;
64 - u32 freq_diff, max_bw;
65 -
66 - start_freq1 = rule1->freq_range.start_freq_khz;
67 - start_freq2 = rule2->freq_range.start_freq_khz;
68 -
69 - end_freq1 = rule1->freq_range.end_freq_khz;
70 - end_freq2 = rule2->freq_range.end_freq_khz;
71 -
72 - new_rule->freq_range.start_freq_khz = max_t(u32, start_freq1,
73 - start_freq2);
74 - new_rule->freq_range.end_freq_khz = min_t(u32, end_freq1, end_freq2);
75 -
76 - freq_diff = new_rule->freq_range.end_freq_khz -
77 - new_rule->freq_range.start_freq_khz;
78 - max_bw = min_t(u32, rule1->freq_range.max_bandwidth_khz,
79 - rule2->freq_range.max_bandwidth_khz);
80 - new_rule->freq_range.max_bandwidth_khz = min_t(u32, max_bw, freq_diff);
81 -
82 - new_rule->power_rule.max_antenna_gain =
83 - min_t(u32, rule1->power_rule.max_antenna_gain,
84 - rule2->power_rule.max_antenna_gain);
85 -
86 - new_rule->power_rule.max_eirp = min_t(u32, rule1->power_rule.max_eirp,
87 - rule2->power_rule.max_eirp);
88 -
89 - /* Use the flags of both the rules */
90 - new_rule->flags = rule1->flags | rule2->flags;
91 -
92 - if ((rule1->flags & NL80211_RRF_PSD) && (rule2->flags & NL80211_RRF_PSD))
93 - new_rule->psd = min_t(s8, rule1->psd, rule2->psd);
94 - else
95 - new_rule->flags &= ~NL80211_RRF_PSD;
96 -
97 - /* To be safe, lts use the max cac timeout of both rules */
98 - new_rule->dfs_cac_ms = max_t(u32, rule1->dfs_cac_ms,
99 - rule2->dfs_cac_ms);
100 -}
101 -
102 -static struct ieee80211_regdomain *
103 -ath11k_regd_intersect(struct ieee80211_regdomain *default_regd,
104 - struct ieee80211_regdomain *curr_regd)
105 -{
106 - u8 num_old_regd_rules, num_curr_regd_rules, num_new_regd_rules;
107 - struct ieee80211_reg_rule *old_rule, *curr_rule, *new_rule;
108 - struct ieee80211_regdomain *new_regd = NULL;
109 - u8 i, j, k;
110 -
111 - num_old_regd_rules = default_regd->n_reg_rules;
112 - num_curr_regd_rules = curr_regd->n_reg_rules;
113 - num_new_regd_rules = 0;
114 -
115 - /* Find the number of intersecting rules to allocate new regd memory */
116 - for (i = 0; i < num_old_regd_rules; i++) {
117 - old_rule = default_regd->reg_rules + i;
118 - for (j = 0; j < num_curr_regd_rules; j++) {
119 - curr_rule = curr_regd->reg_rules + j;
120 -
121 - if (ath11k_reg_can_intersect(old_rule, curr_rule))
122 - num_new_regd_rules++;
123 - }
124 - }
125 -
126 - if (!num_new_regd_rules)
127 - return NULL;
128 -
129 - new_regd = kzalloc(sizeof(*new_regd) + (num_new_regd_rules *
130 - sizeof(struct ieee80211_reg_rule)),
131 - GFP_ATOMIC);
132 -
133 - if (!new_regd)
134 - return NULL;
135 -
136 - /* We set the new country and dfs region directly and only trim
137 - * the freq, power, antenna gain by intersecting with the
138 - * default regdomain. Also MAX of the dfs cac timeout is selected.
139 - */
140 - new_regd->n_reg_rules = num_new_regd_rules;
141 - memcpy(new_regd->alpha2, curr_regd->alpha2, sizeof(new_regd->alpha2));
142 - new_regd->dfs_region = curr_regd->dfs_region;
143 - new_rule = new_regd->reg_rules;
144 -
145 - for (i = 0, k = 0; i < num_old_regd_rules; i++) {
146 - old_rule = default_regd->reg_rules + i;
147 - for (j = 0; j < num_curr_regd_rules; j++) {
148 - curr_rule = curr_regd->reg_rules + j;
149 -
150 - if (ath11k_reg_can_intersect(old_rule, curr_rule))
151 - ath11k_reg_intersect_rules(old_rule, curr_rule,
152 - (new_rule + k++));
153 - }
154 - }
155 - return new_regd;
156 -}
157 -
158 static const char *
159 ath11k_reg_get_regdom_str(enum nl80211_dfs_regions dfs_region)
160 {
161 @@ -641,11 +513,11 @@ ath11k_reg_ap_pwr_convert(enum ieee80211
162
163 struct ieee80211_regdomain *
164 ath11k_reg_build_regd(struct ath11k_base *ab,
165 - struct cur_regulatory_info *reg_info, bool intersect,
166 + struct cur_regulatory_info *reg_info,
167 enum wmi_vdev_type vdev_type,
168 enum ieee80211_ap_reg_power power_type)
169 {
170 - struct ieee80211_regdomain *tmp_regd, *default_regd, *new_regd = NULL;
171 + struct ieee80211_regdomain *new_regd = NULL;
172 struct cur_reg_rule *reg_rule, *reg_rule_6ghz;
173 u8 i = 0, j = 0, k = 0;
174 u8 num_rules;
175 @@ -688,26 +560,26 @@ ath11k_reg_build_regd(struct ath11k_base
176 }
177
178 if (!num_rules)
179 - goto ret;
180 + return new_regd;
181
182 /* Add max additional rules to accommodate weather radar band */
183 if (reg_info->dfs_region == ATH11K_DFS_REG_ETSI)
184 num_rules += 2;
185
186 - tmp_regd = kzalloc(sizeof(*tmp_regd) +
187 + new_regd = kzalloc(sizeof(*new_regd) +
188 (num_rules * sizeof(struct ieee80211_reg_rule)),
189 GFP_ATOMIC);
190 - if (!tmp_regd)
191 - goto ret;
192 + if (!new_regd)
193 + return new_regd;
194
195 - memcpy(tmp_regd->alpha2, reg_info->alpha2, REG_ALPHA2_LEN + 1);
196 + memcpy(new_regd->alpha2, reg_info->alpha2, REG_ALPHA2_LEN + 1);
197 memcpy(alpha2, reg_info->alpha2, REG_ALPHA2_LEN + 1);
198 alpha2[2] = '\0';
199 - tmp_regd->dfs_region = ath11k_map_fw_dfs_region(reg_info->dfs_region);
200 + new_regd->dfs_region = ath11k_map_fw_dfs_region(reg_info->dfs_region);
201
202 ath11k_dbg(ab, ATH11K_DBG_REG,
203 "Country %s, CFG Regdomain %s FW Regdomain %d, num_reg_rules %d\n",
204 - alpha2, ath11k_reg_get_regdom_str(tmp_regd->dfs_region),
205 + alpha2, ath11k_reg_get_regdom_str(new_regd->dfs_region),
206 reg_info->dfs_region, num_rules);
207 /* Update reg_rules[] below. Firmware is expected to
208 * send these rules in order(2 GHz rules first and then 5 GHz)
209 @@ -746,7 +618,7 @@ ath11k_reg_build_regd(struct ath11k_base
210 flags |= ath11k_map_fw_reg_flags(reg_rule->flags);
211 flags |= ath11k_map_fw_phy_flags(reg_info->phybitmap);
212
213 - ath11k_reg_update_rule(tmp_regd->reg_rules + i,
214 + ath11k_reg_update_rule(new_regd->reg_rules + i,
215 reg_rule->start_freq,
216 reg_rule->end_freq, max_bw,
217 reg_rule->ant_gain, reg_rule->reg_power,
218 @@ -761,7 +633,7 @@ ath11k_reg_build_regd(struct ath11k_base
219 reg_info->dfs_region == ATH11K_DFS_REG_ETSI &&
220 (reg_rule->end_freq > ETSI_WEATHER_RADAR_BAND_LOW &&
221 reg_rule->start_freq < ETSI_WEATHER_RADAR_BAND_HIGH)){
222 - ath11k_reg_update_weather_radar_band(ab, tmp_regd,
223 + ath11k_reg_update_weather_radar_band(ab, new_regd,
224 reg_rule, &i,
225 flags, max_bw);
226 continue;
227 @@ -772,51 +644,23 @@ ath11k_reg_build_regd(struct ath11k_base
228 "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d) (%d, %d)\n",
229 i + 1, reg_rule->start_freq, reg_rule->end_freq,
230 max_bw, reg_rule->ant_gain, reg_rule->reg_power,
231 - tmp_regd->reg_rules[i].dfs_cac_ms, flags,
232 + new_regd->reg_rules[i].dfs_cac_ms, flags,
233 reg_rule->psd_flag, reg_rule->psd_eirp);
234 } else {
235 ath11k_dbg(ab, ATH11K_DBG_REG,
236 "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
237 i + 1, reg_rule->start_freq, reg_rule->end_freq,
238 max_bw, reg_rule->ant_gain, reg_rule->reg_power,
239 - tmp_regd->reg_rules[i].dfs_cac_ms,
240 + new_regd->reg_rules[i].dfs_cac_ms,
241 flags);
242 }
243 }
244
245 - tmp_regd->n_reg_rules = i;
246 + new_regd->n_reg_rules = i;
247
248 - if (intersect) {
249 - default_regd = ab->default_regd[reg_info->phy_id];
250 -
251 - /* Get a new regd by intersecting the received regd with
252 - * our default regd.
253 - */
254 - new_regd = ath11k_regd_intersect(default_regd, tmp_regd);
255 - kfree(tmp_regd);
256 - if (!new_regd) {
257 - ath11k_warn(ab, "Unable to create intersected regdomain\n");
258 - goto ret;
259 - }
260 - } else {
261 - new_regd = tmp_regd;
262 - }
263 -
264 -ret:
265 return new_regd;
266 }
267
268 -static bool ath11k_reg_is_world_alpha(char *alpha)
269 -{
270 - if (alpha[0] == '0' && alpha[1] == '0')
271 - return true;
272 -
273 - if (alpha[0] == 'n' && alpha[1] == 'a')
274 - return true;
275 -
276 - return false;
277 -}
278 -
279 static enum wmi_vdev_type ath11k_reg_get_ar_vdev_type(struct ath11k *ar)
280 {
281 struct ath11k_vif *arvif;
282 @@ -839,7 +683,6 @@ int ath11k_reg_handle_chan_list(struct a
283 enum ieee80211_ap_reg_power power_type)
284 {
285 struct ieee80211_regdomain *regd;
286 - bool intersect = false;
287 int pdev_idx;
288 struct ath11k *ar;
289 enum wmi_vdev_type vdev_type;
290 @@ -891,24 +734,14 @@ int ath11k_reg_handle_chan_list(struct a
291 (char *)reg_info->alpha2, 2))
292 goto retfail;
293
294 - /* Intersect new rules with default regd if a new country setting was
295 - * requested, i.e a default regd was already set during initialization
296 - * and the regd coming from this event has a valid country info.
297 - */
298 - if (ab->default_regd[pdev_idx] &&
299 - !ath11k_reg_is_world_alpha((char *)
300 - ab->default_regd[pdev_idx]->alpha2) &&
301 - !ath11k_reg_is_world_alpha((char *)reg_info->alpha2))
302 - intersect = true;
303 -
304 ar = ab->pdevs[pdev_idx].ar;
305 vdev_type = ath11k_reg_get_ar_vdev_type(ar);
306
307 ath11k_dbg(ab, ATH11K_DBG_WMI,
308 - "wmi handle chan list power type %d vdev type %d intersect %d\n",
309 - power_type, vdev_type, intersect);
310 + "wmi handle chan list power type %d vdev type %d\n",
311 + power_type, vdev_type);
312
313 - regd = ath11k_reg_build_regd(ab, reg_info, intersect, vdev_type, power_type);
314 + regd = ath11k_reg_build_regd(ab, reg_info, vdev_type, power_type);
315 if (!regd) {
316 ath11k_warn(ab, "failed to build regd from reg_info\n");
317 goto fallback;
318 --- a/drivers/net/wireless/ath/ath11k/reg.h
319 +++ b/drivers/net/wireless/ath/ath11k/reg.h
320 @@ -35,7 +35,7 @@ void ath11k_reg_free(struct ath11k_base
321 void ath11k_regd_update_work(struct work_struct *work);
322 struct ieee80211_regdomain *
323 ath11k_reg_build_regd(struct ath11k_base *ab,
324 - struct cur_regulatory_info *reg_info, bool intersect,
325 + struct cur_regulatory_info *reg_info,
326 enum wmi_vdev_type vdev_type,
327 enum ieee80211_ap_reg_power power_type);
328 int ath11k_regd_update(struct ath11k *ar);