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