/*
 * Copyright (c) 2012-2018 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.
 */

/**=========================================================================

  \file  vos_api.c

  \brief Stub file for all virtual Operating System Services (vOSS) APIs

  ========================================================================*/
 /*===========================================================================

                       EDIT HISTORY FOR FILE


  This section contains comments describing changes made to the module.
  Notice that changes are listed in reverse chronological order.


  $Header:$ $DateTime: $ $Author: $


  when        who    what, where, why
  --------    ---    --------------------------------------------------------
  03/29/09    kanand     Created module.
===========================================================================*/

/*--------------------------------------------------------------------------
  Include Files
  ------------------------------------------------------------------------*/
#include <vos_mq.h>
#include "vos_sched.h"
#include <vos_api.h>
#include "sirTypes.h"
#include "sirApi.h"
#include "sirMacProtDef.h"
#include "sme_Api.h"
#include "macInitApi.h"
#include "wlan_qct_sys.h"
#include "wlan_qct_tl.h"
#include "wlan_hdd_misc.h"
#include "i_vos_packet.h"
#include "vos_nvitem.h"
#include "wlan_qct_wda.h"
#include "wlan_hdd_main.h"
#include "wlan_hdd_tsf.h"
#include <linux/vmalloc.h>
#include "wlan_hdd_cfg80211.h"
#include "vos_cnss.h"

#include "sapApi.h"
#include "vos_trace.h"
#include "adf_trace.h"



#include "bmi.h"
#include "ol_fw.h"
#include "ol_if_athvar.h"
#if defined(HIF_PCI)
#include "if_pci.h"
#elif defined(HIF_USB)
#include "if_usb.h"
#elif defined(HIF_SDIO)
#include "if_ath_sdio.h"
#endif
#include "vos_utils.h"
#include "wlan_logging_sock_svc.h"
#include "wma.h"

#include "vos_utils.h"

/*---------------------------------------------------------------------------
 * Preprocessor Definitions and Constants
 * ------------------------------------------------------------------------*/
/* Approximate amount of time to wait for WDA to stop WDI */
#define VOS_WDA_STOP_TIMEOUT WDA_STOP_TIMEOUT

/* Approximate amount of time to wait for WDA to issue a DUMP req */
#define VOS_WDA_RESP_TIMEOUT WDA_STOP_TIMEOUT

/* Maximum number of vos message queue get wrapper failures to cause panic */
#define VOS_WRAPPER_MAX_FAIL_COUNT (VOS_CORE_MAX_MESSAGES * 3)

/*---------------------------------------------------------------------------
 * Data definitions
 * ------------------------------------------------------------------------*/
static VosContextType  gVosContext;
static pVosContextType gpVosContext;

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

static uint8_t vos_multicast_logging;
/*---------------------------------------------------------------------------
 * Forward declaration
 * ------------------------------------------------------------------------*/
v_VOID_t vos_sys_probe_thread_cback ( v_VOID_t *pUserData );

v_VOID_t vos_core_return_msg(v_PVOID_t pVContext, pVosMsgWrapper pMsgWrapper);

v_VOID_t vos_fetch_tl_cfg_parms ( WLANTL_ConfigInfoType *pTLConfig,
    hdd_config_t * pConfig );


/*---------------------------------------------------------------------------

  \brief vos_preOpen() - PreOpen the vOSS Module

  The \a vos_preOpen() function allocates the Vos Context, but do not
  initialize all the members. This overal initialization will happen
  at vos_Open().
  The reason why we need vos_preOpen() is to get a minimum context
  where to store BAL and SAL relative data, which happens before
  vos_Open() is called.

  \param  pVosContext: A pointer to where to store the VOS Context


  \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and
          is ready to be used.

          VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/

  \sa vos_Open()

---------------------------------------------------------------------------*/
VOS_STATUS vos_preOpen ( v_CONTEXT_t *pVosContext )
{
   if ( pVosContext == NULL)
      return VOS_STATUS_E_FAILURE;

   /* Allocate the VOS Context */
   *pVosContext = NULL;
   gpVosContext = &gVosContext;

   if (NULL == gpVosContext)
   {
     /* Critical Error ...Cannot proceed further */
      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
                 "%s: Failed to allocate VOS Context", __func__);
      VOS_ASSERT(0);
      return VOS_STATUS_E_RESOURCES;
   }

   vos_mem_zero(gpVosContext, sizeof(VosContextType));

   *pVosContext = gpVosContext;

   /* Initialize the spinlock */
   vos_trace_spin_lock_init();
   /* it is the right time to initialize MTRACE structures */
   #if defined(TRACE_RECORD)
       vosTraceInit();
   #endif
   vos_register_debugcb_init();

   adf_dp_trace_init();
   return VOS_STATUS_SUCCESS;

} /* vos_preOpen()*/


/*---------------------------------------------------------------------------

  \brief vos_preClose() - PreClose the vOSS Module

  The \a vos_preClose() function frees the Vos Context.

  \param  pVosContext: A pointer to where the VOS Context was stored


  \return VOS_STATUS_SUCCESS - Always successful


  \sa vos_preClose()
  \sa vos_close()
---------------------------------------------------------------------------*/
VOS_STATUS vos_preClose( v_CONTEXT_t *pVosContext )
{

   VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
                "%s: De-allocating the VOS Context", __func__);

   if (( pVosContext == NULL) || (*pVosContext == NULL))
   {
      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                "%s: vOS Context is Null", __func__);
      return VOS_STATUS_E_FAILURE;
   }

   if (gpVosContext != *pVosContext)
   {
      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                "%s: Context mismatch", __func__);
      return VOS_STATUS_E_FAILURE;
   }

   *pVosContext = gpVosContext = NULL;

   return VOS_STATUS_SUCCESS;

} /* vos_preClose()*/

#ifdef FEATURE_RUNTIME_PM
static inline void vos_runtime_pm_config(struct ol_softc *scn,
		hdd_context_t *pHddCtx)
{
	scn->enable_runtime_pm = pHddCtx->cfg_ini->runtime_pm;
	scn->runtime_pm_delay = pHddCtx->cfg_ini->runtime_pm_delay;
}
#else
static inline void vos_runtime_pm_config(struct ol_softc *scn,
		hdd_context_t *pHddCtx) { }
#endif

#if defined (FEATURE_SECURE_FIRMWARE) && defined (FEATURE_FW_HASH_CHECK)
static inline void vos_fw_hash_check_config(struct ol_softc *scn,
					hdd_context_t *pHddCtx)
{
	scn->enable_fw_hash_check = pHddCtx->cfg_ini->enable_fw_hash_check;
}
#elif defined (FEATURE_SECURE_FIRMWARE)
static inline void vos_fw_hash_check_config(struct ol_softc *scn,
					hdd_context_t *pHddCtx)
{
	scn->enable_fw_hash_check = true;
}
#else
static inline void vos_fw_hash_check_config(struct ol_softc *scn,
					hdd_context_t *pHddCtx) { }
#endif

#ifdef WLAN_FEATURE_TSF_PLUS
/**
 * vos_set_ptp_enable() - set ptp enable flag in mac open param
 * @wma_handle: Pointer to mac open param
 * @hdd_ctx: Pointer to hdd context
 *
 * Return: none
 */
static void vos_set_ptp_enable(tMacOpenParameters *param,
					hdd_context_t *hdd_ctx)
{
	param->is_ptp_enabled =
		(hdd_ctx->cfg_ini->tsf_ptp_options != 0);
}
#else
static void vos_set_ptp_enable(tMacOpenParameters *param,
					hdd_context_t *pHddCtx)
{
}
#endif

#ifdef WLAN_FEATURE_NAN
/**
 * vos_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 vos_set_nan_enable(tMacOpenParameters *param,
					hdd_context_t *hdd_ctx)
{
	param->is_nan_enabled = hdd_ctx->cfg_ini->enable_nan_support;
}
#else
static void vos_set_nan_enable(tMacOpenParameters *param,
					hdd_context_t *pHddCtx)
{
}
#endif

#ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK
static void vos_set_del_ack_params(tMacOpenParameters *param,
					hdd_context_t *hdd_ctx)
{
	param->del_ack_enable =
		hdd_ctx->cfg_ini->del_ack_enable;
	param->del_ack_timer_value = hdd_ctx->cfg_ini->del_ack_timer_value;
	param->del_ack_pkt_count = hdd_ctx->cfg_ini->del_ack_pkt_count;
}
#else
static void vos_set_del_ack_params(tMacOpenParameters *param,
					hdd_context_t *hdd_ctx)
{
}
#endif

#ifdef QCA_SUPPORT_TXRX_HL_BUNDLE
/**
 * vos_set_bundle_params() - set bundle params in mac open param
 * @wma_handle: Pointer to mac open param
 * @hdd_ctx: Pointer to hdd context
 *
 * Return: none
 */
static void vos_set_bundle_params(tMacOpenParameters *param,
					hdd_context_t *hdd_ctx)
{
	param->pkt_bundle_timer_value =
		hdd_ctx->cfg_ini->pkt_bundle_timer_value;
	param->pkt_bundle_size = hdd_ctx->cfg_ini->pkt_bundle_size;
}
#else
static void vos_set_bundle_params(tMacOpenParameters *param,
					hdd_context_t *hdd_ctx)
{
}
#endif

/**
 * vos_set_ac_specs_params() - set ac_specs params in mac open param
 * @param: Pointer to mac open param
 * @hdd_ctx: Pointer to hdd context
 *
 * Return: none
 */
static void vos_set_ac_specs_params(tMacOpenParameters *param,
					hdd_context_t *hdd_ctx)
{
	uint8_t num_entries = 0;
	uint8_t tx_sched_wrr_param[TX_SCHED_WRR_PARAMS_NUM];
	uint8_t *tx_sched_wrr_ac;
	int i;

	if (NULL == hdd_ctx)
		return;

	if (NULL == param)
		return;

	if (NULL == hdd_ctx->cfg_ini) {
		/* Do nothing if hdd_ctx is invalid */
		VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
			"%s: Warning: hdd_ctx->cfg_ini is NULL", __func__);
		return;
	}

	for (i = 0; i < OL_TX_NUM_WMM_AC; i++) {
		switch (i) {
		case OL_TX_WMM_AC_BE:
			tx_sched_wrr_ac = hdd_ctx->cfg_ini->tx_sched_wrr_be;
			break;
		case OL_TX_WMM_AC_BK:
			tx_sched_wrr_ac = hdd_ctx->cfg_ini->tx_sched_wrr_bk;
			break;
		case OL_TX_WMM_AC_VI:
			tx_sched_wrr_ac = hdd_ctx->cfg_ini->tx_sched_wrr_vi;
			break;
		case OL_TX_WMM_AC_VO:
			tx_sched_wrr_ac = hdd_ctx->cfg_ini->tx_sched_wrr_vo;
			break;
		default:
			tx_sched_wrr_ac = NULL;
		}

		hdd_string_to_u8_array(tx_sched_wrr_ac,
				tx_sched_wrr_param,
				&num_entries,
				sizeof(tx_sched_wrr_param));

		if (num_entries == TX_SCHED_WRR_PARAMS_NUM) {
			param->ac_specs[i].wrr_skip_weight =
						tx_sched_wrr_param[0];
			param->ac_specs[i].credit_threshold =
						tx_sched_wrr_param[1];
			param->ac_specs[i].send_limit =
						tx_sched_wrr_param[2];
			param->ac_specs[i].credit_reserve =
						tx_sched_wrr_param[3];
			param->ac_specs[i].discard_weight =
						tx_sched_wrr_param[4];
		}

		num_entries = 0;
	}
}


/*---------------------------------------------------------------------------

  \brief vos_open() - Open the vOSS Module

  The \a vos_open() function opens the vOSS Scheduler
  Upon successful initialization:

     - All VOS submodules should have been initialized

     - The VOS scheduler should have opened

     - All the WLAN SW components should have been opened. This includes
       SYS, MAC, SME, WDA and TL.


  \param  hddContextSize: Size of the HDD context to allocate.


  \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and
          is ready to be used.

          VOS_STATUS_E_RESOURCES - System resources (other than memory)
          are unavailable to initilize the scheduler


          VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/

  \sa vos_preOpen()

---------------------------------------------------------------------------*/
VOS_STATUS vos_open( v_CONTEXT_t *pVosContext, v_SIZE_t hddContextSize )

{
   VOS_STATUS vStatus      = VOS_STATUS_SUCCESS;
   int iter                = 0;
   tSirRetStatus sirStatus = eSIR_SUCCESS;
   tMacOpenParameters macOpenParms;
   WLANTL_ConfigInfoType TLConfig;
   adf_os_device_t adf_ctx;
   HTC_INIT_INFO  htcInfo;
   struct ol_softc *scn;
   v_VOID_t *HTCHandle;
   hdd_context_t *pHddCtx;

   VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
               "%s: Opening VOSS", __func__);

   if (NULL == gpVosContext)
   {
      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
                    "%s: Trying to open VOSS without a PreOpen", __func__);
      VOS_ASSERT(0);
      return VOS_STATUS_E_FAILURE;
   }

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

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

   /* Initialize the probe event */
   if (vos_event_init(&gpVosContext->ProbeEvent) != VOS_STATUS_SUCCESS)
   {
      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
                    "%s: Unable to init probeEvent", __func__);
      VOS_ASSERT(0);
      return VOS_STATUS_E_FAILURE;
   }
   if (vos_event_init( &(gpVosContext->wdaCompleteEvent) ) != VOS_STATUS_SUCCESS )
   {
      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
                  "%s: Unable to init wdaCompleteEvent", __func__);
      VOS_ASSERT(0);

      goto err_probe_event;
   }

   /* Initialize the free message queue */
   vStatus = vos_mq_init(&gpVosContext->freeVosMq);
   if (! VOS_IS_STATUS_SUCCESS(vStatus))
   {

      /* Critical Error ...  Cannot proceed further */
      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
                "%s: Failed to initialize VOS free message queue", __func__);
      VOS_ASSERT(0);
      goto err_wda_complete_event;
   }

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

   /* Now Open the VOS Scheduler */
   vStatus= vos_sched_open(gpVosContext, &gpVosContext->vosSched,
                           sizeof(VosSchedContext));

   if (!VOS_IS_STATUS_SUCCESS(vStatus))
   {
      /* Critical Error ...  Cannot proceed further */
      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
                "%s: Failed to open VOS Scheduler", __func__);
      VOS_ASSERT(0);
      goto err_msg_queue;
   }

   pHddCtx = (hdd_context_t*)(gpVosContext->pHDDContext);
   if((NULL == pHddCtx) ||
      (NULL == pHddCtx->cfg_ini))
   {
     /* Critical Error ...  Cannot proceed further */
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
               "%s: Hdd Context is Null", __func__);
     VOS_ASSERT(0);
     goto err_sched_close;
   }

   scn = vos_get_context(VOS_MODULE_ID_HIF, gpVosContext);
   if (!scn) {
      VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
                "%s: scn is null!", __func__);
      goto err_sched_close;
   }
   scn->enableuartprint = pHddCtx->cfg_ini->enablefwprint;
   scn->enablefwlog     = pHddCtx->cfg_ini->enablefwlog;
   scn->enableFwSelfRecovery = pHddCtx->cfg_ini->enableFwSelfRecovery;
   scn->max_no_of_peers = pHddCtx->max_peers;
#ifdef WLAN_FEATURE_LPSS
   scn->enablelpasssupport = pHddCtx->cfg_ini->enablelpasssupport;
#endif
   scn->enableRamdumpCollection = pHddCtx->cfg_ini->is_ramdump_enabled;
   scn->enable_self_recovery = pHddCtx->cfg_ini->enableSelfRecovery;

   vos_fw_hash_check_config(scn, pHddCtx);
   vos_runtime_pm_config(scn, pHddCtx);

   /* Initialize BMI and Download firmware */
   if (bmi_download_firmware(scn)) {
        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
                  "%s: BMI failed to download target", __func__);
        goto err_bmi_close;
   }
   htcInfo.pContext = gpVosContext->pHIFContext;
   htcInfo.TargetFailure = ol_target_failure;
   htcInfo.TargetSendSuspendComplete = wma_target_suspend_acknowledge;
   adf_ctx = vos_get_context(VOS_MODULE_ID_ADF, gpVosContext);

   /* Create HTC */
   gpVosContext->htc_ctx = HTCCreate(htcInfo.pContext, &htcInfo, adf_ctx);
   if (!gpVosContext->htc_ctx) {
        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
                  "%s: Failed to Create HTC", __func__);
           goto err_bmi_close;
   }

   if (bmi_done(scn)) {
        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
                  "%s: Failed to complete BMI phase", __func__);
        goto err_htc_close;
   }

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

   /*Open the WDA module */
   vos_mem_set(&macOpenParms, sizeof(macOpenParms), 0);
   /* UMA is supported in hardware for performing the
   ** frame translation 802.11 <-> 802.3
   */
   macOpenParms.frameTransRequired = 1;
   macOpenParms.driverType         = eDRIVER_TYPE_PRODUCTION;
   macOpenParms.powersaveOffloadEnabled =
      pHddCtx->cfg_ini->enablePowersaveOffload;
   macOpenParms.staDynamicDtim = pHddCtx->cfg_ini->enableDynamicDTIM;
   macOpenParms.staModDtim = pHddCtx->cfg_ini->enableModulatedDTIM;
   macOpenParms.staMaxLIModDtim = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
   macOpenParms.wowEnable          = pHddCtx->cfg_ini->wowEnable;
   macOpenParms.maxWoWFilters      = pHddCtx->cfg_ini->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->cfg_ini->fhostArpOffload)
       macOpenParms.olIniInfo      = macOpenParms.olIniInfo | 0x1;
  if ( pHddCtx->cfg_ini->fhostNSOffload)
       macOpenParms.olIniInfo      = macOpenParms.olIniInfo | 0x2;
  /*
   * Copy the DFS Phyerr Filtering Offload status.
   * This parameter reflects the value of the
   * dfsPhyerrFilterOffload flag  as set in the ini.
   */
  macOpenParms.dfsPhyerrFilterOffload =
                        pHddCtx->cfg_ini->fDfsPhyerrFilterOffload;

  macOpenParms.ssdp = pHddCtx->cfg_ini->ssdp;
  macOpenParms.enable_bcst_ptrn = pHddCtx->cfg_ini->bcastptrn;
  macOpenParms.enable_mc_list = pHddCtx->cfg_ini->fEnableMCAddrList;

  macOpenParms.bpf_packet_filter_enable =
               pHddCtx->cfg_ini->bpf_packet_filter_enable;
#ifdef FEATURE_WLAN_RA_FILTERING
   macOpenParms.RArateLimitInterval = pHddCtx->cfg_ini->RArateLimitInterval;
   macOpenParms.IsRArateLimitEnabled = pHddCtx->cfg_ini->IsRArateLimitEnabled;
#endif

   macOpenParms.force_target_assert_enabled =
               pHddCtx->cfg_ini->crash_inject_enabled;
   macOpenParms.apMaxOffloadPeers = pHddCtx->cfg_ini->apMaxOffloadPeers;

   macOpenParms.apMaxOffloadReorderBuffs =
                        pHddCtx->cfg_ini->apMaxOffloadReorderBuffs;

   macOpenParms.apDisableIntraBssFwd = pHddCtx->cfg_ini->apDisableIntraBssFwd;

   macOpenParms.dfsRadarPriMultiplier = pHddCtx->cfg_ini->dfsRadarPriMultiplier;
   macOpenParms.reorderOffload = pHddCtx->cfg_ini->reorderOffloadSupport;

#ifdef IPA_UC_OFFLOAD
    /* IPA micro controller data path offload resource config item */
    macOpenParms.ucOffloadEnabled = pHddCtx->cfg_ini->IpaUcOffloadEnabled;

    if (!is_power_of_2(pHddCtx->cfg_ini->IpaUcTxBufCount)) {
        /* IpaUcTxBufCount should be power of 2 */
        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                    "%s: Round down IpaUcTxBufCount %d to nearest power of two",
                    __func__, pHddCtx->cfg_ini->IpaUcTxBufCount);
        pHddCtx->cfg_ini->IpaUcTxBufCount =
                    vos_rounddown_pow_of_two(pHddCtx->cfg_ini->IpaUcTxBufCount);
        if (!pHddCtx->cfg_ini->IpaUcTxBufCount) {
            VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
                        "%s: Failed to round down IpaUcTxBufCount", __func__);
            goto err_htc_close;
        }
        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                    "%s: IpaUcTxBufCount rounded down to %d", __func__,
                    pHddCtx->cfg_ini->IpaUcTxBufCount);
    }
    macOpenParms.ucTxBufCount = pHddCtx->cfg_ini->IpaUcTxBufCount;
    macOpenParms.ucTxBufSize = pHddCtx->cfg_ini->IpaUcTxBufSize;

    if (!is_power_of_2(pHddCtx->cfg_ini->IpaUcRxIndRingCount)) {
        /* IpaUcRxIndRingCount should be power of 2 */
        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                "%s: Round down IpaUcRxIndRingCount %d to nearest power of two",
                __func__, pHddCtx->cfg_ini->IpaUcRxIndRingCount);
        pHddCtx->cfg_ini->IpaUcRxIndRingCount =
                vos_rounddown_pow_of_two(pHddCtx->cfg_ini->IpaUcRxIndRingCount);
        if (!pHddCtx->cfg_ini->IpaUcRxIndRingCount) {
            VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
                      "%s: Failed to round down IpaUcRxIndRingCount", __func__);
            goto err_htc_close;
        }
        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                    "%s: IpaUcRxIndRingCount rounded down to %d", __func__,
                    pHddCtx->cfg_ini->IpaUcRxIndRingCount);
    }
    macOpenParms.ucRxIndRingCount = pHddCtx->cfg_ini->IpaUcRxIndRingCount;
    macOpenParms.ucTxPartitionBase = pHddCtx->cfg_ini->IpaUcTxPartitionBase;
#endif /* IPA_UC_OFFLOAD */

    macOpenParms.tx_chain_mask_cck = pHddCtx->cfg_ini->tx_chain_mask_cck;
    macOpenParms.self_gen_frm_pwr = pHddCtx->cfg_ini->self_gen_frm_pwr;
    macOpenParms.max_mgmt_tx_fail_count =
                     pHddCtx->cfg_ini->max_mgmt_tx_fail_count;

#ifdef WLAN_FEATURE_LPSS
    macOpenParms.is_lpass_enabled = pHddCtx->cfg_ini->enablelpasssupport;
#endif

   vos_set_nan_enable(&macOpenParms, pHddCtx);
   vos_set_bundle_params(&macOpenParms, pHddCtx);
   vos_set_del_ack_params(&macOpenParms, pHddCtx);
   vos_set_ac_specs_params(&macOpenParms, pHddCtx);
   vos_set_ptp_enable(&macOpenParms, pHddCtx);

   vStatus = WDA_open( gpVosContext, gpVosContext->pHDDContext,
                       hdd_update_tgt_cfg,
                       hdd_dfs_indicate_radar,
                       hdd_update_dfs_cac_block_tx_flag,
                       &macOpenParms );

   if (!VOS_IS_STATUS_SUCCESS(vStatus))
   {
      /* Critical Error ...  Cannot proceed further */
      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
                "%s: Failed to open WDA module", __func__);
      VOS_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 macOpenParms.maxStation. So, make sure
    * pHddCtx->max_peers has adjusted value
   */
   pHddCtx->max_peers = macOpenParms.maxStation;
   HTCHandle = vos_get_context(VOS_MODULE_ID_HTC, gpVosContext);
   if (!HTCHandle) {
      VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
                "%s: HTCHandle is null!", __func__);
      goto err_wda_close;
   }
   if (HTCWaitTarget(HTCHandle)) {
      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
                "%s: Failed to complete BMI phase", __func__);
           goto err_wda_close;
   }

   bmi_target_ready(scn, gpVosContext->cfg_ctx);
   /* Open the SYS module */
   vStatus = sysOpen(gpVosContext);

   if (!VOS_IS_STATUS_SUCCESS(vStatus))
   {
      /* Critical Error ...  Cannot proceed further */
      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
                "%s: Failed to open SYS module", __func__);
      VOS_ASSERT(0);
      goto err_packet_close;
   }


   /* If we arrive here, both threads dispacthing messages correctly */

   /* Now proceed to open the MAC */

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

   sirStatus = macOpen(&(gpVosContext->pMACContext), gpVosContext->pHDDContext,
                         &macOpenParms);

   if (eSIR_SUCCESS != sirStatus)
   {
     /* Critical Error ...  Cannot proceed further */
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
               "%s: Failed to open MAC", __func__);
     VOS_ASSERT(0);
     goto err_nv_close;
   }

   /* Now proceed to open the SME */
   vStatus = sme_Open(gpVosContext->pMACContext);
   if (!VOS_IS_STATUS_SUCCESS(vStatus))
   {
     /* Critical Error ...  Cannot proceed further */
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
               "%s: Failed to open SME", __func__);
     VOS_ASSERT(0);
     goto err_mac_close;
   }

   /* Now proceed to open TL. Read TL config first */
   vos_fetch_tl_cfg_parms ( &TLConfig,
       ((hdd_context_t*)(gpVosContext->pHDDContext))->cfg_ini);

   vStatus = WLANTL_Open(gpVosContext, &TLConfig);
   if (!VOS_IS_STATUS_SUCCESS(vStatus))
   {
     /* Critical Error ...  Cannot proceed further */
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
               "%s: Failed to open TL", __func__);
     VOS_ASSERT(0);
     goto err_sme_close;
   }

#ifdef IPA_UC_OFFLOAD
   WLANTL_GetIpaUcResource(gpVosContext,
       &((hdd_context_t*)(gpVosContext->pHDDContext))->ce_sr_base_paddr,
       &((hdd_context_t*)(gpVosContext->pHDDContext))->ce_sr_ring_size,
       &((hdd_context_t*)(gpVosContext->pHDDContext))->ce_reg_paddr,
       &((hdd_context_t*)(gpVosContext->pHDDContext))->tx_comp_ring_base_paddr,
       &((hdd_context_t*)(gpVosContext->pHDDContext))->tx_comp_ring_size,
       &((hdd_context_t*)(gpVosContext->pHDDContext))->tx_num_alloc_buffer,
       &((hdd_context_t*)(gpVosContext->pHDDContext))->rx_rdy_ring_base_paddr,
       &((hdd_context_t*)(gpVosContext->pHDDContext))->rx_rdy_ring_size,
       &((hdd_context_t*)(gpVosContext->pHDDContext))->rx_proc_done_idx_paddr);
#endif /* IPA_UC_OFFLOAD */

   VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
               "%s: VOSS successfully Opened", __func__);

   *pVosContext = gpVosContext;

   return VOS_STATUS_SUCCESS;


err_sme_close:
   sme_Close(gpVosContext->pMACContext);

err_mac_close:
   macClose(gpVosContext->pMACContext);

err_nv_close:

   sysClose(gpVosContext);

err_packet_close:
err_wda_close:
   WDA_close(gpVosContext);

   wma_wmi_service_close(gpVosContext);

err_htc_close:
   if (gpVosContext->htc_ctx) {
      HTCDestroy(gpVosContext->htc_ctx);
      gpVosContext->htc_ctx = NULL;
   }

err_bmi_close:
      BMICleanup(scn);

err_sched_close:
   vos_sched_close(gpVosContext);


err_msg_queue:
   vos_mq_deinit(&gpVosContext->freeVosMq);

err_wda_complete_event:
   vos_event_destroy( &gpVosContext->wdaCompleteEvent );

err_probe_event:
   vos_event_destroy(&gpVosContext->ProbeEvent);

   return VOS_STATUS_E_FAILURE;

} /* vos_open() */

/*---------------------------------------------------------------------------

  \brief vos_preStart() -

  The \a vos_preStart() function to download CFG.
  including:
      - ccmStart

      - WDA: triggers the CFG download


  \param  pVosContext: The VOS context


  \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and
          is ready to be used.

          VOS_STATUS_E_RESOURCES - System resources (other than memory)
          are unavailable to initilize the scheduler


          VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/

  \sa vos_start

---------------------------------------------------------------------------*/
VOS_STATUS vos_preStart( v_CONTEXT_t vosContext )
{
   VOS_STATUS vStatus          = VOS_STATUS_SUCCESS;
   pVosContextType pVosContext = (pVosContextType)vosContext;
   v_VOID_t *scn;
   VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO,
             "vos prestart");

   if (gpVosContext != pVosContext)
   {
      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                "%s: Context mismatch", __func__);
      VOS_ASSERT(0);
      return VOS_STATUS_E_INVAL;
   }

   if (pVosContext->pMACContext == NULL)
   {
       VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
            "%s: MAC NULL context", __func__);
       VOS_ASSERT(0);
       return VOS_STATUS_E_INVAL;
   }

   if (pVosContext->pWDAContext == NULL)
   {
       VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
          "%s: WDA NULL context", __func__);
       VOS_ASSERT(0);
       return VOS_STATUS_E_INVAL;
   }

   scn = vos_get_context(VOS_MODULE_ID_HIF, gpVosContext);
   if (!scn) {
      VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
                "%s: scn is null!", __func__);
      return VOS_STATUS_E_FAILURE;
   }

   /* call macPreStart */
   vStatus = macPreStart(gpVosContext->pMACContext);
   if ( !VOS_IS_STATUS_SUCCESS(vStatus) )
   {
      VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_FATAL,
             "Failed at macPreStart ");
      return VOS_STATUS_E_FAILURE;
   }

   /* call ccmStart */
   ccmStart(gpVosContext->pMACContext);

   /* Reset wda wait event */
   vos_event_reset(&gpVosContext->wdaCompleteEvent);


   /*call WDA pre start*/
   vStatus = WDA_preStart(gpVosContext);
   if (!VOS_IS_STATUS_SUCCESS(vStatus))
   {
      VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_FATAL,
             "Failed to WDA prestart");
      ccmStop(gpVosContext->pMACContext);
      VOS_ASSERT(0);
      return VOS_STATUS_E_FAILURE;
   }

   /* Need to update time out of complete */
   vStatus = vos_wait_single_event( &gpVosContext->wdaCompleteEvent,
                                    VOS_WDA_TIMEOUT );
   if ( vStatus != VOS_STATUS_SUCCESS )
   {
      if ( vStatus == VOS_STATUS_E_TIMEOUT )
      {
         VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
          "%s: Timeout occurred before WDA complete", __func__);
      }
      else
      {
         VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
           "%s: WDA_preStart reporting other error", __func__);
      }
      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
           "%s: Test MC thread by posting a probe message to SYS", __func__);
      wlan_sys_probe();

      ccmStop(gpVosContext->pMACContext);
      VOS_ASSERT( 0 );
      return VOS_STATUS_E_FAILURE;
   }

   vStatus = HTCStart(gpVosContext->htc_ctx);
   if (!VOS_IS_STATUS_SUCCESS(vStatus))
   {
      VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_FATAL,
               "Failed to Start HTC");
      ccmStop(gpVosContext->pMACContext);
      VOS_ASSERT( 0 );
      return VOS_STATUS_E_FAILURE;
   }
   vStatus = wma_wait_for_ready_event(gpVosContext->pWDAContext);
   if (!VOS_IS_STATUS_SUCCESS(vStatus))
   {
      VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_FATAL,
               "Failed to get ready event from target firmware");
      HTCSetTargetToSleep(scn);
      ccmStop(gpVosContext->pMACContext);
      HTCStop(gpVosContext->htc_ctx);
      VOS_ASSERT( 0 );
      return VOS_STATUS_E_FAILURE;
   }

   HTCSetTargetToSleep(scn);

   return VOS_STATUS_SUCCESS;
}

/*---------------------------------------------------------------------------

  \brief vos_start() - Start the Libra SW Modules

  The \a vos_start() function starts all the components of the Libra SW
  including:
      - SAL/BAL, which in turn starts SSC

      - the MAC (HAL and PE)

      - SME

      - TL

      - SYS: triggers the CFG download


  \param  pVosContext: The VOS context


  \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and
          is ready to be used.

          VOS_STATUS_E_RESOURCES - System resources (other than memory)
          are unavailable to initilize the scheduler


          VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/

  \sa vos_preStart()
  \sa vos_open()

---------------------------------------------------------------------------*/
VOS_STATUS vos_start( v_CONTEXT_t vosContext )
{
  VOS_STATUS vStatus          = VOS_STATUS_SUCCESS;
  tSirRetStatus sirStatus     = eSIR_SUCCESS;
  pVosContextType pVosContext = (pVosContextType)vosContext;
  tHalMacStartParameters halStartParams;

  VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
            "%s: Starting Libra SW", __func__);

  /* We support only one instance for now ...*/
  if (gpVosContext != pVosContext)
  {
     VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
           "%s: mismatch in context", __func__);
     return VOS_STATUS_E_FAILURE;
  }

  if (( pVosContext->pWDAContext == NULL) || ( pVosContext->pMACContext == NULL)
     || ( pVosContext->pTLContext == NULL))
  {
     if (pVosContext->pWDAContext == NULL)
        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
            "%s: WDA NULL context", __func__);
     else if (pVosContext->pMACContext == NULL)
        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
            "%s: MAC NULL context", __func__);
     else
        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
            "%s: TL NULL context", __func__);

     return VOS_STATUS_E_FAILURE;
  }


  /* Start the WDA */
  vStatus = WDA_start(pVosContext);
  if ( vStatus != VOS_STATUS_SUCCESS )
  {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                 "%s: Failed to start WDA", __func__);
     return VOS_STATUS_E_FAILURE;
  }
  VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
            "%s: WDA correctly started", __func__);

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

  /* Start the MAC */
  sirStatus = macStart(pVosContext->pMACContext,(v_PVOID_t)&halStartParams);

  if (eSIR_SUCCESS != sirStatus)
  {
    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
              "%s: Failed to start MAC", __func__);
    goto err_wda_stop;
  }

  VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
            "%s: MAC correctly started", __func__);

  /* START SME */
  vStatus = sme_Start(pVosContext->pMACContext);

  if (!VOS_IS_STATUS_SUCCESS(vStatus))
  {
    VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
               "%s: Failed to start SME", __func__);
    goto err_mac_stop;
  }

  VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
            "%s: SME correctly started", __func__);

  /** START TL */
  vStatus = WLANTL_Start(pVosContext);
  if (!VOS_IS_STATUS_SUCCESS(vStatus))
  {
    VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
               "%s: Failed to start TL", __func__);
    goto err_sme_stop;
  }

  VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
            "TL correctly started");
  VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
            "%s: VOSS Start is successful!!", __func__);

  return VOS_STATUS_SUCCESS;


err_sme_stop:
  sme_Stop(pVosContext->pMACContext, HAL_STOP_TYPE_SYS_RESET);

err_mac_stop:
  macStop( pVosContext->pMACContext, HAL_STOP_TYPE_SYS_RESET );

err_wda_stop:
  vos_event_reset( &(gpVosContext->wdaCompleteEvent) );
  vStatus = WDA_stop( pVosContext, HAL_STOP_TYPE_RF_KILL);
  if (!VOS_IS_STATUS_SUCCESS(vStatus))
  {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: Failed to stop WDA", __func__);
     VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vStatus ) );
     WDA_setNeedShutdown(vosContext);
  }
  else
  {
    vStatus = vos_wait_single_event( &(gpVosContext->wdaCompleteEvent),
                                     VOS_WDA_TIMEOUT );
    if( vStatus != VOS_STATUS_SUCCESS )
    {
       if( vStatus == VOS_STATUS_E_TIMEOUT )
       {
          VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
           "%s: Timeout occurred before WDA_stop complete", __func__);

       }
       else
       {
          VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
           "%s: WDA_stop reporting other error", __func__);
       }
       VOS_ASSERT( 0 );
       WDA_setNeedShutdown(vosContext);
    }
  }

  return VOS_STATUS_E_FAILURE;

} /* vos_start() */


/* vos_stop function */
VOS_STATUS vos_stop( v_CONTEXT_t vosContext )
{
  VOS_STATUS vosStatus;

  /* WDA_Stop is called before the SYS so that the processing of Riva
  pending responces will not be handled during uninitialization of WLAN driver */
  vos_event_reset( &(gpVosContext->wdaCompleteEvent) );

  vosStatus = WDA_stop( vosContext, HAL_STOP_TYPE_RF_KILL );

  if (!VOS_IS_STATUS_SUCCESS(vosStatus))
  {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: Failed to stop WDA", __func__);
     VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
     WDA_setNeedShutdown(vosContext);
  }

  hif_disable_isr(((VosContextType*)vosContext)->pHIFContext);
  hif_reset_soc(((VosContextType*)vosContext)->pHIFContext);

  /* SYS STOP will stop SME and MAC */
  vosStatus = sysStop( vosContext);
  if (!VOS_IS_STATUS_SUCCESS(vosStatus))
  {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: Failed to stop SYS", __func__);
     VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
  }

  vosStatus = WLANTL_Stop( vosContext );
  if (!VOS_IS_STATUS_SUCCESS(vosStatus))
  {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: Failed to stop TL", __func__);
     VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
  }

  return VOS_STATUS_SUCCESS;
}


/* vos_close function */
VOS_STATUS vos_close( v_CONTEXT_t vosContext )
{
  VOS_STATUS vosStatus;

  vosStatus = wma_wmi_work_close( vosContext );
  if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: Failed to close wma_wmi_work", __func__);
     VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
  }

  if (gpVosContext->htc_ctx)
  {
      HTCStop(gpVosContext->htc_ctx);
      HTCDestroy(gpVosContext->htc_ctx);
      gpVosContext->htc_ctx = NULL;
  }

  vosStatus = WLANTL_Close(vosContext);
  if (!VOS_IS_STATUS_SUCCESS(vosStatus))
  {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: Failed to close TL", __func__);
     VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
  }

  vosStatus = sme_Close( ((pVosContextType)vosContext)->pMACContext);
  if (!VOS_IS_STATUS_SUCCESS(vosStatus))
  {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: Failed to close SME", __func__);
     VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
  }

  vosStatus = macClose( ((pVosContextType)vosContext)->pMACContext);
  if (!VOS_IS_STATUS_SUCCESS(vosStatus))
  {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: Failed to close MAC", __func__);
     VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
  }

  ((pVosContextType)vosContext)->pMACContext = NULL;

  vosStatus = sysClose( vosContext );
  if (!VOS_IS_STATUS_SUCCESS(vosStatus))
  {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: Failed to close SYS", __func__);
     VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
  }

  if ( TRUE == WDA_needShutdown(vosContext ))
  {
     /* if WDA stop failed, call WDA shutdown to cleanup WDA/WDI */
     vosStatus = WDA_shutdown( vosContext, VOS_TRUE );
     if (VOS_IS_STATUS_SUCCESS( vosStatus ) )
     {
        hdd_set_ssr_required( HDD_SSR_REQUIRED );
     }
     else
     {
        VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
                               "%s: Failed to shutdown WDA", __func__ );
        VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
     }
  }
  else
  {
     vosStatus = WDA_close( vosContext );
     if (!VOS_IS_STATUS_SUCCESS(vosStatus))
     {
        VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
            "%s: Failed to close WDA", __func__);
        VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
     }
  }

  vosStatus = wma_wmi_service_close( vosContext );
  if (!VOS_IS_STATUS_SUCCESS(vosStatus))
  {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: Failed to close wma_wmi_service", __func__);
     VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
  }


  vos_mq_deinit(&((pVosContextType)vosContext)->freeVosMq);

  vosStatus = vos_event_destroy(&gpVosContext->wdaCompleteEvent);
  if (!VOS_IS_STATUS_SUCCESS(vosStatus))
  {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: failed to destroy wdaCompleteEvent", __func__);
     VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
  }

  vosStatus = vos_event_destroy(&gpVosContext->ProbeEvent);
  if (!VOS_IS_STATUS_SUCCESS(vosStatus))
  {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: failed to destroy ProbeEvent", __func__);
     VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
  }

  vos_deinit_log_completion();

  vos_wdthread_flush_timer_work();

  return VOS_STATUS_SUCCESS;
}


/**---------------------------------------------------------------------------

  \brief vos_get_context() - get context data area

  Each module in the system has a context / data area that is allocated
  and maanged by voss.  This API allows any user to get a pointer to its
  allocated context data area from the VOSS global context.

  \param vosContext - the VOSS Global Context.

  \param moduleId - the module ID, who's context data are is being retrived.

  \return - pointer to the context data area.

          - NULL if the context data is not allocated for the module ID
            specified

  --------------------------------------------------------------------------*/
v_VOID_t* vos_get_context( VOS_MODULE_ID moduleId,
                           v_CONTEXT_t pVosContext )
{
  v_PVOID_t pModContext = NULL;

  if (pVosContext == NULL)
  {
    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
        "%s: vos context pointer is null", __func__);
    return NULL;
  }

  if (gpVosContext != pVosContext)
  {
    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
        "%s: pVosContext != gpVosContext", __func__);
    return NULL;
  }

  switch(moduleId)
  {
    case VOS_MODULE_ID_TL:
    {
      pModContext = gpVosContext->pTLContext;
      break;
    }

    case VOS_MODULE_ID_HDD:
    {
      pModContext = gpVosContext->pHDDContext;
      break;
    }

    case VOS_MODULE_ID_SME:
    case VOS_MODULE_ID_PE:
    case VOS_MODULE_ID_PMC:
    {
      /*
      ** In all these cases, we just return the MAC Context
      */
      pModContext = gpVosContext->pMACContext;
      break;
    }

    case VOS_MODULE_ID_WDA:
    {
      /* For WDA module */
      pModContext = gpVosContext->pWDAContext;
      break;
    }

    case VOS_MODULE_ID_VOSS:
    {
      /* For SYS this is VOS itself*/
      pModContext = gpVosContext;
      break;
    }


    case VOS_MODULE_ID_HIF:
    {
        pModContext = gpVosContext->pHIFContext;
        break;
    }

    case VOS_MODULE_ID_HTC:
    {
        pModContext = gpVosContext->htc_ctx;
        break;
    }

    case VOS_MODULE_ID_ADF:
    {
        pModContext = gpVosContext->adf_ctx;
        break;
    }

    case VOS_MODULE_ID_TXRX:
    {
        pModContext = gpVosContext->pdev_txrx_ctx;
        break;
    }

    case VOS_MODULE_ID_CFG:
    {
       pModContext = gpVosContext->cfg_ctx;
        break;
    }

    default:
    {
      VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,"%s: Module ID %i "
          "does not have its context maintained by VOSS", __func__, moduleId);
      VOS_ASSERT(0);
      return NULL;
    }
  }

  if (pModContext == NULL )
  {
    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,"%s: Module ID %i "
          "context is Null", __func__, moduleId);
  }

  return pModContext;

} /* vos_get_context()*/


/**---------------------------------------------------------------------------

  \brief vos_get_global_context() - get VOSS global Context

  This API allows any user to get the VOS Global Context pointer from a
  module context data area.

  \param moduleContext - the input module context pointer

  \param moduleId - the module ID who's context pointer is input in
         moduleContext.

  \return - pointer to the VOSS global context

          - NULL if the function is unable to retreive the VOSS context.

  --------------------------------------------------------------------------*/
v_CONTEXT_t vos_get_global_context( VOS_MODULE_ID moduleId,
                                    v_VOID_t *moduleContext )
{
  if (gpVosContext == NULL)
  {
    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
        "%s: global voss context is NULL", __func__);
  }

  return gpVosContext;

} /* vos_get_global_context() */


v_U8_t vos_is_logp_in_progress(VOS_MODULE_ID moduleId, v_VOID_t *moduleContext)
{
  if (gpVosContext == NULL)
  {
    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
        "%s: global voss context is NULL", __func__);
    return 1;
  }

   return gpVosContext->isLogpInProgress;
}

void vos_set_logp_in_progress(VOS_MODULE_ID moduleId, v_U8_t value)
{
  hdd_context_t *pHddCtx = NULL;

  if (gpVosContext == NULL)
  {
    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
        "%s: global voss context is NULL", __func__);
    return;
  }

  VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_DEBUG,
           "%s:%pS setting value %d",__func__, (void *)_RET_IP_, value);
  gpVosContext->isLogpInProgress = value;

  /* HDD uses it's own context variable to check if SSR in progress,
   * instead of modifying all HDD APIs set the HDD context variable
   * here */
   pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, gpVosContext);
   if (!pHddCtx) {
      VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
               "%s: HDD context is Null", __func__);
      return;
   }
   pHddCtx->isLogpInProgress = value;
}

v_U8_t vos_is_load_unload_in_progress(VOS_MODULE_ID moduleId, v_VOID_t *moduleContext)
{
  if (gpVosContext == NULL)
  {
    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
        "%s: global voss context is NULL", __func__);
    return 0;
  }

   return gpVosContext->isLoadUnloadInProgress;
}

void vos_set_load_unload_in_progress(VOS_MODULE_ID moduleId, v_U8_t value)
{
    if (gpVosContext == NULL)
    {
        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                "%s: global voss context is NULL", __func__);
        return;
    }
    gpVosContext->isLoadUnloadInProgress = value;

    vos_set_driver_status(value);
}

/**
 * vos_is_unload_in_progress - check if driver unload is in progress
 *
 * Return: true - unload in progress
 *         false - unload not in progress
 */
v_U8_t vos_is_unload_in_progress(void)
{
	if (gpVosContext == NULL) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
			"%s: global voss context is NULL", __func__);
		return 0;
	}

	return gpVosContext->is_unload_in_progress;
}

/**
 * vos_is_load_in_progress - check if driver load is in progress
 *
 * @moduleId: the module ID who's context pointer is input in moduleContext
 * @moduleContext: the input module context pointer
 *
 * Return: true - load in progress
 *         false - load not in progress
 */
v_U8_t vos_is_load_in_progress(VOS_MODULE_ID moduleId, v_VOID_t *moduleContext)
{
	if (gpVosContext == NULL) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
			"%s: global voss context is NULL", __func__);
		return 0;
	}

	return gpVosContext->is_load_in_progress;
}

/**
 * vos_set_unload_in_progress - set driver unload in progress status
 * @value: true - driver unload starts
 *         false - driver unload completes
 *
 * Return: none
 */
void vos_set_unload_in_progress(v_U8_t value)
{
	if (gpVosContext == NULL) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
			"%s: global voss context is NULL", __func__);
		return;
	}

	gpVosContext->is_unload_in_progress = value;
}

/**
 * vos_set_load_in_progress - set driver load in progress status
 *
 * @moduleId: the module ID of the caller
 * @value: true - driver load starts
 *         false - driver load completes
 * Return: none
 */
void vos_set_load_in_progress(VOS_MODULE_ID moduleId, v_U8_t value)
{
	if (gpVosContext == NULL) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
			"%s: global voss context is NULL", __func__);
		return;
	}

	gpVosContext->is_load_in_progress = value;
}

v_U8_t vos_is_reinit_in_progress(VOS_MODULE_ID moduleId, v_VOID_t *moduleContext)
{
  if (gpVosContext == NULL)
  {
    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
        "%s: global voss context is NULL", __func__);
    return 1;
  }

   return gpVosContext->isReInitInProgress;
}

void vos_set_reinit_in_progress(VOS_MODULE_ID moduleId, v_U8_t value)
{
  if (gpVosContext == NULL)
  {
    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
        "%s: global voss context is NULL", __func__);
    return;
  }

   gpVosContext->isReInitInProgress = value;
}


/**
 * vos_set_shutdown_in_progress - set SSR shutdown progress status
 *
 * @moduleId: the module ID of the caller
 * @value: true - CNSS SSR shutdown start
 *         false - CNSS SSR shutdown completes
 * Return: none
 */

void vos_set_shutdown_in_progress(VOS_MODULE_ID moduleId, bool value)
{
	if (gpVosContext == NULL) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
			"%s: global voss context is NULL", __func__);
		return;
	}
	gpVosContext->is_shutdown_in_progress = value;
}

/**
 * vos_is_shutdown_in_progress - check if SSR shutdown is in progress
 *
 * @moduleId: the module ID of the caller
 * @moduleContext: the input module context pointer
 *
 * Return: true - shutdown in progress
 *         false - shutdown is  not in progress
 */

bool vos_is_shutdown_in_progress(VOS_MODULE_ID moduleId,
	 v_VOID_t *moduleContext)
{
	if (gpVosContext == NULL) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
			"%s: global voss context is NULL", __func__);
		return 0;
	}
	return gpVosContext->is_shutdown_in_progress;
}

/**---------------------------------------------------------------------------

  \brief vos_alloc_context() - allocate a context within the VOSS global Context

  This API allows any user to allocate a user context area within the
  VOS Global Context.

  \param pVosContext - pointer to the global Vos context

  \param moduleId - the module ID who's context area is being allocated.

  \param ppModuleContext - pointer to location where the pointer to the
                           allocated context is returned.  Note this
                           output pointer is valid only if the API
                           returns VOS_STATUS_SUCCESS

  \param size - the size of the context area to be allocated.

  \return - VOS_STATUS_SUCCESS - the context for the module ID has been
            allocated successfully.  The pointer to the context area
            can be found in *ppModuleContext.
            \note This function returns VOS_STATUS_SUCCESS if the
            module context was already allocated and the size
            allocated matches the size on this call.

            VOS_STATUS_E_INVAL - the moduleId is not a valid or does
            not identify a module that can have a context allocated.

            VOS_STATUS_E_EXISTS - vos could allocate the requested context
            because a context for this module ID already exists and it is
            a *different* size that specified on this call.

            VOS_STATUS_E_NOMEM - vos could not allocate memory for the
            requested context area.

  \sa vos_get_context(), vos_free_context()

  --------------------------------------------------------------------------*/
VOS_STATUS vos_alloc_context( v_VOID_t *pVosContext, VOS_MODULE_ID moduleID,
                              v_VOID_t **ppModuleContext, v_SIZE_t size )
{
  v_VOID_t ** pGpModContext = NULL;

  if ( pVosContext == NULL) {
    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
        "%s: vos context is null", __func__);
    return VOS_STATUS_E_FAILURE;
  }

  if (( gpVosContext != pVosContext) || ( ppModuleContext == NULL)) {
    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
        "%s: context mismatch or null param passed", __func__);
    return VOS_STATUS_E_FAILURE;
  }

  switch(moduleID)
  {
    case VOS_MODULE_ID_TL:
    {
      pGpModContext = &(gpVosContext->pTLContext);
      break;
    }

    case VOS_MODULE_ID_WDA:
    {
      pGpModContext = &(gpVosContext->pWDAContext);
      break;
    }
    case VOS_MODULE_ID_SME:
    case VOS_MODULE_ID_PE:
    case VOS_MODULE_ID_PMC:
    case VOS_MODULE_ID_HDD:
    case VOS_MODULE_ID_HDD_SOFTAP:
    default:
    {
      VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: Module ID %i "
          "does not have its context allocated by VOSS", __func__, moduleID);
      VOS_ASSERT(0);
      return VOS_STATUS_E_INVAL;
    }
  }

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

  /*
  ** Dynamically allocate the context for module
  */

  *ppModuleContext = vos_mem_malloc(size);


  if ( *ppModuleContext == NULL)
  {
    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,"%s: Failed to "
        "allocate Context for module ID %i", __func__, moduleID);
    VOS_ASSERT(0);
    return VOS_STATUS_E_NOMEM;
  }

  if (moduleID==VOS_MODULE_ID_TL)
  {
     vos_mem_zero(*ppModuleContext, size);
  }

  *pGpModContext = *ppModuleContext;

  return VOS_STATUS_SUCCESS;

} /* vos_alloc_context() */


/**---------------------------------------------------------------------------

  \brief vos_free_context() - free an allocated a context within the
                               VOSS global Context

  This API allows a user to free the user context area within the
  VOS Global Context.

  \param pVosContext - pointer to the global Vos context

  \param moduleId - the module ID who's context area is being free

  \param pModuleContext - pointer to module context area to be free'd.

  \return - VOS_STATUS_SUCCESS - the context for the module ID has been
            free'd.  The pointer to the context area is not longer
            available.

            VOS_STATUS_E_FAULT - pVosContext or pModuleContext are not
            valid pointers.

            VOS_STATUS_E_INVAL - the moduleId is not a valid or does
            not identify a module that can have a context free'd.

            VOS_STATUS_E_EXISTS - vos could not free the requested
            context area because a context for this module ID does not
            exist in the global vos context.

  \sa vos_get_context()

  --------------------------------------------------------------------------*/
VOS_STATUS vos_free_context( v_VOID_t *pVosContext, VOS_MODULE_ID moduleID,
                             v_VOID_t *pModuleContext )
{
  v_VOID_t ** pGpModContext = NULL;

  if (( pVosContext == NULL) || ( gpVosContext != pVosContext) ||
      ( pModuleContext == NULL))
  {
    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
        "%s: Null params or context mismatch", __func__);
    return VOS_STATUS_E_FAILURE;
  }


  switch(moduleID)
  {
    case VOS_MODULE_ID_TL:
    {
      pGpModContext = &(gpVosContext->pTLContext);
      break;
    }

    case VOS_MODULE_ID_WDA:
    {
      pGpModContext = &(gpVosContext->pWDAContext);
      break;
    }
    case VOS_MODULE_ID_HDD:
    case VOS_MODULE_ID_SME:
    case VOS_MODULE_ID_PE:
    case VOS_MODULE_ID_PMC:
    case VOS_MODULE_ID_HDD_SOFTAP:
    default:
    {
      VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: Module ID %i "
          "does not have its context allocated by VOSS", __func__, moduleID);
      VOS_ASSERT(0);
      return VOS_STATUS_E_INVAL;
    }
  }

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

  if (*pGpModContext != pModuleContext)
  {
    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
        "%s: pGpModContext != pModuleContext", __func__);
    return VOS_STATUS_E_FAILURE;
  }

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

  *pGpModContext = NULL;

  return VOS_STATUS_SUCCESS;

} /* vos_free_context() */

/**
 * vos_mq_post_message_by_priority() - posts message using priority
 * to message queue
 * @msgQueueId: message queue id
 * @pMsg: message to be posted
 * @is_high_priority: wheather message is high priority
 *
 * This function is used to post high priority message to message queue
 *
 * Return: VOS_STATUS_SUCCESS on success
 *         VOS_STATUS_E_FAILURE on failure
 *         VOS_STATUS_E_RESOURCES on resource allocation failure
 */
VOS_STATUS vos_mq_post_message_by_priority(VOS_MQ_ID msgQueueId,
					   vos_msg_t *pMsg,
					   int is_high_priority)
{
  pVosMqType      pTargetMq   = NULL;
  pVosMsgWrapper  pMsgWrapper = NULL;
  uint32_t debug_count;

  if ((gpVosContext == NULL) || (pMsg == NULL))
  {
    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
        "%s: Null params or global vos context is null", __func__);
    VOS_ASSERT(0);
    return VOS_STATUS_E_FAILURE;
  }

  switch (msgQueueId)
  {
    /// Message Queue ID for messages bound for SME
    case  VOS_MQ_ID_SME:
    {
       pTargetMq = &(gpVosContext->vosSched.smeMcMq);
       break;
    }

    /// Message Queue ID for messages bound for PE
    case VOS_MQ_ID_PE:
    {
       pTargetMq = &(gpVosContext->vosSched.peMcMq);
       break;
    }

    /// Message Queue ID for messages bound for WDA
    case VOS_MQ_ID_WDA:
    {
       pTargetMq = &(gpVosContext->vosSched.wdaMcMq);
       break;
    }

    /// Message Queue ID for messages bound for TL
    case VOS_MQ_ID_TL:
    {
       pTargetMq = &(gpVosContext->vosSched.tlMcMq);
       break;
    }

    /// Message Queue ID for messages bound for the SYS module
    case VOS_MQ_ID_SYS:
    {
       pTargetMq = &(gpVosContext->vosSched.sysMcMq);
       break;
    }

    default:

    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
              ("%s: Trying to queue msg into unknown MC Msg queue ID %d"),
              __func__, msgQueueId);

    return VOS_STATUS_E_FAILURE;
  }

  VOS_ASSERT(NULL !=pTargetMq);
  if (pTargetMq == NULL)
  {
     VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: pTargetMq == NULL", __func__);
     return VOS_STATUS_E_FAILURE;
  }

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

  if (NULL == pMsgWrapper) {
      debug_count = atomic_inc_return(&vos_wrapper_empty_count);
      if (1 == debug_count) {
           VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
              "%s: VOS Core run out of message wrapper %d",
              __func__, debug_count);
           vos_flush_logs(WLAN_LOG_TYPE_FATAL,
                          WLAN_LOG_INDICATOR_HOST_ONLY,
                          WLAN_LOG_REASON_VOS_MSG_UNDER_RUN,
                          DUMP_VOS_TRACE);
      }
      if (VOS_WRAPPER_MAX_FAIL_COUNT == debug_count) {
          vos_wlanRestart();
      }
      return VOS_STATUS_E_RESOURCES;
  }

  atomic_set(&vos_wrapper_empty_count, 0);

  /*
  ** Copy the message now
  */
  vos_mem_copy( (v_VOID_t*)pMsgWrapper->pVosMsg,
                (v_VOID_t*)pMsg, sizeof(vos_msg_t));

  if (is_high_priority)
      vos_mq_put_front(pTargetMq, pMsgWrapper);
  else
      vos_mq_put(pTargetMq, pMsgWrapper);

  set_bit(MC_POST_EVENT, &gpVosContext->vosSched.mcEventFlag);
  wake_up_interruptible(&gpVosContext->vosSched.mcWaitQueue);

  return VOS_STATUS_SUCCESS;

}

v_VOID_t
vos_sys_probe_thread_cback
(
  v_VOID_t *pUserData
)
{
  if (gpVosContext != pUserData)
  {
     VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: gpVosContext != pUserData", __func__);
     return;
  }

  if (vos_event_set(&gpVosContext->ProbeEvent)!= VOS_STATUS_SUCCESS)
  {
     VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: vos_event_set failed", __func__);
     return;
  }

} /* vos_sys_probe_thread_cback() */

v_VOID_t vos_WDAComplete_cback
(
  v_VOID_t *pUserData
)
{

  if (gpVosContext != pUserData)
  {
     VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: gpVosContext != pUserData", __func__);
     return;
  }

  if (vos_event_set(&gpVosContext->wdaCompleteEvent)!= VOS_STATUS_SUCCESS)
  {
     VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: vos_event_set failed", __func__);
     return;
  }

} /* vos_WDAComplete_cback() */

v_VOID_t vos_core_return_msg
(
  v_PVOID_t      pVContext,
  pVosMsgWrapper pMsgWrapper
)
{
  pVosContextType pVosContext = (pVosContextType) pVContext;

  VOS_ASSERT( gpVosContext == pVosContext);

  if (gpVosContext != pVosContext)
  {
     VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: gpVosContext != pVosContext", __func__);
     return;
  }

  VOS_ASSERT( NULL !=pMsgWrapper );

  if (pMsgWrapper == NULL)
  {
     VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: pMsgWrapper == NULL in function", __func__);
     return;
  }

  /*
  ** Return the message on the free message queue
  */
  INIT_LIST_HEAD(&pMsgWrapper->msgNode);
  vos_mq_put(&pVosContext->freeVosMq, pMsgWrapper);

} /* vos_core_return_msg() */


/**
  @brief vos_fetch_tl_cfg_parms() - this function will attempt to read the
  TL config params from the registry

  @param pAdapter : [inout] pointer to TL config block

  @return
  None

*/
v_VOID_t
vos_fetch_tl_cfg_parms
(
  WLANTL_ConfigInfoType *pTLConfig,
  hdd_config_t * pConfig
)
{
  if (pTLConfig == NULL)
  {
   VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s NULL ptr passed in!", __func__);
   return;
  }

  pTLConfig->uDelayedTriggerFrmInt = pConfig->DelayedTriggerFrmInt;
  pTLConfig->uMinFramesProcThres = pConfig->MinFramesProcThres;
  pTLConfig->ip_checksum_offload = pConfig->enableIPChecksumOffload;
  pTLConfig->enable_rxthread =
    (WLAN_HDD_RX_HANDLE_RX_THREAD == pConfig->rxhandle) ? 1 : 0;
}

/*---------------------------------------------------------------------------

  \brief vos_shutdown() - shutdown VOS

     - All VOS submodules are closed.

     - All the WLAN SW components should have been opened. This includes
       SYS, MAC, SME and TL.


  \param  vosContext: Global vos context


  \return VOS_STATUS_SUCCESS - Operation successfull & vos is shutdown

          VOS_STATUS_E_FAILURE - Failure to close

---------------------------------------------------------------------------*/
VOS_STATUS vos_shutdown(v_CONTEXT_t vosContext)
{
  VOS_STATUS vosStatus;

  vosStatus = wma_wmi_work_close(vosContext);
  if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
     VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
               "%s: Fail to close wma_wmi_work!", __func__);
     VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
  }

  if (gpVosContext->htc_ctx)
  {
    HTCStop(gpVosContext->htc_ctx);
    HTCDestroy(gpVosContext->htc_ctx);
    gpVosContext->htc_ctx = NULL;
  }

  vosStatus = WLANTL_Close(vosContext);
  if (!VOS_IS_STATUS_SUCCESS(vosStatus))
  {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: Failed to close TL", __func__);
     VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
  }

  vosStatus = sme_Close( ((pVosContextType)vosContext)->pMACContext);
  if (!VOS_IS_STATUS_SUCCESS(vosStatus))
  {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: Failed to close SME", __func__);
     VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
  }

  vosStatus = macClose( ((pVosContextType)vosContext)->pMACContext);
  if (!VOS_IS_STATUS_SUCCESS(vosStatus))
  {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: Failed to close MAC", __func__);
     VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
  }

  ((pVosContextType)vosContext)->pMACContext = NULL;

  vosStatus = sysClose( vosContext );
  if (!VOS_IS_STATUS_SUCCESS(vosStatus))
  {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: Failed to close SYS", __func__);
     VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
  }

  if (TRUE == WDA_needShutdown(vosContext))
  {
    /* If WDA stop failed, call WDA shutdown to cleanup WDA/WDI. */
    vosStatus = WDA_shutdown(vosContext, VOS_TRUE);
    if (!VOS_IS_STATUS_SUCCESS(vosStatus))
    {
      VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                "%s: Failed to shutdown WDA!", __func__);
      VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
    }
  }
  else
  {
    vosStatus = WDA_close(vosContext);
    if (!VOS_IS_STATUS_SUCCESS(vosStatus))
    {
      VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                "%s: Failed to close WDA!", __func__);
      VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
    }
  }

  vosStatus = wma_wmi_service_close(vosContext);
  if (!VOS_IS_STATUS_SUCCESS(vosStatus))
  {
     VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
               "%s: Failed to close wma_wmi_service!", __func__);
               VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
  }

  vos_mq_deinit(&((pVosContextType)vosContext)->freeVosMq);

  vosStatus = vos_event_destroy(&gpVosContext->wdaCompleteEvent);
  if (!VOS_IS_STATUS_SUCCESS(vosStatus))
  {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: failed to destroy wdaCompleteEvent", __func__);
     VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
  }

  vosStatus = vos_event_destroy(&gpVosContext->ProbeEvent);
  if (!VOS_IS_STATUS_SUCCESS(vosStatus))
  {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: failed to destroy ProbeEvent", __func__);
     VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
  }

  return VOS_STATUS_SUCCESS;
}

/*---------------------------------------------------------------------------

  \brief vos_wda_shutdown() - VOS interface to wda shutdown

     - WDA/WDI shutdown

  \param  vosContext: Global vos context


  \return VOS_STATUS_SUCCESS - Operation successfull

          VOS_STATUS_E_FAILURE - Failure to close

---------------------------------------------------------------------------*/
VOS_STATUS vos_wda_shutdown(v_CONTEXT_t vosContext)
{
  VOS_STATUS vosStatus;
  vosStatus = WDA_shutdown(vosContext, VOS_FALSE);

  if (!VOS_IS_STATUS_SUCCESS(vosStatus))
  {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
         "%s: failed to shutdown WDA", __func__);
     VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
  }
  return vosStatus;
}
/**
  @brief vos_wlanShutdown() - This API will shutdown WLAN driver

  This function is called when Riva subsystem crashes.  There are two
  methods (or operations) in WLAN driver to handle Riva crash,
    1. shutdown: Called when Riva goes down, this will shutdown WLAN
                 driver without handshaking with Riva.
    2. re-init:  Next API
  @param
       NONE
  @return
       VOS_STATUS_SUCCESS   - Operation completed successfully.
       VOS_STATUS_E_FAILURE - Operation failed.

*/
VOS_STATUS vos_wlanShutdown(void)
{
   VOS_STATUS vstatus;
   vstatus = vos_watchdog_wlan_shutdown();
   return vstatus;
}
/**
  @brief vos_wlanReInit() - This API will re-init WLAN driver

  This function is called when Riva subsystem reboots.  There are two
  methods (or operations) in WLAN driver to handle Riva crash,
    1. shutdown: Previous API
    2. re-init:  Called when Riva comes back after the crash. This will
                 re-initialize WLAN driver. In some cases re-open may be
                 referred instead of re-init.
  @param
       NONE
  @return
       VOS_STATUS_SUCCESS   - Operation completed successfully.
       VOS_STATUS_E_FAILURE - Operation failed.

*/
VOS_STATUS vos_wlanReInit(void)
{
   VOS_STATUS vstatus;
   vstatus = vos_watchdog_wlan_re_init();
   return vstatus;
}
/**
  @brief vos_wlanRestart() - This API will reload WLAN driver.

  This function is called if driver detects any fatal state which
  can be recovered by a WLAN module reload ( Android framwork initiated ).
  Note that this API will not initiate any RIVA subsystem restart.

  The function wlan_hdd_restart_driver protects against re-entrant calls.

  @param
       NONE
  @return
       VOS_STATUS_SUCCESS   - Operation completed successfully.
       VOS_STATUS_E_FAILURE - Operation failed.
       VOS_STATUS_E_EMPTY   - No configured interface
       VOS_STATUS_E_ALREADY - Request already in progress


*/
VOS_STATUS vos_wlanRestart(void)
{
   VOS_STATUS vstatus;
   hdd_context_t *pHddCtx = NULL;
   v_CONTEXT_t pVosContext        = NULL;

   /* Check whether driver load unload is in progress */
   if(vos_is_load_unload_in_progress( VOS_MODULE_ID_VOSS, NULL))
   {
      VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
               "%s: Driver load/unload is in progress, retry later.", __func__);
      return VOS_STATUS_E_AGAIN;
   }

   /* Get the Global VOSS Context */
   pVosContext = vos_get_global_context(VOS_MODULE_ID_VOSS, NULL);
   if(!pVosContext) {
      VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
               "%s: Global VOS context is Null", __func__);
      return VOS_STATUS_E_FAILURE;
   }

   /* Get the HDD context */
   pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
   if(!pHddCtx) {
      VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
               "%s: HDD context is Null", __func__);
      return VOS_STATUS_E_FAILURE;
   }

   /* Reload the driver */
   vstatus = wlan_hdd_restart_driver(pHddCtx);
   return vstatus;
}


/**
  @brief vos_fwDumpReq()

  This function is called to issue dump commands to Firmware

  @param
       cmd - Command No. to execute
       arg1 - argument 1 to cmd
       arg2 - argument 2 to cmd
       arg3 - argument 3 to cmd
       arg4 - argument 4 to cmd
  @return
       NONE
*/
v_VOID_t vos_fwDumpReq(tANI_U32 cmd, tANI_U32 arg1, tANI_U32 arg2,
                        tANI_U32 arg3, tANI_U32 arg4)
{
   WDA_HALDumpCmdReq(NULL, cmd, arg1, arg2, arg3, arg4, NULL);
}

VOS_STATUS vos_get_vdev_types(tVOS_CON_MODE mode, tANI_U32 *type,
        tANI_U32 *sub_type)
{
    VOS_STATUS status = VOS_STATUS_SUCCESS;
    *type = 0;
    *sub_type = 0;
    switch (mode)
    {
        case VOS_STA_MODE:
            *type = WMI_VDEV_TYPE_STA;
            break;
        case VOS_STA_SAP_MODE:
            *type = WMI_VDEV_TYPE_AP;
            break;
        case VOS_P2P_DEVICE_MODE:
            *type = WMI_VDEV_TYPE_AP;
            *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE;
            break;
        case VOS_P2P_CLIENT_MODE:
            *type = WMI_VDEV_TYPE_STA;
            *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT;
            break;
        case VOS_P2P_GO_MODE:
            *type = WMI_VDEV_TYPE_AP;
            *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO;
            break;
        case VOS_OCB_MODE:
            *type = WMI_VDEV_TYPE_OCB;
            break;
        case VOS_IBSS_MODE:
            *type = WMI_VDEV_TYPE_IBSS;
            break;
        case VOS_NDI_MODE:
            *type = WMI_VDEV_TYPE_NDI;
            break;
        default:
            hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid device mode %d", mode);
            status = VOS_STATUS_E_INVAL;
            break;
    }
    return status;
}

v_BOOL_t vos_is_packet_log_enabled(void)
{
   hdd_context_t *pHddCtx;

   pHddCtx = (hdd_context_t*)(gpVosContext->pHDDContext);
   if((NULL == pHddCtx) ||
      (NULL == pHddCtx->cfg_ini))
   {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
               "%s: Hdd Context is Null", __func__);
     return FALSE;
   }

   return pHddCtx->cfg_ini->enablePacketLog;
}

v_BOOL_t vos_config_is_no_ack(void)
{
   hdd_context_t *pHddCtx;

   pHddCtx = (hdd_context_t*)(gpVosContext->pHDDContext);
   if((NULL == pHddCtx) ||
      (NULL == pHddCtx->cfg_ini))
   {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
               "%s: Hdd Context is Null", __func__);
     return FALSE;
   }

   return pHddCtx->cfg_ini->gEnableNoAck;
}

#ifdef WLAN_FEATURE_TSF_PLUS
bool vos_is_ptp_rx_opt_enabled(void)
{
	hdd_context_t *hdd_ctx;

	hdd_ctx = (hdd_context_t *)(gpVosContext->pHDDContext);
	if ((NULL == hdd_ctx) || (NULL == hdd_ctx->cfg_ini)) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
			  "%s: Hdd Context is Null", __func__);
		return false;
	}

	return HDD_TSF_IS_RX_SET(hdd_ctx);
}

bool vos_is_ptp_tx_opt_enabled(void)
{
	hdd_context_t *hdd_ctx;

	hdd_ctx = (hdd_context_t *)(gpVosContext->pHDDContext);
	if ((NULL == hdd_ctx) || (NULL == hdd_ctx->cfg_ini)) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
			  "%s: Hdd Context is Null", __func__);
		return false;
	}

	return HDD_TSF_IS_TX_SET(hdd_ctx);
}
#endif

#ifdef WLAN_FEATURE_DSRC
bool vos_is_ocb_tx_per_pkt_stats_enabled(void)
{
	hdd_context_t *hdd_ctx;

	hdd_ctx = (hdd_context_t *)(gpVosContext->pHDDContext);

	if ((NULL == hdd_ctx) || (NULL == hdd_ctx->cfg_ini)) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
			  "%s: Hdd Context is Null", __func__);
		return false;
	}

	return hdd_ctx->cfg_ini->ocb_tx_per_pkt_stats_enabled;
}
#endif

VOS_STATUS vos_config_silent_recovery(pVosContextType vos_context)
{
	struct ol_softc *scn;
	struct device *dev;

	if (vos_is_logp_in_progress(VOS_MODULE_ID_VOSS, NULL)) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
			FL("LOGP is in progress, ignore!"));
		return VOS_STATUS_E_FAILURE;
	}
	vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, TRUE);
	scn = vos_get_context(VOS_MODULE_ID_HIF, vos_context);
	if (scn && scn->hif_sc) {
		dev = scn->hif_sc->dev;
		if (dev)
			vos_schedule_recovery_work(dev);
	}
	return VOS_STATUS_SUCCESS;
}

void vos_trigger_recovery(bool skip_crash_inject)
{
	pVosContextType vos_context;
	tp_wma_handle wma_handle;
	VOS_STATUS status = VOS_STATUS_SUCCESS;
	void *runtime_context = NULL;

	vos_context = vos_get_global_context(VOS_MODULE_ID_VOSS, NULL);
	if (!vos_context) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
			"VOS context is invald!");
		return;
	}

	wma_handle = (tp_wma_handle)vos_get_context(VOS_MODULE_ID_WDA,
						vos_context);
	if (!wma_handle) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
			"WMA context is invald!");
		return;
	}

	runtime_context = vos_runtime_pm_prevent_suspend_init("vos_recovery");
	vos_runtime_pm_prevent_suspend(runtime_context);

	if (!skip_crash_inject) {
		wma_crash_inject(wma_handle, RECOVERY_SIM_SELF_RECOVERY, 0);
		status = vos_wait_single_event(&wma_handle->recovery_event,
			WMA_CRASH_INJECT_TIMEOUT);

		if (VOS_STATUS_SUCCESS != status) {
			VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
				"CRASH_INJECT command is timed out!");
			if (!vos_config_silent_recovery(vos_context))
				goto out;
		}
	} else {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
				FL("trigger silent recovery!"));
		if (!vos_config_silent_recovery(vos_context))
			goto out;
	}
out:
	vos_runtime_pm_allow_suspend(runtime_context);
	vos_runtime_pm_prevent_suspend_deinit(runtime_context);
}

/**
 * @brief vos_get_monotonic_boottime()
 * Get kernel boot time.
 * @return Time in microseconds
 */

v_U64_t vos_get_monotonic_boottime(void)
{
#ifdef CONFIG_CNSS
   struct timespec ts;

   vos_get_monotonic_boottime_ts(&ts);
   return (((v_U64_t)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000));
#else
   return ((v_U64_t)adf_os_ticks_to_msecs(adf_os_ticks()) * 1000);
#endif
}

#ifdef FEATURE_WLAN_D0WOW
v_VOID_t vos_pm_control(v_BOOL_t vote)
{
    vos_wlan_pm_control(vote);
}
#endif

/**
 * vos_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 vos_set_wakelock_logging(bool value)
{
	VosContextType *vos_context;

	vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
	if (!vos_context) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
				"vos context is Invald");
		return;
	}
	vos_context->is_wakelock_log_enabled = value;
}

/**
 * vos_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 vos_is_wakelock_enabled(void)
{
	VosContextType *vos_context;

	vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
	if (!vos_context) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
				"vos context is Invald");
		return false;
	}
	return vos_context->is_wakelock_log_enabled;
}

/**
 * vos_set_ring_log_level() - Convert HLOS values to driver log levels
 * @ring_id: ring_id
 * @log_levelvalue: Log level specificed
 *
 * This function sets the log level of a particular ring
 *
 * Return: None
 */
void vos_set_ring_log_level(uint32_t ring_id, uint32_t log_level)
{
	VosContextType *vos_context;
	uint32_t log_val;

	vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
	if (!vos_context) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
				"%s: vos 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) {
		vos_context->wakelock_log_level = log_val;
		return;
	} else if (ring_id == RING_ID_CONNECTIVITY) {
		vos_context->connectivity_log_level = log_val;
		return;
	} else if (ring_id == RING_ID_PER_PACKET_STATS) {
		vos_context->packet_stats_log_level = log_val;
		return;
	} else if (ring_id == RING_ID_DRIVER_DEBUG) {
		vos_context->driver_debug_log_level = log_val;
		return;
	} else if (ring_id == RING_ID_FIRMWARE_DEBUG) {
		vos_context->fw_debug_log_level = log_val;
		return;
	}
}

/**
 * vos_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 vos_get_ring_log_level(uint32_t ring_id)
{
	VosContextType *vos_context;

	vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
	if (!vos_context) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
				"%s: vos context is Invald", __func__);
		return WLAN_LOG_LEVEL_OFF;
	}

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

	return WLAN_LOG_LEVEL_OFF;
}

/**
 * vos_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 vos_set_multicast_logging(uint8_t value)
{
	vos_multicast_logging = value;
}

/**
 * vos_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 vos_is_multicast_logging(void)
{
	return vos_multicast_logging;
}

/*
 * vos_reset_log_completion() - Reset log param structure
 *@vos_context: Pointer to global vos context
 *
 * This function is used to reset the logging related
 * parameters to default.
 *
 * Return: None
 */
void vos_reset_log_completion(VosContextType *vos_context)
{
	/* Vos Context is validated by the caller */
	vos_spin_lock_acquire(&vos_context->bug_report_lock);
	vos_context->log_complete.indicator = WLAN_LOG_INDICATOR_UNUSED;
	vos_context->log_complete.is_fatal = WLAN_LOG_TYPE_NON_FATAL;
	vos_context->log_complete.is_report_in_progress = false;
	vos_context->log_complete.reason_code = WLAN_LOG_REASON_CODE_UNUSED;
	vos_spin_lock_release(&vos_context->bug_report_lock);
}

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

	vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
	if (!vos_context) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
				"%s: vos context is Invalid", __func__);
		return;
	}

	vos_context->log_complete.is_fatal = WLAN_LOG_TYPE_NON_FATAL;
	vos_context->log_complete.indicator = WLAN_LOG_INDICATOR_UNUSED;
	vos_context->log_complete.reason_code = WLAN_LOG_REASON_CODE_UNUSED;
	vos_context->log_complete.is_report_in_progress = false;

	vos_spin_lock_init(&vos_context->bug_report_lock);
}

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

	vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
	if (!vos_context) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
				"%s: vos context is Invalid", __func__);
		return;
	}

	vos_spin_lock_destroy(&vos_context->bug_report_lock);
}

/**
 * vos_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
 */
VOS_STATUS vos_set_log_completion(uint32_t is_fatal,
		uint32_t indicator,
		uint32_t reason_code)
{
	VosContextType *vos_context;

	vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
	if (!vos_context) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
				"%s: vos context is Invalid", __func__);
		return VOS_STATUS_E_FAILURE;
	}

	vos_spin_lock_acquire(&vos_context->bug_report_lock);
	vos_context->log_complete.is_fatal = is_fatal;
	vos_context->log_complete.indicator = indicator;
	vos_context->log_complete.reason_code = reason_code;
	vos_context->log_complete.is_report_in_progress = true;
	vos_spin_lock_release(&vos_context->bug_report_lock);
	return VOS_STATUS_SUCCESS;
}

/**
 * vos_get_log_and_reset_completion() - Get and reset 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
 * @ssr_needed: Indicates if SSR is required or not
 *
 * This function is used to get the logging related parameters
 *
 * Return: None
 */
void vos_get_log_and_reset_completion(uint32_t *is_fatal,
		uint32_t *indicator,
		uint32_t *reason_code,
		uint32_t *is_ssr_needed)
{
	VosContextType *vos_context;

	vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
	if (!vos_context) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
				"%s: vos context is Invalid", __func__);
		return;
	}

	vos_spin_lock_acquire(&vos_context->bug_report_lock);
	*is_fatal =  vos_context->log_complete.is_fatal;
	*indicator = vos_context->log_complete.indicator;
	*reason_code = vos_context->log_complete.reason_code;

	if ((WLAN_LOG_INDICATOR_HOST_DRIVER == *indicator) &&
	    ((WLAN_LOG_REASON_SME_OUT_OF_CMD_BUF == *reason_code) ||
		 (WLAN_LOG_REASON_SME_COMMAND_STUCK == *reason_code) ||
		 (WLAN_LOG_REASON_STALE_SESSION_FOUND == *reason_code) ||
		 (WLAN_LOG_REASON_SCAN_NOT_ALLOWED == *reason_code)))
		*is_ssr_needed = true;
	else
		*is_ssr_needed = false;

	vos_spin_lock_release(&vos_context->bug_report_lock);

	vos_reset_log_completion(vos_context);
}

/**
 * vos_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 vos_is_log_report_in_progress(void)
{
	VosContextType *vos_context;

	vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
	if (!vos_context) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
				"%s: vos context is Invalid", __func__);
		return true;
	}
	return vos_context->log_complete.is_report_in_progress;
}
/**
 * vos_is_fatal_event_enabled() - Return if fatal event is enabled
 *
 * Return true if fatal event is enabled is in progress.
 */
bool vos_is_fatal_event_enabled(void)
{
	VosContextType *vos_context =
			 vos_get_global_context(VOS_MODULE_ID_SYS, NULL);

	if (!vos_context) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
				"%s: Global VOS context is Null", __func__);
		return false;
	}

	return vos_context->enable_fatal_event;
}

/**
 * vos_get_log_indicator() - Get the log flush indicator
 *
 * This function is used to get the log flush indicator
 *
 * Return: log indicator
 */
uint32_t vos_get_log_indicator(void)
{
	VosContextType *vos_context;
	uint32_t indicator;

	vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
	if (!vos_context) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
			  FL("vos context is Invalid"));
		return WLAN_LOG_INDICATOR_UNUSED;
	}
	if (vos_context->isLoadUnloadInProgress ||
		vos_context->isLogpInProgress ||
		vos_context->isReInitInProgress) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
			  FL("In LoadUnload: %u LogP: %u ReInit: %u"),
			     vos_context->isLoadUnloadInProgress,
			     vos_context->isLogpInProgress,
			     vos_context->isReInitInProgress);
		return WLAN_LOG_INDICATOR_UNUSED;
	}

	vos_spin_lock_acquire(&vos_context->bug_report_lock);
	indicator = vos_context->log_complete.indicator;
	vos_spin_lock_release(&vos_context->bug_report_lock);
	return indicator;
}

/**
 * vos_wlan_flush_host_logs_for_fatal() - Wrapper to flush host logs
 *
 * This function is used to send signal to the logger thread to
 * flush the host logs.
 *
 * Return: None
 *
 */
void vos_wlan_flush_host_logs_for_fatal(void)
{
	wlan_flush_host_logs_for_fatal();
}

/**
 * vos_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
 * @dump_vos_trace: If vos trace are needed in logs.
 * @pkt_trace: flag to indicate when to report packet trace
 *             dump this info when connection related error occurs
 *
 * 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
 */
VOS_STATUS vos_flush_logs(uint32_t is_fatal,
		uint32_t indicator,
		uint32_t reason_code,
		uint32_t dump_trace)
{
	uint32_t ret;
	VOS_STATUS status;
	VosContextType *vos_context;

	vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
	if (!vos_context) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
				"%s: vos context is Invalid", __func__);
		return eHAL_STATUS_FAILURE;
	}

	if (!vos_context->enable_fatal_event) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
				"%s: Fatal event not enabled", __func__);
		return eHAL_STATUS_FAILURE;
	}
	if (vos_context->is_unload_in_progress ||
	    vos_context->is_load_in_progress ||
	    vos_context->isLogpInProgress) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
				"%s: un/Load/SSR in progress", __func__);
		return eHAL_STATUS_FAILURE;
	}

	if (vos_is_log_report_in_progress() == true) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
				"%s: Bug report already in progress - dropping! type:%d, indicator=%d reason_code=%d",
				__func__, is_fatal, indicator, reason_code);
		return VOS_STATUS_E_FAILURE;
	}

	status = vos_set_log_completion(is_fatal, indicator, reason_code);
	if (VOS_STATUS_SUCCESS != status) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			"%s: Failed to set log trigger params", __func__);
		return VOS_STATUS_E_FAILURE;
	}

	VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			"%s: Triggering bug report: type:%d, indicator=%d reason_code=%d dump_trace=0x%x",
			__func__, is_fatal, indicator, reason_code, dump_trace);

	if (dump_trace & DUMP_VOS_TRACE)
		vosTraceDumpAll(vos_context->pMACContext, 0, 0, 500, 0);

#ifdef QCA_PKT_PROTO_TRACE
	if (dump_trace & DUMP_PACKET_TRACE)
		vos_pkt_trace_buf_dump();
#endif
	if (WLAN_LOG_INDICATOR_HOST_ONLY == indicator) {
		vos_wlan_flush_host_logs_for_fatal();
		return VOS_STATUS_SUCCESS;
	}
	ret = vos_send_flush_logs_cmd_to_fw(vos_context->pMACContext);
	if (0 != ret) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			"%s: Failed to send flush FW log", __func__);
		vos_reset_log_completion(vos_context);
		return VOS_STATUS_E_FAILURE;
	}

	return VOS_STATUS_SUCCESS;
}

/**
 * vos_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 vos_logging_set_fw_flush_complete(void)
{
	wlan_logging_set_fw_flush_complete();
}

/**
 * vos_set_fatal_event() - set fatal event status
 * @value: pending statue to set
 *
 * Return: None
 */
void vos_set_fatal_event(bool value)
{
	if (gpVosContext == NULL) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
			  "%s: global voss context is NULL", __func__);
		return;
	}

	gpVosContext->enable_fatal_event = value;
}

/**
 * vos_probe_threads() - VOS API to post messages
 * to all the threads to detect if they are active or not
 *
 * Return: None
 *
 */
void vos_probe_threads(void)
{
	vos_msg_t msg;

	msg.callback = vos_wd_reset_thread_stuck_count;
	/* Post Message to MC Thread */
	sysBuildMessageHeader(SYS_MSG_ID_MC_THR_PROBE, &msg);
	if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SYS, &msg)) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
			  FL("Unable to post SYS_MSG_ID_MC_THR_PROBE message to MC thread"));
	}
}
/**
 * vos_pkt_stats_to_logger_thread() - send pktstats to user
 * @pl_hdr: Pointer to pl_hdr
 * @pkt_dump: Pointer to pkt_dump data structure.
 * @data: Pointer to data
 *
 * This function is used to send the pkt stats to SVC module.
 *
 * Return: None
 */
inline void vos_pkt_stats_to_logger_thread(void *pl_hdr, void *pkt_dump,
						void *data)
{
	if (vos_get_ring_log_level(RING_ID_PER_PACKET_STATS) !=
						WLAN_LOG_LEVEL_ACTIVE)
		return;

	wlan_pkt_stats_to_logger_thread(pl_hdr, pkt_dump, data);
}

/**
 * vos_get_radio_index() - get radio index
 *
 * Return: radio index otherwise, -EINVAL
 */
int vos_get_radio_index(void)
{
	if (gpVosContext == NULL) {
		/* this should never change to use VOS_TRACE interface */
		pr_err("global voss context is NULL\n");
		return -EINVAL;
	}
	return gpVosContext->radio_index;
}

/**
 * vos_set_radio_index() - set radio index
 * @radio_index:	the radio index
 *
 * Return: 0 for success, otherwise -EINVAL
 */
int vos_set_radio_index(int radio_index)
{
	if (gpVosContext == NULL) {
		/* this should never change to use VOS_TRACE interface */
		pr_err("global voss context is NULL\n");
		return -EINVAL;
	}

	gpVosContext->radio_index = radio_index;
	return 0;
}

/**
 * vos_svc_fw_shutdown_ind() - API to send userspace about FW crash
 *
 * @data: Device Pointer
 *
 * Return: None
*/
void vos_svc_fw_shutdown_ind(struct device *dev)
{
	hdd_svc_fw_shutdown_ind(dev);
}

v_U64_t vos_get_monotonic_boottime_ns(void)
{
	struct timespec ts;

	ktime_get_ts(&ts);
	return timespec_to_ns(&ts);
}

#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 10, 0))
v_U64_t vos_get_bootbased_boottime_ns(void)
{
	return ktime_get_boot_ns();
}

#else
v_U64_t vos_get_bootbased_boottime_ns(void)
{
	return ktime_to_ns(ktime_get_boottime());
}
#endif

/**
 * vos_do_div() - wrapper function for kernel macro(do_div).
 *
 * @dividend: Dividend value
 * @divisor : Divisor value
 *
 * Return: Quotient
 */
uint64_t vos_do_div(uint64_t dividend, uint32_t divisor)
{
	do_div(dividend, divisor);
	/*do_div macro updates dividend with Quotient of dividend/divisor */
	return dividend;
}

uint64_t vos_do_div64(uint64_t dividend, uint64_t divisor)
{
	uint64_t n = dividend;
	uint64_t base = divisor;
	if ((base & 0xffffffff00000000ULL) != 0) {
		n >>= 16;
		base >>= 16;

		if ((base & 0xffff00000000ULL) != 0) {
			n >>= 16;
			base >>= 16;
		}
		return vos_do_div(n, (uint32_t)base);
	} else {
		return vos_do_div(n, base);
	}
}

/**
 * vos_force_fw_dump() - force target to dump
 *
 *return
 * VOS_STATUS_SUCCESS   - Operation completed successfully.
 * VOS_STATUS_E_FAILURE - Operation failed.
 */
VOS_STATUS vos_force_fw_dump(void)
{
	struct ol_softc *scn;

	scn = vos_get_context(VOS_MODULE_ID_HIF, gpVosContext);
	if (!scn) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
			  "%s: scn is null!", __func__);
		return VOS_STATUS_E_FAILURE;
	}
	VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
		  "%s:enter!", __func__);

	ol_target_failure(scn, A_ERROR);

	return VOS_STATUS_SUCCESS;
}

/**
 * vos_is_probe_rsp_offload_enabled - API to check if probe response offload
 *                                    feature is enabled from ini
 *
 * return - false: probe response offload is disabled/any-error
 *          true: probe response offload is enabled
 */
bool vos_is_probe_rsp_offload_enabled(void)
{
	hdd_context_t *pHddCtx = NULL;

	if (gpVosContext == NULL) {
		pr_err("global voss context is NULL\n");
		return false;
	}

	pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD,
						   gpVosContext);
	if (!pHddCtx) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
			  "%s: HDD context is Null", __func__);
		return false;
	}

	return pHddCtx->cfg_ini->sap_probe_resp_offload;
}

bool vos_is_mon_enable(void)
{
	hdd_context_t *phdd_ctx = NULL;

	if (gpVosContext == NULL) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
			  "%s: global voss context is NULL", __func__);
		return false;
	}

	phdd_ctx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD,
						   gpVosContext);
	if (!phdd_ctx) {
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
			  "%s: HDD context is Null", __func__);
		return false;
	}

	return phdd_ctx->is_mon_enable;
}
