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(¶ms->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