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