xref: /wlan-dirver/qcacld-3.0/core/sap/src/sap_module.c (revision f802c97df268be8bf638e3bd1a10a4acc0b52dd9)
1 /*
2  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-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  *                     sap_module.c
22  *  OVERVIEW:
23  *  This software unit holds the implementation of the WLAN SAP modules
24  *  functions providing EXTERNAL APIs. It is also where the global SAP module
25  *  context gets initialised
26  *  DEPENDENCIES:
27  *  Are listed for each API below.
28  */
29 
30 /* $Header$ */
31 
32 /*----------------------------------------------------------------------------
33  * Include Files
34  * -------------------------------------------------------------------------*/
35 #include "qdf_trace.h"
36 #include "qdf_util.h"
37 #include "qdf_atomic.h"
38 /* Pick up the sme callback registration API */
39 #include "sme_api.h"
40 
41 /* SAP API header file */
42 
43 #include "sap_internal.h"
44 #include "sme_inside.h"
45 #include "cds_ieee80211_common_i.h"
46 #include "cds_regdomain.h"
47 #include "wlan_policy_mgr_api.h"
48 #include <wlan_scan_api.h>
49 #include "wlan_reg_services_api.h"
50 #include <wlan_dfs_utils_api.h>
51 #include <wlan_reg_ucfg_api.h>
52 #include <wlan_cfg80211_crypto.h>
53 #include <wlan_crypto_global_api.h>
54 #include "cfg_ucfg_api.h"
55 #include "wlan_mlme_ucfg_api.h"
56 #include "wlan_mlme_vdev_mgr_interface.h"
57 #include "pld_common.h"
58 #include "wlan_pre_cac_api.h"
59 #include "target_if.h"
60 
61 #define SAP_DEBUG
62 static struct sap_context *gp_sap_ctx[SAP_MAX_NUM_SESSION];
63 static qdf_atomic_t sap_ctx_ref_count[SAP_MAX_NUM_SESSION];
64 static qdf_mutex_t sap_context_lock;
65 
66 /**
67  * wlansap_global_init() - Initialize SAP globals
68  *
69  * Initializes the SAP global data structures
70  *
71  * Return: QDF_STATUS
72  */
73 QDF_STATUS wlansap_global_init(void)
74 {
75 	uint32_t i;
76 
77 	if (QDF_IS_STATUS_ERROR(qdf_mutex_create(&sap_context_lock))) {
78 		sap_err("failed to init sap_context_lock");
79 		return QDF_STATUS_E_FAULT;
80 	}
81 
82 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
83 		gp_sap_ctx[i] = NULL;
84 		qdf_atomic_init(&sap_ctx_ref_count[i]);
85 	}
86 
87 	sap_debug("sap global context initialized");
88 
89 	return QDF_STATUS_SUCCESS;
90 }
91 
92 /**
93  * wlansap_global_deinit() - De-initialize SAP globals
94  *
95  * De-initializes the SAP global data structures
96  *
97  * Return: QDF_STATUS
98  */
99 QDF_STATUS wlansap_global_deinit(void)
100 {
101 	uint32_t i;
102 
103 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
104 		if (gp_sap_ctx[i]) {
105 			sap_err("we could be leaking context:%d", i);
106 		}
107 		gp_sap_ctx[i] = NULL;
108 		qdf_atomic_init(&sap_ctx_ref_count[i]);
109 	}
110 
111 	if (QDF_IS_STATUS_ERROR(qdf_mutex_destroy(&sap_context_lock))) {
112 		sap_err("failed to destroy sap_context_lock");
113 		return QDF_STATUS_E_FAULT;
114 	}
115 
116 	sap_debug("sap global context deinitialized");
117 
118 	return QDF_STATUS_SUCCESS;
119 }
120 
121 /**
122  * wlansap_save_context() - Save the context in global SAP context
123  * @ctx: SAP context to be stored
124  *
125  * Stores the given SAP context in the global SAP context array
126  *
127  * Return: QDF_STATUS
128  */
129 static QDF_STATUS wlansap_save_context(struct sap_context *ctx)
130 {
131 	uint32_t i;
132 
133 	qdf_mutex_acquire(&sap_context_lock);
134 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
135 		if (!gp_sap_ctx[i]) {
136 			gp_sap_ctx[i] = ctx;
137 			qdf_atomic_inc(&sap_ctx_ref_count[i]);
138 			qdf_mutex_release(&sap_context_lock);
139 			sap_debug("sap context saved at index: %d", i);
140 			return QDF_STATUS_SUCCESS;
141 		}
142 	}
143 	qdf_mutex_release(&sap_context_lock);
144 
145 	sap_err("failed to save sap context");
146 
147 	return QDF_STATUS_E_FAILURE;
148 }
149 
150 /**
151  * wlansap_context_get() - Verify SAP context and increment ref count
152  * @ctx: Context to be checked
153  *
154  * Verifies the SAP context and increments the reference count maintained for
155  * the corresponding SAP context.
156  *
157  * Return: QDF_STATUS
158  */
159 QDF_STATUS wlansap_context_get(struct sap_context *ctx)
160 {
161 	uint32_t i;
162 
163 	qdf_mutex_acquire(&sap_context_lock);
164 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
165 		if (ctx && (gp_sap_ctx[i] == ctx)) {
166 			qdf_atomic_inc(&sap_ctx_ref_count[i]);
167 			qdf_mutex_release(&sap_context_lock);
168 			return QDF_STATUS_SUCCESS;
169 		}
170 	}
171 	qdf_mutex_release(&sap_context_lock);
172 
173 	sap_debug("sap session is not valid");
174 	return QDF_STATUS_E_FAILURE;
175 }
176 
177 /**
178  * wlansap_context_put() - Check the reference count and free SAP context
179  * @ctx: SAP context to be checked and freed
180  *
181  * Checks the reference count and frees the SAP context
182  *
183  * Return: None
184  */
185 void wlansap_context_put(struct sap_context *ctx)
186 {
187 	uint32_t i;
188 
189 	if (!ctx)
190 		return;
191 
192 	qdf_mutex_acquire(&sap_context_lock);
193 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
194 		if (gp_sap_ctx[i] == ctx) {
195 			if (qdf_atomic_dec_and_test(&sap_ctx_ref_count[i])) {
196 				if (ctx->freq_list) {
197 					qdf_mem_free(ctx->freq_list);
198 					ctx->freq_list = NULL;
199 					ctx->num_of_channel = 0;
200 				}
201 				qdf_mem_free(ctx);
202 				gp_sap_ctx[i] = NULL;
203 				sap_debug("sap session freed: %d", i);
204 			}
205 			qdf_mutex_release(&sap_context_lock);
206 			return;
207 		}
208 	}
209 	qdf_mutex_release(&sap_context_lock);
210 }
211 
212 struct sap_context *sap_create_ctx(void)
213 {
214 	struct sap_context *sap_ctx;
215 	QDF_STATUS status;
216 
217 	sap_ctx = qdf_mem_malloc(sizeof(*sap_ctx));
218 	if (!sap_ctx)
219 		return NULL;
220 
221 	/* Clean up SAP control block, initialize all values */
222 	/* Save the SAP context pointer */
223 	status = wlansap_save_context(sap_ctx);
224 	if (QDF_IS_STATUS_ERROR(status)) {
225 		sap_err("failed to save SAP context");
226 		qdf_mem_free(sap_ctx);
227 		return NULL;
228 	}
229 	sap_debug("Exit");
230 
231 	return sap_ctx;
232 } /* sap_create_ctx */
233 
234 static QDF_STATUS wlansap_owe_init(struct sap_context *sap_ctx)
235 {
236 	qdf_list_create(&sap_ctx->owe_pending_assoc_ind_list, 0);
237 
238 	return QDF_STATUS_SUCCESS;
239 }
240 
241 static QDF_STATUS wlansap_ft_init(struct sap_context *sap_ctx)
242 {
243 	qdf_list_create(&sap_ctx->ft_pending_assoc_ind_list, 0);
244 	qdf_event_create(&sap_ctx->ft_pending_event);
245 
246 	return QDF_STATUS_SUCCESS;
247 }
248 
249 static void wlansap_owe_cleanup(struct sap_context *sap_ctx)
250 {
251 	struct mac_context *mac;
252 	struct owe_assoc_ind *owe_assoc_ind;
253 	struct assoc_ind *assoc_ind = NULL;
254 	qdf_list_node_t *node = NULL, *next_node = NULL;
255 	QDF_STATUS status;
256 
257 	if (!sap_ctx) {
258 		sap_err("Invalid SAP context");
259 		return;
260 	}
261 
262 	mac = sap_get_mac_context();
263 	if (!mac) {
264 		sap_err("Invalid MAC context");
265 		return;
266 	}
267 
268 	if (QDF_STATUS_SUCCESS !=
269 	    qdf_list_peek_front(&sap_ctx->owe_pending_assoc_ind_list,
270 				&node)) {
271 		sap_debug("Failed to find assoc ind list");
272 		return;
273 	}
274 
275 	while (node) {
276 		qdf_list_peek_next(&sap_ctx->owe_pending_assoc_ind_list,
277 				   node, &next_node);
278 		owe_assoc_ind = qdf_container_of(node, struct owe_assoc_ind,
279 						 node);
280 		status = qdf_list_remove_node(
281 					   &sap_ctx->owe_pending_assoc_ind_list,
282 					   node);
283 		if (status == QDF_STATUS_SUCCESS) {
284 			assoc_ind = owe_assoc_ind->assoc_ind;
285 			qdf_mem_free(owe_assoc_ind);
286 			assoc_ind->owe_ie = NULL;
287 			assoc_ind->owe_ie_len = 0;
288 			assoc_ind->owe_status = STATUS_UNSPECIFIED_FAILURE;
289 			status = sme_update_owe_info(mac, assoc_ind);
290 			qdf_mem_free(assoc_ind);
291 		} else {
292 			sap_err("Failed to remove assoc ind");
293 		}
294 		node = next_node;
295 		next_node = NULL;
296 	}
297 }
298 
299 static void wlansap_ft_cleanup(struct sap_context *sap_ctx)
300 {
301 	struct mac_context *mac;
302 	struct ft_assoc_ind *ft_assoc_ind;
303 	struct assoc_ind *assoc_ind = NULL;
304 	qdf_list_node_t *node = NULL, *next_node = NULL;
305 	QDF_STATUS status;
306 
307 	if (!sap_ctx) {
308 		sap_err("Invalid SAP context");
309 		return;
310 	}
311 
312 	mac = sap_get_mac_context();
313 	if (!mac) {
314 		sap_err("Invalid MAC context");
315 		return;
316 	}
317 
318 	if (QDF_STATUS_SUCCESS !=
319 	    qdf_list_peek_front(&sap_ctx->ft_pending_assoc_ind_list,
320 				&node)) {
321 		sap_debug("Failed to find assoc ind list");
322 		return;
323 	}
324 
325 	while (node) {
326 		qdf_list_peek_next(&sap_ctx->ft_pending_assoc_ind_list,
327 				   node, &next_node);
328 		ft_assoc_ind = qdf_container_of(node, struct ft_assoc_ind,
329 						node);
330 		status = qdf_list_remove_node(
331 				    &sap_ctx->ft_pending_assoc_ind_list, node);
332 		if (status == QDF_STATUS_SUCCESS) {
333 			assoc_ind = ft_assoc_ind->assoc_ind;
334 			qdf_mem_free(ft_assoc_ind);
335 			assoc_ind->ft_ie = NULL;
336 			assoc_ind->ft_ie_len = 0;
337 			assoc_ind->ft_status = STATUS_UNSPECIFIED_FAILURE;
338 			qdf_mem_free(assoc_ind);
339 		} else {
340 			sap_err("Failed to remove assoc ind");
341 		}
342 		node = next_node;
343 		next_node = NULL;
344 	}
345 }
346 
347 static void wlansap_owe_deinit(struct sap_context *sap_ctx)
348 {
349 	qdf_list_destroy(&sap_ctx->owe_pending_assoc_ind_list);
350 }
351 
352 static void wlansap_ft_deinit(struct sap_context *sap_ctx)
353 {
354 	qdf_list_destroy(&sap_ctx->ft_pending_assoc_ind_list);
355 	qdf_event_destroy(&sap_ctx->ft_pending_event);
356 }
357 
358 QDF_STATUS sap_init_ctx(struct sap_context *sap_ctx,
359 			 enum QDF_OPMODE mode,
360 			 uint8_t *addr, uint32_t session_id, bool reinit)
361 {
362 	QDF_STATUS status;
363 	struct mac_context *mac;
364 
365 	sap_debug("wlansap_start invoked successfully");
366 
367 	if (!sap_ctx) {
368 		sap_err("Invalid SAP pointer");
369 		return QDF_STATUS_E_FAULT;
370 	}
371 
372 	sap_ctx->csa_reason = CSA_REASON_UNKNOWN;
373 	qdf_mem_copy(sap_ctx->self_mac_addr, addr, QDF_MAC_ADDR_SIZE);
374 
375 	mac = sap_get_mac_context();
376 	if (!mac) {
377 		sap_err("Invalid MAC context");
378 		return QDF_STATUS_E_INVAL;
379 	}
380 
381 	status = sap_set_session_param(MAC_HANDLE(mac), sap_ctx, session_id);
382 	if (QDF_STATUS_SUCCESS != status) {
383 		sap_err("Calling sap_set_session_param status = %d", status);
384 		return QDF_STATUS_E_FAILURE;
385 	}
386 	/* Register with scan component only during init */
387 	if (!reinit)
388 		sap_ctx->req_id =
389 			wlan_scan_register_requester(mac->psoc, "SAP",
390 					sap_scan_event_callback, sap_ctx);
391 
392 	if (!reinit) {
393 		status = wlansap_owe_init(sap_ctx);
394 		if (QDF_STATUS_SUCCESS != status) {
395 			sap_err("OWE init failed");
396 			return QDF_STATUS_E_FAILURE;
397 		}
398 		status = wlansap_ft_init(sap_ctx);
399 		if (QDF_STATUS_SUCCESS != status) {
400 			sap_err("FT init failed");
401 			return QDF_STATUS_E_FAILURE;
402 		}
403 	}
404 
405 	return QDF_STATUS_SUCCESS;
406 }
407 
408 QDF_STATUS sap_deinit_ctx(struct sap_context *sap_ctx)
409 {
410 	struct mac_context *mac;
411 
412 	/* Sanity check - Extract SAP control block */
413 	sap_debug("wlansap_stop invoked successfully ");
414 
415 	if (!sap_ctx) {
416 		sap_err("Invalid SAP pointer");
417 		return QDF_STATUS_E_FAULT;
418 	}
419 
420 	wlansap_ft_cleanup(sap_ctx);
421 	wlansap_ft_deinit(sap_ctx);
422 	wlansap_owe_cleanup(sap_ctx);
423 	wlansap_owe_deinit(sap_ctx);
424 	mac = sap_get_mac_context();
425 	if (!mac) {
426 		sap_err("Invalid MAC context");
427 		return QDF_STATUS_E_FAULT;
428 	}
429 	wlan_scan_unregister_requester(mac->psoc, sap_ctx->req_id);
430 
431 	if (sap_ctx->freq_list) {
432 		qdf_mem_free(sap_ctx->freq_list);
433 		sap_ctx->freq_list = NULL;
434 		sap_ctx->num_of_channel = 0;
435 	}
436 
437 	if (sap_ctx->sessionId != WLAN_UMAC_VDEV_ID_MAX) {
438 		/* empty queues/lists/pkts if any */
439 		sap_clear_session_param(MAC_HANDLE(mac), sap_ctx,
440 					sap_ctx->sessionId);
441 	}
442 
443 	return QDF_STATUS_SUCCESS;
444 }
445 
446 QDF_STATUS sap_destroy_ctx(struct sap_context *sap_ctx)
447 {
448 	sap_debug("Enter");
449 
450 	if (!sap_ctx) {
451 		sap_err("Invalid SAP pointer");
452 		return QDF_STATUS_E_FAULT;
453 	}
454 	/* Cleanup SAP control block */
455 	/*
456 	 * wlansap_context_put will release actual sap_ctx memory
457 	 * allocated during sap_create_ctx
458 	 */
459 	wlansap_context_put(sap_ctx);
460 
461 	return QDF_STATUS_SUCCESS;
462 } /* sap_destroy_ctx */
463 
464 bool wlansap_is_channel_in_nol_list(struct sap_context *sap_ctx,
465 				    qdf_freq_t chan_freq,
466 				    ePhyChanBondState chanBondState)
467 {
468 	if (!sap_ctx) {
469 		sap_err("Invalid SAP pointer from pCtx");
470 		return QDF_STATUS_E_FAULT;
471 	}
472 
473 	return sap_dfs_is_channel_in_nol_list(sap_ctx, chan_freq,
474 					      chanBondState);
475 }
476 
477 static QDF_STATUS wlansap_mark_leaking_channel(struct wlan_objmgr_pdev *pdev,
478 		uint16_t *leakage_adjusted_lst,
479 		uint8_t chan_bw)
480 {
481 
482 	return utils_dfs_mark_leaking_chan_for_freq(pdev, chan_bw, 1,
483 						    leakage_adjusted_lst);
484 }
485 
486 bool wlansap_is_channel_leaking_in_nol(struct sap_context *sap_ctx,
487 				       uint16_t chan_freq,
488 				       uint8_t chan_bw)
489 {
490 	struct mac_context *mac_ctx;
491 	uint16_t leakage_adjusted_lst[1];
492 
493 	leakage_adjusted_lst[0] = chan_freq;
494 	mac_ctx = sap_get_mac_context();
495 	if (!mac_ctx) {
496 		sap_err("Invalid MAC context");
497 		return QDF_STATUS_E_FAULT;
498 	}
499 	if (QDF_IS_STATUS_ERROR(wlansap_mark_leaking_channel(mac_ctx->pdev,
500 			leakage_adjusted_lst, chan_bw)))
501 		return true;
502 
503 	if (!leakage_adjusted_lst[0])
504 		return true;
505 
506 	return false;
507 }
508 
509 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
510 uint16_t wlansap_check_cc_intf(struct sap_context *sap_ctx)
511 {
512 	struct mac_context *mac;
513 	uint16_t intf_ch_freq;
514 	eCsrPhyMode phy_mode;
515 	uint8_t vdev_id;
516 
517 	mac = sap_get_mac_context();
518 	if (!mac) {
519 		sap_err("Invalid MAC context");
520 		return 0;
521 	}
522 	phy_mode = sap_ctx->phyMode;
523 	vdev_id = sap_ctx->sessionId;
524 	intf_ch_freq = sme_check_concurrent_channel_overlap(
525 						MAC_HANDLE(mac),
526 						sap_ctx->chan_freq,
527 						phy_mode,
528 						sap_ctx->cc_switch_mode,
529 						vdev_id);
530 	return intf_ch_freq;
531 }
532 #endif
533 
534  /**
535   * wlansap_set_scan_acs_channel_params() - Config scan and channel parameters.
536   * config:                                Pointer to the SAP config
537   * psap_ctx:                               Pointer to the SAP Context.
538   * pusr_context:                           Parameter that will be passed
539   *                                         back in all the SAP callback events.
540   *
541   * This api function is used to copy Scan and Channel parameters from sap
542   * config to sap context.
543   *
544   * Return:                                 The result code associated with
545   *                                         performing the operation
546   */
547 static QDF_STATUS
548 wlansap_set_scan_acs_channel_params(struct sap_config *config,
549 				    struct sap_context *psap_ctx,
550 				    void *pusr_context)
551 {
552 	struct mac_context *mac;
553 	QDF_STATUS status = QDF_STATUS_SUCCESS;
554 	uint32_t auto_channel_select_weight;
555 
556 	if (!config) {
557 		sap_err("Invalid config passed ");
558 		return QDF_STATUS_E_FAULT;
559 	}
560 
561 	if (!psap_ctx) {
562 		sap_err("Invalid config passed ");
563 		return QDF_STATUS_E_FAULT;
564 	}
565 
566 	mac = sap_get_mac_context();
567 	if (!mac) {
568 		sap_err("Invalid MAC context");
569 		return QDF_STATUS_E_INVAL;
570 	}
571 
572 	/* Channel selection is auto or configured */
573 	wlansap_set_acs_ch_freq(psap_ctx, config->chan_freq);
574 	psap_ctx->dfs_mode = config->acs_dfs_mode;
575 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
576 	psap_ctx->cc_switch_mode = config->cc_switch_mode;
577 #endif
578 	status = ucfg_mlme_get_auto_channel_weight(
579 					mac->psoc,
580 					&auto_channel_select_weight);
581 
582 	if (!QDF_IS_STATUS_SUCCESS(status))
583 		sap_err("get_auto_channel_weight failed");
584 
585 	psap_ctx->auto_channel_select_weight = auto_channel_select_weight;
586 	sap_debug("auto_channel_select_weight %d",
587 		  psap_ctx->auto_channel_select_weight);
588 
589 	psap_ctx->user_context = pusr_context;
590 	psap_ctx->enableOverLapCh = config->enOverLapCh;
591 	psap_ctx->acs_cfg = &config->acs_cfg;
592 	psap_ctx->ch_width_orig = config->acs_cfg.ch_width;
593 	psap_ctx->sec_ch_freq = config->sec_ch_freq;
594 	qdf_mem_copy(psap_ctx->self_mac_addr,
595 		config->self_macaddr.bytes, QDF_MAC_ADDR_SIZE);
596 
597 	return status;
598 }
599 
600 eCsrPhyMode wlan_sap_get_phymode(struct sap_context *sap_ctx)
601 {
602 	if (!sap_ctx) {
603 		sap_err("Invalid SAP pointer from ctx");
604 		return 0;
605 	}
606 	return sap_ctx->phyMode;
607 }
608 
609 enum phy_ch_width wlan_sap_get_concurrent_bw(struct wlan_objmgr_pdev *pdev,
610 					     struct wlan_objmgr_psoc *psoc,
611 					     qdf_freq_t con_ch_freq,
612 					     enum phy_ch_width channel_width)
613 {
614 	enum hw_mode_bandwidth sta_ch_width;
615 	enum phy_ch_width sta_chan_width = CH_WIDTH_20MHZ;
616 	bool scc_sta_present, is_con_chan_dfs = false;
617 	bool is_con_sta_indoor = false;
618 	uint8_t sta_vdev_id;
619 	uint8_t sta_sap_scc_on_dfs_chnl;
620 	uint8_t sta_count = 0;
621 	bool is_hw_dbs_capable = false;
622 
623 	if (WLAN_REG_IS_24GHZ_CH_FREQ(con_ch_freq))
624 		return channel_width;
625 
626 	if (wlan_reg_is_6ghz_chan_freq(con_ch_freq))
627 		return channel_width;
628 
629 	/* sta_count is to check if there is STA present on any other
630 	 * channel freq irrespective of concurrent channel.
631 	 */
632 	sta_count = policy_mgr_mode_specific_connection_count(
633 							psoc,
634 							PM_STA_MODE,
635 							NULL);
636 	scc_sta_present = policy_mgr_is_sta_present_on_freq(psoc,
637 							    &sta_vdev_id,
638 							    con_ch_freq,
639 							    &sta_ch_width);
640 	if (scc_sta_present) {
641 		sta_chan_width = policy_mgr_get_ch_width(sta_ch_width);
642 		sap_debug("sta_chan_width:%d, channel_width:%d",
643 			  sta_chan_width, channel_width);
644 		if (wlan_reg_is_dfs_for_freq(pdev, con_ch_freq) ||
645 		    sta_chan_width == CH_WIDTH_160MHZ)
646 			is_con_chan_dfs = true;
647 		else if (WLAN_REG_IS_5GHZ_CH_FREQ(con_ch_freq) &&
648 			 wlan_reg_is_freq_indoor(pdev, con_ch_freq))
649 			is_con_sta_indoor = true;
650 	}
651 
652 	policy_mgr_get_sta_sap_scc_on_dfs_chnl(psoc, &sta_sap_scc_on_dfs_chnl);
653 	is_hw_dbs_capable = policy_mgr_is_hw_dbs_capable(psoc);
654 	sap_debug("sta_sap_scc_on_dfs_chnl:%d, is_hw_dbs_capable:%d, sta_count:%d, scc_sta_present:%d",
655 		  sta_sap_scc_on_dfs_chnl,
656 		  is_hw_dbs_capable, sta_count, scc_sta_present);
657 
658 	if (!is_hw_dbs_capable)
659 		goto dfs_master_mode_check;
660 
661 	/*
662 	 * In indoor concurrency cases, limit the channel width with the STA
663 	 * interface bandwidth. Since, only the bonded channels are active
664 	 * channels.
665 	 */
666 	if (is_con_sta_indoor) {
667 		channel_width = QDF_MIN(sta_chan_width, channel_width);
668 		sap_debug("STA + SAP on indoor channels");
669 		return channel_width;
670 	} else if (is_con_chan_dfs) {
671 		channel_width = QDF_MIN(sta_chan_width, channel_width);
672 		sap_debug("STA + SAP on dfs channels");
673 		goto dfs_master_mode_check;
674 	} else {
675 		/* Handle "DBS + active channel" concurrency/standalone SAP */
676 		sap_debug("STA + SAP/GO or standalone SAP on active channel");
677 		if (scc_sta_present)
678 			return  QDF_MAX(sta_chan_width, CH_WIDTH_80MHZ);
679 		else if (sta_count)
680 			return  QDF_MIN(channel_width, CH_WIDTH_80MHZ);
681 		return channel_width;
682 	}
683 
684 dfs_master_mode_check:
685 	/* Handle "DBS/non-DBS + dfs channels" concurrency */
686 	if (sta_sap_scc_on_dfs_chnl == PM_STA_SAP_ON_DFS_MASTER_MODE_FLEX) {
687 		if (scc_sta_present) {
688 			sap_debug("STA+SAP/GO: limit the SAP channel width");
689 			return QDF_MIN(sta_chan_width, channel_width);
690 		}
691 
692 		sap_debug("Standalone SAP/GO: set BW coming in start req");
693 		return channel_width;
694 	} else if (sta_sap_scc_on_dfs_chnl ==
695 		   PM_STA_SAP_ON_DFS_MASTER_MODE_DISABLED) {
696 		if (scc_sta_present) {
697 			sap_debug("STA present: Limit the SAP channel width");
698 			channel_width = QDF_MIN(sta_chan_width, channel_width);
699 			return channel_width;
700 		}
701 		/*
702 		 * sta_sap_scc_on_dfs_chnl = 1, DFS master is disabled.
703 		 * If STA not present (SAP single), the SAP (160Mhz) is
704 		 * not allowed on DFS, so limit SAP to 80Mhz.
705 		 */
706 		sap_debug("Limit Standalone SAP/GO to 80Mhz");
707 		return QDF_MIN(channel_width, CH_WIDTH_80MHZ);
708 	}
709 
710 	/*
711 	 * sta_sap_scc_on_dfs_chnl = 0, not allow STA+SAP SCC on DFS.
712 	 * Limit SAP to 80Mhz if STA present.
713 	 */
714 	if (sta_count) {
715 		sap_debug("STA present, Limit SAP/GO to 80Mhz");
716 		return QDF_MIN(channel_width, CH_WIDTH_80MHZ);
717 	}
718 
719 	sap_debug("Single SAP/GO: set BW coming in SAP/GO start req");
720 	return channel_width;
721 
722 }
723 
724 uint32_t wlan_sap_get_vht_ch_width(struct sap_context *sap_ctx)
725 {
726 	if (!sap_ctx) {
727 		sap_err("Invalid SAP pointer");
728 		return 0;
729 	}
730 
731 	return sap_ctx->ch_params.ch_width;
732 }
733 
734 bool wlan_sap_get_ch_params(struct sap_context *sap_ctx,
735 			    struct ch_params *ch_params)
736 {
737 	if (!sap_ctx) {
738 		sap_err("Invalid SAP pointer");
739 		return false;
740 	}
741 
742 	*ch_params = sap_ctx->ch_params;
743 	return true;
744 }
745 
746 /**
747  * wlan_sap_validate_channel_switch() - validate target channel switch w.r.t
748  *      concurreny rules set to avoid channel interference.
749  * @mac_handle: Opaque handle to the global MAC context
750  * @sap_ch_freq: channel to switch
751  * @sap_context: sap session context
752  *
753  * Return: true if there is no channel interference else return false
754  */
755 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
756 static bool wlan_sap_validate_channel_switch(mac_handle_t mac_handle,
757 					     uint32_t sap_ch_freq,
758 					     struct sap_context *sap_context)
759 {
760 	return sme_validate_sap_channel_switch(
761 			mac_handle,
762 			sap_ch_freq,
763 			sap_context->phyMode,
764 			sap_context->cc_switch_mode,
765 			sap_context->sessionId);
766 }
767 #else
768 static bool wlan_sap_validate_channel_switch(mac_handle_t mac_handle,
769 					     uint32_t sap_ch_freq,
770 					     struct sap_context *sap_context)
771 {
772 	return true;
773 }
774 #endif
775 
776 void wlan_sap_set_sap_ctx_acs_cfg(struct sap_context *sap_ctx,
777 				  struct sap_config *sap_config)
778 {
779 	if (!sap_ctx) {
780 		sap_err("Invalid SAP pointer");
781 		return;
782 	}
783 
784 	sap_ctx->acs_cfg = &sap_config->acs_cfg;
785 }
786 
787 QDF_STATUS wlansap_start_bss(struct sap_context *sap_ctx,
788 			     sap_event_cb sap_event_cb,
789 			     struct sap_config *config, void *user_context)
790 {
791 	struct sap_sm_event sap_event;        /* State machine event */
792 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
793 	uint32_t auto_channel_select_weight =
794 			cfg_default(CFG_AUTO_CHANNEL_SELECT_WEIGHT);
795 	int reduced_beacon_interval;
796 	struct mac_context *pmac = NULL;
797 	int sap_chanswitch_beacon_cnt;
798 	bool sap_chanswitch_mode;
799 
800 	if (!sap_ctx) {
801 		sap_info("Invalid SAP context");
802 		return QDF_STATUS_E_FAULT;
803 	}
804 
805 	pmac = sap_get_mac_context();
806 	if (!pmac) {
807 		sap_err("Invalid sap MAC context");
808 		qdf_status = QDF_STATUS_E_INVAL;
809 		goto fail;
810 	}
811 
812 	sap_ctx->fsm_state = SAP_INIT;
813 	sap_debug("sap_fsm: vdev %d:  => SAP_INIT", sap_ctx->vdev_id);
814 
815 	qdf_status = wlan_set_vdev_crypto_prarams_from_ie(
816 			sap_ctx->vdev,
817 			config->RSNWPAReqIE,
818 			config->RSNWPAReqIELength);
819 	if (QDF_IS_STATUS_ERROR(qdf_status))
820 		sap_debug("Failed to set crypto params from IE");
821 
822 	/* Channel selection is auto or configured */
823 	sap_ctx->chan_freq = config->chan_freq;
824 	sap_ctx->dfs_mode = config->acs_dfs_mode;
825 	sap_ctx->ch_params = config->ch_params;
826 	sap_ctx->ch_width_orig = config->ch_width_orig;
827 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
828 	sap_ctx->cc_switch_mode = config->cc_switch_mode;
829 #endif
830 
831 	qdf_status = ucfg_mlme_get_auto_channel_weight(
832 					pmac->psoc,
833 					&auto_channel_select_weight);
834 	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
835 		sap_err("get_auto_channel_weight failed");
836 
837 	sap_ctx->auto_channel_select_weight = auto_channel_select_weight;
838 
839 	sap_ctx->user_context = user_context;
840 	sap_ctx->enableOverLapCh = config->enOverLapCh;
841 	sap_ctx->acs_cfg = &config->acs_cfg;
842 	sap_ctx->sec_ch_freq = config->sec_ch_freq;
843 	sap_ctx->dfs_cac_offload = config->dfs_cac_offload;
844 	sap_ctx->isCacStartNotified = false;
845 	sap_ctx->isCacEndNotified = false;
846 	sap_ctx->is_chan_change_inprogress = false;
847 	sap_ctx->disabled_mcs13 = false;
848 	sap_ctx->phyMode = config->SapHw_mode;
849 	sap_ctx->csa_reason = CSA_REASON_UNKNOWN;
850 	sap_ctx->require_h2e = config->require_h2e;
851 	qdf_mem_copy(sap_ctx->bssid.bytes, config->self_macaddr.bytes,
852 		     QDF_MAC_ADDR_SIZE);
853 	qdf_mem_copy(sap_ctx->self_mac_addr,
854 		     config->self_macaddr.bytes, QDF_MAC_ADDR_SIZE);
855 	/*
856 	 * Set the DFS Test Mode setting
857 	 * Set beacon channel count before channel switch
858 	 */
859 	qdf_status = ucfg_mlme_get_sap_chn_switch_bcn_count(
860 						pmac->psoc,
861 						&sap_chanswitch_beacon_cnt);
862 	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
863 		sap_err("ucfg_mlme_get_sap_chn_switch_bcn_count fail, set def");
864 
865 	pmac->sap.SapDfsInfo.sap_ch_switch_beacon_cnt =
866 				sap_chanswitch_beacon_cnt;
867 	pmac->sap.SapDfsInfo.sap_ch_switch_mode =
868 				sap_chanswitch_beacon_cnt;
869 
870 	qdf_status = ucfg_mlme_get_sap_channel_switch_mode(
871 						pmac->psoc,
872 						&sap_chanswitch_mode);
873 	if (QDF_IS_STATUS_ERROR(qdf_status))
874 		sap_err("ucfg_mlme_get_sap_channel_switch_mode, set def");
875 
876 	pmac->sap.SapDfsInfo.sap_ch_switch_mode = sap_chanswitch_mode;
877 	pmac->sap.sapCtxList[sap_ctx->sessionId].sap_context = sap_ctx;
878 	pmac->sap.sapCtxList[sap_ctx->sessionId].sapPersona =
879 							config->persona;
880 
881 	qdf_status = ucfg_mlme_get_sap_reduces_beacon_interval(
882 						pmac->psoc,
883 						&reduced_beacon_interval);
884 	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
885 		sap_err("ucfg_mlme_get_sap_reduces_beacon_interval fail");
886 
887 	pmac->sap.SapDfsInfo.reduced_beacon_interval =
888 					reduced_beacon_interval;
889 	sap_debug("SAP: auth ch select weight:%d chswitch bcn cnt:%d chswitch mode:%d reduced bcn intv:%d",
890 		  sap_ctx->auto_channel_select_weight,
891 		  sap_chanswitch_beacon_cnt,
892 		  pmac->sap.SapDfsInfo.sap_ch_switch_mode,
893 		  pmac->sap.SapDfsInfo.reduced_beacon_interval);
894 
895 	/* Copy MAC filtering settings to sap context */
896 	sap_ctx->eSapMacAddrAclMode = config->SapMacaddr_acl;
897 	qdf_mem_copy(sap_ctx->acceptMacList, config->accept_mac,
898 		     sizeof(config->accept_mac));
899 	sap_ctx->nAcceptMac = config->num_accept_mac;
900 	sap_sort_mac_list(sap_ctx->acceptMacList, sap_ctx->nAcceptMac);
901 	qdf_mem_copy(sap_ctx->denyMacList, config->deny_mac,
902 		     sizeof(config->deny_mac));
903 	sap_ctx->nDenyMac = config->num_deny_mac;
904 	sap_sort_mac_list(sap_ctx->denyMacList, sap_ctx->nDenyMac);
905 	sap_ctx->beacon_tx_rate = config->beacon_tx_rate;
906 
907 	/* Fill in the event structure for FSM */
908 	sap_event.event = eSAP_HDD_START_INFRA_BSS;
909 	sap_event.params = 0;    /* pSapPhysLinkCreate */
910 
911 	/* Store the HDD callback in SAP context */
912 	sap_ctx->sap_event_cb = sap_event_cb;
913 
914 	sap_ctx->sap_bss_cfg.vdev_id = sap_ctx->sessionId;
915 	sap_build_start_bss_config(&sap_ctx->sap_bss_cfg, config);
916 	/* Handle event */
917 	qdf_status = sap_fsm(sap_ctx, &sap_event);
918 fail:
919 	if (QDF_IS_STATUS_ERROR(qdf_status))
920 		qdf_mem_zero(&sap_ctx->sap_bss_cfg,
921 			     sizeof(sap_ctx->sap_bss_cfg));
922 	return qdf_status;
923 } /* wlansap_start_bss */
924 
925 QDF_STATUS wlansap_set_mac_acl(struct sap_context *sap_ctx,
926 			       struct sap_config *config)
927 {
928 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
929 
930 	sap_debug("wlansap_set_mac_acl");
931 
932 	if (!sap_ctx) {
933 		sap_err("Invalid SAP pointer");
934 		return QDF_STATUS_E_FAULT;
935 	}
936 	/* Copy MAC filtering settings to sap context */
937 	sap_ctx->eSapMacAddrAclMode = config->SapMacaddr_acl;
938 
939 	if (eSAP_DENY_UNLESS_ACCEPTED == sap_ctx->eSapMacAddrAclMode) {
940 		qdf_mem_copy(sap_ctx->acceptMacList,
941 			     config->accept_mac,
942 			     sizeof(config->accept_mac));
943 		sap_ctx->nAcceptMac = config->num_accept_mac;
944 		sap_sort_mac_list(sap_ctx->acceptMacList,
945 			       sap_ctx->nAcceptMac);
946 	} else if (eSAP_ACCEPT_UNLESS_DENIED == sap_ctx->eSapMacAddrAclMode) {
947 		qdf_mem_copy(sap_ctx->denyMacList, config->deny_mac,
948 			     sizeof(config->deny_mac));
949 		sap_ctx->nDenyMac = config->num_deny_mac;
950 		sap_sort_mac_list(sap_ctx->denyMacList, sap_ctx->nDenyMac);
951 	}
952 
953 	return qdf_status;
954 } /* wlansap_set_mac_acl */
955 
956 QDF_STATUS wlansap_stop_bss(struct sap_context *sap_ctx)
957 {
958 	struct sap_sm_event sap_event;        /* State machine event */
959 	QDF_STATUS qdf_status;
960 
961 	if (!sap_ctx) {
962 		sap_err("Invalid SAP pointer");
963 		return QDF_STATUS_E_FAULT;
964 	}
965 
966 	/* Fill in the event structure for FSM */
967 	sap_event.event = eSAP_HDD_STOP_INFRA_BSS;
968 	sap_event.params = 0;
969 
970 	/* Handle event */
971 	qdf_status = sap_fsm(sap_ctx, &sap_event);
972 
973 	return qdf_status;
974 }
975 
976 /* This routine will set the mode of operation for ACL dynamically*/
977 QDF_STATUS wlansap_set_acl_mode(struct sap_context *sap_ctx,
978 				eSapMacAddrACL mode)
979 {
980 	if (!sap_ctx) {
981 		sap_err("Invalid SAP pointer");
982 		return QDF_STATUS_E_FAULT;
983 	}
984 
985 	sap_ctx->eSapMacAddrAclMode = mode;
986 	return QDF_STATUS_SUCCESS;
987 }
988 
989 QDF_STATUS wlansap_get_acl_mode(struct sap_context *sap_ctx,
990 				eSapMacAddrACL *mode)
991 {
992 	if (!sap_ctx) {
993 		sap_err("Invalid SAP pointer");
994 		return QDF_STATUS_E_FAULT;
995 	}
996 
997 	*mode = sap_ctx->eSapMacAddrAclMode;
998 	return QDF_STATUS_SUCCESS;
999 }
1000 
1001 QDF_STATUS wlansap_get_acl_accept_list(struct sap_context *sap_ctx,
1002 				       struct qdf_mac_addr *pAcceptList,
1003 				       uint16_t *nAcceptList)
1004 {
1005 	if (!sap_ctx) {
1006 		sap_err("Invalid SAP pointer");
1007 		return QDF_STATUS_E_FAULT;
1008 	}
1009 
1010 	memcpy(pAcceptList, sap_ctx->acceptMacList,
1011 	       (sap_ctx->nAcceptMac * QDF_MAC_ADDR_SIZE));
1012 	*nAcceptList = sap_ctx->nAcceptMac;
1013 	return QDF_STATUS_SUCCESS;
1014 }
1015 
1016 QDF_STATUS wlansap_get_acl_deny_list(struct sap_context *sap_ctx,
1017 				     struct qdf_mac_addr *pDenyList,
1018 				     uint16_t *nDenyList)
1019 {
1020 	if (!sap_ctx) {
1021 		sap_err("Invalid SAP pointer from p_cds_gctx");
1022 		return QDF_STATUS_E_FAULT;
1023 	}
1024 
1025 	memcpy(pDenyList, sap_ctx->denyMacList,
1026 	       (sap_ctx->nDenyMac * QDF_MAC_ADDR_SIZE));
1027 	*nDenyList = sap_ctx->nDenyMac;
1028 	return QDF_STATUS_SUCCESS;
1029 }
1030 
1031 QDF_STATUS wlansap_clear_acl(struct sap_context *sap_ctx)
1032 {
1033 	uint16_t i;
1034 
1035 	if (!sap_ctx) {
1036 		return QDF_STATUS_E_RESOURCES;
1037 	}
1038 
1039 	for (i = 0; i < sap_ctx->nDenyMac; i++) {
1040 		qdf_mem_zero((sap_ctx->denyMacList + i)->bytes,
1041 			     QDF_MAC_ADDR_SIZE);
1042 	}
1043 
1044 	sap_print_acl(sap_ctx->denyMacList, sap_ctx->nDenyMac);
1045 	sap_ctx->nDenyMac = 0;
1046 
1047 	for (i = 0; i < sap_ctx->nAcceptMac; i++) {
1048 		qdf_mem_zero((sap_ctx->acceptMacList + i)->bytes,
1049 			     QDF_MAC_ADDR_SIZE);
1050 	}
1051 
1052 	sap_print_acl(sap_ctx->acceptMacList, sap_ctx->nAcceptMac);
1053 	sap_ctx->nAcceptMac = 0;
1054 
1055 	return QDF_STATUS_SUCCESS;
1056 }
1057 
1058 QDF_STATUS wlansap_modify_acl(struct sap_context *sap_ctx,
1059 			      uint8_t *peer_sta_mac,
1060 			      eSapACLType list_type, eSapACLCmdType cmd)
1061 {
1062 	bool sta_allow_list = false, sta_deny_list = false;
1063 	uint16_t staWLIndex, staBLIndex;
1064 
1065 	if (!sap_ctx) {
1066 		sap_err("Invalid SAP Context");
1067 		return QDF_STATUS_E_FAULT;
1068 	}
1069 	if (qdf_mem_cmp(sap_ctx->bssid.bytes, peer_sta_mac,
1070 			QDF_MAC_ADDR_SIZE) == 0) {
1071 		sap_err("requested peer mac is "QDF_MAC_ADDR_FMT
1072 			"our own SAP BSSID. Do not denylist or allowlist this BSSID",
1073 			QDF_MAC_ADDR_REF(peer_sta_mac));
1074 		return QDF_STATUS_E_FAULT;
1075 	}
1076 	sap_debug("Modify ACL entered\n" "Before modification of ACL\n"
1077 		  "size of accept and deny lists %d %d", sap_ctx->nAcceptMac,
1078 		  sap_ctx->nDenyMac);
1079 	sap_debug("*** ALLOW LIST ***");
1080 	sap_print_acl(sap_ctx->acceptMacList, sap_ctx->nAcceptMac);
1081 	sap_debug("*** DENY LIST ***");
1082 	sap_print_acl(sap_ctx->denyMacList, sap_ctx->nDenyMac);
1083 
1084 	/* the expectation is a mac addr will not be in both the lists
1085 	 * at the same time. It is the responsibility of userspace to
1086 	 * ensure this
1087 	 */
1088 	sta_allow_list =
1089 		sap_search_mac_list(sap_ctx->acceptMacList, sap_ctx->nAcceptMac,
1090 				 peer_sta_mac, &staWLIndex);
1091 	sta_deny_list =
1092 		sap_search_mac_list(sap_ctx->denyMacList, sap_ctx->nDenyMac,
1093 				 peer_sta_mac, &staBLIndex);
1094 
1095 	if (sta_allow_list && sta_deny_list) {
1096 		sap_err("Peer mac " QDF_MAC_ADDR_FMT
1097 			" found in allow and deny lists."
1098 			"Initial lists passed incorrect. Cannot execute this command.",
1099 			QDF_MAC_ADDR_REF(peer_sta_mac));
1100 		return QDF_STATUS_E_FAILURE;
1101 
1102 	}
1103 	sap_debug("cmd %d", cmd);
1104 
1105 	switch (list_type) {
1106 	case SAP_ALLOW_LIST:
1107 		if (cmd == ADD_STA_TO_ACL || cmd == ADD_STA_TO_ACL_NO_DEAUTH) {
1108 			/* error check */
1109 			/* if list is already at max, return failure */
1110 			if (sap_ctx->nAcceptMac == MAX_ACL_MAC_ADDRESS) {
1111 				sap_err("Allow list is already maxed out. Cannot accept "
1112 					  QDF_MAC_ADDR_FMT,
1113 					  QDF_MAC_ADDR_REF(peer_sta_mac));
1114 				return QDF_STATUS_E_FAILURE;
1115 			}
1116 			if (sta_allow_list) {
1117 				/*
1118 				 * Do nothing if already present in allow
1119 				 * list. Just print a warning
1120 				 */
1121 				sap_warn("MAC address already present in allow list "
1122 					 QDF_MAC_ADDR_FMT,
1123 					 QDF_MAC_ADDR_REF(peer_sta_mac));
1124 				return QDF_STATUS_SUCCESS;
1125 			}
1126 			if (sta_deny_list) {
1127 				/*
1128 				 * remove it from deny list before adding
1129 				 * to the allow list
1130 				 */
1131 				sap_warn("STA present in deny list so first remove from it");
1132 				sap_remove_mac_from_acl(sap_ctx->denyMacList,
1133 						    &sap_ctx->nDenyMac,
1134 						    staBLIndex);
1135 			}
1136 			sap_debug("... Now add to the allow list");
1137 			sap_add_mac_to_acl(sap_ctx->acceptMacList,
1138 					       &sap_ctx->nAcceptMac,
1139 			       peer_sta_mac);
1140 				sap_debug("size of accept and deny lists %d %d",
1141 					  sap_ctx->nAcceptMac,
1142 					  sap_ctx->nDenyMac);
1143 		} else if (cmd == DELETE_STA_FROM_ACL ||
1144 			   cmd == DELETE_STA_FROM_ACL_NO_DEAUTH) {
1145 			if (sta_allow_list) {
1146 
1147 				struct csr_del_sta_params delStaParams;
1148 
1149 				sap_info("Delete from allow list");
1150 				sap_remove_mac_from_acl(sap_ctx->acceptMacList,
1151 						    &sap_ctx->nAcceptMac,
1152 						    staWLIndex);
1153 				/* If a client is deleted from allow list and */
1154 				/* it is connected, send deauth
1155 				 */
1156 				if (cmd == DELETE_STA_FROM_ACL) {
1157 					wlansap_populate_del_sta_params(
1158 						peer_sta_mac,
1159 						eCsrForcedDeauthSta,
1160 						SIR_MAC_MGMT_DEAUTH,
1161 						&delStaParams);
1162 					wlansap_deauth_sta(sap_ctx,
1163 							   &delStaParams);
1164 					sap_debug("size of accept and deny lists %d %d",
1165 						  sap_ctx->nAcceptMac,
1166 						  sap_ctx->nDenyMac);
1167 				}
1168 			} else {
1169 				sap_warn("MAC address to be deleted is not present in the allow list "
1170 					 QDF_MAC_ADDR_FMT,
1171 					 QDF_MAC_ADDR_REF(peer_sta_mac));
1172 				return QDF_STATUS_E_FAILURE;
1173 			}
1174 		} else {
1175 			sap_err("Invalid cmd type passed");
1176 			return QDF_STATUS_E_FAILURE;
1177 		}
1178 		break;
1179 
1180 	case SAP_DENY_LIST:
1181 
1182 		if (cmd == ADD_STA_TO_ACL || cmd == ADD_STA_TO_ACL_NO_DEAUTH) {
1183 			struct csr_del_sta_params delStaParams;
1184 			/* error check */
1185 			/* if list is already at max, return failure */
1186 			if (sap_ctx->nDenyMac == MAX_ACL_MAC_ADDRESS) {
1187 				sap_err("Deny list is already maxed out. Cannot accept "
1188 					QDF_MAC_ADDR_FMT,
1189 					QDF_MAC_ADDR_REF(peer_sta_mac));
1190 				return QDF_STATUS_E_FAILURE;
1191 			}
1192 			if (sta_deny_list) {
1193 				/*
1194 				 * Do nothing if already present in
1195 				 * allow list
1196 				 */
1197 				sap_warn("MAC address already present in deny list "
1198 					 QDF_MAC_ADDR_FMT,
1199 					 QDF_MAC_ADDR_REF(peer_sta_mac));
1200 				return QDF_STATUS_SUCCESS;
1201 			}
1202 			if (sta_allow_list) {
1203 				/*
1204 				 * remove it from allow list before adding to
1205 				 * the deny list
1206 				 */
1207 				sap_warn("Present in allow list so first remove from it");
1208 				sap_remove_mac_from_acl(sap_ctx->acceptMacList,
1209 						    &sap_ctx->nAcceptMac,
1210 						    staWLIndex);
1211 			}
1212 			/* If we are adding a client to the deny list; */
1213 			/* if its connected, send deauth
1214 			 */
1215 			if (cmd == ADD_STA_TO_ACL) {
1216 				wlansap_populate_del_sta_params(
1217 					peer_sta_mac,
1218 					eCsrForcedDeauthSta,
1219 					SIR_MAC_MGMT_DEAUTH,
1220 					&delStaParams);
1221 				wlansap_deauth_sta(sap_ctx, &delStaParams);
1222 			}
1223 			sap_info("... Now add to deny list");
1224 			sap_add_mac_to_acl(sap_ctx->denyMacList,
1225 				       &sap_ctx->nDenyMac, peer_sta_mac);
1226 			sap_debug("size of accept and deny lists %d %d",
1227 				  sap_ctx->nAcceptMac,
1228 				  sap_ctx->nDenyMac);
1229 		} else if (cmd == DELETE_STA_FROM_ACL ||
1230 			   cmd == DELETE_STA_FROM_ACL_NO_DEAUTH) {
1231 			if (sta_deny_list) {
1232 				sap_info("Delete from deny list");
1233 				sap_remove_mac_from_acl(sap_ctx->denyMacList,
1234 						    &sap_ctx->nDenyMac,
1235 						    staBLIndex);
1236 				sap_debug("no accept and deny mac %d %d",
1237 					  sap_ctx->nAcceptMac,
1238 					  sap_ctx->nDenyMac);
1239 			} else {
1240 				sap_warn("MAC address to be deleted is not present in the deny list "
1241 					  QDF_MAC_ADDR_FMT,
1242 					  QDF_MAC_ADDR_REF(peer_sta_mac));
1243 				return QDF_STATUS_E_FAILURE;
1244 			}
1245 		} else {
1246 			sap_err("Invalid cmd type passed");
1247 			return QDF_STATUS_E_FAILURE;
1248 		}
1249 		break;
1250 
1251 	default:
1252 	{
1253 		sap_err("Invalid list type passed %d", list_type);
1254 		return QDF_STATUS_E_FAILURE;
1255 	}
1256 	}
1257 	sap_debug("After modification of ACL");
1258 	sap_debug("*** ALLOW LIST ***");
1259 	sap_print_acl(sap_ctx->acceptMacList, sap_ctx->nAcceptMac);
1260 	sap_debug("*** DENY LIST ***");
1261 	sap_print_acl(sap_ctx->denyMacList, sap_ctx->nDenyMac);
1262 	return QDF_STATUS_SUCCESS;
1263 }
1264 
1265 QDF_STATUS wlansap_disassoc_sta(struct sap_context *sap_ctx,
1266 				struct csr_del_sta_params *params)
1267 {
1268 	struct mac_context *mac;
1269 
1270 	if (!sap_ctx) {
1271 		sap_err("Invalid SAP pointer");
1272 		return QDF_STATUS_E_FAULT;
1273 	}
1274 
1275 	mac = sap_get_mac_context();
1276 	if (!mac) {
1277 		sap_err("Invalid MAC context");
1278 		return QDF_STATUS_E_FAULT;
1279 	}
1280 
1281 	return sme_roam_disconnect_sta(MAC_HANDLE(mac), sap_ctx->sessionId,
1282 				       params);
1283 }
1284 
1285 QDF_STATUS wlansap_deauth_sta(struct sap_context *sap_ctx,
1286 			      struct csr_del_sta_params *params)
1287 {
1288 	struct mac_context *mac;
1289 
1290 	if (!sap_ctx) {
1291 		sap_err("Invalid SAP pointer");
1292 		return QDF_STATUS_E_FAULT;
1293 	}
1294 
1295 	mac = sap_get_mac_context();
1296 	if (!mac) {
1297 		sap_err("Invalid MAC context");
1298 		return QDF_STATUS_E_FAULT;
1299 	}
1300 
1301 	return sme_roam_deauth_sta(MAC_HANDLE(mac), sap_ctx->sessionId,
1302 				   params);
1303 }
1304 
1305 #if defined(WLAN_FEATURE_11BE)
1306 static enum phy_ch_width
1307 wlansap_get_target_eht_phy_ch_width(void)
1308 {
1309 	uint32_t max_fw_bw = sme_get_eht_ch_width();
1310 
1311 	if (max_fw_bw == WNI_CFG_EHT_CHANNEL_WIDTH_320MHZ)
1312 		return CH_WIDTH_320MHZ;
1313 	else if (max_fw_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
1314 		return CH_WIDTH_160MHZ;
1315 	else
1316 		return CH_WIDTH_80MHZ;
1317 }
1318 #else /* !WLAN_FEATURE_11BE */
1319 static enum phy_ch_width
1320 wlansap_get_target_eht_phy_ch_width(void)
1321 {
1322 	return CH_WIDTH_20MHZ;
1323 }
1324 #endif /* WLAN_FEATURE_11BE */
1325 
1326 static enum phy_ch_width
1327 wlansap_5g_original_bw_validate(
1328 	struct sap_context *sap_context,
1329 	uint32_t chan_freq,
1330 	enum phy_ch_width ch_width)
1331 {
1332 	if (sap_context->csa_reason != CSA_REASON_USER_INITIATED &&
1333 	    WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq) &&
1334 	    ch_width >= CH_WIDTH_160MHZ &&
1335 	    sap_context->ch_width_orig < CH_WIDTH_160MHZ)
1336 		ch_width = CH_WIDTH_80MHZ;
1337 
1338 	return ch_width;
1339 }
1340 
1341 /**
1342  * wlansap_2g_original_bw_validate() - validate bw for sap on 2.4 GHz
1343  * @sap_context: sap context
1344  * @chan_freq: channel frequency
1345  * @ch_width: band width
1346  * @sec_ch_freq: secondary channel frequency
1347  *
1348  * If initial SAP starts on 2.4 GHz HT40/HT20 mode, driver honors it.
1349  *
1350  * Return: new bandwidth
1351  */
1352 static enum phy_ch_width
1353 wlansap_2g_original_bw_validate(struct sap_context *sap_context,
1354 				uint32_t chan_freq,
1355 				enum phy_ch_width ch_width,
1356 				qdf_freq_t *sec_ch_freq)
1357 {
1358 	if (sap_context->csa_reason == CSA_REASON_UNKNOWN &&
1359 	    WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq) &&
1360 	    sap_context->ch_width_orig == CH_WIDTH_40MHZ) {
1361 		ch_width = CH_WIDTH_40MHZ;
1362 		if (sap_context->ch_params.sec_ch_offset == LOW_PRIMARY_CH)
1363 			*sec_ch_freq = chan_freq + 20;
1364 		else if (sap_context->ch_params.sec_ch_offset ==
1365 						HIGH_PRIMARY_CH)
1366 			*sec_ch_freq = chan_freq - 20;
1367 		else
1368 			*sec_ch_freq = 0;
1369 	}
1370 
1371 	return ch_width;
1372 }
1373 
1374 enum phy_ch_width
1375 wlansap_get_csa_chanwidth_from_phymode(struct sap_context *sap_context,
1376 				       uint32_t chan_freq,
1377 				       struct ch_params *tgt_ch_params)
1378 {
1379 	enum phy_ch_width ch_width, concurrent_bw = 0;
1380 	struct mac_context *mac;
1381 	struct ch_params ch_params = {0};
1382 	uint32_t channel_bonding_mode = 0;
1383 	qdf_freq_t sec_ch_freq = 0;
1384 
1385 	mac = sap_get_mac_context();
1386 	if (!mac) {
1387 		sap_err("Invalid MAC context");
1388 		return CH_WIDTH_20MHZ;
1389 	}
1390 
1391 	if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) {
1392 		/*
1393 		 * currently OBSS scan is done in hostapd, so to avoid
1394 		 * SAP coming up in HT40 on channel switch we are
1395 		 * disabling channel bonding in 2.4Ghz.
1396 		 */
1397 		ch_width = wlansap_2g_original_bw_validate(
1398 				sap_context, chan_freq, CH_WIDTH_20MHZ,
1399 				&sec_ch_freq);
1400 	} else {
1401 		wlan_mlme_get_channel_bonding_5ghz(mac->psoc,
1402 						   &channel_bonding_mode);
1403 		if (policy_mgr_is_vdev_ll_lt_sap(mac->psoc,
1404 						 sap_context->vdev_id) ||
1405 		    (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq) &&
1406 		     !channel_bonding_mode))
1407 			ch_width = CH_WIDTH_20MHZ;
1408 		else
1409 			ch_width = wlansap_get_max_bw_by_phymode(sap_context);
1410 
1411 		ch_width = wlansap_5g_original_bw_validate(
1412 				sap_context, chan_freq, ch_width);
1413 		concurrent_bw = wlan_sap_get_concurrent_bw(
1414 				mac->pdev, mac->psoc, chan_freq,
1415 				ch_width);
1416 		ch_width = QDF_MIN(ch_width, concurrent_bw);
1417 		if (tgt_ch_params)
1418 			ch_width = QDF_MIN(ch_width, tgt_ch_params->ch_width);
1419 	}
1420 	ch_params.ch_width = ch_width;
1421 	if (sap_phymode_is_eht(sap_context->phyMode))
1422 		wlan_reg_set_create_punc_bitmap(&ch_params, true);
1423 	wlan_reg_set_channel_params_for_pwrmode(mac->pdev, chan_freq,
1424 						sec_ch_freq, &ch_params,
1425 						REG_CURRENT_PWR_MODE);
1426 	ch_width = ch_params.ch_width;
1427 	if (tgt_ch_params)
1428 		*tgt_ch_params = ch_params;
1429 	sap_nofl_debug("csa freq %d bw %d (phymode %d con bw %d tgt bw %d orig %d reason %d) channel bonding 5g %d",
1430 		       chan_freq, ch_width,
1431 		       sap_context->phyMode,
1432 		       concurrent_bw,
1433 		       tgt_ch_params ? tgt_ch_params->ch_width : CH_WIDTH_MAX,
1434 		       sap_context->ch_width_orig,
1435 		       sap_context->csa_reason,
1436 		       channel_bonding_mode);
1437 
1438 	return ch_width;
1439 }
1440 
1441 /**
1442  * sap_start_csa_restart() - send csa start event
1443  * @mac: mac ctx
1444  * @sap_ctx: SAP context
1445  *
1446  * Return: QDF_STATUS
1447  */
1448 static inline void sap_start_csa_restart(struct mac_context *mac,
1449 					 struct sap_context *sap_ctx)
1450 {
1451 	sme_csa_restart(mac, sap_ctx->sessionId);
1452 }
1453 
1454 /**
1455  * sap_get_csa_reason_str() - Get csa reason in string
1456  * @reason: sap reason enum value
1457  *
1458  * Return: string reason
1459  */
1460 const char *sap_get_csa_reason_str(enum sap_csa_reason_code reason)
1461 {
1462 	switch (reason) {
1463 	case CSA_REASON_UNKNOWN:
1464 		return "UNKNOWN";
1465 	case CSA_REASON_STA_CONNECT_DFS_TO_NON_DFS:
1466 		return "STA_CONNECT_DFS_TO_NON_DFS";
1467 	case CSA_REASON_USER_INITIATED:
1468 		return "USER_INITIATED";
1469 	case CSA_REASON_PEER_ACTION_FRAME:
1470 		return "PEER_ACTION_FRAME";
1471 	case CSA_REASON_PRE_CAC_SUCCESS:
1472 		return "PRE_CAC_SUCCESS";
1473 	case CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL:
1474 		return "CONCURRENT_STA_CHANGED_CHANNEL";
1475 	case CSA_REASON_UNSAFE_CHANNEL:
1476 		return "UNSAFE_CHANNEL";
1477 	case CSA_REASON_LTE_COEX:
1478 		return "LTE_COEX";
1479 	case CSA_REASON_CONCURRENT_NAN_EVENT:
1480 		return "CONCURRENT_NAN_EVENT";
1481 	case CSA_REASON_BAND_RESTRICTED:
1482 		return "BAND_RESTRICTED";
1483 	case CSA_REASON_DCS:
1484 		return "DCS";
1485 	case CSA_REASON_CHAN_DISABLED:
1486 		return "DISABLED";
1487 	case CSA_REASON_CHAN_PASSIVE:
1488 		return "PASSIVE";
1489 	case CSA_REASON_GO_BSS_STARTED:
1490 		return "GO_BSS_STARTED";
1491 	case CSA_REASON_SAP_ACS:
1492 		return "CSA_REASON_SAP_ACS";
1493 	case CSA_REASON_SAP_FIX_CH_CONC_WITH_GO:
1494 		return "SAP_FIX_CH_CONC_WITH_GO";
1495 	default:
1496 		return "UNKNOWN";
1497 	}
1498 }
1499 
1500 /**
1501  * wlansap_set_chan_params_for_csa() - Update sap channel parameters
1502  *    for channel switch
1503  * @mac: mac ctx
1504  * @sap_ctx: sap context
1505  * @target_chan_freq: target channel frequency in MHz
1506  * @target_bw: target bandwidth
1507  *
1508  * Return: QDF_STATUS_SUCCESS for success.
1509  */
1510 static QDF_STATUS
1511 wlansap_set_chan_params_for_csa(struct mac_context *mac,
1512 				struct sap_context *sap_ctx,
1513 				uint32_t target_chan_freq,
1514 				enum phy_ch_width target_bw)
1515 {
1516 	struct ch_params tmp_ch_params = {0};
1517 
1518 	tmp_ch_params.ch_width = target_bw;
1519 	mac->sap.SapDfsInfo.new_chanWidth =
1520 		wlansap_get_csa_chanwidth_from_phymode(sap_ctx,
1521 						       target_chan_freq,
1522 						       &tmp_ch_params);
1523 	/*
1524 	 * Copy the requested target channel
1525 	 * to sap context.
1526 	 */
1527 	mac->sap.SapDfsInfo.target_chan_freq = target_chan_freq;
1528 	mac->sap.SapDfsInfo.new_ch_params.ch_width =
1529 		mac->sap.SapDfsInfo.new_chanWidth;
1530 
1531 	/* By this time, the best bandwidth is calculated for
1532 	 * the given target channel. Now, if there was a
1533 	 * request from user to move to a selected bandwidth,
1534 	 * we can see if it can be honored.
1535 	 *
1536 	 * Ex1: BW80 was selected for the target channel and
1537 	 * user wants BW40, it can be allowed
1538 	 * Ex2: BW40 was selected for the target channel and
1539 	 * user wants BW80, it cannot be allowed for the given
1540 	 * target channel.
1541 	 *
1542 	 * So, the MIN of the selected channel bandwidth and
1543 	 * user input is used for the bandwidth
1544 	 */
1545 	if (target_bw != CH_WIDTH_MAX) {
1546 		sap_nofl_debug("SAP CSA: target bw:%d new width:%d",
1547 			       target_bw,
1548 			       mac->sap.SapDfsInfo.new_ch_params.ch_width);
1549 		mac->sap.SapDfsInfo.new_ch_params.ch_width =
1550 			mac->sap.SapDfsInfo.new_chanWidth =
1551 			QDF_MIN(mac->sap.SapDfsInfo.new_ch_params.ch_width,
1552 				target_bw);
1553 	}
1554 	if (sap_phymode_is_eht(sap_ctx->phyMode))
1555 		wlan_reg_set_create_punc_bitmap(&sap_ctx->ch_params, true);
1556 	wlan_reg_set_channel_params_for_pwrmode(
1557 		mac->pdev, target_chan_freq, 0,
1558 		&mac->sap.SapDfsInfo.new_ch_params,
1559 		REG_CURRENT_PWR_MODE);
1560 
1561 	return QDF_STATUS_SUCCESS;
1562 }
1563 
1564 bool
1565 wlansap_override_csa_strict_for_sap(mac_handle_t mac_handle,
1566 				    struct sap_context *sap_ctx,
1567 				    uint32_t target_chan_freq,
1568 				    bool strict)
1569 {
1570 	uint8_t existing_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
1571 	enum policy_mgr_con_mode existing_vdev_mode = PM_MAX_NUM_OF_MODE;
1572 	uint32_t con_freq;
1573 	enum phy_ch_width ch_width;
1574 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
1575 
1576 	if (!mac_ctx || !sap_ctx->vdev ||
1577 	    wlan_vdev_mlme_get_opmode(sap_ctx->vdev) != QDF_SAP_MODE)
1578 		return strict;
1579 
1580 	if (sap_ctx->csa_reason != CSA_REASON_USER_INITIATED)
1581 		return strict;
1582 
1583 	if (!policy_mgr_is_force_scc(mac_ctx->psoc))
1584 		return strict;
1585 
1586 	existing_vdev_id =
1587 		policy_mgr_fetch_existing_con_info(
1588 				mac_ctx->psoc,
1589 				sap_ctx->sessionId,
1590 				target_chan_freq,
1591 				&existing_vdev_mode,
1592 				&con_freq, &ch_width);
1593 	if (existing_vdev_id < WLAN_UMAC_VDEV_ID_MAX &&
1594 	    (existing_vdev_mode == PM_STA_MODE ||
1595 	     existing_vdev_mode == PM_P2P_CLIENT_MODE))
1596 		return strict;
1597 
1598 	return true;
1599 }
1600 
1601 QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sap_ctx,
1602 					       uint32_t target_chan_freq,
1603 					       enum phy_ch_width target_bw,
1604 					       bool strict)
1605 {
1606 	struct mac_context *mac;
1607 	mac_handle_t mac_handle;
1608 	bool valid;
1609 	QDF_STATUS status, hw_mode_status;
1610 	bool sta_sap_scc_on_dfs_chan;
1611 	bool is_dfs;
1612 	struct ch_params tmp_ch_params = {0};
1613 	enum channel_state state;
1614 
1615 	if (!sap_ctx) {
1616 		sap_err("Invalid SAP pointer");
1617 
1618 		return QDF_STATUS_E_FAULT;
1619 	}
1620 
1621 	mac = sap_get_mac_context();
1622 	if (!mac) {
1623 		sap_err("Invalid MAC context");
1624 		return QDF_STATUS_E_FAULT;
1625 	}
1626 	mac_handle = MAC_HANDLE(mac);
1627 
1628 	if (((sap_ctx->acs_cfg && sap_ctx->acs_cfg->acs_mode) ||
1629 	     policy_mgr_restrict_sap_on_unsafe_chan(mac->psoc) ||
1630 	     sap_ctx->csa_reason != CSA_REASON_USER_INITIATED) &&
1631 	    !policy_mgr_is_sap_freq_allowed(mac->psoc, target_chan_freq)) {
1632 		sap_err("%u is unsafe channel freq", target_chan_freq);
1633 		return QDF_STATUS_E_FAULT;
1634 	}
1635 	sap_nofl_debug("SAP CSA: %d BW %d ---> %d BW %d conn on 5GHz:%d, csa_reason:%s(%d) strict %d vdev %d",
1636 		       sap_ctx->chan_freq, sap_ctx->ch_params.ch_width,
1637 		       target_chan_freq, target_bw,
1638 		       policy_mgr_is_any_mode_active_on_band_along_with_session(
1639 		       mac->psoc, sap_ctx->sessionId, POLICY_MGR_BAND_5),
1640 		       sap_get_csa_reason_str(sap_ctx->csa_reason),
1641 		       sap_ctx->csa_reason, strict, sap_ctx->sessionId);
1642 
1643 	state = wlan_reg_get_channel_state_for_pwrmode(mac->pdev,
1644 						       target_chan_freq,
1645 						       REG_CURRENT_PWR_MODE);
1646 	if (state == CHANNEL_STATE_DISABLE || state == CHANNEL_STATE_INVALID) {
1647 		sap_nofl_debug("invalid target freq %d state %d",
1648 			       target_chan_freq, state);
1649 		return QDF_STATUS_E_INVAL;
1650 	}
1651 
1652 	sta_sap_scc_on_dfs_chan =
1653 		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(mac->psoc);
1654 
1655 	tmp_ch_params.ch_width = target_bw;
1656 	wlansap_get_csa_chanwidth_from_phymode(sap_ctx,
1657 					       target_chan_freq,
1658 					       &tmp_ch_params);
1659 	if (target_bw != CH_WIDTH_MAX) {
1660 		tmp_ch_params.ch_width =
1661 			QDF_MIN(tmp_ch_params.ch_width, target_bw);
1662 		sap_nofl_debug("target ch_width %d to %d ", target_bw,
1663 			       tmp_ch_params.ch_width);
1664 	}
1665 
1666 	if (sap_phymode_is_eht(sap_ctx->phyMode))
1667 		wlan_reg_set_create_punc_bitmap(&tmp_ch_params, true);
1668 	wlan_reg_set_channel_params_for_pwrmode(mac->pdev, target_chan_freq, 0,
1669 						&tmp_ch_params,
1670 						REG_CURRENT_PWR_MODE);
1671 	if (sap_ctx->chan_freq == target_chan_freq &&
1672 	    sap_ctx->ch_params.ch_width == tmp_ch_params.ch_width) {
1673 		sap_nofl_debug("target freq and bw %d not changed",
1674 			       tmp_ch_params.ch_width);
1675 		return QDF_STATUS_E_FAULT;
1676 	}
1677 	is_dfs = wlan_mlme_check_chan_param_has_dfs(
1678 			mac->pdev, &tmp_ch_params,
1679 			target_chan_freq);
1680 	/*
1681 	 * Now, validate if the passed channel is valid in the
1682 	 * current regulatory domain.
1683 	 */
1684 	if (!is_dfs ||
1685 	    (!policy_mgr_is_any_mode_active_on_band_along_with_session(
1686 			mac->psoc, sap_ctx->sessionId,
1687 			POLICY_MGR_BAND_5) ||
1688 			sta_sap_scc_on_dfs_chan ||
1689 			sap_ctx->csa_reason == CSA_REASON_DCS)) {
1690 		/*
1691 		 * validate target channel switch w.r.t various concurrency
1692 		 * rules set.
1693 		 */
1694 		if (!strict) {
1695 			valid = wlan_sap_validate_channel_switch(mac_handle,
1696 								 target_chan_freq,
1697 								 sap_ctx);
1698 			if (!valid) {
1699 				sap_err("Channel freq switch to %u is not allowed due to concurrent channel interference",
1700 					target_chan_freq);
1701 				return QDF_STATUS_E_FAULT;
1702 			}
1703 		}
1704 		/*
1705 		 * Post a CSA IE request to SAP state machine with
1706 		 * target channel information and also CSA IE required
1707 		 * flag set in sap_ctx only, if SAP is in SAP_STARTED
1708 		 * state.
1709 		 */
1710 		if (sap_ctx->fsm_state == SAP_STARTED) {
1711 			status = wlansap_set_chan_params_for_csa(
1712 					mac, sap_ctx, target_chan_freq,
1713 					target_bw);
1714 			if (QDF_IS_STATUS_ERROR(status))
1715 				return status;
1716 
1717 			hw_mode_status =
1718 			  policy_mgr_check_and_set_hw_mode_for_channel_switch(
1719 				   mac->psoc, sap_ctx->sessionId,
1720 				   target_chan_freq,
1721 				   POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_SAP);
1722 
1723 			/*
1724 			 * If hw_mode_status is QDF_STATUS_E_FAILURE, mean HW
1725 			 * mode change was required but driver failed to set HW
1726 			 * mode so ignore CSA for the channel.
1727 			 */
1728 			if (hw_mode_status == QDF_STATUS_E_FAILURE) {
1729 				sap_err("HW change required but failed to set hw mode");
1730 				return hw_mode_status;
1731 			}
1732 
1733 			status = policy_mgr_reset_chan_switch_complete_evt(
1734 								mac->psoc);
1735 			if (QDF_IS_STATUS_ERROR(status)) {
1736 				policy_mgr_check_n_start_opportunistic_timer(
1737 								mac->psoc);
1738 				return status;
1739 			}
1740 
1741 			/*
1742 			 * Set the CSA IE required flag.
1743 			 */
1744 			mac->sap.SapDfsInfo.csaIERequired = true;
1745 
1746 			/*
1747 			 * Set the radar found status to allow the channel
1748 			 * change to happen same as in the case of a radar
1749 			 * detection. Since, this will allow SAP to be in
1750 			 * correct state and also resume the netif queues
1751 			 * that were suspended in HDD before the channel
1752 			 * request was issued.
1753 			 */
1754 			sap_ctx->sap_radar_found_status = true;
1755 			sap_cac_reset_notify(mac_handle);
1756 
1757 			/*
1758 			 * If hw_mode_status is QDF_STATUS_SUCCESS mean HW mode
1759 			 * change was required and was successfully requested so
1760 			 * the channel switch will continue after HW mode change
1761 			 * completion.
1762 			 */
1763 			if (QDF_IS_STATUS_SUCCESS(hw_mode_status)) {
1764 				sap_info("Channel change will continue after HW mode change");
1765 				return QDF_STATUS_SUCCESS;
1766 			}
1767 			/*
1768 			 * If hw_mode_status is QDF_STATUS_E_NOSUPPORT or
1769 			 * QDF_STATUS_E_ALREADY (not QDF_STATUS_E_FAILURE and
1770 			 * not QDF_STATUS_SUCCESS), mean DBS is not supported or
1771 			 * required HW mode is already set, So contunue with
1772 			 * CSA from here.
1773 			 */
1774 			sap_start_csa_restart(mac, sap_ctx);
1775 		} else {
1776 			sap_err("Failed to request Channel Change, since SAP is not in SAP_STARTED state");
1777 			return QDF_STATUS_E_FAULT;
1778 		}
1779 
1780 	} else {
1781 		sap_err("Channel freq = %d is not valid in the current"
1782 			"regulatory domain, is_dfs %d", target_chan_freq,
1783 			is_dfs);
1784 
1785 		return QDF_STATUS_E_FAULT;
1786 	}
1787 
1788 	return QDF_STATUS_SUCCESS;
1789 }
1790 
1791 QDF_STATUS wlan_sap_getstation_ie_information(struct sap_context *sap_ctx,
1792 					      uint32_t *len, uint8_t *buf)
1793 {
1794 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
1795 	uint32_t ie_len = 0;
1796 
1797 	if (!sap_ctx) {
1798 		sap_err("Invalid SAP pointer");
1799 		return QDF_STATUS_E_FAULT;
1800 	}
1801 
1802 	if (len) {
1803 		ie_len = *len;
1804 		*len = sap_ctx->nStaWPARSnReqIeLength;
1805 		sap_info("WPAIE len : %x", *len);
1806 		if ((buf) && (ie_len >= sap_ctx->nStaWPARSnReqIeLength)) {
1807 			qdf_mem_copy(buf,
1808 				sap_ctx->pStaWpaRsnReqIE,
1809 				sap_ctx->nStaWPARSnReqIeLength);
1810 			sap_info("WPAIE: "QDF_MAC_ADDR_FMT,
1811 				 QDF_MAC_ADDR_REF(buf));
1812 			qdf_status = QDF_STATUS_SUCCESS;
1813 		}
1814 	}
1815 	return qdf_status;
1816 }
1817 
1818 QDF_STATUS wlan_sap_update_next_channel(struct sap_context *sap_ctx,
1819 					uint8_t channel,
1820 					enum phy_ch_width chan_bw)
1821 {
1822 	if (!sap_ctx) {
1823 		sap_err("Invalid SAP pointer");
1824 		return QDF_STATUS_E_FAULT;
1825 	}
1826 
1827 	sap_ctx->dfs_vendor_channel = channel;
1828 	sap_ctx->dfs_vendor_chan_bw = chan_bw;
1829 
1830 	return QDF_STATUS_SUCCESS;
1831 }
1832 
1833 void wlansap_get_sec_channel(uint8_t sec_ch_offset,
1834 			     uint32_t op_chan_freq,
1835 			     uint32_t *sec_chan_freq)
1836 {
1837 	switch (sec_ch_offset) {
1838 	case LOW_PRIMARY_CH:
1839 		*sec_chan_freq = op_chan_freq + 20;
1840 		break;
1841 	case HIGH_PRIMARY_CH:
1842 		*sec_chan_freq = op_chan_freq - 20;
1843 		break;
1844 	default:
1845 		*sec_chan_freq = 0;
1846 	}
1847 }
1848 
1849 #ifdef WLAN_FEATURE_11BE
1850 static void
1851 wlansap_fill_channel_change_puncture(struct channel_change_req *req,
1852 				     struct ch_params *ch_param)
1853 {
1854 	req->target_punc_bitmap = ch_param->reg_punc_bitmap;
1855 }
1856 #else
1857 static inline void
1858 wlansap_fill_channel_change_puncture(struct channel_change_req *req,
1859 				     struct ch_params *ch_param)
1860 {
1861 }
1862 #endif
1863 
1864 /**
1865  * wlansap_fill_channel_change_request() - Fills the channel change request
1866  * @sap_ctx: sap context
1867  * @req: pointer to change channel request
1868  *
1869  * This function fills the channel change request for SAP
1870  *
1871  * Return: None
1872  */
1873 static void
1874 wlansap_fill_channel_change_request(struct sap_context *sap_ctx,
1875 				    struct channel_change_req *req)
1876 {
1877 	struct mac_context *mac_ctx = sap_get_mac_context();
1878 	struct bss_dot11_config dot11_cfg = {0};
1879 	uint8_t h2e;
1880 
1881 	dot11_cfg.vdev_id = sap_ctx->sessionId;
1882 	dot11_cfg.bss_op_ch_freq = sap_ctx->chan_freq;
1883 	dot11_cfg.phy_mode = sap_ctx->phyMode;
1884 	dot11_cfg.privacy = sap_ctx->sap_bss_cfg.privacy;
1885 
1886 	/* Rates configured from start_bss will have
1887 	 * hostapd rates if hostapd chan rates are enabled
1888 	 */
1889 	qdf_mem_copy(dot11_cfg.opr_rates.rate,
1890 		     sap_ctx->sap_bss_cfg.operationalRateSet.rate,
1891 		     sap_ctx->sap_bss_cfg.operationalRateSet.numRates);
1892 	dot11_cfg.opr_rates.numRates =
1893 		sap_ctx->sap_bss_cfg.operationalRateSet.numRates;
1894 
1895 	qdf_mem_copy(dot11_cfg.ext_rates.rate,
1896 		     sap_ctx->sap_bss_cfg.extendedRateSet.rate,
1897 		     sap_ctx->sap_bss_cfg.extendedRateSet.numRates);
1898 	dot11_cfg.ext_rates.numRates =
1899 		sap_ctx->sap_bss_cfg.extendedRateSet.numRates;
1900 	sme_get_network_params(mac_ctx, &dot11_cfg);
1901 
1902 	req->vdev_id = sap_ctx->sessionId;
1903 	req->target_chan_freq = sap_ctx->chan_freq;
1904 	req->sec_ch_offset = sap_ctx->ch_params.sec_ch_offset;
1905 	req->ch_width =  sap_ctx->ch_params.ch_width;
1906 	req->center_freq_seg0 = sap_ctx->ch_params.center_freq_seg0;
1907 	req->center_freq_seg1 = sap_ctx->ch_params.center_freq_seg1;
1908 	wlansap_fill_channel_change_puncture(req, &sap_ctx->ch_params);
1909 
1910 	req->dot11mode = dot11_cfg.dot11_mode;
1911 	req->nw_type = dot11_cfg.nw_type;
1912 
1913 	sap_get_cac_dur_dfs_region(sap_ctx,
1914 				   &req->cac_duration_ms,
1915 				   &req->dfs_regdomain,
1916 				   sap_ctx->chan_freq,
1917 				   &sap_ctx->ch_params);
1918 	mlme_set_cac_required(sap_ctx->vdev,
1919 			      !!req->cac_duration_ms);
1920 
1921 	/* Update the rates in sap_bss_cfg for subsequent channel switch */
1922 	if (dot11_cfg.opr_rates.numRates) {
1923 		qdf_mem_copy(req->opr_rates.rate,
1924 			     dot11_cfg.opr_rates.rate,
1925 			     dot11_cfg.opr_rates.numRates);
1926 		qdf_mem_copy(sap_ctx->sap_bss_cfg.operationalRateSet.rate,
1927 			     dot11_cfg.opr_rates.rate,
1928 			     dot11_cfg.opr_rates.numRates);
1929 		req->opr_rates.numRates = dot11_cfg.opr_rates.numRates;
1930 		sap_ctx->sap_bss_cfg.operationalRateSet.numRates =
1931 					dot11_cfg.opr_rates.numRates;
1932 	} else {
1933 		qdf_mem_zero(&sap_ctx->sap_bss_cfg.operationalRateSet,
1934 			     sizeof(tSirMacRateSet));
1935 	}
1936 
1937 	if (dot11_cfg.ext_rates.numRates) {
1938 		qdf_mem_copy(req->ext_rates.rate,
1939 			     dot11_cfg.ext_rates.rate,
1940 			     dot11_cfg.ext_rates.numRates);
1941 		qdf_mem_copy(sap_ctx->sap_bss_cfg.extendedRateSet.rate,
1942 			     dot11_cfg.ext_rates.rate,
1943 			     dot11_cfg.ext_rates.numRates);
1944 		req->ext_rates.numRates = dot11_cfg.ext_rates.numRates;
1945 		sap_ctx->sap_bss_cfg.extendedRateSet.numRates =
1946 					dot11_cfg.ext_rates.numRates;
1947 	} else {
1948 		qdf_mem_zero(&sap_ctx->sap_bss_cfg.extendedRateSet,
1949 			     sizeof(tSirMacRateSet));
1950 	}
1951 
1952 	if (sap_ctx->require_h2e) {
1953 		h2e = WLAN_BASIC_RATE_MASK |
1954 			WLAN_BSS_MEMBERSHIP_SELECTOR_SAE_H2E;
1955 		if (req->ext_rates.numRates < SIR_MAC_MAX_NUMBER_OF_RATES) {
1956 			req->ext_rates.rate[req->ext_rates.numRates] = h2e;
1957 			req->ext_rates.numRates++;
1958 			sap_debug("H2E bss membership add to ext support rate");
1959 		} else if (req->opr_rates.numRates <
1960 						SIR_MAC_MAX_NUMBER_OF_RATES) {
1961 			req->opr_rates.rate[req->opr_rates.numRates] = h2e;
1962 			req->opr_rates.numRates++;
1963 			sap_debug("H2E bss membership add to support rate");
1964 		} else {
1965 			sap_err("rates full, can not add H2E bss membership");
1966 		}
1967 	}
1968 	return;
1969 }
1970 
1971 QDF_STATUS wlansap_channel_change_request(struct sap_context *sap_ctx,
1972 					  uint32_t target_chan_freq)
1973 {
1974 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
1975 	struct mac_context *mac_ctx;
1976 	eCsrPhyMode phy_mode;
1977 	struct ch_params *ch_params;
1978 	struct channel_change_req *ch_change_req;
1979 
1980 	if (!target_chan_freq) {
1981 		sap_err("channel 0 requested");
1982 		return QDF_STATUS_E_FAULT;
1983 	}
1984 
1985 	if (!sap_ctx) {
1986 		sap_err("Invalid SAP pointer");
1987 		return QDF_STATUS_E_FAULT;
1988 	}
1989 
1990 	mac_ctx = sap_get_mac_context();
1991 	if (!mac_ctx) {
1992 		sap_err("Invalid MAC context");
1993 		return QDF_STATUS_E_FAULT;
1994 	}
1995 
1996 	phy_mode = sap_ctx->phyMode;
1997 
1998 	/* Update phy_mode if the target channel is in the other band */
1999 	if (WLAN_REG_IS_5GHZ_CH_FREQ(target_chan_freq) &&
2000 	    ((phy_mode == eCSR_DOT11_MODE_11g) ||
2001 	    (phy_mode == eCSR_DOT11_MODE_11g_ONLY)))
2002 		phy_mode = eCSR_DOT11_MODE_11a;
2003 	else if (WLAN_REG_IS_24GHZ_CH_FREQ(target_chan_freq) &&
2004 		 (phy_mode == eCSR_DOT11_MODE_11a))
2005 		phy_mode = eCSR_DOT11_MODE_11g;
2006 	sap_ctx->phyMode = phy_mode;
2007 
2008 	if (!sap_ctx->chan_freq) {
2009 		sap_err("Invalid channel list");
2010 		return QDF_STATUS_E_FAULT;
2011 	}
2012 	/*
2013 	 * We are getting channel bonding mode from sapDfsInfor structure
2014 	 * because we've implemented channel width fallback mechanism for DFS
2015 	 * which will result in channel width changing dynamically.
2016 	 */
2017 	ch_params = &mac_ctx->sap.SapDfsInfo.new_ch_params;
2018 	if (sap_phymode_is_eht(sap_ctx->phyMode))
2019 		wlan_reg_set_create_punc_bitmap(ch_params, true);
2020 	wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev, target_chan_freq,
2021 						0, ch_params,
2022 						REG_CURRENT_PWR_MODE);
2023 	sap_ctx->ch_params = *ch_params;
2024 	sap_ctx->freq_before_ch_switch = sap_ctx->chan_freq;
2025 	/* Update the channel as this will be used to
2026 	 * send event to supplicant
2027 	 */
2028 	sap_ctx->chan_freq = target_chan_freq;
2029 	wlansap_get_sec_channel(ch_params->sec_ch_offset, sap_ctx->chan_freq,
2030 				&sap_ctx->sec_ch_freq);
2031 	sap_dfs_set_current_channel(sap_ctx);
2032 
2033 	ch_change_req = qdf_mem_malloc(sizeof(struct channel_change_req));
2034 	if (!ch_change_req)
2035 		return QDF_STATUS_E_FAILURE;
2036 
2037 	wlansap_fill_channel_change_request(sap_ctx, ch_change_req);
2038 
2039 	status = sme_send_channel_change_req(MAC_HANDLE(mac_ctx),
2040 					     ch_change_req);
2041 	qdf_mem_free(ch_change_req);
2042 	sap_debug("chan_freq:%d phy_mode %d width:%d offset:%d seg0:%d seg1:%d",
2043 		  sap_ctx->chan_freq, phy_mode, ch_params->ch_width,
2044 		  ch_params->sec_ch_offset, ch_params->center_freq_seg0,
2045 		  ch_params->center_freq_seg1);
2046 	if (policy_mgr_update_indoor_concurrency(mac_ctx->psoc,
2047 						wlan_vdev_get_id(sap_ctx->vdev),
2048 						sap_ctx->freq_before_ch_switch,
2049 						DISCONNECT_WITH_CONCURRENCY))
2050 		wlan_reg_recompute_current_chan_list(mac_ctx->psoc,
2051 						     mac_ctx->pdev);
2052 
2053 	return status;
2054 }
2055 
2056 QDF_STATUS wlansap_start_beacon_req(struct sap_context *sap_ctx)
2057 {
2058 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2059 	uint8_t dfs_cac_wait_status;
2060 	struct mac_context *mac;
2061 
2062 	if (!sap_ctx) {
2063 		sap_err("Invalid SAP pointer");
2064 		return QDF_STATUS_E_FAULT;
2065 	}
2066 
2067 	mac = sap_get_mac_context();
2068 	if (!mac) {
2069 		sap_err("Invalid MAC context");
2070 		return QDF_STATUS_E_FAULT;
2071 	}
2072 
2073 	/* No Radar was found during CAC WAIT, So start Beaconing */
2074 	if (!sap_ctx->sap_radar_found_status) {
2075 		/* CAC Wait done without any Radar Detection */
2076 		dfs_cac_wait_status = true;
2077 		wlan_pre_cac_complete_set(sap_ctx->vdev, false);
2078 		status = sme_roam_start_beacon_req(MAC_HANDLE(mac),
2079 						   sap_ctx->bssid,
2080 						   dfs_cac_wait_status);
2081 	}
2082 
2083 	return status;
2084 }
2085 
2086 QDF_STATUS wlansap_dfs_send_csa_ie_request(struct sap_context *sap_ctx)
2087 {
2088 	struct mac_context *mac;
2089 	uint32_t new_cac_ms;
2090 	uint32_t dfs_region;
2091 
2092 	if (!sap_ctx) {
2093 		sap_err("Invalid SAP pointer");
2094 		return QDF_STATUS_E_FAULT;
2095 	}
2096 
2097 	mac = sap_get_mac_context();
2098 	if (!mac) {
2099 		sap_err("Invalid MAC context");
2100 		return QDF_STATUS_E_FAULT;
2101 	}
2102 
2103 	mac->sap.SapDfsInfo.new_ch_params.ch_width =
2104 				mac->sap.SapDfsInfo.new_chanWidth;
2105 	if (sap_phymode_is_eht(sap_ctx->phyMode))
2106 		wlan_reg_set_create_punc_bitmap(
2107 			&mac->sap.SapDfsInfo.new_ch_params, true);
2108 	wlan_reg_set_channel_params_for_pwrmode(mac->pdev,
2109 			mac->sap.SapDfsInfo.target_chan_freq,
2110 			0, &mac->sap.SapDfsInfo.new_ch_params,
2111 			REG_CURRENT_PWR_MODE);
2112 
2113 	sap_get_cac_dur_dfs_region(sap_ctx, &new_cac_ms, &dfs_region,
2114 				   mac->sap.SapDfsInfo.target_chan_freq,
2115 				   &mac->sap.SapDfsInfo.new_ch_params);
2116 	mlme_set_cac_required(sap_ctx->vdev, !!new_cac_ms);
2117 	sap_debug("chan freq:%d req:%d width:%d off:%d cac %d",
2118 		  mac->sap.SapDfsInfo.target_chan_freq,
2119 		  mac->sap.SapDfsInfo.csaIERequired,
2120 		  mac->sap.SapDfsInfo.new_ch_params.ch_width,
2121 		  mac->sap.SapDfsInfo.new_ch_params.sec_ch_offset,
2122 		  new_cac_ms);
2123 
2124 	return sme_roam_csa_ie_request(MAC_HANDLE(mac),
2125 				       sap_ctx->bssid,
2126 				       mac->sap.SapDfsInfo.target_chan_freq,
2127 				       mac->sap.SapDfsInfo.csaIERequired,
2128 				       &mac->sap.SapDfsInfo.new_ch_params,
2129 				       new_cac_ms);
2130 }
2131 
2132 QDF_STATUS wlansap_get_dfs_ignore_cac(mac_handle_t mac_handle,
2133 				      uint8_t *ignore_cac)
2134 {
2135 	struct mac_context *mac = NULL;
2136 
2137 	if (mac_handle) {
2138 		mac = MAC_CONTEXT(mac_handle);
2139 	} else {
2140 		sap_err("Invalid mac_handle pointer");
2141 		return QDF_STATUS_E_FAULT;
2142 	}
2143 
2144 	*ignore_cac = mac->sap.SapDfsInfo.ignore_cac;
2145 	return QDF_STATUS_SUCCESS;
2146 }
2147 
2148 QDF_STATUS wlansap_set_dfs_ignore_cac(mac_handle_t mac_handle,
2149 				      uint8_t ignore_cac)
2150 {
2151 	struct mac_context *mac = NULL;
2152 
2153 	if (mac_handle) {
2154 		mac = MAC_CONTEXT(mac_handle);
2155 	} else {
2156 		sap_err("Invalid mac_handle pointer");
2157 		return QDF_STATUS_E_FAULT;
2158 	}
2159 
2160 	mac->sap.SapDfsInfo.ignore_cac = (ignore_cac >= true) ?
2161 					  true : false;
2162 	return QDF_STATUS_SUCCESS;
2163 }
2164 
2165 QDF_STATUS wlansap_get_dfs_cac_state(mac_handle_t mac_handle,
2166 				     struct sap_context *sapcontext,
2167 				     bool *cac_state)
2168 {
2169 	struct mac_context *mac = NULL;
2170 
2171 	if (mac_handle) {
2172 		mac = MAC_CONTEXT(mac_handle);
2173 	} else {
2174 		sap_err("Invalid mac_handle pointer");
2175 		return QDF_STATUS_E_FAULT;
2176 	}
2177 	if (!sapcontext) {
2178 		sap_err("Invalid sapcontext pointer");
2179 		return QDF_STATUS_E_FAULT;
2180 	}
2181 
2182 	*cac_state = sap_is_dfs_cac_wait_state(sapcontext);
2183 
2184 	return QDF_STATUS_SUCCESS;
2185 }
2186 
2187 bool sap_is_auto_channel_select(struct sap_context *sapcontext)
2188 {
2189 	if (!sapcontext) {
2190 		sap_err("Invalid SAP pointer");
2191 		return false;
2192 	}
2193 	return sapcontext->chan_freq == AUTO_CHANNEL_SELECT;
2194 }
2195 
2196 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2197 /**
2198  * wlan_sap_set_channel_avoidance() - sets sap mcc channel avoidance ini param
2199  * @mac_handle: Opaque handle to the global MAC context
2200  * @sap_channel_avoidance: ini parameter value
2201  *
2202  * sets sap mcc channel avoidance ini param, to be called in sap_start
2203  *
2204  * Return: success of failure of operation
2205  */
2206 QDF_STATUS
2207 wlan_sap_set_channel_avoidance(mac_handle_t mac_handle,
2208 			       bool sap_channel_avoidance)
2209 {
2210 	struct mac_context *mac_ctx = NULL;
2211 
2212 	if (mac_handle) {
2213 		mac_ctx = MAC_CONTEXT(mac_handle);
2214 	} else {
2215 		sap_err("mac_handle or mac_ctx pointer NULL");
2216 		return QDF_STATUS_E_FAULT;
2217 	}
2218 	mac_ctx->sap.sap_channel_avoidance = sap_channel_avoidance;
2219 	return QDF_STATUS_SUCCESS;
2220 }
2221 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2222 
2223 QDF_STATUS
2224 wlan_sap_set_acs_with_more_param(mac_handle_t mac_handle,
2225 				 bool acs_with_more_param)
2226 {
2227 	struct mac_context *mac_ctx;
2228 
2229 	if (mac_handle) {
2230 		mac_ctx = MAC_CONTEXT(mac_handle);
2231 	} else {
2232 		sap_err("mac_handle or mac_ctx pointer NULL");
2233 		return QDF_STATUS_E_FAULT;
2234 	}
2235 	mac_ctx->sap.acs_with_more_param = acs_with_more_param;
2236 	return QDF_STATUS_SUCCESS;
2237 }
2238 
2239 QDF_STATUS
2240 wlansap_set_dfs_preferred_channel_location(mac_handle_t mac_handle)
2241 {
2242 	struct mac_context *mac = NULL;
2243 	QDF_STATUS status;
2244 	enum dfs_reg dfs_region;
2245 	uint8_t dfs_preferred_channels_location = 0;
2246 
2247 	if (mac_handle) {
2248 		mac = MAC_CONTEXT(mac_handle);
2249 	} else {
2250 		sap_err("Invalid mac_handle pointer");
2251 		return QDF_STATUS_E_FAULT;
2252 	}
2253 
2254 	wlan_reg_get_dfs_region(mac->pdev, &dfs_region);
2255 
2256 	/*
2257 	 * The Indoor/Outdoor only random channel selection
2258 	 * restriction is currently enforeced only for
2259 	 * JAPAN regulatory domain.
2260 	 */
2261 	ucfg_mlme_get_pref_chan_location(mac->psoc,
2262 					 &dfs_preferred_channels_location);
2263 	sap_debug("dfs_preferred_channels_location %d dfs region %d",
2264 		  dfs_preferred_channels_location, dfs_region);
2265 
2266 	if (dfs_region == DFS_MKK_REGION ||
2267 	    dfs_region == DFS_MKKN_REGION) {
2268 		mac->sap.SapDfsInfo.sap_operating_chan_preferred_location =
2269 			dfs_preferred_channels_location;
2270 		sap_debug("sapdfs:Set Preferred Operating Channel location=%d",
2271 			  mac->sap.SapDfsInfo.
2272 			  sap_operating_chan_preferred_location);
2273 
2274 		status = QDF_STATUS_SUCCESS;
2275 	} else {
2276 		sap_debug("sapdfs:NOT JAPAN REG, Invalid Set preferred chans location");
2277 
2278 		status = QDF_STATUS_E_FAULT;
2279 	}
2280 
2281 	return status;
2282 }
2283 
2284 QDF_STATUS wlansap_set_dfs_target_chnl(mac_handle_t mac_handle,
2285 				       uint32_t target_chan_freq)
2286 {
2287 	struct mac_context *mac = NULL;
2288 
2289 	if (mac_handle) {
2290 		mac = MAC_CONTEXT(mac_handle);
2291 	} else {
2292 		sap_err("Invalid mac_handle pointer");
2293 		return QDF_STATUS_E_FAULT;
2294 	}
2295 	if (target_chan_freq > 0) {
2296 		mac->sap.SapDfsInfo.user_provided_target_chan_freq =
2297 			target_chan_freq;
2298 	} else {
2299 		mac->sap.SapDfsInfo.user_provided_target_chan_freq = 0;
2300 	}
2301 
2302 	return QDF_STATUS_SUCCESS;
2303 }
2304 
2305 QDF_STATUS
2306 wlansap_update_sap_config_add_ie(struct sap_config *config,
2307 				 const uint8_t *pAdditionIEBuffer,
2308 				 uint16_t additionIELength,
2309 				 eUpdateIEsType updateType)
2310 {
2311 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2312 	uint8_t bufferValid = false;
2313 	uint16_t bufferLength = 0;
2314 	uint8_t *pBuffer = NULL;
2315 
2316 	if (!config) {
2317 		return QDF_STATUS_E_FAULT;
2318 	}
2319 
2320 	if ((pAdditionIEBuffer) && (additionIELength != 0)) {
2321 		/* initialize the buffer pointer so that pe can copy */
2322 		if (additionIELength > 0) {
2323 			bufferLength = additionIELength;
2324 			pBuffer = qdf_mem_malloc(bufferLength);
2325 			if (!pBuffer)
2326 				return QDF_STATUS_E_NOMEM;
2327 
2328 			qdf_mem_copy(pBuffer, pAdditionIEBuffer, bufferLength);
2329 			bufferValid = true;
2330 			sap_debug("update_type: %d", updateType);
2331 			qdf_trace_hex_dump(QDF_MODULE_ID_SAP,
2332 				QDF_TRACE_LEVEL_DEBUG, pBuffer, bufferLength);
2333 		}
2334 	}
2335 
2336 	switch (updateType) {
2337 	case eUPDATE_IE_PROBE_BCN:
2338 		if (config->pProbeRespBcnIEsBuffer)
2339 			qdf_mem_free(config->pProbeRespBcnIEsBuffer);
2340 		if (bufferValid) {
2341 			config->probeRespBcnIEsLen = bufferLength;
2342 			config->pProbeRespBcnIEsBuffer = pBuffer;
2343 		} else {
2344 			config->probeRespBcnIEsLen = 0;
2345 			config->pProbeRespBcnIEsBuffer = NULL;
2346 		}
2347 		break;
2348 	case eUPDATE_IE_PROBE_RESP:
2349 		if (config->pProbeRespIEsBuffer)
2350 			qdf_mem_free(config->pProbeRespIEsBuffer);
2351 		if (bufferValid) {
2352 			config->probeRespIEsBufferLen = bufferLength;
2353 			config->pProbeRespIEsBuffer = pBuffer;
2354 		} else {
2355 			config->probeRespIEsBufferLen = 0;
2356 			config->pProbeRespIEsBuffer = NULL;
2357 		}
2358 		break;
2359 	case eUPDATE_IE_ASSOC_RESP:
2360 		if (config->pAssocRespIEsBuffer)
2361 			qdf_mem_free(config->pAssocRespIEsBuffer);
2362 		if (bufferValid) {
2363 			config->assocRespIEsLen = bufferLength;
2364 			config->pAssocRespIEsBuffer = pBuffer;
2365 		} else {
2366 			config->assocRespIEsLen = 0;
2367 			config->pAssocRespIEsBuffer = NULL;
2368 		}
2369 		break;
2370 	default:
2371 		sap_debug("No matching buffer type %d", updateType);
2372 		if (pBuffer)
2373 			qdf_mem_free(pBuffer);
2374 		break;
2375 	}
2376 
2377 	return status;
2378 }
2379 
2380 QDF_STATUS
2381 wlansap_reset_sap_config_add_ie(struct sap_config *config,
2382 				eUpdateIEsType updateType)
2383 {
2384 	if (!config) {
2385 		sap_err("Invalid Config pointer");
2386 		return QDF_STATUS_E_FAULT;
2387 	}
2388 
2389 	switch (updateType) {
2390 	case eUPDATE_IE_ALL:    /*only used to reset */
2391 	case eUPDATE_IE_PROBE_RESP:
2392 		if (config->pProbeRespIEsBuffer) {
2393 			qdf_mem_free(config->pProbeRespIEsBuffer);
2394 			config->probeRespIEsBufferLen = 0;
2395 			config->pProbeRespIEsBuffer = NULL;
2396 		}
2397 		if (eUPDATE_IE_ALL != updateType)
2398 			break;
2399 		fallthrough;
2400 	case eUPDATE_IE_ASSOC_RESP:
2401 		if (config->pAssocRespIEsBuffer) {
2402 			qdf_mem_free(config->pAssocRespIEsBuffer);
2403 			config->assocRespIEsLen = 0;
2404 			config->pAssocRespIEsBuffer = NULL;
2405 		}
2406 		if (eUPDATE_IE_ALL != updateType)
2407 			break;
2408 		fallthrough;
2409 	case eUPDATE_IE_PROBE_BCN:
2410 		if (config->pProbeRespBcnIEsBuffer) {
2411 			qdf_mem_free(config->pProbeRespBcnIEsBuffer);
2412 			config->probeRespBcnIEsLen = 0;
2413 			config->pProbeRespBcnIEsBuffer = NULL;
2414 		}
2415 		if (eUPDATE_IE_ALL != updateType)
2416 			break;
2417 		fallthrough;
2418 	default:
2419 		if (eUPDATE_IE_ALL != updateType)
2420 			sap_err("Invalid buffer type %d", updateType);
2421 		break;
2422 	}
2423 	return QDF_STATUS_SUCCESS;
2424 }
2425 
2426 #ifdef WLAN_FEATURE_SON
2427 QDF_STATUS
2428 wlansap_son_update_sap_config_phymode(struct wlan_objmgr_vdev *vdev,
2429 				      struct sap_config *config,
2430 				      enum qca_wlan_vendor_phy_mode phy_mode)
2431 {
2432 	struct wlan_objmgr_pdev *pdev;
2433 	struct wlan_objmgr_psoc *psoc;
2434 	struct wlan_channel *des_chan;
2435 
2436 	if (!vdev || !config) {
2437 		sap_err("Invalid input parameters");
2438 		return QDF_STATUS_E_FAULT;
2439 	}
2440 
2441 	pdev = wlan_vdev_get_pdev(vdev);
2442 	if (!pdev) {
2443 		sap_err("Invalid pdev parameters");
2444 		return QDF_STATUS_E_FAULT;
2445 	}
2446 	psoc = wlan_pdev_get_psoc(pdev);
2447 	if (!psoc) {
2448 		sap_err("Invalid psoc parameters");
2449 		return QDF_STATUS_E_FAULT;
2450 	}
2451 	des_chan = wlan_vdev_mlme_get_des_chan(vdev);
2452 	if (!des_chan) {
2453 		sap_err("Invalid desired channel");
2454 		return QDF_STATUS_E_FAULT;
2455 	}
2456 	config->sap_orig_hw_mode = config->SapHw_mode;
2457 	config->ch_width_orig = config->ch_params.ch_width;
2458 	switch (phy_mode) {
2459 	case QCA_WLAN_VENDOR_PHY_MODE_11A:
2460 		config->SapHw_mode = eCSR_DOT11_MODE_11a;
2461 		config->ch_params.ch_width = CH_WIDTH_20MHZ;
2462 		break;
2463 	case QCA_WLAN_VENDOR_PHY_MODE_11B:
2464 		config->SapHw_mode = eCSR_DOT11_MODE_11b;
2465 		config->ch_params.ch_width = CH_WIDTH_20MHZ;
2466 		break;
2467 	case QCA_WLAN_VENDOR_PHY_MODE_11G:
2468 		config->SapHw_mode = eCSR_DOT11_MODE_11g;
2469 		config->ch_params.ch_width = CH_WIDTH_20MHZ;
2470 		break;
2471 	case QCA_WLAN_VENDOR_PHY_MODE_11AGN:
2472 	case QCA_WLAN_VENDOR_PHY_MODE_11NG_HT20:
2473 	case QCA_WLAN_VENDOR_PHY_MODE_11NA_HT20:
2474 		config->SapHw_mode = eCSR_DOT11_MODE_11n;
2475 		config->ch_params.ch_width = CH_WIDTH_20MHZ;
2476 		break;
2477 	case QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40PLUS:
2478 	case QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40MINUS:
2479 	case QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40:
2480 	case QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40PLUS:
2481 	case QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40MINUS:
2482 	case QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40:
2483 		config->SapHw_mode = eCSR_DOT11_MODE_11n;
2484 		config->ch_params.ch_width = CH_WIDTH_40MHZ;
2485 		break;
2486 	case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT20:
2487 		config->SapHw_mode = eCSR_DOT11_MODE_11ac;
2488 		config->ch_params.ch_width = CH_WIDTH_20MHZ;
2489 		break;
2490 	case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40PLUS:
2491 	case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40MINUS:
2492 	case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40:
2493 		config->SapHw_mode = eCSR_DOT11_MODE_11ac;
2494 		config->ch_params.ch_width = CH_WIDTH_40MHZ;
2495 		break;
2496 	case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80:
2497 		config->SapHw_mode = eCSR_DOT11_MODE_11ac;
2498 		config->ch_params.ch_width = CH_WIDTH_80MHZ;
2499 		break;
2500 	case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT160:
2501 		config->SapHw_mode = eCSR_DOT11_MODE_11ac;
2502 		config->ch_params.ch_width = CH_WIDTH_160MHZ;
2503 		break;
2504 	case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE20:
2505 		config->SapHw_mode = eCSR_DOT11_MODE_11ax;
2506 		config->ch_params.ch_width = CH_WIDTH_20MHZ;
2507 		break;
2508 	case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40:
2509 	case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40PLUS:
2510 	case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40MINUS:
2511 		config->SapHw_mode = eCSR_DOT11_MODE_11ax;
2512 		config->ch_params.ch_width = CH_WIDTH_40MHZ;
2513 		break;
2514 	case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE80:
2515 		config->SapHw_mode = eCSR_DOT11_MODE_11ax;
2516 		config->ch_params.ch_width = CH_WIDTH_80MHZ;
2517 		break;
2518 	case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE160:
2519 		config->SapHw_mode = eCSR_DOT11_MODE_11ax;
2520 		config->ch_params.ch_width = CH_WIDTH_160MHZ;
2521 		break;
2522 	case QCA_WLAN_VENDOR_PHY_MODE_AUTO:
2523 		config->SapHw_mode = eCSR_DOT11_MODE_AUTO;
2524 		break;
2525 	default:
2526 		sap_err("Invalid phy mode %d to configure", phy_mode);
2527 		break;
2528 	}
2529 
2530 	if (sap_phymode_is_eht(config->SapHw_mode))
2531 		wlan_reg_set_create_punc_bitmap(&config->ch_params, true);
2532 	if (config->ch_params.ch_width == CH_WIDTH_80P80MHZ &&
2533 	    ucfg_mlme_get_restricted_80p80_bw_supp(psoc)) {
2534 		if (!((config->ch_params.center_freq_seg0 == 138 &&
2535 		       config->ch_params.center_freq_seg1 == 155) ||
2536 		      (config->ch_params.center_freq_seg1 == 138 &&
2537 		       config->ch_params.center_freq_seg0 == 155))) {
2538 			sap_debug("Falling back to 80 from 80p80 as non supported freq_seq0 %d and freq_seq1 %d",
2539 				  config->ch_params.mhz_freq_seg0,
2540 				  config->ch_params.mhz_freq_seg1);
2541 			config->ch_params.center_freq_seg1 = 0;
2542 			config->ch_params.mhz_freq_seg1 = 0;
2543 			config->ch_width_orig = CH_WIDTH_80MHZ;
2544 			config->ch_params.ch_width = config->ch_width_orig;
2545 		}
2546 	}
2547 
2548 	config->chan_freq = des_chan->ch_freq;
2549 	config->sec_ch_freq = 0;
2550 	if (WLAN_REG_IS_24GHZ_CH_FREQ(des_chan->ch_freq) &&
2551 	    config->ch_params.ch_width == CH_WIDTH_40MHZ &&
2552 	    des_chan->ch_width == CH_WIDTH_40MHZ) {
2553 		if (des_chan->ch_cfreq1 == des_chan->ch_freq + BW_10_MHZ)
2554 			config->sec_ch_freq = des_chan->ch_freq + BW_20_MHZ;
2555 		if (des_chan->ch_cfreq1 == des_chan->ch_freq - BW_10_MHZ)
2556 			config->sec_ch_freq = des_chan->ch_freq - BW_20_MHZ;
2557 	}
2558 	wlan_reg_set_channel_params_for_pwrmode(pdev, config->chan_freq,
2559 						config->sec_ch_freq,
2560 						&config->ch_params,
2561 						REG_CURRENT_PWR_MODE);
2562 
2563 	return QDF_STATUS_SUCCESS;
2564 }
2565 #endif
2566 
2567 #define ACS_WLAN_20M_CH_INC 20
2568 #define ACS_2G_EXTEND ACS_WLAN_20M_CH_INC
2569 #define ACS_5G_EXTEND (ACS_WLAN_20M_CH_INC * 3)
2570 
2571 #ifdef CONFIG_BAND_6GHZ
2572 static void wlansap_update_start_range_6ghz(
2573 	uint32_t *start_ch_freq, uint32_t *bandStartChannel)
2574 {
2575 	*bandStartChannel = MIN_6GHZ_CHANNEL;
2576 	*start_ch_freq = (*start_ch_freq - ACS_5G_EXTEND) >
2577 				wlan_reg_ch_to_freq(MIN_6GHZ_CHANNEL) ?
2578 			   (*start_ch_freq - ACS_5G_EXTEND) :
2579 				wlan_reg_ch_to_freq(MIN_6GHZ_CHANNEL);
2580 }
2581 
2582 static void wlansap_update_end_range_6ghz(
2583 	uint32_t *end_ch_freq, uint32_t *bandEndChannel)
2584 {
2585 	*bandEndChannel = MAX_6GHZ_CHANNEL;
2586 	*end_ch_freq = (*end_ch_freq + ACS_5G_EXTEND) <=
2587 			     wlan_reg_ch_to_freq(MAX_6GHZ_CHANNEL) ?
2588 			     (*end_ch_freq + ACS_5G_EXTEND) :
2589 			     wlan_reg_ch_to_freq(MAX_6GHZ_CHANNEL);
2590 }
2591 #else
2592 static void wlansap_update_start_range_6ghz(
2593 	uint32_t *start_ch_freq, uint32_t *bandStartChannel)
2594 {
2595 }
2596 
2597 static void wlansap_update_end_range_6ghz(
2598 	uint32_t *end_ch_freq, uint32_t *bandEndChannel)
2599 {
2600 }
2601 #endif
2602 
2603 /*==========================================================================
2604    FUNCTION  wlansap_extend_to_acs_range
2605 
2606    DESCRIPTION Function extends give channel range to consider ACS chan bonding
2607 
2608    DEPENDENCIES PARAMETERS
2609 
2610    IN /OUT
2611    * start_ch_freq : ACS extend start ch
2612    * end_ch_freq   : ACS extended End ch
2613    * bandStartChannel: Band start ch
2614    * bandEndChannel  : Band end ch
2615 
2616    RETURN VALUE NONE
2617 
2618    SIDE EFFECTS
2619    ============================================================================*/
2620 void wlansap_extend_to_acs_range(mac_handle_t mac_handle,
2621 				 uint32_t *start_ch_freq,
2622 				 uint32_t *end_ch_freq,
2623 				 uint32_t *bandStartChannel,
2624 				 uint32_t *bandEndChannel)
2625 {
2626 	uint32_t tmp_start_ch_freq = 0, tmp_end_ch_freq = 0;
2627 	struct mac_context *mac_ctx;
2628 
2629 	mac_ctx = MAC_CONTEXT(mac_handle);
2630 	if (!mac_ctx) {
2631 		sap_err("Invalid mac_ctx");
2632 		return;
2633 	}
2634 	if (*start_ch_freq <= wlan_reg_ch_to_freq(CHAN_ENUM_2484)) {
2635 		*bandStartChannel = CHAN_ENUM_2412;
2636 		tmp_start_ch_freq = *start_ch_freq >
2637 					wlan_reg_ch_to_freq(CHAN_ENUM_2432) ?
2638 					(*start_ch_freq - ACS_2G_EXTEND) :
2639 					wlan_reg_ch_to_freq(CHAN_ENUM_2412);
2640 	} else if (*start_ch_freq <= wlan_reg_ch_to_freq(CHAN_ENUM_5885)) {
2641 		*bandStartChannel = CHAN_ENUM_5180;
2642 		tmp_start_ch_freq = (*start_ch_freq - ACS_5G_EXTEND) >
2643 					wlan_reg_ch_to_freq(CHAN_ENUM_5180) ?
2644 				   (*start_ch_freq - ACS_5G_EXTEND) :
2645 					wlan_reg_ch_to_freq(CHAN_ENUM_5180);
2646 	} else if (WLAN_REG_IS_6GHZ_CHAN_FREQ(*start_ch_freq)) {
2647 		tmp_start_ch_freq = *start_ch_freq;
2648 		wlansap_update_start_range_6ghz(&tmp_start_ch_freq,
2649 						bandStartChannel);
2650 	} else {
2651 		*bandStartChannel = CHAN_ENUM_2412;
2652 		tmp_start_ch_freq = *start_ch_freq >
2653 					wlan_reg_ch_to_freq(CHAN_ENUM_2432) ?
2654 					(*start_ch_freq - ACS_2G_EXTEND) :
2655 					wlan_reg_ch_to_freq(CHAN_ENUM_2412);
2656 		sap_err("unexpected start freq %d",
2657 			*start_ch_freq);
2658 	}
2659 
2660 	if (*end_ch_freq <= wlan_reg_ch_to_freq(CHAN_ENUM_2484)) {
2661 		*bandEndChannel = CHAN_ENUM_2484;
2662 		tmp_end_ch_freq = (*end_ch_freq + ACS_2G_EXTEND) <=
2663 					wlan_reg_ch_to_freq(CHAN_ENUM_2484) ?
2664 					(*end_ch_freq + ACS_2G_EXTEND) :
2665 					wlan_reg_ch_to_freq(CHAN_ENUM_2484);
2666 	} else if (*end_ch_freq <= wlan_reg_ch_to_freq(CHAN_ENUM_5885)) {
2667 		*bandEndChannel = CHAN_ENUM_5885;
2668 		tmp_end_ch_freq = (*end_ch_freq + ACS_5G_EXTEND) <=
2669 				     wlan_reg_ch_to_freq(CHAN_ENUM_5885) ?
2670 				     (*end_ch_freq + ACS_5G_EXTEND) :
2671 				     wlan_reg_ch_to_freq(CHAN_ENUM_5885);
2672 	} else if (WLAN_REG_IS_6GHZ_CHAN_FREQ(*end_ch_freq)) {
2673 		tmp_end_ch_freq = *end_ch_freq;
2674 		wlansap_update_end_range_6ghz(&tmp_end_ch_freq,
2675 					      bandEndChannel);
2676 	} else {
2677 		*bandEndChannel = CHAN_ENUM_5885;
2678 		tmp_end_ch_freq = (*end_ch_freq + ACS_5G_EXTEND) <=
2679 				     wlan_reg_ch_to_freq(CHAN_ENUM_5885) ?
2680 				     (*end_ch_freq + ACS_5G_EXTEND) :
2681 				     wlan_reg_ch_to_freq(CHAN_ENUM_5885);
2682 
2683 		sap_err("unexpected end freq %d", *end_ch_freq);
2684 	}
2685 	*start_ch_freq = tmp_start_ch_freq;
2686 	*end_ch_freq = tmp_end_ch_freq;
2687 	/* Note if the ACS range include only DFS channels, do not cross range
2688 	* Active scanning in adjacent non DFS channels results in transmission
2689 	* spikes in DFS spectrum channels which is due to emission spill.
2690 	* Remove the active channels from extend ACS range for DFS only range
2691 	*/
2692 	if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev, *start_ch_freq)) {
2693 		while (!wlan_reg_is_dfs_for_freq(
2694 				mac_ctx->pdev,
2695 				tmp_start_ch_freq) &&
2696 		       tmp_start_ch_freq < *start_ch_freq)
2697 			tmp_start_ch_freq += ACS_WLAN_20M_CH_INC;
2698 
2699 		*start_ch_freq = tmp_start_ch_freq;
2700 	}
2701 	if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev, *end_ch_freq)) {
2702 		while (!wlan_reg_is_dfs_for_freq(
2703 				mac_ctx->pdev,
2704 				tmp_end_ch_freq) &&
2705 		       tmp_end_ch_freq > *end_ch_freq)
2706 			tmp_end_ch_freq -= ACS_WLAN_20M_CH_INC;
2707 
2708 		*end_ch_freq = tmp_end_ch_freq;
2709 	}
2710 }
2711 
2712 QDF_STATUS wlan_sap_set_vendor_acs(struct sap_context *sap_context,
2713 				   bool is_vendor_acs)
2714 {
2715 	if (!sap_context) {
2716 		sap_err("Invalid SAP pointer");
2717 		return QDF_STATUS_E_FAULT;
2718 	}
2719 	sap_context->vendor_acs_dfs_lte_enabled = is_vendor_acs;
2720 
2721 	return QDF_STATUS_SUCCESS;
2722 }
2723 
2724 #ifdef DFS_COMPONENT_ENABLE
2725 QDF_STATUS wlansap_set_dfs_nol(struct sap_context *sap_ctx,
2726 			       eSapDfsNolType conf)
2727 {
2728 	struct mac_context *mac;
2729 
2730 	if (!sap_ctx) {
2731 		sap_err("Invalid SAP pointer");
2732 		return QDF_STATUS_E_FAULT;
2733 	}
2734 
2735 	mac = sap_get_mac_context();
2736 	if (!mac) {
2737 		sap_err("Invalid MAC context");
2738 		return QDF_STATUS_E_FAULT;
2739 	}
2740 
2741 	if (conf == eSAP_DFS_NOL_CLEAR) {
2742 		struct wlan_objmgr_pdev *pdev;
2743 
2744 		sap_err("clear the DFS NOL");
2745 
2746 		pdev = mac->pdev;
2747 		if (!pdev) {
2748 			sap_err("null pdev");
2749 			return QDF_STATUS_E_FAULT;
2750 		}
2751 		utils_dfs_clear_nol_channels(pdev);
2752 	} else if (conf == eSAP_DFS_NOL_RANDOMIZE) {
2753 		sap_err("Randomize the DFS NOL");
2754 
2755 	} else {
2756 		sap_err("unsupported type %d", conf);
2757 	}
2758 
2759 	return QDF_STATUS_SUCCESS;
2760 }
2761 #endif
2762 
2763 void wlansap_populate_del_sta_params(const uint8_t *mac,
2764 				     uint16_t reason_code,
2765 				     uint8_t subtype,
2766 				     struct csr_del_sta_params *params)
2767 {
2768 	if (!mac)
2769 		qdf_set_macaddr_broadcast(&params->peerMacAddr);
2770 	else
2771 		qdf_mem_copy(params->peerMacAddr.bytes, mac,
2772 			     QDF_MAC_ADDR_SIZE);
2773 
2774 	if (reason_code == 0)
2775 		params->reason_code = REASON_DEAUTH_NETWORK_LEAVING;
2776 	else
2777 		params->reason_code = reason_code;
2778 
2779 	if (subtype == SIR_MAC_MGMT_DEAUTH || subtype == SIR_MAC_MGMT_DISASSOC)
2780 		params->subtype = subtype;
2781 	else
2782 		params->subtype = SIR_MAC_MGMT_DEAUTH;
2783 
2784 	sap_debug("Delete STA with RC:%hu subtype:%hhu MAC::" QDF_MAC_ADDR_FMT,
2785 		  params->reason_code, params->subtype,
2786 		  QDF_MAC_ADDR_REF(params->peerMacAddr.bytes));
2787 }
2788 
2789 void sap_undo_acs(struct sap_context *sap_ctx, struct sap_config *sap_cfg)
2790 {
2791 	struct sap_acs_cfg *acs_cfg;
2792 
2793 	if (!sap_ctx)
2794 		return;
2795 
2796 	acs_cfg = &sap_cfg->acs_cfg;
2797 	if (!acs_cfg)
2798 		return;
2799 
2800 	if (acs_cfg->freq_list) {
2801 		sap_debug("Clearing ACS cfg ch freq list");
2802 		qdf_mem_free(acs_cfg->freq_list);
2803 		acs_cfg->freq_list = NULL;
2804 	}
2805 	if (acs_cfg->master_freq_list) {
2806 		sap_debug("Clearing master ACS cfg chan freq list");
2807 		qdf_mem_free(acs_cfg->master_freq_list);
2808 		acs_cfg->master_freq_list = NULL;
2809 	}
2810 	if (sap_ctx->freq_list) {
2811 		sap_debug("Clearing sap context ch freq list");
2812 		qdf_mem_free(sap_ctx->freq_list);
2813 		sap_ctx->freq_list = NULL;
2814 	}
2815 	acs_cfg->ch_list_count = 0;
2816 	acs_cfg->master_ch_list_count = 0;
2817 	acs_cfg->acs_mode = false;
2818 	acs_cfg->master_ch_list_updated = false;
2819 	sap_ctx->num_of_channel = 0;
2820 	wlansap_dcs_set_vdev_wlan_interference_mitigation(sap_ctx, false);
2821 }
2822 
2823 QDF_STATUS wlansap_acs_chselect(struct sap_context *sap_context,
2824 				sap_event_cb acs_event_callback,
2825 				struct sap_config *config,
2826 				void *pusr_context)
2827 {
2828 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2829 	struct mac_context *mac;
2830 
2831 	if (!sap_context) {
2832 		sap_err("Invalid SAP pointer");
2833 
2834 		return QDF_STATUS_E_FAULT;
2835 	}
2836 
2837 	mac = sap_get_mac_context();
2838 	if (!mac) {
2839 		sap_err("Invalid MAC context");
2840 		return QDF_STATUS_E_FAULT;
2841 	}
2842 
2843 	sap_context->acs_cfg = &config->acs_cfg;
2844 	sap_context->ch_width_orig = config->acs_cfg.ch_width;
2845 	sap_context->phyMode = config->acs_cfg.hw_mode;
2846 
2847 	/*
2848 	 * Now, configure the scan and ACS channel params
2849 	 * to issue a scan request.
2850 	 */
2851 	wlansap_set_scan_acs_channel_params(config, sap_context,
2852 					    pusr_context);
2853 
2854 	/*
2855 	 * Copy the HDD callback function to report the
2856 	 * ACS result after scan in SAP context callback function.
2857 	 */
2858 	sap_context->sap_event_cb = acs_event_callback;
2859 
2860 	/*
2861 	 * Issue the scan request. This scan request is
2862 	 * issued before the start BSS is done so
2863 	 *
2864 	 * 1. No need to pass the second parameter
2865 	 * as the SAP state machine is not started yet
2866 	 * and there is no need for any event posting.
2867 	 *
2868 	 * 2. Set third parameter to TRUE to indicate the
2869 	 * channel selection function to register a
2870 	 * different scan callback function to process
2871 	 * the results pre start BSS.
2872 	 */
2873 	qdf_status = sap_channel_sel(sap_context);
2874 
2875 	if (QDF_STATUS_E_ABORTED == qdf_status) {
2876 		sap_err("DFS not supported in the current operating mode");
2877 		return QDF_STATUS_E_FAILURE;
2878 	} else if (QDF_STATUS_E_CANCELED == qdf_status) {
2879 		/*
2880 		* ERROR is returned when either the SME scan request
2881 		* failed or ACS is overridden due to other constrainst
2882 		* So send selected channel to HDD
2883 		*/
2884 		sap_err("Scan Req Failed/ACS Overridden");
2885 		sap_err("Selected channel frequency = %d",
2886 			sap_context->chan_freq);
2887 
2888 		return sap_signal_hdd_event(sap_context, NULL,
2889 				eSAP_ACS_CHANNEL_SELECTED,
2890 				(void *) eSAP_STATUS_SUCCESS);
2891 	}
2892 
2893 	return qdf_status;
2894 }
2895 
2896 /**
2897  * wlan_sap_enable_phy_error_logs() - Enable DFS phy error logs
2898  * @mac_handle: Opaque handle to the global MAC context
2899  * @enable_log: value to set
2900  *
2901  * Since the frequency of DFS phy error is very high, enabling logs for them
2902  * all the times can cause crash and will also create lot of useless logs
2903  * causing difficulties in debugging other issue. This function will be called
2904  * from iwpriv cmd to enable such logs temporarily.
2905  *
2906  * Return: void
2907  */
2908 void wlan_sap_enable_phy_error_logs(mac_handle_t mac_handle,
2909 				    uint32_t enable_log)
2910 {
2911 	int error;
2912 
2913 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
2914 
2915 	mac_ctx->sap.enable_dfs_phy_error_logs = !!enable_log;
2916 	tgt_dfs_control(mac_ctx->pdev, DFS_SET_DEBUG_LEVEL, &enable_log,
2917 			sizeof(uint32_t), NULL, NULL, &error);
2918 }
2919 
2920 #ifdef DFS_PRI_MULTIPLIER
2921 void wlan_sap_set_dfs_pri_multiplier(mac_handle_t mac_handle)
2922 {
2923 	int error;
2924 
2925 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
2926 
2927 	tgt_dfs_control(mac_ctx->pdev, DFS_SET_PRI_MULTIPILER,
2928 			&mac_ctx->mlme_cfg->dfs_cfg.dfs_pri_multiplier,
2929 			sizeof(uint32_t), NULL, NULL, &error);
2930 }
2931 #endif
2932 
2933 uint32_t wlansap_get_chan_width(struct sap_context *sap_ctx)
2934 {
2935 	return wlan_sap_get_vht_ch_width(sap_ctx);
2936 }
2937 
2938 enum phy_ch_width
2939 wlansap_get_max_bw_by_phymode(struct sap_context *sap_ctx)
2940 {
2941 	uint32_t max_fw_bw;
2942 	enum phy_ch_width ch_width;
2943 
2944 	if (!sap_ctx) {
2945 		sap_err("Invalid SAP pointer");
2946 		return CH_WIDTH_20MHZ;
2947 	}
2948 
2949 	if (sap_ctx->phyMode == eCSR_DOT11_MODE_11ac ||
2950 	    sap_ctx->phyMode == eCSR_DOT11_MODE_11ac_ONLY ||
2951 	    sap_ctx->phyMode == eCSR_DOT11_MODE_11ax ||
2952 	    sap_ctx->phyMode == eCSR_DOT11_MODE_11ax_ONLY ||
2953 	    CSR_IS_DOT11_PHY_MODE_11BE(sap_ctx->phyMode) ||
2954 	    CSR_IS_DOT11_PHY_MODE_11BE_ONLY(sap_ctx->phyMode)) {
2955 		max_fw_bw = sme_get_vht_ch_width();
2956 		if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
2957 			ch_width = CH_WIDTH_160MHZ;
2958 		else
2959 			ch_width = CH_WIDTH_80MHZ;
2960 		if (CSR_IS_DOT11_PHY_MODE_11BE(sap_ctx->phyMode) ||
2961 		    CSR_IS_DOT11_PHY_MODE_11BE_ONLY(sap_ctx->phyMode))
2962 			ch_width =
2963 			QDF_MAX(wlansap_get_target_eht_phy_ch_width(),
2964 				ch_width);
2965 	} else if (sap_ctx->phyMode == eCSR_DOT11_MODE_11n ||
2966 		   sap_ctx->phyMode == eCSR_DOT11_MODE_11n_ONLY) {
2967 		ch_width = CH_WIDTH_40MHZ;
2968 	} else {
2969 		/* For legacy 11a mode return 20MHz */
2970 		ch_width = CH_WIDTH_20MHZ;
2971 	}
2972 
2973 	return ch_width;
2974 }
2975 
2976 QDF_STATUS wlansap_set_invalid_session(struct sap_context *sap_ctx)
2977 {
2978 	if (!sap_ctx) {
2979 		sap_err("Invalid SAP pointer");
2980 		return QDF_STATUS_E_FAILURE;
2981 	}
2982 
2983 	sap_ctx->sessionId = WLAN_UMAC_VDEV_ID_MAX;
2984 
2985 	return QDF_STATUS_SUCCESS;
2986 }
2987 
2988 QDF_STATUS wlansap_release_vdev_ref(struct sap_context *sap_ctx)
2989 {
2990 	if (!sap_ctx) {
2991 		sap_err("Invalid SAP pointer");
2992 		return QDF_STATUS_E_FAILURE;
2993 	}
2994 
2995 	sap_release_vdev_ref(sap_ctx);
2996 
2997 	return QDF_STATUS_SUCCESS;
2998 }
2999 
3000 void wlansap_cleanup_cac_timer(struct sap_context *sap_ctx)
3001 {
3002 	struct mac_context *mac;
3003 
3004 	if (!sap_ctx) {
3005 		sap_debug("Invalid SAP context");
3006 		return;
3007 	}
3008 
3009 	mac = sap_get_mac_context();
3010 	if (!mac) {
3011 		sap_err("Invalid MAC context");
3012 		return;
3013 	}
3014 
3015 	if (mac->sap.SapDfsInfo.vdev_id != sap_ctx->vdev_id) {
3016 		sap_err("sapdfs, force cleanup vdev mismatch sap vdev id %d mac_ctx vdev id %d",
3017 			sap_ctx->vdev_id, mac->sap.SapDfsInfo.vdev_id);
3018 		return;
3019 	}
3020 
3021 	if (mac->sap.SapDfsInfo.is_dfs_cac_timer_running) {
3022 		mac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
3023 		mac->sap.SapDfsInfo.vdev_id = WLAN_INVALID_VDEV_ID;
3024 
3025 		if (!sap_ctx->dfs_cac_offload) {
3026 			qdf_mc_timer_stop(
3027 				&mac->sap.SapDfsInfo.sap_dfs_cac_timer);
3028 			qdf_mc_timer_destroy(
3029 				&mac->sap.SapDfsInfo.sap_dfs_cac_timer);
3030 			sap_debug("sapdfs, force cleanup running dfs cac timer vdev id %d",
3031 				  sap_ctx->vdev_id);
3032 		}
3033 	}
3034 }
3035 
3036 #define DH_OUI_TYPE	(0x20)
3037 /**
3038  * wlansap_validate_owe_ie() - validate OWE IE
3039  * @ie: IE buffer
3040  * @remaining_ie_len: remaining IE length
3041  *
3042  * Return: validated IE length, negative for failure
3043  */
3044 static int wlansap_validate_owe_ie(const uint8_t *ie, uint32_t remaining_ie_len)
3045 {
3046 	uint8_t ie_id, ie_len, ie_ext_id = 0;
3047 
3048 	if (remaining_ie_len < 2) {
3049 		sap_err("IE too short");
3050 		return -EINVAL;
3051 	}
3052 
3053 	ie_id = ie[0];
3054 	ie_len = ie[1];
3055 
3056 	/* IEs that we are expecting in OWE IEs
3057 	 * - RSN IE
3058 	 * - DH IE
3059 	 */
3060 	switch (ie_id) {
3061 	case DOT11F_EID_RSN:
3062 		if (ie_len < DOT11F_IE_RSN_MIN_LEN ||
3063 		    ie_len > DOT11F_IE_RSN_MAX_LEN) {
3064 			sap_err("Invalid RSN IE len %d", ie_len);
3065 			return -EINVAL;
3066 		}
3067 		ie_len += 2;
3068 		break;
3069 	case DOT11F_EID_DH_PARAMETER_ELEMENT:
3070 		ie_ext_id = ie[2];
3071 		if (ie_ext_id != DH_OUI_TYPE) {
3072 			sap_err("Invalid DH IE ID %d", ie_ext_id);
3073 			return -EINVAL;
3074 		}
3075 		if (ie_len < DOT11F_IE_DH_PARAMETER_ELEMENT_MIN_LEN ||
3076 		    ie_len > DOT11F_IE_DH_PARAMETER_ELEMENT_MAX_LEN) {
3077 			sap_err("Invalid DH IE len %d", ie_len);
3078 			return -EINVAL;
3079 		}
3080 		ie_len += 2;
3081 		break;
3082 	default:
3083 		sap_err("Invalid IE %d", ie_id);
3084 		return -EINVAL;
3085 	}
3086 
3087 	if (ie_len > remaining_ie_len) {
3088 		sap_err("Invalid IE len");
3089 		return -EINVAL;
3090 	}
3091 
3092 	return ie_len;
3093 }
3094 
3095 /**
3096  * wlansap_validate_owe_ies() - validate OWE IEs
3097  * @ie: IE buffer
3098  * @ie_len: IE length
3099  *
3100  * Return: true if validated
3101  */
3102 static bool wlansap_validate_owe_ies(const uint8_t *ie, uint32_t ie_len)
3103 {
3104 	const uint8_t *remaining_ie = ie;
3105 	uint32_t remaining_ie_len = ie_len;
3106 	int validated_len;
3107 	bool validated = true;
3108 
3109 	while (remaining_ie_len) {
3110 		validated_len = wlansap_validate_owe_ie(remaining_ie,
3111 							remaining_ie_len);
3112 		if (validated_len < 0) {
3113 			validated = false;
3114 			break;
3115 		}
3116 		remaining_ie += validated_len;
3117 		remaining_ie_len -= validated_len;
3118 	}
3119 
3120 	return validated;
3121 }
3122 
3123 QDF_STATUS wlansap_update_owe_info(struct sap_context *sap_ctx,
3124 				   uint8_t *peer, const uint8_t *ie,
3125 				   uint32_t ie_len, uint16_t owe_status)
3126 {
3127 	struct mac_context *mac;
3128 	struct owe_assoc_ind *owe_assoc_ind;
3129 	struct assoc_ind *assoc_ind = NULL;
3130 	qdf_list_node_t *node = NULL, *next_node = NULL;
3131 	QDF_STATUS status = QDF_STATUS_SUCCESS;
3132 
3133 	if (!wlansap_validate_owe_ies(ie, ie_len)) {
3134 		sap_err("Invalid OWE IE");
3135 		return QDF_STATUS_E_FAULT;
3136 	}
3137 
3138 	if (!sap_ctx) {
3139 		sap_err("Invalid SAP context");
3140 		return QDF_STATUS_E_FAULT;
3141 	}
3142 
3143 	mac = sap_get_mac_context();
3144 	if (!mac) {
3145 		sap_err("Invalid MAC context");
3146 		return QDF_STATUS_E_FAULT;
3147 	}
3148 
3149 	if (QDF_STATUS_SUCCESS !=
3150 		qdf_list_peek_front(&sap_ctx->owe_pending_assoc_ind_list,
3151 				    &next_node)) {
3152 		sap_err("Failed to find assoc ind list");
3153 		return QDF_STATUS_E_FAILURE;
3154 	}
3155 
3156 	do {
3157 		node = next_node;
3158 		owe_assoc_ind = qdf_container_of(node, struct owe_assoc_ind,
3159 						 node);
3160 		if (qdf_mem_cmp(peer,
3161 				owe_assoc_ind->assoc_ind->peerMacAddr,
3162 				QDF_MAC_ADDR_SIZE) == 0) {
3163 			status = qdf_list_remove_node(
3164 					   &sap_ctx->owe_pending_assoc_ind_list,
3165 					   node);
3166 			if (status != QDF_STATUS_SUCCESS) {
3167 				sap_err("Failed to remove assoc ind");
3168 				return status;
3169 			}
3170 			assoc_ind = owe_assoc_ind->assoc_ind;
3171 			qdf_mem_free(owe_assoc_ind);
3172 			break;
3173 		}
3174 	} while (QDF_STATUS_SUCCESS ==
3175 		 qdf_list_peek_next(&sap_ctx->owe_pending_assoc_ind_list,
3176 				    node, &next_node));
3177 
3178 	if (assoc_ind) {
3179 		assoc_ind->owe_ie = ie;
3180 		assoc_ind->owe_ie_len = ie_len;
3181 		assoc_ind->owe_status = owe_status;
3182 		status = sme_update_owe_info(mac, assoc_ind);
3183 		qdf_mem_free(assoc_ind);
3184 	}
3185 
3186 	return status;
3187 }
3188 
3189 QDF_STATUS wlansap_update_ft_info(struct sap_context *sap_ctx,
3190 				  uint8_t *peer, const uint8_t *ie,
3191 				  uint32_t ie_len, uint16_t ft_status)
3192 {
3193 	struct mac_context *mac;
3194 	struct ft_assoc_ind *ft_assoc_ind;
3195 	struct assoc_ind *assoc_ind = NULL;
3196 	qdf_list_node_t *node = NULL, *next_node = NULL;
3197 	QDF_STATUS status;
3198 
3199 	if (!sap_ctx) {
3200 		sap_err("Invalid SAP context");
3201 		return QDF_STATUS_E_FAULT;
3202 	}
3203 
3204 	mac = sap_get_mac_context();
3205 	if (!mac) {
3206 		sap_err("Invalid MAC context");
3207 		return QDF_STATUS_E_FAULT;
3208 	}
3209 	status = qdf_wait_single_event(&sap_ctx->ft_pending_event,
3210 				       500);
3211 	if (!QDF_IS_STATUS_SUCCESS(status)) {
3212 		sap_err("wait for ft pending event timeout");
3213 		wlansap_ft_cleanup(sap_ctx);
3214 		return QDF_STATUS_E_FAULT;
3215 	}
3216 
3217 	if (QDF_STATUS_SUCCESS !=
3218 		qdf_list_peek_front(&sap_ctx->ft_pending_assoc_ind_list,
3219 				    &next_node)) {
3220 		sap_err("Failed to find ft assoc ind list");
3221 		return QDF_STATUS_E_FAILURE;
3222 	}
3223 
3224 	do {
3225 		node = next_node;
3226 		ft_assoc_ind = qdf_container_of(node, struct ft_assoc_ind, node);
3227 		if (qdf_mem_cmp(peer,
3228 				ft_assoc_ind->assoc_ind->peerMacAddr,
3229 				QDF_MAC_ADDR_SIZE) == 0) {
3230 			status = qdf_list_remove_node(&sap_ctx->ft_pending_assoc_ind_list,
3231 						      node);
3232 			if (status != QDF_STATUS_SUCCESS) {
3233 				sap_err("Failed to remove ft assoc ind");
3234 				return status;
3235 			}
3236 			assoc_ind = ft_assoc_ind->assoc_ind;
3237 			qdf_mem_free(ft_assoc_ind);
3238 			break;
3239 		}
3240 	} while (QDF_STATUS_SUCCESS ==
3241 		 qdf_list_peek_next(&sap_ctx->ft_pending_assoc_ind_list,
3242 				    node, &next_node));
3243 
3244 	if (assoc_ind) {
3245 		assoc_ind->ft_ie = ie;
3246 		assoc_ind->ft_ie_len = ie_len;
3247 		assoc_ind->ft_status = ft_status;
3248 		status = sme_update_ft_info(mac, assoc_ind);
3249 		qdf_mem_free(assoc_ind);
3250 	}
3251 	return status;
3252 }
3253 
3254 bool wlansap_is_channel_present_in_acs_list(uint32_t freq,
3255 					    uint32_t *ch_freq_list,
3256 					    uint8_t ch_count)
3257 {
3258 	uint8_t i;
3259 
3260 	for(i = 0; i < ch_count; i++)
3261 		if (ch_freq_list[i] == freq)
3262 			return true;
3263 
3264 	return false;
3265 }
3266 
3267 QDF_STATUS wlansap_filter_ch_based_acs(struct sap_context *sap_ctx,
3268 				       uint32_t *ch_freq_list,
3269 				       uint32_t *ch_cnt)
3270 {
3271 	size_t ch_index;
3272 	size_t target_ch_cnt = 0;
3273 
3274 	if (!sap_ctx || !ch_freq_list || !ch_cnt) {
3275 		sap_err("NULL parameters");
3276 		return QDF_STATUS_E_FAULT;
3277 	}
3278 
3279 	if (!sap_ctx->acs_cfg->acs_mode) {
3280 		sap_debug("acs not enabled, no filtering required");
3281 		return QDF_STATUS_SUCCESS;
3282 	} else if (!sap_ctx->acs_cfg->master_freq_list ||
3283 		   !sap_ctx->acs_cfg->master_ch_list_count) {
3284 		sap_err("Empty acs channel list");
3285 		return QDF_STATUS_E_FAULT;
3286 	}
3287 
3288 	for (ch_index = 0; ch_index < *ch_cnt; ch_index++) {
3289 		if (wlansap_is_channel_present_in_acs_list(
3290 					ch_freq_list[ch_index],
3291 					sap_ctx->acs_cfg->master_freq_list,
3292 					sap_ctx->acs_cfg->master_ch_list_count))
3293 			ch_freq_list[target_ch_cnt++] = ch_freq_list[ch_index];
3294 	}
3295 
3296 	*ch_cnt = target_ch_cnt;
3297 
3298 	return QDF_STATUS_SUCCESS;
3299 }
3300 
3301 bool wlansap_is_6ghz_included_in_acs_range(struct sap_context *sap_ctx)
3302 {
3303 	uint32_t i;
3304 	uint32_t *ch_freq_list;
3305 
3306 	if (!sap_ctx || !sap_ctx->acs_cfg ||
3307 	    !sap_ctx->acs_cfg->master_freq_list ||
3308 	    !sap_ctx->acs_cfg->master_ch_list_count) {
3309 		sap_err("NULL parameters");
3310 		return false;
3311 	}
3312 	ch_freq_list = sap_ctx->acs_cfg->master_freq_list;
3313 	for (i = 0; i < sap_ctx->acs_cfg->master_ch_list_count; i++) {
3314 		if (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq_list[i]))
3315 			return true;
3316 	}
3317 	return false;
3318 }
3319 
3320 #if defined(FEATURE_WLAN_CH_AVOID)
3321 /**
3322  * wlansap_select_chan_with_best_bandwidth() - Select channel with
3323  * max possible band width
3324  * @sap_ctx: sap context
3325  * @ch_freq_list: candidate channel frequency list
3326  * @ch_cnt: count of channel frequency in list
3327  * @selected_freq: selected channel frequency
3328  * @selected_ch_width: selected channel width
3329  *
3330  * Return: QDF_STATUS_SUCCESS if better channel selected
3331  */
3332 static QDF_STATUS
3333 wlansap_select_chan_with_best_bandwidth(struct sap_context *sap_ctx,
3334 					uint32_t *ch_freq_list,
3335 					uint32_t ch_cnt,
3336 					uint32_t *selected_freq,
3337 					enum phy_ch_width *selected_ch_width)
3338 {
3339 	struct mac_context *mac;
3340 	struct ch_params ch_params = {0};
3341 	enum phy_ch_width ch_width;
3342 	uint32_t center_freq, bw_val, bw_start, bw_end;
3343 	uint16_t i, j;
3344 	uint16_t  unsafe_chan[NUM_CHANNELS];
3345 	uint16_t  unsafe_chan_cnt = 0;
3346 	qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
3347 
3348 	if (!selected_ch_width || !selected_freq)
3349 		return QDF_STATUS_E_INVAL;
3350 
3351 	if (!qdf_ctx) {
3352 		sap_err("invalid qdf_ctx");
3353 		return QDF_STATUS_E_INVAL;
3354 	}
3355 
3356 	if (!sap_ctx) {
3357 		sap_err("invalid sap_ctx");
3358 		return QDF_STATUS_E_INVAL;
3359 	}
3360 
3361 	mac = sap_get_mac_context();
3362 	if (!mac) {
3363 		sap_err("Invalid MAC context");
3364 		return QDF_STATUS_E_INVAL;
3365 	}
3366 
3367 	if (policy_mgr_mode_specific_connection_count(mac->psoc,
3368 						      PM_STA_MODE,
3369 						      NULL) ||
3370 	    policy_mgr_mode_specific_connection_count(mac->psoc,
3371 						      PM_P2P_CLIENT_MODE,
3372 						      NULL) ||
3373 	    policy_mgr_mode_specific_connection_count(mac->psoc,
3374 						      PM_P2P_GO_MODE,
3375 						      NULL)) {
3376 		sap_debug("sta/p2p mode active, skip!");
3377 		return QDF_STATUS_E_INVAL;
3378 	}
3379 
3380 	pld_get_wlan_unsafe_channel(qdf_ctx->dev, unsafe_chan,
3381 				    &unsafe_chan_cnt,
3382 				    sizeof(uint16_t) * NUM_CHANNELS);
3383 	unsafe_chan_cnt = QDF_MIN(unsafe_chan_cnt, NUM_CHANNELS);
3384 	if (!unsafe_chan_cnt)
3385 		return QDF_STATUS_E_INVAL;
3386 
3387 	ch_width = sap_ctx->ch_width_orig;
3388 next_lower_bw:
3389 	for (i = 0; i < ch_cnt; i++) {
3390 		if (!WLAN_REG_IS_SAME_BAND_FREQS(sap_ctx->chan_freq,
3391 						 ch_freq_list[i]))
3392 			continue;
3393 		if (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq_list[i]) &&
3394 		    !WLAN_REG_IS_6GHZ_PSC_CHAN_FREQ(ch_freq_list[i]))
3395 			continue;
3396 		qdf_mem_zero(&ch_params, sizeof(ch_params));
3397 		ch_params.ch_width = ch_width;
3398 		wlan_reg_set_channel_params_for_pwrmode(mac->pdev,
3399 							ch_freq_list[i],
3400 							0, &ch_params,
3401 							REG_CURRENT_PWR_MODE);
3402 		if (!WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq_list[i]) &&
3403 		    wlan_reg_get_5g_bonded_channel_state_for_pwrmode(mac->pdev,
3404 								     ch_freq_list[i],
3405 								     &ch_params,
3406 								     REG_CURRENT_PWR_MODE) !=
3407 				CHANNEL_STATE_ENABLE)
3408 			continue;
3409 
3410 		bw_val = wlan_reg_get_bw_value(ch_params.ch_width);
3411 		if (!ch_params.mhz_freq_seg0)
3412 			continue;
3413 		if (bw_val < wlan_reg_get_bw_value(ch_width))
3414 			continue;
3415 		if (ch_params.mhz_freq_seg1)
3416 			center_freq = ch_params.mhz_freq_seg1;
3417 		else
3418 			center_freq = ch_params.mhz_freq_seg0;
3419 
3420 		bw_start = center_freq - bw_val / 2 + 10;
3421 		bw_end = center_freq + bw_val / 2 - 10;
3422 		for (j = 0; j < unsafe_chan_cnt; j++)
3423 			if (unsafe_chan[j] >= bw_start &&
3424 			    unsafe_chan[j] <= bw_end)
3425 				break;
3426 
3427 		if (j < unsafe_chan_cnt) {
3428 			sap_debug("ch_freq %d bw %d bw start %d, bw end %d unsafe %d",
3429 				  ch_freq_list[i], bw_val, bw_start, bw_end,
3430 				  unsafe_chan[j]);
3431 			continue;
3432 		}
3433 		sap_debug("ch_freq %d bw %d bw start %d, bw end %d",
3434 			  ch_freq_list[i], bw_val, bw_start, bw_end);
3435 		/* found freq/bw pair which is safe for used as sap channel
3436 		 * avoidance csa target channel/bandwidth.
3437 		 */
3438 		*selected_freq = ch_freq_list[i];
3439 		*selected_ch_width = ch_params.ch_width;
3440 		sap_debug("selected freq %d bw %d", *selected_freq,
3441 			  *selected_ch_width);
3442 
3443 		return QDF_STATUS_SUCCESS;
3444 	}
3445 
3446 	ch_width = wlan_reg_get_next_lower_bandwidth(ch_width);
3447 	if (!(wlan_reg_get_bw_value(ch_width) < 20 ||
3448 	      ch_width == CH_WIDTH_INVALID))
3449 		goto next_lower_bw;
3450 
3451 	return QDF_STATUS_E_INVAL;
3452 }
3453 
3454 /**
3455  * wlansap_get_safe_channel() - Get safe channel from current regulatory
3456  * @sap_ctx: Pointer to SAP context
3457  * @ch_width: selected channel bandwdith
3458  * @pref_band: Preferred channel band for sap
3459  *
3460  * This function is used to get safe channel from current regulatory valid
3461  * channels to restart SAP if failed to get safe channel from PCL.
3462  *
3463  * Return: Chan freq num to restart SAP in case of success. In case of any
3464  * failure, the channel number returned is zero.
3465  */
3466 static uint32_t
3467 wlansap_get_safe_channel(struct sap_context *sap_ctx,
3468 			 enum phy_ch_width *ch_width,
3469 			 enum reg_wifi_band pref_band)
3470 {
3471 	struct mac_context *mac;
3472 	uint32_t pcl_freqs[NUM_CHANNELS];
3473 	QDF_STATUS status;
3474 	mac_handle_t mac_handle;
3475 	uint32_t pcl_len = 0, i;
3476 	uint32_t selected_freq;
3477 	enum policy_mgr_con_mode mode;
3478 	uint32_t first_valid_dfs_5g_freq = 0;
3479 	uint32_t first_valid_non_dfs_5g_freq = 0;
3480 	uint32_t first_valid_6g_freq = 0;
3481 
3482 	if (!sap_ctx) {
3483 		sap_err("NULL parameter");
3484 		return INVALID_CHANNEL_ID;
3485 	}
3486 
3487 	mac = sap_get_mac_context();
3488 	if (!mac) {
3489 		sap_err("Invalid MAC context");
3490 		return INVALID_CHANNEL_ID;
3491 	}
3492 	mac_handle = MAC_HANDLE(mac);
3493 
3494 	mode = policy_mgr_qdf_opmode_to_pm_con_mode(mac->psoc,
3495 						    QDF_SAP_MODE,
3496 						    sap_ctx->vdev_id);
3497 	/* get the channel list for current domain */
3498 	status = policy_mgr_get_valid_chans(mac->psoc, pcl_freqs, &pcl_len);
3499 	if (QDF_IS_STATUS_ERROR(status)) {
3500 		sap_err("Error in getting valid channels");
3501 		return INVALID_CHANNEL_ID;
3502 	}
3503 
3504 	status = wlansap_filter_ch_based_acs(sap_ctx, pcl_freqs, &pcl_len);
3505 
3506 	if (QDF_IS_STATUS_ERROR(status)) {
3507 		sap_err("failed to filter ch from acs %d", status);
3508 		return INVALID_CHANNEL_ID;
3509 	}
3510 
3511 	if (pcl_len) {
3512 		status = policy_mgr_get_valid_chans_from_range(mac->psoc,
3513 							       pcl_freqs,
3514 							       &pcl_len,
3515 							       mode);
3516 		if (QDF_IS_STATUS_ERROR(status) || !pcl_len) {
3517 			sap_err("failed to get valid channel: %d len %d",
3518 				status, pcl_len);
3519 			return INVALID_CHANNEL_ID;
3520 		}
3521 
3522 		status =
3523 		wlansap_select_chan_with_best_bandwidth(sap_ctx,
3524 							pcl_freqs,
3525 							pcl_len,
3526 							&selected_freq,
3527 							ch_width);
3528 		if (QDF_IS_STATUS_SUCCESS(status))
3529 			return selected_freq;
3530 
3531 		for (i = 0; i < pcl_len; i++) {
3532 			if (!first_valid_non_dfs_5g_freq &&
3533 			    wlan_reg_is_5ghz_ch_freq(pcl_freqs[i])) {
3534 				if (!wlan_reg_is_dfs_in_secondary_list_for_freq(
3535 							mac->pdev,
3536 							pcl_freqs[i])) {
3537 					first_valid_non_dfs_5g_freq = pcl_freqs[i];
3538 					if (pref_band == REG_BAND_5G)
3539 						break;
3540 				} else if (!first_valid_dfs_5g_freq) {
3541 					first_valid_dfs_5g_freq = pcl_freqs[i];
3542 				}
3543 			}
3544 			if (!first_valid_6g_freq &&
3545 			    wlan_reg_is_6ghz_chan_freq(pcl_freqs[i])) {
3546 				first_valid_6g_freq = pcl_freqs[i];
3547 				if (pref_band == REG_BAND_6G)
3548 					break;
3549 			}
3550 		}
3551 
3552 		selected_freq = pcl_freqs[0];
3553 
3554 		if (pref_band == REG_BAND_6G) {
3555 			if (first_valid_6g_freq)
3556 				selected_freq = first_valid_6g_freq;
3557 			else if (first_valid_non_dfs_5g_freq)
3558 				selected_freq = first_valid_non_dfs_5g_freq;
3559 			else if (first_valid_dfs_5g_freq)
3560 				selected_freq = first_valid_dfs_5g_freq;
3561 		} else if (pref_band == REG_BAND_5G) {
3562 			if (first_valid_non_dfs_5g_freq)
3563 				selected_freq = first_valid_non_dfs_5g_freq;
3564 			else if (first_valid_dfs_5g_freq)
3565 				selected_freq = first_valid_dfs_5g_freq;
3566 		}
3567 
3568 		sap_debug("select %d from valid channel list, pref band = %d",
3569 			  selected_freq, pref_band);
3570 		return selected_freq;
3571 	}
3572 
3573 	return INVALID_CHANNEL_ID;
3574 }
3575 #else
3576 /**
3577  * wlansap_select_chan_with_best_bandwidth() - Select channel with
3578  * max possible band width
3579  * @sap_ctx: sap context
3580  * @ch_freq_list: candidate channel frequency list
3581  * @ch_cnt: count of channel frequency in list
3582  * @selected_freq: selected channel frequency
3583  * @selected_ch_width: selected channel width
3584  *
3585  * Return: QDF_STATUS_SUCCESS if better channel selected
3586  */
3587 static inline QDF_STATUS
3588 wlansap_select_chan_with_best_bandwidth(struct sap_context *sap_ctx,
3589 					uint32_t *ch_freq_list,
3590 					uint32_t ch_cnt,
3591 					uint32_t *selected_freq,
3592 					enum phy_ch_width *selected_ch_width)
3593 {
3594 	return QDF_STATUS_E_NOSUPPORT;
3595 }
3596 
3597 /**
3598  * wlansap_get_safe_channel() - Get safe channel from current regulatory
3599  * @sap_ctx: Pointer to SAP context
3600  * @ch_width: selected channel width
3601  * @pref_band: Preferred channel band for sap
3602  *
3603  * This function is used to get safe channel from current regulatory valid
3604  * channels to restart SAP if failed to get safe channel from PCL.
3605  *
3606  * Return: Channel number to restart SAP in case of success. In case of any
3607  * failure, the channel number returned is zero.
3608  */
3609 static uint8_t
3610 wlansap_get_safe_channel(struct sap_context *sap_ctx,
3611 			 enum phy_ch_width *ch_width,
3612 			 enum reg_wifi_band pref_band)
3613 {
3614 	return 0;
3615 }
3616 #endif
3617 
3618 uint32_t
3619 wlansap_get_safe_channel_from_pcl_and_acs_range(struct sap_context *sap_ctx,
3620 						enum phy_ch_width *ch_width)
3621 {
3622 	struct mac_context *mac;
3623 	struct sir_pcl_list pcl = {0};
3624 	uint32_t pcl_freqs[NUM_CHANNELS] = {0};
3625 	uint32_t select_freq;
3626 	QDF_STATUS status;
3627 	mac_handle_t mac_handle;
3628 	uint32_t pcl_len = 0;
3629 	enum policy_mgr_con_mode mode;
3630 
3631 	if (!sap_ctx) {
3632 		sap_err("NULL parameter");
3633 		return INVALID_CHANNEL_ID;
3634 	}
3635 
3636 	mac = sap_get_mac_context();
3637 	if (!mac) {
3638 		sap_err("Invalid MAC context");
3639 		return INVALID_CHANNEL_ID;
3640 	}
3641 	mac_handle = MAC_HANDLE(mac);
3642 
3643 	if (policy_mgr_get_connection_count(mac->psoc) == 1) {
3644 		sap_debug("only SAP present return best channel from ACS list");
3645 		return wlansap_get_safe_channel(sap_ctx, ch_width, REG_BAND_6G);
3646 	}
3647 
3648 	mode = policy_mgr_qdf_opmode_to_pm_con_mode(mac->psoc, QDF_SAP_MODE,
3649 						    sap_ctx->vdev_id);
3650 
3651 	status =
3652 		policy_mgr_get_pcl_for_scc_in_same_mode(mac->psoc, mode,
3653 							pcl_freqs, &pcl_len,
3654 							pcl.weight_list,
3655 							QDF_ARRAY_SIZE(pcl.weight_list),
3656 							sap_ctx->sessionId);
3657 
3658 	if (QDF_IS_STATUS_ERROR(status)) {
3659 		sap_err("Get PCL failed");
3660 		return INVALID_CHANNEL_ID;
3661 	}
3662 
3663 	if (pcl_len) {
3664 		status = wlansap_filter_ch_based_acs(sap_ctx, pcl_freqs,
3665 						     &pcl_len);
3666 		if (QDF_IS_STATUS_ERROR(status)) {
3667 			sap_err("failed to filter ch from acs %d", status);
3668 			return INVALID_CHANNEL_ID;
3669 		}
3670 
3671 		if (wlansap_select_chan_with_best_bandwidth(sap_ctx,
3672 							    pcl_freqs,
3673 							    pcl_len,
3674 							    &select_freq,
3675 							    ch_width) ==
3676 		    QDF_STATUS_SUCCESS)
3677 			return select_freq;
3678 
3679 		if (pcl_len) {
3680 			sap_debug("select %d from valid ch freq list",
3681 				  pcl_freqs[0]);
3682 			return pcl_freqs[0];
3683 		}
3684 		sap_debug("no safe channel from PCL found in ACS range");
3685 	} else {
3686 		sap_debug("pcl length is zero!");
3687 	}
3688 
3689 	/*
3690 	 * In some scenarios, like hw dbs disabled, sap+sap case, if operating
3691 	 * channel is unsafe channel, the pcl may be empty, instead of return,
3692 	 * try to choose a safe channel from acs range.
3693 	 */
3694 	return wlansap_get_safe_channel(sap_ctx, ch_width, REG_BAND_6G);
3695 }
3696 
3697 static uint32_t wlansap_get_2g_first_safe_chan_freq(struct sap_context *sap_ctx)
3698 {
3699 	uint32_t i;
3700 	uint32_t freq;
3701 	enum channel_state state;
3702 	struct regulatory_channel *cur_chan_list;
3703 	struct wlan_objmgr_pdev *pdev;
3704 	struct wlan_objmgr_psoc *psoc;
3705 	uint32_t *acs_freq_list;
3706 	uint8_t acs_list_count;
3707 
3708 	pdev = sap_ctx->vdev->vdev_objmgr.wlan_pdev;
3709 	psoc = pdev->pdev_objmgr.wlan_psoc;
3710 
3711 	cur_chan_list = qdf_mem_malloc(NUM_CHANNELS *
3712 			sizeof(struct regulatory_channel));
3713 	if (!cur_chan_list)
3714 		return TWOG_CHAN_6_IN_MHZ;
3715 
3716 	if (wlan_reg_get_current_chan_list(pdev, cur_chan_list) !=
3717 					   QDF_STATUS_SUCCESS) {
3718 		freq = TWOG_CHAN_6_IN_MHZ;
3719 		goto err;
3720 	}
3721 
3722 	acs_freq_list = sap_ctx->acs_cfg->master_freq_list;
3723 	acs_list_count = sap_ctx->acs_cfg->master_ch_list_count;
3724 	for (i = 0; i < NUM_CHANNELS; i++) {
3725 		freq = cur_chan_list[i].center_freq;
3726 		state = wlan_reg_get_channel_state_for_pwrmode(
3727 							pdev, freq,
3728 							REG_CURRENT_PWR_MODE);
3729 		if (state != CHANNEL_STATE_DISABLE &&
3730 		    state != CHANNEL_STATE_PASSIVE &&
3731 		    state != CHANNEL_STATE_INVALID &&
3732 		    wlan_reg_is_24ghz_ch_freq(freq) &&
3733 		    policy_mgr_is_safe_channel(psoc, freq) &&
3734 		    wlansap_is_channel_present_in_acs_list(freq,
3735 							   acs_freq_list,
3736 							   acs_list_count)) {
3737 			sap_debug("found a 2g channel: %d", freq);
3738 			goto err;
3739 		}
3740 	}
3741 
3742 	freq = TWOG_CHAN_6_IN_MHZ;
3743 err:
3744 	qdf_mem_free(cur_chan_list);
3745 	return freq;
3746 }
3747 
3748 uint32_t wlansap_get_safe_channel_from_pcl_for_sap(struct sap_context *sap_ctx)
3749 {
3750 	struct wlan_objmgr_pdev *pdev;
3751 	struct mac_context *mac;
3752 	struct sir_pcl_list pcl = {0};
3753 	uint32_t pcl_freqs[NUM_CHANNELS] = {0};
3754 	QDF_STATUS status;
3755 	uint32_t pcl_len = 0;
3756 	enum policy_mgr_con_mode mode;
3757 
3758 	if (!sap_ctx) {
3759 		sap_err("NULL parameter");
3760 		return INVALID_CHANNEL_ID;
3761 	}
3762 
3763 	mac = sap_get_mac_context();
3764 	if (!mac) {
3765 		sap_err("Invalid MAC context");
3766 		return INVALID_CHANNEL_ID;
3767 	}
3768 
3769 	pdev = sap_ctx->vdev->vdev_objmgr.wlan_pdev;
3770 	if (!pdev) {
3771 		sap_err("NULL pdev");
3772 	}
3773 
3774 	mode = policy_mgr_qdf_opmode_to_pm_con_mode(mac->psoc, QDF_SAP_MODE,
3775 						    sap_ctx->vdev_id);
3776 
3777 	status = policy_mgr_get_pcl_for_vdev_id(mac->psoc, mode,
3778 						pcl_freqs, &pcl_len,
3779 						pcl.weight_list,
3780 						QDF_ARRAY_SIZE(pcl.weight_list),
3781 						sap_ctx->sessionId);
3782 
3783 	if (QDF_IS_STATUS_ERROR(status)) {
3784 		sap_err("Get PCL failed");
3785 		return INVALID_CHANNEL_ID;
3786 	}
3787 
3788 	if (pcl_len) {
3789 		status = policy_mgr_filter_passive_ch(pdev, pcl_freqs,
3790 						      &pcl_len);
3791 		if (QDF_IS_STATUS_ERROR(status)) {
3792 			sap_err("failed to filter passive channels");
3793 			return INVALID_CHANNEL_ID;
3794 		}
3795 
3796 		if (pcl_len) {
3797 			sap_debug("select %d from valid ch freq list",
3798 				  pcl_freqs[0]);
3799 			return pcl_freqs[0];
3800 		}
3801 		sap_debug("no active channels found in PCL");
3802 	} else {
3803 		sap_debug("pcl length is zero!");
3804 	}
3805 
3806 	if (mode == PM_LL_LT_SAP_MODE)
3807 		return INVALID_CHANNEL_ID;
3808 
3809 	return wlansap_get_2g_first_safe_chan_freq(sap_ctx);
3810 }
3811 
3812 int wlansap_update_sap_chan_list(struct sap_config *sap_config,
3813 				 qdf_freq_t *freq_list, uint16_t count)
3814 {
3815 	uint32_t *acs_cfg_freq_list;
3816 	uint32_t *master_freq_list;
3817 	uint32_t i;
3818 	bool old_acs_2g_only = true, acs_2g_only_new = true;
3819 
3820 	acs_cfg_freq_list = qdf_mem_malloc(count * sizeof(uint32_t));
3821 	if (!acs_cfg_freq_list)
3822 		return -ENOMEM;
3823 	if (sap_config->acs_cfg.ch_list_count) {
3824 		qdf_mem_free(sap_config->acs_cfg.freq_list);
3825 		sap_config->acs_cfg.freq_list = NULL;
3826 		sap_config->acs_cfg.ch_list_count = 0;
3827 	}
3828 	sap_config->acs_cfg.freq_list = acs_cfg_freq_list;
3829 
3830 	master_freq_list = qdf_mem_malloc(count * sizeof(uint32_t));
3831 	if (!master_freq_list)
3832 		return -ENOMEM;
3833 
3834 	if (sap_config->acs_cfg.master_ch_list_count) {
3835 		for (i = 0; i < sap_config->acs_cfg.master_ch_list_count; i++)
3836 			if (sap_config->acs_cfg.master_freq_list &&
3837 			    !WLAN_REG_IS_24GHZ_CH_FREQ(
3838 				sap_config->acs_cfg.master_freq_list[i])) {
3839 				old_acs_2g_only = false;
3840 				break;
3841 			}
3842 		qdf_mem_free(sap_config->acs_cfg.master_freq_list);
3843 		sap_config->acs_cfg.master_freq_list = NULL;
3844 		sap_config->acs_cfg.master_ch_list_count = 0;
3845 	}
3846 	sap_config->acs_cfg.master_freq_list = master_freq_list;
3847 
3848 	qdf_mem_copy(sap_config->acs_cfg.freq_list, freq_list,
3849 		     sizeof(freq_list[0]) * count);
3850 	qdf_mem_copy(sap_config->acs_cfg.master_freq_list, freq_list,
3851 		     sizeof(freq_list[0]) * count);
3852 	sap_config->acs_cfg.master_ch_list_count = count;
3853 	sap_config->acs_cfg.ch_list_count = count;
3854 	for (i = 0; i < sap_config->acs_cfg.master_ch_list_count; i++)
3855 		if (sap_config->acs_cfg.master_freq_list &&
3856 		    !WLAN_REG_IS_24GHZ_CH_FREQ(
3857 				sap_config->acs_cfg.master_freq_list[i])) {
3858 			acs_2g_only_new = false;
3859 			break;
3860 		}
3861 	/* If SAP initially started on world mode, the SAP ACS master channel
3862 	 * list will only contain 2.4 GHz channels. When country code changed
3863 	 * from world mode to non world mode, the master_ch_list will
3864 	 * be updated by this API from userspace and the list will include
3865 	 * 2.4 GHz + 5/6 GHz normally. If this transition happens, we set
3866 	 * master_ch_list_updated flag. And later only if the flag is set,
3867 	 * wlansap_get_chan_band_restrict will be invoked to select new SAP
3868 	 * channel frequency based on PCL.
3869 	 */
3870 	sap_config->acs_cfg.master_ch_list_updated =
3871 			old_acs_2g_only && !acs_2g_only_new;
3872 	sap_dump_acs_channel(&sap_config->acs_cfg);
3873 
3874 	return 0;
3875 }
3876 
3877 /**
3878  * wlansap_get_valid_freq() - To get valid freq for sap csa
3879  * @psoc: psoc object
3880  * @sap_ctx: sap context
3881  * @freq: pointer to valid freq
3882  *
3883  * If sap master channel list is updated from 2G only to 2G+5G/6G,
3884  * this API will find new SAP channel frequency likely 5G/6G to have
3885  * better performance for SAP. This happens when SAP started in
3886  * world mode, later country code change to non world mode.
3887  *
3888  * Return: None
3889  */
3890 static
3891 void wlansap_get_valid_freq(struct wlan_objmgr_psoc *psoc,
3892 			    struct sap_context *sap_ctx,
3893 			    qdf_freq_t *freq)
3894 {
3895 	uint8_t i, j;
3896 	struct mac_context *mac;
3897 	struct sir_pcl_list pcl = {0};
3898 	uint32_t *pcl_freqs;
3899 	QDF_STATUS status;
3900 	uint32_t pcl_len = 0;
3901 
3902 	if (!sap_ctx->acs_cfg || !sap_ctx->acs_cfg->master_ch_list_count)
3903 		return;
3904 
3905 	if (!sap_ctx->acs_cfg->master_ch_list_updated)
3906 		return;
3907 
3908 	sap_ctx->acs_cfg->master_ch_list_updated = false;
3909 
3910 	pcl_freqs =  qdf_mem_malloc(NUM_CHANNELS * sizeof(uint32_t));
3911 	if (!pcl_freqs)
3912 		return;
3913 
3914 	mac = sap_get_mac_context();
3915 	if (!mac) {
3916 		sap_err("Invalid MAC context");
3917 		goto done;
3918 	}
3919 	status = policy_mgr_reset_sap_mandatory_channels(psoc);
3920 	if (QDF_IS_STATUS_ERROR(status)) {
3921 		sap_err("failed to reset mandatory channels");
3922 		goto done;
3923 	}
3924 	status = policy_mgr_get_pcl_for_vdev_id(mac->psoc, PM_SAP_MODE,
3925 						pcl_freqs, &pcl_len,
3926 						pcl.weight_list,
3927 						NUM_CHANNELS,
3928 						sap_ctx->sessionId);
3929 
3930 	if (QDF_IS_STATUS_ERROR(status)) {
3931 		sap_err("Get PCL failed for session %d", sap_ctx->sessionId);
3932 		goto done;
3933 	}
3934 	for (i = 0; i < pcl_len; i++) {
3935 		for (j = 0; j < sap_ctx->acs_cfg->master_ch_list_count; j++) {
3936 			/*
3937 			 * To keep valid freq list order same as pcl weightage
3938 			 * order pcl list index is compared with all the freq
3939 			 * provided by set wifi config.
3940 			 */
3941 			if (sap_ctx->acs_cfg->master_freq_list[j] ==
3942 			    pcl_freqs[i]) {
3943 				*freq = pcl_freqs[i];
3944 				goto done;
3945 			}
3946 		}
3947 	}
3948 done:
3949 	qdf_mem_free(pcl_freqs);
3950 	pcl_freqs = NULL;
3951 }
3952 
3953 qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx,
3954 					  enum sap_csa_reason_code *csa_reason)
3955 {
3956 	uint32_t restart_freq;
3957 	uint16_t intf_ch_freq;
3958 	uint32_t phy_mode;
3959 	struct mac_context *mac;
3960 	uint8_t cc_mode;
3961 	uint8_t vdev_id;
3962 	enum reg_wifi_band sap_band;
3963 	enum band_info band;
3964 	bool sta_sap_scc_on_indoor_channel;
3965 	qdf_freq_t freq = 0;
3966 	struct ch_params ch_params = {0};
3967 
3968 	if (!sap_ctx) {
3969 		sap_err("sap_ctx NULL parameter");
3970 		return 0;
3971 	}
3972 
3973 	if (!csa_reason) {
3974 		sap_err("csa_reason is NULL");
3975 		return 0;
3976 	}
3977 
3978 	if (cds_is_driver_recovering())
3979 		return 0;
3980 
3981 	mac = cds_get_context(QDF_MODULE_ID_PE);
3982 	if (!mac)
3983 		return 0;
3984 
3985 	if (ucfg_reg_get_band(mac->pdev, &band) != QDF_STATUS_SUCCESS) {
3986 		sap_err("Failed to get current band config");
3987 		return 0;
3988 	}
3989 	sta_sap_scc_on_indoor_channel =
3990 		policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(mac->psoc);
3991 	sap_band = wlan_reg_freq_to_band(sap_ctx->chan_freq);
3992 
3993 	sap_debug("SAP/Go current band: %d, pdev band capability: %d, cur freq %d (is valid %d), prev freq %d (is valid %d)",
3994 		  sap_band, band, sap_ctx->chan_freq,
3995 		  wlan_reg_is_enable_in_secondary_list_for_freq(mac->pdev,
3996 							sap_ctx->chan_freq),
3997 		  sap_ctx->chan_freq_before_switch_band,
3998 		  wlan_reg_is_enable_in_secondary_list_for_freq(mac->pdev,
3999 					sap_ctx->chan_freq_before_switch_band));
4000 
4001 	if (sap_band == REG_BAND_5G && band == BIT(REG_BAND_2G)) {
4002 		sap_ctx->chan_freq_before_switch_band = sap_ctx->chan_freq;
4003 		sap_ctx->chan_width_before_switch_band =
4004 			sap_ctx->ch_params.ch_width;
4005 		sap_debug("Save chan info before switch: %d, width: %d",
4006 			  sap_ctx->chan_freq, sap_ctx->ch_params.ch_width);
4007 		restart_freq = wlansap_get_2g_first_safe_chan_freq(sap_ctx);
4008 		if (restart_freq == 0) {
4009 			sap_debug("use default chan 6");
4010 			restart_freq = TWOG_CHAN_6_IN_MHZ;
4011 		}
4012 		*csa_reason = CSA_REASON_BAND_RESTRICTED;
4013 	} else if (sap_band == REG_BAND_2G && (band & BIT(REG_BAND_5G))) {
4014 		if (sap_ctx->chan_freq_before_switch_band) {
4015 			if (!wlan_reg_is_disable_in_secondary_list_for_freq(
4016 			    mac->pdev,
4017 			    sap_ctx->chan_freq_before_switch_band)) {
4018 				restart_freq =
4019 					sap_ctx->chan_freq_before_switch_band;
4020 				sap_debug("Restore chan freq: %d",
4021 					  restart_freq);
4022 				*csa_reason = CSA_REASON_BAND_RESTRICTED;
4023 			} else {
4024 				enum reg_wifi_band pref_band;
4025 
4026 				pref_band =
4027 					wlan_reg_freq_to_band(
4028 					sap_ctx->chan_freq_before_switch_band);
4029 				restart_freq =
4030 				policy_mgr_get_alternate_channel_for_sap(
4031 							mac->psoc,
4032 							sap_ctx->sessionId,
4033 							sap_ctx->chan_freq,
4034 							pref_band);
4035 				if (restart_freq) {
4036 					sap_debug("restart SAP on freq %d",
4037 						  restart_freq);
4038 					*csa_reason =
4039 						CSA_REASON_BAND_RESTRICTED;
4040 				} else {
4041 					sap_debug("Did not get valid freq for band %d remain on same channel",
4042 						  pref_band);
4043 					return 0;
4044 				}
4045 			}
4046 		} else {
4047 			wlansap_get_valid_freq(mac->psoc, sap_ctx, &freq);
4048 			if (!freq)
4049 				return 0;
4050 
4051 			restart_freq = freq;
4052 			sap_debug("restart SAP on freq %d",
4053 				  restart_freq);
4054 			*csa_reason = CSA_REASON_BAND_RESTRICTED;
4055 		}
4056 	} else if (wlan_reg_is_disable_in_secondary_list_for_freq(
4057 							mac->pdev,
4058 							sap_ctx->chan_freq) &&
4059 		   !utils_dfs_is_freq_in_nol(mac->pdev, sap_ctx->chan_freq)) {
4060 		sap_debug("channel is disabled");
4061 		*csa_reason = CSA_REASON_CHAN_DISABLED;
4062 		return wlansap_get_safe_channel_from_pcl_and_acs_range(sap_ctx,
4063 								       NULL);
4064 	} else if (wlan_reg_is_passive_for_freq(mac->pdev,
4065 						sap_ctx->chan_freq))  {
4066 		sap_ctx->chan_freq_before_switch_band = sap_ctx->chan_freq;
4067 		sap_ctx->chan_width_before_switch_band =
4068 			sap_ctx->ch_params.ch_width;
4069 		sap_debug("Save chan info before switch: %d, width: %d",
4070 			  sap_ctx->chan_freq, sap_ctx->ch_params.ch_width);
4071 		sap_debug("channel is passive");
4072 		*csa_reason = CSA_REASON_CHAN_PASSIVE;
4073 		return wlansap_get_safe_channel_from_pcl_for_sap(sap_ctx);
4074 	} else if (!policy_mgr_is_sap_freq_allowed(mac->psoc,
4075 						   sap_ctx->chan_freq)) {
4076 		sap_debug("channel is unsafe");
4077 		*csa_reason = CSA_REASON_UNSAFE_CHANNEL;
4078 		return wlansap_get_safe_channel_from_pcl_and_acs_range(sap_ctx,
4079 								       NULL);
4080 	} else if (sap_band == REG_BAND_6G &&
4081 		   wlan_reg_get_keep_6ghz_sta_cli_connection(mac->pdev)) {
4082 		ch_params.ch_width = sap_ctx->ch_params.ch_width;
4083 		wlan_reg_set_channel_params_for_pwrmode(mac->pdev,
4084 						sap_ctx->chan_freq,
4085 						0, &ch_params,
4086 						REG_CURRENT_PWR_MODE);
4087 		if (sap_ctx->ch_params.ch_width != ch_params.ch_width) {
4088 			sap_debug("Bonded 6GHz channels are disabled");
4089 			*csa_reason = CSA_REASON_BAND_RESTRICTED;
4090 			return wlansap_get_safe_channel_from_pcl_and_acs_range(
4091 								sap_ctx, NULL);
4092 		} else {
4093 			sap_debug("No need switch SAP/Go channel");
4094 			return sap_ctx->chan_freq;
4095 		}
4096 	} else {
4097 		sap_debug("No need switch SAP/Go channel");
4098 		return sap_ctx->chan_freq;
4099 	}
4100 	cc_mode = sap_ctx->cc_switch_mode;
4101 	phy_mode = sap_ctx->phyMode;
4102 	vdev_id = wlan_vdev_get_id(sap_ctx->vdev);
4103 	intf_ch_freq = sme_check_concurrent_channel_overlap(
4104 						       MAC_HANDLE(mac),
4105 						       restart_freq,
4106 						       phy_mode,
4107 						       cc_mode, vdev_id);
4108 	if (intf_ch_freq)
4109 		restart_freq = intf_ch_freq;
4110 	if (restart_freq == sap_ctx->chan_freq)
4111 		restart_freq = 0;
4112 
4113 	if (restart_freq)
4114 		sap_debug("vdev: %d, CSA target freq: %d", vdev_id,
4115 			  restart_freq);
4116 
4117 	return restart_freq;
4118 }
4119 
4120 static inline bool
4121 wlansap_ch_in_avoid_ranges(uint32_t ch_freq,
4122 			   struct pld_ch_avoid_ind_type *ch_avoid_ranges)
4123 {
4124 	uint32_t i;
4125 
4126 	for (i = 0; i < ch_avoid_ranges->ch_avoid_range_cnt; i++) {
4127 		if (ch_freq >=
4128 			ch_avoid_ranges->avoid_freq_range[i].start_freq &&
4129 		    ch_freq <=
4130 			ch_avoid_ranges->avoid_freq_range[i].end_freq)
4131 			return true;
4132 	}
4133 
4134 	return false;
4135 }
4136 
4137 bool wlansap_filter_vendor_unsafe_ch_freq(
4138 	struct sap_context *sap_context, struct sap_config *sap_config)
4139 {
4140 	struct pld_ch_avoid_ind_type ch_avoid_ranges;
4141 	uint32_t i, j;
4142 	int ret;
4143 	qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
4144 	struct mac_context *mac;
4145 	uint32_t count;
4146 
4147 	if (!qdf_ctx)
4148 		return false;
4149 	mac = sap_get_mac_context();
4150 	if (!mac)
4151 		return false;
4152 
4153 	count = policy_mgr_get_sap_mode_count(mac->psoc, NULL);
4154 
4155 	if (count != policy_mgr_get_connection_count(mac->psoc))
4156 		return false;
4157 
4158 	ch_avoid_ranges.ch_avoid_range_cnt = 0;
4159 	ret = pld_get_wlan_unsafe_channel_sap(qdf_ctx->dev, &ch_avoid_ranges);
4160 	if (ret) {
4161 		sap_debug("failed to get vendor unsafe ch range, ret %d", ret);
4162 		return false;
4163 	}
4164 	if (!ch_avoid_ranges.ch_avoid_range_cnt)
4165 		return false;
4166 	for (i = 0; i < ch_avoid_ranges.ch_avoid_range_cnt; i++) {
4167 		sap_debug("vendor unsafe range[%d] %d %d", i,
4168 			  ch_avoid_ranges.avoid_freq_range[i].start_freq,
4169 			  ch_avoid_ranges.avoid_freq_range[i].end_freq);
4170 	}
4171 	for (i = 0, j = 0; i < sap_config->acs_cfg.ch_list_count; i++) {
4172 		if (!wlansap_ch_in_avoid_ranges(
4173 				sap_config->acs_cfg.freq_list[i],
4174 				&ch_avoid_ranges))
4175 			sap_config->acs_cfg.freq_list[j++] =
4176 				sap_config->acs_cfg.freq_list[i];
4177 	}
4178 	sap_config->acs_cfg.ch_list_count = j;
4179 
4180 	return true;
4181 }
4182 
4183 #ifdef DCS_INTERFERENCE_DETECTION
4184 QDF_STATUS wlansap_dcs_set_vdev_wlan_interference_mitigation(
4185 				struct sap_context *sap_context,
4186 				bool wlan_interference_mitigation_enable)
4187 {
4188 	struct mac_context *mac;
4189 
4190 	if (!sap_context) {
4191 		sap_err("Invalid SAP context pointer");
4192 		return QDF_STATUS_E_FAULT;
4193 	}
4194 
4195 	mac = sap_get_mac_context();
4196 	if (!mac) {
4197 		sap_err("Invalid MAC context");
4198 		return QDF_STATUS_E_FAULT;
4199 	}
4200 
4201 	mac->sap.dcs_info.
4202 		wlan_interference_mitigation_enable[sap_context->sessionId] =
4203 					wlan_interference_mitigation_enable;
4204 
4205 	return QDF_STATUS_SUCCESS;
4206 }
4207 
4208 QDF_STATUS wlansap_dcs_set_wlan_interference_mitigation_on_band(
4209 					struct sap_context *sap_context,
4210 					struct sap_config *sap_cfg)
4211 {
4212 	QDF_STATUS status = QDF_STATUS_SUCCESS;
4213 	bool wlan_interference_mitigation_enable = false;
4214 
4215 	if (!WLAN_REG_IS_24GHZ_CH_FREQ(sap_cfg->acs_cfg.pri_ch_freq))
4216 		wlan_interference_mitigation_enable = true;
4217 
4218 	status = wlansap_dcs_set_vdev_wlan_interference_mitigation(
4219 					sap_context,
4220 					wlan_interference_mitigation_enable);
4221 	return status;
4222 }
4223 
4224 QDF_STATUS wlansap_dcs_set_vdev_starting(struct sap_context *sap_context,
4225 					 bool vdev_starting)
4226 {
4227 	struct mac_context *mac;
4228 
4229 	if (!sap_context) {
4230 		sap_err("Invalid SAP context pointer");
4231 		return QDF_STATUS_E_FAULT;
4232 	}
4233 
4234 	mac = sap_get_mac_context();
4235 	if (!mac) {
4236 		sap_err("Invalid MAC context");
4237 		return QDF_STATUS_E_FAULT;
4238 	}
4239 
4240 	mac->sap.dcs_info.is_vdev_starting[sap_context->sessionId] =
4241 							vdev_starting;
4242 
4243 	return QDF_STATUS_SUCCESS;
4244 }
4245 
4246 bool wlansap_dcs_is_wlan_interference_mitigation_enabled(
4247 					struct sap_context *sap_context)
4248 {
4249 	struct mac_context *mac;
4250 
4251 	if (!sap_context) {
4252 		sap_err("Invalid SAP context pointer");
4253 		return false;
4254 	}
4255 
4256 	mac = sap_get_mac_context();
4257 	if (!mac) {
4258 		sap_err("Invalid MAC context");
4259 		return false;
4260 	}
4261 
4262 	return mac->sap.dcs_info.
4263 		wlan_interference_mitigation_enable[sap_context->sessionId];
4264 }
4265 
4266 qdf_freq_t wlansap_dcs_get_freq(struct sap_context *sap_context)
4267 {
4268 	if (!sap_context) {
4269 		sap_err("Invalid SAP context pointer");
4270 		return false;
4271 	}
4272 
4273 	return sap_context->dcs_ch_freq;
4274 }
4275 
4276 void wlansap_dump_acs_ch_freq(struct sap_context *sap_context)
4277 {
4278 	if (!sap_context) {
4279 		sap_err("Invalid sap_debug");
4280 		return;
4281 	}
4282 
4283 	if (sap_context->fsm_state == SAP_STARTED)
4284 		sap_info("ACS dump DCS freq=%d", sap_context->dcs_ch_freq);
4285 	else
4286 		sap_info("ACS dump ch_freq=%d", sap_context->chan_freq);
4287 }
4288 
4289 void wlansap_set_acs_ch_freq(struct sap_context *sap_context,
4290 			     qdf_freq_t ch_freq)
4291 {
4292 	if (!sap_context) {
4293 		sap_err("Invalid sap_debug");
4294 		return;
4295 	}
4296 
4297 	if (sap_context->fsm_state == SAP_STARTED) {
4298 		sap_context->dcs_ch_freq = ch_freq;
4299 		sap_debug("ACS configuring dcs_ch_freq=%d",
4300 			  sap_context->dcs_ch_freq);
4301 	} else {
4302 		sap_context->chan_freq = ch_freq;
4303 		sap_debug("ACS configuring ch_freq=%d",
4304 			  sap_context->chan_freq);
4305 	}
4306 }
4307 #else
4308 void wlansap_dump_acs_ch_freq(struct sap_context *sap_context)
4309 {
4310 	if (!sap_context) {
4311 		sap_err("Invalid sap_debug");
4312 		return;
4313 	}
4314 
4315 	sap_info("ACS dump ch_freq=%d", sap_context->chan_freq);
4316 }
4317 
4318 void wlansap_set_acs_ch_freq(struct sap_context *sap_context,
4319 			     qdf_freq_t ch_freq)
4320 {
4321 	if (!sap_context) {
4322 		sap_err("Invalid sap_debug");
4323 		return;
4324 	}
4325 
4326 	sap_context->chan_freq = ch_freq;
4327 	sap_debug("ACS configuring ch_freq=%d", sap_context->chan_freq);
4328 }
4329 #endif
4330 
4331 #ifdef WLAN_FEATURE_11BE
4332 bool sap_phymode_is_eht(eCsrPhyMode phymode)
4333 {
4334 	return CSR_IS_DOT11_PHY_MODE_11BE(phymode) ||
4335 	       CSR_IS_DOT11_PHY_MODE_11BE_ONLY(phymode);
4336 }
4337 
4338 bool sap_acs_is_puncture_applicable(struct sap_acs_cfg *acs_cfg)
4339 {
4340 	bool is_eht_bw_80 = false;
4341 
4342 	if (!acs_cfg) {
4343 		sap_err("Invalid parameters");
4344 		return is_eht_bw_80;
4345 	}
4346 
4347 	switch (acs_cfg->ch_width) {
4348 	case CH_WIDTH_80MHZ:
4349 	case CH_WIDTH_80P80MHZ:
4350 	case CH_WIDTH_160MHZ:
4351 	case CH_WIDTH_320MHZ:
4352 		is_eht_bw_80 = acs_cfg->is_eht_enabled;
4353 		break;
4354 	default:
4355 		break;
4356 	}
4357 
4358 	return is_eht_bw_80;
4359 }
4360 
4361 void sap_acs_set_puncture_support(struct sap_context *sap_ctx,
4362 				  struct ch_params *ch_params)
4363 {
4364 	if (!sap_ctx || !ch_params) {
4365 		sap_err("Invalid parameters");
4366 		return;
4367 	}
4368 
4369 	if (sap_acs_is_puncture_applicable(sap_ctx->acs_cfg))
4370 		ch_params->is_create_punc_bitmap = true;
4371 }
4372 #endif
4373 
4374 void wlansap_update_ll_lt_sap_acs_result(struct sap_context *sap_ctx,
4375 					 qdf_freq_t last_acs_freq)
4376 {
4377 	struct mac_context *mac;
4378 
4379 	mac = sap_get_mac_context();
4380 	if (!mac) {
4381 		sap_err("Invalid MAC context");
4382 		return;
4383 	}
4384 
4385 	if (!sap_ctx) {
4386 		sap_err("Invalid sap context");
4387 		return;
4388 	}
4389 
4390 	wlansap_set_acs_ch_freq(sap_ctx, last_acs_freq);
4391 	sap_ctx->acs_cfg->pri_ch_freq = last_acs_freq;
4392 	sap_ctx->acs_cfg->ht_sec_ch_freq = 0;
4393 }
4394 
4395 QDF_STATUS wlansap_sort_channel_list(uint8_t vdev_id, qdf_list_t *list,
4396 				     struct sap_sel_ch_info *ch_info)
4397 {
4398 	struct mac_context *mac_ctx;
4399 
4400 	mac_ctx = sap_get_mac_context();
4401 	if (!mac_ctx) {
4402 		sap_err("Invalid MAC context");
4403 		return QDF_STATUS_E_FAILURE;
4404 	}
4405 
4406 	sap_sort_channel_list(mac_ctx, vdev_id, list,
4407 			      ch_info, NULL, NULL);
4408 
4409 	return QDF_STATUS_SUCCESS;
4410 }
4411 
4412 void wlansap_free_chan_info(struct sap_sel_ch_info *ch_param)
4413 {
4414 	sap_chan_sel_exit(ch_param);
4415 }
4416 
4417 void wlansap_get_user_config_acs_ch_list(uint8_t vdev_id,
4418 					 struct scan_filter *filter)
4419 {
4420 	struct mac_context *mac_ctx;
4421 	struct sap_context *sap_ctx;
4422 	uint8_t ch_count = 0;
4423 
4424 	mac_ctx = sap_get_mac_context();
4425 	if (!mac_ctx) {
4426 		sap_err("Invalid MAC context");
4427 		return;
4428 	}
4429 
4430 	if (vdev_id >= WLAN_UMAC_VDEV_ID_MAX)
4431 		return;
4432 
4433 	sap_ctx = mac_ctx->sap.sapCtxList[vdev_id].sap_context;
4434 
4435 	if (!sap_ctx) {
4436 		sap_err("vdev %d sap_ctx is NULL", vdev_id);
4437 		return;
4438 	}
4439 
4440 	ch_count = sap_ctx->acs_cfg->master_ch_list_count;
4441 
4442 	if (!ch_count || ch_count > NUM_CHANNELS)
4443 		return;
4444 
4445 	filter->num_of_channels = ch_count;
4446 	qdf_mem_copy(filter->chan_freq_list, sap_ctx->acs_cfg->master_freq_list,
4447 		     filter->num_of_channels *
4448 		     sizeof(filter->chan_freq_list[0]));
4449 }
4450