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  					       &regd_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, &params);
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