xref: /wlan-dirver/qcacld-3.0/core/sap/src/sap_module.c (revision c657ef50ea91125e170c3881d4126a267d3adbd6)
1 /*
2  * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
3  *
4  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5  *
6  *
7  * Permission to use, copy, modify, and/or distribute this software for
8  * any purpose with or without fee is hereby granted, provided that the
9  * above copyright notice and this permission notice appear in all
10  * copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19  * PERFORMANCE OF THIS SOFTWARE.
20  */
21 
22 /*
23  * This file was originally distributed by Qualcomm Atheros, Inc.
24  * under proprietary terms before Copyright ownership was assigned
25  * to the Linux Foundation.
26  */
27 
28 /**
29  * ===========================================================================
30  *                     sapModule.C
31  *  OVERVIEW:
32  *  This software unit holds the implementation of the WLAN SAP modules
33  *  functions providing EXTERNAL APIs. It is also where the global SAP module
34  *  context gets initialised
35  *  DEPENDENCIES:
36  *  Are listed for each API below.
37  * ===========================================================================
38  */
39 
40 /* $Header$ */
41 
42 /*----------------------------------------------------------------------------
43  * Include Files
44  * -------------------------------------------------------------------------*/
45 #include "qdf_trace.h"
46 #include "qdf_util.h"
47 #include "qdf_atomic.h"
48 /* Pick up the sme callback registration API */
49 #include "sme_api.h"
50 
51 /* SAP API header file */
52 
53 #include "sap_internal.h"
54 #include "sme_inside.h"
55 #include "cds_ieee80211_common_i.h"
56 #include "cds_regdomain.h"
57 #include "cds_concurrency.h"
58 
59 /*----------------------------------------------------------------------------
60  * Preprocessor Definitions and Constants
61  * -------------------------------------------------------------------------*/
62 #define SAP_DEBUG
63 
64 /*----------------------------------------------------------------------------
65  * Type Declarations
66  * -------------------------------------------------------------------------*/
67 
68 /*----------------------------------------------------------------------------
69  * Global Data Definitions
70  * -------------------------------------------------------------------------*/
71 
72 /*----------------------------------------------------------------------------
73  *  External declarations for global context
74  * -------------------------------------------------------------------------*/
75 /*  No!  Get this from CDS. */
76 /*  The main per-Physical Link (per WLAN association) context. */
77 static ptSapContext gp_sap_ctx[SAP_MAX_NUM_SESSION];
78 static qdf_atomic_t sap_ctx_ref_count[SAP_MAX_NUM_SESSION];
79 
80 /*----------------------------------------------------------------------------
81  * Static Variable Definitions
82  * -------------------------------------------------------------------------*/
83 static qdf_mutex_t sap_context_lock;
84 
85 /*----------------------------------------------------------------------------
86  * Static Function Declarations and Definitions
87  * -------------------------------------------------------------------------*/
88 
89 /*----------------------------------------------------------------------------
90  * Externalized Function Definitions
91  * -------------------------------------------------------------------------*/
92 
93 /*----------------------------------------------------------------------------
94  * Function Declarations and Documentation
95  * -------------------------------------------------------------------------*/
96 
97 /**
98  * wlansap_global_init() - Initialize SAP globals
99  *
100  * Initializes the SAP global data structures
101  *
102  * Return: QDF_STATUS
103  */
104 QDF_STATUS wlansap_global_init(void)
105 {
106 	uint32_t i;
107 
108 	if (QDF_IS_STATUS_ERROR(qdf_mutex_create(&sap_context_lock))) {
109 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
110 			  "failed to init sap_context_lock");
111 		return QDF_STATUS_E_FAULT;
112 	}
113 
114 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
115 		gp_sap_ctx[i] = NULL;
116 		qdf_atomic_init(&sap_ctx_ref_count[i]);
117 	}
118 
119 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
120 			"%s: sap global context initialized", __func__);
121 
122 	return QDF_STATUS_SUCCESS;
123 }
124 
125 /**
126  * wlansap_global_deinit() - De-initialize SAP globals
127  *
128  * De-initializes the SAP global data structures
129  *
130  * Return: QDF_STATUS
131  */
132 QDF_STATUS wlansap_global_deinit(void)
133 {
134 	uint32_t i;
135 
136 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
137 		if (gp_sap_ctx[i]) {
138 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
139 				"we could be leaking context:%d", i);
140 		}
141 		gp_sap_ctx[i] = NULL;
142 		qdf_atomic_init(&sap_ctx_ref_count[i]);
143 	}
144 
145 	if (QDF_IS_STATUS_ERROR(qdf_mutex_destroy(&sap_context_lock))) {
146 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
147 				"failed to destroy sap_context_lock");
148 		return QDF_STATUS_E_FAULT;
149 	}
150 
151 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
152 			"%s: sap global context deinitialized", __func__);
153 
154 	return QDF_STATUS_SUCCESS;
155 }
156 
157 /**
158  * wlansap_save_context() - Save the context in global SAP context
159  * @ctx: SAP context to be stored
160  *
161  * Stores the given SAP context in the global SAP context array
162  *
163  * Return: QDF_STATUS
164  */
165 static QDF_STATUS wlansap_save_context(ptSapContext ctx)
166 {
167 	uint32_t i;
168 
169 	qdf_mutex_acquire(&sap_context_lock);
170 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
171 		if (gp_sap_ctx[i] == NULL) {
172 			gp_sap_ctx[i] = ctx;
173 			qdf_atomic_inc(&sap_ctx_ref_count[i]);
174 			qdf_mutex_release(&sap_context_lock);
175 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
176 				"%s: sap context saved at index:%d",
177 				__func__, i);
178 			return QDF_STATUS_SUCCESS;
179 		}
180 	}
181 	qdf_mutex_release(&sap_context_lock);
182 
183 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
184 		"%s: failed to save sap context", __func__);
185 
186 	return QDF_STATUS_E_FAILURE;
187 }
188 
189 /**
190  * wlansap_context_get() - Verify SAP context and increment ref count
191  * @ctx: Context to be checked
192  *
193  * Verifies the SAP context and increments the reference count maintained for
194  * the corresponding SAP context.
195  *
196  * Return: QDF_STATUS
197  */
198 QDF_STATUS wlansap_context_get(ptSapContext ctx)
199 {
200 	uint32_t i;
201 
202 	qdf_mutex_acquire(&sap_context_lock);
203 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
204 		if (ctx && (gp_sap_ctx[i] == ctx)) {
205 			qdf_atomic_inc(&sap_ctx_ref_count[i]);
206 			qdf_mutex_release(&sap_context_lock);
207 			return QDF_STATUS_SUCCESS;
208 		}
209 	}
210 	qdf_mutex_release(&sap_context_lock);
211 
212 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
213 			"%s: sap session is not valid", __func__);
214 	return QDF_STATUS_E_FAILURE;
215 }
216 
217 /**
218  * wlansap_context_put() - Check the reference count and free SAP context
219  * @ctx: SAP context to be checked and freed
220  *
221  * Checks the reference count and frees the SAP context
222  *
223  * Return: None
224  */
225 void wlansap_context_put(ptSapContext ctx)
226 {
227 	uint32_t i;
228 
229 	if (!ctx)
230 		return;
231 
232 	qdf_mutex_acquire(&sap_context_lock);
233 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
234 		if (gp_sap_ctx[i] == ctx) {
235 			if (qdf_atomic_dec_and_test(&sap_ctx_ref_count[i])) {
236 				qdf_mem_free(ctx);
237 				gp_sap_ctx[i] = NULL;
238 				QDF_TRACE(QDF_MODULE_ID_SAP,
239 					QDF_TRACE_LEVEL_INFO,
240 					"%s: sap session freed: %d",
241 					__func__, i);
242 			}
243 			qdf_mutex_release(&sap_context_lock);
244 			return;
245 		}
246 	}
247 	qdf_mutex_release(&sap_context_lock);
248 }
249 
250 /**
251  * wlansap_open() - WLAN SAP open function call
252  * @p_cds_gctx: Pointer to the global cds context; a handle to SAP's
253  *
254  * Called at driver initialization (cds_open). SAP will initialize
255  * all its internal resources and will wait for the call to start to
256  * register with the other modules.
257  *
258  * Return: Pointer to the SAP context
259  */
260 void *wlansap_open(void *p_cds_gctx)
261 {
262 	ptSapContext pSapCtx = NULL;
263 	QDF_STATUS status;
264 
265 	/* dynamically allocate the sapContext */
266 	pSapCtx = (ptSapContext) qdf_mem_malloc(sizeof(tSapContext));
267 
268 	if (NULL == pSapCtx) {
269 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
270 			  "%s: Invalid SAP pointer from p_cds_gctx", __func__);
271 		return NULL;
272 	}
273 
274 	/* Clean up SAP control block, initialize all values */
275 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "wlansap_open");
276 
277 	wlansap_clean_cb(pSapCtx, 0); /*do not empty */
278 
279 	/* Setup the "link back" to the CDS context */
280 	pSapCtx->p_cds_gctx = p_cds_gctx;
281 
282 	/* Save the SAP context pointer */
283 	status = wlansap_save_context(pSapCtx);
284 	if (QDF_IS_STATUS_ERROR(status)) {
285 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
286 			"%s: failed to save SAP context", __func__);
287 		qdf_mem_free(pSapCtx);
288 		return NULL;
289 	}
290 
291 	return pSapCtx;
292 } /* wlansap_open */
293 
294 /**
295  * wlansap_start() - wlan start SAP.
296  * @pCtx: Pointer to the global cds context; a handle to SAP's
297  *        control block can be extracted from its context
298  *        When MBSSID feature is enabled, SAP context is directly
299  *        passed to SAP APIs
300  * @mode: Device mode
301  * @addr: MAC address of the SAP
302  * @session_id: Pointer to the session id
303  *
304  * Called as part of the overall start procedure (cds_enable). SAP will
305  * use this call to register with TL as the SAP entity for SAP RSN frames.
306  *
307  * Return: The result code associated with performing the operation
308  *         QDF_STATUS_E_FAULT: Pointer to SAP cb is NULL;
309  *                             access would cause a page fault.
310  *         QDF_STATUS_SUCCESS: Success
311  */
312 QDF_STATUS wlansap_start(void *pCtx, enum tQDF_ADAPTER_MODE mode,
313 			 uint8_t *addr, uint32_t *session_id)
314 {
315 	ptSapContext pSapCtx = NULL;
316 	QDF_STATUS qdf_ret_status;
317 	tHalHandle hal;
318 
319 	/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
320 
321 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
322 		  "wlansap_start invoked successfully");
323 	/*------------------------------------------------------------------------
324 	    Sanity check
325 	    Extract SAP control block
326 	   ------------------------------------------------------------------------*/
327 	pSapCtx = CDS_GET_SAP_CB(pCtx);
328 
329 	if (NULL == pSapCtx) {
330 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
331 			  "%s: Invalid SAP pointer from pCtx", __func__);
332 		return QDF_STATUS_E_FAULT;
333 	}
334 
335 	/*------------------------------------------------------------------------
336 	    For now, presume security is not enabled.
337 	   -----------------------------------------------------------------------*/
338 	pSapCtx->ucSecEnabled = WLANSAP_SECURITY_ENABLED_STATE;
339 
340 	/*------------------------------------------------------------------------
341 	    Now configure the roaming profile links. To SSID and bssid.
342 	   ------------------------------------------------------------------------*/
343 	/* We have room for two SSIDs. */
344 	pSapCtx->csr_roamProfile.SSIDs.numOfSSIDs = 1;   /* This is true for now. */
345 	pSapCtx->csr_roamProfile.SSIDs.SSIDList = pSapCtx->SSIDList;     /* Array of two */
346 	pSapCtx->csr_roamProfile.SSIDs.SSIDList[0].SSID.length = 0;
347 	pSapCtx->csr_roamProfile.SSIDs.SSIDList[0].handoffPermitted = false;
348 	pSapCtx->csr_roamProfile.SSIDs.SSIDList[0].ssidHidden =
349 		pSapCtx->SSIDList[0].ssidHidden;
350 
351 	pSapCtx->csr_roamProfile.BSSIDs.numOfBSSIDs = 1; /* This is true for now. */
352 	pSapCtx->csr_roamProfile.BSSIDs.bssid = &pSapCtx->bssid;
353 	pSapCtx->csr_roamProfile.csrPersona = mode;
354 	qdf_mem_copy(pSapCtx->self_mac_addr, addr, QDF_MAC_ADDR_SIZE);
355 	qdf_event_create(&pSapCtx->sap_session_opened_evt);
356 
357 	/* Now configure the auth type in the roaming profile. To open. */
358 	pSapCtx->csr_roamProfile.negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM;        /* open is the default */
359 
360 	if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_create(&pSapCtx->SapGlobalLock))) {
361 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
362 			  "wlansap_start failed init lock");
363 		return QDF_STATUS_E_FAULT;
364 	}
365 
366 	hal = (tHalHandle) CDS_GET_HAL_CB(pSapCtx->p_cds_gctx);
367 	if (!hal) {
368 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
369 			"%s: Invalid HAL pointer", __func__);
370 		return QDF_STATUS_E_INVAL;
371 	}
372 
373 	qdf_ret_status = sap_open_session(hal, pSapCtx, session_id);
374 
375 	if (QDF_STATUS_SUCCESS != qdf_ret_status) {
376 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
377 			"Error: In %s calling sap_open_session status = %d",
378 			__func__, qdf_ret_status);
379 		return QDF_STATUS_E_FAILURE;
380 	}
381 
382 	return QDF_STATUS_SUCCESS;
383 }
384 
385 /**
386  * wlansap_stop() - stop SAP module.
387  * @pCtx: Pointer to the global cds context; a handle to SAP's control block
388  *        can be extracted from its context. When MBSSID feature is enabled,
389  *        SAP context is directly passed to SAP APIs
390  *
391  * Called by cds_disable to stop operation in SAP, before close. SAP will
392  * suspend all BT-AMP Protocol Adaption Layer operation and will wait for the
393  * close request to clean up its resources.
394  *
395  * Return: The result code associated with performing the operation
396  *         QDF_STATUS_E_FAULT: Pointer to SAP cb is NULL;
397  *                             access would cause a page fault.
398  *         QDF_STATUS_SUCCESS: Success
399  */
400 QDF_STATUS wlansap_stop(void *pCtx)
401 {
402 	ptSapContext pSapCtx = NULL;
403 
404 	/* Sanity check - Extract SAP control block */
405 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
406 		  "wlansap_stop invoked successfully ");
407 
408 	pSapCtx = CDS_GET_SAP_CB(pCtx);
409 	if (NULL == pSapCtx) {
410 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
411 			  "%s: Invalid SAP pointer from pCtx", __func__);
412 		return QDF_STATUS_E_FAULT;
413 	}
414 
415 	sap_free_roam_profile(&pSapCtx->csr_roamProfile);
416 
417 	if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_destroy(&pSapCtx->SapGlobalLock))) {
418 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
419 			  "wlansap_stop failed destroy lock");
420 		return QDF_STATUS_E_FAULT;
421 	}
422 
423 	return QDF_STATUS_SUCCESS;
424 }
425 
426 /**
427  * wlansap_close - close SAP module.
428  * @pCtx: Pointer to the global cds context; a handle to SAP's control block
429  *        can be extracted from its context. When MBSSID feature is enabled,
430  *        SAP context is directly passed to SAP APIs.
431  *
432  * Called by cds_close during general driver close procedure. SAP will clean up
433  * all the internal resources.
434  *
435  * Return: The result code associated with performing the operation
436  *         QDF_STATUS_E_FAULT: Pointer to SAP cb is NULL;
437  *                             access would cause a page fault
438  *         QDF_STATUS_SUCCESS: Success
439  */
440 QDF_STATUS wlansap_close(void *pCtx)
441 {
442 	ptSapContext pSapCtx = NULL;
443 
444 	/* Sanity check - Extract SAP control block */
445 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
446 		  "wlansap_close invoked");
447 
448 	pSapCtx = CDS_GET_SAP_CB(pCtx);
449 	if (NULL == pSapCtx) {
450 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
451 			  "%s: Invalid SAP pointer from pCtx", __func__);
452 		return QDF_STATUS_E_FAULT;
453 	}
454 
455 	/* Cleanup SAP control block */
456 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
457 		  "wlansap_close");
458 
459 	/* empty queues/lists/pkts if any */
460 	wlansap_clean_cb(pSapCtx, true);
461 
462 	wlansap_context_put(pSapCtx);
463 
464 	return QDF_STATUS_SUCCESS;
465 } /* wlansap_close */
466 
467 /*----------------------------------------------------------------------------
468  * Utility Function implementations
469  * -------------------------------------------------------------------------*/
470 
471 /**
472  * wlansap_clean_cb() - clean SAP callback function.
473  * @pCtx: Pointer to the global cds context; a handle to SAP's control block
474  *        can be extracted from its context. When MBSSID feature is enabled,
475  *        SAP context is directly passed to SAP APIs.
476  *
477  * Clear out all fields in the SAP context.
478  *
479  * Return: The result code associated with performing the operation
480  *         QDF_STATUS_E_FAULT: Pointer to SAP cb is NULL;
481  *                             access would cause a page fault
482  *         QDF_STATUS_SUCCESS: Success
483  */
484 QDF_STATUS wlansap_clean_cb(ptSapContext pSapCtx, uint32_t freeFlag      /* 0 / *do not empty* /); */
485 			    ) {
486 	tHalHandle hal;
487 
488 	/*------------------------------------------------------------------------
489 	    Sanity check SAP control block
490 	   ------------------------------------------------------------------------*/
491 
492 	if (NULL == pSapCtx) {
493 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
494 			  "%s: Invalid SAP pointer", __func__);
495 		return QDF_STATUS_E_FAULT;
496 	}
497 
498 	/*------------------------------------------------------------------------
499 	    Clean up SAP control block, initialize all values
500 	   ------------------------------------------------------------------------*/
501 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
502 		  "wlansap_clean_cb");
503 
504 	hal = (tHalHandle) CDS_GET_HAL_CB(pSapCtx->p_cds_gctx);
505 	if (eSAP_TRUE == pSapCtx->isSapSessionOpen && hal) {
506 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
507 				"close existing SAP session");
508 		sap_close_session(hal, pSapCtx, NULL, false);
509 	}
510 
511 	qdf_mem_zero(pSapCtx, sizeof(tSapContext));
512 
513 	pSapCtx->p_cds_gctx = NULL;
514 
515 	pSapCtx->sapsMachine = eSAP_DISCONNECTED;
516 
517 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
518 		  "%s: Initializing State: %d, sapContext value = %p", __func__,
519 		  pSapCtx->sapsMachine, pSapCtx);
520 	pSapCtx->sessionId = 0;
521 	pSapCtx->channel = 0;
522 
523 	return QDF_STATUS_SUCCESS;
524 } /* wlansap_clean_cb */
525 
526 /*==========================================================================
527    FUNCTION    wlansap_pmc_full_pwr_req_cb
528 
529    DESCRIPTION
530     Callback provide to PMC in the pmc_request_full_power API.
531 
532    DEPENDENCIES
533 
534    PARAMETERS
535 
536     IN
537     callbackContext:  The user passed in a context to identify
538     status : The qdf_ret_status
539 
540    RETURN VALUE
541     None
542 
543    SIDE EFFECTS
544    ============================================================================*/
545 void
546 wlansap_pmc_full_pwr_req_cb(void *callbackContext, QDF_STATUS status)
547 {
548 	if (QDF_IS_STATUS_SUCCESS(status)) {
549 		/* If success what else to be handled??? */
550 	} else {
551 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
552 			  "wlansap_pmc_full_pwr_req_cb: PMC failed to put the chip in Full power");
553 
554 	}
555 
556 } /* wlansap_pmc_full_pwr_req_cb */
557 
558 /**
559  * wlansap_get_state() - get SAP state
560  * @pCtx: Pointer to the global cds context; a handle to SAP's control block
561  *        can be extracted from its context. When MBSSID feature is enabled,
562  *        SAP context is directly passed to SAP APIs.
563  *
564  * This api returns the current SAP state to the caller.
565  *
566  * Return: uint8_t - the SAP FSM state.
567  */
568 uint8_t wlansap_get_state(void *pCtx)
569 {
570 	ptSapContext pSapCtx = NULL;
571 
572 	pSapCtx = CDS_GET_SAP_CB(pCtx);
573 
574 	if (NULL == pSapCtx) {
575 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
576 			  "%s: Invalid SAP pointer from pCtx", __func__);
577 		return QDF_STATUS_E_FAULT;
578 	}
579 	return pSapCtx->sapsMachine;
580 }
581 
582 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
583 /*==========================================================================
584    FUNCTION    wlansap_check_cc_intf
585 
586    DESCRIPTION Restart SAP if Concurrent Channel interfering
587 
588    DEPENDENCIES NA.
589 
590    PARAMETERS
591    IN
592    Ctx: Pointer to cds Context or Sap Context based on MBSSID
593 
594    RETURN VALUE NONE
595 
596    SIDE EFFECTS
597    ============================================================================*/
598 uint16_t wlansap_check_cc_intf(void *Ctx)
599 {
600 	tHalHandle hHal;
601 	uint16_t intf_ch;
602 	ptSapContext pSapCtx = CDS_GET_SAP_CB(Ctx);
603 
604 	hHal = (tHalHandle) CDS_GET_HAL_CB(pSapCtx->p_cds_gctx);
605 	if (NULL == hHal) {
606 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
607 			  "%s: Invalid MAC context from p_cds_gctx", __func__);
608 		return 0;
609 	}
610 	intf_ch = sme_check_concurrent_channel_overlap(hHal, 0, 0,
611 						       pSapCtx->cc_switch_mode);
612 	return intf_ch;
613 }
614 #endif
615 
616  /**
617   * wlansap_set_scan_acs_channel_params() - Config scan and channel parameters.
618   * pconfig:                                Pointer to the SAP config
619   * psap_ctx:                               Pointer to the SAP Context.
620   * pusr_context:                           Parameter that will be passed
621   *                                         back in all the SAP callback events.
622   *
623   * This api function is used to copy Scan and Channel parameters from sap
624   * config to sap context.
625   *
626   * Return:                                 The result code associated with
627   *                                         performing the operation
628   */
629 QDF_STATUS
630 wlansap_set_scan_acs_channel_params(tsap_Config_t *pconfig,
631 				ptSapContext psap_ctx,
632 				void *pusr_context)
633 {
634 	tHalHandle h_hal = NULL;
635 
636 	if (NULL == pconfig) {
637 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
638 			"%s: Invalid pconfig passed ", __func__);
639 		return QDF_STATUS_E_FAULT;
640 	}
641 
642 	if (NULL == psap_ctx) {
643 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
644 			"%s: Invalid pconfig passed ", __func__);
645 		return QDF_STATUS_E_FAULT;
646 	}
647 
648 	/* Channel selection is auto or configured */
649 	psap_ctx->channel = pconfig->channel;
650 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
651 	psap_ctx->cc_switch_mode = pconfig->cc_switch_mode;
652 #endif
653 	psap_ctx->pUsrContext = pusr_context;
654 	psap_ctx->enableOverLapCh = pconfig->enOverLapCh;
655 	psap_ctx->acs_cfg = &pconfig->acs_cfg;
656 	psap_ctx->ch_width_orig = pconfig->acs_cfg.ch_width;
657 	psap_ctx->secondary_ch = pconfig->sec_ch;
658 
659 	/*
660 	 * Set the BSSID to your "self MAC Addr" read
661 	 * the mac address from Configuation ITEM received
662 	 * from HDD
663 	 */
664 	psap_ctx->csr_roamProfile.BSSIDs.numOfBSSIDs = 1;
665 
666 	/* Save a copy to SAP context */
667 	qdf_mem_copy(psap_ctx->csr_roamProfile.BSSIDs.bssid,
668 		pconfig->self_macaddr.bytes, QDF_MAC_ADDR_SIZE);
669 	qdf_mem_copy(psap_ctx->self_mac_addr,
670 		pconfig->self_macaddr.bytes, QDF_MAC_ADDR_SIZE);
671 
672 	h_hal = (tHalHandle)CDS_GET_HAL_CB(psap_ctx->p_cds_gctx);
673 	if (NULL == h_hal) {
674 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
675 			"%s: Invalid MAC context from pvosGCtx", __func__);
676 	} else {
677 		/*
678 		 * If concurrent session is running that is already associated
679 		 * then we just follow that sessions country info (whether
680 		 * present or not doesn't maater as we have to follow whatever
681 		 * STA session does)
682 		 */
683 		if ((0 == sme_get_concurrent_operation_channel(h_hal)) &&
684 			pconfig->ieee80211d) {
685 			/* Setting the region/country  information */
686 			sme_set_reg_info(h_hal, pconfig->countryCode);
687 			sme_apply_channel_power_info_to_fw(h_hal);
688 		}
689 	}
690 
691 	return QDF_STATUS_SUCCESS;
692 }
693 /**
694  * wlan_sap_get_vht_ch_width() - Returns SAP VHT channel width.
695  * @ctx:	Pointer to cds Context or Sap Context based on MBSSID
696  *
697  * This function provides the SAP current VHT channel with.
698  *
699  * Return: VHT channel width
700  */
701 uint32_t wlan_sap_get_vht_ch_width(void *ctx)
702 {
703 	ptSapContext sap_ctx = CDS_GET_SAP_CB(ctx);
704 
705 	if (!sap_ctx) {
706 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
707 			FL("Invalid SAP pointer from ctx"));
708 		return 0;
709 	}
710 
711 	return sap_ctx->ch_params.ch_width;
712 }
713 
714 /**
715  * wlan_sap_set_vht_ch_width() - Sets SAP VHT channel width.
716  * @ctx:		Pointer to cds Context or Sap Context based on MBSSID
717  * @vht_channel_width:	SAP VHT channel width value.
718  *
719  * This function sets the SAP current VHT channel with.
720  *
721  * Return: None
722  */
723 void wlan_sap_set_vht_ch_width(void *ctx, uint32_t vht_channel_width)
724 {
725 	ptSapContext sap_ctx = CDS_GET_SAP_CB(ctx);
726 
727 	if (!sap_ctx) {
728 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
729 			FL("Invalid SAP pointer from ctx"));
730 		return;
731 	}
732 
733 	sap_ctx->ch_params.ch_width = vht_channel_width;
734 }
735 
736 /**
737  * wlan_sap_validate_channel_switch() - validate target channel switch w.r.t
738  *      concurreny rules set to avoid channel interference.
739  * @hal - Hal context
740  * @sap_ch - channel to switch
741  * @sap_context - sap session context
742  *
743  * Return: true if there is no channel interference else return false
744  */
745 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
746 static bool wlan_sap_validate_channel_switch(tHalHandle hal, uint16_t sap_ch,
747 		ptSapContext sap_context)
748 {
749 	return sme_validate_sap_channel_switch(
750 			hal,
751 			sap_ch,
752 			sap_context->csr_roamProfile.phyMode,
753 			sap_context->cc_switch_mode,
754 			sap_context->sessionId);
755 }
756 #else
757 static inline bool wlan_sap_validate_channel_switch(tHalHandle hal,
758 		uint16_t sap_ch, ptSapContext sap_context)
759 {
760 	return true;
761 }
762 #endif
763 /**
764  * wlansap_start_bss() - start BSS
765  * @pCtx: Pointer to the global cds context; a handle to SAP's control block
766  *        can be extracted from its context. When MBSSID feature is enabled,
767  *        SAP context is directly passed to SAP APIs.
768  * @pQctCommitConfig: Pointer to configuration structure passed down from
769  *                    HDD(HostApd for Android)
770  * @hdd_SapEventCallback: Callback function in HDD called by SAP to inform HDD
771  *                        about SAP results
772  * @pUsrContext: Parameter that will be passed back in all the SAP callback
773  *               events.
774  *
775  * This api function provides SAP FSM event eWLAN_SAP_PHYSICAL_LINK_CREATE for
776  * starting AP BSS
777  *
778  * Return: The result code associated with performing the operation
779  *         QDF_STATUS_E_FAULT: Pointer to SAP cb is NULL;
780  *                             access would cause a page fault
781  *         QDF_STATUS_SUCCESS: Success
782  */
783 QDF_STATUS wlansap_start_bss(void *pCtx,     /* pwextCtx */
784 			     tpWLAN_SAPEventCB pSapEventCallback,
785 			     tsap_Config_t *pConfig, void *pUsrContext) {
786 	tWLAN_SAPEvent sapEvent;        /* State machine event */
787 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
788 	ptSapContext pSapCtx = NULL;
789 	tHalHandle hHal;
790 	tpAniSirGlobal pmac = NULL;
791 
792 	/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
793 
794 	/*------------------------------------------------------------------------
795 	    Sanity check
796 	    Extract SAP control block
797 	   ------------------------------------------------------------------------*/
798 	pSapCtx = CDS_GET_SAP_CB(pCtx);
799 
800 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
801 		  "wlansap_start_bss: sapContext=%p", pSapCtx);
802 
803 	if (NULL == pSapCtx) {
804 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
805 			  "%s: Invalid SAP pointer from pCtx",
806 			  __func__);
807 		return QDF_STATUS_E_FAULT;
808 	}
809 	pSapCtx->sapsMachine = eSAP_DISCONNECTED;
810 
811 	/* Channel selection is auto or configured */
812 	pSapCtx->channel = pConfig->channel;
813 	pSapCtx->ch_params.ch_width = pConfig->ch_params.ch_width;
814 	pSapCtx->ch_params.center_freq_seg0 =
815 		pConfig->ch_params.center_freq_seg0;
816 	pSapCtx->ch_params.center_freq_seg1 =
817 		pConfig->ch_params.center_freq_seg1;
818 	pSapCtx->ch_params.sec_ch_offset =
819 		pConfig->ch_params.sec_ch_offset;
820 	pSapCtx->ch_width_orig = pConfig->ch_width_orig;
821 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
822 	pSapCtx->cc_switch_mode = pConfig->cc_switch_mode;
823 #endif
824 	pSapCtx->pUsrContext = pUsrContext;
825 	pSapCtx->enableOverLapCh = pConfig->enOverLapCh;
826 	pSapCtx->acs_cfg = &pConfig->acs_cfg;
827 	/* Set the BSSID to your "self MAC Addr" read the mac address
828 		from Configuation ITEM received from HDD */
829 	pSapCtx->csr_roamProfile.BSSIDs.numOfBSSIDs = 1;
830 	qdf_mem_copy(pSapCtx->csr_roamProfile.BSSIDs.bssid,
831 		     pSapCtx->self_mac_addr, sizeof(struct qdf_mac_addr));
832 
833 	/* Save a copy to SAP context */
834 	qdf_mem_copy(pSapCtx->csr_roamProfile.BSSIDs.bssid,
835 		     pConfig->self_macaddr.bytes, QDF_MAC_ADDR_SIZE);
836 	qdf_mem_copy(pSapCtx->self_mac_addr,
837 		     pConfig->self_macaddr.bytes, QDF_MAC_ADDR_SIZE);
838 
839 	/* copy the configuration items to csrProfile */
840 	sapconvert_to_csr_profile(pConfig, eCSR_BSS_TYPE_INFRA_AP,
841 			       &pSapCtx->csr_roamProfile);
842 	hHal = (tHalHandle) CDS_GET_HAL_CB(pSapCtx->p_cds_gctx);
843 	if (NULL == hHal) {
844 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
845 			  "%s: Invalid MAC context from p_cds_gctx",
846 			  __func__);
847 		return QDF_STATUS_E_FAULT;
848 	} else {
849 		/* If concurrent session is running that is already associated
850 		 * then we just follow that sessions country info (whether
851 		 * present or not doesn't maater as we have to follow whatever
852 		 * STA session does) */
853 		if ((0 == sme_get_concurrent_operation_channel(hHal)) &&
854 		    pConfig->ieee80211d) {
855 			/* Setting the region/country  information */
856 			sme_set_reg_info(hHal, pConfig->countryCode);
857 			sme_apply_channel_power_info_to_fw(hHal);
858 		}
859 	}
860 
861 	pmac = PMAC_STRUCT(hHal);
862 	if (NULL == pmac) {
863 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
864 			  "%s: Invalid MAC context from p_cds_gctx",
865 			  __func__);
866 		return QDF_STATUS_E_FAULT;
867 	}
868 	/*
869 	 * Copy the DFS Test Mode setting to pmac for
870 	 * access in lower layers
871 	 */
872 	pmac->sap.SapDfsInfo.disable_dfs_ch_switch =
873 				pConfig->disableDFSChSwitch;
874 
875 	/* Copy MAC filtering settings to sap context */
876 	pSapCtx->eSapMacAddrAclMode = pConfig->SapMacaddr_acl;
877 	qdf_mem_copy(pSapCtx->acceptMacList, pConfig->accept_mac,
878 		     sizeof(pConfig->accept_mac));
879 	pSapCtx->nAcceptMac = pConfig->num_accept_mac;
880 	sap_sort_mac_list(pSapCtx->acceptMacList, pSapCtx->nAcceptMac);
881 	qdf_mem_copy(pSapCtx->denyMacList, pConfig->deny_mac,
882 		     sizeof(pConfig->deny_mac));
883 	pSapCtx->nDenyMac = pConfig->num_deny_mac;
884 	sap_sort_mac_list(pSapCtx->denyMacList, pSapCtx->nDenyMac);
885 	/* Fill in the event structure for FSM */
886 	sapEvent.event = eSAP_HDD_START_INFRA_BSS;
887 	sapEvent.params = 0;    /* pSapPhysLinkCreate */
888 
889 	/* Store the HDD callback in SAP context */
890 	pSapCtx->pfnSapEventCallback = pSapEventCallback;
891 
892 	/* Handle event */
893 	qdf_status = sap_fsm(pSapCtx, &sapEvent);
894 
895 	return qdf_status;
896 } /* wlansap_start_bss */
897 
898 /**
899  * wlansap_set_mac_acl() - set MAC list entry in ACL.
900  * @pCtx: Pointer to the global cds context; a handle to SAP's control block
901  *        can be extracted from its context. When MBSSID feature is enabled,
902  *        SAP context is directly passed to SAP APIs.
903  * @pConfig: Pointer to SAP config.
904  *
905  * This api function provides SAP to set mac list entry in accept list as well
906  * as deny list
907  *
908  * Return: The result code associated with performing the operation
909  *         QDF_STATUS_E_FAULT: Pointer to SAP cb is NULL;
910  *                             access would cause a page fault
911  *         QDF_STATUS_SUCCESS: Success
912  */
913 QDF_STATUS wlansap_set_mac_acl(void *pCtx,    /* pwextCtx */
914 			       tsap_Config_t *pConfig) {
915 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
916 	ptSapContext pSapCtx = NULL;
917 
918 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
919 		  "wlansap_set_mac_acl");
920 
921 	pSapCtx = CDS_GET_SAP_CB(pCtx);
922 	if (NULL == pSapCtx) {
923 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
924 			  "%s: Invalid SAP pointer from pCtx",
925 			  __func__);
926 		return QDF_STATUS_E_FAULT;
927 	}
928 	/* Copy MAC filtering settings to sap context */
929 	pSapCtx->eSapMacAddrAclMode = pConfig->SapMacaddr_acl;
930 
931 	if (eSAP_DENY_UNLESS_ACCEPTED == pSapCtx->eSapMacAddrAclMode) {
932 		qdf_mem_copy(pSapCtx->acceptMacList,
933 			     pConfig->accept_mac,
934 			     sizeof(pConfig->accept_mac));
935 		pSapCtx->nAcceptMac = pConfig->num_accept_mac;
936 		sap_sort_mac_list(pSapCtx->acceptMacList,
937 			       pSapCtx->nAcceptMac);
938 	} else if (eSAP_ACCEPT_UNLESS_DENIED ==
939 		   pSapCtx->eSapMacAddrAclMode) {
940 		qdf_mem_copy(pSapCtx->denyMacList, pConfig->deny_mac,
941 			     sizeof(pConfig->deny_mac));
942 		pSapCtx->nDenyMac = pConfig->num_deny_mac;
943 		sap_sort_mac_list(pSapCtx->denyMacList, pSapCtx->nDenyMac);
944 	}
945 
946 	return qdf_status;
947 } /* wlansap_set_mac_acl */
948 
949 /**
950  * wlansap_stop_bss() - stop BSS.
951  * @pCtx: Pointer to the global cds context; a handle to SAP's control block
952  *        can be extracted from its context. When MBSSID feature is enabled,
953  *        SAP context is directly passed to SAP APIs.
954  *
955  * This api function provides SAP FSM event eSAP_HDD_STOP_INFRA_BSS for
956  * stopping AP BSS
957  *
958  * Return: The result code associated with performing the operation
959  *         QDF_STATUS_E_FAULT: Pointer to SAP cb is NULL;
960  *                             access would cause a page fault
961  *         QDF_STATUS_SUCCESS: Success
962  */
963 QDF_STATUS wlansap_stop_bss(void *pCtx)
964 {
965 	tWLAN_SAPEvent sapEvent;        /* State machine event */
966 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
967 	ptSapContext pSapCtx = NULL;
968 	/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
969 
970 	/*------------------------------------------------------------------------
971 	    Sanity check
972 	    Extract SAP control block
973 	   ------------------------------------------------------------------------*/
974 	if (NULL == pCtx) {
975 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
976 			  "%s: Invalid Global CDS handle", __func__);
977 		return QDF_STATUS_E_FAULT;
978 	}
979 
980 	pSapCtx = CDS_GET_SAP_CB(pCtx);
981 
982 	if (NULL == pSapCtx) {
983 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
984 			  "%s: Invalid SAP pointer from pCtx", __func__);
985 		return QDF_STATUS_E_FAULT;
986 	}
987 
988 	/* Fill in the event structure for FSM */
989 	sapEvent.event = eSAP_HDD_STOP_INFRA_BSS;
990 	sapEvent.params = 0;
991 
992 	/* Handle event */
993 	qdf_status = sap_fsm(pSapCtx, &sapEvent);
994 
995 	return qdf_status;
996 }
997 
998 /**
999  * wlansap_get_assoc_stations() - get list of associated stations.
1000  * @pCtx: Pointer to the global cds context; a handle to SAP's control block
1001  *        can be extracted from its context. When MBSSID feature is enabled,
1002  *        SAP context is directly passed to SAP APIs.
1003  * @modId: Module from whom list of associtated stations  is supposed to be
1004  *         probed. If an invalid module is passed then by default
1005  *         QDF_MODULE_ID_PE will be probed
1006  * @pAssocStas: Pointer to list of associated stations that are known to the
1007  *              module specified in mod parameter
1008  *
1009  * This api function is used to probe the list of associated stations from
1010  * various modules of CORE stack
1011  * NOTE: The memory for this list will be allocated by the caller of this API
1012  *
1013  * Return: The result code associated with performing the operation
1014  *         QDF_STATUS_SUCCESS: Success
1015  */
1016 QDF_STATUS
1017 wlansap_get_assoc_stations
1018 	(void *pCtx, QDF_MODULE_ID modId, tpSap_AssocMacAddr pAssocStas) {
1019 	ptSapContext pSapCtx = CDS_GET_SAP_CB(pCtx);
1020 
1021 	/*------------------------------------------------------------------------
1022 	   Sanity check
1023 	   Extract SAP control block
1024 	   ------------------------------------------------------------------------*/
1025 	if (NULL == pSapCtx) {
1026 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1027 			  "%s: Invalid SAP pointer from pCtx", __func__);
1028 		return QDF_STATUS_E_FAULT;
1029 	}
1030 
1031 	sme_roam_get_associated_stas(CDS_GET_HAL_CB(pSapCtx->p_cds_gctx),
1032 				     pSapCtx->sessionId, modId,
1033 				     pSapCtx->pUsrContext,
1034 				     (void **) pSapCtx->pfnSapEventCallback,
1035 				     (uint8_t *) pAssocStas);
1036 
1037 	return QDF_STATUS_SUCCESS;
1038 }
1039 
1040 /**
1041  * wlansap_remove_wps_session_overlap() - remove overlapping wps session.
1042  * @pCtx: Pointer to the global cds context; a handle to SAP's control block
1043  *        can be extracted from its context. When MBSSID feature is enabled,
1044  *        SAP context is directly passed to SAP APIs.
1045  * @pRemoveMac: pointer to struct qdf_mac_addr for session MAC address
1046  *
1047  * This api function provides for Ap App/HDD to remove an entry from session
1048  * overlap info.
1049  *
1050  * Return: The QDF_STATUS code associated with performing the operation
1051  *         QDF_STATUS_SUCCESS:  Success
1052  *         QDF_STATUS_E_FAULT:  Session is not dectected.
1053  *                              The parameter is function not valid.
1054  */
1055 QDF_STATUS
1056 wlansap_remove_wps_session_overlap(void *pCtx,
1057 				   struct qdf_mac_addr pRemoveMac)
1058 {
1059 	ptSapContext pSapCtx = CDS_GET_SAP_CB(pCtx);
1060 
1061 	/*------------------------------------------------------------------------
1062 	   Sanity check
1063 	   Extract SAP control block
1064 	   ------------------------------------------------------------------------*/
1065 	if (NULL == pSapCtx) {
1066 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1067 			  "%s: Invalid SAP pointer from pCtx", __func__);
1068 		return QDF_STATUS_E_FAULT;
1069 	}
1070 
1071 	sme_roam_get_wps_session_overlap(CDS_GET_HAL_CB(pSapCtx->p_cds_gctx),
1072 					 pSapCtx->sessionId, pSapCtx->pUsrContext,
1073 					 (void **) pSapCtx->pfnSapEventCallback,
1074 					 pRemoveMac);
1075 
1076 	return QDF_STATUS_SUCCESS;
1077 }
1078 
1079 /**
1080  * wlansap_get_wps_session_overlap() - get overlapping wps session.
1081  * @pCtx: Pointer to the global cds context; a handle to SAP's control block
1082  *        can be extracted from its context. When MBSSID feature is enabled,
1083  *        SAP context is directly passed to SAP APIs.
1084  *
1085  * This api function provides for Ap App/HDD to get WPS session overlap info.
1086  *
1087  * Return: The QDF_STATUS code associated with performing the operation
1088  *         QDF_STATUS_SUCCESS:  Success
1089  */
1090 QDF_STATUS wlansap_get_wps_session_overlap(void *pCtx)
1091 {
1092 	struct qdf_mac_addr pRemoveMac = QDF_MAC_ADDR_ZERO_INITIALIZER;
1093 
1094 	ptSapContext pSapCtx = CDS_GET_SAP_CB(pCtx);
1095 
1096 	/*------------------------------------------------------------------------
1097 	   Sanity check
1098 	   Extract SAP control block
1099 	   ------------------------------------------------------------------------*/
1100 	if (NULL == pSapCtx) {
1101 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1102 			  "%s: Invalid SAP pointer from pCtx", __func__);
1103 		return QDF_STATUS_E_FAULT;
1104 	}
1105 
1106 	sme_roam_get_wps_session_overlap(CDS_GET_HAL_CB(pSapCtx->p_cds_gctx),
1107 					 pSapCtx->sessionId, pSapCtx->pUsrContext,
1108 					 (void **) pSapCtx->pfnSapEventCallback,
1109 					 pRemoveMac);
1110 
1111 	return QDF_STATUS_SUCCESS;
1112 }
1113 
1114 /* This routine will set the mode of operation for ACL dynamically*/
1115 QDF_STATUS wlansap_set_mode(void *pCtx, uint32_t mode)
1116 {
1117 	ptSapContext pSapCtx = CDS_GET_SAP_CB(pCtx);
1118 
1119 	if (NULL == pSapCtx) {
1120 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1121 			  "%s: Invalid SAP pointer from pCtx", __func__);
1122 		return QDF_STATUS_E_FAULT;
1123 	}
1124 
1125 	pSapCtx->eSapMacAddrAclMode = (eSapMacAddrACL) mode;
1126 	return QDF_STATUS_SUCCESS;
1127 }
1128 
1129 /* Get ACL Mode */
1130 QDF_STATUS wlansap_get_acl_mode(void *pCtx, eSapMacAddrACL *mode)
1131 {
1132 	ptSapContext pSapCtx = CDS_GET_SAP_CB(pCtx);
1133 
1134 	if (NULL == pSapCtx) {
1135 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1136 			  "%s: Invalid SAP pointer from pCtx", __func__);
1137 		return QDF_STATUS_E_FAULT;
1138 	}
1139 
1140 	*mode = pSapCtx->eSapMacAddrAclMode;
1141 	return QDF_STATUS_SUCCESS;
1142 }
1143 
1144 /* API to get ACL Accept List */
1145 QDF_STATUS
1146 wlansap_get_acl_accept_list(void *pCtx, struct qdf_mac_addr *pAcceptList,
1147 				uint8_t *nAcceptList)
1148 {
1149 	ptSapContext pSapCtx = CDS_GET_SAP_CB(pCtx);
1150 	if (NULL == pSapCtx) {
1151 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1152 			  "%s: Invalid SAP pointer from p_cds_gctx", __func__);
1153 		return QDF_STATUS_E_FAULT;
1154 	}
1155 
1156 	memcpy((void *)pAcceptList, (void *)pSapCtx->acceptMacList,
1157 	       (pSapCtx->nAcceptMac * QDF_MAC_ADDR_SIZE));
1158 	*nAcceptList = pSapCtx->nAcceptMac;
1159 	return QDF_STATUS_SUCCESS;
1160 }
1161 
1162 /* API to get Deny List */
1163 QDF_STATUS
1164 wlansap_get_acl_deny_list(void *pCtx, struct qdf_mac_addr *pDenyList,
1165 			  uint8_t *nDenyList)
1166 {
1167 	ptSapContext pSapCtx = CDS_GET_SAP_CB(pCtx);
1168 	if (NULL == pSapCtx) {
1169 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1170 			  "%s: Invalid SAP pointer from p_cds_gctx", __func__);
1171 		return QDF_STATUS_E_FAULT;
1172 	}
1173 
1174 	memcpy((void *)pDenyList, (void *)pSapCtx->denyMacList,
1175 	       (pSapCtx->nDenyMac * QDF_MAC_ADDR_SIZE));
1176 	*nDenyList = pSapCtx->nDenyMac;
1177 	return QDF_STATUS_SUCCESS;
1178 }
1179 
1180 /* This routine will clear all the entries in accept list as well as deny list  */
1181 
1182 QDF_STATUS wlansap_clear_acl(void *pCtx)
1183 {
1184 	ptSapContext pSapCtx = CDS_GET_SAP_CB(pCtx);
1185 	uint8_t i;
1186 
1187 	if (NULL == pSapCtx) {
1188 		return QDF_STATUS_E_RESOURCES;
1189 	}
1190 
1191 	if (pSapCtx->denyMacList != NULL) {
1192 		for (i = 0; i < (pSapCtx->nDenyMac - 1); i++) {
1193 			qdf_mem_zero((pSapCtx->denyMacList + i)->bytes,
1194 				     QDF_MAC_ADDR_SIZE);
1195 
1196 		}
1197 	}
1198 	sap_print_acl(pSapCtx->denyMacList, pSapCtx->nDenyMac);
1199 	pSapCtx->nDenyMac = 0;
1200 
1201 	if (pSapCtx->acceptMacList != NULL) {
1202 		for (i = 0; i < (pSapCtx->nAcceptMac - 1); i++) {
1203 			qdf_mem_zero((pSapCtx->acceptMacList + i)->bytes,
1204 				     QDF_MAC_ADDR_SIZE);
1205 
1206 		}
1207 	}
1208 	sap_print_acl(pSapCtx->acceptMacList, pSapCtx->nAcceptMac);
1209 	pSapCtx->nAcceptMac = 0;
1210 
1211 	return QDF_STATUS_SUCCESS;
1212 }
1213 
1214 /*
1215  * wlansap_modify_acl() -Update ACL entries
1216  *
1217  * @ctx: Global context
1218  * @peer_sta_mac: peer sta mac to be updated.
1219  * @list_type: white/Black list type.
1220  * @cmd: command to be executed on ACL.
1221  *
1222  * This function is called when a peer needs to be added or deleted from the
1223  * white/black ACL
1224  *
1225  * Return: Status
1226  */
1227 
1228 QDF_STATUS
1229 wlansap_modify_acl
1230 	(void *ctx,
1231 	uint8_t *peer_sta_mac, eSapACLType list_type, eSapACLCmdType cmd) {
1232 	eSapBool sta_white_list = eSAP_FALSE, sta_black_list = eSAP_FALSE;
1233 	uint8_t staWLIndex, staBLIndex;
1234 	ptSapContext sap_ctx = CDS_GET_SAP_CB(ctx);
1235 
1236 	if (NULL == sap_ctx) {
1237 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1238 			  "%s: Invalid SAP Context", __func__);
1239 		return QDF_STATUS_E_FAULT;
1240 	}
1241 
1242 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1243 		  "Modify ACL entered\n" "Before modification of ACL\n"
1244 		  "size of accept and deny lists %d %d", sap_ctx->nAcceptMac,
1245 		  sap_ctx->nDenyMac);
1246 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1247 		  "*** WHITE LIST ***");
1248 	sap_print_acl(sap_ctx->acceptMacList, sap_ctx->nAcceptMac);
1249 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1250 		  "*** BLACK LIST ***");
1251 	sap_print_acl(sap_ctx->denyMacList, sap_ctx->nDenyMac);
1252 
1253 	/* the expectation is a mac addr will not be in both the lists at the same time.
1254 	   It is the responsiblity of userspace to ensure this */
1255 	sta_white_list =
1256 		sap_search_mac_list(sap_ctx->acceptMacList, sap_ctx->nAcceptMac,
1257 				 peer_sta_mac, &staWLIndex);
1258 	sta_black_list =
1259 		sap_search_mac_list(sap_ctx->denyMacList, sap_ctx->nDenyMac,
1260 				 peer_sta_mac, &staBLIndex);
1261 
1262 	if (sta_white_list && sta_black_list) {
1263 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1264 			  "Peer mac " MAC_ADDRESS_STR
1265 			  " found in white and black lists."
1266 			  "Initial lists passed incorrect. Cannot execute this command.",
1267 			  MAC_ADDR_ARRAY(peer_sta_mac));
1268 		return QDF_STATUS_E_FAILURE;
1269 
1270 	}
1271 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1272 		  "cmd %d", cmd);
1273 
1274 	switch (list_type) {
1275 	case eSAP_WHITE_LIST:
1276 		if (cmd == ADD_STA_TO_ACL) {
1277 			/* error check */
1278 			/* if list is already at max, return failure */
1279 			if (sap_ctx->nAcceptMac == MAX_ACL_MAC_ADDRESS) {
1280 				QDF_TRACE(QDF_MODULE_ID_SAP,
1281 					  QDF_TRACE_LEVEL_ERROR,
1282 					  "White list is already maxed out. Cannot accept "
1283 					  MAC_ADDRESS_STR,
1284 					  MAC_ADDR_ARRAY(peer_sta_mac));
1285 				return QDF_STATUS_E_FAILURE;
1286 			}
1287 			if (sta_white_list) {
1288 				/* Do nothing if already present in white list. Just print a warning */
1289 				QDF_TRACE(QDF_MODULE_ID_SAP,
1290 					  QDF_TRACE_LEVEL_WARN,
1291 					  "MAC address already present in white list "
1292 					  MAC_ADDRESS_STR,
1293 					  MAC_ADDR_ARRAY(peer_sta_mac));
1294 				return QDF_STATUS_SUCCESS;
1295 			}
1296 			if (sta_black_list) {
1297 				/* remove it from black list before adding to the white list */
1298 				QDF_TRACE(QDF_MODULE_ID_SAP,
1299 					  QDF_TRACE_LEVEL_WARN,
1300 					  "STA present in black list so first remove from it");
1301 				sap_remove_mac_from_acl(sap_ctx->
1302 						    denyMacList,
1303 						    &sap_ctx->nDenyMac,
1304 						    staBLIndex);
1305 			}
1306 			QDF_TRACE(QDF_MODULE_ID_SAP,
1307 				  QDF_TRACE_LEVEL_INFO,
1308 				  "... Now add to the white list");
1309 			sap_add_mac_to_acl(sap_ctx->acceptMacList,
1310 					       &sap_ctx->nAcceptMac,
1311 			       peer_sta_mac);
1312 				QDF_TRACE(QDF_MODULE_ID_SAP,
1313 				  QDF_TRACE_LEVEL_INFO_LOW,
1314 				  "size of accept and deny lists %d %d",
1315 				  sap_ctx->nAcceptMac,
1316 				  sap_ctx->nDenyMac);
1317 		} else if (cmd == DELETE_STA_FROM_ACL) {
1318 			if (sta_white_list) {
1319 
1320 				struct tagCsrDelStaParams delStaParams;
1321 
1322 				QDF_TRACE(QDF_MODULE_ID_SAP,
1323 					  QDF_TRACE_LEVEL_INFO,
1324 					  "Delete from white list");
1325 				sap_remove_mac_from_acl(sap_ctx->acceptMacList,
1326 						    &sap_ctx->nAcceptMac,
1327 						    staWLIndex);
1328 				/* If a client is deleted from white list and it is connected, send deauth */
1329 				wlansap_populate_del_sta_params(peer_sta_mac,
1330 					eCsrForcedDeauthSta,
1331 					(SIR_MAC_MGMT_DEAUTH >> 4),
1332 					&delStaParams);
1333 				wlansap_deauth_sta(ctx, &delStaParams);
1334 				QDF_TRACE(QDF_MODULE_ID_SAP,
1335 					  QDF_TRACE_LEVEL_INFO_LOW,
1336 					  "size of accept and deny lists %d %d",
1337 					  sap_ctx->nAcceptMac,
1338 					  sap_ctx->nDenyMac);
1339 			} else {
1340 				QDF_TRACE(QDF_MODULE_ID_SAP,
1341 					  QDF_TRACE_LEVEL_WARN,
1342 					  "MAC address to be deleted is not present in the white list "
1343 					  MAC_ADDRESS_STR,
1344 					  MAC_ADDR_ARRAY(peer_sta_mac));
1345 				return QDF_STATUS_E_FAILURE;
1346 			}
1347 		} else {
1348 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1349 				  "Invalid cmd type passed");
1350 			return QDF_STATUS_E_FAILURE;
1351 		}
1352 		break;
1353 
1354 	case eSAP_BLACK_LIST:
1355 
1356 		if (cmd == ADD_STA_TO_ACL) {
1357 			struct tagCsrDelStaParams delStaParams;
1358 			/* error check */
1359 			/* if list is already at max, return failure */
1360 			if (sap_ctx->nDenyMac == MAX_ACL_MAC_ADDRESS) {
1361 				QDF_TRACE(QDF_MODULE_ID_SAP,
1362 					  QDF_TRACE_LEVEL_ERROR,
1363 					  "Black list is already maxed out. Cannot accept "
1364 					  MAC_ADDRESS_STR,
1365 					  MAC_ADDR_ARRAY(peer_sta_mac));
1366 				return QDF_STATUS_E_FAILURE;
1367 			}
1368 			if (sta_black_list) {
1369 				/* Do nothing if already present in white list */
1370 				QDF_TRACE(QDF_MODULE_ID_SAP,
1371 					  QDF_TRACE_LEVEL_WARN,
1372 					  "MAC address already present in black list "
1373 					  MAC_ADDRESS_STR,
1374 					  MAC_ADDR_ARRAY(peer_sta_mac));
1375 				return QDF_STATUS_SUCCESS;
1376 			}
1377 			if (sta_white_list) {
1378 				/* remove it from white list before adding to the black list */
1379 				QDF_TRACE(QDF_MODULE_ID_SAP,
1380 					  QDF_TRACE_LEVEL_WARN,
1381 					  "Present in white list so first remove from it");
1382 				sap_remove_mac_from_acl(sap_ctx->
1383 						    acceptMacList,
1384 						    &sap_ctx->
1385 						    nAcceptMac,
1386 						    staWLIndex);
1387 			}
1388 			/* If we are adding a client to the black list; if its connected, send deauth */
1389 			wlansap_populate_del_sta_params(peer_sta_mac,
1390 				eCsrForcedDeauthSta,
1391 				(SIR_MAC_MGMT_DEAUTH >> 4),
1392 				&delStaParams);
1393 			wlansap_deauth_sta(ctx, &delStaParams);
1394 			QDF_TRACE(QDF_MODULE_ID_SAP,
1395 				  QDF_TRACE_LEVEL_INFO,
1396 				  "... Now add to black list");
1397 			sap_add_mac_to_acl(sap_ctx->denyMacList,
1398 				       &sap_ctx->nDenyMac, peer_sta_mac);
1399 			QDF_TRACE(QDF_MODULE_ID_SAP,
1400 				  QDF_TRACE_LEVEL_INFO_LOW,
1401 				  "size of accept and deny lists %d %d",
1402 				  sap_ctx->nAcceptMac,
1403 				  sap_ctx->nDenyMac);
1404 		} else if (cmd == DELETE_STA_FROM_ACL) {
1405 			if (sta_black_list) {
1406 				QDF_TRACE(QDF_MODULE_ID_SAP,
1407 					  QDF_TRACE_LEVEL_INFO,
1408 					  "Delete from black list");
1409 				sap_remove_mac_from_acl(sap_ctx->denyMacList,
1410 						    &sap_ctx->nDenyMac,
1411 						    staBLIndex);
1412 				QDF_TRACE(QDF_MODULE_ID_SAP,
1413 					  QDF_TRACE_LEVEL_INFO_LOW,
1414 					  "no accept and deny mac %d %d",
1415 					  sap_ctx->nAcceptMac,
1416 					  sap_ctx->nDenyMac);
1417 			} else {
1418 				QDF_TRACE(QDF_MODULE_ID_SAP,
1419 					  QDF_TRACE_LEVEL_WARN,
1420 					  "MAC address to be deleted is not present in the black list "
1421 					  MAC_ADDRESS_STR,
1422 					  MAC_ADDR_ARRAY(peer_sta_mac));
1423 				return QDF_STATUS_E_FAILURE;
1424 			}
1425 		} else {
1426 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1427 				  "Invalid cmd type passed");
1428 			return QDF_STATUS_E_FAILURE;
1429 		}
1430 		break;
1431 
1432 	default:
1433 	{
1434 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1435 			  "Invalid list type passed %d", list_type);
1436 		return QDF_STATUS_E_FAILURE;
1437 	}
1438 	}
1439 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1440 		  "After modification of ACL");
1441 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1442 		  "*** WHITE LIST ***");
1443 	sap_print_acl(sap_ctx->acceptMacList, sap_ctx->nAcceptMac);
1444 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1445 		  "*** BLACK LIST ***");
1446 	sap_print_acl(sap_ctx->denyMacList, sap_ctx->nDenyMac);
1447 	return QDF_STATUS_SUCCESS;
1448 }
1449 
1450 /**
1451  * wlansap_disassoc_sta() - initiate disassociation of station.
1452  * @pCtx: Pointer to the global cds context; a handle to SAP's control block
1453  *        can be extracted from its context. When MBSSID feature is enabled,
1454  *        SAP context is directly passed to SAP APIs.
1455  * @pPeerStaMac: Mac address of the station to disassociate
1456  *
1457  * This api function provides for Ap App/HDD initiated disassociation of station
1458  *
1459  * Return: The QDF_STATUS code associated with performing the operation
1460  *         QDF_STATUS_SUCCESS:  Success
1461  */
1462 QDF_STATUS wlansap_disassoc_sta(void *pCtx, const uint8_t *pPeerStaMac)
1463 {
1464 	ptSapContext pSapCtx = CDS_GET_SAP_CB(pCtx);
1465 
1466 	/*------------------------------------------------------------------------
1467 	   Sanity check
1468 	   Extract SAP control block
1469 	   ------------------------------------------------------------------------*/
1470 	if (NULL == pSapCtx) {
1471 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1472 			  "%s: Invalid SAP pointer from pCtx", __func__);
1473 		return QDF_STATUS_E_FAULT;
1474 	}
1475 
1476 	sme_roam_disconnect_sta(CDS_GET_HAL_CB(pSapCtx->p_cds_gctx),
1477 				pSapCtx->sessionId, pPeerStaMac);
1478 
1479 	return QDF_STATUS_SUCCESS;
1480 }
1481 
1482 /**
1483  * wlansap_deauth_sta() - Ap App/HDD initiated deauthentication of station
1484  * @pCtx : Pointer to the global cds context; a handle to SAP's
1485  *         control block can be extracted from its context
1486  *         When MBSSID feature is enabled, SAP context is directly
1487  *         passed to SAP APIs
1488  * @pDelStaParams : Pointer to parameters of the station to deauthenticate
1489  *
1490  * This api function provides for Ap App/HDD initiated deauthentication of
1491  * station
1492  *
1493  * Return: The QDF_STATUS code associated with performing the operation
1494  */
1495 QDF_STATUS wlansap_deauth_sta(void *pCtx,
1496 			      struct tagCsrDelStaParams *pDelStaParams)
1497 {
1498 	QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE;
1499 	QDF_STATUS qdf_status = QDF_STATUS_E_FAULT;
1500 	ptSapContext pSapCtx = CDS_GET_SAP_CB(pCtx);
1501 
1502 	/*------------------------------------------------------------------------
1503 	   Sanity check
1504 	   Extract SAP control block
1505 	   ------------------------------------------------------------------------*/
1506 	if (NULL == pSapCtx) {
1507 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1508 			  "%s: Invalid SAP pointer from pCtx", __func__);
1509 		return qdf_status;
1510 	}
1511 
1512 	qdf_ret_status =
1513 		sme_roam_deauth_sta(CDS_GET_HAL_CB(pSapCtx->p_cds_gctx),
1514 				    pSapCtx->sessionId, pDelStaParams);
1515 
1516 	if (qdf_ret_status == QDF_STATUS_SUCCESS) {
1517 		qdf_status = QDF_STATUS_SUCCESS;
1518 	}
1519 	return qdf_status;
1520 }
1521 
1522 /**
1523  * wlansap_update_bw80_cbmode() - fucntion to update channel bonding mode for
1524  *                                VHT80 channel.
1525  * @channel: target channel
1526  * @sme_config: sme configuration context
1527  *
1528  * Return: none
1529  */
1530 static inline void wlansap_update_bw80_cbmode(uint32_t channel,
1531 		tSmeConfigParams *sme_config)
1532 {
1533 	if (channel == 36 || channel == 52 || channel == 100 ||
1534 		channel == 116 || channel == 149 || channel == 132) {
1535 		sme_config->csrConfig.channelBondingMode5GHz =
1536 			eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW;
1537 	} else if (channel == 40 || channel == 56 || channel == 104 ||
1538 			channel == 120 || channel == 153 || channel == 136) {
1539 		sme_config->csrConfig.channelBondingMode5GHz =
1540 			eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW;
1541 	} else if (channel == 44 || channel == 60 || channel == 108 ||
1542 			channel == 124 || channel == 157 || channel == 140) {
1543 		sme_config->csrConfig.channelBondingMode5GHz =
1544 			eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH;
1545 	} else if (channel == 48 || channel == 64 || channel == 112 ||
1546 		channel == 128 || channel == 144 || channel == 161) {
1547 		sme_config->csrConfig.channelBondingMode5GHz =
1548 			eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH;
1549 	}
1550 }
1551 
1552 /**
1553  * wlansap_update_csa_channel_params() - fucntion to populate channel width and
1554  *                                        bonding modes.
1555  * @sap_context: sap adapter context
1556  * @channel: target channel
1557  *
1558  * Return: The QDF_STATUS code associated with performing the operation
1559  */
1560 static QDF_STATUS wlansap_update_csa_channel_params(ptSapContext sap_context,
1561 	uint32_t channel)
1562 {
1563 	void *hal;
1564 	tpAniSirGlobal mac_ctx;
1565 	uint8_t bw;
1566 
1567 	hal = CDS_GET_HAL_CB(sap_context->p_cds_gctx);
1568 	if (!hal) {
1569 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1570 			"%s: Invalid hal pointer from p_cds_gctx", __func__);
1571 		return QDF_STATUS_E_FAULT;
1572 	}
1573 
1574 	mac_ctx = PMAC_STRUCT(hal);
1575 
1576 	if (channel <= CHAN_ENUM_14) {
1577 		/*
1578 		 * currently OBSS scan is done in hostapd, so to avoid
1579 		 * SAP coming up in HT40 on channel switch we are
1580 		 * disabling channel bonding in 2.4Ghz.
1581 		 */
1582 		mac_ctx->sap.SapDfsInfo.new_chanWidth = 0;
1583 
1584 	} else {
1585 
1586 		if (sap_context->ch_width_orig >= CH_WIDTH_80MHZ)
1587 			bw = BW80;
1588 		else if (sap_context->ch_width_orig == CH_WIDTH_40MHZ)
1589 			bw = BW40_HIGH_PRIMARY;
1590 		else
1591 			bw = BW20;
1592 
1593 		for (; bw >= BW20; bw--) {
1594 			uint16_t op_class;
1595 
1596 			op_class = cds_reg_dmn_get_opclass_from_channel(
1597 					mac_ctx->scan.countryCodeCurrent,
1598 					channel, bw);
1599 			if (!op_class)
1600 				continue;
1601 
1602 			if (bw == BW80) {
1603 				mac_ctx->sap.SapDfsInfo.new_chanWidth =
1604 					CH_WIDTH_80MHZ;
1605 			} else if (bw == BW40_HIGH_PRIMARY) {
1606 				mac_ctx->sap.SapDfsInfo.new_chanWidth =
1607 					CH_WIDTH_40MHZ;
1608 			} else if (bw == BW40_LOW_PRIMARY) {
1609 				mac_ctx->sap.SapDfsInfo.new_chanWidth =
1610 				   CH_WIDTH_40MHZ;
1611 			} else {
1612 				mac_ctx->sap.SapDfsInfo.new_chanWidth =
1613 				   CH_WIDTH_20MHZ;
1614 			}
1615 			break;
1616 		}
1617 
1618 	}
1619 
1620 	return QDF_STATUS_SUCCESS;
1621 }
1622 
1623 /**
1624  * wlansap_set_channel_change_with_csa() - Set channel change with CSA
1625  * @p_cds_gctx: Pointer to cds global context structure
1626  * @targetChannel: Target channel
1627  * @target_bw: Target bandwidth
1628  *
1629  * This api function does a channel change to the target channel specified.
1630  * CSA IE is included in the beacons before doing a channel change.
1631  *
1632  * Return: QDF_STATUS
1633  */
1634 QDF_STATUS
1635 wlansap_set_channel_change_with_csa(void *p_cds_gctx, uint32_t targetChannel,
1636 					enum phy_ch_width target_bw)
1637 {
1638 
1639 	ptSapContext sapContext = NULL;
1640 	tWLAN_SAPEvent sapEvent;
1641 	tpAniSirGlobal pMac = NULL;
1642 	void *hHal = NULL;
1643 	bool valid;
1644 	QDF_STATUS status;
1645 
1646 	sapContext = CDS_GET_SAP_CB(p_cds_gctx);
1647 	if (NULL == sapContext) {
1648 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1649 			  "%s: Invalid SAP pointer from p_cds_gctx", __func__);
1650 
1651 		return QDF_STATUS_E_FAULT;
1652 	}
1653 
1654 	hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx);
1655 	if (NULL == hHal) {
1656 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1657 			  "%s: Invalid HAL pointer from p_cds_gctx", __func__);
1658 		return QDF_STATUS_E_FAULT;
1659 	}
1660 	pMac = PMAC_STRUCT(hHal);
1661 
1662 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
1663 		"%s: sap chan:%d target:%d conc:%d",
1664 		__func__, sapContext->channel, targetChannel,
1665 		cds_concurrent_open_sessions_running());
1666 
1667 	/*
1668 	 * Now, validate if the passed channel is valid in the
1669 	 * current regulatory domain.
1670 	 */
1671 	if (sapContext->channel != targetChannel &&
1672 		((cds_get_channel_state(targetChannel) ==
1673 			CHANNEL_STATE_ENABLE) ||
1674 		(cds_get_channel_state(targetChannel) ==
1675 			CHANNEL_STATE_DFS &&
1676 		!cds_concurrent_open_sessions_running()))) {
1677 		/*
1678 		 * validate target channel switch w.r.t various concurrency
1679 		 * rules set.
1680 		 */
1681 		valid = wlan_sap_validate_channel_switch(hHal, targetChannel,
1682 				sapContext);
1683 		if (!valid) {
1684 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1685 					FL("Channel switch to %u is not allowed due to concurrent channel interference"),
1686 					targetChannel);
1687 			return QDF_STATUS_E_FAULT;
1688 		}
1689 		/*
1690 		 * Post a CSA IE request to SAP state machine with
1691 		 * target channel information and also CSA IE required
1692 		 * flag set in sapContext only, if SAP is in eSAP_STARTED
1693 		 * state.
1694 		 */
1695 		if (eSAP_STARTED == sapContext->sapsMachine) {
1696 			status = wlansap_update_csa_channel_params(sapContext,
1697 					targetChannel);
1698 			if (status != QDF_STATUS_SUCCESS)
1699 				return status;
1700 
1701 			/*
1702 			 * Copy the requested target channel
1703 			 * to sap context.
1704 			 */
1705 			pMac->sap.SapDfsInfo.target_channel = targetChannel;
1706 			pMac->sap.SapDfsInfo.new_ch_params.ch_width =
1707 				pMac->sap.SapDfsInfo.new_chanWidth;
1708 
1709 			/* By this time, the best bandwidth is calculated for
1710 			 * the given target channel. Now, if there was a
1711 			 * request from user to move to a selected bandwidth,
1712 			 * we can see if it can be honored.
1713 			 *
1714 			 * Ex1: BW80 was selected for the target channel and
1715 			 * user wants BW40, it can be allowed
1716 			 * Ex2: BW40 was selected for the target channel and
1717 			 * user wants BW80, it cannot be allowed for the given
1718 			 * target channel.
1719 			 *
1720 			 * So, the MIN of the selected channel bandwidth and
1721 			 * user input is used for the bandwidth
1722 			 */
1723 			if (target_bw != CH_WIDTH_MAX) {
1724 				QDF_TRACE(QDF_MODULE_ID_SAP,
1725 					QDF_TRACE_LEVEL_INFO,
1726 					"%s: target bw:%d new width:%d",
1727 					__func__, target_bw,
1728 					pMac->sap.SapDfsInfo.
1729 					new_ch_params.ch_width);
1730 				pMac->sap.SapDfsInfo.new_ch_params.ch_width =
1731 					pMac->sap.SapDfsInfo.new_chanWidth =
1732 					QDF_MIN(pMac->sap.SapDfsInfo.
1733 							new_ch_params.ch_width,
1734 							target_bw);
1735 			}
1736 			cds_set_channel_params(targetChannel,
1737 				0, &pMac->sap.SapDfsInfo.new_ch_params);
1738 			/*
1739 			 * Set the CSA IE required flag.
1740 			 */
1741 			pMac->sap.SapDfsInfo.csaIERequired = true;
1742 
1743 			/*
1744 			 * Set the radar found status to allow the channel
1745 			 * change to happen same as in the case of a radar
1746 			 * detection. Since, this will allow SAP to be in
1747 			 * correct state and also resume the netif queues
1748 			 * that were suspended in HDD before the channel
1749 			 * request was issued.
1750 			 */
1751 			pMac->sap.SapDfsInfo.sap_radar_found_status = true;
1752 			pMac->sap.SapDfsInfo.cac_state =
1753 					eSAP_DFS_DO_NOT_SKIP_CAC;
1754 			sap_cac_reset_notify(hHal);
1755 
1756 			/*
1757 			 * Post the eSAP_CHANNEL_SWITCH_ANNOUNCEMENT_START
1758 			 * to SAP state machine to process the channel
1759 			 * request with CSA IE set in the beacons.
1760 			 */
1761 			sapEvent.event =
1762 				eSAP_CHANNEL_SWITCH_ANNOUNCEMENT_START;
1763 			sapEvent.params = 0;
1764 			sapEvent.u1 = 0;
1765 			sapEvent.u2 = 0;
1766 
1767 			sap_fsm(sapContext, &sapEvent);
1768 
1769 		} else {
1770 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1771 				  "%s: Failed to request Channel Change, since"
1772 				  "SAP is not in eSAP_STARTED state", __func__);
1773 			return QDF_STATUS_E_FAULT;
1774 		}
1775 
1776 	} else {
1777 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1778 			  "%s: Channel = %d is not valid in the current"
1779 			  "regulatory domain", __func__, targetChannel);
1780 
1781 		return QDF_STATUS_E_FAULT;
1782 	}
1783 
1784 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1785 		  "%s: Posted eSAP_CHANNEL_SWITCH_ANNOUNCEMENT_START successfully to sap_fsm for Channel = %d",
1786 		  __func__, targetChannel);
1787 
1788 	return QDF_STATUS_SUCCESS;
1789 }
1790 
1791 /**
1792  * wlansap_set_counter_measure() - set counter measure.
1793  * @pCtx: Pointer to the global cds context; a handle to SAP's control block
1794  *        can be extracted from its context. When MBSSID feature is enabled,
1795  *        SAP context is directly passed to SAP APIs.
1796  * @bEnable: If true than all stations will be disassociated and no more
1797  *           will be allowed to associate. If false than CORE will come out
1798  *            of this state.
1799  *
1800  * This api function is used to disassociate all the stations and prevent
1801  * association for any other station.Whenever Authenticator receives 2 mic
1802  * failures within 60 seconds, Authenticator will enable counter measure at
1803  * SAP Layer. Authenticator will start the 60 seconds timer. Core stack will
1804  * not allow any STA to associate till HDD disables counter meassure. Core
1805  * stack shall kick out all the STA which are currently associated and DIASSOC
1806  * Event will be propogated to HDD for each STA to clean up the HDD STA table.
1807  * Once the 60 seconds timer expires, Authenticator will disable the counter
1808  * meassure at core stack. Now core stack can allow STAs to associate.
1809  *
1810  * Return: The QDF_STATUS code associated with performing the operation
1811  *         QDF_STATUS_SUCCESS:  Success
1812  */
1813 QDF_STATUS wlansap_set_counter_measure(void *pCtx, bool bEnable)
1814 {
1815 	ptSapContext pSapCtx = CDS_GET_SAP_CB(pCtx);
1816 
1817 	/*------------------------------------------------------------------------
1818 	   Sanity check
1819 	   Extract SAP control block
1820 	   ------------------------------------------------------------------------*/
1821 	if (NULL == pSapCtx) {
1822 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1823 			  "%s: Invalid SAP pointer from pCtx", __func__);
1824 		return QDF_STATUS_E_FAULT;
1825 	}
1826 
1827 	sme_roam_tkip_counter_measures(CDS_GET_HAL_CB(pSapCtx->p_cds_gctx),
1828 				       pSapCtx->sessionId, bEnable);
1829 
1830 	return QDF_STATUS_SUCCESS;
1831 }
1832 
1833 /**
1834  * wlansap_set_key_sta() - set keys for a stations.
1835  * @pCtx: Pointer to the global cds context; a handle to SAP's control block
1836  *        can be extracted from its context. When MBSSID feature is enabled,
1837  *        SAP context is directly passed to SAP APIs.
1838  * @pSetKeyInfo : tCsrRoamSetKey structure for the station
1839  *
1840  * This api function provides for Ap App/HDD to set key for a station.
1841  *
1842  * Return: The QDF_STATUS code associated with performing the operation
1843  *         QDF_STATUS_SUCCESS:  Success
1844  */
1845 QDF_STATUS wlansap_set_key_sta(void *pCtx, tCsrRoamSetKey *pSetKeyInfo)
1846 {
1847 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
1848 	ptSapContext pSapCtx = NULL;
1849 	void *hHal = NULL;
1850 	QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE;
1851 	uint32_t roamId = 0xFF;
1852 
1853 	pSapCtx = CDS_GET_SAP_CB(pCtx);
1854 	if (NULL == pSapCtx) {
1855 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1856 			  "%s: Invalid SAP pointer from pCtx",
1857 			  __func__);
1858 		return QDF_STATUS_E_FAULT;
1859 	}
1860 	hHal = CDS_GET_HAL_CB(pSapCtx->p_cds_gctx);
1861 	if (NULL == hHal) {
1862 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1863 			  "%s: Invalid HAL pointer from p_cds_gctx",
1864 			  __func__);
1865 		return QDF_STATUS_E_FAULT;
1866 	}
1867 	qdf_ret_status =
1868 		sme_roam_set_key(hHal, pSapCtx->sessionId, pSetKeyInfo,
1869 				 &roamId);
1870 
1871 	if (qdf_ret_status == QDF_STATUS_SUCCESS)
1872 		qdf_status = QDF_STATUS_SUCCESS;
1873 	else
1874 		qdf_status = QDF_STATUS_E_FAULT;
1875 
1876 	return qdf_status;
1877 }
1878 
1879 /**
1880  * wlan_sap_getstation_ie_information() - RSNIE Population
1881  *
1882  * @ctx: Global context
1883  * @len: Length of @buf
1884  * @buf: RSNIE IE data
1885  *
1886  *  Populate RSN IE from CSR to HDD context
1887  *
1888  * Return: QDF_STATUS enumeration
1889  */
1890 
1891 QDF_STATUS
1892 wlan_sap_getstation_ie_information
1893 	(void *ctx, uint32_t *len, uint8_t *buf) {
1894 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
1895 	ptSapContext sap_ctx = NULL;
1896 	uint32_t ie_len = 0;
1897 
1898 	sap_ctx = CDS_GET_SAP_CB(ctx);
1899 	if (NULL == sap_ctx) {
1900 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1901 			FL("Invalid SAP pointer from pCtx"));
1902 		return QDF_STATUS_E_FAULT;
1903 	}
1904 
1905 	if (len) {
1906 		ie_len = *len;
1907 		*len = sap_ctx->nStaWPARSnReqIeLength;
1908 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
1909 			FL("WPAIE len : %x"), *len);
1910 		if ((buf) && (ie_len >= sap_ctx->nStaWPARSnReqIeLength)) {
1911 			qdf_mem_copy(buf,
1912 				sap_ctx->pStaWpaRsnReqIE,
1913 				sap_ctx->nStaWPARSnReqIeLength);
1914 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
1915 				FL("WPAIE: %02x:%02x:%02x:%02x:%02x:%02x"),
1916 				buf[0], buf[1], buf[2], buf[3], buf[4],
1917 				buf[5]);
1918 			qdf_status = QDF_STATUS_SUCCESS;
1919 		}
1920 	}
1921 	return qdf_status;
1922 }
1923 
1924 /**
1925  * wlansap_set_wps_ie() - set WPI IE
1926  * @pCtx: Pointer to the global cds context; a handle to SAP's control block
1927  *        can be extracted from its context. When MBSSID feature is enabled,
1928  *        SAP context is directly passed to SAP APIs.
1929  * @pWPSIE: tSap_WPSIE structure that include WPS IEs
1930  *
1931  * This api function provides API for App/HDD to set WPS IE.
1932  *
1933  * Return: The QDF_STATUS code associated with performing the operation
1934  *         QDF_STATUS_SUCCESS:  Success and error code otherwise.
1935  */
1936 QDF_STATUS wlansap_set_wps_ie(void *pCtx, tSap_WPSIE *pSap_WPSIe)
1937 {
1938 	ptSapContext pSapCtx = NULL;
1939 	void *hHal = NULL;
1940 
1941 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
1942 		  "%s, %d", __func__, __LINE__);
1943 
1944 	pSapCtx = CDS_GET_SAP_CB(pCtx);
1945 	if (NULL == pSapCtx) {
1946 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1947 			  "%s: Invalid SAP pointer from pCtx",
1948 			  __func__);
1949 		return QDF_STATUS_E_FAULT;
1950 	}
1951 
1952 	hHal = CDS_GET_HAL_CB(pSapCtx->p_cds_gctx);
1953 	if (NULL == hHal) {
1954 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1955 			  "%s: Invalid HAL pointer from p_cds_gctx",
1956 			  __func__);
1957 		return QDF_STATUS_E_FAULT;
1958 	}
1959 
1960 	if (sap_acquire_global_lock(pSapCtx) == QDF_STATUS_SUCCESS) {
1961 		if (pSap_WPSIe->sapWPSIECode == eSAP_WPS_BEACON_IE) {
1962 			qdf_mem_copy(&pSapCtx->APWPSIEs.SirWPSBeaconIE,
1963 				     &pSap_WPSIe->sapwpsie.
1964 				     sapWPSBeaconIE,
1965 				     sizeof(tSap_WPSBeaconIE));
1966 		} else if (pSap_WPSIe->sapWPSIECode ==
1967 			   eSAP_WPS_PROBE_RSP_IE) {
1968 			qdf_mem_copy(&pSapCtx->APWPSIEs.
1969 				     SirWPSProbeRspIE,
1970 				     &pSap_WPSIe->sapwpsie.
1971 				     sapWPSProbeRspIE,
1972 				     sizeof(tSap_WPSProbeRspIE));
1973 		} else {
1974 			sap_release_global_lock(pSapCtx);
1975 			return QDF_STATUS_E_FAULT;
1976 		}
1977 		sap_release_global_lock(pSapCtx);
1978 		return QDF_STATUS_SUCCESS;
1979 	} else
1980 		return QDF_STATUS_E_FAULT;
1981 }
1982 
1983 /**
1984  * wlansap_update_wps_ie() - update WPI IE
1985  * @pCtx: Pointer to the global cds context; a handle to SAP's control block
1986  *        can be extracted from its context. When MBSSID feature is enabled,
1987  *        SAP context is directly passed to SAP APIs.
1988  *
1989  * This api function provides API for App/HDD to update WPS IE.
1990  *
1991  * Return: The QDF_STATUS code associated with performing the operation
1992  *         QDF_STATUS_SUCCESS:  Success and error code otherwise.
1993  */
1994 QDF_STATUS wlansap_update_wps_ie(void *pCtx)
1995 {
1996 	QDF_STATUS qdf_status = QDF_STATUS_E_FAULT;
1997 	ptSapContext pSapCtx = NULL;
1998 	QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE;
1999 	void *hHal = NULL;
2000 
2001 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2002 		  "%s, %d", __func__, __LINE__);
2003 
2004 	pSapCtx = CDS_GET_SAP_CB(pCtx);
2005 	if (NULL == pSapCtx) {
2006 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2007 			  "%s: Invalid SAP pointer from pCtx",
2008 			  __func__);
2009 		return QDF_STATUS_E_FAULT;
2010 	}
2011 
2012 	hHal = CDS_GET_HAL_CB(pSapCtx->p_cds_gctx);
2013 	if (NULL == hHal) {
2014 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2015 			  "%s: Invalid HAL pointer from p_cds_gctx",
2016 			  __func__);
2017 		return QDF_STATUS_E_FAULT;
2018 	}
2019 
2020 	qdf_ret_status =
2021 		sme_roam_update_apwpsie(hHal, pSapCtx->sessionId,
2022 					&pSapCtx->APWPSIEs);
2023 
2024 	if (qdf_ret_status == QDF_STATUS_SUCCESS)
2025 		qdf_status = QDF_STATUS_SUCCESS;
2026 	else
2027 		qdf_status = QDF_STATUS_E_FAULT;
2028 
2029 	return qdf_status;
2030 }
2031 
2032 /**
2033  * wlansap_get_wps_state() - get WPS session state
2034  * @pCtx: Pointer to the global cds context; a handle to SAP's control block
2035  *        can be extracted from its context. When MBSSID feature is enabled,
2036  *        SAP context is directly passed to SAP APIs.
2037  * @pbWPSState: Pointer to variable to indicate if device is in
2038  *              WPS Registration state
2039  *
2040  * This api function provides for Ap App/HDD to check if WPS session in process.
2041  *
2042  * Return: The QDF_STATUS code associated with performing the operation
2043  *         QDF_STATUS_SUCCESS:  Success
2044  */
2045 QDF_STATUS wlansap_get_wps_state(void *pCtx, bool *bWPSState)
2046 {
2047 	ptSapContext pSapCtx = NULL;
2048 	void *hHal = NULL;
2049 
2050 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
2051 		  "%s, %d", __func__, __LINE__);
2052 
2053 	pSapCtx = CDS_GET_SAP_CB(pCtx);
2054 	if (NULL == pSapCtx) {
2055 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2056 			  "%s: Invalid SAP pointer from pCtx",
2057 			  __func__);
2058 		return QDF_STATUS_E_FAULT;
2059 	}
2060 
2061 	hHal = CDS_GET_HAL_CB(pSapCtx->p_cds_gctx);
2062 	if (NULL == hHal) {
2063 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2064 			  "%s: Invalid HAL pointer from p_cds_gctx",
2065 			  __func__);
2066 		return QDF_STATUS_E_FAULT;
2067 	}
2068 
2069 	if (sap_acquire_global_lock(pSapCtx) == QDF_STATUS_SUCCESS) {
2070 		if (pSapCtx->APWPSIEs.SirWPSProbeRspIE.
2071 		    FieldPresent &
2072 		    SIR_WPS_PROBRSP_SELECTEDREGISTRA_PRESENT)
2073 			*bWPSState = true;
2074 		else
2075 			*bWPSState = false;
2076 
2077 		sap_release_global_lock(pSapCtx);
2078 
2079 		return QDF_STATUS_SUCCESS;
2080 	} else
2081 		return QDF_STATUS_E_FAULT;
2082 
2083 }
2084 
2085 QDF_STATUS sap_acquire_global_lock(ptSapContext pSapCtx)
2086 {
2087 	QDF_STATUS qdf_status = QDF_STATUS_E_FAULT;
2088 
2089 	if (QDF_IS_STATUS_SUCCESS(qdf_mutex_acquire(&pSapCtx->SapGlobalLock))) {
2090 		qdf_status = QDF_STATUS_SUCCESS;
2091 	}
2092 
2093 	return qdf_status;
2094 }
2095 
2096 QDF_STATUS sap_release_global_lock(ptSapContext pSapCtx)
2097 {
2098 	QDF_STATUS qdf_status = QDF_STATUS_E_FAULT;
2099 
2100 	if (QDF_IS_STATUS_SUCCESS(qdf_mutex_release(&pSapCtx->SapGlobalLock))) {
2101 		qdf_status = QDF_STATUS_SUCCESS;
2102 	}
2103 
2104 	return qdf_status;
2105 }
2106 
2107 /**
2108  * wlansap_set_wparsn_ies() - set WPA  RSN IEs
2109  * @pCtx: Pointer to the global cds context; a handle to SAP's control block
2110  *        can be extracted from its context. When MBSSID feature is enabled,
2111  *        SAP context is directly passed to SAP APIs.
2112  * @pWPARSNIEs  : buffer to the WPA/RSN IEs
2113  * @WPARSNIEsLen: length of WPA/RSN IEs
2114  *
2115  * This api function provides for Ap App/HDD to set AP WPA and RSN IE in its
2116  * beacon and probe response.
2117  *
2118  * Return: The QDF_STATUS code associated with performing the operation
2119  *         QDF_STATUS_SUCCESS:  Success and error code otherwise
2120  */
2121 QDF_STATUS wlansap_set_wparsn_ies
2122 	(void *pCtx, uint8_t *pWPARSNIEs, uint32_t WPARSNIEsLen) {
2123 	ptSapContext pSapCtx = NULL;
2124 	QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE;
2125 	void *hHal = NULL;
2126 
2127 	pSapCtx = CDS_GET_SAP_CB(pCtx);
2128 	if (NULL == pSapCtx) {
2129 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2130 			  "%s: Invalid SAP pointer from pCtx",
2131 			  __func__);
2132 		return QDF_STATUS_E_FAULT;
2133 	}
2134 
2135 	hHal = CDS_GET_HAL_CB(pSapCtx->p_cds_gctx);
2136 	if (NULL == hHal) {
2137 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2138 			  "%s: Invalid HAL pointer from p_cds_gctx",
2139 			  __func__);
2140 		return QDF_STATUS_E_FAULT;
2141 	}
2142 
2143 	pSapCtx->APWPARSNIEs.length = (uint16_t) WPARSNIEsLen;
2144 	qdf_mem_copy(pSapCtx->APWPARSNIEs.rsnIEdata, pWPARSNIEs,
2145 		     WPARSNIEsLen);
2146 
2147 	qdf_ret_status =
2148 		sme_roam_update_apwparsni_es(hHal, pSapCtx->sessionId,
2149 					     &pSapCtx->APWPARSNIEs);
2150 
2151 	if (qdf_ret_status == QDF_STATUS_SUCCESS)
2152 		return QDF_STATUS_SUCCESS;
2153 	else
2154 		return QDF_STATUS_E_FAULT;
2155 
2156 	return QDF_STATUS_E_FAULT;
2157 }
2158 
2159 /**
2160  * wlansap_send_action() - send action frame
2161  * @pCtx: Pointer to the global cds context; a handle to SAP's control block
2162  *        can be extracted from its context. When MBSSID feature is enabled,
2163  *        SAP context is directly passed to SAP APIs.
2164  * @pBuf: Pointer of the action frame to be transmitted
2165  * @len: Length of the action frame
2166  *
2167  * This api function provides to send action frame sent by upper layer.
2168  *
2169  * Return: The QDF_STATUS code associated with performing the operation
2170 *          QDF_STATUS_SUCCESS:  Success and error code otherwise
2171  */
2172 QDF_STATUS wlansap_send_action(void *pCtx, const uint8_t *pBuf,
2173 	uint32_t len, uint16_t wait, uint16_t channel_freq)
2174 {
2175 	ptSapContext pSapCtx = NULL;
2176 	void *hHal = NULL;
2177 	QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE;
2178 
2179 	pSapCtx = CDS_GET_SAP_CB(pCtx);
2180 	if (NULL == pSapCtx) {
2181 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2182 			  "%s: Invalid SAP pointer from pCtx",
2183 			  __func__);
2184 		return QDF_STATUS_E_FAULT;
2185 	}
2186 	hHal = CDS_GET_HAL_CB(pSapCtx->p_cds_gctx);
2187 	if ((NULL == hHal) || (eSAP_TRUE != pSapCtx->isSapSessionOpen)) {
2188 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2189 			  "%s: HAL pointer (%p) NULL OR SME session is not open (%d)",
2190 			  __func__, hHal, pSapCtx->isSapSessionOpen);
2191 		return QDF_STATUS_E_FAULT;
2192 	}
2193 
2194 	qdf_ret_status =
2195 		sme_send_action(hHal, pSapCtx->sessionId, pBuf, len, 0,
2196 		0, channel_freq);
2197 
2198 	if (QDF_STATUS_SUCCESS == qdf_ret_status) {
2199 		return QDF_STATUS_SUCCESS;
2200 	}
2201 
2202 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2203 		  "Failed to Send Action Frame");
2204 
2205 	return QDF_STATUS_E_FAULT;
2206 }
2207 
2208 /**
2209  * wlansap_remain_on_channel() - set remain on channel
2210  * @pCtx: Pointer to the global cds context; a handle to SAP's control block
2211  *        can be extracted from its context. When MBSSID feature is enabled,
2212  *        SAP context is directly passed to SAP APIs.
2213  * @channel: Channel on which driver has to listen
2214  * @duration: Duration for which driver has to listen on specified channel
2215  * @callback: Callback function to be called once Listen is done.
2216  * @pContext: Context needs to be called in callback function.
2217  * @scan_id: scan identifier
2218  *
2219  * This api function provides to set Remain On channel on specified channel
2220  * for specified duration.
2221  *
2222  * Return: The QDF_STATUS code associated with performing the operation
2223  *         QDF_STATUS_SUCCESS:  Success and error code otherwise
2224  */
2225 QDF_STATUS wlansap_remain_on_channel(void *pCtx,
2226 	uint8_t channel, uint32_t duration, remainOnChanCallback callback,
2227 	void *pContext, uint32_t *scan_id)
2228 {
2229 	ptSapContext pSapCtx = NULL;
2230 	void *hHal = NULL;
2231 	QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE;
2232 
2233 	pSapCtx = CDS_GET_SAP_CB(pCtx);
2234 	if (NULL == pSapCtx) {
2235 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2236 			  "%s: Invalid SAP pointer from pCtx",
2237 			  __func__);
2238 		return QDF_STATUS_E_FAULT;
2239 	}
2240 	hHal = CDS_GET_HAL_CB(pSapCtx->p_cds_gctx);
2241 	if ((NULL == hHal) || (eSAP_TRUE != pSapCtx->isSapSessionOpen)) {
2242 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2243 			  "%s: HAL pointer (%p) NULL OR SME session is not open (%d)",
2244 			  __func__, hHal, pSapCtx->isSapSessionOpen);
2245 		return QDF_STATUS_E_FAULT;
2246 	}
2247 
2248 	qdf_ret_status = sme_remain_on_channel(hHal, pSapCtx->sessionId,
2249 				channel, duration, callback, pContext,
2250 				true, scan_id);
2251 
2252 	if (QDF_STATUS_SUCCESS == qdf_ret_status) {
2253 		return QDF_STATUS_SUCCESS;
2254 	}
2255 
2256 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2257 		  "Failed to Set Remain on Channel");
2258 
2259 	return QDF_STATUS_E_FAULT;
2260 }
2261 
2262 /**
2263  * wlansap_cancel_remain_on_channel() - cancel remain on channel
2264  * @pCtx: Pointer to the global cds context; a handle to SAP's control block
2265  *        can be extracted from its context. When MBSSID feature is enabled,
2266  *        SAP context is directly passed to SAP APIs.
2267  *
2268  * This api cancel previous remain on channel request.
2269  *
2270  * Return: The QDF_STATUS code associated with performing the operation
2271  *         QDF_STATUS_SUCCESS:  Success and error code otherwie
2272  */
2273 QDF_STATUS wlansap_cancel_remain_on_channel(void *pCtx,
2274 	uint32_t scan_id)
2275 {
2276 	ptSapContext pSapCtx = NULL;
2277 	void *hHal = NULL;
2278 	QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE;
2279 
2280 	pSapCtx = CDS_GET_SAP_CB(pCtx);
2281 	if (NULL == pSapCtx) {
2282 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2283 			  "%s: Invalid SAP pointer from pCtx",
2284 			  __func__);
2285 		return QDF_STATUS_E_FAULT;
2286 	}
2287 	hHal = CDS_GET_HAL_CB(pSapCtx->p_cds_gctx);
2288 	if ((NULL == hHal) ||
2289 		(eSAP_TRUE != pSapCtx->isSapSessionOpen)) {
2290 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2291 			  "%s: HAL pointer (%p) NULL OR SME session is not open (%d)",
2292 			  __func__, hHal, pSapCtx->isSapSessionOpen);
2293 		return QDF_STATUS_E_FAULT;
2294 	}
2295 
2296 	qdf_ret_status =
2297 		sme_cancel_remain_on_channel(hHal, pSapCtx->sessionId,
2298 		scan_id);
2299 
2300 	if (QDF_STATUS_SUCCESS == qdf_ret_status) {
2301 		return QDF_STATUS_SUCCESS;
2302 	}
2303 
2304 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2305 		  "Failed to Cancel Remain on Channel");
2306 
2307 	return QDF_STATUS_E_FAULT;
2308 }
2309 
2310 /**
2311  * wlan_sap_set_pre_cac_status() - Set the pre cac status
2312  * @ctx: SAP context
2313  * @status: Status of pre cac
2314  * @handle: Global MAC handle
2315  *
2316  * Sets the pre cac status in the MAC context and updates the state
2317  *
2318  * Return: QDF_STATUS
2319  */
2320 QDF_STATUS wlan_sap_set_pre_cac_status(void *ctx, bool status,
2321 					tHalHandle handle)
2322 {
2323 	ptSapContext sap_ctx = CDS_GET_SAP_CB(ctx);
2324 	tpAniSirGlobal mac_ctx = PMAC_STRUCT(handle);
2325 
2326 	if (!mac_ctx) {
2327 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2328 			  "%s: Invalid mac pointer", __func__);
2329 		return QDF_STATUS_E_FAULT;
2330 	}
2331 
2332 	if (!sap_ctx) {
2333 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2334 			  "%s: Invalid SAP pointer", __func__);
2335 		return QDF_STATUS_E_FAULT;
2336 	}
2337 
2338 	sap_ctx->is_pre_cac_on = status;
2339 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
2340 		"%s: is_pre_cac_on:%d", __func__, sap_ctx->is_pre_cac_on);
2341 
2342 	return QDF_STATUS_SUCCESS;
2343 }
2344 
2345 /**
2346  * wlan_sap_set_chan_before_pre_cac() - Save the channel before pre cac
2347  * @ctx: SAP context
2348  * @chan_before_pre_cac: Channel before pre cac
2349  *
2350  * Saves the channel that was in use before pre cac operation
2351  *
2352  * Return: QDF_STATUS
2353  */
2354 QDF_STATUS wlan_sap_set_chan_before_pre_cac(void *ctx,
2355 					uint8_t chan_before_pre_cac)
2356 {
2357 	ptSapContext sap_ctx = CDS_GET_SAP_CB(ctx);
2358 
2359 	if (!sap_ctx) {
2360 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2361 			  "%s: Invalid SAP pointer", __func__);
2362 		return QDF_STATUS_E_FAULT;
2363 	}
2364 
2365 	sap_ctx->chan_before_pre_cac = chan_before_pre_cac;
2366 	return QDF_STATUS_SUCCESS;
2367 }
2368 
2369 /**
2370  * wlan_sap_set_pre_cac_complete_status() - Sets pre cac complete status
2371  * @ctx: SAP context
2372  * @status: Status of pre cac complete
2373  *
2374  * Sets the status of pre cac i.e., whether pre cac is complete or not
2375  *
2376  * Return: QDF_STATUS
2377  */
2378 QDF_STATUS wlan_sap_set_pre_cac_complete_status(void *ctx, bool status)
2379 {
2380 	ptSapContext sap_ctx = CDS_GET_SAP_CB(ctx);
2381 
2382 	if (!sap_ctx) {
2383 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2384 			  "%s: Invalid SAP pointer", __func__);
2385 		return QDF_STATUS_E_FAULT;
2386 	}
2387 
2388 	sap_ctx->pre_cac_complete = status;
2389 
2390 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
2391 			"%s: pre cac complete status:%d session:%d",
2392 			__func__, status, sap_ctx->sessionId);
2393 
2394 	return QDF_STATUS_SUCCESS;
2395 }
2396 
2397 /**
2398  * wlan_sap_is_pre_cac_active() - Checks if pre cac in in progress
2399  * @handle: Global MAC handle
2400  *
2401  * Checks if pre cac is in progress in any of the SAP contexts
2402  *
2403  * Return: True is pre cac is active, false otherwise
2404  */
2405 bool wlan_sap_is_pre_cac_active(tHalHandle handle)
2406 {
2407 	tpAniSirGlobal mac = NULL;
2408 	int i;
2409 
2410 	mac = PMAC_STRUCT(handle);
2411 	if (!mac) {
2412 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2413 			"%s: Invalid mac context", __func__);
2414 		return false;
2415 	}
2416 
2417 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
2418 		ptSapContext context =
2419 			(ptSapContext) mac->sap.sapCtxList[i].pSapContext;
2420 		if (context && context->is_pre_cac_on)
2421 			return true;
2422 	}
2423 	return false;
2424 }
2425 
2426 /**
2427  * wlan_sap_get_pre_cac_vdev_id() - Get vdev id of the pre cac interface
2428  * @handle: Global handle
2429  * @vdev_id: vdev id
2430  *
2431  * Fetches the vdev id of the pre cac interface
2432  *
2433  * Return: QDF_STATUS
2434  */
2435 QDF_STATUS wlan_sap_get_pre_cac_vdev_id(tHalHandle handle, uint8_t *vdev_id)
2436 {
2437 	tpAniSirGlobal mac = NULL;
2438 	uint8_t i;
2439 
2440 	mac = PMAC_STRUCT(handle);
2441 	if (!mac) {
2442 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2443 			"%s: Invalid mac context", __func__);
2444 		return QDF_STATUS_E_FAULT;
2445 	}
2446 
2447 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
2448 		ptSapContext context =
2449 			(ptSapContext) mac->sap.sapCtxList[i].pSapContext;
2450 		if (context && context->is_pre_cac_on) {
2451 			*vdev_id = i;
2452 			return QDF_STATUS_SUCCESS;
2453 		}
2454 	}
2455 	return QDF_STATUS_E_FAILURE;
2456 }
2457 
2458 /**
2459  * wlansap_register_mgmt_frame() - register management frame
2460  * @pCtx: Pointer to the global cds context; a handle to SAP's control block
2461  *        can be extracted from its context. When MBSSID feature is enabled,
2462  *        SAP context is directly passed to SAP APIs.
2463  * @frameType: frameType that needs to be registered with PE.
2464  * @matchData: Data pointer which should be matched after frame type is matched.
2465  * @matchLen: Length of the matchData
2466  *
2467  * HDD use this API to register specified type of frame with CORE stack.
2468  * On receiving such kind of frame CORE stack should pass this frame to HDD
2469  *
2470  * Return: The QDF_STATUS code associated with performing the operation
2471  *         QDF_STATUS_SUCCESS:  Success and error code otherwise
2472  */
2473 QDF_STATUS wlansap_register_mgmt_frame
2474 	(void *pCtx,
2475 	uint16_t frameType, uint8_t *matchData, uint16_t matchLen) {
2476 	ptSapContext pSapCtx = NULL;
2477 	void *hHal = NULL;
2478 	QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE;
2479 
2480 	pSapCtx = CDS_GET_SAP_CB(pCtx);
2481 	if (NULL == pSapCtx) {
2482 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2483 			  "%s: Invalid SAP pointer from pCtx",
2484 			  __func__);
2485 		return QDF_STATUS_E_FAULT;
2486 	}
2487 	hHal = CDS_GET_HAL_CB(pSapCtx->p_cds_gctx);
2488 	if ((NULL == hHal) || (eSAP_TRUE != pSapCtx->isSapSessionOpen)) {
2489 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2490 			  "%s: HAL pointer (%p) NULL OR SME session is not open (%d)",
2491 			  __func__, hHal, pSapCtx->isSapSessionOpen);
2492 		return QDF_STATUS_E_FAULT;
2493 	}
2494 
2495 	qdf_ret_status = sme_register_mgmt_frame(hHal, pSapCtx->sessionId,
2496 						 frameType, matchData,
2497 						 matchLen);
2498 
2499 	if (QDF_STATUS_SUCCESS == qdf_ret_status) {
2500 		return QDF_STATUS_SUCCESS;
2501 	}
2502 
2503 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2504 		  "Failed to Register MGMT frame");
2505 
2506 	return QDF_STATUS_E_FAULT;
2507 }
2508 
2509 /**
2510  * wlansap_de_register_mgmt_frame() - de register management frame
2511  * @pCtx: Pointer to the global cds context; a handle to SAP's control block
2512  *        can be extracted from its context. When MBSSID feature is enabled,
2513  *        SAP context is directly passed to SAP APIs.
2514  * @frameType: frameType that needs to be De-registered with PE.
2515  * @matchData: Data pointer which should be matched after frame type is matched.
2516  * @matchLen: Length of the matchData
2517  *
2518  * This API is used to deregister previously registered frame.
2519  *
2520  * Return: The QDF_STATUS code associated with performing the operation
2521  *         QDF_STATUS_SUCCESS:  Success and error code otherwise
2522  */
2523 QDF_STATUS wlansap_de_register_mgmt_frame
2524 	(void *pCtx,
2525 	uint16_t frameType, uint8_t *matchData, uint16_t matchLen) {
2526 	ptSapContext pSapCtx = NULL;
2527 	void *hHal = NULL;
2528 	QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE;
2529 
2530 	pSapCtx = CDS_GET_SAP_CB(pCtx);
2531 	if (NULL == pSapCtx) {
2532 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2533 			  "%s: Invalid SAP pointer from pCtx",
2534 			  __func__);
2535 		return QDF_STATUS_E_FAULT;
2536 	}
2537 	hHal = CDS_GET_HAL_CB(pSapCtx->p_cds_gctx);
2538 	if ((NULL == hHal) || (eSAP_TRUE != pSapCtx->isSapSessionOpen)) {
2539 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2540 			  "%s: HAL pointer (%p) NULL OR SME session is not open (%d)",
2541 			  __func__, hHal, pSapCtx->isSapSessionOpen);
2542 		return QDF_STATUS_E_FAULT;
2543 	}
2544 
2545 	qdf_ret_status =
2546 		sme_deregister_mgmt_frame(hHal, pSapCtx->sessionId, frameType,
2547 					  matchData, matchLen);
2548 
2549 	if (QDF_STATUS_SUCCESS == qdf_ret_status) {
2550 		return QDF_STATUS_SUCCESS;
2551 	}
2552 
2553 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2554 		  "Failed to Deregister MGMT frame");
2555 
2556 	return QDF_STATUS_E_FAULT;
2557 }
2558 
2559 /*==========================================================================
2560    FUNCTION   wlansap_channel_change_request
2561 
2562    DESCRIPTION
2563    This API is used to send an Indication to SME/PE to change the
2564    current operating channel to a different target channel.
2565 
2566    The Channel change will be issued by SAP under the following
2567    scenarios.
2568    1. A radar indication is received  during SAP CAC WAIT STATE and
2569       channel change is required.
2570    2. A radar indication is received during SAP STARTED STATE and
2571       channel change is required.
2572    DEPENDENCIES
2573    NA.
2574 
2575    PARAMETERS
2576    IN
2577    pSapCtx: Pointer to cds global context structure
2578 
2579    RETURN VALUE
2580    The QDF_STATUS code associated with performing the operation
2581 
2582    QDF_STATUS_SUCCESS:  Success
2583 
2584    SIDE EFFECTS
2585    ============================================================================*/
2586 QDF_STATUS
2587 wlansap_channel_change_request(void *pSapCtx, uint8_t target_channel)
2588 {
2589 	ptSapContext sapContext = NULL;
2590 	QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE;
2591 	void *hHal = NULL;
2592 	tpAniSirGlobal mac_ctx = NULL;
2593 	eCsrPhyMode phy_mode;
2594 	struct ch_params_s *ch_params;
2595 	sapContext = (ptSapContext) pSapCtx;
2596 
2597 	if (NULL == sapContext) {
2598 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2599 			  "%s: Invalid SAP pointer", __func__);
2600 		return QDF_STATUS_E_FAULT;
2601 	}
2602 
2603 	hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx);
2604 	if (NULL == hHal) {
2605 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2606 			  "%s: Invalid HAL pointer from p_cds_gctx", __func__);
2607 		return QDF_STATUS_E_FAULT;
2608 	}
2609 	mac_ctx = PMAC_STRUCT(hHal);
2610 	phy_mode = sapContext->csr_roamProfile.phyMode;
2611 	sapContext->csr_roamProfile.ChannelInfo.ChannelList[0] = target_channel;
2612 	/*
2613 	 * We are getting channel bonding mode from sapDfsInfor structure
2614 	 * because we've implemented channel width fallback mechanism for DFS
2615 	 * which will result in channel width changing dynamically.
2616 	 */
2617 	ch_params = &mac_ctx->sap.SapDfsInfo.new_ch_params;
2618 	cds_set_channel_params(target_channel, 0, ch_params);
2619 	sapContext->ch_params.ch_width = ch_params->ch_width;
2620 	/* Update the channel as this will be used to
2621 	 * send event to supplicant
2622 	 */
2623 	sapContext->channel = target_channel;
2624 	sapContext->csr_roamProfile.ch_params.ch_width = ch_params->ch_width;
2625 	sapContext->csr_roamProfile.ch_params.sec_ch_offset =
2626 						ch_params->sec_ch_offset;
2627 	sapContext->csr_roamProfile.ch_params.center_freq_seg0 =
2628 						ch_params->center_freq_seg0;
2629 	sapContext->csr_roamProfile.ch_params.center_freq_seg1 =
2630 						ch_params->center_freq_seg1;
2631 
2632 	qdf_ret_status = sme_roam_channel_change_req(hHal, sapContext->bssid,
2633 				ch_params, &sapContext->csr_roamProfile);
2634 
2635 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
2636 		"%s: chan:%d width:%d offset:%d seg0:%d seg1:%d",
2637 		__func__, sapContext->channel, ch_params->ch_width,
2638 		ch_params->sec_ch_offset, ch_params->center_freq_seg0,
2639 		ch_params->center_freq_seg1);
2640 
2641 	if (qdf_ret_status == QDF_STATUS_SUCCESS) {
2642 		sap_signal_hdd_event(sapContext, NULL,
2643 			eSAP_CHANNEL_CHANGE_EVENT,
2644 			(void *) eSAP_STATUS_SUCCESS);
2645 
2646 		return QDF_STATUS_SUCCESS;
2647 	}
2648 	return QDF_STATUS_E_FAULT;
2649 }
2650 
2651 /*==========================================================================
2652 
2653    FUNCTION    wlansap_start_beacon_req
2654    DESCRIPTION
2655    This API is used to send an Indication to SME/PE to start
2656    beaconing on the current operating channel.
2657 
2658    Brief:When SAP is started on DFS channel and when ADD BSS RESP is received
2659    LIM temporarily holds off Beaconing for SAP to do CAC WAIT. When
2660    CAC WAIT is done SAP resumes the Beacon Tx by sending a start beacon
2661    request to LIM.
2662 
2663    DEPENDENCIES
2664    NA.
2665 
2666    PARAMETERS
2667 
2668    IN
2669    pSapCtx: Pointer to cds global context structure
2670 
2671    RETURN VALUE
2672    The QDF_STATUS code associated with performing the operation
2673 
2674    QDF_STATUS_SUCCESS:  Success
2675 
2676    SIDE EFFECTS
2677    ============================================================================*/
2678 QDF_STATUS wlansap_start_beacon_req(void *pSapCtx)
2679 {
2680 	ptSapContext sapContext = NULL;
2681 	QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE;
2682 	void *hHal = NULL;
2683 	uint8_t dfsCacWaitStatus = 0;
2684 	tpAniSirGlobal pMac = NULL;
2685 	sapContext = (ptSapContext) pSapCtx;
2686 
2687 	if (NULL == sapContext) {
2688 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2689 			  "%s: Invalid SAP pointer", __func__);
2690 		return QDF_STATUS_E_FAULT;
2691 	}
2692 
2693 	hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx);
2694 	if (NULL == hHal) {
2695 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2696 			  "%s: Invalid HAL pointer from p_cds_gctx", __func__);
2697 		return QDF_STATUS_E_FAULT;
2698 	}
2699 	pMac = PMAC_STRUCT(hHal);
2700 
2701 	/* No Radar was found during CAC WAIT, So start Beaconing */
2702 	if (pMac->sap.SapDfsInfo.sap_radar_found_status == false) {
2703 		/* CAC Wait done without any Radar Detection */
2704 		dfsCacWaitStatus = true;
2705 		sapContext->pre_cac_complete = false;
2706 		qdf_ret_status = sme_roam_start_beacon_req(hHal,
2707 							   sapContext->bssid,
2708 							   dfsCacWaitStatus);
2709 		if (qdf_ret_status == QDF_STATUS_SUCCESS) {
2710 			return QDF_STATUS_SUCCESS;
2711 		}
2712 		return QDF_STATUS_E_FAULT;
2713 	}
2714 
2715 	return QDF_STATUS_E_FAULT;
2716 }
2717 
2718 /*==========================================================================
2719    FUNCTION    wlansap_dfs_send_csa_ie_request
2720 
2721    DESCRIPTION
2722    This API is used to send channel switch announcement request to PE
2723    DEPENDENCIES
2724    NA.
2725 
2726    PARAMETERS
2727    IN
2728    pSapCtx: Pointer to cds global context structure
2729 
2730    RETURN VALUE
2731    The QDF_STATUS code associated with performing the operation
2732 
2733    QDF_STATUS_SUCCESS:  Success
2734 
2735    SIDE EFFECTS
2736    ============================================================================*/
2737 QDF_STATUS wlansap_dfs_send_csa_ie_request(void *pSapCtx)
2738 {
2739 	ptSapContext sapContext = NULL;
2740 	QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE;
2741 	void *hHal = NULL;
2742 	tpAniSirGlobal pMac = NULL;
2743 	sapContext = (ptSapContext) pSapCtx;
2744 
2745 	if (NULL == sapContext) {
2746 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2747 			  "%s: Invalid SAP pointer", __func__);
2748 		return QDF_STATUS_E_FAULT;
2749 	}
2750 
2751 	hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx);
2752 	if (NULL == hHal) {
2753 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2754 			  "%s: Invalid HAL pointer from p_cds_gctx", __func__);
2755 		return QDF_STATUS_E_FAULT;
2756 	}
2757 	pMac = PMAC_STRUCT(hHal);
2758 
2759 	pMac->sap.SapDfsInfo.new_ch_params.ch_width =
2760 				pMac->sap.SapDfsInfo.new_chanWidth;
2761 	cds_set_channel_params(pMac->sap.SapDfsInfo.target_channel,
2762 				0, &pMac->sap.SapDfsInfo.new_ch_params);
2763 
2764 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
2765 			"%s: chan:%d req:%d width:%d off:%d",
2766 			__func__, pMac->sap.SapDfsInfo.target_channel,
2767 			pMac->sap.SapDfsInfo.csaIERequired,
2768 			pMac->sap.SapDfsInfo.new_ch_params.ch_width,
2769 			pMac->sap.SapDfsInfo.new_ch_params.sec_ch_offset);
2770 
2771 	qdf_ret_status = sme_roam_csa_ie_request(hHal,
2772 				sapContext->bssid,
2773 				pMac->sap.SapDfsInfo.target_channel,
2774 				pMac->sap.SapDfsInfo.csaIERequired,
2775 				&pMac->sap.SapDfsInfo.new_ch_params);
2776 
2777 	if (qdf_ret_status == QDF_STATUS_SUCCESS) {
2778 		return QDF_STATUS_SUCCESS;
2779 	}
2780 
2781 	return QDF_STATUS_E_FAULT;
2782 }
2783 
2784 /*==========================================================================
2785    FUNCTION    wlansap_get_dfs_ignore_cac
2786 
2787    DESCRIPTION
2788    This API is used to get the value of ignore_cac value
2789 
2790    DEPENDENCIES
2791    NA.
2792 
2793    PARAMETERS
2794    IN
2795    hHal : HAL pointer
2796    pIgnore_cac : pointer to ignore_cac variable
2797 
2798    RETURN VALUE
2799    The QDF_STATUS code associated with performing the operation
2800 
2801    QDF_STATUS_SUCCESS:  Success
2802 
2803    SIDE EFFECTS
2804    ============================================================================*/
2805 QDF_STATUS wlansap_get_dfs_ignore_cac(tHalHandle hHal, uint8_t *pIgnore_cac)
2806 {
2807 	tpAniSirGlobal pMac = NULL;
2808 
2809 	if (NULL != hHal) {
2810 		pMac = PMAC_STRUCT(hHal);
2811 	} else {
2812 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2813 			  "%s: Invalid hHal pointer", __func__);
2814 		return QDF_STATUS_E_FAULT;
2815 	}
2816 
2817 	*pIgnore_cac = pMac->sap.SapDfsInfo.ignore_cac;
2818 	return QDF_STATUS_SUCCESS;
2819 }
2820 
2821 /*==========================================================================
2822    FUNCTION    wlansap_set_dfs_ignore_cac
2823 
2824    DESCRIPTION
2825    This API is used to Set the value of ignore_cac value
2826 
2827    DEPENDENCIES
2828    NA.
2829 
2830    PARAMETERS
2831    IN
2832    hHal : HAL pointer
2833    ignore_cac : value to set for ignore_cac variable in DFS global structure.
2834 
2835    RETURN VALUE
2836    The QDF_STATUS code associated with performing the operation
2837 
2838    QDF_STATUS_SUCCESS:  Success
2839 
2840    SIDE EFFECTS
2841    ============================================================================*/
2842 QDF_STATUS wlansap_set_dfs_ignore_cac(tHalHandle hHal, uint8_t ignore_cac)
2843 {
2844 	tpAniSirGlobal pMac = NULL;
2845 
2846 	if (NULL != hHal) {
2847 		pMac = PMAC_STRUCT(hHal);
2848 	} else {
2849 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2850 			  "%s: Invalid hHal pointer", __func__);
2851 		return QDF_STATUS_E_FAULT;
2852 	}
2853 
2854 	pMac->sap.SapDfsInfo.ignore_cac = (ignore_cac >= true) ?
2855 					  true : false;
2856 	return QDF_STATUS_SUCCESS;
2857 }
2858 
2859 /**
2860  * wlansap_set_dfs_restrict_japan_w53() - enable/disable dfS for japan
2861  * @hHal : HAL pointer
2862  * @disable_Dfs_JapanW3 :Indicates if Japan W53 is disabled when set to 1
2863  *                       Indicates if Japan W53 is enabled when set to 0
2864  *
2865  * This API is used to enable or disable Japan W53 Band
2866  * Return: The QDF_STATUS code associated with performing the operation
2867  *         QDF_STATUS_SUCCESS:  Success
2868  */
2869 QDF_STATUS
2870 wlansap_set_dfs_restrict_japan_w53(tHalHandle hHal, uint8_t disable_Dfs_W53)
2871 {
2872 	tpAniSirGlobal pMac = NULL;
2873 	QDF_STATUS status;
2874 	uint8_t dfs_region;
2875 
2876 	if (NULL != hHal) {
2877 		pMac = PMAC_STRUCT(hHal);
2878 	} else {
2879 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2880 			  "%s: Invalid hHal pointer", __func__);
2881 		return QDF_STATUS_E_FAULT;
2882 	}
2883 
2884 	cds_get_dfs_region(&dfs_region);
2885 
2886 	/*
2887 	 * Set the JAPAN W53 restriction only if the current
2888 	 * regulatory domain is JAPAN.
2889 	 */
2890 	if (DFS_MKK_REGION == dfs_region) {
2891 		pMac->sap.SapDfsInfo.is_dfs_w53_disabled = disable_Dfs_W53;
2892 		QDF_TRACE(QDF_MODULE_ID_SAP,
2893 			  QDF_TRACE_LEVEL_INFO_LOW,
2894 			  FL("sapdfs: SET DFS JAPAN W53 DISABLED = %d"),
2895 			  pMac->sap.SapDfsInfo.is_dfs_w53_disabled);
2896 
2897 		status = QDF_STATUS_SUCCESS;
2898 	} else {
2899 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2900 			  FL
2901 				  ("Regdomain not japan, set disable JP W53 not valid"));
2902 
2903 		status = QDF_STATUS_E_FAULT;
2904 	}
2905 
2906 	return status;
2907 }
2908 
2909 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2910 /**
2911  * wlan_sap_set_channel_avoidance() - sets sap mcc channel avoidance ini param
2912  * @hal:                        hal handle
2913  * @sap_channel_avoidance:      ini parameter value
2914  *
2915  * sets sap mcc channel avoidance ini param, to be called in sap_start
2916  *
2917  * Return: success of failure of operation
2918  */
2919 QDF_STATUS
2920 wlan_sap_set_channel_avoidance(tHalHandle hal, bool sap_channel_avoidance)
2921 {
2922 	tpAniSirGlobal mac_ctx = NULL;
2923 	if (NULL != hal)
2924 		mac_ctx = PMAC_STRUCT(hal);
2925 	if (mac_ctx == NULL || hal == NULL) {
2926 		QDF_TRACE(QDF_MODULE_ID_SAP,
2927 			  QDF_TRACE_LEVEL_ERROR,
2928 			  FL("hal or mac_ctx pointer NULL"));
2929 		return QDF_STATUS_E_FAULT;
2930 	}
2931 	mac_ctx->sap.sap_channel_avoidance = sap_channel_avoidance;
2932 	return QDF_STATUS_SUCCESS;
2933 }
2934 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2935 
2936 /**
2937  * wlansap_set_dfs_preferred_channel_location() - set dfs preferred channel
2938  * @hHal : HAL pointer
2939  * @dfs_Preferred_Channels_location :
2940  *       0 - Indicates No preferred channel location restrictions
2941  *       1 - Indicates SAP Indoor Channels operation only.
2942  *       2 - Indicates SAP Outdoor Channels operation only.
2943  *
2944  * This API is used to set sap preferred channels location
2945  * to resetrict the DFS random channel selection algorithm
2946  * either Indoor/Outdoor channels only.
2947  *
2948  * Return: The QDF_STATUS code associated with performing the operation
2949  *         QDF_STATUS_SUCCESS:  Success and error code otherwise.
2950  */
2951 QDF_STATUS
2952 wlansap_set_dfs_preferred_channel_location(tHalHandle hHal,
2953 					   uint8_t
2954 					   dfs_Preferred_Channels_location)
2955 {
2956 	tpAniSirGlobal pMac = NULL;
2957 	QDF_STATUS status;
2958 	uint8_t dfs_region;
2959 
2960 	if (NULL != hHal) {
2961 		pMac = PMAC_STRUCT(hHal);
2962 	} else {
2963 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2964 			  "%s: Invalid hHal pointer", __func__);
2965 		return QDF_STATUS_E_FAULT;
2966 	}
2967 
2968 	cds_get_dfs_region(&dfs_region);
2969 
2970 	/*
2971 	 * The Indoor/Outdoor only random channel selection
2972 	 * restriction is currently enforeced only for
2973 	 * JAPAN regulatory domain.
2974 	 */
2975 	if (DFS_MKK_REGION == dfs_region) {
2976 		pMac->sap.SapDfsInfo.sap_operating_chan_preferred_location =
2977 			dfs_Preferred_Channels_location;
2978 		QDF_TRACE(QDF_MODULE_ID_SAP,
2979 			  QDF_TRACE_LEVEL_INFO_LOW,
2980 			  FL
2981 				  ("sapdfs:Set Preferred Operating Channel location=%d"),
2982 			  pMac->sap.SapDfsInfo.
2983 			  sap_operating_chan_preferred_location);
2984 
2985 		status = QDF_STATUS_SUCCESS;
2986 	} else {
2987 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2988 			  FL
2989 				  ("sapdfs:NOT JAPAN REG, Invalid Set preferred chans location"));
2990 
2991 		status = QDF_STATUS_E_FAULT;
2992 	}
2993 
2994 	return status;
2995 }
2996 
2997 /*==========================================================================
2998    FUNCTION    wlansap_set_dfs_target_chnl
2999 
3000    DESCRIPTION
3001    This API is used to set next target chnl as provided channel.
3002    you can provide any valid channel to this API.
3003 
3004    DEPENDENCIES
3005    NA.
3006 
3007    PARAMETERS
3008    IN
3009    hHal : HAL pointer
3010    target_channel : target channel to be set
3011 
3012    RETURN VALUE
3013    The QDF_STATUS code associated with performing the operation
3014 
3015    QDF_STATUS_SUCCESS:  Success
3016 
3017    SIDE EFFECTS
3018    ============================================================================*/
3019 QDF_STATUS wlansap_set_dfs_target_chnl(tHalHandle hHal, uint8_t target_channel)
3020 {
3021 	tpAniSirGlobal pMac = NULL;
3022 
3023 	if (NULL != hHal) {
3024 		pMac = PMAC_STRUCT(hHal);
3025 	} else {
3026 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3027 			  "%s: Invalid hHal pointer", __func__);
3028 		return QDF_STATUS_E_FAULT;
3029 	}
3030 	if (target_channel > 0) {
3031 		pMac->sap.SapDfsInfo.user_provided_target_channel =
3032 			target_channel;
3033 	} else {
3034 		pMac->sap.SapDfsInfo.user_provided_target_channel = 0;
3035 	}
3036 
3037 	return QDF_STATUS_SUCCESS;
3038 }
3039 
3040 QDF_STATUS
3041 wlansap_update_sap_config_add_ie(tsap_Config_t *pConfig,
3042 				 const uint8_t *pAdditionIEBuffer,
3043 				 uint16_t additionIELength,
3044 				 eUpdateIEsType updateType)
3045 {
3046 	QDF_STATUS status = QDF_STATUS_SUCCESS;
3047 	uint8_t bufferValid = false;
3048 	uint16_t bufferLength = 0;
3049 	uint8_t *pBuffer = NULL;
3050 
3051 	if (NULL == pConfig) {
3052 		return QDF_STATUS_E_FAULT;
3053 	}
3054 
3055 	if ((pAdditionIEBuffer != NULL) && (additionIELength != 0)) {
3056 		/* initialize the buffer pointer so that pe can copy */
3057 		if (additionIELength > 0) {
3058 			bufferLength = additionIELength;
3059 			pBuffer = qdf_mem_malloc(bufferLength);
3060 			if (NULL == pBuffer) {
3061 				QDF_TRACE(QDF_MODULE_ID_SME,
3062 					  QDF_TRACE_LEVEL_ERROR,
3063 					  FL("Could not allocate the buffer "));
3064 				return QDF_STATUS_E_NOMEM;
3065 			}
3066 			qdf_mem_copy(pBuffer, pAdditionIEBuffer, bufferLength);
3067 			bufferValid = true;
3068 		}
3069 	}
3070 
3071 	switch (updateType) {
3072 	case eUPDATE_IE_PROBE_BCN:
3073 		if (bufferValid) {
3074 			pConfig->probeRespBcnIEsLen = bufferLength;
3075 			pConfig->pProbeRespBcnIEsBuffer = pBuffer;
3076 		} else {
3077 			qdf_mem_free(pConfig->pProbeRespBcnIEsBuffer);
3078 			pConfig->probeRespBcnIEsLen = 0;
3079 			pConfig->pProbeRespBcnIEsBuffer = NULL;
3080 			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
3081 				  FL
3082 					  ("No Probe Resp beacone IE received in set beacon"));
3083 		}
3084 		break;
3085 	case eUPDATE_IE_PROBE_RESP:
3086 		if (bufferValid) {
3087 			pConfig->probeRespIEsBufferLen = bufferLength;
3088 			pConfig->pProbeRespIEsBuffer = pBuffer;
3089 		} else {
3090 			qdf_mem_free(pConfig->pProbeRespIEsBuffer);
3091 			pConfig->probeRespIEsBufferLen = 0;
3092 			pConfig->pProbeRespIEsBuffer = NULL;
3093 			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
3094 				  FL
3095 					  ("No Probe Response IE received in set beacon"));
3096 		}
3097 		break;
3098 	case eUPDATE_IE_ASSOC_RESP:
3099 		if (bufferValid) {
3100 			pConfig->assocRespIEsLen = bufferLength;
3101 			pConfig->pAssocRespIEsBuffer = pBuffer;
3102 		} else {
3103 			qdf_mem_free(pConfig->pAssocRespIEsBuffer);
3104 			pConfig->assocRespIEsLen = 0;
3105 			pConfig->pAssocRespIEsBuffer = NULL;
3106 			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
3107 				  FL
3108 					  ("No Assoc Response IE received in set beacon"));
3109 		}
3110 		break;
3111 	default:
3112 		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
3113 			  FL("No matching buffer type %d"), updateType);
3114 		if (pBuffer != NULL)
3115 			qdf_mem_free(pBuffer);
3116 		break;
3117 	}
3118 
3119 	return status;
3120 }
3121 
3122 QDF_STATUS
3123 wlansap_reset_sap_config_add_ie(tsap_Config_t *pConfig, eUpdateIEsType updateType)
3124 {
3125 	if (NULL == pConfig) {
3126 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3127 			  "%s: Invalid Config pointer", __func__);
3128 		return QDF_STATUS_E_FAULT;
3129 	}
3130 
3131 	switch (updateType) {
3132 	case eUPDATE_IE_ALL:    /*only used to reset */
3133 	case eUPDATE_IE_PROBE_RESP:
3134 		qdf_mem_free(pConfig->pProbeRespIEsBuffer);
3135 		pConfig->probeRespIEsBufferLen = 0;
3136 		pConfig->pProbeRespIEsBuffer = NULL;
3137 		if (eUPDATE_IE_ALL != updateType)
3138 			break;
3139 
3140 	case eUPDATE_IE_ASSOC_RESP:
3141 		qdf_mem_free(pConfig->pAssocRespIEsBuffer);
3142 		pConfig->assocRespIEsLen = 0;
3143 		pConfig->pAssocRespIEsBuffer = NULL;
3144 		if (eUPDATE_IE_ALL != updateType)
3145 			break;
3146 
3147 	case eUPDATE_IE_PROBE_BCN:
3148 		qdf_mem_free(pConfig->pProbeRespBcnIEsBuffer);
3149 		pConfig->probeRespBcnIEsLen = 0;
3150 		pConfig->pProbeRespBcnIEsBuffer = NULL;
3151 		if (eUPDATE_IE_ALL != updateType)
3152 			break;
3153 
3154 	default:
3155 		if (eUPDATE_IE_ALL != updateType)
3156 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3157 				  FL("Invalid buffer type %d"), updateType);
3158 		break;
3159 	}
3160 	return QDF_STATUS_SUCCESS;
3161 }
3162 
3163 /*==========================================================================
3164    FUNCTION  wlansap_extend_to_acs_range
3165 
3166    DESCRIPTION Function extends give channel range to consider ACS chan bonding
3167 
3168    DEPENDENCIES PARAMETERS
3169 
3170    IN /OUT
3171    *startChannelNum : ACS extend start ch
3172    *endChannelNum   : ACS extended End ch
3173    *bandStartChannel: Band start ch
3174    *bandEndChannel  : Band end ch
3175 
3176    RETURN VALUE NONE
3177 
3178    SIDE EFFECTS
3179    ============================================================================*/
3180 void wlansap_extend_to_acs_range(uint8_t *startChannelNum,
3181 				 uint8_t *endChannelNum,
3182 				 uint8_t *bandStartChannel,
3183 				 uint8_t *bandEndChannel)
3184 {
3185 #define ACS_WLAN_20M_CH_INC 4
3186 #define ACS_2G_EXTEND ACS_WLAN_20M_CH_INC
3187 #define ACS_5G_EXTEND (ACS_WLAN_20M_CH_INC * 3)
3188 
3189 	uint8_t tmp_startChannelNum = 0, tmp_endChannelNum = 0;
3190 
3191 	if (*startChannelNum <= 14 && *endChannelNum <= 14) {
3192 		*bandStartChannel = CHAN_ENUM_1;
3193 		*bandEndChannel = CHAN_ENUM_14;
3194 		tmp_startChannelNum = *startChannelNum > 5 ?
3195 				   (*startChannelNum - ACS_2G_EXTEND) : 1;
3196 		tmp_endChannelNum = (*endChannelNum + ACS_2G_EXTEND) <= 14 ?
3197 				 (*endChannelNum + ACS_2G_EXTEND) : 14;
3198 	} else if (*startChannelNum >= 36 && *endChannelNum >= 36) {
3199 		*bandStartChannel = CHAN_ENUM_36;
3200 		*bandEndChannel = CHAN_ENUM_165;
3201 		tmp_startChannelNum = (*startChannelNum - ACS_5G_EXTEND) > 36 ?
3202 				   (*startChannelNum - ACS_5G_EXTEND) : 36;
3203 		tmp_endChannelNum = (*endChannelNum + ACS_5G_EXTEND) <= 165 ?
3204 				 (*endChannelNum + ACS_5G_EXTEND) : 165;
3205 	} else {
3206 		*bandStartChannel = CHAN_ENUM_1;
3207 		*bandEndChannel = CHAN_ENUM_165;
3208 		tmp_startChannelNum = *startChannelNum > 5 ?
3209 			(*startChannelNum - ACS_2G_EXTEND) : 1;
3210 		tmp_endChannelNum = (*endChannelNum + ACS_5G_EXTEND) <= 165 ?
3211 			(*endChannelNum + ACS_5G_EXTEND) : 165;
3212 	}
3213 
3214 	/* Note if the ACS range include only DFS channels, do not cross range
3215 	* Active scanning in adjacent non DFS channels results in transmission
3216 	* spikes in DFS specturm channels which is due to emission spill.
3217 	* Remove the active channels from extend ACS range for DFS only range
3218 	*/
3219 	if (CDS_IS_DFS_CH(*startChannelNum)) {
3220 		while (!CDS_IS_DFS_CH(tmp_startChannelNum) &&
3221 			tmp_startChannelNum < *startChannelNum)
3222 			tmp_startChannelNum += ACS_WLAN_20M_CH_INC;
3223 
3224 		*startChannelNum = tmp_startChannelNum;
3225 	}
3226 	if (CDS_IS_DFS_CH(*endChannelNum)) {
3227 		while (!CDS_IS_DFS_CH(tmp_endChannelNum) &&
3228 				 tmp_endChannelNum > *endChannelNum)
3229 			tmp_endChannelNum -= ACS_WLAN_20M_CH_INC;
3230 
3231 		*endChannelNum = tmp_endChannelNum;
3232 	}
3233 }
3234 
3235 /**
3236  * wlansap_get_dfs_nol() - Get the DFS NOL
3237  * @pSapCtx: SAP context
3238  * @nol: Pointer to the NOL
3239  * @nol_len: Length of the NOL
3240  *
3241  * Provides the DFS NOL
3242  *
3243  * Return: QDF_STATUS
3244  */
3245 QDF_STATUS wlansap_get_dfs_nol(void *pSapCtx, uint8_t *nol, uint32_t *nol_len)
3246 {
3247 	int i = 0, j = 0;
3248 	ptSapContext sapContext = (ptSapContext) pSapCtx;
3249 	void *hHal = NULL;
3250 	tpAniSirGlobal pMac = NULL;
3251 	uint64_t current_time, found_time, elapsed_time;
3252 	unsigned long left_time;
3253 	tSapDfsNolInfo *dfs_nol = NULL;
3254 	bool bAvailable = false;
3255 	*nol_len = 0;
3256 
3257 	if (NULL == sapContext) {
3258 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3259 			  "%s: Invalid SAP pointer from p_cds_gctx", __func__);
3260 		return QDF_STATUS_E_FAULT;
3261 	}
3262 	hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx);
3263 	if (NULL == hHal) {
3264 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3265 			  "%s: Invalid HAL pointer from p_cds_gctx", __func__);
3266 		return QDF_STATUS_E_FAULT;
3267 	}
3268 	pMac = PMAC_STRUCT(hHal);
3269 
3270 	if (!pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels) {
3271 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
3272 			  "%s: DFS NOL is empty", __func__);
3273 		return QDF_STATUS_SUCCESS;
3274 	}
3275 
3276 	dfs_nol = pMac->sap.SapDfsInfo.sapDfsChannelNolList;
3277 
3278 	if (!dfs_nol) {
3279 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
3280 			  "%s: DFS NOL context is null", __func__);
3281 		return QDF_STATUS_E_FAULT;
3282 	}
3283 
3284 	for (i = 0; i < pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels;
3285 	     i++) {
3286 		if (!dfs_nol[i].dfs_channel_number)
3287 			continue;
3288 
3289 		current_time = cds_get_monotonic_boottime();
3290 		found_time = dfs_nol[i].radar_found_timestamp;
3291 
3292 		elapsed_time = current_time - found_time;
3293 
3294 		/* check if channel is available
3295 		 * if either channel is usable or available, or timer expired 30mins
3296 		 */
3297 		bAvailable =
3298 			((dfs_nol[i].radar_status_flag ==
3299 			  eSAP_DFS_CHANNEL_AVAILABLE)
3300 			 || (dfs_nol[i].radar_status_flag ==
3301 			     eSAP_DFS_CHANNEL_USABLE)
3302 			 || (elapsed_time >= SAP_DFS_NON_OCCUPANCY_PERIOD));
3303 
3304 		if (bAvailable) {
3305 			dfs_nol[i].radar_status_flag =
3306 				eSAP_DFS_CHANNEL_AVAILABLE;
3307 			dfs_nol[i].radar_found_timestamp = 0;
3308 
3309 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3310 				  "%s: Channel[%d] is AVAILABLE",
3311 				  __func__, dfs_nol[i].dfs_channel_number);
3312 		} else {
3313 
3314 			/* the time left in min */
3315 			left_time = SAP_DFS_NON_OCCUPANCY_PERIOD - elapsed_time;
3316 			left_time = left_time / (60 * 1000 * 1000);
3317 
3318 			nol[j++] = dfs_nol[i].dfs_channel_number;
3319 			(*nol_len)++;
3320 
3321 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3322 				  "%s: Channel[%d] is UNAVAILABLE [%lu min left]",
3323 				  __func__,
3324 				  dfs_nol[i].dfs_channel_number, left_time);
3325 		}
3326 	}
3327 
3328 	return QDF_STATUS_SUCCESS;
3329 }
3330 
3331 /*==========================================================================
3332    FUNCTION    wlansap_set_dfs_nol
3333 
3334    DESCRIPTION
3335    This API is used to set the dfs nol
3336    DEPENDENCIES
3337    NA.
3338 
3339    PARAMETERS
3340    IN
3341    sapContext: Pointer to cds global context structure
3342    conf: set type
3343 
3344    RETURN VALUE
3345    The QDF_STATUS code associated with performing the operation
3346 
3347    QDF_STATUS_SUCCESS:  Success
3348 
3349    SIDE EFFECTS
3350    ============================================================================*/
3351 QDF_STATUS wlansap_set_dfs_nol(void *pSapCtx, eSapDfsNolType conf)
3352 {
3353 	int i = 0;
3354 	ptSapContext sapContext = (ptSapContext) pSapCtx;
3355 	void *hHal = NULL;
3356 	tpAniSirGlobal pMac = NULL;
3357 
3358 	if (NULL == sapContext) {
3359 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3360 			  "%s: Invalid SAP pointer from p_cds_gctx", __func__);
3361 		return QDF_STATUS_E_FAULT;
3362 	}
3363 	hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx);
3364 	if (NULL == hHal) {
3365 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3366 			  "%s: Invalid HAL pointer from p_cds_gctx", __func__);
3367 		return QDF_STATUS_E_FAULT;
3368 	}
3369 	pMac = PMAC_STRUCT(hHal);
3370 
3371 	if (!pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels) {
3372 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
3373 			  "%s: DFS NOL is empty", __func__);
3374 		return QDF_STATUS_SUCCESS;
3375 	}
3376 
3377 	if (conf == eSAP_DFS_NOL_CLEAR) {
3378 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3379 			  "%s: clear the DFS NOL", __func__);
3380 
3381 		for (i = 0;
3382 		     i < pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels;
3383 		     i++) {
3384 			if (!pMac->sap.SapDfsInfo.
3385 			    sapDfsChannelNolList[i].dfs_channel_number)
3386 				continue;
3387 
3388 			pMac->sap.SapDfsInfo.
3389 			sapDfsChannelNolList[i].radar_status_flag =
3390 				eSAP_DFS_CHANNEL_AVAILABLE;
3391 			pMac->sap.SapDfsInfo.
3392 			sapDfsChannelNolList[i].radar_found_timestamp = 0;
3393 		}
3394 	} else if (conf == eSAP_DFS_NOL_RANDOMIZE) {
3395 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3396 			  "%s: Randomize the DFS NOL", __func__);
3397 
3398 		/* random 1/0 to decide to put the channel into NOL */
3399 		for (i = 0;
3400 		     i < pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels;
3401 		     i++) {
3402 			uint32_t random_bytes = 0;
3403 			get_random_bytes(&random_bytes, 1);
3404 
3405 			if (!pMac->sap.SapDfsInfo.
3406 			    sapDfsChannelNolList[i].dfs_channel_number)
3407 				continue;
3408 
3409 			if ((random_bytes + jiffies) % 2) {
3410 				/* mark the channel unavailable */
3411 				pMac->sap.SapDfsInfo.sapDfsChannelNolList[i]
3412 				.radar_status_flag =
3413 					eSAP_DFS_CHANNEL_UNAVAILABLE;
3414 
3415 				/* mark the timestamp */
3416 				pMac->sap.SapDfsInfo.sapDfsChannelNolList[i]
3417 				.radar_found_timestamp =
3418 					cds_get_monotonic_boottime();
3419 			} else {
3420 				/* mark the channel available */
3421 				pMac->sap.SapDfsInfo.
3422 				sapDfsChannelNolList[i].radar_status_flag =
3423 					eSAP_DFS_CHANNEL_AVAILABLE;
3424 
3425 				/* clear the timestamp */
3426 				pMac->sap.SapDfsInfo.
3427 				sapDfsChannelNolList
3428 				[i].radar_found_timestamp = 0;
3429 			}
3430 
3431 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3432 				  "%s: Set channel[%d] %s",
3433 				  __func__,
3434 				  pMac->sap.SapDfsInfo.sapDfsChannelNolList[i]
3435 				  .dfs_channel_number,
3436 				  (pMac->sap.SapDfsInfo.
3437 				   sapDfsChannelNolList[i].radar_status_flag >
3438 				   eSAP_DFS_CHANNEL_AVAILABLE) ? "UNAVAILABLE" :
3439 				  "AVAILABLE");
3440 		}
3441 	} else {
3442 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3443 			  "%s: unsupport type %d", __func__, conf);
3444 	}
3445 
3446 	/* set DFS-NOL back to keep it update-to-date in CNSS */
3447 	sap_signal_hdd_event(sapContext, NULL, eSAP_DFS_NOL_SET,
3448 			  (void *) eSAP_STATUS_SUCCESS);
3449 
3450 	return QDF_STATUS_SUCCESS;
3451 }
3452 
3453 /**
3454  * wlansap_populate_del_sta_params() - populate delete station parameter
3455  * @mac:           Pointer to peer mac address.
3456  * @reason_code:   Reason code for the disassoc/deauth.
3457  * @subtype:       Subtype points to either disassoc/deauth frame.
3458  * @pDelStaParams: Address where parameters to be populated.
3459  *
3460  * This API is used to populate delete station parameter structure
3461  *
3462  * Return: none
3463  */
3464 
3465 void wlansap_populate_del_sta_params(const uint8_t *mac,
3466 				     uint16_t reason_code,
3467 				     uint8_t subtype,
3468 				     struct tagCsrDelStaParams *pDelStaParams)
3469 {
3470 	if (NULL == mac)
3471 		qdf_set_macaddr_broadcast(&pDelStaParams->peerMacAddr);
3472 	else
3473 		qdf_mem_copy(pDelStaParams->peerMacAddr.bytes, mac,
3474 			     QDF_MAC_ADDR_SIZE);
3475 
3476 	if (reason_code == 0)
3477 		pDelStaParams->reason_code = eSIR_MAC_DEAUTH_LEAVING_BSS_REASON;
3478 	else
3479 		pDelStaParams->reason_code = reason_code;
3480 
3481 	if (subtype == (SIR_MAC_MGMT_DEAUTH >> 4) ||
3482 	    subtype == (SIR_MAC_MGMT_DISASSOC >> 4))
3483 		pDelStaParams->subtype = subtype;
3484 	else
3485 		pDelStaParams->subtype = (SIR_MAC_MGMT_DEAUTH >> 4);
3486 
3487 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
3488 		  FL(
3489 		     "Delete STA with RC:%hu subtype:%hhu MAC::"
3490 		     MAC_ADDRESS_STR),
3491 		  pDelStaParams->reason_code, pDelStaParams->subtype,
3492 		  MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr.bytes));
3493 }
3494 
3495 /**
3496  * wlansap_acs_chselect() - Initiates acs channel selection
3497  * @pvos_gctx:                 Pointer to vos global context structure
3498  * @pacs_event_callback:       Callback function in hdd called by sap
3499  *                             to inform hdd about channel section result
3500  * @pconfig:                   Pointer to configuration structure
3501  *                             passed down from hdd
3502  * @pusr_context:              Parameter that will be passed back in all
3503  *                             the sap callback events.
3504  *
3505  * This function serves as an api for hdd to initiate acs scan pre
3506  * start bss.
3507  *
3508  * Return: The QDF_STATUS code associated with performing the operation.
3509  */
3510 QDF_STATUS
3511 wlansap_acs_chselect(void *pvos_gctx,
3512 			tpWLAN_SAPEventCB pacs_event_callback,
3513 			tsap_Config_t *pconfig,
3514 			void *pusr_context)
3515 {
3516 	ptSapContext sap_context = NULL;
3517 	tHalHandle h_hal = NULL;
3518 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3519 	tpAniSirGlobal pmac = NULL;
3520 
3521 	sap_context = CDS_GET_SAP_CB(pvos_gctx);
3522 	if (NULL == sap_context) {
3523 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3524 			"%s: Invalid SAP pointer from pvos_gctx", __func__);
3525 
3526 		return QDF_STATUS_E_FAULT;
3527 	}
3528 
3529 	h_hal = (tHalHandle)CDS_GET_HAL_CB(sap_context->p_cds_gctx);
3530 	if (NULL == h_hal) {
3531 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3532 			"%s: Invalid MAC context from pvosGCtx", __func__);
3533 		return QDF_STATUS_E_FAULT;
3534 	}
3535 
3536 	pmac = PMAC_STRUCT(h_hal);
3537 	sap_context->acs_cfg = &pconfig->acs_cfg;
3538 	sap_context->ch_width_orig = pconfig->acs_cfg.ch_width;
3539 	sap_context->csr_roamProfile.phyMode = pconfig->acs_cfg.hw_mode;
3540 
3541 	/*
3542 	 * Now, configure the scan and ACS channel params
3543 	 * to issue a scan request.
3544 	 */
3545 	wlansap_set_scan_acs_channel_params(pconfig, sap_context,
3546 						pusr_context);
3547 
3548 	/*
3549 	 * Copy the HDD callback function to report the
3550 	 * ACS result after scan in SAP context callback function.
3551 	 */
3552 	sap_context->pfnSapEventCallback = pacs_event_callback;
3553 	/*
3554 	 * init dfs channel nol
3555 	 */
3556 	sap_init_dfs_channel_nol_list(sap_context);
3557 
3558 	/*
3559 	 * Issue the scan request. This scan request is
3560 	 * issued before the start BSS is done so
3561 	 *
3562 	 * 1. No need to pass the second parameter
3563 	 * as the SAP state machine is not started yet
3564 	 * and there is no need for any event posting.
3565 	 *
3566 	 * 2. Set third parameter to TRUE to indicate the
3567 	 * channel selection function to register a
3568 	 * different scan callback fucntion to process
3569 	 * the results pre start BSS.
3570 	 */
3571 	qdf_status = sap_goto_channel_sel(sap_context, NULL, true, false);
3572 
3573 	if (QDF_STATUS_E_ABORTED == qdf_status) {
3574 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3575 			"In %s,DFS not supported in the current operating mode",
3576 			__func__);
3577 		return QDF_STATUS_E_FAILURE;
3578 	} else if (QDF_STATUS_E_CANCELED == qdf_status) {
3579 		/*
3580 		* ERROR is returned when either the SME scan request
3581 		* failed or ACS is overridden due to other constrainst
3582 		* So send selected channel to HDD
3583 		*/
3584 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3585 			FL("Scan Req Failed/ACS Overridden"));
3586 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3587 			FL("Selected channel = %d"),
3588 			sap_context->channel);
3589 
3590 		return sap_signal_hdd_event(sap_context, NULL,
3591 				eSAP_ACS_CHANNEL_SELECTED,
3592 				(void *) eSAP_STATUS_SUCCESS);
3593 	} else if (QDF_STATUS_SUCCESS == qdf_status) {
3594 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3595 			FL("Successfully Issued a Pre Start Bss Scan Request"));
3596 	}
3597 	return qdf_status;
3598 }
3599 
3600 /**
3601  * wlan_sap_enable_phy_error_logs() - Enable DFS phy error logs
3602  * @hal:        global hal handle
3603  * @enable_log: value to set
3604  *
3605  * Since the frequency of DFS phy error is very high, enabling logs for them
3606  * all the times can cause crash and will also create lot of useless logs
3607  * causing difficulties in debugging other issue. This function will be called
3608  * from iwpriv cmd to eanble such logs temporarily.
3609  *
3610  * Return: void
3611  */
3612 void wlan_sap_enable_phy_error_logs(tHalHandle hal, bool enable_log)
3613 {
3614 	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
3615 	mac_ctx->sap.enable_dfs_phy_error_logs = enable_log;
3616 }
3617