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