1 /*
2 * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for
6 * any purpose with or without fee is hereby granted, provided that the
7 * above copyright notice and this permission notice appear in all
8 * copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 /**
21 * DOC: reg_build_chan_list.c
22 * This file defines the API to build master and current channel list.
23 */
24
25 #include <wlan_cmn.h>
26 #include <reg_services_public_struct.h>
27 #include <wlan_objmgr_psoc_obj.h>
28 #include <wlan_objmgr_pdev_obj.h>
29 #include "reg_priv_objs.h"
30 #include "reg_utils.h"
31 #include "reg_callbacks.h"
32 #include "reg_services_common.h"
33 #include "reg_db.h"
34 #include "reg_db_parser.h"
35 #include "reg_offload_11d_scan.h"
36 #include <scheduler_api.h>
37 #include "reg_build_chan_list.h"
38 #include <qdf_platform.h>
39 #include <wlan_reg_services_api.h>
40 #include <wlan_objmgr_vdev_obj.h>
41
42 #define MAX_PWR_FCC_CHAN_12 8
43 #define MAX_PWR_FCC_CHAN_13 2
44 #define CHAN_144_CENT_FREQ 5720
45
46 /**
47 * reg_init_chan() - Initialize the channel list from the channel_map global
48 * list
49 * @dst_list: list to initialize
50 * @beg_enum: starting point in list(inclusive)
51 * @end_enum: ending point in list(inclusive)
52 * @dst_idx_adj: offset between channel_map and dst_list
53 * @soc_reg: soc private object for regulatory
54 *
55 * Return: none
56 */
reg_init_chan(struct regulatory_channel * dst_list,enum channel_enum beg_enum,enum channel_enum end_enum,uint8_t dst_idx_adj,struct wlan_regulatory_psoc_priv_obj * soc_reg)57 static void reg_init_chan(struct regulatory_channel *dst_list,
58 enum channel_enum beg_enum,
59 enum channel_enum end_enum, uint8_t dst_idx_adj,
60 struct wlan_regulatory_psoc_priv_obj *soc_reg)
61 {
62 enum channel_enum chan_enum;
63 uint8_t dst_idx;
64
65 for (chan_enum = beg_enum; chan_enum <= end_enum; chan_enum++) {
66 dst_idx = chan_enum - dst_idx_adj;
67
68 dst_list[dst_idx].chan_num = channel_map[chan_enum].chan_num;
69 dst_list[dst_idx].center_freq =
70 channel_map[chan_enum].center_freq;
71 dst_list[dst_idx].chan_flags = REGULATORY_CHAN_DISABLED;
72 dst_list[dst_idx].state = CHANNEL_STATE_DISABLE;
73 if (!soc_reg->retain_nol_across_regdmn_update)
74 dst_list[dst_idx].nol_chan = false;
75 }
76 }
77
78 static inline bool
reg_nol_and_history_not_set(struct regulatory_channel * chan)79 reg_nol_and_history_not_set(struct regulatory_channel *chan)
80 {
81 return ((!chan->nol_chan) && (!chan->nol_history));
82 }
83
reg_is_chan_disabled_and_not_nol(struct regulatory_channel * chan)84 bool reg_is_chan_disabled_and_not_nol(struct regulatory_channel *chan)
85 {
86 return (!reg_is_state_allowed(chan->state) &&
87 (chan->chan_flags & REGULATORY_CHAN_DISABLED) &&
88 reg_nol_and_history_not_set(chan));
89 }
90 #ifdef CONFIG_BAND_6GHZ
reg_fill_psd_info(enum channel_enum chan_enum,struct cur_reg_rule * reg_rule,struct regulatory_channel * master_list)91 static void reg_fill_psd_info(enum channel_enum chan_enum,
92 struct cur_reg_rule *reg_rule,
93 struct regulatory_channel *master_list)
94 {
95 master_list[chan_enum].psd_flag = reg_rule->psd_flag;
96
97 master_list[chan_enum].psd_eirp = reg_rule->psd_eirp;
98 }
99
100 /**
101 * reg_init_6ghz_master_chan() - Init 6 GHz channel list
102 * @dst_list: pointer to 6 GHz channel list
103 * @soc_reg: pointer to regulatory psoc private object.
104 *
105 * Return: None
106 */
107 static void
reg_init_6ghz_master_chan(struct regulatory_channel * dst_list,struct wlan_regulatory_psoc_priv_obj * soc_reg)108 reg_init_6ghz_master_chan(struct regulatory_channel *dst_list,
109 struct wlan_regulatory_psoc_priv_obj *soc_reg)
110 {
111 reg_init_chan(dst_list, MIN_6GHZ_CHANNEL, MAX_6GHZ_CHANNEL,
112 MIN_6GHZ_CHANNEL, soc_reg);
113 }
114 #else
reg_fill_psd_info(enum channel_enum chan_enum,struct cur_reg_rule * reg_rule,struct regulatory_channel * master_list)115 static inline void reg_fill_psd_info(enum channel_enum chan_enum,
116 struct cur_reg_rule *reg_rule,
117 struct regulatory_channel *master_list)
118 {
119 }
120
121 static inline void
reg_init_6ghz_master_chan(struct regulatory_channel * dst_list,struct wlan_regulatory_psoc_priv_obj * soc_reg)122 reg_init_6ghz_master_chan(struct regulatory_channel *dst_list,
123 struct wlan_regulatory_psoc_priv_obj *soc_reg)
124 {
125 }
126 #endif
127
128 /**
129 * reg_fill_channel_info() - Populate TX power, antenna gain, channel state,
130 * channel flags, min and max bandwidth to master channel list.
131 * @chan_enum: Channel enum.
132 * @reg_rule: Pointer to regulatory rule which has tx power and antenna gain.
133 * @master_list: Pointer to master channel list.
134 * @min_bw: minimum bandwidth to be used for given channel.
135 */
reg_fill_channel_info(enum channel_enum chan_enum,struct cur_reg_rule * reg_rule,struct regulatory_channel * master_list,uint16_t min_bw)136 static void reg_fill_channel_info(enum channel_enum chan_enum,
137 struct cur_reg_rule *reg_rule,
138 struct regulatory_channel *master_list,
139 uint16_t min_bw)
140 {
141 master_list[chan_enum].chan_flags &= ~REGULATORY_CHAN_DISABLED;
142
143 reg_fill_psd_info(chan_enum, reg_rule, master_list);
144 master_list[chan_enum].tx_power = reg_rule->reg_power;
145 master_list[chan_enum].ant_gain = reg_rule->ant_gain;
146 master_list[chan_enum].state = CHANNEL_STATE_ENABLE;
147
148 if (reg_rule->flags & REGULATORY_CHAN_NO_IR) {
149 master_list[chan_enum].chan_flags |= REGULATORY_CHAN_NO_IR;
150 master_list[chan_enum].state = CHANNEL_STATE_DFS;
151 }
152
153 if (reg_rule->flags & REGULATORY_CHAN_RADAR) {
154 master_list[chan_enum].chan_flags |= REGULATORY_CHAN_RADAR;
155 master_list[chan_enum].state = CHANNEL_STATE_DFS;
156 }
157
158 if (reg_rule->flags & REGULATORY_CHAN_INDOOR_ONLY)
159 master_list[chan_enum].chan_flags |=
160 REGULATORY_CHAN_INDOOR_ONLY;
161
162 if (reg_rule->flags & REGULATORY_CHAN_NO_OFDM)
163 master_list[chan_enum].chan_flags |= REGULATORY_CHAN_NO_OFDM;
164
165 master_list[chan_enum].min_bw = min_bw;
166 if (master_list[chan_enum].max_bw == 20)
167 master_list[chan_enum].max_bw = reg_rule->max_bw;
168 }
169
170 #ifdef CONFIG_BAND_6GHZ
171 /**
172 * reg_dis_chan_state_and_flags() - Disable the input channel state
173 * and chan_flags
174 * @state: Channel state
175 * @chan_flags: Channel flags
176 *
177 * Return: void
178 */
reg_dis_chan_state_and_flags(enum channel_state * state,uint32_t * chan_flags)179 static void reg_dis_chan_state_and_flags(enum channel_state *state,
180 uint32_t *chan_flags)
181 {
182 *state = CHANNEL_STATE_DISABLE;
183 *chan_flags |= REGULATORY_CHAN_DISABLED;
184 }
185
186 /**
187 * reg_populate_band_channels_ext_for_6g() - For all the valid regdb channels in
188 * the master channel list, find the regulatory rules and call
189 * reg_fill_channel_info() to populate master channel list with txpower,
190 * antennagain, BW info, etc.
191 * @start_idx: Start channel range in list
192 * @end_idx: End channel range in list
193 * @rule_start_ptr: Pointer to regulatory rules
194 * @num_reg_rules: Number of regulatory rules
195 * @min_reg_bw: Minimum regulatory bandwidth
196 * @mas_chan_list: Pointer to master channel list
197 */
reg_populate_band_channels_ext_for_6g(uint16_t start_idx,uint16_t end_idx,struct cur_reg_rule * rule_start_ptr,uint32_t num_reg_rules,uint16_t min_reg_bw,struct regulatory_channel * mas_chan_list)198 static void reg_populate_band_channels_ext_for_6g(uint16_t start_idx,
199 uint16_t end_idx,
200 struct cur_reg_rule *rule_start_ptr,
201 uint32_t num_reg_rules,
202 uint16_t min_reg_bw,
203 struct regulatory_channel *mas_chan_list)
204 {
205 struct cur_reg_rule *found_rule_ptr;
206 struct cur_reg_rule *cur_rule_ptr;
207 struct regulatory_channel;
208 uint32_t rule_num, bw;
209 uint16_t i, min_bw, max_bw;
210
211 for (i = start_idx; i <= end_idx; i++) {
212 found_rule_ptr = NULL;
213
214 max_bw = QDF_MIN((uint16_t)20,
215 channel_map[MIN_6GHZ_CHANNEL + i].max_bw);
216 min_bw = QDF_MAX(min_reg_bw,
217 channel_map[MIN_6GHZ_CHANNEL + i].min_bw);
218
219 if (channel_map[MIN_6GHZ_CHANNEL + i].chan_num ==
220 INVALID_CHANNEL_NUM)
221 continue;
222
223 for (bw = max_bw; bw >= min_bw; bw = bw / 2) {
224 for (rule_num = 0, cur_rule_ptr = rule_start_ptr;
225 rule_num < num_reg_rules;
226 cur_rule_ptr++, rule_num++) {
227 if ((cur_rule_ptr->start_freq <=
228 mas_chan_list[i].center_freq -
229 bw / 2) &&
230 (cur_rule_ptr->end_freq >=
231 mas_chan_list[i].center_freq +
232 bw / 2) && (min_bw <= bw)) {
233 found_rule_ptr = cur_rule_ptr;
234 break;
235 }
236 }
237
238 if (found_rule_ptr)
239 break;
240 }
241
242 if (found_rule_ptr) {
243 mas_chan_list[i].max_bw = bw;
244 reg_fill_channel_info(i, found_rule_ptr,
245 mas_chan_list, min_bw);
246 }
247 }
248 }
249 #else
250 static inline void
reg_populate_band_channels_ext_for_6g(enum channel_enum start_chan,enum channel_enum end_chan,struct cur_reg_rule * rule_start_ptr,uint32_t num_reg_rules,uint16_t min_reg_bw,struct regulatory_channel * mas_chan_list)251 reg_populate_band_channels_ext_for_6g(enum channel_enum start_chan,
252 enum channel_enum end_chan,
253 struct cur_reg_rule *rule_start_ptr,
254 uint32_t num_reg_rules,
255 uint16_t min_reg_bw,
256 struct regulatory_channel *mas_chan_list)
257 {
258 }
259 #endif
260
261 /**
262 * reg_populate_band_channels() - For all the valid regdb channels in the master
263 * channel list, find the regulatory rules and call reg_fill_channel_info() to
264 * populate master channel list with txpower, antennagain, BW info, etc.
265 * @start_chan: Start channel enum.
266 * @end_chan: End channel enum.
267 * @rule_start_ptr: Pointer to regulatory rules.
268 * @num_reg_rules: Number of regulatory rules.
269 * @min_reg_bw: Minimum regulatory bandwidth.
270 * @mas_chan_list: Pointer to master channel list.
271 */
reg_populate_band_channels(enum channel_enum start_chan,enum channel_enum end_chan,struct cur_reg_rule * rule_start_ptr,uint32_t num_reg_rules,uint16_t min_reg_bw,struct regulatory_channel * mas_chan_list)272 static void reg_populate_band_channels(enum channel_enum start_chan,
273 enum channel_enum end_chan,
274 struct cur_reg_rule *rule_start_ptr,
275 uint32_t num_reg_rules,
276 uint16_t min_reg_bw,
277 struct regulatory_channel *mas_chan_list)
278 {
279 struct cur_reg_rule *found_rule_ptr;
280 struct cur_reg_rule *cur_rule_ptr;
281 struct regulatory_channel;
282 enum channel_enum chan_enum;
283 uint32_t rule_num, bw;
284 uint16_t max_bw;
285 uint16_t min_bw;
286
287 for (chan_enum = start_chan; chan_enum <= end_chan; chan_enum++) {
288 found_rule_ptr = NULL;
289
290 max_bw = QDF_MIN((uint16_t)20, channel_map[chan_enum].max_bw);
291 min_bw = QDF_MAX(min_reg_bw, channel_map[chan_enum].min_bw);
292
293 if (channel_map[chan_enum].chan_num == INVALID_CHANNEL_NUM)
294 continue;
295
296 for (bw = max_bw; bw >= min_bw; bw = bw / 2) {
297 for (rule_num = 0, cur_rule_ptr = rule_start_ptr;
298 rule_num < num_reg_rules;
299 cur_rule_ptr++, rule_num++) {
300 if ((cur_rule_ptr->start_freq <=
301 mas_chan_list[chan_enum].center_freq -
302 bw / 2) &&
303 (cur_rule_ptr->end_freq >=
304 mas_chan_list[chan_enum].center_freq +
305 bw / 2) && (min_bw <= bw)) {
306 found_rule_ptr = cur_rule_ptr;
307 break;
308 }
309 }
310
311 if (found_rule_ptr)
312 break;
313 }
314
315 if (found_rule_ptr) {
316 mas_chan_list[chan_enum].max_bw = bw;
317 reg_fill_channel_info(chan_enum, found_rule_ptr,
318 mas_chan_list, min_bw);
319 /* Disable 2.4 Ghz channels that dont have 20 mhz bw */
320 if (start_chan == MIN_24GHZ_CHANNEL &&
321 mas_chan_list[chan_enum].max_bw < 20) {
322 mas_chan_list[chan_enum].chan_flags |=
323 REGULATORY_CHAN_DISABLED;
324 mas_chan_list[chan_enum].state =
325 CHANNEL_STATE_DISABLE;
326 }
327 }
328 }
329 }
330
331 /**
332 * reg_update_max_bw_per_rule() - Update max bandwidth value for given regrules.
333 * @num_reg_rules: Number of regulatory rules.
334 * @reg_rule_start: Pointer to regulatory rules.
335 * @max_bw: Maximum bandwidth
336 * @country_max_allowed_bw: max allowed bw for all reg rules of client
337 */
reg_update_max_bw_per_rule(uint32_t num_reg_rules,struct cur_reg_rule * reg_rule_start,uint16_t max_bw,uint32_t * country_max_allowed_bw)338 static void reg_update_max_bw_per_rule(uint32_t num_reg_rules,
339 struct cur_reg_rule *reg_rule_start,
340 uint16_t max_bw,
341 uint32_t *country_max_allowed_bw)
342 {
343 uint32_t count;
344
345 for (count = 0; count < num_reg_rules; count++) {
346 reg_rule_start[count].max_bw =
347 min(reg_rule_start[count].max_bw, max_bw);
348 if (reg_rule_start[count].max_bw > *country_max_allowed_bw)
349 *country_max_allowed_bw = reg_rule_start[count].max_bw;
350 }
351 }
352
353 /**
354 * reg_bw_floor() - Calculate floor of a given bandwidth. Find the nearest
355 * bandwidth, from the set = {5, 10, 20, 40, 80, 160, 320}, which is less
356 * than or equal to the given bandwidth. Any input bandwidth less than 5MHz
357 * is converted to 0.
358 * @in_bw: A positive bandwidth value
359 *
360 * Return: The floor of the given bandwidth.
361 */
reg_bw_floor(uint16_t in_bw)362 static uint16_t reg_bw_floor(uint16_t in_bw)
363 {
364 static const uint16_t chwidth_array[] = {5, 10, 20, 40, 80, 160, 320};
365 int16_t i;
366
367 for (i = QDF_ARRAY_SIZE(chwidth_array) - 1; i >= 0; i--) {
368 if (in_bw >= chwidth_array[i])
369 return chwidth_array[i];
370 }
371 return 0;
372 }
373
374 /**
375 * reg_find_enhanced_bw() - Given two adjacent reg rules, it first finds the
376 * coalesced bandwidth limited by the country/regulatory domain bandwidth. Then
377 * it finds the nearest discrete bandwidth from the discrete
378 * set = {5, 10, 20, 40, 80, 160, 320} of bandwidths.
379 * @reg_rule_ptr: Pointer to reg rule
380 * @cur_idx: Current index to be considered
381 * @max_reg_bw: Maximum bandwidth of the country/regulatory domain
382 *
383 * Return: Return enhanced bandwidth of the coalesced band
384 */
reg_find_enhanced_bw(struct cur_reg_rule * reg_rule_ptr,uint32_t cur_idx,uint16_t max_reg_bw)385 static uint16_t reg_find_enhanced_bw(struct cur_reg_rule *reg_rule_ptr,
386 uint32_t cur_idx,
387 uint16_t max_reg_bw)
388 {
389 uint16_t cur_rule_diff_freq;
390 uint16_t next_rule_diff_freq;
391 uint16_t new_bw;
392 uint16_t enhanced_bw;
393
394 cur_rule_diff_freq = reg_rule_ptr[cur_idx].end_freq -
395 reg_rule_ptr[cur_idx].start_freq;
396 next_rule_diff_freq = reg_rule_ptr[cur_idx + 1].end_freq -
397 reg_rule_ptr[cur_idx + 1].start_freq;
398
399 new_bw = QDF_MIN(max_reg_bw, cur_rule_diff_freq + next_rule_diff_freq);
400 enhanced_bw = reg_bw_floor(new_bw);
401
402 return enhanced_bw;
403 }
404
405 /**
406 * reg_do_auto_bw_correction() - Calculate and update the maximum bandwidth
407 * value.
408 * @num_reg_rules: Number of regulatory rules.
409 * @reg_rule_ptr: Pointer to regulatory rules.
410 * @max_bw: Maximum bandwidth
411 */
reg_do_auto_bw_correction(uint32_t num_reg_rules,struct cur_reg_rule * reg_rule_ptr,uint16_t max_bw)412 static void reg_do_auto_bw_correction(uint32_t num_reg_rules,
413 struct cur_reg_rule *reg_rule_ptr,
414 uint16_t max_bw)
415 {
416 uint32_t count;
417 uint16_t enhanced_bw;
418
419 for (count = 0; count < num_reg_rules - 1; count++) {
420 if (reg_rule_ptr[count].end_freq ==
421 reg_rule_ptr[count + 1].start_freq) {
422 enhanced_bw = reg_find_enhanced_bw(reg_rule_ptr,
423 count,
424 max_bw);
425 reg_rule_ptr[count].max_bw = enhanced_bw;
426 reg_rule_ptr[count + 1].max_bw = enhanced_bw;
427 }
428 }
429 }
430
431 /**
432 * reg_modify_chan_list_for_dfs_channels() - disable the DFS channels if
433 * dfs_enable set to false.
434 * @chan_list: Pointer to regulatory channel list.
435 * @dfs_enabled: if false, then disable the DFS channels.
436 */
reg_modify_chan_list_for_dfs_channels(struct regulatory_channel * chan_list,bool dfs_enabled)437 static void reg_modify_chan_list_for_dfs_channels(
438 struct regulatory_channel *chan_list, bool dfs_enabled)
439 {
440 enum channel_enum chan_enum;
441
442 if (dfs_enabled)
443 return;
444
445 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
446 if (chan_list[chan_enum].chan_flags & REGULATORY_CHAN_RADAR) {
447 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
448 chan_list[chan_enum].chan_flags |=
449 REGULATORY_CHAN_DISABLED;
450 }
451 }
452 }
453
454 #ifdef CONFIG_BAND_6GHZ
455 #ifdef CONFIG_REG_CLIENT
456 /**
457 * reg_get_connected_chan_for_mode() - Get connected channel for given opmode
458 * in given frequency range.
459 *
460 * @pdev_priv_obj: Pdev privect object pointer
461 * @device_mode: Device mode
462 * @start_freq: Start frequency
463 * @end_freq: End frequency
464 *
465 * Return: Channel info if channel in given range is connected for given
466 * device mode
467 */
468 static struct wlan_channel *
reg_get_connected_chan_for_mode(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,enum QDF_OPMODE device_mode,uint16_t start_freq,uint16_t end_freq)469 reg_get_connected_chan_for_mode(
470 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
471 enum QDF_OPMODE device_mode, uint16_t start_freq,
472 uint16_t end_freq)
473 {
474 struct wlan_objmgr_pdev *pdev;
475 struct wlan_objmgr_psoc *psoc;
476 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
477 reg_get_connected_chan_for_mode_callback callback = NULL;
478
479 pdev = pdev_priv_obj->pdev_ptr;
480 if (!pdev) {
481 reg_err("pdev is NULL");
482 return NULL;
483 }
484
485 psoc = wlan_pdev_get_psoc(pdev);
486 psoc_priv_obj = reg_get_psoc_obj(psoc);
487 if (!psoc_priv_obj) {
488 reg_err("reg psoc private obj is NULL");
489 return NULL;
490 }
491
492 qdf_spin_lock_bh(&psoc_priv_obj->cbk_list_lock);
493 if (psoc_priv_obj->conn_chan_cb.cbk)
494 callback = psoc_priv_obj->conn_chan_cb.cbk;
495 qdf_spin_unlock_bh(&psoc_priv_obj->cbk_list_lock);
496
497 if (callback)
498 return callback(psoc, device_mode, start_freq, end_freq);
499
500 return NULL;
501 }
502
503 /**
504 * reg_get_active_6ghz_freq_range_with_fcc_set() - Get 6 GHz bonded channel
505 * range
506 * @pdev_priv_obj: Pointer to regulatory pdev privet object structure
507 * @bonded_chan: Pointer to bonded channel frequency structure
508 *
509 * Return: None.
510 */
511 static void
reg_get_active_6ghz_freq_range_with_fcc_set(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,struct bonded_channel_freq * bonded_chan)512 reg_get_active_6ghz_freq_range_with_fcc_set(
513 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
514 struct bonded_channel_freq *bonded_chan)
515 {
516 struct wlan_channel *conn_chan, *conn_chan_sta, *conn_chan_cli;
517 enum phy_ch_width max_width = CH_WIDTH_INVALID;
518 uint16_t start_freq_6g, end_freq_6g, conn_freq = 0;
519 const struct bonded_channel_freq *cur_bonded_chans;
520
521 start_freq_6g = pdev_priv_obj->cur_chan_list[MIN_6GHZ_CHANNEL].center_freq;
522 end_freq_6g = pdev_priv_obj->cur_chan_list[MAX_6GHZ_CHANNEL].center_freq;
523
524 conn_chan_sta = reg_get_connected_chan_for_mode(pdev_priv_obj,
525 QDF_STA_MODE,
526 start_freq_6g,
527 end_freq_6g);
528
529 conn_chan_cli = reg_get_connected_chan_for_mode(pdev_priv_obj,
530 QDF_P2P_CLIENT_MODE,
531 start_freq_6g,
532 end_freq_6g);
533
534 if (conn_chan_sta && conn_chan_cli)
535 max_width = QDF_MAX(conn_chan_sta->ch_width,
536 conn_chan_cli->ch_width);
537 else if (conn_chan_sta)
538 max_width = conn_chan_sta->ch_width;
539 else if (conn_chan_cli)
540 max_width = conn_chan_cli->ch_width;
541
542 if (max_width < CH_WIDTH_INVALID) {
543 conn_chan = reg_get_connected_chan_for_mode(pdev_priv_obj,
544 QDF_SAP_MODE,
545 start_freq_6g,
546 end_freq_6g);
547 if (conn_chan && max_width < conn_chan->ch_width)
548 max_width = conn_chan->ch_width;
549
550 conn_chan = reg_get_connected_chan_for_mode(pdev_priv_obj,
551 QDF_P2P_GO_MODE,
552 start_freq_6g,
553 end_freq_6g);
554
555 if (conn_chan && max_width < conn_chan->ch_width)
556 max_width = conn_chan->ch_width;
557
558 if (conn_chan_sta)
559 conn_freq = conn_chan_sta->ch_freq;
560 else if (conn_chan_cli)
561 conn_freq = conn_chan_cli->ch_freq;
562
563 if (max_width == CH_WIDTH_20MHZ) {
564 bonded_chan->start_freq = conn_freq;
565 bonded_chan->end_freq = conn_freq;
566 } else {
567 cur_bonded_chans = reg_get_bonded_chan_entry(
568 conn_freq,
569 max_width, 0);
570 if (cur_bonded_chans)
571 qdf_mem_copy(bonded_chan, cur_bonded_chans,
572 sizeof(struct bonded_channel_freq));
573 }
574 }
575 }
576
577 #else
578 static inline struct wlan_channel *
reg_get_connected_chan_for_mode(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,enum QDF_OPMODE device_mode,uint16_t start_freq,uint16_t end_freq)579 reg_get_connected_chan_for_mode(
580 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
581 enum QDF_OPMODE device_mode, uint16_t start_freq,
582 uint16_t end_freq)
583 {
584 return false;
585 }
586 #endif
587 #endif
588
589 #if defined(CONFIG_BAND_6GHZ) && defined(CONFIG_REG_CLIENT)
590 /**
591 * reg_is_lpi_cli_supp_pwr_mode() - Check if the input supported power mode is a
592 * client LPI power mode
593 *
594 * @supp_pwr_mode: 6G supported power mode
595 *
596 * Return: bool
597 */
598 static bool
reg_is_lpi_cli_supp_pwr_mode(enum supported_6g_pwr_types supp_pwr_mode)599 reg_is_lpi_cli_supp_pwr_mode(enum supported_6g_pwr_types supp_pwr_mode)
600 {
601 return ((supp_pwr_mode == REG_CLI_DEF_LPI) ||
602 (supp_pwr_mode == REG_CLI_SUB_LPI));
603 }
604
605 /**
606 * reg_modify_super_chan_list_for_indoor_channels() - Disable the indoor
607 * channels in super channel list if indoor_chan_enabled flag is set to false.
608 *
609 * @pdev_priv_obj: Pointer to regulatory private pdev structure.
610 * @chn_idx: Channel index for which indoor channel needs to be disabled in
611 * super channel list.
612 * @pwr_mode: Input power mode
613 *
614 * Return: None
615 */
reg_modify_super_chan_list_for_indoor_channels(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,uint16_t chn_idx,enum supported_6g_pwr_types pwr_mode)616 static void reg_modify_super_chan_list_for_indoor_channels(
617 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
618 uint16_t chn_idx,
619 enum supported_6g_pwr_types pwr_mode)
620 {
621 struct super_chan_info *super_chan_list;
622
623 if (!reg_is_lpi_cli_supp_pwr_mode(pwr_mode))
624 return;
625
626 super_chan_list = pdev_priv_obj->super_chan_list;
627
628 if (!pdev_priv_obj->indoor_chan_enabled) {
629 if (!reg_is_chan_disabled(
630 super_chan_list[chn_idx].chan_flags_arr[pwr_mode],
631 super_chan_list[chn_idx].state_arr[pwr_mode])) {
632 super_chan_list[chn_idx].chan_flags_arr[pwr_mode] |=
633 REGULATORY_CHAN_NO_IR;
634 super_chan_list[chn_idx].state_arr[pwr_mode] =
635 CHANNEL_STATE_DFS;
636 }
637 }
638
639 if (pdev_priv_obj->force_ssc_disable_indoor_channel &&
640 pdev_priv_obj->sap_state) {
641 if (!reg_is_chan_disabled(
642 super_chan_list[chn_idx].chan_flags_arr[pwr_mode],
643 super_chan_list[chn_idx].state_arr[pwr_mode])) {
644 super_chan_list[chn_idx].chan_flags_arr[pwr_mode] |=
645 REGULATORY_CHAN_NO_IR;
646 super_chan_list[chn_idx].state_arr[pwr_mode] =
647 CHANNEL_STATE_DISABLE;
648 }
649 }
650 }
651
652 /**
653 * reg_get_6g_chan_idx_for_freq() - Get 6 GHz channel index for given frequency
654 *
655 * @freq: Given frequency
656 *
657 * Return: 6 GHz channel index corresponding to the given frequency.
658 */
659 static uint16_t
reg_get_6g_chan_idx_for_freq(qdf_freq_t freq)660 reg_get_6g_chan_idx_for_freq(qdf_freq_t freq)
661 {
662 enum channel_enum freq_idx;
663
664 freq_idx = reg_get_chan_enum_for_freq(freq);
665 return reg_convert_enum_to_6g_idx(freq_idx);
666 }
667
668 static void
reg_dis_6g_chan_in_super_chan_list(struct wlan_objmgr_pdev * pdev,struct super_chan_info * chan_info,enum supported_6g_pwr_types pwr_type,uint16_t chn_idx)669 reg_dis_6g_chan_in_super_chan_list(struct wlan_objmgr_pdev *pdev,
670 struct super_chan_info *chan_info,
671 enum supported_6g_pwr_types pwr_type,
672 uint16_t chn_idx)
673 {
674 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
675 struct bonded_channel_freq *bonded_chan;
676 enum channel_enum active_6g_start = INVALID_CHANNEL;
677 enum channel_enum active_6g_end = INVALID_CHANNEL;
678
679 if (!pdev) {
680 reg_debug("pdev is NULL");
681 return;
682 }
683
684 if (!chan_info) {
685 reg_debug("chan_info is NULL");
686 return;
687 }
688
689 pdev_priv_obj = reg_get_pdev_obj(pdev);
690
691 bonded_chan = qdf_mem_malloc(sizeof(struct bonded_channel_freq));
692 if (!bonded_chan)
693 return;
694
695 qdf_mem_zero(bonded_chan, sizeof(struct bonded_channel_freq));
696
697 if (reg_get_keep_6ghz_sta_cli_connection(pdev))
698 reg_get_active_6ghz_freq_range_with_fcc_set(pdev_priv_obj,
699 bonded_chan);
700 if (bonded_chan->start_freq && bonded_chan->end_freq) {
701 active_6g_start = reg_get_6g_chan_idx_for_freq(
702 bonded_chan->start_freq);
703 active_6g_end = reg_get_6g_chan_idx_for_freq(
704 bonded_chan->end_freq);
705 }
706
707 qdf_mem_free(bonded_chan);
708
709 if (!reg_is_6ghz_band_set(pdev))
710 if (reg_is_chan_enum_invalid(active_6g_start) ||
711 reg_is_chan_enum_invalid(active_6g_end) ||
712 !(chn_idx >= active_6g_start &&
713 chn_idx <= active_6g_end))
714 reg_dis_chan_state_and_flags(
715 &chan_info->state_arr[pwr_type],
716 &chan_info->chan_flags_arr[pwr_type]);
717 }
718 #else
719 static inline bool
reg_is_lpi_cli_supp_pwr_mode(enum supported_6g_pwr_types supp_pwr_mode)720 reg_is_lpi_cli_supp_pwr_mode(enum supported_6g_pwr_types supp_pwr_mode)
721 {
722 return false;
723 }
724
725 static inline void
reg_modify_super_chan_list_for_indoor_channels(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,uint16_t chn_idx,enum supported_6g_pwr_types pwr_mode)726 reg_modify_super_chan_list_for_indoor_channels(
727 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
728 uint16_t chn_idx,
729 enum supported_6g_pwr_types pwr_mode)
730 {
731 }
732
733 static inline void
reg_dis_6g_chan_in_super_chan_list(struct wlan_objmgr_pdev * pdev,struct super_chan_info * chan_info,enum supported_6g_pwr_types pwr_type,uint16_t chn_idx)734 reg_dis_6g_chan_in_super_chan_list(struct wlan_objmgr_pdev *pdev,
735 struct super_chan_info *chan_info,
736 enum supported_6g_pwr_types pwr_type,
737 uint16_t chn_idx)
738 {
739 }
740 #endif /* CONFIG_BAND_6GHZ && CONFIG_REG_CLIENT */
741
742 /**
743 * reg_modify_chan_list_for_indoor_channels() - Disable the indoor channels if
744 * indoor_chan_enabled flag is set to false.
745 * @pdev_priv_obj: Pointer to regulatory private pdev structure.
746 */
747 #ifdef CONFIG_REG_CLIENT
reg_modify_chan_list_for_indoor_channels(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)748 static void reg_modify_chan_list_for_indoor_channels(
749 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
750 {
751 enum channel_enum chan_enum;
752 struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list;
753
754 if (!pdev_priv_obj->indoor_chan_enabled) {
755 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
756 if (!(REGULATORY_CHAN_DISABLED &
757 chan_list[chan_enum].chan_flags) &&
758 (REGULATORY_CHAN_INDOOR_ONLY &
759 chan_list[chan_enum].chan_flags) &&
760 !(pdev_priv_obj->p2p_indoor_ch_support &&
761 reg_is_5ghz_ch_freq(chan_list[chan_enum].center_freq))) {
762 chan_list[chan_enum].state =
763 CHANNEL_STATE_DFS;
764 chan_list[chan_enum].chan_flags |=
765 REGULATORY_CHAN_NO_IR;
766 }
767 }
768 }
769 if (pdev_priv_obj->force_ssc_disable_indoor_channel &&
770 pdev_priv_obj->sap_state) {
771 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
772 if (!(REGULATORY_CHAN_DISABLED &
773 chan_list[chan_enum].chan_flags) &&
774 (REGULATORY_CHAN_INDOOR_ONLY &
775 chan_list[chan_enum].chan_flags)) {
776 chan_list[chan_enum].state =
777 CHANNEL_STATE_DISABLE;
778 chan_list[chan_enum].chan_flags |=
779 REGULATORY_CHAN_DISABLED;
780 }
781 }
782 }
783 }
784
785 /**
786 * reg_modify_chan_list_for_indoor_concurrency() - Enable/Disable the indoor
787 * channels for SAP operation based on the indoor concurrency list
788 *
789 * @pdev_priv_obj: Pointer to regulatory private pdev structure.
790 *
791 * Return: None
792 */
reg_modify_chan_list_for_indoor_concurrency(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)793 static void reg_modify_chan_list_for_indoor_concurrency(
794 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
795 {
796 struct indoor_concurrency_list *indoor_list = NULL;
797 struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list;
798 enum channel_enum chan, min_enum, max_enum;
799 uint8_t i;
800
801 if (pdev_priv_obj->indoor_chan_enabled ||
802 pdev_priv_obj->p2p_indoor_ch_support ||
803 !pdev_priv_obj->sta_sap_scc_on_indoor_channel)
804 return;
805
806 indoor_list = pdev_priv_obj->indoor_list;
807
808 if (!indoor_list)
809 return;
810
811 for (i = 0; i < MAX_INDOOR_LIST_SIZE; i++, indoor_list++) {
812 if (indoor_list->freq == 0 &&
813 indoor_list->vdev_id == INVALID_VDEV_ID)
814 continue;
815
816 if (!indoor_list->chan_range) {
817 min_enum =
818 reg_get_chan_enum_for_freq(indoor_list->freq);
819 max_enum = min_enum;
820 } else {
821 min_enum =
822 reg_get_chan_enum_for_freq(
823 indoor_list->chan_range->start_freq);
824 max_enum =
825 reg_get_chan_enum_for_freq(
826 indoor_list->chan_range->end_freq);
827 }
828
829 if (min_enum == NUM_CHANNELS || max_enum == NUM_CHANNELS)
830 continue;
831
832 for (chan = min_enum; chan <= max_enum; chan++) {
833 if (chan_list[chan].chan_flags & REGULATORY_CHAN_INDOOR_ONLY &&
834 !(chan_list[chan].chan_flags & REGULATORY_CHAN_DISABLED)) {
835 chan_list[chan].chan_flags &= ~REGULATORY_CHAN_NO_IR;
836 }
837 }
838 }
839 }
840
841 #else
reg_modify_chan_list_for_indoor_channels(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)842 static void reg_modify_chan_list_for_indoor_channels(
843 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
844 {
845 }
846
reg_modify_chan_list_for_indoor_concurrency(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)847 static void reg_modify_chan_list_for_indoor_concurrency(
848 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
849 {
850 }
851 #endif
852
853 #ifdef CONFIG_BAND_6GHZ
854 #ifdef CONFIG_REG_CLIENT
855 /**
856 * reg_modify_inactive_6g_channels() - Modify inactive 6 GHz channels
857 * @pdev_priv_obj: pointer to pdev privet object
858 * @chan_list: pointer to channel list
859 *
860 * For standalone STA or P2P client case keep all the bonded channels
861 * active and disable rest 6 GHz channels.
862 * For STA+SAP case or P2P cli+SAP case keep all the bonded channels
863 * active.
864 *
865 * Return: None
866 */
reg_modify_inactive_6g_channels(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,struct regulatory_channel * chan_list)867 static void reg_modify_inactive_6g_channels(
868 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
869 struct regulatory_channel *chan_list)
870 {
871 enum channel_enum chan_enum;
872 struct bonded_channel_freq *bonded_chans;
873 enum channel_enum active_6g_start = INVALID_CHANNEL;
874 enum channel_enum active_6g_end = INVALID_CHANNEL;
875
876 bonded_chans = qdf_mem_malloc(sizeof(struct bonded_channel_freq));
877 if (!bonded_chans)
878 return;
879
880 qdf_mem_zero(bonded_chans, sizeof(struct bonded_channel_freq));
881
882 reg_get_active_6ghz_freq_range_with_fcc_set(pdev_priv_obj,
883 bonded_chans);
884
885 if (bonded_chans->start_freq && bonded_chans->end_freq) {
886 active_6g_start = reg_get_chan_enum_for_freq(
887 bonded_chans->start_freq);
888 active_6g_end = reg_get_chan_enum_for_freq(
889 bonded_chans->end_freq);
890 }
891
892 qdf_mem_free(bonded_chans);
893
894 reg_debug("disabling 6G");
895 for (chan_enum = MIN_6GHZ_CHANNEL;
896 chan_enum <= MAX_6GHZ_CHANNEL; chan_enum++) {
897 if (!reg_is_chan_enum_invalid(active_6g_start) &&
898 !reg_is_chan_enum_invalid(active_6g_end) &&
899 (chan_enum >= active_6g_start &&
900 chan_enum <= active_6g_end))
901 continue;
902
903 chan_list[chan_enum].chan_flags |= REGULATORY_CHAN_DISABLED;
904 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
905 }
906 }
907 #else
reg_modify_inactive_6g_channels(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,struct regulatory_channel * chan_list)908 static inline void reg_modify_inactive_6g_channels(
909 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
910 struct regulatory_channel *chan_list)
911 {
912 }
913 #endif
914 /**
915 * reg_modify_chan_list_for_band_6G() - Modify 6 GHz band channels
916 * @pdev_priv_obj: pointer to pdev privet object
917 * @chan_list: pointer to channel list
918 *
919 * Return: None
920 */
reg_modify_chan_list_for_band_6G(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,struct regulatory_channel * chan_list)921 static void reg_modify_chan_list_for_band_6G(
922 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
923 struct regulatory_channel *chan_list)
924 {
925 enum channel_enum chan_enum;
926 struct wlan_objmgr_pdev *pdev;
927
928 pdev = pdev_priv_obj->pdev_ptr;
929 if (!pdev) {
930 reg_debug("pdev is NULL");
931 return;
932 }
933
934 if (reg_get_keep_6ghz_sta_cli_connection(pdev)) {
935 reg_modify_inactive_6g_channels(pdev_priv_obj, chan_list);
936 } else {
937 reg_debug("disabling 6G");
938 for (chan_enum = MIN_6GHZ_CHANNEL;
939 chan_enum <= MAX_6GHZ_CHANNEL; chan_enum++) {
940 chan_list[chan_enum].chan_flags |=
941 REGULATORY_CHAN_DISABLED;
942 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
943 }
944 }
945 }
946
947 #ifdef CONFIG_REG_CLIENT
948 /**
949 * reg_modify_secondary_cur_chan_list() - Disable secondary current channel
950 * 6 GHz channels if 6 GHz band is disabled
951 *
952 * @pdev_priv_obj: pointer to pdev private object
953 *
954 * Return: None
955 */
reg_modify_secondary_cur_chan_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)956 static void reg_modify_secondary_cur_chan_list(
957 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
958 {
959 uint32_t band_bitmap;
960
961 band_bitmap = pdev_priv_obj->band_capability;
962 if (!band_bitmap)
963 return;
964
965 if (!(band_bitmap & BIT(REG_BAND_6G)))
966 reg_modify_chan_list_for_band_6G(pdev_priv_obj,
967 pdev_priv_obj->secondary_cur_chan_list);
968 }
969 #endif
970 #else
reg_modify_chan_list_for_band_6G(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,struct regulatory_channel * chan_list)971 static inline void reg_modify_chan_list_for_band_6G(
972 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
973 struct regulatory_channel *chan_list)
974 {
975 }
976 #endif
977
978 /**
979 * reg_modify_chan_list_for_band() - Based on the input band bitmap, either
980 * disable 2GHz, 5GHz, or 6GHz channels.
981 * @pdev_priv_obj: pointer to pdev private object
982 *
983 * Return: None
984 */
reg_modify_chan_list_for_band(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)985 static void reg_modify_chan_list_for_band(
986 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
987 {
988 enum channel_enum chan_enum;
989 struct regulatory_channel *chan_list;
990 uint32_t band_bitmap;
991
992 band_bitmap = pdev_priv_obj->band_capability;
993 if (!band_bitmap)
994 return;
995
996 chan_list = pdev_priv_obj->cur_chan_list;
997
998 if (!(band_bitmap & BIT(REG_BAND_5G))) {
999 reg_debug("disabling 5G");
1000 for (chan_enum = MIN_5GHZ_CHANNEL;
1001 chan_enum <= MAX_5GHZ_CHANNEL; chan_enum++) {
1002 chan_list[chan_enum].chan_flags |=
1003 REGULATORY_CHAN_DISABLED;
1004 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
1005 }
1006 }
1007
1008 if (!(band_bitmap & BIT(REG_BAND_2G))) {
1009 reg_debug("disabling 2G");
1010 for (chan_enum = MIN_24GHZ_CHANNEL;
1011 chan_enum <= MAX_24GHZ_CHANNEL; chan_enum++) {
1012 chan_list[chan_enum].chan_flags |=
1013 REGULATORY_CHAN_DISABLED;
1014 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
1015 }
1016 }
1017
1018 if (!(band_bitmap & BIT(REG_BAND_6G)))
1019 reg_modify_chan_list_for_band_6G(pdev_priv_obj, chan_list);
1020
1021 }
1022
1023 #ifdef CONFIG_REG_CLIENT
1024 /**
1025 * reg_get_tx_power_for_fcc_channel() - Set FCC txpower received from firmware
1026 * @chan_list: Regulatory channel to be updated
1027 * @fcc_rule: Pointer to current fcc rule array
1028 *
1029 * Return: true if regulatory channel is present in current fcc rules array
1030 */
reg_get_tx_power_for_fcc_channel(struct regulatory_channel * chan_list,struct cur_fcc_rule * fcc_rule)1031 static bool reg_get_tx_power_for_fcc_channel(
1032 struct regulatory_channel *chan_list,
1033 struct cur_fcc_rule *fcc_rule)
1034 {
1035 int index = 0;
1036
1037 if (!chan_list || !fcc_rule)
1038 return false;
1039
1040 for (index = 0; index < MAX_NUM_FCC_RULES; index++) {
1041 if (chan_list->center_freq == fcc_rule[index].center_freq) {
1042 chan_list->tx_power = fcc_rule[index].tx_power;
1043 return true;
1044 }
1045 }
1046
1047 return false;
1048 }
1049
1050 /**
1051 * reg_modify_chan_list_for_fcc_channel() - Set maximum FCC txpower for channel
1052 * 12 and 13 if set_fcc_channel flag is set to true.
1053 * @pdev_priv_obj: Pointer to pdev private object.
1054 */
reg_modify_chan_list_for_fcc_channel(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)1055 static void reg_modify_chan_list_for_fcc_channel(
1056 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1057 {
1058 struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list;
1059 struct cur_fcc_rule *fcc_rules = pdev_priv_obj->fcc_rules_ptr;
1060
1061 if (!pdev_priv_obj->set_fcc_channel)
1062 return;
1063
1064 if (!chan_list || !fcc_rules)
1065 return;
1066
1067 if (!reg_get_tx_power_for_fcc_channel(
1068 &chan_list[CHAN_ENUM_2467], fcc_rules)) {
1069 chan_list[CHAN_ENUM_2467].tx_power = MAX_PWR_FCC_CHAN_12;
1070 reg_debug("Channel 12 not found from BDF");
1071 }
1072 if (!reg_get_tx_power_for_fcc_channel(
1073 &chan_list[CHAN_ENUM_2472], fcc_rules)) {
1074 chan_list[CHAN_ENUM_2472].tx_power = MAX_PWR_FCC_CHAN_13;
1075 reg_debug("Channel 13 not found from BDF");
1076 }
1077 reg_debug("Channel 12 tx_power = %d, 13 tx_power = %d",
1078 chan_list[CHAN_ENUM_2467].tx_power,
1079 chan_list[CHAN_ENUM_2472].tx_power);
1080 }
1081 #else
reg_modify_chan_list_for_fcc_channel(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)1082 static inline void reg_modify_chan_list_for_fcc_channel(
1083 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1084 {
1085 }
1086 #endif
1087
1088 /**
1089 * reg_modify_chan_list_for_chan_144() - Disable channel 144 if en_chan_144 flag
1090 * is set to false.
1091 * @chan_list: Pointer to regulatory channel list.
1092 * @en_chan_144: if false, then disable channel 144.
1093 */
reg_modify_chan_list_for_chan_144(struct regulatory_channel * chan_list,bool en_chan_144)1094 static void reg_modify_chan_list_for_chan_144(
1095 struct regulatory_channel *chan_list, bool en_chan_144)
1096 {
1097 enum channel_enum chan_enum;
1098
1099 if (en_chan_144)
1100 return;
1101
1102 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
1103 if (chan_list[chan_enum].center_freq == CHAN_144_CENT_FREQ) {
1104 chan_list[chan_enum].chan_flags |=
1105 REGULATORY_CHAN_DISABLED;
1106 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
1107 }
1108 }
1109 }
1110
1111 /**
1112 * reg_modify_chan_list_for_nol_list() - Disable the channel if nol_chan flag is
1113 * set.
1114 * @chan_list: Pointer to regulatory channel list.
1115 */
reg_modify_chan_list_for_nol_list(struct regulatory_channel * chan_list)1116 static void reg_modify_chan_list_for_nol_list(
1117 struct regulatory_channel *chan_list)
1118 {
1119 enum channel_enum chan_enum;
1120
1121 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
1122 if (chan_list[chan_enum].nol_chan) {
1123 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
1124 chan_list[chan_enum].chan_flags |=
1125 REGULATORY_CHAN_DISABLED;
1126 }
1127 }
1128 }
1129
1130 #ifdef CONFIG_REG_CLIENT
1131 /**
1132 * reg_modify_chan_list_for_static_puncture() - Disable the channel if
1133 * static_puncture is set.
1134 * @chan_list: Pointer to regulatory channel list.
1135 */
1136 static void
reg_modify_chan_list_for_static_puncture(struct regulatory_channel * chan_list)1137 reg_modify_chan_list_for_static_puncture(struct regulatory_channel *chan_list)
1138 {
1139 enum channel_enum chan_enum;
1140
1141 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
1142 if (chan_list[chan_enum].is_static_punctured) {
1143 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
1144 chan_list[chan_enum].chan_flags |=
1145 REGULATORY_CHAN_DISABLED;
1146 }
1147 }
1148 }
1149 #else
1150 static void
reg_modify_chan_list_for_static_puncture(struct regulatory_channel * chan_list)1151 reg_modify_chan_list_for_static_puncture(struct regulatory_channel *chan_list)
1152 {
1153 }
1154 #endif
1155
1156 /**
1157 * reg_find_low_limit_chan_enum() - Find low limit 2G and 5G channel enums.
1158 * @chan_list: Pointer to regulatory channel list.
1159 * @low_freq: low limit frequency.
1160 * @low_limit: pointer to output low limit enum.
1161 *
1162 * Return: None
1163 */
reg_find_low_limit_chan_enum(struct regulatory_channel * chan_list,qdf_freq_t low_freq,uint32_t * low_limit)1164 static void reg_find_low_limit_chan_enum(
1165 struct regulatory_channel *chan_list, qdf_freq_t low_freq,
1166 uint32_t *low_limit)
1167 {
1168 enum channel_enum chan_enum;
1169 uint16_t min_bw;
1170 uint16_t max_bw;
1171 qdf_freq_t center_freq;
1172
1173 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
1174 min_bw = chan_list[chan_enum].min_bw;
1175 max_bw = chan_list[chan_enum].max_bw;
1176 center_freq = chan_list[chan_enum].center_freq;
1177
1178 if ((center_freq - min_bw / 2) >= low_freq) {
1179 if ((center_freq - max_bw / 2) < low_freq) {
1180 if (max_bw <= 20)
1181 max_bw = ((center_freq - low_freq) * 2);
1182 if (max_bw < min_bw)
1183 max_bw = min_bw;
1184 chan_list[chan_enum].max_bw = max_bw;
1185 }
1186 *low_limit = chan_enum;
1187 break;
1188 }
1189 }
1190 }
1191
1192 /**
1193 * reg_find_high_limit_chan_enum() - Find high limit 2G and 5G channel enums.
1194 * @chan_list: Pointer to regulatory channel list.
1195 * @high_freq: high limit frequency.
1196 * @high_limit: pointer to output high limit enum.
1197 *
1198 * Return: None
1199 */
reg_find_high_limit_chan_enum(struct regulatory_channel * chan_list,qdf_freq_t high_freq,uint32_t * high_limit)1200 static void reg_find_high_limit_chan_enum(
1201 struct regulatory_channel *chan_list,
1202 qdf_freq_t high_freq,
1203 uint32_t *high_limit)
1204 {
1205 enum channel_enum chan_enum;
1206 uint16_t min_bw;
1207 uint16_t max_bw;
1208 qdf_freq_t center_freq;
1209
1210 for (chan_enum = NUM_CHANNELS - 1; chan_enum >= 0; chan_enum--) {
1211 min_bw = chan_list[chan_enum].min_bw;
1212 max_bw = chan_list[chan_enum].max_bw;
1213 center_freq = chan_list[chan_enum].center_freq;
1214
1215 if (center_freq + min_bw / 2 <= high_freq) {
1216 if ((center_freq + max_bw / 2) > high_freq) {
1217 if (max_bw <= 20)
1218 max_bw = ((high_freq -
1219 center_freq) * 2);
1220 if (max_bw < min_bw)
1221 max_bw = min_bw;
1222 chan_list[chan_enum].max_bw = max_bw;
1223 }
1224 *high_limit = chan_enum;
1225 break;
1226 }
1227
1228 if (chan_enum == 0)
1229 break;
1230 }
1231 }
1232
1233 #ifdef CONFIG_AFC_SUPPORT
1234 /**
1235 * reg_modify_chan_list_for_outdoor() - Set the channel flag for the
1236 * enabled SP channels as REGULATORY_CHAN_AFC_NOT_DONE.
1237 * @pdev_priv_obj: Regulatory pdev private object.
1238 *
1239 * Return: void
1240 */
1241 static void
reg_modify_chan_list_for_outdoor(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)1242 reg_modify_chan_list_for_outdoor(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1243 {
1244 struct regulatory_channel *sp_chan_list;
1245 int i;
1246
1247 sp_chan_list = pdev_priv_obj->mas_chan_list_6g_ap[REG_STANDARD_POWER_AP];
1248 if (pdev_priv_obj->reg_afc_dev_deployment_type != AFC_DEPLOYMENT_OUTDOOR)
1249 return;
1250
1251 if (pdev_priv_obj->is_6g_afc_power_event_received)
1252 return;
1253
1254 if (!pdev_priv_obj->is_6g_channel_list_populated)
1255 return;
1256
1257 for (i = 0; i < NUM_6GHZ_CHANNELS; i++) {
1258 if (sp_chan_list[i].state == CHANNEL_STATE_ENABLE)
1259 sp_chan_list[i].chan_flags |= REGULATORY_CHAN_AFC_NOT_DONE;
1260 }
1261 }
1262 #else
1263 static inline void
reg_modify_chan_list_for_outdoor(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)1264 reg_modify_chan_list_for_outdoor(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1265 {
1266 }
1267 #endif
1268
1269 /**
1270 * reg_modify_chan_list_for_freq_range() - Modify channel list for the given low
1271 * and high frequency range.
1272 * @chan_list: Pointer to regulatory channel list.
1273 * @low_freq_2g: Low frequency 2G.
1274 * @high_freq_2g: High frequency 2G.
1275 * @low_freq_5g: Low frequency 5G.
1276 * @high_freq_5g: High frequency 5G.
1277 *
1278 * Return: None
1279 */
1280 static void
reg_modify_chan_list_for_freq_range(struct regulatory_channel * chan_list,qdf_freq_t low_freq_2g,qdf_freq_t high_freq_2g,qdf_freq_t low_freq_5g,qdf_freq_t high_freq_5g)1281 reg_modify_chan_list_for_freq_range(struct regulatory_channel *chan_list,
1282 qdf_freq_t low_freq_2g,
1283 qdf_freq_t high_freq_2g,
1284 qdf_freq_t low_freq_5g,
1285 qdf_freq_t high_freq_5g)
1286 {
1287 uint32_t low_limit_2g = NUM_CHANNELS;
1288 uint32_t high_limit_2g = NUM_CHANNELS;
1289 uint32_t low_limit_5g = NUM_CHANNELS;
1290 uint32_t high_limit_5g = NUM_CHANNELS;
1291 enum channel_enum chan_enum;
1292 bool chan_in_range;
1293
1294 reg_find_low_limit_chan_enum(chan_list, low_freq_2g, &low_limit_2g);
1295 reg_find_low_limit_chan_enum(chan_list, low_freq_5g, &low_limit_5g);
1296 reg_find_high_limit_chan_enum(chan_list, high_freq_2g, &high_limit_2g);
1297 reg_find_high_limit_chan_enum(chan_list, high_freq_5g, &high_limit_5g);
1298
1299 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
1300 chan_in_range = false;
1301 if ((low_limit_2g <= chan_enum) &&
1302 (high_limit_2g >= chan_enum) &&
1303 (low_limit_2g != NUM_CHANNELS) &&
1304 (high_limit_2g != NUM_CHANNELS))
1305 chan_in_range = true;
1306
1307 if ((low_limit_5g <= chan_enum) &&
1308 (high_limit_5g >= chan_enum) &&
1309 (low_limit_5g != NUM_CHANNELS) &&
1310 (high_limit_5g != NUM_CHANNELS))
1311 chan_in_range = true;
1312
1313 if (!chan_in_range) {
1314 chan_list[chan_enum].chan_flags |=
1315 REGULATORY_CHAN_DISABLED;
1316 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
1317 }
1318 }
1319 }
1320
1321 #ifdef CONFIG_BAND_6GHZ
1322 /**
1323 * reg_propagate_6g_mas_channel_list() - Copy master chan list from PSOC to PDEV
1324 * @pdev_priv_obj: Pointer to pdev
1325 * @mas_chan_params: Master channel parameters
1326 *
1327 * Return: None
1328 */
reg_propagate_6g_mas_channel_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,struct mas_chan_params * mas_chan_params)1329 static void reg_propagate_6g_mas_channel_list(
1330 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
1331 struct mas_chan_params *mas_chan_params)
1332 {
1333 uint8_t i, j;
1334 struct regulatory_channel *src_6g_chan, *dst_6g_chan;
1335 uint32_t size_of_6g_chan_list =
1336 NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel);
1337
1338 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) {
1339 qdf_mem_copy(pdev_priv_obj->mas_chan_list_6g_ap[i],
1340 mas_chan_params->mas_chan_list_6g_ap[i],
1341 size_of_6g_chan_list);
1342
1343 for (j = 0; j < REG_MAX_CLIENT_TYPE; j++) {
1344 dst_6g_chan =
1345 pdev_priv_obj->mas_chan_list_6g_client[i][j];
1346 src_6g_chan =
1347 mas_chan_params->mas_chan_list_6g_client[i][j];
1348 qdf_mem_copy(dst_6g_chan, src_6g_chan,
1349 size_of_6g_chan_list);
1350 }
1351 }
1352
1353 pdev_priv_obj->reg_cur_6g_client_mobility_type =
1354 mas_chan_params->client_type;
1355 pdev_priv_obj->reg_target_client_type =
1356 mas_chan_params->client_type;
1357 pdev_priv_obj->reg_rnr_tpe_usable = mas_chan_params->rnr_tpe_usable;
1358 pdev_priv_obj->reg_unspecified_ap_usable =
1359 mas_chan_params->unspecified_ap_usable;
1360 pdev_priv_obj->is_6g_channel_list_populated =
1361 mas_chan_params->is_6g_channel_list_populated;
1362 reg_set_afc_power_event_received(pdev_priv_obj->pdev_ptr, false);
1363 pdev_priv_obj->reg_6g_superid =
1364 mas_chan_params->reg_6g_superid;
1365 pdev_priv_obj->reg_6g_thresh_priority_freq =
1366 mas_chan_params->reg_6g_thresh_priority_freq;
1367 }
1368
1369 #ifndef CONFIG_REG_CLIENT
1370 #ifdef CONFIG_AFC_SUPPORT
1371 #ifdef CONFIG_6G_FREQ_OVERLAP
reg_set_ap_pwr_type(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)1372 void reg_set_ap_pwr_type(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1373 {
1374 uint8_t *num_rules;
1375 bool is_6ghz_pdev;
1376
1377 is_6ghz_pdev = reg_is_range_overlap_6g(pdev_priv_obj->range_5g_low,
1378 pdev_priv_obj->range_5g_high);
1379
1380 if (!is_6ghz_pdev) {
1381 reg_debug("Not setting 6g_pwr_type for a non 6 GHz pdev");
1382 return;
1383 }
1384
1385 num_rules = pdev_priv_obj->reg_rules.num_of_6g_ap_reg_rules;
1386 if (pdev_priv_obj->reg_afc_dev_deployment_type ==
1387 AFC_DEPLOYMENT_OUTDOOR) {
1388 if (num_rules[REG_VERY_LOW_POWER_AP])
1389 pdev_priv_obj->reg_cur_6g_ap_pwr_type =
1390 REG_VERY_LOW_POWER_AP;
1391 else
1392 pdev_priv_obj->reg_cur_6g_ap_pwr_type =
1393 REG_STANDARD_POWER_AP;
1394 } else {
1395 if (num_rules[REG_INDOOR_AP])
1396 pdev_priv_obj->reg_cur_6g_ap_pwr_type =
1397 REG_INDOOR_AP;
1398 else if (num_rules[REG_VERY_LOW_POWER_AP])
1399 pdev_priv_obj->reg_cur_6g_ap_pwr_type =
1400 REG_VERY_LOW_POWER_AP;
1401 else
1402 pdev_priv_obj->reg_cur_6g_ap_pwr_type =
1403 REG_INDOOR_AP;
1404 }
1405 }
1406 #else
reg_set_ap_pwr_type(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)1407 void reg_set_ap_pwr_type(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1408 {
1409 }
1410 #endif /* CONFIG_6G_FREQ_OVERLAP */
1411 #else
reg_set_ap_pwr_type(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)1412 void reg_set_ap_pwr_type(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1413 {
1414 pdev_priv_obj->reg_cur_6g_ap_pwr_type = REG_INDOOR_AP;
1415 }
1416 #endif /* CONFIG_AFC_SUPPORT */
1417 #else
reg_set_ap_pwr_type(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)1418 void reg_set_ap_pwr_type(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1419 {
1420 enum reg_6g_ap_type ap_pwr_type = REG_CURRENT_MAX_AP_TYPE;
1421 uint8_t *num_rules;
1422
1423 num_rules = pdev_priv_obj->reg_rules.num_of_6g_ap_reg_rules;
1424
1425 if (wlan_reg_is_afc_power_event_received(pdev_priv_obj->pdev_ptr) &&
1426 num_rules[REG_STANDARD_POWER_AP]) {
1427 ap_pwr_type = REG_STANDARD_POWER_AP;
1428 } else if (pdev_priv_obj->indoor_chan_enabled) {
1429 if (num_rules[REG_INDOOR_AP])
1430 ap_pwr_type = REG_INDOOR_AP;
1431 else if (num_rules[REG_VERY_LOW_POWER_AP])
1432 ap_pwr_type = REG_VERY_LOW_POWER_AP;
1433 } else if (num_rules[REG_VERY_LOW_POWER_AP]) {
1434 ap_pwr_type = REG_VERY_LOW_POWER_AP;
1435 }
1436
1437 pdev_priv_obj->reg_cur_6g_ap_pwr_type = ap_pwr_type;
1438
1439 reg_debug("indoor_chan_enabled %d ap_pwr_type %d",
1440 pdev_priv_obj->indoor_chan_enabled, ap_pwr_type);
1441 }
1442 #endif /* CONFIG_REG_CLIENT */
1443 #else
reg_propagate_6g_mas_channel_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,struct mas_chan_params * mas_chan_params)1444 static inline void reg_propagate_6g_mas_channel_list(
1445 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
1446 struct mas_chan_params *mas_chan_params)
1447 {
1448 }
1449 #endif /* CONFIG_BAND_6GHZ */
1450
reg_init_pdev_mas_chan_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,struct mas_chan_params * mas_chan_params)1451 void reg_init_pdev_mas_chan_list(
1452 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
1453 struct mas_chan_params *mas_chan_params)
1454 {
1455 qdf_mem_copy(pdev_priv_obj->mas_chan_list,
1456 mas_chan_params->mas_chan_list,
1457 NUM_CHANNELS * sizeof(struct regulatory_channel));
1458
1459 reg_propagate_6g_mas_channel_list(pdev_priv_obj, mas_chan_params);
1460
1461 pdev_priv_obj->dfs_region = mas_chan_params->dfs_region;
1462
1463 pdev_priv_obj->phybitmap = mas_chan_params->phybitmap;
1464
1465 pdev_priv_obj->reg_dmn_pair = mas_chan_params->reg_dmn_pair;
1466 pdev_priv_obj->ctry_code = mas_chan_params->ctry_code;
1467
1468 pdev_priv_obj->def_region_domain = mas_chan_params->reg_dmn_pair;
1469 pdev_priv_obj->def_country_code = mas_chan_params->ctry_code;
1470 qdf_mem_copy(pdev_priv_obj->default_country,
1471 mas_chan_params->default_country, REG_ALPHA2_LEN + 1);
1472
1473 qdf_mem_copy(pdev_priv_obj->current_country,
1474 mas_chan_params->current_country, REG_ALPHA2_LEN + 1);
1475 }
1476
1477 /**
1478 * reg_modify_chan_list_for_cached_channels() - If num_cache_channels are
1479 * non-zero, then disable the pdev channels which is given in
1480 * cache_disable_chan_list.
1481 * @pdev_priv_obj: Pointer to regulatory pdev private object.
1482 */
1483 #ifdef DISABLE_CHANNEL_LIST
reg_modify_chan_list_for_cached_channels(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)1484 static void reg_modify_chan_list_for_cached_channels(
1485 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1486 {
1487 uint32_t i, j;
1488 uint32_t num_cache_channels = pdev_priv_obj->num_cache_channels;
1489 struct regulatory_channel *cur_chan_list = pdev_priv_obj->cur_chan_list;
1490 struct regulatory_channel *sec_chan_list =
1491 pdev_priv_obj->secondary_cur_chan_list;
1492 struct regulatory_channel *cache_chan_list =
1493 pdev_priv_obj->cache_disable_chan_list;
1494
1495 if (!num_cache_channels)
1496 return;
1497
1498 if (pdev_priv_obj->disable_cached_channels) {
1499 for (i = 0; i < num_cache_channels; i++) {
1500 for (j = 0; j < NUM_CHANNELS; j++) {
1501 if (cache_chan_list[i].center_freq ==
1502 cur_chan_list[j].center_freq) {
1503 cur_chan_list[j].state =
1504 CHANNEL_STATE_DISABLE;
1505 cur_chan_list[j].chan_flags |=
1506 REGULATORY_CHAN_DISABLED;
1507 }
1508 if (cache_chan_list[i].center_freq ==
1509 sec_chan_list[j].center_freq) {
1510 sec_chan_list[j].state =
1511 CHANNEL_STATE_DISABLE;
1512 sec_chan_list[j].chan_flags |=
1513 REGULATORY_CHAN_DISABLED;
1514 }
1515 }
1516 }
1517 }
1518 }
1519 #else
reg_modify_chan_list_for_cached_channels(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)1520 static void reg_modify_chan_list_for_cached_channels(
1521 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1522 {
1523 }
1524 #endif
1525
1526 #ifdef CONFIG_REG_CLIENT
1527 /**
1528 * reg_modify_chan_list_for_srd_channels() - Modify SRD channels in ETSI13
1529 * @pdev: Pointer to pdev object
1530 * @chan_list: Current channel list
1531 *
1532 * This function converts SRD channels to passive in ETSI13 regulatory domain
1533 * when enable_srd_chan_in_master_mode is not set.
1534 */
1535 static void
reg_modify_chan_list_for_srd_channels(struct wlan_objmgr_pdev * pdev,struct regulatory_channel * chan_list)1536 reg_modify_chan_list_for_srd_channels(struct wlan_objmgr_pdev *pdev,
1537 struct regulatory_channel *chan_list)
1538 {
1539 enum channel_enum chan_enum;
1540
1541 if (!reg_is_etsi_regdmn(pdev))
1542 return;
1543
1544 if (reg_is_etsi_srd_chan_allowed_master_mode(pdev))
1545 return;
1546
1547 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
1548 if (chan_list[chan_enum].chan_flags & REGULATORY_CHAN_DISABLED)
1549 continue;
1550
1551 if (reg_is_etsi_srd_chan_for_freq(
1552 pdev,
1553 chan_list[chan_enum].center_freq)) {
1554 chan_list[chan_enum].state =
1555 CHANNEL_STATE_DFS;
1556 chan_list[chan_enum].chan_flags |=
1557 REGULATORY_CHAN_NO_IR;
1558 }
1559 }
1560 }
1561 #else
1562 static inline void
reg_modify_chan_list_for_srd_channels(struct wlan_objmgr_pdev * pdev,struct regulatory_channel * chan_list)1563 reg_modify_chan_list_for_srd_channels(struct wlan_objmgr_pdev *pdev,
1564 struct regulatory_channel *chan_list)
1565 {
1566 }
1567 #endif
1568
1569 #ifdef CONFIG_REG_CLIENT
1570
1571 /**
1572 * reg_is_disabling_5dot9_needed() - Checks if 5.9GHz channels should
1573 * be disabled.
1574 * @psoc: Pointer to psoc object
1575 *
1576 * This function checks only if F/W has enabled the BDF bit for 5.9GHz
1577 * channels for AP target and both the BDF bit as well as if offload is
1578 * enabled for STA target.
1579 */
1580 static inline bool
reg_is_disabling_5dot9_needed(struct wlan_objmgr_psoc * psoc)1581 reg_is_disabling_5dot9_needed(struct wlan_objmgr_psoc *psoc)
1582 {
1583 return (!reg_is_5dot9_ghz_supported(psoc) ||
1584 !reg_is_regdb_offloaded(psoc));
1585 }
1586 #else
1587 static inline bool
reg_is_disabling_5dot9_needed(struct wlan_objmgr_psoc * psoc)1588 reg_is_disabling_5dot9_needed(struct wlan_objmgr_psoc *psoc)
1589 {
1590 return (!reg_is_5dot9_ghz_supported(psoc));
1591 }
1592 #endif
1593
1594 /**
1595 * reg_modify_chan_list_for_5dot9_ghz_channels() - Modify 5.9 GHz channels
1596 * in FCC
1597 * @pdev: Pointer to pdev object
1598 * @chan_list: Current channel list
1599 *
1600 * This function disables 5.9 GHz channels if service bit
1601 * wmi_service_5dot9_ghz_support is not set or the reg db is not offloaded
1602 * to FW. If service bit is set but ini enable_5dot9_ghz_chan_in_master_mode
1603 * is not set, it converts these channels to passive in FCC regulatory domain.
1604 * If both service bit and ini are set, the channels remain enabled.
1605 */
1606 static void
reg_modify_chan_list_for_5dot9_ghz_channels(struct wlan_objmgr_pdev * pdev,struct regulatory_channel * chan_list)1607 reg_modify_chan_list_for_5dot9_ghz_channels(struct wlan_objmgr_pdev *pdev,
1608 struct regulatory_channel
1609 *chan_list)
1610 {
1611 enum channel_enum chan_enum;
1612 struct wlan_objmgr_psoc *psoc;
1613
1614 psoc = wlan_pdev_get_psoc(pdev);
1615
1616 if (!reg_is_fcc_regdmn(pdev))
1617 return;
1618
1619 if (reg_is_disabling_5dot9_needed(psoc)) {
1620 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
1621 if (reg_is_5dot9_ghz_freq(pdev, chan_list[chan_enum].
1622 center_freq)) {
1623 chan_list[chan_enum].state =
1624 CHANNEL_STATE_DISABLE;
1625 chan_list[chan_enum].chan_flags =
1626 REGULATORY_CHAN_DISABLED;
1627 }
1628 }
1629 return;
1630 }
1631
1632 if (reg_is_5dot9_ghz_chan_allowed_master_mode(pdev))
1633 return;
1634
1635 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
1636 if (chan_list[chan_enum].chan_flags & REGULATORY_CHAN_DISABLED)
1637 continue;
1638
1639 if (reg_is_5dot9_ghz_freq(pdev,
1640 chan_list[chan_enum].center_freq)) {
1641 chan_list[chan_enum].state =
1642 CHANNEL_STATE_DFS;
1643 chan_list[chan_enum].chan_flags |=
1644 REGULATORY_CHAN_NO_IR;
1645 }
1646 }
1647 }
1648
1649 #if defined(CONFIG_BAND_6GHZ)
1650 /**
1651 * reg_modify_chan_list_for_6g_edge_channels() - Modify 6 GHz edge channels
1652 *
1653 * @pdev: Pointer to pdev object
1654 * @chan_list: Current channel list
1655 *
1656 * This function disables lower 6G edge channel (5935MHz) if service bit
1657 * wmi_service_lower_6g_edge_ch_supp is not set. If service bit is set
1658 * the channels remain enabled. It disables upper 6G edge channel (7115MHz)
1659 * if the service bit wmi_service_disable_upper_6g_edge_ch_supp is set, it
1660 * is enabled by default.
1661 *
1662 */
1663 static void
reg_modify_chan_list_for_6g_edge_channels(struct wlan_objmgr_pdev * pdev,struct regulatory_channel * chan_list)1664 reg_modify_chan_list_for_6g_edge_channels(struct wlan_objmgr_pdev *pdev,
1665 struct regulatory_channel
1666 *chan_list)
1667 {
1668 struct wlan_objmgr_psoc *psoc;
1669
1670 psoc = wlan_pdev_get_psoc(pdev);
1671
1672 if (!reg_is_lower_6g_edge_ch_supp(psoc)) {
1673 chan_list[CHAN_ENUM_5935].state = CHANNEL_STATE_DISABLE;
1674 chan_list[CHAN_ENUM_5935].chan_flags |=
1675 REGULATORY_CHAN_DISABLED;
1676 }
1677
1678 if (reg_is_upper_6g_edge_ch_disabled(psoc)) {
1679 chan_list[CHAN_ENUM_7115].state = CHANNEL_STATE_DISABLE;
1680 chan_list[CHAN_ENUM_7115].chan_flags |=
1681 REGULATORY_CHAN_DISABLED;
1682 }
1683 }
1684 #else
1685 static inline void
reg_modify_chan_list_for_6g_edge_channels(struct wlan_objmgr_pdev * pdev,struct regulatory_channel * chan_list)1686 reg_modify_chan_list_for_6g_edge_channels(struct wlan_objmgr_pdev *pdev,
1687 struct regulatory_channel
1688 *chan_list)
1689 {
1690 }
1691 #endif
1692
1693 #ifdef DISABLE_UNII_SHARED_BANDS
1694 /**
1695 * reg_is_reg_unii_band_1_set() - Check UNII bitmap
1696 * @unii_bitmap: 5G UNII band bitmap
1697 *
1698 * This function checks the input bitmap to disable UNII-1 band channels.
1699 *
1700 * Return: Return true if UNII-1 channels need to be disabled,
1701 * else return false.
1702 */
reg_is_reg_unii_band_1_set(uint8_t unii_bitmap)1703 static bool reg_is_reg_unii_band_1_set(uint8_t unii_bitmap)
1704 {
1705 return !!(unii_bitmap & BIT(REG_UNII_BAND_1));
1706 }
1707
1708 /**
1709 * reg_is_reg_unii_band_2a_set() - Check UNII bitmap
1710 * @unii_bitmap: 5G UNII band bitmap
1711 *
1712 * This function checks the input bitmap to disable UNII-2A band channels.
1713 *
1714 * Return: Return true if UNII-2A channels need to be disabled,
1715 * else return false.
1716 */
reg_is_reg_unii_band_2a_set(uint8_t unii_bitmap)1717 static bool reg_is_reg_unii_band_2a_set(uint8_t unii_bitmap)
1718 {
1719 return !!(unii_bitmap & BIT(REG_UNII_BAND_2A));
1720 }
1721
1722 /**
1723 * reg_is_5g_enum() - Check if channel enum is a 5G channel enum
1724 * @chan_enum: channel enum
1725 *
1726 * Return: Return true if the input channel enum is 5G, else return false.
1727 */
reg_is_5g_enum(enum channel_enum chan_enum)1728 static bool reg_is_5g_enum(enum channel_enum chan_enum)
1729 {
1730 return (chan_enum >= MIN_5GHZ_CHANNEL && chan_enum <= MAX_5GHZ_CHANNEL);
1731 }
1732
1733 /**
1734 * reg_remove_unii_chan_from_chan_list() - Remove UNII band channels
1735 * @chan_list: Pointer to current channel list
1736 * @start_enum: starting enum value
1737 * @end_enum: ending enum value
1738 *
1739 * Remove channels in a unii band based in on the input start_enum and end_enum.
1740 * Disable the state and flags. Set disable_coex flag to true.
1741 *
1742 * return: void.
1743 */
1744 static void
reg_remove_unii_chan_from_chan_list(struct regulatory_channel * chan_list,enum channel_enum start_enum,enum channel_enum end_enum)1745 reg_remove_unii_chan_from_chan_list(struct regulatory_channel *chan_list,
1746 enum channel_enum start_enum,
1747 enum channel_enum end_enum)
1748 {
1749 enum channel_enum chan_enum;
1750
1751 if (!(reg_is_5g_enum(start_enum) && reg_is_5g_enum(end_enum))) {
1752 reg_err_rl("start_enum or end_enum is invalid");
1753 return;
1754 }
1755
1756 for (chan_enum = start_enum; chan_enum <= end_enum; chan_enum++) {
1757 chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
1758 chan_list[chan_enum].chan_flags |= REGULATORY_CHAN_DISABLED;
1759 }
1760 }
1761
1762 /**
1763 * reg_modify_disable_chan_list_for_unii1_and_unii2a() - Disable UNII-1 and
1764 * UNII2A band
1765 * @pdev_priv_obj: Pointer to pdev private object
1766 *
1767 * This function disables the UNII-1 and UNII-2A band channels
1768 * based on input unii_5g_bitmap.
1769 *
1770 * Return: void.
1771 */
1772 static void
reg_modify_disable_chan_list_for_unii1_and_unii2a(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)1773 reg_modify_disable_chan_list_for_unii1_and_unii2a(
1774 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1775 {
1776 uint8_t unii_bitmap = pdev_priv_obj->unii_5g_bitmap;
1777 struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list;
1778
1779 if (reg_is_reg_unii_band_1_set(unii_bitmap)) {
1780 reg_remove_unii_chan_from_chan_list(chan_list,
1781 MIN_UNII_1_BAND_CHANNEL,
1782 MAX_UNII_1_BAND_CHANNEL);
1783 }
1784
1785 if (reg_is_reg_unii_band_2a_set(unii_bitmap)) {
1786 reg_remove_unii_chan_from_chan_list(chan_list,
1787 MIN_UNII_2A_BAND_CHANNEL,
1788 MAX_UNII_2A_BAND_CHANNEL);
1789 }
1790 }
1791 #else
reg_is_reg_unii_band_1_set(uint8_t unii_bitmap)1792 static inline bool reg_is_reg_unii_band_1_set(uint8_t unii_bitmap)
1793 {
1794 return false;
1795 }
1796
reg_is_reg_unii_band_2a_set(uint8_t unii_bitmap)1797 static inline bool reg_is_reg_unii_band_2a_set(uint8_t unii_bitmap)
1798 {
1799 return false;
1800 }
1801
reg_is_5g_enum(enum channel_enum chan_enum)1802 static inline bool reg_is_5g_enum(enum channel_enum chan_enum)
1803 {
1804 return false;
1805 }
1806
1807 static inline void
reg_remove_unii_chan_from_chan_list(struct regulatory_channel * chan_list,enum channel_enum start_enum,enum channel_enum end_enum)1808 reg_remove_unii_chan_from_chan_list(struct regulatory_channel *chan_list,
1809 enum channel_enum start_enum,
1810 enum channel_enum end_enum)
1811 {
1812 }
1813
1814 static inline void
reg_modify_disable_chan_list_for_unii1_and_unii2a(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)1815 reg_modify_disable_chan_list_for_unii1_and_unii2a(
1816 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
1817 {
1818 }
1819 #endif
1820
1821 #ifdef CONFIG_BAND_6GHZ
1822 #ifdef CONFIG_REG_CLIENT
1823
1824 #ifdef CONFIG_AFC_SUPPORT
1825 /**
1826 * reg_append_mas_chan_list_for_6g_sp() - Append SP channels to the master
1827 * channel list
1828 * @pdev_priv_obj: Pointer to pdev private object
1829 *
1830 * This function appends SP channels to the master channel list
1831 *
1832 * Return: void.
1833 */
1834 static void
reg_append_mas_chan_list_for_6g_sp(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)1835 reg_append_mas_chan_list_for_6g_sp(struct wlan_regulatory_pdev_priv_obj
1836 *pdev_priv_obj)
1837 {
1838 struct regulatory_channel *master_chan_list_6g_client_sp;
1839
1840 master_chan_list_6g_client_sp = pdev_priv_obj->afc_chan_list;
1841
1842 qdf_mem_copy(&pdev_priv_obj->mas_chan_list[MIN_6GHZ_CHANNEL],
1843 master_chan_list_6g_client_sp,
1844 NUM_6GHZ_CHANNELS *
1845 sizeof(struct regulatory_channel));
1846 }
1847 #else
1848 static void
reg_append_mas_chan_list_for_6g_sp(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)1849 reg_append_mas_chan_list_for_6g_sp(struct wlan_regulatory_pdev_priv_obj
1850 *pdev_priv_obj)
1851 {
1852 struct regulatory_channel *master_chan_list_6g_client_sp;
1853 uint8_t i, j;
1854
1855 if (!pdev_priv_obj->reg_rules.num_of_6g_client_reg_rules[REG_STANDARD_POWER_AP]) {
1856 reg_debug("No SP reg rules");
1857 return;
1858 }
1859
1860 master_chan_list_6g_client_sp =
1861 pdev_priv_obj->mas_chan_list_6g_client[REG_STANDARD_POWER_AP]
1862 [pdev_priv_obj->reg_cur_6g_client_mobility_type];
1863
1864 for (i = MIN_6GHZ_CHANNEL, j = 0;
1865 i <= MAX_6GHZ_CHANNEL && j < NUM_6GHZ_CHANNELS; i++, j++) {
1866 if (pdev_priv_obj->mas_chan_list[i].state ==
1867 CHANNEL_STATE_DISABLE ||
1868 pdev_priv_obj->mas_chan_list[i].chan_flags &
1869 REGULATORY_CHAN_DISABLED) {
1870 qdf_mem_copy(&pdev_priv_obj->mas_chan_list[i],
1871 &master_chan_list_6g_client_sp[j],
1872 sizeof(struct regulatory_channel));
1873 pdev_priv_obj->mas_chan_list[i].power_type =
1874 REG_STANDARD_POWER_AP;
1875 }
1876 }
1877 }
1878 #endif
1879
1880 /**
1881 * reg_append_mas_chan_list_for_6g_lpi() - Append LPI channels to the master
1882 * channel list
1883 * @pdev_priv_obj: Pointer to pdev private object
1884 *
1885 * This function appends LPI channels to the master channel list
1886 *
1887 * Return: void.
1888 */
1889 static void
reg_append_mas_chan_list_for_6g_lpi(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)1890 reg_append_mas_chan_list_for_6g_lpi(struct wlan_regulatory_pdev_priv_obj
1891 *pdev_priv_obj)
1892 {
1893 struct regulatory_channel *master_chan_list_6g_client_lpi;
1894 uint8_t i, j;
1895
1896 if (!pdev_priv_obj->reg_rules.num_of_6g_client_reg_rules[REG_INDOOR_AP]) {
1897 reg_debug("No LPI reg rules");
1898 return;
1899 }
1900
1901 master_chan_list_6g_client_lpi =
1902 pdev_priv_obj->mas_chan_list_6g_client[REG_INDOOR_AP]
1903 [pdev_priv_obj->reg_cur_6g_client_mobility_type];
1904
1905 for (i = MIN_6GHZ_CHANNEL, j = 0;
1906 i <= MAX_6GHZ_CHANNEL && j < NUM_6GHZ_CHANNELS; i++, j++) {
1907 if ((pdev_priv_obj->mas_chan_list[i].state ==
1908 CHANNEL_STATE_DISABLE) ||
1909 (pdev_priv_obj->mas_chan_list[i].chan_flags &
1910 REGULATORY_CHAN_DISABLED)) {
1911 qdf_mem_copy(&pdev_priv_obj->mas_chan_list[i],
1912 &master_chan_list_6g_client_lpi[j],
1913 sizeof(struct regulatory_channel));
1914 pdev_priv_obj->mas_chan_list[i].power_type =
1915 REG_INDOOR_AP;
1916 }
1917 }
1918 }
1919
1920 /**
1921 * reg_append_mas_chan_list_for_6g_vlp() - Append VLP channels to the master
1922 * channel list
1923 * @pdev_priv_obj: Pointer to pdev private object
1924 *
1925 * This function appends VLP channels to the master channel list
1926 *
1927 * Return: void.
1928 */
1929 static void
reg_append_mas_chan_list_for_6g_vlp(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)1930 reg_append_mas_chan_list_for_6g_vlp(struct wlan_regulatory_pdev_priv_obj
1931 *pdev_priv_obj)
1932 {
1933 struct regulatory_channel *master_chan_list_6g_client_vlp;
1934 uint8_t i, j;
1935
1936 if (!pdev_priv_obj->reg_rules.num_of_6g_client_reg_rules[REG_VERY_LOW_POWER_AP]) {
1937 reg_debug("No VLP reg rules");
1938 return;
1939 }
1940
1941 master_chan_list_6g_client_vlp =
1942 pdev_priv_obj->mas_chan_list_6g_client[REG_VERY_LOW_POWER_AP]
1943 [pdev_priv_obj->reg_cur_6g_client_mobility_type];
1944
1945 for (i = MIN_6GHZ_CHANNEL, j = 0;
1946 i <= MAX_6GHZ_CHANNEL && j < NUM_6GHZ_CHANNELS; i++, j++) {
1947 if ((pdev_priv_obj->mas_chan_list[i].state ==
1948 CHANNEL_STATE_DISABLE) ||
1949 (pdev_priv_obj->mas_chan_list[i].chan_flags &
1950 REGULATORY_CHAN_DISABLED)) {
1951 qdf_mem_copy(&pdev_priv_obj->mas_chan_list[i],
1952 &master_chan_list_6g_client_vlp[j],
1953 sizeof(struct regulatory_channel));
1954 pdev_priv_obj->mas_chan_list[i].power_type =
1955 REG_VERY_LOW_POWER_AP;
1956 }
1957 }
1958 }
1959
1960 static void
reg_append_mas_chan_list_for_6g(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)1961 reg_append_mas_chan_list_for_6g(struct wlan_regulatory_pdev_priv_obj
1962 *pdev_priv_obj)
1963 {
1964 if (pdev_priv_obj->reg_cur_6g_client_mobility_type >=
1965 REG_MAX_CLIENT_TYPE) {
1966 reg_debug("invalid 6G AP or client power type");
1967 return;
1968 }
1969
1970 /* Client should be able to scan all types of APs, so prepare the
1971 * client list which has all the enabled channels, first priority is
1972 * given to AFC power type and then second priority is decided based on
1973 * gindoor_channel_support ini value
1974 */
1975
1976 if (pdev_priv_obj->indoor_chan_enabled) {
1977 reg_append_mas_chan_list_for_6g_lpi(pdev_priv_obj);
1978 reg_append_mas_chan_list_for_6g_vlp(pdev_priv_obj);
1979 } else {
1980 reg_append_mas_chan_list_for_6g_vlp(pdev_priv_obj);
1981 reg_append_mas_chan_list_for_6g_lpi(pdev_priv_obj);
1982 }
1983
1984 reg_append_mas_chan_list_for_6g_sp(pdev_priv_obj);
1985 }
1986
1987 /**
1988 * reg_dump_valid_6ghz_channel_list() - Function to print valid 6 GHz channel
1989 * list state and attribute.
1990 * @chan: Pointer to array of 6 GHz channel list
1991 *
1992 * Return: None
1993 */
1994 static void
reg_dump_valid_6ghz_channel_list(struct regulatory_channel * chan)1995 reg_dump_valid_6ghz_channel_list(struct regulatory_channel *chan)
1996 {
1997 #define MAX_CHAN_LOG_ONE_LINE 18
1998 uint32_t buf_size = MAX_CHAN_LOG_ONE_LINE * 24 + 1;
1999 uint8_t *buf;
2000 uint32_t i, len = 0, count = 0;
2001
2002 buf = qdf_mem_malloc(buf_size);
2003 if (!buf)
2004 return;
2005
2006 for (i = MIN_6GHZ_CHANNEL; i <= MAX_6GHZ_CHANNEL; i++, chan++) {
2007 if (chan->state == CHANNEL_STATE_DISABLE)
2008 continue;
2009 len += qdf_scnprintf(buf + len, buf_size - len,
2010 "%d:%d:%d:%d:%d:%x ",
2011 chan->center_freq, chan->state,
2012 chan->psd_flag, chan->tx_power,
2013 (int16_t)chan->psd_eirp,
2014 chan->chan_flags);
2015 count++;
2016 if (count >= MAX_CHAN_LOG_ONE_LINE) {
2017 reg_nofl_debug("%s", buf);
2018 count = 0;
2019 len = 0;
2020 }
2021 }
2022
2023 if (len)
2024 reg_nofl_debug("%s", buf);
2025
2026 qdf_mem_free(buf);
2027 }
2028
2029 /**
2030 * reg_dump_valid_6ghz_cur_chan_list() - API to dump pdev current/secondary
2031 * channel list state
2032 * @pdev_priv_obj: pointer to pdev private object
2033 *
2034 * Return: None
2035 */
2036 static void
reg_dump_valid_6ghz_cur_chan_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)2037 reg_dump_valid_6ghz_cur_chan_list(struct wlan_regulatory_pdev_priv_obj
2038 *pdev_priv_obj)
2039 {
2040 reg_debug("sta freq:state:ispsd:pwr:psd:flags(hex):");
2041 reg_dump_valid_6ghz_channel_list(
2042 &pdev_priv_obj->cur_chan_list[MIN_6GHZ_CHANNEL]);
2043 reg_debug("sap freq:state:ispsd:pwr:psd:flags(hex):");
2044 reg_dump_valid_6ghz_channel_list(
2045 &pdev_priv_obj->secondary_cur_chan_list[MIN_6GHZ_CHANNEL]);
2046 }
2047
2048 #ifdef CONFIG_AFC_SUPPORT
2049 /**
2050 * reg_populate_afc_secondary_cur_chan_list() - Function to populate AFC
2051 * channel list to secondary current channel list
2052 * @pdev_priv_obj: Pointer to pdev regulatory private object
2053 * @chan_list: Pointer to array of 6 GHz channel list
2054 *
2055 * Return: None
2056 */
reg_populate_afc_secondary_cur_chan_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,struct regulatory_channel * chan_list)2057 static void reg_populate_afc_secondary_cur_chan_list(
2058 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
2059 struct regulatory_channel *chan_list)
2060 {
2061 uint32_t i;
2062 struct regulatory_channel *afc_chan_list;
2063 struct regulatory_channel *sp_chan_list;
2064
2065 if (!pdev_priv_obj->is_6g_afc_power_event_received)
2066 return;
2067
2068 afc_chan_list = pdev_priv_obj->afc_chan_list;
2069 sp_chan_list = pdev_priv_obj->
2070 mas_chan_list_6g_ap[REG_STANDARD_POWER_AP];
2071 for (i = 0; i < NUM_6GHZ_CHANNELS; i++) {
2072 if (afc_chan_list[i].state == CHANNEL_STATE_DISABLE &&
2073 sp_chan_list[i].state == CHANNEL_STATE_ENABLE) {
2074 chan_list[i].state = CHANNEL_STATE_DISABLE;
2075 chan_list[i].chan_flags |= REGULATORY_CHAN_DISABLED;
2076 } else if (afc_chan_list[i].state == CHANNEL_STATE_ENABLE) {
2077 qdf_mem_copy(&chan_list[i],
2078 &afc_chan_list[i],
2079 sizeof(chan_list[i]));
2080 chan_list[i].chan_flags |= REGULATORY_CHAN_AFC;
2081 }
2082 }
2083 }
2084 #else
reg_populate_afc_secondary_cur_chan_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,struct regulatory_channel * chan_list)2085 static inline void reg_populate_afc_secondary_cur_chan_list(
2086 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
2087 struct regulatory_channel *chan_list)
2088 {
2089 }
2090 #endif
2091
2092 static void
reg_populate_secondary_cur_chan_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)2093 reg_populate_secondary_cur_chan_list(struct wlan_regulatory_pdev_priv_obj
2094 *pdev_priv_obj)
2095 {
2096 struct wlan_objmgr_psoc *psoc;
2097 struct wlan_lmac_if_reg_tx_ops *reg_tx_ops;
2098 struct wlan_regulatory_psoc_priv_obj *soc_reg;
2099 struct regulatory_channel *chan_list;
2100 uint32_t len_6ghz;
2101 enum reg_6g_ap_type cur_ap_power_type = REG_CURRENT_MAX_AP_TYPE;
2102
2103 psoc = wlan_pdev_get_psoc(pdev_priv_obj->pdev_ptr);
2104 if (!psoc) {
2105 reg_err("psoc is NULL");
2106 return;
2107 }
2108
2109 soc_reg = reg_get_psoc_obj(psoc);
2110 if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) {
2111 reg_err("psoc reg component is NULL");
2112 return;
2113 }
2114
2115 reg_tx_ops = reg_get_psoc_tx_ops(psoc);
2116 if (!reg_tx_ops) {
2117 reg_err("reg_tx_ops null");
2118 return;
2119 }
2120
2121 if (!reg_tx_ops->register_master_ext_handler ||
2122 !wlan_psoc_nif_fw_ext_cap_get(psoc, WLAN_SOC_EXT_EVENT_SUPPORTED)) {
2123 qdf_mem_copy(pdev_priv_obj->secondary_cur_chan_list,
2124 pdev_priv_obj->cur_chan_list,
2125 (NUM_CHANNELS) *
2126 sizeof(struct regulatory_channel));
2127 return;
2128 }
2129
2130 len_6ghz = NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel);
2131 chan_list = qdf_mem_malloc(len_6ghz);
2132 if (!chan_list)
2133 return;
2134
2135 reg_get_cur_6g_ap_pwr_type(pdev_priv_obj->pdev_ptr, &cur_ap_power_type);
2136
2137 if (cur_ap_power_type == REG_INDOOR_AP) {
2138 qdf_mem_copy(chan_list,
2139 pdev_priv_obj->mas_chan_list_6g_ap[REG_INDOOR_AP],
2140 len_6ghz);
2141 /* has flag REGULATORY_CHAN_INDOOR_ONLY */
2142 } else if (cur_ap_power_type == REG_VERY_LOW_POWER_AP) {
2143 qdf_mem_copy(chan_list,
2144 pdev_priv_obj->mas_chan_list_6g_ap
2145 [REG_VERY_LOW_POWER_AP],
2146 len_6ghz);
2147 } else {
2148 reg_init_6ghz_master_chan(chan_list, soc_reg);
2149 }
2150
2151 reg_populate_afc_secondary_cur_chan_list(pdev_priv_obj, chan_list);
2152
2153 qdf_mem_copy(pdev_priv_obj->secondary_cur_chan_list,
2154 pdev_priv_obj->cur_chan_list,
2155 (NUM_CHANNELS - NUM_6GHZ_CHANNELS) *
2156 sizeof(struct regulatory_channel));
2157 qdf_mem_copy(&pdev_priv_obj->secondary_cur_chan_list[MIN_6GHZ_CHANNEL],
2158 chan_list,
2159 len_6ghz);
2160 qdf_mem_free(chan_list);
2161
2162 reg_modify_secondary_cur_chan_list(pdev_priv_obj);
2163 reg_dump_valid_6ghz_cur_chan_list(pdev_priv_obj);
2164 }
2165 #else /* CONFIG_REG_CLIENT */
2166
2167 /**
2168 * reg_copy_ap_chan_list_to_mas_chan_list() - Copy the 6G ap channel list to
2169 * the MIN_6GHZ_CHANNEL index of the mas_chan_list based on the AP power type
2170 * In case of standard power type, if the afc channel list is available from
2171 * the afc server, use afc channel list (intersected with SP power list)
2172 * for the copy instead of using the standard power list directly.
2173 * @pdev_priv_obj: pointer to pdev_priv_obj.
2174 * @ap_pwr_type: 6G AP power type
2175 *
2176 * Return type: void.
2177 */
2178 #ifdef CONFIG_AFC_SUPPORT
2179 static void
reg_copy_ap_chan_list_to_mas_chan_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,enum reg_6g_ap_type ap_pwr_type)2180 reg_copy_ap_chan_list_to_mas_chan_list(struct wlan_regulatory_pdev_priv_obj
2181 *pdev_priv_obj,
2182 enum reg_6g_ap_type ap_pwr_type)
2183 {
2184 if (ap_pwr_type == REG_STANDARD_POWER_AP &&
2185 pdev_priv_obj->is_6g_afc_power_event_received) {
2186 qdf_mem_copy(&pdev_priv_obj->mas_chan_list[MIN_6GHZ_CHANNEL],
2187 pdev_priv_obj->afc_chan_list,
2188 NUM_6GHZ_CHANNELS *
2189 sizeof(struct regulatory_channel));
2190 } else {
2191 qdf_mem_copy(&pdev_priv_obj->mas_chan_list[MIN_6GHZ_CHANNEL],
2192 pdev_priv_obj->mas_chan_list_6g_ap[ap_pwr_type],
2193 NUM_6GHZ_CHANNELS *
2194 sizeof(struct regulatory_channel));
2195 }
2196 }
2197 #else
2198 static void
reg_copy_ap_chan_list_to_mas_chan_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,enum reg_6g_ap_type ap_pwr_type)2199 reg_copy_ap_chan_list_to_mas_chan_list(struct wlan_regulatory_pdev_priv_obj
2200 *pdev_priv_obj,
2201 enum reg_6g_ap_type ap_pwr_type)
2202 {
2203 qdf_mem_copy(&pdev_priv_obj->mas_chan_list[MIN_6GHZ_CHANNEL],
2204 pdev_priv_obj->mas_chan_list_6g_ap[ap_pwr_type],
2205 NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel));
2206 }
2207 #endif
2208 static void
reg_append_mas_chan_list_for_6g(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)2209 reg_append_mas_chan_list_for_6g(struct wlan_regulatory_pdev_priv_obj
2210 *pdev_priv_obj)
2211 {
2212 enum reg_6g_ap_type ap_pwr_type = pdev_priv_obj->reg_cur_6g_ap_pwr_type;
2213
2214 if (ap_pwr_type >= REG_CURRENT_MAX_AP_TYPE) {
2215 reg_debug("invalid 6G AP power type");
2216 return;
2217 }
2218
2219 reg_copy_ap_chan_list_to_mas_chan_list(pdev_priv_obj, ap_pwr_type);
2220 }
2221
2222 static inline void
reg_populate_secondary_cur_chan_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)2223 reg_populate_secondary_cur_chan_list(struct wlan_regulatory_pdev_priv_obj
2224 *pdev_priv_obj)
2225 {
2226 }
2227 #endif /* CONFIG_REG_CLIENT */
2228
2229 #ifdef CONFIG_AFC_SUPPORT
2230 /**
2231 * reg_intersect_6g_afc_chan_list() - Do intersection of tx_powers of AFC master
2232 * channel list and SP channel list and store the power in the AFC channel list.
2233 * @pdev_priv_obj: pointer to pdev_priv_obj.
2234 *
2235 * Return type: void.
2236 */
2237 static void
reg_intersect_6g_afc_chan_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)2238 reg_intersect_6g_afc_chan_list(struct wlan_regulatory_pdev_priv_obj
2239 *pdev_priv_obj)
2240 {
2241 struct regulatory_channel *afc_chan_list;
2242 struct regulatory_channel *afc_mas_chan_list;
2243 struct regulatory_channel *sp_chan_list;
2244 uint8_t i;
2245
2246 afc_chan_list = pdev_priv_obj->afc_chan_list;
2247 afc_mas_chan_list = pdev_priv_obj->mas_chan_list_6g_afc;
2248 sp_chan_list =
2249 pdev_priv_obj->mas_chan_list_6g_ap[REG_STANDARD_POWER_AP];
2250
2251 qdf_mem_copy(afc_chan_list, afc_mas_chan_list,
2252 NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel));
2253
2254 for (i = 0; i < NUM_6GHZ_CHANNELS; i++) {
2255 if ((afc_chan_list[i].state != CHANNEL_STATE_DISABLE) &&
2256 !(afc_chan_list[i].chan_flags &
2257 REGULATORY_CHAN_DISABLED)) {
2258 afc_chan_list[i].tx_power =
2259 QDF_MIN(sp_chan_list[i].tx_power,
2260 afc_mas_chan_list[i].tx_power);
2261 afc_chan_list[i].psd_eirp =
2262 QDF_MIN((int16_t)sp_chan_list[i].psd_eirp,
2263 (int16_t)afc_mas_chan_list[i].psd_eirp);
2264 afc_chan_list[i].chan_flags &=
2265 ~REGULATORY_CHAN_AFC_NOT_DONE;
2266 } else if ((pdev_priv_obj->reg_afc_dev_deployment_type ==
2267 AFC_DEPLOYMENT_OUTDOOR) &&
2268 (sp_chan_list[i].chan_flags &
2269 REGULATORY_CHAN_AFC_NOT_DONE)) {
2270 /* This is for the SP channels supported by
2271 * regulatory list that are not supported by AFC i.e.
2272 * SP channel list - AFC Channel list.
2273 */
2274 afc_chan_list[i].tx_power = sp_chan_list[i].tx_power;
2275 afc_chan_list[i].psd_eirp = sp_chan_list[i].psd_eirp;
2276 afc_chan_list[i].chan_flags &= ~REGULATORY_CHAN_DISABLED;
2277 afc_chan_list[i].chan_flags |= REGULATORY_CHAN_AFC_NOT_DONE;
2278 afc_chan_list[i].state = CHANNEL_STATE_ENABLE;
2279 }
2280 }
2281 }
2282
2283 /**
2284 * reg_modify_6g_afc_chan_list() - Modify the AFC channel list if the AFC WMI
2285 * power event is received from the target
2286 * @pdev_priv_obj: pointer to pdev_priv_obj.
2287 *
2288 * Return type: void.
2289 */
2290 static void
reg_modify_6g_afc_chan_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)2291 reg_modify_6g_afc_chan_list(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
2292 {
2293 if (pdev_priv_obj->is_6g_afc_power_event_received)
2294 reg_intersect_6g_afc_chan_list(pdev_priv_obj);
2295 }
2296 #else
2297 static inline void
reg_modify_6g_afc_chan_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)2298 reg_modify_6g_afc_chan_list(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
2299 {
2300 }
2301 #endif
2302
reg_copy_6g_cur_mas_chan_list_to_cmn(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)2303 static void reg_copy_6g_cur_mas_chan_list_to_cmn(
2304 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
2305 {
2306 if (pdev_priv_obj->is_6g_channel_list_populated)
2307 reg_append_mas_chan_list_for_6g(pdev_priv_obj);
2308 }
2309 #else /* CONFIG_BAND_6GHZ */
2310 static inline void
reg_copy_6g_cur_mas_chan_list_to_cmn(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)2311 reg_copy_6g_cur_mas_chan_list_to_cmn(
2312 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
2313 {
2314 }
2315
2316 static inline void
reg_append_mas_chan_list_for_6g(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)2317 reg_append_mas_chan_list_for_6g(
2318 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
2319 {
2320 }
2321
2322 #ifdef CONFIG_REG_CLIENT
2323 static void
reg_populate_secondary_cur_chan_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)2324 reg_populate_secondary_cur_chan_list(struct wlan_regulatory_pdev_priv_obj
2325 *pdev_priv_obj)
2326 {
2327 qdf_mem_copy(pdev_priv_obj->secondary_cur_chan_list,
2328 pdev_priv_obj->cur_chan_list,
2329 NUM_CHANNELS * sizeof(struct regulatory_channel));
2330 }
2331 #else /* CONFIG_REG_CLIENT */
2332 static inline void
reg_populate_secondary_cur_chan_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)2333 reg_populate_secondary_cur_chan_list(struct wlan_regulatory_pdev_priv_obj
2334 *pdev_priv_obj)
2335 {
2336 }
2337 #endif /* CONFIG_REG_CLIENT */
2338 static inline void
reg_modify_6g_afc_chan_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)2339 reg_modify_6g_afc_chan_list(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
2340 {
2341 }
2342 #endif /* CONFIG_BAND_6GHZ */
2343
2344 #if defined(CONFIG_BAND_6GHZ) && defined(CONFIG_REG_CLIENT)
2345 /**
2346 * reg_modify_sec_chan_list_for_6g_edge_chan() - Modify 6 GHz edge channels
2347 * for SAP (for MCC use case)
2348 *
2349 * @pdev_priv_obj: pointer to pdev_priv_obj.
2350 *
2351 * This is a wrapper function that calls the API
2352 * reg_modify_chan_list_for_6g_edge_channels() by passing secondary channel
2353 * list (used by beaconing entities like SAP). This API enables/disables 6GHz
2354 * edge channels ch2 (5935 MHz) and ch233 (7115 MHz) based on service bits.
2355 *
2356 */
2357 static void
reg_modify_sec_chan_list_for_6g_edge_chan(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)2358 reg_modify_sec_chan_list_for_6g_edge_chan(struct wlan_regulatory_pdev_priv_obj
2359 *pdev_priv_obj)
2360 {
2361 reg_modify_chan_list_for_6g_edge_channels(pdev_priv_obj->pdev_ptr,
2362 pdev_priv_obj->
2363 secondary_cur_chan_list);
2364 }
2365 #else
2366 static inline void
reg_modify_sec_chan_list_for_6g_edge_chan(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)2367 reg_modify_sec_chan_list_for_6g_edge_chan(struct wlan_regulatory_pdev_priv_obj
2368 *pdev_priv_obj)
2369 {
2370 }
2371 #endif
2372
2373 #ifdef FEATURE_WLAN_CH_AVOID_EXT
2374 struct chan_5g_center_freq center_5g[MAX_5G_CHAN_NUM] = {
2375 /*36*/
2376 {5180, 5190, 5210, 5250},
2377 /*40*/
2378 {5200, 5190, 5210, 5250},
2379 /*44*/
2380 {5220, 5230, 5210, 5250},
2381 /*48*/
2382 {5240, 5230, 5210, 5250},
2383
2384 /*52*/
2385 {5260, 5270, 5290, 5250},
2386 /*56*/
2387 {5280, 5270, 5290, 5250},
2388 /*60*/
2389 {5300, 5310, 5290, 5250},
2390 /*64*/
2391 {5320, 5310, 5290, 5250},
2392
2393 /*100*/
2394 {5500, 5510, 5530, 5570},
2395 /*104*/
2396 {5520, 5510, 5530, 5570},
2397 /*108*/
2398 {5540, 5550, 5530, 5570},
2399 /*112*/
2400 {5560, 5550, 5530, 5570},
2401
2402 /*116*/
2403 {5580, 5590, 5610, 5570},
2404 /*120*/
2405 {5600, 5590, 5610, 5570},
2406 /*124*/
2407 {5620, 5630, 5610, 5570},
2408 /*128*/
2409 {5640, 5630, 5610, 5570},
2410
2411 /*132*/
2412 {5660, 5670, 5690, INVALID_CENTER_FREQ},
2413 /*136*/
2414 {5680, 5670, 5690, INVALID_CENTER_FREQ},
2415 /*140*/
2416 {5700, 5710, 5690, INVALID_CENTER_FREQ},
2417 /*144*/
2418 {5720, 5710, 5690, INVALID_CENTER_FREQ},
2419
2420 /*149*/
2421 {5745, 5755, 5775, 5815},
2422 /*153*/
2423 {5765, 5755, 5775, 5815},
2424 /*157*/
2425 {5785, 5795, 5775, 5815},
2426 /*161*/
2427 {5805, 5795, 5775, 5815},
2428
2429 /*165*/
2430 {5825, 5835, 5855, 5815},
2431 /*169*/
2432 {5845, 5835, 5855, 5815},
2433 /*173*/
2434 {5865, 5875, 5855, 5815},
2435 /*177*/
2436 {5885, 5875, 5855, 5815},
2437 };
2438
2439 /**
2440 * reg_modify_5g_maxbw() - Update the max bandwidth for 5G channel
2441 * @chan: Pointer to current channel
2442 * @avoid_freq: current avoid frequency range
2443 *
2444 * This function updates the max bandwidth for the 5G channels if
2445 * it has overlap with avoid frequency range. For example, if the
2446 * avoid frequency range is []5755-5775], and current channel is 149 with
2447 * max bandwidth 80Mhz by default, then has to change the max bandwidth
2448 * to 20Mhz, since both 40Mhz [5735-5775] and 80M [5735-5815] has
2449 * overlap with avoid frequency [5755-5775].
2450 *
2451 * Return: void.
2452 */
2453 static void
reg_modify_5g_maxbw(struct regulatory_channel * chan,struct ch_avoid_freq_type * avoid_freq)2454 reg_modify_5g_maxbw(struct regulatory_channel *chan,
2455 struct ch_avoid_freq_type *avoid_freq)
2456 {
2457 int i;
2458 qdf_freq_t start = 0;
2459 qdf_freq_t end = 0;
2460 qdf_freq_t cur;
2461 bool found = false;
2462
2463 for (i = 0; i < MAX_5G_CHAN_NUM; i++) {
2464 cur = center_5g[i].center_freq_20;
2465 if (chan->center_freq == cur) {
2466 while (!found) {
2467 uint16_t h_bw;
2468
2469 if (chan->max_bw < 20 ||
2470 chan->max_bw > 160)
2471 break;
2472
2473 switch (chan->max_bw) {
2474 case 160:
2475 cur = center_5g[i].center_freq_160;
2476 if (!cur) {
2477 chan->max_bw = chan->max_bw / 2;
2478 break;
2479 }
2480 start = cur - HALF_160MHZ_BW;
2481 end = cur + HALF_160MHZ_BW;
2482 break;
2483 case 80:
2484 cur = center_5g[i].center_freq_80;
2485 start = cur - HALF_80MHZ_BW;
2486 end = cur + HALF_80MHZ_BW;
2487 break;
2488 case 40:
2489 cur = center_5g[i].center_freq_40;
2490 start = cur - HALF_40MHZ_BW;
2491 end = cur + HALF_40MHZ_BW;
2492 break;
2493 case 20:
2494 cur = center_5g[i].center_freq_20;
2495 start = cur - HALF_20MHZ_BW;
2496 end = cur + HALF_20MHZ_BW;
2497 break;
2498 default:
2499 break;
2500 }
2501
2502 if (avoid_freq->end_freq <= end &&
2503 avoid_freq->start_freq >= start) {
2504 /* avoid freq inside */
2505 h_bw = chan->max_bw / 2;
2506 chan->max_bw = min(chan->max_bw, h_bw);
2507 continue;
2508 } else if ((avoid_freq->start_freq > start &&
2509 avoid_freq->start_freq < end) ||
2510 (avoid_freq->end_freq > start &&
2511 avoid_freq->end_freq < end)) {
2512 /* avoid freq part overlap */
2513 h_bw = chan->max_bw / 2;
2514 chan->max_bw = min(chan->max_bw, h_bw);
2515 continue;
2516 } else if (avoid_freq->start_freq >= end ||
2517 avoid_freq->end_freq <= start) {
2518 /* beyond the range freq */
2519 found = true;
2520 }
2521 }
2522 }
2523 }
2524 }
2525
2526 /**
2527 * reg_modify_chan_list_for_avoid_chan_ext() - Update the state and bandwidth
2528 * for each channel in the current channel list.
2529 * @pdev_priv_obj: Pointer to wlan regulatory pdev private object.
2530 *
2531 * This function update the state and bandwidth for each channel in the current
2532 * channel list if it is affected by avoid frequency list.
2533 * For 2.4G/5G, all the center frequency of specific channel in the
2534 * avoid_chan_ext_list (avoid frequency list) will be disabled.
2535 * For example, avoid frequency list include [2412,2417,2422],
2536 * then channel 1, 2 and 3 will be disabled. Same logic apply for 5g.
2537 * For 5G, if the max bandwidth of the channel affected by avoid frequency
2538 * range then need to reduce the bandwidth or finally disabled.
2539 * For other bands, to-do in future if need.
2540 *
2541 * Return: void.
2542 */
2543 static void
reg_modify_chan_list_for_avoid_chan_ext(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)2544 reg_modify_chan_list_for_avoid_chan_ext(struct wlan_regulatory_pdev_priv_obj
2545 *pdev_priv_obj)
2546 {
2547 uint32_t i, j, k;
2548 struct wlan_objmgr_psoc *psoc;
2549 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
2550 uint32_t num_avoid_channels;
2551 struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list;
2552 struct regulatory_channel *sec_chan_list;
2553 uint16_t *avoid_chan_ext_list;
2554 uint32_t num_avoid_freq;
2555 struct ch_avoid_freq_type *avoid_freq_ext, *avoid_freq_ext_t;
2556
2557 sec_chan_list = pdev_priv_obj->secondary_cur_chan_list;
2558
2559 avoid_chan_ext_list = pdev_priv_obj->avoid_chan_ext_list.chan_freq_list;
2560 num_avoid_channels = pdev_priv_obj->avoid_chan_ext_list.chan_cnt;
2561
2562 psoc = wlan_pdev_get_psoc(pdev_priv_obj->pdev_ptr);
2563 if (!psoc)
2564 return;
2565
2566 if (!reg_check_coex_unsafe_chan_reg_disable(psoc)) {
2567 reg_debug("Don't disable reg channels for Coex unsafe channels");
2568 return;
2569 }
2570
2571 psoc_priv_obj = reg_get_psoc_obj(psoc);
2572 if (!psoc_priv_obj)
2573 return;
2574
2575 if (!num_avoid_channels || !psoc_priv_obj->ch_avoid_ext_ind)
2576 return;
2577
2578 num_avoid_freq = psoc_priv_obj->avoid_freq_ext_list.ch_avoid_range_cnt;
2579 avoid_freq_ext = psoc_priv_obj->avoid_freq_ext_list.avoid_freq_range;
2580
2581 for (i = 0; i < num_avoid_channels; i++)
2582 for (j = 0; j < NUM_CHANNELS; j++) {
2583 qdf_freq_t c_freq, avoid_tmp = avoid_chan_ext_list[i];
2584
2585 if (chan_list[j].state == CHANNEL_STATE_DISABLE)
2586 goto second_chan_handle;
2587
2588 /* For 2.4G, just only disable the channel if center
2589 * frequecy is in avoid_chan_ext_list.
2590 * For 5G, customer ask for bandwidth reduction if
2591 * it affect by the nearby channel that in the
2592 * avoid_chan_ext_list.
2593 * For example, if block out frequency range is
2594 * [5755-5775], then except for channel 153 need
2595 * to be disabled, and 149 has to change max 80Mhz
2596 * to 20Mhz, since 149 only has [5735-5755] available.
2597 * channel 157/161 [5775-5815] has to change max 80
2598 * to 40.
2599 * For 6G: to-do in future.
2600 */
2601 c_freq = chan_list[j].center_freq;
2602 if (avoid_tmp == c_freq) {
2603 chan_list[j].state = CHANNEL_STATE_DISABLE;
2604 chan_list[j].chan_flags |=
2605 REGULATORY_CHAN_DISABLED;
2606 } else if (reg_is_5ghz_ch_freq(c_freq)) {
2607 for (k = 0; k < num_avoid_freq; k++) {
2608 qdf_freq_t s_freq, e_freq;
2609
2610 avoid_freq_ext_t = &avoid_freq_ext[k];
2611 s_freq = avoid_freq_ext_t->start_freq;
2612 e_freq = avoid_freq_ext_t->end_freq;
2613
2614 /* need to cover [5170-5190] case*/
2615 if ((!reg_is_5ghz_ch_freq(s_freq) &&
2616 ((s_freq + HALF_20MHZ_BW) <
2617 reg_min_5ghz_chan_freq())) ||
2618 (!reg_is_5ghz_ch_freq(e_freq) &&
2619 ((e_freq - HALF_20MHZ_BW) >
2620 reg_max_5ghz_chan_freq())))
2621 continue;
2622
2623 /* if current center freq is in the
2624 * avoid rang, then skip it, it will be
2625 * handled in the branch (avoid_tmp
2626 * == c_freq)
2627 */
2628 if ((c_freq > s_freq &&
2629 c_freq < e_freq))
2630 continue;
2631
2632 reg_modify_5g_maxbw(&chan_list[j],
2633 avoid_freq_ext_t);
2634
2635 if (chan_list[j].max_bw <
2636 HALF_40MHZ_BW) {
2637 chan_list[j].state =
2638 CHANNEL_STATE_DISABLE;
2639 chan_list[j].chan_flags |=
2640 REGULATORY_CHAN_DISABLED;
2641 break;
2642 }
2643 }
2644 }
2645 second_chan_handle:
2646
2647 if (sec_chan_list[j].state ==
2648 CHANNEL_STATE_DISABLE)
2649 continue;
2650
2651 c_freq = sec_chan_list[j].center_freq;
2652 if (avoid_tmp == c_freq) {
2653 sec_chan_list[j].state = CHANNEL_STATE_DISABLE;
2654 sec_chan_list[j].chan_flags |=
2655 REGULATORY_CHAN_DISABLED;
2656 } else if (reg_is_5ghz_ch_freq(c_freq)) {
2657 for (k = 0; k < num_avoid_freq; k++) {
2658 qdf_freq_t s_freq, e_freq;
2659
2660 avoid_freq_ext_t = &avoid_freq_ext[k];
2661 s_freq = avoid_freq_ext_t->start_freq;
2662 e_freq = avoid_freq_ext_t->end_freq;
2663
2664 /* need to cover [5170-5190] case*/
2665 if ((!reg_is_5ghz_ch_freq(s_freq) &&
2666 ((s_freq + HALF_20MHZ_BW) <
2667 reg_min_5ghz_chan_freq())) ||
2668 (!reg_is_5ghz_ch_freq(e_freq) &&
2669 ((e_freq - HALF_20MHZ_BW) >
2670 reg_max_5ghz_chan_freq())))
2671 continue;
2672
2673 /* if current center freq is in the
2674 * avoid rang, then skip it, it will be
2675 * handled in the branch (avoid_tmp
2676 * == c_freq)
2677 */
2678 if ((c_freq > s_freq &&
2679 c_freq < e_freq))
2680 continue;
2681
2682 reg_modify_5g_maxbw(&sec_chan_list[j],
2683 avoid_freq_ext_t);
2684
2685 if (sec_chan_list[j].max_bw <
2686 HALF_40MHZ_BW) {
2687 sec_chan_list[j].state =
2688 CHANNEL_STATE_DISABLE;
2689 sec_chan_list[j].chan_flags |=
2690 REGULATORY_CHAN_DISABLED;
2691 break;
2692 }
2693 }
2694 }
2695 }
2696 }
2697 #else
2698 static inline void
reg_modify_chan_list_for_avoid_chan_ext(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)2699 reg_modify_chan_list_for_avoid_chan_ext(struct wlan_regulatory_pdev_priv_obj
2700 *pdev_priv_obj)
2701 {
2702 }
2703 #endif
2704
2705 #ifdef CONFIG_BAND_6GHZ
2706 /**
2707 * reg_init_super_chan_entry() - Initialize the super channel list entry
2708 * for an input channel index by disabling the state and chan flags.
2709 * @pdev_priv_obj: Pointer to pdev_priv_obj
2710 * @chan_idx: Channel index to initialize
2711 *
2712 * Return: void
2713 */
reg_init_super_chan_entry(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,uint8_t chan_idx)2714 static void reg_init_super_chan_entry(
2715 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
2716 uint8_t chan_idx)
2717 {
2718 enum supported_6g_pwr_types pwr_type;
2719 struct super_chan_info *chan_info;
2720
2721 chan_info = &pdev_priv_obj->super_chan_list[chan_idx];
2722
2723 for (pwr_type = REG_CURRENT_PWR_MODE; pwr_type <= REG_CLI_SUB_VLP;
2724 pwr_type++)
2725 reg_dis_chan_state_and_flags(&chan_info->state_arr[pwr_type],
2726 &chan_info->chan_flags_arr
2727 [pwr_type]);
2728 }
2729
2730 /**
2731 * reg_init_pdev_super_chan_list() - Initialize the super channel list.
2732 * @pdev_priv_obj: Pointer to pdev_priv_obj
2733 *
2734 * Return: void
2735 */
reg_init_pdev_super_chan_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)2736 static void reg_init_pdev_super_chan_list(
2737 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
2738 {
2739 uint8_t i;
2740
2741 qdf_mem_zero(pdev_priv_obj->super_chan_list, NUM_6GHZ_CHANNELS *
2742 sizeof(struct super_chan_info));
2743 for (i = 0; i < NUM_6GHZ_CHANNELS; i++)
2744 reg_init_super_chan_entry(pdev_priv_obj, i);
2745 }
2746
2747 /**
2748 * reg_is_edge_chan_disable_needed() - Check if the 6G edge channels are
2749 * disabled
2750 * @psoc: Pointer to psoc
2751 * @chan_idx: Channel index
2752 *
2753 * Return: bool
2754 */
reg_is_edge_chan_disable_needed(struct wlan_objmgr_psoc * psoc,uint16_t chan_idx)2755 static bool reg_is_edge_chan_disable_needed(struct wlan_objmgr_psoc *psoc,
2756 uint16_t chan_idx)
2757 {
2758 bool is_lower_edge_disable =
2759 ((chan_idx == (CHAN_ENUM_5935 - MIN_6GHZ_CHANNEL)) &&
2760 !reg_is_lower_6g_edge_ch_supp(psoc));
2761 bool is_upper_edge_disable =
2762 ((chan_idx == (CHAN_ENUM_7115 - MIN_6GHZ_CHANNEL)) &&
2763 reg_is_upper_6g_edge_ch_disabled(psoc));
2764
2765 return is_lower_edge_disable || is_upper_edge_disable;
2766 }
2767
2768 #ifdef CONFIG_AFC_SUPPORT
2769 /**
2770 * reg_set_flag_afc_not_done() - Set channel flag REGULATORY_CHAN_AFC_NOT_DONE
2771 * @chan_flags: Channel flags
2772 * @is_set: boolean to set/unset the flag
2773 *
2774 * Return: void
2775 */
2776 static inline void
reg_set_flag_afc_not_done(uint32_t * chan_flags,bool is_set)2777 reg_set_flag_afc_not_done(uint32_t *chan_flags, bool is_set)
2778 {
2779 if (is_set)
2780 *chan_flags |= REGULATORY_CHAN_AFC_NOT_DONE;
2781 else
2782 *chan_flags &= ~REGULATORY_CHAN_AFC_NOT_DONE;
2783 }
2784
2785 #else
2786 static inline void
reg_set_flag_afc_not_done(uint32_t * chan_flags,bool is_set)2787 reg_set_flag_afc_not_done(uint32_t *chan_flags, bool is_set)
2788 {
2789 }
2790 #endif
2791
2792 /**
2793 * reg_dis_6g_edge_chan_in_enh_chan() - Disable the 6g edge
2794 * channels in the super channel list
2795 * @pdev: Pointer to pdev
2796 * @chan_info: Pointer to chan_info
2797 * @chan_idx: Channel index
2798 * @pwr_type: 6G power type bitmap
2799 *
2800 * Return: void
2801 */
2802 static void
reg_dis_6g_edge_chan_in_enh_chan(struct wlan_objmgr_pdev * pdev,struct super_chan_info * chan_info,uint16_t chan_idx,enum supported_6g_pwr_types pwr_type)2803 reg_dis_6g_edge_chan_in_enh_chan(struct wlan_objmgr_pdev *pdev,
2804 struct super_chan_info *chan_info,
2805 uint16_t chan_idx,
2806 enum supported_6g_pwr_types pwr_type)
2807 {
2808 struct wlan_objmgr_psoc *psoc;
2809
2810 if (!pdev) {
2811 reg_debug("pdev is NULL");
2812 return;
2813 }
2814
2815 if (!chan_info) {
2816 reg_debug("chan_info is NULL");
2817 return;
2818 }
2819
2820 if (reg_is_supp_pwr_mode_invalid(pwr_type)) {
2821 reg_debug("pwr_type invalid");
2822 return;
2823 }
2824
2825 if (chan_idx >= NUM_6GHZ_CHANNELS) {
2826 reg_debug("chan_idx is out bounds");
2827 return;
2828 }
2829
2830 psoc = wlan_pdev_get_psoc(pdev);
2831 if (!psoc) {
2832 reg_debug("psoc is NULL");
2833 return;
2834 }
2835
2836 if (reg_is_edge_chan_disable_needed(psoc, chan_idx))
2837 reg_dis_chan_state_and_flags(&chan_info->state_arr[pwr_type],
2838 &chan_info->chan_flags_arr
2839 [pwr_type]);
2840 }
2841
2842 /**
2843 * copy_enh_chan_info_from_reg_chan() - Copy the mas_chan_list entry to the
2844 * super channel list entry
2845 * @chan_info: Pointer to chan_info
2846 * @pwr_type: 6G power type bitmap
2847 * @reg_chan: Pointer to reg_chan
2848 *
2849 * Return: void
2850 */
2851 static void
copy_enh_chan_info_from_reg_chan(struct super_chan_info * chan_info,enum supported_6g_pwr_types pwr_type,struct regulatory_channel * reg_chan)2852 copy_enh_chan_info_from_reg_chan(struct super_chan_info *chan_info,
2853 enum supported_6g_pwr_types pwr_type,
2854 struct regulatory_channel *reg_chan)
2855 {
2856 if (!chan_info) {
2857 reg_debug("chan_info is NULL");
2858 return;
2859 }
2860
2861 if (reg_is_supp_pwr_mode_invalid(pwr_type)) {
2862 reg_debug("pwr_type invalid");
2863 return;
2864 }
2865
2866 if (!reg_chan) {
2867 reg_debug("reg_chan is NULL");
2868 return;
2869 }
2870
2871 chan_info->reg_chan_pwr[pwr_type].psd_flag = reg_chan->psd_flag;
2872 chan_info->reg_chan_pwr[pwr_type].psd_eirp = reg_chan->psd_eirp;
2873 chan_info->reg_chan_pwr[pwr_type].tx_power = reg_chan->tx_power;
2874 chan_info->chan_flags_arr[pwr_type] = reg_chan->chan_flags;
2875 chan_info->state_arr[pwr_type] = reg_chan->state;
2876 chan_info->min_bw[pwr_type] = reg_chan->min_bw;
2877 chan_info->max_bw[pwr_type] = reg_chan->max_bw;
2878 }
2879
2880 const struct ap_cli_pwr_mode_info reg_pwr_enum_2_ap_cli_pwrmode[] = {
2881 [REG_AP_LPI] = {true, REG_INVALID_CLIENT_TYPE, REG_INDOOR_AP},
2882 [REG_AP_SP] = {true, REG_INVALID_CLIENT_TYPE,
2883 REG_STANDARD_POWER_AP},
2884 [REG_AP_VLP] = {true, REG_INVALID_CLIENT_TYPE,
2885 REG_VERY_LOW_POWER_AP},
2886 [REG_CLI_DEF_LPI] = {false, REG_DEFAULT_CLIENT, REG_INDOOR_AP},
2887 [REG_CLI_DEF_SP] = {false, REG_DEFAULT_CLIENT, REG_STANDARD_POWER_AP},
2888 [REG_CLI_DEF_VLP] = {false, REG_DEFAULT_CLIENT, REG_VERY_LOW_POWER_AP},
2889 [REG_CLI_SUB_LPI] = {false, REG_SUBORDINATE_CLIENT, REG_INDOOR_AP},
2890 [REG_CLI_SUB_SP] = {false, REG_SUBORDINATE_CLIENT,
2891 REG_STANDARD_POWER_AP},
2892 [REG_CLI_SUB_VLP] = {false, REG_SUBORDINATE_CLIENT,
2893 REG_VERY_LOW_POWER_AP},
2894 };
2895
2896 enum reg_6g_ap_type
reg_convert_supported_6g_pwr_type_to_ap_pwr_type(enum supported_6g_pwr_types in_6g_pwr_type)2897 reg_convert_supported_6g_pwr_type_to_ap_pwr_type(enum supported_6g_pwr_types
2898 in_6g_pwr_type)
2899 {
2900 if (reg_is_supp_pwr_mode_invalid(in_6g_pwr_type))
2901 return REG_MAX_AP_TYPE;
2902
2903 return reg_pwr_enum_2_ap_cli_pwrmode[in_6g_pwr_type].ap_pwr_mode;
2904 }
2905
reg_get_reg_maschan_lst_frm_6g_pwr_mode(enum supported_6g_pwr_types supp_pwr_mode,struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,uint16_t chan_idx)2906 struct regulatory_channel *reg_get_reg_maschan_lst_frm_6g_pwr_mode(
2907 enum supported_6g_pwr_types supp_pwr_mode,
2908 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
2909 uint16_t chan_idx)
2910 {
2911 struct regulatory_channel *mas_chan_list = NULL;
2912 bool is_ap_chan_lst;
2913 enum reg_6g_ap_type ap_pwr_mode; /* LPI, SP or VLP */
2914
2915 if (reg_is_supp_pwr_mode_invalid(supp_pwr_mode)) {
2916 reg_debug("Unsupported 6G AP power type");
2917 return mas_chan_list;
2918 }
2919
2920 is_ap_chan_lst =
2921 reg_pwr_enum_2_ap_cli_pwrmode[supp_pwr_mode].is_mode_ap;
2922 ap_pwr_mode = reg_pwr_enum_2_ap_cli_pwrmode[supp_pwr_mode].ap_pwr_mode;
2923
2924 if (ap_pwr_mode > REG_MAX_SUPP_AP_TYPE) {
2925 reg_debug("Unsupported 6G AP power type");
2926 return mas_chan_list;
2927 }
2928
2929 if (is_ap_chan_lst) {
2930 mas_chan_list =
2931 &pdev_priv_obj->mas_chan_list_6g_ap[ap_pwr_mode][chan_idx];
2932 } else {
2933 enum reg_6g_client_type cli_type;
2934
2935 cli_type =
2936 reg_pwr_enum_2_ap_cli_pwrmode[supp_pwr_mode].cli_type;
2937 if (cli_type >= REG_MAX_CLIENT_TYPE) {
2938 reg_debug("Unsupported 6G client power type");
2939 return mas_chan_list;
2940 }
2941
2942 mas_chan_list =
2943 &pdev_priv_obj->mas_chan_list_6g_client[ap_pwr_mode][cli_type]
2944 [chan_idx];
2945 }
2946
2947 return mas_chan_list;
2948 }
2949
2950 /**
2951 * reg_is_chan_out_of_chip_range() - Determine if the input channel is
2952 * out of the range
2953 * @reg_chan: Pointer to reg_chan
2954 * @pdev_priv_obj: Pointer to pdev_priv_obj
2955 *
2956 * Return: bool
2957 */
reg_is_chan_out_of_chip_range(struct regulatory_channel * reg_chan,struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)2958 static bool reg_is_chan_out_of_chip_range(
2959 struct regulatory_channel *reg_chan,
2960 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
2961 {
2962 return ((reg_chan->center_freq < pdev_priv_obj->range_5g_low) ||
2963 (reg_chan->center_freq > pdev_priv_obj->range_5g_high));
2964 }
2965
2966 /**
2967 * reg_accumulate_pwr_type() - Accumulate the power type in the super channel
2968 * list entry for a given input channel index.
2969 * @supp_pwr_mode: 6G supported power mode
2970 * @super_chan_list: Pointer to super channel list
2971 * @chn_idx: Channel index
2972 *
2973 * Return: void
2974 */
reg_accumulate_pwr_type(enum supported_6g_pwr_types supp_pwr_mode,struct super_chan_info * super_chan_list,uint16_t chn_idx)2975 static void reg_accumulate_pwr_type(
2976 enum supported_6g_pwr_types supp_pwr_mode,
2977 struct super_chan_info *super_chan_list,
2978 uint16_t chn_idx)
2979 {
2980 if (reg_is_supp_pwr_mode_invalid(supp_pwr_mode))
2981 return;
2982
2983 super_chan_list[chn_idx].power_types |= BIT(supp_pwr_mode);
2984 }
2985
2986 #ifdef CONFIG_REG_CLIENT
2987 /**
2988 * reg_is_ap_sp_supp_pwr_mode() - Check if the input supported power mode is
2989 * a AP SP power mode
2990 * @supp_pwr_mode: 6G supported power mode
2991 *
2992 * Return: bool
2993 */
2994 static bool
reg_is_ap_sp_supp_pwr_mode(enum supported_6g_pwr_types supp_pwr_mode)2995 reg_is_ap_sp_supp_pwr_mode(enum supported_6g_pwr_types supp_pwr_mode)
2996 {
2997 return (supp_pwr_mode == REG_AP_SP);
2998 }
2999
3000 /**
3001 * reg_is_sp_pwr_mode_allowed_in_supchan() - Check if the input supported power
3002 * mode is SP power mode
3003 * @supp_pwr_mode: 6G supported power mode
3004 *
3005 * Return: bool
3006 */
3007 static bool
reg_is_sp_pwr_mode_allowed_in_supchan(enum supported_6g_pwr_types supp_pwr_mode)3008 reg_is_sp_pwr_mode_allowed_in_supchan(enum supported_6g_pwr_types supp_pwr_mode)
3009 {
3010 return reg_is_ap_sp_supp_pwr_mode(supp_pwr_mode);
3011 }
3012 #else
3013 /**
3014 * reg_is_sp_supp_pwr_mode() - Check if the input supported power mode is a
3015 * SP power mode
3016 * @supp_pwr_mode: 6G supported power mode
3017 *
3018 * Return: bool
3019 */
3020 static bool
reg_is_sp_supp_pwr_mode(enum supported_6g_pwr_types supp_pwr_mode)3021 reg_is_sp_supp_pwr_mode(enum supported_6g_pwr_types supp_pwr_mode)
3022 {
3023 return ((supp_pwr_mode == REG_AP_SP) ||
3024 (supp_pwr_mode == REG_CLI_DEF_SP) ||
3025 (supp_pwr_mode == REG_CLI_SUB_SP));
3026 }
3027
3028 static bool
reg_is_sp_pwr_mode_allowed_in_supchan(enum supported_6g_pwr_types supp_pwr_mode)3029 reg_is_sp_pwr_mode_allowed_in_supchan(enum supported_6g_pwr_types supp_pwr_mode)
3030 {
3031 return reg_is_sp_supp_pwr_mode(supp_pwr_mode);
3032 }
3033 #endif
3034
3035 /**
3036 * reg_fill_best_pwr_mode() - Fill the best power mode
3037 * @pdev_priv_obj: Pointer to pdev_priv_obj
3038 * @super_chan_list: Pointer to super_chan_list
3039 * @chn_idx: Channel index
3040 * @supp_pwr_mode: Supported power mode
3041 * @mas_chan_list_power: EIRP of the channel in the mas_chan_list
3042 * @max_eirp_pwr: Maximum EIRP
3043 *
3044 * Return: void
3045 */
3046 #ifdef CONFIG_REG_CLIENT
3047 static void
reg_fill_best_pwr_mode(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,struct super_chan_info * super_chan_list,uint8_t chn_idx,enum supported_6g_pwr_types supp_pwr_mode,uint8_t mas_chan_list_power,uint8_t * max_eirp_pwr)3048 reg_fill_best_pwr_mode(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
3049 struct super_chan_info *super_chan_list,
3050 uint8_t chn_idx,
3051 enum supported_6g_pwr_types supp_pwr_mode,
3052 uint8_t mas_chan_list_power,
3053 uint8_t *max_eirp_pwr)
3054 {
3055 enum reg_6g_client_type curr_6g_client_type;
3056 enum reg_6g_client_type client_type =
3057 reg_pwr_enum_2_ap_cli_pwrmode[supp_pwr_mode].cli_type;
3058
3059 reg_get_cur_6g_client_type(pdev_priv_obj->pdev_ptr,
3060 &curr_6g_client_type);
3061 if (client_type != curr_6g_client_type)
3062 return;
3063
3064 if (reg_is_sp_pwr_mode_allowed_in_supchan(supp_pwr_mode) &&
3065 !wlan_reg_is_afc_power_event_received(pdev_priv_obj->pdev_ptr))
3066 return;
3067
3068 if (*max_eirp_pwr == 0) {
3069 *max_eirp_pwr = mas_chan_list_power;
3070 super_chan_list[chn_idx].best_power_mode = supp_pwr_mode;
3071 return;
3072 } else if (pdev_priv_obj->indoor_chan_enabled &&
3073 (mas_chan_list_power > *max_eirp_pwr)) {
3074 *max_eirp_pwr = mas_chan_list_power;
3075 super_chan_list[chn_idx].best_power_mode = supp_pwr_mode;
3076 return;
3077 }
3078
3079 if (reg_is_lpi_cli_supp_pwr_mode(
3080 super_chan_list[chn_idx].best_power_mode) &&
3081 !reg_is_lpi_cli_supp_pwr_mode(supp_pwr_mode)) {
3082 *max_eirp_pwr = mas_chan_list_power;
3083 super_chan_list[chn_idx].best_power_mode = supp_pwr_mode;
3084 return;
3085 } else if (!reg_is_lpi_cli_supp_pwr_mode(super_chan_list[chn_idx].
3086 best_power_mode) &&
3087 reg_is_lpi_cli_supp_pwr_mode(supp_pwr_mode)) {
3088 return;
3089 } else if (mas_chan_list_power > *max_eirp_pwr) {
3090 *max_eirp_pwr = mas_chan_list_power;
3091 super_chan_list[chn_idx].best_power_mode = supp_pwr_mode;
3092 }
3093 }
3094 #else
3095 static void
reg_fill_best_pwr_mode(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,struct super_chan_info * super_chan_list,uint8_t chn_idx,enum supported_6g_pwr_types supp_pwr_mode,uint8_t mas_chan_list_power,uint8_t * max_eirp_pwr)3096 reg_fill_best_pwr_mode(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
3097 struct super_chan_info *super_chan_list,
3098 uint8_t chn_idx,
3099 enum supported_6g_pwr_types supp_pwr_mode,
3100 uint8_t mas_chan_list_power,
3101 uint8_t *max_eirp_pwr)
3102 {
3103 if (mas_chan_list_power > *max_eirp_pwr) {
3104 *max_eirp_pwr = mas_chan_list_power;
3105 super_chan_list[chn_idx].best_power_mode = supp_pwr_mode;
3106 }
3107 }
3108 #endif
3109
3110 #ifdef CONFIG_AFC_SUPPORT
3111 /**
3112 * reg_assign_afc_chan_entry_to_mas_chan() - Assign the AFC channel list entry
3113 * to the mas_chan
3114 * @pdev_priv_obj: Pointer to pdev_priv_obj
3115 * @mas_chan: Pointer to address of mas_chan
3116 * @chn_idx: Channel index
3117 *
3118 * Return: void
3119 */
3120 static void
reg_assign_afc_chan_entry_to_mas_chan(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,struct regulatory_channel ** mas_chan,uint8_t chn_idx)3121 reg_assign_afc_chan_entry_to_mas_chan(
3122 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
3123 struct regulatory_channel **mas_chan,
3124 uint8_t chn_idx)
3125 {
3126 *mas_chan = &pdev_priv_obj->afc_chan_list[chn_idx];
3127 }
3128
3129 /**
3130 * reg_is_deployment_outdoor() - Check if device deployment type is outdoor
3131 * @pdev_priv_obj: Pointer to pdev_priv_obj
3132 *
3133 * Return: True if deployment is outdoor, else false
3134 */
3135 static bool
reg_is_deployment_outdoor(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)3136 reg_is_deployment_outdoor(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
3137 {
3138 return pdev_priv_obj->reg_afc_dev_deployment_type ==
3139 AFC_DEPLOYMENT_OUTDOOR;
3140 }
3141 #else
3142 static inline void
reg_assign_afc_chan_entry_to_mas_chan(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,struct regulatory_channel ** mas_chan,uint8_t chn_idx)3143 reg_assign_afc_chan_entry_to_mas_chan(
3144 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
3145 struct regulatory_channel **mas_chan,
3146 uint8_t chn_idx)
3147 {
3148 }
3149
3150 static inline bool
reg_is_deployment_outdoor(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)3151 reg_is_deployment_outdoor(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
3152 {
3153 return false;
3154 }
3155 #endif
3156
3157 /**
3158 * reg_update_sup_ch_entry_for_mode() - Construct the super channel list entry
3159 * for a mode
3160 * @pdev_priv_obj: Pointer to pdev_priv_obj
3161 * @supp_pwr_mode: Supported power mode
3162 * @chn_idx: Channel index
3163 * @max_eirp_pwr: Maximum EIRP power
3164 *
3165 * Return: void
3166 */
reg_update_sup_ch_entry_for_mode(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,enum supported_6g_pwr_types supp_pwr_mode,uint16_t chn_idx,uint8_t * max_eirp_pwr)3167 static void reg_update_sup_ch_entry_for_mode(
3168 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
3169 enum supported_6g_pwr_types supp_pwr_mode,
3170 uint16_t chn_idx,
3171 uint8_t *max_eirp_pwr)
3172 {
3173 struct super_chan_info *super_chan_list;
3174 struct wlan_objmgr_pdev *pdev = pdev_priv_obj->pdev_ptr;
3175 struct regulatory_channel *mas_chan;
3176 struct regulatory_channel temp_reg_chan;
3177
3178 mas_chan = reg_get_reg_maschan_lst_frm_6g_pwr_mode(supp_pwr_mode,
3179 pdev_priv_obj,
3180 chn_idx);
3181 if (!mas_chan)
3182 return;
3183
3184 /*
3185 * If AFC is invalid, copy from Regulatory SP channel list.
3186 * If AFC is valid, copy from AFC response channel list.
3187 */
3188 if (reg_is_sp_pwr_mode_allowed_in_supchan(supp_pwr_mode)) {
3189 if (wlan_reg_is_afc_power_event_received(pdev))
3190 reg_assign_afc_chan_entry_to_mas_chan(pdev_priv_obj,
3191 &mas_chan,
3192 chn_idx);
3193 /* In INDOOR mode, before AFC response is received, the SP
3194 * channels should be totally disabled. Therefore, return from
3195 * here so that super channel entry remain disabled
3196 */
3197 else if (!reg_is_deployment_outdoor(pdev_priv_obj))
3198 return;
3199 }
3200
3201 if (!mas_chan)
3202 return;
3203
3204 qdf_mem_copy(&temp_reg_chan, mas_chan,
3205 sizeof(struct regulatory_channel));
3206 /*
3207 * Intersect the hardware frequency range with the
3208 * 6GHz channels.
3209 * If a channel is out of chip range, disable it.
3210 */
3211 if (reg_is_chan_out_of_chip_range(&temp_reg_chan, pdev_priv_obj)) {
3212 reg_dis_chan_state_and_flags(&temp_reg_chan.state,
3213 &temp_reg_chan.chan_flags);
3214 }
3215
3216 super_chan_list = pdev_priv_obj->super_chan_list;
3217 copy_enh_chan_info_from_reg_chan(&super_chan_list[chn_idx],
3218 supp_pwr_mode,
3219 &temp_reg_chan);
3220 if (reg_is_chan_disabled_and_not_nol(&temp_reg_chan))
3221 return;
3222
3223 reg_modify_super_chan_list_for_indoor_channels(pdev_priv_obj, chn_idx,
3224 supp_pwr_mode);
3225
3226 reg_dis_6g_chan_in_super_chan_list(pdev, &super_chan_list[chn_idx],
3227 supp_pwr_mode, chn_idx);
3228
3229 reg_dis_6g_edge_chan_in_enh_chan(pdev, &super_chan_list[chn_idx],
3230 chn_idx, supp_pwr_mode);
3231 reg_fill_best_pwr_mode(pdev_priv_obj, super_chan_list, chn_idx,
3232 supp_pwr_mode, temp_reg_chan.tx_power,
3233 max_eirp_pwr);
3234 reg_accumulate_pwr_type(supp_pwr_mode, super_chan_list, chn_idx);
3235 }
3236
3237 /**
3238 * reg_update_super_chan_entry() - Construct the super channel list entry for an
3239 * input channel index
3240 * @pdev_priv_obj: Pointer to pdev_priv_obj
3241 * @chn_idx: Channel index
3242 *
3243 * Return: void
3244 */
3245 static void
reg_update_super_chan_entry(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,uint16_t chn_idx)3246 reg_update_super_chan_entry(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
3247 uint16_t chn_idx)
3248 {
3249 enum supported_6g_pwr_types supp_pwr_mode;
3250 uint8_t max_eirp_pwr = 0;
3251
3252 for (supp_pwr_mode = REG_AP_LPI; supp_pwr_mode <= REG_CLI_SUB_VLP;
3253 supp_pwr_mode++) {
3254 reg_update_sup_ch_entry_for_mode(pdev_priv_obj, supp_pwr_mode,
3255 chn_idx, &max_eirp_pwr);
3256 }
3257 }
3258
3259 /**
3260 * reg_compute_super_chan_list() - Construct the super channel list
3261 * @pdev_priv_obj: Pointer to pdev_priv_obj
3262 *
3263 * Return: void
3264 */
3265 static void
reg_compute_super_chan_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)3266 reg_compute_super_chan_list(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
3267 {
3268 uint8_t i;
3269
3270 if (!pdev_priv_obj->is_6g_channel_list_populated)
3271 return;
3272
3273 for (i = 0; i < NUM_6GHZ_CHANNELS; i++)
3274 reg_update_super_chan_entry(pdev_priv_obj, i);
3275 }
3276 #else /* CONFIG_BAND_6GHZ */
reg_init_pdev_super_chan_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)3277 static void reg_init_pdev_super_chan_list(
3278 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
3279 {
3280 }
3281
3282 static inline void
reg_compute_super_chan_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)3283 reg_compute_super_chan_list(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
3284 {
3285 }
3286 #endif /* CONFIG_BAND_6GHZ */
3287
3288 #ifndef CONFIG_REG_CLIENT
3289 /**
3290 * reg_disable_enable_opclass_channels() - Disable the channels in the
3291 * current channel list that have opclass_chan_disable flag set.
3292 * @pdev_priv_obj: Pointer to pdev_priv_obj
3293 *
3294 * Return: void
3295 */
3296 static void
reg_disable_enable_opclass_channels(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)3297 reg_disable_enable_opclass_channels(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
3298 {
3299 uint8_t i;
3300 struct regulatory_channel *cur_chan_list;
3301
3302 cur_chan_list = pdev_priv_obj->cur_chan_list;
3303 for (i = 0; i < NUM_CHANNELS; i++) {
3304 if (cur_chan_list[i].opclass_chan_disable) {
3305 cur_chan_list[i].state = CHANNEL_STATE_DISABLE;
3306 cur_chan_list[i].chan_flags |= REGULATORY_CHAN_DISABLED;
3307 }
3308 }
3309 }
3310 #else
3311 static void
reg_disable_enable_opclass_channels(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)3312 reg_disable_enable_opclass_channels(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
3313 {
3314 }
3315 #endif
3316
3317 #ifdef CONFIG_REG_CLIENT
3318 /*
3319 * reg_modify_sp_channels() - Mark 6 GHz channels NO_IR and set state DFS
3320 * if power type is SP
3321 * @chan_list: Pdev current channel list
3322 *
3323 * Return: None
3324 */
3325 static
reg_modify_sp_channels(struct regulatory_channel * chan_list)3326 void reg_modify_sp_channels(struct regulatory_channel *chan_list)
3327 {
3328 int i;
3329
3330 for (i = MIN_6GHZ_CHANNEL; i <= MAX_6GHZ_CHANNEL ; i++) {
3331 if (chan_list[i].power_type == REG_STANDARD_POWER_AP &&
3332 chan_list[i].state != CHANNEL_STATE_DISABLE) {
3333 chan_list[i].state = CHANNEL_STATE_DFS;
3334 chan_list[i].chan_flags |= REGULATORY_CHAN_NO_IR;
3335 }
3336 }
3337 }
3338 #else
3339 static inline
reg_modify_sp_channels(struct regulatory_channel * chan_list)3340 void reg_modify_sp_channels(struct regulatory_channel *chan_list)
3341 {
3342 }
3343 #endif
3344
reg_compute_pdev_current_chan_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)3345 void reg_compute_pdev_current_chan_list(struct wlan_regulatory_pdev_priv_obj
3346 *pdev_priv_obj)
3347 {
3348 reg_modify_6g_afc_chan_list(pdev_priv_obj);
3349
3350 reg_copy_6g_cur_mas_chan_list_to_cmn(pdev_priv_obj);
3351
3352 reg_compute_super_chan_list(pdev_priv_obj);
3353
3354 qdf_mem_copy(pdev_priv_obj->cur_chan_list, pdev_priv_obj->mas_chan_list,
3355 NUM_CHANNELS * sizeof(struct regulatory_channel));
3356
3357 reg_modify_sp_channels(pdev_priv_obj->cur_chan_list);
3358 reg_modify_chan_list_for_freq_range(pdev_priv_obj->cur_chan_list,
3359 pdev_priv_obj->range_2g_low,
3360 pdev_priv_obj->range_2g_high,
3361 pdev_priv_obj->range_5g_low,
3362 pdev_priv_obj->range_5g_high);
3363
3364 reg_modify_chan_list_for_band(pdev_priv_obj);
3365
3366 reg_modify_disable_chan_list_for_unii1_and_unii2a(pdev_priv_obj);
3367
3368 reg_modify_chan_list_for_dfs_channels(pdev_priv_obj->cur_chan_list,
3369 pdev_priv_obj->dfs_enabled);
3370
3371 reg_modify_chan_list_for_nol_list(pdev_priv_obj->cur_chan_list);
3372 reg_modify_chan_list_for_static_puncture(pdev_priv_obj->cur_chan_list);
3373
3374 reg_modify_chan_list_for_indoor_channels(pdev_priv_obj);
3375
3376 reg_modify_chan_list_for_indoor_concurrency(pdev_priv_obj);
3377
3378 reg_modify_chan_list_for_fcc_channel(pdev_priv_obj);
3379
3380 reg_modify_chan_list_for_chan_144(pdev_priv_obj->cur_chan_list,
3381 pdev_priv_obj->en_chan_144);
3382
3383 reg_modify_chan_list_for_srd_channels(pdev_priv_obj->pdev_ptr,
3384 pdev_priv_obj->cur_chan_list);
3385
3386 reg_modify_chan_list_for_5dot9_ghz_channels(pdev_priv_obj->pdev_ptr,
3387 pdev_priv_obj->
3388 cur_chan_list);
3389
3390 reg_modify_chan_list_for_max_chwidth_for_pwrmode(
3391 pdev_priv_obj->pdev_ptr,
3392 pdev_priv_obj->cur_chan_list,
3393 REG_CURRENT_PWR_MODE);
3394
3395 reg_modify_chan_list_for_6g_edge_channels(pdev_priv_obj->pdev_ptr,
3396 pdev_priv_obj->
3397 cur_chan_list);
3398
3399 reg_populate_secondary_cur_chan_list(pdev_priv_obj);
3400
3401 reg_modify_chan_list_for_cached_channels(pdev_priv_obj);
3402
3403 reg_modify_chan_list_for_avoid_chan_ext(pdev_priv_obj);
3404
3405 reg_modify_sec_chan_list_for_6g_edge_chan(pdev_priv_obj);
3406
3407 reg_disable_enable_opclass_channels(pdev_priv_obj);
3408 }
3409
reg_reset_reg_rules(struct reg_rule_info * reg_rules)3410 void reg_reset_reg_rules(struct reg_rule_info *reg_rules)
3411 {
3412 qdf_mem_zero(reg_rules, sizeof(*reg_rules));
3413 }
3414
3415 #ifdef CONFIG_REG_CLIENT
3416 /**
3417 * reg_get_num_reg_rules() - Get number of reg rules.
3418 * @psoc_reg_rules: pointer to psoc reg rules
3419 * @pdev_priv_obj: pointer to pdev priv object
3420 *
3421 * Return: int
3422 */
reg_get_num_reg_rules(struct reg_rule_info * psoc_reg_rules,struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)3423 static int reg_get_num_reg_rules(
3424 struct reg_rule_info *psoc_reg_rules,
3425 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
3426 {
3427 struct reg_rule_info *pdev_reg_rules;
3428
3429 pdev_reg_rules = &pdev_priv_obj->reg_rules;
3430 return pdev_reg_rules->num_of_reg_rules;
3431 }
3432 #else
3433 /**
3434 * reg_get_num_reg_rules() - Get number of reg rules.
3435 * @psoc_reg_rules: pointer to psoc reg rules
3436 * @pdev_priv_obj: pointer to pdev priv object
3437 *
3438 * Return: int.
3439 */
reg_get_num_reg_rules(struct reg_rule_info * psoc_reg_rules,struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)3440 static int reg_get_num_reg_rules(
3441 struct reg_rule_info *psoc_reg_rules,
3442 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
3443 {
3444 enum reg_6g_ap_type cur_6g_ap_pwr_type;
3445 struct reg_rule_info *pdev_reg_rules;
3446
3447 cur_6g_ap_pwr_type = pdev_priv_obj->reg_cur_6g_ap_pwr_type;
3448 if (cur_6g_ap_pwr_type > REG_MAX_SUPP_AP_TYPE) {
3449 reg_err("Unsupported 6G AP power type");
3450 return 0;
3451 }
3452
3453 pdev_reg_rules = &pdev_priv_obj->reg_rules;
3454
3455 return (pdev_reg_rules->num_of_reg_rules +
3456 psoc_reg_rules->num_of_6g_ap_reg_rules[cur_6g_ap_pwr_type]);
3457 }
3458 #endif
3459
3460 #ifdef CONFIG_BAND_6GHZ
3461 #ifdef CONFIG_REG_CLIENT
3462 /**
3463 * reg_append_6g_reg_rules_in_pdev() - Append the 6G reg rules to the reg rules
3464 * list in pdev so that all currently used reg rules are in one common list
3465 * @pdev_priv_obj: Pointer to pdev private object
3466 *
3467 * Return: void
3468 */
reg_append_6g_reg_rules_in_pdev(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)3469 static void reg_append_6g_reg_rules_in_pdev(
3470 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
3471 {
3472 struct reg_rule_info *pdev_reg_rules;
3473 enum reg_6g_ap_type cur_pwr_type;
3474 uint8_t num_reg_rules;
3475 uint8_t *num_6ghz_reg_rules;
3476
3477 pdev_reg_rules = &pdev_priv_obj->reg_rules;
3478
3479 num_reg_rules = pdev_reg_rules->num_of_reg_rules;
3480 num_6ghz_reg_rules = pdev_reg_rules->num_of_6g_client_reg_rules;
3481
3482 if (num_6ghz_reg_rules[REG_INDOOR_AP])
3483 cur_pwr_type = REG_INDOOR_AP;
3484 else if (num_6ghz_reg_rules[REG_VERY_LOW_POWER_AP])
3485 cur_pwr_type = REG_VERY_LOW_POWER_AP;
3486 else if (num_6ghz_reg_rules[REG_STANDARD_POWER_AP])
3487 cur_pwr_type = REG_STANDARD_POWER_AP;
3488 else
3489 return;
3490
3491 pdev_reg_rules->num_of_reg_rules +=
3492 pdev_reg_rules->num_of_6g_client_reg_rules[cur_pwr_type];
3493
3494 qdf_mem_copy(&pdev_reg_rules->reg_rules[num_reg_rules],
3495 pdev_reg_rules->reg_rules_6g_client[cur_pwr_type],
3496 num_6ghz_reg_rules[cur_pwr_type] *
3497 sizeof(struct cur_reg_rule));
3498 }
3499 #else /* CONFIG_REG_CLIENT */
3500 /**
3501 * reg_append_6g_reg_rules_in_pdev() - Append 6 GHz reg rules to reg rules list
3502 * @pdev_priv_obj: Pointer to pdev private object
3503 *
3504 * Append 6 GHz reg rules to the reg rules list in pdev so that all currently
3505 * used reg rules are in one common list.
3506 *
3507 * Return: void
3508 */
reg_append_6g_reg_rules_in_pdev(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)3509 static void reg_append_6g_reg_rules_in_pdev(
3510 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
3511 {
3512 struct reg_rule_info *pdev_reg_rules;
3513 enum reg_6g_ap_type cur_pwr_type;
3514 uint8_t num_reg_rules;
3515
3516 cur_pwr_type = pdev_priv_obj->reg_cur_6g_ap_pwr_type;
3517 if (cur_pwr_type > REG_MAX_SUPP_AP_TYPE) {
3518 reg_err("Unsupported 6G AP power type");
3519 return;
3520 }
3521
3522 pdev_reg_rules = &pdev_priv_obj->reg_rules;
3523
3524 num_reg_rules = pdev_reg_rules->num_of_reg_rules;
3525 pdev_reg_rules->num_of_reg_rules +=
3526 pdev_reg_rules->num_of_6g_ap_reg_rules[cur_pwr_type];
3527
3528 qdf_mem_copy(&pdev_reg_rules->reg_rules[num_reg_rules],
3529 pdev_reg_rules->reg_rules_6g_ap[cur_pwr_type],
3530 pdev_reg_rules->num_of_6g_ap_reg_rules[cur_pwr_type] *
3531 sizeof(struct cur_reg_rule));
3532 }
3533 #endif /* CONFIG_REG_CLIENT */
3534
3535 /**
3536 * reg_copy_6g_reg_rules() - Copy the 6GHz reg rules from PSOC to PDEV
3537 * @pdev_reg_rules: Pointer to pdev reg rules
3538 * @psoc_reg_rules: Pointer to psoc reg rules
3539 *
3540 * Return: void
3541 */
reg_copy_6g_reg_rules(struct reg_rule_info * pdev_reg_rules,struct reg_rule_info * psoc_reg_rules)3542 static void reg_copy_6g_reg_rules(struct reg_rule_info *pdev_reg_rules,
3543 struct reg_rule_info *psoc_reg_rules)
3544 {
3545 uint32_t reg_rule_len_6g_ap, reg_rule_len_6g_client;
3546 uint8_t i;
3547
3548 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) {
3549 pdev_reg_rules->num_of_6g_ap_reg_rules[i] =
3550 psoc_reg_rules->num_of_6g_ap_reg_rules[i];
3551 reg_rule_len_6g_ap = psoc_reg_rules->num_of_6g_ap_reg_rules[i] *
3552 sizeof(struct cur_reg_rule);
3553 qdf_mem_copy(pdev_reg_rules->reg_rules_6g_ap[i],
3554 psoc_reg_rules->reg_rules_6g_ap[i],
3555 reg_rule_len_6g_ap);
3556
3557 pdev_reg_rules->num_of_6g_client_reg_rules[i] =
3558 psoc_reg_rules->num_of_6g_client_reg_rules[i];
3559 reg_rule_len_6g_client =
3560 psoc_reg_rules->num_of_6g_client_reg_rules[i] *
3561 sizeof(struct cur_reg_rule);
3562 qdf_mem_copy(pdev_reg_rules->reg_rules_6g_client[i],
3563 psoc_reg_rules->reg_rules_6g_client[i],
3564 reg_rule_len_6g_client);
3565 }
3566 }
3567 #else /* CONFIG_BAND_6GHZ */
reg_copy_6g_reg_rules(struct reg_rule_info * pdev_reg_rules,struct reg_rule_info * psoc_reg_rules)3568 static inline void reg_copy_6g_reg_rules(struct reg_rule_info *pdev_reg_rules,
3569 struct reg_rule_info *psoc_reg_rules)
3570 {
3571 }
3572
3573 static inline void
reg_append_6g_reg_rules_in_pdev(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)3574 reg_append_6g_reg_rules_in_pdev(
3575 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
3576 {
3577 }
3578 #endif /* CONFIG_BAND_6GHZ */
3579
reg_save_reg_rules_to_pdev(struct reg_rule_info * psoc_reg_rules,struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)3580 void reg_save_reg_rules_to_pdev(struct reg_rule_info *psoc_reg_rules,
3581 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
3582 {
3583 uint32_t reg_rule_len;
3584 struct reg_rule_info *pdev_reg_rules;
3585
3586 qdf_spin_lock_bh(&pdev_priv_obj->reg_rules_lock);
3587
3588 pdev_reg_rules = &pdev_priv_obj->reg_rules;
3589 reg_reset_reg_rules(pdev_reg_rules);
3590
3591 pdev_reg_rules->num_of_reg_rules = psoc_reg_rules->num_of_reg_rules;
3592
3593 if (!reg_get_num_reg_rules(psoc_reg_rules, pdev_priv_obj)) {
3594 qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock);
3595 reg_err("no reg rules in psoc");
3596 return;
3597 }
3598
3599 reg_rule_len = pdev_reg_rules->num_of_reg_rules *
3600 sizeof(struct cur_reg_rule);
3601 qdf_mem_copy(pdev_reg_rules->reg_rules, psoc_reg_rules->reg_rules,
3602 reg_rule_len);
3603
3604 reg_copy_6g_reg_rules(pdev_reg_rules, psoc_reg_rules);
3605 reg_append_6g_reg_rules_in_pdev(pdev_priv_obj);
3606
3607 qdf_mem_copy(pdev_reg_rules->alpha2, pdev_priv_obj->current_country,
3608 REG_ALPHA2_LEN + 1);
3609 pdev_reg_rules->dfs_region = pdev_priv_obj->dfs_region;
3610
3611 qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock);
3612 }
3613
3614 #ifdef CONFIG_REG_CLIENT
3615 /**
3616 * reg_set_pdev_fcc_rules - Set pdev fcc rules array
3617 * @psoc_priv_obj: PSOC private object pointer
3618 * @pdev_priv_obj: PDEV private object pointer
3619 *
3620 */
3621
reg_set_pdev_fcc_rules(struct wlan_regulatory_psoc_priv_obj * psoc_priv_obj,struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)3622 static void reg_set_pdev_fcc_rules(
3623 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj,
3624 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
3625 {
3626 if (!psoc_priv_obj) {
3627 reg_err("psoc priv obj is NULL");
3628 return;
3629 }
3630
3631 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
3632 reg_err("reg pdev priv obj is NULL");
3633 return;
3634 }
3635
3636 qdf_mem_copy(pdev_priv_obj->fcc_rules_ptr,
3637 psoc_priv_obj->fcc_rules_ptr,
3638 sizeof(struct cur_fcc_rule) * MAX_NUM_FCC_RULES);
3639 }
3640 #else
reg_set_pdev_fcc_rules(struct wlan_regulatory_psoc_priv_obj * psoc_priv_obj,struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)3641 static inline void reg_set_pdev_fcc_rules(
3642 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj,
3643 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
3644 {
3645 }
3646 #endif
3647
reg_propagate_mas_chan_list_to_pdev(struct wlan_objmgr_psoc * psoc,void * object,void * arg)3648 void reg_propagate_mas_chan_list_to_pdev(struct wlan_objmgr_psoc *psoc,
3649 void *object, void *arg)
3650 {
3651 struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object;
3652 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
3653 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
3654 enum direction *dir = arg;
3655 uint8_t pdev_id;
3656 uint8_t phy_id;
3657 struct wlan_lmac_if_reg_tx_ops *reg_tx_ops;
3658 struct reg_rule_info *psoc_reg_rules;
3659
3660 psoc_priv_obj = (struct wlan_regulatory_psoc_priv_obj *)
3661 wlan_objmgr_psoc_get_comp_private_obj(
3662 psoc, WLAN_UMAC_COMP_REGULATORY);
3663
3664 if (!psoc_priv_obj) {
3665 reg_err("psoc priv obj is NULL");
3666 return;
3667 }
3668
3669 pdev_priv_obj = reg_get_pdev_obj(pdev);
3670
3671 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
3672 reg_err("reg pdev priv obj is NULL");
3673 return;
3674 }
3675
3676 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
3677
3678 reg_tx_ops = reg_get_psoc_tx_ops(psoc);
3679 if (reg_tx_ops->get_phy_id_from_pdev_id)
3680 reg_tx_ops->get_phy_id_from_pdev_id(psoc, pdev_id, &phy_id);
3681 else
3682 phy_id = pdev_id;
3683
3684 reg_set_pdev_fcc_rules(psoc_priv_obj, pdev_priv_obj);
3685 reg_init_pdev_mas_chan_list(
3686 pdev_priv_obj,
3687 &psoc_priv_obj->mas_chan_params[phy_id]);
3688 psoc_reg_rules = &psoc_priv_obj->mas_chan_params[phy_id].reg_rules;
3689 reg_save_reg_rules_to_pdev(psoc_reg_rules, pdev_priv_obj);
3690 reg_set_ap_pwr_type(pdev_priv_obj);
3691 reg_init_pdev_super_chan_list(pdev_priv_obj);
3692 pdev_priv_obj->chan_list_recvd =
3693 psoc_priv_obj->chan_list_recvd[phy_id];
3694
3695 reg_init_indoor_channel_list(pdev);
3696 reg_compute_indoor_list_on_cc_change(psoc, pdev);
3697
3698 reg_update_max_phymode_chwidth_for_pdev(pdev);
3699 reg_update_channel_ranges(pdev);
3700 reg_modify_chan_list_for_outdoor(pdev_priv_obj);
3701 reg_compute_pdev_current_chan_list(pdev_priv_obj);
3702
3703 if (*dir == NORTHBOUND)
3704 reg_send_scheduler_msg_nb(psoc, pdev);
3705 else
3706 reg_send_scheduler_msg_sb(psoc, pdev);
3707 }
3708
3709 /**
3710 * reg_populate_49g_band_channels() - For all the valid 4.9GHz regdb channels
3711 * in the master channel list, find the regulatory rules and call
3712 * reg_fill_channel_info() to populate master channel list with txpower,
3713 * antennagain, BW info, etc.
3714 * @reg_rule_5g: Pointer to regulatory rule.
3715 * @num_5g_reg_rules: Number of regulatory rules.
3716 * @min_bw_5g: Minimum regulatory bandwidth.
3717 * @mas_chan_list: Pointer to the master channel list.
3718 */
3719 #ifdef CONFIG_49GHZ_CHAN
3720 static void
reg_populate_49g_band_channels(struct cur_reg_rule * reg_rule_5g,uint32_t num_5g_reg_rules,uint16_t min_bw_5g,struct regulatory_channel * mas_chan_list)3721 reg_populate_49g_band_channels(struct cur_reg_rule *reg_rule_5g,
3722 uint32_t num_5g_reg_rules,
3723 uint16_t min_bw_5g,
3724 struct regulatory_channel *mas_chan_list)
3725 {
3726 reg_populate_band_channels(MIN_49GHZ_CHANNEL,
3727 MAX_49GHZ_CHANNEL,
3728 reg_rule_5g,
3729 num_5g_reg_rules,
3730 min_bw_5g,
3731 mas_chan_list);
3732 }
3733 #else
3734 static void
reg_populate_49g_band_channels(struct cur_reg_rule * reg_rule_5g,uint32_t num_5g_reg_rules,uint16_t min_bw_5g,struct regulatory_channel * mas_chan_list)3735 reg_populate_49g_band_channels(struct cur_reg_rule *reg_rule_5g,
3736 uint32_t num_5g_reg_rules,
3737 uint16_t min_bw_5g,
3738 struct regulatory_channel *mas_chan_list)
3739 {
3740 }
3741 #endif /* CONFIG_49GHZ_CHAN */
3742
3743 #ifdef CONFIG_BAND_6GHZ
3744 /**
3745 * reg_populate_6g_band_channels() - For all the valid 6GHz regdb channels
3746 * in the master channel list, find the regulatory rules and call
3747 * reg_fill_channel_info() to populate master channel list with txpower,
3748 * antennagain, BW info, etc.
3749 * @reg_rule_5g: Pointer to regulatory rule.
3750 * @num_5g_reg_rules: Number of regulatory rules.
3751 * @min_bw_5g: Minimum regulatory bandwidth.
3752 * @mas_chan_list: Pointer to the master channel list.
3753 */
3754 static void
reg_populate_6g_band_channels(struct cur_reg_rule * reg_rule_5g,uint32_t num_5g_reg_rules,uint16_t min_bw_5g,struct regulatory_channel * mas_chan_list)3755 reg_populate_6g_band_channels(struct cur_reg_rule *reg_rule_5g,
3756 uint32_t num_5g_reg_rules,
3757 uint16_t min_bw_5g,
3758 struct regulatory_channel *mas_chan_list)
3759 {
3760 reg_populate_band_channels(MIN_6GHZ_CHANNEL,
3761 MAX_6GHZ_CHANNEL,
3762 reg_rule_5g,
3763 num_5g_reg_rules,
3764 min_bw_5g,
3765 mas_chan_list);
3766 }
3767
3768 void
reg_copy_from_super_chan_info_to_reg_channel(struct regulatory_channel * chan,const struct super_chan_info sc_entry,enum supported_6g_pwr_types in_6g_pwr_mode)3769 reg_copy_from_super_chan_info_to_reg_channel(struct regulatory_channel *chan,
3770 const struct super_chan_info sc_entry,
3771 enum supported_6g_pwr_types
3772 in_6g_pwr_mode)
3773 {
3774 if (in_6g_pwr_mode == REG_BEST_PWR_MODE)
3775 in_6g_pwr_mode = sc_entry.best_power_mode;
3776
3777 if (reg_is_supp_pwr_mode_invalid(in_6g_pwr_mode))
3778 return;
3779
3780 chan->state = sc_entry.state_arr[in_6g_pwr_mode];
3781 chan->chan_flags = sc_entry.chan_flags_arr[in_6g_pwr_mode];
3782 chan->tx_power = sc_entry.reg_chan_pwr[in_6g_pwr_mode].tx_power;
3783 chan->min_bw = sc_entry.min_bw[in_6g_pwr_mode];
3784 chan->max_bw = sc_entry.max_bw[in_6g_pwr_mode];
3785 chan->psd_flag = sc_entry.reg_chan_pwr[in_6g_pwr_mode].psd_flag;
3786 chan->psd_eirp = sc_entry.reg_chan_pwr[in_6g_pwr_mode].psd_eirp;
3787 }
3788
3789 QDF_STATUS
reg_get_6g_pwrmode_chan_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,struct regulatory_channel * chan_list,enum supported_6g_pwr_types in_6g_pwr_mode)3790 reg_get_6g_pwrmode_chan_list(struct wlan_regulatory_pdev_priv_obj
3791 *pdev_priv_obj,
3792 struct regulatory_channel *chan_list,
3793 enum supported_6g_pwr_types in_6g_pwr_mode)
3794 {
3795 uint8_t i;
3796
3797 /*
3798 * If 6GHz channel list is present, populate it with desired
3799 * power type
3800 */
3801 if (!pdev_priv_obj->is_6g_channel_list_populated) {
3802 reg_debug("6G channel list is empty");
3803 return QDF_STATUS_SUCCESS;
3804 }
3805
3806 /* Copy the regulatory_channel fields from super_chan_info */
3807 for (i = 0; i < NUM_6GHZ_CHANNELS; i++)
3808 reg_copy_from_super_chan_info_to_reg_channel(
3809 &chan_list[i + MIN_6GHZ_CHANNEL],
3810 pdev_priv_obj->super_chan_list[i],
3811 in_6g_pwr_mode);
3812
3813 return QDF_STATUS_SUCCESS;
3814 }
3815 #else
3816 static void
reg_populate_6g_band_channels(struct cur_reg_rule * reg_rule_5g,uint32_t num_5g_reg_rules,uint16_t min_bw_5g,struct regulatory_channel * mas_chan_list)3817 reg_populate_6g_band_channels(struct cur_reg_rule *reg_rule_5g,
3818 uint32_t num_5g_reg_rules,
3819 uint16_t min_bw_5g,
3820 struct regulatory_channel *mas_chan_list)
3821 {
3822 }
3823 #endif /* CONFIG_BAND_6GHZ */
3824
reg_get_pwrmode_chan_list(struct wlan_objmgr_pdev * pdev,struct regulatory_channel * chan_list,enum supported_6g_pwr_types in_6g_pwr_mode)3825 QDF_STATUS reg_get_pwrmode_chan_list(struct wlan_objmgr_pdev *pdev,
3826 struct regulatory_channel *chan_list,
3827 enum supported_6g_pwr_types in_6g_pwr_mode)
3828 {
3829 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
3830
3831 if (!pdev) {
3832 reg_err_rl("invalid pdev");
3833 return QDF_STATUS_E_INVAL;
3834 }
3835
3836 if (!chan_list) {
3837 reg_err_rl("invalid chanlist");
3838 return QDF_STATUS_E_INVAL;
3839 }
3840
3841 pdev_priv_obj = reg_get_pdev_obj(pdev);
3842
3843 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
3844 reg_err_rl("reg pdev priv obj is NULL");
3845 return QDF_STATUS_E_INVAL;
3846 }
3847
3848 /* Get the current channel list */
3849 qdf_mem_copy(chan_list, pdev_priv_obj->cur_chan_list,
3850 NUM_CHANNELS * sizeof(struct regulatory_channel));
3851
3852 if (in_6g_pwr_mode == REG_CURRENT_PWR_MODE)
3853 return QDF_STATUS_SUCCESS;
3854
3855 return reg_get_6g_pwrmode_chan_list(pdev_priv_obj, chan_list,
3856 in_6g_pwr_mode);
3857 }
3858
3859 #ifdef CONFIG_REG_CLIENT
3860 /**
3861 * reg_send_ctl_info() - Send CTL info to firmware when regdb is not offloaded
3862 * @soc_reg: soc private object for regulatory
3863 * @regulatory_info: regulatory info
3864 * @tx_ops: send operations for regulatory component
3865 *
3866 * Return: QDF_STATUS
3867 */
3868 static QDF_STATUS
reg_send_ctl_info(struct wlan_regulatory_psoc_priv_obj * soc_reg,struct cur_regulatory_info * regulatory_info,struct wlan_lmac_if_reg_tx_ops * tx_ops)3869 reg_send_ctl_info(struct wlan_regulatory_psoc_priv_obj *soc_reg,
3870 struct cur_regulatory_info *regulatory_info,
3871 struct wlan_lmac_if_reg_tx_ops *tx_ops)
3872 {
3873 struct wlan_objmgr_psoc *psoc = regulatory_info->psoc;
3874 struct reg_ctl_params params = {0};
3875 QDF_STATUS status;
3876 uint16_t regd_index;
3877 uint32_t index_2g, index_5g;
3878
3879 if (soc_reg->offload_enabled)
3880 return QDF_STATUS_SUCCESS;
3881
3882 if (!tx_ops || !tx_ops->send_ctl_info) {
3883 reg_err("No regulatory tx_ops");
3884 return QDF_STATUS_E_FAULT;
3885 }
3886
3887 status = reg_get_rdpair_from_regdmn_id(regulatory_info->reg_dmn_pair,
3888 ®d_index);
3889 if (QDF_IS_STATUS_ERROR(status)) {
3890 reg_err("Failed to get regdomain index for regdomain pair: %x",
3891 regulatory_info->reg_dmn_pair);
3892 return status;
3893 }
3894
3895 index_2g = g_reg_dmn_pairs[regd_index].dmn_id_2g;
3896 index_5g = g_reg_dmn_pairs[regd_index].dmn_id_5g;
3897 params.ctl_2g = regdomains_2g[index_2g].ctl_val;
3898 params.ctl_5g = regdomains_5g[index_5g].ctl_val;
3899 params.regd_2g = reg_2g_sub_dmn_code[index_2g];
3900 params.regd_5g = reg_5g_sub_dmn_code[index_5g];
3901
3902 if (reg_is_world_ctry_code(regulatory_info->reg_dmn_pair))
3903 params.regd = regulatory_info->reg_dmn_pair;
3904 else
3905 params.regd = regulatory_info->ctry_code | COUNTRY_ERD_FLAG;
3906
3907 reg_debug("regdomain pair = %u, regdomain index = %u",
3908 regulatory_info->reg_dmn_pair, regd_index);
3909 reg_debug("index_2g = %u, index_5g = %u, ctl_2g = %x, ctl_5g = %x",
3910 index_2g, index_5g, params.ctl_2g, params.ctl_5g);
3911 reg_debug("regd_2g = %x, regd_5g = %x, regd = %x",
3912 params.regd_2g, params.regd_5g, params.regd);
3913
3914 status = tx_ops->send_ctl_info(psoc, ¶ms);
3915 if (QDF_IS_STATUS_ERROR(status))
3916 reg_err("Failed to send CTL info to firmware");
3917
3918 return status;
3919 }
3920 #else
3921 static QDF_STATUS
reg_send_ctl_info(struct wlan_regulatory_psoc_priv_obj * soc_reg,struct cur_regulatory_info * regulatory_info,struct wlan_lmac_if_reg_tx_ops * tx_ops)3922 reg_send_ctl_info(struct wlan_regulatory_psoc_priv_obj *soc_reg,
3923 struct cur_regulatory_info *regulatory_info,
3924 struct wlan_lmac_if_reg_tx_ops *tx_ops)
3925 {
3926 return QDF_STATUS_SUCCESS;
3927 }
3928 #endif
3929
3930 /**
3931 * reg_soc_vars_reset_on_failure() - Reset the PSOC private object variables
3932 * when there is a failure
3933 * @status_code: status code of CC setting event
3934 * @soc_reg: soc private object for regulatory
3935 * @phy_id: physical ID
3936 *
3937 * Return: QDF_STATUS
3938 */
3939 static QDF_STATUS
reg_soc_vars_reset_on_failure(enum cc_setting_code status_code,struct wlan_regulatory_psoc_priv_obj * soc_reg,uint8_t phy_id)3940 reg_soc_vars_reset_on_failure(enum cc_setting_code status_code,
3941 struct wlan_regulatory_psoc_priv_obj *soc_reg,
3942 uint8_t phy_id)
3943 {
3944 if (status_code != REG_SET_CC_STATUS_PASS) {
3945 reg_err("Set country code failed, status code %d",
3946 status_code);
3947
3948 if (status_code != REG_CURRENT_ALPHA2_NOT_FOUND)
3949 return QDF_STATUS_E_FAILURE;
3950
3951 soc_reg->new_user_ctry_pending[phy_id] = false;
3952 soc_reg->new_11d_ctry_pending[phy_id] = false;
3953 soc_reg->world_country_pending[phy_id] = true;
3954 }
3955
3956 return QDF_STATUS_SUCCESS;
3957 }
3958
reg_init_legacy_master_chan(struct regulatory_channel * dst_list,struct wlan_regulatory_psoc_priv_obj * soc_reg)3959 static void reg_init_legacy_master_chan(struct regulatory_channel *dst_list,
3960 struct wlan_regulatory_psoc_priv_obj *soc_reg)
3961 {
3962 reg_init_chan(dst_list, 0, NUM_CHANNELS - 1, 0, soc_reg);
3963 }
3964
3965 #ifdef CONFIG_REG_CLIENT
3966 /**
3967 * reg_set_psoc_fcc_rules - Set PSOC fcc rules array
3968 * @soc_reg: PSOC private object pointer
3969 * @regulat_info: Regulatory info pointer
3970 *
3971 * Return: QDF_STATUS
3972 */
reg_set_psoc_fcc_rules(struct wlan_regulatory_psoc_priv_obj * soc_reg,struct cur_regulatory_info * regulat_info)3973 static QDF_STATUS reg_set_psoc_fcc_rules(
3974 struct wlan_regulatory_psoc_priv_obj *soc_reg,
3975 struct cur_regulatory_info *regulat_info)
3976 {
3977 if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) {
3978 reg_err("psoc reg component is NULL");
3979 return QDF_STATUS_E_FAILURE;
3980 }
3981
3982 if (regulat_info->num_fcc_rules)
3983 qdf_mem_copy(soc_reg->fcc_rules_ptr,
3984 regulat_info->fcc_rules_ptr,
3985 sizeof(struct cur_fcc_rule) *
3986 regulat_info->num_fcc_rules);
3987
3988 return QDF_STATUS_SUCCESS;
3989 }
3990 #else
reg_set_psoc_fcc_rules(struct wlan_regulatory_psoc_priv_obj * soc_reg,struct cur_regulatory_info * regulat_info)3991 static inline QDF_STATUS reg_set_psoc_fcc_rules(
3992 struct wlan_regulatory_psoc_priv_obj *soc_reg,
3993 struct cur_regulatory_info *regulat_info)
3994 {
3995 return QDF_STATUS_SUCCESS;
3996 }
3997 #endif
3998
3999 struct wlan_objmgr_pdev *
reg_get_pdev_from_phy_id(struct wlan_objmgr_psoc * psoc,uint8_t phy_id,struct wlan_lmac_if_reg_tx_ops * reg_tx_ops,bool is_reg_offload,wlan_objmgr_ref_dbgid * dbg_id)4000 reg_get_pdev_from_phy_id(struct wlan_objmgr_psoc *psoc, uint8_t phy_id,
4001 struct wlan_lmac_if_reg_tx_ops *reg_tx_ops,
4002 bool is_reg_offload,
4003 wlan_objmgr_ref_dbgid *dbg_id)
4004 {
4005 uint8_t pdev_id;
4006 struct wlan_objmgr_pdev *pdev;
4007 enum direction dir;
4008
4009 if (reg_tx_ops->get_pdev_id_from_phy_id)
4010 reg_tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id);
4011 else
4012 pdev_id = phy_id;
4013
4014 if (is_reg_offload) {
4015 *dbg_id = WLAN_REGULATORY_NB_ID;
4016 dir = NORTHBOUND;
4017 } else {
4018 *dbg_id = WLAN_REGULATORY_SB_ID;
4019 dir = SOUTHBOUND;
4020 }
4021
4022 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, *dbg_id);
4023
4024 return pdev;
4025 }
4026
4027 static QDF_STATUS
reg_propagate_mas_chan_list_and_fill_legacy_list(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_pdev * pdev,enum direction dir,wlan_objmgr_ref_dbgid dbg_id)4028 reg_propagate_mas_chan_list_and_fill_legacy_list(struct wlan_objmgr_psoc *psoc,
4029 struct wlan_objmgr_pdev *pdev,
4030 enum direction dir,
4031 wlan_objmgr_ref_dbgid dbg_id)
4032 {
4033 struct wlan_lmac_if_reg_tx_ops *reg_tx_ops;
4034 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
4035
4036 reg_tx_ops = reg_get_psoc_tx_ops(psoc);
4037 pdev_priv_obj = reg_get_pdev_obj(pdev);
4038 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
4039 reg_err("reg pdev priv obj is NULL");
4040 return QDF_STATUS_E_FAILURE;
4041 }
4042
4043 reg_propagate_mas_chan_list_to_pdev(psoc, pdev, &dir);
4044 if (reg_tx_ops->fill_umac_legacy_chanlist)
4045 reg_tx_ops->fill_umac_legacy_chanlist(pdev,
4046 pdev_priv_obj->cur_chan_list);
4047
4048 return QDF_STATUS_SUCCESS;
4049 }
4050
4051 #ifdef CONFIG_BAND_6GHZ
reg_init_2g_5g_master_chan(struct regulatory_channel * dst_list,struct wlan_regulatory_psoc_priv_obj * soc_reg)4052 static void reg_init_2g_5g_master_chan(struct regulatory_channel *dst_list,
4053 struct wlan_regulatory_psoc_priv_obj *soc_reg)
4054 {
4055 reg_init_chan(dst_list, 0, MAX_5GHZ_CHANNEL, 0, soc_reg);
4056 }
4057
4058 /**
4059 * reg_store_regulatory_ext_info_to_socpriv() - Copy ext info from regulatory
4060 * to regulatory PSOC private obj
4061 * @soc_reg: soc private object for regulatory
4062 * @regulat_info: regulatory info from CC event
4063 * @phy_id: physical ID
4064 *
4065 * Return: none
4066 */
reg_store_regulatory_ext_info_to_socpriv(struct wlan_regulatory_psoc_priv_obj * soc_reg,struct cur_regulatory_info * regulat_info,uint8_t phy_id)4067 static void reg_store_regulatory_ext_info_to_socpriv(
4068 struct wlan_regulatory_psoc_priv_obj *soc_reg,
4069 struct cur_regulatory_info *regulat_info,
4070 uint8_t phy_id)
4071 {
4072 uint32_t i;
4073
4074 soc_reg->num_phy = regulat_info->num_phy;
4075 soc_reg->mas_chan_params[phy_id].phybitmap = regulat_info->phybitmap;
4076 soc_reg->mas_chan_params[phy_id].dfs_region = regulat_info->dfs_region;
4077 soc_reg->mas_chan_params[phy_id].ctry_code = regulat_info->ctry_code;
4078 soc_reg->mas_chan_params[phy_id].reg_dmn_pair =
4079 regulat_info->reg_dmn_pair;
4080 soc_reg->mas_chan_params[phy_id].reg_6g_superid =
4081 regulat_info->domain_code_6g_super_id;
4082 soc_reg->mas_chan_params[phy_id].max_bw_5g = regulat_info->max_bw_5g;
4083 qdf_mem_copy(soc_reg->mas_chan_params[phy_id].current_country,
4084 regulat_info->alpha2,
4085 REG_ALPHA2_LEN + 1);
4086 qdf_mem_copy(soc_reg->cur_country,
4087 regulat_info->alpha2,
4088 REG_ALPHA2_LEN + 1);
4089 reg_debug("set cur_country %.2s", soc_reg->cur_country);
4090
4091 soc_reg->mas_chan_params[phy_id].ap_pwr_type = REG_INDOOR_AP;
4092 soc_reg->mas_chan_params[phy_id].client_type =
4093 regulat_info->client_type;
4094 soc_reg->mas_chan_params[phy_id].rnr_tpe_usable =
4095 regulat_info->rnr_tpe_usable;
4096 soc_reg->mas_chan_params[phy_id].unspecified_ap_usable =
4097 regulat_info->unspecified_ap_usable;
4098 soc_reg->mas_chan_params[phy_id].reg_6g_thresh_priority_freq =
4099 regulat_info->reg_6g_thresh_priority_freq;
4100
4101 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) {
4102 soc_reg->domain_code_6g_ap[i] =
4103 regulat_info->domain_code_6g_ap[i];
4104
4105 soc_reg->mas_chan_params[phy_id].
4106 is_6g_channel_list_populated = true;
4107
4108 qdf_mem_copy(soc_reg->domain_code_6g_client[i],
4109 regulat_info->domain_code_6g_client[i],
4110 REG_MAX_CLIENT_TYPE * sizeof(uint8_t));
4111 }
4112 }
4113
4114 #ifdef WLAN_FEATURE_11BE
4115 static bool
reg_is_bonded_ch_subset_of_regrule(struct cur_reg_rule * cur_rule_ptr,const struct bonded_channel_freq * bonded_ch_ptr)4116 reg_is_bonded_ch_subset_of_regrule(struct cur_reg_rule *cur_rule_ptr,
4117 const struct bonded_channel_freq
4118 *bonded_ch_ptr)
4119 {
4120 if (bonded_ch_ptr->start_freq >= cur_rule_ptr->start_freq &&
4121 bonded_ch_ptr->end_freq <= cur_rule_ptr->end_freq)
4122 return true;
4123
4124 return false;
4125 }
4126 #endif
4127
4128 /**
4129 * reg_is_5g_240chan_in_rule() - Determine if the given reg rule supports
4130 * 5g 240MHZ chan [100 - 144] and the BW of the rule is greater than 160MHZ.
4131 * @cur_rule_ptr: Pointer to struct cur_reg_rule
4132 * @bonded_ch_ptr: Pointer to const struct bonded_channel_freq
4133 *
4134 * Return -True if 240 chan rule is found, false otherwise.
4135 */
4136 #ifdef WLAN_FEATURE_11BE
4137 static bool
reg_is_5g_240chan_in_rule(struct cur_reg_rule * cur_rule_ptr,const struct bonded_channel_freq * bonded_ch_ptr)4138 reg_is_5g_240chan_in_rule(struct cur_reg_rule *cur_rule_ptr,
4139 const struct bonded_channel_freq *bonded_ch_ptr)
4140 {
4141 if (!bonded_ch_ptr)
4142 return false;
4143
4144 if (reg_is_bonded_ch_subset_of_regrule(cur_rule_ptr, bonded_ch_ptr) &&
4145 cur_rule_ptr->max_bw > BW_160_MHZ)
4146 return true;
4147
4148 return false;
4149 }
4150 #endif
4151
4152 /**
4153 * reg_is_chip_cc_11be_cap() - Determine if country supports a max BW
4154 * greater than 160MHZ and if chip is 11BE capable.
4155 * @psoc: Pointer to struct wlan_objmgr_psoc
4156 * @phy_id: Phy-id
4157 * @max_cc_bw: Maximum 5g BW supported by the country
4158 *
4159 * Return - True if cc_max is greater than 160MHZ and chip is 11BE cap,
4160 * false otherwise.
4161 */
4162 #ifdef WLAN_FEATURE_11BE
reg_is_chip_cc_11be_cap(struct wlan_objmgr_psoc * psoc,uint16_t phy_id,uint16_t max_cc_bw)4163 static bool reg_is_chip_cc_11be_cap(struct wlan_objmgr_psoc *psoc,
4164 uint16_t phy_id,
4165 uint16_t max_cc_bw)
4166 {
4167 struct wlan_lmac_if_reg_tx_ops *tx_ops;
4168
4169 tx_ops = reg_get_psoc_tx_ops(psoc);
4170 if (!tx_ops)
4171 return false;
4172
4173 if (max_cc_bw > BW_160_MHZ && tx_ops->is_chip_11be(psoc, phy_id))
4174 return true;
4175
4176 return false;
4177 }
4178 #endif
4179
4180 /**
4181 * reg_modify_max_bw_for_240mhz_5g_chans() - Manually update the bandwidh
4182 * of the 240MHz channels in 5GHz band [IEEE channels 100 - 144 support 240MHz
4183 * bandwidth using puncturing; 240MHz = 320MHz - 80Mhz(punctured)].
4184 * The max bandwidth for these channels should be 320MHz.
4185 *
4186 * Modify reg rule BW of 100 - 144 channels to 320 if
4187 * a) Chip supports 11BE
4188 * b) Country supports 320MHZ BW.
4189 * c) Reg rule BW advertised by FW is 240MHZ.
4190 * d) Channel is between 5500 and 5720.
4191 *
4192 * @regulat_info: Pointer to struct cur_regulatory_info
4193 * @reg_rule_5g: Pointer to struct cur_reg_rule
4194 */
4195 #ifdef WLAN_FEATURE_11BE
4196 static void
reg_modify_max_bw_for_240mhz_5g_chans(struct cur_regulatory_info * regulat_info,struct cur_reg_rule * reg_rule_5g)4197 reg_modify_max_bw_for_240mhz_5g_chans(struct cur_regulatory_info *regulat_info,
4198 struct cur_reg_rule *reg_rule_5g)
4199
4200 {
4201 #define FREQ_5500_MHZ 5500
4202
4203 uint16_t num_5g_reg_rules = regulat_info->num_5g_reg_rules;
4204 uint16_t rule_num;
4205 struct cur_reg_rule *cur_rule_ptr;
4206 const struct bonded_channel_freq *bonded_ch_ptr;
4207
4208 bonded_ch_ptr = reg_get_bonded_chan_entry(FREQ_5500_MHZ,
4209 CH_WIDTH_320MHZ, 0);
4210 if (!reg_is_chip_cc_11be_cap(regulat_info->psoc,
4211 regulat_info->phy_id,
4212 regulat_info->max_bw_5g))
4213 return;
4214
4215 for (rule_num = 0, cur_rule_ptr = reg_rule_5g;
4216 rule_num < num_5g_reg_rules; cur_rule_ptr++, rule_num++) {
4217 if (reg_is_5g_240chan_in_rule(cur_rule_ptr, bonded_ch_ptr)) {
4218 cur_rule_ptr->max_bw = BW_320_MHZ;
4219 break;
4220 }
4221 }
4222 }
4223 #else
4224 static void
reg_modify_max_bw_for_240mhz_5g_chans(struct cur_regulatory_info * regulat_info,struct cur_reg_rule * reg_rule_5g)4225 reg_modify_max_bw_for_240mhz_5g_chans(struct cur_regulatory_info *regulat_info,
4226 struct cur_reg_rule *reg_rule_5g)
4227 {
4228 }
4229 #endif
4230
4231 /**
4232 * reg_is_pwrmode_not_required - Check if given power mode is needed.
4233 * @soc_reg: soc private object for regulatory
4234 * @pwr_type: input AP power type
4235 *
4236 * Return: True if deployemnt is outdoor and power type is LPI, else false.
4237 */
4238 #if !defined(CONFIG_REG_CLIENT) && defined(CONFIG_AFC_SUPPORT)
reg_is_pwrmode_not_required(struct wlan_regulatory_psoc_priv_obj * soc_reg,enum reg_6g_ap_type pwr_type)4239 static bool reg_is_pwrmode_not_required(
4240 struct wlan_regulatory_psoc_priv_obj *soc_reg,
4241 enum reg_6g_ap_type pwr_type)
4242 {
4243 /*
4244 * In outdoor deployment, LPI(AP INDDOR and CLI INDOOR)
4245 * rules are not needed.
4246 */
4247 return ((soc_reg->reg_afc_dev_type == AFC_DEPLOYMENT_OUTDOOR) &&
4248 (pwr_type == REG_INDOOR_AP));
4249 }
4250 #else
reg_is_pwrmode_not_required(struct wlan_regulatory_psoc_priv_obj * soc_reg,enum reg_6g_ap_type pwr_mode)4251 static bool reg_is_pwrmode_not_required(
4252 struct wlan_regulatory_psoc_priv_obj *soc_reg,
4253 enum reg_6g_ap_type pwr_mode)
4254 {
4255 return false;
4256 }
4257 #endif
4258
4259 /**
4260 * reg_fill_master_channels() - Fill the master channel lists based on the
4261 * regulatory rules
4262 * @regulat_info: regulatory info
4263 * @reg_rules: regulatory rules
4264 * @client_mobility_type: client mobility type
4265 * @mas_chan_list_2g_5g: master chan list to fill with 2GHz and 5GHz channels
4266 * @mas_chan_list_6g_ap: master AP chan list to fill with 6GHz channels
4267 * @mas_chan_list_6g_client: master client chan list to fill with 6GHz channels
4268 * @soc_reg: soc private object for regulatory
4269 *
4270 * Return: QDF_STATUS
4271 */
4272 static QDF_STATUS
reg_fill_master_channels(struct cur_regulatory_info * regulat_info,struct reg_rule_info * reg_rules,enum reg_6g_client_type client_mobility_type,struct regulatory_channel * mas_chan_list_2g_5g,struct regulatory_channel * mas_chan_list_6g_ap[REG_CURRENT_MAX_AP_TYPE],struct regulatory_channel * mas_chan_list_6g_client[REG_CURRENT_MAX_AP_TYPE][REG_MAX_CLIENT_TYPE],struct wlan_regulatory_psoc_priv_obj * soc_reg)4273 reg_fill_master_channels(struct cur_regulatory_info *regulat_info,
4274 struct reg_rule_info *reg_rules,
4275 enum reg_6g_client_type client_mobility_type,
4276 struct regulatory_channel *mas_chan_list_2g_5g,
4277 struct regulatory_channel *mas_chan_list_6g_ap[REG_CURRENT_MAX_AP_TYPE],
4278 struct regulatory_channel *mas_chan_list_6g_client
4279 [REG_CURRENT_MAX_AP_TYPE][REG_MAX_CLIENT_TYPE],
4280 struct wlan_regulatory_psoc_priv_obj *soc_reg)
4281 {
4282 uint32_t i, j, k, curr_reg_rule_location, country_max_allowed_bw = 0;
4283 uint32_t num_2g_reg_rules, num_5g_reg_rules;
4284 uint32_t num_6g_reg_rules_ap[REG_CURRENT_MAX_AP_TYPE];
4285 uint32_t *num_6g_reg_rules_client[REG_CURRENT_MAX_AP_TYPE];
4286 struct cur_reg_rule *reg_rule_2g, *reg_rule_5g,
4287 *reg_rule_6g_ap[REG_CURRENT_MAX_AP_TYPE],
4288 **reg_rule_6g_client[REG_CURRENT_MAX_AP_TYPE];
4289 uint32_t min_bw_2g, max_bw_2g, min_bw_5g, max_bw_5g,
4290 min_bw_6g_ap[REG_CURRENT_MAX_AP_TYPE],
4291 max_bw_6g_ap[REG_CURRENT_MAX_AP_TYPE],
4292 *min_bw_6g_client[REG_CURRENT_MAX_AP_TYPE],
4293 *max_bw_6g_client[REG_CURRENT_MAX_AP_TYPE];
4294
4295 min_bw_2g = regulat_info->min_bw_2g;
4296 max_bw_2g = regulat_info->max_bw_2g;
4297 reg_rule_2g = regulat_info->reg_rules_2g_ptr;
4298 num_2g_reg_rules = regulat_info->num_2g_reg_rules;
4299 reg_update_max_bw_per_rule(num_2g_reg_rules, reg_rule_2g, max_bw_2g,
4300 &country_max_allowed_bw);
4301
4302 min_bw_5g = regulat_info->min_bw_5g;
4303 max_bw_5g = regulat_info->max_bw_5g;
4304 reg_rule_5g = regulat_info->reg_rules_5g_ptr;
4305 num_5g_reg_rules = regulat_info->num_5g_reg_rules;
4306 reg_update_max_bw_per_rule(num_5g_reg_rules, reg_rule_5g, max_bw_5g,
4307 &country_max_allowed_bw);
4308
4309 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) {
4310 min_bw_6g_ap[i] = regulat_info->min_bw_6g_ap[i];
4311 max_bw_6g_ap[i] = regulat_info->max_bw_6g_ap[i];
4312 reg_rule_6g_ap[i] = regulat_info->reg_rules_6g_ap_ptr[i];
4313 num_6g_reg_rules_ap[i] = regulat_info->num_6g_reg_rules_ap[i];
4314 reg_update_max_bw_per_rule(num_6g_reg_rules_ap[i],
4315 reg_rule_6g_ap[i], max_bw_6g_ap[i],
4316 &country_max_allowed_bw);
4317 }
4318
4319 for (j = 0; j < REG_CURRENT_MAX_AP_TYPE; j++) {
4320 min_bw_6g_client[j] = regulat_info->min_bw_6g_client[j];
4321 max_bw_6g_client[j] = regulat_info->max_bw_6g_client[j];
4322 reg_rule_6g_client[j] =
4323 regulat_info->reg_rules_6g_client_ptr[j];
4324 num_6g_reg_rules_client[j] =
4325 regulat_info->num_6g_reg_rules_client[j];
4326 for (k = 0; k < REG_MAX_CLIENT_TYPE; k++) {
4327 reg_update_max_bw_per_rule(
4328 num_6g_reg_rules_client[j][k],
4329 reg_rule_6g_client[j][k],
4330 max_bw_6g_client[j][k],
4331 &country_max_allowed_bw);
4332 }
4333 }
4334
4335 soc_reg->country_max_allowed_bw = country_max_allowed_bw;
4336 reg_debug("max_allowed_bw as per current reg rules: %d",
4337 country_max_allowed_bw);
4338
4339 reg_reset_reg_rules(reg_rules);
4340
4341 reg_rules->num_of_reg_rules = num_5g_reg_rules + num_2g_reg_rules;
4342
4343 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) {
4344 reg_rules->num_of_6g_ap_reg_rules[i] = num_6g_reg_rules_ap[i];
4345 if (num_6g_reg_rules_ap[i] > MAX_6G_REG_RULES) {
4346 reg_err("number of reg rules for 6g ap exceeds limit");
4347 return QDF_STATUS_E_FAILURE;
4348 }
4349
4350 reg_rules->num_of_6g_client_reg_rules[i] =
4351 num_6g_reg_rules_client[i][client_mobility_type];
4352 for (j = 0; j < REG_MAX_CLIENT_TYPE; j++) {
4353 if (num_6g_reg_rules_client[i][j] > MAX_6G_REG_RULES) {
4354 reg_err("number of reg rules for 6g client exceeds limit");
4355 return QDF_STATUS_E_FAILURE;
4356 }
4357 }
4358 }
4359
4360 if (reg_rules->num_of_reg_rules > MAX_REG_RULES) {
4361 reg_err("number of reg rules exceeds limit");
4362 return QDF_STATUS_E_FAILURE;
4363 }
4364
4365 if (reg_rules->num_of_reg_rules) {
4366 if (num_2g_reg_rules)
4367 qdf_mem_copy(reg_rules->reg_rules,
4368 reg_rule_2g, num_2g_reg_rules *
4369 sizeof(struct cur_reg_rule));
4370 curr_reg_rule_location = num_2g_reg_rules;
4371 if (num_5g_reg_rules) {
4372 qdf_mem_copy(reg_rules->reg_rules +
4373 curr_reg_rule_location, reg_rule_5g,
4374 num_5g_reg_rules *
4375 sizeof(struct cur_reg_rule));
4376 reg_modify_max_bw_for_240mhz_5g_chans(regulat_info,
4377 reg_rule_5g);
4378 }
4379 }
4380
4381 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) {
4382 if (num_6g_reg_rules_ap[i])
4383 qdf_mem_copy(reg_rules->reg_rules_6g_ap[i],
4384 reg_rule_6g_ap[i],
4385 num_6g_reg_rules_ap[i] *
4386 sizeof(struct cur_reg_rule));
4387
4388 if (num_6g_reg_rules_client[i][client_mobility_type])
4389 qdf_mem_copy(reg_rules->reg_rules_6g_client[i],
4390 reg_rule_6g_client[i][client_mobility_type],
4391 num_6g_reg_rules_client[i]
4392 [client_mobility_type] *
4393 sizeof(struct cur_reg_rule));
4394 }
4395
4396
4397 if (num_5g_reg_rules)
4398 reg_do_auto_bw_correction(num_5g_reg_rules,
4399 reg_rule_5g, max_bw_5g);
4400
4401 if (num_2g_reg_rules)
4402 reg_populate_band_channels(MIN_24GHZ_CHANNEL, MAX_24GHZ_CHANNEL,
4403 reg_rule_2g, num_2g_reg_rules,
4404 min_bw_2g, mas_chan_list_2g_5g);
4405
4406 if (num_5g_reg_rules) {
4407 reg_populate_band_channels(MIN_5GHZ_CHANNEL, MAX_5GHZ_CHANNEL,
4408 reg_rule_5g, num_5g_reg_rules,
4409 min_bw_5g, mas_chan_list_2g_5g);
4410 reg_populate_49g_band_channels(reg_rule_5g,
4411 num_5g_reg_rules,
4412 min_bw_5g,
4413 mas_chan_list_2g_5g);
4414 }
4415
4416 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) {
4417 if (reg_is_pwrmode_not_required(soc_reg, i))
4418 continue;
4419
4420 if (num_6g_reg_rules_ap[i])
4421 reg_populate_band_channels_ext_for_6g(0,
4422 NUM_6GHZ_CHANNELS - 1,
4423 reg_rule_6g_ap[i],
4424 num_6g_reg_rules_ap[i],
4425 min_bw_6g_ap[i],
4426 mas_chan_list_6g_ap[i]);
4427
4428 for (j = 0; j < REG_MAX_CLIENT_TYPE; j++) {
4429 if (num_6g_reg_rules_client[i][j])
4430 reg_populate_band_channels_ext_for_6g(0,
4431 NUM_6GHZ_CHANNELS - 1,
4432 reg_rule_6g_client[i][j],
4433 num_6g_reg_rules_client[i][j],
4434 min_bw_6g_client[i][j],
4435 mas_chan_list_6g_client[i][j]);
4436 }
4437 }
4438
4439 return QDF_STATUS_SUCCESS;
4440 }
4441
4442 /**
4443 * reg_set_socpriv_vars() - Set the regulatory PSOC variables based on
4444 * pending country status
4445 * @soc_reg: regulatory PSOC private object
4446 * @regulat_info: regulatory info
4447 * @psoc: pointer to PSOC object
4448 * @phy_id: physical ID
4449 *
4450 * Return: none
4451 */
reg_set_socpriv_vars(struct wlan_regulatory_psoc_priv_obj * soc_reg,struct cur_regulatory_info * regulat_info,struct wlan_objmgr_psoc * psoc,uint8_t phy_id)4452 static void reg_set_socpriv_vars(struct wlan_regulatory_psoc_priv_obj *soc_reg,
4453 struct cur_regulatory_info *regulat_info,
4454 struct wlan_objmgr_psoc *psoc,
4455 uint8_t phy_id)
4456 {
4457 soc_reg->chan_list_recvd[phy_id] = true;
4458
4459 if (soc_reg->new_user_ctry_pending[phy_id]) {
4460 soc_reg->new_user_ctry_pending[phy_id] = false;
4461 soc_reg->cc_src = SOURCE_USERSPACE;
4462 soc_reg->user_ctry_set = true;
4463 reg_debug("new user country is set");
4464 reg_run_11d_state_machine(psoc);
4465 } else if (soc_reg->new_init_ctry_pending[phy_id]) {
4466 soc_reg->new_init_ctry_pending[phy_id] = false;
4467 soc_reg->cc_src = SOURCE_USERSPACE;
4468 reg_debug("new init country is set");
4469 } else if (soc_reg->new_11d_ctry_pending[phy_id]) {
4470 soc_reg->new_11d_ctry_pending[phy_id] = false;
4471 soc_reg->cc_src = SOURCE_11D;
4472 soc_reg->user_ctry_set = false;
4473 reg_run_11d_state_machine(psoc);
4474 } else if (soc_reg->world_country_pending[phy_id]) {
4475 soc_reg->world_country_pending[phy_id] = false;
4476 soc_reg->cc_src = SOURCE_CORE;
4477 soc_reg->user_ctry_set = false;
4478 reg_run_11d_state_machine(psoc);
4479 } else {
4480 if (soc_reg->cc_src == SOURCE_UNKNOWN &&
4481 soc_reg->num_phy == phy_id + 1)
4482 soc_reg->cc_src = SOURCE_DRIVER;
4483
4484 qdf_mem_copy(soc_reg->mas_chan_params[phy_id].default_country,
4485 regulat_info->alpha2,
4486 REG_ALPHA2_LEN + 1);
4487
4488 soc_reg->mas_chan_params[phy_id].def_country_code =
4489 regulat_info->ctry_code;
4490 soc_reg->mas_chan_params[phy_id].def_region_domain =
4491 regulat_info->reg_dmn_pair;
4492
4493 if (soc_reg->cc_src == SOURCE_DRIVER) {
4494 qdf_mem_copy(soc_reg->def_country,
4495 regulat_info->alpha2,
4496 REG_ALPHA2_LEN + 1);
4497
4498 soc_reg->def_country_code = regulat_info->ctry_code;
4499 soc_reg->def_region_domain =
4500 regulat_info->reg_dmn_pair;
4501
4502 if (reg_is_world_alpha2(regulat_info->alpha2)) {
4503 soc_reg->cc_src = SOURCE_CORE;
4504 reg_run_11d_state_machine(psoc);
4505 }
4506 }
4507 }
4508 }
4509
4510 /**
4511 * reg_validate_reg_rules() - Function to validate reg rules
4512 * @num_reg_rules: number of reg rules
4513 * @reg_rule: Current reg rule object
4514 * @max_bw: max bandwidth of cur reg rules
4515 *
4516 * This function validates regulatory rules. The reg rule start-frequency must
4517 * not exceed end-frequency. And the band between start and end must not be
4518 * more than allowed country/regdomain bandwidth.
4519 *
4520 * Return: QDF_STATUS
4521 */
4522 static
reg_validate_reg_rules(uint32_t num_reg_rules,struct cur_reg_rule * reg_rule,uint16_t max_bw)4523 QDF_STATUS reg_validate_reg_rules(uint32_t num_reg_rules,
4524 struct cur_reg_rule *reg_rule,
4525 uint16_t max_bw)
4526 {
4527 uint32_t itr, cur_max_bw;
4528
4529 for (itr = 0; itr < num_reg_rules; itr++) {
4530 cur_max_bw = QDF_MIN(reg_rule[itr].max_bw, max_bw);
4531 if (reg_rule[itr].end_freq - cur_max_bw <
4532 reg_rule[itr].start_freq) {
4533 reg_err("start freq = %u, end_freq = %u, max_bw = %u",
4534 reg_rule[itr].start_freq,
4535 reg_rule[itr].end_freq,
4536 cur_max_bw);
4537 return QDF_STATUS_E_INVAL;
4538 }
4539 }
4540 return QDF_STATUS_SUCCESS;
4541 }
4542
4543 /**
4544 * reg_validate_master_chan_list_ext() - Function to validate master chan list
4545 * ext
4546 * @regulat_info: current regulatory info object
4547 *
4548 * This function validates master channel list ext.
4549 *
4550 * Return: QDF_STATUS
4551 */
4552 static
reg_validate_master_chan_list_ext(struct cur_regulatory_info * regulat_info)4553 QDF_STATUS reg_validate_master_chan_list_ext(
4554 struct cur_regulatory_info *regulat_info)
4555 {
4556 uint32_t j, k;
4557 uint32_t num_2g_reg_rules, num_5g_reg_rules;
4558 uint32_t num_6g_reg_rules_ap[REG_CURRENT_MAX_AP_TYPE];
4559 uint32_t *num_6g_reg_rules_client[REG_CURRENT_MAX_AP_TYPE];
4560 struct cur_reg_rule *reg_rule_2g, *reg_rule_5g,
4561 *reg_rule_6g_ap[REG_CURRENT_MAX_AP_TYPE],
4562 **reg_rule_6g_client[REG_CURRENT_MAX_AP_TYPE];
4563 uint32_t max_bw_2g, max_bw_5g,
4564 max_bw_6g_ap[REG_CURRENT_MAX_AP_TYPE],
4565 *max_bw_6g_client[REG_CURRENT_MAX_AP_TYPE];
4566
4567 max_bw_2g = regulat_info->max_bw_2g;
4568 reg_rule_2g = regulat_info->reg_rules_2g_ptr;
4569 num_2g_reg_rules = regulat_info->num_2g_reg_rules;
4570 if (QDF_IS_STATUS_ERROR(reg_validate_reg_rules(num_2g_reg_rules,
4571 reg_rule_2g,
4572 max_bw_2g))) {
4573 reg_err("Invalid 2GHz reg rules received from fw");
4574 return QDF_STATUS_E_INVAL;
4575 }
4576
4577 max_bw_5g = regulat_info->max_bw_5g;
4578 reg_rule_5g = regulat_info->reg_rules_5g_ptr;
4579 num_5g_reg_rules = regulat_info->num_5g_reg_rules;
4580 if (QDF_IS_STATUS_ERROR(reg_validate_reg_rules(num_5g_reg_rules,
4581 reg_rule_5g,
4582 max_bw_5g))) {
4583 reg_err("Invalid 5GHz reg rules received from fw");
4584 return QDF_STATUS_E_INVAL;
4585 }
4586
4587 for (j = 0; j < REG_CURRENT_MAX_AP_TYPE; j++) {
4588 max_bw_6g_ap[j] = regulat_info->max_bw_6g_ap[j];
4589 reg_rule_6g_ap[j] = regulat_info->reg_rules_6g_ap_ptr[j];
4590 num_6g_reg_rules_ap[j] = regulat_info->num_6g_reg_rules_ap[j];
4591 if (QDF_IS_STATUS_ERROR(reg_validate_reg_rules(
4592 num_6g_reg_rules_ap[j],
4593 reg_rule_6g_ap[j],
4594 max_bw_6g_ap[j]))) {
4595 reg_err("Invalid 6GHz AP reg rules received from fw");
4596 return QDF_STATUS_E_INVAL;
4597 }
4598
4599 max_bw_6g_client[j] = regulat_info->max_bw_6g_client[j];
4600 reg_rule_6g_client[j] =
4601 regulat_info->reg_rules_6g_client_ptr[j];
4602 num_6g_reg_rules_client[j] =
4603 regulat_info->num_6g_reg_rules_client[j];
4604 for (k = 0; k < REG_MAX_CLIENT_TYPE; k++) {
4605 if (QDF_IS_STATUS_ERROR(reg_validate_reg_rules(
4606 num_6g_reg_rules_client[j][k],
4607 reg_rule_6g_client[j][k],
4608 max_bw_6g_client[j][k]))) {
4609 reg_err("Invalid 6GHz AP reg rules received from fw");
4610 return QDF_STATUS_E_INVAL;
4611 }
4612 }
4613 }
4614 return QDF_STATUS_SUCCESS;
4615 }
4616
4617 static QDF_STATUS
__reg_process_master_chan_list_ext(struct cur_regulatory_info * regulat_info)4618 __reg_process_master_chan_list_ext(struct cur_regulatory_info *regulat_info)
4619 {
4620 struct wlan_regulatory_psoc_priv_obj *soc_reg;
4621 uint32_t i, j;
4622 struct regulatory_channel *mas_chan_list_2g_5g,
4623 *mas_chan_list_6g_ap[REG_CURRENT_MAX_AP_TYPE],
4624 *mas_chan_list_6g_client[REG_CURRENT_MAX_AP_TYPE]
4625 [REG_MAX_CLIENT_TYPE];
4626 struct wlan_objmgr_psoc *psoc;
4627 wlan_objmgr_ref_dbgid dbg_id;
4628 enum direction dir;
4629 uint8_t phy_id;
4630 uint8_t pdev_id;
4631 struct wlan_objmgr_pdev *pdev;
4632 struct wlan_lmac_if_reg_tx_ops *tx_ops;
4633 QDF_STATUS status;
4634 struct mas_chan_params *this_mchan_params;
4635
4636 psoc = regulat_info->psoc;
4637 soc_reg = reg_get_psoc_obj(psoc);
4638
4639 if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) {
4640 reg_err("psoc reg component is NULL");
4641 return QDF_STATUS_E_FAILURE;
4642 }
4643
4644 tx_ops = reg_get_psoc_tx_ops(psoc);
4645 phy_id = regulat_info->phy_id;
4646
4647 if (tx_ops->get_pdev_id_from_phy_id)
4648 tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id);
4649 else
4650 pdev_id = phy_id;
4651
4652 status = reg_validate_master_chan_list_ext(regulat_info);
4653 if (QDF_IS_STATUS_ERROR(status))
4654 return status;
4655
4656 if (reg_ignore_default_country(soc_reg, regulat_info)) {
4657 status = reg_set_curr_country(soc_reg, regulat_info, tx_ops);
4658 if (QDF_IS_STATUS_SUCCESS(status)) {
4659 reg_debug("WLAN restart - Ignore default CC for phy_id: %u",
4660 phy_id);
4661 return QDF_STATUS_SUCCESS;
4662 }
4663 }
4664
4665 reg_debug("process reg master chan extended list");
4666
4667 if (soc_reg->offload_enabled) {
4668 dbg_id = WLAN_REGULATORY_NB_ID;
4669 dir = NORTHBOUND;
4670 } else {
4671 dbg_id = WLAN_REGULATORY_SB_ID;
4672 dir = SOUTHBOUND;
4673 }
4674
4675 status = reg_soc_vars_reset_on_failure(regulat_info->status_code,
4676 soc_reg, phy_id);
4677
4678 if (!QDF_IS_STATUS_SUCCESS(status))
4679 return status;
4680
4681 this_mchan_params = &soc_reg->mas_chan_params[phy_id];
4682 mas_chan_list_2g_5g = this_mchan_params->mas_chan_list;
4683
4684 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) {
4685 mas_chan_list_6g_ap[i] =
4686 this_mchan_params->mas_chan_list_6g_ap[i];
4687
4688 qdf_mem_zero(mas_chan_list_6g_ap[i],
4689 NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel));
4690
4691 for (j = 0; j < REG_MAX_CLIENT_TYPE; j++) {
4692 mas_chan_list_6g_client[i][j] =
4693 this_mchan_params->mas_chan_list_6g_client[i][j];
4694 qdf_mem_zero(mas_chan_list_6g_client[i][j],
4695 NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel));
4696 }
4697 }
4698
4699 reg_init_channel_map(regulat_info->dfs_region);
4700
4701 reg_init_2g_5g_master_chan(mas_chan_list_2g_5g, soc_reg);
4702
4703 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) {
4704 reg_init_6ghz_master_chan(mas_chan_list_6g_ap[i], soc_reg);
4705 for (j = 0; j < REG_MAX_CLIENT_TYPE; j++)
4706 reg_init_6ghz_master_chan(mas_chan_list_6g_client[i][j],
4707 soc_reg);
4708 }
4709
4710 reg_store_regulatory_ext_info_to_socpriv(soc_reg, regulat_info, phy_id);
4711
4712 status = reg_fill_master_channels(regulat_info,
4713 &this_mchan_params->reg_rules,
4714 this_mchan_params->client_type,
4715 mas_chan_list_2g_5g,
4716 mas_chan_list_6g_ap,
4717 mas_chan_list_6g_client,
4718 soc_reg);
4719 if (!QDF_IS_STATUS_SUCCESS(status))
4720 return status;
4721
4722 status = reg_send_ctl_info(soc_reg, regulat_info, tx_ops);
4723 if (!QDF_IS_STATUS_SUCCESS(status))
4724 return status;
4725
4726 reg_set_socpriv_vars(soc_reg, regulat_info, psoc, phy_id);
4727
4728 status = reg_set_psoc_fcc_rules(soc_reg, regulat_info);
4729 if (!QDF_IS_STATUS_SUCCESS(status))
4730 return status;
4731
4732 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id);
4733 if (pdev) {
4734 status = reg_propagate_mas_chan_list_and_fill_legacy_list(psoc,
4735 pdev,
4736 dir,
4737 dbg_id);
4738 wlan_objmgr_pdev_release_ref(pdev, dbg_id);
4739 return status;
4740 }
4741
4742 return QDF_STATUS_SUCCESS;
4743 }
4744
reg_process_master_chan_list_ext(struct cur_regulatory_info * regulat_info)4745 QDF_STATUS reg_process_master_chan_list_ext(
4746 struct cur_regulatory_info *regulat_info)
4747 {
4748 QDF_STATUS status;
4749 struct wlan_lmac_if_reg_tx_ops *reg_tx_ops;
4750 struct wlan_objmgr_psoc *psoc;
4751 struct wlan_objmgr_pdev *pdev;
4752 wlan_objmgr_ref_dbgid dbg_id;
4753
4754 status = __reg_process_master_chan_list_ext(regulat_info);
4755 psoc = regulat_info->psoc;
4756 reg_tx_ops = reg_get_psoc_tx_ops(psoc);
4757 if (!reg_tx_ops->set_wait_for_init_cc_response_event)
4758 return status;
4759
4760 pdev = reg_get_pdev_from_phy_id(psoc, regulat_info->phy_id, reg_tx_ops,
4761 regulat_info->offload_enabled,
4762 &dbg_id);
4763 if (!pdev) {
4764 reg_err("pdev obj is NULL");
4765 return QDF_STATUS_E_FAILURE;
4766 }
4767 reg_tx_ops->set_wait_for_init_cc_response_event(pdev, status);
4768
4769 wlan_objmgr_pdev_release_ref(pdev, dbg_id);
4770 return status;
4771 }
4772
reg_get_6g_ap_master_chan_list(struct wlan_objmgr_pdev * pdev,enum reg_6g_ap_type ap_pwr_type,struct regulatory_channel * chan_list)4773 QDF_STATUS reg_get_6g_ap_master_chan_list(struct wlan_objmgr_pdev *pdev,
4774 enum reg_6g_ap_type ap_pwr_type,
4775 struct regulatory_channel *chan_list)
4776 {
4777 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
4778 struct regulatory_channel *master_chan_list_6g;
4779
4780 pdev_priv_obj = reg_get_pdev_obj(pdev);
4781
4782 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
4783 reg_err("reg pdev private obj is NULL");
4784 return QDF_STATUS_E_FAILURE;
4785 }
4786
4787 if (ap_pwr_type >= REG_CURRENT_MAX_AP_TYPE)
4788 return QDF_STATUS_E_FAILURE;
4789
4790 master_chan_list_6g = pdev_priv_obj->mas_chan_list_6g_ap[ap_pwr_type];
4791 qdf_mem_copy(chan_list, master_chan_list_6g,
4792 NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel));
4793
4794 return QDF_STATUS_SUCCESS;
4795 }
4796
4797 #ifdef CONFIG_AFC_SUPPORT
reg_disable_afc_mas_chan_list_channels(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)4798 static void reg_disable_afc_mas_chan_list_channels(
4799 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
4800 {
4801 struct regulatory_channel *afc_mas_chan_list;
4802 enum channel_enum chan_idx;
4803
4804 QDF_TRACE(QDF_MODULE_ID_AFC, QDF_TRACE_LEVEL_DEBUG,
4805 "Processing AFC Switch to LPI event");
4806
4807 afc_mas_chan_list = pdev_priv_obj->mas_chan_list_6g_afc;
4808
4809 for (chan_idx = 0; chan_idx < NUM_6GHZ_CHANNELS; chan_idx++) {
4810 if (afc_mas_chan_list[chan_idx].state == CHANNEL_STATE_ENABLE) {
4811 if (pdev_priv_obj->reg_afc_dev_deployment_type ==
4812 AFC_DEPLOYMENT_OUTDOOR) {
4813 afc_mas_chan_list[chan_idx].chan_flags |=
4814 REGULATORY_CHAN_AFC_NOT_DONE;
4815 } else {
4816 afc_mas_chan_list[chan_idx].state =
4817 CHANNEL_STATE_DISABLE;
4818 afc_mas_chan_list[chan_idx].chan_flags |=
4819 REGULATORY_CHAN_DISABLED;
4820 afc_mas_chan_list[chan_idx].psd_eirp = 0;
4821 afc_mas_chan_list[chan_idx].tx_power = 0;
4822 }
4823 }
4824 }
4825
4826 qdf_mem_zero(pdev_priv_obj->afc_chan_list,
4827 NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel));
4828 }
4829
reg_free_expiry_afc_info(struct afc_regulatory_info * afc_info)4830 static void reg_free_expiry_afc_info(struct afc_regulatory_info *afc_info)
4831 {
4832 qdf_mem_free(afc_info->expiry_info);
4833 }
4834
4835 /**
4836 * reg_disable_sp_entries_in_supr_chan_entry() - Disable the SP entries in the
4837 * super channel list
4838 * @chan_info: Pointer to chan_info
4839 * @reg_afc_dev_type: AFC device deployment type
4840 *
4841 * Return: void
4842 */
reg_disable_sp_entries_in_supr_chan_entry(struct super_chan_info * chan_info,enum reg_afc_dev_deploy_type reg_afc_dev_type)4843 static void reg_disable_sp_entries_in_supr_chan_entry(
4844 struct super_chan_info *chan_info,
4845 enum reg_afc_dev_deploy_type reg_afc_dev_type)
4846 {
4847 uint8_t j;
4848 static enum supported_6g_pwr_types list_of_sp_lists[] = {
4849 REG_AP_SP,
4850 REG_CLI_DEF_SP,
4851 REG_CLI_SUB_SP
4852 };
4853 uint8_t num_sp_lists = QDF_ARRAY_SIZE(list_of_sp_lists);
4854
4855 for (j = 0; j < num_sp_lists; j++) {
4856 enum supported_6g_pwr_types idx = list_of_sp_lists[j];
4857
4858 if (reg_is_supp_pwr_mode_invalid(idx))
4859 continue;
4860
4861 if (chan_info->state_arr[idx] == CHANNEL_STATE_DISABLE)
4862 continue;
4863
4864 if (reg_afc_dev_type == AFC_DEPLOYMENT_OUTDOOR)
4865 reg_set_flag_afc_not_done(
4866 &chan_info->chan_flags_arr[idx],
4867 true);
4868 else
4869 reg_dis_chan_state_and_flags(
4870 &chan_info->state_arr[idx],
4871 &chan_info->chan_flags_arr[idx]);
4872 }
4873 }
4874
4875 /**
4876 * reg_disable_sp_channels_in_super_chan_list() - Disable the SP channels in
4877 * the super channel list
4878 * @pdev_priv_obj: Pointer to pdev_priv_obj
4879 *
4880 * Return: void
4881 */
4882 static void
reg_disable_sp_channels_in_super_chan_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)4883 reg_disable_sp_channels_in_super_chan_list(
4884 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
4885 {
4886 uint8_t i;
4887 struct super_chan_info *super_chan_list;
4888
4889 super_chan_list = pdev_priv_obj->super_chan_list;
4890 for (i = 0; i < NUM_6GHZ_CHANNELS; i++) {
4891 struct super_chan_info *chan_info =
4892 &super_chan_list[i];
4893 reg_disable_sp_entries_in_supr_chan_entry(
4894 chan_info,
4895 pdev_priv_obj->reg_afc_dev_deployment_type);
4896 }
4897 }
4898
4899 #if defined(CONFIG_AFC_SUPPORT) && defined(CONFIG_REG_CLIENT)
4900 /**
4901 * reg_client_afc_populate_channels() - Function to populate channels and
4902 * invoke callbacks to notify the channel list change.
4903 * @psoc: Pointer to PSOC object
4904 * @pdev: Pointer to PDEV object
4905 *
4906 * Return: None
4907 */
4908 static void
reg_client_afc_populate_channels(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_pdev * pdev)4909 reg_client_afc_populate_channels(struct wlan_objmgr_psoc *psoc,
4910 struct wlan_objmgr_pdev *pdev)
4911 {
4912 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
4913
4914 pdev_priv_obj = reg_get_pdev_obj(pdev);
4915 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
4916 reg_alert("pdev reg component is NULL");
4917 return;
4918 }
4919 reg_compute_pdev_current_chan_list(pdev_priv_obj);
4920 reg_send_scheduler_msg_nb(psoc, pdev);
4921 }
4922 #else
4923 static inline void
reg_client_afc_populate_channels(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_pdev * pdev)4924 reg_client_afc_populate_channels(struct wlan_objmgr_psoc *psoc,
4925 struct wlan_objmgr_pdev *pdev)
4926 {
4927 }
4928 #endif
4929
4930 /**
4931 * reg_reset_chan_list_and_power_event() - Reset AFC master chan list and
4932 * super channel list. Set is_6g_afc_power_event_received to false
4933 * @pdev_priv_obj: Pointer to pdev_priv_obj
4934 *
4935 * Return: void
4936 */
reg_reset_chan_list_and_power_event(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj)4937 static void reg_reset_chan_list_and_power_event(
4938 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
4939 {
4940 reg_debug("Resetting the afc mas chan list and disabling SP channels");
4941 pdev_priv_obj->is_6g_afc_power_event_received = false;
4942 reg_disable_afc_mas_chan_list_channels(pdev_priv_obj);
4943 reg_disable_sp_channels_in_super_chan_list(pdev_priv_obj);
4944 }
4945
4946 /**
4947 * reg_process_afc_expiry_event() - Process the afc expiry event and get the
4948 * afc request id
4949 * @afc_info: Pointer to afc info
4950 *
4951 * Return: QDF_STATUS
4952 */
4953 static QDF_STATUS
reg_process_afc_expiry_event(struct afc_regulatory_info * afc_info)4954 reg_process_afc_expiry_event(struct afc_regulatory_info *afc_info)
4955 {
4956 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
4957 uint8_t phy_id;
4958 uint8_t pdev_id;
4959 struct wlan_objmgr_psoc *psoc;
4960 struct wlan_regulatory_psoc_priv_obj *soc_reg;
4961 struct wlan_objmgr_pdev *pdev;
4962 struct wlan_lmac_if_reg_tx_ops *tx_ops;
4963 wlan_objmgr_ref_dbgid dbg_id;
4964
4965 psoc = afc_info->psoc;
4966 soc_reg = reg_get_psoc_obj(psoc);
4967
4968 if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) {
4969 reg_err("psoc reg component is NULL");
4970 return QDF_STATUS_E_FAILURE;
4971 }
4972
4973 phy_id = afc_info->phy_id;
4974 tx_ops = reg_get_psoc_tx_ops(psoc);
4975
4976 if (soc_reg->offload_enabled)
4977 dbg_id = WLAN_REGULATORY_NB_ID;
4978 else
4979 dbg_id = WLAN_REGULATORY_SB_ID;
4980
4981 if (tx_ops->get_pdev_id_from_phy_id)
4982 tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id);
4983 else
4984 pdev_id = phy_id;
4985
4986 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id);
4987
4988 if (!pdev) {
4989 reg_err("pdev is NULL");
4990 return QDF_STATUS_E_FAILURE;
4991 }
4992
4993 pdev_priv_obj = reg_get_pdev_obj(pdev);
4994
4995 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
4996 reg_err("reg pdev priv obj is NULL");
4997 wlan_objmgr_pdev_release_ref(pdev, dbg_id);
4998 return QDF_STATUS_E_FAILURE;
4999 }
5000
5001 reg_debug("AFC event subtype: %d",
5002 afc_info->expiry_info->event_subtype);
5003 switch (afc_info->expiry_info->event_subtype) {
5004 case REG_AFC_EXPIRY_EVENT_START:
5005 case REG_AFC_EXPIRY_EVENT_RENEW:
5006 pdev_priv_obj->afc_request_id =
5007 afc_info->expiry_info->request_id;
5008 pdev_priv_obj->is_6g_afc_expiry_event_received = true;
5009 reg_afc_start(pdev, pdev_priv_obj->afc_request_id);
5010 break;
5011 case REG_AFC_EXPIRY_EVENT_SWITCH_TO_LPI:
5012 case REG_AFC_EXPIRY_EVENT_STOP_TX:
5013 /*
5014 * Invalidate the AFC response-payload and associated
5015 * driver memory
5016 */
5017 reg_free_afc_pwr_info(pdev_priv_obj);
5018 reg_reset_chan_list_and_power_event(pdev_priv_obj);
5019 reg_client_afc_populate_channels(psoc, pdev);
5020 reg_send_afc_payload_reset_event(pdev);
5021 if (wlan_reg_is_noaction_on_afc_pwr_evt(pdev)) {
5022 if (tx_ops->trigger_update_channel_list)
5023 tx_ops->trigger_update_channel_list(pdev);
5024 break;
5025 }
5026
5027 if (tx_ops->trigger_acs_for_afc)
5028 tx_ops->trigger_acs_for_afc(pdev);
5029 break;
5030 default:
5031 reg_err_rl("Invalid event subtype");
5032 };
5033
5034 wlan_objmgr_pdev_release_ref(pdev, dbg_id);
5035 reg_free_expiry_afc_info(afc_info);
5036
5037 return QDF_STATUS_SUCCESS;
5038 }
5039
5040 #ifdef WLAN_FEATURE_11BE
5041 /**
5042 * reg_find_afc_max_bw_from_chip_cap() - Find the maximum AFC BW based on the
5043 * chip capabilities.
5044 *
5045 * @pdev: Pointer to PDEV object.
5046 *
5047 * Return:
5048 * AFC_BW_320 if the chip supports 11BE, else return AFC_BW_160.
5049 */
5050 static uint16_t
reg_find_afc_max_bw_from_chip_cap(struct wlan_objmgr_pdev * pdev)5051 reg_find_afc_max_bw_from_chip_cap(struct wlan_objmgr_pdev *pdev)
5052 {
5053 struct wlan_objmgr_psoc *psoc;
5054 struct wlan_lmac_if_reg_tx_ops *reg_ops;
5055 uint8_t phy_id, pdev_id;
5056
5057 psoc = wlan_pdev_get_psoc(pdev);
5058 reg_ops = reg_get_psoc_tx_ops(psoc);
5059 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
5060 if (reg_ops->get_phy_id_from_pdev_id)
5061 reg_ops->get_phy_id_from_pdev_id(psoc, pdev_id, &phy_id);
5062 else
5063 phy_id = pdev_id;
5064
5065 if (reg_ops->is_chip_11be && reg_ops->is_chip_11be(psoc, phy_id))
5066 return AFC_BW_320;
5067
5068 return AFC_BW_160;
5069 }
5070 #else
5071 static inline uint16_t
reg_find_afc_max_bw_from_chip_cap(struct wlan_objmgr_pdev * pdev)5072 reg_find_afc_max_bw_from_chip_cap(struct wlan_objmgr_pdev *pdev)
5073 {
5074 return AFC_BW_160;
5075 }
5076 #endif
5077
5078 /**
5079 * reg_fill_min_max_bw_for_afc_list() - Fill min and max bw in afc list from
5080 * from the SP AFC list
5081 * @pdev_priv_obj: Pointer to pdev_priv_obj
5082 * @afc_chan_list: Pointer to afc_chan_list
5083 *
5084 * Return: void
5085 */
5086 static void
reg_fill_min_max_bw_for_afc_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,struct regulatory_channel * afc_chan_list)5087 reg_fill_min_max_bw_for_afc_list(
5088 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
5089 struct regulatory_channel *afc_chan_list)
5090 {
5091 uint8_t chan_idx;
5092 uint16_t afc_max_bw;
5093
5094 afc_max_bw = reg_find_afc_max_bw_from_chip_cap(pdev_priv_obj->pdev_ptr);
5095 for (chan_idx = 0; chan_idx < NUM_6GHZ_CHANNELS; chan_idx++) {
5096 afc_chan_list[chan_idx].min_bw = MIN_AFC_BW;
5097 afc_chan_list[chan_idx].max_bw = afc_max_bw;
5098 }
5099 }
5100
5101 /**
5102 * reg_fill_subchan_centers() - Fill the subchannels for the given cfi.
5103 * @nchans: Number of sub-channels
5104 * @cfi: Center frequency index
5105 * @subchannels: Array of subchannels to be filled
5106 *
5107 * eg: subchannels[0] = cfi - 6 : The second left hand channel is
5108 * 4 MHz to the left of the previous channel.
5109 * subchannels[1] = cfi - 2 : The first left hand channel is 2 MHz
5110 * to the left of the CFI.
5111 * subchannels[2] = cfi + 2 : The first right hand channel is 2 MHz
5112 * to the right of the center (or CFI) as the distance between
5113 * two IEEE channels is 4 MHz.
5114 * subchannels[3] = cfi + 6 : The second right hand channel is 4 MHz to the
5115 * right the of previous channel
5116 *
5117 * Return: void
5118 */
5119 static void
reg_fill_subchan_centers(uint8_t nchans,uint8_t cfi,uint8_t * subchannels)5120 reg_fill_subchan_centers(uint8_t nchans, uint8_t cfi, uint8_t *subchannels)
5121 {
5122 uint8_t last_idx = nchans - 1;
5123 uint8_t offset = HALF_IEEE_CH_SEP;
5124 uint8_t i;
5125
5126 if (nchans == 1) {
5127 subchannels[0] = cfi;
5128 return;
5129 }
5130
5131 for (i = nchans / 2; i < nchans; i++) {
5132 subchannels[i] = cfi + offset;
5133 subchannels[last_idx - i] = cfi - offset;
5134 offset += IEEE_20MHZ_CH_SEP;
5135 }
5136 }
5137
5138 struct opclass_nchans_pair {
5139 uint8_t opclass;
5140 uint8_t nchans;
5141 };
5142
5143 static const struct opclass_nchans_pair opclass_nchans_map[] = {
5144 {131, 1},
5145 {136, 1},
5146 {132, 2},
5147 {133, 4},
5148 {134, 8},
5149 #ifdef WLAN_FEATURE_11BE
5150 {137, 16},
5151 #endif
5152 };
5153
5154 /**
5155 * reg_get_nsubchaneels_for_opclass() - Get the number of subchannels based on
5156 * the operating class.
5157 * @opclass: Operating class
5158 *
5159 * Return: Number of subchannels
5160 */
reg_get_nsubchaneels_for_opclass(uint8_t opclass)5161 static uint8_t reg_get_nsubchaneels_for_opclass(uint8_t opclass)
5162 {
5163 uint8_t i, n_opclasses = QDF_ARRAY_SIZE(opclass_nchans_map);
5164
5165 for (i = 0; i < n_opclasses; i++)
5166 if (opclass == opclass_nchans_map[i].opclass)
5167 return opclass_nchans_map[i].nchans;
5168
5169 return 0;
5170 }
5171
5172 /**
5173 * reg_get_subchannels_for_opclass() - Get the list of subchannels based on the
5174 * the channel frequency index and opclass.
5175 * @cfi: Channel frequency index
5176 * @opclass: Operating class
5177 * @subchannels: Pointer to list of subchannels
5178 *
5179 * Return: void
5180 */
reg_get_subchannels_for_opclass(uint8_t cfi,uint8_t opclass,uint8_t * subchannels)5181 uint8_t reg_get_subchannels_for_opclass(uint8_t cfi,
5182 uint8_t opclass,
5183 uint8_t *subchannels)
5184 {
5185 uint8_t nchans;
5186
5187 nchans = reg_get_nsubchaneels_for_opclass(opclass);
5188 reg_fill_subchan_centers(nchans, cfi, subchannels);
5189
5190 return nchans;
5191 }
5192
5193 /**
5194 * reg_search_afc_power_info_for_freq() - Search the chan_eirp object for the
5195 * eirp power for a given frequency
5196 * @pdev: Pointer to pdev
5197 * @power_info: Pointer to power_info
5198 * @freq: Channel frequency
5199 * @eirp_power: Pointer to eirp_power
5200 *
5201 * Return: QDF_STATUS
5202 */
5203 static QDF_STATUS
reg_search_afc_power_info_for_freq(struct wlan_objmgr_pdev * pdev,struct reg_fw_afc_power_event * power_info,qdf_freq_t freq,uint16_t * eirp_power)5204 reg_search_afc_power_info_for_freq(
5205 struct wlan_objmgr_pdev *pdev,
5206 struct reg_fw_afc_power_event *power_info,
5207 qdf_freq_t freq,
5208 uint16_t *eirp_power)
5209 {
5210 uint8_t i;
5211
5212 if (!power_info->num_chan_objs) {
5213 reg_debug("num chan objs is zero");
5214 return QDF_STATUS_E_FAILURE;
5215 }
5216
5217 *eirp_power = 0;
5218 for (i = 0; i < power_info->num_chan_objs; i++) {
5219 uint8_t j;
5220 struct afc_chan_obj *chan_obj = &power_info->afc_chan_info[i];
5221
5222 if (!chan_obj->num_chans) {
5223 reg_debug("num chans is zero");
5224 return QDF_STATUS_E_FAILURE;
5225 }
5226
5227 for (j = 0; j < chan_obj->num_chans; j++) {
5228 uint8_t k;
5229 struct chan_eirp_obj *eirp_obj =
5230 &chan_obj->chan_eirp_info[j];
5231 uint8_t opclass = chan_obj->global_opclass;
5232 uint8_t subchannels[REG_MAX_20M_SUB_CH];
5233 uint8_t nchans;
5234
5235 nchans =
5236 reg_get_subchannels_for_opclass(eirp_obj->cfi,
5237 opclass, subchannels);
5238
5239 for (k = 0; k < nchans; k++) {
5240 if (reg_chan_band_to_freq(pdev,
5241 subchannels[k],
5242 BIT(REG_BAND_6G)) ==
5243 freq) {
5244 *eirp_power = eirp_obj->eirp_power;
5245 return QDF_STATUS_SUCCESS;
5246 }
5247 }
5248 }
5249 }
5250
5251 return QDF_STATUS_E_FAILURE;
5252 }
5253
5254 /**
5255 * reg_process_cfi_chan_list() - Fill eirp power and state in the cfi chan list
5256 * @pdev: Pointer to pdev
5257 * @cfi_chan_list: Pointer to cfi_chan_list
5258 * @power_info: Pointer to power_info
5259 *
5260 * Return: QDF_STATUS
5261 */
reg_process_cfi_chan_list(struct wlan_objmgr_pdev * pdev,struct regulatory_channel * cfi_chan_list,struct reg_fw_afc_power_event * power_info)5262 static QDF_STATUS reg_process_cfi_chan_list(
5263 struct wlan_objmgr_pdev *pdev,
5264 struct regulatory_channel *cfi_chan_list,
5265 struct reg_fw_afc_power_event *power_info)
5266
5267 {
5268 uint8_t chan_idx;
5269 uint16_t eirp_power;
5270 QDF_STATUS status = QDF_STATUS_SUCCESS;
5271
5272 for (chan_idx = 0; chan_idx < NUM_6GHZ_CHANNELS; chan_idx++) {
5273 status =
5274 reg_search_afc_power_info_for_freq(pdev,
5275 power_info,
5276 cfi_chan_list[chan_idx].
5277 center_freq,
5278 &eirp_power);
5279 /*
5280 * The eirp_power is divided by 100 because the target
5281 * sends the EIRP in the units of 0.01 dbm.
5282 */
5283 if (QDF_IS_STATUS_SUCCESS(status)) {
5284 cfi_chan_list[chan_idx].tx_power = eirp_power / 100;
5285 cfi_chan_list[chan_idx].state = CHANNEL_STATE_ENABLE;
5286 cfi_chan_list[chan_idx].chan_flags &=
5287 ~REGULATORY_CHAN_DISABLED;
5288 }
5289 }
5290
5291 return status;
5292 }
5293
5294 /**
5295 * reg_find_low_limit_chan_enum_for_6g() - Find 6G channel enum for a given 6G
5296 * lower edge frequency in the input channel list
5297 * @chan_list: Pointer to regulatory channel list.
5298 * @low_freq: Channel frequency.
5299 * @channel_enum: pointer to output channel enum.
5300 *
5301 * Return: None
5302 */
reg_find_low_limit_chan_enum_for_6g(struct regulatory_channel * chan_list,qdf_freq_t low_freq,enum channel_enum * channel_enum)5303 static void reg_find_low_limit_chan_enum_for_6g(
5304 struct regulatory_channel *chan_list, qdf_freq_t low_freq,
5305 enum channel_enum *channel_enum)
5306 {
5307 enum channel_enum chan_enum;
5308 uint16_t min_bw, max_bw, left_edge_of_min_band, left_edge_of_max_band;
5309 qdf_freq_t center_freq;
5310
5311 *channel_enum = 0;
5312 for (chan_enum = 0; chan_enum < NUM_6GHZ_CHANNELS; chan_enum++) {
5313 min_bw = chan_list[chan_enum].min_bw;
5314 max_bw = chan_list[chan_enum].max_bw;
5315 center_freq = chan_list[chan_enum].center_freq;
5316 left_edge_of_min_band = center_freq - min_bw / 2;
5317
5318 if ((left_edge_of_min_band) >= low_freq) {
5319 left_edge_of_max_band = center_freq - max_bw / 2;
5320 if (left_edge_of_max_band < low_freq) {
5321 if (max_bw <= 20)
5322 max_bw = ((center_freq - low_freq) * 2);
5323 if (max_bw < min_bw)
5324 max_bw = min_bw;
5325 chan_list[chan_enum].max_bw = max_bw;
5326 }
5327 *channel_enum = chan_enum;
5328 break;
5329 }
5330 }
5331 }
5332
5333 /**
5334 * reg_find_high_limit_chan_enum_for_6g() - Find 6G channel enum for a given
5335 * 6G higher edge frequency in the input channel list
5336 * @chan_list: Pointer to regulatory channel list.
5337 * @high_freq: Edge Channel frequency.
5338 * @channel_enum: pointer to output channel enum.
5339 *
5340 * Return: None
5341 */
reg_find_high_limit_chan_enum_for_6g(struct regulatory_channel * chan_list,qdf_freq_t high_freq,enum channel_enum * channel_enum)5342 static void reg_find_high_limit_chan_enum_for_6g(
5343 struct regulatory_channel *chan_list,
5344 qdf_freq_t high_freq,
5345 enum channel_enum *channel_enum)
5346 {
5347 enum channel_enum chan_enum;
5348 uint16_t min_bw, max_bw, right_edge_of_min_band, right_edge_of_max_band;
5349 qdf_freq_t center_freq;
5350
5351 *channel_enum = 0;
5352 for (chan_enum = NUM_6GHZ_CHANNELS - 1; chan_enum >= 0; chan_enum--) {
5353 min_bw = chan_list[chan_enum].min_bw;
5354 max_bw = chan_list[chan_enum].max_bw;
5355 center_freq = chan_list[chan_enum].center_freq;
5356 right_edge_of_min_band = center_freq + min_bw / 2;
5357
5358 if (right_edge_of_min_band <= high_freq) {
5359 right_edge_of_max_band = center_freq + max_bw / 2;
5360 if (right_edge_of_max_band > high_freq) {
5361 if (max_bw <= 20)
5362 max_bw = ((high_freq -
5363 center_freq) * 2);
5364 if (max_bw < min_bw)
5365 max_bw = min_bw;
5366 chan_list[chan_enum].max_bw = max_bw;
5367 }
5368 *channel_enum = chan_enum;
5369 break;
5370 }
5371
5372 if (chan_enum == 0)
5373 break;
5374 }
5375 }
5376
5377 /**
5378 * reg_find_range_for_chan_idx() - Compute freq range object for the
5379 * given chan_enum in the given channel list.
5380 * @chan_enum: Channel enum
5381 * @afc_chan_list: Pointer to regulatory channel list
5382 * @range: Pointer to frequency range to be filled
5383 *
5384 * Return: None
5385 */
5386 static void
reg_find_range_for_chan_idx(enum channel_enum chan_enum,struct regulatory_channel * afc_chan_list,struct freq_range * range)5387 reg_find_range_for_chan_idx(enum channel_enum chan_enum,
5388 struct regulatory_channel *afc_chan_list,
5389 struct freq_range *range)
5390 {
5391 qdf_freq_t center_freq = afc_chan_list[chan_enum].center_freq;
5392 uint16_t min_bw = afc_chan_list[chan_enum].min_bw;
5393
5394 range->left = center_freq - min_bw / 2;
5395 range->right = center_freq + min_bw / 2;
5396 }
5397
5398 /**
5399 * reg_is_range_subset_of_freq_obj() - Return true if the given range
5400 * fits into the freq_obj range
5401 * @range: Pointer to range
5402 * @freq_obj: Pointer to frequency object
5403 *
5404 * Return: True if the range fits, false otherwise
5405 */
5406 static bool
reg_is_range_subset_of_freq_obj(struct freq_range * range,struct afc_freq_obj * freq_obj)5407 reg_is_range_subset_of_freq_obj(struct freq_range *range,
5408 struct afc_freq_obj *freq_obj)
5409 {
5410 return (range->left >= freq_obj->low_freq &&
5411 range->right <= freq_obj->high_freq);
5412 }
5413
5414 /**
5415 * reg_coalesce_afc_freq_info() - Coalesce the frequency objects of the
5416 * AFC payload.
5417 *
5418 * @power_info: Pointer to afc payload
5419 * @in_range: Pointer to the current freq range.
5420 * @in_out_freq_index: frequency index, is both an input and output value.
5421 * @out_coal_freq_obj: Pointer to coalesced freq range
5422 *
5423 * If the high freq of n_freq_obj is same as low_freq of
5424 * n+1_freq_obj, coalescing can be done. The coalesced object is the
5425 * minimum length object that includes the given @in_range. The in_range should
5426 * completely fall within the output coalesced frequency object.
5427 * "in_out_freq_index" is updated to the new index only if range fits
5428 * in the coalesced freq object and it is based on the number of
5429 * frequency objects coalesced.
5430 *
5431 * Return: None
5432 */
5433 static void
reg_coalesce_afc_freq_info(struct reg_fw_afc_power_event * power_info,struct freq_range * in_range,uint8_t * in_out_freq_index,struct afc_freq_obj * out_coal_freq_obj)5434 reg_coalesce_afc_freq_info(struct reg_fw_afc_power_event *power_info,
5435 struct freq_range *in_range,
5436 uint8_t *in_out_freq_index,
5437 struct afc_freq_obj *out_coal_freq_obj)
5438 {
5439 struct afc_freq_obj *cur_freq_obj, *n_freq_obj, coal_freq_obj;
5440 uint8_t cur_freq_index = *in_out_freq_index;
5441 uint8_t nxt_freq_index = cur_freq_index + 1;
5442
5443 coal_freq_obj = power_info->afc_freq_info[cur_freq_index];
5444 *out_coal_freq_obj = coal_freq_obj;
5445
5446 /* The low edge of the input range must fall within freq object
5447 * else coalescing is meaningless.
5448 * eg: center freq 6135 cannot fit in the range 6123-6129 and hence
5449 * considering this range need not be considered for any tx power
5450 * manipulation.
5451 */
5452 if (!IS_WITHIN_RANGE_ASYM(in_range->left, coal_freq_obj.low_freq,
5453 coal_freq_obj.high_freq))
5454 return;
5455
5456 /* Coalesecing is not needed if the input range is already a subset of
5457 * freq obj range of the afc payload.
5458 */
5459 if (reg_is_range_subset_of_freq_obj(in_range, &coal_freq_obj))
5460 return;
5461
5462 /* The input range is not within the first freq object.
5463 * Keep coalescing until the input range is found in the
5464 * coalesced object.
5465 */
5466 while (nxt_freq_index < power_info->num_freq_objs) {
5467 cur_freq_obj = &power_info->afc_freq_info[cur_freq_index];
5468 n_freq_obj = &power_info->afc_freq_info[nxt_freq_index];
5469
5470 if (cur_freq_obj->high_freq == n_freq_obj->low_freq) {
5471 coal_freq_obj.high_freq = n_freq_obj->high_freq;
5472 coal_freq_obj.max_psd = qdf_min(coal_freq_obj.max_psd,
5473 n_freq_obj->max_psd);
5474 /* Exit if the coalesced object already
5475 * includes the input range.
5476 */
5477 if (reg_is_range_subset_of_freq_obj(in_range,
5478 &coal_freq_obj)) {
5479 /* Since the coalesced object includes upto
5480 * nxt_freq_index, update the in_out_freq_index
5481 * so that it is used in the caller to skip
5482 * the last processed index.
5483 */
5484 *in_out_freq_index = nxt_freq_index;
5485 *out_coal_freq_obj = coal_freq_obj;
5486 return;
5487 }
5488 } else {
5489 /* current object and next object not continuous */
5490 break;
5491 }
5492 cur_freq_index++;
5493 nxt_freq_index++;
5494 }
5495
5496 reg_debug("Coalesced freq range: low: %u, high: %u, psd: %d\n",
5497 out_coal_freq_obj->low_freq, out_coal_freq_obj->high_freq,
5498 out_coal_freq_obj->max_psd);
5499 }
5500
5501 /**
5502 * reg_find_low_and_high_limit() - Find low_limit and high_limit channel enum
5503 * for the given freq range.
5504 * @afc_chan_list: Pointer to regulatory_channel
5505 * @freq_obj: Pointer to struct afc_freq_obj
5506 * @low_limit_enum: Pointer to low limit channel enum
5507 * @high_limit_enum: Pointer to high limit channel enum
5508 */
5509 static void
reg_find_low_and_high_limit(struct regulatory_channel * afc_chan_list,struct afc_freq_obj * freq_obj,enum channel_enum * low_limit_enum,enum channel_enum * high_limit_enum)5510 reg_find_low_and_high_limit(struct regulatory_channel *afc_chan_list,
5511 struct afc_freq_obj *freq_obj,
5512 enum channel_enum *low_limit_enum,
5513 enum channel_enum *high_limit_enum)
5514 {
5515 reg_find_low_limit_chan_enum_for_6g(afc_chan_list,
5516 freq_obj->low_freq,
5517 low_limit_enum);
5518 reg_find_high_limit_chan_enum_for_6g(afc_chan_list,
5519 freq_obj->high_freq,
5520 high_limit_enum);
5521 }
5522
5523 /**
5524 * reg_try_coalescing_freq_objs() - Try to coalesce frequency objects.
5525 *
5526 * @chan_enum: channel enum @afc_chan_list, that may be ignored by the
5527 * current frequency object power_info[*cur_freq_index], if coalescing
5528 * does not happen.
5529 * @afc_chan_list: Pointer to afc channel list
5530 * @power_info: Pointer to reg_fw_afc_power_event
5531 * @cur_freq_index: Pointer to freq_index of the afc payload
5532 * @coal_freq_obj: Pointer to coal_freq_obj
5533 *
5534 * Try to coalesce adjacent frequency objects of the afc response
5535 * if coalescing is needed. After coalescing, return the coalesced_freq_obj
5536 * if it is valid. If invalid, return the current freq object.
5537 *
5538 * Return: None
5539 */
5540 static void
reg_try_coalescing_freq_objs(enum channel_enum chan_enum,struct regulatory_channel * afc_chan_list,struct reg_fw_afc_power_event * power_info,uint8_t * cur_freq_index,struct afc_freq_obj * coal_freq_obj)5541 reg_try_coalescing_freq_objs(enum channel_enum chan_enum,
5542 struct regulatory_channel *afc_chan_list,
5543 struct reg_fw_afc_power_event *power_info,
5544 uint8_t *cur_freq_index,
5545 struct afc_freq_obj *coal_freq_obj)
5546 {
5547 struct freq_range range;
5548
5549 reg_find_range_for_chan_idx(chan_enum, afc_chan_list, &range);
5550 reg_coalesce_afc_freq_info(power_info, &range, cur_freq_index,
5551 coal_freq_obj);
5552 }
5553
5554 /**
5555 * reg_fill_max_psd_in_afc_chan_list() - Fill max_psd in the afc master chan
5556 * list
5557 * @pdev_priv_obj: Pointer to pdev_priv_obj
5558 * @afc_chan_list: Pointer to afc_chan_list
5559 * @power_info: Pointer to power_info
5560 *
5561 * Return: QDF_STATUS
5562 */
reg_fill_max_psd_in_afc_chan_list(struct wlan_regulatory_pdev_priv_obj * pdev_priv_obj,struct regulatory_channel * afc_chan_list,struct reg_fw_afc_power_event * power_info)5563 static QDF_STATUS reg_fill_max_psd_in_afc_chan_list(
5564 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
5565 struct regulatory_channel *afc_chan_list,
5566 struct reg_fw_afc_power_event *power_info)
5567 {
5568 uint8_t i;
5569 struct regulatory_channel *sp_chan_list;
5570 struct regulatory_channel *cfi_chan_list;
5571 enum channel_enum last_enum = reg_convert_enum_to_6g_idx(MIN_6GHZ_CHANNEL);
5572 struct afc_freq_obj coal_freq_obj = {};
5573
5574 if (!power_info) {
5575 reg_err("power_info is NULL");
5576 return QDF_STATUS_E_FAILURE;
5577 }
5578
5579 if (!power_info->num_freq_objs)
5580 reg_debug("num freq objs is zero");
5581
5582 cfi_chan_list = qdf_mem_malloc(sizeof(struct regulatory_channel) *
5583 NUM_6GHZ_CHANNELS);
5584
5585 if (!cfi_chan_list)
5586 return QDF_STATUS_E_NOMEM;
5587
5588 qdf_mem_copy(cfi_chan_list, afc_chan_list,
5589 sizeof(struct regulatory_channel) * NUM_6GHZ_CHANNELS);
5590 sp_chan_list =
5591 pdev_priv_obj->mas_chan_list_6g_ap[REG_STANDARD_POWER_AP];
5592
5593 reg_process_cfi_chan_list(pdev_priv_obj->pdev_ptr, cfi_chan_list,
5594 power_info);
5595
5596 for (i = 0; i < power_info->num_freq_objs; i++) {
5597 enum channel_enum low_limit_enum, high_limit_enum;
5598 uint8_t j;
5599
5600 /* Counter variable 'i' may be incremented in the following
5601 * function. The following function guarantees that 'i'
5602 * shall never be greater than the number of frequency objects.
5603 */
5604 reg_try_coalescing_freq_objs(last_enum, afc_chan_list,
5605 power_info, &i, &coal_freq_obj);
5606 reg_find_low_and_high_limit(afc_chan_list, &coal_freq_obj,
5607 &low_limit_enum, &high_limit_enum);
5608
5609 for (j = low_limit_enum; j <= high_limit_enum; j++) {
5610 if ((sp_chan_list[j].state == CHANNEL_STATE_ENABLE) &&
5611 (cfi_chan_list[j].state == CHANNEL_STATE_ENABLE)) {
5612 afc_chan_list[j].state = CHANNEL_STATE_ENABLE;
5613 afc_chan_list[j].chan_flags &=
5614 ~REGULATORY_CHAN_DISABLED;
5615 /*
5616 * The max_psd is divided by 100 because the
5617 * target sends the PSD in the units of
5618 * 0.01 dbm/MHz.
5619 */
5620 afc_chan_list[j].psd_eirp = coal_freq_obj.max_psd / 100;
5621 afc_chan_list[j].psd_flag = true;
5622 afc_chan_list[j].tx_power =
5623 cfi_chan_list[j].tx_power;
5624 }
5625 }
5626 last_enum = j;
5627 }
5628
5629 qdf_mem_free(cfi_chan_list);
5630
5631 return QDF_STATUS_SUCCESS;
5632 }
5633
5634 /**
5635 * reg_is_afc_mas_chan_list_valid() - Check if the AFC master channel list
5636 * is non-empty
5637 * @afc_mas_chan_list: Pointer to afc_mas_chan_list.
5638 *
5639 * Return: True, if atleast one channel has the state "CHANNEL_STATE_ENABLE",
5640 * else false.
5641 */
5642 static bool
reg_is_afc_mas_chan_list_valid(struct regulatory_channel * afc_mas_chan_list)5643 reg_is_afc_mas_chan_list_valid(struct regulatory_channel *afc_mas_chan_list)
5644 {
5645 uint8_t i;
5646
5647 for (i = 0; i < NUM_6GHZ_CHANNELS; i++)
5648 if (afc_mas_chan_list[i].state == CHANNEL_STATE_ENABLE)
5649 return true;
5650
5651 return false;
5652 }
5653
5654 /**
5655 * reg_process_afc_power_event() - Process the afc event and compute the 6G AFC
5656 * channel list based on the frequency range and channel frequency indice set.
5657 * @afc_info: Pointer to afc info
5658 *
5659 * Return: QDF_STATUS
5660 */
5661 static QDF_STATUS
reg_process_afc_power_event(struct afc_regulatory_info * afc_info)5662 reg_process_afc_power_event(struct afc_regulatory_info *afc_info)
5663 {
5664 struct wlan_objmgr_psoc *psoc;
5665 uint8_t phy_id;
5666 uint8_t pdev_id;
5667 wlan_objmgr_ref_dbgid dbg_id;
5668 struct wlan_objmgr_pdev *pdev;
5669 struct mas_chan_params *this_mchan_params;
5670 struct wlan_lmac_if_reg_tx_ops *tx_ops;
5671 struct regulatory_channel *afc_mas_chan_list;
5672 struct wlan_regulatory_psoc_priv_obj *soc_reg;
5673 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
5674 uint32_t size_of_6g_chan_list =
5675 NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel);
5676 QDF_STATUS status;
5677 enum reg_6g_ap_type cur_6g_ap_pwr_type;
5678
5679 QDF_TRACE(QDF_MODULE_ID_AFC, QDF_TRACE_LEVEL_DEBUG,
5680 "Processing AFC Power event");
5681
5682 psoc = afc_info->psoc;
5683 soc_reg = reg_get_psoc_obj(psoc);
5684
5685 if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) {
5686 reg_err("psoc reg component is NULL");
5687 return QDF_STATUS_E_FAILURE;
5688 }
5689
5690 tx_ops = reg_get_psoc_tx_ops(psoc);
5691 phy_id = afc_info->phy_id;
5692
5693 if (tx_ops->get_pdev_id_from_phy_id)
5694 tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id);
5695 else
5696 pdev_id = phy_id;
5697
5698 if (soc_reg->offload_enabled)
5699 dbg_id = WLAN_REGULATORY_NB_ID;
5700 else
5701 dbg_id = WLAN_REGULATORY_SB_ID;
5702
5703 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id);
5704
5705 if (!pdev) {
5706 reg_err("pdev is NULL");
5707 return QDF_STATUS_E_FAILURE;
5708 }
5709
5710 pdev_priv_obj = reg_get_pdev_obj(pdev);
5711
5712 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
5713 reg_err("reg pdev priv obj is NULL");
5714 wlan_objmgr_pdev_release_ref(pdev, dbg_id);
5715 return QDF_STATUS_E_FAILURE;
5716 }
5717
5718 if (afc_info->power_info->fw_status_code !=
5719 REG_FW_AFC_POWER_EVENT_SUCCESS) {
5720 reg_err_rl("AFC Power event failure status code %d",
5721 afc_info->power_info->fw_status_code);
5722 reg_reset_chan_list_and_power_event(pdev_priv_obj);
5723 reg_send_afc_power_event(pdev, afc_info->power_info);
5724 wlan_objmgr_pdev_release_ref(pdev, dbg_id);
5725 return QDF_STATUS_E_FAILURE;
5726 }
5727
5728 reg_debug("process reg afc master chan list");
5729 this_mchan_params = &soc_reg->mas_chan_params[phy_id];
5730 afc_mas_chan_list = this_mchan_params->mas_chan_list_6g_afc;
5731 qdf_mem_zero(afc_mas_chan_list,
5732 NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel));
5733 reg_init_6ghz_master_chan(afc_mas_chan_list, soc_reg);
5734 soc_reg->mas_chan_params[phy_id].is_6g_afc_power_event_received = true;
5735
5736 reg_init_pdev_super_chan_list(pdev_priv_obj);
5737 reg_init_6ghz_master_chan(pdev_priv_obj->afc_chan_list, soc_reg);
5738 /* Free the old power_info event if it was allocated */
5739 if (pdev_priv_obj->power_info)
5740 reg_free_afc_pwr_info(pdev_priv_obj);
5741
5742 pdev_priv_obj->power_info = afc_info->power_info;
5743 reg_fill_min_max_bw_for_afc_list(pdev_priv_obj,
5744 afc_mas_chan_list);
5745 status = reg_fill_max_psd_in_afc_chan_list(pdev_priv_obj,
5746 afc_mas_chan_list,
5747 afc_info->power_info);
5748 if (QDF_IS_STATUS_ERROR(status)) {
5749 reg_err("Error in filling max_psd in AFC chan list");
5750 wlan_objmgr_pdev_release_ref(pdev, dbg_id);
5751 return status;
5752 }
5753
5754 qdf_mem_copy(pdev_priv_obj->mas_chan_list_6g_afc,
5755 afc_mas_chan_list,
5756 size_of_6g_chan_list);
5757 pdev_priv_obj->is_6g_afc_power_event_received =
5758 soc_reg->mas_chan_params[phy_id].is_6g_afc_power_event_received;
5759
5760 reg_modify_6g_afc_chan_list(pdev_priv_obj);
5761 reg_compute_super_chan_list(pdev_priv_obj);
5762 reg_client_afc_populate_channels(psoc, pdev);
5763
5764 if (tx_ops->trigger_acs_for_afc &&
5765 !wlan_reg_is_noaction_on_afc_pwr_evt(pdev)) {
5766 reg_get_cur_6g_ap_pwr_type(pdev, &cur_6g_ap_pwr_type);
5767 /* Do not trigger when the current power mode is LPI/VLP and
5768 * there are no valid channels in the AFC response
5769 */
5770 if (cur_6g_ap_pwr_type == REG_STANDARD_POWER_AP ||
5771 reg_is_afc_mas_chan_list_valid(
5772 pdev_priv_obj->mas_chan_list_6g_afc)) {
5773 tx_ops->trigger_acs_for_afc(pdev);
5774 }
5775 }
5776
5777 reg_send_afc_power_event(pdev, afc_info->power_info);
5778 wlan_objmgr_pdev_release_ref(pdev, dbg_id);
5779
5780 return QDF_STATUS_SUCCESS;
5781 }
5782
5783 /**
5784 * reg_process_afc_event() - Process the afc event received from the target.
5785 * @afc_info: Pointer to afc_info
5786 *
5787 * Return: QDF_STATUS
5788 */
5789 QDF_STATUS
reg_process_afc_event(struct afc_regulatory_info * afc_info)5790 reg_process_afc_event(struct afc_regulatory_info *afc_info)
5791 {
5792 switch (afc_info->event_type) {
5793 case REG_AFC_EVENT_POWER_INFO:
5794 return reg_process_afc_power_event(afc_info);
5795 case REG_AFC_EVENT_TIMER_EXPIRY:
5796 return reg_process_afc_expiry_event(afc_info);
5797 default:
5798 reg_err_rl("Invalid event type");
5799 return QDF_STATUS_E_FAILURE;
5800 }
5801 }
5802 #endif /* CONFIG_AFC_SUPPORT */
5803 #ifdef CONFIG_REG_CLIENT
reg_get_power_string(enum reg_6g_ap_type power_type)5804 const char *reg_get_power_string(enum reg_6g_ap_type power_type)
5805 {
5806 switch (power_type) {
5807 case REG_INDOOR_AP:
5808 return "LP";
5809 case REG_STANDARD_POWER_AP:
5810 return "SP";
5811 case REG_VERY_LOW_POWER_AP:
5812 return "VLP";
5813 default:
5814 return "INVALID";
5815 }
5816 }
5817 #endif
5818 #endif /* CONFIG_BAND_6GHZ */
5819
5820 static QDF_STATUS
__reg_process_master_chan_list(struct cur_regulatory_info * regulat_info)5821 __reg_process_master_chan_list(struct cur_regulatory_info *regulat_info)
5822 {
5823 struct wlan_regulatory_psoc_priv_obj *soc_reg;
5824 uint32_t num_2g_reg_rules, num_5g_reg_rules, country_max_allowed_bw = 0;
5825 struct cur_reg_rule *reg_rule_2g, *reg_rule_5g;
5826 uint16_t min_bw_2g, max_bw_2g, min_bw_5g, max_bw_5g;
5827 struct regulatory_channel *mas_chan_list;
5828 struct wlan_objmgr_psoc *psoc;
5829 wlan_objmgr_ref_dbgid dbg_id;
5830 enum direction dir;
5831 uint8_t phy_id;
5832 uint8_t pdev_id;
5833 struct wlan_objmgr_pdev *pdev;
5834 struct wlan_lmac_if_reg_tx_ops *tx_ops;
5835 struct reg_rule_info *reg_rules;
5836 QDF_STATUS status;
5837
5838 psoc = regulat_info->psoc;
5839 soc_reg = reg_get_psoc_obj(psoc);
5840
5841 if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) {
5842 reg_err("psoc reg component is NULL");
5843 return QDF_STATUS_E_FAILURE;
5844 }
5845
5846 tx_ops = reg_get_psoc_tx_ops(psoc);
5847 phy_id = regulat_info->phy_id;
5848
5849 if (tx_ops->get_pdev_id_from_phy_id)
5850 tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id);
5851 else
5852 pdev_id = phy_id;
5853
5854 if (reg_ignore_default_country(soc_reg, regulat_info)) {
5855 status = reg_set_curr_country(soc_reg, regulat_info, tx_ops);
5856 if (QDF_IS_STATUS_SUCCESS(status)) {
5857 reg_debug("WLAN restart - Ignore default CC for phy_id: %u",
5858 phy_id);
5859 return QDF_STATUS_SUCCESS;
5860 }
5861 }
5862
5863 reg_debug("process reg master chan list");
5864
5865 if (soc_reg->offload_enabled) {
5866 dbg_id = WLAN_REGULATORY_NB_ID;
5867 dir = NORTHBOUND;
5868 } else {
5869 dbg_id = WLAN_REGULATORY_SB_ID;
5870 dir = SOUTHBOUND;
5871 }
5872
5873 status = reg_soc_vars_reset_on_failure(regulat_info->status_code,
5874 soc_reg, phy_id);
5875
5876 if (!QDF_IS_STATUS_SUCCESS(status))
5877 return status;
5878
5879 mas_chan_list = soc_reg->mas_chan_params[phy_id].mas_chan_list;
5880
5881 reg_init_channel_map(regulat_info->dfs_region);
5882
5883 reg_init_legacy_master_chan(mas_chan_list, soc_reg);
5884
5885 soc_reg->num_phy = regulat_info->num_phy;
5886 soc_reg->mas_chan_params[phy_id].phybitmap =
5887 regulat_info->phybitmap;
5888 soc_reg->mas_chan_params[phy_id].dfs_region =
5889 regulat_info->dfs_region;
5890 soc_reg->mas_chan_params[phy_id].ctry_code =
5891 regulat_info->ctry_code;
5892 soc_reg->mas_chan_params[phy_id].reg_dmn_pair =
5893 regulat_info->reg_dmn_pair;
5894 qdf_mem_copy(soc_reg->mas_chan_params[phy_id].current_country,
5895 regulat_info->alpha2,
5896 REG_ALPHA2_LEN + 1);
5897 qdf_mem_copy(soc_reg->cur_country,
5898 regulat_info->alpha2,
5899 REG_ALPHA2_LEN + 1);
5900 reg_debug("set cur_country %.2s", soc_reg->cur_country);
5901
5902 min_bw_2g = regulat_info->min_bw_2g;
5903 max_bw_2g = regulat_info->max_bw_2g;
5904 reg_rule_2g = regulat_info->reg_rules_2g_ptr;
5905 num_2g_reg_rules = regulat_info->num_2g_reg_rules;
5906 reg_update_max_bw_per_rule(num_2g_reg_rules,
5907 reg_rule_2g, max_bw_2g,
5908 &country_max_allowed_bw);
5909
5910 min_bw_5g = regulat_info->min_bw_5g;
5911 max_bw_5g = regulat_info->max_bw_5g;
5912 reg_rule_5g = regulat_info->reg_rules_5g_ptr;
5913 num_5g_reg_rules = regulat_info->num_5g_reg_rules;
5914 reg_update_max_bw_per_rule(num_5g_reg_rules,
5915 reg_rule_5g, max_bw_5g,
5916 &country_max_allowed_bw);
5917
5918 soc_reg->country_max_allowed_bw = country_max_allowed_bw;
5919 soc_reg->mas_chan_params[phy_id].max_bw_5g = regulat_info->max_bw_5g;
5920 reg_rules = &soc_reg->mas_chan_params[phy_id].reg_rules;
5921 reg_reset_reg_rules(reg_rules);
5922
5923 reg_rules->num_of_reg_rules = num_5g_reg_rules + num_2g_reg_rules;
5924 if (reg_rules->num_of_reg_rules > MAX_REG_RULES) {
5925 reg_err("number of reg rules exceeds limit");
5926 return QDF_STATUS_E_FAILURE;
5927 }
5928
5929 if (reg_rules->num_of_reg_rules) {
5930 if (num_2g_reg_rules)
5931 qdf_mem_copy(reg_rules->reg_rules,
5932 reg_rule_2g, num_2g_reg_rules *
5933 sizeof(struct cur_reg_rule));
5934 if (num_5g_reg_rules)
5935 qdf_mem_copy(reg_rules->reg_rules +
5936 num_2g_reg_rules, reg_rule_5g,
5937 num_5g_reg_rules *
5938 sizeof(struct cur_reg_rule));
5939 }
5940
5941 if (num_5g_reg_rules != 0)
5942 reg_do_auto_bw_correction(num_5g_reg_rules,
5943 reg_rule_5g, max_bw_5g);
5944
5945 if (num_2g_reg_rules != 0)
5946 reg_populate_band_channels(MIN_24GHZ_CHANNEL, MAX_24GHZ_CHANNEL,
5947 reg_rule_2g, num_2g_reg_rules,
5948 min_bw_2g, mas_chan_list);
5949
5950 if (num_5g_reg_rules != 0) {
5951 reg_populate_band_channels(MIN_5GHZ_CHANNEL, MAX_5GHZ_CHANNEL,
5952 reg_rule_5g, num_5g_reg_rules,
5953 min_bw_5g, mas_chan_list);
5954 reg_populate_49g_band_channels(reg_rule_5g,
5955 num_5g_reg_rules,
5956 min_bw_5g,
5957 mas_chan_list);
5958 reg_populate_6g_band_channels(reg_rule_5g,
5959 num_5g_reg_rules,
5960 min_bw_5g,
5961 mas_chan_list);
5962 }
5963
5964 soc_reg->chan_list_recvd[phy_id] = true;
5965 status = reg_send_ctl_info(soc_reg, regulat_info, tx_ops);
5966 if (!QDF_IS_STATUS_SUCCESS(status))
5967 return status;
5968
5969 if (soc_reg->new_user_ctry_pending[phy_id]) {
5970 soc_reg->new_user_ctry_pending[phy_id] = false;
5971 soc_reg->cc_src = SOURCE_USERSPACE;
5972 soc_reg->user_ctry_set = true;
5973 reg_debug("new user country is set");
5974 reg_run_11d_state_machine(psoc);
5975 } else if (soc_reg->new_init_ctry_pending[phy_id]) {
5976 soc_reg->new_init_ctry_pending[phy_id] = false;
5977 soc_reg->cc_src = SOURCE_USERSPACE;
5978 reg_debug("new init country is set");
5979 } else if (soc_reg->new_11d_ctry_pending[phy_id]) {
5980 soc_reg->new_11d_ctry_pending[phy_id] = false;
5981 soc_reg->cc_src = SOURCE_11D;
5982 soc_reg->user_ctry_set = false;
5983 reg_run_11d_state_machine(psoc);
5984 } else if (soc_reg->world_country_pending[phy_id]) {
5985 soc_reg->world_country_pending[phy_id] = false;
5986 soc_reg->cc_src = SOURCE_CORE;
5987 soc_reg->user_ctry_set = false;
5988 reg_run_11d_state_machine(psoc);
5989 } else {
5990 if (soc_reg->cc_src == SOURCE_UNKNOWN &&
5991 soc_reg->num_phy == phy_id + 1)
5992 soc_reg->cc_src = SOURCE_DRIVER;
5993
5994 qdf_mem_copy(soc_reg->mas_chan_params[phy_id].default_country,
5995 regulat_info->alpha2,
5996 REG_ALPHA2_LEN + 1);
5997
5998 soc_reg->mas_chan_params[phy_id].def_country_code =
5999 regulat_info->ctry_code;
6000 soc_reg->mas_chan_params[phy_id].def_region_domain =
6001 regulat_info->reg_dmn_pair;
6002
6003 if (soc_reg->cc_src == SOURCE_DRIVER) {
6004 qdf_mem_copy(soc_reg->def_country,
6005 regulat_info->alpha2,
6006 REG_ALPHA2_LEN + 1);
6007
6008 soc_reg->def_country_code = regulat_info->ctry_code;
6009 soc_reg->def_region_domain =
6010 regulat_info->reg_dmn_pair;
6011
6012 if (reg_is_world_alpha2(regulat_info->alpha2)) {
6013 soc_reg->cc_src = SOURCE_CORE;
6014 reg_run_11d_state_machine(psoc);
6015 }
6016 }
6017 }
6018
6019 status = reg_set_psoc_fcc_rules(soc_reg, regulat_info);
6020 if (!QDF_IS_STATUS_SUCCESS(status))
6021 return status;
6022
6023 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id);
6024 if (pdev) {
6025 status = reg_propagate_mas_chan_list_and_fill_legacy_list(psoc,
6026 pdev,
6027 dir,
6028 dbg_id);
6029 wlan_objmgr_pdev_release_ref(pdev, dbg_id);
6030 return status;
6031 }
6032
6033 return QDF_STATUS_SUCCESS;
6034 }
6035
reg_process_master_chan_list(struct cur_regulatory_info * regulat_info)6036 QDF_STATUS reg_process_master_chan_list(
6037 struct cur_regulatory_info *regulat_info)
6038 {
6039 QDF_STATUS status;
6040 struct wlan_lmac_if_reg_tx_ops *reg_tx_ops;
6041 struct wlan_objmgr_psoc *psoc;
6042 struct wlan_objmgr_pdev *pdev;
6043 wlan_objmgr_ref_dbgid dbg_id;
6044
6045 status = __reg_process_master_chan_list(regulat_info);
6046 psoc = regulat_info->psoc;
6047 reg_tx_ops = reg_get_psoc_tx_ops(psoc);
6048 if (!reg_tx_ops->set_wait_for_init_cc_response_event)
6049 return status;
6050
6051 pdev = reg_get_pdev_from_phy_id(psoc, regulat_info->phy_id, reg_tx_ops,
6052 regulat_info->offload_enabled,
6053 &dbg_id);
6054 if (!pdev) {
6055 reg_err("pdev obj is NULL");
6056 return QDF_STATUS_E_FAILURE;
6057 }
6058
6059 reg_tx_ops->set_wait_for_init_cc_response_event(pdev, status);
6060
6061 wlan_objmgr_pdev_release_ref(pdev, dbg_id);
6062 return status;
6063 }
6064
reg_get_current_chan_list(struct wlan_objmgr_pdev * pdev,struct regulatory_channel * chan_list)6065 QDF_STATUS reg_get_current_chan_list(struct wlan_objmgr_pdev *pdev,
6066 struct regulatory_channel *chan_list)
6067 {
6068 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
6069
6070 pdev_priv_obj = reg_get_pdev_obj(pdev);
6071
6072 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
6073 reg_err("reg pdev private obj is NULL");
6074 return QDF_STATUS_E_FAILURE;
6075 }
6076
6077 qdf_mem_copy(chan_list, pdev_priv_obj->cur_chan_list,
6078 NUM_CHANNELS * sizeof(struct regulatory_channel));
6079
6080 return QDF_STATUS_SUCCESS;
6081 }
6082
6083 #ifdef CONFIG_REG_CLIENT
6084 QDF_STATUS
reg_get_secondary_current_chan_list(struct wlan_objmgr_pdev * pdev,struct regulatory_channel * chan_list)6085 reg_get_secondary_current_chan_list(struct wlan_objmgr_pdev *pdev,
6086 struct regulatory_channel *chan_list)
6087 {
6088 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
6089
6090 pdev_priv_obj = reg_get_pdev_obj(pdev);
6091
6092 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
6093 reg_err("reg pdev private obj is NULL");
6094 return QDF_STATUS_E_FAILURE;
6095 }
6096
6097 qdf_mem_copy(chan_list, pdev_priv_obj->secondary_cur_chan_list,
6098 NUM_CHANNELS * sizeof(struct regulatory_channel));
6099
6100 return QDF_STATUS_SUCCESS;
6101 }
6102 #endif
6103
6104 #if defined(CONFIG_AFC_SUPPORT) && defined(CONFIG_BAND_6GHZ)
reg_get_6g_afc_chan_list(struct wlan_objmgr_pdev * pdev,struct regulatory_channel * chan_list)6105 QDF_STATUS reg_get_6g_afc_chan_list(struct wlan_objmgr_pdev *pdev,
6106 struct regulatory_channel *chan_list)
6107 {
6108 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
6109 struct regulatory_channel *afc_chan_list;
6110
6111 pdev_priv_obj = reg_get_pdev_obj(pdev);
6112
6113 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
6114 reg_err("reg pdev private obj is NULL");
6115 return QDF_STATUS_E_FAILURE;
6116 }
6117
6118 afc_chan_list = pdev_priv_obj->afc_chan_list;
6119 qdf_mem_copy(chan_list, afc_chan_list,
6120 NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel));
6121
6122 return QDF_STATUS_SUCCESS;
6123 }
6124
6125 QDF_STATUS
reg_get_6g_afc_mas_chan_list(struct wlan_objmgr_pdev * pdev,struct regulatory_channel * chan_list)6126 reg_get_6g_afc_mas_chan_list(struct wlan_objmgr_pdev *pdev,
6127 struct regulatory_channel *chan_list)
6128 {
6129 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
6130
6131 pdev_priv_obj = reg_get_pdev_obj(pdev);
6132
6133 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
6134 reg_err("reg pdev private obj is NULL");
6135 return QDF_STATUS_E_FAILURE;
6136 }
6137
6138 qdf_mem_copy(chan_list, pdev_priv_obj->mas_chan_list_6g_afc,
6139 NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel));
6140
6141 return QDF_STATUS_SUCCESS;
6142 }
6143 #endif
6144
6145 #ifdef CONFIG_BAND_6GHZ
6146 /**
6147 * struct bw_10log10_pair - The bandwidth and 10*log10(bandwidth) pair.
6148 * ten_l_len = trunc(10*log10(bw)). 'trunc' is truncation function.
6149 * @bw: The input bandwidth
6150 * @ten_l_ten: Integer value of 10 times the Logarithm (to the base-10) of the
6151 * input bandwidth(@bw).
6152 */
6153 struct bw_10log10_pair {
6154 uint16_t bw;
6155 int16_t ten_l_ten;
6156 };
6157
6158 /* The array of bandwidth to trunc(10log10(bandwidth)) mapping */
6159 static const struct bw_10log10_pair bw_to_10log10_map[] = {
6160 { 20, 13}, /* 10* 1.30102 = 13.0102 */
6161 { 40, 16}, /* 10* 1.60205 = 16.0205 */
6162 { 80, 19}, /* 10* 1.90308 = 19.0308 */
6163 {160, 22}, /* 10* 2.20411 = 22.0411 */
6164 #ifdef WLAN_FEATURE_11BE
6165 {320, 25}, /* 10* 2.50514 = 25.0514 */
6166 { 60, 18}, /* 10* 1.77815 = 17.7815 */
6167 {140, 21}, /* 10* 2.14612 = 21.4612 */
6168 {120, 21}, /* 10* 2.07918 = 20.7918 */
6169 {200, 23}, /* 10* 2.30102 = 23.0102 */
6170 {240, 24}, /* 10* 2.38021 = 23.8021 */
6171 {280, 24}, /* 10* 2.44715 = 24.4715 */
6172 #endif
6173 };
6174
reg_psd_2_eirp(struct wlan_objmgr_pdev * pdev,int16_t psd,uint16_t ch_bw,int16_t * eirp)6175 QDF_STATUS reg_psd_2_eirp(struct wlan_objmgr_pdev *pdev,
6176 int16_t psd,
6177 uint16_t ch_bw,
6178 int16_t *eirp)
6179 {
6180 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
6181 int16_t ten_log10_bw;
6182 uint8_t i;
6183 uint8_t num_bws;
6184
6185 pdev_priv_obj = reg_get_pdev_obj(pdev);
6186
6187 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
6188 reg_err("reg pdev private obj is NULL");
6189 return QDF_STATUS_E_FAILURE;
6190 }
6191
6192 /* EIRP = PSD + (10 * log10(CH_BW)) */
6193 num_bws = QDF_ARRAY_SIZE(bw_to_10log10_map);
6194 for (i = 0; i < num_bws; i++) {
6195 if (ch_bw == bw_to_10log10_map[i].bw) {
6196 ten_log10_bw = bw_to_10log10_map[i].ten_l_ten;
6197 *eirp = psd + ten_log10_bw;
6198 return QDF_STATUS_SUCCESS;
6199 }
6200 }
6201 reg_err("Invalid input bandwidth %hd", ch_bw);
6202 return QDF_STATUS_E_FAILURE;
6203 }
6204
reg_eirp_2_psd(struct wlan_objmgr_pdev * pdev,uint16_t ch_bw,int16_t eirp,int16_t * psd)6205 QDF_STATUS reg_eirp_2_psd(struct wlan_objmgr_pdev *pdev,
6206 uint16_t ch_bw,
6207 int16_t eirp,
6208 int16_t *psd)
6209 {
6210 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
6211 int16_t ten_log10_bw;
6212 uint8_t i;
6213 uint8_t num_bws;
6214
6215 pdev_priv_obj = reg_get_pdev_obj(pdev);
6216
6217 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
6218 reg_err("reg pdev private obj is NULL");
6219 return QDF_STATUS_E_FAILURE;
6220 }
6221
6222 /* EIRP = PSD + (10 * log10(CH_BW)) */
6223 num_bws = QDF_ARRAY_SIZE(bw_to_10log10_map);
6224 for (i = 0; i < num_bws; i++) {
6225 if (ch_bw == bw_to_10log10_map[i].bw) {
6226 ten_log10_bw = bw_to_10log10_map[i].ten_l_ten;
6227 *psd = eirp - ten_log10_bw;
6228 return QDF_STATUS_SUCCESS;
6229 }
6230 }
6231 reg_err("Invalid input bandwidth %hd", ch_bw);
6232 return QDF_STATUS_E_FAILURE;
6233 }
6234 #endif
6235