xref: /wlan-dirver/qcacld-3.0/core/sap/src/sap_fsm.c (revision bb8e47c200751dd274982fa7d00566e04456aa23)
1 /*
2  * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /*===========================================================================
20 
21 			s a p F s m . C
22 
23    OVERVIEW:
24 
25    This software unit holds the implementation of the WLAN SAP Finite
26    State Machine modules
27 
28    DEPENDENCIES:
29 
30    Are listed for each API below.
31    ===========================================================================*/
32 
33 /*----------------------------------------------------------------------------
34  * Include Files
35  * -------------------------------------------------------------------------*/
36 #include "sap_internal.h"
37 #include <wlan_dfs_tgt_api.h>
38 #include <wlan_dfs_utils_api.h>
39 #include <wlan_dfs_public_struct.h>
40 #include <wlan_reg_services_api.h>
41 /* Pick up the SME API definitions */
42 #include "sme_api.h"
43 /* Pick up the PMC API definitions */
44 #include "cds_utils.h"
45 #include "cds_ieee80211_common_i.h"
46 #include "cds_reg_service.h"
47 #include "qdf_util.h"
48 #include "wlan_policy_mgr_api.h"
49 #include "cfg_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_ucfg_api.h>
57 #include "wlan_reg_services_api.h"
58 
59 /*----------------------------------------------------------------------------
60  * Preprocessor Definitions and Constants
61  * -------------------------------------------------------------------------*/
62 
63 /*----------------------------------------------------------------------------
64  * Type Declarations
65  * -------------------------------------------------------------------------*/
66 
67 /*----------------------------------------------------------------------------
68  * Global Data Definitions
69  * -------------------------------------------------------------------------*/
70 
71 /*----------------------------------------------------------------------------
72  *  External declarations for global context
73  * -------------------------------------------------------------------------*/
74 #ifdef FEATURE_WLAN_CH_AVOID
75 extern sapSafeChannelType safe_channels[];
76 #endif /* FEATURE_WLAN_CH_AVOID */
77 
78 /*----------------------------------------------------------------------------
79  * Static Variable Definitions
80  * -------------------------------------------------------------------------*/
81 
82 /*----------------------------------------------------------------------------
83  * Static Function Declarations and Definitions
84  * -------------------------------------------------------------------------*/
85 #ifdef SOFTAP_CHANNEL_RANGE
86 static QDF_STATUS sap_get_channel_list(struct sap_context *sapContext,
87 				    uint8_t **channelList,
88 				    uint8_t *numberOfChannels);
89 #endif
90 
91 /*==========================================================================
92    FUNCTION    sapStopDfsCacTimer
93 
94    DESCRIPTION
95     Function to sttop the DFS CAC timer when SAP is stopped
96    DEPENDENCIES
97     NA.
98 
99    PARAMETERS
100 
101     IN
102     sapContext: SAP Context
103    RETURN VALUE
104     DFS Timer start status
105    SIDE EFFECTS
106    ============================================================================*/
107 
108 static int sap_stop_dfs_cac_timer(struct sap_context *sapContext);
109 
110 /*==========================================================================
111    FUNCTION    sapStartDfsCacTimer
112 
113    DESCRIPTION
114     Function to start the DFS CAC timer when SAP is started on DFS Channel
115    DEPENDENCIES
116     NA.
117 
118    PARAMETERS
119 
120     IN
121     sapContext: SAP Context
122    RETURN VALUE
123     DFS Timer start status
124    SIDE EFFECTS
125    ============================================================================*/
126 
127 static int sap_start_dfs_cac_timer(struct sap_context *sapContext);
128 
129 /** sap_hdd_event_to_string() - convert hdd event to string
130  * @event: eSapHddEvent event type
131  *
132  * This function converts eSapHddEvent into string
133  *
134  * Return: string for the @event.
135  */
136 static uint8_t *sap_hdd_event_to_string(eSapHddEvent event)
137 {
138 	switch (event) {
139 	CASE_RETURN_STRING(eSAP_START_BSS_EVENT);
140 	CASE_RETURN_STRING(eSAP_STOP_BSS_EVENT);
141 	CASE_RETURN_STRING(eSAP_STA_ASSOC_IND);
142 	CASE_RETURN_STRING(eSAP_STA_ASSOC_EVENT);
143 	CASE_RETURN_STRING(eSAP_STA_REASSOC_EVENT);
144 	CASE_RETURN_STRING(eSAP_STA_DISASSOC_EVENT);
145 	CASE_RETURN_STRING(eSAP_STA_SET_KEY_EVENT);
146 	CASE_RETURN_STRING(eSAP_STA_MIC_FAILURE_EVENT);
147 	CASE_RETURN_STRING(eSAP_ASSOC_STA_CALLBACK_EVENT);
148 	CASE_RETURN_STRING(eSAP_WPS_PBC_PROBE_REQ_EVENT);
149 	CASE_RETURN_STRING(eSAP_DISCONNECT_ALL_P2P_CLIENT);
150 	CASE_RETURN_STRING(eSAP_MAC_TRIG_STOP_BSS_EVENT);
151 	CASE_RETURN_STRING(eSAP_UNKNOWN_STA_JOIN);
152 	CASE_RETURN_STRING(eSAP_MAX_ASSOC_EXCEEDED);
153 	CASE_RETURN_STRING(eSAP_CHANNEL_CHANGE_EVENT);
154 	CASE_RETURN_STRING(eSAP_DFS_CAC_START);
155 	CASE_RETURN_STRING(eSAP_DFS_CAC_INTERRUPTED);
156 	CASE_RETURN_STRING(eSAP_DFS_CAC_END);
157 	CASE_RETURN_STRING(eSAP_DFS_PRE_CAC_END);
158 	CASE_RETURN_STRING(eSAP_DFS_RADAR_DETECT);
159 	CASE_RETURN_STRING(eSAP_DFS_RADAR_DETECT_DURING_PRE_CAC);
160 	CASE_RETURN_STRING(eSAP_DFS_NO_AVAILABLE_CHANNEL);
161 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
162 	CASE_RETURN_STRING(eSAP_ACS_SCAN_SUCCESS_EVENT);
163 #endif
164 	CASE_RETURN_STRING(eSAP_ACS_CHANNEL_SELECTED);
165 	CASE_RETURN_STRING(eSAP_ECSA_CHANGE_CHAN_IND);
166 	default:
167 		return "eSAP_HDD_EVENT_UNKNOWN";
168 	}
169 }
170 
171 /*----------------------------------------------------------------------------
172  * Externalized Function Definitions
173  * -------------------------------------------------------------------------*/
174 
175 /*----------------------------------------------------------------------------
176  * Function Declarations and Documentation
177  * -------------------------------------------------------------------------*/
178 
179 /*==========================================================================
180    FUNCTION    sap_event_init
181 
182    DESCRIPTION
183     Function for initializing sWLAN_SAPEvent structure
184 
185    DEPENDENCIES
186     NA.
187 
188    PARAMETERS
189 
190     IN
191     sapEvent    : State machine event
192 
193    RETURN VALUE
194 
195     None
196 
197    SIDE EFFECTS
198    ============================================================================*/
199 static inline void sap_event_init(ptWLAN_SAPEvent sapEvent)
200 {
201 	sapEvent->event = eSAP_MAC_SCAN_COMPLETE;
202 	sapEvent->params = 0;
203 	sapEvent->u1 = 0;
204 	sapEvent->u2 = 0;
205 }
206 
207 #ifdef DFS_COMPONENT_ENABLE
208 /**
209  * sap_random_channel_sel() - This function randomly pick up an available
210  * channel
211  * @sap_ctx: sap context.
212  *
213  * This function first eliminates invalid channel, then selects random channel
214  * using following algorithm:
215  *
216  * Return: channel number picked
217  **/
218 static uint8_t sap_random_channel_sel(struct sap_context *sap_ctx)
219 {
220 	uint8_t ch;
221 	uint8_t ch_wd;
222 	struct wlan_objmgr_pdev *pdev = NULL;
223 	tHalHandle hal;
224 	struct ch_params *ch_params;
225 	uint32_t hw_mode;
226 	tpAniSirGlobal mac_ctx;
227 	struct dfs_acs_info acs_info = {0};
228 
229 	hal = CDS_GET_HAL_CB();
230 	if (!hal) {
231 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
232 			  FL("null hal"));
233 		return 0;
234 	}
235 
236 	mac_ctx = PMAC_STRUCT(hal);
237 	if (!mac_ctx) {
238 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
239 			  FL("null mac_ctx"));
240 		return 0;
241 	}
242 
243 	pdev = mac_ctx->pdev;
244 	if (!pdev) {
245 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
246 			  FL("null pdev"));
247 		return 0;
248 	}
249 
250 	ch_params = &mac_ctx->sap.SapDfsInfo.new_ch_params;
251 	if (mac_ctx->sap.SapDfsInfo.orig_chanWidth == 0) {
252 		ch_wd = sap_ctx->ch_width_orig;
253 		mac_ctx->sap.SapDfsInfo.orig_chanWidth = ch_wd;
254 	} else {
255 		ch_wd = mac_ctx->sap.SapDfsInfo.orig_chanWidth;
256 	}
257 
258 	ch_params->ch_width = ch_wd;
259 	if (sap_ctx->acs_cfg) {
260 		acs_info.acs_mode = sap_ctx->acs_cfg->acs_mode;
261 		acs_info.start_ch = sap_ctx->acs_cfg->start_ch;
262 		acs_info.end_ch = sap_ctx->acs_cfg->end_ch;
263 	} else {
264 		acs_info.acs_mode = false;
265 	}
266 	if (QDF_IS_STATUS_ERROR(utils_dfs_get_random_channel(
267 	    pdev, 0, ch_params, &hw_mode, &ch, &acs_info))) {
268 		/* No available channel found */
269 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
270 			  FL("No available channel found!!!"));
271 		sap_signal_hdd_event(sap_ctx, NULL,
272 				eSAP_DFS_NO_AVAILABLE_CHANNEL,
273 				(void *)eSAP_STATUS_SUCCESS);
274 		return 0;
275 	}
276 	mac_ctx->sap.SapDfsInfo.new_chanWidth = ch_params->ch_width;
277 	sap_ctx->ch_params.ch_width = ch_params->ch_width;
278 	sap_ctx->ch_params.sec_ch_offset = ch_params->sec_ch_offset;
279 	sap_ctx->ch_params.center_freq_seg0 = ch_params->center_freq_seg0;
280 	sap_ctx->ch_params.center_freq_seg1 = ch_params->center_freq_seg1;
281 	return ch;
282 }
283 #else
284 static uint8_t sap_random_channel_sel(struct sap_context *sap_ctx)
285 {
286 	return 0;
287 }
288 #endif
289 
290 /**
291  * sap_is_channel_bonding_etsi_weather_channel() - check weather chan bonding.
292  * @sap_ctx: sap context
293  *
294  * Check if the current SAP operating channel is bonded to weather radar
295  * channel in ETSI domain.
296  *
297  * Return: True if bonded to weather channel in ETSI
298  */
299 static bool
300 sap_is_channel_bonding_etsi_weather_channel(struct sap_context *sap_ctx)
301 {
302 	if (IS_CH_BONDING_WITH_WEATHER_CH(sap_ctx->channel) &&
303 	    (sap_ctx->ch_params.ch_width != CH_WIDTH_20MHZ))
304 		return true;
305 
306 	return false;
307 }
308 
309 /*
310  * sap_get_bonding_channels() - get bonding channels from primary channel.
311  * @sapContext: Handle to SAP context.
312  * @channel: Channel to get bonded channels.
313  * @channels: Bonded channel list
314  * @size: Max bonded channels
315  * @chanBondState: The channel bonding mode of the passed channel.
316  *
317  * Return: Number of sub channels
318  */
319 static uint8_t sap_get_bonding_channels(struct sap_context *sapContext,
320 					uint8_t channel,
321 					uint8_t *channels, uint8_t size,
322 					ePhyChanBondState chanBondState)
323 {
324 	tHalHandle hHal = CDS_GET_HAL_CB();
325 	tpAniSirGlobal pMac;
326 	uint8_t numChannel;
327 
328 	if (channels == NULL)
329 		return 0;
330 
331 	if (size < MAX_BONDED_CHANNELS)
332 		return 0;
333 
334 	if (NULL != hHal)
335 		pMac = PMAC_STRUCT(hHal);
336 	else
337 		return 0;
338 
339 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
340 		  FL("cbmode: %d, channel: %d"), chanBondState, channel);
341 
342 	switch (chanBondState) {
343 	case PHY_SINGLE_CHANNEL_CENTERED:
344 		numChannel = 1;
345 		channels[0] = channel;
346 		break;
347 	case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
348 		numChannel = 2;
349 		channels[0] = channel - 4;
350 		channels[1] = channel;
351 		break;
352 	case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
353 		numChannel = 2;
354 		channels[0] = channel;
355 		channels[1] = channel + 4;
356 		break;
357 	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
358 		numChannel = 4;
359 		channels[0] = channel;
360 		channels[1] = channel + 4;
361 		channels[2] = channel + 8;
362 		channels[3] = channel + 12;
363 		break;
364 	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
365 		numChannel = 4;
366 		channels[0] = channel - 4;
367 		channels[1] = channel;
368 		channels[2] = channel + 4;
369 		channels[3] = channel + 8;
370 		break;
371 	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
372 		numChannel = 4;
373 		channels[0] = channel - 8;
374 		channels[1] = channel - 4;
375 		channels[2] = channel;
376 		channels[3] = channel + 4;
377 		break;
378 	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
379 		numChannel = 4;
380 		channels[0] = channel - 12;
381 		channels[1] = channel - 8;
382 		channels[2] = channel - 4;
383 		channels[3] = channel;
384 		break;
385 	default:
386 		numChannel = 1;
387 		channels[0] = channel;
388 		break;
389 	}
390 
391 	return numChannel;
392 }
393 
394 /**
395  * sap_ch_params_to_bonding_channels() - get bonding channels from channel param
396  * @ch_params: channel params ( bw, pri and sec channel info)
397  * @channels: bonded channel list
398  *
399  * Return: Number of sub channels
400  */
401 static uint8_t sap_ch_params_to_bonding_channels(
402 		struct ch_params *ch_params,
403 		uint8_t *channels)
404 {
405 	uint8_t center_chan = ch_params->center_freq_seg0;
406 	uint8_t nchannels = 0;
407 
408 	switch (ch_params->ch_width) {
409 	case CH_WIDTH_160MHZ:
410 		nchannels = 8;
411 		center_chan = ch_params->center_freq_seg1;
412 		channels[0] = center_chan - 14;
413 		channels[1] = center_chan - 10;
414 		channels[2] = center_chan - 6;
415 		channels[3] = center_chan - 2;
416 		channels[4] = center_chan + 2;
417 		channels[5] = center_chan + 6;
418 		channels[6] = center_chan + 10;
419 		channels[7] = center_chan + 14;
420 		break;
421 	case CH_WIDTH_80P80MHZ:
422 		nchannels = 8;
423 		channels[0] = center_chan - 6;
424 		channels[1] = center_chan - 2;
425 		channels[2] = center_chan + 2;
426 		channels[3] = center_chan + 6;
427 
428 		center_chan = ch_params->center_freq_seg1;
429 		channels[4] = center_chan - 6;
430 		channels[5] = center_chan - 2;
431 		channels[6] = center_chan + 2;
432 		channels[7] = center_chan + 6;
433 		break;
434 	case CH_WIDTH_80MHZ:
435 		nchannels = 4;
436 		channels[0] = center_chan - 6;
437 		channels[1] = center_chan - 2;
438 		channels[2] = center_chan + 2;
439 		channels[3] = center_chan + 6;
440 		break;
441 	case CH_WIDTH_40MHZ:
442 		nchannels = 2;
443 		channels[0] = center_chan - 2;
444 		channels[1] = center_chan + 2;
445 		break;
446 	default:
447 		nchannels = 1;
448 		channels[0] = center_chan;
449 		break;
450 	}
451 
452 	return nchannels;
453 }
454 
455 /**
456  * sap_get_cac_dur_dfs_region() - get cac duration and dfs region.
457  * @sap_ctxt: sap context
458  * @cac_duration_ms: pointer to cac duration
459  * @dfs_region: pointer to dfs region
460  *
461  * Get cac duration and dfs region.
462  *
463  * Return: None
464  */
465 static void sap_get_cac_dur_dfs_region(struct sap_context *sap_ctx,
466 		uint32_t *cac_duration_ms,
467 		uint32_t *dfs_region)
468 {
469 	int i;
470 	uint8_t channels[MAX_BONDED_CHANNELS];
471 	uint8_t num_channels;
472 	struct ch_params *ch_params = &sap_ctx->ch_params;
473 	tHalHandle hal = NULL;
474 	tpAniSirGlobal mac = NULL;
475 
476 	if (!sap_ctx) {
477 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
478 			  "%s: null sap_ctx", __func__);
479 		return;
480 	}
481 
482 	hal = CDS_GET_HAL_CB();
483 	if (!hal) {
484 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
485 			  "%s: null hal", __func__);
486 		return;
487 	}
488 
489 	mac = PMAC_STRUCT(hal);
490 	wlan_reg_get_dfs_region(mac->pdev, dfs_region);
491 	if (mac->sap.SapDfsInfo.ignore_cac) {
492 		*cac_duration_ms = 0;
493 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
494 			  "%s: ignore_cac is set", __func__);
495 		return;
496 	}
497 	*cac_duration_ms = DEFAULT_CAC_TIMEOUT;
498 
499 	if (*dfs_region != DFS_ETSI_REG) {
500 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
501 			 FL("sapdfs: default cac duration"));
502 		return;
503 	}
504 
505 	if (sap_is_channel_bonding_etsi_weather_channel(sap_ctx)) {
506 		*cac_duration_ms = ETSI_WEATHER_CH_CAC_TIMEOUT;
507 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
508 			  FL("sapdfs: bonding_etsi_weather_channel"));
509 		return;
510 	}
511 
512 	qdf_mem_zero(channels, sizeof(channels));
513 	num_channels = sap_ch_params_to_bonding_channels(ch_params, channels);
514 	for (i = 0; i < num_channels; i++) {
515 		if (IS_ETSI_WEATHER_CH(channels[i])) {
516 			*cac_duration_ms = ETSI_WEATHER_CH_CAC_TIMEOUT;
517 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
518 				  FL("sapdfs: ch=%d is etsi weather channel"),
519 				  channels[i]);
520 			return;
521 		}
522 	}
523 
524 }
525 
526 void sap_dfs_set_current_channel(void *ctx)
527 {
528 	struct sap_context *sap_ctx = ctx;
529 	uint32_t ic_flags = 0;
530 	uint16_t ic_flagext = 0;
531 	uint8_t ic_ieee = sap_ctx->channel;
532 	uint16_t ic_freq = utils_dfs_chan_to_freq(sap_ctx->channel);
533 	uint8_t vht_seg0 = sap_ctx->csr_roamProfile.ch_params.center_freq_seg0;
534 	uint8_t vht_seg1 = sap_ctx->csr_roamProfile.ch_params.center_freq_seg1;
535 	struct wlan_objmgr_pdev *pdev;
536 	tpAniSirGlobal mac_ctx;
537 	tHalHandle hal;
538 	uint32_t use_nol = 0;
539 	int error;
540 
541 	hal = CDS_GET_HAL_CB();
542 	if (!hal) {
543 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
544 			FL("null hal"));
545 		return;
546 	}
547 
548 	mac_ctx = PMAC_STRUCT(hal);
549 	pdev = mac_ctx->pdev;
550 	if (!pdev) {
551 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
552 			FL("null pdev"));
553 		return;
554 	}
555 
556 	switch (sap_ctx->csr_roamProfile.ch_params.ch_width) {
557 	case CH_WIDTH_20MHZ:
558 		ic_flags |= IEEE80211_CHAN_VHT20;
559 		break;
560 	case CH_WIDTH_40MHZ:
561 		ic_flags |= IEEE80211_CHAN_VHT40PLUS;
562 		break;
563 	case CH_WIDTH_80MHZ:
564 		ic_flags |= IEEE80211_CHAN_VHT80;
565 		break;
566 	case CH_WIDTH_80P80MHZ:
567 		ic_flags |= IEEE80211_CHAN_VHT80_80;
568 		break;
569 	case CH_WIDTH_160MHZ:
570 		ic_flags |= IEEE80211_CHAN_VHT160;
571 		break;
572 	default:
573 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
574 			  FL("Invalid channel width=%d"),
575 			  sap_ctx->csr_roamProfile.ch_params.ch_width);
576 		return;
577 	}
578 
579 	if (WLAN_REG_IS_24GHZ_CH(sap_ctx->channel))
580 		ic_flags |= IEEE80211_CHAN_2GHZ;
581 	else
582 		ic_flags |= IEEE80211_CHAN_5GHZ;
583 
584 	if (wlan_reg_is_dfs_ch(pdev, sap_ctx->channel))
585 		ic_flagext |= IEEE80211_CHAN_DFS;
586 
587 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
588 		  FL("freq=%d, channel=%d, seg0=%d, seg1=%d, flags=0x%x, ext flags=0x%x"),
589 		  ic_freq, ic_ieee, vht_seg0, vht_seg1, ic_flags, ic_flagext);
590 
591 	tgt_dfs_set_current_channel(pdev, ic_freq, ic_flags,
592 			ic_flagext, ic_ieee, vht_seg0, vht_seg1);
593 
594 	if (wlan_reg_is_dfs_ch(pdev, sap_ctx->channel)) {
595 		if (policy_mgr_concurrent_beaconing_sessions_running(
596 		    mac_ctx->psoc)) {
597 			uint16_t con_ch;
598 
599 			con_ch = sme_get_concurrent_operation_channel(hal);
600 			if (!con_ch || !wlan_reg_is_dfs_ch(pdev, con_ch))
601 				tgt_dfs_get_radars(pdev);
602 		} else {
603 			tgt_dfs_get_radars(pdev);
604 		}
605 		tgt_dfs_set_phyerr_filter_offload(pdev);
606 		if (sap_ctx->csr_roamProfile.disableDFSChSwitch)
607 			tgt_dfs_control(pdev, DFS_SET_USENOL, &use_nol,
608 					sizeof(uint32_t), NULL, NULL, &error);
609 	}
610 }
611 
612 /*
613  * FUNCTION  sap_dfs_is_w53_invalid
614  *
615  * DESCRIPTION Checks if the passed channel is W53 and returns if
616  *             SAP W53 opearation is allowed.
617  *
618  * DEPENDENCIES PARAMETERS
619  * IN hHAL : HAL pointer
620  * channelID: Channel Number to be verified
621  *
622  * RETURN VALUE  : bool
623  *                 true: If W53 operation is disabled
624  *                 false: If W53 operation is enabled
625  *
626  * SIDE EFFECTS
627  */
628 bool sap_dfs_is_w53_invalid(tHalHandle hHal, uint8_t channelID)
629 {
630 	tpAniSirGlobal pMac;
631 
632 	pMac = PMAC_STRUCT(hHal);
633 	if (NULL == pMac) {
634 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
635 			  FL("invalid pMac"));
636 		return false;
637 	}
638 
639 	/*
640 	 * Check for JAPAN W53 Channel operation capability
641 	 */
642 	if (true == pMac->sap.SapDfsInfo.is_dfs_w53_disabled &&
643 	    true == IS_CHAN_JAPAN_W53(channelID)) {
644 		return true;
645 	}
646 
647 	return false;
648 }
649 
650 /*
651  * FUNCTION  sap_dfs_is_channel_in_preferred_location
652  *
653  * DESCRIPTION Checks if the passed channel is in accordance with preferred
654  *          Channel location settings.
655  *
656  * DEPENDENCIES PARAMETERS
657  * IN hHAL : HAL pointer
658  * channelID: Channel Number to be verified
659  *
660  * RETURN VALUE  :bool
661  *        true:If Channel location is same as the preferred location
662  *        false:If Channel location is not same as the preferred location
663  *
664  * SIDE EFFECTS
665  */
666 bool sap_dfs_is_channel_in_preferred_location(tHalHandle hHal, uint8_t channelID)
667 {
668 	tpAniSirGlobal pMac;
669 
670 	pMac = PMAC_STRUCT(hHal);
671 	if (NULL == pMac) {
672 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
673 			  FL("invalid pMac"));
674 		return true;
675 	}
676 	if ((SAP_CHAN_PREFERRED_INDOOR ==
677 	     pMac->sap.SapDfsInfo.sap_operating_chan_preferred_location) &&
678 	    (true == IS_CHAN_JAPAN_OUTDOOR(channelID))) {
679 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
680 			  FL
681 				  ("CHAN=%d is Outdoor so invalid,preferred Indoor only"),
682 			  channelID);
683 		return false;
684 	} else if ((SAP_CHAN_PREFERRED_OUTDOOR ==
685 		    pMac->sap.SapDfsInfo.sap_operating_chan_preferred_location)
686 		   && (true == IS_CHAN_JAPAN_INDOOR(channelID))) {
687 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
688 			  FL
689 				  ("CHAN=%d is Indoor so invalid,preferred Outdoor only"),
690 			  channelID);
691 		return false;
692 	}
693 
694 	return true;
695 }
696 
697 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
698 /**
699  * sap_check_in_avoid_ch_list() - checks if given channel present is channel
700  * avoidance list
701  *
702  * @sap_ctx:        sap context.
703  * @channel:        channel to be checked in sap_ctx's avoid ch list
704  *
705  * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on
706  * which MDM device's AP with MCC was detected. This function checks if given
707  * channel is present in that list.
708  *
709  * Return: true, if channel was present, false othersie.
710  */
711 bool sap_check_in_avoid_ch_list(struct sap_context *sap_ctx, uint8_t channel)
712 {
713 	uint8_t i = 0;
714 	struct sap_avoid_channels_info *ie_info =
715 		&sap_ctx->sap_detected_avoid_ch_ie;
716 	for (i = 0; i < sizeof(ie_info->channels); i++)
717 		if (ie_info->channels[i] == channel)
718 			return true;
719 	return false;
720 }
721 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
722 
723 /**
724  * sap_dfs_is_channel_in_nol_list() - given bonded channel is available
725  * @sap_context: Handle to SAP context.
726  * @channel_number: Channel on which availability should be checked.
727  * @chan_bondState: The channel bonding mode of the passed channel.
728  *
729  * This function Checks if a given bonded channel is available or
730  * usable for DFS operation.
731  *
732  * Return: false if channel is available, true if channel is in NOL.
733  */
734 bool
735 sap_dfs_is_channel_in_nol_list(struct sap_context *sap_context,
736 			       uint8_t channel_number,
737 			       ePhyChanBondState chan_bondState)
738 {
739 	int i;
740 	tHalHandle h_hal = CDS_GET_HAL_CB();
741 	tpAniSirGlobal mac_ctx;
742 	uint8_t channels[MAX_BONDED_CHANNELS];
743 	uint8_t num_channels;
744 	struct wlan_objmgr_pdev *pdev = NULL;
745 	enum channel_state ch_state;
746 
747 	if (!h_hal) {
748 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
749 			  FL("invalid h_hal"));
750 		return false;
751 	} else {
752 		mac_ctx = PMAC_STRUCT(h_hal);
753 	}
754 
755 	/* get the bonded channels */
756 	if (channel_number == sap_context->channel && chan_bondState >=
757 						PHY_CHANNEL_BONDING_STATE_MAX)
758 		num_channels = sap_ch_params_to_bonding_channels(
759 					&sap_context->ch_params, channels);
760 	else
761 		num_channels = sap_get_bonding_channels(sap_context,
762 					channel_number, channels,
763 					MAX_BONDED_CHANNELS, chan_bondState);
764 
765 	pdev = mac_ctx->pdev;
766 	if (!pdev) {
767 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
768 			  FL("null pdev"));
769 		return false;
770 	}
771 
772 	/* check for NOL, first on will break the loop */
773 	for (i = 0; i < num_channels; i++) {
774 		ch_state = wlan_reg_get_channel_state(pdev, channels[i]);
775 		if (CHANNEL_STATE_ENABLE != ch_state &&
776 		    CHANNEL_STATE_DFS != ch_state) {
777 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
778 				  FL("Invalid ch num=%d, ch state=%d"),
779 				  channels[i], ch_state);
780 			return true;
781 		}
782 	} /* loop for bonded channels */
783 
784 	return false;
785 }
786 
787 uint8_t sap_select_default_oper_chan(struct sap_acs_cfg *acs_cfg)
788 {
789 	uint8_t channel;
790 
791 	if (NULL == acs_cfg) {
792 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
793 			"ACS config invalid!");
794 		QDF_BUG(0);
795 		return 0;
796 	}
797 
798 	if (acs_cfg->hw_mode == eCSR_DOT11_MODE_11a) {
799 		channel = SAP_DEFAULT_5GHZ_CHANNEL;
800 	} else if ((acs_cfg->hw_mode == eCSR_DOT11_MODE_11n) ||
801 		   (acs_cfg->hw_mode == eCSR_DOT11_MODE_11n_ONLY) ||
802 		   (acs_cfg->hw_mode == eCSR_DOT11_MODE_11ac) ||
803 		   (acs_cfg->hw_mode == eCSR_DOT11_MODE_11ac_ONLY) ||
804 		   (acs_cfg->hw_mode == eCSR_DOT11_MODE_11ax) ||
805 		   (acs_cfg->hw_mode == eCSR_DOT11_MODE_11ax_ONLY)) {
806 		if (WLAN_REG_IS_5GHZ_CH(acs_cfg->start_ch))
807 			channel = SAP_DEFAULT_5GHZ_CHANNEL;
808 		else
809 			channel = SAP_DEFAULT_24GHZ_CHANNEL;
810 	} else {
811 		channel = SAP_DEFAULT_24GHZ_CHANNEL;
812 	}
813 
814 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
815 			FL("channel selected to start bss %d"), channel);
816 	return channel;
817 }
818 
819 /**
820  * sap_goto_channel_sel - Function for initiating scan request for SME
821  * @sap_context: Sap Context value.
822  * @sap_event: State machine event
823  * @sap_do_acs_pre_start_bss: true, if ACS scan is issued pre start BSS
824  *                            false, if ACS scan is issued post start BSS.
825  * @check_for_connection_update: true, check and wait for connection update
826  *                               false, do not perform connection update
827  *
828  * Initiates sme scan for ACS to pick a channel.
829  *
830  * Return: The QDF_STATUS code associated with performing the operation.
831  */
832 QDF_STATUS sap_goto_channel_sel(struct sap_context *sap_context,
833 	ptWLAN_SAPEvent sap_event,
834 	bool sap_do_acs_pre_start_bss,
835 	bool check_for_connection_update)
836 {
837 
838 	/* Initiate a SCAN request */
839 	QDF_STATUS qdf_ret_status;
840 	/* To be initialised if scan is required */
841 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
842 	tpAniSirGlobal mac_ctx;
843 	struct scan_start_request *req;
844 	struct wlan_objmgr_vdev *vdev;
845 	uint8_t i;
846 	uint8_t pdev_id;
847 
848 #ifdef SOFTAP_CHANNEL_RANGE
849 	uint8_t *channel_list = NULL;
850 	uint8_t num_of_channels = 0;
851 #endif
852 	tHalHandle h_hal;
853 	uint8_t con_ch;
854 	uint8_t vdev_id;
855 	uint32_t scan_id;
856 
857 	h_hal = cds_get_context(QDF_MODULE_ID_SME);
858 	if (NULL == h_hal) {
859 		/* we have a serious problem */
860 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
861 			  FL("invalid h_hal"));
862 		return QDF_STATUS_E_FAULT;
863 	}
864 
865 	mac_ctx = PMAC_STRUCT(h_hal);
866 	if (NULL == mac_ctx) {
867 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
868 				FL("Invalid MAC context"));
869 		return QDF_STATUS_E_FAILURE;
870 	}
871 	if (policy_mgr_concurrent_beaconing_sessions_running(mac_ctx->psoc) ||
872 	   ((sap_context->cc_switch_mode ==
873 		QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) &&
874 	   (policy_mgr_mode_specific_connection_count(mac_ctx->psoc,
875 		PM_SAP_MODE, NULL) ||
876 	     policy_mgr_mode_specific_connection_count(mac_ctx->psoc,
877 		PM_P2P_GO_MODE, NULL)))) {
878 		con_ch =
879 			sme_get_concurrent_operation_channel(h_hal);
880 #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
881 		if (con_ch && sap_context->channel == AUTO_CHANNEL_SELECT) {
882 			sap_context->dfs_ch_disable = true;
883 		} else if (con_ch && sap_context->channel != con_ch &&
884 			   wlan_reg_is_dfs_ch(mac_ctx->pdev,
885 				   sap_context->channel)) {
886 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
887 				  FL("MCC DFS not supported in AP_AP Mode"));
888 			return QDF_STATUS_E_ABORTED;
889 		}
890 #endif
891 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
892 		if (sap_context->cc_switch_mode !=
893 					QDF_MCC_TO_SCC_SWITCH_DISABLE &&
894 					sap_context->channel) {
895 			/*
896 			 * For ACS request ,the sapContext->channel is 0,
897 			 * we skip below overlap checking. When the ACS
898 			 * finish and SAPBSS start, the sapContext->channel
899 			 * will not be 0. Then the overlap checking will be
900 			 * reactivated.If we use sapContext->channel = 0
901 			 * to perform the overlap checking, an invalid overlap
902 			 * channel con_ch could becreated. That may cause
903 			 * SAP start failed.
904 			 */
905 			con_ch = sme_check_concurrent_channel_overlap(h_hal,
906 					sap_context->channel,
907 					sap_context->csr_roamProfile.phyMode,
908 					sap_context->cc_switch_mode);
909 			if (con_ch && !(wlan_reg_is_dfs_ch(mac_ctx->pdev,
910 						con_ch) &&
911 			sap_context->cc_switch_mode ==
912 	QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION)) {
913 				QDF_TRACE(QDF_MODULE_ID_SAP,
914 					QDF_TRACE_LEVEL_ERROR,
915 					"%s: Override ch %d to %d due to CC Intf",
916 					__func__, sap_context->channel, con_ch);
917 				sap_context->channel = con_ch;
918 				wlan_reg_set_channel_params(mac_ctx->pdev,
919 						sap_context->channel, 0,
920 						&sap_context->ch_params);
921 			}
922 		}
923 #endif
924 	}
925 
926 	if ((policy_mgr_get_concurrency_mode(mac_ctx->psoc) ==
927 		(QDF_STA_MASK | QDF_SAP_MASK)) ||
928 		((sap_context->cc_switch_mode ==
929 		QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) &&
930 		(policy_mgr_get_concurrency_mode(mac_ctx->psoc) ==
931 		(QDF_STA_MASK | QDF_P2P_GO_MASK)))) {
932 #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
933 		if (sap_context->channel == AUTO_CHANNEL_SELECT)
934 			sap_context->dfs_ch_disable = true;
935 		else if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
936 					sap_context->channel)) {
937 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
938 				  FL("DFS not supported in STA_AP Mode"));
939 			return QDF_STATUS_E_ABORTED;
940 		}
941 #endif
942 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
943 		if (sap_context->cc_switch_mode !=
944 					QDF_MCC_TO_SCC_SWITCH_DISABLE &&
945 					sap_context->channel) {
946 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
947 				FL("check for overlap: chan:%d mode:%d"),
948 				sap_context->channel,
949 				sap_context->csr_roamProfile.phyMode);
950 			con_ch = sme_check_concurrent_channel_overlap(h_hal,
951 					sap_context->channel,
952 					sap_context->csr_roamProfile.phyMode,
953 					sap_context->cc_switch_mode);
954 			if (sap_context->cc_switch_mode !=
955 		QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) {
956 				if (QDF_IS_STATUS_ERROR(
957 					policy_mgr_valid_sap_conc_channel_check(
958 						mac_ctx->psoc, &con_ch,
959 						sap_context->channel)))	{
960 					QDF_TRACE(QDF_MODULE_ID_SAP,
961 						QDF_TRACE_LEVEL_WARN,
962 						FL("SAP can't start (no MCC)"));
963 					return QDF_STATUS_E_ABORTED;
964 				}
965 			}
966 			if (con_ch && !wlan_reg_is_dfs_ch(mac_ctx->pdev,
967 						con_ch)) {
968 				QDF_TRACE(QDF_MODULE_ID_SAP,
969 					QDF_TRACE_LEVEL_ERROR,
970 					"%s: Override ch %d to %d due to CC Intf",
971 					__func__, sap_context->channel, con_ch);
972 				sap_context->channel = con_ch;
973 				wlan_reg_set_channel_params(mac_ctx->pdev,
974 						sap_context->channel, 0,
975 						&sap_context->ch_params);
976 			}
977 		}
978 #endif
979 	}
980 
981 	if (sap_context->channel == AUTO_CHANNEL_SELECT) {
982 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
983 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
984 			  FL("%s skip_acs_status = %d "), __func__,
985 			  sap_context->acs_cfg->skip_scan_status);
986 		if (sap_context->acs_cfg->skip_scan_status !=
987 						eSAP_SKIP_ACS_SCAN) {
988 #endif
989 
990 		req = qdf_mem_malloc(sizeof(*req));
991 		if (!req) {
992 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
993 			  FL("Failed to allocate memory"));
994 			return QDF_STATUS_E_NOMEM;
995 		}
996 
997 		pdev_id = wlan_objmgr_pdev_get_pdev_id(mac_ctx->pdev);
998 		vdev = wlan_objmgr_get_vdev_by_macaddr_from_psoc(mac_ctx->psoc,
999 						pdev_id,
1000 						sap_context->self_mac_addr,
1001 						WLAN_LEGACY_SME_ID);
1002 		if (!vdev) {
1003 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1004 				  FL("Invalid vdev objmgr"));
1005 			return QDF_STATUS_E_INVAL;
1006 		}
1007 
1008 		ucfg_scan_init_default_params(vdev, req);
1009 		req->scan_req.dwell_time_active = 0;
1010 		scan_id = ucfg_scan_get_scan_id(mac_ctx->psoc);
1011 		req->scan_req.scan_id = scan_id;
1012 		vdev_id = wlan_vdev_get_id(vdev);
1013 		req->scan_req.vdev_id = vdev_id;
1014 		req->scan_req.scan_req_id = sap_context->req_id;
1015 		sap_get_channel_list(sap_context, &channel_list,
1016 				  &num_of_channels);
1017 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
1018 		if (num_of_channels != 0) {
1019 #endif
1020 
1021 		req->scan_req.chan_list.num_chan = num_of_channels;
1022 		for (i = 0; i < num_of_channels; i++)
1023 			req->scan_req.chan_list.chan[i].freq =
1024 				wlan_chan_to_freq(channel_list[i]);
1025 		if (sap_context->channelList) {
1026 			qdf_mem_free(sap_context->channelList);
1027 			sap_context->channelList = NULL;
1028 			sap_context->num_of_channel = 0;
1029 		}
1030 		sap_context->channelList = channel_list;
1031 		sap_context->num_of_channel = num_of_channels;
1032 		/* Set requestType to Full scan */
1033 
1034 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1035 			  FL("calling ucfg_scan_start"));
1036 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
1037 		if (sap_context->acs_cfg->skip_scan_status ==
1038 			eSAP_DO_NEW_ACS_SCAN)
1039 #endif
1040 			sme_scan_flush_result(h_hal);
1041 		sap_context->sap_acs_pre_start_bss = sap_do_acs_pre_start_bss;
1042 		qdf_ret_status = ucfg_scan_start(req);
1043 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
1044 
1045 		if (QDF_STATUS_SUCCESS != qdf_ret_status) {
1046 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1047 				  FL("scan request  fail %d!!!"),
1048 				  qdf_ret_status);
1049 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1050 				  FL("SAP Configuring default channel, Ch=%d"),
1051 				  sap_context->channel);
1052 			sap_context->channel = sap_select_default_oper_chan(
1053 					sap_context->acs_cfg);
1054 
1055 #ifdef SOFTAP_CHANNEL_RANGE
1056 			if (sap_context->channelList != NULL) {
1057 				sap_context->channel =
1058 					sap_context->channelList[0];
1059 				qdf_mem_free(sap_context->
1060 					channelList);
1061 				sap_context->channelList = NULL;
1062 				sap_context->num_of_channel = 0;
1063 			}
1064 #endif
1065 			if (true == sap_do_acs_pre_start_bss) {
1066 				/*
1067 				* In case of ACS req before start Bss,
1068 				* return failure so that the calling
1069 				* function can use the default channel.
1070 				*/
1071 				return QDF_STATUS_E_FAILURE;
1072 			} else {
1073 				/* Fill in the event structure */
1074 				sap_event_init(sap_event);
1075 				/* Handle event */
1076 				qdf_status = sap_fsm(sap_context, sap_event);
1077 			}
1078 		} else {
1079 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1080 				 FL("return sme_ScanReq, scanID=%d, Ch=%d"),
1081 				 scan_id,
1082 				 sap_context->channel);
1083 			host_log_acs_scan_start(scan_id, vdev_id);
1084 		}
1085 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
1086 		}
1087 	} else {
1088 		sap_context->acs_cfg->skip_scan_status = eSAP_SKIP_ACS_SCAN;
1089 	}
1090 
1091 	if (sap_context->acs_cfg->skip_scan_status == eSAP_SKIP_ACS_SCAN) {
1092 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1093 			  FL("## %s SKIPPED ACS SCAN"), __func__);
1094 
1095 		if (true == sap_do_acs_pre_start_bss)
1096 			wlansap_pre_start_bss_acs_scan_callback(h_hal,
1097 				sap_context, sap_context->sessionId, 0,
1098 				eCSR_SCAN_SUCCESS);
1099 		else
1100 			wlansap_scan_callback(h_hal, sap_context,
1101 				sap_context->sessionId, 0, eCSR_SCAN_SUCCESS);
1102 	}
1103 #endif
1104 	} else {
1105 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1106 			  FL("for configured channel, Ch= %d"),
1107 			  sap_context->channel);
1108 
1109 		if (check_for_connection_update) {
1110 			/* This wait happens in the hostapd context. The event
1111 			 * is set in the MC thread context.
1112 			 */
1113 			qdf_status =
1114 			policy_mgr_update_and_wait_for_connection_update(
1115 					mac_ctx->psoc,
1116 					sap_context->sessionId,
1117 					sap_context->channel,
1118 					POLICY_MGR_UPDATE_REASON_START_AP);
1119 			if (QDF_IS_STATUS_ERROR(qdf_status))
1120 				return qdf_status;
1121 		}
1122 
1123 		if (sap_do_acs_pre_start_bss == true) {
1124 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
1125 				FL("ACS end due to Ch override. Sel Ch = %d"),
1126 							sap_context->channel);
1127 			sap_context->acs_cfg->pri_ch = sap_context->channel;
1128 			sap_context->acs_cfg->ch_width =
1129 						 sap_context->ch_width_orig;
1130 			sap_config_acs_result(h_hal, sap_context, 0);
1131 			return QDF_STATUS_E_CANCELED;
1132 		} else {
1133 			/*
1134 			 * Fill in the event structure
1135 			 * Eventhough scan was not done,
1136 			 * means a user set channel was chosen
1137 			 */
1138 			sap_event_init(sap_event);
1139 			/* Handle event */
1140 			qdf_status = sap_fsm(sap_context, sap_event);
1141 		}
1142 	}
1143 
1144 	/*
1145 	 * If scan failed, get default channel and advance state
1146 	 * machine as success with default channel
1147 	 *
1148 	 * Have to wait for the call back to be called to get the
1149 	 * channel cannot advance state machine here as said above
1150 	 */
1151 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1152 		  FL("before exiting sap_goto_channel_sel channel=%d"),
1153 		  sap_context->channel);
1154 
1155 	return QDF_STATUS_SUCCESS;
1156 }
1157 
1158 /**
1159  * sap_find_valid_concurrent_session() - to find valid concurrent session
1160  * @hal: pointer to hal abstration layer
1161  *
1162  * This API will check if any valid concurrent SAP session is present
1163  *
1164  * Return: pointer to sap context of valid concurrent session
1165  */
1166 static struct sap_context *sap_find_valid_concurrent_session(tHalHandle hal)
1167 {
1168 	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
1169 	uint8_t intf = 0;
1170 	struct sap_context *sap_ctx;
1171 
1172 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
1173 		if (((QDF_SAP_MODE ==
1174 				mac_ctx->sap.sapCtxList[intf].sapPersona) ||
1175 		     (QDF_P2P_GO_MODE ==
1176 				mac_ctx->sap.sapCtxList[intf].sapPersona)) &&
1177 		    mac_ctx->sap.sapCtxList[intf].sap_context != NULL) {
1178 			sap_ctx = mac_ctx->sap.sapCtxList[intf].sap_context;
1179 			if (sap_ctx->sapsMachine != eSAP_DISCONNECTED)
1180 				return sap_ctx;
1181 		}
1182 	}
1183 
1184 	return NULL;
1185 }
1186 
1187 static QDF_STATUS sap_clear_global_dfs_param(tHalHandle hal)
1188 {
1189 	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
1190 
1191 	if (NULL != sap_find_valid_concurrent_session(hal)) {
1192 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
1193 			  "conc session exists, no need to clear dfs struct");
1194 		return QDF_STATUS_SUCCESS;
1195 	}
1196 	/*
1197 	 * CAC timer will be initiated and started only when SAP starts
1198 	 * on DFS channel and it will be stopped and destroyed
1199 	 * immediately once the radar detected or timedout. So
1200 	 * as per design CAC timer should be destroyed after stop
1201 	 */
1202 	if (mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) {
1203 		qdf_mc_timer_stop(&mac_ctx->sap.SapDfsInfo.sap_dfs_cac_timer);
1204 		mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
1205 		qdf_mc_timer_destroy(
1206 			&mac_ctx->sap.SapDfsInfo.sap_dfs_cac_timer);
1207 	}
1208 	mac_ctx->sap.SapDfsInfo.cac_state = eSAP_DFS_DO_NOT_SKIP_CAC;
1209 	sap_cac_reset_notify(hal);
1210 	qdf_mem_zero(&mac_ctx->sap, sizeof(mac_ctx->sap));
1211 
1212 	return QDF_STATUS_SUCCESS;
1213 }
1214 
1215 QDF_STATUS sap_set_session_param(tHalHandle hal, struct sap_context *sapctx,
1216 				uint32_t session_id)
1217 {
1218 	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
1219 	int i;
1220 
1221 	sapctx->sessionId = session_id;
1222 	sapctx->is_pre_cac_on = false;
1223 	sapctx->pre_cac_complete = false;
1224 	sapctx->chan_before_pre_cac = 0;
1225 
1226 	/* When SSR, SAP will restart, clear the old context,sessionId */
1227 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
1228 		if (mac_ctx->sap.sapCtxList[i].sap_context == sapctx)
1229 			mac_ctx->sap.sapCtxList[i].sap_context = NULL;
1230 	}
1231 	mac_ctx->sap.sapCtxList[sapctx->sessionId].sessionID =
1232 				sapctx->sessionId;
1233 	mac_ctx->sap.sapCtxList[sapctx->sessionId].sap_context = sapctx;
1234 	mac_ctx->sap.sapCtxList[sapctx->sessionId].sapPersona =
1235 				sapctx->csr_roamProfile.csrPersona;
1236 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
1237 		"%s: Initializing sapContext = %pK with session = %d", __func__,
1238 		sapctx, session_id);
1239 
1240 	return QDF_STATUS_SUCCESS;
1241 }
1242 
1243 QDF_STATUS sap_clear_session_param(tHalHandle hal, struct sap_context *sapctx,
1244 				uint32_t session_id)
1245 {
1246 	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
1247 
1248 	if (sapctx->sessionId >= SAP_MAX_NUM_SESSION)
1249 		return QDF_STATUS_E_FAILURE;
1250 
1251 	mac_ctx->sap.sapCtxList[sapctx->sessionId].sessionID =
1252 		CSR_SESSION_ID_INVALID;
1253 	mac_ctx->sap.sapCtxList[sapctx->sessionId].sap_context = NULL;
1254 	mac_ctx->sap.sapCtxList[sapctx->sessionId].sapPersona =
1255 		QDF_MAX_NO_OF_MODE;
1256 	sap_clear_global_dfs_param(hal);
1257 	sap_free_roam_profile(&sapctx->csr_roamProfile);
1258 	qdf_mem_zero(sapctx, sizeof(*sapctx));
1259 	sapctx->sessionId = CSR_SESSION_ID_INVALID;
1260 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
1261 		"%s: Initializing State: %d, sapContext value = %pK", __func__,
1262 		sapctx->sapsMachine, sapctx);
1263 
1264 	return QDF_STATUS_SUCCESS;
1265 }
1266 
1267 /*==========================================================================
1268    FUNCTION    sapGotoStarting
1269 
1270    DESCRIPTION
1271     Function for initiating start bss request for SME
1272 
1273    DEPENDENCIES
1274     NA.
1275 
1276    PARAMETERS
1277 
1278     IN
1279     sapContext  : Sap Context value
1280     sapEvent    : State machine event
1281     bssType     : Type of bss to start, INRA AP
1282     status      : Return the SAP status here
1283 
1284    RETURN VALUE
1285     The QDF_STATUS code associated with performing the operation
1286 
1287     QDF_STATUS_SUCCESS: Success
1288 
1289    SIDE EFFECTS
1290    ============================================================================*/
1291 static QDF_STATUS sap_goto_starting(struct sap_context *sapContext,
1292 				    ptWLAN_SAPEvent sapEvent,
1293 				    eCsrRoamBssType bssType)
1294 {
1295 	/* tHalHandle */
1296 	tHalHandle hHal = CDS_GET_HAL_CB();
1297 	QDF_STATUS qdf_ret_status;
1298 
1299 	/*- - - - - - - - TODO:once configs from hdd available - - - - - - - - -*/
1300 	char key_material[32] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3,
1301 		4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, };
1302 	sapContext->key_type = 0x05;
1303 	sapContext->key_length = 32;
1304 	/* Need a key size define */
1305 	qdf_mem_copy(sapContext->key_material, key_material,
1306 		     sizeof(key_material));
1307 
1308 	if (NULL == hHal) {
1309 		/* we have a serious problem */
1310 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
1311 			  "In %s, invalid hHal", __func__);
1312 		return QDF_STATUS_E_FAULT;
1313 	}
1314 
1315 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, "%s: session: %d",
1316 		  __func__, sapContext->sessionId);
1317 
1318 	qdf_ret_status = sme_roam_connect(hHal, sapContext->sessionId,
1319 					  &sapContext->csr_roamProfile,
1320 					  &sapContext->csr_roamId);
1321 	if (QDF_STATUS_SUCCESS != qdf_ret_status)
1322 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1323 			"%s: Failed to issue sme_roam_connect", __func__);
1324 
1325 	return qdf_ret_status;
1326 } /* sapGotoStarting */
1327 
1328 /*==========================================================================
1329    FUNCTION    sapGotoDisconnecting
1330 
1331    DESCRIPTION
1332     Processing of SAP FSM Disconnecting state
1333 
1334    DEPENDENCIES
1335     NA.
1336 
1337    PARAMETERS
1338 
1339     IN
1340     sapContext  : Sap Context value
1341     status      : Return the SAP status here
1342 
1343    RETURN VALUE
1344     The QDF_STATUS code associated with performing the operation
1345 
1346     QDF_STATUS_SUCCESS: Success
1347 
1348    SIDE EFFECTS
1349    ============================================================================*/
1350 static QDF_STATUS sap_goto_disconnecting(struct sap_context *sapContext)
1351 {
1352 	QDF_STATUS qdf_ret_status;
1353 	tHalHandle hHal;
1354 
1355 	hHal = CDS_GET_HAL_CB();
1356 	if (NULL == hHal) {
1357 		/* we have a serious problem */
1358 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1359 			  "In %s, invalid hHal", __func__);
1360 		return QDF_STATUS_E_FAULT;
1361 	}
1362 
1363 	sap_free_roam_profile(&sapContext->csr_roamProfile);
1364 	qdf_ret_status = sme_roam_stop_bss(hHal, sapContext->sessionId);
1365 	if (QDF_STATUS_SUCCESS != qdf_ret_status) {
1366 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1367 			  "Error: In %s calling sme_roam_stop_bss status = %d",
1368 			  __func__, qdf_ret_status);
1369 		return QDF_STATUS_E_FAILURE;
1370 	}
1371 
1372 	return QDF_STATUS_SUCCESS;
1373 }
1374 
1375 /*==========================================================================
1376    FUNCTION    sapGotoDisconnected
1377 
1378    DESCRIPTION
1379     Function for setting the SAP FSM to Disconnection state
1380 
1381    DEPENDENCIES
1382     NA.
1383 
1384    PARAMETERS
1385 
1386     IN
1387     sapContext  : Sap Context value
1388     sapEvent    : State machine event
1389     status      : Return the SAP status here
1390 
1391    RETURN VALUE
1392     The QDF_STATUS code associated with performing the operation
1393 
1394     QDF_STATUS_SUCCESS: Success
1395 
1396    SIDE EFFECTS
1397    ============================================================================*/
1398 static QDF_STATUS sap_goto_disconnected(struct sap_context *sapContext)
1399 {
1400 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
1401 	tWLAN_SAPEvent sapEvent;
1402 	/* Processing has to be coded */
1403 	/* Clean up stations from TL etc as AP BSS is shut down then set event */
1404 	sapEvent.event = eSAP_MAC_READY_FOR_CONNECTIONS;        /* hardcoded */
1405 	sapEvent.params = 0;
1406 	sapEvent.u1 = 0;
1407 	sapEvent.u2 = 0;
1408 	/* Handle event */
1409 	qdf_status = sap_fsm(sapContext, &sapEvent);
1410 
1411 	return qdf_status;
1412 }
1413 
1414 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
1415 /**
1416  * sap_handle_acs_scan_event() - handle acs scan event for SAP
1417  * @sap_context: ptSapContext
1418  * @sap_event: tSap_Event
1419  * @status: status of acs scan
1420  *
1421  * The function is to handle the eSAP_ACS_SCAN_SUCCESS_EVENT event.
1422  *
1423  * Return: void
1424  */
1425 static void sap_handle_acs_scan_event(struct sap_context *sap_context,
1426 		tSap_Event *sap_event, eSapStatus status)
1427 {
1428 	sap_event->sapHddEventCode = eSAP_ACS_SCAN_SUCCESS_EVENT;
1429 	sap_event->sapevt.sap_acs_scan_comp.status = status;
1430 	sap_event->sapevt.sap_acs_scan_comp.num_of_channels =
1431 			sap_context->num_of_channel;
1432 	sap_event->sapevt.sap_acs_scan_comp.channellist =
1433 			sap_context->channelList;
1434 }
1435 #else
1436 static void sap_handle_acs_scan_event(struct sap_context *sap_context,
1437 		tSap_Event *sap_event, eSapStatus status)
1438 {
1439 }
1440 #endif
1441 
1442 /**
1443  * sap_signal_hdd_event() - send event notification
1444  * @sap_ctx: Sap Context
1445  * @csr_roaminfo: Pointer to CSR roam information
1446  * @sap_hddevent: SAP HDD event
1447  * @context: to pass the element for future support
1448  *
1449  * Function for HDD to send the event notification using callback
1450  *
1451  * Return: QDF_STATUS
1452  */
1453 QDF_STATUS sap_signal_hdd_event(struct sap_context *sap_ctx,
1454 		struct csr_roam_info *csr_roaminfo, eSapHddEvent sap_hddevent,
1455 		void *context)
1456 {
1457 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
1458 	tSap_Event sap_ap_event = {0};
1459 	tHalHandle hal = CDS_GET_HAL_CB();
1460 	tpAniSirGlobal mac_ctx;
1461 	tSirSmeChanInfo *chaninfo;
1462 	tSap_StationAssocIndication *assoc_ind;
1463 	tSap_StartBssCompleteEvent *bss_complete;
1464 	struct sap_ch_selected_s *acs_selected;
1465 	tSap_StationAssocReassocCompleteEvent *reassoc_complete;
1466 	tSap_StationDisassocCompleteEvent *disassoc_comp;
1467 	tSap_StationSetKeyCompleteEvent *key_complete;
1468 	tSap_StationMICFailureEvent *mic_failure;
1469 
1470 	/* Format the Start BSS Complete event to return... */
1471 	if (NULL == sap_ctx->pfnSapEventCallback) {
1472 		return QDF_STATUS_E_FAILURE;
1473 	}
1474 	if (NULL == hal) {
1475 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1476 			  FL("Invalid hal"));
1477 		return QDF_STATUS_E_FAILURE;
1478 	}
1479 	mac_ctx = PMAC_STRUCT(hal);
1480 	if (NULL == mac_ctx) {
1481 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1482 			  FL("Invalid MAC context"));
1483 		return QDF_STATUS_E_FAILURE;
1484 	}
1485 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1486 		  FL("SAP event callback event = %s"),
1487 		  sap_hdd_event_to_string(sap_hddevent));
1488 
1489 	switch (sap_hddevent) {
1490 	case eSAP_STA_ASSOC_IND:
1491 		if (!csr_roaminfo) {
1492 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1493 				  FL("Invalid CSR Roam Info"));
1494 			return QDF_STATUS_E_INVAL;
1495 		}
1496 		/*  TODO - Indicate the assoc request indication to OS */
1497 		sap_ap_event.sapHddEventCode = eSAP_STA_ASSOC_IND;
1498 		assoc_ind = &sap_ap_event.sapevt.sapAssocIndication;
1499 
1500 		qdf_copy_macaddr(&assoc_ind->staMac, &csr_roaminfo->peerMac);
1501 		assoc_ind->staId = csr_roaminfo->staId;
1502 		assoc_ind->status = 0;
1503 		/* Required for indicating the frames to upper layer */
1504 		assoc_ind->beaconLength = csr_roaminfo->beaconLength;
1505 		assoc_ind->beaconPtr = csr_roaminfo->beaconPtr;
1506 		assoc_ind->assocReqLength = csr_roaminfo->assocReqLength;
1507 		assoc_ind->assocReqPtr = csr_roaminfo->assocReqPtr;
1508 		assoc_ind->fWmmEnabled = csr_roaminfo->wmmEnabledSta;
1509 		assoc_ind->ecsa_capable = csr_roaminfo->ecsa_capable;
1510 		if (csr_roaminfo->u.pConnectedProfile != NULL) {
1511 			assoc_ind->negotiatedAuthType =
1512 				csr_roaminfo->u.pConnectedProfile->AuthType;
1513 			assoc_ind->negotiatedUCEncryptionType =
1514 			    csr_roaminfo->u.pConnectedProfile->EncryptionType;
1515 			assoc_ind->negotiatedMCEncryptionType =
1516 			    csr_roaminfo->u.pConnectedProfile->mcEncryptionType;
1517 			assoc_ind->fAuthRequired = csr_roaminfo->fAuthRequired;
1518 		}
1519 		break;
1520 	case eSAP_START_BSS_EVENT:
1521 		sap_ap_event.sapHddEventCode = eSAP_START_BSS_EVENT;
1522 		bss_complete = &sap_ap_event.sapevt.sapStartBssCompleteEvent;
1523 
1524 		bss_complete->status = (eSapStatus) context;
1525 		bss_complete->staId = sap_ctx->sap_sta_id;
1526 
1527 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1528 			  FL("(eSAP_START_BSS_EVENT): staId = %d"),
1529 			  bss_complete->staId);
1530 
1531 		bss_complete->operatingChannel = (uint8_t) sap_ctx->channel;
1532 		bss_complete->sessionId = sap_ctx->sessionId;
1533 		break;
1534 	case eSAP_DFS_CAC_START:
1535 	case eSAP_DFS_CAC_INTERRUPTED:
1536 	case eSAP_DFS_CAC_END:
1537 	case eSAP_DFS_PRE_CAC_END:
1538 	case eSAP_DFS_RADAR_DETECT:
1539 	case eSAP_DFS_RADAR_DETECT_DURING_PRE_CAC:
1540 	case eSAP_DFS_NO_AVAILABLE_CHANNEL:
1541 		sap_ap_event.sapHddEventCode = sap_hddevent;
1542 		sap_ap_event.sapevt.sapStopBssCompleteEvent.status =
1543 			(eSapStatus) context;
1544 		break;
1545 	case eSAP_ACS_SCAN_SUCCESS_EVENT:
1546 		sap_handle_acs_scan_event(sap_ctx, &sap_ap_event,
1547 			(eSapStatus)context);
1548 		break;
1549 	case eSAP_ACS_CHANNEL_SELECTED:
1550 		sap_ap_event.sapHddEventCode = sap_hddevent;
1551 		acs_selected = &sap_ap_event.sapevt.sap_ch_selected;
1552 		if (eSAP_STATUS_SUCCESS == (eSapStatus)context) {
1553 			acs_selected->pri_ch = sap_ctx->acs_cfg->pri_ch;
1554 			acs_selected->ht_sec_ch = sap_ctx->acs_cfg->ht_sec_ch;
1555 			acs_selected->ch_width = sap_ctx->acs_cfg->ch_width;
1556 			acs_selected->vht_seg0_center_ch =
1557 				sap_ctx->acs_cfg->vht_seg0_center_ch;
1558 			acs_selected->vht_seg1_center_ch =
1559 				sap_ctx->acs_cfg->vht_seg1_center_ch;
1560 		} else if (eSAP_STATUS_FAILURE == (eSapStatus)context) {
1561 			acs_selected->pri_ch = 0;
1562 		}
1563 		break;
1564 
1565 	case eSAP_STOP_BSS_EVENT:
1566 		sap_ap_event.sapHddEventCode = eSAP_STOP_BSS_EVENT;
1567 		sap_ap_event.sapevt.sapStopBssCompleteEvent.status =
1568 			(eSapStatus) context;
1569 		break;
1570 
1571 	case eSAP_STA_ASSOC_EVENT:
1572 	case eSAP_STA_REASSOC_EVENT:
1573 
1574 		if (!csr_roaminfo) {
1575 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1576 				  FL("Invalid CSR Roam Info"));
1577 			return QDF_STATUS_E_INVAL;
1578 		}
1579 		if (eSAP_DISCONNECTING == sap_ctx->sapsMachine) {
1580 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1581 				  "SAP is disconnecting, not able to handle any incoming (re)assoc req");
1582 			return QDF_STATUS_E_ABORTED;
1583 		}
1584 
1585 		reassoc_complete =
1586 		    &sap_ap_event.sapevt.sapStationAssocReassocCompleteEvent;
1587 
1588 		if (csr_roaminfo->fReassocReq)
1589 			sap_ap_event.sapHddEventCode = eSAP_STA_REASSOC_EVENT;
1590 		else
1591 			sap_ap_event.sapHddEventCode = eSAP_STA_ASSOC_EVENT;
1592 
1593 		qdf_copy_macaddr(&reassoc_complete->staMac,
1594 				 &csr_roaminfo->peerMac);
1595 		reassoc_complete->staId = csr_roaminfo->staId;
1596 		reassoc_complete->statusCode = csr_roaminfo->statusCode;
1597 		reassoc_complete->iesLen = csr_roaminfo->rsnIELen;
1598 		qdf_mem_copy(reassoc_complete->ies, csr_roaminfo->prsnIE,
1599 			     csr_roaminfo->rsnIELen);
1600 
1601 #ifdef FEATURE_WLAN_WAPI
1602 		if (csr_roaminfo->wapiIELen) {
1603 			uint8_t len = reassoc_complete->iesLen;
1604 
1605 			reassoc_complete->iesLen += csr_roaminfo->wapiIELen;
1606 			qdf_mem_copy(&reassoc_complete->ies[len],
1607 				     csr_roaminfo->pwapiIE,
1608 				     csr_roaminfo->wapiIELen);
1609 		}
1610 #endif
1611 		if (csr_roaminfo->addIELen) {
1612 			uint8_t len = reassoc_complete->iesLen;
1613 
1614 			reassoc_complete->iesLen += csr_roaminfo->addIELen;
1615 			qdf_mem_copy(&reassoc_complete->ies[len],
1616 				     csr_roaminfo->paddIE,
1617 				     csr_roaminfo->addIELen);
1618 			if (wlan_get_vendor_ie_ptr_from_oui(
1619 			    SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE,
1620 			    csr_roaminfo->paddIE, csr_roaminfo->addIELen)) {
1621 				reassoc_complete->staType = eSTA_TYPE_P2P_CLI;
1622 			} else {
1623 				reassoc_complete->staType = eSTA_TYPE_INFRA;
1624 			}
1625 		}
1626 
1627 		/* also fill up the channel info from the csr_roamInfo */
1628 		chaninfo = &reassoc_complete->chan_info;
1629 
1630 		chaninfo->chan_id = csr_roaminfo->chan_info.chan_id;
1631 		chaninfo->mhz = csr_roaminfo->chan_info.mhz;
1632 		chaninfo->info = csr_roaminfo->chan_info.info;
1633 		chaninfo->band_center_freq1 =
1634 			csr_roaminfo->chan_info.band_center_freq1;
1635 		chaninfo->band_center_freq2 =
1636 			csr_roaminfo->chan_info.band_center_freq2;
1637 		chaninfo->reg_info_1 =
1638 			csr_roaminfo->chan_info.reg_info_1;
1639 		chaninfo->reg_info_2 =
1640 			csr_roaminfo->chan_info.reg_info_2;
1641 		chaninfo->nss = csr_roaminfo->chan_info.nss;
1642 		chaninfo->rate_flags = csr_roaminfo->chan_info.rate_flags;
1643 
1644 		reassoc_complete->wmmEnabled = csr_roaminfo->wmmEnabledSta;
1645 		reassoc_complete->status = (eSapStatus) context;
1646 		reassoc_complete->timingMeasCap = csr_roaminfo->timingMeasCap;
1647 		reassoc_complete->ampdu = csr_roaminfo->ampdu;
1648 		reassoc_complete->sgi_enable = csr_roaminfo->sgi_enable;
1649 		reassoc_complete->tx_stbc = csr_roaminfo->tx_stbc;
1650 		reassoc_complete->rx_stbc = csr_roaminfo->rx_stbc;
1651 		reassoc_complete->ch_width = csr_roaminfo->ch_width;
1652 		reassoc_complete->mode = csr_roaminfo->mode;
1653 		reassoc_complete->max_supp_idx = csr_roaminfo->max_supp_idx;
1654 		reassoc_complete->max_ext_idx = csr_roaminfo->max_ext_idx;
1655 		reassoc_complete->max_mcs_idx = csr_roaminfo->max_mcs_idx;
1656 		reassoc_complete->rx_mcs_map = csr_roaminfo->rx_mcs_map;
1657 		reassoc_complete->tx_mcs_map = csr_roaminfo->tx_mcs_map;
1658 		reassoc_complete->ecsa_capable = csr_roaminfo->ecsa_capable;
1659 		if (csr_roaminfo->ht_caps.present)
1660 			reassoc_complete->ht_caps = csr_roaminfo->ht_caps;
1661 		if (csr_roaminfo->vht_caps.present)
1662 			reassoc_complete->vht_caps = csr_roaminfo->vht_caps;
1663 
1664 		break;
1665 
1666 	case eSAP_STA_DISASSOC_EVENT:
1667 		if (!csr_roaminfo) {
1668 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1669 				  FL("Invalid CSR Roam Info"));
1670 			return QDF_STATUS_E_INVAL;
1671 		}
1672 		sap_ap_event.sapHddEventCode = eSAP_STA_DISASSOC_EVENT;
1673 		disassoc_comp =
1674 			&sap_ap_event.sapevt.sapStationDisassocCompleteEvent;
1675 
1676 		qdf_copy_macaddr(&disassoc_comp->staMac,
1677 				 &csr_roaminfo->peerMac);
1678 		disassoc_comp->staId = csr_roaminfo->staId;
1679 		if (csr_roaminfo->reasonCode == eCSR_ROAM_RESULT_FORCED)
1680 			disassoc_comp->reason = eSAP_USR_INITATED_DISASSOC;
1681 		else
1682 			disassoc_comp->reason = eSAP_MAC_INITATED_DISASSOC;
1683 
1684 		disassoc_comp->statusCode = csr_roaminfo->statusCode;
1685 		disassoc_comp->status = (eSapStatus) context;
1686 		disassoc_comp->rssi = csr_roaminfo->rssi;
1687 		disassoc_comp->rx_rate = csr_roaminfo->rx_rate;
1688 		disassoc_comp->tx_rate = csr_roaminfo->tx_rate;
1689 		disassoc_comp->reason_code = csr_roaminfo->disassoc_reason;
1690 		break;
1691 
1692 	case eSAP_STA_SET_KEY_EVENT:
1693 
1694 		if (!csr_roaminfo) {
1695 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1696 				  FL("Invalid CSR Roam Info"));
1697 			return QDF_STATUS_E_INVAL;
1698 		}
1699 		sap_ap_event.sapHddEventCode = eSAP_STA_SET_KEY_EVENT;
1700 		key_complete =
1701 			&sap_ap_event.sapevt.sapStationSetKeyCompleteEvent;
1702 		key_complete->status = (eSapStatus) context;
1703 		qdf_copy_macaddr(&key_complete->peerMacAddr,
1704 				 &csr_roaminfo->peerMac);
1705 		break;
1706 
1707 	case eSAP_STA_MIC_FAILURE_EVENT:
1708 
1709 		if (!csr_roaminfo) {
1710 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1711 				  FL("Invalid CSR Roam Info"));
1712 			return QDF_STATUS_E_INVAL;
1713 		}
1714 		sap_ap_event.sapHddEventCode = eSAP_STA_MIC_FAILURE_EVENT;
1715 		mic_failure = &sap_ap_event.sapevt.sapStationMICFailureEvent;
1716 
1717 		qdf_mem_copy(&mic_failure->srcMacAddr,
1718 			     csr_roaminfo->u.pMICFailureInfo->srcMacAddr,
1719 			     sizeof(tSirMacAddr));
1720 		qdf_mem_copy(&mic_failure->staMac.bytes,
1721 			     csr_roaminfo->u.pMICFailureInfo->taMacAddr,
1722 			     sizeof(tSirMacAddr));
1723 		qdf_mem_copy(&mic_failure->dstMacAddr.bytes,
1724 			     csr_roaminfo->u.pMICFailureInfo->dstMacAddr,
1725 			     sizeof(tSirMacAddr));
1726 		mic_failure->multicast =
1727 			csr_roaminfo->u.pMICFailureInfo->multicast;
1728 		mic_failure->IV1 = csr_roaminfo->u.pMICFailureInfo->IV1;
1729 		mic_failure->keyId = csr_roaminfo->u.pMICFailureInfo->keyId;
1730 		qdf_mem_copy(mic_failure->TSC,
1731 			     csr_roaminfo->u.pMICFailureInfo->TSC,
1732 			     SIR_CIPHER_SEQ_CTR_SIZE);
1733 		break;
1734 
1735 	case eSAP_ASSOC_STA_CALLBACK_EVENT:
1736 		break;
1737 
1738 	case eSAP_WPS_PBC_PROBE_REQ_EVENT:
1739 
1740 		if (!csr_roaminfo) {
1741 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1742 				  FL("Invalid CSR Roam Info"));
1743 			return QDF_STATUS_E_INVAL;
1744 		}
1745 		sap_ap_event.sapHddEventCode = eSAP_WPS_PBC_PROBE_REQ_EVENT;
1746 
1747 		qdf_mem_copy(&sap_ap_event.sapevt.sapPBCProbeReqEvent.
1748 			     WPSPBCProbeReq, csr_roaminfo->u.pWPSPBCProbeReq,
1749 			     sizeof(tSirWPSPBCProbeReq));
1750 		break;
1751 
1752 	case eSAP_DISCONNECT_ALL_P2P_CLIENT:
1753 		sap_ap_event.sapHddEventCode = eSAP_DISCONNECT_ALL_P2P_CLIENT;
1754 		sap_ap_event.sapevt.sapActionCnf.actionSendSuccess =
1755 			(eSapStatus) context;
1756 		break;
1757 
1758 	case eSAP_MAC_TRIG_STOP_BSS_EVENT:
1759 		sap_ap_event.sapHddEventCode = eSAP_MAC_TRIG_STOP_BSS_EVENT;
1760 		sap_ap_event.sapevt.sapActionCnf.actionSendSuccess =
1761 			(eSapStatus) context;
1762 		break;
1763 
1764 	case eSAP_UNKNOWN_STA_JOIN:
1765 		sap_ap_event.sapHddEventCode = eSAP_UNKNOWN_STA_JOIN;
1766 		qdf_mem_copy((void *) sap_ap_event.sapevt.sapUnknownSTAJoin.
1767 			     macaddr.bytes, (void *) context,
1768 			     QDF_MAC_ADDR_SIZE);
1769 		break;
1770 
1771 	case eSAP_MAX_ASSOC_EXCEEDED:
1772 
1773 		if (!csr_roaminfo) {
1774 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1775 				  FL("Invalid CSR Roam Info"));
1776 			return QDF_STATUS_E_INVAL;
1777 		}
1778 		sap_ap_event.sapHddEventCode = eSAP_MAX_ASSOC_EXCEEDED;
1779 		qdf_copy_macaddr(&sap_ap_event.sapevt.
1780 				 sapMaxAssocExceeded.macaddr,
1781 				 &csr_roaminfo->peerMac);
1782 		break;
1783 
1784 	case eSAP_CHANNEL_CHANGE_EVENT:
1785 		/*
1786 		 * Reconfig ACS result info. For DFS AP-AP Mode Sec AP ACS
1787 		 * follows pri AP
1788 		 */
1789 		sap_ctx->acs_cfg->pri_ch = sap_ctx->channel;
1790 		sap_ctx->acs_cfg->ch_width =
1791 				sap_ctx->csr_roamProfile.ch_params.ch_width;
1792 		sap_config_acs_result(hal, sap_ctx, sap_ctx->secondary_ch);
1793 
1794 		sap_ap_event.sapHddEventCode = eSAP_CHANNEL_CHANGE_EVENT;
1795 
1796 		acs_selected = &sap_ap_event.sapevt.sap_ch_selected;
1797 		acs_selected->pri_ch = sap_ctx->acs_cfg->pri_ch;
1798 		acs_selected->ht_sec_ch = sap_ctx->acs_cfg->ht_sec_ch;
1799 		acs_selected->ch_width =
1800 			sap_ctx->csr_roamProfile.ch_params.ch_width;
1801 		acs_selected->vht_seg0_center_ch =
1802 			sap_ctx->csr_roamProfile.ch_params.center_freq_seg0;
1803 		acs_selected->vht_seg1_center_ch =
1804 			sap_ctx->csr_roamProfile.ch_params.center_freq_seg1;
1805 		break;
1806 
1807 	case eSAP_ECSA_CHANGE_CHAN_IND:
1808 
1809 		if (!csr_roaminfo) {
1810 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1811 				  FL("Invalid CSR Roam Info"));
1812 			return QDF_STATUS_E_INVAL;
1813 		}
1814 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1815 				"In %s, SAP event callback event = %s",
1816 				__func__, "eSAP_ECSA_CHANGE_CHAN_IND");
1817 		sap_ap_event.sapHddEventCode = eSAP_ECSA_CHANGE_CHAN_IND;
1818 		sap_ap_event.sapevt.sap_chan_cng_ind.new_chan =
1819 					   csr_roaminfo->target_channel;
1820 		break;
1821 	case eSAP_DFS_NEXT_CHANNEL_REQ:
1822 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1823 				"In %s, SAP event callback event = %s",
1824 				__func__, "eSAP_DFS_NEXT_CHANNEL_REQ");
1825 		sap_ap_event.sapHddEventCode = eSAP_DFS_NEXT_CHANNEL_REQ;
1826 		break;
1827 	case eSAP_STOP_BSS_DUE_TO_NO_CHNL:
1828 		sap_ap_event.sapHddEventCode = eSAP_STOP_BSS_DUE_TO_NO_CHNL;
1829 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
1830 			  FL("stopping session_id:%d, bssid:%pM, channel:%d"),
1831 			     sap_ctx->sessionId, sap_ctx->self_mac_addr,
1832 			     sap_ctx->channel);
1833 		break;
1834 	default:
1835 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1836 			  FL("SAP Unknown callback event = %d"),
1837 			  sap_hddevent);
1838 		break;
1839 	}
1840 	qdf_status = (*sap_ctx->pfnSapEventCallback)
1841 			(&sap_ap_event, sap_ctx->pUsrContext);
1842 
1843 	return qdf_status;
1844 
1845 }
1846 
1847 /**
1848  * sap_find_cac_wait_session() - Get context of a SAP session in CAC wait state
1849  * @handle: Global MAC handle
1850  *
1851  * Finds and gets the context of a SAP session in CAC wait state.
1852  *
1853  * Return: Valid SAP context on success, else NULL
1854  */
1855 static struct sap_context *sap_find_cac_wait_session(tHalHandle handle)
1856 {
1857 	tpAniSirGlobal mac = PMAC_STRUCT(handle);
1858 	uint8_t i = 0;
1859 	struct sap_context *sapContext;
1860 
1861 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
1862 			"%s", __func__);
1863 
1864 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
1865 		sapContext = mac->sap.sapCtxList[i].sap_context;
1866 		if (((QDF_SAP_MODE == mac->sap.sapCtxList[i].sapPersona)
1867 		    ||
1868 		    (QDF_P2P_GO_MODE == mac->sap.sapCtxList[i].sapPersona)) &&
1869 		    (sapContext) &&
1870 		    (sapContext->sapsMachine == eSAP_DFS_CAC_WAIT)) {
1871 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
1872 				"%s: found SAP in cac wait state", __func__);
1873 			return sapContext;
1874 		}
1875 		if (sapContext) {
1876 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
1877 					"sapdfs: mode:%d intf:%d state:%d",
1878 					mac->sap.sapCtxList[i].sapPersona, i,
1879 					sapContext->sapsMachine);
1880 		}
1881 	}
1882 
1883 	return NULL;
1884 }
1885 
1886 /*==========================================================================
1887    FUNCTION  sap_cac_reset_notify
1888 
1889    DESCRIPTION Function will be called up on stop bss indication to clean up
1890    DFS global structure.
1891 
1892    DEPENDENCIES PARAMETERS
1893      IN hHAL : HAL pointer
1894 
1895    RETURN VALUE  : void.
1896 
1897    SIDE EFFECTS
1898    ============================================================================*/
1899 void sap_cac_reset_notify(tHalHandle hHal)
1900 {
1901 	uint8_t intf = 0;
1902 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1903 
1904 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
1905 		struct sap_context *sap_context =
1906 			pMac->sap.sapCtxList[intf].sap_context;
1907 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
1908 		    ||
1909 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
1910 		    && pMac->sap.sapCtxList[intf].sap_context != NULL) {
1911 			sap_context->isCacStartNotified = false;
1912 			sap_context->isCacEndNotified = false;
1913 		}
1914 	}
1915 }
1916 
1917 /*==========================================================================
1918    FUNCTION  sap_cac_start_notify
1919 
1920    DESCRIPTION Function will be called to notify eSAP_DFS_CAC_START event
1921    to HDD
1922 
1923    DEPENDENCIES PARAMETERS
1924      IN hHAL : HAL pointer
1925 
1926    RETURN VALUE  : QDF_STATUS.
1927 
1928    SIDE EFFECTS
1929    ============================================================================*/
1930 static QDF_STATUS sap_cac_start_notify(tHalHandle hHal)
1931 {
1932 	uint8_t intf = 0;
1933 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1934 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
1935 
1936 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
1937 		struct sap_context *sap_context =
1938 			pMac->sap.sapCtxList[intf].sap_context;
1939 		struct csr_roam_profile *profile;
1940 
1941 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
1942 		    ||
1943 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
1944 		    && pMac->sap.sapCtxList[intf].sap_context != NULL &&
1945 		    (false == sap_context->isCacStartNotified)) {
1946 			/* Don't start CAC for non-dfs channel, its violation */
1947 			profile = &sap_context->csr_roamProfile;
1948 			if (!wlan_reg_is_dfs_ch(pMac->pdev,
1949 						profile->operationChannel))
1950 				continue;
1951 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
1952 				  "sapdfs: Signaling eSAP_DFS_CAC_START to HDD for sapctx[%pK]",
1953 				  sap_context);
1954 
1955 			qdf_status = sap_signal_hdd_event(sap_context, NULL,
1956 							  eSAP_DFS_CAC_START,
1957 							  (void *)
1958 							  eSAP_STATUS_SUCCESS);
1959 			if (QDF_STATUS_SUCCESS != qdf_status) {
1960 				QDF_TRACE(QDF_MODULE_ID_SAP,
1961 					  QDF_TRACE_LEVEL_ERROR,
1962 					  "In %s, failed setting isCacStartNotified on interface[%d]",
1963 					  __func__, intf);
1964 				return qdf_status;
1965 			}
1966 			sap_context->isCacStartNotified = true;
1967 		}
1968 	}
1969 	return qdf_status;
1970 }
1971 
1972 /**
1973  * wlansap_update_pre_cac_end() - Update pre cac end to upper layer
1974  * @sap_context: SAP context
1975  * @mac: Global MAC structure
1976  * @intf: Interface number
1977  *
1978  * Notifies pre cac end to upper layer
1979  *
1980  * Return: QDF_STATUS
1981  */
1982 static QDF_STATUS wlansap_update_pre_cac_end(struct sap_context *sap_context,
1983 		tpAniSirGlobal mac, uint8_t intf)
1984 {
1985 	QDF_STATUS qdf_status;
1986 
1987 	sap_context->isCacEndNotified = true;
1988 	mac->sap.SapDfsInfo.sap_radar_found_status = false;
1989 	sap_context->sapsMachine = eSAP_STARTED;
1990 
1991 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1992 			"In %s, pre cac end notify on %d: from state %s => %s",
1993 			__func__, intf, "eSAP_DFS_CAC_WAIT",
1994 			"eSAP_STARTED");
1995 
1996 	qdf_status = sap_signal_hdd_event(sap_context,
1997 			NULL, eSAP_DFS_PRE_CAC_END,
1998 			(void *)eSAP_STATUS_SUCCESS);
1999 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
2000 		QDF_TRACE(QDF_MODULE_ID_SAP,
2001 				QDF_TRACE_LEVEL_ERROR,
2002 				"In %s, pre cac notify failed on intf %d",
2003 				__func__, intf);
2004 		return qdf_status;
2005 	}
2006 
2007 	return QDF_STATUS_SUCCESS;
2008 }
2009 
2010 /*==========================================================================
2011    FUNCTION  sap_cac_end_notify
2012 
2013    DESCRIPTION Function will be called to notify eSAP_DFS_CAC_END event
2014    to HDD
2015 
2016    DEPENDENCIES PARAMETERS
2017      IN hHAL : HAL pointer
2018 
2019    RETURN VALUE  : QDF_STATUS.
2020 
2021    SIDE EFFECTS
2022    ============================================================================*/
2023 static QDF_STATUS sap_cac_end_notify(tHalHandle hHal,
2024 				     struct csr_roam_info *roamInfo)
2025 {
2026 	uint8_t intf;
2027 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
2028 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2029 
2030 	/*
2031 	 * eSAP_DFS_CHANNEL_CAC_END:
2032 	 * CAC Period elapsed and there was no radar
2033 	 * found so, SAP can continue beaconing.
2034 	 * sap_radar_found_status is set to 0
2035 	 */
2036 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
2037 		struct sap_context *sap_context =
2038 			pMac->sap.sapCtxList[intf].sap_context;
2039 		struct csr_roam_profile *profile;
2040 
2041 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
2042 		    ||
2043 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
2044 		    && pMac->sap.sapCtxList[intf].sap_context != NULL &&
2045 		    (false == sap_context->isCacEndNotified) &&
2046 		    (sap_context->sapsMachine == eSAP_DFS_CAC_WAIT)) {
2047 			sap_context = pMac->sap.sapCtxList[intf].sap_context;
2048 			/* Don't check CAC for non-dfs channel */
2049 			profile = &sap_context->csr_roamProfile;
2050 			if (!wlan_reg_is_dfs_ch(pMac->pdev,
2051 						profile->operationChannel))
2052 				continue;
2053 
2054 			/* If this is an end notification of a pre cac, the
2055 			 * SAP must not start beaconing and must delete the
2056 			 * temporary interface created for pre cac and switch
2057 			 * the original SAP to the pre CAC channel.
2058 			 */
2059 			if (sap_context->is_pre_cac_on) {
2060 				qdf_status = wlansap_update_pre_cac_end(
2061 						sap_context, pMac, intf);
2062 				if (QDF_IS_STATUS_ERROR(qdf_status))
2063 					return qdf_status;
2064 				/* pre CAC is not allowed with any concurrency.
2065 				 * So, we can break from here.
2066 				 */
2067 				break;
2068 			}
2069 
2070 			qdf_status = sap_signal_hdd_event(sap_context, NULL,
2071 							  eSAP_DFS_CAC_END,
2072 							  (void *)
2073 							  eSAP_STATUS_SUCCESS);
2074 			if (QDF_STATUS_SUCCESS != qdf_status) {
2075 				QDF_TRACE(QDF_MODULE_ID_SAP,
2076 					  QDF_TRACE_LEVEL_ERROR,
2077 					  "In %s, failed setting isCacEndNotified on interface[%d]",
2078 					  __func__, intf);
2079 				return qdf_status;
2080 			}
2081 			sap_context->isCacEndNotified = true;
2082 			pMac->sap.SapDfsInfo.sap_radar_found_status = false;
2083 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
2084 				  "sapdfs: Start beacon request on sapctx[%pK]",
2085 				  sap_context);
2086 
2087 			/* Start beaconing on the new channel */
2088 			wlansap_start_beacon_req(sap_context);
2089 
2090 			/* Transition from eSAP_STARTING to eSAP_STARTED
2091 			 * (both without substates)
2092 			 */
2093 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
2094 				  "sapdfs: channel[%d] from state %s => %s",
2095 				  sap_context->channel, "eSAP_STARTING",
2096 				  "eSAP_STARTED");
2097 
2098 			sap_context->sapsMachine = eSAP_STARTED;
2099 
2100 			/*Action code for transition */
2101 			qdf_status = sap_signal_hdd_event(sap_context, roamInfo,
2102 							  eSAP_START_BSS_EVENT,
2103 							  (void *)
2104 							  eSAP_STATUS_SUCCESS);
2105 			if (QDF_STATUS_SUCCESS != qdf_status) {
2106 				QDF_TRACE(QDF_MODULE_ID_SAP,
2107 					  QDF_TRACE_LEVEL_ERROR,
2108 					  "In %s, failed setting isCacEndNotified on interface[%d]",
2109 					  __func__, intf);
2110 				return qdf_status;
2111 			}
2112 
2113 			/* Transition from eSAP_STARTING to eSAP_STARTED
2114 			 * (both without substates)
2115 			 */
2116 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2117 				  "In %s, from state %s => %s",
2118 				  __func__, "eSAP_DFS_CAC_WAIT",
2119 				  "eSAP_STARTED");
2120 		}
2121 	}
2122 	/*
2123 	 * All APs are done with CAC timer, all APs should start beaconing.
2124 	 * Lets assume AP1 and AP2 started beaconing on DFS channel, Now lets
2125 	 * say AP1 goes down and comes back on same DFS channel. In this case
2126 	 * AP1 shouldn't start CAC timer and start beacon immediately beacause
2127 	 * AP2 is already beaconing on this channel. This case will be handled
2128 	 * by checking against eSAP_DFS_SKIP_CAC while starting the timer.
2129 	 */
2130 	pMac->sap.SapDfsInfo.cac_state = eSAP_DFS_SKIP_CAC;
2131 	return qdf_status;
2132 }
2133 
2134 /**
2135  * sap_fsm_state_disconnected() - utility function called from sap fsm
2136  * @sap_ctx: SAP context
2137  * @sap_event: SAP event buffer
2138  * @mac_ctx: global MAC context
2139  * @hal: HAL handle
2140  *
2141  * This function is called for state transition from "eSAP_DISCONNECTED"
2142  *
2143  * Return: QDF_STATUS
2144  */
2145 static QDF_STATUS sap_fsm_state_disconnected(struct sap_context *sap_ctx,
2146 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
2147 			tHalHandle hal)
2148 {
2149 	uint32_t msg = sap_event->event;
2150 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2151 
2152 	if (msg == eSAP_HDD_START_INFRA_BSS) {
2153 		/*
2154 		 * Transition from eSAP_DISCONNECTED to eSAP_CH_SELECT
2155 		 * (both without substates)
2156 		 */
2157 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2158 			  FL("new from state %s => %s: session:%d"),
2159 			  "eSAP_DISCONNECTED", "eSAP_CH_SELECT",
2160 			  sap_ctx->sessionId);
2161 
2162 		/* init dfs channel nol */
2163 		sap_init_dfs_channel_nol_list(sap_ctx);
2164 
2165 		/* Set SAP device role */
2166 		sap_ctx->sapsMachine = eSAP_CH_SELECT;
2167 
2168 		/*
2169 		 * Perform sme_ScanRequest. This scan request is post start bss
2170 		 * request so, set the third to false.
2171 		 */
2172 		qdf_status = sap_goto_channel_sel(sap_ctx, sap_event, false,
2173 						true);
2174 	} else if (msg == eSAP_DFS_CHANNEL_CAC_START) {
2175 		/*
2176 		 * No need of state check here, caller is expected to perform
2177 		 * the checks before sending the event
2178 		 */
2179 		sap_ctx->sapsMachine = eSAP_DFS_CAC_WAIT;
2180 
2181 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
2182 			FL("from state eSAP_DISCONNECTED => SAP_DFS_CAC_WAIT"));
2183 		if (mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running != true) {
2184 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
2185 			    FL("sapdfs: starting dfs cac timer on sapctx[%pK]"),
2186 			    sap_ctx);
2187 			sap_start_dfs_cac_timer(sap_ctx);
2188 		}
2189 
2190 		qdf_status = sap_cac_start_notify(hal);
2191 	} else if (msg == eSAP_CHANNEL_SELECTION_RETRY) {
2192 		/* Set SAP device role */
2193 		sap_ctx->sapsMachine = eSAP_CH_SELECT;
2194 
2195 		/*
2196 		 * Perform sme_ScanRequest. This scan request is post start bss
2197 		 * request so, set the third to false.
2198 		 */
2199 		qdf_status = sap_goto_channel_sel(sap_ctx, sap_event, false,
2200 					false);
2201 	} else {
2202 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2203 			  FL("in state %s, event msg %d"),
2204 			  "eSAP_DISCONNECTED", msg);
2205 	}
2206 
2207 	return qdf_status;
2208 }
2209 
2210 /**
2211  * sap_fsm_state_ch_select() - utility function called from sap fsm
2212  * @sap_ctx: SAP context
2213  * @sap_event: SAP event buffer
2214  * @mac_ctx: global MAC context
2215  * @hal: HAL handle
2216  *
2217  * This function is called for state transition from "eSAP_CH_SELECT"
2218  *
2219  * Return: QDF_STATUS
2220  */
2221 static QDF_STATUS sap_fsm_state_ch_select(struct sap_context *sap_ctx,
2222 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
2223 			tHalHandle hal)
2224 {
2225 	uint32_t msg = sap_event->event;
2226 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2227 	bool b_leak_chan = false;
2228 	uint8_t temp_chan;
2229 
2230 	if (msg == eSAP_MAC_SCAN_COMPLETE) {
2231 		temp_chan = sap_ctx->channel;
2232 		utils_dfs_mark_leaking_ch(mac_ctx->pdev,
2233 					sap_ctx->ch_params.ch_width,
2234 					1, &temp_chan);
2235 
2236 		/*
2237 		 * if selelcted channel has leakage to channels
2238 		 * in NOL, the temp_chan will be reset
2239 		 */
2240 		b_leak_chan = (temp_chan != sap_ctx->channel);
2241 		/*
2242 		 * check if channel is in DFS_NOL or if the channel
2243 		 * has leakage to the channels in NOL
2244 		 */
2245 		if (sap_dfs_is_channel_in_nol_list(sap_ctx, sap_ctx->channel,
2246 			PHY_CHANNEL_BONDING_STATE_MAX) || b_leak_chan) {
2247 			uint8_t ch;
2248 
2249 			/* find a new available channel */
2250 			ch = sap_random_channel_sel(sap_ctx);
2251 			if (ch == 0) {
2252 				/* No available channel found */
2253 				QDF_TRACE(QDF_MODULE_ID_SAP,
2254 					QDF_TRACE_LEVEL_ERROR,
2255 					FL("No available channel found!!!"));
2256 				sap_signal_hdd_event(sap_ctx, NULL,
2257 					eSAP_DFS_NO_AVAILABLE_CHANNEL,
2258 					(void *)eSAP_STATUS_SUCCESS);
2259 				return QDF_STATUS_E_FAULT;
2260 			}
2261 
2262 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2263 				  FL("channel %d is in NOL, StartBss on new channel %d"),
2264 				  sap_ctx->channel, ch);
2265 
2266 			sap_ctx->channel = ch;
2267 			wlan_reg_set_channel_params(mac_ctx->pdev,
2268 					sap_ctx->channel,
2269 					sap_ctx->secondary_ch,
2270 					&sap_ctx->ch_params);
2271 		}
2272 		if (sap_ctx->channel > 14 &&
2273 		    (sap_ctx->csr_roamProfile.phyMode == eCSR_DOT11_MODE_11g ||
2274 		     sap_ctx->csr_roamProfile.phyMode ==
2275 						eCSR_DOT11_MODE_11g_ONLY))
2276 			sap_ctx->csr_roamProfile.phyMode = eCSR_DOT11_MODE_11a;
2277 
2278 		/*
2279 		 * when AP2 is started while AP1 is performing ACS, we may not
2280 		 * have the AP1 channel yet.So here after the completion of AP2
2281 		 * ACS check if AP1 ACS resulting channel is DFS and if yes
2282 		 * override AP2 ACS scan result with AP1 DFS channel
2283 		 */
2284 		if (policy_mgr_concurrent_beaconing_sessions_running(
2285 			mac_ctx->psoc)) {
2286 			uint16_t con_ch;
2287 
2288 			con_ch = sme_get_concurrent_operation_channel(hal);
2289 			if (con_ch && wlan_reg_is_dfs_ch(mac_ctx->pdev, con_ch))
2290 				sap_ctx->channel = con_ch;
2291 		}
2292 
2293 		/*
2294 		 * Transition from eSAP_CH_SELECT to eSAP_STARTING
2295 		 * (both without substates)
2296 		 */
2297 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2298 			  FL("from state %s => %s"),
2299 			  "eSAP_CH_SELECT", "eSAP_STARTING");
2300 		/* Channel selected. Now can sap_goto_starting */
2301 		sap_ctx->sapsMachine = eSAP_STARTING;
2302 		/* Specify the channel */
2303 		sap_ctx->csr_roamProfile.ChannelInfo.numOfChannels =
2304 						1;
2305 		sap_ctx->csr_roamProfile.ChannelInfo.ChannelList =
2306 			&sap_ctx->csr_roamProfile.operationChannel;
2307 		sap_ctx->csr_roamProfile.operationChannel =
2308 			(uint8_t) sap_ctx->channel;
2309 		sap_ctx->csr_roamProfile.ch_params.ch_width =
2310 					sap_ctx->ch_params.ch_width;
2311 		sap_ctx->csr_roamProfile.ch_params.center_freq_seg0 =
2312 				sap_ctx->ch_params.center_freq_seg0;
2313 		sap_ctx->csr_roamProfile.ch_params.center_freq_seg1 =
2314 				sap_ctx->ch_params.center_freq_seg1;
2315 		sap_ctx->csr_roamProfile.ch_params.sec_ch_offset =
2316 				sap_ctx->ch_params.sec_ch_offset;
2317 		sap_get_cac_dur_dfs_region(sap_ctx,
2318 				&sap_ctx->csr_roamProfile.cac_duration_ms,
2319 				&sap_ctx->csr_roamProfile.dfs_regdomain);
2320 		sap_ctx->csr_roamProfile.beacon_tx_rate =
2321 				sap_ctx->beacon_tx_rate;
2322 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2323 		    FL("notify hostapd about channel selection: %d"),
2324 		    sap_ctx->channel);
2325 		sap_signal_hdd_event(sap_ctx, NULL,
2326 					eSAP_CHANNEL_CHANGE_EVENT,
2327 					(void *) eSAP_STATUS_SUCCESS);
2328 		sap_dfs_set_current_channel(sap_ctx);
2329 		qdf_status = sap_goto_starting(sap_ctx, sap_event,
2330 					  eCSR_BSS_TYPE_INFRA_AP);
2331 	} else if (msg == eSAP_CHANNEL_SELECTION_FAILED) {
2332 		sap_ctx->sapsMachine = eSAP_DISCONNECTED;
2333 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2334 		FL("Cannot start BSS, ACS Fail"));
2335 		sap_signal_hdd_event(sap_ctx, NULL, eSAP_START_BSS_EVENT,
2336 					(void *)eSAP_STATUS_FAILURE);
2337 	} else if (msg == eSAP_HDD_STOP_INFRA_BSS) {
2338 		sap_ctx->sapsMachine = eSAP_DISCONNECTED;
2339 		sap_signal_hdd_event(sap_ctx, NULL, eSAP_START_BSS_EVENT,
2340 					(void *)eSAP_STATUS_FAILURE);
2341 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
2342 			"%s: BSS stopped when Ch select in Progress", __func__);
2343 	} else {
2344 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2345 			  FL("in state %s, invalid event msg %d"),
2346 			  "eSAP_CH_SELECT", msg);
2347 	}
2348 
2349 	return qdf_status;
2350 }
2351 
2352 /**
2353  * sap_fsm_state_dfs_cac_wait() - utility function called from sap fsm
2354  * @sap_ctx: SAP context
2355  * @sap_event: SAP event buffer
2356  * @mac_ctx: global MAC context
2357  * @hal: HAL handle
2358  *
2359  * This function is called for state transition from "eSAP_DFS_CAC_WAIT"
2360  *
2361  * Return: QDF_STATUS
2362  */
2363 static QDF_STATUS sap_fsm_state_dfs_cac_wait(struct sap_context *sap_ctx,
2364 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
2365 			tHalHandle hal)
2366 {
2367 	uint32_t msg = sap_event->event;
2368 	struct csr_roam_info *roam_info =
2369 		(struct csr_roam_info *) (sap_event->params);
2370 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2371 
2372 	if (msg == eSAP_DFS_CHANNEL_CAC_START) {
2373 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2374 			  FL("from state %s => %s"),
2375 			  "eSAP_CH_SELECT", "eSAP_DFS_CAC_WAIT");
2376 		if (mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running != true)
2377 			sap_start_dfs_cac_timer(sap_ctx);
2378 		qdf_status = sap_cac_start_notify(hal);
2379 	} else if (msg == eSAP_DFS_CHANNEL_CAC_RADAR_FOUND) {
2380 		uint8_t intf;
2381 		/*
2382 		 * Radar found while performing channel availability
2383 		 * check, need to switch the channel again
2384 		 */
2385 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
2386 			  "ENTERTRED CAC WAIT STATE-->eSAP_DISCONNECTING\n");
2387 		if (mac_ctx->sap.SapDfsInfo.target_channel) {
2388 			wlan_reg_set_channel_params(mac_ctx->pdev,
2389 				mac_ctx->sap.SapDfsInfo.target_channel, 0,
2390 				&sap_ctx->ch_params);
2391 		} else {
2392 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2393 				FL("Invalid target channel %d"),
2394 				mac_ctx->sap.SapDfsInfo.target_channel);
2395 			return qdf_status;
2396 		}
2397 
2398 		for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
2399 			struct sap_context *t_sap_ctx;
2400 			struct csr_roam_profile *profile;
2401 
2402 			t_sap_ctx = mac_ctx->sap.sapCtxList[intf].sap_context;
2403 			if (((QDF_SAP_MODE ==
2404 				 mac_ctx->sap.sapCtxList[intf].sapPersona) ||
2405 			     (QDF_P2P_GO_MODE ==
2406 				mac_ctx->sap.sapCtxList[intf].sapPersona)) &&
2407 			    t_sap_ctx != NULL &&
2408 			    t_sap_ctx->sapsMachine != eSAP_DISCONNECTED) {
2409 				profile = &t_sap_ctx->csr_roamProfile;
2410 				if (!wlan_reg_is_passive_or_disable_ch(
2411 						mac_ctx->pdev,
2412 						profile->operationChannel))
2413 					continue;
2414 				/* SAP to be moved to DISCONNECTING state */
2415 				t_sap_ctx->sapsMachine = eSAP_DISCONNECTING;
2416 				/*
2417 				 * eSAP_DFS_CHANNEL_CAC_RADAR_FOUND:
2418 				 * A Radar is found on current DFS Channel
2419 				 * while in CAC WAIT period So, do a channel
2420 				 * switch to randomly selected  target channel.
2421 				 * Send the Channel change message to SME/PE.
2422 				 * sap_radar_found_status is set to 1
2423 				 */
2424 				wlansap_channel_change_request(
2425 					t_sap_ctx,
2426 					mac_ctx->sap.SapDfsInfo.target_channel);
2427 			}
2428 		}
2429 	} else if (msg == eSAP_DFS_CHANNEL_CAC_END) {
2430 		qdf_status = sap_cac_end_notify(hal, roam_info);
2431 	} else if (msg == eSAP_HDD_STOP_INFRA_BSS) {
2432 		/* Transition from eSAP_DFS_CAC_WAIT to eSAP_DISCONNECTING */
2433 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2434 			  FL("from state %s => %s"),
2435 			  "eSAP_DFS_CAC_WAIT", "eSAP_DISCONNECTING");
2436 
2437 		/*
2438 		 * Stop the CAC timer only in following conditions
2439 		 * single AP: if there is a single AP then stop the timer
2440 		 * mulitple APs: incase of multiple APs, make sure that
2441 		 *               all APs are down.
2442 		 */
2443 		if (NULL == sap_find_valid_concurrent_session(hal)) {
2444 			QDF_TRACE(QDF_MODULE_ID_SAP,
2445 				  QDF_TRACE_LEVEL_INFO_MED,
2446 				  FL("sapdfs: no sessions are valid, stopping timer"));
2447 			sap_stop_dfs_cac_timer(sap_ctx);
2448 		}
2449 
2450 		sap_ctx->sapsMachine = eSAP_DISCONNECTING;
2451 		qdf_status = sap_goto_disconnecting(sap_ctx);
2452 	} else {
2453 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2454 			  FL("in state %s, invalid event msg %d"),
2455 			  "eSAP_DFS_CAC_WAIT", msg);
2456 	}
2457 
2458 	return qdf_status;
2459 }
2460 
2461 /**
2462  * sap_fsm_state_starting() - utility function called from sap fsm
2463  * @sap_ctx: SAP context
2464  * @sap_event: SAP event buffer
2465  * @mac_ctx: global MAC context
2466  * @hal: HAL handle
2467  *
2468  * This function is called for state transition from "eSAP_STARTING"
2469  *
2470  * Return: QDF_STATUS
2471  */
2472 static QDF_STATUS sap_fsm_state_starting(struct sap_context *sap_ctx,
2473 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
2474 			tHalHandle hal)
2475 {
2476 	uint32_t msg = sap_event->event;
2477 	struct csr_roam_info *roam_info =
2478 		(struct csr_roam_info *) (sap_event->params);
2479 	tSapDfsInfo *sap_dfs_info;
2480 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2481 	uint8_t is_dfs = false;
2482 
2483 	if (msg == eSAP_MAC_START_BSS_SUCCESS) {
2484 		/*
2485 		 * Transition from eSAP_STARTING to eSAP_STARTED
2486 		 * (both without substates)
2487 		 */
2488 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2489 			  FL("from state channel = %d %s => %s ch_width %d"),
2490 			  sap_ctx->channel, "eSAP_STARTING", "eSAP_STARTED",
2491 			  sap_ctx->ch_params.ch_width);
2492 		sap_ctx->sapsMachine = eSAP_STARTED;
2493 
2494 		/* Action code for transition */
2495 		qdf_status = sap_signal_hdd_event(sap_ctx, roam_info,
2496 				eSAP_START_BSS_EVENT,
2497 				(void *) eSAP_STATUS_SUCCESS);
2498 
2499 		/*
2500 		 * The upper layers have been informed that AP is up and
2501 		 * running, however, the AP is still not beaconing, until
2502 		 * CAC is done if the operating channel is DFS
2503 		 */
2504 		if (sap_ctx->ch_params.ch_width == CH_WIDTH_160MHZ) {
2505 			is_dfs = true;
2506 		} else if (sap_ctx->ch_params.ch_width == CH_WIDTH_80P80MHZ) {
2507 			if (wlan_reg_get_channel_state(mac_ctx->pdev,
2508 						sap_ctx->channel) ==
2509 			    CHANNEL_STATE_DFS ||
2510 			    wlan_reg_get_channel_state(mac_ctx->pdev,
2511 				    sap_ctx->ch_params.center_freq_seg1 -
2512 				SIR_80MHZ_START_CENTER_CH_DIFF) ==
2513 					CHANNEL_STATE_DFS)
2514 				is_dfs = true;
2515 		} else {
2516 			if (wlan_reg_get_channel_state(mac_ctx->pdev,
2517 						sap_ctx->channel) ==
2518 							CHANNEL_STATE_DFS)
2519 				is_dfs = true;
2520 		}
2521 
2522 		if (is_dfs) {
2523 			sap_dfs_info = &mac_ctx->sap.SapDfsInfo;
2524 			if ((false == sap_dfs_info->ignore_cac) &&
2525 			    (eSAP_DFS_DO_NOT_SKIP_CAC ==
2526 					sap_dfs_info->cac_state) &&
2527 			    !sap_ctx->pre_cac_complete) {
2528 				/* Move the device in CAC_WAIT_STATE */
2529 				sap_ctx->sapsMachine = eSAP_DFS_CAC_WAIT;
2530 
2531 				/*
2532 				 * Need to stop the OS transmit queues,
2533 				 * so that no traffic can flow down the stack
2534 				 */
2535 
2536 				/* Start CAC wait timer */
2537 				if (sap_dfs_info->is_dfs_cac_timer_running !=
2538 									true)
2539 					sap_start_dfs_cac_timer(sap_ctx);
2540 				qdf_status = sap_cac_start_notify(hal);
2541 
2542 			} else {
2543 				wlansap_start_beacon_req(sap_ctx);
2544 			}
2545 		}
2546 	} else if (msg == eSAP_MAC_START_FAILS ||
2547 			msg == eSAP_HDD_STOP_INFRA_BSS) {
2548 		/*
2549 		 * Transition from eSAP_STARTING to eSAP_DISCONNECTED
2550 		 * (both without substates)
2551 		 */
2552 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2553 			  FL("from state %s => %s"),
2554 			  "eSAP_STARTING", "eSAP_DISCONNECTED");
2555 
2556 		/* Advance outer statevar */
2557 		sap_ctx->sapsMachine = eSAP_DISCONNECTED;
2558 		qdf_status = sap_signal_hdd_event(sap_ctx, NULL,
2559 				eSAP_START_BSS_EVENT,
2560 				(void *) eSAP_STATUS_FAILURE);
2561 		qdf_status = sap_goto_disconnected(sap_ctx);
2562 		/* Close the SME session */
2563 	} else if (msg == eSAP_OPERATING_CHANNEL_CHANGED) {
2564 		/* The operating channel has changed, update hostapd */
2565 		sap_ctx->channel =
2566 			(uint8_t) mac_ctx->sap.SapDfsInfo.target_channel;
2567 
2568 		sap_ctx->sapsMachine = eSAP_STARTED;
2569 
2570 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2571 			  FL("from state %s => %s"),
2572 			  "eSAP_STARTING", "eSAP_STARTED");
2573 
2574 		/* Indicate change in the state to upper layers */
2575 		qdf_status = sap_signal_hdd_event(sap_ctx, roam_info,
2576 				  eSAP_START_BSS_EVENT,
2577 				  (void *)eSAP_STATUS_SUCCESS);
2578 	} else {
2579 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2580 			  FL("in state %s, invalid event msg %d"),
2581 			  "eSAP_STARTING", msg);
2582 	}
2583 
2584 	return qdf_status;
2585 }
2586 
2587 /**
2588  * sap_fsm_state_started() - utility function called from sap fsm
2589  * @sap_ctx: SAP context
2590  * @sap_event: SAP event buffer
2591  * @mac_ctx: global MAC context
2592  *
2593  * This function is called for state transition from "eSAP_STARTED"
2594  *
2595  * Return: QDF_STATUS
2596  */
2597 static QDF_STATUS sap_fsm_state_started(struct sap_context *sap_ctx,
2598 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx)
2599 {
2600 	uint32_t msg = sap_event->event;
2601 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2602 
2603 	if (msg == eSAP_HDD_STOP_INFRA_BSS) {
2604 		/*
2605 		 * Transition from eSAP_STARTED to eSAP_DISCONNECTING
2606 		 * (both without substates)
2607 		 */
2608 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2609 			  FL("from state %s => %s"),
2610 			  "eSAP_STARTED", "eSAP_DISCONNECTING");
2611 		sap_ctx->sapsMachine = eSAP_DISCONNECTING;
2612 		qdf_status = sap_goto_disconnecting(sap_ctx);
2613 	} else if (eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START == msg) {
2614 		uint8_t intf;
2615 		if (!mac_ctx->sap.SapDfsInfo.target_channel) {
2616 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2617 				FL("Invalid target channel %d"),
2618 				mac_ctx->sap.SapDfsInfo.target_channel);
2619 			return qdf_status;
2620 		}
2621 
2622 		/*
2623 		 * Radar is seen on the current operating channel
2624 		 * send CSA IE for all associated stations
2625 		 * Request for CSA IE transmission
2626 		 */
2627 		for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
2628 			struct sap_context *temp_sap_ctx;
2629 			struct csr_roam_profile *profile;
2630 
2631 			if (((QDF_SAP_MODE ==
2632 				mac_ctx->sap.sapCtxList[intf].sapPersona) ||
2633 			    (QDF_P2P_GO_MODE ==
2634 				mac_ctx->sap.sapCtxList[intf].sapPersona)) &&
2635 			    mac_ctx->sap.sapCtxList[intf].sap_context != NULL) {
2636 				temp_sap_ctx =
2637 				    mac_ctx->sap.sapCtxList[intf].sap_context;
2638 				/*
2639 				 * Radar won't come on non-dfs channel, so
2640 				 * no need to move them
2641 				 */
2642 				profile = &temp_sap_ctx->csr_roamProfile;
2643 				if (!wlan_reg_is_passive_or_disable_ch(
2644 						mac_ctx->pdev,
2645 						profile->operationChannel))
2646 					continue;
2647 				QDF_TRACE(QDF_MODULE_ID_SAP,
2648 					  QDF_TRACE_LEVEL_INFO_MED,
2649 					  FL("sapdfs: Sending CSAIE for sapctx[%pK]"),
2650 					  temp_sap_ctx);
2651 
2652 				qdf_status =
2653 					wlansap_dfs_send_csa_ie_request(temp_sap_ctx);
2654 			}
2655 		}
2656 	} else if (eSAP_CHANNEL_SWITCH_ANNOUNCEMENT_START == msg) {
2657 		enum QDF_OPMODE persona;
2658 
2659 		if (!sap_ctx) {
2660 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2661 					FL("Invalid sap_ctx"));
2662 			return qdf_status;
2663 		}
2664 
2665 		persona = mac_ctx->sap.sapCtxList[sap_ctx->sessionId].
2666 								sapPersona;
2667 
2668 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
2669 				FL("app trigger chan switch: mode:%d vdev:%d"),
2670 				persona, sap_ctx->sessionId);
2671 
2672 		if ((QDF_SAP_MODE == persona) || (QDF_P2P_GO_MODE == persona))
2673 			qdf_status = wlansap_dfs_send_csa_ie_request(sap_ctx);
2674 	} else {
2675 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2676 			  FL("in state %s, invalid event msg %d"),
2677 			  "eSAP_STARTED", msg);
2678 	}
2679 
2680 	return qdf_status;
2681 }
2682 
2683 /**
2684  * sap_fsm_state_disconnecting() - utility function called from sap fsm
2685  * @sap_ctx: SAP context
2686  * @sap_event: SAP event buffer
2687  * @mac_ctx: global MAC context
2688  *
2689  * This function is called for state transition from "eSAP_DISCONNECTING"
2690  *
2691  * Return: QDF_STATUS
2692  */
2693 static QDF_STATUS sap_fsm_state_disconnecting(struct sap_context *sap_ctx,
2694 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
2695 			tHalHandle hal)
2696 {
2697 	uint32_t msg = sap_event->event;
2698 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2699 
2700 	if (msg == eSAP_MAC_READY_FOR_CONNECTIONS) {
2701 		/*
2702 		 * Transition from eSAP_DISCONNECTING to eSAP_DISCONNECTED
2703 		 * (both without substates)
2704 		 */
2705 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2706 			  FL("from state %s => %s"),
2707 			  "eSAP_DISCONNECTING", "eSAP_DISCONNECTED");
2708 		sap_ctx->sapsMachine = eSAP_DISCONNECTED;
2709 
2710 		/* Close the SME session */
2711 		qdf_status = sap_signal_hdd_event(sap_ctx, NULL,
2712 					eSAP_STOP_BSS_EVENT,
2713 					(void *)eSAP_STATUS_SUCCESS);
2714 	} else if (msg == eWNI_SME_CHANNEL_CHANGE_REQ) {
2715 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
2716 			  FL("sapdfs: Send channel change request on sapctx[%pK]"),
2717 			  sap_ctx);
2718 
2719 		sap_get_cac_dur_dfs_region(sap_ctx,
2720 				&sap_ctx->csr_roamProfile.cac_duration_ms,
2721 				&sap_ctx->csr_roamProfile.dfs_regdomain);
2722 		/*
2723 		 * Most likely, radar has been detected and SAP wants to
2724 		 * change the channel
2725 		 */
2726 		qdf_status = wlansap_channel_change_request(sap_ctx,
2727 				mac_ctx->sap.SapDfsInfo.target_channel);
2728 
2729 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
2730 			  FL("Sending DFS eWNI_SME_CHANNEL_CHANGE_REQ"));
2731 	} else if (msg == eWNI_SME_CHANNEL_CHANGE_RSP) {
2732 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
2733 			  FL("in state %s, event msg %d result %d"),
2734 			  "eSAP_DISCONNECTING ", msg, sap_event->u2);
2735 		if (sap_event->u2 == eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE)
2736 			qdf_status = sap_goto_disconnecting(sap_ctx);
2737 	} else if ((msg == eSAP_HDD_STOP_INFRA_BSS) &&
2738 			(sap_ctx->is_chan_change_inprogress)) {
2739 		/* stop bss is received while processing channel change */
2740 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
2741 			  FL("in state %s, event msg %d result %d"),
2742 			  "eSAP_DISCONNECTING ", msg, sap_event->u2);
2743 		qdf_status = sap_goto_disconnecting(sap_ctx);
2744 	} else {
2745 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2746 			  FL("in state %s, invalid event msg %d"),
2747 			  "eSAP_DISCONNECTING", msg);
2748 	}
2749 
2750 	return qdf_status;
2751 }
2752 
2753 /**
2754  * sap_fsm() - SAP statem machine entry function
2755  * @sap_ctx: SAP context
2756  * @sap_event: SAP event
2757  *
2758  * SAP statem machine entry function
2759  *
2760  * Return: QDF_STATUS
2761  */
2762 QDF_STATUS sap_fsm(struct sap_context *sap_ctx, ptWLAN_SAPEvent sap_event)
2763 {
2764 	/*
2765 	 * Retrieve the phy link state machine structure
2766 	 * from the sap_ctx value
2767 	 * state var that keeps track of state machine
2768 	 */
2769 	eSapFsmStates_t state_var = sap_ctx->sapsMachine;
2770 	uint32_t msg = sap_event->event; /* State machine input event message */
2771 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2772 	tHalHandle hal = CDS_GET_HAL_CB();
2773 	tpAniSirGlobal mac_ctx;
2774 
2775 	if (NULL == hal) {
2776 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2777 			  FL("Invalid hal"));
2778 		return QDF_STATUS_E_FAILURE;
2779 	}
2780 
2781 	mac_ctx = PMAC_STRUCT(hal);
2782 	if (NULL == mac_ctx) {
2783 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2784 			  FL("Invalid MAC context"));
2785 		return QDF_STATUS_E_FAILURE;
2786 	}
2787 
2788 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
2789 		  FL("sap_ctx=%pK, state_var=%d, msg=0x%x"),
2790 		  sap_ctx, state_var, msg);
2791 
2792 	switch (state_var) {
2793 	case eSAP_DISCONNECTED:
2794 		qdf_status = sap_fsm_state_disconnected(sap_ctx, sap_event,
2795 				mac_ctx, hal);
2796 		break;
2797 
2798 	case eSAP_CH_SELECT:
2799 		qdf_status = sap_fsm_state_ch_select(sap_ctx, sap_event,
2800 				mac_ctx, hal);
2801 		break;
2802 
2803 	case eSAP_DFS_CAC_WAIT:
2804 		qdf_status = sap_fsm_state_dfs_cac_wait(sap_ctx, sap_event,
2805 				mac_ctx, hal);
2806 		break;
2807 
2808 	case eSAP_STARTING:
2809 		qdf_status = sap_fsm_state_starting(sap_ctx, sap_event,
2810 				mac_ctx, hal);
2811 		break;
2812 
2813 	case eSAP_STARTED:
2814 		qdf_status = sap_fsm_state_started(sap_ctx, sap_event,
2815 				mac_ctx);
2816 		break;
2817 
2818 	case eSAP_DISCONNECTING:
2819 		qdf_status = sap_fsm_state_disconnecting(sap_ctx, sap_event,
2820 				mac_ctx, hal);
2821 		break;
2822 	}
2823 	return qdf_status;
2824 }
2825 
2826 eSapStatus
2827 sapconvert_to_csr_profile(tsap_config_t *pconfig_params, eCsrRoamBssType bssType,
2828 			  struct csr_roam_profile *profile)
2829 {
2830 	/* Create Roam profile for SoftAP to connect */
2831 	profile->BSSType = eCSR_BSS_TYPE_INFRA_AP;
2832 	profile->SSIDs.numOfSSIDs = 1;
2833 	profile->csrPersona = pconfig_params->persona;
2834 	profile->disableDFSChSwitch = pconfig_params->disableDFSChSwitch;
2835 
2836 	qdf_mem_zero(profile->SSIDs.SSIDList[0].SSID.ssId,
2837 		     sizeof(profile->SSIDs.SSIDList[0].SSID.ssId));
2838 
2839 	/* Flag to not broadcast the SSID information */
2840 	profile->SSIDs.SSIDList[0].ssidHidden =
2841 		pconfig_params->SSIDinfo.ssidHidden;
2842 
2843 	profile->SSIDs.SSIDList[0].SSID.length =
2844 		pconfig_params->SSIDinfo.ssid.length;
2845 	qdf_mem_copy(&profile->SSIDs.SSIDList[0].SSID.ssId,
2846 		     pconfig_params->SSIDinfo.ssid.ssId,
2847 		     sizeof(pconfig_params->SSIDinfo.ssid.ssId));
2848 
2849 	profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
2850 
2851 	if (pconfig_params->authType == eSAP_OPEN_SYSTEM) {
2852 		profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
2853 	} else if (pconfig_params->authType == eSAP_SHARED_KEY) {
2854 		profile->negotiatedAuthType = eCSR_AUTH_TYPE_SHARED_KEY;
2855 	} else {
2856 		profile->negotiatedAuthType = eCSR_AUTH_TYPE_AUTOSWITCH;
2857 	}
2858 
2859 	profile->AuthType.numEntries = 1;
2860 	profile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
2861 
2862 	/* Always set the Encryption Type */
2863 	profile->EncryptionType.numEntries = 1;
2864 	profile->EncryptionType.encryptionType[0] =
2865 		pconfig_params->RSNEncryptType;
2866 
2867 	profile->mcEncryptionType.numEntries = 1;
2868 	profile->mcEncryptionType.encryptionType[0] =
2869 		pconfig_params->mcRSNEncryptType;
2870 
2871 	if (pconfig_params->privacy & eSAP_SHARED_KEY) {
2872 		profile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY;
2873 	}
2874 
2875 	profile->privacy = pconfig_params->privacy;
2876 	profile->fwdWPSPBCProbeReq = pconfig_params->fwdWPSPBCProbeReq;
2877 
2878 	if (pconfig_params->authType == eSAP_SHARED_KEY) {
2879 		profile->csr80211AuthType = eSIR_SHARED_KEY;
2880 	} else if (pconfig_params->authType == eSAP_OPEN_SYSTEM) {
2881 		profile->csr80211AuthType = eSIR_OPEN_SYSTEM;
2882 	} else {
2883 		profile->csr80211AuthType = eSIR_AUTO_SWITCH;
2884 	}
2885 
2886 	/* Initialize we are not going to use it */
2887 	profile->pWPAReqIE = NULL;
2888 	profile->nWPAReqIELength = 0;
2889 
2890 	if (profile->pRSNReqIE) {
2891 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
2892 			  FL("pRSNReqIE already allocated."));
2893 		qdf_mem_free(profile->pRSNReqIE);
2894 		profile->pRSNReqIE = NULL;
2895 	}
2896 
2897 	/* set the RSN/WPA IE */
2898 	profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength;
2899 	if (pconfig_params->RSNWPAReqIELength) {
2900 		profile->pRSNReqIE =
2901 			qdf_mem_malloc(pconfig_params->RSNWPAReqIELength);
2902 		if (NULL == profile->pRSNReqIE) {
2903 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2904 				  " %s Fail to alloc memory", __func__);
2905 			return eSAP_STATUS_FAILURE;
2906 		}
2907 		qdf_mem_copy(profile->pRSNReqIE, pconfig_params->RSNWPAReqIE,
2908 			     pconfig_params->RSNWPAReqIELength);
2909 		profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength;
2910 	}
2911 
2912 	/* set the phyMode to accept anything */
2913 	/* Best means everything because it covers all the things we support */
2914 	/* eCSR_DOT11_MODE_BEST */
2915 	profile->phyMode = pconfig_params->SapHw_mode;
2916 
2917 	/* Configure beaconInterval */
2918 	profile->beaconInterval = (uint16_t) pconfig_params->beacon_int;
2919 
2920 	/* set DTIM period */
2921 	profile->dtimPeriod = pconfig_params->dtim_period;
2922 
2923 	/* set Uapsd enable bit */
2924 	profile->ApUapsdEnable = pconfig_params->UapsdEnable;
2925 
2926 	/* Enable protection parameters */
2927 	profile->protEnabled = pconfig_params->protEnabled;
2928 	profile->obssProtEnabled = pconfig_params->obssProtEnabled;
2929 	profile->cfg_protection = pconfig_params->ht_capab;
2930 
2931 	/* country code */
2932 	if (pconfig_params->countryCode[0])
2933 		qdf_mem_copy(profile->countryCode, pconfig_params->countryCode,
2934 			     WNI_CFG_COUNTRY_CODE_LEN);
2935 	profile->ieee80211d = pconfig_params->ieee80211d;
2936 	/* wps config info */
2937 	profile->wps_state = pconfig_params->wps_state;
2938 
2939 #ifdef WLAN_FEATURE_11W
2940 	/* MFP capable/required */
2941 	profile->MFPCapable = pconfig_params->mfpCapable ? 1 : 0;
2942 	profile->MFPRequired = pconfig_params->mfpRequired ? 1 : 0;
2943 #endif
2944 
2945 	if (pconfig_params->probeRespIEsBufferLen > 0 &&
2946 	    pconfig_params->pProbeRespIEsBuffer != NULL) {
2947 		profile->addIeParams.probeRespDataLen =
2948 			pconfig_params->probeRespIEsBufferLen;
2949 		profile->addIeParams.probeRespData_buff =
2950 			pconfig_params->pProbeRespIEsBuffer;
2951 	} else {
2952 		profile->addIeParams.probeRespDataLen = 0;
2953 		profile->addIeParams.probeRespData_buff = NULL;
2954 	}
2955 	/*assoc resp IE */
2956 	if (pconfig_params->assocRespIEsLen > 0 &&
2957 	    pconfig_params->pAssocRespIEsBuffer != NULL) {
2958 		profile->addIeParams.assocRespDataLen =
2959 			pconfig_params->assocRespIEsLen;
2960 		profile->addIeParams.assocRespData_buff =
2961 			pconfig_params->pAssocRespIEsBuffer;
2962 	} else {
2963 		profile->addIeParams.assocRespDataLen = 0;
2964 		profile->addIeParams.assocRespData_buff = NULL;
2965 	}
2966 
2967 	if (pconfig_params->probeRespBcnIEsLen > 0 &&
2968 	    pconfig_params->pProbeRespBcnIEsBuffer != NULL) {
2969 		profile->addIeParams.probeRespBCNDataLen =
2970 			pconfig_params->probeRespBcnIEsLen;
2971 		profile->addIeParams.probeRespBCNData_buff =
2972 			pconfig_params->pProbeRespBcnIEsBuffer;
2973 	} else {
2974 		profile->addIeParams.probeRespBCNDataLen = 0;
2975 		profile->addIeParams.probeRespBCNData_buff = NULL;
2976 	}
2977 	profile->sap_dot11mc = pconfig_params->sap_dot11mc;
2978 
2979 	if (pconfig_params->supported_rates.numRates) {
2980 		qdf_mem_copy(profile->supported_rates.rate,
2981 				pconfig_params->supported_rates.rate,
2982 				pconfig_params->supported_rates.numRates);
2983 		profile->supported_rates.numRates =
2984 			pconfig_params->supported_rates.numRates;
2985 	}
2986 
2987 	if (pconfig_params->extended_rates.numRates) {
2988 		qdf_mem_copy(profile->extended_rates.rate,
2989 				pconfig_params->extended_rates.rate,
2990 				pconfig_params->extended_rates.numRates);
2991 		profile->extended_rates.numRates =
2992 			pconfig_params->extended_rates.numRates;
2993 	}
2994 
2995 	profile->chan_switch_hostapd_rate_enabled =
2996 		pconfig_params->chan_switch_hostapd_rate_enabled;
2997 
2998 	return eSAP_STATUS_SUCCESS;     /* Success. */
2999 }
3000 
3001 void sap_free_roam_profile(struct csr_roam_profile *profile)
3002 {
3003 	if (profile->pRSNReqIE) {
3004 		qdf_mem_free(profile->pRSNReqIE);
3005 		profile->pRSNReqIE = NULL;
3006 	}
3007 }
3008 
3009 void sap_sort_mac_list(struct qdf_mac_addr *macList, uint8_t size)
3010 {
3011 	uint8_t outer, inner;
3012 	struct qdf_mac_addr temp;
3013 	int32_t nRes = -1;
3014 
3015 	if ((NULL == macList) || (size > MAX_ACL_MAC_ADDRESS)) {
3016 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3017 			FL("either buffer is NULL or size = %d is more"), size);
3018 		return;
3019 	}
3020 
3021 	for (outer = 0; outer < size; outer++) {
3022 		for (inner = 0; inner < size - 1; inner++) {
3023 			nRes =
3024 				qdf_mem_cmp((macList + inner)->bytes,
3025 						 (macList + inner + 1)->bytes,
3026 						 QDF_MAC_ADDR_SIZE);
3027 			if (nRes > 0) {
3028 				qdf_mem_copy(temp.bytes,
3029 					     (macList + inner + 1)->bytes,
3030 					     QDF_MAC_ADDR_SIZE);
3031 				qdf_mem_copy((macList + inner + 1)->bytes,
3032 					     (macList + inner)->bytes,
3033 					     QDF_MAC_ADDR_SIZE);
3034 				qdf_mem_copy((macList + inner)->bytes,
3035 					     temp.bytes, QDF_MAC_ADDR_SIZE);
3036 			}
3037 		}
3038 	}
3039 }
3040 
3041 bool
3042 sap_search_mac_list(struct qdf_mac_addr *macList,
3043 		    uint8_t num_mac, uint8_t *peerMac,
3044 		    uint8_t *index)
3045 {
3046 	int32_t nRes = -1;
3047 	int8_t nStart = 0, nEnd, nMiddle;
3048 
3049 	nEnd = num_mac - 1;
3050 
3051 	if ((NULL == macList) || (num_mac > MAX_ACL_MAC_ADDRESS)) {
3052 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3053 		    FL("either buffer is NULL or size = %d is more."), num_mac);
3054 		return false;
3055 	}
3056 
3057 	while (nStart <= nEnd) {
3058 		nMiddle = (nStart + nEnd) / 2;
3059 		nRes =
3060 			qdf_mem_cmp(&macList[nMiddle], peerMac,
3061 					 QDF_MAC_ADDR_SIZE);
3062 
3063 		if (0 == nRes) {
3064 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3065 				  "search SUCC");
3066 			/* "index equals NULL" means the caller does not need the */
3067 			/* index value of the peerMac being searched */
3068 			if (index != NULL) {
3069 				*index = (uint8_t) nMiddle;
3070 				QDF_TRACE(QDF_MODULE_ID_SAP,
3071 					  QDF_TRACE_LEVEL_INFO_HIGH, "index %d",
3072 					  *index);
3073 			}
3074 			return true;
3075 		}
3076 		if (nRes < 0)
3077 			nStart = nMiddle + 1;
3078 		else
3079 			nEnd = nMiddle - 1;
3080 	}
3081 
3082 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3083 		  "search not succ");
3084 	return false;
3085 }
3086 
3087 void sap_add_mac_to_acl(struct qdf_mac_addr *macList,
3088 			uint8_t *size, uint8_t *peerMac)
3089 {
3090 	int32_t nRes = -1;
3091 	int i;
3092 
3093 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3094 		  "add acl entered");
3095 
3096 	if (NULL == macList || *size > MAX_ACL_MAC_ADDRESS) {
3097 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3098 			FL("either buffer is NULL or size = %d is incorrect."),
3099 			*size);
3100 		return;
3101 	}
3102 
3103 	for (i = ((*size) - 1); i >= 0; i--) {
3104 		nRes =
3105 			qdf_mem_cmp(&macList[i], peerMac, QDF_MAC_ADDR_SIZE);
3106 		if (nRes > 0) {
3107 			/* Move alphabetically greater mac addresses one index down to allow for insertion
3108 			   of new mac in sorted order */
3109 			qdf_mem_copy((macList + i + 1)->bytes,
3110 				     (macList + i)->bytes, QDF_MAC_ADDR_SIZE);
3111 		} else {
3112 			break;
3113 		}
3114 	}
3115 	/* This should also take care of if the element is the first to be added in the list */
3116 	qdf_mem_copy((macList + i + 1)->bytes, peerMac, QDF_MAC_ADDR_SIZE);
3117 	/* increment the list size */
3118 	(*size)++;
3119 }
3120 
3121 void sap_remove_mac_from_acl(struct qdf_mac_addr *macList,
3122 			     uint8_t *size, uint8_t index)
3123 {
3124 	int i;
3125 
3126 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3127 		  "remove acl entered");
3128 	/*
3129 	 * Return if the list passed is empty. Ideally this should never happen
3130 	 * since this funcn is always called after sap_search_mac_list to get
3131 	 * the index of the mac addr to be removed and this will only get
3132 	 * called if the search is successful. Still no harm in having the check
3133 	 */
3134 	if ((macList == NULL) || (*size == 0) ||
3135 					(*size > MAX_ACL_MAC_ADDRESS)) {
3136 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3137 			FL("either buffer is NULL or size %d is incorrect."),
3138 			*size);
3139 		return;
3140 	}
3141 	for (i = index; i < ((*size) - 1); i++) {
3142 		/* Move mac addresses starting from "index" passed one index up to delete the void
3143 		   created by deletion of a mac address in ACL */
3144 		qdf_mem_copy((macList + i)->bytes, (macList + i + 1)->bytes,
3145 			     QDF_MAC_ADDR_SIZE);
3146 	}
3147 	/* The last space should be made empty since all mac addesses moved one step up */
3148 	qdf_mem_zero((macList + (*size) - 1)->bytes, QDF_MAC_ADDR_SIZE);
3149 	/* reduce the list size by 1 */
3150 	(*size)--;
3151 }
3152 
3153 void sap_print_acl(struct qdf_mac_addr *macList, uint8_t size)
3154 {
3155 	int i;
3156 	uint8_t *macArray;
3157 
3158 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3159 		  "print acl entered");
3160 
3161 	if ((NULL == macList) || (size == 0) || (size >= MAX_ACL_MAC_ADDRESS)) {
3162 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3163 			  "In %s, either buffer is NULL or size %d is incorrect.",
3164 			  __func__, size);
3165 		return;
3166 	}
3167 
3168 	for (i = 0; i < size; i++) {
3169 		macArray = (macList + i)->bytes;
3170 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3171 			  "** ACL entry %i - " MAC_ADDRESS_STR, i,
3172 			  MAC_ADDR_ARRAY(macArray));
3173 	}
3174 	return;
3175 }
3176 
3177 QDF_STATUS sap_is_peer_mac_allowed(struct sap_context *sapContext,
3178 				   uint8_t *peerMac)
3179 {
3180 	if (eSAP_ALLOW_ALL == sapContext->eSapMacAddrAclMode)
3181 		return QDF_STATUS_SUCCESS;
3182 
3183 	if (sap_search_mac_list
3184 		    (sapContext->acceptMacList, sapContext->nAcceptMac, peerMac, NULL))
3185 		return QDF_STATUS_SUCCESS;
3186 
3187 	if (sap_search_mac_list
3188 		    (sapContext->denyMacList, sapContext->nDenyMac, peerMac, NULL)) {
3189 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3190 			  "In %s, Peer " MAC_ADDRESS_STR " in deny list",
3191 			  __func__, MAC_ADDR_ARRAY(peerMac));
3192 		return QDF_STATUS_E_FAILURE;
3193 	}
3194 	/* A new station CAN associate, unless in deny list. Less stringent mode */
3195 	if (eSAP_ACCEPT_UNLESS_DENIED == sapContext->eSapMacAddrAclMode)
3196 		return QDF_STATUS_SUCCESS;
3197 
3198 	/* A new station CANNOT associate, unless in accept list. More stringent mode */
3199 	if (eSAP_DENY_UNLESS_ACCEPTED == sapContext->eSapMacAddrAclMode) {
3200 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3201 			  "In %s, Peer " MAC_ADDRESS_STR
3202 			  " denied, Mac filter mode is eSAP_DENY_UNLESS_ACCEPTED",
3203 			  __func__, MAC_ADDR_ARRAY(peerMac));
3204 		return QDF_STATUS_E_FAILURE;
3205 	}
3206 
3207 	/* The new STA is neither in accept list nor in deny list. In this case, deny the association
3208 	 * but send a wifi event notification indicating the mac address being denied
3209 	 */
3210 	if (eSAP_SUPPORT_ACCEPT_AND_DENY == sapContext->eSapMacAddrAclMode) {
3211 		sap_signal_hdd_event(sapContext, NULL, eSAP_UNKNOWN_STA_JOIN,
3212 				     (void *) peerMac);
3213 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3214 			  "In %s, Peer " MAC_ADDRESS_STR
3215 			  " denied, Mac filter mode is eSAP_SUPPORT_ACCEPT_AND_DENY",
3216 			  __func__, MAC_ADDR_ARRAY(peerMac));
3217 		return QDF_STATUS_E_FAILURE;
3218 	}
3219 	return QDF_STATUS_SUCCESS;
3220 }
3221 
3222 #ifdef SOFTAP_CHANNEL_RANGE
3223 /**
3224  * sap_get_channel_list() - get the list of channels
3225  * @sap_ctx: sap context
3226  * @ch_list: pointer to channel list array
3227  * @num_ch: pointer to number of channels.
3228  *
3229  * This function populates the list of channels for scanning.
3230  *
3231  * Return: QDF_STATUS
3232  */
3233 static QDF_STATUS sap_get_channel_list(struct sap_context *sap_ctx,
3234 				       uint8_t **ch_list,
3235 				       uint8_t *num_ch)
3236 {
3237 	uint8_t loop_count;
3238 	uint8_t *list;
3239 	uint8_t ch_count;
3240 	uint8_t start_ch_num, band_start_ch;
3241 	uint8_t end_ch_num, band_end_ch;
3242 	uint32_t en_lte_coex;
3243 	tHalHandle hal = CDS_GET_HAL_CB();
3244 #ifdef FEATURE_WLAN_CH_AVOID
3245 	uint8_t i;
3246 #endif
3247 	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
3248 	tSapChSelSpectInfo spect_info_obj = { NULL, 0 };
3249 	uint16_t ch_width;
3250 
3251 	if (NULL == hal) {
3252 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3253 			FL("Invalid HAL pointer from p_cds_gctx"));
3254 		*num_ch = 0;
3255 		*ch_list = NULL;
3256 		return QDF_STATUS_E_FAULT;
3257 	}
3258 
3259 	start_ch_num = sap_ctx->acs_cfg->start_ch;
3260 	end_ch_num = sap_ctx->acs_cfg->end_ch;
3261 	ch_width = sap_ctx->acs_cfg->ch_width;
3262 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
3263 		  FL("startChannel %d, EndChannel %d, ch_width %d, HW:%d"),
3264 		     start_ch_num, end_ch_num, ch_width,
3265 		     sap_ctx->acs_cfg->hw_mode);
3266 
3267 	wlansap_extend_to_acs_range(hal, &start_ch_num, &end_ch_num,
3268 					    &band_start_ch, &band_end_ch);
3269 
3270 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
3271 			  FL("expanded startChannel %d,EndChannel %d"),
3272 			  start_ch_num, end_ch_num);
3273 
3274 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
3275 			  FL("band_start_ch %d, band_end_ch %d"),
3276 			  band_start_ch, band_end_ch);
3277 
3278 	sme_cfg_get_int(hal, WNI_CFG_ENABLE_LTE_COEX, &en_lte_coex);
3279 
3280 	/* Check if LTE coex is enabled and 2.4GHz is selected */
3281 	if (en_lte_coex && (band_start_ch == CHAN_ENUM_1) &&
3282 	    (band_end_ch == CHAN_ENUM_14)) {
3283 		/* Set 2.4GHz upper limit to channel 9 for LTE COEX */
3284 		band_end_ch = CHAN_ENUM_9;
3285 	}
3286 
3287 	/* Allocate the max number of channel supported */
3288 	list = (uint8_t *) qdf_mem_malloc(NUM_5GHZ_CHANNELS +
3289 						NUM_24GHZ_CHANNELS);
3290 	if (NULL == list) {
3291 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3292 			  FL("Unable to allocate channel list"));
3293 		*num_ch = 0;
3294 		*ch_list = NULL;
3295 		return QDF_STATUS_E_NOMEM;
3296 	}
3297 
3298 	/* Search for the Active channels in the given range */
3299 	ch_count = 0;
3300 	for (loop_count = band_start_ch; loop_count <= band_end_ch;
3301 	     loop_count++) {
3302 		/* go to next channel if rf_channel is out of range */
3303 		if ((start_ch_num > WLAN_REG_CH_NUM(loop_count)) ||
3304 		    (end_ch_num < WLAN_REG_CH_NUM(loop_count)))
3305 			continue;
3306 		/*
3307 		 * go to next channel if none of these condition pass
3308 		 * - DFS scan enabled and chan not in CHANNEL_STATE_DISABLE
3309 		 * - DFS scan disable but chan in CHANNEL_STATE_ENABLE
3310 		 */
3311 		if (!(((true == mac_ctx->scan.fEnableDFSChnlScan) &&
3312 		      wlan_reg_get_channel_state(mac_ctx->pdev, loop_count)) ||
3313 		    ((false == mac_ctx->scan.fEnableDFSChnlScan) &&
3314 		     (CHANNEL_STATE_ENABLE ==
3315 		      wlan_reg_get_channel_state(mac_ctx->pdev, loop_count)))))
3316 			continue;
3317 
3318 		/*
3319 		 * Skip the channels which are not in ACS config from user
3320 		 * space
3321 		 */
3322 		if (SAP_CHANNEL_NOT_SELECTED ==
3323 			sap_channel_in_acs_channel_list(
3324 				WLAN_REG_CH_NUM(loop_count),
3325 				sap_ctx, &spect_info_obj))
3326 			continue;
3327 		/* Dont scan DFS channels in case of MCC disallowed
3328 		 * As it can result in SAP starting on DFS channel
3329 		 * resulting  MCC on DFS channel
3330 		 */
3331 		if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
3332 		    WLAN_REG_CH_NUM(loop_count)) &&
3333 		    policy_mgr_disallow_mcc(mac_ctx->psoc,
3334 		    WLAN_REG_CH_NUM(loop_count)))
3335 			continue;
3336 
3337 		/*
3338 		 * If we have any 5Ghz channel in the channel list
3339 		 * and bw is 40/80/160 Mhz then we don't want SAP to
3340 		 * come up in 2.4Ghz as for 40Mhz, 2.4Ghz channel is
3341 		 * not preferred and 80/160Mhz is not allowed for 2.4Ghz
3342 		 * band. So, don't even scan on 2.4Ghz channels if bw is
3343 		 * 40/80/160Mhz and channel list has any 5Ghz channel.
3344 		 */
3345 		if (end_ch_num >= WLAN_REG_CH_NUM(CHAN_ENUM_36) &&
3346 		    ((ch_width == CH_WIDTH_40MHZ) ||
3347 		     (ch_width == CH_WIDTH_80MHZ) ||
3348 		     (ch_width == CH_WIDTH_80P80MHZ) ||
3349 		     (ch_width == CH_WIDTH_160MHZ))) {
3350 			if (WLAN_REG_CH_NUM(loop_count) >=
3351 			    WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
3352 			    WLAN_REG_CH_NUM(loop_count) <=
3353 			    WLAN_REG_CH_NUM(CHAN_ENUM_14))
3354 				continue;
3355 		}
3356 
3357 #ifdef FEATURE_WLAN_CH_AVOID
3358 		for (i = 0; i < NUM_CHANNELS; i++) {
3359 			if (safe_channels[i].channelNumber ==
3360 			     WLAN_REG_CH_NUM(loop_count)) {
3361 				/* Check if channel is safe */
3362 				if (true == safe_channels[i].isSafe) {
3363 #endif
3364 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
3365 		uint8_t ch;
3366 
3367 		ch = WLAN_REG_CH_NUM(loop_count);
3368 		if ((sap_ctx->acs_cfg->skip_scan_status ==
3369 			eSAP_DO_PAR_ACS_SCAN)) {
3370 		    if ((ch >= sap_ctx->acs_cfg->skip_scan_range1_stch &&
3371 			 ch <= sap_ctx->acs_cfg->skip_scan_range1_endch) ||
3372 			(ch >= sap_ctx->acs_cfg->skip_scan_range2_stch &&
3373 			 ch <= sap_ctx->acs_cfg->skip_scan_range2_endch)) {
3374 			list[ch_count] =
3375 				WLAN_REG_CH_NUM(loop_count);
3376 			ch_count++;
3377 			QDF_TRACE(QDF_MODULE_ID_SAP,
3378 				QDF_TRACE_LEVEL_INFO,
3379 				FL("%d %d added to ACS ch range"),
3380 				ch_count, ch);
3381 		    } else {
3382 			QDF_TRACE(QDF_MODULE_ID_SAP,
3383 				QDF_TRACE_LEVEL_INFO_HIGH,
3384 				FL("%d %d skipped from ACS ch range"),
3385 				ch_count, ch);
3386 		    }
3387 		} else {
3388 			list[ch_count] =
3389 				WLAN_REG_CH_NUM(loop_count);
3390 			ch_count++;
3391 			QDF_TRACE(QDF_MODULE_ID_SAP,
3392 				QDF_TRACE_LEVEL_INFO,
3393 				FL("%d %d added to ACS ch range"),
3394 				ch_count, ch);
3395 		}
3396 #else
3397 		list[ch_count] = WLAN_REG_CH_NUM(loop_count);
3398 		ch_count++;
3399 #endif
3400 #ifdef FEATURE_WLAN_CH_AVOID
3401 				}
3402 				break;
3403 			}
3404 		}
3405 #endif
3406 	}
3407 	if (0 == ch_count) {
3408 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3409 		    FL("No active channels present for the current region"));
3410 		/*
3411 		 * LTE COEX: channel range outside the restricted 2.4GHz
3412 		 * band limits
3413 		 */
3414 		if (en_lte_coex && (start_ch_num > band_end_ch))
3415 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
3416 				FL("SAP can't be started as due to LTE COEX"));
3417 	}
3418 
3419 	/* return the channel list and number of channels to scan */
3420 	*num_ch = ch_count;
3421 	if (ch_count != 0) {
3422 		*ch_list = list;
3423 	} else {
3424 		*ch_list = NULL;
3425 		qdf_mem_free(list);
3426 	}
3427 
3428 	for (loop_count = 0; loop_count < ch_count; loop_count++) {
3429 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
3430 			FL("channel number: %d"), list[loop_count]);
3431 	}
3432 	return QDF_STATUS_SUCCESS;
3433 }
3434 #endif
3435 
3436 #ifdef DFS_COMPONENT_ENABLE
3437 uint8_t sap_indicate_radar(struct sap_context *sap_ctx)
3438 {
3439 	uint8_t target_channel = 0;
3440 	tHalHandle hal;
3441 	tpAniSirGlobal mac;
3442 
3443 	if (!sap_ctx) {
3444 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3445 			FL("null sap_ctx"));
3446 		return 0;
3447 	}
3448 
3449 	hal = CDS_GET_HAL_CB();
3450 	if (!hal) {
3451 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3452 			FL("null hal"));
3453 		return 0;
3454 	}
3455 
3456 	mac = PMAC_STRUCT(hal);
3457 
3458 	/*
3459 	 * SAP needs to generate Channel Switch IE
3460 	 * if the radar is found in the STARTED state
3461 	 */
3462 	if (eSAP_STARTED == sap_ctx->sapsMachine)
3463 		mac->sap.SapDfsInfo.csaIERequired = true;
3464 
3465 	if (sap_ctx->csr_roamProfile.disableDFSChSwitch)
3466 		return sap_ctx->channel;
3467 
3468 	/* set the Radar Found flag in SapDfsInfo */
3469 	mac->sap.SapDfsInfo.sap_radar_found_status = true;
3470 
3471 	if (sap_ctx->chan_before_pre_cac) {
3472 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
3473 			FL("sapdfs: set chan before pre cac %d as target chan"),
3474 			sap_ctx->chan_before_pre_cac);
3475 		return sap_ctx->chan_before_pre_cac;
3476 	}
3477 
3478 	if (sap_ctx->vendor_acs_dfs_lte_enabled && (QDF_STATUS_SUCCESS ==
3479 	    sap_signal_hdd_event(sap_ctx, NULL, eSAP_DFS_NEXT_CHANNEL_REQ,
3480 	    (void *) eSAP_STATUS_SUCCESS)))
3481 		return 0;
3482 
3483 	target_channel = sap_random_channel_sel(sap_ctx);
3484 	if (!target_channel)
3485 		sap_signal_hdd_event(sap_ctx, NULL,
3486 		eSAP_DFS_NO_AVAILABLE_CHANNEL, (void *) eSAP_STATUS_SUCCESS);
3487 
3488 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
3489 		  FL("sapdfs: New selected target channel is [%d]"),
3490 		  target_channel);
3491 
3492 	return target_channel;
3493 }
3494 #endif
3495 
3496 /*
3497  * CAC timer callback function.
3498  * Post eSAP_DFS_CHANNEL_CAC_END event to sap_fsm().
3499  */
3500 void sap_dfs_cac_timer_callback(void *data)
3501 {
3502 	struct sap_context *sapContext;
3503 	tWLAN_SAPEvent sapEvent;
3504 	tHalHandle hHal = (tHalHandle) data;
3505 	tpAniSirGlobal pMac;
3506 
3507 	if (NULL == hHal) {
3508 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3509 			  "In %s invalid hHal", __func__);
3510 		return;
3511 	}
3512 	pMac = PMAC_STRUCT(hHal);
3513 	sapContext = sap_find_cac_wait_session(hHal);
3514 	if (NULL == sapContext) {
3515 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3516 			"%s: no SAP contexts in wait state", __func__);
3517 		return;
3518 	}
3519 
3520 	/*
3521 	 * SAP may not be in CAC wait state, when the timer runs out.
3522 	 * if following flag is set, then timer is in initialized state,
3523 	 * destroy timer here.
3524 	 */
3525 	if (pMac->sap.SapDfsInfo.is_dfs_cac_timer_running == true) {
3526 		if (!sapContext->dfs_cac_offload)
3527 			qdf_mc_timer_destroy(
3528 				&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
3529 		pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = false;
3530 	}
3531 
3532 	/*
3533 	 * CAC Complete, post eSAP_DFS_CHANNEL_CAC_END to sap_fsm
3534 	 */
3535 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3536 			"sapdfs: Sending eSAP_DFS_CHANNEL_CAC_END for target_channel = %d on sapctx[%pK]",
3537 			sapContext->channel, sapContext);
3538 
3539 	sapEvent.event = eSAP_DFS_CHANNEL_CAC_END;
3540 	sapEvent.params = 0;
3541 	sapEvent.u1 = 0;
3542 	sapEvent.u2 = 0;
3543 
3544 	sap_fsm(sapContext, &sapEvent);
3545 }
3546 
3547 /*
3548  * Function to stop the DFS CAC Timer
3549  */
3550 static int sap_stop_dfs_cac_timer(struct sap_context *sapContext)
3551 {
3552 	tHalHandle hHal;
3553 	tpAniSirGlobal pMac;
3554 
3555 	if (sapContext == NULL)
3556 		return 0;
3557 
3558 	hHal = CDS_GET_HAL_CB();
3559 	if (NULL == hHal) {
3560 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3561 			  "In %s invalid hHal", __func__);
3562 		return 0;
3563 	}
3564 	pMac = PMAC_STRUCT(hHal);
3565 
3566 	if (sapContext->dfs_cac_offload) {
3567 		pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
3568 		return 0;
3569 	}
3570 
3571 	if (QDF_TIMER_STATE_RUNNING !=
3572 	    qdf_mc_timer_get_current_state(&pMac->sap.SapDfsInfo.
3573 					   sap_dfs_cac_timer)) {
3574 		return 0;
3575 	}
3576 
3577 	qdf_mc_timer_stop(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
3578 	pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
3579 	qdf_mc_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
3580 
3581 	return 0;
3582 }
3583 
3584 
3585 /*
3586  * Function to start the DFS CAC Timer
3587  * when SAP is started on a DFS channel
3588  */
3589 static int sap_start_dfs_cac_timer(struct sap_context *sap_ctx)
3590 {
3591 	QDF_STATUS status;
3592 	uint32_t cac_dur;
3593 	tHalHandle hal = NULL;
3594 	tpAniSirGlobal mac = NULL;
3595 	enum dfs_reg dfs_region;
3596 
3597 	if (!sap_ctx) {
3598 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3599 			  "%s: null sap_ctx", __func__);
3600 		return 0;
3601 	}
3602 
3603 	hal = CDS_GET_HAL_CB();
3604 	if (!hal) {
3605 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3606 			  "%s: null hal", __func__);
3607 		return 0;
3608 	}
3609 
3610 	mac = PMAC_STRUCT(hal);
3611 	if (sap_ctx->dfs_cac_offload) {
3612 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
3613 			  "%s: cac timer offloaded to firmware", __func__);
3614 		mac->sap.SapDfsInfo.is_dfs_cac_timer_running = true;
3615 		return 1;
3616 	}
3617 
3618 	sap_get_cac_dur_dfs_region(sap_ctx, &cac_dur, &dfs_region);
3619 	if (0 == cac_dur)
3620 		return 0;
3621 
3622 #ifdef QCA_WIFI_NAPIER_EMULATION
3623 	cac_dur = cac_dur / 100;
3624 #endif
3625 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3626 		  "sapdfs: SAP_DFS_CHANNEL_CAC_START on CH-%d, CAC_DUR-%d sec",
3627 		  sap_ctx->channel, cac_dur / 1000);
3628 
3629 	qdf_mc_timer_init(&mac->sap.SapDfsInfo.sap_dfs_cac_timer,
3630 			  QDF_TIMER_TYPE_SW,
3631 			  sap_dfs_cac_timer_callback, (void *)hal);
3632 
3633 	/* Start the CAC timer */
3634 	status = qdf_mc_timer_start(&mac->sap.SapDfsInfo.sap_dfs_cac_timer,
3635 			cac_dur);
3636 	if (status == QDF_STATUS_SUCCESS) {
3637 		mac->sap.SapDfsInfo.is_dfs_cac_timer_running = true;
3638 		return 1;
3639 	} else {
3640 		mac->sap.SapDfsInfo.is_dfs_cac_timer_running = false;
3641 		qdf_mc_timer_destroy(&mac->sap.SapDfsInfo.sap_dfs_cac_timer);
3642 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3643 			  "%s: failed to start cac timer", __func__);
3644 		return 0;
3645 	}
3646 }
3647 
3648 /*
3649  * This function initializes the NOL list
3650  * parameters required to track the radar
3651  * found DFS channels in the current Reg. Domain .
3652  */
3653 QDF_STATUS sap_init_dfs_channel_nol_list(struct sap_context *sapContext)
3654 {
3655 	tHalHandle hHal;
3656 	tpAniSirGlobal pMac;
3657 
3658 	if (NULL == sapContext) {
3659 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3660 			  "Invalid sapContext pointer on sap_init_dfs_channel_nol_list");
3661 		return QDF_STATUS_E_FAULT;
3662 	}
3663 	hHal = CDS_GET_HAL_CB();
3664 
3665 	if (NULL == hHal) {
3666 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3667 			  "In %s invalid hHal", __func__);
3668 		return QDF_STATUS_E_FAULT;
3669 	}
3670 	pMac = PMAC_STRUCT(hHal);
3671 
3672 	utils_dfs_init_nol(pMac->pdev);
3673 
3674 	return QDF_STATUS_SUCCESS;
3675 }
3676 
3677 /*
3678  * This function will calculate how many interfaces
3679  * have sap persona and returns total number of sap persona.
3680  */
3681 uint8_t sap_get_total_number_sap_intf(tHalHandle hHal)
3682 {
3683 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3684 	uint8_t intf = 0;
3685 	uint8_t intf_count = 0;
3686 
3687 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
3688 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
3689 		    ||
3690 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
3691 		    && pMac->sap.sapCtxList[intf].sap_context != NULL) {
3692 			intf_count++;
3693 		}
3694 	}
3695 	return intf_count;
3696 }
3697 
3698 /**
3699  * is_concurrent_sap_ready_for_channel_change() - to check all saps are ready
3700  *						  for channel change
3701  * @hHal: HAL pointer
3702  * @sapContext: sap context for which this function has been called
3703  *
3704  * This function will find the concurrent sap context apart from
3705  * passed sap context and return its channel change ready status
3706  *
3707  *
3708  * Return: true if other SAP personas are ready to channel switch else false
3709  */
3710 bool is_concurrent_sap_ready_for_channel_change(tHalHandle hHal,
3711 						struct sap_context *sapContext)
3712 {
3713 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3714 	struct sap_context *sap_context;
3715 	uint8_t intf = 0;
3716 
3717 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
3718 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
3719 		    ||
3720 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
3721 		    && pMac->sap.sapCtxList[intf].sap_context != NULL) {
3722 			sap_context =
3723 				pMac->sap.sapCtxList[intf].sap_context;
3724 			if (sap_context == sapContext) {
3725 				QDF_TRACE(QDF_MODULE_ID_SAP,
3726 					  QDF_TRACE_LEVEL_ERROR,
3727 					  FL("sapCtx matched [%pK]"),
3728 					  sapContext);
3729 				continue;
3730 			} else {
3731 				QDF_TRACE(QDF_MODULE_ID_SAP,
3732 					  QDF_TRACE_LEVEL_ERROR,
3733 					  FL
3734 						  ("concurrent sapCtx[%pK] didn't matche with [%pK]"),
3735 					  sap_context, sapContext);
3736 				return sap_context->is_sap_ready_for_chnl_chng;
3737 			}
3738 		}
3739 	}
3740 	return false;
3741 }
3742 
3743 /**
3744  * sap_is_conc_sap_doing_scc_dfs() - check if conc SAPs are doing SCC DFS
3745  * @hal: pointer to hal
3746  * @sap_context: current SAP persona's channel
3747  *
3748  * If provided SAP's channel is DFS then Loop through each SAP or GO persona and
3749  * check if other beaconing entity's channel is same DFS channel. If they are
3750  * same then concurrent sap is doing SCC DFS.
3751  *
3752  * Return: true if two or more beaconing entitity doing SCC DFS else false
3753  */
3754 bool sap_is_conc_sap_doing_scc_dfs(tHalHandle hal,
3755 				   struct sap_context *given_sapctx)
3756 {
3757 	tpAniSirGlobal mac = PMAC_STRUCT(hal);
3758 	struct sap_context *sap_ctx;
3759 	uint8_t intf = 0, scc_dfs_counter = 0;
3760 
3761 	/*
3762 	 * current SAP persona's channel itself is not DFS, so no need to check
3763 	 * what other persona's channel is
3764 	 */
3765 	if (!wlan_reg_is_dfs_ch(mac->pdev,
3766 			given_sapctx->csr_roamProfile.operationChannel)) {
3767 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
3768 			  FL("skip this loop as provided channel is non-dfs"));
3769 		return false;
3770 	}
3771 
3772 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
3773 		if ((QDF_SAP_MODE != mac->sap.sapCtxList[intf].sapPersona) &&
3774 		    (QDF_P2P_GO_MODE != mac->sap.sapCtxList[intf].sapPersona))
3775 			continue;
3776 		if (!mac->sap.sapCtxList[intf].sap_context)
3777 			continue;
3778 		sap_ctx = mac->sap.sapCtxList[intf].sap_context;
3779 		/* if same SAP contexts then skip to next context */
3780 		if (sap_ctx == given_sapctx)
3781 			continue;
3782 		if (given_sapctx->csr_roamProfile.operationChannel ==
3783 				sap_ctx->csr_roamProfile.operationChannel)
3784 			scc_dfs_counter++;
3785 	}
3786 
3787 	/* Found atleast two of the beaconing entities doing SCC DFS */
3788 	if (scc_dfs_counter)
3789 		return true;
3790 
3791 	return false;
3792 }
3793