/*
 * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */

/**
 * DOC: cds_api.c
 *
 * Connectivity driver services APIs
 */

#include <cds_mq.h>
#include "cds_sched.h"
#include <cds_api.h>
#include "sir_types.h"
#include "sir_api.h"
#include "sir_mac_prot_def.h"
#include "sme_api.h"
#include "mac_init_api.h"
#include "wlan_qct_sys.h"
#include "i_cds_packet.h"
#include "cds_reg_service.h"
#include "wma_types.h"
#include "wlan_hdd_main.h"
#include <linux/vmalloc.h>
#ifdef CONFIG_CNSS
#include <net/cnss.h>
#endif

#include "sap_api.h"
#include "cdf_trace.h"
#include "bmi.h"
#include "ol_fw.h"
#include "ol_if_athvar.h"
#include "hif.h"

#include "cds_utils.h"
#include "wlan_logging_sock_svc.h"
#include "wma.h"

#include "wlan_hdd_ipa.h"
/* Preprocessor Definitions and Constants */

/* Maximum number of cds message queue get wrapper failures to cause panic */
#define CDS_WRAPPER_MAX_FAIL_COUNT (CDS_CORE_MAX_MESSAGES * 3)

/* Data definitions */
static cds_context_type g_cds_context;
static p_cds_contextType gp_cds_context;
static struct __cdf_device g_cdf_ctx;

/* Debug variable to detect MC thread stuck */
static atomic_t cds_wrapper_empty_count;

static uint8_t cds_multicast_logging;

void cds_sys_probe_thread_cback(void *pUserData);

/**
 * cds_init() - Initialize CDS
 *
 * This function allocates the resource required for CDS, but does not
 * initialize all the members. This overall initialization will happen at
 * cds_open().
 *
 * Return: Global context on success and NULL on failure.
 */
v_CONTEXT_t cds_init(void)
{
	cdf_mc_timer_manager_init();
	cdf_mem_init();

	gp_cds_context = &g_cds_context;

	gp_cds_context->cdf_ctx = &g_cdf_ctx;
	cdf_mem_zero(&g_cdf_ctx, sizeof(g_cdf_ctx));

	cdf_trace_spin_lock_init();

#if defined(TRACE_RECORD)
	cdf_trace_init();
#endif
	cdf_dp_trace_init();

	cds_ssr_protect_init();

	return gp_cds_context;
}

/**
 * cds_deinit() - Deinitialize CDS
 *
 * This function frees the CDS resources
 */
void cds_deinit(void)
{
	if (gp_cds_context == NULL)
		return;

	gp_cds_context->cdf_ctx = NULL;
	gp_cds_context = NULL;

	cdf_mem_zero(&g_cds_context, sizeof(g_cds_context));

	cdf_mc_timer_exit();
	cdf_mem_exit();

	return;
}

#ifdef WLAN_FEATURE_NAN
/**
 * cds_set_nan_enable() - set nan enable flag in mac open param
 * @wma_handle: Pointer to mac open param
 * @hdd_ctx: Pointer to hdd context
 *
 * Return: none
 */
static void cds_set_nan_enable(tMacOpenParameters *param,
					hdd_context_t *hdd_ctx)
{
	param->is_nan_enabled = hdd_ctx->config->enable_nan_support;
}
#else
static void cds_set_nan_enable(tMacOpenParameters *param,
					hdd_context_t *pHddCtx)
{
}
#endif

/**
 * cds_open() - open the CDS Module
 *
 * cds_open() function opens the CDS Scheduler
 * Upon successful initialization:
 * - All CDS submodules should have been initialized
 *
 * - The CDS scheduler should have opened
 *
 * - All the WLAN SW components should have been opened. This includes
 * SYS, MAC, SME, WMA and TL.
 *
 * Return: CDF status
 */
CDF_STATUS cds_open(void)
{
	CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
	int iter = 0;
	tSirRetStatus sirStatus = eSIR_SUCCESS;
	tMacOpenParameters mac_openParms;
	cdf_device_t cdf_ctx;
	HTC_INIT_INFO htcInfo;
	struct ol_context *ol_ctx;
	struct hif_opaque_softc *scn;
	void *HTCHandle;
	hdd_context_t *pHddCtx;

	CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_INFO_HIGH,
		  "%s: Opening CDS", __func__);

	if (NULL == gp_cds_context) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
			  "%s: Trying to open CDS without a PreOpen", __func__);
		CDF_ASSERT(0);
		return CDF_STATUS_E_FAILURE;
	}

	/* Initialize the timer module */
	cdf_timer_module_init();

	/* Initialize bug reporting structure */
	cds_init_log_completion();

	/* Initialize the probe event */
	if (qdf_event_create(&gp_cds_context->ProbeEvent) != QDF_STATUS_SUCCESS) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
			  "%s: Unable to init probeEvent", __func__);
		CDF_ASSERT(0);
		return CDF_STATUS_E_FAILURE;
	}
	if (qdf_event_create(&(gp_cds_context->wmaCompleteEvent)) !=
	    QDF_STATUS_SUCCESS) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
			  "%s: Unable to init wmaCompleteEvent", __func__);
		CDF_ASSERT(0);
		goto err_probe_event;
	}

	/* Initialize the free message queue */
	cdf_status = cds_mq_init(&gp_cds_context->freeVosMq);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		/* Critical Error ...  Cannot proceed further */
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
			  "%s: Failed to initialize CDS free message queue",
			  __func__);
		CDF_ASSERT(0);
		goto err_wma_complete_event;
	}

	for (iter = 0; iter < CDS_CORE_MAX_MESSAGES; iter++) {
		(gp_cds_context->aMsgWrappers[iter]).pVosMsg =
			&(gp_cds_context->aMsgBuffers[iter]);
		INIT_LIST_HEAD(&gp_cds_context->aMsgWrappers[iter].msgNode);
		cds_mq_put(&gp_cds_context->freeVosMq,
			   &(gp_cds_context->aMsgWrappers[iter]));
	}

	/* Now Open the CDS Scheduler */
	cdf_status = cds_sched_open(gp_cds_context, &gp_cds_context->cdf_sched,
				    sizeof(cds_sched_context));

	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		/* Critical Error ...  Cannot proceed further */
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
			  "%s: Failed to open CDS Scheduler", __func__);
		CDF_ASSERT(0);
		goto err_msg_queue;
	}

	pHddCtx = (hdd_context_t *) (gp_cds_context->pHDDContext);
	if ((NULL == pHddCtx) || (NULL == pHddCtx->config)) {
		/* Critical Error ...  Cannot proceed further */
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
			  "%s: Hdd Context is Null", __func__);
		CDF_ASSERT(0);
		goto err_sched_close;
	}

	scn = cds_get_context(CDF_MODULE_ID_HIF);
	if (!scn) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
			  "%s: scn is null!", __func__);
		goto err_sched_close;
	}

	hdd_update_config(pHddCtx);

	ol_ctx = cds_get_context(CDF_MODULE_ID_BMI);
	/* Initialize BMI and Download firmware */
	cdf_status = bmi_download_firmware(ol_ctx);
	if (cdf_status != CDF_STATUS_SUCCESS) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
			  "BMI FIALED status:%d", cdf_status);
		goto err_bmi_close;
	}

	htcInfo.pContext = ol_ctx;
	htcInfo.TargetFailure = ol_target_failure;
	htcInfo.TargetSendSuspendComplete = wma_target_suspend_acknowledge;
	cdf_ctx = cds_get_context(CDF_MODULE_ID_CDF_DEVICE);

	/* Create HTC */
	gp_cds_context->htc_ctx =
		htc_create(scn, &htcInfo, cdf_ctx);
	if (!gp_cds_context->htc_ctx) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
			  "%s: Failed to Create HTC", __func__);
		goto err_bmi_close;
	}

	if (bmi_done(ol_ctx)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
			  "%s: Failed to complete BMI phase", __func__);
		goto err_htc_close;
	}

	/*
	** Need to open WMA first because it calls WDI_Init, which calls wpalOpen
	** The reason that is needed becasue cds_packet_open need to use PAL APIs
	*/

	/*Open the WMA module */
	cdf_mem_set(&mac_openParms, sizeof(mac_openParms), 0);
	/* UMA is supported in hardware for performing the
	** frame translation 802.11 <-> 802.3
	*/
	mac_openParms.frameTransRequired = 1;
	mac_openParms.driverType = eDRIVER_TYPE_PRODUCTION;
	mac_openParms.powersaveOffloadEnabled =
		pHddCtx->config->enablePowersaveOffload;
	mac_openParms.staDynamicDtim = pHddCtx->config->enableDynamicDTIM;
	mac_openParms.staModDtim = pHddCtx->config->enableModulatedDTIM;
	mac_openParms.staMaxLIModDtim = pHddCtx->config->fMaxLIModulatedDTIM;
	mac_openParms.wowEnable = pHddCtx->config->wowEnable;
	mac_openParms.maxWoWFilters = pHddCtx->config->maxWoWFilters;
	/* Here olIniInfo is used to store ini status of arp offload
	 * ns offload and others. Currently 1st bit is used for arp
	 * off load and 2nd bit for ns offload currently, rest bits are unused
	 */
	if (pHddCtx->config->fhostArpOffload)
		mac_openParms.olIniInfo = mac_openParms.olIniInfo | 0x1;
	if (pHddCtx->config->fhostNSOffload)
		mac_openParms.olIniInfo = mac_openParms.olIniInfo | 0x2;
	/*
	 * Copy the DFS Phyerr Filtering Offload status.
	 * This parameter reflects the value of the
	 * dfsPhyerrFilterOffload flag  as set in the ini.
	 */
	mac_openParms.dfsPhyerrFilterOffload =
		pHddCtx->config->fDfsPhyerrFilterOffload;
	if (pHddCtx->config->ssdp)
		mac_openParms.ssdp = pHddCtx->config->ssdp;
#ifdef FEATURE_WLAN_RA_FILTERING
	mac_openParms.RArateLimitInterval =
		pHddCtx->config->RArateLimitInterval;
	mac_openParms.IsRArateLimitEnabled =
		pHddCtx->config->IsRArateLimitEnabled;
#endif

	mac_openParms.apMaxOffloadPeers = pHddCtx->config->apMaxOffloadPeers;

	mac_openParms.apMaxOffloadReorderBuffs =
		pHddCtx->config->apMaxOffloadReorderBuffs;

	mac_openParms.apDisableIntraBssFwd =
		pHddCtx->config->apDisableIntraBssFwd;

	mac_openParms.dfsRadarPriMultiplier =
		pHddCtx->config->dfsRadarPriMultiplier;
	mac_openParms.reorderOffload = pHddCtx->config->reorderOffloadSupport;

	/* IPA micro controller data path offload resource config item */
	mac_openParms.ucOffloadEnabled = hdd_ipa_uc_is_enabled(pHddCtx);
	mac_openParms.ucTxBufCount = pHddCtx->config->IpaUcTxBufCount;
	mac_openParms.ucTxBufSize = pHddCtx->config->IpaUcTxBufSize;
	mac_openParms.ucRxIndRingCount = pHddCtx->config->IpaUcRxIndRingCount;
	mac_openParms.ucTxPartitionBase = pHddCtx->config->IpaUcTxPartitionBase;
	mac_openParms.max_scan = pHddCtx->config->max_scan_count;

	mac_openParms.ip_tcp_udp_checksum_offload =
			pHddCtx->config->enable_ip_tcp_udp_checksum_offload;
	mac_openParms.enable_rxthread = pHddCtx->config->enableRxThread;
	mac_openParms.ce_classify_enabled =
				pHddCtx->config->ce_classify_enabled;

#ifdef QCA_LL_TX_FLOW_CONTROL_V2
	mac_openParms.tx_flow_stop_queue_th =
				pHddCtx->config->TxFlowStopQueueThreshold;
	mac_openParms.tx_flow_start_queue_offset =
				pHddCtx->config->TxFlowStartQueueOffset;
#endif
	cds_set_nan_enable(&mac_openParms, pHddCtx);

	mac_openParms.tx_chain_mask_cck = pHddCtx->config->tx_chain_mask_cck;
	mac_openParms.self_gen_frm_pwr = pHddCtx->config->self_gen_frm_pwr;
	mac_openParms.maxStation = pHddCtx->config->maxNumberOfPeers;

	cdf_status = wma_open(gp_cds_context,
			      hdd_update_tgt_cfg,
			      hdd_dfs_indicate_radar, &mac_openParms);

	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		/* Critical Error ...  Cannot proceed further */
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
			  "%s: Failed to open WMA module", __func__);
		CDF_ASSERT(0);
		goto err_htc_close;
	}

	/* Number of peers limit differs in each chip version. If peer max
	 * limit configured in ini exceeds more than supported, WMA adjusts
	 * and keeps correct limit in mac_openParms.maxStation. So, make sure
	 * config entry pHddCtx->config->maxNumberOfPeers has adjusted value
	 */
	pHddCtx->config->maxNumberOfPeers = mac_openParms.maxStation;
	HTCHandle = cds_get_context(CDF_MODULE_ID_HTC);
	if (!HTCHandle) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
			  "%s: HTCHandle is null!", __func__);
		goto err_wma_close;
	}
	if (htc_wait_target(HTCHandle)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
			  "%s: Failed to complete BMI phase", __func__);
		goto err_wma_close;
	}

	/* Now proceed to open the MAC */

	/* UMA is supported in hardware for performing the
	 * frame translation 802.11 <-> 802.3
	 */
	mac_openParms.frameTransRequired = 1;

	sirStatus =
		mac_open(&(gp_cds_context->pMACContext), gp_cds_context->pHDDContext,
			 &mac_openParms);

	if (eSIR_SUCCESS != sirStatus) {
		/* Critical Error ...  Cannot proceed further */
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
			  "%s: Failed to open MAC", __func__);
		CDF_ASSERT(0);
		goto err_wma_close;
	}

	/* Now proceed to open the SME */
	cdf_status = sme_open(gp_cds_context->pMACContext);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		/* Critical Error ...  Cannot proceed further */
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
			  "%s: Failed to open SME", __func__);
		CDF_ASSERT(0);
		goto err_mac_close;
	}

	gp_cds_context->pdev_txrx_ctx =
		ol_txrx_pdev_alloc(gp_cds_context->cfg_ctx,
				    gp_cds_context->htc_ctx,
				    gp_cds_context->cdf_ctx);
	if (!gp_cds_context->pdev_txrx_ctx) {
		/* Critical Error ...  Cannot proceed further */
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
			  "%s: Failed to open TXRX", __func__);
		CDF_ASSERT(0);
		goto err_sme_close;
	}

	CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_INFO_HIGH,
		  "%s: CDS successfully Opened", __func__);

	return CDF_STATUS_SUCCESS;

err_sme_close:
	sme_close(gp_cds_context->pMACContext);

err_mac_close:
	mac_close(gp_cds_context->pMACContext);

err_wma_close:
	wma_close(gp_cds_context);

	wma_wmi_service_close(gp_cds_context);

err_htc_close:
	if (gp_cds_context->htc_ctx) {
		htc_destroy(gp_cds_context->htc_ctx);
		gp_cds_context->htc_ctx = NULL;
	}

err_bmi_close:
	bmi_cleanup(ol_ctx);

err_sched_close:
	cds_sched_close(gp_cds_context);

err_msg_queue:
	cds_mq_deinit(&gp_cds_context->freeVosMq);

err_wma_complete_event:
	qdf_event_destroy(&gp_cds_context->wmaCompleteEvent);

err_probe_event:
	qdf_event_destroy(&gp_cds_context->ProbeEvent);

	return CDF_STATUS_E_FAILURE;
} /* cds_open() */

/**
 * cds_pre_enable() - pre enable cds
 * @cds_context: CDS context
 *
 * Return: CDF status
 */
CDF_STATUS cds_pre_enable(v_CONTEXT_t cds_context)
{
	CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	p_cds_contextType p_cds_context = (p_cds_contextType) cds_context;
	void *scn;
	CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_INFO, "cds prestart");

	if (gp_cds_context != p_cds_context) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: Context mismatch", __func__);
		CDF_ASSERT(0);
		return CDF_STATUS_E_INVAL;
	}

	if (p_cds_context->pMACContext == NULL) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: MAC NULL context", __func__);
		CDF_ASSERT(0);
		return CDF_STATUS_E_INVAL;
	}

	if (p_cds_context->pWMAContext == NULL) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: WMA NULL context", __func__);
		CDF_ASSERT(0);
		return CDF_STATUS_E_INVAL;
	}

	scn = cds_get_context(CDF_MODULE_ID_HIF);
	if (!scn) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
			  "%s: scn is null!", __func__);
		return CDF_STATUS_E_FAILURE;
	}

	/* Reset wma wait event */
	qdf_event_reset(&gp_cds_context->wmaCompleteEvent);

	/*call WMA pre start */
	cdf_status = wma_pre_start(gp_cds_context);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_FATAL,
			  "Failed to WMA prestart");
		CDF_ASSERT(0);
		return CDF_STATUS_E_FAILURE;
	}

	/* Need to update time out of complete */
	qdf_status = qdf_wait_single_event(&gp_cds_context->wmaCompleteEvent,
					   CDS_WMA_TIMEOUT);
	if (qdf_status != QDF_STATUS_SUCCESS) {
		if (qdf_status == QDF_STATUS_E_TIMEOUT) {
			CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
				  "%s: Timeout occurred before WMA complete",
				  __func__);
		} else {
			CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
				  "%s: wma_pre_start reporting other error",
				  __func__);
		}
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: Test MC thread by posting a probe message to SYS",
			  __func__);
		wlan_sys_probe();

		CDF_ASSERT(0);
		return CDF_STATUS_E_FAILURE;
	}

	cdf_status = htc_start(gp_cds_context->htc_ctx);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_FATAL,
			  "Failed to Start HTC");
		CDF_ASSERT(0);
		return CDF_STATUS_E_FAILURE;
	}
	cdf_status = wma_wait_for_ready_event(gp_cds_context->pWMAContext);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
			  "Failed to get ready event from target firmware");
		htc_set_target_to_sleep(scn);
		htc_stop(gp_cds_context->htc_ctx);
		CDF_ASSERT(0);
		return CDF_STATUS_E_FAILURE;
	}

	if (ol_txrx_pdev_attach(gp_cds_context->pdev_txrx_ctx)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
			"Failed to attach pdev");
		htc_set_target_to_sleep(scn);
		htc_stop(gp_cds_context->htc_ctx);
		CDF_ASSERT(0);
		return CDF_STATUS_E_FAILURE;
	}

	htc_set_target_to_sleep(scn);

	return CDF_STATUS_SUCCESS;
}

/**
 * cds_enable() - start/enable cds module
 * @cds_context: CDS context
 *
 * Return: CDF status
 */
CDF_STATUS cds_enable(v_CONTEXT_t cds_context)
{
	CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tSirRetStatus sirStatus = eSIR_SUCCESS;
	p_cds_contextType p_cds_context = (p_cds_contextType) cds_context;
	tHalMacStartParameters halStartParams;

	CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_INFO,
		  "%s: Starting Libra SW", __func__);

	/* We support only one instance for now ... */
	if (gp_cds_context != p_cds_context) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: mismatch in context", __func__);
		return CDF_STATUS_E_FAILURE;
	}

	if ((p_cds_context->pWMAContext == NULL) ||
	    (p_cds_context->pMACContext == NULL)) {
		if (p_cds_context->pWMAContext == NULL)
			CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
				  "%s: WMA NULL context", __func__);
		else
			CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
				  "%s: MAC NULL context", __func__);

		return CDF_STATUS_E_FAILURE;
	}

	/* Start the wma */
	cdf_status = wma_start(p_cds_context);
	if (cdf_status != CDF_STATUS_SUCCESS) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: Failed to start wma", __func__);
		return CDF_STATUS_E_FAILURE;
	}
	CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_INFO,
		  "%s: wma correctly started", __func__);

	/* Start the MAC */
	cdf_mem_zero(&halStartParams,
		     sizeof(tHalMacStartParameters));

	/* Start the MAC */
	sirStatus =
		mac_start(p_cds_context->pMACContext, &halStartParams);

	if (eSIR_SUCCESS != sirStatus) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
			  "%s: Failed to start MAC", __func__);
		goto err_wma_stop;
	}

	CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_INFO,
		  "%s: MAC correctly started", __func__);

	/* START SME */
	cdf_status = sme_start(p_cds_context->pMACContext);

	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
			  "%s: Failed to start SME", __func__);
		goto err_mac_stop;
	}

	CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_INFO,
		  "%s: SME correctly started", __func__);

	if (ol_txrx_pdev_attach_target
		       (p_cds_context->pdev_txrx_ctx) != A_OK) {
	   CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
				"%s: Failed attach target", __func__);
	   goto err_sme_stop;
	}

	CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_INFO,
		  "TL correctly started");
	CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_INFO,
		  "%s: CDS Start is successful!!", __func__);

	return CDF_STATUS_SUCCESS;

err_sme_stop:
	sme_stop(p_cds_context->pMACContext, HAL_STOP_TYPE_SYS_RESET);

err_mac_stop:
	mac_stop(p_cds_context->pMACContext, HAL_STOP_TYPE_SYS_RESET);

err_wma_stop:
	qdf_event_reset(&(gp_cds_context->wmaCompleteEvent));
	cdf_status = wma_stop(p_cds_context, HAL_STOP_TYPE_RF_KILL);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: Failed to stop wma", __func__);
		CDF_ASSERT(CDF_IS_STATUS_SUCCESS(cdf_status));
		wma_setneedshutdown(cds_context);
	} else {
		qdf_status =
			qdf_wait_single_event(&(gp_cds_context->wmaCompleteEvent),
					      CDS_WMA_TIMEOUT);
		if (qdf_status != QDF_STATUS_SUCCESS) {
			if (qdf_status == QDF_STATUS_E_TIMEOUT) {
				CDF_TRACE(CDF_MODULE_ID_CDF,
					  CDF_TRACE_LEVEL_FATAL,
					  "%s: Timeout occurred before WMA_stop complete",
					  __func__);
			} else {
				CDF_TRACE(CDF_MODULE_ID_CDF,
					  CDF_TRACE_LEVEL_FATAL,
					  "%s: WMA_stop reporting other error",
					  __func__);
			}
			CDF_ASSERT(0);
			wma_setneedshutdown(cds_context);
		}
	}

	return CDF_STATUS_E_FAILURE;
} /* cds_enable() */

/**
 * cds_disable() - stop/disable cds module
 * @cds_context: CDS context
 *
 * Return: CDF status
 */
CDF_STATUS cds_disable(v_CONTEXT_t cds_context)
{
	CDF_STATUS cdf_status;

	/* wma_stop is called before the SYS so that the processing of target
	 * pending responses will not be handled during uninitialization of
	 * WLAN driver
	 */
	qdf_event_reset(&(gp_cds_context->wmaCompleteEvent));

	cdf_status = wma_stop(cds_context, HAL_STOP_TYPE_RF_KILL);

	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: Failed to stop wma", __func__);
		CDF_ASSERT(CDF_IS_STATUS_SUCCESS(cdf_status));
		wma_setneedshutdown(cds_context);
	}

	hif_disable_isr(((cds_context_type *) cds_context)->pHIFContext);
	hif_reset_soc(((cds_context_type *) cds_context)->pHIFContext);

	/* SYS STOP will stop SME and MAC */
	cdf_status = sys_stop(cds_context);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: Failed to stop SYS", __func__);
		CDF_ASSERT(CDF_IS_STATUS_SUCCESS(cdf_status));
	}

	return CDF_STATUS_SUCCESS;
}

/**
 * cds_close() - close cds module
 * @cds_context: CDS context
 *
 * Return: CDF status
 */
CDF_STATUS cds_close(v_CONTEXT_t cds_context)
{
	CDF_STATUS cdf_status;
	QDF_STATUS qdf_status;

	cdf_status = wma_wmi_work_close(cds_context);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
		 "%s: Failed to close wma_wmi_work", __func__);
		CDF_ASSERT(0);
	}

	if (gp_cds_context->htc_ctx) {
		htc_stop(gp_cds_context->htc_ctx);
		htc_destroy(gp_cds_context->htc_ctx);
		gp_cds_context->htc_ctx = NULL;
	}

	ol_txrx_pdev_detach(gp_cds_context->pdev_txrx_ctx, 1);
	cds_free_context(cds_context, CDF_MODULE_ID_TXRX,
			 gp_cds_context->pdev_txrx_ctx);

	cdf_status = sme_close(((p_cds_contextType) cds_context)->pMACContext);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: Failed to close SME", __func__);
		CDF_ASSERT(CDF_IS_STATUS_SUCCESS(cdf_status));
	}

	cdf_status = mac_close(((p_cds_contextType) cds_context)->pMACContext);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: Failed to close MAC", __func__);
		CDF_ASSERT(CDF_IS_STATUS_SUCCESS(cdf_status));
	}

	((p_cds_contextType) cds_context)->pMACContext = NULL;

	if (true == wma_needshutdown(cds_context)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
				  "%s: Failed to shutdown wma", __func__);
	} else {
		cdf_status = wma_close(cds_context);
		if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
			CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
				  "%s: Failed to close wma", __func__);
			CDF_ASSERT(CDF_IS_STATUS_SUCCESS(cdf_status));
		}
	}

	cdf_status = wma_wmi_service_close(cds_context);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: Failed to close wma_wmi_service", __func__);
		CDF_ASSERT(CDF_IS_STATUS_SUCCESS(cdf_status));
	}

	cds_mq_deinit(&((p_cds_contextType) cds_context)->freeVosMq);

	qdf_status = qdf_event_destroy(&gp_cds_context->wmaCompleteEvent);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: failed to destroy wmaCompleteEvent", __func__);
		CDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
	}

	qdf_status = qdf_event_destroy(&gp_cds_context->ProbeEvent);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: failed to destroy ProbeEvent", __func__);
		CDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
	}

	cds_deinit_log_completion();

	gp_cds_context->pHDDContext = NULL;

	return CDF_STATUS_SUCCESS;
}

/**
 * cds_get_context() - get context data area
 *
 * @moduleId: ID of the module who's context data is being retrived.
 *
 * Each module in the system has a context / data area that is allocated
 * and managed by CDS.  This API allows any user to get a pointer to its
 * allocated context data area from the CDS global context.
 *
 * Return: pointer to the context data area of the module ID
 *	   specified, or NULL if the context data is not allocated for
 *	   the module ID specified
 */
void *cds_get_context(CDF_MODULE_ID moduleId)
{
	void *pModContext = NULL;

	if (gp_cds_context == NULL) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: cds context pointer is null", __func__);
		return NULL;
	}

	switch (moduleId) {
	case CDF_MODULE_ID_HDD:
	{
		pModContext = gp_cds_context->pHDDContext;
		break;
	}

	case CDF_MODULE_ID_SME:
	case CDF_MODULE_ID_PE:
	{
		/* In all these cases, we just return the MAC Context */
		pModContext = gp_cds_context->pMACContext;
		break;
	}

	case CDF_MODULE_ID_WMA:
	{
		/* For wma module */
		pModContext = gp_cds_context->pWMAContext;
		break;
	}

	case CDF_MODULE_ID_CDF:
	{
		/* For SYS this is CDS itself */
		pModContext = gp_cds_context;
		break;
	}

	case CDF_MODULE_ID_HIF:
	{
		pModContext = gp_cds_context->pHIFContext;
		break;
	}

	case CDF_MODULE_ID_HTC:
	{
		pModContext = gp_cds_context->htc_ctx;
		break;
	}

	case CDF_MODULE_ID_CDF_DEVICE:
	{
		pModContext = gp_cds_context->cdf_ctx;
		break;
	}

	case CDF_MODULE_ID_BMI:
	{
		pModContext = gp_cds_context->g_ol_context;
		break;
	}

	case CDF_MODULE_ID_TXRX:
	{
		pModContext = gp_cds_context->pdev_txrx_ctx;
		break;
	}

	case CDF_MODULE_ID_CFG:
	{
		pModContext = gp_cds_context->cfg_ctx;
		break;
	}

	default:
	{
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: Module ID %i does not have its context maintained by CDS",
			  __func__, moduleId);
		CDF_ASSERT(0);
		return NULL;
	}
	}

	if (pModContext == NULL) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: Module ID %i context is Null", __func__,
			  moduleId);
	}

	return pModContext;
} /* cds_get_context() */

/**
 * cds_get_global_context() - get CDS global Context
 *
 * This API allows any user to get the CDS Global Context pointer from a
 * module context data area.
 *
 * Return: pointer to the CDS global context, NULL if the function is
 *	   unable to retreive the CDS context.
 */
v_CONTEXT_t cds_get_global_context(void)
{
	if (gp_cds_context == NULL) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: global cds context is NULL", __func__);
	}

	return gp_cds_context;
} /* cds_get_global_context() */

/**
 * cds_get_driver_state() - Get current driver state
 *
 * This API returns current driver state stored in global context.
 *
 * Return: Driver state enum
 */
enum cds_driver_state cds_get_driver_state(void)
{
	if (gp_cds_context == NULL) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: global cds context is NULL", __func__);

		return CDS_DRIVER_STATE_UNINITIALIZED;
	}

	return gp_cds_context->driver_state;
}

/**
 * cds_set_driver_state() - Set current driver state
 * @state:	Driver state to be set to.
 *
 * This API sets driver state to state. This API only sets the state and doesn't
 * clear states, please make sure to use cds_clear_driver_state to clear any
 * state if required.
 *
 * Return: None
 */
void cds_set_driver_state(enum cds_driver_state state)
{
	if (gp_cds_context == NULL) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: global cds context is NULL: %x", __func__,
			  state);

		return;
	}

	gp_cds_context->driver_state |= state;
}

/**
 * cds_clear_driver_state() - Clear current driver state
 * @state:	Driver state to be cleared.
 *
 * This API clears driver state. This API only clears the state, please make
 * sure to use cds_set_driver_state to set any new states.
 *
 * Return: None
 */
void cds_clear_driver_state(enum cds_driver_state state)
{
	if (gp_cds_context == NULL) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: global cds context is NULL: %x", __func__,
			  state);

		return;
	}

	gp_cds_context->driver_state &= ~state;
}

/**
 * cds_alloc_context() - allocate a context within the CDS global Context
 * @p_cds_context: pointer to the global Vos context
 * @moduleId: module ID who's context area is being allocated.
 * @ppModuleContext: pointer to location where the pointer to the
 *	allocated context is returned. Note this output pointer
 *	is valid only if the API returns CDF_STATUS_SUCCESS
 * @param size: size of the context area to be allocated.
 *
 * This API allows any user to allocate a user context area within the
 * CDS Global Context.
 *
 * Return: CDF status
 */
CDF_STATUS cds_alloc_context(void *p_cds_context, CDF_MODULE_ID moduleID,
			     void **ppModuleContext, uint32_t size)
{
	void **pGpModContext = NULL;

	if (p_cds_context == NULL) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: cds context is null", __func__);
		return CDF_STATUS_E_FAILURE;
	}

	if ((gp_cds_context != p_cds_context) || (ppModuleContext == NULL)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: context mismatch or null param passed",
			  __func__);
		return CDF_STATUS_E_FAILURE;
	}

	switch (moduleID) {
	case CDF_MODULE_ID_WMA:
	{
		pGpModContext = &(gp_cds_context->pWMAContext);
		break;
	}

	case CDF_MODULE_ID_HIF:
	{
		pGpModContext = &(gp_cds_context->pHIFContext);
		break;
	}

	case CDF_MODULE_ID_BMI:
	{
		pGpModContext = &(gp_cds_context->g_ol_context);
		break;
	}

	case CDF_MODULE_ID_EPPING:
	case CDF_MODULE_ID_SME:
	case CDF_MODULE_ID_PE:
	case CDF_MODULE_ID_HDD:
	case CDF_MODULE_ID_HDD_SOFTAP:
	default:
	{
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: Module ID %i "
			  "does not have its context allocated by CDS",
			  __func__, moduleID);
		CDF_ASSERT(0);
		return CDF_STATUS_E_INVAL;
	}
	}

	if (NULL != *pGpModContext) {
		/* Context has already been allocated!
		 * Prevent double allocation
		 */
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: Module ID %i context has already been allocated",
			  __func__, moduleID);
		return CDF_STATUS_E_EXISTS;
	}

	/* Dynamically allocate the context for module */

	*ppModuleContext = cdf_mem_malloc(size);

	if (*ppModuleContext == NULL) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: Failed to " "allocate Context for module ID %i",
			  __func__, moduleID);
		CDF_ASSERT(0);
		return CDF_STATUS_E_NOMEM;
	}

	if (moduleID == CDF_MODULE_ID_TLSHIM)
		cdf_mem_zero(*ppModuleContext, size);

	*pGpModContext = *ppModuleContext;

	return CDF_STATUS_SUCCESS;
} /* cds_alloc_context() */

/**
 * cds_set_context() - API to set context in global CDS Context
 * @moduleID: Module ID
 * @context: Pointer to the Module Context
 *
 * API to set a MODULE Context in gloabl CDS Context
 *
 * Return: CDF_STATUS
 */
CDF_STATUS cds_set_context(CDF_MODULE_ID module_id, void *context)
{
	p_cds_contextType p_cds_context = cds_get_global_context();

	if (!p_cds_context) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "cds context is Invald");
		return CDF_STATUS_NOT_INITIALIZED;
	}

	switch (module_id) {
	case CDF_MODULE_ID_HIF:
		p_cds_context->pHIFContext = context;
		break;
	default:
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: Module ID %i does not have its context "
			  "allocated by CDS", __func__, module_id);
		CDF_ASSERT(0);
		return CDF_STATUS_E_INVAL;
	}

	return CDF_STATUS_SUCCESS;
}

/**
 * cds_free_context() - free an allocated context within the
 *			CDS global Context
 * @p_cds_context: pointer to the global Vos context
 * @moduleId: module ID who's context area is being free
 * @pModuleContext: pointer to module context area to be free'd.
 *
 *  This API allows a user to free the user context area within the
 *  CDS Global Context.
 *
 * Return: CDF status
 */
CDF_STATUS cds_free_context(void *p_cds_context, CDF_MODULE_ID moduleID,
			    void *pModuleContext)
{
	void **pGpModContext = NULL;

	if ((p_cds_context == NULL) || (gp_cds_context != p_cds_context) ||
	    (pModuleContext == NULL)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: Null params or context mismatch", __func__);
		return CDF_STATUS_E_FAILURE;
	}

	switch (moduleID) {
	case CDF_MODULE_ID_WMA:
	{
		pGpModContext = &(gp_cds_context->pWMAContext);
		break;
	}

	case CDF_MODULE_ID_HIF:
	{
		pGpModContext = &(gp_cds_context->pHIFContext);
		break;
	}

	case CDF_MODULE_ID_TXRX:
	{
		pGpModContext = &(gp_cds_context->pdev_txrx_ctx);
		break;
	}

	case CDF_MODULE_ID_BMI:
	{
		pGpModContext = &(gp_cds_context->g_ol_context);
		break;
	}

	case CDF_MODULE_ID_EPPING:
	case CDF_MODULE_ID_HDD:
	case CDF_MODULE_ID_SME:
	case CDF_MODULE_ID_PE:
	case CDF_MODULE_ID_HDD_SOFTAP:
	default:
	{
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: Module ID %i "
			  "does not have its context allocated by CDS",
			  __func__, moduleID);
		CDF_ASSERT(0);
		return CDF_STATUS_E_INVAL;
	}
	}

	if (NULL == *pGpModContext) {
		/* Context has not been allocated or freed already! */
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: Module ID %i "
			  "context has not been allocated or freed already",
			  __func__, moduleID);
		return CDF_STATUS_E_FAILURE;
	}

	if (*pGpModContext != pModuleContext) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: pGpModContext != pModuleContext", __func__);
		return CDF_STATUS_E_FAILURE;
	}

	if (pModuleContext != NULL)
		cdf_mem_free(pModuleContext);

	*pGpModContext = NULL;

	return CDF_STATUS_SUCCESS;
} /* cds_free_context() */

/**
 * cds_mq_post_message() - post a message to a message queue
 * @msgQueueId: identifies the message queue upon which the message
 *	will be posted.
 * @message: a pointer to a message buffer. Memory for this message
 *	buffer is allocated by the caller and free'd by the CDF after the
 *	message is posted to the message queue.  If the consumer of the
 *	message needs anything in this message, it needs to copy the contents
 *	before returning from the message queue handler.
 *
 * Return: CDF status
 */
CDF_STATUS cds_mq_post_message(CDS_MQ_ID msgQueueId, cds_msg_t *pMsg)
{
	p_cds_mq_type pTargetMq = NULL;
	p_cds_msg_wrapper pMsgWrapper = NULL;
	uint32_t debug_count = 0;

	if ((gp_cds_context == NULL) || (pMsg == NULL)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: Null params or global cds context is null",
			  __func__);
		CDF_ASSERT(0);
		return CDF_STATUS_E_FAILURE;
	}

	switch (msgQueueId) {
	/* Message Queue ID for messages bound for SME */
	case CDS_MQ_ID_SME:
	{
		pTargetMq = &(gp_cds_context->cdf_sched.smeMcMq);
		break;
	}

	/* Message Queue ID for messages bound for PE */
	case CDS_MQ_ID_PE:
	{
		pTargetMq = &(gp_cds_context->cdf_sched.peMcMq);
		break;
	}

	/* Message Queue ID for messages bound for wma */
	case CDS_MQ_ID_WMA:
	{
		pTargetMq = &(gp_cds_context->cdf_sched.wmaMcMq);
		break;
	}

	/* Message Queue ID for messages bound for the SYS module */
	case CDS_MQ_ID_SYS:
	{
		pTargetMq = &(gp_cds_context->cdf_sched.sysMcMq);
		break;
	}

	default:
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  ("%s: Trying to queue msg into unknown MC Msg queue ID %d"),
			  __func__, msgQueueId);

		return CDF_STATUS_E_FAILURE;
	}

	CDF_ASSERT(NULL != pTargetMq);
	if (pTargetMq == NULL) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: pTargetMq == NULL", __func__);
		return CDF_STATUS_E_FAILURE;
	}

	/* Try and get a free Msg wrapper */
	pMsgWrapper = cds_mq_get(&gp_cds_context->freeVosMq);

	if (NULL == pMsgWrapper) {
		debug_count = atomic_inc_return(&cds_wrapper_empty_count);
		if (1 == debug_count)
			CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
				"%s: CDS Core run out of message wrapper %d",
				__func__, debug_count);

		if (CDS_WRAPPER_MAX_FAIL_COUNT == debug_count)
			CDF_BUG(0);

		return CDF_STATUS_E_RESOURCES;
	}

	atomic_set(&cds_wrapper_empty_count, 0);

	/* Copy the message now */
	cdf_mem_copy((void *)pMsgWrapper->pVosMsg,
		     (void *)pMsg, sizeof(cds_msg_t));

	cds_mq_put(pTargetMq, pMsgWrapper);

	set_bit(MC_POST_EVENT_MASK, &gp_cds_context->cdf_sched.mcEventFlag);
	wake_up_interruptible(&gp_cds_context->cdf_sched.mcWaitQueue);

	return CDF_STATUS_SUCCESS;
} /* cds_mq_post_message() */

/**
 * cds_sys_probe_thread_cback() -  probe mc thread callback
 * @pUserData: pointer to user data
 *
 * Return: none
 */
void cds_sys_probe_thread_cback(void *pUserData)
{
	if (gp_cds_context != pUserData) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: gp_cds_context != pUserData", __func__);
		return;
	}

	if (qdf_event_set(&gp_cds_context->ProbeEvent) != QDF_STATUS_SUCCESS) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: qdf_event_set failed", __func__);
		return;
	}
} /* cds_sys_probe_thread_cback() */

/**
 * cds_wma_complete_cback() - wma complete callback
 * @pUserData: pointer to user data
 *
 * Return: none
 */
void cds_wma_complete_cback(void *pUserData)
{
	if (gp_cds_context != pUserData) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: gp_cds_context != pUserData", __func__);
		return;
	}

	if (qdf_event_set(&gp_cds_context->wmaCompleteEvent) !=
	    QDF_STATUS_SUCCESS) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: qdf_event_set failed", __func__);
		return;
	}
} /* cds_wma_complete_cback() */

/**
 * cds_core_return_msg() - return core message
 * @pVContext: pointer to cds context
 * @pMsgWrapper: pointer to message wrapper
 *
 * Return: none
 */
void cds_core_return_msg(void *pVContext, p_cds_msg_wrapper pMsgWrapper)
{
	p_cds_contextType p_cds_context = (p_cds_contextType) pVContext;

	CDF_ASSERT(gp_cds_context == p_cds_context);

	if (gp_cds_context != p_cds_context) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: gp_cds_context != p_cds_context", __func__);
		return;
	}

	CDF_ASSERT(NULL != pMsgWrapper);

	if (pMsgWrapper == NULL) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: pMsgWrapper == NULL in function", __func__);
		return;
	}

	/*
	** Return the message on the free message queue
	*/
	INIT_LIST_HEAD(&pMsgWrapper->msgNode);
	cds_mq_put(&p_cds_context->freeVosMq, pMsgWrapper);
} /* cds_core_return_msg() */


/**
 * cds_shutdown() - shutdown CDS
 * @cds_context: global cds context
 *
 * Return: CDF status
 */
CDF_STATUS cds_shutdown(v_CONTEXT_t cds_context)
{
	CDF_STATUS cdf_status;
	QDF_STATUS qdf_status;
	tpAniSirGlobal pmac = (((p_cds_contextType)cds_context)->pMACContext);

	ol_txrx_pdev_detach(gp_cds_context->pdev_txrx_ctx, 1);
	cds_free_context(cds_context, CDF_MODULE_ID_TXRX,
			 gp_cds_context->pdev_txrx_ctx);

	cdf_status = sme_close(((p_cds_contextType) cds_context)->pMACContext);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: Failed to close SME", __func__);
		CDF_ASSERT(CDF_IS_STATUS_SUCCESS(cdf_status));
	}
	/*
	 * CAC timer will be initiated and started only when SAP starts on
	 * DFS channel and it will be stopped and destroyed immediately once the
	 * radar detected or timedout. So as per design CAC timer should be
	 * destroyed after stop
	 */
	if (pmac->sap.SapDfsInfo.is_dfs_cac_timer_running) {
		cdf_mc_timer_stop(&pmac->sap.SapDfsInfo.sap_dfs_cac_timer);
		pmac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
		cdf_mc_timer_destroy(&pmac->sap.SapDfsInfo.sap_dfs_cac_timer);
	}

	cdf_status = mac_close(((p_cds_contextType) cds_context)->pMACContext);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: Failed to close MAC", __func__);
		CDF_ASSERT(CDF_IS_STATUS_SUCCESS(cdf_status));
	}

	((p_cds_contextType) cds_context)->pMACContext = NULL;

	if (false == wma_needshutdown(cds_context)) {

		cdf_status = wma_close(cds_context);
		if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
			CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
				  "%s: Failed to close wma!", __func__);
			CDF_ASSERT(CDF_IS_STATUS_SUCCESS(cdf_status));
		}
	}

	cdf_status = wma_wmi_work_close(cds_context);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
		"%s: Failed to close wma_wmi_work!", __func__);
		CDF_ASSERT(0);
	}

	if (gp_cds_context->htc_ctx) {
		htc_stop(gp_cds_context->htc_ctx);
		htc_destroy(gp_cds_context->htc_ctx);
		gp_cds_context->htc_ctx = NULL;
	}

	cdf_status = wma_wmi_service_close(cds_context);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: Failed to close wma_wmi_service!", __func__);
		CDF_ASSERT(CDF_IS_STATUS_SUCCESS(cdf_status));
	}

	cds_mq_deinit(&((p_cds_contextType) cds_context)->freeVosMq);

	qdf_status = qdf_event_destroy(&gp_cds_context->wmaCompleteEvent);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: failed to destroy wmaCompleteEvent", __func__);
		CDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
	}

	qdf_status = qdf_event_destroy(&gp_cds_context->ProbeEvent);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "%s: failed to destroy ProbeEvent", __func__);
		CDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
	}

	return CDF_STATUS_SUCCESS;
}

/**
 * cds_get_vdev_types() - get vdev type
 * @mode: mode
 * @type: type
 * @sub_type: sub_type
 *
 * Return: WMI vdev type
 */
CDF_STATUS cds_get_vdev_types(enum tCDF_ADAPTER_MODE mode, uint32_t *type,
			      uint32_t *sub_type)
{
	CDF_STATUS status = CDF_STATUS_SUCCESS;
	*type = 0;
	*sub_type = 0;

	switch (mode) {
	case CDF_STA_MODE:
		*type = WMI_VDEV_TYPE_STA;
		break;
	case CDF_SAP_MODE:
		*type = WMI_VDEV_TYPE_AP;
		break;
	case CDF_P2P_DEVICE_MODE:
		*type = WMI_VDEV_TYPE_AP;
		*sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE;
		break;
	case CDF_P2P_CLIENT_MODE:
		*type = WMI_VDEV_TYPE_STA;
		*sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT;
		break;
	case CDF_P2P_GO_MODE:
		*type = WMI_VDEV_TYPE_AP;
		*sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO;
		break;
	case CDF_OCB_MODE:
		*type = WMI_VDEV_TYPE_OCB;
		break;
	default:
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			  "Invalid device mode %d", mode);
		status = CDF_STATUS_E_INVAL;
		break;
	}
	return status;
}

/**
 * cds_flush_work() - flush pending works
 * @work: pointer to work
 *
 * Return: none
 */
void cds_flush_work(void *work)
{
#if defined (CONFIG_CNSS)
	cnss_flush_work(work);
#elif defined (WLAN_OPEN_SOURCE)
	cancel_work_sync(work);
#endif
}

/**
 * cds_flush_delayed_work() - flush delayed works
 * @dwork: pointer to delayed work
 *
 * Return: none
 */
void cds_flush_delayed_work(void *dwork)
{
#if defined (CONFIG_CNSS)
	cnss_flush_delayed_work(dwork);
#elif defined (WLAN_OPEN_SOURCE)
	cancel_delayed_work_sync(dwork);
#endif
}

/**
 * cds_is_packet_log_enabled() - check if packet log is enabled
 *
 * Return: true if packet log is enabled else false
 */
bool cds_is_packet_log_enabled(void)
{
	hdd_context_t *pHddCtx;

	pHddCtx = (hdd_context_t *) (gp_cds_context->pHDDContext);
	if ((NULL == pHddCtx) || (NULL == pHddCtx->config)) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
			  "%s: Hdd Context is Null", __func__);
		return false;
	}

	return pHddCtx->config->enablePacketLog;
}

/**
 * cds_trigger_recovery() - trigger self recovery
 *
 * Return: none
 */
void cds_trigger_recovery(void)
{
	tp_wma_handle wma_handle = cds_get_context(CDF_MODULE_ID_WMA);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	if (!wma_handle) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			"WMA context is invald!");
		return;
	}

	wma_crash_inject(wma_handle, RECOVERY_SIM_SELF_RECOVERY, 0);

	status = qdf_wait_single_event(&wma_handle->recovery_event,
		WMA_CRASH_INJECT_TIMEOUT);

	if (QDF_STATUS_SUCCESS != status) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			"CRASH_INJECT command is timed out!");
 #ifdef CONFIG_CNSS
		if (cds_is_driver_recovering()) {
			CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
				"Recovery is in progress, ignore!");
			return;
		}
		cds_set_recovery_in_progress(true);
		cnss_schedule_recovery_work();
 #endif

		return;
	}
}

/**
 * cds_get_monotonic_boottime() - Get kernel boot time.
 *
 * Return: Time in microseconds
 */

uint64_t cds_get_monotonic_boottime(void)
{
#ifdef CONFIG_CNSS
	struct timespec ts;

	cnss_get_monotonic_boottime(&ts);
	return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
#else
	return ((uint64_t)cdf_system_ticks_to_msecs(cdf_system_ticks()) *
			 1000);
#endif
}

/**
 * cds_set_wakelock_logging() - Logging of wakelock enabled/disabled
 * @value: Boolean value
 *
 * This function is used to set the flag which will indicate whether
 * logging of wakelock is enabled or not
 *
 * Return: None
 */
void cds_set_wakelock_logging(bool value)
{
	p_cds_contextType p_cds_context;

	p_cds_context = cds_get_global_context();
	if (!p_cds_context) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
				"cds context is Invald");
		return;
	}
	p_cds_context->is_wakelock_log_enabled = value;
}

/**
 * cds_is_wakelock_enabled() - Check if logging of wakelock is enabled/disabled
 * @value: Boolean value
 *
 * This function is used to check whether logging of wakelock is enabled or not
 *
 * Return: true if logging of wakelock is enabled
 */
bool cds_is_wakelock_enabled(void)
{
	p_cds_contextType p_cds_context;

	p_cds_context = cds_get_global_context();
	if (!p_cds_context) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
				"cds context is Invald");
		return false;
	}
	return p_cds_context->is_wakelock_log_enabled;
}

/**
 * cds_set_ring_log_level() - Sets the log level of a particular ring
 * @ring_id: ring_id
 * @log_levelvalue: Log level specificed
 *
 * This function converts HLOS values to driver log levels and sets the log
 * level of a particular ring accordingly.
 *
 * Return: None
 */
void cds_set_ring_log_level(uint32_t ring_id, uint32_t log_level)
{
	p_cds_contextType p_cds_context;
	uint32_t log_val;

	p_cds_context = cds_get_global_context();
	if (!p_cds_context) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
				"%s: cds context is Invald", __func__);
		return;
	}

	switch (log_level) {
	case LOG_LEVEL_NO_COLLECTION:
		log_val = WLAN_LOG_LEVEL_OFF;
		break;
	case LOG_LEVEL_NORMAL_COLLECT:
		log_val = WLAN_LOG_LEVEL_NORMAL;
		break;
	case LOG_LEVEL_ISSUE_REPRO:
		log_val = WLAN_LOG_LEVEL_REPRO;
		break;
	case LOG_LEVEL_ACTIVE:
	default:
		log_val = WLAN_LOG_LEVEL_ACTIVE;
		break;
	}

	if (ring_id == RING_ID_WAKELOCK) {
		p_cds_context->wakelock_log_level = log_val;
		return;
	} else if (ring_id == RING_ID_CONNECTIVITY) {
		p_cds_context->connectivity_log_level = log_val;
		return;
	} else if (ring_id == RING_ID_PER_PACKET_STATS) {
		p_cds_context->packet_stats_log_level = log_val;
		return;
	} else if (ring_id == RING_ID_DRIVER_DEBUG) {
		p_cds_context->driver_debug_log_level = log_val;
		return;
	} else if (ring_id == RING_ID_FIRMWARE_DEBUG) {
		p_cds_context->fw_debug_log_level = log_val;
		return;
	}
}

/**
 * cds_get_ring_log_level() - Get the a ring id's log level
 * @ring_id: Ring id
 *
 * Fetch and return the log level corresponding to a ring id
 *
 * Return: Log level corresponding to the ring ID
 */
enum wifi_driver_log_level cds_get_ring_log_level(uint32_t ring_id)
{
	p_cds_contextType p_cds_context;

	p_cds_context = cds_get_global_context();
	if (!p_cds_context) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
				"%s: cds context is Invald", __func__);
		return WLAN_LOG_LEVEL_OFF;
	}

	if (ring_id == RING_ID_WAKELOCK)
		return p_cds_context->wakelock_log_level;
	else if (ring_id == RING_ID_CONNECTIVITY)
		return p_cds_context->connectivity_log_level;
	else if (ring_id == RING_ID_PER_PACKET_STATS)
		return p_cds_context->packet_stats_log_level;
	else if (ring_id == RING_ID_DRIVER_DEBUG)
		return p_cds_context->driver_debug_log_level;
	else if (ring_id == RING_ID_FIRMWARE_DEBUG)
		return p_cds_context->fw_debug_log_level;

	return WLAN_LOG_LEVEL_OFF;
}

/**
 * cds_set_multicast_logging() - Set mutlicast logging value
 * @value: Value of multicast logging
 *
 * Set the multicast logging value which will indicate
 * whether to multicast host and fw messages even
 * without any registration by userspace entity
 *
 * Return: None
 */
void cds_set_multicast_logging(uint8_t value)
{
	cds_multicast_logging = value;
}

/**
 * cds_is_multicast_logging() - Get multicast logging value
 *
 * Get the multicast logging value which will indicate
 * whether to multicast host and fw messages even
 * without any registration by userspace entity
 *
 * Return: 0 - Multicast logging disabled, 1 - Multicast logging enabled
 */
uint8_t cds_is_multicast_logging(void)
{
	return cds_multicast_logging;
}

/*
 * cds_init_log_completion() - Initialize log param structure
 *
 * This function is used to initialize the logging related
 * parameters
 *
 * Return: None
 */
void cds_init_log_completion(void)
{
	p_cds_contextType p_cds_context;

	p_cds_context = cds_get_global_context();
	if (!p_cds_context) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
				"%s: cds context is Invalid", __func__);
		return;
	}

	p_cds_context->log_complete.is_fatal = WLAN_LOG_TYPE_NON_FATAL;
	p_cds_context->log_complete.indicator = WLAN_LOG_INDICATOR_UNUSED;
	p_cds_context->log_complete.reason_code = WLAN_LOG_REASON_CODE_UNUSED;
	p_cds_context->log_complete.is_report_in_progress = false;
	/* Attempting to initialize an already initialized lock
	 * results in a failure. This must be ok here.
	 */
	cdf_spinlock_init(&p_cds_context->bug_report_lock);
}

/**
 * cds_deinit_log_completion() - Deinitialize log param structure
 *
 * This function is used to deinitialize the logging related
 * parameters
 *
 * Return: None
 */
void cds_deinit_log_completion(void)
{
	p_cds_contextType p_cds_context;

	p_cds_context = cds_get_global_context();
	if (!p_cds_context) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
				"%s: cds context is Invalid", __func__);
		return;
	}

	cdf_spinlock_destroy(&p_cds_context->bug_report_lock);
}

/**
 * cds_set_log_completion() - Store the logging params
 * @is_fatal: Indicates if the event triggering bug report is fatal or not
 * @indicator: Source which trigerred the bug report
 * @reason_code: Reason for triggering bug report
 *
 * This function is used to set the logging parameters based on the
 * caller
 *
 * Return: 0 if setting of params is successful
 */
CDF_STATUS cds_set_log_completion(uint32_t is_fatal,
		uint32_t indicator,
		uint32_t reason_code)
{
	p_cds_contextType p_cds_context;

	p_cds_context = cds_get_global_context();
	if (!p_cds_context) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
				"%s: cds context is Invalid", __func__);
		return CDF_STATUS_E_FAILURE;
	}

	cdf_spinlock_acquire(&p_cds_context->bug_report_lock);
	p_cds_context->log_complete.is_fatal = is_fatal;
	p_cds_context->log_complete.indicator = indicator;
	p_cds_context->log_complete.reason_code = reason_code;
	p_cds_context->log_complete.is_report_in_progress = true;
	cdf_spinlock_release(&p_cds_context->bug_report_lock);
	return CDF_STATUS_SUCCESS;
}

/**
 * cds_get_log_completion() - Get the logging related params
 * @is_fatal: Indicates if the event triggering bug report is fatal or not
 * @indicator: Source which trigerred the bug report
 * @reason_code: Reason for triggering bug report
 *
 * This function is used to get the logging related parameters
 *
 * Return: None
 */
void cds_get_log_completion(uint32_t *is_fatal,
		uint32_t *indicator,
		uint32_t *reason_code)
{
	p_cds_contextType p_cds_context;

	p_cds_context = cds_get_global_context();
	if (!p_cds_context) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
				"%s: cds context is Invalid", __func__);
		return;
	}

	cdf_spinlock_acquire(&p_cds_context->bug_report_lock);
	*is_fatal =  p_cds_context->log_complete.is_fatal;
	*indicator = p_cds_context->log_complete.indicator;
	*reason_code = p_cds_context->log_complete.reason_code;
	p_cds_context->log_complete.is_report_in_progress = false;
	cdf_spinlock_release(&p_cds_context->bug_report_lock);
}

/**
 * cds_is_log_report_in_progress() - Check if bug reporting is in progress
 *
 * This function is used to check if the bug reporting is already in progress
 *
 * Return: true if the bug reporting is in progress
 */
bool cds_is_log_report_in_progress(void)
{
	p_cds_contextType p_cds_context;

	p_cds_context = cds_get_global_context();
	if (!p_cds_context) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
				"%s: cds context is Invalid", __func__);
		return true;
	}
	return p_cds_context->log_complete.is_report_in_progress;
}

/**
 * cds_flush_logs() - Report fatal event to userspace
 * @is_fatal: Indicates if the event triggering bug report is fatal or not
 * @indicator: Source which trigerred the bug report
 * @reason_code: Reason for triggering bug report
 *
 * This function sets the log related params and send the WMI command to the
 * FW to flush its logs. On receiving the flush completion event from the FW
 * the same will be conveyed to userspace
 *
 * Return: 0 on success
 */
CDF_STATUS cds_flush_logs(uint32_t is_fatal,
		uint32_t indicator,
		uint32_t reason_code)
{
	uint32_t ret;
	CDF_STATUS status;

	p_cds_contextType p_cds_context;

	p_cds_context = cds_get_global_context();
	if (!p_cds_context) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
				"%s: cds context is Invalid", __func__);
		return CDF_STATUS_E_FAILURE;
	}

	if (cds_is_log_report_in_progress() == true) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
				"%s: Bug report already in progress - dropping! type:%d, indicator=%d reason_code=%d",
				__func__, is_fatal, indicator, reason_code);
		return CDF_STATUS_E_FAILURE;
	}

	status = cds_set_log_completion(is_fatal, indicator, reason_code);
	if (CDF_STATUS_SUCCESS != status) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
			"%s: Failed to set log trigger params", __func__);
		return CDF_STATUS_E_FAILURE;
	}

	CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_INFO,
			"%s: Triggering bug report: type:%d, indicator=%d reason_code=%d",
			__func__, is_fatal, indicator, reason_code);

	ret = sme_send_flush_logs_cmd_to_fw(p_cds_context->pMACContext);
	if (0 != ret) {
		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
				"%s: Failed to send flush FW log", __func__);
		cds_init_log_completion();
		return CDF_STATUS_E_FAILURE;
	}

	return CDF_STATUS_SUCCESS;
}

/**
 * cds_logging_set_fw_flush_complete() - Wrapper for FW log flush completion
 *
 * This function is used to send signal to the logger thread to indicate
 * that the flushing of FW logs is complete by the FW
 *
 * Return: None
 *
 */
void cds_logging_set_fw_flush_complete(void)
{
	wlan_logging_set_fw_flush_complete();
}
