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