1 /*
2  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-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 
22 			s a p C h S e l e c t . C
23    OVERVIEW:
24 
25    This software unit holds the implementation of the WLAN SAP modules
26    functions for channel selection.
27 
28    DEPENDENCIES:
29 
30    Are listed for each API below.
31    ===========================================================================*/
32 
33 /*--------------------------------------------------------------------------
34    Include Files
35    ------------------------------------------------------------------------*/
36 #include "qdf_trace.h"
37 #include "csr_api.h"
38 #include "sme_api.h"
39 #include "sap_ch_select.h"
40 #include "sap_internal.h"
41 #ifdef ANI_OS_TYPE_QNX
42 #include "stdio.h"
43 #endif
44 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
45 #include "lim_utils.h"
46 #include "parser_api.h"
47 #include <wlan_utility.h>
48 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
49 #include "cds_utils.h"
50 #include "pld_common.h"
51 #include "wlan_reg_services_api.h"
52 #include <wlan_scan_utils_api.h>
53 #include <wlan_cp_stats_mc_ucfg_api.h>
54 #include <wlan_policy_mgr_api.h>
55 
56 /*--------------------------------------------------------------------------
57    Function definitions
58    --------------------------------------------------------------------------*/
59 
60 /*--------------------------------------------------------------------------
61    Defines
62    --------------------------------------------------------------------------*/
63 #define SAP_DEBUG
64 
65 #define IS_RSSI_VALID(extRssi, rssi) \
66 	( \
67 		((extRssi < rssi) ? true : false) \
68 	)
69 
70 #define SET_ACS_BAND(acs_band, sap_ctx) \
71 { \
72 	if (sap_ctx->acs_cfg->start_ch_freq <= \
73 	    WLAN_REG_CH_TO_FREQ(CHAN_ENUM_2484) && \
74 	    sap_ctx->acs_cfg->end_ch_freq <= \
75 			WLAN_REG_CH_TO_FREQ(CHAN_ENUM_2484)) \
76 		acs_band = eCSR_DOT11_MODE_11g; \
77 	else if (sap_ctx->acs_cfg->start_ch_freq >= \
78 		 WLAN_REG_CH_TO_FREQ(CHAN_ENUM_2484))\
79 		acs_band = eCSR_DOT11_MODE_11a; \
80 	else \
81 		acs_band = eCSR_DOT11_MODE_abg; \
82 }
83 
84 #define ACS_WEIGHT_AMOUNT_LOCAL    240
85 
86 #define ACS_WEIGHT_AMOUNT_CONFIG(weights) \
87 	(((weights) & 0xf) + \
88 	(((weights) & 0xf0) >> 4) + \
89 	(((weights) & 0xf00) >> 8) + \
90 	(((weights) & 0xf000) >> 12) + \
91 	(((weights) & 0xf0000) >> 16) + \
92 	(((weights) & 0xf00000) >> 20) + \
93 	(((weights) & 0xf000000) >> 24))
94 
95 /*
96  * LSH/RSH 4 to enhance the accurate since
97  * need to do modulation to ACS_WEIGHT_AMOUNT_LOCAL.
98  */
99 #define ACS_WEIGHT_COMPUTE(weights, weight, factor, base) \
100 	(((((((((weight) << 4) * ACS_WEIGHT_AMOUNT_LOCAL * (factor)) + \
101 	(ACS_WEIGHT_AMOUNT_CONFIG((weights)) >> 1)) / \
102 	ACS_WEIGHT_AMOUNT_CONFIG((weights))) + \
103 	((base) >> 1)) / (base)) + 8) >> 4)
104 
105 #define ACS_WEIGHT_CFG_TO_LOCAL(weights, weight) \
106 	(((((((weight) << 4) * ACS_WEIGHT_AMOUNT_LOCAL) + \
107 	(ACS_WEIGHT_AMOUNT_CONFIG((weights)) >> 1)) / \
108 	ACS_WEIGHT_AMOUNT_CONFIG((weights))) + 8) >> 4)
109 
110 #define ACS_WEIGHT_SOFTAP_RSSI_CFG(weights) \
111 	((weights) & 0xf)
112 
113 #define ACS_WEIGHT_SOFTAP_COUNT_CFG(weights) \
114 	(((weights) & 0xf0) >> 4)
115 
116 #define ACS_WEIGHT_SOFTAP_NOISE_FLOOR_CFG(weights) \
117 	(((weights) & 0xf00) >> 8)
118 
119 #define ACS_WEIGHT_SOFTAP_CHANNEL_FREE_CFG(weights) \
120 	(((weights) & 0xf000) >> 12)
121 
122 #define ACS_WEIGHT_SOFTAP_TX_POWER_RANGE_CFG(weights) \
123 	(((weights) & 0xf0000) >> 16)
124 
125 #define ACS_WEIGHT_SOFTAP_TX_POWER_THROUGHPUT_CFG(weights) \
126 	(((weights) & 0xf00000) >> 20)
127 
128 #define ACS_WEIGHT_SOFTAP_REG_MAX_POWER_CFG(weights) \
129 	(((weights) & 0xf000000) >> 24)
130 
131 typedef struct {
132 	uint16_t chStartNum;
133 	uint32_t weight;
134 } sapAcsChannelInfo;
135 
136 sapAcsChannelInfo acs_ht40_channels5_g[] = {
137 	{36, SAP_ACS_WEIGHT_MAX},
138 	{44, SAP_ACS_WEIGHT_MAX},
139 	{52, SAP_ACS_WEIGHT_MAX},
140 	{60, SAP_ACS_WEIGHT_MAX},
141 	{100, SAP_ACS_WEIGHT_MAX},
142 	{108, SAP_ACS_WEIGHT_MAX},
143 	{116, SAP_ACS_WEIGHT_MAX},
144 	{124, SAP_ACS_WEIGHT_MAX},
145 	{132, SAP_ACS_WEIGHT_MAX},
146 	{140, SAP_ACS_WEIGHT_MAX},
147 	{149, SAP_ACS_WEIGHT_MAX},
148 	{157, SAP_ACS_WEIGHT_MAX},
149 };
150 
151 sapAcsChannelInfo acs_ht80_channels[] = {
152 	{36, SAP_ACS_WEIGHT_MAX},
153 	{52, SAP_ACS_WEIGHT_MAX},
154 	{100, SAP_ACS_WEIGHT_MAX},
155 	{116, SAP_ACS_WEIGHT_MAX},
156 	{132, SAP_ACS_WEIGHT_MAX},
157 	{149, SAP_ACS_WEIGHT_MAX},
158 };
159 
160 sapAcsChannelInfo acs_vht160_channels[] = {
161 	{36, SAP_ACS_WEIGHT_MAX},
162 	{100, SAP_ACS_WEIGHT_MAX},
163 };
164 
165 sapAcsChannelInfo acs_ht40_channels24_g[] = {
166 	{1, SAP_ACS_WEIGHT_MAX},
167 	{2, SAP_ACS_WEIGHT_MAX},
168 	{3, SAP_ACS_WEIGHT_MAX},
169 	{4, SAP_ACS_WEIGHT_MAX},
170 	{9, SAP_ACS_WEIGHT_MAX},
171 };
172 
173 #define CHANNEL_165  165
174 
175 /* rssi discount for channels in PCL */
176 #define PCL_RSSI_DISCOUNT 10
177 
178 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
179 /**
180  * sap_check_n_add_channel() - checks and add given channel in sap context's
181  * avoid_channels_info struct
182  * @sap_ctx:           sap context.
183  * @new_channel:       channel to be added to sap_ctx's avoid ch info
184  *
185  * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on
186  * which MDM device's AP with MCC was detected. This function will add channels
187  * to that list after checking for duplicates.
188  *
189  * Return: true: if channel was added or already present
190  *   else false: if channel list was already full.
191  */
192 static bool
sap_check_n_add_channel(struct sap_context * sap_ctx,uint8_t new_channel)193 sap_check_n_add_channel(struct sap_context *sap_ctx,
194 			uint8_t new_channel)
195 {
196 	uint8_t i = 0;
197 	struct sap_avoid_channels_info *ie_info =
198 		&sap_ctx->sap_detected_avoid_ch_ie;
199 
200 	for (i = 0; i < sizeof(ie_info->channels); i++) {
201 		if (ie_info->channels[i] == new_channel)
202 			break;
203 
204 		if (ie_info->channels[i] == 0) {
205 			ie_info->channels[i] = new_channel;
206 			break;
207 		}
208 	}
209 	if (i == sizeof(ie_info->channels))
210 		return false;
211 	else
212 		return true;
213 }
214 /**
215  * sap_check_n_add_overlapped_chnls() - checks & add overlapped channels
216  *                                      to primary channel in 2.4Ghz band.
217  * @sap_ctx:           sap context.
218  * @primary_channel:      primary channel to be avoided.
219  *
220  * sap_ctx contains sap_avoid_ch_info struct containing the list of channels on
221  * which MDM device's AP with MCC was detected. This function will add channels
222  * to that list after checking for duplicates.
223  *
224  * Return: true: if channel was added or already present
225  *   else false: if channel list was already full.
226  */
227 static bool
sap_check_n_add_overlapped_chnls(struct sap_context * sap_ctx,uint8_t primary_channel)228 sap_check_n_add_overlapped_chnls(struct sap_context *sap_ctx,
229 				 uint8_t primary_channel)
230 {
231 	uint8_t i = 0, j = 0, upper_chnl = 0, lower_chnl = 0;
232 	struct sap_avoid_channels_info *ie_info =
233 		&sap_ctx->sap_detected_avoid_ch_ie;
234 	/*
235 	 * if primary channel less than channel 1 or out of 2g band then
236 	 * no further process is required. return true in this case.
237 	 */
238 	if (primary_channel < CHANNEL_1 || primary_channel > CHANNEL_14)
239 		return true;
240 
241 	/* lower channel is one channel right before primary channel */
242 	lower_chnl = primary_channel - 1;
243 	/* upper channel is one channel right after primary channel */
244 	upper_chnl = primary_channel + 1;
245 
246 	/* lower channel needs to be non-zero, zero is not valid channel */
247 	if (lower_chnl > (CHANNEL_1 - 1)) {
248 		for (i = 0; i < sizeof(ie_info->channels); i++) {
249 			if (ie_info->channels[i] == lower_chnl)
250 				break;
251 			if (ie_info->channels[i] == 0) {
252 				ie_info->channels[i] = lower_chnl;
253 				break;
254 			}
255 		}
256 	}
257 	/* upper channel needs to be atleast last channel in 2.4Ghz band */
258 	if (upper_chnl < (CHANNEL_14 + 1)) {
259 		for (j = 0; j < sizeof(ie_info->channels); j++) {
260 			if (ie_info->channels[j] == upper_chnl)
261 				break;
262 			if (ie_info->channels[j] == 0) {
263 				ie_info->channels[j] = upper_chnl;
264 				break;
265 			}
266 		}
267 	}
268 	if (i == sizeof(ie_info->channels) || j == sizeof(ie_info->channels))
269 		return false;
270 	else
271 		return true;
272 }
273 
274 /**
275  * sap_process_avoid_ie() - processes the detected Q2Q IE
276  * context's avoid_channels_info struct
277  * @mac_ctx:            pointer to mac_context structure
278  * @sap_ctx:            sap context.
279  * @scan_list:        scan results for ACS scan.
280  * @spect_info:         spectrum weights array to update
281  *
282  * Detection of Q2Q IE indicates presence of another MDM device with its AP
283  * operating in MCC mode. This function parses the scan results and processes
284  * the Q2Q IE if found. It then extracts the channels and populates them in
285  * sap_ctx struct. It also increases the weights of those channels so that
286  * ACS logic will avoid those channels in its selection algorithm.
287  *
288  * Return: void
289  */
290 static void
sap_process_avoid_ie(struct mac_context * mac_ctx,struct sap_context * sap_ctx,qdf_list_t * scan_list,struct sap_sel_ch_info * spect_info)291 sap_process_avoid_ie(struct mac_context *mac_ctx,
292 		     struct sap_context *sap_ctx,
293 		     qdf_list_t *scan_list,
294 		     struct sap_sel_ch_info *spect_info)
295 {
296 	const uint8_t *temp_ptr = NULL;
297 	uint8_t i = 0;
298 	struct sAvoidChannelIE *avoid_ch_ie;
299 	struct sap_ch_info *spect_ch = NULL;
300 	qdf_list_node_t *cur_lst = NULL, *next_lst = NULL;
301 	struct scan_cache_node *cur_node = NULL;
302 	uint32_t chan_freq;
303 
304 	spect_ch = spect_info->ch_info;
305 
306 	if (scan_list)
307 		qdf_list_peek_front(scan_list, &cur_lst);
308 
309 	while (cur_lst) {
310 		cur_node = qdf_container_of(cur_lst, struct scan_cache_node,
311 					    node);
312 
313 		temp_ptr = wlan_get_vendor_ie_ptr_from_oui(
314 				SIR_MAC_QCOM_VENDOR_OUI,
315 				SIR_MAC_QCOM_VENDOR_SIZE,
316 				util_scan_entry_ie_data(cur_node->entry),
317 				util_scan_entry_ie_len(cur_node->entry));
318 
319 		if (temp_ptr) {
320 			avoid_ch_ie = (struct sAvoidChannelIE *)temp_ptr;
321 			if (avoid_ch_ie->type !=
322 					QCOM_VENDOR_IE_MCC_AVOID_CH) {
323 				qdf_list_peek_next(scan_list,
324 						   cur_lst, &next_lst);
325 				cur_lst = next_lst;
326 				next_lst = NULL;
327 				continue;
328 			}
329 
330 			sap_ctx->sap_detected_avoid_ch_ie.present = 1;
331 
332 			chan_freq =
333 			    wlan_reg_legacy_chan_to_freq(mac_ctx->pdev,
334 							 avoid_ch_ie->channel);
335 
336 			sap_debug("Q2Q-IE avoid freq = %d", chan_freq);
337 			/* add this channel to to_avoid channel list */
338 			sap_check_n_add_channel(sap_ctx, avoid_ch_ie->channel);
339 			sap_check_n_add_overlapped_chnls(sap_ctx,
340 							 avoid_ch_ie->channel);
341 			/*
342 			 * Mark weight of these channel present in IE to MAX
343 			 * so that ACS logic will to avoid thse channels
344 			 */
345 			for (i = 0; i < spect_info->num_ch; i++) {
346 				if (spect_ch[i].chan_freq != chan_freq)
347 					continue;
348 				/*
349 				 * weight is set more than max so that,
350 				 * in the case of other channels being
351 				 * assigned max weight due to noise,
352 				 * they may be preferred over channels
353 				 * with Q2Q IE.
354 				 */
355 				spect_ch[i].weight = SAP_ACS_WEIGHT_MAX + 1;
356 				spect_ch[i].weight_copy =
357 							SAP_ACS_WEIGHT_MAX + 1;
358 				break;
359 			}
360 		}
361 
362 		qdf_list_peek_next(scan_list, cur_lst, &next_lst);
363 		cur_lst = next_lst;
364 		next_lst = NULL;
365 	}
366 }
367 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
368 
369 /**
370  * sap_select_preferred_channel_from_channel_list() - to calc best channel
371  * @best_ch_freq: best chan freq already calculated among all the channels
372  * @sap_ctx: sap context
373  * @spectinfo_param: Pointer to sap_sel_ch_info structure
374  *
375  * This function calculates the best channel among the configured channel list.
376  * If channel list not configured then returns the best channel calculated
377  * among all the channel list.
378  *
379  * Return: uint32_t best channel frequency
380  */
381 static
sap_select_preferred_channel_from_channel_list(uint32_t best_ch_freq,struct sap_context * sap_ctx,struct sap_sel_ch_info * spectinfo_param)382 uint32_t sap_select_preferred_channel_from_channel_list(uint32_t best_ch_freq,
383 				struct sap_context *sap_ctx,
384 				struct sap_sel_ch_info *spectinfo_param)
385 {
386 	/*
387 	 * If Channel List is not Configured don't do anything
388 	 * Else return the Best Channel from the Channel List
389 	 */
390 	if ((!sap_ctx->acs_cfg->freq_list) ||
391 	    (!spectinfo_param) ||
392 	    (!sap_ctx->acs_cfg->ch_list_count))
393 		return best_ch_freq;
394 
395 	if (wlansap_is_channel_present_in_acs_list(best_ch_freq,
396 					sap_ctx->acs_cfg->freq_list,
397 					sap_ctx->acs_cfg->ch_list_count))
398 		return best_ch_freq;
399 
400 	return SAP_CHANNEL_NOT_SELECTED;
401 }
402 
403 /**
404  * sap_chan_sel_init() - Initialize channel select
405  * @mac: Opaque handle to the global MAC context
406  * @ch_info_params: Pointer to tSapChSelSpectInfo structure
407  * @sap_ctx: Pointer to SAP Context
408  * @ignore_acs_range: Whether ignore channel which is out of acs range
409  *
410  * Function sap_chan_sel_init allocates the memory, initializes the
411  * structures used by the channel selection algorithm
412  *
413  * Return: bool Success or FAIL
414  */
sap_chan_sel_init(struct mac_context * mac,struct sap_sel_ch_info * ch_info_params,struct sap_context * sap_ctx,bool ignore_acs_range)415 static bool sap_chan_sel_init(struct mac_context *mac,
416 			      struct sap_sel_ch_info *ch_info_params,
417 			      struct sap_context *sap_ctx,
418 			      bool ignore_acs_range)
419 {
420 	struct sap_ch_info *ch_info = NULL;
421 	uint32_t *ch_list = NULL;
422 	uint16_t num_chan = 0;
423 	bool include_dfs_ch = true;
424 	uint8_t sta_sap_scc_on_dfs_chnl_config_value;
425 	bool ch_support_puncture;
426 
427 	ch_info_params->num_ch =
428 		mac->scan.base_channels.numChannels;
429 
430 	/* Allocate memory for weight computation of 2.4GHz */
431 	ch_info = qdf_mem_malloc((ch_info_params->num_ch) *
432 			sizeof(*ch_info));
433 	if (!ch_info)
434 		return false;
435 
436 	/* Initialize the pointers in the DfsParams to the allocated memory */
437 	ch_info_params->ch_info = ch_info;
438 
439 	ch_list = mac->scan.base_channels.channel_freq_list;
440 
441 	policy_mgr_get_sta_sap_scc_on_dfs_chnl(mac->psoc,
442 			&sta_sap_scc_on_dfs_chnl_config_value);
443 #if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
444 	if (sap_ctx->dfs_ch_disable == true)
445 		include_dfs_ch = false;
446 #endif
447 	if (!mac->mlme_cfg->dfs_cfg.dfs_master_capable ||
448 	    ACS_DFS_MODE_DISABLE == sap_ctx->dfs_mode)
449 		include_dfs_ch = false;
450 
451 	/* Fill the channel number in the spectrum in the operating freq band */
452 	for (num_chan = 0;
453 	     num_chan < ch_info_params->num_ch;
454 	     num_chan++, ch_list++, ch_info++) {
455 		ch_support_puncture = false;
456 		ch_info->chan_freq = *ch_list;
457 		/* Initialise for all channels */
458 		ch_info->rssi_agr = SOFTAP_MIN_RSSI;
459 		/* Initialise max ACS weight for all channels */
460 		ch_info->weight = SAP_ACS_WEIGHT_MAX;
461 
462 		/* check if the channel is in NOL denylist */
463 		if (sap_dfs_is_channel_in_nol_list(
464 					sap_ctx, *ch_list,
465 					PHY_SINGLE_CHANNEL_CENTERED)) {
466 			if (sap_acs_is_puncture_applicable(sap_ctx->acs_cfg)) {
467 				sap_debug_rl("freq %d is in NOL list, can be punctured",
468 					     *ch_list);
469 				ch_support_puncture = true;
470 			} else {
471 				sap_debug_rl("freq %d is in NOL list",
472 					     *ch_list);
473 				continue;
474 			}
475 		}
476 
477 		if (!include_dfs_ch ||
478 		    (sta_sap_scc_on_dfs_chnl_config_value ==
479 				PM_STA_SAP_ON_DFS_MASTER_MODE_DISABLED &&
480 		     !policy_mgr_is_sta_sap_scc(mac->psoc,
481 						ch_info->chan_freq))) {
482 			if (wlan_reg_is_dfs_for_freq(mac->pdev,
483 						     ch_info->chan_freq)) {
484 				sap_debug("DFS Ch %d not considered for ACS. include_dfs_ch %u, sta_sap_scc_on_dfs_chnl_config_value %d",
485 					  *ch_list, include_dfs_ch,
486 					  sta_sap_scc_on_dfs_chnl_config_value);
487 				continue;
488 			}
489 		}
490 
491 		if (!policy_mgr_is_sap_freq_allowed(mac->psoc,
492 			wlan_vdev_mlme_get_opmode(sap_ctx->vdev), *ch_list)) {
493 			if (sap_acs_is_puncture_applicable(sap_ctx->acs_cfg)) {
494 				sap_info("freq %d is not allowed, can be punctured",
495 					 *ch_list);
496 				ch_support_puncture = true;
497 			} else {
498 				sap_info("Skip freq %d", *ch_list);
499 				continue;
500 			}
501 		}
502 
503 		/* OFDM rates are not supported on frequency 2484 */
504 		if (*ch_list == 2484 &&
505 		    eCSR_DOT11_MODE_11b != sap_ctx->phyMode)
506 			continue;
507 
508 		/* Skip DSRC channels */
509 		if (wlan_reg_is_dsrc_freq(ch_info->chan_freq))
510 			continue;
511 
512 		/* Skip indoor channels for non-scc indoor scenario*/
513 		if (!policy_mgr_is_sap_go_interface_allowed_on_indoor(
514 							mac->pdev,
515 							sap_ctx->sessionId,
516 							*ch_list)) {
517 			sap_debug("Do not allow SAP on indoor frequency %u",
518 				  *ch_list);
519 			continue;
520 		}
521 
522 		/*
523 		 * Skip the channels which are not in ACS config from user
524 		 * space
525 		 */
526 		if (!ignore_acs_range &&
527 		    !wlansap_is_channel_present_in_acs_list(
528 		    *ch_list, sap_ctx->acs_cfg->freq_list,
529 		    sap_ctx->acs_cfg->ch_list_count)) {
530 			if (wlansap_is_channel_present_in_acs_list(
531 					ch_info->chan_freq,
532 					sap_ctx->acs_cfg->master_freq_list,
533 					sap_ctx->acs_cfg->master_ch_list_count))
534 				ch_info->weight = SAP_ACS_WEIGHT_ADJUSTABLE;
535 			continue;
536 		}
537 
538 		ch_info->valid = true;
539 		if (!ch_support_puncture)
540 			ch_info->weight = 0;
541 	}
542 
543 	return true;
544 }
545 
546 /**
547  * sapweight_rssi_count() - calculates the channel weight due to rssi
548  *                          and data count(here number of BSS observed)
549  * @sap_ctx     : Softap context
550  * @rssi        : Max signal strength received from a BSS for the channel
551  * @count       : Number of BSS observed in the channel
552  *
553  * Return: uint32_t Calculated channel weight based on above two
554  */
555 static
sapweight_rssi_count(struct sap_context * sap_ctx,int8_t rssi,uint16_t count)556 uint32_t sapweight_rssi_count(struct sap_context *sap_ctx, int8_t rssi,
557 			      uint16_t count)
558 {
559 	int32_t rssiWeight = 0;
560 	int32_t countWeight = 0;
561 	uint32_t rssicountWeight = 0;
562 	uint8_t softap_rssi_weight_cfg, softap_count_weight_cfg;
563 	uint8_t softap_rssi_weight_local, softap_count_weight_local;
564 
565 	softap_rssi_weight_cfg =
566 	    ACS_WEIGHT_SOFTAP_RSSI_CFG(sap_ctx->auto_channel_select_weight);
567 
568 	softap_count_weight_cfg =
569 	    ACS_WEIGHT_SOFTAP_COUNT_CFG(sap_ctx->auto_channel_select_weight);
570 
571 	softap_rssi_weight_local =
572 	    ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
573 				    softap_rssi_weight_cfg);
574 
575 	softap_count_weight_local =
576 	    ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
577 				    softap_count_weight_cfg);
578 
579 	/* Weight from RSSI */
580 	rssiWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
581 					softap_rssi_weight_cfg,
582 					rssi - SOFTAP_MIN_RSSI,
583 					SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI);
584 
585 	if (rssiWeight > softap_rssi_weight_local)
586 		rssiWeight = softap_rssi_weight_local;
587 
588 	else if (rssiWeight < 0)
589 		rssiWeight = 0;
590 
591 	/* Weight from data count */
592 	countWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
593 					 softap_count_weight_cfg,
594 					 count - SOFTAP_MIN_COUNT,
595 					 SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT);
596 
597 	if (countWeight > softap_count_weight_local)
598 		countWeight = softap_count_weight_local;
599 
600 	rssicountWeight = rssiWeight + countWeight;
601 
602 	return rssicountWeight;
603 }
604 
605 /**
606  * sap_get_channel_status() - get channel info via channel number
607  * @p_mac: Pointer to Global MAC structure
608  * @chan_freq: channel frequency
609  *
610  * Return: chan status info
611  */
sap_get_channel_status(struct mac_context * p_mac,uint32_t chan_freq)612 static struct channel_status *sap_get_channel_status
613 	(struct mac_context *p_mac, uint32_t chan_freq)
614 {
615 	if (!p_mac->sap.acs_with_more_param)
616 		return NULL;
617 
618 	return ucfg_mc_cp_stats_get_channel_status(p_mac->pdev, chan_freq);
619 }
620 
621 #ifndef WLAN_FEATURE_SAP_ACS_OPTIMIZE
622 /**
623  * sap_clear_channel_status() - clear chan info
624  * @p_mac: Pointer to Global MAC structure
625  *
626  * Return: none
627  */
sap_clear_channel_status(struct mac_context * p_mac)628 static void sap_clear_channel_status(struct mac_context *p_mac)
629 {
630 	if (!p_mac->sap.acs_with_more_param)
631 		return;
632 
633 	ucfg_mc_cp_stats_clear_channel_status(p_mac->pdev);
634 }
635 #else
sap_clear_channel_status(struct mac_context * p_mac)636 static void sap_clear_channel_status(struct mac_context *p_mac)
637 {
638 }
639 #endif
640 
641 /**
642  * sap_weight_channel_noise_floor() - compute noise floor weight
643  * @sap_ctx:  sap context
644  * @channel_stat: Pointer to chan status info
645  *
646  * Return: channel noise floor weight
647  */
sap_weight_channel_noise_floor(struct sap_context * sap_ctx,struct channel_status * channel_stat)648 static uint32_t sap_weight_channel_noise_floor(struct sap_context *sap_ctx,
649 					       struct channel_status
650 						*channel_stat)
651 {
652 	uint32_t    noise_floor_weight;
653 	uint8_t     softap_nf_weight_cfg;
654 	uint8_t     softap_nf_weight_local;
655 
656 	softap_nf_weight_cfg =
657 	    ACS_WEIGHT_SOFTAP_NOISE_FLOOR_CFG
658 	    (sap_ctx->auto_channel_select_weight);
659 
660 	softap_nf_weight_local =
661 	    ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
662 				    softap_nf_weight_cfg);
663 
664 	if (!channel_stat || channel_stat->channel_freq == 0)
665 		return softap_nf_weight_local;
666 
667 	noise_floor_weight = (channel_stat->noise_floor == 0) ? 0 :
668 			    (ACS_WEIGHT_COMPUTE(
669 			     sap_ctx->auto_channel_select_weight,
670 			     softap_nf_weight_cfg,
671 			     channel_stat->noise_floor -
672 			     SOFTAP_MIN_NF,
673 			     SOFTAP_MAX_NF - SOFTAP_MIN_NF));
674 
675 	if (noise_floor_weight > softap_nf_weight_local)
676 		noise_floor_weight = softap_nf_weight_local;
677 
678 	sap_debug("nf=%d, nfwc=%d, nfwl=%d, nfw=%d freq=%d",
679 		  channel_stat->noise_floor,
680 		  softap_nf_weight_cfg, softap_nf_weight_local,
681 		  noise_floor_weight, channel_stat->channel_freq);
682 
683 	return noise_floor_weight;
684 }
685 
686 /**
687  * sap_weight_channel_free() - compute channel free weight
688  * @sap_ctx:  sap context
689  * @channel_stat: Pointer to chan status info
690  *
691  * Return: channel free weight
692  */
sap_weight_channel_free(struct sap_context * sap_ctx,struct channel_status * channel_stat)693 static uint32_t sap_weight_channel_free(struct sap_context *sap_ctx,
694 					struct channel_status
695 					*channel_stat)
696 {
697 	uint32_t     channel_free_weight;
698 	uint8_t      softap_channel_free_weight_cfg;
699 	uint8_t      softap_channel_free_weight_local;
700 	uint32_t     rx_clear_count = 0;
701 	uint32_t     cycle_count = 0;
702 
703 	softap_channel_free_weight_cfg =
704 	    ACS_WEIGHT_SOFTAP_CHANNEL_FREE_CFG
705 	    (sap_ctx->auto_channel_select_weight);
706 
707 	softap_channel_free_weight_local =
708 	    ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
709 				    softap_channel_free_weight_cfg);
710 
711 	if (!channel_stat || channel_stat->channel_freq == 0)
712 		return softap_channel_free_weight_local;
713 
714 	rx_clear_count = channel_stat->rx_clear_count -
715 			channel_stat->tx_frame_count -
716 			channel_stat->rx_frame_count;
717 	cycle_count = channel_stat->cycle_count;
718 
719 	/* LSH 4, otherwise it is always 0. */
720 	channel_free_weight = (cycle_count == 0) ? 0 :
721 			 (ACS_WEIGHT_COMPUTE(
722 			  sap_ctx->auto_channel_select_weight,
723 			  softap_channel_free_weight_cfg,
724 			 ((rx_clear_count << 8) +
725 			 (cycle_count >> 1))/cycle_count -
726 			 (SOFTAP_MIN_CHNFREE << 8),
727 			 (SOFTAP_MAX_CHNFREE -
728 			 SOFTAP_MIN_CHNFREE) << 8));
729 
730 	if (channel_free_weight > softap_channel_free_weight_local)
731 		channel_free_weight = softap_channel_free_weight_local;
732 
733 	sap_debug_rl("rcc=%d, cc=%d, tc=%d, rc=%d, cfwc=%d, cfwl=%d, cfw=%d",
734 		     rx_clear_count, cycle_count,
735 		     channel_stat->tx_frame_count,
736 		     channel_stat->rx_frame_count,
737 		     softap_channel_free_weight_cfg,
738 		     softap_channel_free_weight_local,
739 		     channel_free_weight);
740 
741 	return channel_free_weight;
742 }
743 
744 /**
745  * sap_weight_channel_txpwr_range() - compute channel tx power range weight
746  * @sap_ctx:  sap context
747  * @channel_stat: Pointer to chan status info
748  *
749  * Return: tx power range weight
750  */
sap_weight_channel_txpwr_range(struct sap_context * sap_ctx,struct channel_status * channel_stat)751 static uint32_t sap_weight_channel_txpwr_range(struct sap_context *sap_ctx,
752 					       struct channel_status
753 					       *channel_stat)
754 {
755 	uint32_t     txpwr_weight_low_speed;
756 	uint8_t      softap_txpwr_range_weight_cfg;
757 	uint8_t      softap_txpwr_range_weight_local;
758 
759 	softap_txpwr_range_weight_cfg =
760 	    ACS_WEIGHT_SOFTAP_TX_POWER_RANGE_CFG
761 	    (sap_ctx->auto_channel_select_weight);
762 
763 	softap_txpwr_range_weight_local =
764 	    ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
765 				    softap_txpwr_range_weight_cfg);
766 
767 	if (!channel_stat || channel_stat->channel_freq == 0)
768 		return softap_txpwr_range_weight_local;
769 
770 
771 	txpwr_weight_low_speed = (channel_stat->chan_tx_pwr_range == 0) ? 0 :
772 				(ACS_WEIGHT_COMPUTE(
773 				 sap_ctx->auto_channel_select_weight,
774 				 softap_txpwr_range_weight_cfg,
775 				 SOFTAP_MAX_TXPWR -
776 				 channel_stat->chan_tx_pwr_range,
777 				 SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
778 
779 	if (txpwr_weight_low_speed > softap_txpwr_range_weight_local)
780 		txpwr_weight_low_speed = softap_txpwr_range_weight_local;
781 
782 	sap_debug_rl("tpr=%d, tprwc=%d, tprwl=%d, tprw=%d",
783 		     channel_stat->chan_tx_pwr_range,
784 		     softap_txpwr_range_weight_cfg,
785 		     softap_txpwr_range_weight_local,
786 		     txpwr_weight_low_speed);
787 
788 	return txpwr_weight_low_speed;
789 }
790 
791 /**
792  * sap_weight_channel_txpwr_tput() - compute channel tx power
793  * throughput weight
794  * @sap_ctx:  sap context
795  * @channel_stat: Pointer to chan status info
796  *
797  * Return: tx power throughput weight
798  */
sap_weight_channel_txpwr_tput(struct sap_context * sap_ctx,struct channel_status * channel_stat)799 static uint32_t sap_weight_channel_txpwr_tput(struct sap_context *sap_ctx,
800 					      struct channel_status
801 					      *channel_stat)
802 {
803 	uint32_t     txpwr_weight_high_speed;
804 	uint8_t      softap_txpwr_tput_weight_cfg;
805 	uint8_t      softap_txpwr_tput_weight_local;
806 
807 	softap_txpwr_tput_weight_cfg =
808 	    ACS_WEIGHT_SOFTAP_TX_POWER_THROUGHPUT_CFG
809 	    (sap_ctx->auto_channel_select_weight);
810 
811 	softap_txpwr_tput_weight_local =
812 	    ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
813 				    softap_txpwr_tput_weight_cfg);
814 
815 	if (!channel_stat || channel_stat->channel_freq == 0)
816 		return softap_txpwr_tput_weight_local;
817 
818 	txpwr_weight_high_speed = (channel_stat->chan_tx_pwr_throughput == 0)
819 				  ? 0 : (ACS_WEIGHT_COMPUTE(
820 				  sap_ctx->auto_channel_select_weight,
821 				  softap_txpwr_tput_weight_cfg,
822 				  SOFTAP_MAX_TXPWR -
823 				  channel_stat->chan_tx_pwr_throughput,
824 				  SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
825 
826 	if (txpwr_weight_high_speed > softap_txpwr_tput_weight_local)
827 		txpwr_weight_high_speed = softap_txpwr_tput_weight_local;
828 
829 	sap_debug_rl("tpt=%d, tptwc=%d, tptwl=%d, tptw=%d",
830 		     channel_stat->chan_tx_pwr_throughput,
831 		     softap_txpwr_tput_weight_cfg,
832 		     softap_txpwr_tput_weight_local,
833 		     txpwr_weight_high_speed);
834 
835 	return txpwr_weight_high_speed;
836 }
837 
838 /**
839  * sap_weight_channel_status() - compute chan status weight
840  * @sap_ctx:  sap context
841  * @channel_stat: Pointer to chan status info
842  *
843  * Return: chan status weight
844  */
845 static
sap_weight_channel_status(struct sap_context * sap_ctx,struct channel_status * channel_stat)846 uint32_t sap_weight_channel_status(struct sap_context *sap_ctx,
847 				   struct channel_status *channel_stat)
848 {
849 	return sap_weight_channel_noise_floor(sap_ctx, channel_stat) +
850 	       sap_weight_channel_free(sap_ctx, channel_stat) +
851 	       sap_weight_channel_txpwr_range(sap_ctx, channel_stat) +
852 	       sap_weight_channel_txpwr_tput(sap_ctx, channel_stat);
853 }
854 
855 /**
856  * sap_update_rssi_bsscount() - updates bss count and rssi effect.
857  *
858  * @ch_info:     Channel Information
859  * @offset:       Channel Offset
860  * @sap_24g:      Channel is in 2.4G or 5G
861  * @ch_start: the start of channel array
862  * @ch_end: the end of channel array
863  *
864  * sap_update_rssi_bsscount updates bss count and rssi effect based
865  * on the channel offset.
866  *
867  * Return: None.
868  */
869 
sap_update_rssi_bsscount(struct sap_ch_info * ch_info,int32_t offset,bool sap_24g,struct sap_ch_info * ch_start,struct sap_ch_info * ch_end)870 static void sap_update_rssi_bsscount(struct sap_ch_info *ch_info,
871 				     int32_t offset, bool sap_24g,
872 				     struct sap_ch_info *ch_start,
873 				     struct sap_ch_info *ch_end)
874 {
875 	struct sap_ch_info *chan_info = NULL;
876 	int32_t rssi, rsssi_effect;
877 
878 	chan_info = (ch_info + offset);
879 	if (chan_info && chan_info >= ch_start &&
880 	    chan_info < ch_end) {
881 		if (!WLAN_REG_IS_SAME_BAND_FREQS(ch_info->chan_freq,
882 						 chan_info->chan_freq))
883 			return;
884 		++chan_info->bss_count;
885 		switch (offset) {
886 		case -1:
887 		case 1:
888 			rsssi_effect = sap_24g ?
889 			    SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
890 			    SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
891 			break;
892 		case -2:
893 		case 2:
894 			rsssi_effect = sap_24g ?
895 			    SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
896 			    SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
897 			break;
898 		case -3:
899 		case 3:
900 			rsssi_effect = sap_24g ?
901 			    SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
902 			    SAP_SUBBAND3_RSSI_EFFECT_PRIMARY;
903 			break;
904 		case -4:
905 		case 4:
906 			rsssi_effect = sap_24g ?
907 			    SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
908 			    SAP_SUBBAND4_RSSI_EFFECT_PRIMARY;
909 			break;
910 		case -5:
911 		case 5:
912 			rsssi_effect = SAP_SUBBAND5_RSSI_EFFECT_PRIMARY;
913 			break;
914 		case -6:
915 		case 6:
916 			rsssi_effect = SAP_SUBBAND6_RSSI_EFFECT_PRIMARY;
917 			break;
918 		case -7:
919 		case 7:
920 			rsssi_effect = SAP_SUBBAND7_RSSI_EFFECT_PRIMARY;
921 			break;
922 		default:
923 			rsssi_effect = 0;
924 			break;
925 		}
926 
927 		rssi = ch_info->rssi_agr + rsssi_effect;
928 		if (IS_RSSI_VALID(chan_info->rssi_agr, rssi))
929 			chan_info->rssi_agr = rssi;
930 		if (chan_info->rssi_agr < SOFTAP_MIN_RSSI)
931 			chan_info->rssi_agr = SOFTAP_MIN_RSSI;
932 	}
933 }
934 
935 /**
936  * sap_update_rssi_bsscount_vht_5G() - updates bss count and rssi effect.
937  *
938  * @spect_ch:     Channel Information
939  * @offset:       Channel Offset
940  * @num_ch:       no.of channels
941  * @ch_start: the start of spect ch array
942  * @ch_end: the end of spect ch array
943  *
944  * sap_update_rssi_bsscount_vht_5G updates bss count and rssi effect based
945  * on the channel offset.
946  *
947  * Return: None.
948  */
949 
sap_update_rssi_bsscount_vht_5G(struct sap_ch_info * spect_ch,int32_t offset,uint16_t num_ch,struct sap_ch_info * ch_start,struct sap_ch_info * ch_end)950 static void sap_update_rssi_bsscount_vht_5G(
951 					struct sap_ch_info *spect_ch,
952 					int32_t offset,
953 					uint16_t num_ch,
954 					struct sap_ch_info *ch_start,
955 					struct sap_ch_info *ch_end)
956 {
957 	int32_t ch_offset;
958 	uint16_t i, cnt;
959 
960 	if (!offset)
961 		return;
962 	if (offset > 0)
963 		cnt = num_ch;
964 	else
965 		cnt = num_ch + 1;
966 	for (i = 0; i < cnt; i++) {
967 		ch_offset = offset + i;
968 		if (ch_offset == 0)
969 			continue;
970 		sap_update_rssi_bsscount(spect_ch, ch_offset, false,
971 			ch_start, ch_end);
972 	}
973 }
974 /**
975  * sap_interference_rssi_count_5G() - sap_interference_rssi_count
976  *                                    considers the Adjacent channel rssi and
977  *                                    data count(here number of BSS observed)
978  * @spect_ch:        Channel Information
979  * @chan_width:      Channel width parsed from beacon IE
980  * @sec_chan_offset: Secondary Channel Offset
981  * @ch_freq0:     frequency_0 for the given channel.
982  * @ch_freq1:     frequency_1 for the given channel.
983  * @op_chan_freq: Operating channel frequency.
984  * @ch_start: the start of spect ch array
985  * @ch_end: the end of spect ch array
986  *
987  * sap_interference_rssi_count_5G considers the Adjacent channel rssi
988  * and data count(here number of BSS observed)
989  *
990  * Return: NA.
991  */
992 
sap_interference_rssi_count_5G(struct sap_ch_info * spect_ch,uint16_t chan_width,uint16_t sec_chan_offset,uint32_t ch_freq0,uint32_t ch_freq1,uint32_t op_chan_freq,struct sap_ch_info * ch_start,struct sap_ch_info * ch_end)993 static void sap_interference_rssi_count_5G(struct sap_ch_info *spect_ch,
994 					   uint16_t chan_width,
995 					   uint16_t sec_chan_offset,
996 					   uint32_t ch_freq0,
997 					   uint32_t ch_freq1,
998 					   uint32_t op_chan_freq,
999 					   struct sap_ch_info *ch_start,
1000 					   struct sap_ch_info *ch_end)
1001 {
1002 	uint16_t num_ch;
1003 	int32_t offset = 0;
1004 
1005 	sap_debug("freq = %d, ch width = %d, ch_freq0 = %d ch_freq1 = %d",
1006 		  op_chan_freq, chan_width, ch_freq0, ch_freq1);
1007 
1008 	switch (chan_width) {
1009 	case eHT_CHANNEL_WIDTH_40MHZ:
1010 		switch (sec_chan_offset) {
1011 		/* Above the Primary Channel */
1012 		case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
1013 			sap_update_rssi_bsscount(spect_ch, 1, false,
1014 						 ch_start, ch_end);
1015 			return;
1016 
1017 		/* Below the Primary channel */
1018 		case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
1019 			sap_update_rssi_bsscount(spect_ch, -1, false,
1020 						 ch_start, ch_end);
1021 			return;
1022 		}
1023 		return;
1024 	case eHT_CHANNEL_WIDTH_80MHZ:
1025 	case eHT_CHANNEL_WIDTH_80P80MHZ:
1026 		num_ch = 3;
1027 		if ((ch_freq0 - op_chan_freq) == 30) {
1028 			offset = 1;
1029 		} else if ((ch_freq0 - op_chan_freq) == 10) {
1030 			offset = -1;
1031 		} else if ((ch_freq0 - op_chan_freq) == -10) {
1032 			offset = -2;
1033 		} else if ((ch_freq0 - op_chan_freq) == -30) {
1034 			offset = -3;
1035 		}
1036 		break;
1037 	case eHT_CHANNEL_WIDTH_160MHZ:
1038 		num_ch = 7;
1039 		if ((ch_freq0 - op_chan_freq) == 70)
1040 			offset = 1;
1041 		else if ((ch_freq0 - op_chan_freq) == 50)
1042 			offset = -1;
1043 		else if ((ch_freq0 - op_chan_freq) == 30)
1044 			offset = -2;
1045 		else if ((ch_freq0 - op_chan_freq) == 10)
1046 			offset = -3;
1047 		else if ((ch_freq0 - op_chan_freq) == -10)
1048 			offset = -4;
1049 		else if ((ch_freq0 - op_chan_freq) == -30)
1050 			offset = -5;
1051 		else if ((ch_freq0 - op_chan_freq) == -50)
1052 			offset = -6;
1053 		else if ((ch_freq0 - op_chan_freq) == -70)
1054 			offset = -7;
1055 		break;
1056 	default:
1057 		return;
1058 	}
1059 
1060 	sap_update_rssi_bsscount_vht_5G(spect_ch, offset, num_ch, ch_start,
1061 					ch_end);
1062 }
1063 
1064 /**
1065  * sap_interference_rssi_count() - sap_interference_rssi_count
1066  *                                 considers the Adjacent channel rssi
1067  *                                 and data count(here number of BSS observed)
1068  * @spect_ch: Channel Information
1069  * @ch_start: the start of spect ch array
1070  * @ch_end: the end of spect ch array
1071  * @mac: Opaque handle to the global MAC context
1072  *
1073  * sap_interference_rssi_count considers the Adjacent channel rssi
1074  * and data count(here number of BSS observed)
1075  *
1076  * Return: None.
1077  */
1078 
sap_interference_rssi_count(struct sap_ch_info * spect_ch,struct sap_ch_info * ch_start,struct sap_ch_info * ch_end,struct mac_context * mac)1079 static void sap_interference_rssi_count(struct sap_ch_info *spect_ch,
1080 					struct sap_ch_info *ch_start,
1081 					struct sap_ch_info *ch_end,
1082 					struct mac_context *mac)
1083 {
1084 	if (!spect_ch) {
1085 		sap_err("spect_ch is NULL");
1086 		return;
1087 	}
1088 
1089 	switch (wlan_reg_freq_to_chan(mac->pdev, spect_ch->chan_freq)) {
1090 	case CHANNEL_1:
1091 		sap_update_rssi_bsscount(spect_ch, 1, true,
1092 			ch_start, ch_end);
1093 		sap_update_rssi_bsscount(spect_ch, 2, true,
1094 			ch_start, ch_end);
1095 		sap_update_rssi_bsscount(spect_ch, 3, true,
1096 			ch_start, ch_end);
1097 		sap_update_rssi_bsscount(spect_ch, 4, true,
1098 			ch_start, ch_end);
1099 		break;
1100 
1101 	case CHANNEL_2:
1102 		sap_update_rssi_bsscount(spect_ch, -1, true,
1103 			ch_start, ch_end);
1104 		sap_update_rssi_bsscount(spect_ch, 1, true,
1105 			ch_start, ch_end);
1106 		sap_update_rssi_bsscount(spect_ch, 2, true,
1107 			ch_start, ch_end);
1108 		sap_update_rssi_bsscount(spect_ch, 3, true,
1109 			ch_start, ch_end);
1110 		sap_update_rssi_bsscount(spect_ch, 4, true,
1111 			ch_start, ch_end);
1112 		break;
1113 	case CHANNEL_3:
1114 		sap_update_rssi_bsscount(spect_ch, -2, true,
1115 			ch_start, ch_end);
1116 		sap_update_rssi_bsscount(spect_ch, -1, true,
1117 			ch_start, ch_end);
1118 		sap_update_rssi_bsscount(spect_ch, 1, true,
1119 			ch_start, ch_end);
1120 		sap_update_rssi_bsscount(spect_ch, 2, true,
1121 			ch_start, ch_end);
1122 		sap_update_rssi_bsscount(spect_ch, 3, true,
1123 			ch_start, ch_end);
1124 		sap_update_rssi_bsscount(spect_ch, 4, true,
1125 			ch_start, ch_end);
1126 		break;
1127 	case CHANNEL_4:
1128 		sap_update_rssi_bsscount(spect_ch, -3, true,
1129 			ch_start, ch_end);
1130 		sap_update_rssi_bsscount(spect_ch, -2, true,
1131 			ch_start, ch_end);
1132 		sap_update_rssi_bsscount(spect_ch, -1, true,
1133 			ch_start, ch_end);
1134 		sap_update_rssi_bsscount(spect_ch, 1, true,
1135 			ch_start, ch_end);
1136 		sap_update_rssi_bsscount(spect_ch, 2, true,
1137 			ch_start, ch_end);
1138 		sap_update_rssi_bsscount(spect_ch, 3, true,
1139 			ch_start, ch_end);
1140 		sap_update_rssi_bsscount(spect_ch, 4, true,
1141 			ch_start, ch_end);
1142 		break;
1143 
1144 	case CHANNEL_5:
1145 	case CHANNEL_6:
1146 	case CHANNEL_7:
1147 	case CHANNEL_8:
1148 	case CHANNEL_9:
1149 	case CHANNEL_10:
1150 		sap_update_rssi_bsscount(spect_ch, -4, true,
1151 			ch_start, ch_end);
1152 		sap_update_rssi_bsscount(spect_ch, -3, true,
1153 			ch_start, ch_end);
1154 		sap_update_rssi_bsscount(spect_ch, -2, true,
1155 			ch_start, ch_end);
1156 		sap_update_rssi_bsscount(spect_ch, -1, true,
1157 			ch_start, ch_end);
1158 		sap_update_rssi_bsscount(spect_ch, 1, true,
1159 			ch_start, ch_end);
1160 		sap_update_rssi_bsscount(spect_ch, 2, true,
1161 			ch_start, ch_end);
1162 		sap_update_rssi_bsscount(spect_ch, 3, true,
1163 			ch_start, ch_end);
1164 		sap_update_rssi_bsscount(spect_ch, 4, true,
1165 			ch_start, ch_end);
1166 		break;
1167 
1168 	case CHANNEL_11:
1169 		sap_update_rssi_bsscount(spect_ch, -4, true,
1170 			ch_start, ch_end);
1171 		sap_update_rssi_bsscount(spect_ch, -3, true,
1172 			ch_start, ch_end);
1173 		sap_update_rssi_bsscount(spect_ch, -2, true,
1174 			ch_start, ch_end);
1175 		sap_update_rssi_bsscount(spect_ch, -1, true,
1176 			ch_start, ch_end);
1177 		sap_update_rssi_bsscount(spect_ch, 1, true,
1178 			ch_start, ch_end);
1179 		sap_update_rssi_bsscount(spect_ch, 2, true,
1180 			ch_start, ch_end);
1181 		sap_update_rssi_bsscount(spect_ch, 3, true,
1182 			ch_start, ch_end);
1183 		break;
1184 
1185 	case CHANNEL_12:
1186 		sap_update_rssi_bsscount(spect_ch, -4, true,
1187 			ch_start, ch_end);
1188 		sap_update_rssi_bsscount(spect_ch, -3, true,
1189 			ch_start, ch_end);
1190 		sap_update_rssi_bsscount(spect_ch, -2, true,
1191 			ch_start, ch_end);
1192 		sap_update_rssi_bsscount(spect_ch, -1, true,
1193 			ch_start, ch_end);
1194 		sap_update_rssi_bsscount(spect_ch, 1, true,
1195 			ch_start, ch_end);
1196 		sap_update_rssi_bsscount(spect_ch, 2, true,
1197 			ch_start, ch_end);
1198 		break;
1199 
1200 	case CHANNEL_13:
1201 		sap_update_rssi_bsscount(spect_ch, -4, true,
1202 			ch_start, ch_end);
1203 		sap_update_rssi_bsscount(spect_ch, -3, true,
1204 			ch_start, ch_end);
1205 		sap_update_rssi_bsscount(spect_ch, -2, true,
1206 			ch_start, ch_end);
1207 		sap_update_rssi_bsscount(spect_ch, -1, true,
1208 			ch_start, ch_end);
1209 		sap_update_rssi_bsscount(spect_ch, 1, true,
1210 			ch_start, ch_end);
1211 		break;
1212 
1213 	case CHANNEL_14:
1214 		sap_update_rssi_bsscount(spect_ch, -4, true,
1215 			ch_start, ch_end);
1216 		sap_update_rssi_bsscount(spect_ch, -3, true,
1217 			ch_start, ch_end);
1218 		sap_update_rssi_bsscount(spect_ch, -2, true,
1219 			ch_start, ch_end);
1220 		sap_update_rssi_bsscount(spect_ch, -1, true,
1221 			ch_start, ch_end);
1222 		break;
1223 
1224 	default:
1225 		break;
1226 	}
1227 }
1228 
1229 /**
1230  * ch_in_pcl() - Is channel in the Preferred Channel List (PCL)
1231  * @sap_ctx: SAP context which contains the current PCL
1232  * @ch_freq: Input channel number to be checked
1233  *
1234  * Check if a channel is in the preferred channel list
1235  *
1236  * Return: True if channel is in PCL, else False
1237  */
ch_in_pcl(struct sap_context * sap_ctx,uint32_t ch_freq)1238 static bool ch_in_pcl(struct sap_context *sap_ctx, uint32_t ch_freq)
1239 {
1240 	uint32_t i;
1241 
1242 	for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
1243 		if (ch_freq == sap_ctx->acs_cfg->pcl_chan_freq[i])
1244 			return true;
1245 	}
1246 
1247 	return false;
1248 }
1249 
1250 /**
1251  * sap_upd_chan_spec_params() - sap_upd_chan_spec_params
1252  *  updates channel parameters obtained from Beacon
1253  * @scan_entry: Beacon structure populated by scan
1254  * @ch_width: Channel width
1255  * @sec_ch_offset: Secondary Channel Offset
1256  * @center_freq0: Central frequency 0 for the given channel
1257  * @center_freq1: Central frequency 1 for the given channel
1258  *
1259  * sap_upd_chan_spec_params updates the spectrum channels based on the
1260  * scan_entry
1261  *
1262  * Return: NA.
1263  */
1264 static void
sap_upd_chan_spec_params(struct scan_cache_node * scan_entry,tSirMacHTChannelWidth * ch_width,uint16_t * sec_ch_offset,uint32_t * center_freq0,uint32_t * center_freq1)1265 sap_upd_chan_spec_params(struct scan_cache_node *scan_entry,
1266 			 tSirMacHTChannelWidth *ch_width,
1267 			 uint16_t *sec_ch_offset,
1268 			 uint32_t *center_freq0,
1269 			 uint32_t *center_freq1)
1270 {
1271 	enum wlan_phymode phy_mode;
1272 	struct channel_info *chan;
1273 
1274 	phy_mode = util_scan_entry_phymode(scan_entry->entry);
1275 	chan = util_scan_entry_channel(scan_entry->entry);
1276 
1277 	if (IS_WLAN_PHYMODE_160MHZ(phy_mode)) {
1278 		if (phy_mode == WLAN_PHYMODE_11AC_VHT80_80 ||
1279 		    phy_mode == WLAN_PHYMODE_11AXA_HE80_80) {
1280 			*ch_width = eHT_CHANNEL_WIDTH_80P80MHZ;
1281 			*center_freq0 = chan->cfreq0;
1282 			*center_freq1 = chan->cfreq1;
1283 		} else {
1284 			*ch_width = eHT_CHANNEL_WIDTH_160MHZ;
1285 			if (chan->cfreq1)
1286 				*center_freq0 = chan->cfreq1;
1287 			else
1288 				*center_freq0 = chan->cfreq0;
1289 		}
1290 
1291 	} else if (IS_WLAN_PHYMODE_80MHZ(phy_mode)) {
1292 		*ch_width = eHT_CHANNEL_WIDTH_80MHZ;
1293 		*center_freq0 = chan->cfreq0;
1294 	} else if (IS_WLAN_PHYMODE_40MHZ(phy_mode)) {
1295 		if (chan->cfreq0 > chan->chan_freq)
1296 			*sec_ch_offset = PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
1297 		else
1298 			*sec_ch_offset = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
1299 		*ch_width = eHT_CHANNEL_WIDTH_40MHZ;
1300 		*center_freq0 = chan->cfreq0;
1301 	} else {
1302 		*ch_width = eHT_CHANNEL_WIDTH_20MHZ;
1303 	}
1304 }
1305 
1306 /**
1307  * sap_weight_channel_reg_max_power() - API to calculate channel weight of max
1308  *                                      tx power allowed
1309  * @sap_ctx: SAP context
1310  * @freq: channel frequency
1311  *
1312  * This function get channel tx power limit from secondary current channel
1313  * list and calculate weight with power factor configure
1314  *
1315  * Return: channel power weight
1316  */
1317 static uint32_t
sap_weight_channel_reg_max_power(struct sap_context * sap_ctx,qdf_freq_t freq)1318 sap_weight_channel_reg_max_power(struct sap_context *sap_ctx, qdf_freq_t freq)
1319 {
1320 	struct wlan_objmgr_pdev *pdev;
1321 	int32_t power_weight;
1322 	uint8_t power_weight_cfg, power_weight_local;
1323 	uint16_t eirp_pwr, psd_pwr;
1324 	bool is_psd;
1325 	uint32_t chan_flags;
1326 	QDF_STATUS status;
1327 
1328 	power_weight_cfg = ACS_WEIGHT_SOFTAP_REG_MAX_POWER_CFG(
1329 			sap_ctx->auto_channel_select_weight);
1330 
1331 	/* reg max power factor not configure, return zero weight */
1332 	if (!power_weight_cfg)
1333 		return 0;
1334 
1335 	power_weight_local = ACS_WEIGHT_CFG_TO_LOCAL(
1336 			sap_ctx->auto_channel_select_weight, power_weight_cfg);
1337 
1338 	if (!sap_ctx->vdev) {
1339 		sap_err("sap ctx vdev is null.");
1340 		return power_weight_local;
1341 	}
1342 	pdev = wlan_vdev_get_pdev(sap_ctx->vdev);
1343 	status = wlan_reg_get_chan_pwr_attr_from_secondary_list_for_freq(
1344 			pdev, freq, &is_psd, &eirp_pwr, &psd_pwr, &chan_flags);
1345 	if (status != QDF_STATUS_SUCCESS) {
1346 		sap_err("fail to get power attribute.");
1347 		return power_weight_local;
1348 	}
1349 
1350 	if (eirp_pwr > REG_MAX_EIRP_POWER) {
1351 		sap_debug("eirp_pwr %d exceed max", eirp_pwr);
1352 		eirp_pwr = REG_MAX_EIRP_POWER;
1353 	}
1354 	if (eirp_pwr < REG_MIN_EIRP_POWER) {
1355 		sap_debug("eirp_pwr %d below min", eirp_pwr);
1356 		eirp_pwr = REG_MIN_EIRP_POWER;
1357 	}
1358 
1359 	power_weight = ACS_WEIGHT_COMPUTE(
1360 			sap_ctx->auto_channel_select_weight,
1361 			power_weight_cfg,
1362 			REG_MAX_EIRP_POWER - eirp_pwr,
1363 			REG_MAX_EIRP_POWER - REG_MIN_EIRP_POWER);
1364 
1365 	if (power_weight > power_weight_local)
1366 		power_weight = power_weight_local;
1367 	else if (power_weight < 0)
1368 		power_weight = 0;
1369 
1370 	return power_weight;
1371 }
1372 
1373 static void
sap_normalize_channel_weight_with_factors(struct mac_context * mac,struct sap_ch_info * spect_ch)1374 sap_normalize_channel_weight_with_factors(struct mac_context *mac,
1375 					  struct sap_ch_info *spect_ch)
1376 {
1377 	uint32_t normalized_weight;
1378 	uint8_t normalize_factor = 100;
1379 	uint8_t dfs_normalize_factor;
1380 	uint32_t chan_freq, i;
1381 	struct acs_weight *weight_list =
1382 			mac->mlme_cfg->acs.normalize_weight_chan;
1383 	struct acs_weight_range *range_list =
1384 			mac->mlme_cfg->acs.normalize_weight_range;
1385 	bool freq_present_in_list = false;
1386 
1387 	chan_freq = spect_ch->chan_freq;
1388 
1389 	/* Check if the freq is present in range list */
1390 	for (i = 0; i < mac->mlme_cfg->acs.num_weight_range; i++) {
1391 		if (chan_freq >= range_list[i].start_freq &&
1392 		    chan_freq <= range_list[i].end_freq) {
1393 			normalize_factor = range_list[i].normalize_weight;
1394 			sap_debug_rl("Range list, freq %d normalize weight factor %d",
1395 				     chan_freq, normalize_factor);
1396 			freq_present_in_list = true;
1397 		}
1398 	}
1399 
1400 	/* Check if user wants a special factor for this freq */
1401 	for (i = 0; i < mac->mlme_cfg->acs.normalize_weight_num_chan; i++) {
1402 		if (chan_freq == weight_list[i].chan_freq) {
1403 			normalize_factor = weight_list[i].normalize_weight;
1404 			sap_debug("freq %d normalize weight factor %d",
1405 				  chan_freq, normalize_factor);
1406 			freq_present_in_list = true;
1407 		}
1408 	}
1409 
1410 	if (wlan_reg_is_dfs_for_freq(mac->pdev, chan_freq)) {
1411 		dfs_normalize_factor = MLME_GET_DFS_CHAN_WEIGHT(
1412 				mac->mlme_cfg->acs.np_chan_weightage);
1413 		if (freq_present_in_list)
1414 			normalize_factor = qdf_min(dfs_normalize_factor,
1415 						   normalize_factor);
1416 		else
1417 			normalize_factor = dfs_normalize_factor;
1418 		freq_present_in_list = true;
1419 		sap_debug_rl("DFS channel weightage %d min %d",
1420 			     dfs_normalize_factor, normalize_factor);
1421 	}
1422 
1423 	if (freq_present_in_list) {
1424 		normalized_weight =
1425 			((SAP_ACS_WEIGHT_MAX - spect_ch->weight) *
1426 			(100 - normalize_factor)) / 100;
1427 		sap_debug_rl("freq %d old weight %d new weight %d",
1428 			     chan_freq, spect_ch->weight,
1429 			     spect_ch->weight + normalized_weight);
1430 		spect_ch->weight += normalized_weight;
1431 	}
1432 }
1433 
1434 /**
1435  * sap_update_6ghz_max_weight() - Update 6 GHz channel max weight
1436  * @ch_info_params: Pointer to the sap_sel_ch_info structure
1437  * @max_valid_weight: max valid weight on 6 GHz channels
1438  *
1439  * If ACS frequency list includes 6 GHz channels, the user prefers
1440  * to start SAP on 6 GHz as much as possible. The acs logic in
1441  * sap_chan_sel_init will mark channel weight to Max weight value
1442  * of SAP_ACS_WEIGHT_MAX if channel is no in ACS channel list(filtered
1443  * by PCL).
1444  * In ACS bw 160 case, sometime the combined weight of 8 channels
1445  * on 6 GHz(some of them have weight SAP_ACS_WEIGHT_MAX)
1446  * may higher than 5 GHz channels and finally select 5 GHz channel.
1447  * This API is to update the 6 GHz weight to max valid weight in
1448  * 6 GHz instead of value SAP_ACS_WEIGHT_MAX. All those channels have
1449  * special weight value SAP_ACS_WEIGHT_ADJUSTABLE which is assigned
1450  * sap_chan_sel_init.
1451  *
1452  * Return: void
1453  */
sap_update_6ghz_max_weight(struct sap_sel_ch_info * ch_info_params,uint32_t max_valid_weight)1454 static void sap_update_6ghz_max_weight(struct sap_sel_ch_info *ch_info_params,
1455 				       uint32_t max_valid_weight)
1456 {
1457 	uint8_t chn_num;
1458 	struct sap_ch_info *pspect_ch;
1459 
1460 	sap_debug("max_valid_weight_on_6ghz_channels %d",
1461 		  max_valid_weight);
1462 	if (!max_valid_weight)
1463 		return;
1464 	for (chn_num = 0; chn_num < ch_info_params->num_ch;
1465 	     chn_num++) {
1466 		pspect_ch = &ch_info_params->ch_info[chn_num];
1467 		if (!wlan_reg_is_6ghz_chan_freq(pspect_ch->chan_freq))
1468 			continue;
1469 		if (pspect_ch->weight == SAP_ACS_WEIGHT_ADJUSTABLE) {
1470 			pspect_ch->weight = max_valid_weight;
1471 			pspect_ch->weight_copy = pspect_ch->weight;
1472 		}
1473 	}
1474 }
1475 
1476 /**
1477  * sap_update_5ghz_low_freq_weight() - Update weight of 5GHz low frequency
1478  * @psoc: Pointer to psoc
1479  * @ch_info_params: Pointer to sap_sel_ch_info structure
1480  *
1481  * This api helps to lower the 5GHz low frequency weight by
1482  * SAP_NORMALISE_ACS_WEIGHT so that it will get more preference to get
1483  * selected during ACS.
1484  *
1485  * Return: void
1486  */
sap_update_5ghz_low_freq_weight(struct wlan_objmgr_psoc * psoc,struct sap_sel_ch_info * ch_info_params)1487 static void sap_update_5ghz_low_freq_weight(
1488 					struct wlan_objmgr_psoc *psoc,
1489 					struct sap_sel_ch_info *ch_info_params)
1490 {
1491 	uint8_t ch_num;
1492 	qdf_freq_t freq;
1493 	uint32_t weight;
1494 
1495 	if (!policy_mgr_is_hw_sbs_capable(psoc))
1496 		return;
1497 
1498 	for (ch_num = 0; ch_num < ch_info_params->num_ch; ch_num++) {
1499 		freq = ch_info_params->ch_info[ch_num].chan_freq;
1500 		weight = ch_info_params->ch_info[ch_num].weight;
1501 		if (policy_mgr_is_given_freq_5g_low(psoc, freq)) {
1502 			/*
1503 			 * Lower the weight by SAP_NORMALISE_ACS_WEIGHT i.e 5%
1504 			 * from channel weight itself. Later if required, modify
1505 			 * this value.
1506 			 * Here are the few observation captured which results
1507 			 * to go with SAP_NORMALISE_ACS_WEIGHT.
1508 			 *
1509 			 * +-----------+-------------+------------+---------------+--------------------------------------+
1510 			 * |   freq    |  bss_count  |    rssi    |     weight    |              observation             |
1511 			 * +---------------------------------------------------------------------------------------------+
1512 			 * |  5G low   |    >6       | -76 - -56  | 17419 - 17774 | Diff b/w 5G low & 5G high min weight |
1513 			 * |  5G high  |    <4       | -100 - -50 | 16842 - 17685 | is ~5% of 5G low min weight		 |
1514 			 * |	       |	     |		  |		  |					 |
1515 			 * |  5G low   |    >6       | -77 - -54  | 17419 - 17730 | Diff b/w 5G low & 5G high min weight |
1516 			 * |  5G high  |    <4	     | -100 - -50 | 16842 - 17552 | is ~5% of 5G low min weight		 |
1517 			 * |	       |	     |		  |		  |					 |
1518 			 * |  5G low   |    >5       | -77 - -57  | 17286 - 17552 | Diff b/w 5G low & 5G high min weight |
1519 			 * |  5G high  |    <4       | -100 - -50 | 16842 - 17596 | is ~5% of 5G low min weight		 |
1520 			 * +-----------+-------------+------------+---------------+--------------------------------------+
1521 			 */
1522 
1523 			weight = weight - ((weight * SAP_NORMALISE_ACS_WEIGHT ) / 100);
1524 			ch_info_params->ch_info[ch_num].weight = weight;
1525 		}
1526 	}
1527 }
1528 
1529 /**
1530  * sap_compute_spect_weight() - Compute spectrum weight
1531  * @ch_info_params: Pointer to the tSpectInfoParams structure
1532  * @mac: Pointer to mac_context struucture
1533  * @scan_list: Pointer to channel list
1534  * @sap_ctx: Context of the SAP
1535  *
1536  * Main function for computing the weight of each channel in the
1537  * spectrum based on the RSSI value of the BSSes on the channel
1538  * and number of BSS
1539  */
sap_compute_spect_weight(struct sap_sel_ch_info * ch_info_params,struct mac_context * mac,qdf_list_t * scan_list,struct sap_context * sap_ctx)1540 static void sap_compute_spect_weight(struct sap_sel_ch_info *ch_info_params,
1541 				     struct mac_context *mac,
1542 				     qdf_list_t *scan_list,
1543 				     struct sap_context *sap_ctx)
1544 {
1545 	int8_t rssi = 0;
1546 	uint8_t chn_num = 0;
1547 	struct sap_ch_info *ch_info = ch_info_params->ch_info;
1548 	tSirMacHTChannelWidth ch_width = 0;
1549 	uint16_t secondaryChannelOffset;
1550 	uint32_t center_freq0, center_freq1, chan_freq;
1551 	uint8_t i;
1552 	bool found;
1553 	struct sap_ch_info *ch_start = ch_info_params->ch_info;
1554 	struct sap_ch_info *ch_end = ch_info_params->ch_info +
1555 		ch_info_params->num_ch;
1556 	qdf_list_node_t *cur_lst = NULL, *next_lst = NULL;
1557 	struct scan_cache_node *cur_node = NULL;
1558 	uint32_t rssi_bss_weight = 0, chan_status_weight = 0, power_weight = 0;
1559 	uint32_t max_valid_weight_6ghz = 0;
1560 
1561 	sap_debug("Computing spectral weight");
1562 
1563 	if (scan_list)
1564 		qdf_list_peek_front(scan_list, &cur_lst);
1565 	while (cur_lst) {
1566 		cur_node = qdf_container_of(cur_lst, struct scan_cache_node,
1567 					    node);
1568 		ch_info = ch_info_params->ch_info;
1569 		/* Defining the default values, so that any value will hold the default values */
1570 
1571 		secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
1572 		center_freq0 = 0;
1573 		center_freq1 = 0;
1574 
1575 		chan_freq =
1576 		    util_scan_entry_channel_frequency(cur_node->entry);
1577 
1578 		sap_upd_chan_spec_params(cur_node, &ch_width,
1579 					 &secondaryChannelOffset,
1580 					 &center_freq0, &center_freq1);
1581 
1582 		/* Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list */
1583 		for (chn_num = 0; chn_num < ch_info_params->num_ch;
1584 		     chn_num++) {
1585 
1586 			if (chan_freq != ch_info->chan_freq) {
1587 				ch_info++;
1588 				continue;
1589 			}
1590 
1591 			if (ch_info->rssi_agr < cur_node->entry->rssi_raw)
1592 				ch_info->rssi_agr = cur_node->entry->rssi_raw;
1593 
1594 			++ch_info->bss_count;
1595 
1596 			if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq))
1597 				sap_interference_rssi_count(ch_info, ch_start,
1598 							    ch_end, mac);
1599 			else
1600 				sap_interference_rssi_count_5G(
1601 				    ch_info, ch_width, secondaryChannelOffset,
1602 				    center_freq0, center_freq1, chan_freq,
1603 				    ch_start, ch_end);
1604 
1605 			ch_info++;
1606 			break;
1607 
1608 		}
1609 
1610 		qdf_list_peek_next(scan_list, cur_lst, &next_lst);
1611 		cur_lst = next_lst;
1612 		next_lst = NULL;
1613 	}
1614 
1615 	/* Calculate the weights for all channels in the spectrum ch_info */
1616 	ch_info = ch_info_params->ch_info;
1617 
1618 	for (chn_num = 0; chn_num < (ch_info_params->num_ch);
1619 	     chn_num++) {
1620 
1621 		/*
1622 		   rssi : Maximum received signal strength among all BSS on that channel
1623 		   bss_count : Number of BSS on that channel
1624 		 */
1625 
1626 		rssi = (int8_t)ch_info->rssi_agr;
1627 		if (ch_in_pcl(sap_ctx, ch_info->chan_freq))
1628 			rssi -= PCL_RSSI_DISCOUNT;
1629 
1630 		if (rssi < SOFTAP_MIN_RSSI)
1631 			rssi = SOFTAP_MIN_RSSI;
1632 
1633 		if (ch_info->weight == SAP_ACS_WEIGHT_MAX ||
1634 		    ch_info->weight == SAP_ACS_WEIGHT_ADJUSTABLE) {
1635 			ch_info->weight_copy = ch_info->weight;
1636 			goto debug_info;
1637 		}
1638 
1639 		/* There may be channels in scanlist, which were not sent to
1640 		 * FW for scanning as part of ACS scan list, but they do have an
1641 		 * effect on the neighbouring channels, so they help to find a
1642 		 * suitable channel, but there weight should be max as they were
1643 		 * and not meant to be included in the ACS scan results.
1644 		 * So just assign RSSI as -100, bsscount as 0, and weight as max
1645 		 * to them, so that they always stay low in sorting of best
1646 		 * channels which were included in ACS scan list
1647 		 */
1648 		found = false;
1649 		for (i = 0; i < sap_ctx->num_of_channel; i++) {
1650 			if (ch_info->chan_freq == sap_ctx->freq_list[i]) {
1651 			/* Scan channel was included in ACS scan list */
1652 				found = true;
1653 				break;
1654 			}
1655 		}
1656 
1657 		rssi_bss_weight = 0;
1658 		chan_status_weight = 0;
1659 		power_weight = 0;
1660 		if (found) {
1661 			rssi_bss_weight = sapweight_rssi_count(
1662 					sap_ctx,
1663 					rssi,
1664 					ch_info->bss_count);
1665 			chan_status_weight = sap_weight_channel_status(
1666 					sap_ctx,
1667 					sap_get_channel_status(
1668 					mac, ch_info->chan_freq));
1669 			power_weight = sap_weight_channel_reg_max_power(
1670 					sap_ctx, ch_info->chan_freq);
1671 			ch_info->weight = SAPDFS_NORMALISE_1000 *
1672 					(rssi_bss_weight + chan_status_weight
1673 					+ power_weight);
1674 		} else {
1675 			if (wlansap_is_channel_present_in_acs_list(
1676 					ch_info->chan_freq,
1677 					sap_ctx->acs_cfg->master_freq_list,
1678 					sap_ctx->acs_cfg->master_ch_list_count))
1679 				ch_info->weight = SAP_ACS_WEIGHT_ADJUSTABLE;
1680 			else
1681 				ch_info->weight = SAP_ACS_WEIGHT_MAX;
1682 			ch_info->rssi_agr = SOFTAP_MIN_RSSI;
1683 			rssi = SOFTAP_MIN_RSSI;
1684 			ch_info->bss_count = SOFTAP_MIN_COUNT;
1685 		}
1686 
1687 		sap_normalize_channel_weight_with_factors(mac, ch_info);
1688 
1689 		if (ch_info->weight > SAP_ACS_WEIGHT_MAX)
1690 			ch_info->weight = SAP_ACS_WEIGHT_MAX;
1691 		ch_info->weight_copy = ch_info->weight;
1692 
1693 debug_info:
1694 		if (wlan_reg_is_6ghz_chan_freq(ch_info->chan_freq) &&
1695 		    ch_info->weight < SAP_ACS_WEIGHT_ADJUSTABLE &&
1696 		    max_valid_weight_6ghz < ch_info->weight)
1697 			max_valid_weight_6ghz = ch_info->weight;
1698 
1699 		sap_debug("freq %d valid %d weight %d(%d,%d,%d) rssi %d bss %d",
1700 			  ch_info->chan_freq, ch_info->valid,
1701 			  ch_info->weight, rssi_bss_weight,
1702 			  chan_status_weight, power_weight,
1703 			  ch_info->rssi_agr, ch_info->bss_count);
1704 
1705 		ch_info++;
1706 	}
1707 	sap_update_6ghz_max_weight(ch_info_params,
1708 				   max_valid_weight_6ghz);
1709 
1710 	if (policy_mgr_is_vdev_ll_lt_sap(mac->psoc, sap_ctx->vdev_id))
1711 		sap_update_5ghz_low_freq_weight(mac->psoc, ch_info_params);
1712 
1713 	sap_clear_channel_status(mac);
1714 }
1715 
sap_chan_sel_exit(struct sap_sel_ch_info * ch_info_params)1716 void sap_chan_sel_exit(struct sap_sel_ch_info *ch_info_params)
1717 {
1718 	/* Free all the allocated memory */
1719 	qdf_mem_free(ch_info_params->ch_info);
1720 }
1721 
1722 /*==========================================================================
1723    FUNCTION    sap_sort_chl_weight
1724 
1725    DESCRIPTION
1726     Function to sort the channels with the least weight first for 20MHz channels
1727 
1728    DEPENDENCIES
1729     NA.
1730 
1731    PARAMETERS
1732 
1733     IN
1734     ch_info_params       : Pointer to the tSapChSelSpectInfo structure
1735 
1736    RETURN VALUE
1737     void     : NULL
1738 
1739    SIDE EFFECTS
1740    ============================================================================*/
sap_sort_chl_weight(struct sap_sel_ch_info * ch_info_params)1741 static void sap_sort_chl_weight(struct sap_sel_ch_info *ch_info_params)
1742 {
1743 	struct sap_ch_info temp;
1744 
1745 	struct sap_ch_info *ch_info = NULL;
1746 	uint32_t i = 0, j = 0, min_weight_index = 0;
1747 
1748 	ch_info = ch_info_params->ch_info;
1749 	for (i = 0; i < ch_info_params->num_ch; i++) {
1750 		min_weight_index = i;
1751 		for (j = i + 1; j < ch_info_params->num_ch; j++) {
1752 			if (ch_info[j].weight <
1753 			    ch_info[min_weight_index].weight) {
1754 				min_weight_index = j;
1755 			} else if (ch_info[j].weight ==
1756 				   ch_info[min_weight_index].weight) {
1757 				if (ch_info[j].bss_count <
1758 				    ch_info[min_weight_index].bss_count)
1759 					min_weight_index = j;
1760 			}
1761 		}
1762 		if (min_weight_index != i) {
1763 			qdf_mem_copy(&temp, &ch_info[min_weight_index],
1764 				     sizeof(*ch_info));
1765 			qdf_mem_copy(&ch_info[min_weight_index], &ch_info[i],
1766 				     sizeof(*ch_info));
1767 			qdf_mem_copy(&ch_info[i], &temp, sizeof(*ch_info));
1768 		}
1769 	}
1770 }
1771 
1772 /**
1773  * sap_override_6ghz_psc_minidx() - override mindex to 6 GHz PSC channel's idx
1774  * @mac_ctx: pointer to max context
1775  * @spectinfo: Pointer to array of tSach_infoInfo
1776  * @count: number of tSach_infoInfo element to search
1777  * @minidx: index to be overridden
1778  *
1779  * Return: QDF STATUS
1780  */
1781 static void
sap_override_6ghz_psc_minidx(struct mac_context * mac_ctx,struct sap_ch_info * spectinfo,uint8_t count,uint8_t * minidx)1782 sap_override_6ghz_psc_minidx(struct mac_context *mac_ctx,
1783 			     struct sap_ch_info *spectinfo,
1784 			     uint8_t count,
1785 			     uint8_t *minidx)
1786 {
1787 	uint8_t i;
1788 
1789 	if (!mac_ctx->mlme_cfg->acs.acs_prefer_6ghz_psc)
1790 		return;
1791 
1792 	for (i = 0; i < count; i++) {
1793 		if (wlan_reg_is_6ghz_chan_freq(
1794 				spectinfo[i].chan_freq) &&
1795 		    wlan_reg_is_6ghz_psc_chan_freq(
1796 				spectinfo[i].chan_freq)) {
1797 			*minidx = i;
1798 			return;
1799 		}
1800 	}
1801 }
1802 
1803 /**
1804  * sap_sort_chl_weight_80_mhz() - to sort the channels with the least weight
1805  * @mac_ctx: pointer to max context
1806  * @sap_ctx: Pointer to the struct sap_context *structure
1807  * @ch_info_params: Pointer to the tSapChSelSpectInfo structure
1808  * Function to sort the channels with the least weight first for HT80 channels
1809  *
1810  * Return: QDF STATUS
1811  */
1812 static QDF_STATUS
sap_sort_chl_weight_80_mhz(struct mac_context * mac_ctx,struct sap_context * sap_ctx,struct sap_sel_ch_info * ch_info_params)1813 sap_sort_chl_weight_80_mhz(struct mac_context *mac_ctx,
1814 			   struct sap_context *sap_ctx,
1815 			   struct sap_sel_ch_info *ch_info_params)
1816 {
1817 	uint8_t i, j;
1818 	struct sap_ch_info *chan_info;
1819 	uint8_t minIdx;
1820 	struct ch_params acs_ch_params = {0};
1821 	int8_t center_freq_diff;
1822 	uint32_t combined_weight;
1823 	uint32_t min_ch_weight;
1824 	uint32_t valid_chans = 0;
1825 	bool has_valid;
1826 
1827 	chan_info = ch_info_params->ch_info;
1828 
1829 	for (j = 0; j < ch_info_params->num_ch; j++) {
1830 
1831 		if (chan_info[j].weight_calc_done)
1832 			continue;
1833 
1834 		acs_ch_params.ch_width = CH_WIDTH_80MHZ;
1835 		sap_acs_set_puncture_support(sap_ctx, &acs_ch_params);
1836 
1837 		wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev,
1838 							chan_info[j].chan_freq,
1839 							0, &acs_ch_params,
1840 							REG_CURRENT_PWR_MODE);
1841 
1842 		/* Check if the freq supports 80 Mhz */
1843 		if (acs_ch_params.ch_width != CH_WIDTH_80MHZ) {
1844 			chan_info[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1845 			chan_info[j].weight_calc_done = true;
1846 			continue;
1847 		}
1848 
1849 		center_freq_diff = acs_ch_params.mhz_freq_seg0 -
1850 				   chan_info[j].chan_freq;
1851 
1852 		/* This channel frequency does not have all channels */
1853 		if (center_freq_diff != 30) {
1854 			chan_info[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1855 			chan_info[j].weight_calc_done = true;
1856 			continue;
1857 		}
1858 
1859 		/* no other freq left for 80 Mhz operation in spectrum */
1860 		if (j + 3 > ch_info_params->num_ch)
1861 			continue;
1862 
1863 		/* Check whether all frequencies are present for 80 Mhz */
1864 
1865 		if (!(((chan_info[j].chan_freq + 20) ==
1866 			chan_info[j + 1].chan_freq) &&
1867 			((chan_info[j].chan_freq + 40) ==
1868 				 chan_info[j + 2].chan_freq) &&
1869 			((chan_info[j].chan_freq + 60) ==
1870 				 chan_info[j + 3].chan_freq))) {
1871 			/*
1872 			 * some channels does not exist in pSectInfo array,
1873 			 * skip this channel and those in the same HT80 width
1874 			 */
1875 			chan_info[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1876 			chan_info[j].weight_calc_done = true;
1877 			if ((chan_info[j].chan_freq + 20) ==
1878 					chan_info[j + 1].chan_freq) {
1879 				chan_info[j + 1].weight =
1880 					SAP_ACS_WEIGHT_MAX * 4;
1881 				chan_info[j + 1].weight_calc_done = true;
1882 			}
1883 			if ((chan_info[j].chan_freq + 40) ==
1884 					chan_info[j + 2].chan_freq) {
1885 				chan_info[j + 2].weight =
1886 					SAP_ACS_WEIGHT_MAX * 4;
1887 				chan_info[j + 2].weight_calc_done = true;
1888 			}
1889 			if ((chan_info[j].chan_freq + 60) ==
1890 					chan_info[j + 3].chan_freq) {
1891 				chan_info[j + 3].weight =
1892 					SAP_ACS_WEIGHT_MAX * 4;
1893 				chan_info[j + 3].weight_calc_done = true;
1894 			}
1895 
1896 			continue;
1897 		}
1898 
1899 		/* We have 4 channels to calculate cumulative weight */
1900 
1901 		combined_weight = chan_info[j].weight +
1902 				  chan_info[j + 1].weight +
1903 				  chan_info[j + 2].weight +
1904 				  chan_info[j + 3].weight;
1905 
1906 		min_ch_weight = chan_info[j].weight;
1907 		minIdx = 0;
1908 		has_valid = false;
1909 
1910 		for (i = 0; i < 4; i++) {
1911 			if (min_ch_weight > chan_info[j + i].weight) {
1912 				min_ch_weight = chan_info[j + i].weight;
1913 				minIdx = i;
1914 			}
1915 			chan_info[j + i].weight = SAP_ACS_WEIGHT_MAX * 4;
1916 			chan_info[j + i].weight_calc_done = true;
1917 			if (chan_info[j + i].valid)
1918 				has_valid = true;
1919 		}
1920 		sap_override_6ghz_psc_minidx(mac_ctx, &chan_info[j], 4,
1921 					     &minIdx);
1922 
1923 		chan_info[j + minIdx].weight = combined_weight;
1924 		if (has_valid)
1925 			valid_chans++;
1926 
1927 		sap_debug("best freq = %d for 80mhz center freq %d combined weight = %d valid %d cnt %d",
1928 			  chan_info[j + minIdx].chan_freq,
1929 			  acs_ch_params.mhz_freq_seg0,
1930 			  combined_weight, has_valid, valid_chans);
1931 	}
1932 
1933 	if (!valid_chans) {
1934 		sap_debug("no valid chan bonding with CH_WIDTH_80MHZ");
1935 		return QDF_STATUS_E_INVAL;
1936 	}
1937 
1938 	sap_sort_chl_weight(ch_info_params);
1939 
1940 	return QDF_STATUS_SUCCESS;
1941 }
1942 
1943 /**
1944  * sap_sort_chl_weight_160_mhz() - to sort the channels with the least weight
1945  * @mac_ctx: pointer to max context
1946  * @sap_ctx: Pointer to the struct sap_context *structure
1947  * @ch_info_params: Pointer to the tSapChSelSpectInfo structure
1948  *
1949  * Function to sort the channels with the least weight first for VHT160 channels
1950  *
1951  * Return: QDF STATUS
1952  */
1953 static QDF_STATUS
sap_sort_chl_weight_160_mhz(struct mac_context * mac_ctx,struct sap_context * sap_ctx,struct sap_sel_ch_info * ch_info_params)1954 sap_sort_chl_weight_160_mhz(struct mac_context *mac_ctx,
1955 			    struct sap_context *sap_ctx,
1956 			    struct sap_sel_ch_info *ch_info_params)
1957 {
1958 	uint8_t i, j;
1959 	struct sap_ch_info *chan_info;
1960 	uint8_t minIdx;
1961 	struct ch_params acs_ch_params = {0};
1962 	int8_t center_freq_diff;
1963 	uint32_t combined_weight;
1964 	uint32_t min_ch_weight;
1965 	uint32_t valid_chans = 0;
1966 	bool has_valid;
1967 
1968 	chan_info = ch_info_params->ch_info;
1969 
1970 	for (j = 0; j < ch_info_params->num_ch; j++) {
1971 
1972 		if (chan_info[j].weight_calc_done)
1973 			continue;
1974 
1975 		acs_ch_params.ch_width = CH_WIDTH_160MHZ;
1976 		sap_acs_set_puncture_support(sap_ctx, &acs_ch_params);
1977 
1978 		wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev,
1979 							chan_info[j].chan_freq,
1980 							0, &acs_ch_params,
1981 							REG_CURRENT_PWR_MODE);
1982 
1983 		/* Check if the freq supports 160 Mhz */
1984 		if (acs_ch_params.ch_width != CH_WIDTH_160MHZ) {
1985 			chan_info[j].weight = SAP_ACS_WEIGHT_MAX * 8;
1986 			chan_info[j].weight_calc_done = true;
1987 			continue;
1988 		}
1989 
1990 		center_freq_diff = acs_ch_params.mhz_freq_seg1 -
1991 				   chan_info[j].chan_freq;
1992 
1993 		/* This channel frequency does not have all channels */
1994 		if (center_freq_diff != 70) {
1995 			chan_info[j].weight = SAP_ACS_WEIGHT_MAX * 8;
1996 			chan_info[j].weight_calc_done = true;
1997 			continue;
1998 		}
1999 
2000 		/* no other freq left for 160 Mhz operation in spectrum */
2001 		if (j + 7 > ch_info_params->num_ch)
2002 			continue;
2003 
2004 		/* Check whether all frequencies are present for 160 Mhz */
2005 
2006 		if (!(((chan_info[j].chan_freq + 20) ==
2007 			chan_info[j + 1].chan_freq) &&
2008 			((chan_info[j].chan_freq + 40) ==
2009 				 chan_info[j + 2].chan_freq) &&
2010 			((chan_info[j].chan_freq + 60) ==
2011 				 chan_info[j + 3].chan_freq) &&
2012 			((chan_info[j].chan_freq + 80) ==
2013 				 chan_info[j + 4].chan_freq) &&
2014 			((chan_info[j].chan_freq + 100) ==
2015 				 chan_info[j + 5].chan_freq) &&
2016 			((chan_info[j].chan_freq + 120) ==
2017 				 chan_info[j + 6].chan_freq) &&
2018 			((chan_info[j].chan_freq + 140) ==
2019 				 chan_info[j + 7].chan_freq))) {
2020 			/*
2021 			 * some channels does not exist in pSectInfo array,
2022 			 * skip this channel and those in the same VHT160 width
2023 			 */
2024 			chan_info[j].weight = SAP_ACS_WEIGHT_MAX * 8;
2025 			chan_info[j].weight_calc_done = true;
2026 			if ((chan_info[j].chan_freq + 20) ==
2027 					chan_info[j + 1].chan_freq) {
2028 				chan_info[j + 1].weight =
2029 					SAP_ACS_WEIGHT_MAX * 8;
2030 				chan_info[j + 1].weight_calc_done = true;
2031 			}
2032 			if ((chan_info[j].chan_freq + 40) ==
2033 					chan_info[j + 2].chan_freq) {
2034 				chan_info[j + 2].weight =
2035 					SAP_ACS_WEIGHT_MAX * 8;
2036 				chan_info[j + 2].weight_calc_done = true;
2037 			}
2038 			if ((chan_info[j].chan_freq + 60) ==
2039 					chan_info[j + 3].chan_freq) {
2040 				chan_info[j + 3].weight =
2041 					SAP_ACS_WEIGHT_MAX * 8;
2042 				chan_info[j + 3].weight_calc_done = true;
2043 			}
2044 			if ((chan_info[j].chan_freq + 80) ==
2045 					chan_info[j + 4].chan_freq) {
2046 				chan_info[j + 4].weight =
2047 					SAP_ACS_WEIGHT_MAX * 8;
2048 				chan_info[j + 4].weight_calc_done = true;
2049 			}
2050 			if ((chan_info[j].chan_freq + 100) ==
2051 					chan_info[j + 5].chan_freq) {
2052 				chan_info[j + 5].weight =
2053 					SAP_ACS_WEIGHT_MAX * 8;
2054 				chan_info[j + 5].weight_calc_done = true;
2055 			}
2056 			if ((chan_info[j].chan_freq + 120) ==
2057 					chan_info[j + 6].chan_freq) {
2058 				chan_info[j + 6].weight =
2059 					SAP_ACS_WEIGHT_MAX * 8;
2060 				chan_info[j + 6].weight_calc_done = true;
2061 			}
2062 			if ((chan_info[j].chan_freq + 140) ==
2063 					chan_info[j + 7].chan_freq) {
2064 				chan_info[j + 7].weight =
2065 					SAP_ACS_WEIGHT_MAX * 8;
2066 				chan_info[j + 7].weight_calc_done = true;
2067 			}
2068 
2069 			continue;
2070 		}
2071 
2072 		/* We have 8 channels to calculate cumulative weight */
2073 
2074 		combined_weight = chan_info[j].weight +
2075 				  chan_info[j + 1].weight +
2076 				  chan_info[j + 2].weight +
2077 				  chan_info[j + 3].weight +
2078 				  chan_info[j + 4].weight +
2079 				  chan_info[j + 5].weight +
2080 				  chan_info[j + 6].weight +
2081 				  chan_info[j + 7].weight;
2082 
2083 		min_ch_weight = chan_info[j].weight;
2084 		minIdx = 0;
2085 		has_valid = false;
2086 
2087 		for (i = 0; i < 8; i++) {
2088 			if (min_ch_weight > chan_info[j + i].weight) {
2089 				min_ch_weight = chan_info[j + i].weight;
2090 				minIdx = i;
2091 			}
2092 			chan_info[j + i].weight = SAP_ACS_WEIGHT_MAX * 8;
2093 			chan_info[j + i].weight_calc_done = true;
2094 			if (chan_info[j + i].valid)
2095 				has_valid = true;
2096 		}
2097 		sap_override_6ghz_psc_minidx(mac_ctx, &chan_info[j], 8,
2098 					     &minIdx);
2099 
2100 		chan_info[j + minIdx].weight = combined_weight;
2101 		if (has_valid)
2102 			valid_chans++;
2103 
2104 		sap_debug("best freq = %d for 160mhz center freq %d combined weight = %d valid %d cnt %d",
2105 			  chan_info[j + minIdx].chan_freq,
2106 			  acs_ch_params.mhz_freq_seg1,
2107 			  combined_weight, has_valid, valid_chans);
2108 	}
2109 
2110 	if (!valid_chans) {
2111 		sap_debug("no valid chan bonding with CH_WIDTH_160MHZ");
2112 		return QDF_STATUS_E_INVAL;
2113 	}
2114 
2115 	sap_sort_chl_weight(ch_info_params);
2116 
2117 	return QDF_STATUS_SUCCESS;
2118 }
2119 
2120 #if defined(WLAN_FEATURE_11BE)
2121 /**
2122  * sap_sort_chl_weight_320_mhz() - to sort the channels with the least weight
2123  * @mac_ctx: pointer to max context
2124  * @sap_ctx: Pointer to the struct sap_context *structure
2125  * @ch_info_params: Pointer to the tSapChSelSpectInfo structure
2126  *
2127  * Function to sort the channels with the least weight first for 320MHz channels
2128  *
2129  * Return: QDF STATUS
2130  */
2131 static QDF_STATUS
sap_sort_chl_weight_320_mhz(struct mac_context * mac_ctx,struct sap_context * sap_ctx,struct sap_sel_ch_info * ch_info_params)2132 sap_sort_chl_weight_320_mhz(struct mac_context *mac_ctx,
2133 			    struct sap_context *sap_ctx,
2134 			    struct sap_sel_ch_info *ch_info_params)
2135 {
2136 	uint8_t i, j;
2137 	struct sap_ch_info *chan_info;
2138 	uint8_t minIdx;
2139 	struct ch_params acs_ch_params = {0};
2140 	uint32_t combined_weight;
2141 	uint32_t min_ch_weight;
2142 	uint32_t valid_chans = 0;
2143 	bool has_valid;
2144 
2145 	chan_info = ch_info_params->ch_info;
2146 
2147 	for (j = 0; j < ch_info_params->num_ch; j++) {
2148 		if (chan_info[j].weight_calc_done)
2149 			continue;
2150 
2151 		qdf_mem_zero(&acs_ch_params, sizeof(acs_ch_params));
2152 		acs_ch_params.ch_width = CH_WIDTH_320MHZ;
2153 		sap_acs_set_puncture_support(sap_ctx, &acs_ch_params);
2154 
2155 		wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev,
2156 							chan_info[j].chan_freq,
2157 							0, &acs_ch_params,
2158 							REG_CURRENT_PWR_MODE);
2159 
2160 		/* Check if the freq supports 320 Mhz */
2161 		if (acs_ch_params.ch_width != CH_WIDTH_320MHZ) {
2162 			chan_info[j].weight = SAP_ACS_WEIGHT_MAX * 16;
2163 			chan_info[j].weight_calc_done = true;
2164 			continue;
2165 		}
2166 
2167 		/* no other freq left for 320 Mhz operation in spectrum */
2168 		if (j + 15 > ch_info_params->num_ch) {
2169 			chan_info[j].weight = SAP_ACS_WEIGHT_MAX * 16;
2170 			chan_info[j].weight_calc_done = true;
2171 			continue;
2172 		}
2173 
2174 		/* Check whether all frequencies are present for 160 Mhz */
2175 
2176 		if (!(((chan_info[j].chan_freq + 20) ==
2177 			chan_info[j + 1].chan_freq) &&
2178 			((chan_info[j].chan_freq + 40) ==
2179 				 chan_info[j + 2].chan_freq) &&
2180 			((chan_info[j].chan_freq + 60) ==
2181 				 chan_info[j + 3].chan_freq) &&
2182 			((chan_info[j].chan_freq + 80) ==
2183 				 chan_info[j + 4].chan_freq) &&
2184 			((chan_info[j].chan_freq + 100) ==
2185 				 chan_info[j + 5].chan_freq) &&
2186 			((chan_info[j].chan_freq + 120) ==
2187 				 chan_info[j + 6].chan_freq) &&
2188 			((chan_info[j].chan_freq + 140) ==
2189 				 chan_info[j + 7].chan_freq) &&
2190 			((chan_info[j].chan_freq + 160) ==
2191 				 chan_info[j + 8].chan_freq) &&
2192 			((chan_info[j].chan_freq + 180) ==
2193 				 chan_info[j + 9].chan_freq) &&
2194 			((chan_info[j].chan_freq + 200) ==
2195 				 chan_info[j + 10].chan_freq) &&
2196 			((chan_info[j].chan_freq + 220) ==
2197 				 chan_info[j + 11].chan_freq) &&
2198 			((chan_info[j].chan_freq + 240) ==
2199 				 chan_info[j + 12].chan_freq) &&
2200 			((chan_info[j].chan_freq + 260) ==
2201 				 chan_info[j + 13].chan_freq) &&
2202 			((chan_info[j].chan_freq + 280) ==
2203 				 chan_info[j + 14].chan_freq) &&
2204 			((chan_info[j].chan_freq + 300) ==
2205 				 chan_info[j + 15].chan_freq))) {
2206 			/*
2207 			 * some channels does not exist in pSectInfo array,
2208 			 * skip this channel and those in the same ETH320 width
2209 			 */
2210 			chan_info[j].weight = SAP_ACS_WEIGHT_MAX * 16;
2211 			chan_info[j].weight_calc_done = true;
2212 			if ((chan_info[j].chan_freq + 20) ==
2213 					chan_info[j + 1].chan_freq) {
2214 				chan_info[j + 1].weight =
2215 					SAP_ACS_WEIGHT_MAX * 16;
2216 				chan_info[j + 1].weight_calc_done = true;
2217 			}
2218 			if ((chan_info[j].chan_freq + 40) ==
2219 					chan_info[j + 2].chan_freq) {
2220 				chan_info[j + 2].weight =
2221 					SAP_ACS_WEIGHT_MAX * 16;
2222 				chan_info[j + 2].weight_calc_done = true;
2223 			}
2224 			if ((chan_info[j].chan_freq + 60) ==
2225 					chan_info[j + 3].chan_freq) {
2226 				chan_info[j + 3].weight =
2227 					SAP_ACS_WEIGHT_MAX * 16;
2228 				chan_info[j + 3].weight_calc_done = true;
2229 			}
2230 			if ((chan_info[j].chan_freq + 80) ==
2231 					chan_info[j + 4].chan_freq) {
2232 				chan_info[j + 4].weight =
2233 					SAP_ACS_WEIGHT_MAX * 16;
2234 				chan_info[j + 4].weight_calc_done = true;
2235 			}
2236 			if ((chan_info[j].chan_freq + 100) ==
2237 					chan_info[j + 5].chan_freq) {
2238 				chan_info[j + 5].weight =
2239 					SAP_ACS_WEIGHT_MAX * 16;
2240 				chan_info[j + 5].weight_calc_done = true;
2241 			}
2242 			if ((chan_info[j].chan_freq + 120) ==
2243 					chan_info[j + 6].chan_freq) {
2244 				chan_info[j + 6].weight =
2245 					SAP_ACS_WEIGHT_MAX * 16;
2246 				chan_info[j + 6].weight_calc_done = true;
2247 			}
2248 			if ((chan_info[j].chan_freq + 140) ==
2249 					chan_info[j + 7].chan_freq) {
2250 				chan_info[j + 7].weight =
2251 					SAP_ACS_WEIGHT_MAX * 16;
2252 				chan_info[j + 7].weight_calc_done = true;
2253 			}
2254 			if ((chan_info[j].chan_freq + 160) ==
2255 					chan_info[j + 8].chan_freq) {
2256 				chan_info[j + 8].weight =
2257 					SAP_ACS_WEIGHT_MAX * 16;
2258 				chan_info[j + 8].weight_calc_done = true;
2259 			}
2260 			if ((chan_info[j].chan_freq + 180) ==
2261 					chan_info[j + 9].chan_freq) {
2262 				chan_info[j + 9].weight =
2263 					SAP_ACS_WEIGHT_MAX * 16;
2264 				chan_info[j + 9].weight_calc_done = true;
2265 			}
2266 			if ((chan_info[j].chan_freq + 200) ==
2267 					chan_info[j + 10].chan_freq) {
2268 				chan_info[j + 10].weight =
2269 					SAP_ACS_WEIGHT_MAX * 16;
2270 				chan_info[j + 10].weight_calc_done = true;
2271 			}
2272 			if ((chan_info[j].chan_freq + 220) ==
2273 					chan_info[j + 11].chan_freq) {
2274 				chan_info[j + 11].weight =
2275 					SAP_ACS_WEIGHT_MAX * 16;
2276 				chan_info[j + 11].weight_calc_done = true;
2277 			}
2278 			if ((chan_info[j].chan_freq + 240) ==
2279 					chan_info[j + 12].chan_freq) {
2280 				chan_info[j + 12].weight =
2281 					SAP_ACS_WEIGHT_MAX * 16;
2282 				chan_info[j + 12].weight_calc_done = true;
2283 			}
2284 			if ((chan_info[j].chan_freq + 260) ==
2285 					chan_info[j + 13].chan_freq) {
2286 				chan_info[j + 13].weight =
2287 					SAP_ACS_WEIGHT_MAX * 16;
2288 				chan_info[j + 13].weight_calc_done = true;
2289 			}
2290 			if ((chan_info[j].chan_freq + 280) ==
2291 					chan_info[j + 14].chan_freq) {
2292 				chan_info[j + 14].weight =
2293 					SAP_ACS_WEIGHT_MAX * 16;
2294 				chan_info[j + 14].weight_calc_done = true;
2295 			}
2296 			if ((chan_info[j].chan_freq + 300) ==
2297 					chan_info[j + 15].chan_freq) {
2298 				chan_info[j + 15].weight =
2299 					SAP_ACS_WEIGHT_MAX * 16;
2300 				chan_info[j + 15].weight_calc_done = true;
2301 			}
2302 
2303 			continue;
2304 		}
2305 
2306 		/* We have 16 channels to calculate cumulative weight */
2307 		combined_weight = chan_info[j].weight +
2308 				  chan_info[j + 1].weight +
2309 				  chan_info[j + 2].weight +
2310 				  chan_info[j + 3].weight +
2311 				  chan_info[j + 4].weight +
2312 				  chan_info[j + 5].weight +
2313 				  chan_info[j + 6].weight +
2314 				  chan_info[j + 7].weight +
2315 				  chan_info[j + 8].weight +
2316 				  chan_info[j + 9].weight +
2317 				  chan_info[j + 10].weight +
2318 				  chan_info[j + 11].weight +
2319 				  chan_info[j + 12].weight +
2320 				  chan_info[j + 13].weight +
2321 				  chan_info[j + 14].weight +
2322 				  chan_info[j + 15].weight;
2323 
2324 		min_ch_weight = chan_info[j].weight;
2325 		minIdx = 0;
2326 		has_valid = false;
2327 		for (i = 0; i < 16; i++) {
2328 			if (min_ch_weight > chan_info[j + i].weight) {
2329 				min_ch_weight = chan_info[j + i].weight;
2330 				minIdx = i;
2331 			}
2332 			chan_info[j + i].weight = SAP_ACS_WEIGHT_MAX * 16;
2333 			chan_info[j + i].weight_calc_done = true;
2334 			if (chan_info[j + i].valid)
2335 				has_valid = true;
2336 		}
2337 		sap_override_6ghz_psc_minidx(mac_ctx, &chan_info[j], 16,
2338 					     &minIdx);
2339 
2340 		chan_info[j + minIdx].weight = combined_weight;
2341 		if (has_valid)
2342 			valid_chans++;
2343 
2344 		sap_debug("best freq = %d for 320mhz center freq %d combined weight = %d valid %d cnt %d",
2345 			  chan_info[j + minIdx].chan_freq,
2346 			  acs_ch_params.mhz_freq_seg1,
2347 			  combined_weight,
2348 			  has_valid, valid_chans);
2349 	}
2350 
2351 	if (!valid_chans) {
2352 		sap_debug("no valid chan bonding with CH_WIDTH_320MHZ");
2353 		return QDF_STATUS_E_INVAL;
2354 	}
2355 
2356 	sap_sort_chl_weight(ch_info_params);
2357 
2358 	return QDF_STATUS_SUCCESS;
2359 }
2360 #endif /* WLAN_FEATURE_11BE */
2361 
2362 /**
2363  * sap_allocate_max_weight_40_mhz_24_g() - allocate max weight for 40Mhz
2364  *                                       to all 2.4Ghz channels
2365  * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
2366  *
2367  * Return: none
2368  */
2369 static void
sap_allocate_max_weight_40_mhz_24_g(struct sap_sel_ch_info * spect_info_params)2370 sap_allocate_max_weight_40_mhz_24_g(struct sap_sel_ch_info *spect_info_params)
2371 {
2372 	struct sap_ch_info *spect_info;
2373 	uint8_t j;
2374 
2375 	/*
2376 	 * Assign max weight for 40Mhz (SAP_ACS_WEIGHT_MAX * 2) to all
2377 	 * 2.4 Ghz channels
2378 	 */
2379 	spect_info = spect_info_params->ch_info;
2380 	for (j = 0; j < spect_info_params->num_ch; j++) {
2381 		if (WLAN_REG_IS_24GHZ_CH_FREQ(spect_info[j].chan_freq))
2382 			spect_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2383 	}
2384 }
2385 
2386 /**
2387  * sap_allocate_max_weight_40_mhz() - allocate max weight for 40Mhz
2388  *                                      to all 5Ghz channels
2389  * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
2390  *
2391  * Return: none
2392  */
2393 static void
sap_allocate_max_weight_40_mhz(struct sap_sel_ch_info * spect_info_params)2394 sap_allocate_max_weight_40_mhz(struct sap_sel_ch_info *spect_info_params)
2395 {
2396 	struct sap_ch_info *spect_info;
2397 	uint8_t j;
2398 
2399 	/*
2400 	 * Assign max weight for 40Mhz (SAP_ACS_WEIGHT_MAX * 2) to all
2401 	 * 5 Ghz channels
2402 	 */
2403 	spect_info = spect_info_params->ch_info;
2404 	for (j = 0; j < spect_info_params->num_ch; j++) {
2405 		if (WLAN_REG_IS_5GHZ_CH_FREQ(spect_info[j].chan_freq) ||
2406 		    WLAN_REG_IS_6GHZ_CHAN_FREQ(spect_info[j].chan_freq))
2407 			spect_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2408 	}
2409 }
2410 
2411 /**
2412  * sap_sort_chl_weight_ht40_24_g() - To sort channel with the least weight
2413  * @mac_ctx: Pointer to mac_ctx
2414  * @ch_info_params: Pointer to the sap_sel_ch_info structure
2415  * @domain: Regulatory domain
2416  *
2417  * Function to sort the channels with the least weight first for HT40 channels
2418  *
2419  * Return: none
2420  */
sap_sort_chl_weight_ht40_24_g(struct mac_context * mac_ctx,struct sap_sel_ch_info * ch_info_params,v_REGDOMAIN_t domain)2421 static void sap_sort_chl_weight_ht40_24_g(
2422 				struct mac_context *mac_ctx,
2423 				struct sap_sel_ch_info *ch_info_params,
2424 				v_REGDOMAIN_t domain)
2425 {
2426 	uint8_t i, j;
2427 	struct sap_ch_info *chan_info;
2428 	uint32_t tmp_weight1, tmp_weight2;
2429 	uint32_t ht40plus2gendch = 0;
2430 	uint32_t channel;
2431 	uint32_t chan_freq;
2432 
2433 	chan_info = ch_info_params->ch_info;
2434 	/*
2435 	 * for each HT40 channel, calculate the combined weight of the
2436 	 * two 20MHz weight
2437 	 */
2438 	for (i = 0; i < ARRAY_SIZE(acs_ht40_channels24_g); i++) {
2439 		for (j = 0; j < ch_info_params->num_ch; j++) {
2440 			channel = wlan_reg_freq_to_chan(mac_ctx->pdev,
2441 							chan_info[j].chan_freq);
2442 			if (channel == acs_ht40_channels24_g[i].chStartNum)
2443 				break;
2444 		}
2445 		if (j == ch_info_params->num_ch)
2446 			continue;
2447 
2448 		if (!((chan_info[j].chan_freq + 20) ==
2449 		       chan_info[j + 4].chan_freq)) {
2450 			chan_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2451 			continue;
2452 		}
2453 		/*
2454 		 * check if there is another channel combination possibility
2455 		 * e.g., {1, 5} & {5, 9}
2456 		 */
2457 		if ((chan_info[j + 4].chan_freq + 20) ==
2458 		     chan_info[j + 8].chan_freq) {
2459 			/* need to compare two channel pairs */
2460 			tmp_weight1 = chan_info[j].weight +
2461 						chan_info[j + 4].weight;
2462 			tmp_weight2 = chan_info[j + 4].weight +
2463 						chan_info[j + 8].weight;
2464 			if (tmp_weight1 <= tmp_weight2) {
2465 				if (chan_info[j].weight <=
2466 						chan_info[j + 4].weight) {
2467 					chan_info[j].weight =
2468 						tmp_weight1;
2469 					chan_info[j + 4].weight =
2470 						SAP_ACS_WEIGHT_MAX * 2;
2471 					chan_info[j + 8].weight =
2472 						SAP_ACS_WEIGHT_MAX * 2;
2473 				} else {
2474 					chan_info[j + 4].weight =
2475 						tmp_weight1;
2476 					/* for secondary channel selection */
2477 					chan_info[j].weight =
2478 						SAP_ACS_WEIGHT_MAX * 2
2479 						- 1;
2480 					chan_info[j + 8].weight =
2481 						SAP_ACS_WEIGHT_MAX * 2;
2482 				}
2483 			} else {
2484 				if (chan_info[j + 4].weight <=
2485 						chan_info[j + 8].weight) {
2486 					chan_info[j + 4].weight =
2487 						tmp_weight2;
2488 					chan_info[j].weight =
2489 						SAP_ACS_WEIGHT_MAX * 2;
2490 					/* for secondary channel selection */
2491 					chan_info[j + 8].weight =
2492 						SAP_ACS_WEIGHT_MAX * 2
2493 						- 1;
2494 				} else {
2495 					chan_info[j + 8].weight =
2496 						tmp_weight2;
2497 					chan_info[j].weight =
2498 						SAP_ACS_WEIGHT_MAX * 2;
2499 					chan_info[j + 4].weight =
2500 						SAP_ACS_WEIGHT_MAX * 2;
2501 				}
2502 			}
2503 		} else {
2504 			tmp_weight1 = chan_info[j].weight_copy +
2505 						chan_info[j + 4].weight_copy;
2506 			if (chan_info[j].weight_copy <=
2507 					chan_info[j + 4].weight_copy) {
2508 				chan_info[j].weight = tmp_weight1;
2509 				chan_info[j + 4].weight =
2510 					SAP_ACS_WEIGHT_MAX * 2;
2511 			} else {
2512 				chan_info[j + 4].weight = tmp_weight1;
2513 				chan_info[j].weight =
2514 					SAP_ACS_WEIGHT_MAX * 2;
2515 			}
2516 		}
2517 	}
2518 	/*
2519 	 * Every channel should be checked. Add the check for the omissive
2520 	 * channel. Mark the channel whose combination can't satisfy 40MHZ
2521 	 * as max value, so that it will be sorted to the bottom.
2522 	 */
2523 	if (REGDOMAIN_FCC == domain)
2524 		ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
2525 	else
2526 		ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
2527 	for (i = HT40MINUS_2G_CH_START; i <= ht40plus2gendch; i++) {
2528 		chan_freq = wlan_reg_legacy_chan_to_freq(mac_ctx->pdev, i);
2529 		for (j = 0; j < ch_info_params->num_ch; j++) {
2530 			if (chan_info[j].chan_freq == chan_freq &&
2531 			    ((chan_info[j].chan_freq + 20) !=
2532 					chan_info[j + 4].chan_freq) &&
2533 			    ((chan_info[j].chan_freq - 20) !=
2534 					chan_info[j - 4].chan_freq))
2535 				chan_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2536 		}
2537 	}
2538 	for (i = ht40plus2gendch + 1; i <= HT40MINUS_2G_CH_END; i++) {
2539 		chan_freq = wlan_reg_legacy_chan_to_freq(mac_ctx->pdev, i);
2540 		for (j = 0; j < ch_info_params->num_ch; j++) {
2541 			if (chan_info[j].chan_freq == chan_freq &&
2542 			    (chan_info[j].chan_freq - 20) !=
2543 					chan_info[j - 4].chan_freq)
2544 				chan_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2545 		}
2546 	}
2547 
2548 	chan_info = ch_info_params->ch_info;
2549 	for (j = 0; j < (ch_info_params->num_ch); j++) {
2550 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_TRACE,
2551 			  "%s: freq = %d weight = %d rssi = %d bss count = %d",
2552 			  __func__, chan_info->chan_freq, chan_info->weight,
2553 			     chan_info->rssi_agr, chan_info->bss_count);
2554 
2555 		chan_info++;
2556 	}
2557 
2558 	sap_sort_chl_weight(ch_info_params);
2559 }
2560 
2561 /**
2562  * sap_sort_chl_weight_40_mhz() - To sort 5 GHz channel in 40 MHz bandwidth
2563  * @mac_ctx: mac context handle
2564  * @sap_ctx: pointer to SAP context
2565  * @ch_info_params: pointer to the tSapChSelSpectInfo structure
2566  *
2567  * Return: QDF STATUS
2568  */
2569 static QDF_STATUS
sap_sort_chl_weight_40_mhz(struct mac_context * mac_ctx,struct sap_context * sap_ctx,struct sap_sel_ch_info * ch_info_params)2570 sap_sort_chl_weight_40_mhz(struct mac_context *mac_ctx,
2571 			   struct sap_context *sap_ctx,
2572 			   struct sap_sel_ch_info *ch_info_params)
2573 {
2574 	uint8_t i, j;
2575 	struct sap_ch_info *chan_info;
2576 	uint8_t minIdx;
2577 	struct ch_params acs_ch_params = {0};
2578 	int8_t center_freq_diff;
2579 	uint32_t combined_weight;
2580 	uint32_t min_ch_weight;
2581 	uint32_t valid_chans = 0;
2582 	bool has_valid;
2583 
2584 	chan_info = ch_info_params->ch_info;
2585 
2586 	for (j = 0; j < ch_info_params->num_ch; j++) {
2587 
2588 		if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_info[j].chan_freq))
2589 			continue;
2590 
2591 		if (chan_info[j].weight_calc_done)
2592 			continue;
2593 
2594 		acs_ch_params.ch_width = CH_WIDTH_40MHZ;
2595 
2596 		wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev,
2597 							chan_info[j].chan_freq,
2598 							0, &acs_ch_params,
2599 							REG_CURRENT_PWR_MODE);
2600 
2601 		/* Check if the freq supports 40 Mhz */
2602 		if (acs_ch_params.ch_width != CH_WIDTH_40MHZ) {
2603 			chan_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2604 			chan_info[j].weight_calc_done = true;
2605 			continue;
2606 		}
2607 
2608 		center_freq_diff = acs_ch_params.mhz_freq_seg0 -
2609 				   chan_info[j].chan_freq;
2610 
2611 		/* This channel frequency does not have all channels */
2612 		if (center_freq_diff != 10) {
2613 			chan_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2614 			chan_info[j].weight_calc_done = true;
2615 			continue;
2616 		}
2617 
2618 		/* no other freq left for 40 Mhz operation in spectrum */
2619 		if (j + 1 > ch_info_params->num_ch)
2620 			continue;
2621 
2622 		/* Check whether all frequencies are present for 40 Mhz */
2623 
2624 		if (!((chan_info[j].chan_freq + 20) ==
2625 		       chan_info[j + 1].chan_freq)) {
2626 			/*
2627 			 * some channels does not exist in pSectInfo array,
2628 			 * skip this channel and those in the same 40 width
2629 			 */
2630 			chan_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2631 			chan_info[j].weight_calc_done = true;
2632 
2633 			if ((chan_info[j].chan_freq + 20) ==
2634 					chan_info[j + 1].chan_freq) {
2635 				chan_info[j + 1].weight =
2636 					SAP_ACS_WEIGHT_MAX * 2;
2637 				chan_info[j + 1].weight_calc_done = true;
2638 			}
2639 
2640 			continue;
2641 		}
2642 
2643 		/* We have 2 channels to calculate cumulative weight */
2644 
2645 		combined_weight = chan_info[j].weight +
2646 				  chan_info[j + 1].weight;
2647 
2648 		min_ch_weight = chan_info[j].weight;
2649 		minIdx = 0;
2650 		has_valid = false;
2651 
2652 		for (i = 0; i < 2; i++) {
2653 			if (min_ch_weight > chan_info[j + i].weight) {
2654 				min_ch_weight = chan_info[j + i].weight;
2655 				minIdx = i;
2656 			}
2657 			chan_info[j + i].weight = SAP_ACS_WEIGHT_MAX * 2;
2658 			chan_info[j + i].weight_calc_done = true;
2659 			if (chan_info[j + i].valid)
2660 				has_valid = true;
2661 		}
2662 		sap_override_6ghz_psc_minidx(mac_ctx, &chan_info[j], 2,
2663 					     &minIdx);
2664 
2665 		chan_info[j + minIdx].weight = combined_weight;
2666 		if (has_valid)
2667 			valid_chans++;
2668 
2669 		sap_debug("best freq = %d for 40mhz center freq %d combined weight = %d valid %d cnt %d",
2670 			  chan_info[j + minIdx].chan_freq,
2671 			  acs_ch_params.mhz_freq_seg0,
2672 			  combined_weight, has_valid, valid_chans);
2673 	}
2674 
2675 	if (!valid_chans) {
2676 		sap_debug("no valid chan bonding with CH_WIDTH_40MHZ");
2677 		return QDF_STATUS_E_INVAL;
2678 	}
2679 
2680 	sap_sort_chl_weight(ch_info_params);
2681 
2682 	return QDF_STATUS_SUCCESS;
2683 }
2684 
2685 /**
2686  * sap_restore_chan_weight() - Restore every channel weight to original
2687  * @spect_info: pointer to the tSapChSelSpectInfo structure
2688  *
2689  * Return: None
2690  */
sap_restore_chan_weight(struct sap_sel_ch_info * spect_info)2691 static void sap_restore_chan_weight(struct sap_sel_ch_info *spect_info)
2692 {
2693 	uint32_t i;
2694 	struct sap_ch_info *spect_ch = spect_info->ch_info;
2695 
2696 	for (i = 0; i < spect_info->num_ch; i++) {
2697 		spect_ch->weight = spect_ch->weight_copy;
2698 		spect_ch->weight_calc_done = false;
2699 		spect_ch++;
2700 	}
2701 }
2702 
2703 /**
2704  * sap_sort_chl_weight_all() - Function to sort the channels with the least
2705  * weight first
2706  * @mac_ctx: Pointer to mac_ctx structure
2707  * @sap_ctx: Pointer to sap_context structure
2708  * @ch_info_params: Pointer to the sap_sel_ch_info structure
2709  * @operating_band: Operating Band
2710  * @domain: Regulatory domain
2711  * @bw: Bandwidth
2712  *
2713  * Return: NULL
2714  */
sap_sort_chl_weight_all(struct mac_context * mac_ctx,struct sap_context * sap_ctx,struct sap_sel_ch_info * ch_info_params,uint32_t operating_band,v_REGDOMAIN_t domain,enum phy_ch_width * bw)2715 static void sap_sort_chl_weight_all(struct mac_context *mac_ctx,
2716 				    struct sap_context *sap_ctx,
2717 				    struct sap_sel_ch_info *ch_info_params,
2718 				    uint32_t operating_band,
2719 				    v_REGDOMAIN_t domain,
2720 				    enum phy_ch_width *bw)
2721 {
2722 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2723 	enum phy_ch_width ch_width = *bw;
2724 
2725 next_bw:
2726 	switch (ch_width) {
2727 	case CH_WIDTH_40MHZ:
2728 		/*
2729 		 * Assign max weight to all 5Ghz channels when operating band
2730 		 * is 11g and to all 2.4Ghz channels when operating band is 11a
2731 		 * or 11abg to avoid selection in ACS algorithm for starting SAP
2732 		 */
2733 		if (eCSR_DOT11_MODE_11g == operating_band) {
2734 			sap_allocate_max_weight_40_mhz(ch_info_params);
2735 			sap_sort_chl_weight_ht40_24_g(
2736 					mac_ctx,
2737 					ch_info_params,
2738 					domain);
2739 		} else {
2740 			sap_allocate_max_weight_40_mhz_24_g(ch_info_params);
2741 			status = sap_sort_chl_weight_40_mhz(mac_ctx,
2742 							    sap_ctx,
2743 							    ch_info_params);
2744 		}
2745 		break;
2746 	case CH_WIDTH_80MHZ:
2747 	case CH_WIDTH_80P80MHZ:
2748 		status = sap_sort_chl_weight_80_mhz(mac_ctx,
2749 						    sap_ctx,
2750 						    ch_info_params);
2751 		break;
2752 	case CH_WIDTH_160MHZ:
2753 		status = sap_sort_chl_weight_160_mhz(mac_ctx,
2754 						     sap_ctx,
2755 						     ch_info_params);
2756 		break;
2757 #if defined(WLAN_FEATURE_11BE)
2758 	case CH_WIDTH_320MHZ:
2759 		status = sap_sort_chl_weight_320_mhz(mac_ctx,
2760 						     sap_ctx,
2761 						     ch_info_params);
2762 		break;
2763 #endif
2764 	case CH_WIDTH_20MHZ:
2765 	default:
2766 		/* Sorting the channels as per weights as 20MHz channels */
2767 		sap_sort_chl_weight(ch_info_params);
2768 		status = QDF_STATUS_SUCCESS;
2769 	}
2770 
2771 	if (status != QDF_STATUS_SUCCESS) {
2772 		ch_width = wlan_reg_get_next_lower_bandwidth(ch_width);
2773 		sap_restore_chan_weight(ch_info_params);
2774 		goto next_bw;
2775 	}
2776 
2777 	if (ch_width != *bw) {
2778 		sap_info("channel width change from %d to %d", *bw, ch_width);
2779 		*bw = ch_width;
2780 	}
2781 }
2782 
2783 /**
2784  * sap_is_ch_non_overlap() - returns true if non-overlapping channel
2785  * @sap_ctx: Sap context
2786  * @ch: channel number
2787  *
2788  * Returns: true if non-overlapping (1, 6, 11) channel, false otherwise
2789  */
sap_is_ch_non_overlap(struct sap_context * sap_ctx,uint16_t ch)2790 static bool sap_is_ch_non_overlap(struct sap_context *sap_ctx, uint16_t ch)
2791 {
2792 	if (sap_ctx->enableOverLapCh)
2793 		return true;
2794 
2795 	if ((ch == CHANNEL_1) || (ch == CHANNEL_6) || (ch == CHANNEL_11))
2796 		return true;
2797 
2798 	return false;
2799 }
2800 
2801 static enum phy_ch_width
sap_acs_next_lower_bandwidth(enum phy_ch_width ch_width)2802 sap_acs_next_lower_bandwidth(enum phy_ch_width ch_width)
2803 {
2804 	if (ch_width <= CH_WIDTH_20MHZ ||
2805 	    ch_width == CH_WIDTH_5MHZ ||
2806 	    ch_width == CH_WIDTH_10MHZ ||
2807 	    ch_width >= CH_WIDTH_INVALID)
2808 		return CH_WIDTH_INVALID;
2809 
2810 	return wlan_reg_get_next_lower_bandwidth(ch_width);
2811 }
2812 
sap_sort_channel_list(struct mac_context * mac_ctx,uint8_t vdev_id,qdf_list_t * ch_list,struct sap_sel_ch_info * ch_info,v_REGDOMAIN_t * domain,uint32_t * operating_band)2813 void sap_sort_channel_list(struct mac_context *mac_ctx, uint8_t vdev_id,
2814 			   qdf_list_t *ch_list, struct sap_sel_ch_info *ch_info,
2815 			   v_REGDOMAIN_t *domain, uint32_t *operating_band)
2816 {
2817 	uint8_t country[CDS_COUNTRY_CODE_LEN + 1];
2818 	struct sap_context *sap_ctx;
2819 	enum phy_ch_width cur_bw;
2820 	v_REGDOMAIN_t reg_domain;
2821 	uint32_t op_band;
2822 
2823 	sap_ctx = mac_ctx->sap.sapCtxList[vdev_id].sap_context;
2824 	cur_bw = sap_ctx->acs_cfg->ch_width;
2825 
2826 	/* Initialize the structure pointed by spect_info */
2827 	if (!sap_chan_sel_init(mac_ctx, ch_info, sap_ctx, false)) {
2828 		sap_err("vdev %d ch select initialization failed", vdev_id);
2829 		return;
2830 	}
2831 
2832 	/* Compute the weight of the entire spectrum in the operating band */
2833 	sap_compute_spect_weight(ch_info, mac_ctx, ch_list, sap_ctx);
2834 
2835 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2836 	/* process avoid channel IE to collect all channels to avoid */
2837 	sap_process_avoid_ie(mac_ctx, sap_ctx, ch_list, ch_info);
2838 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2839 
2840 	wlan_reg_read_current_country(mac_ctx->psoc, country);
2841 	wlan_reg_get_domain_from_country_code(&reg_domain, country,
2842 					      SOURCE_DRIVER);
2843 
2844 	SET_ACS_BAND(op_band, sap_ctx);
2845 
2846 	/* Sort the ch lst as per the computed weights, lesser weight first. */
2847 	sap_sort_chl_weight_all(mac_ctx, sap_ctx, ch_info, op_band,
2848 				reg_domain, &cur_bw);
2849 	sap_ctx->acs_cfg->ch_width = cur_bw;
2850 
2851 	if (domain)
2852 		*domain = reg_domain;
2853 	if (operating_band)
2854 		*operating_band = op_band;
2855 }
2856 
sap_select_channel(mac_handle_t mac_handle,struct sap_context * sap_ctx,qdf_list_t * scan_list)2857 uint32_t sap_select_channel(mac_handle_t mac_handle,
2858 			    struct sap_context *sap_ctx,
2859 			    qdf_list_t *scan_list)
2860 {
2861 	/* DFS param object holding all the data req by the algo */
2862 	struct sap_sel_ch_info spect_info_obj = { NULL, 0 };
2863 	struct sap_sel_ch_info *spect_info = &spect_info_obj;
2864 	uint8_t best_ch_num = SAP_CHANNEL_NOT_SELECTED;
2865 	uint32_t best_ch_weight = SAP_ACS_WEIGHT_MAX;
2866 	uint32_t ht40plus2gendch = 0;
2867 	v_REGDOMAIN_t domain;
2868 	uint8_t count;
2869 	uint32_t operating_band = 0;
2870 	struct mac_context *mac_ctx;
2871 	uint32_t best_chan_freq = 0;
2872 
2873 	mac_ctx = MAC_CONTEXT(mac_handle);
2874 
2875 	sap_sort_channel_list(mac_ctx, sap_ctx->vdev_id, scan_list,
2876 			      spect_info, &domain, &operating_band);
2877 
2878 	/*Loop till get the best channel in the given range */
2879 	for (count = 0; count < spect_info->num_ch; count++) {
2880 		if (!spect_info->ch_info[count].valid)
2881 			continue;
2882 
2883 		best_chan_freq = spect_info->ch_info[count].chan_freq;
2884 		/* check if best_ch_num is in preferred channel list */
2885 		best_chan_freq =
2886 			sap_select_preferred_channel_from_channel_list(
2887 				best_chan_freq, sap_ctx, spect_info);
2888 		/* if not in preferred ch lst, go to nxt best ch */
2889 		if (best_chan_freq == SAP_CHANNEL_NOT_SELECTED)
2890 			continue;
2891 
2892 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2893 		/*
2894 		 * Weight of the channels(device's AP is operating)
2895 		 * increased to MAX+1 so that they will be chosen only
2896 		 * when there is no other best channel to choose
2897 		 */
2898 		if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(best_chan_freq) &&
2899 		    sap_check_in_avoid_ch_list(sap_ctx,
2900 		    wlan_reg_freq_to_chan(mac_ctx->pdev, best_chan_freq))) {
2901 			best_chan_freq = SAP_CHANNEL_NOT_SELECTED;
2902 			continue;
2903 		}
2904 #endif
2905 
2906 		/* Give preference to Non-overlap channels */
2907 		if (WLAN_REG_IS_24GHZ_CH_FREQ(best_chan_freq) &&
2908 		    !sap_is_ch_non_overlap(sap_ctx,
2909 		    wlan_reg_freq_to_chan(mac_ctx->pdev, best_chan_freq))) {
2910 			sap_debug("freq %d is overlapping, skipped",
2911 				  best_chan_freq);
2912 			continue;
2913 		}
2914 
2915 		best_ch_weight = spect_info->ch_info[count].weight;
2916 		sap_debug("Freq = %d selected as best frequency weight = %d",
2917 			  best_chan_freq, best_ch_weight);
2918 
2919 		break;
2920 	}
2921 
2922 	/*
2923 	 * in case the best channel selected is not in PCL and there is another
2924 	 * channel which has same weightage and is in PCL, choose the one in
2925 	 * PCL
2926 	 */
2927 	if (!ch_in_pcl(sap_ctx, best_chan_freq)) {
2928 		uint32_t cal_chan_freq, cal_chan_weight;
2929 
2930 		enum phy_ch_width pref_bw = sap_ctx->acs_cfg->ch_width;
2931 next_bw:
2932 		sap_debug("check bw %d", pref_bw);
2933 		for (count = 0; count < spect_info->num_ch; count++) {
2934 			struct ch_params ch_params = {0};
2935 
2936 			if (!spect_info->ch_info[count].valid)
2937 				continue;
2938 
2939 			cal_chan_freq = spect_info->ch_info[count].chan_freq;
2940 			cal_chan_weight = spect_info->ch_info[count].weight;
2941 			/* skip pcl channel whose weight is bigger than best */
2942 			if (!ch_in_pcl(sap_ctx, cal_chan_freq) ||
2943 			    (cal_chan_weight > best_ch_weight))
2944 				continue;
2945 
2946 			if (best_chan_freq == cal_chan_freq)
2947 				continue;
2948 
2949 			if (sap_select_preferred_channel_from_channel_list(
2950 				cal_chan_freq, sap_ctx,
2951 				spect_info)
2952 				== SAP_CHANNEL_NOT_SELECTED)
2953 				continue;
2954 			ch_params.ch_width = pref_bw;
2955 			sap_acs_set_puncture_support(sap_ctx, &ch_params);
2956 			wlan_reg_set_channel_params_for_pwrmode(
2957 				mac_ctx->pdev, cal_chan_freq, 0, &ch_params,
2958 				REG_CURRENT_PWR_MODE);
2959 			if (ch_params.ch_width != pref_bw)
2960 				continue;
2961 			best_chan_freq = cal_chan_freq;
2962 			sap_ctx->acs_cfg->ch_width = pref_bw;
2963 			sap_debug("Changed best freq to %d Preferred freq bw %d",
2964 				  best_chan_freq, pref_bw);
2965 			break;
2966 		}
2967 		if (count == spect_info->num_ch) {
2968 			pref_bw = sap_acs_next_lower_bandwidth(pref_bw);
2969 			if (pref_bw != CH_WIDTH_INVALID)
2970 				goto next_bw;
2971 		}
2972 	}
2973 
2974 	sap_ctx->acs_cfg->pri_ch_freq = best_chan_freq;
2975 
2976 	/* Below code is for 2.4Ghz freq, so freq to channel is safe here */
2977 
2978 	/* determine secondary channel for 2.4G channel 5, 6, 7 in HT40 */
2979 	if ((operating_band != eCSR_DOT11_MODE_11g) ||
2980 	    (sap_ctx->acs_cfg->ch_width != CH_WIDTH_40MHZ))
2981 		goto sap_ch_sel_end;
2982 
2983 	best_ch_num = wlan_reg_freq_to_chan(mac_ctx->pdev, best_chan_freq);
2984 
2985 	if (REGDOMAIN_FCC == domain)
2986 		ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
2987 	else
2988 		ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
2989 	if ((best_ch_num >= HT40MINUS_2G_CH_START) &&
2990 			(best_ch_num <= ht40plus2gendch)) {
2991 		int weight_below, weight_above, i;
2992 		struct sap_ch_info *pspect_info;
2993 
2994 		weight_below = weight_above = SAP_ACS_WEIGHT_MAX;
2995 		pspect_info = spect_info->ch_info;
2996 		for (i = 0; i < spect_info->num_ch; i++) {
2997 			if (pspect_info[i].chan_freq == (best_chan_freq - 20))
2998 				weight_below = pspect_info[i].weight;
2999 			if (pspect_info[i].chan_freq == (best_ch_num + 20))
3000 				weight_above = pspect_info[i].weight;
3001 		}
3002 
3003 		if (weight_below < weight_above)
3004 			sap_ctx->acs_cfg->ht_sec_ch_freq =
3005 					sap_ctx->acs_cfg->pri_ch_freq - 20;
3006 		else
3007 			sap_ctx->acs_cfg->ht_sec_ch_freq =
3008 					sap_ctx->acs_cfg->pri_ch_freq + 20;
3009 	} else if (best_ch_num >= 1 && best_ch_num <= 4) {
3010 		sap_ctx->acs_cfg->ht_sec_ch_freq =
3011 					sap_ctx->acs_cfg->pri_ch_freq + 20;
3012 	} else if (best_ch_num >= ht40plus2gendch && best_ch_num <=
3013 			HT40MINUS_2G_CH_END) {
3014 		sap_ctx->acs_cfg->ht_sec_ch_freq =
3015 					sap_ctx->acs_cfg->pri_ch_freq - 20;
3016 	} else if (best_ch_num == 14) {
3017 		sap_ctx->acs_cfg->ht_sec_ch_freq = 0;
3018 	}
3019 	sap_ctx->sec_ch_freq = sap_ctx->acs_cfg->ht_sec_ch_freq;
3020 
3021 sap_ch_sel_end:
3022 	/* Free all the allocated memory */
3023 	sap_chan_sel_exit(spect_info);
3024 
3025 	return best_chan_freq;
3026 }
3027 
3028 #ifdef CONFIG_AFC_SUPPORT
3029 /**
3030  * sap_max_weight_invalidate_2ghz_channels() - Invalidate 2 GHz channel and set
3031  *                                             max channel weight
3032  * @spect_info: pointer to array of channel spectrum info
3033  *
3034  * Return: None
3035  */
3036 static void
sap_max_weight_invalidate_2ghz_channels(struct sap_sel_ch_info * spect_info)3037 sap_max_weight_invalidate_2ghz_channels(struct sap_sel_ch_info *spect_info)
3038 {
3039 	uint32_t i;
3040 	struct sap_ch_info *spect_ch;
3041 
3042 	spect_ch = spect_info->ch_info;
3043 	for (i = 0; i < spect_info->num_ch; i++) {
3044 		if (WLAN_REG_IS_24GHZ_CH_FREQ(spect_ch[i].chan_freq)) {
3045 			spect_ch[i].weight = SAP_ACS_WEIGHT_MAX;
3046 			spect_ch[i].valid = false;
3047 		}
3048 	}
3049 }
3050 
3051 /**
3052  * sap_compute_spect_max_power_weight() - Compute channel weight use max power
3053  *                                        factor
3054  * @spect_info: pointer to SAP channel select structure of spectrum info
3055  * @mac: mac context
3056  * @sap_ctx: pointer to SAP context
3057  *
3058  * Return: None
3059  */
3060 static void
sap_compute_spect_max_power_weight(struct sap_sel_ch_info * spect_info,struct mac_context * mac,struct sap_context * sap_ctx)3061 sap_compute_spect_max_power_weight(struct sap_sel_ch_info *spect_info,
3062 				   struct mac_context *mac,
3063 				   struct sap_context *sap_ctx)
3064 {
3065 	uint32_t i;
3066 	struct sap_ch_info *spect_ch = spect_info->ch_info;
3067 
3068 	for (i = 0; i < spect_info->num_ch; i++) {
3069 		if (spect_ch[i].weight == SAP_ACS_WEIGHT_MAX) {
3070 			spect_ch[i].weight_copy = spect_ch[i].weight;
3071 			continue;
3072 		}
3073 		spect_ch[i].weight = SAPDFS_NORMALISE_1000 *
3074 			sap_weight_channel_reg_max_power(sap_ctx,
3075 							 spect_ch[i].chan_freq);
3076 
3077 		sap_normalize_channel_weight_with_factors(mac, &spect_ch[i]);
3078 
3079 		if (spect_ch[i].weight > SAP_ACS_WEIGHT_MAX)
3080 			spect_ch[i].weight = SAP_ACS_WEIGHT_MAX;
3081 		spect_ch[i].weight_copy = spect_ch[i].weight;
3082 
3083 		sap_debug("freq = %d, weight = %d",
3084 			  spect_ch[i].chan_freq, spect_ch[i].weight);
3085 	}
3086 }
3087 
3088 /**
3089  * sap_afc_dcs_target_chan() - Select best channel frequency from sorted list
3090  * @mac_ctx: pointer to mac context
3091  * @sap_ctx: pointer to SAP context
3092  * @spect_info: pointer to SAP channel select structure of spectrum info
3093  * @cur_freq: SAP current home channel frequency
3094  * @cur_bw: SAP current channel bandwidth
3095  * @pref_bw: SAP target channel bandwidth can switch to
3096  *
3097  * Return: Best home channel frequency, if no available channel return 0.
3098  */
3099 static qdf_freq_t
sap_afc_dcs_target_chan(struct mac_context * mac_ctx,struct sap_context * sap_ctx,struct sap_sel_ch_info * spect_info,qdf_freq_t cur_freq,enum phy_ch_width cur_bw,enum phy_ch_width pref_bw)3100 sap_afc_dcs_target_chan(struct mac_context *mac_ctx,
3101 			struct sap_context *sap_ctx,
3102 			struct sap_sel_ch_info *spect_info,
3103 			qdf_freq_t cur_freq,
3104 			enum phy_ch_width cur_bw,
3105 			enum phy_ch_width pref_bw)
3106 {
3107 	uint32_t i, best_weight;
3108 	qdf_freq_t best_chan_freq;
3109 	struct sap_ch_info *spect_ch = spect_info->ch_info;
3110 
3111 	best_weight = spect_ch[0].weight;
3112 	best_chan_freq = spect_ch[0].chan_freq;
3113 
3114 	/*
3115 	 * If current channel is already best channel and no bandwidth
3116 	 * change, return the current channel so no channel switch happen.
3117 	 */
3118 	if (cur_bw == pref_bw) {
3119 		for (i = 1; i < spect_info->num_ch; i++) {
3120 			if (!spect_ch[i].valid)
3121 				continue;
3122 			if (spect_ch[i].weight <= best_weight) {
3123 				sap_debug("best freq = %d, weight = %d",
3124 					  spect_ch[i].chan_freq,
3125 					  spect_ch[i].weight);
3126 				if (spect_ch[i].chan_freq == cur_freq)
3127 					return cur_freq;
3128 			}
3129 		}
3130 	}
3131 
3132 	return best_chan_freq;
3133 }
3134 
3135 #ifdef WLAN_FEATURE_AFC_DCS_SKIP_ACS_RANGE
3136 /**
3137  * is_sap_afc_dcs_skip_acs() - API to get whether to skip ACS range
3138  * when doing automatically channel selection for AFC DCS.
3139  * @sap_ctx: SAP context pointer
3140  *
3141  * Return: True if skip ACS range and can select channel out of it.
3142  */
is_sap_afc_dcs_skip_acs(struct sap_context * sap_ctx)3143 static bool is_sap_afc_dcs_skip_acs(struct sap_context *sap_ctx)
3144 {
3145 	struct sap_acs_cfg *acs_cfg;
3146 	uint32_t i;
3147 
3148 	if (!sap_ctx || !sap_ctx->acs_cfg)
3149 		return false;
3150 
3151 	acs_cfg = sap_ctx->acs_cfg;
3152 	for (i = 0; i < acs_cfg->ch_list_count; i++) {
3153 		if (WLAN_REG_IS_6GHZ_CHAN_FREQ(acs_cfg->freq_list[i]))
3154 			return false;
3155 	}
3156 	return true;
3157 }
3158 #else
is_sap_afc_dcs_skip_acs(struct sap_context * sap_ctx)3159 static bool is_sap_afc_dcs_skip_acs(struct sap_context *sap_ctx)
3160 {
3161 	return false;
3162 }
3163 #endif
3164 
sap_afc_dcs_sel_chan(struct sap_context * sap_ctx,qdf_freq_t cur_freq,enum phy_ch_width cur_bw,enum phy_ch_width * pref_bw)3165 qdf_freq_t sap_afc_dcs_sel_chan(struct sap_context *sap_ctx,
3166 				qdf_freq_t cur_freq,
3167 				enum phy_ch_width cur_bw,
3168 				enum phy_ch_width *pref_bw)
3169 {
3170 	struct mac_context *mac_ctx;
3171 	mac_handle_t mac_handle;
3172 	struct sap_sel_ch_info spect_info_obj = {NULL, 0};
3173 	struct sap_sel_ch_info *spect_info = &spect_info_obj;
3174 	qdf_freq_t target_freq;
3175 
3176 	if (!sap_ctx || !pref_bw)
3177 		return SAP_CHANNEL_NOT_SELECTED;
3178 
3179 	if (!sap_ctx->acs_cfg || !sap_ctx->acs_cfg->acs_mode) {
3180 		sap_debug("SAP session id %d acs not enable",
3181 			  sap_ctx->sessionId);
3182 		return SAP_CHANNEL_NOT_SELECTED;
3183 	}
3184 
3185 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
3186 	mac_ctx = MAC_CONTEXT(mac_handle);
3187 	if (!mac_ctx)
3188 		return SAP_CHANNEL_NOT_SELECTED;
3189 
3190 	/*
3191 	 * If AFC response received after SAP started, SP channels are
3192 	 * not included in current ACS range, ignore ACS range check
3193 	 * in this scenario so that SAP can move to new SP channel.
3194 	 */
3195 	sap_chan_sel_init(mac_ctx, spect_info, sap_ctx,
3196 			  is_sap_afc_dcs_skip_acs(sap_ctx));
3197 
3198 	sap_max_weight_invalidate_2ghz_channels(spect_info);
3199 
3200 	sap_compute_spect_max_power_weight(spect_info, mac_ctx, sap_ctx);
3201 
3202 	sap_sort_chl_weight_all(mac_ctx, sap_ctx, spect_info,
3203 				eCSR_DOT11_MODE_11a, REGDOMAIN_FCC, pref_bw);
3204 
3205 	target_freq = sap_afc_dcs_target_chan(mac_ctx,
3206 					      sap_ctx,
3207 					      spect_info,
3208 					      cur_freq,
3209 					      cur_bw,
3210 					      *pref_bw);
3211 	sap_chan_sel_exit(spect_info);
3212 	return target_freq;
3213 }
3214 #endif
3215