b0ceb00ba034e09faf1518de1d3bc53d0ad19fd8
[librecmc/librecmc.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 @@ -352,129 +352,6 @@ static u32 ath11k_map_fw_reg_flags(u16 r
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 -       /* To be safe, lts use the max cac timeout of both rules */
93 -       new_rule->dfs_cac_ms = max_t(u32, rule1->dfs_cac_ms,
94 -                                    rule2->dfs_cac_ms);
95 -}
96 -
97 -static struct ieee80211_regdomain *
98 -ath11k_regd_intersect(struct ieee80211_regdomain *default_regd,
99 -                     struct ieee80211_regdomain *curr_regd)
100 -{
101 -       u8 num_old_regd_rules, num_curr_regd_rules, num_new_regd_rules;
102 -       struct ieee80211_reg_rule *old_rule, *curr_rule, *new_rule;
103 -       struct ieee80211_regdomain *new_regd = NULL;
104 -       u8 i, j, k;
105 -
106 -       num_old_regd_rules = default_regd->n_reg_rules;
107 -       num_curr_regd_rules = curr_regd->n_reg_rules;
108 -       num_new_regd_rules = 0;
109 -
110 -       /* Find the number of intersecting rules to allocate new regd memory */
111 -       for (i = 0; i < num_old_regd_rules; i++) {
112 -               old_rule = default_regd->reg_rules + i;
113 -               for (j = 0; j < num_curr_regd_rules; j++) {
114 -                       curr_rule = curr_regd->reg_rules + j;
115 -
116 -                       if (ath11k_reg_can_intersect(old_rule, curr_rule))
117 -                               num_new_regd_rules++;
118 -               }
119 -       }
120 -
121 -       if (!num_new_regd_rules)
122 -               return NULL;
123 -
124 -       new_regd = kzalloc(sizeof(*new_regd) + (num_new_regd_rules *
125 -                       sizeof(struct ieee80211_reg_rule)),
126 -                       GFP_ATOMIC);
127 -
128 -       if (!new_regd)
129 -               return NULL;
130 -
131 -       /* We set the new country and dfs region directly and only trim
132 -        * the freq, power, antenna gain by intersecting with the
133 -        * default regdomain. Also MAX of the dfs cac timeout is selected.
134 -        */
135 -       new_regd->n_reg_rules = num_new_regd_rules;
136 -       memcpy(new_regd->alpha2, curr_regd->alpha2, sizeof(new_regd->alpha2));
137 -       new_regd->dfs_region = curr_regd->dfs_region;
138 -       new_rule = new_regd->reg_rules;
139 -
140 -       for (i = 0, k = 0; i < num_old_regd_rules; i++) {
141 -               old_rule = default_regd->reg_rules + i;
142 -               for (j = 0; j < num_curr_regd_rules; j++) {
143 -                       curr_rule = curr_regd->reg_rules + j;
144 -
145 -                       if (ath11k_reg_can_intersect(old_rule, curr_rule))
146 -                               ath11k_reg_intersect_rules(old_rule, curr_rule,
147 -                                                          (new_rule + k++));
148 -               }
149 -       }
150 -       return new_regd;
151 -}
152 -
153  static const char *
154  ath11k_reg_get_regdom_str(enum nl80211_dfs_regions dfs_region)
155  {
156 @@ -609,9 +486,9 @@ ath11k_reg_update_weather_radar_band(str
157  
158  struct ieee80211_regdomain *
159  ath11k_reg_build_regd(struct ath11k_base *ab,
160 -                     struct cur_regulatory_info *reg_info, bool intersect)
161 +                     struct cur_regulatory_info *reg_info)
162  {
163 -       struct ieee80211_regdomain *tmp_regd, *default_regd, *new_regd = NULL;
164 +       struct ieee80211_regdomain *new_regd = NULL;
165         struct cur_reg_rule *reg_rule;
166         u8 i = 0, j = 0, k = 0;
167         u8 num_rules;
168 @@ -628,26 +505,26 @@ ath11k_reg_build_regd(struct ath11k_base
169                 num_rules += reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP];
170  
171         if (!num_rules)
172 -               goto ret;
173 +               return new_regd;
174  
175         /* Add max additional rules to accommodate weather radar band */
176         if (reg_info->dfs_region == ATH11K_DFS_REG_ETSI)
177                 num_rules += 2;
178  
179 -       tmp_regd =  kzalloc(sizeof(*tmp_regd) +
180 +       new_regd =  kzalloc(sizeof(*new_regd) +
181                         (num_rules * sizeof(struct ieee80211_reg_rule)),
182                         GFP_ATOMIC);
183 -       if (!tmp_regd)
184 -               goto ret;
185 +       if (!new_regd)
186 +               return new_regd;
187  
188 -       memcpy(tmp_regd->alpha2, reg_info->alpha2, REG_ALPHA2_LEN + 1);
189 +       memcpy(new_regd->alpha2, reg_info->alpha2, REG_ALPHA2_LEN + 1);
190         memcpy(alpha2, reg_info->alpha2, REG_ALPHA2_LEN + 1);
191         alpha2[2] = '\0';
192 -       tmp_regd->dfs_region = ath11k_map_fw_dfs_region(reg_info->dfs_region);
193 +       new_regd->dfs_region = ath11k_map_fw_dfs_region(reg_info->dfs_region);
194  
195         ath11k_dbg(ab, ATH11K_DBG_REG,
196                    "Country %s, CFG Regdomain %s FW Regdomain %d, num_reg_rules %d\n",
197 -                  alpha2, ath11k_reg_get_regdom_str(tmp_regd->dfs_region),
198 +                  alpha2, ath11k_reg_get_regdom_str(new_regd->dfs_region),
199                    reg_info->dfs_region, num_rules);
200         /* Update reg_rules[] below. Firmware is expected to
201          * send these rules in order(2 GHz rules first and then 5 GHz)
202 @@ -686,7 +563,7 @@ ath11k_reg_build_regd(struct ath11k_base
203  
204                 flags |= ath11k_map_fw_reg_flags(reg_rule->flags);
205  
206 -               ath11k_reg_update_rule(tmp_regd->reg_rules + i,
207 +               ath11k_reg_update_rule(new_regd->reg_rules + i,
208                                        reg_rule->start_freq,
209                                        reg_rule->end_freq, max_bw,
210                                        reg_rule->ant_gain, reg_rule->reg_power,
211 @@ -701,7 +578,7 @@ ath11k_reg_build_regd(struct ath11k_base
212                     reg_info->dfs_region == ATH11K_DFS_REG_ETSI &&
213                     (reg_rule->end_freq > ETSI_WEATHER_RADAR_BAND_LOW &&
214                     reg_rule->start_freq < ETSI_WEATHER_RADAR_BAND_HIGH)){
215 -                       ath11k_reg_update_weather_radar_band(ab, tmp_regd,
216 +                       ath11k_reg_update_weather_radar_band(ab, new_regd,
217                                                              reg_rule, &i,
218                                                              flags, max_bw);
219                         continue;
220 @@ -712,37 +589,20 @@ ath11k_reg_build_regd(struct ath11k_base
221                                    "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d) (%d, %d)\n",
222                                    i + 1, reg_rule->start_freq, reg_rule->end_freq,
223                                    max_bw, reg_rule->ant_gain, reg_rule->reg_power,
224 -                                  tmp_regd->reg_rules[i].dfs_cac_ms, flags,
225 +                                  new_regd->reg_rules[i].dfs_cac_ms, flags,
226                                    reg_rule->psd_flag, reg_rule->psd_eirp);
227                 } else {
228                         ath11k_dbg(ab, ATH11K_DBG_REG,
229                                    "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
230                                    i + 1, reg_rule->start_freq, reg_rule->end_freq,
231                                    max_bw, reg_rule->ant_gain, reg_rule->reg_power,
232 -                                  tmp_regd->reg_rules[i].dfs_cac_ms,
233 +                                  new_regd->reg_rules[i].dfs_cac_ms,
234                                    flags);
235                 }
236         }
237  
238 -       tmp_regd->n_reg_rules = i;
239 -
240 -       if (intersect) {
241 -               default_regd = ab->default_regd[reg_info->phy_id];
242 -
243 -               /* Get a new regd by intersecting the received regd with
244 -                * our default regd.
245 -                */
246 -               new_regd = ath11k_regd_intersect(default_regd, tmp_regd);
247 -               kfree(tmp_regd);
248 -               if (!new_regd) {
249 -                       ath11k_warn(ab, "Unable to create intersected regdomain\n");
250 -                       goto ret;
251 -               }
252 -       } else {
253 -               new_regd = tmp_regd;
254 -       }
255 +       new_regd->n_reg_rules = i;
256  
257 -ret:
258         return new_regd;
259  }
260  
261 --- a/drivers/net/wireless/ath/ath11k/reg.h
262 +++ b/drivers/net/wireless/ath/ath11k/reg.h
263 @@ -30,7 +30,7 @@ void ath11k_reg_free(struct ath11k_base
264  void ath11k_regd_update_work(struct work_struct *work);
265  struct ieee80211_regdomain *
266  ath11k_reg_build_regd(struct ath11k_base *ab,
267 -                     struct cur_regulatory_info *reg_info, bool intersect);
268 +                     struct cur_regulatory_info *reg_info);
269  int ath11k_regd_update(struct ath11k *ar);
270  int ath11k_reg_update_chan_list(struct ath11k *ar, bool wait);
271  #endif
272 --- a/drivers/net/wireless/ath/ath11k/wmi.c
273 +++ b/drivers/net/wireless/ath/ath11k/wmi.c
274 @@ -6996,24 +6996,12 @@ static void ath11k_wmi_htc_tx_complete(s
275                 wake_up(&wmi->tx_ce_desc_wq);
276  }
277  
278 -static bool ath11k_reg_is_world_alpha(char *alpha)
279 -{
280 -       if (alpha[0] == '0' && alpha[1] == '0')
281 -               return true;
282 -
283 -       if (alpha[0] == 'n' && alpha[1] == 'a')
284 -               return true;
285 -
286 -       return false;
287 -}
288 -
289  static int ath11k_reg_chan_list_event(struct ath11k_base *ab,
290                                       struct sk_buff *skb,
291                                       enum wmi_reg_chan_list_cmd_type id)
292  {
293         struct cur_regulatory_info *reg_info = NULL;
294         struct ieee80211_regdomain *regd = NULL;
295 -       bool intersect = false;
296         int ret = 0, pdev_idx, i, j;
297         struct ath11k *ar;
298  
299 @@ -7075,17 +7063,7 @@ static int ath11k_reg_chan_list_event(st
300                     (char *)reg_info->alpha2, 2))
301                 goto mem_free;
302  
303 -       /* Intersect new rules with default regd if a new country setting was
304 -        * requested, i.e a default regd was already set during initialization
305 -        * and the regd coming from this event has a valid country info.
306 -        */
307 -       if (ab->default_regd[pdev_idx] &&
308 -           !ath11k_reg_is_world_alpha((char *)
309 -               ab->default_regd[pdev_idx]->alpha2) &&
310 -           !ath11k_reg_is_world_alpha((char *)reg_info->alpha2))
311 -               intersect = true;
312 -
313 -       regd = ath11k_reg_build_regd(ab, reg_info, intersect);
314 +       regd = ath11k_reg_build_regd(ab, reg_info);
315         if (!regd) {
316                 ath11k_warn(ab, "failed to build regd from reg_info\n");
317                 goto fallback;