1 /*
2  * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /*
21  * DOC: csr_api_scan.c
22  *
23  * Implementation for the Common Scan interfaces.
24  */
25 
26 #include "ani_global.h"
27 
28 #include "csr_inside_api.h"
29 #include "sme_inside.h"
30 
31 #include "csr_support.h"
32 
33 #include "host_diag_core_log.h"
34 #include "host_diag_core_event.h"
35 
36 #include "cds_reg_service.h"
37 #include "wma_types.h"
38 #include "cds_utils.h"
39 #include "wma.h"
40 
41 #include "wlan_policy_mgr_api.h"
42 #include "wlan_hdd_main.h"
43 #include "pld_common.h"
44 #include "csr_internal.h"
45 #include <wlan_scan_api.h>
46 #include <wlan_scan_api.h>
47 #include <wlan_scan_utils_api.h>
48 #include <wlan_objmgr_vdev_obj.h>
49 #include <wlan_objmgr_pdev_obj.h>
50 #include <wlan_utility.h>
51 #include "wlan_reg_services_api.h"
52 #include "sch_api.h"
53 #include "wlan_dlm_api.h"
54 #include "qdf_crypto.h"
55 #include <wlan_crypto_global_api.h>
56 #include "wlan_reg_ucfg_api.h"
57 #include "wlan_cm_bss_score_param.h"
58 
59 static void csr_set_cfg_valid_channel_list(struct mac_context *mac,
60 					   uint32_t *pchan_freq_list,
61 					   uint8_t NumChannels);
62 
63 static void csr_save_tx_power_to_cfg(struct mac_context *mac,
64 				     tDblLinkList *pList,
65 				     uint32_t cfgId);
66 
67 static void csr_purge_channel_power(struct mac_context *mac,
68 				    tDblLinkList *pChannelList);
69 
70 /* pResult is invalid calling this function. */
csr_free_scan_result_entry(struct mac_context * mac,struct tag_csrscan_result * pResult)71 void csr_free_scan_result_entry(struct mac_context *mac,
72 				struct tag_csrscan_result *pResult)
73 {
74 	if (pResult->Result.pvIes)
75 		qdf_mem_free(pResult->Result.pvIes);
76 
77 	qdf_mem_free(pResult);
78 }
79 
csr_ll_scan_purge_result(struct mac_context * mac,tDblLinkList * pList)80 static QDF_STATUS csr_ll_scan_purge_result(struct mac_context *mac,
81 					   tDblLinkList *pList)
82 {
83 	QDF_STATUS status = QDF_STATUS_SUCCESS;
84 	tListElem *pEntry;
85 	struct tag_csrscan_result *bss_desc;
86 
87 	while ((pEntry = csr_ll_remove_head(pList, LL_ACCESS_NOLOCK)) != NULL) {
88 		bss_desc = GET_BASE_ADDR(pEntry, struct tag_csrscan_result,
89 					 Link);
90 		csr_free_scan_result_entry(mac, bss_desc);
91 	}
92 
93 	return status;
94 }
95 
csr_scan_open(struct mac_context * mac_ctx)96 QDF_STATUS csr_scan_open(struct mac_context *mac_ctx)
97 {
98 	csr_ll_open(&mac_ctx->scan.channelPowerInfoList24);
99 	csr_ll_open(&mac_ctx->scan.channelPowerInfoList5G);
100 
101 	return QDF_STATUS_SUCCESS;
102 }
103 
csr_scan_close(struct mac_context * mac)104 QDF_STATUS csr_scan_close(struct mac_context *mac)
105 {
106 	csr_purge_channel_power(mac, &mac->scan.channelPowerInfoList24);
107 	csr_purge_channel_power(mac, &mac->scan.channelPowerInfoList5G);
108 	csr_ll_close(&mac->scan.channelPowerInfoList24);
109 	csr_ll_close(&mac->scan.channelPowerInfoList5G);
110 	wlan_scan_psoc_set_disable(mac->psoc, REASON_SYSTEM_DOWN);
111 
112 	return QDF_STATUS_SUCCESS;
113 }
114 
csr_scan_result_purge(struct mac_context * mac,tScanResultHandle hScanList)115 QDF_STATUS csr_scan_result_purge(struct mac_context *mac,
116 				 tScanResultHandle hScanList)
117 {
118 	QDF_STATUS status = QDF_STATUS_E_INVAL;
119 	struct scan_result_list *pScanList =
120 				(struct scan_result_list *) hScanList;
121 
122 	if (pScanList) {
123 		status = csr_ll_scan_purge_result(mac, &pScanList->List);
124 		csr_ll_close(&pScanList->List);
125 		qdf_mem_free(pScanList);
126 	}
127 	return status;
128 }
129 
csr_purge_channel_power(struct mac_context * mac,tDblLinkList * pChannelList)130 static void csr_purge_channel_power(struct mac_context *mac,
131 				    tDblLinkList *pChannelList)
132 {
133 	struct csr_channel_powerinfo *pChannelSet;
134 	tListElem *pEntry;
135 
136 	/*
137 	 * Remove the channel sets from the learned list and put them
138 	 * in the free list
139 	 */
140 	csr_ll_lock(pChannelList);
141 	while ((pEntry = csr_ll_remove_head(pChannelList,
142 					    LL_ACCESS_NOLOCK)) != NULL) {
143 		pChannelSet = GET_BASE_ADDR(pEntry,
144 					struct csr_channel_powerinfo, link);
145 		if (pChannelSet)
146 			qdf_mem_free(pChannelSet);
147 	}
148 	csr_ll_unlock(pChannelList);
149 }
150 
151 #define FREQ_SIZE 4
152 #define SPACE_SIZE 2
153 #define SIZEOFNULL 1
154 #define BUF24GHZSIZE (NUM_24GHZ_CHANNELS * (\
155 					FREQ_SIZE + SPACE_SIZE) + SIZEOFNULL)
156 #define BUF5GHZSIZE (NUM_5GHZ_CHANNELS * (\
157 					FREQ_SIZE + SPACE_SIZE) + SIZEOFNULL)
158 
159 /*
160  * Save the channelList into the ultimate storage as the final stage of channel
161  * Input: pCountryInfo -- the country code (e.g. "USI"), channel list, and power
162  * limit are all stored inside this data structure
163  */
csr_save_to_channel_power2_g_5_g(struct mac_context * mac,uint32_t tableSize,struct pwr_channel_info * channelTable)164 QDF_STATUS csr_save_to_channel_power2_g_5_g(struct mac_context *mac,
165 					    uint32_t tableSize,
166 					    struct pwr_channel_info *channelTable)
167 {
168 	uint32_t i = tableSize / sizeof(struct pwr_channel_info);
169 	struct pwr_channel_info *pChannelInfo;
170 	struct csr_channel_powerinfo *pchannelset;
171 	bool f2GHzInfoFound = false;
172 	bool f2GListPurged = false, f5GListPurged = false;
173 	uint8_t *buf24ghz = qdf_mem_malloc(BUF24GHZSIZE);
174 	uint8_t *buf5ghz = qdf_mem_malloc(BUF5GHZSIZE);
175 	uint32_t size24ghz = 0, size5ghz = 0;
176 
177 	if (!buf24ghz || !buf5ghz) {
178 		if (buf24ghz)
179 			qdf_mem_free(buf24ghz);
180 		if (buf5ghz)
181 			qdf_mem_free(buf5ghz);
182 		return QDF_STATUS_E_NOMEM;
183 	}
184 	pChannelInfo = channelTable;
185 	/* atleast 3 bytes have to be remaining  -- from "countryString" */
186 	while (i--) {
187 	pchannelset = qdf_mem_malloc(sizeof(struct csr_channel_powerinfo));
188 		if (!pchannelset) {
189 			pChannelInfo++;
190 			continue;
191 		}
192 		pchannelset->first_chan_freq = pChannelInfo->first_freq;
193 		pchannelset->numChannels = pChannelInfo->num_chan;
194 		/*
195 		 * Now set the inter-channel offset based on the frequency band
196 		 * the channel set lies in
197 		 */
198 		if (WLAN_REG_IS_24GHZ_CH_FREQ(pchannelset->first_chan_freq) &&
199 		    (pchannelset->first_chan_freq + 5 * (pchannelset->numChannels - 1) <=
200 		     WLAN_REG_MAX_24GHZ_CHAN_FREQ)) {
201 			pchannelset->interChannelOffset = 5;
202 			f2GHzInfoFound = true;
203 		} else if (WLAN_REG_IS_5GHZ_CH_FREQ(pchannelset->first_chan_freq) &&
204 			   (pchannelset->first_chan_freq + 20 * (pchannelset->numChannels - 1) <=
205 			   WLAN_REG_MAX_5GHZ_CHAN_FREQ)) {
206 			pchannelset->interChannelOffset = 20;
207 			f2GHzInfoFound = false;
208 		} else {
209 			sme_warn("Invalid Channel freq %d Present in Country IE",
210 				 pchannelset->first_chan_freq);
211 			qdf_mem_free(pchannelset);
212 			qdf_mem_free(buf24ghz);
213 			qdf_mem_free(buf5ghz);
214 			return QDF_STATUS_E_FAILURE;
215 		}
216 		pchannelset->txPower = pChannelInfo->max_tx_pwr;
217 		if (f2GHzInfoFound) {
218 			if (!f2GListPurged) {
219 				/* purge previous results if found new */
220 				csr_purge_channel_power(mac,
221 							&mac->scan.
222 							channelPowerInfoList24);
223 				f2GListPurged = true;
224 			}
225 			if (CSR_IS_OPERATING_BG_BAND(mac)) {
226 				/* add to the list of 2.4 GHz channel sets */
227 				csr_ll_insert_tail(&mac->scan.
228 						   channelPowerInfoList24,
229 						   &pchannelset->link,
230 						   LL_ACCESS_LOCK);
231 			} else {
232 				size24ghz += qdf_scnprintf(
233 					buf24ghz + size24ghz,
234 					BUF24GHZSIZE - size24ghz, "  %d",
235 					pchannelset->first_chan_freq);
236 				qdf_mem_free(pchannelset);
237 			}
238 		} else {
239 			/* 5GHz info found */
240 			if (!f5GListPurged) {
241 				/* purge previous results if found new */
242 				csr_purge_channel_power(mac,
243 							&mac->scan.
244 							channelPowerInfoList5G);
245 				f5GListPurged = true;
246 			}
247 			if (CSR_IS_OPERATING_A_BAND(mac)) {
248 				/* add to the list of 5GHz channel sets */
249 				csr_ll_insert_tail(&mac->scan.
250 						   channelPowerInfoList5G,
251 						   &pchannelset->link,
252 						   LL_ACCESS_LOCK);
253 			} else {
254 				size5ghz += qdf_scnprintf(
255 						buf5ghz + size5ghz,
256 						BUF5GHZSIZE - size5ghz, "  %d",
257 						pchannelset->first_chan_freq);
258 				qdf_mem_free(pchannelset);
259 			}
260 		}
261 		pChannelInfo++; /* move to next entry */
262 	}
263 	if (size24ghz)
264 		sme_nofl_debug("Adding 11B/G ch in 11A:%s", buf24ghz);
265 	qdf_mem_free(buf24ghz);
266 	if (size5ghz)
267 		sme_nofl_debug("Adding 11A ch in B/G:%s", buf5ghz);
268 	qdf_mem_free(buf5ghz);
269 	return QDF_STATUS_SUCCESS;
270 }
csr_apply_power2_current(struct mac_context * mac)271 void csr_apply_power2_current(struct mac_context *mac)
272 {
273 	sme_debug("Updating Cfg with power settings");
274 	csr_save_tx_power_to_cfg(mac, &mac->scan.channelPowerInfoList24,
275 				 BAND_2G);
276 	csr_save_tx_power_to_cfg(mac, &mac->scan.channelPowerInfoList5G,
277 				 BAND_5G);
278 }
279 
csr_apply_channel_power_info_to_fw(struct mac_context * mac_ctx,struct csr_channel * ch_lst)280 void csr_apply_channel_power_info_to_fw(struct mac_context *mac_ctx,
281 					struct csr_channel *ch_lst)
282 {
283 	int i;
284 	uint8_t num_ch = 0;
285 	uint8_t tempNumChannels = 0;
286 	struct csr_channel tmp_ch_lst;
287 
288 	if (ch_lst->numChannels) {
289 		tempNumChannels = QDF_MIN(ch_lst->numChannels,
290 					  CFG_VALID_CHANNEL_LIST_LEN);
291 		for (i = 0; i < tempNumChannels; i++) {
292 			tmp_ch_lst.channel_freq_list[num_ch] = ch_lst->channel_freq_list[i];
293 			num_ch++;
294 		}
295 		tmp_ch_lst.numChannels = num_ch;
296 		/* Store the channel+power info in the global place: Cfg */
297 		csr_apply_power2_current(mac_ctx);
298 		csr_set_cfg_valid_channel_list(mac_ctx, tmp_ch_lst.channel_freq_list,
299 					       tmp_ch_lst.numChannels);
300 	} else {
301 		sme_err("11D channel list is empty");
302 	}
303 	sch_edca_profile_update_all(mac_ctx);
304 }
305 
306 #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
csr_diag_reset_country_information(struct mac_context * mac)307 static void csr_diag_reset_country_information(struct mac_context *mac)
308 {
309 
310 	host_log_802_11d_pkt_type *p11dLog;
311 	int Index;
312 	uint8_t reg_cc[REG_ALPHA2_LEN + 1];
313 
314 	WLAN_HOST_DIAG_LOG_ALLOC(p11dLog, host_log_802_11d_pkt_type,
315 				 LOG_WLAN_80211D_C);
316 	if (!p11dLog)
317 		return;
318 
319 	p11dLog->eventId = WLAN_80211D_EVENT_RESET;
320 	wlan_reg_read_current_country(mac->psoc, reg_cc);
321 	qdf_mem_copy(p11dLog->countryCode, reg_cc, 3);
322 	p11dLog->numChannel = mac->scan.base_channels.numChannels;
323 	if (p11dLog->numChannel <= HOST_LOG_MAX_NUM_CHANNEL) {
324 		for (Index = 0;
325 		     Index < mac->scan.base_channels.numChannels;
326 		     Index++) {
327 			p11dLog->Channels[Index] =
328 				wlan_reg_freq_to_chan(mac->pdev, mac->scan.base_channels.channel_freq_list[Index]);
329 			p11dLog->TxPwr[Index] =
330 				mac->scan.defaultPowerTable[Index].tx_power;
331 		}
332 	}
333 
334 	WLAN_HOST_DIAG_LOG_REPORT(p11dLog);
335 }
336 #endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
337 
338 /**
339  * csr_apply_channel_power_info_wrapper() - sends channel info to fw
340  * @mac: main MAC data structure
341  *
342  * This function sends the channel power info to firmware
343  *
344  * Return: none
345  */
csr_apply_channel_power_info_wrapper(struct mac_context * mac)346 void csr_apply_channel_power_info_wrapper(struct mac_context *mac)
347 {
348 
349 #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
350 	csr_diag_reset_country_information(mac);
351 #endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
352 	csr_prune_channel_list_for_mode(mac, &mac->scan.base_channels);
353 	csr_save_channel_power_for_band(mac, false);
354 	csr_save_channel_power_for_band(mac, true);
355 	/* apply the channel list, power settings, and the country code. */
356 	csr_apply_channel_power_info_to_fw(mac, &mac->scan.base_channels);
357 	/* clear the 11d channel list */
358 	qdf_mem_zero(&mac->scan.channels11d, sizeof(mac->scan.channels11d));
359 }
360 
csr_save_channel_power_for_band(struct mac_context * mac,bool fill_5f)361 void csr_save_channel_power_for_band(struct mac_context *mac, bool fill_5f)
362 {
363 	uint32_t idx, count = 0;
364 	struct pwr_channel_info *chan_info;
365 	struct pwr_channel_info *ch_info_start;
366 	int32_t max_ch_idx;
367 	bool tmp_bool;
368 	uint32_t ch_freq = 0;
369 
370 	max_ch_idx =
371 		(mac->scan.base_channels.numChannels <
372 		CFG_VALID_CHANNEL_LIST_LEN) ?
373 		mac->scan.base_channels.numChannels :
374 		CFG_VALID_CHANNEL_LIST_LEN;
375 
376 	chan_info = qdf_mem_malloc(sizeof(struct pwr_channel_info) *
377 				   CFG_VALID_CHANNEL_LIST_LEN);
378 	if (!chan_info)
379 		return;
380 
381 	ch_info_start = chan_info;
382 	for (idx = 0; idx < max_ch_idx; idx++) {
383 		ch_freq = mac->scan.defaultPowerTable[idx].center_freq;
384 		tmp_bool = (fill_5f && WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq)) ||
385 			(!fill_5f && WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq));
386 		if (!tmp_bool)
387 			continue;
388 
389 		if (count >= CFG_VALID_CHANNEL_LIST_LEN) {
390 			sme_warn("count: %d exceeded", count);
391 			break;
392 		}
393 
394 		chan_info->first_freq =
395 			mac->scan.defaultPowerTable[idx].center_freq;
396 		chan_info->num_chan = 1;
397 		chan_info->max_tx_pwr =
398 			mac->scan.defaultPowerTable[idx].tx_power;
399 		chan_info++;
400 		count++;
401 	}
402 	if (count) {
403 		csr_save_to_channel_power2_g_5_g(mac,
404 				count * sizeof(struct pwr_channel_info),
405 				ch_info_start);
406 	}
407 	qdf_mem_free(ch_info_start);
408 }
409 
csr_is_supported_channel(struct mac_context * mac,uint32_t chan_freq)410 bool csr_is_supported_channel(struct mac_context *mac, uint32_t chan_freq)
411 {
412 	bool fRet = false;
413 	uint32_t i;
414 
415 	for (i = 0; i < mac->scan.base_channels.numChannels; i++) {
416 		if (chan_freq == mac->scan.base_channels.channel_freq_list[i]) {
417 			fRet = true;
418 			break;
419 		}
420 	}
421 
422 	return fRet;
423 }
424 
csr_scan_result_get_first(struct mac_context * mac,tScanResultHandle hScanResult)425 tCsrScanResultInfo *csr_scan_result_get_first(struct mac_context *mac,
426 					      tScanResultHandle hScanResult)
427 {
428 	tListElem *pEntry;
429 	struct tag_csrscan_result *pResult;
430 	tCsrScanResultInfo *pRet = NULL;
431 	struct scan_result_list *pResultList =
432 				(struct scan_result_list *) hScanResult;
433 
434 	if (pResultList) {
435 		pEntry = csr_ll_peek_head(&pResultList->List, LL_ACCESS_NOLOCK);
436 		if (pEntry) {
437 			pResult = GET_BASE_ADDR(pEntry, struct
438 						tag_csrscan_result, Link);
439 			pRet = &pResult->Result;
440 		}
441 		pResultList->pCurEntry = pEntry;
442 	}
443 
444 	return pRet;
445 }
446 
csr_scan_result_get_next(struct mac_context * mac,tScanResultHandle hScanResult)447 tCsrScanResultInfo *csr_scan_result_get_next(struct mac_context *mac,
448 					     tScanResultHandle hScanResult)
449 {
450 	tListElem *pEntry = NULL;
451 	struct tag_csrscan_result *pResult = NULL;
452 	tCsrScanResultInfo *pRet = NULL;
453 	struct scan_result_list *pResultList =
454 				(struct scan_result_list *) hScanResult;
455 
456 	if (!pResultList)
457 		return NULL;
458 
459 	if (!pResultList->pCurEntry)
460 		pEntry = csr_ll_peek_head(&pResultList->List, LL_ACCESS_NOLOCK);
461 	else
462 		pEntry = csr_ll_next(&pResultList->List, pResultList->pCurEntry,
463 				     LL_ACCESS_NOLOCK);
464 
465 	if (pEntry) {
466 		pResult = GET_BASE_ADDR(pEntry, struct tag_csrscan_result,
467 					Link);
468 		pRet = &pResult->Result;
469 	}
470 	pResultList->pCurEntry = pEntry;
471 
472 	return pRet;
473 }
474 
csr_set_cfg_valid_channel_list(struct mac_context * mac,uint32_t * pchan_freq_list,uint8_t NumChannels)475 static void csr_set_cfg_valid_channel_list(struct mac_context *mac,
476 					   uint32_t *pchan_freq_list,
477 					   uint8_t NumChannels)
478 {
479 	QDF_STATUS status;
480 	uint8_t i;
481 
482 	sme_debug("dump valid channel list(NumChannels(%d))", NumChannels);
483 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
484 			   pchan_freq_list, NumChannels);
485 	for (i = 0; i < NumChannels; i++) {
486 		mac->mlme_cfg->reg.valid_channel_freq_list[i] = pchan_freq_list[i];
487 	}
488 
489 	mac->mlme_cfg->reg.valid_channel_list_num = NumChannels;
490 
491 	sme_debug("Scan offload is enabled, update default chan list");
492 	/*
493 	 * disable fcc constraint since new country code
494 	 * is being set
495 	 */
496 	mac->scan.fcc_constraint = false;
497 	status = csr_update_channel_list(mac);
498 	if (QDF_STATUS_SUCCESS != status) {
499 		sme_err("failed to update the supported channel list");
500 	}
501 }
502 
503 /*
504  * The Tx power limits are saved in the cfg for future usage.
505  */
csr_save_tx_power_to_cfg(struct mac_context * mac,tDblLinkList * pList,enum band_info band)506 static void csr_save_tx_power_to_cfg(struct mac_context *mac,
507 				     tDblLinkList *pList,
508 				     enum band_info band)
509 {
510 	tListElem *pEntry;
511 	uint32_t cbLen = 0, dataLen, tmp_len;
512 	struct csr_channel_powerinfo *ch_set;
513 	uint32_t idx, count = 0;
514 	struct pwr_channel_info *ch_pwr_set;
515 	uint8_t *p_buf = NULL;
516 
517 	/* allocate maximum space for all channels */
518 	dataLen = CFG_VALID_CHANNEL_LIST_LEN * sizeof(struct pwr_channel_info);
519 	p_buf = qdf_mem_malloc(dataLen);
520 	if (!p_buf)
521 		return;
522 
523 	ch_pwr_set = (struct pwr_channel_info *)(p_buf);
524 	csr_ll_lock(pList);
525 	pEntry = csr_ll_peek_head(pList, LL_ACCESS_NOLOCK);
526 	/*
527 	 * write the tuples (startChan, numChan, txPower) for each channel found
528 	 * in the channel power list.
529 	 */
530 	while (pEntry) {
531 		ch_set = GET_BASE_ADDR(pEntry,
532 				struct csr_channel_powerinfo, link);
533 		if (ch_set->interChannelOffset != 5) {
534 			/*
535 			 * we keep the 5G channel sets internally with an
536 			 * interchannel offset of 4. Expand these to the right
537 			 * format. (inter channel offset of 1 is the only option
538 			 * for the triplets that 11d advertises.
539 			 */
540 			tmp_len = cbLen + (ch_set->numChannels *
541 						sizeof(struct pwr_channel_info));
542 			if (tmp_len >= dataLen) {
543 				/*
544 				 * expanding this entry will overflow our
545 				 * allocation
546 				 */
547 				sme_err(
548 					"Buffer overflow, start freq %d, num %d, offset %d",
549 					ch_set->first_chan_freq,
550 					ch_set->numChannels,
551 					ch_set->interChannelOffset);
552 				break;
553 			}
554 
555 			for (idx = 0; idx < ch_set->numChannels; idx++) {
556 				ch_pwr_set->first_freq =
557 					ch_set->first_chan_freq;
558 				ch_pwr_set->num_chan = 1;
559 				ch_pwr_set->max_tx_pwr = ch_set->txPower;
560 				cbLen += sizeof(struct pwr_channel_info);
561 				ch_pwr_set++;
562 				count++;
563 			}
564 		} else {
565 			if (cbLen + sizeof(struct pwr_channel_info) >= dataLen) {
566 				/* this entry will overflow our allocation */
567 				sme_err(
568 					"Buffer overflow, start freq %d, num %d, offset %d",
569 					ch_set->first_chan_freq,
570 					ch_set->numChannels,
571 					ch_set->interChannelOffset);
572 				break;
573 			}
574 			ch_pwr_set->first_freq = ch_set->first_chan_freq;
575 			ch_pwr_set->num_chan = ch_set->numChannels;
576 			ch_pwr_set->max_tx_pwr = ch_set->txPower;
577 			cbLen += sizeof(struct pwr_channel_info);
578 			ch_pwr_set++;
579 			count++;
580 		}
581 		pEntry = csr_ll_next(pList, pEntry, LL_ACCESS_NOLOCK);
582 	}
583 	csr_ll_unlock(pList);
584 	if (band == BAND_2G) {
585 		mac->mlme_cfg->power.max_tx_power_24.len =
586 					sizeof(struct pwr_channel_info) * count;
587 		if (mac->mlme_cfg->power.max_tx_power_24.len >
588 						CFG_MAX_TX_POWER_2_4_LEN)
589 			mac->mlme_cfg->power.max_tx_power_24.len =
590 						CFG_MAX_TX_POWER_2_4_LEN;
591 		qdf_mem_copy(mac->mlme_cfg->power.max_tx_power_24.data,
592 			     (uint8_t *)p_buf,
593 			     mac->mlme_cfg->power.max_tx_power_24.len);
594 	}
595 	if (band == BAND_5G) {
596 		mac->mlme_cfg->power.max_tx_power_5.len =
597 					sizeof(struct pwr_channel_info) * count;
598 		if (mac->mlme_cfg->power.max_tx_power_5.len >
599 							CFG_MAX_TX_POWER_5_LEN)
600 			mac->mlme_cfg->power.max_tx_power_5.len =
601 							CFG_MAX_TX_POWER_5_LEN;
602 		qdf_mem_copy(mac->mlme_cfg->power.max_tx_power_5.data,
603 			     (uint8_t *)p_buf,
604 			     mac->mlme_cfg->power.max_tx_power_5.len);
605 	}
606 	qdf_mem_free(p_buf);
607 }
608 
csr_fill_rsn_auth_type(enum csr_akm_type * auth_type,uint32_t akm)609 static void csr_fill_rsn_auth_type(enum csr_akm_type *auth_type, uint32_t akm)
610 {
611 	/* Try the more preferred ones first. */
612 	if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA384))
613 		*auth_type = eCSR_AUTH_TYPE_FT_FILS_SHA384;
614 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256))
615 		*auth_type = eCSR_AUTH_TYPE_FT_FILS_SHA256;
616 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FILS_SHA384))
617 		*auth_type = eCSR_AUTH_TYPE_FILS_SHA384;
618 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FILS_SHA256))
619 		*auth_type = eCSR_AUTH_TYPE_FILS_SHA256;
620 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE_EXT_KEY))
621 		*auth_type = eCSR_AUTH_TYPE_FT_SAE_EXT_KEY;
622 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_SAE_EXT_KEY))
623 		*auth_type = eCSR_AUTH_TYPE_SAE_EXT_KEY;
624 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE))
625 		*auth_type = eCSR_AUTH_TYPE_FT_SAE;
626 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_SAE))
627 		*auth_type = eCSR_AUTH_TYPE_SAE;
628 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_DPP))
629 		*auth_type = eCSR_AUTH_TYPE_DPP_RSN;
630 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_OSEN))
631 		*auth_type = eCSR_AUTH_TYPE_OSEN;
632 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_OWE))
633 		*auth_type = eCSR_AUTH_TYPE_OWE;
634 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X))
635 		*auth_type = eCSR_AUTH_TYPE_FT_RSN;
636 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_PSK))
637 		*auth_type = eCSR_AUTH_TYPE_FT_RSN_PSK;
638 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X))
639 		*auth_type = eCSR_AUTH_TYPE_RSN;
640 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_PSK))
641 		*auth_type = eCSR_AUTH_TYPE_RSN_PSK;
642 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_CCKM))
643 		*auth_type = eCSR_AUTH_TYPE_CCKM_RSN;
644 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_PSK_SHA256))
645 		*auth_type = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
646 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256))
647 		*auth_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
648 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B))
649 		*auth_type = eCSR_AUTH_TYPE_SUITEB_EAP_SHA256;
650 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B_192))
651 		*auth_type = eCSR_AUTH_TYPE_SUITEB_EAP_SHA384;
652 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384))
653 		*auth_type = eCSR_AUTH_TYPE_FT_SUITEB_EAP_SHA384;
654 	else
655 		*auth_type = eCSR_AUTH_TYPE_NONE;
656 }
657 
csr_fill_wpa_auth_type(enum csr_akm_type * auth_type,uint32_t akm)658 static void csr_fill_wpa_auth_type(enum csr_akm_type *auth_type, uint32_t akm)
659 {
660 	/* Try the more preferred ones first. */
661 	if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X))
662 		*auth_type = eCSR_AUTH_TYPE_WPA;
663 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_PSK))
664 		*auth_type = eCSR_AUTH_TYPE_WPA_PSK;
665 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_CCKM))
666 		*auth_type = eCSR_AUTH_TYPE_CCKM_WPA;
667 	else
668 		*auth_type = eCSR_AUTH_TYPE_WPA_NONE;
669 }
670 
csr_fill_wapi_auth_type(enum csr_akm_type * auth_type,uint32_t akm)671 static void csr_fill_wapi_auth_type(enum csr_akm_type *auth_type, uint32_t akm)
672 {
673 	/* Try the more preferred ones first. */
674 	if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_WAPI_CERT))
675 		*auth_type = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
676 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_WAPI_PSK))
677 		*auth_type = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
678 	else
679 		*auth_type = eCSR_AUTH_TYPE_NONE;
680 }
681 
csr_fill_auth_type(enum csr_akm_type * auth_type,uint32_t authmodeset,uint32_t akm,uint32_t ucastcipherset)682 void csr_fill_auth_type(enum csr_akm_type *auth_type,
683 			uint32_t authmodeset, uint32_t akm,
684 			uint32_t ucastcipherset)
685 {
686 	if (!authmodeset) {
687 		*auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM;
688 		return;
689 	}
690 
691 	if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_NONE) ||
692 	    QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_OPEN)) {
693 		*auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM;
694 		return;
695 	}
696 
697 	if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_AUTO)) {
698 		if ((QDF_HAS_PARAM(ucastcipherset, WLAN_CRYPTO_CIPHER_WEP) ||
699 		     QDF_HAS_PARAM(ucastcipherset, WLAN_CRYPTO_CIPHER_WEP_40) ||
700 		     QDF_HAS_PARAM(ucastcipherset, WLAN_CRYPTO_CIPHER_WEP_104)))
701 			*auth_type = eCSR_AUTH_TYPE_AUTOSWITCH;
702 		else
703 			*auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM;
704 
705 		return;
706 	}
707 
708 	if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_SHARED)) {
709 		*auth_type = eCSR_AUTH_TYPE_SHARED_KEY;
710 		return;
711 	}
712 
713 	if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_8021X) ||
714 	    QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_RSNA) ||
715 	    QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_CCKM) ||
716 	    QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_SAE) ||
717 	    QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_FILS_SK)) {
718 		csr_fill_rsn_auth_type(auth_type, akm);
719 		return;
720 	}
721 
722 	if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_WPA)) {
723 		csr_fill_wpa_auth_type(auth_type, akm);
724 		return;
725 	}
726 
727 	if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_WAPI)) {
728 		csr_fill_wapi_auth_type(auth_type, akm);
729 		return;
730 	}
731 
732 	*auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM;
733 }
734 
csr_fill_enc_type(eCsrEncryptionType * cipher_type,uint32_t cipherset)735 void csr_fill_enc_type(eCsrEncryptionType *cipher_type, uint32_t cipherset)
736 {
737 	if (!cipherset) {
738 		*cipher_type = eCSR_ENCRYPT_TYPE_NONE;
739 		return;
740 	}
741 	if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_GCM_256))
742 		*cipher_type = eCSR_ENCRYPT_TYPE_AES_GCMP_256;
743 	else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_GCM))
744 		*cipher_type = eCSR_ENCRYPT_TYPE_AES_GCMP;
745 	else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_CCM) ||
746 		 QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_OCB) ||
747 		 QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_CCM_256))
748 		*cipher_type = eCSR_ENCRYPT_TYPE_AES;
749 	else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_TKIP))
750 		*cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
751 	else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_CMAC) ||
752 		 QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_CMAC_256))
753 		*cipher_type = eCSR_ENCRYPT_TYPE_AES_CMAC;
754 	else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_WAPI_GCM4) ||
755 		 QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_WAPI_SMS4))
756 		*cipher_type = eCSR_ENCRYPT_TYPE_WPI;
757 	else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_GMAC))
758 		*cipher_type = eCSR_ENCRYPT_TYPE_AES_GMAC_128;
759 	else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_GMAC_256))
760 		*cipher_type = eCSR_ENCRYPT_TYPE_AES_GMAC_256;
761 	else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_WEP))
762 		*cipher_type = eCSR_ENCRYPT_TYPE_WEP40;
763 	else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_WEP_40))
764 		*cipher_type = eCSR_ENCRYPT_TYPE_WEP40;
765 	else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_WEP_104))
766 		*cipher_type = eCSR_ENCRYPT_TYPE_WEP104;
767 	else
768 		*cipher_type = eCSR_ENCRYPT_TYPE_NONE;
769 }
770 
csr_fill_neg_crypto_info(struct tag_csrscan_result * bss,struct security_info * sec_info)771 static void csr_fill_neg_crypto_info(struct tag_csrscan_result *bss,
772 				     struct security_info *sec_info)
773 {
774 	if (!sec_info->authmodeset && !sec_info->key_mgmt &&
775 	    !sec_info->ucastcipherset)
776 		return;
777 
778 	csr_fill_enc_type(&bss->ucEncryptionType, sec_info->ucastcipherset);
779 	csr_fill_enc_type(&bss->mcEncryptionType, sec_info->mcastcipherset);
780 	csr_fill_auth_type(&bss->authType, sec_info->authmodeset,
781 			   sec_info->key_mgmt, sec_info->ucastcipherset);
782 	sme_debug("Authmode %x, AKM %x, Cipher Uc %x Mc %x CSR: Auth %d, Cipher Uc %d Mc %d",
783 		  sec_info->authmodeset, sec_info->key_mgmt,
784 		  sec_info->ucastcipherset, sec_info->mcastcipherset,
785 		  bss->authType, bss->ucEncryptionType, bss->mcEncryptionType);
786 }
787 
csr_fill_bss_from_scan_entry(struct mac_context * mac_ctx,struct scan_cache_entry * scan_entry,struct tag_csrscan_result ** p_result)788 static QDF_STATUS csr_fill_bss_from_scan_entry(struct mac_context *mac_ctx,
789 					struct scan_cache_entry *scan_entry,
790 					struct tag_csrscan_result **p_result)
791 {
792 	tDot11fBeaconIEs *bcn_ies;
793 	struct bss_description *bss_desc;
794 	tCsrScanResultInfo *result_info;
795 	uint8_t *ie_ptr;
796 	struct tag_csrscan_result *bss;
797 	uint32_t bss_len, alloc_len, ie_len;
798 	QDF_STATUS status;
799 	enum channel_state ap_channel_state;
800 
801 	ap_channel_state =
802 		wlan_reg_get_channel_state_for_pwrmode(
803 				mac_ctx->pdev,
804 				scan_entry->channel.chan_freq,
805 				REG_CURRENT_PWR_MODE);
806 	if (ap_channel_state == CHANNEL_STATE_DISABLE ||
807 	    ap_channel_state == CHANNEL_STATE_INVALID) {
808 		sme_err("BSS "QDF_MAC_ADDR_FMT" channel %d invalid, not populating this BSSID",
809 			QDF_MAC_ADDR_REF(scan_entry->bssid.bytes),
810 			scan_entry->channel.chan_freq);
811 		return QDF_STATUS_E_INVAL;
812 	}
813 
814 	ie_len = util_scan_entry_ie_len(scan_entry);
815 	ie_ptr = util_scan_entry_ie_data(scan_entry);
816 
817 	bss_len = (uint16_t)(offsetof(struct bss_description,
818 			   ieFields[0]) + ie_len);
819 	alloc_len = sizeof(struct tag_csrscan_result) + bss_len;
820 	bss = qdf_mem_malloc(alloc_len);
821 	if (!bss)
822 		return QDF_STATUS_E_NOMEM;
823 
824 	csr_fill_neg_crypto_info(bss, &scan_entry->neg_sec_info);
825 
826 	result_info = &bss->Result;
827 	result_info->ssId.length = scan_entry->ssid.length;
828 	qdf_mem_copy(result_info->ssId.ssId,
829 		scan_entry->ssid.ssid,
830 		result_info->ssId.length);
831 	result_info->timer = scan_entry->hidden_ssid_timestamp;
832 
833 	bss_desc = &result_info->BssDescriptor;
834 
835 	wlan_fill_bss_desc_from_scan_entry(mac_ctx, bss_desc, scan_entry);
836 
837 	status = wlan_get_parsed_bss_description_ies(mac_ctx, bss_desc,
838 						     &bcn_ies);
839 	if (QDF_IS_STATUS_ERROR(status)) {
840 		qdf_mem_free(bss);
841 		return status;
842 	}
843 	result_info->pvIes = bcn_ies;
844 
845 	*p_result = bss;
846 	return QDF_STATUS_SUCCESS;
847 }
848 
csr_parse_scan_list(struct mac_context * mac_ctx,struct scan_result_list * ret_list,qdf_list_t * scan_list)849 static QDF_STATUS csr_parse_scan_list(struct mac_context *mac_ctx,
850 				      struct scan_result_list *ret_list,
851 				      qdf_list_t *scan_list)
852 {
853 	struct tag_csrscan_result *pResult = NULL;
854 	struct scan_cache_node *cur_node = NULL;
855 	struct scan_cache_node *next_node = NULL;
856 
857 	qdf_list_peek_front(scan_list, (qdf_list_node_t **) &cur_node);
858 
859 	while (cur_node) {
860 		qdf_list_peek_next(scan_list, (qdf_list_node_t *) cur_node,
861 				  (qdf_list_node_t **) &next_node);
862 		pResult = NULL;
863 		csr_fill_bss_from_scan_entry(mac_ctx,
864 					     cur_node->entry, &pResult);
865 		if (pResult)
866 			csr_ll_insert_tail(&ret_list->List, &pResult->Link,
867 					   LL_ACCESS_NOLOCK);
868 		cur_node = next_node;
869 		next_node = NULL;
870 	}
871 
872 	return QDF_STATUS_SUCCESS;
873 }
874 
csr_scan_get_result(struct mac_context * mac_ctx,struct scan_filter * filter,tScanResultHandle * results)875 QDF_STATUS csr_scan_get_result(struct mac_context *mac_ctx,
876 			       struct scan_filter *filter,
877 			       tScanResultHandle *results)
878 {
879 	QDF_STATUS status;
880 	struct scan_result_list *ret_list = NULL;
881 	qdf_list_t *list = NULL;
882 	struct wlan_objmgr_pdev *pdev = NULL;
883 	uint32_t num_bss = 0;
884 
885 	if (results)
886 		*results = CSR_INVALID_SCANRESULT_HANDLE;
887 
888 	pdev = wlan_objmgr_get_pdev_by_id(mac_ctx->psoc,
889 		0, WLAN_LEGACY_MAC_ID);
890 	if (!pdev) {
891 		sme_err("pdev is NULL");
892 		return QDF_STATUS_E_INVAL;
893 	}
894 
895 	list = wlan_scan_get_result(pdev, filter);
896 	if (list) {
897 		num_bss = qdf_list_size(list);
898 		sme_debug("num_entries %d", num_bss);
899 	}
900 
901 	if (!list || (list && !qdf_list_size(list))) {
902 		sme_debug("scan list empty");
903 		if (num_bss)
904 			status = QDF_STATUS_E_EXISTS;
905 		else
906 			status = QDF_STATUS_E_NULL_VALUE;
907 		goto error;
908 	}
909 
910 	ret_list = qdf_mem_malloc(sizeof(struct scan_result_list));
911 	if (!ret_list) {
912 		status = QDF_STATUS_E_NOMEM;
913 		goto error;
914 	}
915 
916 	csr_ll_open(&ret_list->List);
917 	ret_list->pCurEntry = NULL;
918 	status = csr_parse_scan_list(mac_ctx, ret_list, list);
919 	if (QDF_IS_STATUS_ERROR(status) || !results)
920 		/* Fail or No one wants the result. */
921 		csr_scan_result_purge(mac_ctx, (tScanResultHandle) ret_list);
922 	else {
923 		if (!csr_ll_count(&ret_list->List)) {
924 			/* This mean that there is no match */
925 			csr_ll_close(&ret_list->List);
926 			qdf_mem_free(ret_list);
927 			/*
928 			 * Do not trigger scan for ssid if the scan entries
929 			 * are removed either due to rssi reject or assoc
930 			 * disallowed.
931 			 */
932 			if (num_bss)
933 				status = QDF_STATUS_E_EXISTS;
934 			else
935 				status = QDF_STATUS_E_NULL_VALUE;
936 		} else if (results) {
937 			*results = ret_list;
938 		}
939 	}
940 
941 error:
942 	if (list)
943 		wlan_scan_purge_results(list);
944 	if (pdev)
945 		wlan_objmgr_pdev_release_ref(pdev, WLAN_LEGACY_MAC_ID);
946 
947 	return status;
948 }
949 
csr_scan_get_result_for_bssid(struct mac_context * mac_ctx,struct qdf_mac_addr * bssid,qdf_list_t ** ret_list)950 QDF_STATUS csr_scan_get_result_for_bssid(struct mac_context *mac_ctx,
951 					 struct qdf_mac_addr *bssid,
952 					 qdf_list_t **ret_list)
953 {
954 	struct scan_filter *scan_filter;
955 	qdf_list_t *list = NULL;
956 
957 	*ret_list = NULL;
958 	scan_filter = qdf_mem_malloc(sizeof(*scan_filter));
959 	if (!scan_filter)
960 		return QDF_STATUS_E_NOMEM;
961 
962 	scan_filter->num_of_bssid = 1;
963 	qdf_mem_copy(scan_filter->bssid_list[0].bytes, bssid->bytes,
964 		     QDF_MAC_ADDR_SIZE);
965 	scan_filter->ignore_auth_enc_type = true;
966 
967 	list = wlan_scan_get_result(mac_ctx->pdev, scan_filter);
968 	qdf_mem_free(scan_filter);
969 	if (!list || (list && !qdf_list_size(list)))
970 		goto purge_list;
971 
972 	*ret_list = list;
973 	return QDF_STATUS_SUCCESS;
974 
975 purge_list:
976 	if (list)
977 		wlan_scan_purge_results(list);
978 
979 	return QDF_STATUS_E_FAILURE;
980 }
981 
csr_scan_filter_results(struct mac_context * mac_ctx)982 QDF_STATUS csr_scan_filter_results(struct mac_context *mac_ctx)
983 {
984 	uint32_t len = mac_ctx->mlme_cfg->reg.valid_channel_list_num;
985 	struct wlan_objmgr_pdev *pdev = NULL;
986 	uint32_t i, valid_chan_len = 0;
987 	uint32_t ch_freq;
988 	uint32_t valid_ch_freq_list[CFG_VALID_CHANNEL_LIST_LEN];
989 
990 	pdev = wlan_objmgr_get_pdev_by_id(mac_ctx->psoc,
991 		0, WLAN_LEGACY_MAC_ID);
992 	if (!pdev) {
993 		sme_err("pdev is NULL");
994 		return QDF_STATUS_E_INVAL;
995 	}
996 
997 	/* This is a temporary conversion till the scm handles freq */
998 	for (i = 0; i < len; i++) {
999 		if (wlan_reg_is_dsrc_freq(
1000 			mac_ctx->mlme_cfg->reg.valid_channel_freq_list[i]))
1001 			continue;
1002 		ch_freq = mac_ctx->mlme_cfg->reg.valid_channel_freq_list[i];
1003 		valid_ch_freq_list[valid_chan_len++] = ch_freq;
1004 	}
1005 	sme_debug("No of valid channel %d", valid_chan_len);
1006 
1007 	ucfg_scan_filter_valid_channel(pdev, valid_ch_freq_list,
1008 				       valid_chan_len);
1009 
1010 	wlan_objmgr_pdev_release_ref(pdev, WLAN_LEGACY_MAC_ID);
1011 
1012 	return QDF_STATUS_SUCCESS;
1013 }
1014 
csr_update_beacon(struct mac_context * mac)1015 void csr_update_beacon(struct mac_context *mac)
1016 {
1017 	struct scheduler_msg msg = { 0 };
1018 	QDF_STATUS status;
1019 
1020 	msg.type = SIR_LIM_UPDATE_BEACON;
1021 	status = scheduler_post_message(QDF_MODULE_ID_SME, QDF_MODULE_ID_PE,
1022 					QDF_MODULE_ID_PE, &msg);
1023 	if (status != QDF_STATUS_SUCCESS)
1024 		sme_err("scheduler_post_message failed, status = %u", status);
1025 }
1026