xref: /wlan-dirver/qcacld-3.0/core/sap/src/sap_fsm.c (revision e22f9adc774eb030715d9a453ec9ea346916ed3b)
1 /*
2  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /*===========================================================================
21 
22 			s a p F s m . C
23 
24    OVERVIEW:
25 
26    This software unit holds the implementation of the WLAN SAP Finite
27    State Machine modules
28 
29    DEPENDENCIES:
30 
31    Are listed for each API below.
32    ===========================================================================*/
33 
34 /*----------------------------------------------------------------------------
35  * Include Files
36  * -------------------------------------------------------------------------*/
37 #include "sap_internal.h"
38 #include <wlan_dfs_tgt_api.h>
39 #include <wlan_dfs_utils_api.h>
40 #include <wlan_dfs_public_struct.h>
41 #include <wlan_reg_services_api.h>
42 /* Pick up the SME API definitions */
43 #include "sme_api.h"
44 /* Pick up the PMC API definitions */
45 #include "cds_utils.h"
46 #include "cds_ieee80211_common_i.h"
47 #include "cds_reg_service.h"
48 #include "qdf_util.h"
49 #include "wlan_policy_mgr_api.h"
50 #include <wlan_objmgr_pdev_obj.h>
51 #include <wlan_objmgr_vdev_obj.h>
52 #include <wlan_utility.h>
53 #include <linux/netdevice.h>
54 #include <net/cfg80211.h>
55 #include <qca_vendor.h>
56 #include <wlan_scan_api.h>
57 #include "wlan_reg_services_api.h"
58 #include "wlan_mlme_ucfg_api.h"
59 #include "wlan_policy_mgr_ucfg.h"
60 #include "cfg_ucfg_api.h"
61 #include "wlan_mlme_vdev_mgr_interface.h"
62 #include "wlan_vdev_mgr_utils_api.h"
63 #include "wlan_pre_cac_api.h"
64 #include <wlan_cmn_ieee80211.h>
65 #include <target_if.h>
66 
67 /*----------------------------------------------------------------------------
68  * Preprocessor Definitions and Constants
69  * -------------------------------------------------------------------------*/
70 
71 /*----------------------------------------------------------------------------
72  * Type Declarations
73  * -------------------------------------------------------------------------*/
74 
75 /*----------------------------------------------------------------------------
76  * Global Data Definitions
77  * -------------------------------------------------------------------------*/
78 
79 /*----------------------------------------------------------------------------
80  *  External declarations for global context
81  * -------------------------------------------------------------------------*/
82 /*----------------------------------------------------------------------------
83  * Static Variable Definitions
84  * -------------------------------------------------------------------------*/
85 
86 /*----------------------------------------------------------------------------
87  * Static Function Declarations and Definitions
88  * -------------------------------------------------------------------------*/
89 #ifdef SOFTAP_CHANNEL_RANGE
90 static QDF_STATUS sap_get_freq_list(struct sap_context *sap_ctx,
91 				    uint32_t **freq_list,
92 				    uint8_t *num_ch);
93 #endif
94 
95 /*==========================================================================
96    FUNCTION    sapStopDfsCacTimer
97 
98    DESCRIPTION
99     Function to sttop the DFS CAC timer when SAP is stopped
100    DEPENDENCIES
101     NA.
102 
103    PARAMETERS
104 
105     IN
106     sap_ctx: SAP Context
107    RETURN VALUE
108     DFS Timer start status
109    SIDE EFFECTS
110    ============================================================================*/
111 
112 static int sap_stop_dfs_cac_timer(struct sap_context *sap_ctx);
113 
114 /*==========================================================================
115    FUNCTION    sapStartDfsCacTimer
116 
117    DESCRIPTION
118     Function to start the DFS CAC timer when SAP is started on DFS Channel
119    DEPENDENCIES
120     NA.
121 
122    PARAMETERS
123 
124     IN
125     sap_ctx: SAP Context
126    RETURN VALUE
127     DFS Timer start status
128    SIDE EFFECTS
129    ============================================================================*/
130 
131 static int sap_start_dfs_cac_timer(struct sap_context *sap_ctx);
132 
133 /** sap_hdd_event_to_string() - convert hdd event to string
134  * @event: eSapHddEvent event type
135  *
136  * This function converts eSapHddEvent into string
137  *
138  * Return: string for the @event.
139  */
140 static uint8_t *sap_hdd_event_to_string(eSapHddEvent event)
141 {
142 	switch (event) {
143 	CASE_RETURN_STRING(eSAP_START_BSS_EVENT);
144 	CASE_RETURN_STRING(eSAP_STOP_BSS_EVENT);
145 	CASE_RETURN_STRING(eSAP_STA_ASSOC_IND);
146 	CASE_RETURN_STRING(eSAP_STA_ASSOC_EVENT);
147 	CASE_RETURN_STRING(eSAP_STA_REASSOC_EVENT);
148 	CASE_RETURN_STRING(eSAP_STA_DISASSOC_EVENT);
149 	CASE_RETURN_STRING(eSAP_STA_SET_KEY_EVENT);
150 	CASE_RETURN_STRING(eSAP_STA_MIC_FAILURE_EVENT);
151 	CASE_RETURN_STRING(eSAP_WPS_PBC_PROBE_REQ_EVENT);
152 	CASE_RETURN_STRING(eSAP_DISCONNECT_ALL_P2P_CLIENT);
153 	CASE_RETURN_STRING(eSAP_MAC_TRIG_STOP_BSS_EVENT);
154 	CASE_RETURN_STRING(eSAP_UNKNOWN_STA_JOIN);
155 	CASE_RETURN_STRING(eSAP_MAX_ASSOC_EXCEEDED);
156 	CASE_RETURN_STRING(eSAP_CHANNEL_CHANGE_EVENT);
157 	CASE_RETURN_STRING(eSAP_DFS_CAC_START);
158 	CASE_RETURN_STRING(eSAP_DFS_CAC_INTERRUPTED);
159 	CASE_RETURN_STRING(eSAP_DFS_CAC_END);
160 	CASE_RETURN_STRING(eSAP_DFS_RADAR_DETECT);
161 	CASE_RETURN_STRING(eSAP_DFS_NO_AVAILABLE_CHANNEL);
162 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
163 	CASE_RETURN_STRING(eSAP_ACS_SCAN_SUCCESS_EVENT);
164 #endif
165 	CASE_RETURN_STRING(eSAP_ACS_CHANNEL_SELECTED);
166 	CASE_RETURN_STRING(eSAP_ECSA_CHANGE_CHAN_IND);
167 	default:
168 		return "eSAP_HDD_EVENT_UNKNOWN";
169 	}
170 }
171 
172 #ifdef QCA_DFS_BW_PUNCTURE
173 /**
174  * sap_is_chan_change_needed() - Check if SAP channel change needed
175  * @sap_ctx: sap context.
176  *
177  * Even some 20 MHz sub channel disabled for nol, if puncture pattern is valid,
178  * SAP still can keep current channel width and primary channel, don't need
179  * change channel.
180  *
181  * Return: bool, true: channel change needed
182  */
183 static bool
184 sap_is_chan_change_needed(struct sap_context *sap_ctx)
185 {
186 	uint8_t ch_wd;
187 	uint16_t pri_freq_puncture = 0;
188 	struct ch_params *ch_params;
189 	QDF_STATUS status;
190 	struct mac_context *mac_ctx;
191 
192 	mac_ctx = sap_get_mac_context();
193 	if (!mac_ctx) {
194 		sap_err("Invalid MAC context");
195 		return true;
196 	}
197 
198 	ch_params = &mac_ctx->sap.SapDfsInfo.new_ch_params;
199 	if (mac_ctx->sap.SapDfsInfo.orig_chanWidth == 0) {
200 		ch_wd = sap_ctx->ch_width_orig;
201 		mac_ctx->sap.SapDfsInfo.orig_chanWidth = ch_wd;
202 	} else {
203 		ch_wd = mac_ctx->sap.SapDfsInfo.orig_chanWidth;
204 	}
205 
206 	ch_params->ch_width = ch_wd;
207 
208 	if (sap_phymode_is_eht(sap_ctx->phyMode))
209 		wlan_reg_set_create_punc_bitmap(ch_params, true);
210 	wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev,
211 						sap_ctx->chan_freq,
212 						0,
213 						ch_params,
214 						REG_CURRENT_PWR_MODE);
215 	if (ch_params->ch_width == sap_ctx->ch_params.ch_width) {
216 		status = wlan_reg_extract_puncture_by_bw(ch_params->ch_width,
217 							 ch_params->reg_punc_bitmap,
218 							 sap_ctx->chan_freq,
219 							 ch_params->mhz_freq_seg1,
220 							 CH_WIDTH_20MHZ,
221 							 &pri_freq_puncture);
222 		if (QDF_IS_STATUS_SUCCESS(status) && !pri_freq_puncture) {
223 			sap_debug("Eht valid puncture : 0x%x, keep freq %d",
224 				  ch_params->reg_punc_bitmap,
225 				  sap_ctx->chan_freq);
226 			mac_ctx->sap.SapDfsInfo.new_chanWidth =
227 						ch_params->ch_width;
228 			return false;
229 		}
230 	}
231 
232 	return true;
233 }
234 #else
235 static inline bool
236 sap_is_chan_change_needed(struct sap_context *sap_ctx)
237 {
238 	return true;
239 }
240 #endif
241 
242 #ifdef DFS_COMPONENT_ENABLE
243 /**
244  * sap_random_channel_sel() - This function randomly pick up an available
245  * channel
246  * @sap_ctx: sap context.
247  *
248  * This function first eliminates invalid channel, then selects random channel
249  * using following algorithm:
250  *
251  * Return: channel frequency picked
252  */
253 static qdf_freq_t sap_random_channel_sel(struct sap_context *sap_ctx)
254 {
255 	uint16_t chan_freq;
256 	uint8_t ch_wd;
257 	struct wlan_objmgr_pdev *pdev = NULL;
258 	struct ch_params *ch_params;
259 	uint32_t hw_mode, flag  = 0;
260 	struct mac_context *mac_ctx;
261 	struct dfs_acs_info acs_info = {0};
262 
263 	mac_ctx = sap_get_mac_context();
264 	if (!mac_ctx) {
265 		sap_err("Invalid MAC context");
266 		return 0;
267 	}
268 
269 	pdev = mac_ctx->pdev;
270 	if (!pdev) {
271 		sap_err("null pdev");
272 		return 0;
273 	}
274 
275 	ch_params = &mac_ctx->sap.SapDfsInfo.new_ch_params;
276 	if (mac_ctx->sap.SapDfsInfo.orig_chanWidth == 0) {
277 		ch_wd = sap_ctx->ch_width_orig;
278 		mac_ctx->sap.SapDfsInfo.orig_chanWidth = ch_wd;
279 	} else {
280 		ch_wd = mac_ctx->sap.SapDfsInfo.orig_chanWidth;
281 	}
282 
283 	ch_params->ch_width = ch_wd;
284 	if (sap_ctx->acs_cfg) {
285 		acs_info.acs_mode = sap_ctx->acs_cfg->acs_mode;
286 		acs_info.chan_freq_list = sap_ctx->acs_cfg->master_freq_list;
287 		acs_info.num_of_channel =
288 					sap_ctx->acs_cfg->master_ch_list_count;
289 	} else {
290 		acs_info.acs_mode = false;
291 	}
292 
293 	if (mac_ctx->mlme_cfg->dfs_cfg.dfs_prefer_non_dfs)
294 		flag |= DFS_RANDOM_CH_FLAG_NO_DFS_CH;
295 	if (mac_ctx->mlme_cfg->dfs_cfg.dfs_disable_japan_w53)
296 		flag |= DFS_RANDOM_CH_FLAG_NO_JAPAN_W53_CH;
297 	if (mac_ctx->sap.SapDfsInfo.sap_operating_chan_preferred_location
298 	    == 1)
299 		flag |= DFS_RANDOM_CH_FLAG_NO_UPEER_5G_CH;
300 	else if (mac_ctx->sap.SapDfsInfo.
301 		 sap_operating_chan_preferred_location == 2)
302 		flag |= DFS_RANDOM_CH_FLAG_NO_LOWER_5G_CH;
303 
304 	/*
305 	 * Dont choose 6ghz channel currently as legacy clients won't be able to
306 	 * scan them. In future create an ini if any customer wants 6ghz freq
307 	 * to be prioritize over 5ghz/2.4ghz.
308 	 * Currently for SAP there is a high chance of 6ghz being selected as
309 	 * an op frequency as PCL will have only 5, 6ghz freq as preferred for
310 	 * standalone SAP, and 6ghz channels being high in number.
311 	 */
312 	flag |= DFS_RANDOM_CH_FLAG_NO_6GHZ_CH;
313 
314 	if (sap_ctx->candidate_freq &&
315 	    sap_ctx->chan_freq != sap_ctx->candidate_freq &&
316 	    !utils_dfs_is_freq_in_nol(pdev, sap_ctx->candidate_freq)) {
317 		chan_freq = sap_ctx->candidate_freq;
318 		if (sap_phymode_is_eht(sap_ctx->phyMode))
319 			wlan_reg_set_create_punc_bitmap(ch_params, true);
320 		wlan_reg_set_channel_params_for_pwrmode(pdev, chan_freq, 0,
321 							ch_params,
322 							REG_CURRENT_PWR_MODE);
323 		sap_debug("random chan select candidate freq=%d", chan_freq);
324 		sap_ctx->candidate_freq = 0;
325 	} else if (QDF_IS_STATUS_ERROR(
326 				utils_dfs_get_vdev_random_channel_for_freq(
327 					pdev, sap_ctx->vdev, flag, ch_params,
328 					&hw_mode, &chan_freq, &acs_info))) {
329 		/* No available channel found */
330 		sap_err("No available channel found!!!");
331 		sap_signal_hdd_event(sap_ctx, NULL,
332 				     eSAP_DFS_NO_AVAILABLE_CHANNEL,
333 				     (void *)eSAP_STATUS_SUCCESS);
334 		return 0;
335 	}
336 
337 	mac_ctx->sap.SapDfsInfo.new_chanWidth = ch_params->ch_width;
338 	sap_ctx->ch_params.ch_width = ch_params->ch_width;
339 	sap_ctx->ch_params.sec_ch_offset = ch_params->sec_ch_offset;
340 	sap_ctx->ch_params.center_freq_seg0 = ch_params->center_freq_seg0;
341 	sap_ctx->ch_params.center_freq_seg1 = ch_params->center_freq_seg1;
342 	return chan_freq;
343 }
344 #else
345 static uint8_t sap_random_channel_sel(struct sap_context *sap_ctx)
346 {
347 	return 0;
348 }
349 #endif
350 
351 /**
352  * sap_is_channel_bonding_etsi_weather_channel() - check weather chan bonding.
353  * @sap_ctx: sap context.
354  * @chan_freq: chan frequency
355  * @ch_params: pointer to ch_params
356  *
357  * Check if given channel and channel params are bonded to weather radar
358  * channel in ETSI domain.
359  *
360  * Return: True if bonded to weather channel in ETSI
361  */
362 static bool
363 sap_is_channel_bonding_etsi_weather_channel(struct sap_context *sap_ctx,
364 					    qdf_freq_t chan_freq,
365 					    struct ch_params *ch_params)
366 {
367 	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(sap_ctx->vdev);
368 
369 	if (IS_CH_BONDING_WITH_WEATHER_CH(wlan_reg_freq_to_chan(pdev,
370 								chan_freq)) &&
371 	    ch_params->ch_width != CH_WIDTH_20MHZ)
372 		return true;
373 
374 	return false;
375 }
376 
377 /*
378  * sap_get_bonding_channels() - get bonding channels from primary channel.
379  * @sap_ctx: Handle to SAP context.
380  * @chan_freq: Channel frequency to get bonded channels.
381  * @freq_list: Bonded channel frequency list
382  * @size: Max bonded channels
383  * @chanBondState: The channel bonding mode of the passed channel.
384  *
385  * Return: Number of sub channels
386  */
387 static uint8_t sap_get_bonding_channels(struct sap_context *sap_ctx,
388 					qdf_freq_t chan_freq,
389 					qdf_freq_t *freq_list, uint8_t size,
390 					ePhyChanBondState chanBondState)
391 {
392 	uint8_t num_freq;
393 
394 	if (!freq_list)
395 		return 0;
396 
397 	if (size < MAX_BONDED_CHANNELS)
398 		return 0;
399 
400 	switch (chanBondState) {
401 	case PHY_SINGLE_CHANNEL_CENTERED:
402 		num_freq = 1;
403 		freq_list[0] = chan_freq;
404 		break;
405 	case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
406 		num_freq = 2;
407 		freq_list[0] = chan_freq - 20;
408 		freq_list[1] = chan_freq;
409 		break;
410 	case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
411 		num_freq = 2;
412 		freq_list[0] = chan_freq;
413 		freq_list[1] = chan_freq + 20;
414 		break;
415 	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
416 		num_freq = 4;
417 		freq_list[0] = chan_freq;
418 		freq_list[1] = chan_freq + 20;
419 		freq_list[2] = chan_freq + 40;
420 		freq_list[3] = chan_freq + 60;
421 		break;
422 	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
423 		num_freq = 4;
424 		freq_list[0] = chan_freq - 20;
425 		freq_list[1] = chan_freq;
426 		freq_list[2] = chan_freq + 20;
427 		freq_list[3] = chan_freq + 40;
428 		break;
429 	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
430 		num_freq = 4;
431 		freq_list[0] = chan_freq - 40;
432 		freq_list[1] = chan_freq - 20;
433 		freq_list[2] = chan_freq;
434 		freq_list[3] = chan_freq + 20;
435 		break;
436 	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
437 		num_freq = 4;
438 		freq_list[0] = chan_freq - 60;
439 		freq_list[1] = chan_freq - 40;
440 		freq_list[2] = chan_freq - 20;
441 		freq_list[3] = chan_freq;
442 		break;
443 	default:
444 		num_freq = 1;
445 		freq_list[0] = chan_freq;
446 		break;
447 	}
448 
449 	return num_freq;
450 }
451 
452 /**
453  * sap_ch_params_to_bonding_channels() - get bonding channels from channel param
454  * @ch_params: channel params ( bw, pri and sec channel info)
455  * @freq_list: bonded channel frequency list
456  *
457  * Return: Number of sub channel frequencies
458  */
459 static uint8_t sap_ch_params_to_bonding_channels(
460 		struct ch_params *ch_params,
461 		qdf_freq_t *freq_list)
462 {
463 	qdf_freq_t center_freq = ch_params->mhz_freq_seg0;
464 	uint8_t num_freq = 0;
465 
466 	switch (ch_params->ch_width) {
467 	case CH_WIDTH_160MHZ:
468 		num_freq = 8;
469 		center_freq = ch_params->mhz_freq_seg1;
470 		freq_list[0] = center_freq - 70;
471 		freq_list[1] = center_freq - 50;
472 		freq_list[2] = center_freq - 30;
473 		freq_list[3] = center_freq - 10;
474 		freq_list[4] = center_freq + 10;
475 		freq_list[5] = center_freq + 30;
476 		freq_list[6] = center_freq + 50;
477 		freq_list[7] = center_freq + 70;
478 		break;
479 	case CH_WIDTH_80P80MHZ:
480 		num_freq = 8;
481 		freq_list[0] = center_freq - 30;
482 		freq_list[1] = center_freq - 10;
483 		freq_list[2] = center_freq + 10;
484 		freq_list[3] = center_freq + 30;
485 
486 		center_freq = ch_params->mhz_freq_seg1;
487 		freq_list[4] = center_freq - 30;
488 		freq_list[5] = center_freq - 10;
489 		freq_list[6] = center_freq + 10;
490 		freq_list[7] = center_freq + 30;
491 		break;
492 	case CH_WIDTH_80MHZ:
493 		num_freq = 4;
494 		freq_list[0] = center_freq - 30;
495 		freq_list[1] = center_freq - 10;
496 		freq_list[2] = center_freq + 10;
497 		freq_list[3] = center_freq + 30;
498 		break;
499 	case CH_WIDTH_40MHZ:
500 		num_freq = 2;
501 		freq_list[0] = center_freq - 10;
502 		freq_list[1] = center_freq + 10;
503 		break;
504 	default:
505 		num_freq = 1;
506 		freq_list[0] = center_freq;
507 		break;
508 	}
509 
510 	return num_freq;
511 }
512 
513 /**
514  * sap_operating_on_dfs() - check current sap operating on dfs
515  * @mac_ctx: mac ctx
516  * @sap_ctx: SAP context
517  *
518  * Return: true if any sub channel is dfs channel
519  */
520 static
521 bool sap_operating_on_dfs(struct mac_context *mac_ctx,
522 			  struct sap_context *sap_ctx)
523 {
524 	struct wlan_channel *chan;
525 
526 	if (!sap_ctx->vdev) {
527 		sap_debug("vdev invalid");
528 		return false;
529 	}
530 
531 	chan = wlan_vdev_get_active_channel(sap_ctx->vdev);
532 	if (!chan) {
533 		sap_debug("Couldn't get vdev active channel");
534 		return false;
535 	}
536 
537 	if (chan->ch_flagext & (IEEE80211_CHAN_DFS |
538 				IEEE80211_CHAN_DFS_CFREQ2))
539 		return true;
540 
541 	return false;
542 }
543 
544 bool sap_plus_sap_cac_skip(struct mac_context *mac,
545 			   struct sap_context *sap_ctx,
546 			   qdf_freq_t chan_freq)
547 {
548 	uint8_t intf;
549 
550 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
551 		struct sap_context *sap_context =
552 			mac->sap.sapCtxList[intf].sap_context;
553 
554 		if (!sap_context || sap_context == sap_ctx)
555 			continue;
556 		if (mac->sap.sapCtxList[intf].sapPersona != QDF_SAP_MODE &&
557 		    mac->sap.sapCtxList[intf].sapPersona != QDF_P2P_GO_MODE)
558 			continue;
559 		if (sap_context->isCacEndNotified &&
560 		    sap_context->chan_freq == chan_freq &&
561 		    sap_operating_on_dfs(mac, sap_context)) {
562 			sap_debug("SAP vid %d CAC can skip due to CAC completed on other SAP vid %d",
563 				  sap_ctx->sessionId, sap_context->sessionId);
564 			return true;
565 		}
566 	}
567 
568 	return false;
569 }
570 
571 /**
572  * is_wlansap_cac_required_for_chan() - Is cac required for given channel
573  * @mac_ctx: mac ctx
574  * @sap_ctx: sap context
575  * @chan_freq: given channel
576  * @ch_params: pointer to ch_params
577  *
578  * Return: True if cac is required for given channel
579  */
580 static bool
581 is_wlansap_cac_required_for_chan(struct mac_context *mac_ctx,
582 				 struct sap_context *sap_ctx,
583 				 qdf_freq_t chan_freq,
584 				 struct ch_params *ch_params)
585 {
586 	bool is_ch_dfs = false;
587 	bool cac_required;
588 	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
589 	uint32_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
590 	uint8_t sta_cnt, i;
591 	eSapDfsCACState_t cac_state = eSAP_DFS_DO_NOT_SKIP_CAC;
592 
593 	if (ch_params->ch_width == CH_WIDTH_160MHZ) {
594 		wlan_reg_set_create_punc_bitmap(ch_params, true);
595 		if (wlan_reg_get_5g_bonded_channel_state_for_pwrmode(mac_ctx->pdev,
596 								     chan_freq,
597 								     ch_params,
598 								     REG_CURRENT_PWR_MODE) ==
599 		    CHANNEL_STATE_DFS)
600 			is_ch_dfs = true;
601 	} else if (ch_params->ch_width == CH_WIDTH_80P80MHZ) {
602 		if (wlan_reg_get_channel_state_for_pwrmode(
603 						mac_ctx->pdev,
604 						chan_freq,
605 						REG_CURRENT_PWR_MODE) ==
606 		    CHANNEL_STATE_DFS ||
607 		    wlan_reg_get_channel_state_for_pwrmode(
608 					mac_ctx->pdev,
609 					ch_params->mhz_freq_seg1,
610 					REG_CURRENT_PWR_MODE) ==
611 				CHANNEL_STATE_DFS)
612 			is_ch_dfs = true;
613 	} else {
614 		/* Indoor channels are also marked DFS, therefore
615 		 * check if the channel has REGULATORY_CHAN_RADAR
616 		 * channel flag to identify if the channel is DFS
617 		 */
618 		if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev, chan_freq))
619 			is_ch_dfs = true;
620 	}
621 	if (WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq))
622 		is_ch_dfs = false;
623 	if (is_ch_dfs && sap_plus_sap_cac_skip(mac_ctx, sap_ctx, chan_freq))
624 		cac_state = eSAP_DFS_SKIP_CAC;
625 	sap_debug("vdev id %d chan %d is_ch_dfs %d pre_cac_complete %d ignore_cac %d cac_state %d",
626 		  sap_ctx->sessionId, chan_freq, is_ch_dfs,
627 		  wlan_pre_cac_complete_get(sap_ctx->vdev),
628 		  mac_ctx->sap.SapDfsInfo.ignore_cac,
629 		  cac_state);
630 
631 	if (!is_ch_dfs || wlan_pre_cac_complete_get(sap_ctx->vdev) ||
632 	    mac_ctx->sap.SapDfsInfo.ignore_cac ||
633 	    cac_state == eSAP_DFS_SKIP_CAC)
634 		cac_required = false;
635 	else
636 		cac_required = true;
637 
638 	if (cac_required) {
639 		sta_cnt =
640 		  policy_mgr_get_mode_specific_conn_info(mac_ctx->psoc,
641 							 freq_list,
642 							 vdev_id_list,
643 							 PM_STA_MODE);
644 
645 		for (i = 0; i < sta_cnt; i++) {
646 			if (chan_freq == freq_list[i]) {
647 				sap_debug("STA vdev id %d exists, ignore CAC",
648 					  vdev_id_list[i]);
649 				cac_required = false;
650 			}
651 		}
652 	}
653 
654 	return cac_required;
655 }
656 
657 void sap_get_cac_dur_dfs_region(struct sap_context *sap_ctx,
658 				uint32_t *cac_duration_ms,
659 				uint32_t *dfs_region,
660 				qdf_freq_t chan_freq,
661 				struct ch_params *ch_params)
662 {
663 	int i;
664 	qdf_freq_t freq_list[MAX_BONDED_CHANNELS];
665 	uint8_t num_freq;
666 	struct mac_context *mac;
667 	bool cac_required;
668 
669 	*cac_duration_ms = 0;
670 	if (!sap_ctx) {
671 		sap_err("null sap_ctx");
672 		return;
673 	}
674 
675 	mac = sap_get_mac_context();
676 	if (!mac) {
677 		sap_err("Invalid MAC context");
678 		return;
679 	}
680 
681 	wlan_reg_get_dfs_region(mac->pdev, dfs_region);
682 	cac_required = is_wlansap_cac_required_for_chan(mac, sap_ctx,
683 							chan_freq, ch_params);
684 
685 	if (!cac_required) {
686 		sap_debug("cac is not required");
687 		return;
688 	}
689 	*cac_duration_ms = DEFAULT_CAC_TIMEOUT;
690 
691 	if (*dfs_region != DFS_ETSI_REGION) {
692 		sap_debug("sapdfs: default cac duration");
693 		return;
694 	}
695 
696 	if (sap_is_channel_bonding_etsi_weather_channel(sap_ctx, chan_freq,
697 							ch_params)) {
698 		*cac_duration_ms = ETSI_WEATHER_CH_CAC_TIMEOUT;
699 		sap_debug("sapdfs: bonding_etsi_weather_channel");
700 		return;
701 	}
702 
703 	qdf_mem_zero(freq_list, sizeof(freq_list));
704 	num_freq = sap_ch_params_to_bonding_channels(ch_params, freq_list);
705 	for (i = 0; i < num_freq; i++) {
706 		if (IS_ETSI_WEATHER_FREQ(freq_list[i])) {
707 			*cac_duration_ms = ETSI_WEATHER_CH_CAC_TIMEOUT;
708 			sap_debug("sapdfs: ch freq=%d is etsi weather channel",
709 				  freq_list[i]);
710 			return;
711 		}
712 	}
713 
714 }
715 
716 void sap_dfs_set_current_channel(void *ctx)
717 {
718 	struct sap_context *sap_ctx = ctx;
719 	uint8_t vht_seg0 = sap_ctx->ch_params.center_freq_seg0;
720 	uint8_t vht_seg1 = sap_ctx->ch_params.center_freq_seg1;
721 	struct wlan_objmgr_pdev *pdev;
722 	struct mac_context *mac_ctx;
723 	uint32_t use_nol = 0;
724 	int error;
725 	bool is_dfs;
726 
727 	mac_ctx = sap_get_mac_context();
728 	if (!mac_ctx) {
729 		sap_err("Invalid MAC context");
730 		return;
731 	}
732 
733 	pdev = mac_ctx->pdev;
734 	if (!pdev) {
735 		sap_err("null pdev");
736 		return;
737 	}
738 
739 	is_dfs = wlan_mlme_check_chan_param_has_dfs(pdev,
740 						    &sap_ctx->ch_params,
741 						    sap_ctx->chan_freq);
742 
743 	sap_debug("freq=%d, dfs %d seg0=%d, seg1=%d, bw %d",
744 		  sap_ctx->chan_freq, is_dfs, vht_seg0, vht_seg1,
745 		  sap_ctx->ch_params.ch_width);
746 
747 	if (is_dfs) {
748 		if (policy_mgr_concurrent_beaconing_sessions_running(
749 		    mac_ctx->psoc)) {
750 			uint16_t con_ch_freq;
751 			mac_handle_t handle = MAC_HANDLE(mac_ctx);
752 
753 			con_ch_freq =
754 				sme_get_beaconing_concurrent_operation_channel(
755 					handle, sap_ctx->sessionId);
756 			if (!con_ch_freq ||
757 			    !wlan_reg_is_dfs_for_freq(pdev,
758 							con_ch_freq))
759 				tgt_dfs_get_radars(pdev);
760 		} else {
761 			tgt_dfs_get_radars(pdev);
762 		}
763 		tgt_dfs_set_phyerr_filter_offload(pdev);
764 
765 		if (mac_ctx->mlme_cfg->dfs_cfg.dfs_disable_channel_switch)
766 			tgt_dfs_control(pdev, DFS_SET_USENOL, &use_nol,
767 					sizeof(uint32_t), NULL, NULL, &error);
768 	}
769 }
770 
771 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
772 /**
773  * sap_check_in_avoid_ch_list() - checks if given channel present is channel
774  * avoidance list
775  *
776  * @sap_ctx:        sap context.
777  * @channel:        channel to be checked in sap_ctx's avoid ch list
778  *
779  * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on
780  * which MDM device's AP with MCC was detected. This function checks if given
781  * channel is present in that list.
782  *
783  * Return: true, if channel was present, false othersie.
784  */
785 bool sap_check_in_avoid_ch_list(struct sap_context *sap_ctx, uint8_t channel)
786 {
787 	uint8_t i = 0;
788 	struct sap_avoid_channels_info *ie_info =
789 		&sap_ctx->sap_detected_avoid_ch_ie;
790 	for (i = 0; i < sizeof(ie_info->channels); i++)
791 		if (ie_info->channels[i] == channel)
792 			return true;
793 	return false;
794 }
795 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
796 
797 /**
798  * sap_dfs_is_channel_in_nol_list() - given bonded channel is available
799  * @sap_context: Handle to SAP context.
800  * @channel_freq: Channel freq on which availability should be checked.
801  * @chan_bondState: The channel bonding mode of the passed channel.
802  *
803  * This function Checks if a given bonded channel is available or
804  * usable for DFS operation.
805  *
806  * Return: false if channel is available, true if channel is in NOL.
807  */
808 bool
809 sap_dfs_is_channel_in_nol_list(struct sap_context *sap_context,
810 			       qdf_freq_t channel_freq,
811 			       ePhyChanBondState chan_bondState)
812 {
813 	int i;
814 	struct mac_context *mac_ctx;
815 	qdf_freq_t freq_list[MAX_BONDED_CHANNELS];
816 	uint8_t num_ch_freq;
817 	struct wlan_objmgr_pdev *pdev = NULL;
818 	enum channel_state ch_state;
819 	qdf_freq_t ch_freq;
820 
821 	mac_ctx = sap_get_mac_context();
822 	if (!mac_ctx) {
823 		sap_err("Invalid MAC context");
824 		return false;
825 	}
826 
827 	pdev = mac_ctx->pdev;
828 	if (!pdev) {
829 		sap_err("null pdev");
830 		return false;
831 	}
832 
833 	sap_context->ch_params.mhz_freq_seg0 =
834 			wlan_reg_legacy_chan_to_freq(
835 				pdev,
836 				sap_context->ch_params.center_freq_seg0);
837 	sap_context->ch_params.mhz_freq_seg1 =
838 			wlan_reg_legacy_chan_to_freq(
839 				pdev,
840 				sap_context->ch_params.center_freq_seg1);
841 
842 	/* get the bonded channels */
843 	if (channel_freq == sap_context->chan_freq &&
844 	    chan_bondState >= PHY_CHANNEL_BONDING_STATE_MAX)
845 		num_ch_freq = sap_ch_params_to_bonding_channels(
846 					&sap_context->ch_params, freq_list);
847 	else
848 		num_ch_freq = sap_get_bonding_channels(
849 					sap_context, channel_freq,
850 					freq_list, MAX_BONDED_CHANNELS,
851 					chan_bondState);
852 
853 	/* check for NOL, first on will break the loop */
854 	for (i = 0; i < num_ch_freq; i++) {
855 		ch_freq = freq_list[i];
856 
857 		ch_state =
858 			wlan_reg_get_channel_state_from_secondary_list_for_freq(
859 								pdev, ch_freq);
860 		if (CHANNEL_STATE_ENABLE != ch_state &&
861 		    CHANNEL_STATE_DFS != ch_state) {
862 			sap_err_rl("Invalid ch freq = %d, ch state=%d", ch_freq,
863 				   ch_state);
864 			return true;
865 		}
866 	} /* loop for bonded channels */
867 
868 	return false;
869 }
870 
871 bool
872 sap_chan_bond_dfs_sub_chan(struct sap_context *sap_context,
873 			   qdf_freq_t channel_freq,
874 			   ePhyChanBondState bond_state)
875 {
876 	int i;
877 	struct mac_context *mac_ctx;
878 	qdf_freq_t freq_list[MAX_BONDED_CHANNELS];
879 	uint8_t num_freq;
880 	struct wlan_objmgr_pdev *pdev;
881 
882 	mac_ctx = sap_get_mac_context();
883 	if (!mac_ctx) {
884 		sap_err("Invalid MAC context");
885 		return false;
886 	}
887 
888 	pdev = mac_ctx->pdev;
889 	if (!pdev) {
890 		sap_err("null pdev");
891 		return false;
892 	}
893 
894 	if (wlan_reg_chan_has_dfs_attribute_for_freq(pdev, channel_freq))
895 		return true;
896 
897 	/* get the bonded channels */
898 	if (channel_freq == sap_context->chan_freq &&
899 	    bond_state >= PHY_CHANNEL_BONDING_STATE_MAX)
900 		num_freq = sap_ch_params_to_bonding_channels(
901 					&sap_context->ch_params, freq_list);
902 	else
903 		num_freq = sap_get_bonding_channels(
904 					sap_context, channel_freq, freq_list,
905 					MAX_BONDED_CHANNELS, bond_state);
906 
907 	for (i = 0; i < num_freq; i++) {
908 		if (wlan_reg_chan_has_dfs_attribute_for_freq(pdev, freq_list[i])) {
909 			sap_debug("sub ch freq=%d is dfs in %d",
910 				  freq_list[i], channel_freq);
911 			return true;
912 		}
913 	}
914 
915 	return false;
916 }
917 
918 uint32_t sap_select_default_oper_chan(struct mac_context *mac_ctx,
919 				      struct sap_acs_cfg *acs_cfg)
920 {
921 	uint16_t i;
922 	uint32_t freq0 = 0, freq1 = 0, freq2 = 0, default_freq;
923 
924 	if (!acs_cfg)
925 		return 0;
926 
927 	if (!acs_cfg->ch_list_count || !acs_cfg->freq_list) {
928 		if (mac_ctx->mlme_cfg->acs.force_sap_start) {
929 			sap_debug("SAP forced, freq selected %d",
930 				  acs_cfg->master_freq_list[0]);
931 			return acs_cfg->master_freq_list[0];
932 		} else {
933 			sap_debug("No channel left for operation");
934 			return 0;
935 		}
936 	}
937 	/*
938 	 * There could be both 2.4Ghz and 5ghz channels present in the list
939 	 * based upon the Hw mode received from hostapd, it is always better
940 	 * to chose a default 5ghz operating channel than 2.4ghz, as it can
941 	 * provide a better throughput, latency than 2.4ghz. Also 40 Mhz is
942 	 * rare in 2.4ghz band, so 5ghz should be preferred. If we get a 5Ghz
943 	 * chan in the acs cfg ch list , we should go for that first else the
944 	 * default channel can be 2.4ghz.
945 	 * Add check regulatory channel state before select the channel.
946 	 */
947 
948 	for (i = 0; i < acs_cfg->ch_list_count; i++) {
949 		enum channel_state state =
950 			wlan_reg_get_channel_state_for_pwrmode(
951 					mac_ctx->pdev, acs_cfg->freq_list[i],
952 					REG_CURRENT_PWR_MODE);
953 		if (!freq0 && state == CHANNEL_STATE_ENABLE &&
954 		    WLAN_REG_IS_5GHZ_CH_FREQ(acs_cfg->freq_list[i])) {
955 			freq0 = acs_cfg->freq_list[i];
956 			break;
957 		} else if (!freq1 && state == CHANNEL_STATE_DFS &&
958 			   WLAN_REG_IS_5GHZ_CH_FREQ(acs_cfg->freq_list[i])) {
959 			freq1 = acs_cfg->freq_list[i];
960 		} else if (!freq2 && state == CHANNEL_STATE_ENABLE) {
961 			freq2 = acs_cfg->freq_list[i];
962 		}
963 	}
964 	default_freq = freq0;
965 	if (!default_freq)
966 		default_freq = freq1;
967 	if (!default_freq)
968 		default_freq = freq2;
969 	if (!default_freq)
970 		default_freq = acs_cfg->freq_list[0];
971 
972 	sap_debug("default freq %d chosen from %d %d %d %d", default_freq,
973 		  freq0, freq1, freq2, acs_cfg->freq_list[0]);
974 
975 	return default_freq;
976 }
977 
978 static bool is_mcc_preferred(struct sap_context *sap_context,
979 			     uint32_t con_ch_freq)
980 {
981 	/*
982 	 * If SAP ACS channel list is 1-11 and STA is on non-preferred
983 	 * channel i.e. 12, 13, 14 then MCC is unavoidable. This is because
984 	 * if SAP is started on 12,13,14 some clients may not be able to
985 	 * join dependending on their regulatory country.
986 	 */
987 	if ((con_ch_freq >= 2467) && (con_ch_freq <= 2484) &&
988 	    (sap_context->acs_cfg->start_ch_freq >= 2412 &&
989 	     sap_context->acs_cfg->end_ch_freq <= 2462)) {
990 		sap_debug("conc ch freq %d & sap acs ch list is 1-11, prefer mcc",
991 			  con_ch_freq);
992 		return true;
993 	}
994 
995 	return false;
996 }
997 
998 /**
999  * sap_process_force_scc_with_go_start - Check GO force SCC or not
1000  * psoc: psoc object
1001  * sap_context: sap_context
1002  *
1003  * This function checks the current SAP MCC or not with the GO's home channel.
1004  * If it is, skip the GO's force SCC. The SAP will do force SCC after
1005  * GO's started.
1006  *
1007  * Return: true if skip GO's force SCC
1008  */
1009 static bool
1010 sap_process_force_scc_with_go_start(struct wlan_objmgr_psoc *psoc,
1011 				    struct sap_context *sap_context)
1012 {
1013 	uint8_t existing_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
1014 	enum policy_mgr_con_mode existing_vdev_mode = PM_MAX_NUM_OF_MODE;
1015 	uint32_t con_freq;
1016 	enum phy_ch_width ch_width;
1017 
1018 	existing_vdev_id =
1019 		policy_mgr_fetch_existing_con_info(psoc,
1020 						   sap_context->sessionId,
1021 						   sap_context->chan_freq,
1022 						   &existing_vdev_mode,
1023 						   &con_freq, &ch_width);
1024 	if (existing_vdev_id < WLAN_UMAC_VDEV_ID_MAX &&
1025 	    existing_vdev_mode == PM_SAP_MODE) {
1026 		sap_debug("concurrent sap vdev: %d on freq %d, skip GO force scc",
1027 			  existing_vdev_id, con_freq);
1028 		return true;
1029 	}
1030 
1031 	return false;
1032 }
1033 
1034 #ifdef WLAN_FEATURE_P2P_P2P_STA
1035 /**
1036  * sap_set_forcescc_required - set force scc flag for provided p2p go vdev
1037  *
1038  * vdev_id - vdev_id for which flag needs to be set
1039  *
1040  * Return: None
1041  */
1042 static void sap_set_forcescc_required(uint8_t vdev_id)
1043 {
1044 	struct mac_context *mac_ctx;
1045 	struct sap_context *sap_ctx;
1046 	uint8_t i = 0;
1047 
1048 	mac_ctx = sap_get_mac_context();
1049 	if (!mac_ctx) {
1050 		sap_err("Invalid MAC context");
1051 		return;
1052 	}
1053 
1054 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
1055 		sap_ctx = mac_ctx->sap.sapCtxList[i].sap_context;
1056 		if (QDF_P2P_GO_MODE == mac_ctx->sap.sapCtxList[i].sapPersona &&
1057 		    sap_ctx->sessionId == vdev_id) {
1058 			sap_debug("update forcescc restart for vdev %d",
1059 				  vdev_id);
1060 			sap_ctx->is_forcescc_restart_required = true;
1061 		}
1062 	}
1063 }
1064 
1065 /**
1066  * sap_process_liberal_scc_for_go - based on existing connections this
1067  * function decides current go should start on provided channel or not and
1068  * sets force scc required bit for existing GO.
1069  *
1070  * sap_context: sap_context
1071  *
1072  * Return: bool
1073  */
1074 static bool sap_process_liberal_scc_for_go(struct sap_context *sap_context)
1075 {
1076 	uint8_t existing_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
1077 	enum policy_mgr_con_mode existing_vdev_mode = PM_MAX_NUM_OF_MODE;
1078 	uint32_t con_freq;
1079 	enum phy_ch_width ch_width;
1080 	struct mac_context *mac_ctx;
1081 	mac_handle_t mac_handle;
1082 
1083 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
1084 	mac_ctx = MAC_CONTEXT(mac_handle);
1085 	if (!mac_ctx) {
1086 		sap_alert("invalid MAC handle");
1087 		return true;
1088 	}
1089 
1090 	existing_vdev_id =
1091 		policy_mgr_fetch_existing_con_info(
1092 				mac_ctx->psoc,
1093 				sap_context->sessionId,
1094 				sap_context->chan_freq,
1095 				&existing_vdev_mode,
1096 				&con_freq, &ch_width);
1097 
1098 	if (existing_vdev_id <
1099 			WLAN_UMAC_VDEV_ID_MAX &&
1100 			existing_vdev_mode == PM_P2P_GO_MODE) {
1101 		sap_debug("set forcescc flag for go vdev: %d",
1102 			  existing_vdev_id);
1103 		sap_set_forcescc_required(
1104 				existing_vdev_id);
1105 		return true;
1106 	}
1107 	if (existing_vdev_id < WLAN_UMAC_VDEV_ID_MAX &&
1108 	    (existing_vdev_mode == PM_STA_MODE ||
1109 	    existing_vdev_mode == PM_P2P_CLIENT_MODE)) {
1110 		sap_debug("don't override channel, start go on %d",
1111 			  sap_context->chan_freq);
1112 		return true;
1113 	}
1114 
1115 	return false;
1116 }
1117 #else
1118 static bool sap_process_liberal_scc_for_go(struct sap_context *sap_context)
1119 {
1120 	return false;
1121 }
1122 #endif
1123 
1124 QDF_STATUS
1125 sap_validate_chan(struct sap_context *sap_context,
1126 		  bool pre_start_bss,
1127 		  bool check_for_connection_update)
1128 {
1129 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
1130 	struct mac_context *mac_ctx;
1131 	mac_handle_t mac_handle;
1132 	uint32_t con_ch_freq;
1133 	bool sta_sap_scc_on_dfs_chan;
1134 	uint32_t sta_go_bit_mask = QDF_STA_MASK | QDF_P2P_GO_MASK;
1135 	uint32_t sta_sap_bit_mask = QDF_STA_MASK | QDF_SAP_MASK;
1136 	uint32_t concurrent_state;
1137 	bool go_force_scc;
1138 	struct ch_params ch_params = {0};
1139 	bool is_go_scc_strict = false;
1140 	bool start_sap_on_provided_freq = false;
1141 
1142 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
1143 	mac_ctx = MAC_CONTEXT(mac_handle);
1144 	if (!mac_ctx) {
1145 		/* we have a serious problem */
1146 		sap_alert("invalid MAC handle");
1147 		return QDF_STATUS_E_FAULT;
1148 	}
1149 
1150 	if (!sap_context->chan_freq) {
1151 		sap_err("Invalid channel");
1152 		return QDF_STATUS_E_FAILURE;
1153 	}
1154 
1155 	if (sap_context->vdev &&
1156 	    sap_context->vdev->vdev_mlme.vdev_opmode == QDF_P2P_GO_MODE) {
1157 	       /*
1158 		* check whether go_force_scc is enabled or not.
1159 		* If it not enabled then don't any force scc on existing go and
1160 		* new p2p go vdevs.
1161 		* Otherwise, if it is enabled then check whether it's in strict
1162 		* mode or liberal mode.
1163 		* For strict mode, do force scc on newly p2p go to existing vdev
1164 		* channel.
1165 		* For liberal first form new p2p go on requested channel and
1166 		* follow below rules:
1167 		* a.) If Existing vdev mode is P2P GO Once set key is done, do
1168 		* force scc for existing p2p go and move that go to new p2p
1169 		* go's channel.
1170 		*
1171 		* b.) If Existing vdev mode is P2P CLI/STA Once set key is
1172 		* done, do force scc for p2p go and move go to cli/sta channel.
1173 		*/
1174 		go_force_scc = policy_mgr_go_scc_enforced(mac_ctx->psoc);
1175 		sap_debug("go force scc enabled %d", go_force_scc);
1176 
1177 		if (sap_process_force_scc_with_go_start(mac_ctx->psoc,
1178 							sap_context))
1179 			goto validation_done;
1180 
1181 		if (go_force_scc) {
1182 			is_go_scc_strict =
1183 				policy_mgr_is_go_scc_strict(mac_ctx->psoc);
1184 			if (!is_go_scc_strict) {
1185 				sap_debug("liberal mode is enabled");
1186 				start_sap_on_provided_freq =
1187 				sap_process_liberal_scc_for_go(sap_context);
1188 				if (start_sap_on_provided_freq)
1189 					goto validation_done;
1190 			}
1191 		} else {
1192 			goto validation_done;
1193 		}
1194 	}
1195 
1196 	concurrent_state = policy_mgr_get_concurrency_mode(mac_ctx->psoc);
1197 	if (policy_mgr_concurrent_beaconing_sessions_running(mac_ctx->psoc) ||
1198 	    ((concurrent_state & sta_sap_bit_mask) == sta_sap_bit_mask) ||
1199 	    ((concurrent_state & sta_go_bit_mask) == sta_go_bit_mask)) {
1200 #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
1201 		if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev,
1202 					     sap_context->chan_freq)) {
1203 			sap_warn("DFS not supported in STA_AP Mode");
1204 			return QDF_STATUS_E_ABORTED;
1205 		}
1206 #endif
1207 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
1208 		if (sap_context->cc_switch_mode !=
1209 					QDF_MCC_TO_SCC_SWITCH_DISABLE) {
1210 			con_ch_freq = sme_check_concurrent_channel_overlap(
1211 					mac_handle,
1212 					sap_context->chan_freq,
1213 					sap_context->phyMode,
1214 					sap_context->cc_switch_mode,
1215 					sap_context->sessionId);
1216 			sap_debug("After check overlap: sap freq %d con freq:%d",
1217 				  sap_context->chan_freq, con_ch_freq);
1218 			/*
1219 			 * For non-DBS platform, a 2.4Ghz can become a 5Ghz freq
1220 			 * so lets used max BW in that case, if it remain 2.4Ghz
1221 			 * then BW will be limited to 20 anyway
1222 			 */
1223 			if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_context->chan_freq))
1224 				ch_params.ch_width = CH_WIDTH_MAX;
1225 			else
1226 				ch_params = sap_context->ch_params;
1227 
1228 			if (sap_context->cc_switch_mode !=
1229 		QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) {
1230 				if (QDF_IS_STATUS_ERROR(
1231 					policy_mgr_valid_sap_conc_channel_check(
1232 						mac_ctx->psoc, &con_ch_freq,
1233 						sap_context->chan_freq,
1234 						sap_context->sessionId,
1235 						&ch_params))) {
1236 					sap_warn("SAP can't start (no MCC)");
1237 					return QDF_STATUS_E_ABORTED;
1238 				}
1239 			}
1240 			/* if CH width didn't change fallback to original */
1241 			if (ch_params.ch_width == CH_WIDTH_MAX)
1242 				ch_params = sap_context->ch_params;
1243 
1244 			sap_debug("After check concurrency: con freq:%d",
1245 				  con_ch_freq);
1246 			sta_sap_scc_on_dfs_chan =
1247 				policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(
1248 						mac_ctx->psoc);
1249 			if (con_ch_freq &&
1250 			    (policy_mgr_sta_sap_scc_on_lte_coex_chan(
1251 						mac_ctx->psoc) ||
1252 			     policy_mgr_is_safe_channel(
1253 						mac_ctx->psoc, con_ch_freq)) &&
1254 			    (!wlan_mlme_check_chan_param_has_dfs(
1255 					mac_ctx->pdev, &ch_params,
1256 					con_ch_freq) ||
1257 			    sta_sap_scc_on_dfs_chan)) {
1258 				if (is_mcc_preferred(sap_context, con_ch_freq))
1259 					goto validation_done;
1260 
1261 				sap_debug("Override ch freq %d (bw %d) to %d (bw %d) due to CC Intf",
1262 					  sap_context->chan_freq,
1263 					  sap_context->ch_params.ch_width,
1264 					  con_ch_freq, ch_params.ch_width);
1265 				sap_context->chan_freq = con_ch_freq;
1266 				sap_context->ch_params = ch_params;
1267 			}
1268 		}
1269 #endif
1270 	}
1271 validation_done:
1272 	sap_debug("for configured channel, Ch_freq = %d",
1273 		  sap_context->chan_freq);
1274 
1275 	/*
1276 	 * Don't check if the frequency is allowed or not if SAP is started
1277 	 * in fixed channel, or WLAN CH AVOID EXT feature explicit restrict
1278 	 * SAP start on unsafe channel.
1279 	 */
1280 
1281 	if ((sap_context->acs_cfg->acs_mode ||
1282 	     policy_mgr_restrict_sap_on_unsafe_chan(mac_ctx->psoc)) &&
1283 	    !policy_mgr_is_sap_freq_allowed(mac_ctx->psoc,
1284 					    sap_context->chan_freq)) {
1285 		sap_warn("Abort SAP start due to unsafe channel");
1286 		return QDF_STATUS_E_ABORTED;
1287 	}
1288 
1289 	if (check_for_connection_update) {
1290 		/* This wait happens in the hostapd context. The event
1291 		 * is set in the MC thread context.
1292 		 */
1293 		qdf_status =
1294 		policy_mgr_update_and_wait_for_connection_update(
1295 			mac_ctx->psoc, sap_context->sessionId,
1296 			sap_context->chan_freq,
1297 			POLICY_MGR_UPDATE_REASON_START_AP);
1298 		if (QDF_IS_STATUS_ERROR(qdf_status))
1299 			return qdf_status;
1300 	}
1301 
1302 	if (pre_start_bss) {
1303 		sap_info("ACS end due to Ch override. Sel Ch freq = %d",
1304 			  sap_context->chan_freq);
1305 		sap_context->acs_cfg->pri_ch_freq = sap_context->chan_freq;
1306 		sap_context->acs_cfg->ch_width =
1307 					 sap_context->ch_width_orig;
1308 		sap_config_acs_result(mac_handle, sap_context, 0);
1309 		return QDF_STATUS_E_CANCELED;
1310 	}
1311 
1312 	return QDF_STATUS_SUCCESS;
1313 }
1314 
1315 #ifdef WLAN_FEATURE_SAP_ACS_OPTIMIZE
1316 
1317 static void sap_sort_freq_list(struct chan_list *list,
1318 			       uint8_t num_ch)
1319 {
1320 	int i, j, temp;
1321 
1322 	for (i = 0; i < num_ch - 1; i++) {
1323 		for (j = 0 ; j < num_ch - i - 1; j++) {
1324 			if (list->chan[j].freq < list->chan[j + 1].freq) {
1325 				temp = list->chan[j].freq;
1326 				list->chan[j].freq = list->chan[j + 1].freq;
1327 				list->chan[j + 1].freq = temp;
1328 			}
1329 		}
1330 	}
1331 }
1332 
1333 /**
1334  * sap_acs_scan_freq_list_optimize - optimize the ACS scan freq list based
1335  * on when last scan was performed on particular frequency. If last scan
1336  * performed on particular frequency is less than configured last_scan_ageout
1337  * time, then skip that frequency from ACS scan freq list.
1338  *
1339  * sap_ctx: sap context
1340  * list: ACS scan frequency list
1341  * ch_count: number of frequency in list
1342  *
1343  * Return: None
1344  */
1345 static void sap_acs_scan_freq_list_optimize(struct sap_context *sap_ctx,
1346 					    struct chan_list *list,
1347 					    uint8_t *ch_count)
1348 {
1349 	int loop_count = 0, j = 0;
1350 	uint32_t ts_last_scan;
1351 
1352 	sap_ctx->partial_acs_scan = false;
1353 
1354 	while (loop_count < *ch_count) {
1355 		ts_last_scan = scm_get_last_scan_time_per_channel(
1356 				sap_ctx->vdev, list->chan[loop_count].freq);
1357 
1358 		if (qdf_system_time_before(
1359 		    qdf_get_time_of_the_day_ms(),
1360 		    ts_last_scan + sap_ctx->acs_cfg->last_scan_ageout_time)) {
1361 			sap_info("ACS chan %d skipped from scan as last scan ts %lu\n",
1362 				 list->chan[loop_count].freq,
1363 				 qdf_get_time_of_the_day_ms() - ts_last_scan);
1364 
1365 			for (j = loop_count; j < *ch_count - 1; j++)
1366 				list->chan[j].freq = list->chan[j + 1].freq;
1367 
1368 			(*ch_count)--;
1369 			sap_ctx->partial_acs_scan = true;
1370 			continue;
1371 		}
1372 		loop_count++;
1373 	}
1374 	if (*ch_count == 0)
1375 		sap_info("All ACS freq channels are scanned recently, skip ACS scan\n");
1376 	else
1377 		sap_sort_freq_list(list, *ch_count);
1378 }
1379 #else
1380 static void sap_acs_scan_freq_list_optimize(struct sap_context *sap_ctx,
1381 					    struct chan_list *list,
1382 					    uint8_t *ch_count)
1383 {
1384 }
1385 #endif
1386 
1387 #ifdef WLAN_FEATURE_SAP_ACS_OPTIMIZE
1388 /**
1389  * sap_reset_clean_freq_array(): clear freq array that contains info
1390  * channel is free or not
1391  * @sap_context: sap context
1392  *
1393  * Return: void
1394  */
1395 static
1396 void sap_reset_clean_freq_array(struct sap_context *sap_context)
1397 {
1398 	memset(sap_context->clean_channel_array, 0, NUM_CHANNELS);
1399 }
1400 #else
1401 static inline
1402 void sap_reset_clean_freq_array(struct sap_context *sap_context)
1403 {}
1404 #endif
1405 
1406 /**
1407  * wlansap_set_aux_scan_ctrl_ext_flag() – update aux scan policy
1408  * @req: pointer to scan request
1409  *
1410  * Set aux scan bits in scan_ctrl_ext_flag value depending on scan type.
1411  *
1412  * Return: None
1413  */
1414 static void wlansap_set_aux_scan_ctrl_ext_flag(struct scan_start_request  *req)
1415 {
1416 	sap_debug("Set Reliable Scan Flag");
1417 	req->scan_req.scan_ctrl_flags_ext |=
1418 			SCAN_FLAG_EXT_AUX_RELIABLE_SCAN;
1419 }
1420 
1421 QDF_STATUS sap_channel_sel(struct sap_context *sap_context)
1422 {
1423 	QDF_STATUS qdf_ret_status;
1424 	struct mac_context *mac_ctx;
1425 	struct scan_start_request *req;
1426 	struct wlan_objmgr_vdev *vdev = NULL;
1427 	uint8_t i, j;
1428 	uint32_t *freq_list = NULL;
1429 	uint8_t num_of_channels = 0;
1430 	mac_handle_t mac_handle;
1431 	uint32_t con_ch_freq;
1432 	uint8_t vdev_id;
1433 	uint32_t scan_id;
1434 	uint32_t default_op_freq;
1435 
1436 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
1437 	if (!mac_handle)
1438 		return QDF_STATUS_E_FAULT;
1439 
1440 	mac_ctx = MAC_CONTEXT(mac_handle);
1441 	if (!mac_ctx) {
1442 		sap_err("Invalid MAC context");
1443 		return QDF_STATUS_E_FAILURE;
1444 	}
1445 	if (sap_context->fsm_state != SAP_STARTED && sap_context->chan_freq)
1446 		return sap_validate_chan(sap_context, true, false);
1447 
1448 	if (policy_mgr_concurrent_beaconing_sessions_running(mac_ctx->psoc) ||
1449 	    ((sap_context->cc_switch_mode ==
1450 	      QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) &&
1451 	     (policy_mgr_mode_specific_connection_count(mac_ctx->psoc,
1452 							PM_SAP_MODE, NULL) ||
1453 	     policy_mgr_mode_specific_connection_count(mac_ctx->psoc,
1454 						       PM_P2P_GO_MODE,
1455 						       NULL)))) {
1456 		con_ch_freq = sme_get_beaconing_concurrent_operation_channel(
1457 					mac_handle, sap_context->sessionId);
1458 #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
1459 		if (con_ch_freq)
1460 			sap_context->dfs_ch_disable = true;
1461 #endif
1462 	}
1463 
1464 	if ((policy_mgr_get_concurrency_mode(mac_ctx->psoc) ==
1465 		(QDF_STA_MASK | QDF_SAP_MASK)) ||
1466 		((sap_context->cc_switch_mode ==
1467 		QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) &&
1468 		(policy_mgr_get_concurrency_mode(mac_ctx->psoc) ==
1469 		(QDF_STA_MASK | QDF_P2P_GO_MASK)))) {
1470 #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
1471 		sap_context->dfs_ch_disable = true;
1472 #endif
1473 	}
1474 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
1475 	sap_debug("skip_acs_status = %d",
1476 		  sap_context->acs_cfg->skip_scan_status);
1477 	if (sap_context->acs_cfg->skip_scan_status !=
1478 					eSAP_SKIP_ACS_SCAN) {
1479 #endif
1480 
1481 		if (sap_context->freq_list) {
1482 			qdf_mem_free(sap_context->freq_list);
1483 			sap_context->freq_list = NULL;
1484 			sap_context->num_of_channel = 0;
1485 		}
1486 
1487 		sap_get_freq_list(sap_context, &freq_list, &num_of_channels);
1488 		if (!num_of_channels || !freq_list) {
1489 			sap_err("No freq sutiable for SAP in current list, SAP failed");
1490 			return QDF_STATUS_E_FAILURE;
1491 		}
1492 
1493 		req = qdf_mem_malloc(sizeof(*req));
1494 		if (!req) {
1495 			qdf_mem_free(freq_list);
1496 			return QDF_STATUS_E_NOMEM;
1497 		}
1498 
1499 		vdev_id = sap_context->sessionId;
1500 		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
1501 							    vdev_id,
1502 							    WLAN_LEGACY_SME_ID);
1503 		if (!vdev) {
1504 			sap_err("Invalid vdev objmgr");
1505 			qdf_mem_free(freq_list);
1506 			qdf_mem_free(req);
1507 			return QDF_STATUS_E_INVAL;
1508 		}
1509 
1510 		/* Initiate a SCAN request */
1511 		wlan_scan_init_default_params(vdev, req);
1512 		scan_id = wlan_scan_get_scan_id(mac_ctx->psoc);
1513 		req->scan_req.scan_id = scan_id;
1514 		req->scan_req.vdev_id = vdev_id;
1515 		req->scan_req.scan_f_passive = false;
1516 		req->scan_req.scan_req_id = sap_context->req_id;
1517 		req->scan_req.scan_priority = SCAN_PRIORITY_HIGH;
1518 		req->scan_req.scan_f_bcast_probe = true;
1519 		for (i = 0, j = 0; i < num_of_channels; i++) {
1520 			if (wlan_reg_is_6ghz_chan_freq(freq_list[i]) &&
1521 			    !wlan_reg_is_6ghz_psc_chan_freq(freq_list[i]))
1522 				continue;
1523 			req->scan_req.chan_list.chan[j++].freq = freq_list[i];
1524 		}
1525 		req->scan_req.chan_list.num_chan = j;
1526 		sap_context->freq_list = freq_list;
1527 		sap_context->num_of_channel = num_of_channels;
1528 		sap_context->optimize_acs_chan_selected = false;
1529 		sap_reset_clean_freq_array(sap_context);
1530 		/* Set requestType to Full scan */
1531 
1532 		/*
1533 		 * send partial channels to be scanned in SCAN request if
1534 		 * vendor command included last scan ageout time to be used to
1535 		 * optimize the SAP bring up time
1536 		 */
1537 		if (sap_context->acs_cfg->last_scan_ageout_time)
1538 			sap_acs_scan_freq_list_optimize(
1539 					sap_context, &req->scan_req.chan_list,
1540 					&req->scan_req.chan_list.num_chan);
1541 
1542 		if (!req->scan_req.chan_list.num_chan) {
1543 			sap_info("## SKIPPED ACS SCAN");
1544 			sap_context->acs_cfg->skip_acs_scan = true;
1545 			wlansap_pre_start_bss_acs_scan_callback(
1546 				mac_handle, sap_context, sap_context->sessionId,
1547 				0, eCSR_SCAN_SUCCESS);
1548 			qdf_mem_free(req);
1549 			qdf_ret_status = QDF_STATUS_SUCCESS;
1550 			goto release_vdev_ref;
1551 		}
1552 
1553 		sap_context->acs_req_timestamp = qdf_get_time_of_the_day_ms();
1554 
1555 		if (wlan_scan_get_aux_support(mac_ctx->psoc))
1556 			wlansap_set_aux_scan_ctrl_ext_flag(req);
1557 		qdf_ret_status = wlan_scan_start(req);
1558 		if (qdf_ret_status != QDF_STATUS_SUCCESS) {
1559 			sap_err("scan request  fail %d!!!", qdf_ret_status);
1560 			sap_info("SAP Configuring default ch, Ch_freq=%d",
1561 				  sap_context->chan_freq);
1562 			default_op_freq = sap_select_default_oper_chan(
1563 						mac_ctx, sap_context->acs_cfg);
1564 			wlansap_set_acs_ch_freq(sap_context, default_op_freq);
1565 
1566 			if (sap_context->freq_list) {
1567 				wlansap_set_acs_ch_freq(
1568 					sap_context, sap_context->freq_list[0]);
1569 				qdf_mem_free(sap_context->freq_list);
1570 				sap_context->freq_list = NULL;
1571 				sap_context->num_of_channel = 0;
1572 			}
1573 			/*
1574 			* In case of ACS req before start Bss,
1575 			* return failure so that the calling
1576 			* function can use the default channel.
1577 			*/
1578 			qdf_ret_status = QDF_STATUS_E_FAILURE;
1579 			goto release_vdev_ref;
1580 		} else {
1581 			wlansap_dump_acs_ch_freq(sap_context);
1582 			host_log_acs_scan_start(scan_id, vdev_id);
1583 		}
1584 
1585 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
1586 	} else {
1587 		sap_context->acs_cfg->skip_scan_status = eSAP_SKIP_ACS_SCAN;
1588 	}
1589 
1590 	if (sap_context->acs_cfg->skip_scan_status == eSAP_SKIP_ACS_SCAN) {
1591 		sap_err("## SKIPPED ACS SCAN");
1592 		wlansap_pre_start_bss_acs_scan_callback(mac_handle,
1593 				sap_context, sap_context->sessionId, 0,
1594 				eCSR_SCAN_SUCCESS);
1595 	}
1596 #endif
1597 
1598 	wlansap_dump_acs_ch_freq(sap_context);
1599 
1600 	qdf_ret_status = QDF_STATUS_SUCCESS;
1601 
1602 release_vdev_ref:
1603 	if (vdev)
1604 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
1605 	return qdf_ret_status;
1606 }
1607 
1608 /**
1609  * sap_find_valid_concurrent_session() - to find valid concurrent session
1610  * @mac_handle: Opaque handle to the global MAC context
1611  *
1612  * This API will check if any valid concurrent SAP session is present
1613  *
1614  * Return: pointer to sap context of valid concurrent session
1615  */
1616 static struct sap_context *
1617 sap_find_valid_concurrent_session(mac_handle_t mac_handle)
1618 {
1619 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
1620 	uint8_t intf = 0;
1621 	struct sap_context *sap_ctx;
1622 
1623 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
1624 		if (((QDF_SAP_MODE ==
1625 				mac_ctx->sap.sapCtxList[intf].sapPersona) ||
1626 		     (QDF_P2P_GO_MODE ==
1627 				mac_ctx->sap.sapCtxList[intf].sapPersona)) &&
1628 		    mac_ctx->sap.sapCtxList[intf].sap_context) {
1629 			sap_ctx = mac_ctx->sap.sapCtxList[intf].sap_context;
1630 			if (sap_ctx->fsm_state != SAP_INIT)
1631 				return sap_ctx;
1632 		}
1633 	}
1634 
1635 	return NULL;
1636 }
1637 
1638 QDF_STATUS sap_clear_global_dfs_param(mac_handle_t mac_handle,
1639 				      struct sap_context *sap_ctx)
1640 {
1641 	struct sap_context *con_sap_ctx;
1642 
1643 	con_sap_ctx = sap_find_valid_concurrent_session(mac_handle);
1644 	if (con_sap_ctx && WLAN_REG_IS_5GHZ_CH_FREQ(con_sap_ctx->chan_freq)) {
1645 		sap_debug("conc session exists, no need to clear dfs struct");
1646 		return QDF_STATUS_SUCCESS;
1647 	}
1648 	/*
1649 	 * CAC timer will be initiated and started only when SAP starts
1650 	 * on DFS channel and it will be stopped and destroyed
1651 	 * immediately once the radar detected or timedout. So
1652 	 * as per design CAC timer should be destroyed after stop
1653 	 */
1654 	wlansap_cleanup_cac_timer(sap_ctx);
1655 	sap_cac_reset_notify(mac_handle);
1656 
1657 	return QDF_STATUS_SUCCESS;
1658 }
1659 
1660 QDF_STATUS sap_acquire_vdev_ref(struct wlan_objmgr_psoc *psoc,
1661 				struct sap_context *sap_ctx,
1662 				uint8_t session_id)
1663 {
1664 	struct wlan_objmgr_vdev *vdev;
1665 
1666 	if (sap_ctx->vdev) {
1667 		sap_err("Invalid vdev obj in sap context");
1668 		return QDF_STATUS_E_FAULT;
1669 	}
1670 
1671 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, session_id,
1672 						    WLAN_LEGACY_SAP_ID);
1673 	if (!vdev) {
1674 		sap_err("vdev is NULL for vdev_id: %u", session_id);
1675 		return QDF_STATUS_E_FAILURE;
1676 	}
1677 
1678 	sap_ctx->vdev = vdev;
1679 	return QDF_STATUS_SUCCESS;
1680 }
1681 
1682 void sap_release_vdev_ref(struct sap_context *sap_ctx)
1683 {
1684 	struct wlan_objmgr_vdev *vdev;
1685 
1686 	if (!sap_ctx) {
1687 		sap_debug("Invalid SAP pointer");
1688 		return;
1689 	}
1690 
1691 	vdev = sap_ctx->vdev;
1692 	if (vdev) {
1693 		sap_ctx->vdev = NULL;
1694 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SAP_ID);
1695 	}
1696 }
1697 
1698 QDF_STATUS sap_set_session_param(mac_handle_t mac_handle,
1699 				 struct sap_context *sapctx,
1700 				 uint32_t session_id)
1701 {
1702 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
1703 	int i;
1704 
1705 	sapctx->sessionId = session_id;
1706 	wlan_pre_cac_set_status(sapctx->vdev, false);
1707 	wlan_pre_cac_complete_set(sapctx->vdev, false);
1708 	wlan_pre_cac_set_freq_before_pre_cac(sapctx->vdev, 0);
1709 
1710 	/* When SSR, SAP will restart, clear the old context,sessionId */
1711 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
1712 		if (mac_ctx->sap.sapCtxList[i].sap_context == sapctx)
1713 			mac_ctx->sap.sapCtxList[i].sap_context = NULL;
1714 	}
1715 
1716 	mac_ctx->sap.sapCtxList[sapctx->sessionId].sap_context = sapctx;
1717 	mac_ctx->sap.sapCtxList[sapctx->sessionId].sapPersona =
1718 			wlan_get_opmode_from_vdev_id(mac_ctx->pdev, session_id);
1719 	sap_debug("Initializing sap_ctx = %pK with session = %d",
1720 		   sapctx, session_id);
1721 
1722 	return QDF_STATUS_SUCCESS;
1723 }
1724 
1725 QDF_STATUS sap_clear_session_param(mac_handle_t mac_handle,
1726 				   struct sap_context *sapctx,
1727 				   uint32_t session_id)
1728 {
1729 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
1730 
1731 	if (sapctx->sessionId >= SAP_MAX_NUM_SESSION)
1732 		return QDF_STATUS_E_FAILURE;
1733 
1734 	mac_ctx->sap.sapCtxList[sapctx->sessionId].sap_context = NULL;
1735 	mac_ctx->sap.sapCtxList[sapctx->sessionId].sapPersona =
1736 		QDF_MAX_NO_OF_MODE;
1737 	sap_clear_global_dfs_param(mac_handle, sapctx);
1738 
1739 	sap_err("Set sapCtxList null for session %d", sapctx->sessionId);
1740 	qdf_mem_zero(sapctx, sizeof(*sapctx));
1741 	sapctx->sessionId = WLAN_UMAC_VDEV_ID_MAX;
1742 
1743 	return QDF_STATUS_SUCCESS;
1744 }
1745 
1746 #ifdef WLAN_FEATURE_11AX
1747 static uint16_t he_mcs_12_13_support(void)
1748 {
1749 	struct mac_context *mac_ctx;
1750 
1751 	mac_ctx = sap_get_mac_context();
1752 	if (!mac_ctx) {
1753 		sap_err("Invalid MAC context");
1754 		return 0;
1755 	}
1756 
1757 	return mac_ctx->mlme_cfg->he_caps.he_mcs_12_13_supp_5g;
1758 }
1759 #else
1760 static inline uint16_t he_mcs_12_13_support(void)
1761 {
1762 	return 0;
1763 }
1764 #endif
1765 
1766 static bool is_mcs13_ch_width(enum phy_ch_width ch_width)
1767 {
1768 	if ((ch_width == CH_WIDTH_320MHZ) ||
1769 	    (ch_width == CH_WIDTH_160MHZ) ||
1770 	    (ch_width == CH_WIDTH_80P80MHZ))
1771 		return true;
1772 
1773 	return false;
1774 }
1775 
1776 /**
1777  * sap_update_mcs_rate() - Update SAP MCS rate
1778  * @sap_ctx: pointer to sap Context
1779  * @is_start: Start or stop SAP
1780  *
1781  * Return: QDF_STATUS
1782  */
1783 static QDF_STATUS
1784 sap_update_mcs_rate(struct sap_context *sap_ctx, bool is_start)
1785 {
1786 	uint32_t default_mcs[] = {26, 0x3fff};
1787 	uint32_t fixed_mcs[] = {26, 0x1fff};
1788 	bool disable_mcs13_support = false;
1789 	uint16_t he_mcs_12_13_supp;
1790 	struct mac_context *mac_ctx;
1791 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1792 
1793 	mac_ctx = sap_get_mac_context();
1794 	if (!mac_ctx) {
1795 		sap_err("Invalid MAC context");
1796 		return QDF_STATUS_E_INVAL;
1797 	}
1798 
1799 	he_mcs_12_13_supp = he_mcs_12_13_support();
1800 	disable_mcs13_support = cfg_get(mac_ctx->psoc,
1801 					CFG_DISABLE_MCS13_SUPPORT);
1802 	sap_debug("session id %d, disable mcs13 support %d, he_mcs_12_13 %d, start %d, disabled_mcs13 %d, ch width %d",
1803 		  sap_ctx->sessionId, disable_mcs13_support,
1804 		  he_mcs_12_13_supp,
1805 		  is_start, sap_ctx->disabled_mcs13,
1806 		  sap_ctx->ch_params.ch_width);
1807 
1808 	if (!disable_mcs13_support ||
1809 	    !he_mcs_12_13_supp)
1810 		return status;
1811 
1812 	if (!is_start && !sap_ctx->disabled_mcs13)
1813 		return status;
1814 
1815 	if (!is_mcs13_ch_width(sap_ctx->ch_params.ch_width))
1816 		return status;
1817 
1818 	if (is_start) {
1819 		status = sme_send_unit_test_cmd(sap_ctx->sessionId,
1820 						10, 2, fixed_mcs);
1821 		if (QDF_IS_STATUS_ERROR(status)) {
1822 			sap_err("Set fixed mcs rate failed, session %d",
1823 				sap_ctx->sessionId);
1824 		} else {
1825 			sap_ctx->disabled_mcs13 = true;
1826 		}
1827 	} else {
1828 		status = sme_send_unit_test_cmd(sap_ctx->sessionId,
1829 						10, 2, default_mcs);
1830 		if (QDF_IS_STATUS_ERROR(status)) {
1831 			sap_err("Set default mcs rate failed, session %d",
1832 				sap_ctx->sessionId);
1833 		} else {
1834 			sap_ctx->disabled_mcs13 = false;
1835 		}
1836 	}
1837 
1838 	return status;
1839 }
1840 
1841 /**
1842  * sap_goto_stopping() - Processing of SAP FSM stopping state
1843  * @sap_ctx: pointer to sap Context
1844  *
1845  * Return: QDF_STATUS code associated with performing the operation
1846  */
1847 static QDF_STATUS sap_goto_stopping(struct sap_context *sap_ctx)
1848 {
1849 	QDF_STATUS status;
1850 	struct mac_context *mac_ctx;
1851 
1852 	mac_ctx = sap_get_mac_context();
1853 	if (!mac_ctx) {
1854 		/* we have a serious problem */
1855 		sap_err("Invalid MAC context");
1856 		return QDF_STATUS_E_FAULT;
1857 	}
1858 
1859 	sap_update_mcs_rate(sap_ctx, false);
1860 	qdf_mem_zero(&sap_ctx->sap_bss_cfg, sizeof(sap_ctx->sap_bss_cfg));
1861 
1862 	status = sme_roam_stop_bss(MAC_HANDLE(mac_ctx), sap_ctx->sessionId);
1863 	if (status != QDF_STATUS_SUCCESS) {
1864 		sap_err("Calling sme_roam_stop_bss status = %d", status);
1865 		return QDF_STATUS_E_FAILURE;
1866 	}
1867 
1868 	return QDF_STATUS_SUCCESS;
1869 }
1870 
1871 /**
1872  * sap_goto_init() - Function for setting the SAP FSM to init state
1873  * @sap_ctx: pointer to sap context
1874  *
1875  * Return: QDF_STATUS code associated with performing the operation
1876  */
1877 static QDF_STATUS sap_goto_init(struct sap_context *sap_ctx)
1878 {
1879 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
1880 	struct sap_sm_event sap_event;
1881 	/* Processing has to be coded */
1882 
1883 	/*
1884 	 * Clean up stations from TL etc as AP BSS is shut down
1885 	 * then set event
1886 	 */
1887 
1888 	/* hardcoded event */
1889 	sap_event.event = eSAP_MAC_READY_FOR_CONNECTIONS;
1890 	sap_event.params = 0;
1891 	sap_event.u1 = 0;
1892 	sap_event.u2 = 0;
1893 	/* Handle event */
1894 	qdf_status = sap_fsm(sap_ctx, &sap_event);
1895 
1896 	return qdf_status;
1897 }
1898 
1899 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
1900 /**
1901  * sap_handle_acs_scan_event() - handle acs scan event for SAP
1902  * @sap_context: ptSapContext
1903  * @sap_event: struct sap_event
1904  * @status: status of acs scan
1905  *
1906  * The function is to handle the eSAP_ACS_SCAN_SUCCESS_EVENT event.
1907  *
1908  * Return: void
1909  */
1910 static void sap_handle_acs_scan_event(struct sap_context *sap_context,
1911 		struct sap_event *sap_event, eSapStatus status)
1912 {
1913 	sap_event->sapHddEventCode = eSAP_ACS_SCAN_SUCCESS_EVENT;
1914 	sap_event->sapevt.sap_acs_scan_comp.status = status;
1915 	sap_event->sapevt.sap_acs_scan_comp.num_of_channels =
1916 			sap_context->num_of_channel;
1917 	sap_event->sapevt.sap_acs_scan_comp.freq_list =
1918 			sap_context->freq_list;
1919 }
1920 #else
1921 static void sap_handle_acs_scan_event(struct sap_context *sap_context,
1922 		struct sap_event *sap_event, eSapStatus status)
1923 {
1924 }
1925 #endif
1926 
1927 #define DH_OUI_TYPE      "\x20"
1928 #define DH_OUI_TYPE_SIZE (1)
1929 /**
1930  * sap_fill_owe_ie_in_assoc_ind() - Fill OWE IE in assoc indication
1931  * Function to fill OWE IE in assoc indication
1932  * @assoc_ind: SAP STA association indication
1933  * @sme_assoc_ind: SME association indication
1934  * @reassoc: True if it is reassoc frame
1935  *
1936  * This function is to get OWE IEs (RSN IE, DH IE etc) from assoc request
1937  * and fill them in association indication.
1938  *
1939  * Return: true for success and false for failure
1940  */
1941 static bool sap_fill_owe_ie_in_assoc_ind(tSap_StationAssocIndication *assoc_ind,
1942 					 struct assoc_ind *sme_assoc_ind,
1943 					 bool reassoc)
1944 {
1945 	uint32_t owe_ie_len, rsn_ie_len, dh_ie_len;
1946 	const uint8_t *rsn_ie, *dh_ie;
1947 	uint8_t *assoc_req_ie;
1948 	uint16_t assoc_req_ie_len;
1949 
1950 	if (reassoc) {
1951 		if (assoc_ind->assocReqLength < WLAN_REASSOC_REQ_IES_OFFSET) {
1952 			sap_err("Invalid reassoc req");
1953 			return false;
1954 		}
1955 
1956 		assoc_req_ie = assoc_ind->assocReqPtr +
1957 			       WLAN_REASSOC_REQ_IES_OFFSET;
1958 		assoc_req_ie_len = assoc_ind->assocReqLength -
1959 				   WLAN_REASSOC_REQ_IES_OFFSET;
1960 	} else {
1961 		if (assoc_ind->assocReqLength < WLAN_ASSOC_REQ_IES_OFFSET) {
1962 			sap_err("Invalid assoc req");
1963 			return false;
1964 		}
1965 
1966 		assoc_req_ie = assoc_ind->assocReqPtr +
1967 			       WLAN_ASSOC_REQ_IES_OFFSET;
1968 		assoc_req_ie_len = assoc_ind->assocReqLength -
1969 				   WLAN_ASSOC_REQ_IES_OFFSET;
1970 	}
1971 	rsn_ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_RSN,
1972 					  assoc_req_ie, assoc_req_ie_len);
1973 	if (!rsn_ie) {
1974 		sap_err("RSN IE is not present");
1975 		return false;
1976 	}
1977 	rsn_ie_len = rsn_ie[1] + 2;
1978 	if (rsn_ie_len < DOT11F_IE_RSN_MIN_LEN ||
1979 	    rsn_ie_len > DOT11F_IE_RSN_MAX_LEN) {
1980 		sap_err("Invalid RSN IE len %d", rsn_ie_len);
1981 		return false;
1982 	}
1983 
1984 	dh_ie = wlan_get_ext_ie_ptr_from_ext_id(DH_OUI_TYPE, DH_OUI_TYPE_SIZE,
1985 						assoc_req_ie, assoc_req_ie_len);
1986 	if (!dh_ie) {
1987 		sap_err("DH IE is not present");
1988 		return false;
1989 	}
1990 	dh_ie_len = dh_ie[1] + 2;
1991 	if (dh_ie_len < DOT11F_IE_DH_PARAMETER_ELEMENT_MIN_LEN ||
1992 	    dh_ie_len > DOT11F_IE_DH_PARAMETER_ELEMENT_MAX_LEN) {
1993 		sap_err("Invalid DH IE len %d", dh_ie_len);
1994 		return false;
1995 	}
1996 
1997 	sap_debug("rsn_ie_len = %d, dh_ie_len = %d", rsn_ie_len, dh_ie_len);
1998 
1999 	owe_ie_len = rsn_ie_len + dh_ie_len;
2000 	assoc_ind->owe_ie = qdf_mem_malloc(owe_ie_len);
2001 	if (!assoc_ind->owe_ie)
2002 		return false;
2003 
2004 	qdf_mem_copy(assoc_ind->owe_ie, rsn_ie, rsn_ie_len);
2005 	qdf_mem_copy(assoc_ind->owe_ie + rsn_ie_len, dh_ie, dh_ie_len);
2006 	assoc_ind->owe_ie_len = owe_ie_len;
2007 
2008 	return true;
2009 }
2010 
2011 /**
2012  * sap_save_owe_pending_assoc_ind() - Save pending assoc indication
2013  * Function to save pending assoc indication in SAP context
2014  * @sap_ctx: SAP context
2015  * @sme_assoc_ind: SME association indication
2016  *
2017  * This function is to save pending assoc indication in linked list
2018  * in SAP context.
2019  *
2020  * Return: true for success and false for failure
2021  */
2022 static bool sap_save_owe_pending_assoc_ind(struct sap_context *sap_ctx,
2023 				       struct assoc_ind *sme_assoc_ind)
2024 {
2025 	struct owe_assoc_ind *assoc_ind;
2026 	QDF_STATUS status;
2027 
2028 	assoc_ind = qdf_mem_malloc(sizeof(*assoc_ind));
2029 	if (!assoc_ind)
2030 		return false;
2031 	assoc_ind->assoc_ind = sme_assoc_ind;
2032 	status = qdf_list_insert_back(&sap_ctx->owe_pending_assoc_ind_list,
2033 				      &assoc_ind->node);
2034 	if (QDF_STATUS_SUCCESS != status) {
2035 		qdf_mem_free(assoc_ind);
2036 		return false;
2037 	}
2038 
2039 	return true;
2040 }
2041 
2042 static bool sap_save_ft_pending_assoc_ind(struct sap_context *sap_ctx,
2043 					  struct assoc_ind *sme_assoc_ind)
2044 {
2045 	struct ft_assoc_ind *assoc_ind;
2046 	QDF_STATUS status;
2047 
2048 	assoc_ind = qdf_mem_malloc(sizeof(*assoc_ind));
2049 	if (!assoc_ind)
2050 		return false;
2051 	assoc_ind->assoc_ind = sme_assoc_ind;
2052 	status = qdf_list_insert_back(&sap_ctx->ft_pending_assoc_ind_list,
2053 				      &assoc_ind->node);
2054 	if (QDF_STATUS_SUCCESS != status) {
2055 		qdf_mem_free(assoc_ind);
2056 		return false;
2057 	}
2058 	qdf_event_set(&sap_ctx->ft_pending_event);
2059 
2060 	return true;
2061 }
2062 
2063 #ifdef FEATURE_RADAR_HISTORY
2064 /* Last cac result */
2065 static struct prev_cac_result prev_cac_history;
2066 
2067 /**
2068  * sap_update_cac_history() - record SAP Radar found result in last
2069  * "active" or CAC period
2070  * @mac_ctx: mac context
2071  * @sap_ctx: sap context
2072  * @event_id: sap event
2073  *
2074  *  The function is to save the dfs channel information
2075  *  If SAP has been "active" or "CAC" on DFS channel for 60s and
2076  *  no found radar event.
2077  *
2078  * Return: void
2079  */
2080 static void
2081 sap_update_cac_history(struct mac_context *mac_ctx,
2082 		       struct sap_context *sap_ctx,
2083 		       eSapHddEvent event_id)
2084 {
2085 	struct prev_cac_result *cac_result = &sap_ctx->cac_result;
2086 
2087 	switch (event_id) {
2088 	case eSAP_START_BSS_EVENT:
2089 	case eSAP_CHANNEL_CHANGE_RESP:
2090 	case eSAP_DFS_CAC_START:
2091 		if (sap_operating_on_dfs(mac_ctx, sap_ctx)) {
2092 			qdf_mem_zero(cac_result,
2093 				     sizeof(struct prev_cac_result));
2094 			if (!sap_ctx->ch_params.mhz_freq_seg0) {
2095 				sap_debug("invalid seq0");
2096 				return;
2097 			}
2098 			cac_result->ap_start_time =
2099 				qdf_get_monotonic_boottime();
2100 			cac_result->cac_ch_param = sap_ctx->ch_params;
2101 			sap_debug("ap start(CAC) (%d, %d) bw %d",
2102 				  cac_result->cac_ch_param.mhz_freq_seg0,
2103 				  cac_result->cac_ch_param.mhz_freq_seg1,
2104 				  cac_result->cac_ch_param.ch_width);
2105 		}
2106 		break;
2107 	case eSAP_DFS_RADAR_DETECT:
2108 		qdf_mem_zero(cac_result,
2109 			     sizeof(struct prev_cac_result));
2110 		break;
2111 	case eSAP_DFS_CAC_END:
2112 	case eSAP_STOP_BSS_EVENT:
2113 		if (cac_result->ap_start_time) {
2114 			uint64_t diff_ms;
2115 
2116 			cac_result->ap_end_time =
2117 				qdf_get_monotonic_boottime();
2118 			diff_ms = qdf_do_div(cac_result->ap_end_time -
2119 				     cac_result->ap_start_time, 1000);
2120 			if (diff_ms < DEFAULT_CAC_TIMEOUT - 5000) {
2121 				if (event_id == eSAP_STOP_BSS_EVENT)
2122 					qdf_mem_zero(
2123 					cac_result,
2124 					sizeof(struct prev_cac_result));
2125 				sap_debug("ap cac dur %llu ms", diff_ms);
2126 				break;
2127 			}
2128 			cac_result->cac_complete = true;
2129 			qdf_mem_copy(&prev_cac_history, cac_result,
2130 				     sizeof(struct prev_cac_result));
2131 			sap_debug("ap cac saved %llu ms %llu (%d, %d) bw %d",
2132 				  diff_ms,
2133 				  cac_result->ap_end_time,
2134 				  cac_result->cac_ch_param.mhz_freq_seg0,
2135 				  cac_result->cac_ch_param.mhz_freq_seg1,
2136 				  cac_result->cac_ch_param.ch_width);
2137 			if (event_id == eSAP_STOP_BSS_EVENT)
2138 				qdf_mem_zero(cac_result,
2139 					     sizeof(struct prev_cac_result));
2140 		}
2141 		break;
2142 	default:
2143 		break;
2144 	}
2145 }
2146 
2147 /**
2148  * find_ch_freq_in_radar_hist() - check channel frequency existing
2149  * in radar history buffer
2150  * @radar_result: radar history buffer
2151  * @count: radar history element number
2152  * @ch_freq: channel frequency
2153  *
2154  * Return: bool
2155  */
2156 static
2157 bool find_ch_freq_in_radar_hist(struct dfs_radar_history *radar_result,
2158 				uint32_t count, uint16_t ch_freq)
2159 {
2160 	while (count) {
2161 		if (radar_result->ch_freq == ch_freq)
2162 			return true;
2163 		radar_result++;
2164 		count--;
2165 	}
2166 
2167 	return false;
2168 }
2169 
2170 /**
2171  * sap_append_cac_history() - Add CAC history to list
2172  * @radar_result: radar history buffer
2173  * @idx: current radar history element number
2174  * @max_elems: max elements number of radar history buffer.
2175  *
2176  * This function is to add the CAC history to radar history list.
2177  *
2178  * Return: void
2179  */
2180 static
2181 void sap_append_cac_history(struct mac_context *mac_ctx,
2182 			    struct dfs_radar_history *radar_result,
2183 			    uint32_t *idx, uint32_t max_elems)
2184 {
2185 	struct prev_cac_result *cac_result = &prev_cac_history;
2186 	struct ch_params ch_param = cac_result->cac_ch_param;
2187 	uint32_t count = *idx;
2188 
2189 	if (!cac_result->cac_complete || !cac_result->ap_end_time) {
2190 		sap_debug("cac hist empty");
2191 		return;
2192 	}
2193 
2194 	if (ch_param.ch_width <= CH_WIDTH_20MHZ) {
2195 		if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev,
2196 					     ch_param.mhz_freq_seg0) &&
2197 		    !find_ch_freq_in_radar_hist(radar_result, count,
2198 						ch_param.mhz_freq_seg0) &&
2199 		    *idx < max_elems) {
2200 			radar_result[*idx].ch_freq = ch_param.mhz_freq_seg0;
2201 			radar_result[*idx].time = cac_result->ap_end_time;
2202 			radar_result[*idx].radar_found = false;
2203 			sap_debug("radar hist[%d] freq %d time %llu no radar",
2204 				  *idx, ch_param.mhz_freq_seg0,
2205 				  cac_result->ap_end_time);
2206 			(*idx)++;
2207 		}
2208 	} else {
2209 		uint16_t chan_cfreq;
2210 		enum channel_state state;
2211 		const struct bonded_channel_freq *bonded_chan_ptr = NULL;
2212 
2213 		state = wlan_reg_get_5g_bonded_channel_and_state_for_pwrmode
2214 			(mac_ctx->pdev, ch_param.mhz_freq_seg0,
2215 			 ch_param.ch_width, &bonded_chan_ptr,
2216 			 REG_CURRENT_PWR_MODE, NO_SCHANS_PUNC);
2217 		if (!bonded_chan_ptr || state == CHANNEL_STATE_INVALID) {
2218 			sap_debug("invalid freq %d", ch_param.mhz_freq_seg0);
2219 			return;
2220 		}
2221 
2222 		chan_cfreq = bonded_chan_ptr->start_freq;
2223 		while (chan_cfreq <= bonded_chan_ptr->end_freq) {
2224 			state = wlan_reg_get_channel_state_for_pwrmode(
2225 					mac_ctx->pdev, chan_cfreq,
2226 					REG_CURRENT_PWR_MODE);
2227 			if (state == CHANNEL_STATE_INVALID) {
2228 				sap_debug("invalid ch freq %d",
2229 					  chan_cfreq);
2230 				chan_cfreq = chan_cfreq + 20;
2231 				continue;
2232 			}
2233 			if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev,
2234 						     chan_cfreq) &&
2235 			    !find_ch_freq_in_radar_hist(radar_result, count,
2236 							chan_cfreq) &&
2237 			    *idx < max_elems) {
2238 				radar_result[*idx].ch_freq = chan_cfreq;
2239 				radar_result[*idx].time =
2240 						cac_result->ap_end_time;
2241 				radar_result[*idx].radar_found = false;
2242 				sap_debug("radar hist[%d] freq %d time %llu no radar",
2243 					  *idx, chan_cfreq,
2244 					  cac_result->ap_end_time);
2245 				(*idx)++;
2246 			}
2247 			chan_cfreq = chan_cfreq + 20;
2248 		}
2249 	}
2250 }
2251 
2252 QDF_STATUS
2253 wlansap_query_radar_history(mac_handle_t mac_handle,
2254 			    struct dfs_radar_history **radar_history,
2255 			    uint32_t *count)
2256 {
2257 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
2258 	struct dfsreq_nolinfo *nol_info;
2259 	uint32_t i;
2260 	uint32_t hist_count;
2261 	struct dfs_radar_history *radar_result;
2262 
2263 	nol_info = qdf_mem_malloc(sizeof(struct dfsreq_nolinfo));
2264 	if (!nol_info)
2265 		return QDF_STATUS_E_NOMEM;
2266 
2267 	ucfg_dfs_getnol(mac_ctx->pdev, nol_info);
2268 
2269 	hist_count = nol_info->dfs_ch_nchans + MAX_NUM_OF_CAC_HISTORY;
2270 	radar_result = qdf_mem_malloc(sizeof(struct dfs_radar_history) *
2271 					hist_count);
2272 	if (!radar_result) {
2273 		qdf_mem_free(nol_info);
2274 		return QDF_STATUS_E_NOMEM;
2275 	}
2276 
2277 	for (i = 0; i < nol_info->dfs_ch_nchans && i < DFS_CHAN_MAX; i++) {
2278 		radar_result[i].ch_freq = nol_info->dfs_nol[i].nol_freq;
2279 		radar_result[i].time = nol_info->dfs_nol[i].nol_start_us;
2280 		radar_result[i].radar_found = true;
2281 		sap_debug("radar hist[%d] freq %d time %llu radar",
2282 			  i, nol_info->dfs_nol[i].nol_freq,
2283 			  nol_info->dfs_nol[i].nol_start_us);
2284 	}
2285 
2286 	sap_append_cac_history(mac_ctx, radar_result, &i, hist_count);
2287 	sap_debug("hist count %d cur %llu", i, qdf_get_monotonic_boottime());
2288 
2289 	*radar_history = radar_result;
2290 	*count = i;
2291 	qdf_mem_free(nol_info);
2292 
2293 	return QDF_STATUS_SUCCESS;
2294 }
2295 #else
2296 static inline void
2297 sap_update_cac_history(struct mac_context *mac_ctx,
2298 		       struct sap_context *sap_ctx,
2299 		       eSapHddEvent event_id)
2300 {
2301 }
2302 #endif
2303 
2304 #ifdef WLAN_FEATURE_11BE_MLO
2305 static inline
2306 bool sap_check_peer_for_peer_null_mldaddr(struct wlan_objmgr_peer *peer)
2307 {
2308 	if (qdf_is_macaddr_zero((struct qdf_mac_addr *)peer->mldaddr))
2309 		return true;
2310 	else
2311 		return false;
2312 }
2313 #else
2314 static inline
2315 bool sap_check_peer_for_peer_null_mldaddr(struct wlan_objmgr_peer *peer)
2316 {
2317 	return true;
2318 }
2319 #endif
2320 
2321 static
2322 QDF_STATUS sap_populate_peer_assoc_info(struct mac_context *mac_ctx,
2323 					struct csr_roam_info *csr_roaminfo,
2324 					struct sap_event *sap_ap_event)
2325 {
2326 	struct wlan_objmgr_peer *peer;
2327 	tSap_StationAssocReassocCompleteEvent *reassoc_complete;
2328 
2329 	reassoc_complete =
2330 		&sap_ap_event->sapevt.sapStationAssocReassocCompleteEvent;
2331 
2332 	peer = wlan_objmgr_get_peer_by_mac(mac_ctx->psoc,
2333 					   csr_roaminfo->peerMac.bytes,
2334 					   WLAN_LEGACY_MAC_ID);
2335 	if (!peer) {
2336 		sap_err("Peer object not found");
2337 		return QDF_STATUS_E_FAILURE;
2338 	}
2339 
2340 	sap_debug("mlo peer assoc:%d", wlan_peer_mlme_is_assoc_peer(peer));
2341 
2342 	if (sap_check_peer_for_peer_null_mldaddr(peer) ||
2343 	    wlan_peer_mlme_is_assoc_peer(peer)) {
2344 		if (csr_roaminfo->assocReqLength < ASSOC_REQ_IE_OFFSET) {
2345 			sap_err("Invalid assoc request length:%d",
2346 				csr_roaminfo->assocReqLength);
2347 			wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID);
2348 			return QDF_STATUS_E_INVAL;
2349 		}
2350 		reassoc_complete->ies_len = (csr_roaminfo->assocReqLength -
2351 					    ASSOC_REQ_IE_OFFSET);
2352 		reassoc_complete->ies = (csr_roaminfo->assocReqPtr +
2353 					 ASSOC_REQ_IE_OFFSET);
2354 		/* skip current AP address in reassoc frame */
2355 		if (csr_roaminfo->fReassocReq) {
2356 			reassoc_complete->ies_len -= QDF_MAC_ADDR_SIZE;
2357 			reassoc_complete->ies += QDF_MAC_ADDR_SIZE;
2358 		}
2359 	}
2360 
2361 	if (csr_roaminfo->addIELen) {
2362 		if (wlan_get_vendor_ie_ptr_from_oui(
2363 		    SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE,
2364 		    csr_roaminfo->paddIE, csr_roaminfo->addIELen)) {
2365 			reassoc_complete->staType = eSTA_TYPE_P2P_CLI;
2366 		} else {
2367 			reassoc_complete->staType = eSTA_TYPE_INFRA;
2368 		}
2369 	}
2370 
2371 	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID);
2372 
2373 	return QDF_STATUS_SUCCESS;
2374 }
2375 
2376 #ifdef WLAN_FEATURE_11BE_MLO
2377 static void
2378 sap_reassoc_mld_copy(struct csr_roam_info *csr_roaminfo,
2379 		     tSap_StationAssocReassocCompleteEvent *reassoc_complete)
2380 {
2381 	qdf_copy_macaddr(&reassoc_complete->sta_mld,
2382 			 &csr_roaminfo->peer_mld);
2383 	sap_debug("reassoc_complete->staMld: " QDF_MAC_ADDR_FMT,
2384 		  QDF_MAC_ADDR_REF(reassoc_complete->sta_mld.bytes));
2385 }
2386 #else /* WLAN_FEATURE_11BE_MLO */
2387 static inline void
2388 sap_reassoc_mld_copy(struct csr_roam_info *csr_roaminfo,
2389 		     tSap_StationAssocReassocCompleteEvent *reassoc_complete)
2390 {
2391 }
2392 #endif /* WLAN_FEATURE_11BE_MLO */
2393 
2394 /**
2395  * sap_signal_hdd_event() - send event notification
2396  * @sap_ctx: Sap Context
2397  * @csr_roaminfo: Pointer to CSR roam information
2398  * @sap_hddevent: SAP HDD event
2399  * @context: to pass the element for future support
2400  *
2401  * Function for HDD to send the event notification using callback
2402  *
2403  * Return: QDF_STATUS
2404  */
2405 QDF_STATUS sap_signal_hdd_event(struct sap_context *sap_ctx,
2406 		struct csr_roam_info *csr_roaminfo, eSapHddEvent sap_hddevent,
2407 		void *context)
2408 {
2409 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
2410 	struct sap_event *sap_ap_event;
2411 	struct mac_context *mac_ctx;
2412 	struct oem_channel_info *chaninfo;
2413 	tSap_StationAssocIndication *assoc_ind;
2414 	tSap_StartBssCompleteEvent *bss_complete;
2415 	struct sap_ch_selected_s *acs_selected;
2416 	tSap_StationAssocReassocCompleteEvent *reassoc_complete;
2417 	tSap_StationDisassocCompleteEvent *disassoc_comp;
2418 	tSap_StationSetKeyCompleteEvent *key_complete;
2419 	tSap_StationMICFailureEvent *mic_failure;
2420 
2421 	/* Format the Start BSS Complete event to return... */
2422 	if (!sap_ctx->sap_event_cb)
2423 		return QDF_STATUS_E_FAILURE;
2424 
2425 	mac_ctx = sap_get_mac_context();
2426 	if (!mac_ctx) {
2427 		sap_err("Invalid MAC context");
2428 		return QDF_STATUS_E_FAILURE;
2429 	}
2430 
2431 	sap_ap_event = qdf_mem_malloc(sizeof(*sap_ap_event));
2432 	if (!sap_ap_event)
2433 		return QDF_STATUS_E_NOMEM;
2434 
2435 	sap_debug("SAP event callback event = %s",
2436 		  sap_hdd_event_to_string(sap_hddevent));
2437 
2438 	switch (sap_hddevent) {
2439 	case eSAP_STA_ASSOC_IND:
2440 		if (!csr_roaminfo) {
2441 			sap_debug("Invalid CSR Roam Info");
2442 			qdf_mem_free(sap_ap_event);
2443 			return QDF_STATUS_E_INVAL;
2444 		}
2445 		/*  TODO - Indicate the assoc request indication to OS */
2446 		sap_ap_event->sapHddEventCode = eSAP_STA_ASSOC_IND;
2447 		assoc_ind = &sap_ap_event->sapevt.sapAssocIndication;
2448 
2449 		qdf_copy_macaddr(&assoc_ind->staMac, &csr_roaminfo->peerMac);
2450 		assoc_ind->staId = csr_roaminfo->staId;
2451 		assoc_ind->status = 0;
2452 		/* Required for indicating the frames to upper layer */
2453 		assoc_ind->assocReqLength = csr_roaminfo->assocReqLength;
2454 		assoc_ind->assocReqPtr = csr_roaminfo->assocReqPtr;
2455 		assoc_ind->fWmmEnabled = csr_roaminfo->wmmEnabledSta;
2456 		assoc_ind->ecsa_capable = csr_roaminfo->ecsa_capable;
2457 		if (csr_roaminfo->owe_pending_assoc_ind) {
2458 			if (!sap_fill_owe_ie_in_assoc_ind(assoc_ind,
2459 					 csr_roaminfo->owe_pending_assoc_ind,
2460 					 csr_roaminfo->fReassocReq)) {
2461 				sap_err("Failed to fill OWE IE");
2462 				qdf_mem_free(csr_roaminfo->
2463 					     owe_pending_assoc_ind);
2464 				csr_roaminfo->owe_pending_assoc_ind = NULL;
2465 				qdf_mem_free(sap_ap_event);
2466 				return QDF_STATUS_E_INVAL;
2467 			}
2468 			if (!sap_save_owe_pending_assoc_ind(sap_ctx,
2469 					 csr_roaminfo->owe_pending_assoc_ind)) {
2470 				sap_err("Failed to save assoc ind");
2471 				qdf_mem_free(csr_roaminfo->
2472 					     owe_pending_assoc_ind);
2473 				csr_roaminfo->owe_pending_assoc_ind = NULL;
2474 				qdf_mem_free(sap_ap_event);
2475 				return QDF_STATUS_E_INVAL;
2476 			}
2477 			csr_roaminfo->owe_pending_assoc_ind = NULL;
2478 		}
2479 
2480 		if (csr_roaminfo->ft_pending_assoc_ind) {
2481 			if (!sap_save_ft_pending_assoc_ind(sap_ctx,
2482 			    csr_roaminfo->ft_pending_assoc_ind)) {
2483 				sap_err("Failed to save ft assoc ind");
2484 				qdf_mem_free(csr_roaminfo->ft_pending_assoc_ind);
2485 				csr_roaminfo->ft_pending_assoc_ind = NULL;
2486 				qdf_mem_free(sap_ap_event);
2487 				return QDF_STATUS_E_INVAL;
2488 			}
2489 			csr_roaminfo->ft_pending_assoc_ind = NULL;
2490 		}
2491 		break;
2492 	case eSAP_START_BSS_EVENT:
2493 		sap_ap_event->sapHddEventCode = eSAP_START_BSS_EVENT;
2494 		bss_complete = &sap_ap_event->sapevt.sapStartBssCompleteEvent;
2495 
2496 		bss_complete->sessionId = sap_ctx->sessionId;
2497 		if (bss_complete->sessionId == WLAN_UMAC_VDEV_ID_MAX) {
2498 			sap_err("Invalid sessionId");
2499 			qdf_mem_free(sap_ap_event);
2500 			return QDF_STATUS_E_INVAL;
2501 		}
2502 
2503 		bss_complete->status = (eSapStatus) context;
2504 		bss_complete->staId = sap_ctx->sap_sta_id;
2505 
2506 		sap_debug("(eSAP_START_BSS_EVENT): staId = %d",
2507 			  bss_complete->staId);
2508 
2509 		bss_complete->operating_chan_freq = sap_ctx->chan_freq;
2510 		bss_complete->ch_width = sap_ctx->ch_params.ch_width;
2511 		if (QDF_IS_STATUS_SUCCESS(bss_complete->status)) {
2512 			sap_update_cac_history(mac_ctx, sap_ctx,
2513 					       sap_hddevent);
2514 			sap_update_mcs_rate(sap_ctx, true);
2515 		}
2516 		break;
2517 	case eSAP_DFS_CAC_START:
2518 	case eSAP_DFS_CAC_INTERRUPTED:
2519 	case eSAP_DFS_CAC_END:
2520 	case eSAP_DFS_RADAR_DETECT:
2521 	case eSAP_DFS_NO_AVAILABLE_CHANNEL:
2522 		sap_ap_event->sapHddEventCode = sap_hddevent;
2523 		sap_ap_event->sapevt.sapStopBssCompleteEvent.status =
2524 			(eSapStatus) context;
2525 		sap_update_cac_history(mac_ctx, sap_ctx,
2526 				       sap_hddevent);
2527 		break;
2528 	case eSAP_ACS_SCAN_SUCCESS_EVENT:
2529 		sap_handle_acs_scan_event(sap_ctx, sap_ap_event,
2530 					  (eSapStatus)context);
2531 		break;
2532 	case eSAP_ACS_CHANNEL_SELECTED:
2533 		sap_ap_event->sapHddEventCode = sap_hddevent;
2534 		acs_selected = &sap_ap_event->sapevt.sap_ch_selected;
2535 		if (eSAP_STATUS_SUCCESS == (eSapStatus)context) {
2536 			acs_selected->pri_ch_freq =
2537 						sap_ctx->acs_cfg->pri_ch_freq;
2538 			acs_selected->ht_sec_ch_freq =
2539 					sap_ctx->acs_cfg->ht_sec_ch_freq;
2540 			acs_selected->ch_width = sap_ctx->acs_cfg->ch_width;
2541 			acs_selected->vht_seg0_center_ch_freq =
2542 				sap_ctx->acs_cfg->vht_seg0_center_ch_freq;
2543 			acs_selected->vht_seg1_center_ch_freq =
2544 				sap_ctx->acs_cfg->vht_seg1_center_ch_freq;
2545 		} else if (eSAP_STATUS_FAILURE == (eSapStatus)context) {
2546 			acs_selected->pri_ch_freq = 0;
2547 		}
2548 		break;
2549 
2550 	case eSAP_STOP_BSS_EVENT:
2551 		sap_ap_event->sapHddEventCode = eSAP_STOP_BSS_EVENT;
2552 		sap_ap_event->sapevt.sapStopBssCompleteEvent.status =
2553 			(eSapStatus) context;
2554 		break;
2555 
2556 	case eSAP_STA_ASSOC_EVENT:
2557 	case eSAP_STA_REASSOC_EVENT:
2558 
2559 		if (!csr_roaminfo) {
2560 			sap_err("Invalid CSR Roam Info");
2561 			qdf_mem_free(sap_ap_event);
2562 			return QDF_STATUS_E_INVAL;
2563 		}
2564 		if (sap_ctx->fsm_state == SAP_STOPPING) {
2565 			sap_err("SAP is stopping, not able to handle any incoming (re)assoc req");
2566 			qdf_mem_free(sap_ap_event);
2567 			return QDF_STATUS_E_ABORTED;
2568 		}
2569 
2570 		qdf_status = sap_populate_peer_assoc_info(mac_ctx, csr_roaminfo,
2571 							  sap_ap_event);
2572 		if (QDF_IS_STATUS_ERROR(qdf_status)) {
2573 			qdf_mem_free(sap_ap_event);
2574 			return QDF_STATUS_E_INVAL;
2575 		}
2576 
2577 		reassoc_complete =
2578 		    &sap_ap_event->sapevt.sapStationAssocReassocCompleteEvent;
2579 
2580 		if (csr_roaminfo->fReassocReq)
2581 			sap_ap_event->sapHddEventCode = eSAP_STA_REASSOC_EVENT;
2582 		else
2583 			sap_ap_event->sapHddEventCode = eSAP_STA_ASSOC_EVENT;
2584 
2585 		qdf_copy_macaddr(&reassoc_complete->staMac,
2586 				 &csr_roaminfo->peerMac);
2587 		sap_reassoc_mld_copy(csr_roaminfo, reassoc_complete);
2588 		reassoc_complete->staId = csr_roaminfo->staId;
2589 		reassoc_complete->status_code = csr_roaminfo->status_code;
2590 
2591 		/* also fill up the channel info from the csr_roamInfo */
2592 		chaninfo = &reassoc_complete->chan_info;
2593 
2594 		chaninfo->mhz = csr_roaminfo->chan_info.mhz;
2595 		chaninfo->info = csr_roaminfo->chan_info.info;
2596 		chaninfo->band_center_freq1 =
2597 			csr_roaminfo->chan_info.band_center_freq1;
2598 		chaninfo->band_center_freq2 =
2599 			csr_roaminfo->chan_info.band_center_freq2;
2600 		chaninfo->reg_info_1 =
2601 			csr_roaminfo->chan_info.reg_info_1;
2602 		chaninfo->reg_info_2 =
2603 			csr_roaminfo->chan_info.reg_info_2;
2604 		chaninfo->nss = csr_roaminfo->chan_info.nss;
2605 		chaninfo->rate_flags = csr_roaminfo->chan_info.rate_flags;
2606 
2607 		reassoc_complete->wmmEnabled = csr_roaminfo->wmmEnabledSta;
2608 		reassoc_complete->status = (eSapStatus) context;
2609 		reassoc_complete->timingMeasCap = csr_roaminfo->timingMeasCap;
2610 		reassoc_complete->ampdu = csr_roaminfo->ampdu;
2611 		reassoc_complete->sgi_enable = csr_roaminfo->sgi_enable;
2612 		reassoc_complete->tx_stbc = csr_roaminfo->tx_stbc;
2613 		reassoc_complete->rx_stbc = csr_roaminfo->rx_stbc;
2614 		reassoc_complete->ch_width = csr_roaminfo->ch_width;
2615 		reassoc_complete->mode = csr_roaminfo->mode;
2616 		reassoc_complete->max_supp_idx = csr_roaminfo->max_supp_idx;
2617 		reassoc_complete->max_ext_idx = csr_roaminfo->max_ext_idx;
2618 		reassoc_complete->max_mcs_idx = csr_roaminfo->max_mcs_idx;
2619 		reassoc_complete->max_real_mcs_idx =
2620 						csr_roaminfo->max_real_mcs_idx;
2621 		reassoc_complete->rx_mcs_map = csr_roaminfo->rx_mcs_map;
2622 		reassoc_complete->tx_mcs_map = csr_roaminfo->tx_mcs_map;
2623 		reassoc_complete->ecsa_capable = csr_roaminfo->ecsa_capable;
2624 		reassoc_complete->ext_cap = csr_roaminfo->ext_cap;
2625 		reassoc_complete->supported_band = csr_roaminfo->supported_band;
2626 		if (csr_roaminfo->ht_caps.present)
2627 			reassoc_complete->ht_caps = csr_roaminfo->ht_caps;
2628 		if (csr_roaminfo->vht_caps.present)
2629 			reassoc_complete->vht_caps = csr_roaminfo->vht_caps;
2630 		reassoc_complete->he_caps_present =
2631 						csr_roaminfo->he_caps_present;
2632 		reassoc_complete->eht_caps_present =
2633 						csr_roaminfo->eht_caps_present;
2634 		reassoc_complete->capability_info =
2635 						csr_roaminfo->capability_info;
2636 
2637 		break;
2638 
2639 	case eSAP_STA_DISASSOC_EVENT:
2640 		if (!csr_roaminfo) {
2641 			sap_debug("Invalid CSR Roam Info");
2642 			qdf_mem_free(sap_ap_event);
2643 			return QDF_STATUS_E_INVAL;
2644 		}
2645 		sap_ap_event->sapHddEventCode = eSAP_STA_DISASSOC_EVENT;
2646 		disassoc_comp =
2647 			&sap_ap_event->sapevt.sapStationDisassocCompleteEvent;
2648 
2649 		qdf_copy_macaddr(&disassoc_comp->staMac,
2650 				 &csr_roaminfo->peerMac);
2651 		disassoc_comp->staId = csr_roaminfo->staId;
2652 		if (csr_roaminfo->reasonCode == eCSR_ROAM_RESULT_FORCED)
2653 			disassoc_comp->reason = eSAP_USR_INITATED_DISASSOC;
2654 		else
2655 			disassoc_comp->reason = eSAP_MAC_INITATED_DISASSOC;
2656 
2657 		disassoc_comp->status_code = csr_roaminfo->status_code;
2658 		disassoc_comp->status = (eSapStatus) context;
2659 		disassoc_comp->rssi = csr_roaminfo->rssi;
2660 		disassoc_comp->rx_rate = csr_roaminfo->rx_rate;
2661 		disassoc_comp->tx_rate = csr_roaminfo->tx_rate;
2662 		disassoc_comp->rx_mc_bc_cnt = csr_roaminfo->rx_mc_bc_cnt;
2663 		disassoc_comp->rx_retry_cnt = csr_roaminfo->rx_retry_cnt;
2664 		disassoc_comp->reason_code = csr_roaminfo->disassoc_reason;
2665 		break;
2666 
2667 	case eSAP_STA_SET_KEY_EVENT:
2668 
2669 		if (!csr_roaminfo) {
2670 			sap_debug("Invalid CSR Roam Info");
2671 			qdf_mem_free(sap_ap_event);
2672 			return QDF_STATUS_E_INVAL;
2673 		}
2674 		sap_ap_event->sapHddEventCode = eSAP_STA_SET_KEY_EVENT;
2675 		key_complete =
2676 			&sap_ap_event->sapevt.sapStationSetKeyCompleteEvent;
2677 		key_complete->status = (eSapStatus) context;
2678 		qdf_copy_macaddr(&key_complete->peerMacAddr,
2679 				 &csr_roaminfo->peerMac);
2680 		break;
2681 
2682 	case eSAP_STA_MIC_FAILURE_EVENT:
2683 
2684 		if (!csr_roaminfo) {
2685 			sap_debug("Invalid CSR Roam Info");
2686 			qdf_mem_free(sap_ap_event);
2687 			return QDF_STATUS_E_INVAL;
2688 		}
2689 		sap_ap_event->sapHddEventCode = eSAP_STA_MIC_FAILURE_EVENT;
2690 		mic_failure = &sap_ap_event->sapevt.sapStationMICFailureEvent;
2691 
2692 		qdf_mem_copy(&mic_failure->srcMacAddr,
2693 			     csr_roaminfo->u.pMICFailureInfo->srcMacAddr,
2694 			     sizeof(tSirMacAddr));
2695 		qdf_mem_copy(&mic_failure->staMac.bytes,
2696 			     csr_roaminfo->u.pMICFailureInfo->taMacAddr,
2697 			     sizeof(tSirMacAddr));
2698 		qdf_mem_copy(&mic_failure->dstMacAddr.bytes,
2699 			     csr_roaminfo->u.pMICFailureInfo->dstMacAddr,
2700 			     sizeof(tSirMacAddr));
2701 		mic_failure->multicast =
2702 			csr_roaminfo->u.pMICFailureInfo->multicast;
2703 		mic_failure->IV1 = csr_roaminfo->u.pMICFailureInfo->IV1;
2704 		mic_failure->keyId = csr_roaminfo->u.pMICFailureInfo->keyId;
2705 		qdf_mem_copy(mic_failure->TSC,
2706 			     csr_roaminfo->u.pMICFailureInfo->TSC,
2707 			     SIR_CIPHER_SEQ_CTR_SIZE);
2708 		break;
2709 
2710 	case eSAP_WPS_PBC_PROBE_REQ_EVENT:
2711 
2712 		if (!csr_roaminfo) {
2713 			sap_debug("Invalid CSR Roam Info");
2714 			qdf_mem_free(sap_ap_event);
2715 			return QDF_STATUS_E_INVAL;
2716 		}
2717 		sap_ap_event->sapHddEventCode = eSAP_WPS_PBC_PROBE_REQ_EVENT;
2718 
2719 		qdf_mem_copy(&sap_ap_event->sapevt.sapPBCProbeReqEvent.
2720 			     WPSPBCProbeReq, csr_roaminfo->u.pWPSPBCProbeReq,
2721 			     sizeof(tSirWPSPBCProbeReq));
2722 		break;
2723 
2724 	case eSAP_DISCONNECT_ALL_P2P_CLIENT:
2725 		sap_ap_event->sapHddEventCode = eSAP_DISCONNECT_ALL_P2P_CLIENT;
2726 		sap_ap_event->sapevt.sapActionCnf.actionSendSuccess =
2727 			(eSapStatus) context;
2728 		break;
2729 
2730 	case eSAP_MAC_TRIG_STOP_BSS_EVENT:
2731 		sap_ap_event->sapHddEventCode = eSAP_MAC_TRIG_STOP_BSS_EVENT;
2732 		sap_ap_event->sapevt.sapActionCnf.actionSendSuccess =
2733 			(eSapStatus) context;
2734 		break;
2735 
2736 	case eSAP_UNKNOWN_STA_JOIN:
2737 		sap_ap_event->sapHddEventCode = eSAP_UNKNOWN_STA_JOIN;
2738 		qdf_mem_copy((void *)sap_ap_event->sapevt.sapUnknownSTAJoin.
2739 			     macaddr.bytes, (void *) context,
2740 			     QDF_MAC_ADDR_SIZE);
2741 		break;
2742 
2743 	case eSAP_MAX_ASSOC_EXCEEDED:
2744 
2745 		if (!csr_roaminfo) {
2746 			sap_debug("Invalid CSR Roam Info");
2747 			qdf_mem_free(sap_ap_event);
2748 			return QDF_STATUS_E_INVAL;
2749 		}
2750 		sap_ap_event->sapHddEventCode = eSAP_MAX_ASSOC_EXCEEDED;
2751 		qdf_copy_macaddr(&sap_ap_event->sapevt.
2752 				 sapMaxAssocExceeded.macaddr,
2753 				 &csr_roaminfo->peerMac);
2754 		break;
2755 
2756 	case eSAP_CHANNEL_CHANGE_EVENT:
2757 		/*
2758 		 * Reconfig ACS result info. For DFS AP-AP Mode Sec AP ACS
2759 		 * follows pri AP
2760 		 */
2761 		sap_ctx->acs_cfg->pri_ch_freq = sap_ctx->chan_freq;
2762 		sap_ctx->acs_cfg->ch_width =
2763 					sap_ctx->ch_params.ch_width;
2764 		sap_config_acs_result(MAC_HANDLE(mac_ctx), sap_ctx,
2765 				      sap_ctx->sec_ch_freq);
2766 
2767 		sap_ap_event->sapHddEventCode = eSAP_CHANNEL_CHANGE_EVENT;
2768 
2769 		acs_selected = &sap_ap_event->sapevt.sap_ch_selected;
2770 		acs_selected->pri_ch_freq = sap_ctx->chan_freq;
2771 		acs_selected->ht_sec_ch_freq = sap_ctx->sec_ch_freq;
2772 		acs_selected->ch_width =
2773 			sap_ctx->acs_cfg->ch_width;
2774 		acs_selected->vht_seg0_center_ch_freq =
2775 			sap_ctx->acs_cfg->vht_seg0_center_ch_freq;
2776 		acs_selected->vht_seg1_center_ch_freq =
2777 			sap_ctx->acs_cfg->vht_seg1_center_ch_freq;
2778 		break;
2779 
2780 	case eSAP_ECSA_CHANGE_CHAN_IND:
2781 
2782 		if (!csr_roaminfo) {
2783 			sap_debug("Invalid CSR Roam Info");
2784 			qdf_mem_free(sap_ap_event);
2785 			return QDF_STATUS_E_INVAL;
2786 		}
2787 		sap_debug("SAP event callback event = %s",
2788 			  "eSAP_ECSA_CHANGE_CHAN_IND");
2789 		sap_ap_event->sapHddEventCode = eSAP_ECSA_CHANGE_CHAN_IND;
2790 		sap_ap_event->sapevt.sap_chan_cng_ind.new_chan_freq =
2791 					   csr_roaminfo->target_chan_freq;
2792 		break;
2793 	case eSAP_DFS_NEXT_CHANNEL_REQ:
2794 		sap_debug("SAP event callback event = %s",
2795 			  "eSAP_DFS_NEXT_CHANNEL_REQ");
2796 		sap_ap_event->sapHddEventCode = eSAP_DFS_NEXT_CHANNEL_REQ;
2797 		break;
2798 	case eSAP_STOP_BSS_DUE_TO_NO_CHNL:
2799 		sap_ap_event->sapHddEventCode = eSAP_STOP_BSS_DUE_TO_NO_CHNL;
2800 		sap_debug("stopping session_id:%d, bssid:"QDF_MAC_ADDR_FMT", chan_freq:%d",
2801 			   sap_ctx->sessionId,
2802 			   QDF_MAC_ADDR_REF(sap_ctx->self_mac_addr),
2803 			   sap_ctx->chan_freq);
2804 		break;
2805 
2806 	case eSAP_CHANNEL_CHANGE_RESP:
2807 		sap_ap_event->sapHddEventCode = eSAP_CHANNEL_CHANGE_RESP;
2808 		sap_ap_event->sapevt.sap_chan_cng_rsp.ch_change_rsp_status =
2809 					(eSapStatus)context;
2810 		acs_selected =
2811 			&sap_ap_event->sapevt.sap_chan_cng_rsp.sap_ch_selected;
2812 		acs_selected->pri_ch_freq = sap_ctx->chan_freq;
2813 		acs_selected->ht_sec_ch_freq = sap_ctx->sec_ch_freq;
2814 		acs_selected->ch_width =
2815 				sap_ctx->ch_params.ch_width;
2816 		acs_selected->vht_seg0_center_ch_freq =
2817 				sap_ctx->ch_params.mhz_freq_seg0;
2818 		acs_selected->vht_seg1_center_ch_freq =
2819 				sap_ctx->ch_params.mhz_freq_seg1;
2820 		sap_update_cac_history(mac_ctx, sap_ctx,
2821 				       sap_hddevent);
2822 		sap_debug("SAP event callback event = %s",
2823 			  "eSAP_CHANNEL_CHANGE_RESP");
2824 		break;
2825 
2826 	default:
2827 		sap_err("SAP Unknown callback event = %d", sap_hddevent);
2828 		break;
2829 	}
2830 	qdf_status = (*sap_ctx->sap_event_cb)
2831 			(sap_ap_event, sap_ctx->user_context);
2832 
2833 	qdf_mem_free(sap_ap_event);
2834 
2835 	return qdf_status;
2836 }
2837 
2838 bool sap_is_dfs_cac_wait_state(struct sap_context *sap_ctx)
2839 {
2840 	struct wlan_objmgr_vdev *vdev;
2841 	QDF_STATUS status;
2842 	struct mac_context *mac_ctx;
2843 	mac_handle_t mac_handle;
2844 
2845 	if (!sap_ctx) {
2846 		sap_err("Invalid sap context");
2847 		return false;
2848 	}
2849 
2850 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
2851 	if (!mac_handle)
2852 		return false;
2853 
2854 	mac_ctx = MAC_CONTEXT(mac_handle);
2855 	if (!mac_ctx) {
2856 		sap_err("Invalid MAC context");
2857 		return false;
2858 	}
2859 
2860 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
2861 						    sap_ctx->sessionId,
2862 						    WLAN_DFS_ID);
2863 	if (!vdev) {
2864 		sap_err("vdev is NULL for vdev_id: %u", sap_ctx->sessionId);
2865 		return false;
2866 	}
2867 
2868 	status = wlan_vdev_is_dfs_cac_wait(vdev);
2869 	wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID);
2870 
2871 	return QDF_IS_STATUS_SUCCESS(status);
2872 }
2873 
2874 /**
2875  * sap_find_cac_wait_session() - Get context of a SAP session in CAC wait state
2876  * @handle: Global MAC handle
2877  *
2878  * Finds and gets the context of a SAP session in CAC wait state.
2879  *
2880  * Return: Valid SAP context on success, else NULL
2881  */
2882 static struct sap_context *sap_find_cac_wait_session(mac_handle_t handle)
2883 {
2884 	struct mac_context *mac = MAC_CONTEXT(handle);
2885 	uint8_t i = 0;
2886 	struct sap_context *sap_ctx;
2887 
2888 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
2889 		sap_ctx = mac->sap.sapCtxList[i].sap_context;
2890 		if (((QDF_SAP_MODE == mac->sap.sapCtxList[i].sapPersona)
2891 		    ||
2892 		    (QDF_P2P_GO_MODE == mac->sap.sapCtxList[i].sapPersona)) &&
2893 		    (sap_is_dfs_cac_wait_state(sap_ctx))) {
2894 			sap_debug("found SAP in cac wait state");
2895 			return sap_ctx;
2896 		}
2897 		if (sap_ctx) {
2898 			sap_debug("sapdfs: mode:%d intf:%d state:%d",
2899 				  mac->sap.sapCtxList[i].sapPersona, i,
2900 				  sap_ctx->fsm_state);
2901 		}
2902 	}
2903 
2904 	return NULL;
2905 }
2906 
2907 void sap_cac_reset_notify(mac_handle_t mac_handle)
2908 {
2909 	uint8_t intf = 0;
2910 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
2911 
2912 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
2913 		struct sap_context *sap_context =
2914 			mac->sap.sapCtxList[intf].sap_context;
2915 		if (((QDF_SAP_MODE == mac->sap.sapCtxList[intf].sapPersona)
2916 		    ||
2917 		    (QDF_P2P_GO_MODE == mac->sap.sapCtxList[intf].sapPersona))
2918 		    && mac->sap.sapCtxList[intf].sap_context) {
2919 			sap_context->isCacStartNotified = false;
2920 			sap_context->isCacEndNotified = false;
2921 		}
2922 	}
2923 }
2924 
2925 /**
2926  * sap_cac_start_notify() - Notify CAC start to HDD
2927  * @mac_handle: Opaque handle to the global MAC context
2928  *
2929  * Function will be called to notify eSAP_DFS_CAC_START event to HDD
2930  *
2931  * Return: QDF_STATUS_SUCCESS if the notification was sent, otherwise
2932  *         an appropriate QDF_STATUS error
2933  */
2934 static QDF_STATUS sap_cac_start_notify(mac_handle_t mac_handle)
2935 {
2936 	uint8_t intf = 0;
2937 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
2938 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2939 
2940 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
2941 		struct sap_context *sap_context =
2942 			mac->sap.sapCtxList[intf].sap_context;
2943 
2944 		if (((QDF_SAP_MODE == mac->sap.sapCtxList[intf].sapPersona)
2945 		    ||
2946 		    (QDF_P2P_GO_MODE == mac->sap.sapCtxList[intf].sapPersona))
2947 		    && mac->sap.sapCtxList[intf].sap_context &&
2948 		    (false == sap_context->isCacStartNotified)) {
2949 			/* Don't start CAC for non-dfs channel, its violation */
2950 			if (!sap_operating_on_dfs(
2951 					mac,
2952 					mac->sap.sapCtxList[intf].sap_context))
2953 				continue;
2954 			sap_debug("sapdfs: Signaling eSAP_DFS_CAC_START to HDD for sapctx[%pK]",
2955 				  sap_context);
2956 
2957 			qdf_status = sap_signal_hdd_event(sap_context, NULL,
2958 							  eSAP_DFS_CAC_START,
2959 							  (void *)
2960 							  eSAP_STATUS_SUCCESS);
2961 			if (QDF_STATUS_SUCCESS != qdf_status) {
2962 				sap_err("Failed setting isCacStartNotified on interface[%d]",
2963 					 intf);
2964 				return qdf_status;
2965 			}
2966 			sap_context->isCacStartNotified = true;
2967 		}
2968 	}
2969 	return qdf_status;
2970 }
2971 
2972 #ifdef PRE_CAC_SUPPORT
2973 /**
2974  * wlansap_pre_cac_end_notify() - Update pre cac end to upper layer
2975  * @sap_context: SAP context
2976  * @mac: Global MAC structure
2977  * @intf: Interface number
2978  *
2979  * Notifies pre cac end to upper layer
2980  *
2981  * Return: None
2982  */
2983 static void wlansap_pre_cac_end_notify(struct sap_context *sap_context,
2984 				       struct mac_context *mac,
2985 				       uint8_t intf)
2986 {
2987 	sap_context->isCacEndNotified = true;
2988 	sap_context->sap_radar_found_status = false;
2989 	sap_context->fsm_state = SAP_STARTED;
2990 	sap_warn("sap_fsm: vdev %d => SAP_STARTED, pre cac end notify on %d",
2991 		 sap_context->vdev_id, intf);
2992 	wlan_pre_cac_handle_cac_end(sap_context->vdev);
2993 }
2994 #endif
2995 
2996 QDF_STATUS sap_cac_end_notify(mac_handle_t mac_handle,
2997 			      struct csr_roam_info *roamInfo)
2998 {
2999 	uint8_t intf;
3000 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
3001 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3002 	bool is_acs;
3003 
3004 	/*
3005 	 * eSAP_DFS_CHANNEL_CAC_END:
3006 	 * CAC Period elapsed and there was no radar
3007 	 * found so, SAP can continue beaconing.
3008 	 * sap_radar_found_status is set to 0
3009 	 */
3010 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
3011 		struct sap_context *sap_context =
3012 			mac->sap.sapCtxList[intf].sap_context;
3013 
3014 		if (((QDF_SAP_MODE == mac->sap.sapCtxList[intf].sapPersona)
3015 		    ||
3016 		    (QDF_P2P_GO_MODE == mac->sap.sapCtxList[intf].sapPersona))
3017 		    && mac->sap.sapCtxList[intf].sap_context &&
3018 		    (false == sap_context->isCacEndNotified) &&
3019 		    sap_is_dfs_cac_wait_state(sap_context)) {
3020 			sap_context = mac->sap.sapCtxList[intf].sap_context;
3021 			/* Don't check CAC for non-dfs channel */
3022 			if (!sap_operating_on_dfs(
3023 					mac,
3024 					mac->sap.sapCtxList[intf].sap_context))
3025 				continue;
3026 
3027 			/* If this is an end notification of a pre cac, the
3028 			 * SAP must not start beaconing and must delete the
3029 			 * temporary interface created for pre cac and switch
3030 			 * the original SAP to the pre CAC channel.
3031 			 */
3032 			if (wlan_pre_cac_get_status(mac->psoc)) {
3033 				wlansap_pre_cac_end_notify(sap_context,
3034 							   mac, intf);
3035 				/* pre CAC is not allowed with any concurrency.
3036 				 * So, we can break from here.
3037 				 */
3038 				break;
3039 			}
3040 
3041 			qdf_status = sap_signal_hdd_event(sap_context, NULL,
3042 							  eSAP_DFS_CAC_END,
3043 							  (void *)
3044 							  eSAP_STATUS_SUCCESS);
3045 			if (QDF_STATUS_SUCCESS != qdf_status) {
3046 				sap_err("failed setting isCacEndNotified on interface[%d]",
3047 					 intf);
3048 				return qdf_status;
3049 			}
3050 			sap_context->isCacEndNotified = true;
3051 			sap_context->sap_radar_found_status = false;
3052 			sap_debug("sapdfs: Start beacon request on sapctx[%pK]",
3053 				  sap_context);
3054 
3055 			/* Start beaconing on the new channel */
3056 			wlansap_start_beacon_req(sap_context);
3057 
3058 			/* Transition from SAP_STARTING to SAP_STARTED
3059 			 * (both without substates)
3060 			 */
3061 			sap_context->fsm_state = SAP_STARTED;
3062 			sap_debug("sap_fsm: vdev %d: SAP_STARTING => SAP_STARTED, freq %d",
3063 				  sap_context->vdev_id, sap_context->chan_freq);
3064 
3065 			/*Action code for transition */
3066 			qdf_status = sap_signal_hdd_event(sap_context, roamInfo,
3067 							  eSAP_START_BSS_EVENT,
3068 							  (void *)
3069 							  eSAP_STATUS_SUCCESS);
3070 			if (QDF_STATUS_SUCCESS != qdf_status) {
3071 				sap_err("Failed setting isCacEndNotified on interface[%d]",
3072 					 intf);
3073 				return qdf_status;
3074 			}
3075 
3076 			/*
3077 			 * CAC wait prevent SAP restart, check if need
3078 			 * restart SAP after CAC end
3079 			 */
3080 			is_acs = sap_context->acs_cfg &&
3081 				 sap_context->acs_cfg->acs_mode;
3082 			policy_mgr_check_concurrent_intf_and_restart_sap(mac->psoc,
3083 									 is_acs);
3084 		}
3085 	}
3086 
3087 	return qdf_status;
3088 }
3089 
3090 /**
3091  * sap_validate_dfs_nol() - Validate SAP channel with NOL list
3092  * @sap_ctx: SAP context
3093  * @sap_ctx: MAC context
3094  *
3095  * Function will be called to validate SAP channel and bonded sub channels
3096  * included in DFS NOL or not.
3097  *
3098  * Return: QDF_STATUS_SUCCESS for NOT in NOL
3099  */
3100 static QDF_STATUS sap_validate_dfs_nol(struct sap_context *sap_ctx,
3101 				       struct mac_context *mac_ctx)
3102 {
3103 	bool b_leak_chan = false;
3104 	uint16_t temp_freq;
3105 	uint16_t sap_freq;
3106 	enum channel_state ch_state;
3107 	bool is_chan_nol = false;
3108 
3109 	sap_freq = sap_ctx->chan_freq;
3110 	temp_freq = sap_freq;
3111 	utils_dfs_mark_leaking_chan_for_freq(mac_ctx->pdev,
3112 					     sap_ctx->ch_params.ch_width, 1,
3113 					     &temp_freq);
3114 
3115 	/*
3116 	 * if selelcted channel has leakage to channels
3117 	 * in NOL, the temp_freq will be reset
3118 	 */
3119 	b_leak_chan = (temp_freq != sap_freq);
3120 	/*
3121 	 * check if channel is in DFS_NOL or if the channel
3122 	 * has leakage to the channels in NOL
3123 	 */
3124 
3125 	if (sap_phymode_is_eht(sap_ctx->phyMode)) {
3126 		ch_state =
3127 			wlan_reg_get_channel_state_from_secondary_list_for_freq(
3128 						mac_ctx->pdev, sap_freq);
3129 		if (CHANNEL_STATE_ENABLE != ch_state &&
3130 		    CHANNEL_STATE_DFS != ch_state) {
3131 			sap_err_rl("Invalid sap freq = %d, ch state=%d",
3132 				   sap_freq, ch_state);
3133 			is_chan_nol = true;
3134 		}
3135 	} else {
3136 		is_chan_nol = sap_dfs_is_channel_in_nol_list(
3137 					sap_ctx, sap_ctx->chan_freq,
3138 					PHY_CHANNEL_BONDING_STATE_MAX);
3139 	}
3140 
3141 	if (is_chan_nol || b_leak_chan) {
3142 		qdf_freq_t chan_freq;
3143 
3144 		/* find a new available channel */
3145 		chan_freq = sap_random_channel_sel(sap_ctx);
3146 		if (!chan_freq) {
3147 			/* No available channel found */
3148 			sap_err("No available channel found!!!");
3149 			sap_signal_hdd_event(sap_ctx, NULL,
3150 					     eSAP_DFS_NO_AVAILABLE_CHANNEL,
3151 					     (void *)eSAP_STATUS_SUCCESS);
3152 			return QDF_STATUS_E_FAULT;
3153 		}
3154 
3155 		sap_debug("ch_freq %d is in NOL, start bss on new freq %d",
3156 			  sap_ctx->chan_freq, chan_freq);
3157 
3158 		sap_ctx->chan_freq = chan_freq;
3159 		if (sap_phymode_is_eht(sap_ctx->phyMode))
3160 			wlan_reg_set_create_punc_bitmap(&sap_ctx->ch_params,
3161 							true);
3162 		wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev,
3163 							sap_ctx->chan_freq,
3164 							sap_ctx->sec_ch_freq,
3165 							&sap_ctx->ch_params,
3166 							REG_CURRENT_PWR_MODE);
3167 	}
3168 
3169 	return QDF_STATUS_SUCCESS;
3170 }
3171 
3172 static void sap_validate_chanmode_and_chwidth(struct mac_context *mac_ctx,
3173 					      struct sap_context *sap_ctx)
3174 {
3175 	uint32_t orig_phymode;
3176 	enum phy_ch_width orig_ch_width;
3177 
3178 	orig_ch_width = sap_ctx->ch_params.ch_width;
3179 	orig_phymode = sap_ctx->phyMode;
3180 
3181 	if (WLAN_REG_IS_5GHZ_CH_FREQ(sap_ctx->chan_freq) &&
3182 	    (sap_ctx->phyMode == eCSR_DOT11_MODE_11g ||
3183 	     sap_ctx->phyMode == eCSR_DOT11_MODE_11g_ONLY)) {
3184 		sap_ctx->phyMode = eCSR_DOT11_MODE_11a;
3185 	} else if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_ctx->chan_freq) &&
3186 		   (sap_ctx->phyMode == eCSR_DOT11_MODE_11a)) {
3187 		sap_ctx->phyMode = eCSR_DOT11_MODE_11g;
3188 	}
3189 
3190 	if (sap_ctx->ch_params.ch_width > CH_WIDTH_20MHZ &&
3191 	    (sap_ctx->phyMode == eCSR_DOT11_MODE_abg ||
3192 	     sap_ctx->phyMode == eCSR_DOT11_MODE_11a ||
3193 	     sap_ctx->phyMode == eCSR_DOT11_MODE_11g ||
3194 	     sap_ctx->phyMode == eCSR_DOT11_MODE_11b)) {
3195 		sap_ctx->ch_params.ch_width = CH_WIDTH_20MHZ;
3196 		wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev,
3197 					       sap_ctx->chan_freq,
3198 					       sap_ctx->ch_params.sec_ch_offset,
3199 					       &sap_ctx->ch_params,
3200 					       REG_CURRENT_PWR_MODE);
3201 	} else if (sap_ctx->ch_params.ch_width > CH_WIDTH_40MHZ &&
3202 		   sap_ctx->phyMode == eCSR_DOT11_MODE_11n) {
3203 		sap_ctx->ch_params.ch_width = CH_WIDTH_40MHZ;
3204 		wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev,
3205 					       sap_ctx->chan_freq,
3206 					       sap_ctx->ch_params.sec_ch_offset,
3207 					       &sap_ctx->ch_params,
3208 					       REG_CURRENT_PWR_MODE);
3209 	}
3210 
3211 	if (orig_ch_width != sap_ctx->ch_params.ch_width ||
3212 	    orig_phymode != sap_ctx->phyMode)
3213 		sap_info("Freq %d Updated BW %d -> %d , phymode %d -> %d",
3214 			 sap_ctx->chan_freq, orig_ch_width,
3215 			 sap_ctx->ch_params.ch_width,
3216 			 orig_phymode, sap_ctx->phyMode);
3217 }
3218 
3219 static bool
3220 wlansap_is_power_change_required(struct mac_context *mac_ctx,
3221 				 qdf_freq_t sap_freq)
3222 {
3223 	struct wlan_objmgr_vdev *sta_vdev;
3224 	uint8_t sta_vdev_id;
3225 	enum hw_mode_bandwidth ch_wd;
3226 	uint8_t country[CDS_COUNTRY_CODE_LEN + 1];
3227 	enum channel_state state;
3228 	uint32_t ap_pwr_type_6g = 0;
3229 	bool indoor_ch_support = false;
3230 
3231 	if (!mac_ctx || !mac_ctx->psoc || !mac_ctx->pdev)
3232 		return false;
3233 
3234 	if (!policy_mgr_is_sta_present_on_freq(mac_ctx->psoc, &sta_vdev_id,
3235 					       sap_freq, &ch_wd)) {
3236 		return false;
3237 	}
3238 
3239 	sta_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
3240 							sta_vdev_id,
3241 							WLAN_LEGACY_SAP_ID);
3242 	if (!sta_vdev)
3243 		return false;
3244 
3245 	ap_pwr_type_6g = wlan_mlme_get_6g_ap_power_type(sta_vdev);
3246 
3247 	wlan_objmgr_vdev_release_ref(sta_vdev, WLAN_LEGACY_SAP_ID);
3248 
3249 	if (ap_pwr_type_6g == REG_VERY_LOW_POWER_AP)
3250 		return false;
3251 	ucfg_mlme_get_indoor_channel_support(mac_ctx->psoc, &indoor_ch_support);
3252 
3253 	if (ap_pwr_type_6g == REG_INDOOR_AP && indoor_ch_support) {
3254 		sap_debug("STA is connected to Indoor AP and indoor concurrency is supported");
3255 		return false;
3256 	}
3257 
3258 	wlan_reg_read_current_country(mac_ctx->psoc, country);
3259 	if (!wlan_reg_ctry_support_vlp(country)) {
3260 		sap_debug("Device country doesn't support VLP");
3261 		return false;
3262 	}
3263 
3264 	state = wlan_reg_get_channel_state_for_pwrmode(mac_ctx->pdev,
3265 						       sap_freq, REG_AP_VLP);
3266 
3267 	return state & CHANNEL_STATE_ENABLE;
3268 }
3269 
3270 /**
3271  * sap_goto_starting() - Trigger softap start
3272  * @sap_ctx: SAP context
3273  * @sap_event: SAP event buffer
3274  * @mac_ctx: global MAC context
3275  * @mac_handle: Opaque handle to the global MAC context
3276  *
3277  * This function triggers start of softap. Before starting, it can select
3278  * new channel if given channel has leakage or if given channel in DFS_NOL.
3279  *
3280  * Return: QDF_STATUS
3281  */
3282 static QDF_STATUS sap_goto_starting(struct sap_context *sap_ctx,
3283 				    struct sap_sm_event *sap_event,
3284 				    struct mac_context *mac_ctx,
3285 				    mac_handle_t mac_handle)
3286 {
3287 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3288 	struct bss_dot11_config dot11_cfg = {0};
3289 	tSirMacRateSet *opr_rates = &sap_ctx->sap_bss_cfg.operationalRateSet;
3290 	tSirMacRateSet *ext_rates = &sap_ctx->sap_bss_cfg.extendedRateSet;
3291 	uint8_t h2e;
3292 
3293 	/*
3294 	 * check if channel is in DFS_NOL or if the channel
3295 	 * has leakage to the channels in NOL.
3296 	 */
3297 	if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ctx->chan_freq)) {
3298 		qdf_status = sap_validate_dfs_nol(sap_ctx, mac_ctx);
3299 		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
3300 			return qdf_status;
3301 	} else if (!policy_mgr_get_ap_6ghz_capable(mac_ctx->psoc,
3302 						   sap_ctx->sessionId, NULL)) {
3303 		return QDF_STATUS_E_FAILURE;
3304 	} else if (wlansap_is_power_change_required(mac_ctx,
3305 						    sap_ctx->chan_freq)) {
3306 		wlan_set_tpc_update_required_for_sta(sap_ctx->vdev, true);
3307 	}
3308 
3309 	/*
3310 	 * when AP2 is started while AP1 is performing ACS, we may not
3311 	 * have the AP1 channel yet.So here after the completion of AP2
3312 	 * ACS check if AP1 ACS resulting channel is DFS and if yes
3313 	 * override AP2 ACS scan result with AP1 DFS channel
3314 	 */
3315 	if (policy_mgr_concurrent_beaconing_sessions_running(mac_ctx->psoc)) {
3316 		uint32_t con_ch_freq;
3317 		uint16_t con_ch;
3318 
3319 		con_ch_freq = sme_get_beaconing_concurrent_operation_channel(
3320 				mac_handle, sap_ctx->sessionId);
3321 		con_ch = wlan_reg_freq_to_chan(mac_ctx->pdev, con_ch_freq);
3322 		/* Overwrite second AP's channel with first only when:
3323 		 * 1. If operating mode is single mac
3324 		 * 2. or if 2nd AP is coming up on 5G band channel
3325 		 */
3326 		if ((!policy_mgr_is_hw_dbs_capable(mac_ctx->psoc) ||
3327 		     WLAN_REG_IS_5GHZ_CH_FREQ(sap_ctx->chan_freq)) &&
3328 		     con_ch &&
3329 		     wlan_reg_is_dfs_for_freq(mac_ctx->pdev,
3330 					      con_ch_freq)) {
3331 			sap_ctx->chan_freq = con_ch_freq;
3332 			if (sap_phymode_is_eht(sap_ctx->phyMode))
3333 				wlan_reg_set_create_punc_bitmap(
3334 					&sap_ctx->ch_params, true);
3335 			wlan_reg_set_channel_params_for_pwrmode(
3336 						    mac_ctx->pdev,
3337 						    con_ch_freq, 0,
3338 						    &sap_ctx->ch_params,
3339 						    REG_CURRENT_PWR_MODE);
3340 		}
3341 	}
3342 
3343 	sap_validate_chanmode_and_chwidth(mac_ctx, sap_ctx);
3344 	/* Channel selected. Now can sap_goto_starting */
3345 	sap_ctx->fsm_state = SAP_STARTING;
3346 	sap_debug("sap_fsm: vdev %d: SAP_INIT => SAP_STARTING, phyMode %d bw %d",
3347 		  sap_ctx->vdev_id, sap_ctx->phyMode,
3348 		  sap_ctx->ch_params.ch_width);
3349 	/* Specify the channel */
3350 	sap_get_cac_dur_dfs_region(sap_ctx,
3351 				   &sap_ctx->sap_bss_cfg.cac_duration_ms,
3352 				   &sap_ctx->sap_bss_cfg.dfs_regdomain,
3353 				   sap_ctx->chan_freq,
3354 				   &sap_ctx->ch_params);
3355 	mlme_set_cac_required(sap_ctx->vdev,
3356 			      !!sap_ctx->sap_bss_cfg.cac_duration_ms);
3357 
3358 	sap_ctx->sap_bss_cfg.oper_ch_freq = sap_ctx->chan_freq;
3359 	sap_ctx->sap_bss_cfg.vht_channel_width = sap_ctx->ch_params.ch_width;
3360 	sap_ctx->sap_bss_cfg.center_freq_seg0 =
3361 					sap_ctx->ch_params.center_freq_seg0;
3362 	sap_ctx->sap_bss_cfg.center_freq_seg1 =
3363 					sap_ctx->ch_params.center_freq_seg1;
3364 	sap_ctx->sap_bss_cfg.sec_ch_offset = sap_ctx->ch_params.sec_ch_offset;
3365 
3366 	dot11_cfg.vdev_id = sap_ctx->sessionId;
3367 	dot11_cfg.bss_op_ch_freq = sap_ctx->chan_freq;
3368 	dot11_cfg.phy_mode = sap_ctx->phyMode;
3369 	dot11_cfg.privacy = sap_ctx->sap_bss_cfg.privacy;
3370 
3371 	qdf_mem_copy(dot11_cfg.opr_rates.rate,
3372 		     opr_rates->rate, opr_rates->numRates);
3373 	dot11_cfg.opr_rates.numRates = opr_rates->numRates;
3374 
3375 	qdf_mem_copy(dot11_cfg.ext_rates.rate,
3376 		     ext_rates->rate, ext_rates->numRates);
3377 	dot11_cfg.ext_rates.numRates = ext_rates->numRates;
3378 
3379 	sme_get_network_params(mac_ctx, &dot11_cfg);
3380 
3381 	sap_ctx->sap_bss_cfg.nwType = dot11_cfg.nw_type;
3382 	sap_ctx->sap_bss_cfg.dot11mode = dot11_cfg.dot11_mode;
3383 
3384 	if (dot11_cfg.opr_rates.numRates) {
3385 		qdf_mem_copy(opr_rates->rate,
3386 			     dot11_cfg.opr_rates.rate,
3387 			     dot11_cfg.opr_rates.numRates);
3388 		opr_rates->numRates = dot11_cfg.opr_rates.numRates;
3389 	} else {
3390 		qdf_mem_zero(opr_rates, sizeof(tSirMacRateSet));
3391 	}
3392 
3393 	if (dot11_cfg.ext_rates.numRates) {
3394 		qdf_mem_copy(ext_rates->rate,
3395 			     dot11_cfg.ext_rates.rate,
3396 			     dot11_cfg.ext_rates.numRates);
3397 		ext_rates->numRates = dot11_cfg.ext_rates.numRates;
3398 	} else {
3399 		qdf_mem_zero(ext_rates, sizeof(tSirMacRateSet));
3400 	}
3401 
3402 	if (sap_ctx->require_h2e) {
3403 		h2e = WLAN_BASIC_RATE_MASK |
3404 			WLAN_BSS_MEMBERSHIP_SELECTOR_SAE_H2E;
3405 		if (ext_rates->numRates < SIR_MAC_MAX_NUMBER_OF_RATES) {
3406 			ext_rates->rate[ext_rates->numRates] = h2e;
3407 			ext_rates->numRates++;
3408 			sap_debug("H2E bss membership add to ext support rate");
3409 		} else if (opr_rates->numRates < SIR_MAC_MAX_NUMBER_OF_RATES) {
3410 			opr_rates->rate[opr_rates->numRates] = h2e;
3411 			opr_rates->numRates++;
3412 			sap_debug("H2E bss membership add to support rate");
3413 		} else {
3414 			sap_err("rates full, can not add H2E bss membership");
3415 		}
3416 	}
3417 	sap_dfs_set_current_channel(sap_ctx);
3418 	/* Reset radar found flag before start sap, the flag will
3419 	 * be set when radar found in CAC wait.
3420 	 */
3421 	sap_ctx->sap_radar_found_status = false;
3422 
3423 	sap_debug("session: %d", sap_ctx->sessionId);
3424 
3425 	qdf_status = sme_start_bss(mac_handle, sap_ctx->sessionId,
3426 				   &sap_ctx->sap_bss_cfg);
3427 	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
3428 		sap_err("Failed to issue sme_roam_connect");
3429 
3430 	return qdf_status;
3431 }
3432 
3433 /**
3434  * sap_fsm_cac_start() - start cac wait timer
3435  * @sap_ctx: SAP context
3436  * @mac_ctx: global MAC context
3437  * @mac_handle: Opaque handle to the global MAC context
3438  *
3439  * Return: QDF_STATUS
3440  */
3441 static QDF_STATUS sap_fsm_cac_start(struct sap_context *sap_ctx,
3442 				    struct mac_context *mac_ctx,
3443 				    mac_handle_t mac_handle)
3444 {
3445 	if (!mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) {
3446 		sap_debug("sapdfs: starting dfs cac timer on sapctx[%pK]",
3447 			  sap_ctx);
3448 		sap_start_dfs_cac_timer(sap_ctx);
3449 	}
3450 
3451 	return sap_cac_start_notify(mac_handle);
3452 }
3453 
3454 /**
3455  * sap_fsm_state_init() - utility function called from sap fsm
3456  * @sap_ctx: SAP context
3457  * @sap_event: SAP event buffer
3458  * @mac_ctx: global MAC context
3459  * @mac_handle: Opaque handle to the global MAC context
3460  *
3461  * This function is called for state transition from "SAP_INIT"
3462  *
3463  * Return: QDF_STATUS
3464  */
3465 static QDF_STATUS sap_fsm_state_init(struct sap_context *sap_ctx,
3466 				     struct sap_sm_event *sap_event,
3467 				     struct mac_context *mac_ctx,
3468 				     mac_handle_t mac_handle)
3469 {
3470 	uint32_t msg = sap_event->event;
3471 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3472 
3473 	if (msg == eSAP_HDD_START_INFRA_BSS) {
3474 		/* init dfs channel nol */
3475 		sap_init_dfs_channel_nol_list(sap_ctx);
3476 
3477 		/*
3478 		 * Perform sme_ScanRequest. This scan request is post start bss
3479 		 * request so, set the third to false.
3480 		 */
3481 		qdf_status = sap_validate_chan(sap_ctx, false, true);
3482 		if (QDF_IS_STATUS_ERROR(qdf_status)) {
3483 			sap_err("vdev %d: channel is not valid!",
3484 				sap_ctx->vdev_id);
3485 			goto exit;
3486 		}
3487 
3488 		qdf_status = sap_goto_starting(sap_ctx, sap_event,
3489 					       mac_ctx, mac_handle);
3490 		if (QDF_IS_STATUS_ERROR(qdf_status))
3491 			sap_err("vdev %d: sap_goto_starting failed",
3492 				sap_ctx->vdev_id);
3493 	} else {
3494 		sap_err("sap_fsm: vdev %d: SAP_INIT, invalid event %d",
3495 			sap_ctx->vdev_id, msg);
3496 	}
3497 
3498 exit:
3499 	return qdf_status;
3500 }
3501 
3502 /**
3503  * sap_fsm_handle_radar_during_cac() - uhandle radar event during cac
3504  * @sap_ctx: SAP context
3505  * @mac_ctx: global MAC context
3506  *
3507  * Return: QDF_STATUS
3508  */
3509 static QDF_STATUS sap_fsm_handle_radar_during_cac(struct sap_context *sap_ctx,
3510 						  struct mac_context *mac_ctx)
3511 {
3512 	uint8_t intf;
3513 
3514 	if (mac_ctx->sap.SapDfsInfo.target_chan_freq) {
3515 		if (sap_phymode_is_eht(sap_ctx->phyMode))
3516 			wlan_reg_set_create_punc_bitmap(&sap_ctx->ch_params,
3517 							true);
3518 		wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev,
3519 				    mac_ctx->sap.SapDfsInfo.target_chan_freq, 0,
3520 				    &sap_ctx->ch_params, REG_CURRENT_PWR_MODE);
3521 	} else {
3522 		sap_err("Invalid target channel freq %d",
3523 			 mac_ctx->sap.SapDfsInfo.target_chan_freq);
3524 		return QDF_STATUS_E_FAILURE;
3525 	}
3526 
3527 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
3528 		struct sap_context *t_sap_ctx;
3529 
3530 		t_sap_ctx = mac_ctx->sap.sapCtxList[intf].sap_context;
3531 		if (((QDF_SAP_MODE ==
3532 		      mac_ctx->sap.sapCtxList[intf].sapPersona) ||
3533 		     (QDF_P2P_GO_MODE ==
3534 		      mac_ctx->sap.sapCtxList[intf].sapPersona)) &&
3535 		    t_sap_ctx && t_sap_ctx->fsm_state != SAP_INIT) {
3536 			if (!sap_operating_on_dfs(mac_ctx, t_sap_ctx))
3537 				continue;
3538 			t_sap_ctx->is_chan_change_inprogress = true;
3539 			/*
3540 			 * eSAP_DFS_CHANNEL_CAC_RADAR_FOUND:
3541 			 * A Radar is found on current DFS Channel
3542 			 * while in CAC WAIT period So, do a channel
3543 			 * switch to randomly selected	target channel.
3544 			 * Send the Channel change message to SME/PE.
3545 			 * sap_radar_found_status is set to 1
3546 			 */
3547 			wlansap_channel_change_request(t_sap_ctx,
3548 				mac_ctx->sap.SapDfsInfo.target_chan_freq);
3549 		}
3550 	}
3551 
3552 	return QDF_STATUS_SUCCESS;
3553 }
3554 
3555 /**
3556  * sap_fsm_handle_start_failure() - handle sap start failure
3557  * @sap_ctx: SAP context
3558  * @msg: event msg
3559  * @mac_handle: Opaque handle to the global MAC context
3560  *
3561  * Return: QDF_STATUS
3562  */
3563 static QDF_STATUS sap_fsm_handle_start_failure(struct sap_context *sap_ctx,
3564 					       uint32_t msg,
3565 					       mac_handle_t mac_handle)
3566 {
3567 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3568 
3569 	if (msg == eSAP_HDD_STOP_INFRA_BSS) {
3570 		/*
3571 		 * Stop the CAC timer only in following conditions
3572 		 * single AP: if there is a single AP then stop timer
3573 		 * multiple APs: incase of multiple APs, make sure that
3574 		 * all APs are down.
3575 		 */
3576 		if (!sap_find_valid_concurrent_session(mac_handle)) {
3577 			sap_debug("sapdfs: no sessions are valid, stopping timer");
3578 			sap_stop_dfs_cac_timer(sap_ctx);
3579 		}
3580 		/* Transition from SAP_STARTING to SAP_STOPPING */
3581 		sap_ctx->fsm_state = SAP_STOPPING;
3582 		sap_debug("sap_fsm: vdev %d: SAP_STARTING => SAP_STOPPING, start is in progress",
3583 			  sap_ctx->vdev_id);
3584 		qdf_status = sap_goto_stopping(sap_ctx);
3585 	} else {
3586 		/*
3587 		 * Transition from SAP_STARTING to SAP_INIT
3588 		 * (both without substates)
3589 		 */
3590 		sap_ctx->fsm_state = SAP_INIT;
3591 		sap_debug("sap_fsm: vdev %d: SAP_STARTING => SAP_INIT",
3592 			  sap_ctx->vdev_id);
3593 		qdf_status = sap_signal_hdd_event(sap_ctx, NULL,
3594 						  eSAP_START_BSS_EVENT,
3595 						  (void *)
3596 						  eSAP_STATUS_FAILURE);
3597 		qdf_status = sap_goto_init(sap_ctx);
3598 	}
3599 
3600 	return qdf_status;
3601 }
3602 
3603 /**
3604  * sap_propagate_cac_events() - Indicate CAC START/END event
3605  * @sap_ctx: SAP context
3606  *
3607  * This function is to indicate CAC START/END event if CAC process
3608  * is skipped.
3609  *
3610  * Return: void
3611  */
3612 static void sap_propagate_cac_events(struct sap_context *sap_ctx)
3613 {
3614 	QDF_STATUS qdf_status;
3615 
3616 	qdf_status = sap_signal_hdd_event(sap_ctx, NULL,
3617 					  eSAP_DFS_CAC_START,
3618 					  (void *)
3619 					  eSAP_STATUS_SUCCESS);
3620 	if (qdf_status != QDF_STATUS_SUCCESS) {
3621 		sap_err("Failed to indicate CAC START vdev %d",
3622 			sap_ctx->sessionId);
3623 		return;
3624 	}
3625 
3626 	qdf_status = sap_signal_hdd_event(sap_ctx, NULL,
3627 					  eSAP_DFS_CAC_END,
3628 					  (void *)
3629 					  eSAP_STATUS_SUCCESS);
3630 	if (qdf_status != QDF_STATUS_SUCCESS) {
3631 		sap_debug("Failed to indicate CAC End vdev %d",
3632 			  sap_ctx->sessionId);
3633 	}
3634 }
3635 
3636 static void sap_check_and_update_vdev_ch_params(struct sap_context *sap_ctx)
3637 {
3638 	struct wlan_channel *chan;
3639 	enum phy_ch_width orig_ch_width;
3640 
3641 	chan = wlan_vdev_get_active_channel(sap_ctx->vdev);
3642 	if (!chan) {
3643 		sap_debug("Couldn't get vdev active channel");
3644 		return;
3645 	}
3646 	if (sap_ctx->ch_params.ch_width == chan->ch_width)
3647 		return;
3648 
3649 	orig_ch_width = sap_ctx->ch_params.ch_width;
3650 
3651 	sap_ctx->ch_params.ch_width = chan->ch_width;
3652 	sap_ctx->ch_params.center_freq_seg0 = chan->ch_freq_seg1;
3653 	sap_ctx->ch_params.center_freq_seg1 = chan->ch_freq_seg2;
3654 	sap_ctx->ch_params.mhz_freq_seg0 = chan->ch_cfreq1;
3655 	sap_ctx->ch_params.mhz_freq_seg1 = chan->ch_cfreq2;
3656 
3657 	if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_ctx->chan_freq) &&
3658 	    (chan->ch_width == CH_WIDTH_40MHZ)) {
3659 		if (sap_ctx->chan_freq < chan->ch_freq_seg1)
3660 			sap_ctx->ch_params.sec_ch_offset = LOW_PRIMARY_CH;
3661 		else
3662 			sap_ctx->ch_params.sec_ch_offset = HIGH_PRIMARY_CH;
3663 	}
3664 	sap_debug("updated BW %d -> %d", orig_ch_width,
3665 		  sap_ctx->ch_params.ch_width);
3666 }
3667 
3668 static qdf_freq_t sap_get_safe_channel_freq(struct sap_context *sap_ctx)
3669 {
3670 	qdf_freq_t freq;
3671 
3672 	freq = wlan_pre_cac_get_freq_before_pre_cac(sap_ctx->vdev);
3673 	if (!freq)
3674 		freq = wlansap_get_safe_channel_from_pcl_and_acs_range(
3675 								sap_ctx,
3676 								NULL);
3677 
3678 	sap_debug("new selected freq %d as target chan as current freq unsafe %d",
3679 		  freq, sap_ctx->chan_freq);
3680 
3681 	return freq;
3682 }
3683 
3684 /**
3685  * sap_fsm_send_csa_restart_req() - send csa start event
3686  * @mac_ctx: mac ctx
3687  * @sap_ctx: SAP context
3688  *
3689  * Return: QDF_STATUS
3690  */
3691 static inline QDF_STATUS
3692 sap_fsm_send_csa_restart_req(struct mac_context *mac_ctx,
3693 			     struct sap_context *sap_ctx)
3694 {
3695 	QDF_STATUS status;
3696 
3697 	status = policy_mgr_check_and_set_hw_mode_for_channel_switch(
3698 				mac_ctx->psoc, sap_ctx->sessionId,
3699 				mac_ctx->sap.SapDfsInfo.target_chan_freq,
3700 				POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_SAP);
3701 
3702 	/*
3703 	 * If hw_mode_status is QDF_STATUS_E_FAILURE, mean HW
3704 	 * mode change was required but driver failed to set HW
3705 	 * mode so ignore CSA for the channel.
3706 	 */
3707 	if (status == QDF_STATUS_E_FAILURE) {
3708 		sap_err("HW change required but failed to set hw mode");
3709 		return status;
3710 	}
3711 
3712 	/*
3713 	 * If hw_mode_status is QDF_STATUS_SUCCESS mean HW mode
3714 	 * change was required and was successfully requested so
3715 	 * the channel switch will continue after HW mode change
3716 	 * completion.
3717 	 */
3718 	if (QDF_IS_STATUS_SUCCESS(status)) {
3719 		sap_info("Channel change will continue after HW mode change");
3720 		return QDF_STATUS_SUCCESS;
3721 	}
3722 
3723 	return sme_csa_restart(mac_ctx, sap_ctx->sessionId);
3724 }
3725 
3726 /**
3727  * sap_fsm_validate_and_change_channel() - handle channel Avoid event event
3728  *                                         or channel list update during cac
3729  * @mac_ctx: global MAC context
3730  *
3731  * Return: QDF_STATUS
3732  */
3733 static void sap_fsm_validate_and_change_channel(struct mac_context *mac_ctx,
3734 						struct sap_context *sap_ctx)
3735 {
3736 	qdf_freq_t target_chan_freq;
3737 	struct ch_params ch_params = {0};
3738 	QDF_STATUS status;
3739 	enum phy_ch_width target_bw = sap_ctx->ch_params.ch_width;
3740 
3741 	if (((!sap_ctx->acs_cfg || !sap_ctx->acs_cfg->acs_mode) &&
3742 	     (!policy_mgr_restrict_sap_on_unsafe_chan(mac_ctx->psoc) ||
3743 	      target_psoc_get_sap_coex_fixed_chan_cap(
3744 		      wlan_psoc_get_tgt_if_handle(mac_ctx->psoc)))) ||
3745 	    (policy_mgr_is_sap_freq_allowed(mac_ctx->psoc, sap_ctx->chan_freq) &&
3746 	     !wlan_reg_is_disable_for_pwrmode(mac_ctx->pdev, sap_ctx->chan_freq,
3747 					      REG_CURRENT_PWR_MODE)))
3748 		return;
3749 
3750 	/*
3751 	 * The selected channel is not safe channel. Hence,
3752 	 * change the sap channel to a safe channel.
3753 	 */
3754 	target_chan_freq = sap_get_safe_channel_freq(sap_ctx);
3755 	ch_params.ch_width = target_bw;
3756 	target_bw = wlansap_get_csa_chanwidth_from_phymode(
3757 			sap_ctx, target_chan_freq, &ch_params);
3758 	sap_debug("sap vdev %d change to safe ch freq %d bw %d from unsafe %d",
3759 		  sap_ctx->sessionId, target_chan_freq, target_bw,
3760 		  sap_ctx->chan_freq);
3761 	status = wlansap_set_channel_change_with_csa(
3762 			sap_ctx, target_chan_freq, target_bw, false);
3763 	if (QDF_IS_STATUS_ERROR(status))
3764 		sap_err("SAP set channel failed for freq: %d, bw: %d",
3765 			target_chan_freq, target_bw);
3766 }
3767 
3768 /**
3769  * sap_fsm_state_starting() - utility function called from sap fsm
3770  * @sap_ctx: SAP context
3771  * @sap_event: SAP event buffer
3772  * @mac_ctx: global MAC context
3773  * @mac_handle: Opaque handle to the global MAC context
3774  *
3775  * This function is called for state transition from "SAP_STARTING"
3776  *
3777  * Return: QDF_STATUS
3778  */
3779 static QDF_STATUS sap_fsm_state_starting(struct sap_context *sap_ctx,
3780 					 struct sap_sm_event *sap_event,
3781 					 struct mac_context *mac_ctx,
3782 					 mac_handle_t mac_handle)
3783 {
3784 	uint32_t msg = sap_event->event;
3785 	struct csr_roam_info *roam_info =
3786 		(struct csr_roam_info *) (sap_event->params);
3787 	tSapDfsInfo *sap_dfs_info;
3788 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3789 	uint8_t is_dfs = false;
3790 	uint32_t sap_chan_freq;
3791 	uint32_t ch_cfreq1 = 0;
3792 	enum reg_wifi_band band;
3793 	eSapDfsCACState_t cac_state = eSAP_DFS_DO_NOT_SKIP_CAC;
3794 
3795 	if (msg == eSAP_MAC_START_BSS_SUCCESS) {
3796 		/*
3797 		 * Update sap_ctx->ch_params from vdev to make up with any BW
3798 		 * change in lower layer
3799 		 */
3800 		sap_check_and_update_vdev_ch_params(sap_ctx);
3801 
3802 		/*
3803 		 * Transition from SAP_STARTING to SAP_STARTED
3804 		 * (both without substates)
3805 		 */
3806 		sap_ctx->fsm_state = SAP_STARTED;
3807 		sap_debug("sap_fsm: vdev %d: SAP_STARTING => SAP_STARTED, freq %d ch_width %d",
3808 			  sap_ctx->vdev_id, sap_ctx->chan_freq,
3809 			  sap_ctx->ch_params.ch_width);
3810 
3811 		if (sap_ctx->is_chan_change_inprogress) {
3812 			/* SAP channel change request processing is completed */
3813 			qdf_status = sap_signal_hdd_event(sap_ctx, roam_info,
3814 						eSAP_CHANNEL_CHANGE_EVENT,
3815 						(void *)eSAP_STATUS_SUCCESS);
3816 			sap_ctx->is_chan_change_inprogress = false;
3817 		} else {
3818 			sap_debug("vdev %d notify hostapd about chan freq selection: %d",
3819 				  sap_ctx->vdev_id, sap_ctx->chan_freq);
3820 			qdf_status =
3821 				sap_signal_hdd_event(sap_ctx, roam_info,
3822 						     eSAP_CHANNEL_CHANGE_EVENT,
3823 						     (void *)eSAP_STATUS_SUCCESS);
3824 			/* Action code for transition */
3825 			qdf_status = sap_signal_hdd_event(sap_ctx, roam_info,
3826 					eSAP_START_BSS_EVENT,
3827 					(void *) eSAP_STATUS_SUCCESS);
3828 		}
3829 		sap_chan_freq = sap_ctx->chan_freq;
3830 		band = wlan_reg_freq_to_band(sap_ctx->chan_freq);
3831 		if (sap_ctx->ch_params.center_freq_seg1)
3832 			ch_cfreq1 = wlan_reg_chan_band_to_freq(
3833 					mac_ctx->pdev,
3834 					sap_ctx->ch_params.center_freq_seg1,
3835 					BIT(band));
3836 
3837 		/*
3838 		 * The upper layers have been informed that AP is up and
3839 		 * running, however, the AP is still not beaconing, until
3840 		 * CAC is done if the operating channel is DFS
3841 		 */
3842 		if (sap_ctx->ch_params.ch_width == CH_WIDTH_160MHZ) {
3843 			struct ch_params ch_params = {0};
3844 
3845 			wlan_reg_set_create_punc_bitmap(&ch_params, true);
3846 			ch_params.ch_width = CH_WIDTH_160MHZ;
3847 			is_dfs =
3848 			wlan_reg_get_5g_bonded_channel_state_for_pwrmode(mac_ctx->pdev,
3849 									 sap_chan_freq,
3850 									 &ch_params,
3851 									 REG_CURRENT_PWR_MODE) ==
3852 			CHANNEL_STATE_DFS;
3853 		} else if (sap_ctx->ch_params.ch_width == CH_WIDTH_80P80MHZ) {
3854 			if (wlan_reg_get_channel_state_for_pwrmode(
3855 							mac_ctx->pdev,
3856 							sap_chan_freq,
3857 							REG_CURRENT_PWR_MODE) ==
3858 			    CHANNEL_STATE_DFS ||
3859 			    wlan_reg_get_channel_state_for_pwrmode(
3860 							mac_ctx->pdev,
3861 							ch_cfreq1,
3862 							REG_CURRENT_PWR_MODE) ==
3863 					CHANNEL_STATE_DFS)
3864 				is_dfs = true;
3865 		} else {
3866 			/* Indoor channels are also marked DFS, therefore
3867 			 * check if the channel has REGULATORY_CHAN_RADAR
3868 			 * channel flag to identify if the channel is DFS
3869 			 */
3870 			if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev,
3871 						     sap_chan_freq))
3872 				is_dfs = true;
3873 		}
3874 		if (WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ctx->chan_freq))
3875 			is_dfs = false;
3876 
3877 		sap_debug("vdev %d freq %d, is_dfs %d", sap_ctx->vdev_id,
3878 			  sap_ctx->chan_freq, is_dfs);
3879 		if (is_dfs) {
3880 			sap_dfs_info = &mac_ctx->sap.SapDfsInfo;
3881 			if (sap_plus_sap_cac_skip(mac_ctx, sap_ctx,
3882 						  sap_chan_freq))
3883 				cac_state = eSAP_DFS_SKIP_CAC;
3884 			if ((false == sap_dfs_info->ignore_cac) &&
3885 			    (cac_state == eSAP_DFS_DO_NOT_SKIP_CAC) &&
3886 			    !wlan_pre_cac_complete_get(sap_ctx->vdev) &&
3887 			    policy_mgr_get_dfs_master_dynamic_enabled(
3888 					mac_ctx->psoc,
3889 					sap_ctx->sessionId)) {
3890 				sap_ctx->fsm_state = SAP_STARTING;
3891 				sap_debug("sap_fsm: vdev %d: SAP_STARTED => SAP_STARTING to start cac timer",
3892 					  sap_ctx->vdev_id);
3893 				qdf_status = sap_fsm_cac_start(sap_ctx, mac_ctx,
3894 							       mac_handle);
3895 			} else {
3896 				sap_debug("vdev %d skip cac timer",
3897 					  sap_ctx->vdev_id);
3898 				sap_ctx->sap_radar_found_status = false;
3899 				/*
3900 				 * If hostapd starts AP on dfs channel,
3901 				 * hostapd will wait for CAC START/CAC END
3902 				 * event and finish AP start process.
3903 				 * If we skip CAC timer, we will need to
3904 				 * indicate the CAC event even though driver
3905 				 * doesn't perform CAC.
3906 				 */
3907 				sap_propagate_cac_events(sap_ctx);
3908 
3909 				wlansap_start_beacon_req(sap_ctx);
3910 			}
3911 		}
3912 		/*
3913 		 * During CSA, it might be possible that ch avoidance event to
3914 		 * avoid the sap frequency is received. So, check after CSA,
3915 		 * whether sap frequency is safe if not restart sap to a safe
3916 		 * channel.
3917 		 */
3918 		sap_fsm_validate_and_change_channel(mac_ctx, sap_ctx);
3919 	} else if (msg == eSAP_MAC_START_FAILS ||
3920 		 msg == eSAP_HDD_STOP_INFRA_BSS) {
3921 			qdf_status = sap_fsm_handle_start_failure(sap_ctx, msg,
3922 								  mac_handle);
3923 	} else if (msg == eSAP_OPERATING_CHANNEL_CHANGED) {
3924 		/* The operating channel has changed, update hostapd */
3925 		sap_ctx->chan_freq = mac_ctx->sap.SapDfsInfo.target_chan_freq;
3926 
3927 		sap_ctx->fsm_state = SAP_STARTED;
3928 		sap_debug("sap_fsm: vdev %d: SAP_STARTING => SAP_STARTED",
3929 			  sap_ctx->vdev_id);
3930 
3931 		/* Indicate change in the state to upper layers */
3932 		qdf_status = sap_signal_hdd_event(sap_ctx, roam_info,
3933 				  eSAP_START_BSS_EVENT,
3934 				  (void *)eSAP_STATUS_SUCCESS);
3935 	} else if (msg == eSAP_DFS_CHANNEL_CAC_RADAR_FOUND) {
3936 		qdf_status = sap_fsm_handle_radar_during_cac(sap_ctx, mac_ctx);
3937 	} else if (msg == eSAP_DFS_CHANNEL_CAC_END) {
3938 		if (sap_ctx->vdev &&
3939 		    wlan_util_vdev_mgr_get_cac_timeout_for_vdev(sap_ctx->vdev)) {
3940 			qdf_status = sap_cac_end_notify(mac_handle, roam_info);
3941 		} else {
3942 			sap_debug("vdev %d cac duration is zero",
3943 				  sap_ctx->vdev_id);
3944 			qdf_status = QDF_STATUS_SUCCESS;
3945 		}
3946 	} else if (msg == eSAP_DFS_CHANNEL_CAC_START) {
3947 		if (sap_ctx->is_chan_change_inprogress) {
3948 			sap_signal_hdd_event(sap_ctx,
3949 					     NULL,
3950 					     eSAP_CHANNEL_CHANGE_EVENT,
3951 					     (void *)eSAP_STATUS_SUCCESS);
3952 			sap_ctx->is_chan_change_inprogress = false;
3953 		}
3954 		qdf_status = sap_fsm_cac_start(sap_ctx, mac_ctx, mac_handle);
3955 	} else {
3956 		sap_err("sap_fsm: vdev %d: SAP_STARTING, invalid event %d",
3957 			sap_ctx->vdev_id, msg);
3958 	}
3959 
3960 	return qdf_status;
3961 }
3962 
3963 /**
3964  * sap_fsm_state_started() - utility function called from sap fsm
3965  * @sap_ctx: SAP context
3966  * @sap_event: SAP event buffer
3967  * @mac_ctx: global MAC context
3968  *
3969  * This function is called for state transition from "SAP_STARTED"
3970  *
3971  * Return: QDF_STATUS
3972  */
3973 static QDF_STATUS sap_fsm_state_started(struct sap_context *sap_ctx,
3974 					struct sap_sm_event *sap_event,
3975 					struct mac_context *mac_ctx)
3976 {
3977 	uint32_t msg = sap_event->event;
3978 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3979 
3980 	if (msg == eSAP_HDD_STOP_INFRA_BSS) {
3981 		/*
3982 		 * Transition from SAP_STARTED to SAP_STOPPING
3983 		 * (both without substates)
3984 		 */
3985 		sap_ctx->fsm_state = SAP_STOPPING;
3986 		sap_debug("sap_fsm: vdev %d: SAP_STARTED => SAP_STOPPING",
3987 			  sap_ctx->vdev_id);
3988 		qdf_status = sap_goto_stopping(sap_ctx);
3989 	} else if (eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START == msg) {
3990 		uint8_t intf;
3991 		if (!mac_ctx->sap.SapDfsInfo.target_chan_freq) {
3992 			sap_err("Invalid target channel freq %d",
3993 				mac_ctx->sap.SapDfsInfo.target_chan_freq);
3994 			return qdf_status;
3995 		}
3996 
3997 		/*
3998 		 * Radar is seen on the current operating channel
3999 		 * send CSA IE for all associated stations
4000 		 * Request for CSA IE transmission
4001 		 */
4002 		for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
4003 			struct sap_context *temp_sap_ctx;
4004 
4005 			if (((QDF_SAP_MODE ==
4006 				mac_ctx->sap.sapCtxList[intf].sapPersona) ||
4007 			    (QDF_P2P_GO_MODE ==
4008 				mac_ctx->sap.sapCtxList[intf].sapPersona)) &&
4009 			    mac_ctx->sap.sapCtxList[intf].sap_context) {
4010 				temp_sap_ctx =
4011 				    mac_ctx->sap.sapCtxList[intf].sap_context;
4012 				/*
4013 				 * Radar won't come on non-dfs channel, so
4014 				 * no need to move them
4015 				 */
4016 				if (!sap_operating_on_dfs(
4017 						mac_ctx, temp_sap_ctx)) {
4018 					sap_debug("vdev %d freq %d (state %d) is not DFS or disabled so continue",
4019 						  temp_sap_ctx->sessionId,
4020 						  temp_sap_ctx->chan_freq,
4021 						  wlan_reg_get_channel_state_for_pwrmode(
4022 						  mac_ctx->pdev,
4023 						  temp_sap_ctx->chan_freq,
4024 						  REG_CURRENT_PWR_MODE));
4025 					continue;
4026 				}
4027 				sap_debug("vdev %d switch freq %d -> %d",
4028 					  temp_sap_ctx->sessionId,
4029 					  temp_sap_ctx->chan_freq,
4030 					  mac_ctx->sap.SapDfsInfo.target_chan_freq);
4031 				qdf_status =
4032 				   sap_fsm_send_csa_restart_req(mac_ctx,
4033 								temp_sap_ctx);
4034 			}
4035 		}
4036 	} else {
4037 		sap_err("sap_fsm: vdev %d: SAP_STARTED, invalid event %d",
4038 			sap_ctx->vdev_id, msg);
4039 	}
4040 
4041 	return qdf_status;
4042 }
4043 
4044 /**
4045  * sap_fsm_state_stopping() - utility function called from sap fsm
4046  * @sap_ctx: SAP context
4047  * @sap_event: SAP event buffer
4048  * @mac_ctx: global MAC context
4049  *
4050  * This function is called for state transition from "SAP_STOPPING"
4051  *
4052  * Return: QDF_STATUS
4053  */
4054 static QDF_STATUS
4055 sap_fsm_state_stopping(struct sap_context *sap_ctx,
4056 		       struct sap_sm_event *sap_event,
4057 		       struct mac_context *mac_ctx,
4058 		       mac_handle_t mac_handle)
4059 {
4060 	uint32_t msg = sap_event->event;
4061 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
4062 
4063 	if (msg == eSAP_MAC_READY_FOR_CONNECTIONS) {
4064 		/*
4065 		 * Transition from SAP_STOPPING to SAP_INIT
4066 		 * (both without substates)
4067 		 */
4068 		sap_ctx->fsm_state = SAP_INIT;
4069 		sap_debug("sap_fsm: vdev %d: SAP_STOPPING => SAP_INIT",
4070 			  sap_ctx->vdev_id);
4071 
4072 		/* Close the SME session */
4073 		qdf_status = sap_signal_hdd_event(sap_ctx, NULL,
4074 					eSAP_STOP_BSS_EVENT,
4075 					(void *)eSAP_STATUS_SUCCESS);
4076 	} else if (msg == eSAP_HDD_STOP_INFRA_BSS) {
4077 		/*
4078 		 * In case the SAP is already in stopping case and
4079 		 * we get a STOP request, return success.
4080 		 */
4081 		sap_debug("vdev %d SAP already in Stopping state",
4082 			  sap_ctx->vdev_id);
4083 		qdf_status = QDF_STATUS_SUCCESS;
4084 	} else {
4085 		sap_err("sap_fsm: vdev %d: SAP_STOPPING, invalid event %d",
4086 			sap_ctx->vdev_id, msg);
4087 	}
4088 
4089 	return qdf_status;
4090 }
4091 
4092 /**
4093  * sap_fsm() - SAP statem machine entry function
4094  * @sap_ctx: SAP context
4095  * @sap_event: SAP event
4096  *
4097  * SAP state machine entry function
4098  *
4099  * Return: QDF_STATUS
4100  */
4101 QDF_STATUS sap_fsm(struct sap_context *sap_ctx, struct sap_sm_event *sap_event)
4102 {
4103 	/*
4104 	 * Retrieve the phy link state machine structure
4105 	 * from the sap_ctx value
4106 	 * state var that keeps track of state machine
4107 	 */
4108 	enum sap_fsm_state state_var = sap_ctx->fsm_state;
4109 	uint32_t msg = sap_event->event; /* State machine input event message */
4110 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
4111 	struct mac_context *mac_ctx;
4112 	mac_handle_t mac_handle;
4113 
4114 	mac_ctx = sap_get_mac_context();
4115 	if (!mac_ctx) {
4116 		sap_err("Invalid MAC context");
4117 		return QDF_STATUS_E_FAILURE;
4118 	}
4119 	mac_handle = MAC_HANDLE(mac_ctx);
4120 
4121 	sap_debug("vdev %d: state %d event %d", sap_ctx->vdev_id, state_var,
4122 		  msg);
4123 
4124 	switch (state_var) {
4125 	case SAP_INIT:
4126 		qdf_status = sap_fsm_state_init(sap_ctx, sap_event,
4127 						mac_ctx, mac_handle);
4128 		break;
4129 
4130 	case SAP_STARTING:
4131 		qdf_status = sap_fsm_state_starting(sap_ctx, sap_event,
4132 						    mac_ctx, mac_handle);
4133 		break;
4134 
4135 	case SAP_STARTED:
4136 		qdf_status = sap_fsm_state_started(sap_ctx, sap_event,
4137 						   mac_ctx);
4138 		break;
4139 
4140 	case SAP_STOPPING:
4141 		qdf_status = sap_fsm_state_stopping(sap_ctx, sap_event,
4142 						    mac_ctx, mac_handle);
4143 		break;
4144 	}
4145 	return qdf_status;
4146 }
4147 
4148 void sap_sort_mac_list(struct qdf_mac_addr *macList, uint16_t size)
4149 {
4150 	uint16_t outer, inner;
4151 	struct qdf_mac_addr temp;
4152 	int32_t nRes = -1;
4153 
4154 	if ((!macList) || (size > MAX_ACL_MAC_ADDRESS)) {
4155 		sap_err("either buffer is NULL or size = %d is more", size);
4156 		return;
4157 	}
4158 
4159 	for (outer = 0; outer < size; outer++) {
4160 		for (inner = 0; inner < size - 1; inner++) {
4161 			nRes =
4162 				qdf_mem_cmp((macList + inner)->bytes,
4163 						 (macList + inner + 1)->bytes,
4164 						 QDF_MAC_ADDR_SIZE);
4165 			if (nRes > 0) {
4166 				qdf_mem_copy(temp.bytes,
4167 					     (macList + inner + 1)->bytes,
4168 					     QDF_MAC_ADDR_SIZE);
4169 				qdf_mem_copy((macList + inner + 1)->bytes,
4170 					     (macList + inner)->bytes,
4171 					     QDF_MAC_ADDR_SIZE);
4172 				qdf_mem_copy((macList + inner)->bytes,
4173 					     temp.bytes, QDF_MAC_ADDR_SIZE);
4174 			}
4175 		}
4176 	}
4177 }
4178 
4179 bool
4180 sap_search_mac_list(struct qdf_mac_addr *macList,
4181 		    uint16_t num_mac, uint8_t *peerMac,
4182 		    uint16_t *index)
4183 {
4184 	int32_t nRes = -1, nStart = 0, nEnd, nMiddle;
4185 
4186 	nEnd = num_mac - 1;
4187 
4188 	if ((!macList) || (num_mac > MAX_ACL_MAC_ADDRESS)) {
4189 		sap_err("either buffer is NULL or size = %d is more", num_mac);
4190 		return false;
4191 	}
4192 
4193 	while (nStart <= nEnd) {
4194 		nMiddle = (nStart + nEnd) / 2;
4195 		nRes =
4196 			qdf_mem_cmp(&macList[nMiddle], peerMac,
4197 					 QDF_MAC_ADDR_SIZE);
4198 
4199 		if (0 == nRes) {
4200 			sap_debug("search SUCC");
4201 			/* "index equals NULL" means the caller does not need the */
4202 			/* index value of the peerMac being searched */
4203 			if (index) {
4204 				*index = (uint16_t)nMiddle;
4205 				sap_debug("index %d", *index);
4206 			}
4207 			return true;
4208 		}
4209 		if (nRes < 0)
4210 			nStart = nMiddle + 1;
4211 		else
4212 			nEnd = nMiddle - 1;
4213 	}
4214 
4215 	sap_debug("search not succ");
4216 	return false;
4217 }
4218 
4219 void sap_add_mac_to_acl(struct qdf_mac_addr *macList,
4220 			uint16_t *size, uint8_t *peerMac)
4221 {
4222 	int32_t nRes = -1;
4223 	int i;
4224 
4225 	sap_debug("add acl entered");
4226 
4227 	if (!macList || *size > MAX_ACL_MAC_ADDRESS) {
4228 		sap_debug("either buffer is NULL or size = %d is incorrect",
4229 			  *size);
4230 		return;
4231 	}
4232 
4233 	for (i = ((*size) - 1); i >= 0; i--) {
4234 		nRes =
4235 			qdf_mem_cmp(&macList[i], peerMac, QDF_MAC_ADDR_SIZE);
4236 		if (nRes > 0) {
4237 			/* Move alphabetically greater mac addresses one index down to allow for insertion
4238 			   of new mac in sorted order */
4239 			qdf_mem_copy((macList + i + 1)->bytes,
4240 				     (macList + i)->bytes, QDF_MAC_ADDR_SIZE);
4241 		} else {
4242 			break;
4243 		}
4244 	}
4245 	/* This should also take care of if the element is the first to be added in the list */
4246 	qdf_mem_copy((macList + i + 1)->bytes, peerMac, QDF_MAC_ADDR_SIZE);
4247 	/* increment the list size */
4248 	(*size)++;
4249 }
4250 
4251 void sap_remove_mac_from_acl(struct qdf_mac_addr *macList,
4252 			     uint16_t *size, uint16_t index)
4253 {
4254 	int i;
4255 
4256 	sap_debug("remove acl entered");
4257 	/*
4258 	 * Return if the list passed is empty. Ideally this should never happen
4259 	 * since this funcn is always called after sap_search_mac_list to get
4260 	 * the index of the mac addr to be removed and this will only get
4261 	 * called if the search is successful. Still no harm in having the check
4262 	 */
4263 	if ((!macList) || (*size == 0) ||
4264 					(*size > MAX_ACL_MAC_ADDRESS)) {
4265 		sap_err("either buffer is NULL or size %d is incorrect",
4266 			 *size);
4267 		return;
4268 	}
4269 	for (i = index; i < ((*size) - 1); i++) {
4270 		/* Move mac addresses starting from "index" passed one index up to delete the void
4271 		   created by deletion of a mac address in ACL */
4272 		qdf_mem_copy((macList + i)->bytes, (macList + i + 1)->bytes,
4273 			     QDF_MAC_ADDR_SIZE);
4274 	}
4275 	/* The last space should be made empty since all mac addresses moved one step up */
4276 	qdf_mem_zero((macList + (*size) - 1)->bytes, QDF_MAC_ADDR_SIZE);
4277 	/* reduce the list size by 1 */
4278 	(*size)--;
4279 }
4280 
4281 void sap_print_acl(struct qdf_mac_addr *macList, uint16_t size)
4282 {
4283 	uint16_t i;
4284 	uint8_t *macArray;
4285 
4286 	sap_debug("print acl entered");
4287 
4288 	if ((!macList) || (size == 0) || (size > MAX_ACL_MAC_ADDRESS)) {
4289 		sap_err("Either buffer is NULL or size %d is incorrect", size);
4290 		return;
4291 	}
4292 
4293 	for (i = 0; i < size; i++) {
4294 		macArray = (macList + i)->bytes;
4295 		sap_debug("** ACL entry %i - " QDF_MAC_ADDR_FMT, i,
4296 			  QDF_MAC_ADDR_REF(macArray));
4297 	}
4298 	return;
4299 }
4300 
4301 QDF_STATUS sap_is_peer_mac_allowed(struct sap_context *sap_ctx,
4302 				   uint8_t *peerMac)
4303 {
4304 	if (eSAP_ALLOW_ALL == sap_ctx->eSapMacAddrAclMode)
4305 		return QDF_STATUS_SUCCESS;
4306 
4307 	if (sap_search_mac_list
4308 		    (sap_ctx->acceptMacList, sap_ctx->nAcceptMac, peerMac, NULL))
4309 		return QDF_STATUS_SUCCESS;
4310 
4311 	if (sap_search_mac_list
4312 		    (sap_ctx->denyMacList, sap_ctx->nDenyMac, peerMac, NULL)) {
4313 		sap_err("Peer " QDF_MAC_ADDR_FMT " in deny list",
4314 			 QDF_MAC_ADDR_REF(peerMac));
4315 		return QDF_STATUS_E_FAILURE;
4316 	}
4317 	/* A new station CAN associate, unless in deny list. Less stringent mode */
4318 	if (eSAP_ACCEPT_UNLESS_DENIED == sap_ctx->eSapMacAddrAclMode)
4319 		return QDF_STATUS_SUCCESS;
4320 
4321 	/* A new station CANNOT associate, unless in accept list. More stringent mode */
4322 	if (eSAP_DENY_UNLESS_ACCEPTED == sap_ctx->eSapMacAddrAclMode) {
4323 		sap_debug("Peer " QDF_MAC_ADDR_FMT
4324 			  " denied, Mac filter mode is eSAP_DENY_UNLESS_ACCEPTED",
4325 			  QDF_MAC_ADDR_REF(peerMac));
4326 		return QDF_STATUS_E_FAILURE;
4327 	}
4328 
4329 	/* The new STA is neither in accept list nor in deny list. In this case, deny the association
4330 	 * but send a wifi event notification indicating the mac address being denied
4331 	 */
4332 	if (eSAP_SUPPORT_ACCEPT_AND_DENY == sap_ctx->eSapMacAddrAclMode) {
4333 		sap_signal_hdd_event(sap_ctx, NULL, eSAP_UNKNOWN_STA_JOIN,
4334 				     (void *) peerMac);
4335 		sap_debug("Peer " QDF_MAC_ADDR_FMT
4336 			  " denied, Mac filter mode is eSAP_SUPPORT_ACCEPT_AND_DENY",
4337 			  QDF_MAC_ADDR_REF(peerMac));
4338 		return QDF_STATUS_E_FAILURE;
4339 	}
4340 	return QDF_STATUS_SUCCESS;
4341 }
4342 
4343 void sap_dump_acs_channel(struct sap_acs_cfg *acs_cfg)
4344 {
4345 	uint32_t buf_len = 0, len = 0, i;
4346 	uint8_t *chan_buff = NULL;
4347 
4348 	/*
4349 	 * Buffer of (num channel * 5) + 1  to consider the 4 char freq
4350 	 * and 1 space after it for each channel and 1 to end the string
4351 	 * with NULL.
4352 	 */
4353 	buf_len = (acs_cfg->ch_list_count * 5) + 1;
4354 	chan_buff = qdf_mem_malloc(buf_len);
4355 	if (!chan_buff)
4356 		return;
4357 
4358 	for (i = 0; i < acs_cfg->ch_list_count; i++)
4359 		len += qdf_scnprintf(chan_buff + len, buf_len - len,
4360 				     " %d", acs_cfg->freq_list[i]);
4361 
4362 	sap_nofl_debug("ACS freq list[%d]:%s",
4363 		       acs_cfg->ch_list_count, chan_buff);
4364 	qdf_mem_free(chan_buff);
4365 }
4366 
4367 #ifdef SOFTAP_CHANNEL_RANGE
4368 /**
4369  * sap_get_freq_list() - get the list of channel frequency
4370  * @sap_ctx: sap context
4371  * @freq_list: pointer to channel list array
4372  * @num_ch: pointer to number of channels.
4373  *
4374  * This function populates the list of channel frequency for scanning.
4375  *
4376  * Return: QDF_STATUS
4377  */
4378 static QDF_STATUS sap_get_freq_list(struct sap_context *sap_ctx,
4379 				    uint32_t **freq_list,
4380 				    uint8_t *num_ch)
4381 {
4382 	uint8_t loop_count;
4383 	uint32_t *list;
4384 	uint8_t ch_count;
4385 	uint8_t dfs_master_enable;
4386 	uint32_t start_ch_freq, band_start_ch;
4387 	uint32_t end_ch_freq, band_end_ch;
4388 	uint32_t en_lte_coex;
4389 	struct mac_context *mac_ctx;
4390 	uint16_t ch_width;
4391 	uint8_t normalize_factor = 100;
4392 	uint32_t chan_freq;
4393 	struct acs_weight *weight_list;
4394 	struct acs_weight_range *range_list;
4395 	bool freq_present_in_list = false;
4396 	uint8_t i;
4397 	bool srd_chan_enabled;
4398 	enum QDF_OPMODE vdev_opmode;
4399 
4400 	mac_ctx = sap_get_mac_context();
4401 	if (!mac_ctx) {
4402 		sap_err("Invalid MAC context");
4403 		*num_ch = 0;
4404 		*freq_list = NULL;
4405 		return QDF_STATUS_E_FAULT;
4406 	}
4407 
4408 	weight_list = mac_ctx->mlme_cfg->acs.normalize_weight_chan;
4409 	range_list = mac_ctx->mlme_cfg->acs.normalize_weight_range;
4410 
4411 	dfs_master_enable = mac_ctx->mlme_cfg->dfs_cfg.dfs_master_capable;
4412 	if (sap_ctx->dfs_mode == ACS_DFS_MODE_DISABLE)
4413 		dfs_master_enable = false;
4414 
4415 	start_ch_freq = sap_ctx->acs_cfg->start_ch_freq;
4416 	end_ch_freq = sap_ctx->acs_cfg->end_ch_freq;
4417 	ch_width = sap_ctx->acs_cfg->ch_width;
4418 
4419 	sap_debug("startChannel %d, EndChannel %d, ch_width %d, HW:%d",
4420 		  start_ch_freq, end_ch_freq, ch_width,
4421 		  sap_ctx->acs_cfg->hw_mode);
4422 
4423 	wlansap_extend_to_acs_range(MAC_HANDLE(mac_ctx),
4424 				    &start_ch_freq, &end_ch_freq,
4425 				    &band_start_ch, &band_end_ch);
4426 
4427 	sap_debug("expanded startChannel %d,EndChannel %d band_start_ch %d, band_end_ch %d",
4428 		  start_ch_freq, end_ch_freq, band_start_ch, band_end_ch);
4429 
4430 	en_lte_coex = mac_ctx->mlme_cfg->sap_cfg.enable_lte_coex;
4431 
4432 	/* Check if LTE coex is enabled and 2.4GHz is selected */
4433 	if (en_lte_coex && (band_start_ch == CHAN_ENUM_2412) &&
4434 	    (band_end_ch == CHAN_ENUM_2484)) {
4435 		/* Set 2.4GHz upper limit to channel 9 for LTE COEX */
4436 		band_end_ch = CHAN_ENUM_2452;
4437 	}
4438 
4439 	/* Allocate the max number of channel supported */
4440 	list = qdf_mem_malloc((NUM_CHANNELS) * sizeof(uint32_t));
4441 	if (!list) {
4442 		*num_ch = 0;
4443 		*freq_list = NULL;
4444 		return QDF_STATUS_E_NOMEM;
4445 	}
4446 
4447 	/* Search for the Active channels in the given range */
4448 	ch_count = 0;
4449 	for (loop_count = band_start_ch; loop_count <= band_end_ch;
4450 	     loop_count++) {
4451 		chan_freq = WLAN_REG_CH_TO_FREQ(loop_count);
4452 
4453 		/* go to next channel if rf_channel is out of range */
4454 		if (start_ch_freq > WLAN_REG_CH_TO_FREQ(loop_count) ||
4455 		    end_ch_freq < WLAN_REG_CH_TO_FREQ(loop_count))
4456 			continue;
4457 		/*
4458 		 * go to next channel if none of these condition pass
4459 		 * - DFS scan enabled and chan not in CHANNEL_STATE_DISABLE
4460 		 * - DFS scan disable but chan in CHANNEL_STATE_ENABLE
4461 		 */
4462 		if (!(((true == mac_ctx->scan.fEnableDFSChnlScan) &&
4463 		      wlan_reg_get_channel_state_from_secondary_list_for_freq(
4464 			mac_ctx->pdev, WLAN_REG_CH_TO_FREQ(loop_count)))
4465 		      ||
4466 		    ((false == mac_ctx->scan.fEnableDFSChnlScan) &&
4467 		     (CHANNEL_STATE_ENABLE ==
4468 		      wlan_reg_get_channel_state_from_secondary_list_for_freq(
4469 			mac_ctx->pdev, WLAN_REG_CH_TO_FREQ(loop_count)))
4470 		     )))
4471 			continue;
4472 
4473 		/* check if the channel is in NOL denylist */
4474 		if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(WLAN_REG_CH_TO_FREQ(
4475 					loop_count))) {
4476 			if (sap_dfs_is_channel_in_nol_list(
4477 					sap_ctx,
4478 					chan_freq,
4479 					PHY_SINGLE_CHANNEL_CENTERED)) {
4480 				sap_debug("Ch freq %d in NOL list", chan_freq);
4481 				continue;
4482 			}
4483 		}
4484 		/* Skip DSRC channels */
4485 		if (wlan_reg_is_dsrc_freq(WLAN_REG_CH_TO_FREQ(loop_count)))
4486 			continue;
4487 
4488 		/*
4489 		 * Skip the channels which are not in ACS config from user
4490 		 * space
4491 		 */
4492 		if (!wlansap_is_channel_present_in_acs_list(
4493 					chan_freq,
4494 					sap_ctx->acs_cfg->freq_list,
4495 					sap_ctx->acs_cfg->ch_list_count))
4496 			continue;
4497 		/* Dont scan DFS channels in case of MCC disallowed
4498 		 * As it can result in SAP starting on DFS channel
4499 		 * resulting  MCC on DFS channel
4500 		 */
4501 		if (wlan_reg_is_dfs_in_secondary_list_for_freq(
4502 					mac_ctx->pdev,
4503 					WLAN_REG_CH_TO_FREQ(loop_count))) {
4504 			if (!dfs_master_enable)
4505 				continue;
4506 			if (wlansap_dcs_is_wlan_interference_mitigation_enabled(
4507 								sap_ctx))
4508 				sap_debug("dfs chan_freq %d added when dcs enabled",
4509 					  WLAN_REG_CH_TO_FREQ(loop_count));
4510 			else if (policy_mgr_disallow_mcc(
4511 					mac_ctx->psoc,
4512 					WLAN_REG_CH_TO_FREQ(loop_count)))
4513 				continue;
4514 			normalize_factor =
4515 				MLME_GET_DFS_CHAN_WEIGHT(
4516 				mac_ctx->mlme_cfg->acs.np_chan_weightage);
4517 			freq_present_in_list = true;
4518 		}
4519 
4520 		vdev_opmode = wlan_vdev_mlme_get_opmode(sap_ctx->vdev);
4521 		wlan_mlme_get_srd_master_mode_for_vdev(mac_ctx->psoc,
4522 						       vdev_opmode,
4523 						       &srd_chan_enabled);
4524 
4525 		if (!srd_chan_enabled &&
4526 		    wlan_reg_is_etsi_srd_chan_for_freq(
4527 					mac_ctx->pdev,
4528 					WLAN_REG_CH_TO_FREQ(loop_count))) {
4529 			sap_debug("vdev opmode %d not allowed on SRD freq %d",
4530 				  vdev_opmode, WLAN_REG_CH_TO_FREQ(loop_count));
4531 			continue;
4532 		}
4533 
4534 		/* Check if the freq is present in range list */
4535 		for (i = 0; i < mac_ctx->mlme_cfg->acs.num_weight_range; i++) {
4536 			if (chan_freq >= range_list[i].start_freq &&
4537 			    chan_freq <= range_list[i].end_freq) {
4538 				normalize_factor =
4539 					range_list[i].normalize_weight;
4540 				sap_debug("Range list, freq %d normalize weight factor %d",
4541 					  chan_freq, normalize_factor);
4542 				freq_present_in_list = true;
4543 			}
4544 		}
4545 
4546 		for (i = 0;
4547 		     i < mac_ctx->mlme_cfg->acs.normalize_weight_num_chan;
4548 		     i++) {
4549 			if (chan_freq == weight_list[i].chan_freq) {
4550 				normalize_factor =
4551 					weight_list[i].normalize_weight;
4552 				sap_debug("freq %d normalize weight factor %d",
4553 					  chan_freq, normalize_factor);
4554 				freq_present_in_list = true;
4555 			}
4556 		}
4557 
4558 		/* This would mean that the user does not want this freq */
4559 		if (freq_present_in_list && !normalize_factor) {
4560 			sap_debug("chan_freq %d ecluded normalize weight 0",
4561 				  chan_freq);
4562 			freq_present_in_list = false;
4563 			continue;
4564 		}
4565 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
4566 		if (sap_ctx->acs_cfg->skip_scan_status ==
4567 			eSAP_DO_PAR_ACS_SCAN) {
4568 			uint32_t ch_freq;
4569 
4570 			ch_freq = WLAN_REG_CH_TO_FREQ(loop_count);
4571 			if ((ch_freq >=
4572 				sap_ctx->acs_cfg->skip_scan_range1_stch &&
4573 			      ch_freq <=
4574 				sap_ctx->acs_cfg->skip_scan_range1_endch) ||
4575 			     (ch_freq >=
4576 				sap_ctx->acs_cfg->skip_scan_range2_stch &&
4577 			      ch_freq <=
4578 				sap_ctx->acs_cfg->skip_scan_range2_endch)) {
4579 				list[ch_count] =
4580 					WLAN_REG_CH_TO_FREQ(loop_count);
4581 				ch_count++;
4582 				sap_debug("%d %d added to ACS ch range",
4583 					  ch_count, ch_freq);
4584 			} else {
4585 				sap_debug("%d %d skipped from ACS ch range",
4586 					  ch_count, ch_freq);
4587 			}
4588 		} else {
4589 			list[ch_count] = WLAN_REG_CH_TO_FREQ(loop_count);
4590 			ch_count++;
4591 			sap_debug("%d added to ACS ch range", ch_count);
4592 		}
4593 #else
4594 		list[ch_count] = WLAN_REG_CH_TO_FREQ(loop_count);
4595 		ch_count++;
4596 #endif
4597 	}
4598 	if (!ch_count) {
4599 		sap_info("No active channels present for the current region");
4600 		/*
4601 		 * LTE COEX: channel range outside the restricted 2.4GHz
4602 		 * band limits
4603 		 */
4604 		if (en_lte_coex &&
4605 		    start_ch_freq > WLAN_REG_CH_TO_FREQ(band_end_ch))
4606 			sap_info("SAP can't be started as due to LTE COEX");
4607 	}
4608 
4609 	/* return the channel list and number of channels to scan */
4610 	*num_ch = ch_count;
4611 	if (ch_count != 0) {
4612 		*freq_list = list;
4613 	} else {
4614 		*freq_list = NULL;
4615 		qdf_mem_free(list);
4616 		return QDF_STATUS_SUCCESS;
4617 	}
4618 
4619 	for (loop_count = 0; loop_count < ch_count; loop_count++) {
4620 		sap_ctx->acs_cfg->freq_list[loop_count] = list[loop_count];
4621 	}
4622 	sap_ctx->acs_cfg->ch_list_count = ch_count;
4623 	sap_dump_acs_channel(sap_ctx->acs_cfg);
4624 
4625 	return QDF_STATUS_SUCCESS;
4626 }
4627 #endif
4628 
4629 #ifdef DFS_COMPONENT_ENABLE
4630 qdf_freq_t sap_indicate_radar(struct sap_context *sap_ctx)
4631 {
4632 	qdf_freq_t chan_freq = 0;
4633 	struct mac_context *mac;
4634 
4635 	if (!sap_ctx) {
4636 		sap_err("null sap_ctx");
4637 		return 0;
4638 	}
4639 
4640 	mac = sap_get_mac_context();
4641 	if (!mac) {
4642 		sap_err("Invalid MAC context");
4643 		return 0;
4644 	}
4645 
4646 	/*
4647 	 * SAP needs to generate Channel Switch IE
4648 	 * if the radar is found in the STARTED state
4649 	 */
4650 	if (sap_ctx->fsm_state == SAP_STARTED)
4651 		mac->sap.SapDfsInfo.csaIERequired = true;
4652 
4653 	if (mac->mlme_cfg->dfs_cfg.dfs_disable_channel_switch) {
4654 		mac->sap.SapDfsInfo.new_chanWidth =
4655 					sap_ctx->ch_params.ch_width;
4656 		sap_debug("DFS channel switch disabled, CSA to same ch %d wd %d",
4657 			  sap_ctx->chan_freq, sap_ctx->ch_params.ch_width);
4658 		return sap_ctx->chan_freq;
4659 	}
4660 
4661 	/* set the Radar Found flag in SapDfsInfo */
4662 	sap_ctx->sap_radar_found_status = true;
4663 
4664 	chan_freq = wlan_pre_cac_get_freq_before_pre_cac(sap_ctx->vdev);
4665 	if (chan_freq) {
4666 		sap_info("sapdfs: set chan freq before pre cac %d as target chan",
4667 			 chan_freq);
4668 		return chan_freq;
4669 	}
4670 
4671 	if (sap_ctx->vendor_acs_dfs_lte_enabled && (QDF_STATUS_SUCCESS ==
4672 	    sap_signal_hdd_event(sap_ctx, NULL, eSAP_DFS_NEXT_CHANNEL_REQ,
4673 	    (void *) eSAP_STATUS_SUCCESS)))
4674 		return 0;
4675 
4676 	if (!sap_is_chan_change_needed(sap_ctx))
4677 		return sap_ctx->chan_freq;
4678 
4679 	chan_freq = sap_random_channel_sel(sap_ctx);
4680 	if (!chan_freq)
4681 		sap_signal_hdd_event(sap_ctx, NULL,
4682 		eSAP_DFS_NO_AVAILABLE_CHANNEL, (void *) eSAP_STATUS_SUCCESS);
4683 
4684 	sap_warn("sapdfs: New selected target freq is [%d]", chan_freq);
4685 
4686 	return chan_freq;
4687 }
4688 #endif
4689 
4690 /*
4691  * CAC timer callback function.
4692  * Post eSAP_DFS_CHANNEL_CAC_END event to sap_fsm().
4693  */
4694 void sap_dfs_cac_timer_callback(void *data)
4695 {
4696 	struct sap_context *sap_ctx;
4697 	struct sap_sm_event sap_event;
4698 	mac_handle_t mac_handle = data;
4699 	struct mac_context *mac;
4700 
4701 	if (!mac_handle) {
4702 		sap_err("Invalid mac_handle");
4703 		return;
4704 	}
4705 	mac = MAC_CONTEXT(mac_handle);
4706 	sap_ctx = sap_find_cac_wait_session(mac_handle);
4707 	if (!sap_ctx) {
4708 		sap_err("no SAP contexts in wait state");
4709 		return;
4710 	}
4711 
4712 	/*
4713 	 * SAP may not be in CAC wait state, when the timer runs out.
4714 	 * if following flag is set, then timer is in initialized state,
4715 	 * destroy timer here.
4716 	 */
4717 	if (mac->sap.SapDfsInfo.is_dfs_cac_timer_running == true) {
4718 		if (!sap_ctx->dfs_cac_offload)
4719 			qdf_mc_timer_destroy(
4720 				&mac->sap.SapDfsInfo.sap_dfs_cac_timer);
4721 		mac->sap.SapDfsInfo.is_dfs_cac_timer_running = false;
4722 	}
4723 
4724 	/*
4725 	 * CAC Complete, post eSAP_DFS_CHANNEL_CAC_END to sap_fsm
4726 	 */
4727 	sap_debug("sapdfs: Sending eSAP_DFS_CHANNEL_CAC_END for target_chan_freq = %d on sapctx[%pK]",
4728 		  sap_ctx->chan_freq, sap_ctx);
4729 
4730 	sap_event.event = eSAP_DFS_CHANNEL_CAC_END;
4731 	sap_event.params = 0;
4732 	sap_event.u1 = 0;
4733 	sap_event.u2 = 0;
4734 
4735 	sap_fsm(sap_ctx, &sap_event);
4736 }
4737 
4738 /*
4739  * Function to stop the DFS CAC Timer
4740  */
4741 static int sap_stop_dfs_cac_timer(struct sap_context *sap_ctx)
4742 {
4743 	struct mac_context *mac;
4744 
4745 	if (!sap_ctx)
4746 		return 0;
4747 
4748 	mac = sap_get_mac_context();
4749 	if (!mac) {
4750 		sap_err("Invalid MAC context");
4751 		return 0;
4752 	}
4753 
4754 	if (sap_ctx->dfs_cac_offload) {
4755 		mac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
4756 		return 0;
4757 	}
4758 
4759 	if (QDF_TIMER_STATE_RUNNING !=
4760 	    qdf_mc_timer_get_current_state(&mac->sap.SapDfsInfo.
4761 					   sap_dfs_cac_timer)) {
4762 		return 0;
4763 	}
4764 
4765 	qdf_mc_timer_stop(&mac->sap.SapDfsInfo.sap_dfs_cac_timer);
4766 	mac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
4767 	qdf_mc_timer_destroy(&mac->sap.SapDfsInfo.sap_dfs_cac_timer);
4768 
4769 	return 0;
4770 }
4771 
4772 /*
4773  * Function to start the DFS CAC Timer
4774  * when SAP is started on a DFS channel
4775  */
4776 static int sap_start_dfs_cac_timer(struct sap_context *sap_ctx)
4777 {
4778 	QDF_STATUS status;
4779 	uint32_t cac_dur;
4780 	struct mac_context *mac;
4781 	enum dfs_reg dfs_region;
4782 
4783 	if (!sap_ctx) {
4784 		sap_err("null sap_ctx");
4785 		return 0;
4786 	}
4787 
4788 	mac = sap_get_mac_context();
4789 	if (!mac) {
4790 		sap_err("Invalid MAC context");
4791 		return 0;
4792 	}
4793 
4794 	if (sap_ctx->dfs_cac_offload) {
4795 		sap_debug("cac timer offloaded to firmware");
4796 		mac->sap.SapDfsInfo.is_dfs_cac_timer_running = true;
4797 		return 1;
4798 	}
4799 
4800 	sap_get_cac_dur_dfs_region(sap_ctx, &cac_dur, &dfs_region,
4801 				   sap_ctx->chan_freq, &sap_ctx->ch_params);
4802 	if (0 == cac_dur)
4803 		return 0;
4804 
4805 #ifdef QCA_WIFI_EMULATION
4806 	cac_dur = cac_dur / 100;
4807 #endif
4808 	sap_debug("sapdfs: SAP_DFS_CHANNEL_CAC_START on CH freq %d, CAC_DUR-%d sec",
4809 		  sap_ctx->chan_freq, cac_dur / 1000);
4810 
4811 	qdf_mc_timer_init(&mac->sap.SapDfsInfo.sap_dfs_cac_timer,
4812 			  QDF_TIMER_TYPE_SW,
4813 			  sap_dfs_cac_timer_callback, MAC_HANDLE(mac));
4814 
4815 	/* Start the CAC timer */
4816 	status = qdf_mc_timer_start(&mac->sap.SapDfsInfo.sap_dfs_cac_timer,
4817 			cac_dur);
4818 	if (QDF_IS_STATUS_ERROR(status)) {
4819 		sap_err("failed to start cac timer");
4820 		goto destroy_timer;
4821 	}
4822 
4823 	mac->sap.SapDfsInfo.is_dfs_cac_timer_running = true;
4824 
4825 	return 0;
4826 
4827 destroy_timer:
4828 	mac->sap.SapDfsInfo.is_dfs_cac_timer_running = false;
4829 	qdf_mc_timer_destroy(&mac->sap.SapDfsInfo.sap_dfs_cac_timer);
4830 
4831 	return 1;
4832 }
4833 
4834 /*
4835  * This function initializes the NOL list
4836  * parameters required to track the radar
4837  * found DFS channels in the current Reg. Domain .
4838  */
4839 QDF_STATUS sap_init_dfs_channel_nol_list(struct sap_context *sap_ctx)
4840 {
4841 	struct mac_context *mac;
4842 
4843 	if (!sap_ctx) {
4844 		sap_err("Invalid SAP context");
4845 		return QDF_STATUS_E_FAULT;
4846 	}
4847 
4848 	mac = sap_get_mac_context();
4849 	if (!mac) {
4850 		sap_err("Invalid MAC context");
4851 		return QDF_STATUS_E_FAULT;
4852 	}
4853 
4854 	utils_dfs_init_nol(mac->pdev);
4855 
4856 	return QDF_STATUS_SUCCESS;
4857 }
4858 
4859 /**
4860  * sap_is_active() - Check SAP active or not by sap_context object
4861  * @sap_ctx: Pointer to the SAP context
4862  *
4863  * Return: true if SAP is active
4864  */
4865 static bool sap_is_active(struct sap_context *sap_ctx)
4866 {
4867 	return sap_ctx->fsm_state != SAP_INIT;
4868 }
4869 
4870 /*
4871  * This function will calculate how many interfaces
4872  * have sap persona and returns total number of sap persona.
4873  */
4874 uint8_t sap_get_total_number_sap_intf(mac_handle_t mac_handle)
4875 {
4876 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
4877 	uint8_t intf = 0;
4878 	uint8_t intf_count = 0;
4879 	struct sap_context *sap_context;
4880 
4881 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
4882 		if (((QDF_SAP_MODE == mac->sap.sapCtxList[intf].sapPersona)
4883 		    ||
4884 		    (QDF_P2P_GO_MODE == mac->sap.sapCtxList[intf].sapPersona))
4885 		    && mac->sap.sapCtxList[intf].sap_context) {
4886 			sap_context =
4887 				mac->sap.sapCtxList[intf].sap_context;
4888 			if (!sap_is_active(sap_context))
4889 				continue;
4890 			intf_count++;
4891 		}
4892 	}
4893 	return intf_count;
4894 }
4895 
4896 /**
4897  * is_concurrent_sap_ready_for_channel_change() - to check all saps are ready
4898  *						  for channel change
4899  * @mac_handle: Opaque handle to the global MAC context
4900  * @sap_ctx: sap context for which this function has been called
4901  *
4902  * This function will find the concurrent sap context apart from
4903  * passed sap context and return its channel change ready status
4904  *
4905  *
4906  * Return: true if other SAP personas are ready to channel switch else false
4907  */
4908 bool is_concurrent_sap_ready_for_channel_change(mac_handle_t mac_handle,
4909 						struct sap_context *sap_ctx)
4910 {
4911 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
4912 	struct sap_context *sap_context;
4913 	uint8_t intf = 0;
4914 
4915 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
4916 		if (((QDF_SAP_MODE == mac->sap.sapCtxList[intf].sapPersona)
4917 		    ||
4918 		    (QDF_P2P_GO_MODE == mac->sap.sapCtxList[intf].sapPersona))
4919 		    && mac->sap.sapCtxList[intf].sap_context) {
4920 			sap_context =
4921 				mac->sap.sapCtxList[intf].sap_context;
4922 			if (!sap_is_active(sap_context))
4923 				continue;
4924 			if (sap_context == sap_ctx) {
4925 				sap_err("sapCtx matched [%pK]", sap_ctx);
4926 				continue;
4927 			} else {
4928 				sap_err("concurrent sapCtx[%pK] didn't matche with [%pK]",
4929 					 sap_context, sap_ctx);
4930 				return sap_context->is_sap_ready_for_chnl_chng;
4931 			}
4932 		}
4933 	}
4934 	return false;
4935 }
4936 
4937 /**
4938  * sap_is_conc_sap_doing_scc_dfs() - check if conc SAPs are doing SCC DFS
4939  * @mac_handle: Opaque handle to the global MAC context
4940  * @sap_context: current SAP persona's channel
4941  *
4942  * If provided SAP's channel is DFS then Loop through each SAP or GO persona and
4943  * check if other beaconing entity's channel is same DFS channel. If they are
4944  * same then concurrent sap is doing SCC DFS.
4945  *
4946  * Return: true if two or more beaconing entities doing SCC DFS else false
4947  */
4948 bool sap_is_conc_sap_doing_scc_dfs(mac_handle_t mac_handle,
4949 				   struct sap_context *given_sapctx)
4950 {
4951 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
4952 	struct sap_context *sap_ctx;
4953 	uint8_t intf = 0, scc_dfs_counter = 0;
4954 	qdf_freq_t ch_freq;
4955 
4956 	ch_freq = given_sapctx->chan_freq;
4957 	/*
4958 	 * current SAP persona's channel itself is not DFS, so no need to check
4959 	 * what other persona's channel is
4960 	 */
4961 	if (!wlan_reg_is_dfs_for_freq(mac->pdev,
4962 				      ch_freq)) {
4963 		sap_debug("skip this loop as provided channel is non-dfs");
4964 		return false;
4965 	}
4966 
4967 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
4968 		if ((QDF_SAP_MODE != mac->sap.sapCtxList[intf].sapPersona) &&
4969 		    (QDF_P2P_GO_MODE != mac->sap.sapCtxList[intf].sapPersona))
4970 			continue;
4971 		if (!mac->sap.sapCtxList[intf].sap_context)
4972 			continue;
4973 		sap_ctx = mac->sap.sapCtxList[intf].sap_context;
4974 		if (!sap_is_active(sap_ctx))
4975 			continue;
4976 		/* if same SAP contexts then skip to next context */
4977 		if (sap_ctx == given_sapctx)
4978 			continue;
4979 		if (given_sapctx->chan_freq == sap_ctx->chan_freq)
4980 			scc_dfs_counter++;
4981 	}
4982 
4983 	/* Found atleast two of the beaconing entities doing SCC DFS */
4984 	if (scc_dfs_counter)
4985 		return true;
4986 
4987 	return false;
4988 }
4989 
4990 /**
4991  * sap_build_start_bss_config() - Fill the start bss request for SAP
4992  * @sap_bss_cfg: start bss config
4993  * @config: sap config
4994  *
4995  * This function fills the start bss request for SAP
4996  *
4997  * Return: None
4998  */
4999 void
5000 sap_build_start_bss_config(struct start_bss_config *sap_bss_cfg,
5001 			   struct sap_config *config)
5002 {
5003 	qdf_mem_zero(&sap_bss_cfg->ssId.ssId, sizeof(sap_bss_cfg->ssId.ssId));
5004 	sap_bss_cfg->ssId.length = config->SSIDinfo.ssid.length;
5005 	qdf_mem_copy(&sap_bss_cfg->ssId.ssId, config->SSIDinfo.ssid.ssId,
5006 		     config->SSIDinfo.ssid.length);
5007 
5008 	if (config->authType == eSAP_SHARED_KEY)
5009 		sap_bss_cfg->authType = eSIR_SHARED_KEY;
5010 	else if (config->authType == eSAP_OPEN_SYSTEM)
5011 		sap_bss_cfg->authType = eSIR_OPEN_SYSTEM;
5012 	else
5013 		sap_bss_cfg->authType = eSIR_AUTO_SWITCH;
5014 
5015 	sap_bss_cfg->beaconInterval = (uint16_t)config->beacon_int;
5016 	sap_bss_cfg->privacy = config->privacy;
5017 	sap_bss_cfg->ssidHidden = config->SSIDinfo.ssidHidden;
5018 	sap_bss_cfg->dtimPeriod = config->dtim_period;
5019 	sap_bss_cfg->wps_state = config->wps_state;
5020 	sap_bss_cfg->beacon_tx_rate = config->beacon_tx_rate;
5021 
5022 	/* RSNIE */
5023 	sap_bss_cfg->rsnIE.length = config->RSNWPAReqIELength;
5024 	if (config->RSNWPAReqIELength)
5025 		qdf_mem_copy(sap_bss_cfg->rsnIE.rsnIEdata,
5026 			     config->RSNWPAReqIE, config->RSNWPAReqIELength);
5027 
5028 	/* Probe response IE */
5029 	if (config->probeRespIEsBufferLen > 0 &&
5030 	    config->pProbeRespIEsBuffer) {
5031 		sap_bss_cfg->add_ie_params.probeRespDataLen =
5032 						config->probeRespIEsBufferLen;
5033 		sap_bss_cfg->add_ie_params.probeRespData_buff =
5034 						config->pProbeRespIEsBuffer;
5035 	} else {
5036 		sap_bss_cfg->add_ie_params.probeRespDataLen = 0;
5037 		sap_bss_cfg->add_ie_params.probeRespData_buff = NULL;
5038 	}
5039 
5040 	/*assoc resp IE */
5041 	if (config->assocRespIEsLen > 0 && config->pAssocRespIEsBuffer) {
5042 		sap_bss_cfg->add_ie_params.assocRespDataLen =
5043 						config->assocRespIEsLen;
5044 		sap_bss_cfg->add_ie_params.assocRespData_buff =
5045 						config->pAssocRespIEsBuffer;
5046 	} else {
5047 		sap_bss_cfg->add_ie_params.assocRespDataLen = 0;
5048 		sap_bss_cfg->add_ie_params.assocRespData_buff = NULL;
5049 	}
5050 
5051 	if (config->probeRespBcnIEsLen > 0 &&
5052 	    config->pProbeRespBcnIEsBuffer) {
5053 		sap_bss_cfg->add_ie_params.probeRespBCNDataLen =
5054 						config->probeRespBcnIEsLen;
5055 		sap_bss_cfg->add_ie_params.probeRespBCNData_buff =
5056 						config->pProbeRespBcnIEsBuffer;
5057 	} else {
5058 		sap_bss_cfg->add_ie_params.probeRespBCNDataLen = 0;
5059 		sap_bss_cfg->add_ie_params.probeRespBCNData_buff = NULL;
5060 	}
5061 
5062 	if (config->supported_rates.numRates) {
5063 		qdf_mem_copy(sap_bss_cfg->operationalRateSet.rate,
5064 			     config->supported_rates.rate,
5065 			     config->supported_rates.numRates);
5066 		sap_bss_cfg->operationalRateSet.numRates =
5067 					config->supported_rates.numRates;
5068 	}
5069 
5070 	if (config->extended_rates.numRates) {
5071 		qdf_mem_copy(sap_bss_cfg->extendedRateSet.rate,
5072 			     config->extended_rates.rate,
5073 			     config->extended_rates.numRates);
5074 		sap_bss_cfg->extendedRateSet.numRates =
5075 				config->extended_rates.numRates;
5076 	}
5077 
5078 	return;
5079 }
5080