xref: /wlan-dirver/qcacld-3.0/core/sap/src/sap_fsm.c (revision 75795d61a6758742814b135a806ae32b342c28f5)
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->ch_width = sap_ctx->ch_params.ch_width;
1533 		bss_complete->sessionId = sap_ctx->sessionId;
1534 		break;
1535 	case eSAP_DFS_CAC_START:
1536 	case eSAP_DFS_CAC_INTERRUPTED:
1537 	case eSAP_DFS_CAC_END:
1538 	case eSAP_DFS_PRE_CAC_END:
1539 	case eSAP_DFS_RADAR_DETECT:
1540 	case eSAP_DFS_RADAR_DETECT_DURING_PRE_CAC:
1541 	case eSAP_DFS_NO_AVAILABLE_CHANNEL:
1542 		sap_ap_event.sapHddEventCode = sap_hddevent;
1543 		sap_ap_event.sapevt.sapStopBssCompleteEvent.status =
1544 			(eSapStatus) context;
1545 		break;
1546 	case eSAP_ACS_SCAN_SUCCESS_EVENT:
1547 		sap_handle_acs_scan_event(sap_ctx, &sap_ap_event,
1548 			(eSapStatus)context);
1549 		break;
1550 	case eSAP_ACS_CHANNEL_SELECTED:
1551 		sap_ap_event.sapHddEventCode = sap_hddevent;
1552 		acs_selected = &sap_ap_event.sapevt.sap_ch_selected;
1553 		if (eSAP_STATUS_SUCCESS == (eSapStatus)context) {
1554 			acs_selected->pri_ch = sap_ctx->acs_cfg->pri_ch;
1555 			acs_selected->ht_sec_ch = sap_ctx->acs_cfg->ht_sec_ch;
1556 			acs_selected->ch_width = sap_ctx->acs_cfg->ch_width;
1557 			acs_selected->vht_seg0_center_ch =
1558 				sap_ctx->acs_cfg->vht_seg0_center_ch;
1559 			acs_selected->vht_seg1_center_ch =
1560 				sap_ctx->acs_cfg->vht_seg1_center_ch;
1561 		} else if (eSAP_STATUS_FAILURE == (eSapStatus)context) {
1562 			acs_selected->pri_ch = 0;
1563 		}
1564 		break;
1565 
1566 	case eSAP_STOP_BSS_EVENT:
1567 		sap_ap_event.sapHddEventCode = eSAP_STOP_BSS_EVENT;
1568 		sap_ap_event.sapevt.sapStopBssCompleteEvent.status =
1569 			(eSapStatus) context;
1570 		break;
1571 
1572 	case eSAP_STA_ASSOC_EVENT:
1573 	case eSAP_STA_REASSOC_EVENT:
1574 
1575 		if (!csr_roaminfo) {
1576 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1577 				  FL("Invalid CSR Roam Info"));
1578 			return QDF_STATUS_E_INVAL;
1579 		}
1580 		if (eSAP_DISCONNECTING == sap_ctx->sapsMachine) {
1581 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1582 				  "SAP is disconnecting, not able to handle any incoming (re)assoc req");
1583 			return QDF_STATUS_E_ABORTED;
1584 		}
1585 
1586 		reassoc_complete =
1587 		    &sap_ap_event.sapevt.sapStationAssocReassocCompleteEvent;
1588 
1589 		if (csr_roaminfo->fReassocReq)
1590 			sap_ap_event.sapHddEventCode = eSAP_STA_REASSOC_EVENT;
1591 		else
1592 			sap_ap_event.sapHddEventCode = eSAP_STA_ASSOC_EVENT;
1593 
1594 		qdf_copy_macaddr(&reassoc_complete->staMac,
1595 				 &csr_roaminfo->peerMac);
1596 		reassoc_complete->staId = csr_roaminfo->staId;
1597 		reassoc_complete->statusCode = csr_roaminfo->statusCode;
1598 		reassoc_complete->iesLen = csr_roaminfo->rsnIELen;
1599 		qdf_mem_copy(reassoc_complete->ies, csr_roaminfo->prsnIE,
1600 			     csr_roaminfo->rsnIELen);
1601 
1602 #ifdef FEATURE_WLAN_WAPI
1603 		if (csr_roaminfo->wapiIELen) {
1604 			uint8_t len = reassoc_complete->iesLen;
1605 
1606 			reassoc_complete->iesLen += csr_roaminfo->wapiIELen;
1607 			qdf_mem_copy(&reassoc_complete->ies[len],
1608 				     csr_roaminfo->pwapiIE,
1609 				     csr_roaminfo->wapiIELen);
1610 		}
1611 #endif
1612 		if (csr_roaminfo->addIELen) {
1613 			uint8_t len = reassoc_complete->iesLen;
1614 
1615 			reassoc_complete->iesLen += csr_roaminfo->addIELen;
1616 			qdf_mem_copy(&reassoc_complete->ies[len],
1617 				     csr_roaminfo->paddIE,
1618 				     csr_roaminfo->addIELen);
1619 			if (wlan_get_vendor_ie_ptr_from_oui(
1620 			    SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE,
1621 			    csr_roaminfo->paddIE, csr_roaminfo->addIELen)) {
1622 				reassoc_complete->staType = eSTA_TYPE_P2P_CLI;
1623 			} else {
1624 				reassoc_complete->staType = eSTA_TYPE_INFRA;
1625 			}
1626 		}
1627 
1628 		/* also fill up the channel info from the csr_roamInfo */
1629 		chaninfo = &reassoc_complete->chan_info;
1630 
1631 		chaninfo->chan_id = csr_roaminfo->chan_info.chan_id;
1632 		chaninfo->mhz = csr_roaminfo->chan_info.mhz;
1633 		chaninfo->info = csr_roaminfo->chan_info.info;
1634 		chaninfo->band_center_freq1 =
1635 			csr_roaminfo->chan_info.band_center_freq1;
1636 		chaninfo->band_center_freq2 =
1637 			csr_roaminfo->chan_info.band_center_freq2;
1638 		chaninfo->reg_info_1 =
1639 			csr_roaminfo->chan_info.reg_info_1;
1640 		chaninfo->reg_info_2 =
1641 			csr_roaminfo->chan_info.reg_info_2;
1642 		chaninfo->nss = csr_roaminfo->chan_info.nss;
1643 		chaninfo->rate_flags = csr_roaminfo->chan_info.rate_flags;
1644 
1645 		reassoc_complete->wmmEnabled = csr_roaminfo->wmmEnabledSta;
1646 		reassoc_complete->status = (eSapStatus) context;
1647 		reassoc_complete->timingMeasCap = csr_roaminfo->timingMeasCap;
1648 		reassoc_complete->ampdu = csr_roaminfo->ampdu;
1649 		reassoc_complete->sgi_enable = csr_roaminfo->sgi_enable;
1650 		reassoc_complete->tx_stbc = csr_roaminfo->tx_stbc;
1651 		reassoc_complete->rx_stbc = csr_roaminfo->rx_stbc;
1652 		reassoc_complete->ch_width = csr_roaminfo->ch_width;
1653 		reassoc_complete->mode = csr_roaminfo->mode;
1654 		reassoc_complete->max_supp_idx = csr_roaminfo->max_supp_idx;
1655 		reassoc_complete->max_ext_idx = csr_roaminfo->max_ext_idx;
1656 		reassoc_complete->max_mcs_idx = csr_roaminfo->max_mcs_idx;
1657 		reassoc_complete->rx_mcs_map = csr_roaminfo->rx_mcs_map;
1658 		reassoc_complete->tx_mcs_map = csr_roaminfo->tx_mcs_map;
1659 		reassoc_complete->ecsa_capable = csr_roaminfo->ecsa_capable;
1660 		if (csr_roaminfo->ht_caps.present)
1661 			reassoc_complete->ht_caps = csr_roaminfo->ht_caps;
1662 		if (csr_roaminfo->vht_caps.present)
1663 			reassoc_complete->vht_caps = csr_roaminfo->vht_caps;
1664 
1665 		break;
1666 
1667 	case eSAP_STA_DISASSOC_EVENT:
1668 		if (!csr_roaminfo) {
1669 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1670 				  FL("Invalid CSR Roam Info"));
1671 			return QDF_STATUS_E_INVAL;
1672 		}
1673 		sap_ap_event.sapHddEventCode = eSAP_STA_DISASSOC_EVENT;
1674 		disassoc_comp =
1675 			&sap_ap_event.sapevt.sapStationDisassocCompleteEvent;
1676 
1677 		qdf_copy_macaddr(&disassoc_comp->staMac,
1678 				 &csr_roaminfo->peerMac);
1679 		disassoc_comp->staId = csr_roaminfo->staId;
1680 		if (csr_roaminfo->reasonCode == eCSR_ROAM_RESULT_FORCED)
1681 			disassoc_comp->reason = eSAP_USR_INITATED_DISASSOC;
1682 		else
1683 			disassoc_comp->reason = eSAP_MAC_INITATED_DISASSOC;
1684 
1685 		disassoc_comp->statusCode = csr_roaminfo->statusCode;
1686 		disassoc_comp->status = (eSapStatus) context;
1687 		disassoc_comp->rssi = csr_roaminfo->rssi;
1688 		disassoc_comp->rx_rate = csr_roaminfo->rx_rate;
1689 		disassoc_comp->tx_rate = csr_roaminfo->tx_rate;
1690 		disassoc_comp->reason_code = csr_roaminfo->disassoc_reason;
1691 		break;
1692 
1693 	case eSAP_STA_SET_KEY_EVENT:
1694 
1695 		if (!csr_roaminfo) {
1696 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1697 				  FL("Invalid CSR Roam Info"));
1698 			return QDF_STATUS_E_INVAL;
1699 		}
1700 		sap_ap_event.sapHddEventCode = eSAP_STA_SET_KEY_EVENT;
1701 		key_complete =
1702 			&sap_ap_event.sapevt.sapStationSetKeyCompleteEvent;
1703 		key_complete->status = (eSapStatus) context;
1704 		qdf_copy_macaddr(&key_complete->peerMacAddr,
1705 				 &csr_roaminfo->peerMac);
1706 		break;
1707 
1708 	case eSAP_STA_MIC_FAILURE_EVENT:
1709 
1710 		if (!csr_roaminfo) {
1711 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1712 				  FL("Invalid CSR Roam Info"));
1713 			return QDF_STATUS_E_INVAL;
1714 		}
1715 		sap_ap_event.sapHddEventCode = eSAP_STA_MIC_FAILURE_EVENT;
1716 		mic_failure = &sap_ap_event.sapevt.sapStationMICFailureEvent;
1717 
1718 		qdf_mem_copy(&mic_failure->srcMacAddr,
1719 			     csr_roaminfo->u.pMICFailureInfo->srcMacAddr,
1720 			     sizeof(tSirMacAddr));
1721 		qdf_mem_copy(&mic_failure->staMac.bytes,
1722 			     csr_roaminfo->u.pMICFailureInfo->taMacAddr,
1723 			     sizeof(tSirMacAddr));
1724 		qdf_mem_copy(&mic_failure->dstMacAddr.bytes,
1725 			     csr_roaminfo->u.pMICFailureInfo->dstMacAddr,
1726 			     sizeof(tSirMacAddr));
1727 		mic_failure->multicast =
1728 			csr_roaminfo->u.pMICFailureInfo->multicast;
1729 		mic_failure->IV1 = csr_roaminfo->u.pMICFailureInfo->IV1;
1730 		mic_failure->keyId = csr_roaminfo->u.pMICFailureInfo->keyId;
1731 		qdf_mem_copy(mic_failure->TSC,
1732 			     csr_roaminfo->u.pMICFailureInfo->TSC,
1733 			     SIR_CIPHER_SEQ_CTR_SIZE);
1734 		break;
1735 
1736 	case eSAP_ASSOC_STA_CALLBACK_EVENT:
1737 		break;
1738 
1739 	case eSAP_WPS_PBC_PROBE_REQ_EVENT:
1740 
1741 		if (!csr_roaminfo) {
1742 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1743 				  FL("Invalid CSR Roam Info"));
1744 			return QDF_STATUS_E_INVAL;
1745 		}
1746 		sap_ap_event.sapHddEventCode = eSAP_WPS_PBC_PROBE_REQ_EVENT;
1747 
1748 		qdf_mem_copy(&sap_ap_event.sapevt.sapPBCProbeReqEvent.
1749 			     WPSPBCProbeReq, csr_roaminfo->u.pWPSPBCProbeReq,
1750 			     sizeof(tSirWPSPBCProbeReq));
1751 		break;
1752 
1753 	case eSAP_DISCONNECT_ALL_P2P_CLIENT:
1754 		sap_ap_event.sapHddEventCode = eSAP_DISCONNECT_ALL_P2P_CLIENT;
1755 		sap_ap_event.sapevt.sapActionCnf.actionSendSuccess =
1756 			(eSapStatus) context;
1757 		break;
1758 
1759 	case eSAP_MAC_TRIG_STOP_BSS_EVENT:
1760 		sap_ap_event.sapHddEventCode = eSAP_MAC_TRIG_STOP_BSS_EVENT;
1761 		sap_ap_event.sapevt.sapActionCnf.actionSendSuccess =
1762 			(eSapStatus) context;
1763 		break;
1764 
1765 	case eSAP_UNKNOWN_STA_JOIN:
1766 		sap_ap_event.sapHddEventCode = eSAP_UNKNOWN_STA_JOIN;
1767 		qdf_mem_copy((void *) sap_ap_event.sapevt.sapUnknownSTAJoin.
1768 			     macaddr.bytes, (void *) context,
1769 			     QDF_MAC_ADDR_SIZE);
1770 		break;
1771 
1772 	case eSAP_MAX_ASSOC_EXCEEDED:
1773 
1774 		if (!csr_roaminfo) {
1775 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1776 				  FL("Invalid CSR Roam Info"));
1777 			return QDF_STATUS_E_INVAL;
1778 		}
1779 		sap_ap_event.sapHddEventCode = eSAP_MAX_ASSOC_EXCEEDED;
1780 		qdf_copy_macaddr(&sap_ap_event.sapevt.
1781 				 sapMaxAssocExceeded.macaddr,
1782 				 &csr_roaminfo->peerMac);
1783 		break;
1784 
1785 	case eSAP_CHANNEL_CHANGE_EVENT:
1786 		/*
1787 		 * Reconfig ACS result info. For DFS AP-AP Mode Sec AP ACS
1788 		 * follows pri AP
1789 		 */
1790 		sap_ctx->acs_cfg->pri_ch = sap_ctx->channel;
1791 		sap_ctx->acs_cfg->ch_width =
1792 				sap_ctx->csr_roamProfile.ch_params.ch_width;
1793 		sap_config_acs_result(hal, sap_ctx, sap_ctx->secondary_ch);
1794 
1795 		sap_ap_event.sapHddEventCode = eSAP_CHANNEL_CHANGE_EVENT;
1796 
1797 		acs_selected = &sap_ap_event.sapevt.sap_ch_selected;
1798 		acs_selected->pri_ch = sap_ctx->acs_cfg->pri_ch;
1799 		acs_selected->ht_sec_ch = sap_ctx->acs_cfg->ht_sec_ch;
1800 		acs_selected->ch_width =
1801 			sap_ctx->csr_roamProfile.ch_params.ch_width;
1802 		acs_selected->vht_seg0_center_ch =
1803 			sap_ctx->csr_roamProfile.ch_params.center_freq_seg0;
1804 		acs_selected->vht_seg1_center_ch =
1805 			sap_ctx->csr_roamProfile.ch_params.center_freq_seg1;
1806 		break;
1807 
1808 	case eSAP_ECSA_CHANGE_CHAN_IND:
1809 
1810 		if (!csr_roaminfo) {
1811 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1812 				  FL("Invalid CSR Roam Info"));
1813 			return QDF_STATUS_E_INVAL;
1814 		}
1815 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1816 				"In %s, SAP event callback event = %s",
1817 				__func__, "eSAP_ECSA_CHANGE_CHAN_IND");
1818 		sap_ap_event.sapHddEventCode = eSAP_ECSA_CHANGE_CHAN_IND;
1819 		sap_ap_event.sapevt.sap_chan_cng_ind.new_chan =
1820 					   csr_roaminfo->target_channel;
1821 		break;
1822 	case eSAP_DFS_NEXT_CHANNEL_REQ:
1823 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1824 				"In %s, SAP event callback event = %s",
1825 				__func__, "eSAP_DFS_NEXT_CHANNEL_REQ");
1826 		sap_ap_event.sapHddEventCode = eSAP_DFS_NEXT_CHANNEL_REQ;
1827 		break;
1828 	case eSAP_STOP_BSS_DUE_TO_NO_CHNL:
1829 		sap_ap_event.sapHddEventCode = eSAP_STOP_BSS_DUE_TO_NO_CHNL;
1830 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
1831 			  FL("stopping session_id:%d, bssid:%pM, channel:%d"),
1832 			     sap_ctx->sessionId, sap_ctx->self_mac_addr,
1833 			     sap_ctx->channel);
1834 		break;
1835 	default:
1836 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1837 			  FL("SAP Unknown callback event = %d"),
1838 			  sap_hddevent);
1839 		break;
1840 	}
1841 	qdf_status = (*sap_ctx->pfnSapEventCallback)
1842 			(&sap_ap_event, sap_ctx->pUsrContext);
1843 
1844 	return qdf_status;
1845 
1846 }
1847 
1848 /**
1849  * sap_find_cac_wait_session() - Get context of a SAP session in CAC wait state
1850  * @handle: Global MAC handle
1851  *
1852  * Finds and gets the context of a SAP session in CAC wait state.
1853  *
1854  * Return: Valid SAP context on success, else NULL
1855  */
1856 static struct sap_context *sap_find_cac_wait_session(tHalHandle handle)
1857 {
1858 	tpAniSirGlobal mac = PMAC_STRUCT(handle);
1859 	uint8_t i = 0;
1860 	struct sap_context *sapContext;
1861 
1862 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
1863 			"%s", __func__);
1864 
1865 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
1866 		sapContext = mac->sap.sapCtxList[i].sap_context;
1867 		if (((QDF_SAP_MODE == mac->sap.sapCtxList[i].sapPersona)
1868 		    ||
1869 		    (QDF_P2P_GO_MODE == mac->sap.sapCtxList[i].sapPersona)) &&
1870 		    (sapContext) &&
1871 		    (sapContext->sapsMachine == eSAP_DFS_CAC_WAIT)) {
1872 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
1873 				"%s: found SAP in cac wait state", __func__);
1874 			return sapContext;
1875 		}
1876 		if (sapContext) {
1877 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
1878 					"sapdfs: mode:%d intf:%d state:%d",
1879 					mac->sap.sapCtxList[i].sapPersona, i,
1880 					sapContext->sapsMachine);
1881 		}
1882 	}
1883 
1884 	return NULL;
1885 }
1886 
1887 /*==========================================================================
1888    FUNCTION  sap_cac_reset_notify
1889 
1890    DESCRIPTION Function will be called up on stop bss indication to clean up
1891    DFS global structure.
1892 
1893    DEPENDENCIES PARAMETERS
1894      IN hHAL : HAL pointer
1895 
1896    RETURN VALUE  : void.
1897 
1898    SIDE EFFECTS
1899    ============================================================================*/
1900 void sap_cac_reset_notify(tHalHandle hHal)
1901 {
1902 	uint8_t intf = 0;
1903 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1904 
1905 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
1906 		struct sap_context *sap_context =
1907 			pMac->sap.sapCtxList[intf].sap_context;
1908 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
1909 		    ||
1910 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
1911 		    && pMac->sap.sapCtxList[intf].sap_context != NULL) {
1912 			sap_context->isCacStartNotified = false;
1913 			sap_context->isCacEndNotified = false;
1914 		}
1915 	}
1916 }
1917 
1918 /*==========================================================================
1919    FUNCTION  sap_cac_start_notify
1920 
1921    DESCRIPTION Function will be called to notify eSAP_DFS_CAC_START event
1922    to HDD
1923 
1924    DEPENDENCIES PARAMETERS
1925      IN hHAL : HAL pointer
1926 
1927    RETURN VALUE  : QDF_STATUS.
1928 
1929    SIDE EFFECTS
1930    ============================================================================*/
1931 static QDF_STATUS sap_cac_start_notify(tHalHandle hHal)
1932 {
1933 	uint8_t intf = 0;
1934 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1935 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
1936 
1937 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
1938 		struct sap_context *sap_context =
1939 			pMac->sap.sapCtxList[intf].sap_context;
1940 		struct csr_roam_profile *profile;
1941 
1942 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
1943 		    ||
1944 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
1945 		    && pMac->sap.sapCtxList[intf].sap_context != NULL &&
1946 		    (false == sap_context->isCacStartNotified)) {
1947 			/* Don't start CAC for non-dfs channel, its violation */
1948 			profile = &sap_context->csr_roamProfile;
1949 			if (!wlan_reg_is_dfs_ch(pMac->pdev,
1950 						profile->operationChannel))
1951 				continue;
1952 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
1953 				  "sapdfs: Signaling eSAP_DFS_CAC_START to HDD for sapctx[%pK]",
1954 				  sap_context);
1955 
1956 			qdf_status = sap_signal_hdd_event(sap_context, NULL,
1957 							  eSAP_DFS_CAC_START,
1958 							  (void *)
1959 							  eSAP_STATUS_SUCCESS);
1960 			if (QDF_STATUS_SUCCESS != qdf_status) {
1961 				QDF_TRACE(QDF_MODULE_ID_SAP,
1962 					  QDF_TRACE_LEVEL_ERROR,
1963 					  "In %s, failed setting isCacStartNotified on interface[%d]",
1964 					  __func__, intf);
1965 				return qdf_status;
1966 			}
1967 			sap_context->isCacStartNotified = true;
1968 		}
1969 	}
1970 	return qdf_status;
1971 }
1972 
1973 /**
1974  * wlansap_update_pre_cac_end() - Update pre cac end to upper layer
1975  * @sap_context: SAP context
1976  * @mac: Global MAC structure
1977  * @intf: Interface number
1978  *
1979  * Notifies pre cac end to upper layer
1980  *
1981  * Return: QDF_STATUS
1982  */
1983 static QDF_STATUS wlansap_update_pre_cac_end(struct sap_context *sap_context,
1984 		tpAniSirGlobal mac, uint8_t intf)
1985 {
1986 	QDF_STATUS qdf_status;
1987 
1988 	sap_context->isCacEndNotified = true;
1989 	mac->sap.SapDfsInfo.sap_radar_found_status = false;
1990 	sap_context->sapsMachine = eSAP_STARTED;
1991 
1992 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1993 			"In %s, pre cac end notify on %d: from state %s => %s",
1994 			__func__, intf, "eSAP_DFS_CAC_WAIT",
1995 			"eSAP_STARTED");
1996 
1997 	qdf_status = sap_signal_hdd_event(sap_context,
1998 			NULL, eSAP_DFS_PRE_CAC_END,
1999 			(void *)eSAP_STATUS_SUCCESS);
2000 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
2001 		QDF_TRACE(QDF_MODULE_ID_SAP,
2002 				QDF_TRACE_LEVEL_ERROR,
2003 				"In %s, pre cac notify failed on intf %d",
2004 				__func__, intf);
2005 		return qdf_status;
2006 	}
2007 
2008 	return QDF_STATUS_SUCCESS;
2009 }
2010 
2011 /*==========================================================================
2012    FUNCTION  sap_cac_end_notify
2013 
2014    DESCRIPTION Function will be called to notify eSAP_DFS_CAC_END event
2015    to HDD
2016 
2017    DEPENDENCIES PARAMETERS
2018      IN hHAL : HAL pointer
2019 
2020    RETURN VALUE  : QDF_STATUS.
2021 
2022    SIDE EFFECTS
2023    ============================================================================*/
2024 static QDF_STATUS sap_cac_end_notify(tHalHandle hHal,
2025 				     struct csr_roam_info *roamInfo)
2026 {
2027 	uint8_t intf;
2028 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
2029 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2030 
2031 	/*
2032 	 * eSAP_DFS_CHANNEL_CAC_END:
2033 	 * CAC Period elapsed and there was no radar
2034 	 * found so, SAP can continue beaconing.
2035 	 * sap_radar_found_status is set to 0
2036 	 */
2037 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
2038 		struct sap_context *sap_context =
2039 			pMac->sap.sapCtxList[intf].sap_context;
2040 		struct csr_roam_profile *profile;
2041 
2042 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
2043 		    ||
2044 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
2045 		    && pMac->sap.sapCtxList[intf].sap_context != NULL &&
2046 		    (false == sap_context->isCacEndNotified) &&
2047 		    (sap_context->sapsMachine == eSAP_DFS_CAC_WAIT)) {
2048 			sap_context = pMac->sap.sapCtxList[intf].sap_context;
2049 			/* Don't check CAC for non-dfs channel */
2050 			profile = &sap_context->csr_roamProfile;
2051 			if (!wlan_reg_is_dfs_ch(pMac->pdev,
2052 						profile->operationChannel))
2053 				continue;
2054 
2055 			/* If this is an end notification of a pre cac, the
2056 			 * SAP must not start beaconing and must delete the
2057 			 * temporary interface created for pre cac and switch
2058 			 * the original SAP to the pre CAC channel.
2059 			 */
2060 			if (sap_context->is_pre_cac_on) {
2061 				qdf_status = wlansap_update_pre_cac_end(
2062 						sap_context, pMac, intf);
2063 				if (QDF_IS_STATUS_ERROR(qdf_status))
2064 					return qdf_status;
2065 				/* pre CAC is not allowed with any concurrency.
2066 				 * So, we can break from here.
2067 				 */
2068 				break;
2069 			}
2070 
2071 			qdf_status = sap_signal_hdd_event(sap_context, NULL,
2072 							  eSAP_DFS_CAC_END,
2073 							  (void *)
2074 							  eSAP_STATUS_SUCCESS);
2075 			if (QDF_STATUS_SUCCESS != qdf_status) {
2076 				QDF_TRACE(QDF_MODULE_ID_SAP,
2077 					  QDF_TRACE_LEVEL_ERROR,
2078 					  "In %s, failed setting isCacEndNotified on interface[%d]",
2079 					  __func__, intf);
2080 				return qdf_status;
2081 			}
2082 			sap_context->isCacEndNotified = true;
2083 			pMac->sap.SapDfsInfo.sap_radar_found_status = false;
2084 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
2085 				  "sapdfs: Start beacon request on sapctx[%pK]",
2086 				  sap_context);
2087 
2088 			/* Start beaconing on the new channel */
2089 			wlansap_start_beacon_req(sap_context);
2090 
2091 			/* Transition from eSAP_STARTING to eSAP_STARTED
2092 			 * (both without substates)
2093 			 */
2094 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
2095 				  "sapdfs: channel[%d] from state %s => %s",
2096 				  sap_context->channel, "eSAP_STARTING",
2097 				  "eSAP_STARTED");
2098 
2099 			sap_context->sapsMachine = eSAP_STARTED;
2100 
2101 			/*Action code for transition */
2102 			qdf_status = sap_signal_hdd_event(sap_context, roamInfo,
2103 							  eSAP_START_BSS_EVENT,
2104 							  (void *)
2105 							  eSAP_STATUS_SUCCESS);
2106 			if (QDF_STATUS_SUCCESS != qdf_status) {
2107 				QDF_TRACE(QDF_MODULE_ID_SAP,
2108 					  QDF_TRACE_LEVEL_ERROR,
2109 					  "In %s, failed setting isCacEndNotified on interface[%d]",
2110 					  __func__, intf);
2111 				return qdf_status;
2112 			}
2113 
2114 			/* Transition from eSAP_STARTING to eSAP_STARTED
2115 			 * (both without substates)
2116 			 */
2117 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2118 				  "In %s, from state %s => %s",
2119 				  __func__, "eSAP_DFS_CAC_WAIT",
2120 				  "eSAP_STARTED");
2121 		}
2122 	}
2123 	/*
2124 	 * All APs are done with CAC timer, all APs should start beaconing.
2125 	 * Lets assume AP1 and AP2 started beaconing on DFS channel, Now lets
2126 	 * say AP1 goes down and comes back on same DFS channel. In this case
2127 	 * AP1 shouldn't start CAC timer and start beacon immediately beacause
2128 	 * AP2 is already beaconing on this channel. This case will be handled
2129 	 * by checking against eSAP_DFS_SKIP_CAC while starting the timer.
2130 	 */
2131 	pMac->sap.SapDfsInfo.cac_state = eSAP_DFS_SKIP_CAC;
2132 	return qdf_status;
2133 }
2134 
2135 /**
2136  * sap_fsm_state_disconnected() - utility function called from sap fsm
2137  * @sap_ctx: SAP context
2138  * @sap_event: SAP event buffer
2139  * @mac_ctx: global MAC context
2140  * @hal: HAL handle
2141  *
2142  * This function is called for state transition from "eSAP_DISCONNECTED"
2143  *
2144  * Return: QDF_STATUS
2145  */
2146 static QDF_STATUS sap_fsm_state_disconnected(struct sap_context *sap_ctx,
2147 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
2148 			tHalHandle hal)
2149 {
2150 	uint32_t msg = sap_event->event;
2151 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2152 
2153 	if (msg == eSAP_HDD_START_INFRA_BSS) {
2154 		/*
2155 		 * Transition from eSAP_DISCONNECTED to eSAP_CH_SELECT
2156 		 * (both without substates)
2157 		 */
2158 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2159 			  FL("new from state %s => %s: session:%d"),
2160 			  "eSAP_DISCONNECTED", "eSAP_CH_SELECT",
2161 			  sap_ctx->sessionId);
2162 
2163 		/* init dfs channel nol */
2164 		sap_init_dfs_channel_nol_list(sap_ctx);
2165 
2166 		/* Set SAP device role */
2167 		sap_ctx->sapsMachine = eSAP_CH_SELECT;
2168 
2169 		/*
2170 		 * Perform sme_ScanRequest. This scan request is post start bss
2171 		 * request so, set the third to false.
2172 		 */
2173 		qdf_status = sap_goto_channel_sel(sap_ctx, sap_event, false,
2174 						true);
2175 	} else if (msg == eSAP_DFS_CHANNEL_CAC_START) {
2176 		/*
2177 		 * No need of state check here, caller is expected to perform
2178 		 * the checks before sending the event
2179 		 */
2180 		sap_ctx->sapsMachine = eSAP_DFS_CAC_WAIT;
2181 
2182 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
2183 			FL("from state eSAP_DISCONNECTED => SAP_DFS_CAC_WAIT"));
2184 		if (mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running != true) {
2185 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
2186 			    FL("sapdfs: starting dfs cac timer on sapctx[%pK]"),
2187 			    sap_ctx);
2188 			sap_start_dfs_cac_timer(sap_ctx);
2189 		}
2190 
2191 		qdf_status = sap_cac_start_notify(hal);
2192 	} else if (msg == eSAP_CHANNEL_SELECTION_RETRY) {
2193 		/* Set SAP device role */
2194 		sap_ctx->sapsMachine = eSAP_CH_SELECT;
2195 
2196 		/*
2197 		 * Perform sme_ScanRequest. This scan request is post start bss
2198 		 * request so, set the third to false.
2199 		 */
2200 		qdf_status = sap_goto_channel_sel(sap_ctx, sap_event, false,
2201 					false);
2202 	} else {
2203 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2204 			  FL("in state %s, event msg %d"),
2205 			  "eSAP_DISCONNECTED", msg);
2206 	}
2207 
2208 	return qdf_status;
2209 }
2210 
2211 /**
2212  * sap_fsm_state_ch_select() - utility function called from sap fsm
2213  * @sap_ctx: SAP context
2214  * @sap_event: SAP event buffer
2215  * @mac_ctx: global MAC context
2216  * @hal: HAL handle
2217  *
2218  * This function is called for state transition from "eSAP_CH_SELECT"
2219  *
2220  * Return: QDF_STATUS
2221  */
2222 static QDF_STATUS sap_fsm_state_ch_select(struct sap_context *sap_ctx,
2223 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
2224 			tHalHandle hal)
2225 {
2226 	uint32_t msg = sap_event->event;
2227 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2228 	bool b_leak_chan = false;
2229 	uint8_t temp_chan;
2230 
2231 	if (msg == eSAP_MAC_SCAN_COMPLETE) {
2232 		temp_chan = sap_ctx->channel;
2233 		utils_dfs_mark_leaking_ch(mac_ctx->pdev,
2234 					sap_ctx->ch_params.ch_width,
2235 					1, &temp_chan);
2236 
2237 		/*
2238 		 * if selelcted channel has leakage to channels
2239 		 * in NOL, the temp_chan will be reset
2240 		 */
2241 		b_leak_chan = (temp_chan != sap_ctx->channel);
2242 		/*
2243 		 * check if channel is in DFS_NOL or if the channel
2244 		 * has leakage to the channels in NOL
2245 		 */
2246 		if (sap_dfs_is_channel_in_nol_list(sap_ctx, sap_ctx->channel,
2247 			PHY_CHANNEL_BONDING_STATE_MAX) || b_leak_chan) {
2248 			uint8_t ch;
2249 
2250 			/* find a new available channel */
2251 			ch = sap_random_channel_sel(sap_ctx);
2252 			if (ch == 0) {
2253 				/* No available channel found */
2254 				QDF_TRACE(QDF_MODULE_ID_SAP,
2255 					QDF_TRACE_LEVEL_ERROR,
2256 					FL("No available channel found!!!"));
2257 				sap_signal_hdd_event(sap_ctx, NULL,
2258 					eSAP_DFS_NO_AVAILABLE_CHANNEL,
2259 					(void *)eSAP_STATUS_SUCCESS);
2260 				return QDF_STATUS_E_FAULT;
2261 			}
2262 
2263 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2264 				  FL("channel %d is in NOL, StartBss on new channel %d"),
2265 				  sap_ctx->channel, ch);
2266 
2267 			sap_ctx->channel = ch;
2268 			wlan_reg_set_channel_params(mac_ctx->pdev,
2269 					sap_ctx->channel,
2270 					sap_ctx->secondary_ch,
2271 					&sap_ctx->ch_params);
2272 		}
2273 		if (sap_ctx->channel > 14 &&
2274 		    (sap_ctx->csr_roamProfile.phyMode == eCSR_DOT11_MODE_11g ||
2275 		     sap_ctx->csr_roamProfile.phyMode ==
2276 						eCSR_DOT11_MODE_11g_ONLY))
2277 			sap_ctx->csr_roamProfile.phyMode = eCSR_DOT11_MODE_11a;
2278 
2279 		/*
2280 		 * when AP2 is started while AP1 is performing ACS, we may not
2281 		 * have the AP1 channel yet.So here after the completion of AP2
2282 		 * ACS check if AP1 ACS resulting channel is DFS and if yes
2283 		 * override AP2 ACS scan result with AP1 DFS channel
2284 		 */
2285 		if (policy_mgr_concurrent_beaconing_sessions_running(
2286 			mac_ctx->psoc)) {
2287 			uint16_t con_ch;
2288 
2289 			con_ch = sme_get_concurrent_operation_channel(hal);
2290 			if (con_ch && wlan_reg_is_dfs_ch(mac_ctx->pdev, con_ch))
2291 				sap_ctx->channel = con_ch;
2292 		}
2293 
2294 		/*
2295 		 * Transition from eSAP_CH_SELECT to eSAP_STARTING
2296 		 * (both without substates)
2297 		 */
2298 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2299 			  FL("from state %s => %s"),
2300 			  "eSAP_CH_SELECT", "eSAP_STARTING");
2301 		/* Channel selected. Now can sap_goto_starting */
2302 		sap_ctx->sapsMachine = eSAP_STARTING;
2303 		/* Specify the channel */
2304 		sap_ctx->csr_roamProfile.ChannelInfo.numOfChannels =
2305 						1;
2306 		sap_ctx->csr_roamProfile.ChannelInfo.ChannelList =
2307 			&sap_ctx->csr_roamProfile.operationChannel;
2308 		sap_ctx->csr_roamProfile.operationChannel =
2309 			(uint8_t) sap_ctx->channel;
2310 		sap_ctx->csr_roamProfile.ch_params.ch_width =
2311 					sap_ctx->ch_params.ch_width;
2312 		sap_ctx->csr_roamProfile.ch_params.center_freq_seg0 =
2313 				sap_ctx->ch_params.center_freq_seg0;
2314 		sap_ctx->csr_roamProfile.ch_params.center_freq_seg1 =
2315 				sap_ctx->ch_params.center_freq_seg1;
2316 		sap_ctx->csr_roamProfile.ch_params.sec_ch_offset =
2317 				sap_ctx->ch_params.sec_ch_offset;
2318 		sap_get_cac_dur_dfs_region(sap_ctx,
2319 				&sap_ctx->csr_roamProfile.cac_duration_ms,
2320 				&sap_ctx->csr_roamProfile.dfs_regdomain);
2321 		sap_ctx->csr_roamProfile.beacon_tx_rate =
2322 				sap_ctx->beacon_tx_rate;
2323 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2324 		    FL("notify hostapd about channel selection: %d"),
2325 		    sap_ctx->channel);
2326 		sap_signal_hdd_event(sap_ctx, NULL,
2327 					eSAP_CHANNEL_CHANGE_EVENT,
2328 					(void *) eSAP_STATUS_SUCCESS);
2329 		sap_dfs_set_current_channel(sap_ctx);
2330 		qdf_status = sap_goto_starting(sap_ctx, sap_event,
2331 					  eCSR_BSS_TYPE_INFRA_AP);
2332 	} else if (msg == eSAP_CHANNEL_SELECTION_FAILED) {
2333 		sap_ctx->sapsMachine = eSAP_DISCONNECTED;
2334 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2335 		FL("Cannot start BSS, ACS Fail"));
2336 		sap_signal_hdd_event(sap_ctx, NULL, eSAP_START_BSS_EVENT,
2337 					(void *)eSAP_STATUS_FAILURE);
2338 	} else if (msg == eSAP_HDD_STOP_INFRA_BSS) {
2339 		sap_ctx->sapsMachine = eSAP_DISCONNECTED;
2340 		sap_signal_hdd_event(sap_ctx, NULL, eSAP_START_BSS_EVENT,
2341 					(void *)eSAP_STATUS_FAILURE);
2342 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
2343 			"%s: BSS stopped when Ch select in Progress", __func__);
2344 	} else {
2345 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2346 			  FL("in state %s, invalid event msg %d"),
2347 			  "eSAP_CH_SELECT", msg);
2348 	}
2349 
2350 	return qdf_status;
2351 }
2352 
2353 /**
2354  * sap_fsm_state_dfs_cac_wait() - utility function called from sap fsm
2355  * @sap_ctx: SAP context
2356  * @sap_event: SAP event buffer
2357  * @mac_ctx: global MAC context
2358  * @hal: HAL handle
2359  *
2360  * This function is called for state transition from "eSAP_DFS_CAC_WAIT"
2361  *
2362  * Return: QDF_STATUS
2363  */
2364 static QDF_STATUS sap_fsm_state_dfs_cac_wait(struct sap_context *sap_ctx,
2365 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
2366 			tHalHandle hal)
2367 {
2368 	uint32_t msg = sap_event->event;
2369 	struct csr_roam_info *roam_info =
2370 		(struct csr_roam_info *) (sap_event->params);
2371 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2372 
2373 	if (msg == eSAP_DFS_CHANNEL_CAC_START) {
2374 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2375 			  FL("from state %s => %s"),
2376 			  "eSAP_CH_SELECT", "eSAP_DFS_CAC_WAIT");
2377 		if (mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running != true)
2378 			sap_start_dfs_cac_timer(sap_ctx);
2379 		qdf_status = sap_cac_start_notify(hal);
2380 	} else if (msg == eSAP_DFS_CHANNEL_CAC_RADAR_FOUND) {
2381 		uint8_t intf;
2382 		/*
2383 		 * Radar found while performing channel availability
2384 		 * check, need to switch the channel again
2385 		 */
2386 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
2387 			  "ENTERTRED CAC WAIT STATE-->eSAP_DISCONNECTING\n");
2388 		if (mac_ctx->sap.SapDfsInfo.target_channel) {
2389 			wlan_reg_set_channel_params(mac_ctx->pdev,
2390 				mac_ctx->sap.SapDfsInfo.target_channel, 0,
2391 				&sap_ctx->ch_params);
2392 		} else {
2393 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2394 				FL("Invalid target channel %d"),
2395 				mac_ctx->sap.SapDfsInfo.target_channel);
2396 			return qdf_status;
2397 		}
2398 
2399 		for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
2400 			struct sap_context *t_sap_ctx;
2401 			struct csr_roam_profile *profile;
2402 
2403 			t_sap_ctx = mac_ctx->sap.sapCtxList[intf].sap_context;
2404 			if (((QDF_SAP_MODE ==
2405 				 mac_ctx->sap.sapCtxList[intf].sapPersona) ||
2406 			     (QDF_P2P_GO_MODE ==
2407 				mac_ctx->sap.sapCtxList[intf].sapPersona)) &&
2408 			    t_sap_ctx != NULL &&
2409 			    t_sap_ctx->sapsMachine != eSAP_DISCONNECTED) {
2410 				profile = &t_sap_ctx->csr_roamProfile;
2411 				if (!wlan_reg_is_passive_or_disable_ch(
2412 						mac_ctx->pdev,
2413 						profile->operationChannel))
2414 					continue;
2415 				/* SAP to be moved to DISCONNECTING state */
2416 				t_sap_ctx->sapsMachine = eSAP_DISCONNECTING;
2417 				/*
2418 				 * eSAP_DFS_CHANNEL_CAC_RADAR_FOUND:
2419 				 * A Radar is found on current DFS Channel
2420 				 * while in CAC WAIT period So, do a channel
2421 				 * switch to randomly selected  target channel.
2422 				 * Send the Channel change message to SME/PE.
2423 				 * sap_radar_found_status is set to 1
2424 				 */
2425 				wlansap_channel_change_request(
2426 					t_sap_ctx,
2427 					mac_ctx->sap.SapDfsInfo.target_channel);
2428 			}
2429 		}
2430 	} else if (msg == eSAP_DFS_CHANNEL_CAC_END) {
2431 		qdf_status = sap_cac_end_notify(hal, roam_info);
2432 	} else if (msg == eSAP_HDD_STOP_INFRA_BSS) {
2433 		/* Transition from eSAP_DFS_CAC_WAIT to eSAP_DISCONNECTING */
2434 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2435 			  FL("from state %s => %s"),
2436 			  "eSAP_DFS_CAC_WAIT", "eSAP_DISCONNECTING");
2437 
2438 		/*
2439 		 * Stop the CAC timer only in following conditions
2440 		 * single AP: if there is a single AP then stop the timer
2441 		 * mulitple APs: incase of multiple APs, make sure that
2442 		 *               all APs are down.
2443 		 */
2444 		if (NULL == sap_find_valid_concurrent_session(hal)) {
2445 			QDF_TRACE(QDF_MODULE_ID_SAP,
2446 				  QDF_TRACE_LEVEL_INFO_MED,
2447 				  FL("sapdfs: no sessions are valid, stopping timer"));
2448 			sap_stop_dfs_cac_timer(sap_ctx);
2449 		}
2450 
2451 		sap_ctx->sapsMachine = eSAP_DISCONNECTING;
2452 		qdf_status = sap_goto_disconnecting(sap_ctx);
2453 	} else {
2454 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2455 			  FL("in state %s, invalid event msg %d"),
2456 			  "eSAP_DFS_CAC_WAIT", msg);
2457 	}
2458 
2459 	return qdf_status;
2460 }
2461 
2462 /**
2463  * sap_fsm_state_starting() - utility function called from sap fsm
2464  * @sap_ctx: SAP context
2465  * @sap_event: SAP event buffer
2466  * @mac_ctx: global MAC context
2467  * @hal: HAL handle
2468  *
2469  * This function is called for state transition from "eSAP_STARTING"
2470  *
2471  * Return: QDF_STATUS
2472  */
2473 static QDF_STATUS sap_fsm_state_starting(struct sap_context *sap_ctx,
2474 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
2475 			tHalHandle hal)
2476 {
2477 	uint32_t msg = sap_event->event;
2478 	struct csr_roam_info *roam_info =
2479 		(struct csr_roam_info *) (sap_event->params);
2480 	tSapDfsInfo *sap_dfs_info;
2481 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2482 	uint8_t is_dfs = false;
2483 
2484 	if (msg == eSAP_MAC_START_BSS_SUCCESS) {
2485 		/*
2486 		 * Transition from eSAP_STARTING to eSAP_STARTED
2487 		 * (both without substates)
2488 		 */
2489 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2490 			  FL("from state channel = %d %s => %s ch_width %d"),
2491 			  sap_ctx->channel, "eSAP_STARTING", "eSAP_STARTED",
2492 			  sap_ctx->ch_params.ch_width);
2493 		sap_ctx->sapsMachine = eSAP_STARTED;
2494 
2495 		/* Action code for transition */
2496 		qdf_status = sap_signal_hdd_event(sap_ctx, roam_info,
2497 				eSAP_START_BSS_EVENT,
2498 				(void *) eSAP_STATUS_SUCCESS);
2499 
2500 		/*
2501 		 * The upper layers have been informed that AP is up and
2502 		 * running, however, the AP is still not beaconing, until
2503 		 * CAC is done if the operating channel is DFS
2504 		 */
2505 		if (sap_ctx->ch_params.ch_width == CH_WIDTH_160MHZ) {
2506 			is_dfs = true;
2507 		} else if (sap_ctx->ch_params.ch_width == CH_WIDTH_80P80MHZ) {
2508 			if (wlan_reg_get_channel_state(mac_ctx->pdev,
2509 						sap_ctx->channel) ==
2510 			    CHANNEL_STATE_DFS ||
2511 			    wlan_reg_get_channel_state(mac_ctx->pdev,
2512 				    sap_ctx->ch_params.center_freq_seg1 -
2513 				SIR_80MHZ_START_CENTER_CH_DIFF) ==
2514 					CHANNEL_STATE_DFS)
2515 				is_dfs = true;
2516 		} else {
2517 			if (wlan_reg_get_channel_state(mac_ctx->pdev,
2518 						sap_ctx->channel) ==
2519 							CHANNEL_STATE_DFS)
2520 				is_dfs = true;
2521 		}
2522 
2523 		if (is_dfs) {
2524 			sap_dfs_info = &mac_ctx->sap.SapDfsInfo;
2525 			if ((false == sap_dfs_info->ignore_cac) &&
2526 			    (eSAP_DFS_DO_NOT_SKIP_CAC ==
2527 					sap_dfs_info->cac_state) &&
2528 			    !sap_ctx->pre_cac_complete) {
2529 				/* Move the device in CAC_WAIT_STATE */
2530 				sap_ctx->sapsMachine = eSAP_DFS_CAC_WAIT;
2531 
2532 				/*
2533 				 * Need to stop the OS transmit queues,
2534 				 * so that no traffic can flow down the stack
2535 				 */
2536 
2537 				/* Start CAC wait timer */
2538 				if (sap_dfs_info->is_dfs_cac_timer_running !=
2539 									true)
2540 					sap_start_dfs_cac_timer(sap_ctx);
2541 				qdf_status = sap_cac_start_notify(hal);
2542 
2543 			} else {
2544 				wlansap_start_beacon_req(sap_ctx);
2545 			}
2546 		}
2547 	} else if (msg == eSAP_MAC_START_FAILS ||
2548 			msg == eSAP_HDD_STOP_INFRA_BSS) {
2549 		/*
2550 		 * Transition from eSAP_STARTING to eSAP_DISCONNECTED
2551 		 * (both without substates)
2552 		 */
2553 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2554 			  FL("from state %s => %s"),
2555 			  "eSAP_STARTING", "eSAP_DISCONNECTED");
2556 
2557 		/* Advance outer statevar */
2558 		sap_ctx->sapsMachine = eSAP_DISCONNECTED;
2559 		qdf_status = sap_signal_hdd_event(sap_ctx, NULL,
2560 				eSAP_START_BSS_EVENT,
2561 				(void *) eSAP_STATUS_FAILURE);
2562 		qdf_status = sap_goto_disconnected(sap_ctx);
2563 		/* Close the SME session */
2564 	} else if (msg == eSAP_OPERATING_CHANNEL_CHANGED) {
2565 		/* The operating channel has changed, update hostapd */
2566 		sap_ctx->channel =
2567 			(uint8_t) mac_ctx->sap.SapDfsInfo.target_channel;
2568 
2569 		sap_ctx->sapsMachine = eSAP_STARTED;
2570 
2571 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2572 			  FL("from state %s => %s"),
2573 			  "eSAP_STARTING", "eSAP_STARTED");
2574 
2575 		/* Indicate change in the state to upper layers */
2576 		qdf_status = sap_signal_hdd_event(sap_ctx, roam_info,
2577 				  eSAP_START_BSS_EVENT,
2578 				  (void *)eSAP_STATUS_SUCCESS);
2579 	} else {
2580 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2581 			  FL("in state %s, invalid event msg %d"),
2582 			  "eSAP_STARTING", msg);
2583 	}
2584 
2585 	return qdf_status;
2586 }
2587 
2588 /**
2589  * sap_fsm_state_started() - utility function called from sap fsm
2590  * @sap_ctx: SAP context
2591  * @sap_event: SAP event buffer
2592  * @mac_ctx: global MAC context
2593  *
2594  * This function is called for state transition from "eSAP_STARTED"
2595  *
2596  * Return: QDF_STATUS
2597  */
2598 static QDF_STATUS sap_fsm_state_started(struct sap_context *sap_ctx,
2599 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx)
2600 {
2601 	uint32_t msg = sap_event->event;
2602 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2603 
2604 	if (msg == eSAP_HDD_STOP_INFRA_BSS) {
2605 		/*
2606 		 * Transition from eSAP_STARTED to eSAP_DISCONNECTING
2607 		 * (both without substates)
2608 		 */
2609 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2610 			  FL("from state %s => %s"),
2611 			  "eSAP_STARTED", "eSAP_DISCONNECTING");
2612 		sap_ctx->sapsMachine = eSAP_DISCONNECTING;
2613 		qdf_status = sap_goto_disconnecting(sap_ctx);
2614 	} else if (eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START == msg) {
2615 		uint8_t intf;
2616 		if (!mac_ctx->sap.SapDfsInfo.target_channel) {
2617 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2618 				FL("Invalid target channel %d"),
2619 				mac_ctx->sap.SapDfsInfo.target_channel);
2620 			return qdf_status;
2621 		}
2622 
2623 		/*
2624 		 * Radar is seen on the current operating channel
2625 		 * send CSA IE for all associated stations
2626 		 * Request for CSA IE transmission
2627 		 */
2628 		for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
2629 			struct sap_context *temp_sap_ctx;
2630 			struct csr_roam_profile *profile;
2631 
2632 			if (((QDF_SAP_MODE ==
2633 				mac_ctx->sap.sapCtxList[intf].sapPersona) ||
2634 			    (QDF_P2P_GO_MODE ==
2635 				mac_ctx->sap.sapCtxList[intf].sapPersona)) &&
2636 			    mac_ctx->sap.sapCtxList[intf].sap_context != NULL) {
2637 				temp_sap_ctx =
2638 				    mac_ctx->sap.sapCtxList[intf].sap_context;
2639 				/*
2640 				 * Radar won't come on non-dfs channel, so
2641 				 * no need to move them
2642 				 */
2643 				profile = &temp_sap_ctx->csr_roamProfile;
2644 				if (!wlan_reg_is_passive_or_disable_ch(
2645 						mac_ctx->pdev,
2646 						profile->operationChannel))
2647 					continue;
2648 				QDF_TRACE(QDF_MODULE_ID_SAP,
2649 					  QDF_TRACE_LEVEL_INFO_MED,
2650 					  FL("sapdfs: Sending CSAIE for sapctx[%pK]"),
2651 					  temp_sap_ctx);
2652 
2653 				qdf_status =
2654 					wlansap_dfs_send_csa_ie_request(temp_sap_ctx);
2655 			}
2656 		}
2657 	} else if (eSAP_CHANNEL_SWITCH_ANNOUNCEMENT_START == msg) {
2658 		enum QDF_OPMODE persona;
2659 
2660 		if (!sap_ctx) {
2661 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2662 					FL("Invalid sap_ctx"));
2663 			return qdf_status;
2664 		}
2665 
2666 		persona = mac_ctx->sap.sapCtxList[sap_ctx->sessionId].
2667 								sapPersona;
2668 
2669 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
2670 				FL("app trigger chan switch: mode:%d vdev:%d"),
2671 				persona, sap_ctx->sessionId);
2672 
2673 		if ((QDF_SAP_MODE == persona) || (QDF_P2P_GO_MODE == persona))
2674 			qdf_status = wlansap_dfs_send_csa_ie_request(sap_ctx);
2675 	} else {
2676 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2677 			  FL("in state %s, invalid event msg %d"),
2678 			  "eSAP_STARTED", msg);
2679 	}
2680 
2681 	return qdf_status;
2682 }
2683 
2684 /**
2685  * sap_fsm_state_disconnecting() - utility function called from sap fsm
2686  * @sap_ctx: SAP context
2687  * @sap_event: SAP event buffer
2688  * @mac_ctx: global MAC context
2689  *
2690  * This function is called for state transition from "eSAP_DISCONNECTING"
2691  *
2692  * Return: QDF_STATUS
2693  */
2694 static QDF_STATUS sap_fsm_state_disconnecting(struct sap_context *sap_ctx,
2695 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
2696 			tHalHandle hal)
2697 {
2698 	uint32_t msg = sap_event->event;
2699 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2700 
2701 	if (msg == eSAP_MAC_READY_FOR_CONNECTIONS) {
2702 		/*
2703 		 * Transition from eSAP_DISCONNECTING to eSAP_DISCONNECTED
2704 		 * (both without substates)
2705 		 */
2706 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2707 			  FL("from state %s => %s"),
2708 			  "eSAP_DISCONNECTING", "eSAP_DISCONNECTED");
2709 		sap_ctx->sapsMachine = eSAP_DISCONNECTED;
2710 
2711 		/* Close the SME session */
2712 		qdf_status = sap_signal_hdd_event(sap_ctx, NULL,
2713 					eSAP_STOP_BSS_EVENT,
2714 					(void *)eSAP_STATUS_SUCCESS);
2715 	} else if (msg == eWNI_SME_CHANNEL_CHANGE_REQ) {
2716 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
2717 			  FL("sapdfs: Send channel change request on sapctx[%pK]"),
2718 			  sap_ctx);
2719 
2720 		sap_get_cac_dur_dfs_region(sap_ctx,
2721 				&sap_ctx->csr_roamProfile.cac_duration_ms,
2722 				&sap_ctx->csr_roamProfile.dfs_regdomain);
2723 		/*
2724 		 * Most likely, radar has been detected and SAP wants to
2725 		 * change the channel
2726 		 */
2727 		qdf_status = wlansap_channel_change_request(sap_ctx,
2728 				mac_ctx->sap.SapDfsInfo.target_channel);
2729 
2730 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
2731 			  FL("Sending DFS eWNI_SME_CHANNEL_CHANGE_REQ"));
2732 	} else if (msg == eWNI_SME_CHANNEL_CHANGE_RSP) {
2733 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
2734 			  FL("in state %s, event msg %d result %d"),
2735 			  "eSAP_DISCONNECTING ", msg, sap_event->u2);
2736 		if (sap_event->u2 == eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE)
2737 			qdf_status = sap_goto_disconnecting(sap_ctx);
2738 	} else if ((msg == eSAP_HDD_STOP_INFRA_BSS) &&
2739 			(sap_ctx->is_chan_change_inprogress)) {
2740 		/* stop bss is received while processing channel change */
2741 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
2742 			  FL("in state %s, event msg %d result %d"),
2743 			  "eSAP_DISCONNECTING ", msg, sap_event->u2);
2744 		qdf_status = sap_goto_disconnecting(sap_ctx);
2745 	} else {
2746 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2747 			  FL("in state %s, invalid event msg %d"),
2748 			  "eSAP_DISCONNECTING", msg);
2749 	}
2750 
2751 	return qdf_status;
2752 }
2753 
2754 /**
2755  * sap_fsm() - SAP statem machine entry function
2756  * @sap_ctx: SAP context
2757  * @sap_event: SAP event
2758  *
2759  * SAP statem machine entry function
2760  *
2761  * Return: QDF_STATUS
2762  */
2763 QDF_STATUS sap_fsm(struct sap_context *sap_ctx, ptWLAN_SAPEvent sap_event)
2764 {
2765 	/*
2766 	 * Retrieve the phy link state machine structure
2767 	 * from the sap_ctx value
2768 	 * state var that keeps track of state machine
2769 	 */
2770 	eSapFsmStates_t state_var = sap_ctx->sapsMachine;
2771 	uint32_t msg = sap_event->event; /* State machine input event message */
2772 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2773 	tHalHandle hal = CDS_GET_HAL_CB();
2774 	tpAniSirGlobal mac_ctx;
2775 
2776 	if (NULL == hal) {
2777 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2778 			  FL("Invalid hal"));
2779 		return QDF_STATUS_E_FAILURE;
2780 	}
2781 
2782 	mac_ctx = PMAC_STRUCT(hal);
2783 	if (NULL == mac_ctx) {
2784 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2785 			  FL("Invalid MAC context"));
2786 		return QDF_STATUS_E_FAILURE;
2787 	}
2788 
2789 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
2790 		  FL("sap_ctx=%pK, state_var=%d, msg=0x%x"),
2791 		  sap_ctx, state_var, msg);
2792 
2793 	switch (state_var) {
2794 	case eSAP_DISCONNECTED:
2795 		qdf_status = sap_fsm_state_disconnected(sap_ctx, sap_event,
2796 				mac_ctx, hal);
2797 		break;
2798 
2799 	case eSAP_CH_SELECT:
2800 		qdf_status = sap_fsm_state_ch_select(sap_ctx, sap_event,
2801 				mac_ctx, hal);
2802 		break;
2803 
2804 	case eSAP_DFS_CAC_WAIT:
2805 		qdf_status = sap_fsm_state_dfs_cac_wait(sap_ctx, sap_event,
2806 				mac_ctx, hal);
2807 		break;
2808 
2809 	case eSAP_STARTING:
2810 		qdf_status = sap_fsm_state_starting(sap_ctx, sap_event,
2811 				mac_ctx, hal);
2812 		break;
2813 
2814 	case eSAP_STARTED:
2815 		qdf_status = sap_fsm_state_started(sap_ctx, sap_event,
2816 				mac_ctx);
2817 		break;
2818 
2819 	case eSAP_DISCONNECTING:
2820 		qdf_status = sap_fsm_state_disconnecting(sap_ctx, sap_event,
2821 				mac_ctx, hal);
2822 		break;
2823 	}
2824 	return qdf_status;
2825 }
2826 
2827 eSapStatus
2828 sapconvert_to_csr_profile(tsap_config_t *pconfig_params, eCsrRoamBssType bssType,
2829 			  struct csr_roam_profile *profile)
2830 {
2831 	/* Create Roam profile for SoftAP to connect */
2832 	profile->BSSType = eCSR_BSS_TYPE_INFRA_AP;
2833 	profile->SSIDs.numOfSSIDs = 1;
2834 	profile->csrPersona = pconfig_params->persona;
2835 	profile->disableDFSChSwitch = pconfig_params->disableDFSChSwitch;
2836 
2837 	qdf_mem_zero(profile->SSIDs.SSIDList[0].SSID.ssId,
2838 		     sizeof(profile->SSIDs.SSIDList[0].SSID.ssId));
2839 
2840 	/* Flag to not broadcast the SSID information */
2841 	profile->SSIDs.SSIDList[0].ssidHidden =
2842 		pconfig_params->SSIDinfo.ssidHidden;
2843 
2844 	profile->SSIDs.SSIDList[0].SSID.length =
2845 		pconfig_params->SSIDinfo.ssid.length;
2846 	qdf_mem_copy(&profile->SSIDs.SSIDList[0].SSID.ssId,
2847 		     pconfig_params->SSIDinfo.ssid.ssId,
2848 		     sizeof(pconfig_params->SSIDinfo.ssid.ssId));
2849 
2850 	profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
2851 
2852 	if (pconfig_params->authType == eSAP_OPEN_SYSTEM) {
2853 		profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
2854 	} else if (pconfig_params->authType == eSAP_SHARED_KEY) {
2855 		profile->negotiatedAuthType = eCSR_AUTH_TYPE_SHARED_KEY;
2856 	} else {
2857 		profile->negotiatedAuthType = eCSR_AUTH_TYPE_AUTOSWITCH;
2858 	}
2859 
2860 	profile->AuthType.numEntries = 1;
2861 	profile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
2862 
2863 	/* Always set the Encryption Type */
2864 	profile->EncryptionType.numEntries = 1;
2865 	profile->EncryptionType.encryptionType[0] =
2866 		pconfig_params->RSNEncryptType;
2867 
2868 	profile->mcEncryptionType.numEntries = 1;
2869 	profile->mcEncryptionType.encryptionType[0] =
2870 		pconfig_params->mcRSNEncryptType;
2871 
2872 	if (pconfig_params->privacy & eSAP_SHARED_KEY) {
2873 		profile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY;
2874 	}
2875 
2876 	profile->privacy = pconfig_params->privacy;
2877 	profile->fwdWPSPBCProbeReq = pconfig_params->fwdWPSPBCProbeReq;
2878 
2879 	if (pconfig_params->authType == eSAP_SHARED_KEY) {
2880 		profile->csr80211AuthType = eSIR_SHARED_KEY;
2881 	} else if (pconfig_params->authType == eSAP_OPEN_SYSTEM) {
2882 		profile->csr80211AuthType = eSIR_OPEN_SYSTEM;
2883 	} else {
2884 		profile->csr80211AuthType = eSIR_AUTO_SWITCH;
2885 	}
2886 
2887 	/* Initialize we are not going to use it */
2888 	profile->pWPAReqIE = NULL;
2889 	profile->nWPAReqIELength = 0;
2890 
2891 	if (profile->pRSNReqIE) {
2892 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
2893 			  FL("pRSNReqIE already allocated."));
2894 		qdf_mem_free(profile->pRSNReqIE);
2895 		profile->pRSNReqIE = NULL;
2896 	}
2897 
2898 	/* set the RSN/WPA IE */
2899 	profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength;
2900 	if (pconfig_params->RSNWPAReqIELength) {
2901 		profile->pRSNReqIE =
2902 			qdf_mem_malloc(pconfig_params->RSNWPAReqIELength);
2903 		if (NULL == profile->pRSNReqIE) {
2904 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2905 				  " %s Fail to alloc memory", __func__);
2906 			return eSAP_STATUS_FAILURE;
2907 		}
2908 		qdf_mem_copy(profile->pRSNReqIE, pconfig_params->RSNWPAReqIE,
2909 			     pconfig_params->RSNWPAReqIELength);
2910 		profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength;
2911 	}
2912 
2913 	/* set the phyMode to accept anything */
2914 	/* Best means everything because it covers all the things we support */
2915 	/* eCSR_DOT11_MODE_BEST */
2916 	profile->phyMode = pconfig_params->SapHw_mode;
2917 
2918 	/* Configure beaconInterval */
2919 	profile->beaconInterval = (uint16_t) pconfig_params->beacon_int;
2920 
2921 	/* set DTIM period */
2922 	profile->dtimPeriod = pconfig_params->dtim_period;
2923 
2924 	/* set Uapsd enable bit */
2925 	profile->ApUapsdEnable = pconfig_params->UapsdEnable;
2926 
2927 	/* Enable protection parameters */
2928 	profile->protEnabled = pconfig_params->protEnabled;
2929 	profile->obssProtEnabled = pconfig_params->obssProtEnabled;
2930 	profile->cfg_protection = pconfig_params->ht_capab;
2931 
2932 	/* country code */
2933 	if (pconfig_params->countryCode[0])
2934 		qdf_mem_copy(profile->countryCode, pconfig_params->countryCode,
2935 			     WNI_CFG_COUNTRY_CODE_LEN);
2936 	profile->ieee80211d = pconfig_params->ieee80211d;
2937 	/* wps config info */
2938 	profile->wps_state = pconfig_params->wps_state;
2939 
2940 #ifdef WLAN_FEATURE_11W
2941 	/* MFP capable/required */
2942 	profile->MFPCapable = pconfig_params->mfpCapable ? 1 : 0;
2943 	profile->MFPRequired = pconfig_params->mfpRequired ? 1 : 0;
2944 #endif
2945 
2946 	if (pconfig_params->probeRespIEsBufferLen > 0 &&
2947 	    pconfig_params->pProbeRespIEsBuffer != NULL) {
2948 		profile->addIeParams.probeRespDataLen =
2949 			pconfig_params->probeRespIEsBufferLen;
2950 		profile->addIeParams.probeRespData_buff =
2951 			pconfig_params->pProbeRespIEsBuffer;
2952 	} else {
2953 		profile->addIeParams.probeRespDataLen = 0;
2954 		profile->addIeParams.probeRespData_buff = NULL;
2955 	}
2956 	/*assoc resp IE */
2957 	if (pconfig_params->assocRespIEsLen > 0 &&
2958 	    pconfig_params->pAssocRespIEsBuffer != NULL) {
2959 		profile->addIeParams.assocRespDataLen =
2960 			pconfig_params->assocRespIEsLen;
2961 		profile->addIeParams.assocRespData_buff =
2962 			pconfig_params->pAssocRespIEsBuffer;
2963 	} else {
2964 		profile->addIeParams.assocRespDataLen = 0;
2965 		profile->addIeParams.assocRespData_buff = NULL;
2966 	}
2967 
2968 	if (pconfig_params->probeRespBcnIEsLen > 0 &&
2969 	    pconfig_params->pProbeRespBcnIEsBuffer != NULL) {
2970 		profile->addIeParams.probeRespBCNDataLen =
2971 			pconfig_params->probeRespBcnIEsLen;
2972 		profile->addIeParams.probeRespBCNData_buff =
2973 			pconfig_params->pProbeRespBcnIEsBuffer;
2974 	} else {
2975 		profile->addIeParams.probeRespBCNDataLen = 0;
2976 		profile->addIeParams.probeRespBCNData_buff = NULL;
2977 	}
2978 	profile->sap_dot11mc = pconfig_params->sap_dot11mc;
2979 
2980 	if (pconfig_params->supported_rates.numRates) {
2981 		qdf_mem_copy(profile->supported_rates.rate,
2982 				pconfig_params->supported_rates.rate,
2983 				pconfig_params->supported_rates.numRates);
2984 		profile->supported_rates.numRates =
2985 			pconfig_params->supported_rates.numRates;
2986 	}
2987 
2988 	if (pconfig_params->extended_rates.numRates) {
2989 		qdf_mem_copy(profile->extended_rates.rate,
2990 				pconfig_params->extended_rates.rate,
2991 				pconfig_params->extended_rates.numRates);
2992 		profile->extended_rates.numRates =
2993 			pconfig_params->extended_rates.numRates;
2994 	}
2995 
2996 	profile->chan_switch_hostapd_rate_enabled =
2997 		pconfig_params->chan_switch_hostapd_rate_enabled;
2998 
2999 	return eSAP_STATUS_SUCCESS;     /* Success. */
3000 }
3001 
3002 void sap_free_roam_profile(struct csr_roam_profile *profile)
3003 {
3004 	if (profile->pRSNReqIE) {
3005 		qdf_mem_free(profile->pRSNReqIE);
3006 		profile->pRSNReqIE = NULL;
3007 	}
3008 }
3009 
3010 void sap_sort_mac_list(struct qdf_mac_addr *macList, uint8_t size)
3011 {
3012 	uint8_t outer, inner;
3013 	struct qdf_mac_addr temp;
3014 	int32_t nRes = -1;
3015 
3016 	if ((NULL == macList) || (size > MAX_ACL_MAC_ADDRESS)) {
3017 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3018 			FL("either buffer is NULL or size = %d is more"), size);
3019 		return;
3020 	}
3021 
3022 	for (outer = 0; outer < size; outer++) {
3023 		for (inner = 0; inner < size - 1; inner++) {
3024 			nRes =
3025 				qdf_mem_cmp((macList + inner)->bytes,
3026 						 (macList + inner + 1)->bytes,
3027 						 QDF_MAC_ADDR_SIZE);
3028 			if (nRes > 0) {
3029 				qdf_mem_copy(temp.bytes,
3030 					     (macList + inner + 1)->bytes,
3031 					     QDF_MAC_ADDR_SIZE);
3032 				qdf_mem_copy((macList + inner + 1)->bytes,
3033 					     (macList + inner)->bytes,
3034 					     QDF_MAC_ADDR_SIZE);
3035 				qdf_mem_copy((macList + inner)->bytes,
3036 					     temp.bytes, QDF_MAC_ADDR_SIZE);
3037 			}
3038 		}
3039 	}
3040 }
3041 
3042 bool
3043 sap_search_mac_list(struct qdf_mac_addr *macList,
3044 		    uint8_t num_mac, uint8_t *peerMac,
3045 		    uint8_t *index)
3046 {
3047 	int32_t nRes = -1;
3048 	int8_t nStart = 0, nEnd, nMiddle;
3049 
3050 	nEnd = num_mac - 1;
3051 
3052 	if ((NULL == macList) || (num_mac > MAX_ACL_MAC_ADDRESS)) {
3053 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3054 		    FL("either buffer is NULL or size = %d is more."), num_mac);
3055 		return false;
3056 	}
3057 
3058 	while (nStart <= nEnd) {
3059 		nMiddle = (nStart + nEnd) / 2;
3060 		nRes =
3061 			qdf_mem_cmp(&macList[nMiddle], peerMac,
3062 					 QDF_MAC_ADDR_SIZE);
3063 
3064 		if (0 == nRes) {
3065 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3066 				  "search SUCC");
3067 			/* "index equals NULL" means the caller does not need the */
3068 			/* index value of the peerMac being searched */
3069 			if (index != NULL) {
3070 				*index = (uint8_t) nMiddle;
3071 				QDF_TRACE(QDF_MODULE_ID_SAP,
3072 					  QDF_TRACE_LEVEL_INFO_HIGH, "index %d",
3073 					  *index);
3074 			}
3075 			return true;
3076 		}
3077 		if (nRes < 0)
3078 			nStart = nMiddle + 1;
3079 		else
3080 			nEnd = nMiddle - 1;
3081 	}
3082 
3083 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3084 		  "search not succ");
3085 	return false;
3086 }
3087 
3088 void sap_add_mac_to_acl(struct qdf_mac_addr *macList,
3089 			uint8_t *size, uint8_t *peerMac)
3090 {
3091 	int32_t nRes = -1;
3092 	int i;
3093 
3094 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3095 		  "add acl entered");
3096 
3097 	if (NULL == macList || *size > MAX_ACL_MAC_ADDRESS) {
3098 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3099 			FL("either buffer is NULL or size = %d is incorrect."),
3100 			*size);
3101 		return;
3102 	}
3103 
3104 	for (i = ((*size) - 1); i >= 0; i--) {
3105 		nRes =
3106 			qdf_mem_cmp(&macList[i], peerMac, QDF_MAC_ADDR_SIZE);
3107 		if (nRes > 0) {
3108 			/* Move alphabetically greater mac addresses one index down to allow for insertion
3109 			   of new mac in sorted order */
3110 			qdf_mem_copy((macList + i + 1)->bytes,
3111 				     (macList + i)->bytes, QDF_MAC_ADDR_SIZE);
3112 		} else {
3113 			break;
3114 		}
3115 	}
3116 	/* This should also take care of if the element is the first to be added in the list */
3117 	qdf_mem_copy((macList + i + 1)->bytes, peerMac, QDF_MAC_ADDR_SIZE);
3118 	/* increment the list size */
3119 	(*size)++;
3120 }
3121 
3122 void sap_remove_mac_from_acl(struct qdf_mac_addr *macList,
3123 			     uint8_t *size, uint8_t index)
3124 {
3125 	int i;
3126 
3127 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3128 		  "remove acl entered");
3129 	/*
3130 	 * Return if the list passed is empty. Ideally this should never happen
3131 	 * since this funcn is always called after sap_search_mac_list to get
3132 	 * the index of the mac addr to be removed and this will only get
3133 	 * called if the search is successful. Still no harm in having the check
3134 	 */
3135 	if ((macList == NULL) || (*size == 0) ||
3136 					(*size > MAX_ACL_MAC_ADDRESS)) {
3137 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3138 			FL("either buffer is NULL or size %d is incorrect."),
3139 			*size);
3140 		return;
3141 	}
3142 	for (i = index; i < ((*size) - 1); i++) {
3143 		/* Move mac addresses starting from "index" passed one index up to delete the void
3144 		   created by deletion of a mac address in ACL */
3145 		qdf_mem_copy((macList + i)->bytes, (macList + i + 1)->bytes,
3146 			     QDF_MAC_ADDR_SIZE);
3147 	}
3148 	/* The last space should be made empty since all mac addesses moved one step up */
3149 	qdf_mem_zero((macList + (*size) - 1)->bytes, QDF_MAC_ADDR_SIZE);
3150 	/* reduce the list size by 1 */
3151 	(*size)--;
3152 }
3153 
3154 void sap_print_acl(struct qdf_mac_addr *macList, uint8_t size)
3155 {
3156 	int i;
3157 	uint8_t *macArray;
3158 
3159 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3160 		  "print acl entered");
3161 
3162 	if ((NULL == macList) || (size == 0) || (size >= MAX_ACL_MAC_ADDRESS)) {
3163 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3164 			  "In %s, either buffer is NULL or size %d is incorrect.",
3165 			  __func__, size);
3166 		return;
3167 	}
3168 
3169 	for (i = 0; i < size; i++) {
3170 		macArray = (macList + i)->bytes;
3171 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3172 			  "** ACL entry %i - " MAC_ADDRESS_STR, i,
3173 			  MAC_ADDR_ARRAY(macArray));
3174 	}
3175 	return;
3176 }
3177 
3178 QDF_STATUS sap_is_peer_mac_allowed(struct sap_context *sapContext,
3179 				   uint8_t *peerMac)
3180 {
3181 	if (eSAP_ALLOW_ALL == sapContext->eSapMacAddrAclMode)
3182 		return QDF_STATUS_SUCCESS;
3183 
3184 	if (sap_search_mac_list
3185 		    (sapContext->acceptMacList, sapContext->nAcceptMac, peerMac, NULL))
3186 		return QDF_STATUS_SUCCESS;
3187 
3188 	if (sap_search_mac_list
3189 		    (sapContext->denyMacList, sapContext->nDenyMac, peerMac, NULL)) {
3190 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3191 			  "In %s, Peer " MAC_ADDRESS_STR " in deny list",
3192 			  __func__, MAC_ADDR_ARRAY(peerMac));
3193 		return QDF_STATUS_E_FAILURE;
3194 	}
3195 	/* A new station CAN associate, unless in deny list. Less stringent mode */
3196 	if (eSAP_ACCEPT_UNLESS_DENIED == sapContext->eSapMacAddrAclMode)
3197 		return QDF_STATUS_SUCCESS;
3198 
3199 	/* A new station CANNOT associate, unless in accept list. More stringent mode */
3200 	if (eSAP_DENY_UNLESS_ACCEPTED == sapContext->eSapMacAddrAclMode) {
3201 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3202 			  "In %s, Peer " MAC_ADDRESS_STR
3203 			  " denied, Mac filter mode is eSAP_DENY_UNLESS_ACCEPTED",
3204 			  __func__, MAC_ADDR_ARRAY(peerMac));
3205 		return QDF_STATUS_E_FAILURE;
3206 	}
3207 
3208 	/* The new STA is neither in accept list nor in deny list. In this case, deny the association
3209 	 * but send a wifi event notification indicating the mac address being denied
3210 	 */
3211 	if (eSAP_SUPPORT_ACCEPT_AND_DENY == sapContext->eSapMacAddrAclMode) {
3212 		sap_signal_hdd_event(sapContext, NULL, eSAP_UNKNOWN_STA_JOIN,
3213 				     (void *) peerMac);
3214 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3215 			  "In %s, Peer " MAC_ADDRESS_STR
3216 			  " denied, Mac filter mode is eSAP_SUPPORT_ACCEPT_AND_DENY",
3217 			  __func__, MAC_ADDR_ARRAY(peerMac));
3218 		return QDF_STATUS_E_FAILURE;
3219 	}
3220 	return QDF_STATUS_SUCCESS;
3221 }
3222 
3223 #ifdef SOFTAP_CHANNEL_RANGE
3224 /**
3225  * sap_get_channel_list() - get the list of channels
3226  * @sap_ctx: sap context
3227  * @ch_list: pointer to channel list array
3228  * @num_ch: pointer to number of channels.
3229  *
3230  * This function populates the list of channels for scanning.
3231  *
3232  * Return: QDF_STATUS
3233  */
3234 static QDF_STATUS sap_get_channel_list(struct sap_context *sap_ctx,
3235 				       uint8_t **ch_list,
3236 				       uint8_t *num_ch)
3237 {
3238 	uint8_t loop_count;
3239 	uint8_t *list;
3240 	uint8_t ch_count;
3241 	uint8_t start_ch_num, band_start_ch;
3242 	uint8_t end_ch_num, band_end_ch;
3243 	uint32_t en_lte_coex;
3244 	tHalHandle hal = CDS_GET_HAL_CB();
3245 #ifdef FEATURE_WLAN_CH_AVOID
3246 	uint8_t i;
3247 #endif
3248 	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
3249 	tSapChSelSpectInfo spect_info_obj = { NULL, 0 };
3250 	uint16_t ch_width;
3251 
3252 	if (NULL == hal) {
3253 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3254 			FL("Invalid HAL pointer from p_cds_gctx"));
3255 		*num_ch = 0;
3256 		*ch_list = NULL;
3257 		return QDF_STATUS_E_FAULT;
3258 	}
3259 
3260 	start_ch_num = sap_ctx->acs_cfg->start_ch;
3261 	end_ch_num = sap_ctx->acs_cfg->end_ch;
3262 	ch_width = sap_ctx->acs_cfg->ch_width;
3263 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
3264 		  FL("startChannel %d, EndChannel %d, ch_width %d, HW:%d"),
3265 		     start_ch_num, end_ch_num, ch_width,
3266 		     sap_ctx->acs_cfg->hw_mode);
3267 
3268 	wlansap_extend_to_acs_range(hal, &start_ch_num, &end_ch_num,
3269 					    &band_start_ch, &band_end_ch);
3270 
3271 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
3272 			  FL("expanded startChannel %d,EndChannel %d"),
3273 			  start_ch_num, end_ch_num);
3274 
3275 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
3276 			  FL("band_start_ch %d, band_end_ch %d"),
3277 			  band_start_ch, band_end_ch);
3278 
3279 	sme_cfg_get_int(hal, WNI_CFG_ENABLE_LTE_COEX, &en_lte_coex);
3280 
3281 	/* Check if LTE coex is enabled and 2.4GHz is selected */
3282 	if (en_lte_coex && (band_start_ch == CHAN_ENUM_1) &&
3283 	    (band_end_ch == CHAN_ENUM_14)) {
3284 		/* Set 2.4GHz upper limit to channel 9 for LTE COEX */
3285 		band_end_ch = CHAN_ENUM_9;
3286 	}
3287 
3288 	/* Allocate the max number of channel supported */
3289 	list = (uint8_t *) qdf_mem_malloc(NUM_5GHZ_CHANNELS +
3290 						NUM_24GHZ_CHANNELS);
3291 	if (NULL == list) {
3292 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3293 			  FL("Unable to allocate channel list"));
3294 		*num_ch = 0;
3295 		*ch_list = NULL;
3296 		return QDF_STATUS_E_NOMEM;
3297 	}
3298 
3299 	/* Search for the Active channels in the given range */
3300 	ch_count = 0;
3301 	for (loop_count = band_start_ch; loop_count <= band_end_ch;
3302 	     loop_count++) {
3303 		/* go to next channel if rf_channel is out of range */
3304 		if ((start_ch_num > WLAN_REG_CH_NUM(loop_count)) ||
3305 		    (end_ch_num < WLAN_REG_CH_NUM(loop_count)))
3306 			continue;
3307 		/*
3308 		 * go to next channel if none of these condition pass
3309 		 * - DFS scan enabled and chan not in CHANNEL_STATE_DISABLE
3310 		 * - DFS scan disable but chan in CHANNEL_STATE_ENABLE
3311 		 */
3312 		if (!(((true == mac_ctx->scan.fEnableDFSChnlScan) &&
3313 		      wlan_reg_get_channel_state(mac_ctx->pdev, loop_count)) ||
3314 		    ((false == mac_ctx->scan.fEnableDFSChnlScan) &&
3315 		     (CHANNEL_STATE_ENABLE ==
3316 		      wlan_reg_get_channel_state(mac_ctx->pdev, loop_count)))))
3317 			continue;
3318 
3319 		/*
3320 		 * Skip the channels which are not in ACS config from user
3321 		 * space
3322 		 */
3323 		if (SAP_CHANNEL_NOT_SELECTED ==
3324 			sap_channel_in_acs_channel_list(
3325 				WLAN_REG_CH_NUM(loop_count),
3326 				sap_ctx, &spect_info_obj))
3327 			continue;
3328 		/* Dont scan DFS channels in case of MCC disallowed
3329 		 * As it can result in SAP starting on DFS channel
3330 		 * resulting  MCC on DFS channel
3331 		 */
3332 		if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
3333 		    WLAN_REG_CH_NUM(loop_count)) &&
3334 		    policy_mgr_disallow_mcc(mac_ctx->psoc,
3335 		    WLAN_REG_CH_NUM(loop_count)))
3336 			continue;
3337 
3338 		/*
3339 		 * If we have any 5Ghz channel in the channel list
3340 		 * and bw is 40/80/160 Mhz then we don't want SAP to
3341 		 * come up in 2.4Ghz as for 40Mhz, 2.4Ghz channel is
3342 		 * not preferred and 80/160Mhz is not allowed for 2.4Ghz
3343 		 * band. So, don't even scan on 2.4Ghz channels if bw is
3344 		 * 40/80/160Mhz and channel list has any 5Ghz channel.
3345 		 */
3346 		if (end_ch_num >= WLAN_REG_CH_NUM(CHAN_ENUM_36) &&
3347 		    ((ch_width == CH_WIDTH_40MHZ) ||
3348 		     (ch_width == CH_WIDTH_80MHZ) ||
3349 		     (ch_width == CH_WIDTH_80P80MHZ) ||
3350 		     (ch_width == CH_WIDTH_160MHZ))) {
3351 			if (WLAN_REG_CH_NUM(loop_count) >=
3352 			    WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
3353 			    WLAN_REG_CH_NUM(loop_count) <=
3354 			    WLAN_REG_CH_NUM(CHAN_ENUM_14))
3355 				continue;
3356 		}
3357 
3358 #ifdef FEATURE_WLAN_CH_AVOID
3359 		for (i = 0; i < NUM_CHANNELS; i++) {
3360 			if (safe_channels[i].channelNumber ==
3361 			     WLAN_REG_CH_NUM(loop_count)) {
3362 				/* Check if channel is safe */
3363 				if (true == safe_channels[i].isSafe) {
3364 #endif
3365 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
3366 		uint8_t ch;
3367 
3368 		ch = WLAN_REG_CH_NUM(loop_count);
3369 		if ((sap_ctx->acs_cfg->skip_scan_status ==
3370 			eSAP_DO_PAR_ACS_SCAN)) {
3371 		    if ((ch >= sap_ctx->acs_cfg->skip_scan_range1_stch &&
3372 			 ch <= sap_ctx->acs_cfg->skip_scan_range1_endch) ||
3373 			(ch >= sap_ctx->acs_cfg->skip_scan_range2_stch &&
3374 			 ch <= sap_ctx->acs_cfg->skip_scan_range2_endch)) {
3375 			list[ch_count] =
3376 				WLAN_REG_CH_NUM(loop_count);
3377 			ch_count++;
3378 			QDF_TRACE(QDF_MODULE_ID_SAP,
3379 				QDF_TRACE_LEVEL_INFO,
3380 				FL("%d %d added to ACS ch range"),
3381 				ch_count, ch);
3382 		    } else {
3383 			QDF_TRACE(QDF_MODULE_ID_SAP,
3384 				QDF_TRACE_LEVEL_INFO_HIGH,
3385 				FL("%d %d skipped from ACS ch range"),
3386 				ch_count, ch);
3387 		    }
3388 		} else {
3389 			list[ch_count] =
3390 				WLAN_REG_CH_NUM(loop_count);
3391 			ch_count++;
3392 			QDF_TRACE(QDF_MODULE_ID_SAP,
3393 				QDF_TRACE_LEVEL_INFO,
3394 				FL("%d %d added to ACS ch range"),
3395 				ch_count, ch);
3396 		}
3397 #else
3398 		list[ch_count] = WLAN_REG_CH_NUM(loop_count);
3399 		ch_count++;
3400 #endif
3401 #ifdef FEATURE_WLAN_CH_AVOID
3402 				}
3403 				break;
3404 			}
3405 		}
3406 #endif
3407 	}
3408 	if (0 == ch_count) {
3409 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3410 		    FL("No active channels present for the current region"));
3411 		/*
3412 		 * LTE COEX: channel range outside the restricted 2.4GHz
3413 		 * band limits
3414 		 */
3415 		if (en_lte_coex && (start_ch_num > band_end_ch))
3416 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
3417 				FL("SAP can't be started as due to LTE COEX"));
3418 	}
3419 
3420 	/* return the channel list and number of channels to scan */
3421 	*num_ch = ch_count;
3422 	if (ch_count != 0) {
3423 		*ch_list = list;
3424 	} else {
3425 		*ch_list = NULL;
3426 		qdf_mem_free(list);
3427 	}
3428 
3429 	for (loop_count = 0; loop_count < ch_count; loop_count++) {
3430 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
3431 			FL("channel number: %d"), list[loop_count]);
3432 	}
3433 	return QDF_STATUS_SUCCESS;
3434 }
3435 #endif
3436 
3437 #ifdef DFS_COMPONENT_ENABLE
3438 uint8_t sap_indicate_radar(struct sap_context *sap_ctx)
3439 {
3440 	uint8_t target_channel = 0;
3441 	tHalHandle hal;
3442 	tpAniSirGlobal mac;
3443 
3444 	if (!sap_ctx) {
3445 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3446 			FL("null sap_ctx"));
3447 		return 0;
3448 	}
3449 
3450 	hal = CDS_GET_HAL_CB();
3451 	if (!hal) {
3452 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3453 			FL("null hal"));
3454 		return 0;
3455 	}
3456 
3457 	mac = PMAC_STRUCT(hal);
3458 
3459 	/*
3460 	 * SAP needs to generate Channel Switch IE
3461 	 * if the radar is found in the STARTED state
3462 	 */
3463 	if (eSAP_STARTED == sap_ctx->sapsMachine)
3464 		mac->sap.SapDfsInfo.csaIERequired = true;
3465 
3466 	if (sap_ctx->csr_roamProfile.disableDFSChSwitch)
3467 		return sap_ctx->channel;
3468 
3469 	/* set the Radar Found flag in SapDfsInfo */
3470 	mac->sap.SapDfsInfo.sap_radar_found_status = true;
3471 
3472 	if (sap_ctx->chan_before_pre_cac) {
3473 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
3474 			FL("sapdfs: set chan before pre cac %d as target chan"),
3475 			sap_ctx->chan_before_pre_cac);
3476 		return sap_ctx->chan_before_pre_cac;
3477 	}
3478 
3479 	if (sap_ctx->vendor_acs_dfs_lte_enabled && (QDF_STATUS_SUCCESS ==
3480 	    sap_signal_hdd_event(sap_ctx, NULL, eSAP_DFS_NEXT_CHANNEL_REQ,
3481 	    (void *) eSAP_STATUS_SUCCESS)))
3482 		return 0;
3483 
3484 	target_channel = sap_random_channel_sel(sap_ctx);
3485 	if (!target_channel)
3486 		sap_signal_hdd_event(sap_ctx, NULL,
3487 		eSAP_DFS_NO_AVAILABLE_CHANNEL, (void *) eSAP_STATUS_SUCCESS);
3488 
3489 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
3490 		  FL("sapdfs: New selected target channel is [%d]"),
3491 		  target_channel);
3492 
3493 	return target_channel;
3494 }
3495 #endif
3496 
3497 /*
3498  * CAC timer callback function.
3499  * Post eSAP_DFS_CHANNEL_CAC_END event to sap_fsm().
3500  */
3501 void sap_dfs_cac_timer_callback(void *data)
3502 {
3503 	struct sap_context *sapContext;
3504 	tWLAN_SAPEvent sapEvent;
3505 	tHalHandle hHal = (tHalHandle) data;
3506 	tpAniSirGlobal pMac;
3507 
3508 	if (NULL == hHal) {
3509 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3510 			  "In %s invalid hHal", __func__);
3511 		return;
3512 	}
3513 	pMac = PMAC_STRUCT(hHal);
3514 	sapContext = sap_find_cac_wait_session(hHal);
3515 	if (NULL == sapContext) {
3516 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3517 			"%s: no SAP contexts in wait state", __func__);
3518 		return;
3519 	}
3520 
3521 	/*
3522 	 * SAP may not be in CAC wait state, when the timer runs out.
3523 	 * if following flag is set, then timer is in initialized state,
3524 	 * destroy timer here.
3525 	 */
3526 	if (pMac->sap.SapDfsInfo.is_dfs_cac_timer_running == true) {
3527 		if (!sapContext->dfs_cac_offload)
3528 			qdf_mc_timer_destroy(
3529 				&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
3530 		pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = false;
3531 	}
3532 
3533 	/*
3534 	 * CAC Complete, post eSAP_DFS_CHANNEL_CAC_END to sap_fsm
3535 	 */
3536 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3537 			"sapdfs: Sending eSAP_DFS_CHANNEL_CAC_END for target_channel = %d on sapctx[%pK]",
3538 			sapContext->channel, sapContext);
3539 
3540 	sapEvent.event = eSAP_DFS_CHANNEL_CAC_END;
3541 	sapEvent.params = 0;
3542 	sapEvent.u1 = 0;
3543 	sapEvent.u2 = 0;
3544 
3545 	sap_fsm(sapContext, &sapEvent);
3546 }
3547 
3548 /*
3549  * Function to stop the DFS CAC Timer
3550  */
3551 static int sap_stop_dfs_cac_timer(struct sap_context *sapContext)
3552 {
3553 	tHalHandle hHal;
3554 	tpAniSirGlobal pMac;
3555 
3556 	if (sapContext == NULL)
3557 		return 0;
3558 
3559 	hHal = CDS_GET_HAL_CB();
3560 	if (NULL == hHal) {
3561 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3562 			  "In %s invalid hHal", __func__);
3563 		return 0;
3564 	}
3565 	pMac = PMAC_STRUCT(hHal);
3566 
3567 	if (sapContext->dfs_cac_offload) {
3568 		pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
3569 		return 0;
3570 	}
3571 
3572 	if (QDF_TIMER_STATE_RUNNING !=
3573 	    qdf_mc_timer_get_current_state(&pMac->sap.SapDfsInfo.
3574 					   sap_dfs_cac_timer)) {
3575 		return 0;
3576 	}
3577 
3578 	qdf_mc_timer_stop(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
3579 	pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
3580 	qdf_mc_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
3581 
3582 	return 0;
3583 }
3584 
3585 
3586 /*
3587  * Function to start the DFS CAC Timer
3588  * when SAP is started on a DFS channel
3589  */
3590 static int sap_start_dfs_cac_timer(struct sap_context *sap_ctx)
3591 {
3592 	QDF_STATUS status;
3593 	uint32_t cac_dur;
3594 	tHalHandle hal = NULL;
3595 	tpAniSirGlobal mac = NULL;
3596 	enum dfs_reg dfs_region;
3597 
3598 	if (!sap_ctx) {
3599 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3600 			  "%s: null sap_ctx", __func__);
3601 		return 0;
3602 	}
3603 
3604 	hal = CDS_GET_HAL_CB();
3605 	if (!hal) {
3606 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3607 			  "%s: null hal", __func__);
3608 		return 0;
3609 	}
3610 
3611 	mac = PMAC_STRUCT(hal);
3612 	if (sap_ctx->dfs_cac_offload) {
3613 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
3614 			  "%s: cac timer offloaded to firmware", __func__);
3615 		mac->sap.SapDfsInfo.is_dfs_cac_timer_running = true;
3616 		return 1;
3617 	}
3618 
3619 	sap_get_cac_dur_dfs_region(sap_ctx, &cac_dur, &dfs_region);
3620 	if (0 == cac_dur)
3621 		return 0;
3622 
3623 #ifdef QCA_WIFI_NAPIER_EMULATION
3624 	cac_dur = cac_dur / 100;
3625 #endif
3626 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3627 		  "sapdfs: SAP_DFS_CHANNEL_CAC_START on CH-%d, CAC_DUR-%d sec",
3628 		  sap_ctx->channel, cac_dur / 1000);
3629 
3630 	qdf_mc_timer_init(&mac->sap.SapDfsInfo.sap_dfs_cac_timer,
3631 			  QDF_TIMER_TYPE_SW,
3632 			  sap_dfs_cac_timer_callback, (void *)hal);
3633 
3634 	/* Start the CAC timer */
3635 	status = qdf_mc_timer_start(&mac->sap.SapDfsInfo.sap_dfs_cac_timer,
3636 			cac_dur);
3637 	if (status == QDF_STATUS_SUCCESS) {
3638 		mac->sap.SapDfsInfo.is_dfs_cac_timer_running = true;
3639 		return 1;
3640 	} else {
3641 		mac->sap.SapDfsInfo.is_dfs_cac_timer_running = false;
3642 		qdf_mc_timer_destroy(&mac->sap.SapDfsInfo.sap_dfs_cac_timer);
3643 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3644 			  "%s: failed to start cac timer", __func__);
3645 		return 0;
3646 	}
3647 }
3648 
3649 /*
3650  * This function initializes the NOL list
3651  * parameters required to track the radar
3652  * found DFS channels in the current Reg. Domain .
3653  */
3654 QDF_STATUS sap_init_dfs_channel_nol_list(struct sap_context *sapContext)
3655 {
3656 	tHalHandle hHal;
3657 	tpAniSirGlobal pMac;
3658 
3659 	if (NULL == sapContext) {
3660 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3661 			  "Invalid sapContext pointer on sap_init_dfs_channel_nol_list");
3662 		return QDF_STATUS_E_FAULT;
3663 	}
3664 	hHal = CDS_GET_HAL_CB();
3665 
3666 	if (NULL == hHal) {
3667 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3668 			  "In %s invalid hHal", __func__);
3669 		return QDF_STATUS_E_FAULT;
3670 	}
3671 	pMac = PMAC_STRUCT(hHal);
3672 
3673 	utils_dfs_init_nol(pMac->pdev);
3674 
3675 	return QDF_STATUS_SUCCESS;
3676 }
3677 
3678 /*
3679  * This function will calculate how many interfaces
3680  * have sap persona and returns total number of sap persona.
3681  */
3682 uint8_t sap_get_total_number_sap_intf(tHalHandle hHal)
3683 {
3684 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3685 	uint8_t intf = 0;
3686 	uint8_t intf_count = 0;
3687 
3688 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
3689 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
3690 		    ||
3691 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
3692 		    && pMac->sap.sapCtxList[intf].sap_context != NULL) {
3693 			intf_count++;
3694 		}
3695 	}
3696 	return intf_count;
3697 }
3698 
3699 /**
3700  * is_concurrent_sap_ready_for_channel_change() - to check all saps are ready
3701  *						  for channel change
3702  * @hHal: HAL pointer
3703  * @sapContext: sap context for which this function has been called
3704  *
3705  * This function will find the concurrent sap context apart from
3706  * passed sap context and return its channel change ready status
3707  *
3708  *
3709  * Return: true if other SAP personas are ready to channel switch else false
3710  */
3711 bool is_concurrent_sap_ready_for_channel_change(tHalHandle hHal,
3712 						struct sap_context *sapContext)
3713 {
3714 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3715 	struct sap_context *sap_context;
3716 	uint8_t intf = 0;
3717 
3718 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
3719 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
3720 		    ||
3721 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
3722 		    && pMac->sap.sapCtxList[intf].sap_context != NULL) {
3723 			sap_context =
3724 				pMac->sap.sapCtxList[intf].sap_context;
3725 			if (sap_context == sapContext) {
3726 				QDF_TRACE(QDF_MODULE_ID_SAP,
3727 					  QDF_TRACE_LEVEL_ERROR,
3728 					  FL("sapCtx matched [%pK]"),
3729 					  sapContext);
3730 				continue;
3731 			} else {
3732 				QDF_TRACE(QDF_MODULE_ID_SAP,
3733 					  QDF_TRACE_LEVEL_ERROR,
3734 					  FL
3735 						  ("concurrent sapCtx[%pK] didn't matche with [%pK]"),
3736 					  sap_context, sapContext);
3737 				return sap_context->is_sap_ready_for_chnl_chng;
3738 			}
3739 		}
3740 	}
3741 	return false;
3742 }
3743 
3744 /**
3745  * sap_is_conc_sap_doing_scc_dfs() - check if conc SAPs are doing SCC DFS
3746  * @hal: pointer to hal
3747  * @sap_context: current SAP persona's channel
3748  *
3749  * If provided SAP's channel is DFS then Loop through each SAP or GO persona and
3750  * check if other beaconing entity's channel is same DFS channel. If they are
3751  * same then concurrent sap is doing SCC DFS.
3752  *
3753  * Return: true if two or more beaconing entitity doing SCC DFS else false
3754  */
3755 bool sap_is_conc_sap_doing_scc_dfs(tHalHandle hal,
3756 				   struct sap_context *given_sapctx)
3757 {
3758 	tpAniSirGlobal mac = PMAC_STRUCT(hal);
3759 	struct sap_context *sap_ctx;
3760 	uint8_t intf = 0, scc_dfs_counter = 0;
3761 
3762 	/*
3763 	 * current SAP persona's channel itself is not DFS, so no need to check
3764 	 * what other persona's channel is
3765 	 */
3766 	if (!wlan_reg_is_dfs_ch(mac->pdev,
3767 			given_sapctx->csr_roamProfile.operationChannel)) {
3768 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
3769 			  FL("skip this loop as provided channel is non-dfs"));
3770 		return false;
3771 	}
3772 
3773 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
3774 		if ((QDF_SAP_MODE != mac->sap.sapCtxList[intf].sapPersona) &&
3775 		    (QDF_P2P_GO_MODE != mac->sap.sapCtxList[intf].sapPersona))
3776 			continue;
3777 		if (!mac->sap.sapCtxList[intf].sap_context)
3778 			continue;
3779 		sap_ctx = mac->sap.sapCtxList[intf].sap_context;
3780 		/* if same SAP contexts then skip to next context */
3781 		if (sap_ctx == given_sapctx)
3782 			continue;
3783 		if (given_sapctx->csr_roamProfile.operationChannel ==
3784 				sap_ctx->csr_roamProfile.operationChannel)
3785 			scc_dfs_counter++;
3786 	}
3787 
3788 	/* Found atleast two of the beaconing entities doing SCC DFS */
3789 	if (scc_dfs_counter)
3790 		return true;
3791 
3792 	return false;
3793 }
3794