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