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

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




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

                       W L A N _ Q C T _ W D I. C

  OVERVIEW:

  This software unit holds the implementation of the WLAN Device Abstraction
  Layer Interface.

  The functions externalized by this module are to be called by any upper
  MAC implementation that wishes to use the WLAN Device.

  DEPENDENCIES:

  Are listed for each API below.


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

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

                      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
----------    ---    --------------------------------------------------------
10/05/11      hap     Adding support for Keep Alive
2010-08-09    lti     Created module

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

/*----------------------------------------------------------------------------
 * Include Files
 * -------------------------------------------------------------------------*/
#include "wlan_qct_wdi.h"
#include "wlan_qct_wdi_i.h"
#include "wlan_qct_wdi_sta.h"
#include "wlan_qct_wdi_dp.h"

#include "wlan_qct_wdi_cts.h"

#include "wlan_qct_pal_api.h"
#include "wlan_qct_pal_type.h"
#include "wlan_qct_pal_status.h"
#include "wlan_qct_pal_sync.h"
#include "wlan_qct_pal_msg.h"
#include "wlan_qct_pal_trace.h"
#include "wlan_qct_pal_packet.h"

#include "wlan_qct_wdi_dts.h"

#include "wlan_hal_msg.h"

#include "pttMsgApi.h"
#include "vos_trace.h"

#include "vos_api.h"

/*===========================================================================
   WLAN DAL Control Path Internal Data Definitions and Declarations
 ===========================================================================*/
#define WDI_WCTS_ACTION_TIMEOUT       2000 /* in msec a very high upper limit */

#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x"

#define FEATURE_NOT_SUPPORTED 127
#define MAX_FW_HOST_CAP_SIZE 1024
#ifdef FEATURE_WLAN_SCAN_PNO
#define WDI_PNO_VERSION_MASK 0x8000
#endif

/* host capability bitmap global */
static tWlanFeatCaps *gpHostWlanFeatCaps;
/* FW capability bitmap global */
static tWlanFeatCaps *gpFwWlanFeatCaps;
/* array of features supported. Need to add a new feature
 * and other two places - wlan_hal_msg.h and halMsg.c (FW file)
 */
static placeHolderInCapBitmap supportEnabledFeatures[] =
   {MCC, P2P, DOT11AC, SLM_SESSIONIZATION, DOT11AC_OPMODE
#ifdef WLAN_SOFTAP_VSTA_FEATURE
    ,SAP32STA                       //5
#else
    ,FEATURE_NOT_SUPPORTED
#endif
#ifdef FEATURE_WLAN_TDLS
    ,TDLS                           //6
#else
    ,FEATURE_NOT_SUPPORTED
#endif
    ,P2P_GO_NOA_DECOUPLE_INIT_SCAN  //7
#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
    ,WLANACTIVE_OFFLOAD             //8
#else
    ,FEATURE_NOT_SUPPORTED
#endif
    ,FEATURE_NOT_SUPPORTED          //9
    ,FEATURE_NOT_SUPPORTED          //10
    ,FEATURE_NOT_SUPPORTED          //11
    ,FEATURE_NOT_SUPPORTED          //12
    ,FEATURE_NOT_SUPPORTED          //13
    ,FEATURE_NOT_SUPPORTED          //14
    ,FEATURE_NOT_SUPPORTED          //15
    ,FEATURE_NOT_SUPPORTED          //16
    ,FEATURE_NOT_SUPPORTED          //17
    ,FEATURE_NOT_SUPPORTED          //18
    ,FEATURE_NOT_SUPPORTED          //19
    ,FEATURE_NOT_SUPPORTED          //20
    ,FEATURE_NOT_SUPPORTED          //21
    ,WOW                            //22
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
    ,WLAN_ROAM_SCAN_OFFLOAD         //23
#else
    ,FEATURE_NOT_SUPPORTED
#endif
    ,FEATURE_NOT_SUPPORTED          //24
    ,FEATURE_NOT_SUPPORTED          //25
    ,IBSS_HEARTBEAT_OFFLOAD         //26
    ,FEATURE_NOT_SUPPORTED          //27
    ,WLAN_PERIODIC_TX_PTRN          //28
#ifdef FEATURE_WLAN_TDLS
    ,ADVANCE_TDLS                   //29
#else
    ,FEATURE_NOT_SUPPORTED          //29
#endif
    ,FEATURE_NOT_SUPPORTED          //30
    ,FW_IN_TX_PATH                  //31
    ,EXTENDED_NSOFFLOAD_SLOT        //32
    ,CH_SWITCH_V1                   //33
    ,HT40_OBSS_SCAN                 //34
    ,UPDATE_CHANNEL_LIST            //35
    ,FEATURE_NOT_SUPPORTED          //36
    ,FEATURE_NOT_SUPPORTED          //37
    ,FEATURE_NOT_SUPPORTED          //38
#ifdef FEATURE_WLAN_TDLS
    ,TDLS_SCAN_COEXISTENCE          //39
#else
    ,FEATURE_NOT_SUPPORTED          //39
#endif
#ifdef WLAN_FEATURE_LINK_LAYER_STATS
    ,LINK_LAYER_STATS_MEAS          //40
#else
    ,FEATURE_NOT_SUPPORTED          //40
#endif
    ,MU_MIMO                        //41
#ifdef WLAN_FEATURE_EXTSCAN
    ,EXTENDED_SCAN                  //42
#else
    ,FEATURE_NOT_SUPPORTED          //42
#endif
   ,DYNAMIC_WMM_PS                 //43

   ,MAC_SPOOFED_SCAN               //44
   ,BMU_ERROR_GENERIC_RECOVERY     //45
   ,DISA                           //46
   ,FW_STATS                       //47
   ,WPS_PRBRSP_TMPL                //48
   ,BCN_IE_FLT_DELTA               //49
   ,FEATURE_NOT_SUPPORTED          //50
#ifdef FEATURE_WLAN_TDLS
    ,TDLS_OFF_CHANNEL              //51
#else
    ,FEATURE_NOT_SUPPORTED         //51
#endif
   ,RTT3                           //52
   ,MGMT_FRAME_LOGGING             //53
   ,ENHANCED_TXBD_COMPLETION       //54
   ,LOGGING_ENHANCEMENT            //55
#ifdef WLAN_FEATURE_EXTSCAN
   ,EXT_SCAN_ENHANCED              //56
#else
    ,FEATURE_NOT_SUPPORTED         //56
#endif
   ,MEMORY_DUMP_SUPPORTED          //57
   ,PER_PKT_STATS_SUPPORTED        //58
   ,FEATURE_NOT_SUPPORTED          //59
#ifdef FEATURE_EXT_LL_STAT
   ,EXT_LL_STAT                    //60
#else
   ,FEATURE_NOT_SUPPORTED
#endif
   ,WIFI_CONFIG                    //61
   ,ANTENNA_DIVERSITY_SELECTION    //62
};

/*-------------------------------------------------------------------------- 
   WLAN DAL  State Machine
 --------------------------------------------------------------------------*/
WPT_STATIC const WDI_MainFsmEntryType wdiMainFSM[WDI_MAX_ST] =
{
  /*WDI_INIT_ST*/
  {{
    WDI_MainStart,              /*WDI_START_EVENT*/
    NULL,                       /*WDI_STOP_EVENT*/
    WDI_MainReqBusy,            /*WDI_REQUEST_EVENT*/
    WDI_MainRspInit,            /*WDI_RESPONSE_EVENT*/
    WDI_MainClose,              /*WDI_CLOSE_EVENT*/
    WDI_MainShutdown            /*WDI_SHUTDOWN_EVENT*/
  }},

  /*WDI_STARTED_ST*/
  {{
    WDI_MainStartStarted,       /*WDI_START_EVENT*/
    WDI_MainStopStarted,        /*WDI_STOP_EVENT*/
    WDI_MainReqStarted,         /*WDI_REQUEST_EVENT*/
    WDI_MainRsp,                /*WDI_RESPONSE_EVENT*/
    NULL,                       /*WDI_CLOSE_EVENT*/
    WDI_MainShutdown            /*WDI_SHUTDOWN_EVENT*/
  }},

  /*WDI_STOPPED_ST*/
  {{
    WDI_MainStart,              /*WDI_START_EVENT*/
    WDI_MainStopStopped,        /*WDI_STOP_EVENT*/
    NULL,                       /*WDI_REQUEST_EVENT*/
    WDI_MainRsp,                /*WDI_RESPONSE_EVENT*/
    WDI_MainClose,              /*WDI_CLOSE_EVENT*/
    WDI_MainShutdown            /*WDI_SHUTDOWN_EVENT*/
  }},

  /*WDI_BUSY_ST*/
  {{
    WDI_MainStartBusy,          /*WDI_START_EVENT*/
    WDI_MainStopBusy,           /*WDI_STOP_EVENT*/
    WDI_MainReqBusy,            /*WDI_REQUEST_EVENT*/
    WDI_MainRsp,                /*WDI_RESPONSE_EVENT*/
    WDI_MainCloseBusy,          /*WDI_CLOSE_EVENT*/
    WDI_MainShutdownBusy        /*WDI_SHUTDOWN_EVENT*/
  }}
};

/*---------------------------------------------------------------------------
  DAL Request Processing Array  - the functions in this table will only be
  called when the processing of the specific request is allowed by the
  Main FSM
 ---------------------------------------------------------------------------*/
WDI_ReqProcFuncType  pfnReqProcTbl[WDI_MAX_UMAC_IND] =
{
  /*INIT*/
  WDI_ProcessStartReq,      /* WDI_START_REQ  */
  WDI_ProcessStopReq,       /* WDI_STOP_REQ  */
  WDI_ProcessCloseReq,      /* WDI_CLOSE_REQ  */

  /*SCAN*/
  WDI_ProcessInitScanReq,   /* WDI_INIT_SCAN_REQ  */
  WDI_ProcessStartScanReq,  /* WDI_START_SCAN_REQ  */
  WDI_ProcessEndScanReq,    /* WDI_END_SCAN_REQ  */
  WDI_ProcessFinishScanReq, /* WDI_FINISH_SCAN_REQ  */

  /*ASSOCIATION*/
  WDI_ProcessJoinReq,       /* WDI_JOIN_REQ  */
  WDI_ProcessConfigBSSReq,  /* WDI_CONFIG_BSS_REQ  */
  WDI_ProcessDelBSSReq,     /* WDI_DEL_BSS_REQ  */
  WDI_ProcessPostAssocReq,  /* WDI_POST_ASSOC_REQ  */
  WDI_ProcessDelSTAReq,     /* WDI_DEL_STA_REQ  */

  /* Security */
  WDI_ProcessSetBssKeyReq,        /* WDI_SET_BSS_KEY_REQ  */
  WDI_ProcessRemoveBssKeyReq,     /* WDI_RMV_BSS_KEY_REQ  */
  WDI_ProcessSetStaKeyReq,        /* WDI_SET_STA_KEY_REQ  */
  WDI_ProcessRemoveStaKeyReq,     /* WDI_RMV_BSS_KEY_REQ  */

  /* QoS and BA APIs */
  WDI_ProcessAddTSpecReq,          /* WDI_ADD_TS_REQ  */
  WDI_ProcessDelTSpecReq,          /* WDI_DEL_TS_REQ  */
  WDI_ProcessUpdateEDCAParamsReq,  /* WDI_UPD_EDCA_PRMS_REQ  */
  WDI_ProcessAddBASessionReq,      /* WDI_ADD_BA_SESSION_REQ  */
  WDI_ProcessDelBAReq,             /* WDI_DEL_BA_REQ  */

  /* Miscellaneous Control APIs */
  WDI_ProcessChannelSwitchReq,     /* WDI_CH_SWITCH_REQ  */
  WDI_ProcessConfigStaReq,         /* WDI_CONFIG_STA_REQ  */
  WDI_ProcessSetLinkStateReq,      /* WDI_SET_LINK_ST_REQ  */
  WDI_ProcessGetStatsReq,          /* WDI_GET_STATS_REQ  */
  WDI_ProcessUpdateCfgReq,         /* WDI_UPDATE_CFG_REQ  */

  /*BA APIs*/
  WDI_ProcessAddBAReq,             /* WDI_ADD_BA_REQ  */
  WDI_ProcessTriggerBAReq,         /* WDI_TRIGGER_BA_REQ  */

  /*Beacon processing APIs*/
  WDI_ProcessUpdateBeaconParamsReq, /* WDI_UPD_BCON_PRMS_REQ */
  WDI_ProcessSendBeaconParamsReq, /* WDI_SND_BCON_REQ */

  WDI_ProcessUpdateProbeRspTemplateReq, /* WDI_UPD_PROBE_RSP_TEMPLATE_REQ */
  WDI_ProcessSetStaBcastKeyReq,        /* WDI_SET_STA_BCAST_KEY_REQ  */
  WDI_ProcessRemoveStaBcastKeyReq,     /* WDI_RMV_STA_BCAST_KEY_REQ  */
  WDI_ProcessSetMaxTxPowerReq,         /*WDI_SET_MAX_TX_POWER_REQ*/
  WDI_ProcessP2PGONOAReq,              /* WDI_P2P_GO_NOTICE_OF_ABSENCE_REQ */
  /* PowerSave APIs */
  WDI_ProcessEnterImpsReq,         /* WDI_ENTER_IMPS_REQ  */
  WDI_ProcessExitImpsReq,          /* WDI_EXIT_IMPS_REQ  */
  WDI_ProcessEnterBmpsReq,         /* WDI_ENTER_BMPS_REQ  */
  WDI_ProcessExitBmpsReq,          /* WDI_EXIT_BMPS_REQ  */
  WDI_ProcessEnterUapsdReq,        /* WDI_ENTER_UAPSD_REQ  */
  WDI_ProcessExitUapsdReq,         /* WDI_EXIT_UAPSD_REQ  */
  WDI_ProcessSetUapsdAcParamsReq,  /* WDI_SET_UAPSD_PARAM_REQ  */
  WDI_ProcessUpdateUapsdParamsReq, /* WDI_UPDATE_UAPSD_PARAM_REQ  */
  WDI_ProcessConfigureRxpFilterReq, /* WDI_CONFIGURE_RXP_FILTER_REQ  */
  WDI_ProcessSetBeaconFilterReq,   /* WDI_SET_BEACON_FILTER_REQ  */
  WDI_ProcessRemBeaconFilterReq,   /* WDI_REM_BEACON_FILTER_REQ  */
  WDI_ProcessSetRSSIThresholdsReq, /* WDI_SET_RSSI_THRESHOLDS_REQ  */
  WDI_ProcessHostOffloadReq,       /* WDI_HOST_OFFLOAD_REQ  */
  WDI_ProcessWowlAddBcPtrnReq,     /* WDI_WOWL_ADD_BC_PTRN_REQ  */
  WDI_ProcessWowlDelBcPtrnReq,     /* WDI_WOWL_DEL_BC_PTRN_REQ  */
  WDI_ProcessWowlEnterReq,         /* WDI_WOWL_ENTER_REQ  */
  WDI_ProcessWowlExitReq,          /* WDI_WOWL_EXIT_REQ  */
  WDI_ProcessConfigureAppsCpuWakeupStateReq, /* WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_REQ  */
  /*NV Download APIs*/
  WDI_ProcessNvDownloadReq,      /* WDI_NV_DOWNLOAD_REQ*/
  WDI_ProcessFlushAcReq,           /* WDI_FLUSH_AC_REQ  */
  WDI_ProcessBtAmpEventReq,        /* WDI_BTAMP_EVENT_REQ  */
#ifdef WLAN_FEATURE_VOWIFI_11R
  WDI_ProcessAggrAddTSpecReq,      /* WDI_AGGR_ADD_TS_REQ */
#else
  NULL,
#endif /* WLAN_FEATURE_VOWIFI_11R */
  WDI_ProcessAddSTASelfReq,         /* WDI_ADD_STA_SELF_REQ */
  WDI_ProcessDelSTASelfReq,          /* WDI DEL STA SELF REQ */
  WDI_ProcessFTMCommandReq,            /* WDI_FTM_CMD_REQ */

#ifdef FEATURE_OEM_DATA_SUPPORT
  WDI_ProcessStartOemDataReq,     /*WDI_START_OEM_DATA_REQ*/
#else
  NULL,
#endif /*FEATURE_OEM_DATA_SUPPORT*/
  WDI_ProcessHostResumeReq,            /*WDI_HOST_RESUME_REQ*/

  WDI_ProcessKeepAliveReq,       /* WDI_KEEP_ALIVE_REQ */

#ifdef FEATURE_WLAN_SCAN_PNO
  WDI_ProcessSetPreferredNetworkReq,  /* WDI_SET_PREF_NETWORK_REQ */
  WDI_ProcessSetRssiFilterReq,        /* WDI_SET_RSSI_FILTER_REQ */
  WDI_ProcessUpdateScanParamsReq,     /* WDI_UPDATE_SCAN_PARAMS_REQ */
#else
  NULL,
  NULL,
  NULL,
#endif /* FEATURE_WLAN_SCAN_PNO */

  WDI_ProcessSetTxPerTrackingReq,     /* WDI_SET_TX_PER_TRACKING_REQ  */

#ifdef WLAN_FEATURE_PACKET_FILTERING
  /* WDI_8023_MULTICAST_LIST_REQ */
  WDI_Process8023MulticastListReq,
  /* WDI_RECEIVE_FILTER_SET_FILTER_REQ */
  WDI_ProcessReceiveFilterSetFilterReq,
  /* WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ */
  WDI_ProcessFilterMatchCountReq,
  /* WDI_RECEIVE_FILTER_CLEAR_FILTER_REQ */
  WDI_ProcessReceiveFilterClearFilterReq,
#else
  NULL,
  NULL,
  NULL,
  NULL,
#endif // WLAN_FEATURE_PACKET_FILTERING
  WDI_ProcessInitScanReq,               /* WDI_INIT_SCAN_CON_REQ */
  WDI_ProcessHALDumpCmdReq,             /*WDI_HAL_DUMP_CMD_REQ */
  WDI_ProcessShutdownReq,               /* WDI_SHUTDOWN_REQ  */

  WDI_ProcessSetPowerParamsReq,         /*WDI_SET_POWER_PARAMS_REQ*/
#ifdef FEATURE_WLAN_ESE
  WDI_ProcessTSMStatsReq,          /* WDI_TSM_STATS_REQ */
#else
  NULL,
#endif

#ifdef WLAN_FEATURE_GTK_OFFLOAD
  WDI_ProcessGTKOffloadReq,          /* WDI_GTK_OFFLOAD_REQ  */
  WDI_ProcessGTKOffloadGetInfoReq,   /* WDI_GTK_OFFLOAD_GETINFO_REQ  */
#else
  NULL,
  NULL,
#endif // WLAN_FEATURE_GTK_OFFLOAD

  WDI_ProcessSetTmLevelReq,             /*WDI_SET_TM_LEVEL_REQ*/
  WDI_ProcessFeatureCapsExchangeReq,    /* WDI_FEATURE_CAPS_EXCHANGE_REQ */
#ifdef WLAN_FEATURE_11AC
  WDI_ProcessUpdateVHTOpModeReq,        /* WDI_UPDATE_VHT_OP_MODE_REQ */
#else
  NULL,
#endif
#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
  WDI_ProcessGetRoamRssiReq,            /* WDI_GET_ROAM_RSSI_REQ  */
#else
  NULL,
#endif
  WDI_ProcessSetTxPowerReq,             /* WDI_SET_TX_POWER_REQ*/
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
  WDI_ProcessRoamScanOffloadReq,  /* WDI_ROAM_SCAN_OFFLOAD_REQ */
#else
  NULL,
#endif /* WLAN_FEATURE_ROAM_SCAN_OFFLOAD */
#ifdef FEATURE_WLAN_TDLS
  WDI_ProcessTdlsLinkEstablishReq,       /* WDI_TDLS_LINK_ESTABLISH_REQ */
#else
 NULL,
#endif
#ifdef FEATURE_WLAN_LPHB
  WDI_ProcessLPHBConfReq,               /* WDI_LPHB_CFG_REQ */
#else
  NULL,
#endif /* FEATURE_WLAN_LPHB */

#ifdef FEATURE_WLAN_BATCH_SCAN
  WDI_ProcessSetBatchScanReq,               /* WDI_SET_BATCH_SCAN_REQ */
#else
  NULL,
#endif /* FEATURE_WLAN_BATCH_SCAN */

  WDI_ProcessSetMaxTxPowerPerBandReq,   /* WDI_SET_MAX_TX_POWER_PER_BAND_REQ*/

  WDI_ProcessUpdateChannelParamsReq,    /* WDI_UPDATE_CHAN_REQ */

  WDI_ProcessGetBcnMissRateReq,          /* WDI_GET_BCN_MISS_RATE_REQ */

#ifdef WLAN_FEATURE_LINK_LAYER_STATS
  WDI_ProcessLLStatsSetReq,              /* WDI_LL_STATS_SET_REQ */
  WDI_ProcessLLStatsGetReq,              /* WDI_LL_STATS_GET_REQ */
  WDI_ProcessLLStatsClearReq,            /* WDI_LL_STATS_CLEAR_REQ */
#else
  NULL,
  NULL,
  NULL,
#endif
#ifdef WLAN_FEATURE_EXTSCAN
  WDI_ProcessEXTScanStartReq,                /* WDI_EXTSCAN_START_REQ */
  WDI_ProcessEXTScanStopReq,                 /* WDI_EXTSCAN_STOP_REQ */
  WDI_ProcessEXTScanGetCachedResultsReq,     /* WDI_EXTSCAN_GET_CACHED_RESULTS_REQ */
  WDI_ProcessEXTScanGetCapabilitiesReq,      /* WDI_EXTSCAN_GET_CAPABILITIES_REQ */
  WDI_ProcessEXTScanSetBSSIDHotlistReq,      /* WDI_EXTSCAN_SET_BSSID_HOTLIST_REQ */
  WDI_ProcessEXTScanResetBSSIDHotlistReq,    /* WDI_EXTSCAN_RESET_BSSID_HOTLIST_REQ */
  WDI_ProcessEXTScanSetSSIDHotlistReq,       /* WDI_EXTSCAN_SET_SSID_HOTLIST_REQ */
  WDI_ProcessEXTScanResetSSIDHotlistReq,     /* WDI_EXTSCAN_RESET_SSID_HOTLIST_REQ */
#else
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
#endif /* WLAN_FEATURE_EXTSCAN */
  WDI_ProcessSpoofMacAddrReq,       /* WDI_SPOOF_MAC_ADDR_REQ */

  WDI_ProcessGetFwStatsReq,                   /*WDI_GET_FW_STATS_REQ*/

  WDI_ProcessEncryptMsgReq,         /* WDI_ENCRYPT_MSG_REQ*/

  WDI_ProcessFWLoggingInitReq,          /* WDI_FW_LOGGING_INIT_REQ*/
  WDI_ProcessGetFrameLogReq,            /* WDI_GET_FRAME_LOG_REQ*/

  WDI_ProcessNanRequest,            /* WDI_NAN_REQUEST*/

  WDI_ProcessMonStartReq,          /* WDI_MON_START_REQ */
  WDI_ProcessMonStopReq,           /* WDI_MON_STOP_REQ */
  WDI_ProcessFatalEventLogsReq,     /*WDI_FATAL_EVENT_LOGGING_REQ*/
  WDI_ProcessFwrMemDumpReq,           /* WDI_FWR_MEM_DUMP_REQ*/

  WDI_ProcessRssiMonitorStartReq,          /* WDI_START_RSSI_MONITOR_REQ */
  WDI_ProcessRssiMonitorStopReq,           /* WDI_STOP_RSSI_MONITOR_REQ */

  WDI_ProcessWifiConfigReq,                /*WDI_WIFI_CONFIG_SET_REQ*/
  /*-------------------------------------------------------------------------
    Indications
  -------------------------------------------------------------------------*/
  WDI_ProcessHostSuspendInd,            /* WDI_HOST_SUSPEND_IND*/
  WDI_ProcessTrafficStatsInd,           /* WDI_TRAFFIC_STATS_IND*/
  WDI_ProcessDHCPStartInd,              /* WDI_DHCP_START_IND*/
  WDI_ProcessDHCPStopInd,               /* WDI_DHCP_STOP_IND*/
#ifdef WLAN_FEATURE_11W
  WDI_ProcessExcludeUnencryptInd,       /* WDI_EXCLUDE_UNENCRYPTED_IND */
#else
  NULL,
#endif
  WDI_ProcessAddPeriodicTxPtrnInd,      /* WDI_ADD_PERIODIC_TX_PATTERN_IND */
  WDI_ProcessDelPeriodicTxPtrnInd,      /* WDI_DEL_PERIODIC_TX_PATTERN_IND */
#ifdef FEATURE_WLAN_BATCH_SCAN
  WDI_ProcessStopBatchScanInd,          /* WDI_STOP_BATCH_SCAN_IND */
  WDI_ProcessTriggerBatchScanResultInd, /* WDI_TRIGGER_BATCH_SCAN_RESULT_IND */
#else
  NULL,
  NULL,
#endif /* FEATURE_WLAN_BATCH_SCAN */
  WDI_ProcessRateUpdateInd,              /* WDI_RATE_UPDATE_IND */

  WDI_ProcessHT40OBSSScanInd,        /*WDI_START_HT40_OBSS_SCAN_IND */
  WDI_ProcessHT40OBSSStopScanInd,    /*WDI_STOP_HT40_OBSS_SCAN_IND */

  WDI_ProcessChannelSwitchReq_V1,    /* WDI_CH_SWITCH_REQ_V1*/
#ifdef FEATURE_WLAN_TDLS
  WDI_ProcessTdlsChanSwitchReq,       /* WDI_TDLS_CHAN_SWITCH_REQ */
#else
  NULL,
#endif
  WDI_ProcessSetRtsCtsHtvhtInd,       /* WDI_SET_RTS_CTS_HTVHT_IND */
  WDI_ProcessFWLoggingDXEdoneInd,       /* WDI_FW_LOGGING_DXE_DONE_IND */
  WDI_ProcessEnableDisableCAEventInd,   /* WDI_SEND_FREQ_RANGE_CONTROL_IND */

#ifdef WLAN_FEATURE_EXTSCAN
  WDI_ProcessHighPriorityDataInfoInd,        /* WDI_HIGH_PRIORITY_DATA_INFO_IND */
#else
  NULL,
#endif /* WLAN_FEATURE_EXTSCAN */

#ifdef FEATURE_OEM_DATA_SUPPORT
  WDI_ProcessStartOemDataReqIndNew,           /* WDI_START_OEM_DATA_REQ_IND_NEW */
#else
  NULL,
#endif /* FEATURE_OEM_DATA_SUPPORT */
  WDI_ProcessGetCurrentAntennaIndex,          /* WDI_ANTENNA_DIVERSITY_SELECTION_REQ  */
};


/*---------------------------------------------------------------------------
  DAL Request Processing Array  - the functions in this table will only be
  called when the processing of the specific request is allowed by the
  Main FSM
 ---------------------------------------------------------------------------*/
WDI_RspProcFuncType  pfnRspProcTbl[WDI_MAX_RESP] =
{
  /*INIT*/
  WDI_ProcessStartRsp,            /* WDI_START_RESP  */
  WDI_ProcessStopRsp,             /* WDI_STOP_RESP  */
  WDI_ProcessCloseRsp,            /* WDI_CLOSE_RESP  */

  /*SCAN*/
  WDI_ProcessInitScanRsp,         /* WDI_INIT_SCAN_RESP  */
  WDI_ProcessStartScanRsp,        /* WDI_START_SCAN_RESP  */
  WDI_ProcessEndScanRsp,          /* WDI_END_SCAN_RESP  */
  WDI_ProcessFinishScanRsp,       /* WDI_FINISH_SCAN_RESP  */

  /* ASSOCIATION*/
  WDI_ProcessJoinRsp,             /* WDI_JOIN_RESP  */
  WDI_ProcessConfigBSSRsp,        /* WDI_CONFIG_BSS_RESP  */
  WDI_ProcessDelBSSRsp,           /* WDI_DEL_BSS_RESP  */
  WDI_ProcessPostAssocRsp,        /* WDI_POST_ASSOC_RESP  */
  WDI_ProcessDelSTARsp,           /* WDI_DEL_STA_RESP  */

  /* Security */
  WDI_ProcessSetBssKeyRsp,        /* WDI_SET_BSS_KEY_RESP  */
  WDI_ProcessRemoveBssKeyRsp,     /* WDI_RMV_BSS_KEY_RESP  */
  WDI_ProcessSetStaKeyRsp,        /* WDI_SET_STA_KEY_RESP  */
  WDI_ProcessRemoveStaKeyRsp,     /* WDI_RMV_BSS_KEY_RESP  */

  /* QoS and BA APIs */
  WDI_ProcessAddTSpecRsp,          /* WDI_ADD_TS_RESP  */
  WDI_ProcessDelTSpecRsp,          /* WDI_DEL_TS_RESP  */
  WDI_ProcessUpdateEDCAParamsRsp,  /* WDI_UPD_EDCA_PRMS_RESP  */
  WDI_ProcessAddBASessionRsp,      /* WDI_ADD_BA_SESSION_RESP  */
  WDI_ProcessDelBARsp,             /* WDI_DEL_BA_RESP  */

  /* Miscellaneous Control APIs */
  WDI_ProcessChannelSwitchRsp,     /* WDI_CH_SWITCH_RESP  */
  WDI_ProcessConfigStaRsp,         /* WDI_CONFIG_STA_RESP  */
  WDI_ProcessSetLinkStateRsp,      /* WDI_SET_LINK_ST_RESP  */
  WDI_ProcessGetStatsRsp,          /* WDI_GET_STATS_RESP  */
  WDI_ProcessUpdateCfgRsp,         /* WDI_UPDATE_CFG_RESP  */

  /* BA APIs*/
  WDI_ProcessAddBARsp,             /* WDI_ADD_BA_RESP  */
  WDI_ProcessTriggerBARsp,         /* WDI_TRIGGER_BA_RESP  */

  /* IBSS APIs*/
  WDI_ProcessUpdateBeaconParamsRsp, /* WDI_UPD_BCON_PRMS_RSP */
  WDI_ProcessSendBeaconParamsRsp,   /* WDI_SND_BCON_RSP */

  /*Soft AP APIs*/
  WDI_ProcessUpdateProbeRspTemplateRsp,/*WDI_UPD_PROBE_RSP_TEMPLATE_RESP */
  WDI_ProcessSetStaBcastKeyRsp,        /*WDI_SET_STA_BCAST_KEY_RESP */
  WDI_ProcessRemoveStaBcastKeyRsp,     /*WDI_RMV_STA_BCAST_KEY_RESP */
  WDI_ProcessSetMaxTxPowerRsp,         /*WDI_SET_MAX_TX_POWER_RESP */

  /* PowerSave APIs */
  WDI_ProcessEnterImpsRsp,         /* WDI_ENTER_IMPS_RESP  */
  WDI_ProcessExitImpsRsp,          /* WDI_EXIT_IMPS_RESP  */
  WDI_ProcessEnterBmpsRsp,         /* WDI_ENTER_BMPS_RESP  */
  WDI_ProcessExitBmpsRsp,          /* WDI_EXIT_BMPS_RESP  */
  WDI_ProcessEnterUapsdRsp,        /* WDI_ENTER_UAPSD_RESP  */
  WDI_ProcessExitUapsdRsp,         /* WDI_EXIT_UAPSD_RESP  */
  WDI_ProcessSetUapsdAcParamsRsp,  /* WDI_SET_UAPSD_PARAM_RESP  */
  WDI_ProcessUpdateUapsdParamsRsp, /* WDI_UPDATE_UAPSD_PARAM_RESP  */
  WDI_ProcessConfigureRxpFilterRsp,/* WDI_CONFIGURE_RXP_FILTER_RESP  */
  WDI_ProcessSetBeaconFilterRsp,   /* WDI_SET_BEACON_FILTER_RESP  */
  WDI_ProcessRemBeaconFilterRsp,   /* WDI_REM_BEACON_FILTER_RESP  */
  WDI_ProcessSetRSSIThresoldsRsp,  /* WDI_SET_RSSI_THRESHOLDS_RESP  */
  WDI_ProcessHostOffloadRsp,       /* WDI_HOST_OFFLOAD_RESP  */
  WDI_ProcessWowlAddBcPtrnRsp,     /* WDI_WOWL_ADD_BC_PTRN_RESP  */
  WDI_ProcessWowlDelBcPtrnRsp,     /* WDI_WOWL_DEL_BC_PTRN_RESP  */
  WDI_ProcessWowlEnterRsp,         /* WDI_WOWL_ENTER_RESP  */
  WDI_ProcessWowlExitRsp,          /* WDI_WOWL_EXIT_RESP  */
  WDI_ProcessConfigureAppsCpuWakeupStateRsp, /* WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_RESP  */


  WDI_ProcessNvDownloadRsp, /* WDI_NV_DOWNLOAD_RESP*/

  WDI_ProcessFlushAcRsp,           /* WDI_FLUSH_AC_RESP  */
  WDI_ProcessBtAmpEventRsp,        /* WDI_BTAMP_EVENT_RESP  */
#ifdef WLAN_FEATURE_VOWIFI_11R
  WDI_ProcessAggrAddTSpecRsp,       /* WDI_AGGR_ADD_TS_RESP  */
#else
  NULL,
#endif /* WLAN_FEATURE_VOWIFI_11R */
  WDI_ProcessAddSTASelfRsp,          /* WDI_ADD_STA_SELF_RESP */
  WDI_ProcessDelSTASelfRsp,          /* WDI_DEL_STA_SELF_RESP */
#ifdef FEATURE_OEM_DATA_SUPPORT
  WDI_ProcessStartOemDataRsp,     /*WDI_START_OEM_DATA_RESP*/
#else
  NULL,
#endif /*FEATURE_OEM_DATA_SUPPORT*/
  WDI_ProcessHostResumeRsp,        /*WDI_HOST_RESUME_RESP*/

  WDI_ProcessP2PGONOARsp,           /*WDI_P2P_GO_NOTICE_OF_ABSENCE_RESP */

  WDI_ProcessFTMCommandRsp,         /* WDI_FTM_CMD_RESP */

  WDI_ProcessKeepAliveRsp,       /* WDI_KEEP_ALIVE_RESP  */

#ifdef FEATURE_WLAN_SCAN_PNO
  WDI_ProcessSetPreferredNetworkRsp,     /* WDI_SET_PREF_NETWORK_RESP */
  WDI_ProcessSetRssiFilterRsp,           /* WDI_SET_RSSI_FILTER_RESP */
  WDI_ProcessUpdateScanParamsRsp,        /* WDI_UPDATE_SCAN_PARAMS_RESP */
#else
  NULL,
  NULL,
  NULL,
#endif // FEATURE_WLAN_SCAN_PNO

  WDI_ProcessSetTxPerTrackingRsp,      /* WDI_SET_TX_PER_TRACKING_RESP  */
  /*---------------------------------------------------------------------
    Indications
  ---------------------------------------------------------------------*/
#ifdef WLAN_FEATURE_PACKET_FILTERING
  /* WDI_8023_MULTICAST_LIST_RESP */
  WDI_Process8023MulticastListRsp,
  /* WDI_RECEIVE_FILTER_SET_FILTER_RESP */
  WDI_ProcessReceiveFilterSetFilterRsp,
  /* WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_RESP */
  WDI_ProcessFilterMatchCountRsp,
  /* WDI_RECEIVE_FILTER_CLEAR_FILTER_RESP */
  WDI_ProcessReceiveFilterClearFilterRsp,
#else
  NULL,
  NULL,
  NULL,
  NULL,
#endif // WLAN_FEATURE_PACKET_FILTERING

  WDI_ProcessHALDumpCmdRsp,       /* WDI_HAL_DUMP_CMD_RESP */
  WDI_ProcessShutdownRsp,         /* WDI_SHUTDOWN_RESP */
  
  WDI_ProcessSetPowerParamsRsp,         /*WDI_SET_POWER_PARAMS_RESP*/
#ifdef FEATURE_WLAN_ESE
  WDI_ProcessTsmStatsRsp,          /* WDI_TSM_STATS_RESP  */
#else
  NULL,
#endif
  
#ifdef WLAN_FEATURE_GTK_OFFLOAD
  WDI_ProcessGtkOffloadRsp,             /* WDI_GTK_OFFLOAD_RESP  */
  WDI_ProcessGTKOffloadGetInfoRsp,      /* WDI_GTK_OFFLOAD_GETINFO_RESP  */
#else
  NULL,
  NULL,
#endif // WLAN_FEATURE_GTK_OFFLOAD
  WDI_ProcessSetTmLevelRsp,             /* WDI_SET_TM_LEVEL_RESP */
  WDI_ProcessFeatureCapsExchangeRsp,    /* WDI_FEATURE_CAPS_EXCHANGE_RESP */
#ifdef WLAN_FEATURE_11AC
  WDI_ProcessUpdateVHTOpModeRsp,        /* WDI_UPDATE_VHT_OP_MODE_RESP */
#else
   NULL,
#endif
#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
  WDI_ProcessGetRoamRssiRsp,            /* WDI_GET_ROAM_RSSI_RESP  */
#else
  NULL,
#endif
  WDI_ProcessSetTxPowerRsp,             /* WDI_SET_TX_POWER_RESP */
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
    WDI_ProcessRoamScanOffloadRsp, /* WDI_ROAM_SCAN_OFFLOAD_RESP */
#else
    NULL,
#endif
#ifdef FEATURE_WLAN_TDLS
  WDI_ProcessLinkEstablishReqRsp,       /*WDI_TDLS_LINK_ESTABLISH_REQ_RESP*/
#else
  NULL,
#endif
#ifdef FEATURE_WLAN_LPHB
    WDI_ProcessLphbCfgRsp,             /* WDI_LPHB_CFG_RESP */
#else
    NULL,
#endif /* FEATURE_WLAN_LPHB */

#ifdef FEATURE_WLAN_BATCH_SCAN
    WDI_ProcessSetBatchScanRsp,        /* WDI_SET_BATCH_SCAN_RESP */
#else
    NULL,
#endif /*FEATURE_WLAN_BATCH_SCAN*/
  WDI_ProcessSetMaxTxPowerPerBandRsp,  /* WDI_SET_MAX_TX_POWER_PER_BAND_RSP */

  WDI_ProcessUpdateChanRsp,         /* WDI_UPDATE_CHAN_RESP */

  WDI_ProcessChannelSwitchRsp_V1,     /* WDI_CH_SWITCH_RESP_V1  */

  WDI_ProcessGetBcnMissRateRsp,        /*WDI_GET_BCN_MISS_RATE_RSP*/


#ifdef WLAN_FEATURE_LINK_LAYER_STATS
    WDI_ProcessLLStatsSetRsp,           /* WDI_LL_STATS_SET_RSP */
    WDI_ProcessLLStatsGetRsp,           /* WDI_LL_STATS_GET_RSP */
    WDI_ProcessLLStatsClearRsp,           /* WDI_LL_STATS_CLEAR_RSP */
#else
    NULL,
    NULL,
    NULL,
#endif
#ifdef WLAN_FEATURE_EXTSCAN
    WDI_ProcessEXTScanStartRsp,                /* WDI_EXTSCAN_START_RSP */
    WDI_ProcessEXTScanStopRsp,                 /* WDI_EXTSCAN_STOP_RSP */
    WDI_ProcessEXTScanGetCachedResultsRsp,     /* WDI_EXTSCAN_GET_CACHED_RESULTS_RSP */
    WDI_ProcessEXTScanGetCapabilitiesRsp,      /* WDI_EXTSCAN_GET_CAPABILITIES_RSP */
    WDI_ProcessEXTScanSetHotlistBSSIDRsp,      /* WDI_EXTSCAN_SET_HOTLIST_BSSID_RSP */
    WDI_ProcessEXTScanResetHotlistBSSIDRsp,    /* WDI_EXTSCAN_RESET_HOTLIST_BSSID_RSP */
    WDI_ProcessEXTScanSetHotlistSSIDRsp,      /* WDI_EXTSCAN_SET_HOTLIST_SSID_RSP */
    WDI_ProcessEXTScanResetHotlistSSIDRsp,    /* WDI_EXTSCAN_RESET_HOTLIST_SSID_RSP */
#else
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
#endif /* WLAN_FEATURE_EXTSCAN */
    WDI_ProcessSpoofMacAddrRsp,                /* WDI_SPOOF_MAC_ADDR_RSP */

    WDI_ProcessGetFwStatsRsp,                     /*WDI_GET_FW_STATS_RSP*/

    WDI_ProcessEncryptMsgRsp,                  /* WDI_ENCRYPT_MSG_RSP*/
    WDI_ProcessFWFrameLoggingInitRsp,          /* WDI_FW_LOGGING_INIT_RSP*/
    WDI_ProcessGetFrameLogRsp,                 /* WDI_GET_FRAME_LOG_RSP*/

    WDI_ProcessNanResponse,                    /* WDI_NAN_RESPONSE */

    WDI_ProcessMonStartRsp,                    /* WDI_MON_START_RSP*/
    WDI_ProcessMonStopRsp,                    /* WDI_MON_STOP_RSP*/
    WDI_ProcessFatalEventLogsRsp,              /*WDI_FATAL_EVENT_LOGGING_RSP*/
    WDI_ProcessFwrMemDumpRsp,                 /* WDI_FWR_MEM_DUMP_RSP */
    WDI_ProcessRssiMonitorStartRsp,            /* WDI_START_RSSI_MONITOR_RSP*/
    WDI_ProcessRssiMonitorStopRsp,             /* WDI_STOP_RSSI_MONITOR_RSP*/

    WDI_ProcessWificonfigSetRsp,                   /* /WDI_WIFI_CONFIG_SET_RSP*/
  /*---------------------------------------------------------------------
    Indications
  ---------------------------------------------------------------------*/
  WDI_ProcessLowRSSIInd,            /* Just threshold crossing not really low WDI_HAL_RSSI_NOTIFICATION_IND  */
  WDI_ProcessMissedBeaconInd,       /* WDI_HAL_MISSED_BEACON_IND  */
  WDI_ProcessUnkAddrFrameInd,       /* WDI_HAL_UNKNOWN_ADDR2_FRAME_RX_IND  */
  WDI_ProcessMicFailureInd,         /* WDI_HAL_MIC_FAILURE_IND  */
  WDI_ProcessFatalErrorInd,         /* WDI_HAL_FATAL_ERROR_IND  */
  WDI_ProcessDelSTAInd,             /* WDI_HAL_DEL_STA_IND  */

  WDI_ProcessCoexInd,               /* WDI_HAL_COEX_IND  */

  WDI_ProcessTxCompleteInd,         /* WDI_HAL_TX_COMPLETE_IND  */

  WDI_ProcessP2pNoaAttrInd,         /*WDI_HOST_NOA_ATTR_IND*/

#ifdef FEATURE_WLAN_SCAN_PNO
  WDI_ProcessPrefNetworkFoundInd,   /* WDI_HAL_PREF_NETWORK_FOUND_IND */
#else
  NULL,
#endif // FEATURE_WLAN_SCAN_PNO

#ifdef WLAN_WAKEUP_EVENTS
  WDI_ProcessWakeReasonInd,          /* WDI_WAKE_REASON_IND */
#else // WLAN_WAKEUP_EVENTS
  NULL,
#endif // WLAN_WAKEUP_EVENTS

  WDI_ProcessTxPerHitInd,               /* WDI_HAL_TX_PER_HIT_IND  */

  WDI_ProcessP2pNoaStartInd,             /* WDI_NOA_START_IND */
#ifdef FEATURE_WLAN_TDLS
  WDI_ProcessTdlsInd,                   /* WDI_HAL_TDLS_IND */
#else
  NULL,
#endif

#ifdef FEATURE_WLAN_LPHB
  WDI_ProcessLphbInd,                   /* WDI_HAL_LPHB_IND */
#else
  NULL,
#endif /* FEATURE_WLAN_LPHB */

  WDI_ProcessIbssPeerInactivityInd,     /* WDI_HAL_IBSS_PEER_INACTIVITY_IND */

  WDI_ProcessPeriodicTxPtrnFwInd,   /* WDI_HAL_PERIODIC_TX_PTRN_FW_IND */

#ifdef FEATURE_WLAN_BATCH_SCAN
  WDI_ProcessBatchScanResultInd,     /* WDI_BATCHSCAN_RESULT_IND */
#else
  NULL,
#endif

#ifdef FEATURE_WLAN_CH_AVOID
    WDI_ProcessChAvoidInd,               /* WDI_LBP_UPDATE_IND_TO_HOST */
#else
   NULL,
#endif /* FEATURE_WLAN_CH_AVOID */

    WDI_printRegInfo,                        /* WDI_PRINT_REG_INFO_IND */
#ifdef WLAN_FEATURE_LINK_LAYER_STATS
  WDI_ProcessLinkLayerStatsResultsInd,     /* WDI_HAL_LL_STATS_RESULTS_IND */
#else
  NULL,
#endif
#ifdef WLAN_FEATURE_EXTSCAN
  WDI_ProcessEXTScanProgressInd,            /* WDI_HAL_EXTSCAN_PROGRESS_IND */
  WDI_ProcessEXTScanScanAvailableInd,       /* WDI_HAL_EXTSCAN_SCAN_AVAILABLE_IND */
  WDI_ProcessEXTScanResultInd,              /* WDI_HAL_EXTSCAN_RESULT_IND */
  WDI_ProcessEXTScanBssidHotListResultInd,  /* WDI_HAL_EXTSCAN_BSSID_HOTLIST_RESULT_IND */
  WDI_ProcessEXTScanSsidHotListResultInd,  /* WDI_HAL_EXTSCAN_SSID_HOTLIST_RESULT_IND */
#else
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
#endif /* WLAN_FEATURE_EXTSCAN */
#ifdef FEATURE_WLAN_TDLS
  WDI_ProcessChanSwitchReqRsp,              /*WDI_TDLS_CHAN_SWITCH_REQ_RESP*/
#else
  NULL,
#endif
  WDI_delBaInd,                             /* WDI_HAL_DEL_BA_IND*/
  WDI_ProcessNanEvent,                      /* WDI_HAL_NAN_EVENT */
  WDI_Process_LostLinkParamInd,             /* WDI_HAL_LOST_LINK_PARAMS_IND*/
  WDI_Process_RssiBreachedInd,             /* WDI_HAL_RSSI_BREACHED_IND */
#ifdef FEATURE_OEM_DATA_SUPPORT
  WDI_ProcessStartOemDataRspIndNew,         /* WDI_HAL_START_OEM_DATA_RSP_IND_NEW */
#else
  NULL,
#endif
  WDI_ProcessGetCurrentAntennaIndexRsp,     /* WDI_ANTENNA_DIVERSITY_SELECTION_RSP */
};


/*---------------------------------------------------------------------------
  WLAN DAL Global Control Block
 ---------------------------------------------------------------------------*/
WDI_ControlBlockType  gWDICb;
static wpt_uint8      gWDIInitialized = eWLAN_PAL_FALSE;

const wpt_uint8 szTransportChName[] = "WLAN_CTRL";

/*Helper routine for retrieving the PAL Context from WDI*/
WPT_INLINE
void* WDI_GET_PAL_CTX( void )
{
  return gWDICb.pPALContext;
}/*WDI_GET_PAL_CTX*/

/*============================================================================
  Helper inline converters
 ============================================================================*/
/*Convert WDI driver type into HAL driver type*/
WPT_STATIC WPT_INLINE WDI_Status
WDI_HAL_2_WDI_STATUS
(
  eHalStatus halStatus
);

/*Convert WDI request type into HAL request type*/
WPT_STATIC WPT_INLINE tHalHostMsgType
WDI_2_HAL_REQ_TYPE
(
  WDI_RequestEnumType    wdiReqType
);

/*Convert WDI response type into HAL response type*/
WPT_STATIC WPT_INLINE WDI_ResponseEnumType
HAL_2_WDI_RSP_TYPE
(
  tHalHostMsgType halMsg
);

/*Convert WDI driver type into HAL driver type*/
WPT_STATIC WPT_INLINE tDriverType
WDI_2_HAL_DRV_TYPE
(
  WDI_DriverType wdiDriverType
);

/*Convert WDI stop reason into HAL stop reason*/
WPT_STATIC WPT_INLINE tHalStopType
WDI_2_HAL_STOP_REASON
(
  WDI_StopType wdiStopType
);

/*Convert WDI scan mode type into HAL scan mode type*/
WPT_STATIC WPT_INLINE eHalSysMode
WDI_2_HAL_SCAN_MODE
(
  WDI_ScanMode wdiScanMode
);

/*Convert WDI sec ch offset into HAL sec ch offset type*/
WPT_STATIC WPT_INLINE ePhyChanBondState
WDI_2_HAL_SEC_CH_OFFSET
(
  WDI_HTSecondaryChannelOffset wdiSecChOffset
);

/*Convert WDI BSS type into HAL BSS type*/
WPT_STATIC WPT_INLINE tSirBssType
WDI_2_HAL_BSS_TYPE
(
  WDI_BssType wdiBSSType
);

/*Convert WDI NW type into HAL NW type*/
WPT_STATIC WPT_INLINE tSirNwType
WDI_2_HAL_NW_TYPE
(
  WDI_NwType wdiNWType
);

/*Convert WDI chanel bonding type into HAL cb type*/
WPT_STATIC WPT_INLINE ePhyChanBondState
WDI_2_HAL_CB_STATE
(
  WDI_PhyChanBondState wdiCbState
);

/*Convert WDI chanel bonding type into HAL cb type*/
WPT_STATIC WPT_INLINE tSirMacHTOperatingMode
WDI_2_HAL_HT_OPER_MODE
(
  WDI_HTOperatingMode wdiHTOperMode
);

/*Convert WDI mimo PS type into HAL mimo PS type*/
WPT_STATIC WPT_INLINE tSirMacHTMIMOPowerSaveState
WDI_2_HAL_MIMO_PS
(
  WDI_HTMIMOPowerSaveState wdiHTOperMode
);

/*Convert WDI ENC type into HAL ENC type*/
WPT_STATIC WPT_INLINE tAniEdType
WDI_2_HAL_ENC_TYPE
(
  WDI_EncryptType wdiEncType
);

/*Convert WDI WEP type into HAL WEP type*/
WPT_STATIC WPT_INLINE tAniWepType
WDI_2_HAL_WEP_TYPE
(
  WDI_WepType  wdiWEPType
);

/*Convert WDI Link State into HAL Link State*/
WPT_STATIC WPT_INLINE tSirLinkState
WDI_2_HAL_LINK_STATE
(
  WDI_LinkStateType  wdiLinkState
);

/*Translate a STA Context from WDI into HAL*/
WPT_STATIC WPT_INLINE
void
WDI_CopyWDIStaCtxToHALStaCtx
(
  tConfigStaParams*          phalConfigSta,
  WDI_ConfigStaReqInfoType*  pwdiConfigSta
);

/*Translate a Rate set info from WDI into HAL*/
WPT_STATIC WPT_INLINE void
WDI_CopyWDIRateSetToHALRateSet
(
  tSirMacRateSet* pHalRateSet,
  WDI_RateSet*    pwdiRateSet
);

/*Translate an EDCA Parameter Record from WDI into HAL*/
WPT_STATIC WPT_INLINE void
WDI_CopyWDIEDCAParamsToHALEDCAParams
(
  tSirMacEdcaParamRecord* phalEdcaParam,
  WDI_EdcaParamRecord*    pWDIEdcaParam
);

/*Copy a management frame header from WDI fmt into HAL fmt*/
WPT_STATIC WPT_INLINE void
WDI_CopyWDIMgmFrameHdrToHALMgmFrameHdr
(
  tSirMacMgmtHdr* pmacMgmtHdr,
  WDI_MacMgmtHdr* pwdiMacMgmtHdr
);

/*Copy config bss parameters from WDI fmt into HAL fmt*/
WPT_STATIC WPT_INLINE void
WDI_CopyWDIConfigBSSToHALConfigBSS
(
  tConfigBssParams*         phalConfigBSS,
  WDI_ConfigBSSReqInfoType* pwdiConfigBSS
);

/*Extract the request CB function and user data from a request structure
  pointed to by user data */
WPT_STATIC WPT_INLINE void
WDI_ExtractRequestCBFromEvent
(
  WDI_EventInfoType* pEvent,
  WDI_ReqStatusCb*   ppfnReqCB,
  void**             ppUserData
);

wpt_uint8
WDI_FindEmptySession
(
  WDI_ControlBlockType*   pWDICtx,
  WDI_BSSSessionType**    ppSession
);

void
WDI_AddBcastSTAtoSTATable
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_AddStaParams *     staParams,
  wpt_uint16             usBcastStaIdx
);

WDI_Status WDI_SendNvBlobReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
);

void
WDI_SetPowerStateCb
(
   wpt_status status,
   unsigned int dxePhyAddr,
   void      *pContext
);

/**
 @brief WDI_getReqMsgString prints the WDI request message in string.

 @param wdiReqMsgId: WDI Message request Id

 @see
 @return Result of the function call
*/
static char *WDI_getReqMsgString(wpt_uint16 wdiReqMsgId)
{
  switch (wdiReqMsgId)
  {
    CASE_RETURN_STRING( WDI_START_REQ );
    CASE_RETURN_STRING( WDI_STOP_REQ );
    CASE_RETURN_STRING( WDI_CLOSE_REQ );
    CASE_RETURN_STRING( WDI_INIT_SCAN_REQ );
    CASE_RETURN_STRING( WDI_START_SCAN_REQ );
    CASE_RETURN_STRING( WDI_END_SCAN_REQ );
    CASE_RETURN_STRING( WDI_FINISH_SCAN_REQ );
    CASE_RETURN_STRING( WDI_JOIN_REQ );
    CASE_RETURN_STRING( WDI_CONFIG_BSS_REQ );
    CASE_RETURN_STRING( WDI_DEL_BSS_REQ );
    CASE_RETURN_STRING( WDI_POST_ASSOC_REQ );
    CASE_RETURN_STRING( WDI_DEL_STA_REQ );
    CASE_RETURN_STRING( WDI_SET_BSS_KEY_REQ );
    CASE_RETURN_STRING( WDI_RMV_BSS_KEY_REQ );
    CASE_RETURN_STRING( WDI_SET_STA_KEY_REQ );
    CASE_RETURN_STRING( WDI_RMV_STA_KEY_REQ );
    CASE_RETURN_STRING( WDI_ADD_TS_REQ );
    CASE_RETURN_STRING( WDI_DEL_TS_REQ );
    CASE_RETURN_STRING( WDI_UPD_EDCA_PRMS_REQ );
    CASE_RETURN_STRING( WDI_ADD_BA_SESSION_REQ );
    CASE_RETURN_STRING( WDI_DEL_BA_REQ );
    CASE_RETURN_STRING( WDI_CH_SWITCH_REQ );
    CASE_RETURN_STRING( WDI_CH_SWITCH_REQ_V1);
    CASE_RETURN_STRING( WDI_CONFIG_STA_REQ );
    CASE_RETURN_STRING( WDI_SET_LINK_ST_REQ );
    CASE_RETURN_STRING( WDI_GET_STATS_REQ );
    CASE_RETURN_STRING( WDI_UPDATE_CFG_REQ );
    CASE_RETURN_STRING( WDI_ADD_BA_REQ );
    CASE_RETURN_STRING( WDI_TRIGGER_BA_REQ );
    CASE_RETURN_STRING( WDI_UPD_BCON_PRMS_REQ );
    CASE_RETURN_STRING( WDI_SND_BCON_REQ );
    CASE_RETURN_STRING( WDI_UPD_PROBE_RSP_TEMPLATE_REQ );
    CASE_RETURN_STRING( WDI_SET_STA_BCAST_KEY_REQ );
    CASE_RETURN_STRING( WDI_RMV_STA_BCAST_KEY_REQ );
    CASE_RETURN_STRING( WDI_SET_MAX_TX_POWER_REQ );
    CASE_RETURN_STRING( WDI_SET_MAX_TX_POWER_PER_BAND_REQ );
    CASE_RETURN_STRING( WDI_P2P_GO_NOTICE_OF_ABSENCE_REQ );
#ifdef FEATURE_WLAN_TDLS
    CASE_RETURN_STRING( WDI_TDLS_LINK_ESTABLISH_REQ );
    CASE_RETURN_STRING( WDI_TDLS_CHAN_SWITCH_REQ );
#endif
    CASE_RETURN_STRING( WDI_ENTER_IMPS_REQ );
    CASE_RETURN_STRING( WDI_EXIT_IMPS_REQ );
    CASE_RETURN_STRING( WDI_ENTER_BMPS_REQ );
    CASE_RETURN_STRING( WDI_EXIT_BMPS_REQ );
    CASE_RETURN_STRING( WDI_ENTER_UAPSD_REQ );
    CASE_RETURN_STRING( WDI_EXIT_UAPSD_REQ );
    CASE_RETURN_STRING( WDI_SET_UAPSD_PARAM_REQ );
    CASE_RETURN_STRING( WDI_UPDATE_UAPSD_PARAM_REQ );
    CASE_RETURN_STRING( WDI_CONFIGURE_RXP_FILTER_REQ );
    CASE_RETURN_STRING( WDI_SET_BEACON_FILTER_REQ);
    CASE_RETURN_STRING( WDI_REM_BEACON_FILTER_REQ );
    CASE_RETURN_STRING( WDI_SET_RSSI_THRESHOLDS_REQ );
    CASE_RETURN_STRING( WDI_HOST_OFFLOAD_REQ );
    CASE_RETURN_STRING( WDI_WOWL_ADD_BC_PTRN_REQ );
    CASE_RETURN_STRING( WDI_WOWL_DEL_BC_PTRN_REQ );
    CASE_RETURN_STRING( WDI_WOWL_ENTER_REQ );
    CASE_RETURN_STRING( WDI_WOWL_EXIT_REQ );
    CASE_RETURN_STRING( WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_REQ );
    CASE_RETURN_STRING( WDI_NV_DOWNLOAD_REQ );
    CASE_RETURN_STRING( WDI_FLUSH_AC_REQ );
    CASE_RETURN_STRING( WDI_BTAMP_EVENT_REQ );
    CASE_RETURN_STRING( WDI_AGGR_ADD_TS_REQ );
    CASE_RETURN_STRING( WDI_ADD_STA_SELF_REQ );
    CASE_RETURN_STRING( WDI_DEL_STA_SELF_REQ );
    CASE_RETURN_STRING( WDI_FTM_CMD_REQ );
    CASE_RETURN_STRING( WDI_START_OEM_DATA_REQ );
    CASE_RETURN_STRING( WDI_HOST_RESUME_REQ );
    CASE_RETURN_STRING( WDI_KEEP_ALIVE_REQ);
  #ifdef FEATURE_WLAN_SCAN_PNO
    CASE_RETURN_STRING( WDI_SET_PREF_NETWORK_REQ );
    CASE_RETURN_STRING( WDI_SET_RSSI_FILTER_REQ );
    CASE_RETURN_STRING( WDI_UPDATE_SCAN_PARAMS_REQ );
  #endif
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
    CASE_RETURN_STRING( WDI_ROAM_SCAN_OFFLOAD_REQ );
#endif
    CASE_RETURN_STRING( WDI_SET_TX_PER_TRACKING_REQ );
    CASE_RETURN_STRING( WDI_8023_MULTICAST_LIST_REQ );
    CASE_RETURN_STRING( WDI_RECEIVE_FILTER_SET_FILTER_REQ );
    CASE_RETURN_STRING( WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ );
    CASE_RETURN_STRING( WDI_RECEIVE_FILTER_CLEAR_FILTER_REQ );
    CASE_RETURN_STRING( WDI_INIT_SCAN_CON_REQ );
    CASE_RETURN_STRING( WDI_HAL_DUMP_CMD_REQ );
    CASE_RETURN_STRING( WDI_SHUTDOWN_REQ );
    CASE_RETURN_STRING( WDI_SET_POWER_PARAMS_REQ );
    CASE_RETURN_STRING( WDI_GET_BCN_MISS_RATE_REQ );
    CASE_RETURN_STRING( WDI_TRAFFIC_STATS_IND );
    CASE_RETURN_STRING( WDI_GET_ROAM_RSSI_REQ );
#ifdef WLAN_FEATURE_11W
    CASE_RETURN_STRING( WDI_EXCLUDE_UNENCRYPTED_IND );
#endif
#ifdef FEATURE_WLAN_BATCH_SCAN
    CASE_RETURN_STRING( WDI_SET_BATCH_SCAN_REQ);
    CASE_RETURN_STRING( WDI_STOP_BATCH_SCAN_IND );
    CASE_RETURN_STRING( WDI_TRIGGER_BATCH_SCAN_RESULT_IND);
#endif
    CASE_RETURN_STRING(WDI_START_HT40_OBSS_SCAN_IND);
    CASE_RETURN_STRING(WDI_STOP_HT40_OBSS_SCAN_IND);
    CASE_RETURN_STRING(WDI_UPDATE_CHAN_REQ);
#ifdef WLAN_FEATURE_LINK_LAYER_STATS
    CASE_RETURN_STRING( WDI_LL_STATS_SET_REQ);
    CASE_RETURN_STRING( WDI_LL_STATS_GET_REQ);
    CASE_RETURN_STRING( WDI_LL_STATS_CLEAR_REQ);
#endif
#ifdef WLAN_FEATURE_EXTSCAN
    CASE_RETURN_STRING( WDI_EXTSCAN_START_REQ);
    CASE_RETURN_STRING( WDI_EXTSCAN_STOP_REQ);
    CASE_RETURN_STRING( WDI_EXTSCAN_GET_CACHED_RESULTS_REQ);
    CASE_RETURN_STRING( WDI_EXTSCAN_GET_CAPABILITIES_REQ);
    CASE_RETURN_STRING( WDI_EXTSCAN_SET_BSSID_HOTLIST_REQ);
    CASE_RETURN_STRING( WDI_EXTSCAN_RESET_BSSID_HOTLIST_REQ);
    CASE_RETURN_STRING( WDI_EXTSCAN_SET_SSID_HOTLIST_REQ);
    CASE_RETURN_STRING( WDI_EXTSCAN_RESET_SSID_HOTLIST_REQ);
    CASE_RETURN_STRING( WDI_HIGH_PRIORITY_DATA_INFO_IND);
#endif /* WLAN_FEATURE_EXTSCAN */
    CASE_RETURN_STRING( WDI_SPOOF_MAC_ADDR_REQ);
    CASE_RETURN_STRING( WDI_GET_FW_STATS_REQ);
    CASE_RETURN_STRING( WDI_ENCRYPT_MSG_REQ);
    CASE_RETURN_STRING( WDI_FW_LOGGING_INIT_REQ);
    CASE_RETURN_STRING( WDI_GET_FRAME_LOG_REQ);
    CASE_RETURN_STRING( WDI_NAN_REQUEST );
    CASE_RETURN_STRING( WDI_SET_RTS_CTS_HTVHT_IND );
    CASE_RETURN_STRING( WDI_MON_START_REQ );
    CASE_RETURN_STRING( WDI_MON_STOP_REQ );
    CASE_RETURN_STRING( WDI_FATAL_EVENT_LOGGING_REQ );
    CASE_RETURN_STRING( WDI_SEND_FREQ_RANGE_CONTROL_IND );
    CASE_RETURN_STRING( WDI_FWR_MEM_DUMP_REQ);
    CASE_RETURN_STRING( WDI_START_RSSI_MONITOR_REQ );
    CASE_RETURN_STRING( WDI_STOP_RSSI_MONITOR_REQ );
    CASE_RETURN_STRING( WDI_START_OEM_DATA_REQ_IND_NEW );
    CASE_RETURN_STRING( WDI_ANTENNA_DIVERSITY_SELECTION_REQ );
    default:
        return "Unknown WDI MessageId";
  }
}



/**
 @brief WDI_getRespMsgString prints the WDI resonse message in string.

 @param wdiRespMsgId: WDI Message response Id

 @see
 @return Result of the function call
*/
static char *WDI_getRespMsgString(wpt_uint16 wdiRespMsgId)
{
  switch (wdiRespMsgId)
  {
    CASE_RETURN_STRING( WDI_START_RESP );
    CASE_RETURN_STRING( WDI_STOP_RESP );
    CASE_RETURN_STRING( WDI_CLOSE_RESP );
    CASE_RETURN_STRING( WDI_INIT_SCAN_RESP );
    CASE_RETURN_STRING( WDI_START_SCAN_RESP );
    CASE_RETURN_STRING( WDI_END_SCAN_RESP );
    CASE_RETURN_STRING( WDI_FINISH_SCAN_RESP );
    CASE_RETURN_STRING( WDI_JOIN_RESP );
    CASE_RETURN_STRING( WDI_CONFIG_BSS_RESP );
    CASE_RETURN_STRING( WDI_DEL_BSS_RESP );
    CASE_RETURN_STRING( WDI_POST_ASSOC_RESP );
    CASE_RETURN_STRING( WDI_DEL_STA_RESP );
    CASE_RETURN_STRING( WDI_SET_BSS_KEY_RESP );
    CASE_RETURN_STRING( WDI_RMV_BSS_KEY_RESP );
    CASE_RETURN_STRING( WDI_SET_STA_KEY_RESP );
    CASE_RETURN_STRING( WDI_RMV_STA_KEY_RESP );
    CASE_RETURN_STRING( WDI_ADD_TS_RESP );
    CASE_RETURN_STRING( WDI_DEL_TS_RESP );
    CASE_RETURN_STRING( WDI_UPD_EDCA_PRMS_RESP );
    CASE_RETURN_STRING( WDI_ADD_BA_SESSION_RESP );
    CASE_RETURN_STRING( WDI_DEL_BA_RESP );
    CASE_RETURN_STRING( WDI_CH_SWITCH_RESP );
    CASE_RETURN_STRING( WDI_CONFIG_STA_RESP );
    CASE_RETURN_STRING( WDI_SET_LINK_ST_RESP );
    CASE_RETURN_STRING( WDI_GET_STATS_RESP );
    CASE_RETURN_STRING( WDI_UPDATE_CFG_RESP );
    CASE_RETURN_STRING( WDI_ADD_BA_RESP );
    CASE_RETURN_STRING( WDI_TRIGGER_BA_RESP );
    CASE_RETURN_STRING( WDI_UPD_BCON_PRMS_RESP );
    CASE_RETURN_STRING( WDI_SND_BCON_RESP );
    CASE_RETURN_STRING( WDI_UPD_PROBE_RSP_TEMPLATE_RESP );
    CASE_RETURN_STRING( WDI_SET_STA_BCAST_KEY_RESP );
    CASE_RETURN_STRING( WDI_RMV_STA_BCAST_KEY_RESP );
    CASE_RETURN_STRING( WDI_SET_MAX_TX_POWER_RESP );
    CASE_RETURN_STRING( WDI_P2P_GO_NOTICE_OF_ABSENCE_RESP );
#ifdef FEATURE_WLAN_TDLS
    CASE_RETURN_STRING( WDI_TDLS_LINK_ESTABLISH_REQ_RESP );
    CASE_RETURN_STRING( WDI_TDLS_CHAN_SWITCH_REQ_RESP);
    CASE_RETURN_STRING( WDI_HAL_TDLS_IND );
#endif
    CASE_RETURN_STRING( WDI_ENTER_IMPS_RESP );
    CASE_RETURN_STRING( WDI_EXIT_IMPS_RESP );
    CASE_RETURN_STRING( WDI_ENTER_BMPS_RESP );
    CASE_RETURN_STRING( WDI_EXIT_BMPS_RESP );
    CASE_RETURN_STRING( WDI_ENTER_UAPSD_RESP );
    CASE_RETURN_STRING( WDI_EXIT_UAPSD_RESP );
    CASE_RETURN_STRING( WDI_SET_UAPSD_PARAM_RESP );
    CASE_RETURN_STRING( WDI_UPDATE_UAPSD_PARAM_RESP );
    CASE_RETURN_STRING( WDI_CONFIGURE_RXP_FILTER_RESP );
    CASE_RETURN_STRING( WDI_SET_BEACON_FILTER_RESP);
    CASE_RETURN_STRING( WDI_REM_BEACON_FILTER_RESP );
    CASE_RETURN_STRING( WDI_SET_RSSI_THRESHOLDS_RESP );
    CASE_RETURN_STRING( WDI_HOST_OFFLOAD_RESP );
    CASE_RETURN_STRING( WDI_WOWL_ADD_BC_PTRN_RESP );
    CASE_RETURN_STRING( WDI_WOWL_DEL_BC_PTRN_RESP );
    CASE_RETURN_STRING( WDI_WOWL_ENTER_RESP );
    CASE_RETURN_STRING( WDI_WOWL_EXIT_RESP );
    CASE_RETURN_STRING( WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_RESP );
    CASE_RETURN_STRING( WDI_NV_DOWNLOAD_RESP );
    CASE_RETURN_STRING( WDI_FLUSH_AC_RESP );
    CASE_RETURN_STRING( WDI_BTAMP_EVENT_RESP );
    CASE_RETURN_STRING( WDI_AGGR_ADD_TS_RESP );
    CASE_RETURN_STRING( WDI_ADD_STA_SELF_RESP );
    CASE_RETURN_STRING( WDI_DEL_STA_SELF_RESP );
    CASE_RETURN_STRING( WDI_FTM_CMD_RESP );
    CASE_RETURN_STRING( WDI_START_OEM_DATA_RESP );
    CASE_RETURN_STRING( WDI_HOST_RESUME_RESP );
    CASE_RETURN_STRING( WDI_KEEP_ALIVE_RESP);
  #ifdef FEATURE_WLAN_SCAN_PNO
    CASE_RETURN_STRING( WDI_SET_PREF_NETWORK_RESP );
    CASE_RETURN_STRING( WDI_SET_RSSI_FILTER_RESP );
    CASE_RETURN_STRING( WDI_UPDATE_SCAN_PARAMS_RESP );
  #endif
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
    CASE_RETURN_STRING( WDI_ROAM_SCAN_OFFLOAD_RESP );
#endif
    CASE_RETURN_STRING( WDI_SET_TX_PER_TRACKING_RESP );
    CASE_RETURN_STRING( WDI_8023_MULTICAST_LIST_RESP );
    CASE_RETURN_STRING( WDI_RECEIVE_FILTER_SET_FILTER_RESP );
    CASE_RETURN_STRING( WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_RESP );
    CASE_RETURN_STRING( WDI_RECEIVE_FILTER_CLEAR_FILTER_RESP );
    CASE_RETURN_STRING( WDI_HAL_DUMP_CMD_RESP );
    CASE_RETURN_STRING( WDI_SHUTDOWN_RESP );
    CASE_RETURN_STRING( WDI_SET_POWER_PARAMS_RESP );
    CASE_RETURN_STRING( WDI_GET_ROAM_RSSI_RESP );
#ifdef FEATURE_WLAN_BATCH_SCAN
    CASE_RETURN_STRING( WDI_SET_BATCH_SCAN_RESP);
#endif
    CASE_RETURN_STRING( WDI_UPDATE_CHAN_RESP);
    CASE_RETURN_STRING( WDI_CH_SWITCH_RESP_V1 );
    CASE_RETURN_STRING( WDI_GET_BCN_MISS_RATE_RSP );
#ifdef WLAN_FEATURE_LINK_LAYER_STATS
    CASE_RETURN_STRING( WDI_LL_STATS_SET_RSP);
    CASE_RETURN_STRING( WDI_LL_STATS_GET_RSP);
    CASE_RETURN_STRING( WDI_LL_STATS_CLEAR_RSP);
#endif
#ifdef WLAN_FEATURE_EXTSCAN
    CASE_RETURN_STRING( WDI_EXTSCAN_START_RSP);
    CASE_RETURN_STRING( WDI_EXTSCAN_STOP_RSP);
    CASE_RETURN_STRING( WDI_EXTSCAN_GET_CACHED_RESULTS_RSP);
    CASE_RETURN_STRING( WDI_EXTSCAN_GET_CAPABILITIES_RSP);
    CASE_RETURN_STRING( WDI_EXTSCAN_SET_HOTLIST_BSSID_RSP);
    CASE_RETURN_STRING( WDI_EXTSCAN_RESET_HOTLIST_BSSID_RSP);
    CASE_RETURN_STRING( WDI_EXTSCAN_SET_HOTLIST_SSID_RSP);
    CASE_RETURN_STRING( WDI_EXTSCAN_RESET_HOTLIST_SSID_RSP);
    CASE_RETURN_STRING( WDI_HAL_EXTSCAN_PROGRESS_IND);
    CASE_RETURN_STRING( WDI_HAL_EXTSCAN_SCAN_AVAILABLE_IND);
    CASE_RETURN_STRING( WDI_HAL_EXTSCAN_RESULT_IND);
    CASE_RETURN_STRING( WDI_HAL_EXTSCAN_BSSID_HOTLIST_RESULT_IND);
    CASE_RETURN_STRING( WDI_HAL_EXTSCAN_SSID_HOTLIST_RESULT_IND);
#endif /* WLAN_FEATURE_EXTSCAN */
    CASE_RETURN_STRING( WDI_GET_FW_STATS_RSP);
    CASE_RETURN_STRING( WDI_ENCRYPT_MSG_RSP);
    CASE_RETURN_STRING( WDI_FW_LOGGING_INIT_RSP);
    CASE_RETURN_STRING( WDI_GET_FRAME_LOG_RSP);
    CASE_RETURN_STRING (WDI_FATAL_EVENT_LOGGING_RSP);
    CASE_RETURN_STRING( WDI_FWR_MEM_DUMP_RSP);
    CASE_RETURN_STRING (WDI_START_RSSI_MONITOR_RSP);
    CASE_RETURN_STRING (WDI_STOP_RSSI_MONITOR_RSP);
    CASE_RETURN_STRING( WDI_WIFI_CONFIG_SET_RSP);
#ifdef FEATURE_OEM_DATA_SUPPORT
    CASE_RETURN_STRING (WDI_HAL_START_OEM_DATA_RSP_IND_NEW);
#endif
    CASE_RETURN_STRING (WDI_ANTENNA_DIVERSITY_SELECTION_RSP);
    default:
        return "Unknown WDI MessageId";
  }
}

/**
  @brief WDI_TraceHostFWCapabilities - Parses both host and Firmware
                                         Capability bitmap array.
  @param capabilityBitmap - Base address of a 4 element Bitmap array
                                               of type tANI_U32.
  @see
  @returns  None
  */
void WDI_TraceHostFWCapabilities(tANI_U32 *capabilityBitmap)
{
     int i,j;
     char *pTempCapStr = NULL;
     char *pCapStr = NULL;
     pTempCapStr = vos_mem_malloc(MAX_FW_HOST_CAP_SIZE);
     if (NULL == pTempCapStr)
     {
         WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Memory allocation failed for CapStr");
         return;
     }

     pCapStr = pTempCapStr;
     for (j = 0; j < 4; j++) {
         for (i = 0; i < 32; i++) {
             if ((*(capabilityBitmap + j) & (1 << i))) {
                 switch(i + (j * 32)) {
                     case MCC: snprintf(pCapStr, sizeof("MCC"), "%s", "MCC");
                          pCapStr += strlen("MCC");
                          break;
                     case P2P: snprintf(pCapStr, sizeof("P2P"), "%s", "P2P");
                          pCapStr += strlen("P2P");
                          break;
                     case DOT11AC: snprintf(pCapStr, sizeof("DOT11AC") , "%s", "DOT11AC");
                          pCapStr += strlen("DOT11AC");
                          break;
                     case SLM_SESSIONIZATION: snprintf(pCapStr, sizeof("SLM_SESSIONIZATION"), "%s", "SLM_SESSIONIZATION");
                          pCapStr += strlen("SLM_SESSIONIZATION");
                          break;
                     case DOT11AC_OPMODE: snprintf(pCapStr,  sizeof("DOT11AC_OPMODE"), "%s", "DOT11AC_OPMODE");
                          pCapStr += strlen("DOT11AC_OPMODE");
                          break;
                     case SAP32STA: snprintf(pCapStr, sizeof("SAP32STA"), "%s", "SAP32STA");
                          pCapStr += strlen("SAP32STA");
                          break;
                     case TDLS: snprintf(pCapStr, sizeof("TDLS"), "%s", "TDLS");
                          pCapStr += strlen("TDLS");
                          break;
                     case P2P_GO_NOA_DECOUPLE_INIT_SCAN: snprintf(pCapStr, sizeof("P2P_GO_NOA_DECOUPLE_INIT_SCAN"), "%s", "P2P_GO_NOA_DECOUPLE_INIT_SCAN");
                          pCapStr += strlen("P2P_GO_NOA_DECOUPLE_INIT_SCAN");
                          break;
                     case WLANACTIVE_OFFLOAD: snprintf(pCapStr, sizeof("WLANACTIVE_OFFLOAD"), "%s", "WLANACTIVE_OFFLOAD");
                          pCapStr += strlen("WLANACTIVE_OFFLOAD");
                          break;
                     case BEACON_OFFLOAD: snprintf(pCapStr, sizeof("BEACON_OFFLOAD"), "%s","BEACON_OFFLOAD");
                          pCapStr += strlen("BEACON_OFFLOAD");
                          break;
                     case SCAN_OFFLOAD: snprintf(pCapStr, sizeof("SCAN_OFFLOAD"), "%s", "SCAN_OFFLOAD");
                          pCapStr += strlen("SCAN_OFFLOAD");
                          break;
                     case ROAM_OFFLOAD: snprintf(pCapStr,  sizeof("ROAM_OFFLOAD"), "%s", "ROAM_OFFLOAD");
                          pCapStr += strlen("ROAM_OFFLOAD");
                          break;
                     case BCN_MISS_OFFLOAD: snprintf(pCapStr, sizeof("BCN_MISS_OFFLOAD"), "%s", "BCN_MISS_OFFLOAD");
                          pCapStr += strlen("BCN_MISS_OFFLOAD");
                          break;
                     case STA_POWERSAVE: snprintf(pCapStr, sizeof("STA_POWERSAVE"), "%s", "STA_POWERSAVE");
                          pCapStr += strlen("STA_POWERSAVE");
                          break;
                     case AP_UAPSD: snprintf(pCapStr, sizeof("AP_UAPSD"), "%s", "AP_UAPSD");
                          pCapStr += strlen("AP_UAPSD");
                          break;
                     case AP_DFS: snprintf(pCapStr, sizeof("AP_DFS"), "%s", "AP_DFS");
                          pCapStr += strlen("AP_DFS");
                          break;
                     case BLOCKACK: snprintf(pCapStr, sizeof("BLOCKACK"), "%s", "BLOCKACK");
                          pCapStr += strlen("BLOCKACK");
                          break;
                     case PHY_ERR: snprintf(pCapStr, sizeof("PHY_ERR"), "%s", "PHY_ERR");
                          pCapStr += strlen("PHY_ERR");
                          break;
                     case BCN_FILTER: snprintf(pCapStr, sizeof("BCN_FILTER"), "%s", "BCN_FILTER");
                          pCapStr += strlen("BCN_FILTER");
                          break;
                     case RTT: snprintf(pCapStr, sizeof("RTT"), "%s", "RTT");
                          pCapStr += strlen("RTT");
                          break;
                     case RATECTRL: snprintf(pCapStr, sizeof("RATECTRL"), "%s", "RATECTRL");
                          pCapStr += strlen("RATECTRL");
                          break;
                     case WOW: snprintf(pCapStr, sizeof("WOW"), "%s", "WOW");
                          pCapStr += strlen("WOW");
                          break;
                     case WLAN_ROAM_SCAN_OFFLOAD: snprintf(pCapStr, sizeof("WLAN_ROAM_SCAN_OFFLOAD"), "%s", "WLAN_ROAM_SCAN_OFFLOAD");
                          pCapStr += strlen("WLAN_ROAM_SCAN_OFFLOAD");
                          break;
                     case FW_IN_TX_PATH: snprintf(pCapStr, sizeof("FW_IN_TX_PATH"), "%s", "FW_IN_TX_PATH");
                          pCapStr += strlen("FW_IN_TX_PATH");
                          break;
                     case HT40_OBSS_SCAN:
                          snprintf(pCapStr, sizeof("HT40_OBSS_SCAN"),
                                   "%s", "HT40_OBSS_SCAN");
                          pCapStr += strlen("HT40_OBSS_SCAN");
                          break;
                     case EXTENDED_NSOFFLOAD_SLOT: snprintf(pCapStr,
                                              sizeof("EXTENDED_NSOFFLOAD_SLOT"),
                                              "%s", "EXTENDED_NSOFFLOAD_SLOT");
                          pCapStr += strlen("EXTENDED_NSOFFLOAD_SLOT");
                          break;
                     case TDLS_SCAN_COEXISTENCE: snprintf(pCapStr, sizeof("TDLS_SCAN_COEXISTENCE"), "%s", "TDLS_SCAN_COEXISTENCE");
                          pCapStr += strlen("TDLS_SCAN_COEXISTENCE");
                          break;
                     case CH_SWITCH_V1: snprintf(pCapStr, sizeof("CH_SWITCH_V1"), "%s", "CH_SWITCH_V1");
                          pCapStr += strlen("CH_SWITCH_V1");
                          break;
#ifdef WLAN_FEATURE_LINK_LAYER_STATS
                     case LINK_LAYER_STATS_MEAS: snprintf(pCapStr, sizeof("LINK_LAYER_STATS_MEAS"), "%s", "LINK_LAYER_STATS_MEAS");
                          pCapStr += strlen("LINK_LAYER_STATS_MEAS");
                          break;
#endif
#ifdef WLAN_FEATURE_EXTSCAN
                     case EXTENDED_SCAN: snprintf(pCapStr, sizeof("EXTENDED_SCAN"), "%s", "EXTENDED_SCAN");
                          pCapStr += strlen("EXTENDED_SCAN");
                          break;
                     case EXT_SCAN_ENHANCED: snprintf(pCapStr, sizeof("EXT_SCAN_ENHANCED"), "%s", "EXT_SCAN_ENHANCED");
                          pCapStr += strlen("EXT_SCAN_ENHANCED");
                          break;
#endif
                     case MU_MIMO: snprintf(pCapStr, sizeof("MU_MIMO"), "%s", "MU_MIMO");
                          pCapStr += strlen("MU_MIMO");
                          break;

                     case DYNAMIC_WMM_PS: snprintf(pCapStr, sizeof("DYNAMIC_WMM_PS"), "%s", "DYNAMIC_WMM_PS");
                          pCapStr += strlen("DYNAMIC_WMM_PS");
                          break;
                     case FW_STATS: snprintf(pCapStr, sizeof("FW_STATS"), "%s", "FW_STATS");
                          pCapStr += strlen("FW_STATS");
                          break;
                     case MAC_SPOOFED_SCAN: snprintf(pCapStr, sizeof("MAC_SPOOFED_SCAN"), "%s", "MAC_SPOOFED_SCAN");
                          pCapStr += strlen("MAC_SPOOFED_SCAN");
                          break;
                     case WPS_PRBRSP_TMPL: snprintf(pCapStr, sizeof("WPS_PRBRSP_TMPL"), "%s", "WPS_PRBRSP_TMPL");
                          pCapStr += strlen("WPS_PRBRSP_TMPL");
                          break;
                     case BCN_IE_FLT_DELTA: snprintf(pCapStr, sizeof("BCN_IE_FLT_DELTA"), "%s", "BCN_IE_FLT_DELTA");
                          pCapStr += strlen("BCN_IE_FLT_DELTA");
                          break;
                     case MGMT_FRAME_LOGGING: snprintf(pCapStr, sizeof("MGMT_FRAME_LOGGING"), "%s", "MGMT_FRAME_LOGGING");
                          pCapStr += strlen("MGMT_FRAME_LOGGING");
                          break;
                     case BMU_ERROR_GENERIC_RECOVERY: snprintf(pCapStr, sizeof("BMU_ERROR_GENERIC_RECOVERY"), "%s", "BMU_ERROR_GENERIC_RECOVERY");
                          pCapStr += strlen("BMU_ERROR_GENERIC_RECOVERY");
                          break;

                     case DISA: snprintf(pCapStr, sizeof("DISA"), "%s", "DISA");
                          pCapStr += strlen("DISA");
                          break;

                     case TDLS_OFF_CHANNEL: snprintf(pCapStr, sizeof("TDLS_OFF_CHANNEL"), "%s", "TDLS_OFF_CHANNEL");
                          pCapStr += strlen("TDLS_OFF_CHANNEL");
                          break;
                     case LOGGING_ENHANCEMENT: snprintf(pCapStr, sizeof("LOGGING_ENHANCEMENT"), "%s", "LOGGING_ENHANCEMENT");
                          pCapStr += strlen("LOGGING_ENHANCEMENT");
                          break;
                     case MEMORY_DUMP_SUPPORTED:snprintf(pCapStr, sizeof("FW_MEM_DUMP_LOGGING"), "%s", "FW_MEM_DUMP_LOGGING");
                          pCapStr += strlen("FW_MEM_DUMP_LOGGING");
                          break;
                     case PER_PKT_STATS_SUPPORTED: snprintf(pCapStr, sizeof("PER_PKT_STATS_SUPPORTED"), "%s", "PER_PKT_STATS_SUPPORTED");
                          pCapStr += strlen("PER_PKT_STATS_SUPPORTED");
                          break;
                     case EXT_LL_STAT: snprintf(pCapStr, sizeof("EXT_LL_STAT"), "%s", "EXT_LL_STAT");
                          pCapStr += strlen("EXT_LL_STAT");
                          break;
                     case RTT3: snprintf(pCapStr, sizeof("RTT3"), "%s", "RTT3");
                          pCapStr += strlen("RTT3");
                          break;
                     case ANTENNA_DIVERSITY_SELECTION:
                          snprintf(pCapStr,
                          sizeof("ANTENNA_DIVERSITY_SELECTION"), "%s",
                                 "ANTENNA_DIVERSITY_SELECTION");
                          pCapStr += strlen("ANTENNA_DIVERSITY_SELECTION");
                          break;
                 }
                 *pCapStr++ = ',';
                 *pCapStr++ = ' ';
             }
         }
     }
     pCapStr -= 2;
     *pCapStr = '\0';
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_INFO, "\t\t%s", pTempCapStr);
     if (pTempCapStr)
     {
         vos_mem_free(pTempCapStr);
         pTempCapStr = NULL;
     }
}

/**
 @brief WDI_getHALStatusMsgString prints the HAL status in string.

 @param halStatusId: HAL status Id

 @see
 @return Result of the function call
*/
static char *WDI_getHALStatusMsgString(wpt_uint16 halStatusId)
{
  switch (halStatusId)
  {
    CASE_RETURN_STRING( eHAL_STATUS_SUCCESS );
    CASE_RETURN_STRING( PAL_STATUS_INVAL );
    CASE_RETURN_STRING( PAL_STATUS_ALREADY );
    CASE_RETURN_STRING( PAL_STATUS_EMPTY );
    CASE_RETURN_STRING( PAL_STATUS_FAILURE );
    CASE_RETURN_STRING( eHAL_STATUS_FAILURE );
    CASE_RETURN_STRING( eHAL_STATUS_INVALID_PARAMETER );
    CASE_RETURN_STRING( eHAL_STATUS_INVALID_STAIDX );
    CASE_RETURN_STRING( eHAL_STATUS_DPU_DESCRIPTOR_TABLE_FULL );
    CASE_RETURN_STRING( eHAL_STATUS_NO_INTERRUPTS );
    CASE_RETURN_STRING( eHAL_STATUS_INTERRUPT_PRESENT );
    CASE_RETURN_STRING( eHAL_STATUS_STA_TABLE_FULL );
    CASE_RETURN_STRING( eHAL_STATUS_DUPLICATE_STA );
    CASE_RETURN_STRING( eHAL_STATUS_BSSID_INVALID );
    CASE_RETURN_STRING( eHAL_STATUS_STA_INVALID );
    CASE_RETURN_STRING( eHAL_STATUS_DUPLICATE_BSSID );
    CASE_RETURN_STRING( eHAL_STATUS_INVALID_BSSIDX );
    CASE_RETURN_STRING( eHAL_STATUS_BSSID_TABLE_FULL );
    CASE_RETURN_STRING( eHAL_STATUS_INVALID_SIGNATURE );
    CASE_RETURN_STRING( eHAL_STATUS_INVALID_KEYID );
    CASE_RETURN_STRING( eHAL_STATUS_SET_CHAN_ALREADY_ON_REQUESTED_CHAN );
    CASE_RETURN_STRING( eHAL_STATUS_UMA_DESCRIPTOR_TABLE_FULL );
    CASE_RETURN_STRING( eHAL_STATUS_DPU_MICKEY_TABLE_FULL );
    CASE_RETURN_STRING( eHAL_STATUS_BA_RX_BUFFERS_FULL );
    CASE_RETURN_STRING( eHAL_STATUS_BA_RX_MAX_SESSIONS_REACHED );
    CASE_RETURN_STRING( eHAL_STATUS_BA_RX_INVALID_SESSION_ID );
    CASE_RETURN_STRING( eHAL_STATUS_TIMER_START_FAILED );
    CASE_RETURN_STRING( eHAL_STATUS_TIMER_STOP_FAILED );
    CASE_RETURN_STRING( eHAL_STATUS_FAILED_ALLOC );
    CASE_RETURN_STRING( eHAL_STATUS_NOTIFY_BSS_FAIL );
    CASE_RETURN_STRING( eHAL_STATUS_DEL_STA_SELF_IGNORED_REF_COUNT_NOT_ZERO );
    CASE_RETURN_STRING( eHAL_STATUS_ADD_STA_SELF_IGNORED_REF_COUNT_NOT_ZERO );
    CASE_RETURN_STRING( eHAL_STATUS_FW_SEND_MSG_FAILED );
    default:
        return "Unknown HAL status";
  }
}

/**
 * wdi_state_info_dump() - prints state information of wdi layer
 */
static void wdi_state_info_dump(void)
{
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                "%s pending commands: %d", __func__,
                gWDICb.wptPendingQueue.count);
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                "uGlobalState %d wdiExpectedResponse: %d",
                gWDICb.uGlobalState, gWDICb.wdiExpectedResponse);
}


/**
 * wdi_register_debug_callback() - registration function for wdi layer
 * to print WDI state information
  */
static void wdi_register_debug_callback(void)
{
    vos_register_debug_callback(VOS_MODULE_ID_WDI, &wdi_state_info_dump);
}


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

                             INITIALIZATION APIs

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

/**
 @brief WDI_Init is used to initialize the DAL.

 DAL will allocate all the resources it needs. It will open PAL, it will also
 open both the data and the control transport which in their turn will open
 DXE/SMD or any other drivers that they need.

 @param devHandle: pointer to the OS specific device handle
        ppWDIGlobalCtx: output pointer of Global Context
        pWdiDevCapability: output pointer of device capability

 @return Result of the function call
*/
WDI_Status
WDI_Init
(
  void*                      devHandle,
  void**                     ppWDIGlobalCtx,
  WDI_DeviceCapabilityType*  pWdiDevCapability,
  unsigned int               driverType
)
{
  wpt_uint8               i;
  wpt_status              wptStatus;
  WDI_Status              wdiStatus;
  WCTS_TransportCBsType   wctsCBs;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /*---------------------------------------------------------------------
    Sanity check
  ---------------------------------------------------------------------*/
  if (( NULL == ppWDIGlobalCtx ) || ( NULL == pWdiDevCapability ))
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Invalid input parameters in WDI_Init");

    return WDI_STATUS_E_FAILURE;
  }

  /*---------------------------------------------------------------------
    Check to see if the module has already been initialized or not
  ---------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE != gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "WDI module already initialized - return");

    return WDI_STATUS_SUCCESS;
  }

  /*Module is now initialized - this flag is to ensure the fact that multiple
   init will not happen on WDI
   !! - potential race does exist because read and set are not atomic,
   however an atomic operation would be closely here - reanalyze if necessary*/
  gWDIInitialized = eWLAN_PAL_TRUE;

  /*Setup the control block */
  WDI_CleanCB(&gWDICb);
  gWDICb.pOSContext = devHandle ;

  /*Setup the STA Table*/
  wdiStatus = WDI_STATableInit(&gWDICb);
  if ( WDI_STATUS_SUCCESS != wdiStatus )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
               "%s: Failure while initializing STA Table, status %d",
               __func__, wdiStatus);
    goto fail_STATableInit;
  }

  /*------------------------------------------------------------------------
    Open the PAL
   ------------------------------------------------------------------------*/
  wptStatus =  wpalOpen(&gWDICb.pPALContext, devHandle);
  if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
               "%s: Failed to open PAL, status %d",
               __func__, wptStatus);
    goto fail_wpalOpen;
  }

  /*Initialize main synchro mutex - it will be used to ensure integrity of
   the main WDI Control Block*/
  wptStatus =  wpalMutexInit(&gWDICb.wptMutex);
  if ( eWLAN_PAL_STATUS_SUCCESS !=  wptStatus )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
               "%s: Failed to init mutex, status %d",
               __func__, wptStatus);
    goto fail_mutex;
  }

  /*Initialize the response timer - it will be used to time all messages
    expected as response from device*/
  wptStatus = wpalTimerInit( &gWDICb.wptResponseTimer,
                             WDI_ResponseTimerCB,
                             &gWDICb);
  if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
              "%s: Failed to init response timer, status %d",
               __func__, wptStatus);
    goto fail_timer;
  }

  wptStatus = wpalTimerInit( &gWDICb.ssrTimer,
                             WDI_SsrTimerCB,
                             &gWDICb);
  if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
              "%s: Failed to init SSR timer, status %d",
               __func__, wptStatus);
    goto fail_timer2;
  }
  /* Initialize the  WDI Pending Request Queue*/
  wptStatus = wpal_list_init(&(gWDICb.wptPendingQueue));
  if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
              "%s: Failed to init pending request queue, status %d",
               __func__, wptStatus);
    goto fail_pend_queue;
  }

  /*Init WDI Pending Assoc Id Queue */
  wptStatus = wpal_list_init(&(gWDICb.wptPendingAssocSessionIdQueue));
  if ( eWLAN_PAL_STATUS_SUCCESS !=  wptStatus )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
              "%s: Failed to init assoc session queue, status %d",
               __func__, wptStatus);
    goto fail_assoc_queue;
  }

  /*Initialize the BSS sessions pending Queue */
  for ( i = 0; i < WDI_MAX_BSS_SESSIONS; i++ )
  {
    wptStatus = wpal_list_init(&(gWDICb.aBSSSessions[i].wptPendingQueue));
    if ( eWLAN_PAL_STATUS_SUCCESS !=  wptStatus )
    {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                 "%s: Failed to init BSS %d pending queue, status %d",
                 __func__, i, wptStatus);
      goto fail_bss_queue;
    }
  }

  /*Indicate the control block is sufficiently initialized for callbacks*/
  gWDICb.magic = WDI_CONTROL_BLOCK_MAGIC;

  /*------------------------------------------------------------------------
    Initialize the Data Path Utility Module
   ------------------------------------------------------------------------*/
  wdiStatus = WDI_DP_UtilsInit(&gWDICb);
  if ( WDI_STATUS_SUCCESS != wdiStatus )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
               "%s: Failed to initialize the DP Util Module, status %d",
               __func__, wdiStatus);
    goto fail_dp_util_init;
  }

  /* Init Set power state event */
  wptStatus = wpalEventInit(&gWDICb.setPowerStateEvent);
  if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus )
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                "%s: Failed to initialize power state event, status %d",
                __func__, wptStatus);
     goto fail_power_event;
  }

  /* Init WCTS action event */
  wptStatus = wpalEventInit(&gWDICb.wctsActionEvent);
  if ( eWLAN_PAL_STATUS_SUCCESS !=  wptStatus )
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                "%s: Failed to initialize WCTS action event, status %d",
                __func__, wptStatus);
     goto fail_wcts_event;
  }

  /*------------------------------------------------------------------------
    Open the Transport Services for Control and Data
   ------------------------------------------------------------------------*/
  wctsCBs.wctsNotifyCB      = WDI_NotifyMsgCTSCB;
  wctsCBs.wctsNotifyCBData  = &gWDICb;
  wctsCBs.wctsRxMsgCB       = WDI_RXMsgCTSCB;
  wctsCBs.wctsRxMsgCBData   = &gWDICb;

  gWDICb.bCTOpened          = eWLAN_PAL_FALSE;
  gWDICb.wctsHandle = WCTS_OpenTransport( szTransportChName ,
                                          WDI_CT_CHANNEL_SIZE,
                                          &wctsCBs );

  if ( NULL == gWDICb.wctsHandle )
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                "%s: Failed to open WCTS transport", __func__);
     goto fail_wcts_open;
  }

  gWDICb.driverMode = (tDriverType)driverType;
  /* FTM mode not need to open Transport Driver */
  if(eDRIVER_TYPE_MFG != (tDriverType)driverType)
  {
    /*------------------------------------------------------------------------
     Open the Data Transport
     ------------------------------------------------------------------------*/
    if(eWLAN_PAL_STATUS_SUCCESS != WDTS_openTransport(&gWDICb))
    {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                 "%s: Failed to open the DT Transport", __func__);
      goto fail_wdts_open;
    }
  }

  /*The WDI is initialized - set state to init */
  gWDICb.uGlobalState = WDI_INIT_ST;
  gWDICb.roamDelayStatsEnabled = vos_get_roam_delay_stats_enabled();
  /*Send the context as a ptr to the global WDI Control Block*/
  *ppWDIGlobalCtx = &gWDICb;

  /*Fill in the device capabilities*/
  pWdiDevCapability->bFrameXtlSupported = eWLAN_PAL_FALSE;
  pWdiDevCapability->ucMaxSTASupported  = gWDICb.ucMaxStations;
  pWdiDevCapability->ucMaxBSSSupported  = gWDICb.ucMaxBssids;

  wdi_register_debug_callback();

  return WDI_STATUS_SUCCESS;

  /* ERROR handlers
     Undo everything that completed successfully */

 fail_wdts_open:
  {
     wpt_status             eventStatus;

     /* Closing WCTS in this scenario is tricky since it has to close
        the SMD channel and then we get notified asynchronously when
        the channel has been closed. So we take some of the logic from
        the "normal" close procedure in WDI_Close()
     */

     eventStatus = wpalEventReset(&gWDICb.wctsActionEvent);
     if ( eWLAN_PAL_STATUS_SUCCESS != eventStatus )
     {
        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                   "%s: Failed to reset WCTS action event", __func__);
     }

     WCTS_CloseTransport(gWDICb.wctsHandle);

     /* Wait for WCTS to close the control transport.  If we were able
        to reset the event flag, then we'll wait for the event,
        otherwise we'll wait for a maximum amount of time required for
        the channel to be closed */
     if ( eWLAN_PAL_STATUS_SUCCESS == eventStatus )
     {
        eventStatus = wpalEventWait(&gWDICb.wctsActionEvent,
                                    WDI_WCTS_ACTION_TIMEOUT);
        if ( eWLAN_PAL_STATUS_SUCCESS != eventStatus )
        {
           WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                      "%s: Failed to wait on WCTS action event", __func__);
        }
     }
     else
     {
        wpalSleep(WDI_WCTS_ACTION_TIMEOUT);
     }
  }
 fail_wcts_open:
  wpalEventDelete(&gWDICb.wctsActionEvent);
 fail_wcts_event:
  wpalEventDelete(&gWDICb.setPowerStateEvent);
 fail_power_event:
  WDI_DP_UtilsExit(&gWDICb);
 fail_dp_util_init:
  gWDICb.magic = 0;
 fail_bss_queue:
  /* entries 0 thru i-1 were successfully initialized */
  while (0 < i)
  {
     i--;
     wpal_list_destroy(&(gWDICb.aBSSSessions[i].wptPendingQueue));
  }
  wpal_list_destroy(&(gWDICb.wptPendingAssocSessionIdQueue));
 fail_assoc_queue:
  wpal_list_destroy(&(gWDICb.wptPendingQueue));
 fail_pend_queue:
  wpalTimerDelete(&gWDICb.ssrTimer);
 fail_timer2:
  wpalTimerDelete(&gWDICb.wptResponseTimer);
 fail_timer:
  wpalMutexDelete(&gWDICb.wptMutex);
 fail_mutex:
  wpalClose(gWDICb.pPALContext);
 fail_wpalOpen:
  WDI_STATableClose(&gWDICb);
 fail_STATableInit:
  gWDIInitialized = eWLAN_PAL_FALSE; 

  return WDI_STATUS_E_FAILURE; 

}/*WDI_Init*/;

/**
 @brief WDI_Start will be called when the upper MAC is ready to
        commence operation with the WLAN Device. Upon the call
        of this API the WLAN DAL will pack and send a HAL Start
        message to the lower RIVA sub-system if the SMD channel
        has been fully opened and the RIVA subsystem is up.

         If the RIVA sub-system is not yet up and running DAL
         will queue the request for Open and will wait for the
         SMD notification before attempting to send down the
         message to HAL.

 WDI_Init must have been called.

 @param wdiStartParams: the start parameters as specified by
                      the Device Interface

        wdiStartRspCb: callback for passing back the response of
        the start operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_Start
 @return Result of the function call
*/
WDI_Status
WDI_Start
(
  WDI_StartReqParamsType*  pwdiStartParams,
  WDI_StartRspCb           wdiStartRspCb,
  void*                    pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_START_REQ;
  wdiEventData.pEventData      = pwdiStartParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiStartParams);
  wdiEventData.pCBfnc          = wdiStartRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_Start*/

/**
 @brief WDI_Stop will be called when the upper MAC is ready to
        stop any operation with the WLAN Device. Upon the call
        of this API the WLAN DAL will pack and send a HAL Stop
        message to the lower RIVA sub-system if the DAL Core is
        in started state.

         In state BUSY this request will be queued.

         Request will not be accepted in any other state.

 WDI_Start must have been called.

 @param wdiStopParams: the stop parameters as specified by
                      the Device Interface

        wdiStopRspCb: callback for passing back the response of
        the stop operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_Start
 @return Result of the function call
*/
WDI_Status
WDI_Stop
(
  WDI_StopReqParamsType*  pwdiStopParams,
  WDI_StopRspCb           wdiStopRspCb,
  void*                   pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  WDI_ControlBlockType*  pWDICtx = &gWDICb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*Access to the global state must be locked before cleaning */
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*Clear all pending request*/
  WDI_ClearPendingRequests(pWDICtx);

  /*We have completed cleaning unlock now*/
  wpalMutexRelease(&pWDICtx->wptMutex);

  /* Free the global variables */
  wpalMemoryFree(gpHostWlanFeatCaps);
  wpalMemoryFree(gpFwWlanFeatCaps);
  gpHostWlanFeatCaps = NULL;
  gpFwWlanFeatCaps = NULL;

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_STOP_REQ;
  wdiEventData.pEventData      = pwdiStopParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiStopParams);
  wdiEventData.pCBfnc          = wdiStopRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_STOP_EVENT, &wdiEventData);

}/*WDI_Stop*/



/**
 @brief WDI_Close will be called when the upper MAC no longer
        needs to interact with DAL. DAL will free its control
        block.

        It is only accepted in state STOPPED.

 WDI_Stop must have been called.

 @param none

 @see WDI_Stop
 @return Result of the function call
*/
WDI_Status
WDI_Close
(
  void
)
{
  wpt_uint8              i;
  WDI_EventInfoType      wdiEventData;
  wpt_status             wptStatus;
  wpt_status             eventStatus;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*Reset WCTS action event prior to posting the WDI_CLOSE_REQ
   (the control transport will be closed by the FSM and we'll want
   to wait until that completes)*/
  eventStatus = wpalEventReset(&gWDICb.wctsActionEvent);
  if ( eWLAN_PAL_STATUS_SUCCESS != eventStatus )
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Failed to reset WCTS action event", __func__);
     /* fall through and try to finish closing via the FSM */
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_CLOSE_REQ;
  wdiEventData.pEventData      = NULL;
  wdiEventData.uEventDataSize  = 0;
  wdiEventData.pCBfnc          = NULL;
  wdiEventData.pUserData       = NULL;

  gWDIInitialized = eWLAN_PAL_FALSE;

  wptStatus = WDI_PostMainEvent(&gWDICb, WDI_CLOSE_EVENT, &wdiEventData);

  /*Wait for WCTS to close the control transport
    (but only if we were able to reset the event flag*/
  if ( eWLAN_PAL_STATUS_SUCCESS == eventStatus )
  {
     eventStatus = wpalEventWait(&gWDICb.wctsActionEvent,
                                 WDI_WCTS_ACTION_TIMEOUT);
     if ( eWLAN_PAL_STATUS_SUCCESS != eventStatus )
     {
        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                   "%s: Failed to wait on WCTS action event", __func__);
     }
  }

  /* Destroy the WCTS action event */
  wptStatus = wpalEventDelete(&gWDICb.wctsActionEvent);
  if ( eWLAN_PAL_STATUS_SUCCESS !=  wptStatus )
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "WDI Close failed to destroy an event");
     WDI_ASSERT(0);
  }

   /* Destroy the Set Power State event */
   wptStatus = wpalEventDelete(&gWDICb.setPowerStateEvent);
   if ( eWLAN_PAL_STATUS_SUCCESS !=  wptStatus )
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "WDI Close failed to destroy an event");

      WDI_ASSERT(0);
   }

  /*------------------------------------------------------------------------
    Closes the Data Path Utility Module
   ------------------------------------------------------------------------*/
  if ( WDI_STATUS_SUCCESS != WDI_DP_UtilsExit(&gWDICb))
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "WDI Init failed to close the DP Util Module");

    WDI_ASSERT(0);
  }

  /*destroy the BSS sessions pending Queue */
  for ( i = 0; i < WDI_MAX_BSS_SESSIONS; i++ )
  {
    wpal_list_destroy(&(gWDICb.aBSSSessions[i].wptPendingQueue));
  }

  /* destroy the WDI Pending Assoc Id Request Queue*/
  wpal_list_destroy(&(gWDICb.wptPendingAssocSessionIdQueue));

  /* destroy the WDI Pending Request Queue*/
  wpal_list_destroy(&(gWDICb.wptPendingQueue));

  /*destroy the response timer */
  wptStatus = wpalTimerDelete( &gWDICb.wptResponseTimer);

  /*destroy the SSR timer */
  wptStatus = wpalTimerDelete( &gWDICb.ssrTimer);

  /*invalidate the main synchro mutex */
  wptStatus = wpalMutexDelete(&gWDICb.wptMutex);
  if ( eWLAN_PAL_STATUS_SUCCESS !=  wptStatus )
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                "Failed to delete mutex %d", wptStatus);
     WDI_ASSERT(0);
  }

  /*Clear control block.  note that this will clear the "magic"
    which will inhibit all asynchronous callbacks*/
  WDI_CleanCB(&gWDICb);

  return wptStatus;

}/*WDI_Close*/

/**
 @brief  WDI_Shutdown will be called during 'SSR shutdown' operation.
         This will do most of the WDI stop & close
         operations without doing any handshake with Riva

         This will also make sure that the control transport
         will NOT be closed.

         This request will not be queued.


 WDI_Start must have been called.

 @param  closeTransport:  Close control channel if this is set

 @return Result of the function call
*/
WDI_Status
WDI_Shutdown
(
 wpt_boolean closeTransport
)
{
   WDI_EventInfoType      wdiEventData;
   wpt_status             wptStatus;
   int                    i = 0;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check
     ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
            "WDI API call before module is initialized - Fail request");

      return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
     ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_SHUTDOWN_REQ;
   wdiEventData.pEventData      = NULL;
   wdiEventData.uEventDataSize  = 0;

   /* Shutdown will not be queued, if the state is busy timer will be
    * stopped & this message will be processed.*/
   wptStatus = WDI_PostMainEvent(&gWDICb, WDI_SHUTDOWN_EVENT, &wdiEventData);
   if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus )
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
            "%s: Failed to process shutdown event", __func__);
   }
   /* Destroy the Set Power State event */
   wptStatus = wpalEventDelete(&gWDICb.setPowerStateEvent);
   if ( eWLAN_PAL_STATUS_SUCCESS !=  wptStatus )
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
            "WDI Close failed to destroy an event");

      WDI_ASSERT(0);
   }
   /*------------------------------------------------------------------------
     Closes the Data Path Utility Module
     ------------------------------------------------------------------------*/
   if ( WDI_STATUS_SUCCESS != WDI_DP_UtilsExit(&gWDICb))
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
            "WDI Init failed to close the DP Util Module");

      WDI_ASSERT(0);
   }
   if ( closeTransport )
   {
      /* Close control transport, called from module unload */
      WCTS_CloseTransport(gWDICb.wctsHandle);
   }
   else
   {
      /* Riva is crashed then SMD is already closed so cleaning all 
         the pending messages in the transport queue  */
      WCTS_ClearPendingQueue(gWDICb.wctsHandle);
   }
   /*destroy the BSS sessions pending Queue */
   for ( i = 0; i < WDI_MAX_BSS_SESSIONS; i++ )
   {
      wpal_list_destroy(&(gWDICb.aBSSSessions[i].wptPendingQueue));
   }

   /* destroy the WDI Pending Assoc Id Request Queue*/
   wpal_list_destroy(&(gWDICb.wptPendingAssocSessionIdQueue));
   /* destroy the WDI Pending Request Queue*/
   wpal_list_destroy(&(gWDICb.wptPendingQueue));
   /*destroy the response timer */
   wptStatus = wpalTimerDelete( &gWDICb.wptResponseTimer);
   /*destroy the SSR timer */
   wptStatus = wpalTimerDelete( &gWDICb.ssrTimer);

   /*invalidate the main synchro mutex */
   wptStatus = wpalMutexDelete(&gWDICb.wptMutex);
   if ( eWLAN_PAL_STATUS_SUCCESS !=  wptStatus )
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
            "%s: Failed to delete mutex %d",  __func__, wptStatus);
      WDI_ASSERT(0);
   }
   /* Free the global variables */
   wpalMemoryFree(gpHostWlanFeatCaps);
   wpalMemoryFree(gpFwWlanFeatCaps);
   gpHostWlanFeatCaps = NULL;
   gpFwWlanFeatCaps = NULL;
   /*Clear control block.  note that this will clear the "magic"
     which will inhibit all asynchronous callbacks*/
   WDI_CleanCB(&gWDICb);
   return wptStatus;

}/*WDI_Shutdown*/


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

                             SCAN APIs

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

/**
 @brief WDI_InitScanReq will be called when the upper MAC wants
        the WLAN Device to get ready for a scan procedure. Upon
        the call of this API the WLAN DAL will pack and send a
        HAL Init Scan request message to the lower RIVA
        sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_Start must have been called.

 @param wdiInitScanParams: the init scan parameters as specified
                      by the Device Interface

        wdiInitScanRspCb: callback for passing back the response
        of the init scan operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_Start
 @return Result of the function call
*/
WDI_Status
WDI_InitScanReq
(
  WDI_InitScanReqParamsType*  pwdiInitScanParams,
  WDI_InitScanRspCb           wdiInitScanRspCb,
  void*                       pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_INIT_SCAN_REQ;
  wdiEventData.pEventData      = pwdiInitScanParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiInitScanParams);
  wdiEventData.pCBfnc          = wdiInitScanRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_InitScanReq*/

/**
 @brief WDI_StartScanReq will be called when the upper MAC
        wishes to change the Scan channel on the WLAN Device.
        Upon the call of this API the WLAN DAL will pack and
        send a HAL Start Scan request message to the lower RIVA
        sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_InitScanReq must have been called.

 @param wdiStartScanParams: the start scan parameters as
                      specified by the Device Interface

        wdiStartScanRspCb: callback for passing back the
        response of the start scan operation received from the
        device

        pUserData: user data will be passed back with the
        callback

 @see WDI_InitScanReq
 @return Result of the function call
*/
WDI_Status
WDI_StartScanReq
(
  WDI_StartScanReqParamsType*  pwdiStartScanParams,
  WDI_StartScanRspCb           wdiStartScanRspCb,
  void*                        pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_START_SCAN_REQ;
  wdiEventData.pEventData      = pwdiStartScanParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiStartScanParams);
  wdiEventData.pCBfnc          = wdiStartScanRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_StartScanReq*/


/**
 @brief WDI_EndScanReq will be called when the upper MAC is
        wants to end scanning for a particular channel that it
        had set before by calling Scan Start on the WLAN Device.
        Upon the call of this API the WLAN DAL will pack and
        send a HAL End Scan request message to the lower RIVA
        sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_StartScanReq must have been called.

 @param wdiEndScanParams: the end scan parameters as specified
                      by the Device Interface

        wdiEndScanRspCb: callback for passing back the response
        of the end scan operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_StartScanReq
 @return Result of the function call
*/
WDI_Status
WDI_EndScanReq
(
  WDI_EndScanReqParamsType* pwdiEndScanParams,
  WDI_EndScanRspCb          wdiEndScanRspCb,
  void*                     pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_END_SCAN_REQ;
  wdiEventData.pEventData      = pwdiEndScanParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiEndScanParams);
  wdiEventData.pCBfnc          = wdiEndScanRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_EndScanReq*/


/**
 @brief WDI_FinishScanReq will be called when the upper MAC has
        completed the scan process on the WLAN Device. Upon the
        call of this API the WLAN DAL will pack and send a HAL
        Finish Scan Request request message to the lower RIVA
        sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_InitScanReq must have been called.

 @param wdiFinishScanParams: the finish scan  parameters as
                      specified by the Device Interface

        wdiFinishScanRspCb: callback for passing back the
        response of the finish scan operation received from the
        device

        pUserData: user data will be passed back with the
        callback

 @see WDI_InitScanReq
 @return Result of the function call
*/
WDI_Status
WDI_FinishScanReq
(
  WDI_FinishScanReqParamsType* pwdiFinishScanParams,
  WDI_FinishScanRspCb          wdiFinishScanRspCb,
  void*                        pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_FINISH_SCAN_REQ;
  wdiEventData.pEventData      = pwdiFinishScanParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiFinishScanParams);
  wdiEventData.pCBfnc          = wdiFinishScanRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_FinishScanReq*/

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

                          ASSOCIATION APIs

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

/**
 @brief WDI_JoinReq will be called when the upper MAC is ready
        to start an association procedure to a BSS. Upon the
        call of this API the WLAN DAL will pack and send a HAL
        Join request message to the lower RIVA sub-system if
        DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_Start must have been called.

 @param wdiJoinParams: the join parameters as specified by
                      the Device Interface

        wdiJoinRspCb: callback for passing back the response of
        the join operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_Start
 @return Result of the function call
*/
WDI_Status
WDI_JoinReq
(
  WDI_JoinReqParamsType* pwdiJoinParams,
  WDI_JoinRspCb          wdiJoinRspCb,
  void*                  pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_JOIN_REQ;
  wdiEventData.pEventData      = pwdiJoinParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiJoinParams);
  wdiEventData.pCBfnc          = wdiJoinRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_JoinReq*/

/**
 @brief WDI_ConfigBSSReq will be called when the upper MAC
        wishes to configure the newly acquired or in process of
        being acquired BSS to the HW . Upon the call of this API
        the WLAN DAL will pack and send a HAL Config BSS request
        message to the lower RIVA sub-system if DAL is in state
        STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_JoinReq must have been called.

 @param wdiConfigBSSParams: the config BSS parameters as
                      specified by the Device Interface

        wdiConfigBSSRspCb: callback for passing back the
        response of the config BSS operation received from the
        device

        pUserData: user data will be passed back with the
        callback

 @see WDI_JoinReq
 @return Result of the function call
*/
WDI_Status
WDI_ConfigBSSReq
(
  WDI_ConfigBSSReqParamsType* pwdiConfigBSSParams,
  WDI_ConfigBSSRspCb          wdiConfigBSSRspCb,
  void*                       pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_CONFIG_BSS_REQ;
  wdiEventData.pEventData      = pwdiConfigBSSParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiConfigBSSParams);
  wdiEventData.pCBfnc          = wdiConfigBSSRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_ConfigBSSReq*/

/**
 @brief WDI_DelBSSReq will be called when the upper MAC is
        disassociating from the BSS and wishes to notify HW.
        Upon the call of this API the WLAN DAL will pack and
        send a HAL Del BSS request message to the lower RIVA
        sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_ConfigBSSReq or WDI_PostAssocReq must have been called.

 @param wdiDelBSSParams: the del BSS parameters as specified by
                      the Device Interface

        wdiDelBSSRspCb: callback for passing back the response
        of the del bss operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_ConfigBSSReq, WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_DelBSSReq
(
  WDI_DelBSSReqParamsType* pwdiDelBSSParams,
  WDI_DelBSSRspCb          wdiDelBSSRspCb,
  void*                    pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_DEL_BSS_REQ;
  wdiEventData.pEventData      = pwdiDelBSSParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiDelBSSParams);
  wdiEventData.pCBfnc          = wdiDelBSSRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_DelBSSReq*/

/**
 @brief WDI_PostAssocReq will be called when the upper MAC has
        associated to a BSS and wishes to configure HW for
        associated state. Upon the call of this API the WLAN DAL
        will pack and send a HAL Post Assoc request message to
        the lower RIVA sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_JoinReq must have been called.

 @param wdiPostAssocReqParams: the assoc parameters as specified
                      by the Device Interface

        wdiPostAssocRspCb: callback for passing back the
        response of the post assoc operation received from the
        device

        pUserData: user data will be passed back with the
        callback

 @see WDI_JoinReq
 @return Result of the function call
*/
WDI_Status
WDI_PostAssocReq
(
  WDI_PostAssocReqParamsType* pwdiPostAssocReqParams,
  WDI_PostAssocRspCb          wdiPostAssocRspCb,
  void*                       pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_POST_ASSOC_REQ;
  wdiEventData.pEventData      = pwdiPostAssocReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiPostAssocReqParams);
  wdiEventData.pCBfnc          = wdiPostAssocRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_PostAssocReq*/

/**
 @brief WDI_DelSTAReq will be called when the upper MAC when an
        association with another STA has ended and the station
        must be deleted from HW. Upon the call of this API the
        WLAN DAL will pack and send a HAL Del STA request
        message to the lower RIVA sub-system if DAL is in state
        STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_PostAssocReq must have been called.

 @param wdiDelSTAParams: the Del STA parameters as specified by
                      the Device Interface

        wdiDelSTARspCb: callback for passing back the response
        of the del STA operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_DelSTAReq
(
  WDI_DelSTAReqParamsType* pwdiDelSTAParams,
  WDI_DelSTARspCb          wdiDelSTARspCb,
  void*                    pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_DEL_STA_REQ;
  wdiEventData.pEventData      = pwdiDelSTAParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiDelSTAParams);
  wdiEventData.pCBfnc          = wdiDelSTARspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_DelSTAReq*/

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

                             SECURITY APIs

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

/**
 @brief WDI_SetBSSKeyReq will be called when the upper MAC wants to
        install a BSS encryption key on the HW. Upon the call of this
        API the WLAN DAL will pack and send a Set BSS Key request
        message to the lower RIVA sub-system if DAL is in state
        STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_PostAssocReq must have been called.

 @param wdiSetBSSKeyParams: the BSS Key set parameters as
                      specified by the Device Interface

        wdiSetBSSKeyRspCb: callback for passing back the
        response of the set BSS Key operation received from the
        device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_SetBSSKeyReq
(
  WDI_SetBSSKeyReqParamsType* pwdiSetBSSKeyParams,
  WDI_SetBSSKeyRspCb          wdiSetBSSKeyRspCb,
  void*                       pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_SET_BSS_KEY_REQ;
  wdiEventData.pEventData      = pwdiSetBSSKeyParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiSetBSSKeyParams);
  wdiEventData.pCBfnc          = wdiSetBSSKeyRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_SetBSSKeyReq*/

/**
 @brief WDI_RemoveBSSKeyReq will be called when the upper MAC wants to
        uninstall a BSS key from HW. Upon the call of this API the
        WLAN DAL will pack and send a HAL Remove BSS Key request
        message to the lower RIVA sub-system if DAL is in state
        STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_SetBSSKeyReq must have been called.

 @param wdiRemoveBSSKeyParams: the remove BSS key parameters as
                      specified by the Device Interface

        wdiRemoveBSSKeyRspCb: callback for passing back the
        response of the remove BSS key operation received from
        the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_SetBSSKeyReq
 @return Result of the function call
*/
WDI_Status
WDI_RemoveBSSKeyReq
(
  WDI_RemoveBSSKeyReqParamsType* pwdiRemoveBSSKeyParams,
  WDI_RemoveBSSKeyRspCb          wdiRemoveBSSKeyRspCb,
  void*                          pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_RMV_BSS_KEY_REQ;
  wdiEventData.pEventData      = pwdiRemoveBSSKeyParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiRemoveBSSKeyParams);
  wdiEventData.pCBfnc          = wdiRemoveBSSKeyRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_RemoveBSSKeyReq*/


/**
 @brief WDI_SetSTAKeyReq will be called when the upper MAC is
        ready to install a STA(ast) encryption key in HW. Upon
        the call of this API the WLAN DAL will pack and send a
        HAL Set STA Key request message to the lower RIVA
        sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_PostAssocReq must have been called.

 @param wdiSetSTAKeyParams: the set STA key parameters as
                      specified by the Device Interface

        wdiSetSTAKeyRspCb: callback for passing back the
        response of the set STA key operation received from the
        device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_SetSTAKeyReq
(
  WDI_SetSTAKeyReqParamsType* pwdiSetSTAKeyParams,
  WDI_SetSTAKeyRspCb          wdiSetSTAKeyRspCb,
  void*                       pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_SET_STA_KEY_REQ;
  wdiEventData.pEventData      = pwdiSetSTAKeyParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiSetSTAKeyParams);
  wdiEventData.pCBfnc          = wdiSetSTAKeyRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_SetSTAKeyReq*/


/**
 @brief WDI_RemoveSTAKeyReq will be called when the upper MAC
        wants to uninstall a previously set STA key in HW. Upon
        the call of this API the WLAN DAL will pack and send a
        HAL Remove STA Key request message to the lower RIVA
        sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_SetSTAKeyReq must have been called.

 @param wdiRemoveSTAKeyParams: the remove STA key parameters as
                      specified by the Device Interface

        wdiRemoveSTAKeyRspCb: callback for passing back the
        response of the remove STA key operation received from
        the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_SetSTAKeyReq
 @return Result of the function call
*/
WDI_Status
WDI_RemoveSTAKeyReq
(
  WDI_RemoveSTAKeyReqParamsType* pwdiRemoveSTAKeyParams,
  WDI_RemoveSTAKeyRspCb          wdiRemoveSTAKeyRspCb,
  void*                          pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_RMV_STA_KEY_REQ;
  wdiEventData.pEventData      = pwdiRemoveSTAKeyParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiRemoveSTAKeyParams);
  wdiEventData.pCBfnc          = wdiRemoveSTAKeyRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_RemoveSTAKeyReq*/


/**
 @brief WDI_SetSTABcastKeyReq will be called when the upper MAC
        wants to install a STA Bcast encryption key on the HW.
        Upon the call of this API the WLAN DAL will pack and
        send a HAL Start request message to the lower RIVA
        sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_PostAssocReq must have been called.

 @param pwdiSetSTABcastKeyParams: the BSS Key set parameters as
                      specified by the Device Interface

        wdiSetSTABcastKeyRspCb: callback for passing back the
        response of the set BSS Key operation received from the
        device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_SetSTABcastKeyReq
(
  WDI_SetSTAKeyReqParamsType* pwdiSetSTABcastKeyParams,
  WDI_SetSTAKeyRspCb          wdiSetSTABcastKeyRspCb,
  void*                       pUserData
)

{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_SET_STA_BCAST_KEY_REQ;
  wdiEventData.pEventData      = pwdiSetSTABcastKeyParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiSetSTABcastKeyParams);
  wdiEventData.pCBfnc          = wdiSetSTABcastKeyRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_SetSTABcastKeyReq*/

/**
 @brief WDI_RemoveSTABcastKeyReq will be called when the upper
        MAC wants to uninstall a STA Bcast key from HW. Upon the
        call of this API the WLAN DAL will pack and send a HAL
        Remove STA Bcast Key request message to the lower RIVA
        sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_SetSTABcastKeyReq must have been called.

 @param pwdiRemoveSTABcastKeyParams: the remove BSS key
                      parameters as specified by the Device
                      Interface

        wdiRemoveSTABcastKeyRspCb: callback for passing back the
        response of the remove STA Bcast key operation received
        from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_SetSTABcastKeyReq
 @return Result of the function call
*/
WDI_Status
WDI_RemoveSTABcastKeyReq
(
  WDI_RemoveSTAKeyReqParamsType* pwdiRemoveSTABcastKeyParams,
  WDI_RemoveSTAKeyRspCb          wdiRemoveSTABcastKeyRspCb,
  void*                          pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_RMV_STA_BCAST_KEY_REQ;
  wdiEventData.pEventData      = pwdiRemoveSTABcastKeyParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiRemoveSTABcastKeyParams);
  wdiEventData.pCBfnc          = wdiRemoveSTABcastKeyRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_RemoveSTABcastKeyReq*/

/**
 @brief WDI_SetMaxTxPowerReq will be called when the upper
        MAC wants to set Max Tx Power to HW. Upon the
        call of this API the WLAN DAL will pack and send a HAL
        Remove STA Bcast Key request message to the lower RIVA
        sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_SetSTABcastKeyReq must have been called.

 @param pwdiRemoveSTABcastKeyParams: the remove BSS key
                      parameters as specified by the Device
                      Interface

        wdiRemoveSTABcastKeyRspCb: callback for passing back the
        response of the remove STA Bcast key operation received
        from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_SetMaxTxPowerReq
 @return Result of the function call
*/
WDI_Status
WDI_SetMaxTxPowerReq
(
  WDI_SetMaxTxPowerParamsType*   pwdiSetMaxTxPowerParams,
  WDA_SetMaxTxPowerRspCb         wdiReqStatusCb,
  void*                          pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_SET_MAX_TX_POWER_REQ;
  wdiEventData.pEventData      = pwdiSetMaxTxPowerParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiSetMaxTxPowerParams);
  wdiEventData.pCBfnc          = wdiReqStatusCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief WDI_SetMaxTxPowerPerBandReq will be called when the upper
        MAC wants to set Max Tx Power to HW for specific band.

 @param pwdiSetMaxTxPowerPerBandParams: Tx Power Information

        wdiReqStatusCb: callback for passing back the
        response msg from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_SetMaxTxPowerPerBandReq
 @return Result of the function call
*/
WDI_Status
WDI_SetMaxTxPowerPerBandReq
(
  WDI_SetMaxTxPowerPerBandParamsType*   pwdiSetMaxTxPowerPerBandParams,
  WDA_SetMaxTxPowerPerBandRspCb         wdiReqStatusCb,
  void*                          pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_SET_MAX_TX_POWER_PER_BAND_REQ;
  wdiEventData.pEventData      = pwdiSetMaxTxPowerPerBandParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiSetMaxTxPowerPerBandParams);
  wdiEventData.pCBfnc          = wdiReqStatusCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief WDI_SetTxPowerReq will be called when the upper
        MAC wants to set Tx Power to HW.
        In state BUSY this request will be queued. Request won't
        be allowed in any other state.


 @param pwdiSetTxPowerParams: set TS Power parameters
           BSSID and target TX Power with dbm included

        wdiReqStatusCb: callback for passing back the response

        pUserData: user data will be passed back with the
        callback

 @return Result of the function call
*/
WDI_Status
WDI_SetTxPowerReq
(
  WDI_SetTxPowerParamsType*   pwdiSetTxPowerParams,
  WDA_SetTxPowerRspCb         wdiReqStatusCb,
  void*                       pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_SET_TX_POWER_REQ;
  wdiEventData.pEventData      = pwdiSetTxPowerParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiSetTxPowerParams);
  wdiEventData.pCBfnc          = wdiReqStatusCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

#ifdef FEATURE_WLAN_ESE
WDI_Status
WDI_TSMStatsReq
(
   WDI_TSMStatsReqParamsType*        pwdiTsmReqParams,
   WDI_TsmRspCb                 wdiReqStatusCb,
   void*                        pUserData
)
{
  WDI_EventInfoType wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  /*------------------------------------------------------------------------
    Sanity Check 
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED; 
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_TSM_STATS_REQ;
  wdiEventData.pEventData      = pwdiTsmReqParams; 
  wdiEventData.uEventDataSize  = sizeof(*pwdiTsmReqParams); 
  wdiEventData.pCBfnc          = wdiReqStatusCb; 
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}
#endif

/*======================================================================== 
 
                            QoS and BA APIs

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

/**
 @brief WDI_AddTSReq will be called when the upper MAC to inform
        the device of a successful add TSpec negotiation. HW
        needs to receive the TSpec Info from the UMAC in order
        to configure properly the QoS data traffic. Upon the
        call of this API the WLAN DAL will pack and send a HAL
        Add TS request message to the lower RIVA sub-system if
        DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_PostAssocReq must have been called.

 @param wdiAddTsReqParams: the add TS parameters as specified by
                      the Device Interface

        wdiAddTsRspCb: callback for passing back the response of
        the add TS operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_AddTSReq
(
  WDI_AddTSReqParamsType* pwdiAddTsReqParams,
  WDI_AddTsRspCb          wdiAddTsRspCb,
  void*                   pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_ADD_TS_REQ;
  wdiEventData.pEventData      = pwdiAddTsReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiAddTsReqParams);
  wdiEventData.pCBfnc          = wdiAddTsRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_AddTSReq*/



/**
 @brief WDI_DelTSReq will be called when the upper MAC has ended
        admission on a specific AC. This is to inform HW that
        QoS traffic parameters must be rest. Upon the call of
        this API the WLAN DAL will pack and send a HAL Del TS
        request message to the lower RIVA sub-system if DAL is
        in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_AddTSReq must have been called.

 @param wdiDelTsReqParams: the del TS parameters as specified by
                      the Device Interface

        wdiDelTsRspCb: callback for passing back the response of
        the del TS operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_AddTSReq
 @return Result of the function call
*/
WDI_Status
WDI_DelTSReq
(
  WDI_DelTSReqParamsType* pwdiDelTsReqParams,
  WDI_DelTsRspCb          wdiDelTsRspCb,
  void*                   pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_DEL_TS_REQ;
  wdiEventData.pEventData      = pwdiDelTsReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiDelTsReqParams);
  wdiEventData.pCBfnc          = wdiDelTsRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_DelTSReq*/



/**
 @brief WDI_UpdateEDCAParams will be called when the upper MAC
        wishes to update the EDCA parameters used by HW for QoS
        data traffic. Upon the call of this API the WLAN DAL
        will pack and send a HAL Update EDCA Params request
        message to the lower RIVA sub-system if DAL is in state
        STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_PostAssocReq must have been called.

 @param wdiUpdateEDCAParams: the start parameters as specified
                      by the Device Interface

        wdiUpdateEDCAParamsRspCb: callback for passing back the
        response of the start operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_UpdateEDCAParams
(
  WDI_UpdateEDCAParamsType*    pwdiUpdateEDCAParams,
  WDI_UpdateEDCAParamsRspCb    wdiUpdateEDCAParamsRspCb,
  void*                        pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_UPD_EDCA_PRMS_REQ;
  wdiEventData.pEventData      = pwdiUpdateEDCAParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiUpdateEDCAParams);
  wdiEventData.pCBfnc          = wdiUpdateEDCAParamsRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_UpdateEDCAParams*/


/**
 @brief WDI_AddBASessionReq will be called when the upper MAC has setup
        successfully a BA session and needs to notify the HW for
        the appropriate settings to take place. Upon the call of
        this API the WLAN DAL will pack and send a HAL Add BA
        request message to the lower RIVA sub-system if DAL is
        in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_PostAssocReq must have been called.

 @param wdiAddBAReqParams: the add BA parameters as specified by
                      the Device Interface

        wdiAddBARspCb: callback for passing back the response of
        the add BA operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_AddBASessionReq
(
  WDI_AddBASessionReqParamsType* pwdiAddBASessionReqParams,
  WDI_AddBASessionRspCb          wdiAddBASessionRspCb,
  void*                          pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_ADD_BA_SESSION_REQ;
  wdiEventData.pEventData      = pwdiAddBASessionReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiAddBASessionReqParams);
  wdiEventData.pCBfnc          = wdiAddBASessionRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_AddBASessionReq*/

/**
 @brief WDI_DelBAReq will be called when the upper MAC wants to
        inform HW that it has deleted a previously created BA
        session. Upon the call of this API the WLAN DAL will
        pack and send a HAL Del BA request message to the lower
        RIVA sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_AddBAReq must have been called.

 @param wdiDelBAReqParams: the del BA parameters as specified by
                      the Device Interface

        wdiDelBARspCb: callback for passing back the response of
        the del BA operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_AddBAReq
 @return Result of the function call
*/
WDI_Status
WDI_DelBAReq
(
  WDI_DelBAReqParamsType* pwdiDelBAReqParams,
  WDI_DelBARspCb          wdiDelBARspCb,
  void*                   pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_DEL_BA_REQ;
  wdiEventData.pEventData      = pwdiDelBAReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiDelBAReqParams);
  wdiEventData.pCBfnc          = wdiDelBARspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_DelBAReq*/

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

                            Power Save APIs

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

/**
 @brief WDI_SetPwrSaveCfgReq will be called when the upper MAC
        wants to set the power save related configurations of
        the WLAN Device. Upon the call of this API the WLAN DAL
        will pack and send a HAL Update CFG request message to
        the lower RIVA sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_Start must have been called.

 @param pwdiPowerSaveCfg: the power save cfg parameters as
                      specified by the Device Interface

        wdiSetPwrSaveCfgCb: callback for passing back the
        response of the set power save cfg operation received
        from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_Start
 @return Result of the function call
*/
WDI_Status
WDI_SetPwrSaveCfgReq
(
  WDI_UpdateCfgReqParamsType*   pwdiPowerSaveCfg,
  WDI_SetPwrSaveCfgCb     wdiSetPwrSaveCfgCb,
  void*                   pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_UPDATE_CFG_REQ;
  wdiEventData.pEventData      = pwdiPowerSaveCfg;
  wdiEventData.uEventDataSize  = sizeof(*pwdiPowerSaveCfg);
  wdiEventData.pCBfnc          = wdiSetPwrSaveCfgCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_SetPwrSaveCfgReq*/

/**
 @brief WDI_EnterImpsReq will be called when the upper MAC to
        request the device to get into IMPS power state. Upon
        the call of this API the WLAN DAL will send a HAL Enter
        IMPS request message to the lower RIVA sub-system if DAL
        is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.


 @param wdiEnterImpsRspCb: callback for passing back the
        response of the Enter IMPS operation received from the
        device

        pUserData: user data will be passed back with the
        callback

 @see WDI_Start
 @return Result of the function call
*/
WDI_Status
WDI_EnterImpsReq
(
   WDI_EnterImpsReqParamsType *pwdiEnterImpsReqParams,
   WDI_EnterImpsRspCb  wdiEnterImpsRspCb,
   void*                   pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_ENTER_IMPS_REQ;
  wdiEventData.pEventData      = pwdiEnterImpsReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiEnterImpsReqParams);
  wdiEventData.pCBfnc          = wdiEnterImpsRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_EnterImpsReq*/

/**
 @brief WDI_ExitImpsReq will be called when the upper MAC to
        request the device to get out of IMPS power state. Upon
        the call of this API the WLAN DAL will send a HAL Exit
        IMPS request message to the lower RIVA sub-system if DAL
        is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.



 @param wdiExitImpsRspCb: callback for passing back the response
        of the Exit IMPS operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_Start
 @return Result of the function call
*/
WDI_Status
WDI_ExitImpsReq
(
   WDI_ExitImpsReqParamsType *pwdiExitImpsReqParams,
   WDI_ExitImpsRspCb  wdiExitImpsRspCb,
   void*                   pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_EXIT_IMPS_REQ;
  wdiEventData.pEventData      = pwdiExitImpsReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiExitImpsReqParams);
  wdiEventData.pCBfnc          = wdiExitImpsRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_ExitImpsReq*/

/**
 @brief WDI_EnterBmpsReq will be called when the upper MAC to
        request the device to get into BMPS power state. Upon
        the call of this API the WLAN DAL will pack and send a
        HAL Enter BMPS request message to the lower RIVA
        sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_PostAssocReq must have been called.

 @param pwdiEnterBmpsReqParams: the Enter BMPS parameters as
                      specified by the Device Interface

        wdiEnterBmpsRspCb: callback for passing back the
        response of the Enter BMPS operation received from the
        device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_EnterBmpsReq
(
   WDI_EnterBmpsReqParamsType *pwdiEnterBmpsReqParams,
   WDI_EnterBmpsRspCb  wdiEnterBmpsRspCb,
   void*                   pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_ENTER_BMPS_REQ;
  wdiEventData.pEventData      = pwdiEnterBmpsReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiEnterBmpsReqParams);
  wdiEventData.pCBfnc          = wdiEnterBmpsRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_EnterBmpsReq*/

/**
 @brief WDI_ExitBmpsReq will be called when the upper MAC to
        request the device to get out of BMPS power state. Upon
        the call of this API the WLAN DAL will pack and send a
        HAL Exit BMPS request message to the lower RIVA
        sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_PostAssocReq must have been called.

 @param pwdiExitBmpsReqParams: the Exit BMPS parameters as
                      specified by the Device Interface

        wdiExitBmpsRspCb: callback for passing back the response
        of the Exit BMPS operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_ExitBmpsReq
(
   WDI_ExitBmpsReqParamsType *pwdiExitBmpsReqParams,
   WDI_ExitBmpsRspCb  wdiExitBmpsRspCb,
   void*                   pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_EXIT_BMPS_REQ;
  wdiEventData.pEventData      = pwdiExitBmpsReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiExitBmpsReqParams);
  wdiEventData.pCBfnc          = wdiExitBmpsRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_ExitBmpsReq*/

/**
 @brief WDI_EnterUapsdReq will be called when the upper MAC to
        request the device to get into UAPSD power state. Upon
        the call of this API the WLAN DAL will pack and send a
        HAL Enter UAPSD request message to the lower RIVA
        sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_PostAssocReq must have been called.
 WDI_SetUapsdAcParamsReq must have been called.

 @param pwdiEnterUapsdReqParams: the Enter UAPSD parameters as
                      specified by the Device Interface

        wdiEnterUapsdRspCb: callback for passing back the
        response of the Enter UAPSD operation received from the
        device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq, WDI_SetUapsdAcParamsReq
 @return Result of the function call
*/
WDI_Status
WDI_EnterUapsdReq
(
   WDI_EnterUapsdReqParamsType *pwdiEnterUapsdReqParams,
   WDI_EnterUapsdRspCb  wdiEnterUapsdRspCb,
   void*                   pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_ENTER_UAPSD_REQ;
  wdiEventData.pEventData      = pwdiEnterUapsdReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiEnterUapsdReqParams);
  wdiEventData.pCBfnc          = wdiEnterUapsdRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_EnterUapsdReq*/

/**
 @brief WDI_ExitUapsdReq will be called when the upper MAC to
        request the device to get out of UAPSD power state. Upon
        the call of this API the WLAN DAL will send a HAL Exit
        UAPSD request message to the lower RIVA sub-system if
        DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_PostAssocReq must have been called.

 @param wdiExitUapsdRspCb: callback for passing back the
        response of the Exit UAPSD operation received from the
        device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_ExitUapsdReq
(
   WDI_ExitUapsdReqParamsType *pwdiExitUapsdReqParams,
   WDI_ExitUapsdRspCb  wdiExitUapsdRspCb,
   void*                   pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_EXIT_UAPSD_REQ;
  wdiEventData.pEventData      = pwdiExitUapsdReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiExitUapsdReqParams);
  wdiEventData.pCBfnc          = wdiExitUapsdRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_ExitUapsdReq*/

/**
 @brief WDI_UpdateUapsdParamsReq will be called when the upper
        MAC wants to set the UAPSD related configurations
        of an associated STA (while acting as an AP) to the WLAN
        Device. Upon the call of this API the WLAN DAL will pack
        and send a HAL Update UAPSD params request message to
        the lower RIVA sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_ConfigBSSReq must have been called.

 @param pwdiUpdateUapsdReqParams: the UAPSD parameters
                      as specified by the Device Interface

        wdiUpdateUapsdParamsCb: callback for passing back the
        response of the update UAPSD params operation received
        from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_ConfigBSSReq
 @return Result of the function call
*/
WDI_Status
WDI_UpdateUapsdParamsReq
(
   WDI_UpdateUapsdReqParamsType *pwdiUpdateUapsdReqParams,
   WDI_UpdateUapsdParamsCb  wdiUpdateUapsdParamsCb,
   void*                   pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_UPDATE_UAPSD_PARAM_REQ;
  wdiEventData.pEventData      = pwdiUpdateUapsdReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiUpdateUapsdReqParams);
  wdiEventData.pCBfnc          = wdiUpdateUapsdParamsCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_UpdateUapsdParamsReq*/

/**
 @brief WDI_SetUapsdAcParamsReq will be called when the upper
        MAC wants to set the UAPSD related configurations before
        requesting for enter UAPSD power state to the WLAN
        Device. Upon the call of this API the WLAN DAL will pack
        and send a HAL Set UAPSD params request message to
        the lower RIVA sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_PostAssocReq must have been called.

 @param pwdiUapsdInfo: the UAPSD parameters as specified by
                      the Device Interface

        wdiSetUapsdAcParamsCb: callback for passing back the
        response of the set UAPSD params operation received from
        the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_SetUapsdAcParamsReq
(
  WDI_SetUapsdAcParamsReqParamsType*      pwdiUapsdInfo,
  WDI_SetUapsdAcParamsCb  wdiSetUapsdAcParamsCb,
  void*                   pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_SET_UAPSD_PARAM_REQ;
  wdiEventData.pEventData      = pwdiUapsdInfo;
  wdiEventData.uEventDataSize  = sizeof(*pwdiUapsdInfo);
  wdiEventData.pCBfnc          = wdiSetUapsdAcParamsCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_SetUapsdAcParamsReq*/

/**
 @brief WDI_FWLoggingDXEdoneInd

        FW Logging DXE done Indication from the upper layer will be sent
        down to HAL

 @param WDI_FWLoggingDXEdoneIndInfoType

 @see

 @return Status of the request
*/
WDI_Status
WDI_FWLoggingDXEdoneInd
(
  wpt_uint32    data
)
{

  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_FW_LOGGING_DXE_DONE_IND;
  wdiEventData.pEventData      = (void *)&data;
  wdiEventData.uEventDataSize  = sizeof(wpt_uint32);
  wdiEventData.pCBfnc          = NULL;
  wdiEventData.pUserData       = NULL;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_FWLoggingDXEdoneInd*/

/**
 @brief WDI_GetFrameLogReq will be called when the upper
        MAC wants to initialize frame logging. Upon the call of
        this API the WLAN DAL will pack and send a HAL
        Frame logging init request message to
        the lower RIVA sub-system.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.


 @param pwdiGetFrameLogReqInfo: the Frame Logging params
                      as specified by the Device Interface

        wdiGetFrameLogRspCb: callback for passing back the
        response of the frame logging init operation received
        from the device

        pUserData: user data will be passed back with the
        callback

 @return Result of the function call
*/
WDI_Status
WDI_GetFrameLogReq
(
   WDI_GetFrameLogReqInfoType    *pwdiGetFrameLogReqInfo,
   WDI_GetFrameLogRspCb             wdiGetFrameLogRspCb,
   void*                                pUserData
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_GET_FRAME_LOG_REQ;
   wdiEventData.pEventData      = pwdiGetFrameLogReqInfo;
   wdiEventData.uEventDataSize  = sizeof(*pwdiGetFrameLogReqInfo);
   wdiEventData.pCBfnc          = wdiGetFrameLogRspCb;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}


/**
 @brief WDI_FatalEventLogsReq will be called when the upper
        MAC wants to send the flush command. Upon the call of
        this API the WLAN DAL will pack and send a HAL
        Fatal Event Req message to the lower RIVA sub-system.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.


 @param pwdiFlushLogsReqInfo: the Flush Logs params
                      as specified by the Device Interface

        wdiFlushLogsRspCb: callback for passing back the
        response of the Flush Logs operation received
        from the device

        pUserData: user data will be passed back with the
        callback

 @return Result of the function call
*/

WDI_Status
WDI_FatalEventLogsReq
(
   WDI_FatalEventLogsReqInfoType      *pwdiFatalEventLogsReqInfo,
   WDI_FatalEventLogsRspCb             wdiFatalEventLogsRspCb,
   void*                               pUserData
)
{
    WDI_EventInfoType      wdiEventData;

    /*------------------------------------------------------------------------
      Sanity Check
    ------------------------------------------------------------------------*/
    if ( eWLAN_PAL_FALSE == gWDIInitialized )
    {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                "WDI API call before module is initialized - Fail request");

      return WDI_STATUS_E_NOT_ALLOWED;
    }

    /*------------------------------------------------------------------------
      Fill in Event data and post to the Main FSM
    ------------------------------------------------------------------------*/
    wdiEventData.wdiRequest      = WDI_FATAL_EVENT_LOGGING_REQ;
    wdiEventData.pEventData      = pwdiFatalEventLogsReqInfo;
    wdiEventData.uEventDataSize  = sizeof(*pwdiFatalEventLogsReqInfo);
    wdiEventData.pCBfnc          = wdiFatalEventLogsRspCb;
    wdiEventData.pUserData       = pUserData;

    return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}


/**
 @brief WDI_FWLoggingInitReq will be called when the upper
        MAC wants to initialize frame logging. Upon the call of
        this API the WLAN DAL will pack and send a HAL
        Frame logging init request message to
        the lower RIVA sub-system.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.


 @param pwdiFWLoggingInitReqParams: the Frame Logging params
                      as specified by the Device Interface

        wdiFWLoggingInitReqCb: callback for passing back the
        response of the frame logging init operation received
        from the device

        pUserData: user data will be passed back with the
        callback

 @return Result of the function call
*/
WDI_Status
WDI_FWLoggingInitReq
(
   WDI_FWLoggingInitReqInfoType         *pwdiFWLoggingInitReqInfo,
   WDI_FWLoggingInitRspCb               wdiFWLoggingInitRspCb,
   void*                                pUserData
)
{
   WDI_EventInfoType      wdiEventData;

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_FW_LOGGING_INIT_REQ;
   wdiEventData.pEventData      = pwdiFWLoggingInitReqInfo;
   wdiEventData.uEventDataSize  = sizeof(*pwdiFWLoggingInitReqInfo);
   wdiEventData.pCBfnc          = wdiFWLoggingInitRspCb;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}


/**
 @brief WDI_FwrMemDumpReq will be called when the upper
        MAC wants to get fwr mem dump. Upon the call of
        this API the WLAN DAL will pack and send a HAL
        Frame logging init request message to
        the lower RIVA sub-system.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.


 @param pWdiFwrMemDumpReq: the fwr mem dump req params
                      as specified by the Device Interface

        wdiFWLoggingInitReqCb: callback for passing back the
        response of the frame logging init operation received
        from the device

        pUserData: user data will be passed back with the
        callback

 @return Result of the function call
*/

WDI_Status
WDI_FwrMemDumpReq

(
   WDI_FwrMemDumpReqType          *pwdiFwrMemDumpReqInfo,
   WDI_FwrMemDumpCb                wdiFwrMemDumpRspCb,
   void*                           pUserData
)
{
   WDI_EventInfoType      wdiEventData;

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_FWR_MEM_DUMP_REQ;
   wdiEventData.pEventData      = pwdiFwrMemDumpReqInfo;
   wdiEventData.uEventDataSize  = sizeof(WDI_FwrMemDumpReqType);
   wdiEventData.pCBfnc          = wdiFwrMemDumpRspCb;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}



/**
 @brief WDI_StartRssiMonitorReq will be called when the upper
        MAC wants to initialize Rssi Monitor on a bssid.
        Upon the call of this API the WLAN DAL will pack and
        send a HAL Rssi Monitor init request message to
        the lower RIVA sub-system.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.


 @param pwdiRssiMonitorInfo: the Rssi Monitor params
                      as specified by the Device Interface

        wdiRssiMonitorStartRspCb: callback for passing back the
        response of the rssi monitor operation received
        from the device

        pUserData: user data will be passed back with the
        callback

 @return Result of the function call
*/
WDI_Status
WDI_StartRssiMonitorReq
(
   WDI_RssiMonitorReqInfoType          *pwdiRssiMonitorInfo,
   WDI_RssiMonitorStartRspCb            wdiRssiMonitorStartRspCb,
   void*                                pUserData
)
{
   WDI_EventInfoType      wdiEventData;

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_START_RSSI_MONITOR_REQ;
   wdiEventData.pEventData      = pwdiRssiMonitorInfo;
   wdiEventData.uEventDataSize  = sizeof(*pwdiRssiMonitorInfo);
   wdiEventData.pCBfnc          = wdiRssiMonitorStartRspCb;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief WDI_StopRssiMonitorReq will be called when the upper
        MAC wants to stop Rssi Monitor on a bssid.
        Upon the call of this API the WLAN DAL will pack and
        send a HAL Rssi Monitor stop request message to
        the lower RIVA sub-system.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.


 @param pwdiRssiMonitorInfo: the Rssi Monitor params
                      as specified by the Device Interface

        wdiRssiMonitorStopRspCb: callback for passing back the
        response of the rssi monitor operation received
        from the device

        pUserData: user data will be passed back with the
        callback

 @return Result of the function call
*/
WDI_Status
WDI_StopRssiMonitorReq
(
   WDI_RssiMonitorReqInfoType          *pwdiRssiMonitorInfo,
   WDI_RssiMonitorStopRspCb            wdiRssiMonitorStopRspCb,
   void*                               pUserData
)
{
   WDI_EventInfoType      wdiEventData;

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_STOP_RSSI_MONITOR_REQ;
   wdiEventData.pEventData      = pwdiRssiMonitorInfo;
   wdiEventData.uEventDataSize  = sizeof(*pwdiRssiMonitorInfo);
   wdiEventData.pCBfnc          = wdiRssiMonitorStopRspCb;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}


/**
 @brief WDI_ConfigureRxpFilterReq will be called when the upper
        MAC wants to set/reset the RXP filters for received pkts
        (MC, BC etc.). Upon the call of this API the WLAN DAL will pack
        and send a HAL configure RXP filter request message to
        the lower RIVA sub-system.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.


 @param pwdiConfigureRxpFilterReqParams: the RXP
                      filter as specified by the Device
                      Interface

        wdiConfigureRxpFilterCb: callback for passing back the
        response of the configure RXP filter operation received
        from the device

        pUserData: user data will be passed back with the
        callback

 @return Result of the function call
*/
WDI_Status
WDI_ConfigureRxpFilterReq
(
   WDI_ConfigureRxpFilterReqParamsType *pwdiConfigureRxpFilterReqParams,
   WDI_ConfigureRxpFilterCb             wdiConfigureRxpFilterCb,
   void*                                pUserData
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_CONFIGURE_RXP_FILTER_REQ;
   wdiEventData.pEventData      = pwdiConfigureRxpFilterReqParams;
   wdiEventData.uEventDataSize  = sizeof(*pwdiConfigureRxpFilterReqParams);
   wdiEventData.pCBfnc          = wdiConfigureRxpFilterCb;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}/*WDI_ConfigureRxpFilterReq*/

/**
 @brief WDI_SetBeaconFilterReq will be called when the upper MAC
        wants to set the beacon filters while in power save.
        Upon the call of this API the WLAN DAL will pack and
        send a Beacon filter request message to the
        lower RIVA sub-system.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.


 @param pwdiBeaconFilterReqParams: the beacon
                      filter as specified by the Device
                      Interface

        wdiBeaconFilterCb: callback for passing back the
        response of the set beacon filter operation received
        from the device

        pUserData: user data will be passed back with the
        callback

 @return Result of the function call
*/
WDI_Status
WDI_SetBeaconFilterReq
(
   WDI_BeaconFilterReqParamsType   *pwdiBeaconFilterReqParams,
   WDI_SetBeaconFilterCb            wdiBeaconFilterCb,
   void*                            pUserData
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_SET_BEACON_FILTER_REQ;
   wdiEventData.pEventData      = pwdiBeaconFilterReqParams;
   wdiEventData.uEventDataSize  = sizeof(*pwdiBeaconFilterReqParams);
   wdiEventData.pCBfnc          = wdiBeaconFilterCb;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}/*WDI_SetBeaconFilterReq*/

/**
 @brief WDI_RemBeaconFilterReq will be called when the upper MAC
        wants to remove the beacon filter for particular IE
        while in power save. Upon the call of this API the WLAN
        DAL will pack and send a remove Beacon filter request
        message to the lower RIVA sub-system.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.


 @param pwdiBeaconFilterReqParams: the beacon
                      filter as specified by the Device
                      Interface

        wdiBeaconFilterCb: callback for passing back the
        response of the remove beacon filter operation received
        from the device

        pUserData: user data will be passed back with the
        callback

 @return Result of the function call
*/
WDI_Status
WDI_RemBeaconFilterReq
(
   WDI_RemBeaconFilterReqParamsType *pwdiBeaconFilterReqParams,
   WDI_RemBeaconFilterCb             wdiBeaconFilterCb,
   void*                             pUserData
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_REM_BEACON_FILTER_REQ;
   wdiEventData.pEventData      = pwdiBeaconFilterReqParams;
   wdiEventData.uEventDataSize  = sizeof(*pwdiBeaconFilterReqParams);
   wdiEventData.pCBfnc          = wdiBeaconFilterCb;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}/*WDI_RemBeaconFilterReq*/

/**
 @brief WDI_SetRSSIThresholdsReq will be called when the upper
        MAC wants to set the RSSI thresholds related
        configurations while in power save. Upon the call of
        this API the WLAN DAL will pack and send a HAL Set RSSI
        thresholds request message to the lower RIVA
        sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_PostAssocReq must have been called.

 @param pwdiUapsdInfo: the UAPSD parameters as specified by
                      the Device Interface

        wdiSetUapsdAcParamsCb: callback for passing back the
        response of the set UAPSD params operation received from
        the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_SetRSSIThresholdsReq
(
  WDI_SetRSSIThresholdsReqParamsType*      pwdiRSSIThresholdsParams,
  WDI_SetRSSIThresholdsCb                  wdiSetRSSIThresholdsCb,
  void*                                    pUserData
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_SET_RSSI_THRESHOLDS_REQ;
   wdiEventData.pEventData      = pwdiRSSIThresholdsParams;
   wdiEventData.uEventDataSize  = sizeof(*pwdiRSSIThresholdsParams);
   wdiEventData.pCBfnc          = wdiSetRSSIThresholdsCb;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}/* WDI_SetRSSIThresholdsReq*/

/**
 @brief WDI_HostOffloadReq will be called when the upper MAC
        wants to set the filter to minimize unnecessary host
        wakeup due to broadcast traffic while in power save.
        Upon the call of this API the WLAN DAL will pack and
        send a HAL host offload request message to the
        lower RIVA sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_PostAssocReq must have been called.

 @param pwdiHostOffloadParams: the host offload as specified
                      by the Device Interface

        wdiHostOffloadCb: callback for passing back the response
        of the host offload operation received from the
        device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_HostOffloadReq
(
  WDI_HostOffloadReqParamsType*      pwdiHostOffloadParams,
  WDI_HostOffloadCb                  wdiHostOffloadCb,
  void*                              pUserData
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_HOST_OFFLOAD_REQ;
   wdiEventData.pEventData      = pwdiHostOffloadParams;
   wdiEventData.uEventDataSize  = sizeof(*pwdiHostOffloadParams);
   wdiEventData.pCBfnc          = wdiHostOffloadCb;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}/*WDI_HostOffloadReq*/

/**
 @brief WDI_KeepAliveReq will be called when the upper MAC
        wants to set the filter to send NULL or unsolicited ARP responses
        and minimize unnecessary host wakeups due to while in power save.
        Upon the call of this API the WLAN DAL will pack and
        send a HAL Keep Alive request message to the
        lower RIVA sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_PostAssocReq must have been called.

 @param pwdiKeepAliveParams: the Keep Alive as specified
                      by the Device Interface

        wdiKeepAliveCb: callback for passing back the response
        of the Keep Alive operation received from the
        device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_KeepAliveReq
(
  WDI_KeepAliveReqParamsType*        pwdiKeepAliveParams,
  WDI_KeepAliveCb                    wdiKeepAliveCb,
  void*                              pUserData
)
{
    WDI_EventInfoType      wdiEventData;
    /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

    /*------------------------------------------------------------------------
     Sanity Check
    ------------------------------------------------------------------------*/
    if ( eWLAN_PAL_FALSE == gWDIInitialized )
    {
         WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                    "WDI_KeepAliveReq: WDI API call before module "
                    "is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
    }

    /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
    ------------------------------------------------------------------------*/
    wdiEventData.wdiRequest      = WDI_KEEP_ALIVE_REQ;
    wdiEventData.pEventData      = pwdiKeepAliveParams;
    wdiEventData.uEventDataSize  = sizeof(*pwdiKeepAliveParams);
    wdiEventData.pCBfnc          = wdiKeepAliveCb;
    wdiEventData.pUserData       = pUserData;

    return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}/*WDI_KeepAliveReq*/

/**
 @brief WDI_WowlAddBcPtrnReq will be called when the upper MAC
        wants to set the Wowl Bcast ptrn to minimize unnecessary
        host wakeup due to broadcast traffic while in power
        save. Upon the call of this API the WLAN DAL will pack
        and send a HAL Wowl Bcast ptrn request message to the
        lower RIVA sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_PostAssocReq must have been called.

 @param pwdiWowlAddBcPtrnParams: the Wowl bcast ptrn as
                      specified by the Device Interface

        wdiWowlAddBcPtrnCb: callback for passing back the
        response of the add Wowl bcast ptrn operation received
        from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_WowlAddBcPtrnReq
(
  WDI_WowlAddBcPtrnReqParamsType*    pwdiWowlAddBcPtrnParams,
  WDI_WowlAddBcPtrnCb                wdiWowlAddBcPtrnCb,
  void*                              pUserData
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_WOWL_ADD_BC_PTRN_REQ;
   wdiEventData.pEventData      = pwdiWowlAddBcPtrnParams;
   wdiEventData.uEventDataSize  = sizeof(*pwdiWowlAddBcPtrnParams);
   wdiEventData.pCBfnc          = wdiWowlAddBcPtrnCb;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}/*WDI_WowlAddBcPtrnReq*/

/**
 @brief WDI_WowlDelBcPtrnReq will be called when the upper MAC
        wants to clear the Wowl Bcast ptrn. Upon the call of
        this API the WLAN DAL will pack and send a HAL delete
        Wowl Bcast ptrn request message to the lower RIVA
        sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_WowlAddBcPtrnReq must have been called.

 @param pwdiWowlDelBcPtrnParams: the Wowl bcast ptrn as
                      specified by the Device Interface

        wdiWowlDelBcPtrnCb: callback for passing back the
        response of the del Wowl bcast ptrn operation received
        from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_WowlAddBcPtrnReq
 @return Result of the function call
*/
WDI_Status
WDI_WowlDelBcPtrnReq
(
  WDI_WowlDelBcPtrnReqParamsType*    pwdiWowlDelBcPtrnParams,
  WDI_WowlDelBcPtrnCb                wdiWowlDelBcPtrnCb,
  void*                              pUserData
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_WOWL_DEL_BC_PTRN_REQ;
   wdiEventData.pEventData      = pwdiWowlDelBcPtrnParams;
   wdiEventData.uEventDataSize  = sizeof(*pwdiWowlDelBcPtrnParams);
   wdiEventData.pCBfnc          = wdiWowlDelBcPtrnCb;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}/*WDI_WowlDelBcPtrnReq*/

/**
 @brief WDI_WowlEnterReq will be called when the upper MAC
        wants to enter the Wowl state to minimize unnecessary
        host wakeup while in power save. Upon the call of this
        API the WLAN DAL will pack and send a HAL Wowl enter
        request message to the lower RIVA sub-system if DAL is
        in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_PostAssocReq must have been called.

 @param pwdiWowlEnterReqParams: the Wowl enter info as
                      specified by the Device Interface

        wdiWowlEnterReqCb: callback for passing back the
        response of the enter Wowl operation received from the
        device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_WowlEnterReq
(
  WDI_WowlEnterReqParamsType*    pwdiWowlEnterParams,
  WDI_WowlEnterReqCb             wdiWowlEnterCb,
  void*                          pUserData
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_WOWL_ENTER_REQ;
   wdiEventData.pEventData      = pwdiWowlEnterParams;
   wdiEventData.uEventDataSize  = sizeof(*pwdiWowlEnterParams);
   wdiEventData.pCBfnc          = wdiWowlEnterCb;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}/*WDI_WowlEnterReq*/

/**
 @brief WDI_WowlExitReq will be called when the upper MAC
        wants to exit the Wowl state. Upon the call of this API
        the WLAN DAL will pack and send a HAL Wowl exit request
        message to the lower RIVA sub-system if DAL is in state
        STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_WowlEnterReq must have been called.

 @param pwdiWowlExitReqParams: the Wowl exit info as
                      specified by the Device Interface

        wdiWowlExitReqCb: callback for passing back the response
        of the exit Wowl operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_WowlEnterReq
 @return Result of the function call
*/
WDI_Status
WDI_WowlExitReq
(
  WDI_WowlExitReqParamsType*    pwdiWowlExitParams,
  WDI_WowlExitReqCb              wdiWowlExitCb,
  void*                          pUserData
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_WOWL_EXIT_REQ;
   wdiEventData.pEventData      = pwdiWowlExitParams;
   wdiEventData.uEventDataSize  = sizeof(*pwdiWowlExitParams);
   wdiEventData.pCBfnc          = wdiWowlExitCb;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}/*WDI_WowlExitReq*/

/**
 @brief WDI_ConfigureAppsCpuWakeupStateReq will be called when
        the upper MAC wants to dynamically adjusts the listen
        interval based on the WLAN/MSM activity. Upon the call
        of this API the WLAN DAL will pack and send a HAL
        configure Apps Cpu Wakeup State request message to the
        lower RIVA sub-system.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.


 @param pwdiConfigureAppsCpuWakeupStateReqParams: the
                      Apps Cpu Wakeup State as specified by the
                      Device Interface

        wdiConfigureAppsCpuWakeupStateCb: callback for passing
        back the response of the configure Apps Cpu Wakeup State
        operation received from the device

        pUserData: user data will be passed back with the
        callback

 @return Result of the function call
*/
WDI_Status
WDI_ConfigureAppsCpuWakeupStateReq
(
   WDI_ConfigureAppsCpuWakeupStateReqParamsType *pwdiConfigureAppsCpuWakeupStateReqParams,
   WDI_ConfigureAppsCpuWakeupStateCb             wdiConfigureAppsCpuWakeupStateCb,
   void*                                         pUserData
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_REQ;
   wdiEventData.pEventData      = pwdiConfigureAppsCpuWakeupStateReqParams;
   wdiEventData.uEventDataSize  = sizeof(*pwdiConfigureAppsCpuWakeupStateReqParams);
   wdiEventData.pCBfnc          = wdiConfigureAppsCpuWakeupStateCb;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}/*WDI_ConfigureAppsCpuWakeupStateReq*/
/**
 @brief WDI_FlushAcReq will be called when the upper MAC wants
        to to perform a flush operation on a given AC. Upon the
        call of this API the WLAN DAL will pack and send a HAL
        Flush AC request message to the lower RIVA sub-system if
        DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_AddBAReq must have been called.

 @param pwdiFlushAcReqParams: the Flush AC parameters as
                      specified by the Device Interface

        wdiFlushAcRspCb: callback for passing back the response
        of the Flush AC operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_AddBAReq
 @return Result of the function call
*/
WDI_Status
WDI_FlushAcReq
(
  WDI_FlushAcReqParamsType* pwdiFlushAcReqParams,
  WDI_FlushAcRspCb          wdiFlushAcRspCb,
  void*                     pUserData
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_FLUSH_AC_REQ;
   wdiEventData.pEventData      = pwdiFlushAcReqParams;
   wdiEventData.uEventDataSize  = sizeof(*pwdiFlushAcReqParams);
   wdiEventData.pCBfnc          = wdiFlushAcRspCb;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_FlushAcReq*/

/**
 @brief WDI_BtAmpEventReq will be called when the upper MAC
        wants to notify the lower mac on a BT AMP event. This is
        to inform BTC-SLM that some BT AMP event occurred. Upon
        the call of this API the WLAN DAL will pack and send a
        HAL BT AMP event request message to the lower RIVA
        sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.


 @param wdiBtAmpEventReqParams: the BT AMP event parameters as
                      specified by the Device Interface

        wdiBtAmpEventRspCb: callback for passing back the
        response of the BT AMP event operation received from the
        device

        pUserData: user data will be passed back with the
        callback

 @return Result of the function call
*/
WDI_Status
WDI_BtAmpEventReq
(
  WDI_BtAmpEventParamsType* pwdiBtAmpEventReqParams,
  WDI_BtAmpEventRspCb       wdiBtAmpEventRspCb,
  void*                     pUserData
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_BTAMP_EVENT_REQ;
   wdiEventData.pEventData      = pwdiBtAmpEventReqParams;
   wdiEventData.uEventDataSize  = sizeof(*pwdiBtAmpEventReqParams);
   wdiEventData.pCBfnc          = wdiBtAmpEventRspCb;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_BtAmpEventReq*/

#ifdef FEATURE_OEM_DATA_SUPPORT
/**
 @brief WDI_Start Oem Data Req will be called when the upper MAC 
        wants to notify the lower mac on a oem data Req event.Upon
        the call of this API the WLAN DAL will pack and send a
        HAL OEM Data Req event request message to the lower RIVA
        sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.


  
 @param pwdiOemDataReqParams: the Oem Data Req as 
        specified by the Device Interface

        wdiStartOemDataRspCb: callback for passing back the
        response of the Oem Data Req received from the
        device

        pUserData: user data will be passed back with the
        callback

 @return Result of the function call
*/
WDI_Status
WDI_StartOemDataReq
(
  WDI_oemDataReqParamsType*         pwdiOemDataReqParams,
  WDI_oemDataRspCb                  wdiOemDataRspCb,
  void*                             pUserData
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_START_OEM_DATA_REQ;
   wdiEventData.pEventData      = pwdiOemDataReqParams; 
   wdiEventData.uEventDataSize  = sizeof(*pwdiOemDataReqParams); 
   wdiEventData.pCBfnc          = wdiOemDataRspCb; 
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);


}

#endif


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

                             CONTROL APIs

==========================================================================*/
/**
 @brief WDI_SwitchChReq will be called when the upper MAC wants
        the WLAN HW to change the current channel of operation.
        Upon the call of this API the WLAN DAL will pack and
        send a HAL Start request message to the lower RIVA
        sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_Start must have been called.

 @param wdiSwitchChReqParams: the switch ch parameters as
                      specified by the Device Interface

        wdiSwitchChRspCb: callback for passing back the response
        of the switch ch operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_Start
 @return Result of the function call
*/
WDI_Status
WDI_SwitchChReq
(
  WDI_SwitchChReqParamsType* pwdiSwitchChReqParams,
  WDI_SwitchChRspCb          wdiSwitchChRspCb,
  void*                      pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_CH_SWITCH_REQ;
  wdiEventData.pEventData      = pwdiSwitchChReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiSwitchChReqParams);
  wdiEventData.pCBfnc          = wdiSwitchChRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_SwitchChReq*/

/**
 @brief WDI_SwitchChReq_V1 will be called when the upper MAC wants
        the WLAN HW to change the current channel of operation.
        Upon the call of this API the WLAN DAL will pack and
        send a HAL Start request message to the lower RIVA
        sub-system if DAL is in state STARTED.
        This request message also includes source of channel switch,
        like CSA,

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_Start must have been called.

 @param wdiSwitchChReqParams: the switch ch parameters as
                      specified by the Device Interface

        wdiSwitchChRspCb: callback for passing back the response
        of the switch ch operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_Start
 @return Result of the function call
*/
WDI_Status
WDI_SwitchChReq_V1
(
  WDI_SwitchChReqParamsType_V1* pwdiSwitchChReqParams,
  WDI_SwitchChRspCb_V1          wdiSwitchChRspCb,
  void*                      pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
   WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
              "WDI API call WDI_SwitchChReq_V1");
  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_CH_SWITCH_REQ_V1;
  wdiEventData.pEventData      = pwdiSwitchChReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiSwitchChReqParams);
  wdiEventData.pCBfnc          = wdiSwitchChRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_SwitchChReq_V1*/


/**
 @brief WDI_ConfigSTAReq will be called when the upper MAC
        wishes to add or update a STA in HW. Upon the call of
        this API the WLAN DAL will pack and send a HAL Start
        message request message to the lower RIVA sub-system if
        DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_Start must have been called.

 @param wdiConfigSTAReqParams: the config STA parameters as
                      specified by the Device Interface

        wdiConfigSTARspCb: callback for passing back the
        response of the config STA operation received from the
        device

        pUserData: user data will be passed back with the
        callback

 @see WDI_Start
 @return Result of the function call
*/
WDI_Status
WDI_ConfigSTAReq
(
  WDI_ConfigSTAReqParamsType* pwdiConfigSTAReqParams,
  WDI_ConfigSTARspCb          wdiConfigSTARspCb,
  void*                       pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_CONFIG_STA_REQ;
  wdiEventData.pEventData      = pwdiConfigSTAReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiConfigSTAReqParams);
  wdiEventData.pCBfnc          = wdiConfigSTARspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_ConfigSTAReq*/

 /**
 @brief WDI_UpdateChannelReq will be called when the upper MAC
        wants to update the channel list on change in country code.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_UpdateChannelReq must have been called.

 @param wdiUpdateChannelReqParams: the updated channel parameters
                      as specified by the Device Interface

        wdiUpdateChannelRspCb: callback for passing back the
        response of the update channel operation received from
        the device

        pUserData: user data will be passed back with the
        callback

 @return Result of the function call
*/
WDI_Status
WDI_UpdateChannelReq
(
  WDI_UpdateChReqParamsType *pwdiUpdateChannelReqParams,
  WDI_UpdateChannelRspCb     wdiUpdateChannelRspCb,
  void*                     pUserData
)
{
  WDI_EventInfoType      wdiEventData = {{0}};
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_UPDATE_CHAN_REQ;
  wdiEventData.pEventData      = pwdiUpdateChannelReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiUpdateChannelReqParams);
  wdiEventData.pCBfnc          = wdiUpdateChannelRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_UpdateChannelReq*/

/**
 @brief WDI_SetLinkStateReq will be called when the upper MAC
        wants to change the state of an ongoing link. Upon the
        call of this API the WLAN DAL will pack and send a HAL
        Start message request message to the lower RIVA
        sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_JoinStartReq must have been called.

 @param wdiSetLinkStateReqParams: the set link state parameters
                      as specified by the Device Interface

        wdiSetLinkStateRspCb: callback for passing back the
        response of the set link state operation received from
        the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_JoinStartReq
 @return Result of the function call
*/
WDI_Status
WDI_SetLinkStateReq
(
  WDI_SetLinkReqParamsType* pwdiSetLinkStateReqParams,
  WDI_SetLinkStateRspCb     wdiSetLinkStateRspCb,
  void*                     pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_SET_LINK_ST_REQ;
  wdiEventData.pEventData      = pwdiSetLinkStateReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiSetLinkStateReqParams);
  wdiEventData.pCBfnc          = wdiSetLinkStateRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_SetLinkStateReq*/


/**
 @brief WDI_GetStatsReq will be called when the upper MAC wants
        to get statistics (MIB counters) from the device. Upon
        the call of this API the WLAN DAL will pack and send a
        HAL Start request message to the lower RIVA sub-system
        if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_Start must have been called.

 @param wdiGetStatsReqParams: the stats parameters to get as
                      specified by the Device Interface

        wdiGetStatsRspCb: callback for passing back the response
        of the get stats operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_Start
 @return Result of the function call
*/
WDI_Status
WDI_GetStatsReq
(
  WDI_GetStatsReqParamsType* pwdiGetStatsReqParams,
  WDI_GetStatsRspCb          wdiGetStatsRspCb,
  void*                      pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_GET_STATS_REQ;
  wdiEventData.pEventData      = pwdiGetStatsReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiGetStatsReqParams);
  wdiEventData.pCBfnc          = wdiGetStatsRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_GetStatsReq*/

#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
/**
 @brief WDI_GetRoamRssiReq will be called when the upper MAC wants
        to get roam rssi from the device. Upon
        the call of this API the WLAN DAL will pack and send a
        HAL Start request message to the lower RIVA sub-system
        if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_Start must have been called.

 @param wdiGetRoamRssiReqParams: the stats parameters to get as
                      specified by the Device Interface

        wdiGetRoamRssiRspCb: callback for passing back the response
        of the get stats operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_Start
 @return Result of the function call
*/
WDI_Status
WDI_GetRoamRssiReq
(
  WDI_GetRoamRssiReqParamsType* pwdiGetRoamRssiReqParams,
  WDI_GetRoamRssiRspCb          wdiGetRoamRssiRspCb,
  void*                      pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }
  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_GET_ROAM_RSSI_REQ;
  wdiEventData.pEventData      = pwdiGetRoamRssiReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiGetRoamRssiReqParams);
  wdiEventData.pCBfnc          = wdiGetRoamRssiRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_GetRoamRssiReq*/
#endif


/**
 @brief WDI_UpdateCfgReq will be called when the upper MAC when
        it wishes to change the configuration of the WLAN
        Device. Upon the call of this API the WLAN DAL will pack
        and send a HAL Update CFG request message to the lower
        RIVA sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_Start must have been called.

 @param wdiUpdateCfgReqParams: the update cfg parameters as
                      specified by the Device Interface

        wdiUpdateCfgsRspCb: callback for passing back the
        response of the update cfg operation received from the
        device

        pUserData: user data will be passed back with the
        callback

 @see WDI_Start
 @return Result of the function call
*/
WDI_Status
WDI_UpdateCfgReq
(
  WDI_UpdateCfgReqParamsType* pwdiUpdateCfgReqParams,
  WDI_UpdateCfgRspCb          wdiUpdateCfgsRspCb,
  void*                       pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_UPDATE_CFG_REQ;
  wdiEventData.pEventData      = pwdiUpdateCfgReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiUpdateCfgReqParams);
  wdiEventData.pCBfnc          = wdiUpdateCfgsRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_UpdateCfgReq*/



/**
 @brief WDI_AddBAReq will be called when the upper MAC has setup
        successfully a BA session and needs to notify the HW for
        the appropriate settings to take place. Upon the call of
        this API the WLAN DAL will pack and send a HAL Add BA
        request message to the lower RIVA sub-system if DAL is
        in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_PostAssocReq must have been called.

 @param wdiAddBAReqParams: the add BA parameters as specified by
                      the Device Interface

        wdiAddBARspCb: callback for passing back the response of
        the add BA operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_AddBAReq
(
  WDI_AddBAReqParamsType* pwdiAddBAReqParams,
  WDI_AddBARspCb          wdiAddBARspCb,
  void*                   pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_ADD_BA_REQ;
  wdiEventData.pEventData      = pwdiAddBAReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiAddBAReqParams);
  wdiEventData.pCBfnc          = wdiAddBARspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_AddBAReq*/


/**
 @brief WDI_TriggerBAReq will be called when the upper MAC has setup
        successfully a BA session and needs to notify the HW for
        the appropriate settings to take place. Upon the call of
        this API the WLAN DAL will pack and send a HAL Add BA
        request message to the lower RIVA sub-system if DAL is
        in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_PostAssocReq must have been called.

 @param wdiAddBAReqParams: the add BA parameters as specified by
                      the Device Interface

        baReqParamUserDataSize: user data size of wdiAddBAReqParams
        wdiAddBARspCb: callback for passing back the response of
        the add BA operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_TriggerBAReq
(
  WDI_TriggerBAReqParamsType* pwdiTriggerBAReqParams,
  wpt_uint8                   baReqParamUserDataSize,
  WDI_TriggerBARspCb          wdiTriggerBARspCb,
  void*                       pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_TRIGGER_BA_REQ;
  wdiEventData.pEventData      = pwdiTriggerBAReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiTriggerBAReqParams)
                                      + baReqParamUserDataSize;
  wdiEventData.pCBfnc          = wdiTriggerBARspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_AddBAReq*/

/**
 @brief WDI_UpdateBeaconParamsReq will be called when the upper MAC
        wishes to update any of the Beacon parameters used by HW.
        Upon the call of this API the WLAN DAL will pack and send a HAL Update Beacon Params request
        message to the lower RIVA sub-system if DAL is in state
        STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_PostAssocReq must have been called.

 @param wdiUpdateBeaconParams: the Beacon parameters as specified
                      by the Device Interface

        wdiUpdateBeaconParamsRspCb: callback for passing back the
        response of the start operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_UpdateBeaconParamsReq
(
  WDI_UpdateBeaconParamsType*    pwdiUpdateBeaconParams,
  WDI_UpdateBeaconParamsRspCb    wdiUpdateBeaconParamsRspCb,
  void*                        pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_UPD_BCON_PRMS_REQ;
  wdiEventData.pEventData      = pwdiUpdateBeaconParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiUpdateBeaconParams);
  wdiEventData.pCBfnc          = wdiUpdateBeaconParamsRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_UpdateBeaconParamsReq*/

/**
 @brief WDI_SendBeaconParamsReq will be called when the upper MAC
        wishes to update  the Beacon template used by HW.
        Upon the call of this API the WLAN DAL will pack and send a HAL Update Beacon template request
        message to the lower RIVA sub-system if DAL is in state
        STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_PostAssocReq must have been called.

 @param wdiSendBeaconParams: the Beacon parameters as specified
                      by the Device Interface

        wdiSendBeaconParamsRspCb: callback for passing back the
        response of the start operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_SendBeaconParamsReq
(
  WDI_SendBeaconParamsType*    pwdiSendBeaconParams,
  WDI_SendBeaconParamsRspCb    wdiSendBeaconParamsRspCb,
  void*                        pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_SND_BCON_REQ;
  wdiEventData.pEventData      = pwdiSendBeaconParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiSendBeaconParams);
  wdiEventData.pCBfnc          = wdiSendBeaconParamsRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_SendBeaconParamsReq*/

/**
 @brief WDI_UpdateProbeRspTemplateReq will be called when the
        upper MAC wants to update the probe response template to
        be transmitted as Soft AP
         Upon the call of this API the WLAN DAL will
        pack and send the probe rsp template  message to the
        lower RIVA sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.


 @param pwdiUpdateProbeRspParams: the Update Beacon parameters as
                      specified by the Device Interface

        wdiSendBeaconParamsRspCb: callback for passing back the
        response of the Send Beacon Params operation received
        from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_AddBAReq
 @return Result of the function call
*/

WDI_Status
WDI_UpdateProbeRspTemplateReq
(
  WDI_UpdateProbeRspTemplateParamsType*    pwdiUpdateProbeRspParams,
  WDI_UpdateProbeRspTemplateRspCb          wdiUpdateProbeRspParamsRspCb,
  void*                                    pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_UPD_PROBE_RSP_TEMPLATE_REQ;
  wdiEventData.pEventData      = pwdiUpdateProbeRspParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiUpdateProbeRspParams);
  wdiEventData.pCBfnc          = wdiUpdateProbeRspParamsRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_UpdateProbeRspTemplateReq*/

/**
 @brief WDI_NvDownloadReq will be called by the UMAC to download the NV blob
        to the NV memory.


 @param wdiNvDownloadReqParams: the NV Download parameters as specified by
                      the Device Interface

        wdiNvDownloadRspCb: callback for passing back the response of
        the NV Download operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_NvDownloadReq
(
  WDI_NvDownloadReqParamsType* pwdiNvDownloadReqParams,
  WDI_NvDownloadRspCb        wdiNvDownloadRspCb,
  void*                   pUserData
)
{
  WDI_EventInfoType      wdiEventData;

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_NV_DOWNLOAD_REQ;
  wdiEventData.pEventData      = (void *)pwdiNvDownloadReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiNvDownloadReqParams);
  wdiEventData.pCBfnc          = wdiNvDownloadRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_START_EVENT, &wdiEventData);

}/*WDI_NVDownloadReq*/

/**
 @brief WDI_SetP2PGONOAReq will be called when the
        upper MAC wants to send Notice of Absence
         Upon the call of this API the WLAN DAL will
        pack and send the probe rsp template  message to the
        lower RIVA sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.


 @param pwdiUpdateProbeRspParams: the Update Beacon parameters as
                      specified by the Device Interface

        wdiSendBeaconParamsRspCb: callback for passing back the
        response of the Send Beacon Params operation received
        from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_AddBAReq
 @return Result of the function call
*/
WDI_Status
WDI_SetP2PGONOAReq
(
  WDI_SetP2PGONOAReqParamsType*    pwdiP2PGONOAReqParams,
  WDI_SetP2PGONOAReqParamsRspCb    wdiP2PGONOAReqParamsRspCb,
  void*                            pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_P2P_GO_NOTICE_OF_ABSENCE_REQ;
  wdiEventData.pEventData      = pwdiP2PGONOAReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiP2PGONOAReqParams);
  wdiEventData.pCBfnc          = wdiP2PGONOAReqParamsRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_SetP2PGONOAReq*/

#ifdef FEATURE_WLAN_TDLS
/**
 @brief WDI_SetTDLSLinkEstablishReq will be called when the
        upper MAC wants to send TDLS Link Establish Request Parameters
         Upon the call of this API the WLAN DAL will
        pack and send the TDLS Link Establish Request  message to the
        lower RIVA sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.


 @param pwdiTDLSLinkEstablishReqParams: TDLS Peer Parameters
        for Link Establishment (Used for PUAPSD , TDLS Off Channel ...)

        wdiTDLSLinkEstablishReqRspCb: callback for passing back the
        response of the TDLS Link Establish request received
        from the device

        pUserData: user data will be passed back with the
        callback

 @see
 @return Result of the function call
*/
WDI_Status
WDI_SetTDLSLinkEstablishReq
(
  WDI_SetTDLSLinkEstablishReqParamsType*    pwdiTDLSLinkEstablishReqParams,
  WDI_SetTDLSLinkEstablishReqParamsRspCb    wdiTDLSLinkEstablishReqRspCb,
  void*                            pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_TDLS_LINK_ESTABLISH_REQ;
  wdiEventData.pEventData      = pwdiTDLSLinkEstablishReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiTDLSLinkEstablishReqParams);
  wdiEventData.pCBfnc          = wdiTDLSLinkEstablishReqRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_SetTDLSLinkEstablishReq*/

//tdlsoffchan
/**
 @brief WDI_SetTDLSChanSwitchReq will be called when the
        upper MAC wants to send TDLS Chan Switch Request Parameters
         Upon the call of this API the WLAN DAL will
        pack and send the TDLS Link Establish Request  message to the
        lower RIVA sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.


 @param pwdiTDLSChanSwitchReqParams: TDLS Peer Parameters
        for Link Establishment (Used for TDLS Off Channel ...)

        wdiTDLSChanSwitchReqRspCb: callback for passing back the
        response of the TDLS Chan Switch request received
        from the device

        pUserData: user data will be passed back with the
        callback

 @see
 @return Result of the function call
*/
WDI_Status
WDI_SetTDLSChanSwitchReq
(
  WDI_SetTDLSChanSwitchReqParamsType*    pwdiTDLSChanSwitchReqParams,
  WDI_SetTDLSChanSwitchReqParamsRspCb    wdiTDLSChanSwitchRReqRspCb,
  void*                            pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_TDLS_CHAN_SWITCH_REQ;
  wdiEventData.pEventData      = pwdiTDLSChanSwitchReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiTDLSChanSwitchReqParams);
  wdiEventData.pCBfnc          = wdiTDLSChanSwitchRReqRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_SetTDLSChanSwitchReq*/

#endif

/**
 @brief WDI_AddSTASelfReq will be called when the
        UMAC wanted to add STA self while opening any new session
        In state BUSY this request will be queued. Request won't
        be allowed in any other state.


 @param pwdiAddSTASelfParams: the add sta self parameters as
                      specified by the Device Interface

        pUserData: user data will be passed back with the
        callback

 @see
 @return Result of the function call
*/
WDI_Status
WDI_AddSTASelfReq
(
  WDI_AddSTASelfReqParamsType* pwdiAddSTASelfReqParams,
  WDI_AddSTASelfParamsRspCb    wdiAddSTASelfReqParamsRspCb,
  void*                        pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_ADD_STA_SELF_REQ;
  wdiEventData.pEventData      = pwdiAddSTASelfReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiAddSTASelfReqParams);
  wdiEventData.pCBfnc          = wdiAddSTASelfReqParamsRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_AddSTASelfReq*/


#ifdef WLAN_FEATURE_VOWIFI_11R
/**
 @brief WDI_AggrAddTSReq will be called when the upper MAC to inform
        the device of a successful add TSpec negotiation. HW
        needs to receive the TSpec Info from the UMAC in order
        to configure properly the QoS data traffic. Upon the
        call of this API the WLAN DAL will pack and send a HAL
        Add TS request message to the lower RIVA sub-system if
        DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 WDI_PostAssocReq must have been called.

 @param wdiAddTsReqParams: the add TS parameters as specified by
                      the Device Interface

        wdiAddTsRspCb: callback for passing back the response of
        the add TS operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_AggrAddTSReq
(
  WDI_AggrAddTSReqParamsType* pwdiAggrAddTsReqParams,
  WDI_AggrAddTsRspCb          wdiAggrAddTsRspCb,
  void*                   pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_AGGR_ADD_TS_REQ;
  wdiEventData.pEventData      = pwdiAggrAddTsReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiAggrAddTsReqParams);
  wdiEventData.pCBfnc          = wdiAggrAddTsRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_AggrAddTSReq*/

#endif /* WLAN_FEATURE_VOWIFI_11R */

/**
 @brief WDI_FTMCommandReq
        Post FTM Command Event

 @param  ftmCommandReq:   FTM Command Body
 @param  ftmCommandRspCb: FTM Response from HAL CB
 @param  pUserData:       Client Data

 @see
 @return Result of the function call
*/
WDI_Status
WDI_FTMCommandReq
(
  WDI_FTMCommandReqType *ftmCommandReq,
  WDI_FTMCommandRspCb    ftmCommandRspCb,
  void                  *pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest     = WDI_FTM_CMD_REQ;
  wdiEventData.pEventData     = (void *)ftmCommandReq;
  wdiEventData.uEventDataSize = ftmCommandReq->bodyLength + sizeof(wpt_uint32);
  wdiEventData.pCBfnc         = ftmCommandRspCb;
  wdiEventData.pUserData      = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}
/**
 @brief WDI_HostResumeReq will be called

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.


 @param pwdiResumeReqParams:  as specified by
                      the Device Interface

        wdiResumeReqRspCb: callback for passing back the response of
        the  Resume Req received from the device

        pUserData: user data will be passed back with the
        callback

 @see
 @return Result of the function call
*/
WDI_Status
WDI_HostResumeReq
(
  WDI_ResumeParamsType*            pwdiResumeReqParams,
  WDI_HostResumeEventRspCb         wdiResumeReqRspCb,
  void*                            pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_HOST_RESUME_REQ;
  wdiEventData.pEventData      = pwdiResumeReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiResumeReqParams);
  wdiEventData.pCBfnc          = wdiResumeReqRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_HostResumeReq*/

/**
 @brief WDI_DelSTASelfReq will be called

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.


 @param pwdiDelStaSelfReqParams:  as specified by
                      the Device Interface

        wdiDelStaSelfRspCb: callback for passing back the response of
        the add TS operation received from the device

        pUserData: user data will be passed back with the
        callback

 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status
WDI_DelSTASelfReq
(
  WDI_DelSTASelfReqParamsType*      pwdiDelStaSelfReqParams,
  WDI_DelSTASelfRspCb               wdiDelStaSelfRspCb,
  void*                             pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_DEL_STA_SELF_REQ;
  wdiEventData.pEventData      = pwdiDelStaSelfReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiDelStaSelfReqParams);
  wdiEventData.pCBfnc          = wdiDelStaSelfRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_AggrAddTSReq*/

/**
 @brief WDI_SetTxPerTrackingReq will be called when the upper MAC
        wants to set the Tx Per Tracking configurations.
        Upon the call of this API the WLAN DAL will pack
        and send a HAL Set Tx Per Tracking request message to the
        lower RIVA sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state.

 @param pwdiSetTxPerTrackingReqParams: the Set Tx PER Tracking configurations as
                      specified by the Device Interface

        pwdiSetTxPerTrackingRspCb: callback for passing back the
        response of the set Tx PER Tracking configurations operation received
        from the device

        pUserData: user data will be passed back with the
        callback

 @return Result of the function call
*/
WDI_Status
WDI_SetTxPerTrackingReq
(
  WDI_SetTxPerTrackingReqParamsType*      pwdiSetTxPerTrackingReqParams,
  WDI_SetTxPerTrackingRspCb               pwdiSetTxPerTrackingRspCb,
  void*                                   pUserData
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_SET_TX_PER_TRACKING_REQ;
   wdiEventData.pEventData      = pwdiSetTxPerTrackingReqParams;
   wdiEventData.uEventDataSize  = sizeof(*pwdiSetTxPerTrackingReqParams);
   wdiEventData.pCBfnc          = pwdiSetTxPerTrackingRspCb;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_SetTxPerTrackingReq*/

/**
 @brief WDI_SetTmLevelReq
        If HW Thermal condition changed, driver should react based on new 
        HW thermal condition.

 @param pwdiSetTmLevelReq: New thermal condition information
  
        pwdiSetTmLevelRspCb: callback
  
        usrData: user data will be passed back with the
        callback 
  
 @return Result of the function call
*/
WDI_Status
WDI_SetTmLevelReq
(
   WDI_SetTmLevelReqType        *pwdiSetTmLevelReq,
   WDI_SetTmLevelCb              pwdiSetTmLevelRspCb,
   void                         *usrData  
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check 
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED; 
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_SET_TM_LEVEL_REQ;
   wdiEventData.pEventData      = pwdiSetTmLevelReq; 
   wdiEventData.uEventDataSize  = sizeof(*pwdiSetTmLevelReq);
   wdiEventData.pCBfnc          = pwdiSetTmLevelRspCb; 
   wdiEventData.pUserData       = usrData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief WDI_HostSuspendInd 
  
        Suspend Indication from the upper layer will be sent
        down to HAL

 @param WDI_SuspendResumeIndParamsType

 @see

 @return Status of the request
*/
WDI_Status
WDI_HostSuspendInd
(
  WDI_SuspendParamsType*    pwdiSuspendIndParams
)
{

  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_HOST_SUSPEND_IND;
  wdiEventData.pEventData      = pwdiSuspendIndParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiSuspendIndParams);
  wdiEventData.pCBfnc          = NULL;
  wdiEventData.pUserData       = NULL;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_HostSuspendInd*/

/**
 @brief WDI_TrafficStatsInd
       Traffic Stats from the upper layer will be sent
        down to HAL

 @param WDI_TrafficStatsIndType

 @see

 @return Status of the request
*/
WDI_Status
WDI_TrafficStatsInd
(
  WDI_TrafficStatsIndType *pWdiTrafficStatsIndParams
)
{

  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_TRAFFIC_STATS_IND;
  wdiEventData.pEventData      = pWdiTrafficStatsIndParams;
  wdiEventData.uEventDataSize  = sizeof(*pWdiTrafficStatsIndParams);
  wdiEventData.pCBfnc          = NULL;
  wdiEventData.pUserData       = NULL;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_TrafficStatsInd*/

#ifdef WLAN_FEATURE_11W
/**
 @brief WDI_ExcludeUnencryptedInd
       Register with HAL to receive/drop unencrypted frames

 @param WDI_ExcludeUnencryptIndType

 @see

 @return Status of the request
*/
WDI_Status
WDI_ExcludeUnencryptedInd
(
  WDI_ExcludeUnencryptIndType *pWdiExcUnencParams
)
{

  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_EXCLUDE_UNENCRYPTED_IND;
  wdiEventData.pEventData      = pWdiExcUnencParams;
  wdiEventData.uEventDataSize  = sizeof(*pWdiExcUnencParams);
  wdiEventData.pCBfnc          = NULL;
  wdiEventData.pUserData       = NULL;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/*WDI_TrafficStatsInd*/
#endif

/**
 @brief WDI_AddPeriodicTxPtrnInd: Add Periodic TX Pattern Indication to FW

 @param addPeriodicTxPtrnParams: Add Pattern parameters

 @see

 @return Status of the request
*/
WDI_Status
WDI_AddPeriodicTxPtrnInd
(
  WDI_AddPeriodicTxPtrnParamsType*    addPeriodicTxPtrnParams
)
{
  WDI_EventInfoType      wdiEventData;

  /*-------------------------------------------------------------------------
    Sanity Check
   ------------------------------------------------------------------------*/
  if (eWLAN_PAL_FALSE == gWDIInitialized)
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request!");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*-------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_ADD_PERIODIC_TX_PATTERN_IND;
  wdiEventData.pEventData      = addPeriodicTxPtrnParams;
  wdiEventData.uEventDataSize  = sizeof(WDI_AddPeriodicTxPtrnParamsType);
  wdiEventData.pCBfnc          = NULL;
  wdiEventData.pUserData       = NULL;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief WDI_DelPeriodicTxPtrnInd: Delete Periodic TX Pattern Indication to FW

 @param delPeriodicTxPtrnParams: Delete Pattern parameters

 @see

 @return Status of the request
*/
WDI_Status
WDI_DelPeriodicTxPtrnInd
(
  WDI_DelPeriodicTxPtrnParamsType*    delPeriodicTxPtrnParams
)
{
  WDI_EventInfoType      wdiEventData;

  /*-------------------------------------------------------------------------
    Sanity Check
   ------------------------------------------------------------------------*/
  if (eWLAN_PAL_FALSE == gWDIInitialized)
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request!");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*-------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_DEL_PERIODIC_TX_PATTERN_IND;
  wdiEventData.pEventData      = delPeriodicTxPtrnParams;
  wdiEventData.uEventDataSize  = sizeof(WDI_DelPeriodicTxPtrnParamsType);
  wdiEventData.pCBfnc          = NULL;
  wdiEventData.pUserData       = NULL;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief WDI_HALDumpCmdReq
        Post HAL DUMP Command Event

 @param  halDumpCmdReqParams:   Hal Dump Command Body
 @param  halDumpCmdRspCb: HAL DUMP Response from HAL CB
 @param  pUserData:       Client Data

 @see
 @return Result of the function call
*/
WDI_Status WDI_HALDumpCmdReq
(
  WDI_HALDumpCmdReqParamsType *halDumpCmdReqParams,
  WDI_HALDumpCmdRspCb    halDumpCmdRspCb,
  void                  *pUserData
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest     =   WDI_HAL_DUMP_CMD_REQ;
  wdiEventData.pEventData     =   (void *)halDumpCmdReqParams;
  wdiEventData.uEventDataSize =   sizeof(WDI_HALDumpCmdReqParamsType);
  wdiEventData.pCBfnc         =   halDumpCmdRspCb;
  wdiEventData.pUserData      =   pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

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

            DAL Control Path Main FSM Function Implementation

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

/**
 @brief Main FSM Start function for all states except BUSY


 @param  pWDICtx:         pointer to the WLAN DAL context
         wdiEV:           event posted to the main DAL FSM
         pEventData:      pointer to the event information
         structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_PostMainEvent
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_MainEventType      wdiEV,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status         wdiStatus;
  WDI_MainFuncType   pfnWDIMainEvHdlr;
  WDI_MainStateType  wdiOldState;
  static int failCnt = 0;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
  if (( pWDICtx->uGlobalState >= WDI_MAX_ST ) ||
      ( wdiEV >= WDI_MAX_EVENT ))
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "Invalid state or event in Post Main Ev function ST: %d EV: %d",
               pWDICtx->uGlobalState, wdiEV);
     return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*Access to the global state must be locked */
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*Fetch event handler for state*/
  pfnWDIMainEvHdlr = wdiMainFSM[pWDICtx->uGlobalState].pfnMainTbl[wdiEV];

  wdiOldState = pWDICtx->uGlobalState;

  /*
  --Incase of WDI event is WDI_RESPONSE_EVENT and this is called when a
  response comes from CCPU for the request sent by host:
  the WDI global state will be in WDI_BUSY_ST already, so do not set it to BUSY again.
  This state will be set to WDI_STARTED_ST in WDI_MainRsp, if it is a expected response.
  --Incase of WDI event is WDI_RESPONSE_EVENT and it is an indication from the
  CCPU:
  don't change the state */
  if ( WDI_RESPONSE_EVENT != wdiEV)
  {
    /*Transition to BUSY State - the request is now being processed by the FSM,
     if the request fails we shall transition back to the old state, if not
     the request will manage its own state transition*/
    WDI_STATE_TRANSITION( pWDICtx, WDI_BUSY_ST);
  }
  /* If the state function associated with the EV is NULL it means that this
     event is not allowed in this state*/
  if ( NULL != pfnWDIMainEvHdlr )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "Posting event %d in state: %d to the Main FSM",
              wdiEV, wdiOldState);
    wdiStatus = pfnWDIMainEvHdlr( pWDICtx, pEventData);
  }
  else
  {
    if (!(failCnt & 0xF))
        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Unexpected event %d in state: %d",
              wdiEV, wdiOldState);
    failCnt++;
    wdiStatus = WDI_STATUS_E_NOT_ALLOWED;
  }

  /* If a request handles itself well it will end up in a success or in a
     pending
     Success - means that the request was processed and the proper state
     transition already occurred or will occur when the resp is received
     - NO other state transition or dequeueing is required

     Pending - means the request could not be processed at this moment in time
     because the FSM was already busy so no state transition or dequeueing
     is necessary anymore

     Success for synchronous case means that the transition may occur and
     processing of pending requests may continue - so it should go through
     and restores the state and continue processing queued requests*/
  if (( WDI_STATUS_SUCCESS != wdiStatus )&&
      ( WDI_STATUS_PENDING != wdiStatus ))
  {
    if ( WDI_RESPONSE_EVENT != wdiEV)
    {
      /*The request has failed or could not be processed - transition back to
        the old state - check to see if anything was queued and try to execute
        The dequeue logic should post a message to a thread and return - no
        actual processing can occur */
      WDI_STATE_TRANSITION( pWDICtx, wdiOldState);
    }
    WDI_DequeuePendingReq(pWDICtx);

  }

  /* we have completed processing the event */
  wpalMutexRelease(&pWDICtx->wptMutex);

  return wdiStatus;

}/*WDI_PostMainEvent*/


/*--------------------------------------------------------------------------
  INIT State Functions
--------------------------------------------------------------------------*/
/**
 @brief Main FSM Start function for all states except BUSY


 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_MainStart
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{

  /*--------------------------------------------------------------------
     Sanity Check
  ----------------------------------------------------------------------*/
  if (( NULL ==  pWDICtx ) || ( NULL == pEventData ))
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
               "Invalid parameters on Main Start Started %p %p",
               pWDICtx, pEventData);
     return WDI_STATUS_E_FAILURE;
  }

  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*--------------------------------------------------------------------
     Check if the Control Transport has been opened
  ----------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == pWDICtx->bCTOpened )
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
               "Control Transport not yet Open - queueing the request");

     WDI_STATE_TRANSITION( pWDICtx, WDI_INIT_ST);
     WDI_QueuePendingReq( pWDICtx, pEventData);

     wpalMutexRelease(&pWDICtx->wptMutex);
     return WDI_STATUS_PENDING;
  }

  wpalMutexRelease(&pWDICtx->wptMutex);

  /*Return Success*/
  return WDI_ProcessRequest( pWDICtx, pEventData );

}/*WDI_MainStart*/

/**
 @brief Main FSM Response function for state INIT


 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_MainRspInit
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  /*------------------------------------------------------------------------
    Not expecting a response from the device before it is started
  ------------------------------------------------------------------------*/
  WDI_ASSERT(0);

  /*Return Success*/
  return WDI_STATUS_E_NOT_ALLOWED;
}/* WDI_MainRspInit */

/**
 @brief Main FSM Close function for all states except BUSY


 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_MainClose
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{

  /*--------------------------------------------------------------------
     Sanity Check
  ----------------------------------------------------------------------*/
  if (( NULL ==  pWDICtx ) || ( NULL == pEventData ))
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
               "Invalid parameters on Main Close %p %p",
               pWDICtx, pEventData);
     return WDI_STATUS_E_FAILURE;
  }

  /*Return Success*/
  return WDI_ProcessRequest( pWDICtx, pEventData );

}/*WDI_MainClose*/
/*--------------------------------------------------------------------------
  STARTED State Functions
--------------------------------------------------------------------------*/
/**
 @brief Main FSM Start function for state STARTED


 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_MainStartStarted
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_StartRspCb           wdiStartRspCb = NULL;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*--------------------------------------------------------------------
     Sanity Check
  ----------------------------------------------------------------------*/
  if (( NULL ==  pWDICtx ) || ( NULL == pEventData ))
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
               "Invalid parameters on Main Start %p %p",
               pWDICtx, pEventData);
     return WDI_STATUS_E_FAILURE;
  }

  /*--------------------------------------------------------------------
     Nothing to do transport was already started
  ----------------------------------------------------------------------*/
  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
    "Received start while transport was already started - nothing to do");

  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*Transition back to started because the post function transitioned us to
    busy*/
  WDI_STATE_TRANSITION( pWDICtx, WDI_STARTED_ST);

  /*Check to see if any request is pending*/
  WDI_DequeuePendingReq(pWDICtx);

  wpalMutexRelease(&pWDICtx->wptMutex);

  /*Tell UMAC Success*/
  wdiStartRspCb = (WDI_StartRspCb)pEventData->pCBfnc;

   /*Notify UMAC*/
  wdiStartRspCb( &pWDICtx->wdiCachedStartRspParams, pEventData->pUserData);

  /*Return Success*/
  return WDI_STATUS_SUCCESS;

}/*WDI_MainStartStarted*/

/**
 @brief Main FSM Stop function for state STARTED


 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_MainStopStarted
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  /*--------------------------------------------------------------------
     Sanity Check
  ----------------------------------------------------------------------*/
  if (( NULL ==  pWDICtx ) || ( NULL == pEventData ))
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "Invalid parameters on Main Stop Started %p %p",
               pWDICtx, pEventData);
     return WDI_STATUS_E_FAILURE;
  }

  /*State at this point is BUSY - because we enter this state before posting
    an event to the FSM in order to prevent potential race conditions*/

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
            "Processing stop request in FSM");

  /*Return Success*/
  return WDI_ProcessRequest( pWDICtx, pEventData );

}/*WDI_MainStopStarted*/
/**
 @brief Main FSM Request function for state started


 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_MainReqStarted
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{

  /*--------------------------------------------------------------------
     Sanity Check
  ----------------------------------------------------------------------*/
  if (( NULL ==  pWDICtx ) || ( NULL == pEventData ))
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
               "Invalid parameters on Main Req Started %p %p",
               pWDICtx, pEventData);
     return WDI_STATUS_E_FAILURE;
  }

  /*State at this point is BUSY - because we enter this state before posting
    an event to the FSM in order to prevent potential race conditions*/

  /*Return Success*/
  return WDI_ProcessRequest( pWDICtx, pEventData );

}/*WDI_MainReqStarted*/

/**
 @brief Main FSM Response function for all states except INIT


 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_MainRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status  wdiStatus;
  wpt_boolean expectedResponse;

  /*--------------------------------------------------------------------
     Sanity Check
  ----------------------------------------------------------------------*/
  if (( NULL ==  pWDICtx ) || ( NULL == pEventData ))
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
               "Invalid parameters on Main Response %p %p",
               pWDICtx, pEventData);
     return WDI_STATUS_E_FAILURE;
  }

  if ( pEventData->wdiResponse ==  pWDICtx->wdiExpectedResponse )
  {
    /* we received an expected response */
    expectedResponse = eWLAN_PAL_TRUE;

    /*We expect that we will transition to started after this processing*/
    pWDICtx->ucExpectedStateTransition = WDI_STARTED_ST;

    /* we are no longer expecting a response */
     pWDICtx->wdiExpectedResponse = WDI_MAX_RESP;
  }
  else
  {
    /* we received an indication or unexpected response */
    expectedResponse = eWLAN_PAL_FALSE;
    /* for indications no need to update state from what it is right
       now, unless it explicitly does it in the indication handler (say
       for device failure ind) */
    pWDICtx->ucExpectedStateTransition = pWDICtx->uGlobalState;
  }

  /*Process the response and indication */
  wdiStatus = WDI_ProcessResponse( pWDICtx, pEventData );

  /*Lock the CB as we are about to do a state transition*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*Transition to the expected state after the response processing
  - this should always be started state with the following exceptions:
  1. processing of a failed start response
  2. device failure detected while processing response
  3. stop response received*/
  WDI_STATE_TRANSITION( pWDICtx, pWDICtx->ucExpectedStateTransition);

  /*Dequeue request that may have been queued while we were waiting for the
    response */
  if ( expectedResponse )
  {
     WDI_DequeuePendingReq(pWDICtx);
  }

  wpalMutexRelease(&pWDICtx->wptMutex);

  /*Return Success - always */
  return WDI_STATUS_SUCCESS;

}/*WDI_MainRsp*/

/*--------------------------------------------------------------------------
  STOPPED State Functions
--------------------------------------------------------------------------*/
/**
 @brief Main FSM Stop function for state STOPPED


 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_MainStopStopped
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  /*--------------------------------------------------------------------
     Sanity Check
  ----------------------------------------------------------------------*/
  if (( NULL ==  pWDICtx ) || ( NULL == pEventData ))
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "Invalid parameters on Main Stop Stopped %p %p",
               pWDICtx, pEventData);
     return WDI_STATUS_E_FAILURE;
  }

  /*We should normally not get a STOP request if we are already stopped
    since we should normally be stopped by the UMAC.  However in some
    error situations we put ourselves in the stopped state without the
    UMAC knowing, so when we get a STOP request in this state we still
    process it since we need to clean up the underlying state */
  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
            "Processing stop request while stopped in FSM");

  /*Return Success*/
  return WDI_ProcessRequest( pWDICtx, pEventData );

}/*WDI_MainStopStopped*/

/*--------------------------------------------------------------------------
  BUSY State Functions
--------------------------------------------------------------------------*/
/**
 @brief Main FSM Start function for state BUSY


 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_MainStartBusy
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  /*--------------------------------------------------------------------
     Sanity Check
  ----------------------------------------------------------------------*/
  if (( NULL ==  pWDICtx ) || ( NULL == pEventData ))
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
               "Invalid parameters on Main Start in BUSY %p %p",
               pWDICtx, pEventData);
     return WDI_STATUS_E_FAILURE;
  }

  /*--------------------------------------------------------------------
     Check if the Control Transport has been opened
  ----------------------------------------------------------------------*/
  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
           "WDI Busy state - queue start request");

  /*Queue the start request*/
  WDI_QueuePendingReq( pWDICtx, pEventData);

  /*Return Success*/
  return WDI_STATUS_PENDING;
}/*WDI_MainStartBusy*/

/**
 @brief Main FSM Stop function for state BUSY


 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_MainStopBusy
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  /*--------------------------------------------------------------------
     Sanity Check
  ----------------------------------------------------------------------*/
  if (( NULL ==  pWDICtx ) || ( NULL == pEventData ))
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
               "Invalid parameters on Main Stop in BUSY %p %p",
               pWDICtx, pEventData);
     return WDI_STATUS_E_FAILURE;
  }

  /*--------------------------------------------------------------------
     Check if the Control Transport has been opened
  ----------------------------------------------------------------------*/
  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
           "WDI Busy state - queue stop request");

  WDI_QueuePendingReq( pWDICtx, pEventData);
  return WDI_STATUS_PENDING;

}/*WDI_MainStopBusy*/

/**
 @brief Main FSM Request function for state BUSY


 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_MainReqBusy
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  /*--------------------------------------------------------------------
     Sanity Check
  ----------------------------------------------------------------------*/
  if (( NULL ==  pWDICtx ) || ( NULL == pEventData ))
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
               "Invalid parameters on Main Request in BUSY %p %p",
               pWDICtx, pEventData);
     return WDI_STATUS_E_FAILURE;
  }

  /*--------------------------------------------------------------------
     Check if the Control Transport has been opened
  ----------------------------------------------------------------------*/
  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
           "WDI Busy state - queue request %d because waiting for response %d",
             pEventData->wdiRequest, pWDICtx->wdiExpectedResponse);

  WDI_QueuePendingReq( pWDICtx, pEventData);
  return WDI_STATUS_PENDING;

}/*WDI_MainReqBusy*/
/**
 @brief Main FSM Close function for state BUSY


 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_MainCloseBusy
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  /*--------------------------------------------------------------------
     Sanity Check
  ----------------------------------------------------------------------*/
  if (( NULL ==  pWDICtx ) || ( NULL == pEventData ))
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
               "Invalid parameters on Main Close in BUSY %p %p",
               pWDICtx, pEventData);
     return WDI_STATUS_E_FAILURE;
  }

  /*--------------------------------------------------------------------
     Check if the Control Transport has been opened
  ----------------------------------------------------------------------*/
  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
           "WDI Busy state - queue close request");

  WDI_QueuePendingReq( pWDICtx, pEventData);
  return WDI_STATUS_PENDING;

}/*WDI_MainCloseBusy*/

/**
 @brief Main FSM Shutdown function for INIT & STARTED states


 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_MainShutdown
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  /*--------------------------------------------------------------------
     Sanity Check
  ----------------------------------------------------------------------*/
  if (( NULL ==  pWDICtx ) || ( NULL == pEventData ))
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "Invalid parameters on Main Start %p %p",
               pWDICtx, pEventData);
     return WDI_STATUS_E_FAILURE;
  }

  /*State at this point is BUSY - because we enter this state before posting
    an event to the FSM in order to prevent potential race conditions*/

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
            "Processing shutdown request in FSM");

  /*Return Success*/
  return WDI_ProcessRequest( pWDICtx, pEventData );

}/*WDI_MainShutdown*/

/**
 @brief Main FSM Shutdown function for BUSY state


 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_MainShutdownBusy
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  /*--------------------------------------------------------------------
     Sanity Check
  ----------------------------------------------------------------------*/
  if (( NULL ==  pWDICtx ) || ( NULL == pEventData ))
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "Invalid parameters on Main Start %p %p",
               pWDICtx, pEventData);
     return WDI_STATUS_E_FAILURE;
  }

  /* If you are waiting for a HAL response at this stage, you are not
   * going to get it. Riva is already shutdown/crashed.
   */
  wpalTimerStop(&gWDICb.wptResponseTimer);

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
            "Processing shutdown request in FSM: Busy state ");

  return WDI_ProcessRequest( pWDICtx, pEventData );

}/*WDI_MainShutdownBusy*/


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

           WLAN DAL Control Path Main Processing Functions

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

/*========================================================================
          Main DAL Control Path Request Processing API
========================================================================*/
/**
 @brief Process Start Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessStartReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_StartReqParamsType* pwdiStartParams    = NULL;
  WDI_StartRspCb          wdiStartRspCb      = NULL;
  wpt_uint8*              pSendBuffer        = NULL;
  wpt_uint16              usDataOffset       = 0;
  wpt_uint16              usSendSize         = 0;

  tHalMacStartReqMsg      halStartReq;
  wpt_uint16              usLen              = 0;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == (pwdiStartParams = (WDI_StartReqParamsType*)pEventData->pEventData)) ||
      ( NULL == (wdiStartRspCb   = (WDI_StartRspCb)pEventData->pCBfnc)))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  usLen = sizeof(halStartReq.startReqParams) +
          pwdiStartParams->usConfigBufferLen;

  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_START_REQ,
                        usLen,
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + usLen )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
              "Unable to get send buffer in start req %p %p %p",
                pEventData, pwdiStartParams, wdiStartRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-----------------------------------------------------------------------
    Fill in the message
  -----------------------------------------------------------------------*/
  halStartReq.startReqParams.driverType =
     WDI_2_HAL_DRV_TYPE(pwdiStartParams->wdiDriverType);

  halStartReq.startReqParams.uConfigBufferLen =
                  pwdiStartParams->usConfigBufferLen;
  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halStartReq.startReqParams,
                  sizeof(halStartReq.startReqParams));

  usDataOffset  += sizeof(halStartReq.startReqParams);
  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  pwdiStartParams->pConfigBuffer,
                  pwdiStartParams->usConfigBufferLen);

  pWDICtx->wdiReqStatusCB     = pwdiStartParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiStartParams->pUserData;

  /*Save Low Level Ind CB and associated user data - it will be used further
    on when an indication is coming from the lower MAC*/
  pWDICtx->wdiLowLevelIndCB   = pwdiStartParams->wdiLowLevelIndCB;
  pWDICtx->pIndUserData       = pwdiStartParams->pIndUserData;

  pWDICtx->bFrameTransEnabled = pwdiStartParams->bFrameTransEnabled;
  /*-------------------------------------------------------------------------
    Send Start Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiStartRspCb, pEventData->pUserData, WDI_START_RESP);


}/*WDI_ProcessStartReq*/

/**
 @brief Process Stop Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessStopReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_StopReqParamsType* pwdiStopParams      = NULL;
  WDI_StopRspCb          wdiStopRspCb        = NULL;
  wpt_uint8*             pSendBuffer         = NULL;
  wpt_uint16             usDataOffset        = 0;
  wpt_uint16             usSendSize          = 0;
  wpt_status             status;
  tHalMacStopReqMsg      halStopReq;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

 /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == (pwdiStopParams = (WDI_StopReqParamsType*)pEventData->pEventData)) ||
      ( NULL == (wdiStopRspCb   = (WDI_StopRspCb)pEventData->pCBfnc)))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     goto failRequest;
  }

  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_STOP_REQ,
                        sizeof(halStopReq.stopReqParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halStopReq.stopReqParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in stop req %p %p %p",
                pEventData, pwdiStopParams, wdiStopRspCb);
     WDI_ASSERT(0);
     goto failRequest;
  }

  /*-----------------------------------------------------------------------
    Fill in the message
  -----------------------------------------------------------------------*/
  halStopReq.stopReqParams.reason = WDI_2_HAL_STOP_REASON(
                                          pwdiStopParams->wdiStopReason);

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halStopReq.stopReqParams,
                  sizeof(halStopReq.stopReqParams));

  pWDICtx->wdiReqStatusCB     = pwdiStopParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiStopParams->pUserData;

  /*! TO DO: stop the data services */
  if ( eDRIVER_TYPE_MFG != pWDICtx->driverMode )
  {
     /*Stop the STA Table !UT- check this logic again
      It is safer to do it here than on the response - because a stop is imminent*/
     WDI_STATableStop(pWDICtx);

     /* Reset the event to be not signalled */
     status = wpalEventReset(&pWDICtx->setPowerStateEvent);
     if (eWLAN_PAL_STATUS_SUCCESS != status)
     {
        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "WDI Init failed to reset power state event");

        WDI_ASSERT(0);
        goto fail;
     }
     /* Stop Transport Driver, DXE */
     status = WDTS_SetPowerState(pWDICtx, WDTS_POWER_STATE_DOWN, WDI_SetPowerStateCb);
     if( eWLAN_PAL_STATUS_SUCCESS != status ) 
     {
        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                "WDTS_SetPowerState returned with status %d when trying to notify DTS that host is entering Power Down state", status);
        WDI_ASSERT(0);
        goto fail;
     }
     /*
      * Wait for the event to be set once the ACK comes back from DXE
      */
     status = wpalEventWait(&pWDICtx->setPowerStateEvent, 
                            WDI_SET_POWER_STATE_TIMEOUT);
     if (eWLAN_PAL_STATUS_SUCCESS != status)
     {
        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "WDI Init failed to wait on an event");

        WDI_ASSERT(0);
        goto fail;
      }
  }

  /*-------------------------------------------------------------------------
    Send Stop Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiStopRspCb, pEventData->pUserData, WDI_STOP_RESP);

fail:
   // Release the message buffer so we don't leak
   wpalMemoryFree(pSendBuffer);

failRequest:
   //WDA should have failure check to avoid the memory leak
   return WDI_STATUS_E_FAILURE;

}/*WDI_ProcessStopReq*/

/**
 @brief Process Close Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessCloseReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   wpt_status              wptStatus;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*Lock control block for cleanup*/
   wpalMutexAcquire(&pWDICtx->wptMutex);

   /*Clear all pending request*/
   WDI_ClearPendingRequests(pWDICtx);

   /* Close Control transport*/
   WCTS_CloseTransport(pWDICtx->wctsHandle);

   /* Close Data transport*/
   /* FTM mode does not open Data Path */
   if ( eDRIVER_TYPE_MFG != pWDICtx->driverMode )
   {
      WDTS_Close(pWDICtx);
   }

   /*Close the STA Table !UT- check this logic again*/
   WDI_STATableClose(pWDICtx);

   /*close the PAL */
   wptStatus = wpalClose(pWDICtx->pPALContext);
   if ( eWLAN_PAL_STATUS_SUCCESS !=  wptStatus )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "Failed to wpal Close %d", wptStatus);
     WDI_ASSERT(0);
   }

   /*Transition back to init state*/
   WDI_STATE_TRANSITION( pWDICtx, WDI_INIT_ST);

   wpalMutexRelease(&pWDICtx->wptMutex);

   /*Make sure the expected state is properly defaulted to Init*/
   pWDICtx->ucExpectedStateTransition = WDI_INIT_ST;

   return WDI_STATUS_SUCCESS;
}/*WDI_ProcessCloseReq*/


/*===========================================================================
                  SCANING REQUEST PROCESSING API
===========================================================================*/

/**
 @brief Process Init Scan Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessInitScanReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_InitScanReqParamsType*  pwdiInitScanParams    = NULL;
  WDI_InitScanRspCb           wdiInitScanRspCb      = NULL;
  wpt_uint8*                  pSendBuffer           = NULL;
  wpt_uint16                  usDataOffset          = 0;
  wpt_uint16                  usSendSize            = 0;
  wpt_uint8                   i = 0;

  tHalInitScanReqMsg          halInitScanReqMsg;

  /*This is temporary fix.
   * It shold be removed once host and riva changes are in sync*/
  tHalInitScanConReqMsg       halInitScanConReqMsg;

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

  /*-------------------------------------------------------------------------
    Sanity check
    -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == (pwdiInitScanParams = (WDI_InitScanReqParamsType*)pEventData->pEventData)) ||
      ( NULL == (wdiInitScanRspCb   = (WDI_InitScanRspCb)pEventData->pCBfnc)))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
        "%s: Invalid parameters", __func__);
    WDI_ASSERT(0);
    return WDI_STATUS_E_FAILURE;
  }

#if 0
  wpalMutexAcquire(&pWDICtx->wptMutex);
  /*-----------------------------------------------------------------------
    Check to see if SCAN is already in progress - if so reject the req
    We only allow one scan at a time
    ! TO DO: - revisit this constraint
    -----------------------------------------------------------------------*/
  if ( pWDICtx->bScanInProgress )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
        "Scan is already in progress - subsequent scan is not allowed"
        " until the first scan completes");

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  pWDICtx->bScanInProgress = eWLAN_PAL_TRUE;
  pWDICtx->uScanState      = WDI_SCAN_INITIALIZED_ST;

  wpalMutexRelease(&pWDICtx->wptMutex);
#endif
  if ((pwdiInitScanParams->wdiReqInfo.bUseNOA) && (!WDI_getFwWlanFeatCaps(P2P_GO_NOA_DECOUPLE_INIT_SCAN)))
  {
    /*This is temporary fix.
     * It shold be removed once host and riva changes are in sync*/
    /*-----------------------------------------------------------------------
      Get message buffer
      -----------------------------------------------------------------------*/
    if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_INIT_SCAN_CON_REQ,
            sizeof(halInitScanConReqMsg.initScanParams),
            &pSendBuffer, &usDataOffset, &usSendSize))||
        ( usSendSize < (usDataOffset + sizeof(halInitScanConReqMsg.initScanParams) )))
    {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
          "Unable to get send buffer in init scan req %p %p %p",
          pEventData, pwdiInitScanParams, wdiInitScanRspCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
    }


    /*-----------------------------------------------------------------------
      Fill in the message
      -----------------------------------------------------------------------*/
    halInitScanConReqMsg.initScanParams.scanMode =
      WDI_2_HAL_SCAN_MODE(pwdiInitScanParams->wdiReqInfo.wdiScanMode);

    wpalMemoryCopy(halInitScanConReqMsg.initScanParams.bssid,
        pwdiInitScanParams->wdiReqInfo.macBSSID, WDI_MAC_ADDR_LEN);

    halInitScanConReqMsg.initScanParams.notifyBss =
      pwdiInitScanParams->wdiReqInfo.bNotifyBSS;
    halInitScanConReqMsg.initScanParams.frameType =
      pwdiInitScanParams->wdiReqInfo.ucFrameType;
    halInitScanConReqMsg.initScanParams.frameLength =
      pwdiInitScanParams->wdiReqInfo.ucFrameLength;

    WDI_CopyWDIMgmFrameHdrToHALMgmFrameHdr( &halInitScanConReqMsg.initScanParams.macMgmtHdr,
        &pwdiInitScanParams->wdiReqInfo.wdiMACMgmtHdr);

    halInitScanConReqMsg.initScanParams.useNoA = pwdiInitScanParams->wdiReqInfo.bUseNOA;
    halInitScanConReqMsg.initScanParams.scanDuration = pwdiInitScanParams->wdiReqInfo.scanDuration;

    halInitScanConReqMsg.initScanParams.scanEntry.activeBSScnt =
      pwdiInitScanParams->wdiReqInfo.wdiScanEntry.activeBSScnt;

    for (i=0; i < pwdiInitScanParams->wdiReqInfo.wdiScanEntry.activeBSScnt; i++)
    {
      halInitScanConReqMsg.initScanParams.scanEntry.bssIdx[i] =
        pwdiInitScanParams->wdiReqInfo.wdiScanEntry.bssIdx[i];
    }

    wpalMemoryCopy( pSendBuffer+usDataOffset,
        &halInitScanConReqMsg.initScanParams,
        sizeof(halInitScanConReqMsg.initScanParams));
  }
  else
  {
    /*-----------------------------------------------------------------------
      Get message buffer
      -----------------------------------------------------------------------*/
    if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_INIT_SCAN_REQ,
            sizeof(halInitScanReqMsg.initScanParams),
            &pSendBuffer, &usDataOffset, &usSendSize))||
        ( usSendSize < (usDataOffset + sizeof(halInitScanReqMsg.initScanParams) )))
    {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
          "Unable to get send buffer in init scan req %p %p %p",
          pEventData, pwdiInitScanParams, wdiInitScanRspCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
    }


    /*-----------------------------------------------------------------------
      Fill in the message
      -----------------------------------------------------------------------*/
    halInitScanReqMsg.initScanParams.scanMode =
      WDI_2_HAL_SCAN_MODE(pwdiInitScanParams->wdiReqInfo.wdiScanMode);

    wpalMemoryCopy(halInitScanReqMsg.initScanParams.bssid,
        pwdiInitScanParams->wdiReqInfo.macBSSID, WDI_MAC_ADDR_LEN);

    halInitScanReqMsg.initScanParams.notifyBss =
      pwdiInitScanParams->wdiReqInfo.bNotifyBSS;
    halInitScanReqMsg.initScanParams.frameType =
      pwdiInitScanParams->wdiReqInfo.ucFrameType;
    halInitScanReqMsg.initScanParams.frameLength =
      pwdiInitScanParams->wdiReqInfo.ucFrameLength;

    WDI_CopyWDIMgmFrameHdrToHALMgmFrameHdr( &halInitScanReqMsg.initScanParams.macMgmtHdr,
        &pwdiInitScanParams->wdiReqInfo.wdiMACMgmtHdr);

    halInitScanReqMsg.initScanParams.scanEntry.activeBSScnt =
      pwdiInitScanParams->wdiReqInfo.wdiScanEntry.activeBSScnt;

    for (i=0; i < pwdiInitScanParams->wdiReqInfo.wdiScanEntry.activeBSScnt; i++)
    {
      halInitScanReqMsg.initScanParams.scanEntry.bssIdx[i] =
        pwdiInitScanParams->wdiReqInfo.wdiScanEntry.bssIdx[i];
    }

    wpalMemoryCopy( pSendBuffer+usDataOffset,
        &halInitScanReqMsg.initScanParams,
        sizeof(halInitScanReqMsg.initScanParams));
  }

  pWDICtx->wdiReqStatusCB     = pwdiInitScanParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiInitScanParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Init Scan Request to HAL
    -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
      wdiInitScanRspCb, pEventData->pUserData, WDI_INIT_SCAN_RESP);

}/*WDI_ProcessInitScanReq*/

/**
 @brief Process Start Scan Request function (called when Main
        FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessStartScanReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_StartScanReqParamsType*  pwdiStartScanParams    = NULL;
  WDI_StartScanRspCb           wdiStartScanRspCb      = NULL;
  wpt_uint8*                   pSendBuffer            = NULL;
  wpt_uint16                   usDataOffset           = 0;
  wpt_uint16                   usSendSize             = 0;

  tHalStartScanReqMsg          halStartScanReqMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == (pwdiStartScanParams = (WDI_StartScanReqParamsType*)pEventData->pEventData)) ||
      ( NULL == (wdiStartScanRspCb   = (WDI_StartScanRspCb)pEventData->pCBfnc)))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

#if 0
  wpalMutexAcquire(&pWDICtx->wptMutex);
  /*-----------------------------------------------------------------------
    Check to see if SCAN is already in progress - start scan is only
    allowed when a scan is ongoing and the state of the scan procedure
    is either init or end
  -----------------------------------------------------------------------*/
  if (( !pWDICtx->bScanInProgress ) ||
      (( WDI_SCAN_INITIALIZED_ST != pWDICtx->uScanState ) &&
       ( WDI_SCAN_ENDED_ST != pWDICtx->uScanState )))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Scan start not allowed in this state %d %d",
               pWDICtx->bScanInProgress, pWDICtx->uScanState);

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  pWDICtx->uScanState      = WDI_SCAN_STARTED_ST;

  wpalMutexRelease(&pWDICtx->wptMutex);
#endif

  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_START_SCAN_REQ,
                        sizeof(halStartScanReqMsg.startScanParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halStartScanReqMsg.startScanParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in start scan req %p %p %p",
                pEventData, pwdiStartScanParams, wdiStartScanRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  halStartScanReqMsg.startScanParams.scanChannel =
                              pwdiStartScanParams->ucChannel;
  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halStartScanReqMsg.startScanParams,
                  sizeof(halStartScanReqMsg.startScanParams));

  pWDICtx->wdiReqStatusCB     = pwdiStartScanParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiStartScanParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Start Scan Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiStartScanRspCb, pEventData->pUserData, WDI_START_SCAN_RESP);
}/*WDI_ProcessStartScanReq*/


/**
 @brief Process End Scan Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessEndScanReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_EndScanReqParamsType*  pwdiEndScanParams    = NULL;
  WDI_EndScanRspCb           wdiEndScanRspCb      = NULL;
  wpt_uint8*                 pSendBuffer          = NULL;
  wpt_uint16                 usDataOffset         = 0;
  wpt_uint16                 usSendSize           = 0;

  tHalEndScanReqMsg          halEndScanReqMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == (pwdiEndScanParams = (WDI_EndScanReqParamsType*)pEventData->pEventData)) ||
      ( NULL == (wdiEndScanRspCb   = (WDI_EndScanRspCb)pEventData->pCBfnc)))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /* commenting this check as UMAC is sending END_SCAN_REQ after FINISH_SCAN
  * sometimes  because of this check the scan request is not being
  * forwarded to HAL and result in hang*/
#if 0
  wpalMutexAcquire(&pWDICtx->wptMutex);
  /*-----------------------------------------------------------------------
    Check to see if SCAN is already in progress - end scan is only
    allowed when a scan is ongoing and the state of the scan procedure
    is started
  -----------------------------------------------------------------------*/
  if (( !pWDICtx->bScanInProgress ) ||
      ( WDI_SCAN_STARTED_ST != pWDICtx->uScanState ))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "End start not allowed in this state %d %d",
               pWDICtx->bScanInProgress, pWDICtx->uScanState);

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  pWDICtx->uScanState      = WDI_SCAN_ENDED_ST;

  wpalMutexRelease(&pWDICtx->wptMutex);
#endif

  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_END_SCAN_REQ,
                        sizeof(halEndScanReqMsg.endScanParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halEndScanReqMsg.endScanParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in start scan req %p %p %p",
                pEventData, pwdiEndScanParams, wdiEndScanRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  halEndScanReqMsg.endScanParams.scanChannel = pwdiEndScanParams->ucChannel;

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halEndScanReqMsg.endScanParams,
                  sizeof(halEndScanReqMsg.endScanParams));

  pWDICtx->wdiReqStatusCB     = pwdiEndScanParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiEndScanParams->pUserData;

  /*-------------------------------------------------------------------------
    Send End Scan Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiEndScanRspCb, pEventData->pUserData, WDI_END_SCAN_RESP);
}/*WDI_ProcessEndScanReq*/


/**
 @brief Process Finish Scan Request function (called when Main
        FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessFinishScanReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_FinishScanReqParamsType*  pwdiFinishScanParams;
  WDI_FinishScanRspCb           wdiFinishScanRspCb;
  wpt_uint8*                    pSendBuffer          = NULL;
  wpt_uint16                    usDataOffset         = 0;
  wpt_uint16                    usSendSize           = 0;
  wpt_uint8                     i                    = 0;
  wpt_status                    wptStatus;
  tHalFinishScanReqMsg          halFinishScanReqMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData) ||
      ( NULL == pEventData->pCBfnc))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiFinishScanParams = (WDI_FinishScanReqParamsType*)pEventData->pEventData;
  wdiFinishScanRspCb   = (WDI_FinishScanRspCb)pEventData->pCBfnc;
  /* commenting this check as UMAC is sending END_SCAN_REQ after FINISH_SCAN
  * sometimes  because of this check the scan request is not being
  * forwarded to HAL and result in hang*/
#if 0
  wpalMutexAcquire(&pWDICtx->wptMutex);
   /*-----------------------------------------------------------------------
    Check to see if SCAN is already in progress
    Finish scan gets invoked any scan states. ie. abort scan
    It should be allowed in any states.
  -----------------------------------------------------------------------*/
  if ( !pWDICtx->bScanInProgress )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Finish start not allowed in this state %d",
               pWDICtx->bScanInProgress );

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED; 
  }

  /*-----------------------------------------------------------------------
    It is safe to reset the scan flags here because until the response comes
    back all subsequent requests will be blocked at BUSY state
  -----------------------------------------------------------------------*/
  pWDICtx->uScanState      = WDI_SCAN_FINISHED_ST;
  pWDICtx->bScanInProgress = eWLAN_PAL_FALSE;
  wpalMutexRelease(&pWDICtx->wptMutex);
#endif

  if ( pWDICtx->bInBmps )
  {
     // notify DTS that we are entering BMPS
     wptStatus = WDTS_SetPowerState(pWDICtx, WDTS_POWER_STATE_BMPS, NULL);
     if( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) 
     {
        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                "WDTS_SetPowerState returned with status %d when trying to notify DTS that host is entering BMPS", wptStatus);
        WDI_ASSERT(0);
     }
  }

  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_FINISH_SCAN_REQ,
                        sizeof(halFinishScanReqMsg.finishScanParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halFinishScanReqMsg.finishScanParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in start scan req %p %p %p",
                pEventData, pwdiFinishScanParams, wdiFinishScanRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  halFinishScanReqMsg.finishScanParams.scanMode =
    WDI_2_HAL_SCAN_MODE(pwdiFinishScanParams->wdiReqInfo.wdiScanMode);

  halFinishScanReqMsg.finishScanParams.currentOperChannel =
    pwdiFinishScanParams->wdiReqInfo.ucCurrentOperatingChannel;

  halFinishScanReqMsg.finishScanParams.cbState =
    WDI_2_HAL_CB_STATE(pwdiFinishScanParams->wdiReqInfo.wdiCBState);

  wpalMemoryCopy(halFinishScanReqMsg.finishScanParams.bssid,
                 pwdiFinishScanParams->wdiReqInfo.macBSSID, WDI_MAC_ADDR_LEN);

  halFinishScanReqMsg.finishScanParams.notifyBss   =
                              pwdiFinishScanParams->wdiReqInfo.bNotifyBSS ;
  halFinishScanReqMsg.finishScanParams.frameType   =
                              pwdiFinishScanParams->wdiReqInfo.ucFrameType ;
  halFinishScanReqMsg.finishScanParams.frameLength =
                              pwdiFinishScanParams->wdiReqInfo.ucFrameLength ;

  halFinishScanReqMsg.finishScanParams.scanEntry.activeBSScnt =
                   pwdiFinishScanParams->wdiReqInfo.wdiScanEntry.activeBSScnt ;

  for (i = 0; i < pwdiFinishScanParams->wdiReqInfo.wdiScanEntry.activeBSScnt; i++)
  {
    halFinishScanReqMsg.finishScanParams.scanEntry.bssIdx[i] =
               pwdiFinishScanParams->wdiReqInfo.wdiScanEntry.bssIdx[i] ;
  }

  WDI_CopyWDIMgmFrameHdrToHALMgmFrameHdr( &halFinishScanReqMsg.finishScanParams.macMgmtHdr,
                              &pwdiFinishScanParams->wdiReqInfo.wdiMACMgmtHdr);

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halFinishScanReqMsg.finishScanParams,
                  sizeof(halFinishScanReqMsg.finishScanParams));

  pWDICtx->wdiReqStatusCB     = pwdiFinishScanParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiFinishScanParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Finish Scan Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiFinishScanRspCb, pEventData->pUserData, WDI_FINISH_SCAN_RESP);
}/*WDI_ProcessFinishScanReq*/


/*==========================================================================
                    ASSOCIATION REQUEST API
==========================================================================*/
/**
 @brief Process BSS Join for a given Session

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessBSSSessionJoinReq
(
  WDI_ControlBlockType*   pWDICtx,
  WDI_JoinReqParamsType*  pwdiJoinParams,
  WDI_JoinRspCb           wdiJoinRspCb,
  void*                   pUserData
)
{
  WDI_BSSSessionType*     pBSSSes             = NULL;
  wpt_uint8*              pSendBuffer         = NULL;
  wpt_uint16              usDataOffset        = 0;
  wpt_uint16              usSendSize          = 0;
  wpt_uint8               ucCurrentBSSSesIdx  = 0;

  tHalJoinReqMsg          halJoinReqMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Check to see if we have any session with this BSSID already stored, we
    should not
  ------------------------------------------------------------------------*/
  ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx,
                                   pwdiJoinParams->wdiReqInfo.macBSSID,
                                  &pBSSSes);

  if ( NULL != pBSSSes )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
          "Association for this BSSID: " MAC_ADDRESS_STR " is already in place",
          MAC_ADDR_ARRAY(pwdiJoinParams->wdiReqInfo.macBSSID));

    /*reset the bAssociationInProgress otherwise the next 
     *join request will be queued*/
    pWDICtx->bAssociationInProgress = eWLAN_PAL_FALSE;
    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED; 
  }

  /*------------------------------------------------------------------------
    Fetch an empty session block
  ------------------------------------------------------------------------*/
  ucCurrentBSSSesIdx = WDI_FindEmptySession( pWDICtx, &pBSSSes);
  if ( NULL == pBSSSes )
  {

    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "DAL has no free sessions - cannot run another join");

    /*reset the bAssociationInProgress otherwise the next 
     *join request will be queued*/
    pWDICtx->bAssociationInProgress = eWLAN_PAL_FALSE;
    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_RES_FAILURE;
  }

  /*Save BSS Session Info*/
  pBSSSes->bInUse = eWLAN_PAL_TRUE;
  wpalMemoryCopy( pBSSSes->macBSSID, pwdiJoinParams->wdiReqInfo.macBSSID,
                  WDI_MAC_ADDR_LEN);

  /*Transition to state Joining*/
  pBSSSes->wdiAssocState      = WDI_ASSOC_JOINING_ST;
  pWDICtx->ucCurrentBSSSesIdx = ucCurrentBSSSesIdx;

  wpalMutexRelease(&pWDICtx->wptMutex);

  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_JOIN_REQ,
                        sizeof(halJoinReqMsg.joinReqParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halJoinReqMsg.joinReqParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in join req %p %p %p",
                pUserData, pwdiJoinParams, wdiJoinRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wpalMemoryCopy(halJoinReqMsg.joinReqParams.bssId,
                 pwdiJoinParams->wdiReqInfo.macBSSID, WDI_MAC_ADDR_LEN);

  wpalMemoryCopy(halJoinReqMsg.joinReqParams.selfStaMacAddr,
                 pwdiJoinParams->wdiReqInfo.macSTASelf,
                 WDI_MAC_ADDR_LEN);

  halJoinReqMsg.joinReqParams.ucChannel =
    pwdiJoinParams->wdiReqInfo.wdiChannelInfo.ucChannel;

  halJoinReqMsg.joinReqParams.linkState = pwdiJoinParams->wdiReqInfo.linkState;

#ifdef WLAN_FEATURE_VOWIFI
  halJoinReqMsg.joinReqParams.maxTxPower =
    pwdiJoinParams->wdiReqInfo.wdiChannelInfo.cMaxTxPower;
#else
  halJoinReqMsg.joinReqParams.ucLocalPowerConstraint =
    pwdiJoinParams->wdiReqInfo.wdiChannelInfo.ucLocalPowerConstraint;
#endif

  halJoinReqMsg.joinReqParams.secondaryChannelOffset =
     WDI_2_HAL_SEC_CH_OFFSET(pwdiJoinParams->wdiReqInfo.wdiChannelInfo.
                             wdiSecondaryChannelOffset);

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halJoinReqMsg.joinReqParams,
                  sizeof(halJoinReqMsg.joinReqParams));

  pWDICtx->wdiReqStatusCB     = pwdiJoinParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiJoinParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Join Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiJoinRspCb, pUserData, WDI_JOIN_RESP);

}/*WDI_ProcessBSSSessionJoinReq*/

/**
 @brief Process Join Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessJoinReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status              wdiStatus          = WDI_STATUS_SUCCESS;
  WDI_JoinReqParamsType*  pwdiJoinParams     = NULL;
  WDI_JoinRspCb           wdiJoinRspCb       = NULL;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == (pwdiJoinParams = (WDI_JoinReqParamsType*)pEventData->pEventData)) ||
      ( NULL == (wdiJoinRspCb   = (WDI_JoinRspCb)pEventData->pCBfnc)))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  if ( eWLAN_PAL_FALSE != pWDICtx->bAssociationInProgress )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "Association is currently in progress, queueing new join req");

    /*Association is in progress - queue current one*/
    wdiStatus = WDI_QueueNewAssocRequest(pWDICtx, pEventData,
                             pwdiJoinParams->wdiReqInfo.macBSSID);

    wpalMutexRelease(&pWDICtx->wptMutex);

    return wdiStatus;
  }

  /*Starting a new association */
  pWDICtx->bAssociationInProgress = eWLAN_PAL_TRUE;
  wpalMutexRelease(&pWDICtx->wptMutex);

  /*Process the Join Request*/
  return WDI_ProcessBSSSessionJoinReq( pWDICtx, pwdiJoinParams,
                                       wdiJoinRspCb,pEventData->pUserData);

}/*WDI_ProcessJoinReq*/


/**
 @brief Process Config BSS Request function (called when Main
        FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessConfigBSSReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_ConfigBSSReqParamsType*  pwdiConfigBSSParams;
  WDI_ConfigBSSRspCb           wdiConfigBSSRspCb;
  wpt_uint8                    ucCurrentBSSSesIdx  = 0;
  WDI_BSSSessionType*          pBSSSes             = NULL;
  wpt_uint16                   uMsgSize            = 0;
  wpt_uint8*                   pSendBuffer         = NULL;
  wpt_uint16                   usDataOffset        = 0;
  wpt_uint16                   usSendSize          = 0;
  WDI_Status                   wdiStatus           = WDI_STATUS_SUCCESS;

  tConfigBssReqMsg             halConfigBssReqMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wpalMemoryZero(&halConfigBssReqMsg, sizeof(tConfigBssReqMsg));
  pwdiConfigBSSParams = (WDI_ConfigBSSReqParamsType*)pEventData->pEventData;
  wdiConfigBSSRspCb   = (WDI_ConfigBSSRspCb)pEventData->pCBfnc;
  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made
  ------------------------------------------------------------------------*/
  ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx,
                                 pwdiConfigBSSParams->wdiReqInfo.macBSSID,
                                 &pBSSSes);

  if ( NULL == pBSSSes )
  {
#ifdef WLAN_FEATURE_VOWIFI_11R
      /*------------------------------------------------------------------------
        Fetch an empty session block
      ------------------------------------------------------------------------*/
      ucCurrentBSSSesIdx = WDI_FindEmptySession( pWDICtx, &pBSSSes);
      if ( NULL == pBSSSes )
      {

        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                  "DAL has no free sessions - cannot run another join");

        wpalMutexRelease(&pWDICtx->wptMutex);
        return WDI_STATUS_RES_FAILURE;
      }

      /*Save BSS Session Info*/
      pBSSSes->bInUse = eWLAN_PAL_TRUE;
      wpalMemoryCopy( pBSSSes->macBSSID, pwdiConfigBSSParams->wdiReqInfo.macBSSID,
                      WDI_MAC_ADDR_LEN);

      /*Transition to state Joining*/
      pBSSSes->wdiAssocState      = WDI_ASSOC_JOINING_ST;
      pWDICtx->ucCurrentBSSSesIdx = ucCurrentBSSSesIdx;
#else
    /* If the BSS type is IBSS create the session here as there is no Join
     * Request in case of IBSS*/
    if((pwdiConfigBSSParams->wdiReqInfo.wdiBSSType == WDI_IBSS_MODE) ||
       (pwdiConfigBSSParams->wdiReqInfo.wdiBSSType == WDI_INFRA_AP_MODE) ||
       (pwdiConfigBSSParams->wdiReqInfo.wdiBSSType == WDI_BTAMP_AP_MODE) ||
       (pwdiConfigBSSParams->wdiReqInfo.wdiBSSType == WDI_BTAMP_STA_MODE))
    {
      /*------------------------------------------------------------------------
        Fetch an empty session block
      ------------------------------------------------------------------------*/
      ucCurrentBSSSesIdx = WDI_FindEmptySession( pWDICtx, &pBSSSes);
      if ( NULL == pBSSSes )
      {

        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                  "DAL has no free sessions - cannot run another join");

        wpalMutexRelease(&pWDICtx->wptMutex);
        return WDI_STATUS_RES_FAILURE;
      }

      /*Save BSS Session Info*/
      pBSSSes->bInUse = eWLAN_PAL_TRUE;
      wpalMemoryCopy( pBSSSes->macBSSID, pwdiConfigBSSParams->wdiReqInfo.macBSSID,
                      WDI_MAC_ADDR_LEN);

      /*Transition to state Joining*/
      pBSSSes->wdiAssocState      = WDI_ASSOC_JOINING_ST;
      pWDICtx->ucCurrentBSSSesIdx = ucCurrentBSSSesIdx;
    }
    else
    {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                "%s: Association sequence for this BSS does not yet exist." MAC_ADDRESS_STR "wdiBssType %d",
                __func__, MAC_ADDR_ARRAY(pwdiConfigBSSParams->wdiReqInfo.macBSSID), 
                pwdiConfigBSSParams->wdiReqInfo.wdiBSSType);
      
      /* for IBSS testing */
      wpalMutexRelease(&pWDICtx->wptMutex);
      return WDI_STATUS_E_NOT_ALLOWED;
    }
#endif
  }

  /*------------------------------------------------------------------------
    Check if this BSS is being currently processed or queued,
    if queued - queue the new request as well
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "%s: Association sequence for this BSS exists but currently queued. " MAC_ADDRESS_STR " bssIdx %d", 
              __func__, MAC_ADDR_ARRAY(pwdiConfigBSSParams->wdiReqInfo.macBSSID), 
              ucCurrentBSSSesIdx);

    wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData);

    wpalMutexRelease(&pWDICtx->wptMutex);

    return wdiStatus;
  }

  /* Cache the request for response processing */
  wpalMemoryCopy(&pWDICtx->wdiCachedConfigBssReq,
                 pwdiConfigBSSParams,
                 sizeof(pWDICtx->wdiCachedConfigBssReq));

  wpalMutexRelease(&pWDICtx->wptMutex);

  /* Allocation of BssReqMsg Memory Based on Firmware Capabilities */
#ifdef WLAN_FEATURE_11AC
  if (WDI_getFwWlanFeatCaps(DOT11AC))
     uMsgSize = sizeof(halConfigBssReqMsg.uBssParams.configBssParams_V1); // Version - 1 For 11AC
  else
#endif
     uMsgSize = sizeof(halConfigBssReqMsg.uBssParams.configBssParams); // default Version - 0 Structure

  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_CONFIG_BSS_REQ,
                    uMsgSize, &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + uMsgSize )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in config bss req %p %p %p",
                pEventData, pwdiConfigBSSParams, wdiConfigBSSRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*Copy the BSS request */
#ifdef WLAN_FEATURE_11AC
  if (WDI_getFwWlanFeatCaps(DOT11AC))
    WDI_CopyWDIConfigBSSToHALConfigBSS( (tConfigBssParams*)&halConfigBssReqMsg.uBssParams.configBssParams_V1,
                                        &pwdiConfigBSSParams->wdiReqInfo);
  else
#endif
  WDI_CopyWDIConfigBSSToHALConfigBSS( &halConfigBssReqMsg.uBssParams.configBssParams,
                                      &pwdiConfigBSSParams->wdiReqInfo);

  /* Need to fill in the STA Index to invalid, since at this point we have not
     yet received it from HAL */
  halConfigBssReqMsg.uBssParams.configBssParams.staContext.staIdx = WDI_STA_INVALID_IDX;

  /* Need to fill in the BSS index */
  halConfigBssReqMsg.uBssParams.configBssParams.staContext.bssIdx = pBSSSes->ucBSSIdx;

#ifdef WLAN_FEATURE_11AC
  if (WDI_getFwWlanFeatCaps(DOT11AC)){
    wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halConfigBssReqMsg.uBssParams.configBssParams_V1,
                  uMsgSize);
  }else
#endif
  {
    if ( uMsgSize <= sizeof(tConfigBssParams) )
    {
      wpalMemoryCopy( pSendBuffer+usDataOffset,
                      &halConfigBssReqMsg.uBssParams.configBssParams,
                      uMsgSize);
    }
    else
    {
      return WDI_STATUS_E_FAILURE;
    }
  }

  pWDICtx->wdiReqStatusCB     = pwdiConfigBSSParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiConfigBSSParams->pUserData;
  wpalMemoryZero(&halConfigBssReqMsg, sizeof(halConfigBssReqMsg));
  /*-------------------------------------------------------------------------
    Send Config BSS Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiConfigBSSRspCb, pEventData->pUserData,
                       WDI_CONFIG_BSS_RESP);

}/*WDI_ProcessConfigBSSReq*/


/**
 @brief Process Del BSS Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessDelBSSReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_DelBSSReqParamsType*  pwdiDelBSSParams    = NULL;
  WDI_DelBSSRspCb           wdiDelBSSRspCb      = NULL;
  wpt_uint8                 ucCurrentBSSSesIdx  = 0;
  WDI_BSSSessionType*       pBSSSes             = NULL;
  wpt_uint8*                pSendBuffer         = NULL;
  wpt_uint16                usDataOffset        = 0;
  wpt_uint16                usSendSize          = 0;
  WDI_Status                wdiStatus           = WDI_STATUS_SUCCESS;

  tDeleteBssReqMsg          halBssReqMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == (pwdiDelBSSParams = (WDI_DelBSSReqParamsType*)pEventData->pEventData)) ||
      ( NULL == (wdiDelBSSRspCb   = (WDI_DelBSSRspCb)pEventData->pCBfnc)))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made
  ------------------------------------------------------------------------*/
  ucCurrentBSSSesIdx = WDI_FindAssocSessionByBSSIdx( pWDICtx,
                                             pwdiDelBSSParams->ucBssIdx,
                                            &pBSSSes);

  if ( NULL == pBSSSes )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
        "%s: BSS does not yet exist. ucBssIdx %d",
        __func__, pwdiDelBSSParams->ucBssIdx);

    wpalMutexRelease(&pWDICtx->wptMutex);

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Check if this BSS is being currently processed or queued,
    if queued - queue the new request as well
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "%s: Association sequence for this BSS exists but currently queued. ucBssIdx %d",
              __func__, pwdiDelBSSParams->ucBssIdx);

    wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData);

    wpalMutexRelease(&pWDICtx->wptMutex);

    return wdiStatus;
  }

  /*-----------------------------------------------------------------------
    If we receive a Del BSS request for an association that is already in
    progress, it indicates that the assoc has failed => we no longer have
    an association in progress => we must check for pending associations
    that were queued and start as soon as the Del BSS response is received
  -----------------------------------------------------------------------*/
  if ( ucCurrentBSSSesIdx == pWDICtx->ucCurrentBSSSesIdx )
  {
    /*We can switch to false here because even if a subsequent Join comes in
      it will only be processed when DAL transitions out of BUSY state which
      happens when the Del BSS request comes */
     pWDICtx->bAssociationInProgress = eWLAN_PAL_FALSE;

     /*Former association is complete - prepare next pending assoc for
       processing */
     WDI_DequeueAssocRequest(pWDICtx);
  }

  wpalMutexRelease(&pWDICtx->wptMutex);
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_DEL_BSS_REQ,
                        sizeof(halBssReqMsg.deleteBssParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halBssReqMsg.deleteBssParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in start req %p %p %p",
                pEventData, pwdiDelBSSParams, wdiDelBSSRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*Fill in the message request structure*/

  /*BSS Index is saved on config BSS response and Post Assoc Response */
  halBssReqMsg.deleteBssParams.bssIdx = pBSSSes->ucBSSIdx;

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halBssReqMsg.deleteBssParams,
                  sizeof(halBssReqMsg.deleteBssParams));

  pWDICtx->wdiReqStatusCB     = pwdiDelBSSParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiDelBSSParams->pUserData;


  /*-------------------------------------------------------------------------
    Send Del BSS Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiDelBSSRspCb, pEventData->pUserData, WDI_DEL_BSS_RESP);


}/*WDI_ProcessDelBSSReq*/

/**
 @brief Process Post Assoc Request function (called when Main
        FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessPostAssocReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_PostAssocReqParamsType* pwdiPostAssocParams   = NULL;
  WDI_PostAssocRspCb          wdiPostAssocRspCb     = NULL;
  wpt_uint8                   ucCurrentBSSSesIdx    = 0;
  WDI_BSSSessionType*         pBSSSes               = NULL;
  wpt_uint8*                  pSendBuffer           = NULL;
  wpt_uint16                  usDataOffset          = 0;
  wpt_uint16                  usSendSize            = 0;
  wpt_uint16                  uMsgSize              = 0;
  wpt_uint16                  uOffset               = 0;
  WDI_Status                  wdiStatus             = WDI_STATUS_SUCCESS;

  tPostAssocReqMsg            halPostAssocReqMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == (pwdiPostAssocParams = (WDI_PostAssocReqParamsType*)pEventData->pEventData)) ||
      ( NULL == (wdiPostAssocRspCb   = (WDI_PostAssocRspCb)pEventData->pCBfnc)))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made
  ------------------------------------------------------------------------*/
  ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx,
                              pwdiPostAssocParams->wdiBSSParams.macBSSID,
                              &pBSSSes);

  if ( NULL == pBSSSes )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, 
              "%s: Association sequence for this BSS does not yet exist - " 
              "operation not allowed. macBSSID " MAC_ADDRESS_STR, 
              __func__, MAC_ADDR_ARRAY(pwdiPostAssocParams->wdiBSSParams.macBSSID));

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Check if this BSS is being currently processed or queued,
    if queued - queue the new request as well
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, 
              __func__, MAC_ADDR_ARRAY(pwdiPostAssocParams->wdiBSSParams.macBSSID));

    wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData);

    wpalMutexRelease(&pWDICtx->wptMutex);

    return wdiStatus;
  }

  /*-----------------------------------------------------------------------
    If Post Assoc was not yet received - the current association must
    be in progress
    -----------------------------------------------------------------------*/
  if (( ucCurrentBSSSesIdx != pWDICtx->ucCurrentBSSSesIdx ) ||
      ( eWLAN_PAL_FALSE == pWDICtx->bAssociationInProgress ))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Association sequence for this BSS association no longer in "
              "progress - not allowed");

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*-----------------------------------------------------------------------
    Post Assoc Request is only allowed in Joining state
  -----------------------------------------------------------------------*/
  if ( WDI_ASSOC_JOINING_ST != pBSSSes->wdiAssocState)
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Post Assoc not allowed before JOIN - failing request");

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  wpalMutexRelease(&pWDICtx->wptMutex);

  uMsgSize = sizeof(halPostAssocReqMsg.postAssocReqParams.configStaParams) +
             sizeof(halPostAssocReqMsg.postAssocReqParams.configBssParams) ;
  /*-----------------------------------------------------------------------
    Fill message for tx over the bus
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_POST_ASSOC_REQ,
                        uMsgSize,&pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + uMsgSize )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in start req %p %p %p",
                pEventData, pwdiPostAssocParams, wdiPostAssocRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*Copy the STA parameters */
  WDI_CopyWDIStaCtxToHALStaCtx(&halPostAssocReqMsg.postAssocReqParams.configStaParams,
                               &pwdiPostAssocParams->wdiSTAParams );

  /* Need to fill in the self STA Index */
  if ( WDI_STATUS_SUCCESS !=
       WDI_STATableFindStaidByAddr(pWDICtx,
                                   pwdiPostAssocParams->wdiSTAParams.macSTA,
                                   (wpt_uint8*)&halPostAssocReqMsg.postAssocReqParams.configStaParams.staIdx ))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                MAC_ADDRESS_STR
                ": This station does not exist in the WDI Station Table",
                MAC_ADDR_ARRAY(pwdiPostAssocParams->wdiSTAParams.macSTA));
    wpalMutexRelease(&pWDICtx->wptMutex);
    wpalMemoryFree(pSendBuffer);
    return WDI_STATUS_E_FAILURE;
  }

  /* Need to fill in the BSS index */
  halPostAssocReqMsg.postAssocReqParams.configStaParams.bssIdx =
     pBSSSes->ucBSSIdx;

  /*Copy the BSS parameters */
  WDI_CopyWDIConfigBSSToHALConfigBSS( &halPostAssocReqMsg.postAssocReqParams.configBssParams,
                                      &pwdiPostAssocParams->wdiBSSParams);

  /* Need to fill in the STA index of the peer */
  if ( WDI_STATUS_SUCCESS !=
       WDI_STATableFindStaidByAddr(pWDICtx,
                                   pwdiPostAssocParams->wdiBSSParams.wdiSTAContext.macSTA,
                                   (wpt_uint8*)&halPostAssocReqMsg.postAssocReqParams.configBssParams.staContext.staIdx))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                MAC_ADDRESS_STR
                ": This station does not exist in the WDI Station Table",
                MAC_ADDR_ARRAY(pwdiPostAssocParams->wdiBSSParams.wdiSTAContext.macSTA));
    wpalMutexRelease(&pWDICtx->wptMutex);
    wpalMemoryFree(pSendBuffer);
    return WDI_STATUS_E_FAILURE;
  }

  /* Need to fill in the BSS index */
  halPostAssocReqMsg.postAssocReqParams.configStaParams.bssIdx =
     pBSSSes->ucBSSIdx;


  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halPostAssocReqMsg.postAssocReqParams.configStaParams,
                  sizeof(halPostAssocReqMsg.postAssocReqParams.configStaParams));

  uOffset = sizeof(halPostAssocReqMsg.postAssocReqParams.configStaParams);

  wpalMemoryCopy( pSendBuffer+usDataOffset + uOffset,
                  &halPostAssocReqMsg.postAssocReqParams.configBssParams,
                  sizeof(halPostAssocReqMsg.postAssocReqParams.configBssParams));


  pWDICtx->wdiReqStatusCB     = pwdiPostAssocParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiPostAssocParams->pUserData;


  wpalMemoryCopy( &pWDICtx->wdiCachedPostAssocReq,
                  pwdiPostAssocParams,
                  sizeof(pWDICtx->wdiCachedPostAssocReq));

  wpalMemoryZero(&halPostAssocReqMsg, sizeof(halPostAssocReqMsg));
  /*-------------------------------------------------------------------------
    Send Post Assoc Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiPostAssocRspCb, pEventData->pUserData, WDI_POST_ASSOC_RESP);


}/*WDI_ProcessPostAssocReq*/

/**
 @brief Process Del STA Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessDelSTAReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_DelSTAReqParamsType*  pwdiDelSTAParams;
  WDI_DelSTARspCb           wdiDelSTARspCb;
  wpt_uint8                 ucCurrentBSSSesIdx  = 0;
  WDI_BSSSessionType*       pBSSSes             = NULL;
  wpt_uint8*                pSendBuffer         = NULL;
  wpt_uint16                usDataOffset        = 0;
  wpt_uint16                usSendSize          = 0;
  wpt_macAddr               macBSSID;
  WDI_Status                wdiStatus           = WDI_STATUS_SUCCESS;

  tDeleteStaReqMsg          halDelStaReqMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiDelSTAParams = (WDI_DelSTAReqParamsType*)pEventData->pEventData;
  wdiDelSTARspCb   = (WDI_DelSTARspCb)pEventData->pCBfnc;
  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made and identify WDI session
  ------------------------------------------------------------------------*/
  if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx,
                                                         pwdiDelSTAParams->ucSTAIdx,
                                                         &macBSSID))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                "This station does not exist in the WDI Station Table %d",
                pwdiDelSTAParams->ucSTAIdx);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_FAILURE;
  }

  ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes);
  if ( NULL == pBSSSes )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, 
              "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, 
              __func__, MAC_ADDR_ARRAY(macBSSID));

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Check if this BSS is being currently processed or queued,
    if queued - queue the new request as well
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR,
              __func__, MAC_ADDR_ARRAY(macBSSID));

    wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return wdiStatus;
  }

  wpalMutexRelease(&pWDICtx->wptMutex);
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_DEL_STA_REQ,
                        sizeof(halDelStaReqMsg.delStaParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halDelStaReqMsg.delStaParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in start req %p %p %p",
                pEventData, pwdiDelSTAParams, wdiDelSTARspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  halDelStaReqMsg.delStaParams.staIdx = pwdiDelSTAParams->ucSTAIdx;
  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halDelStaReqMsg.delStaParams,
                  sizeof(halDelStaReqMsg.delStaParams));

  pWDICtx->wdiReqStatusCB     = pwdiDelSTAParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiDelSTAParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Del STA Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiDelSTARspCb, pEventData->pUserData, WDI_DEL_STA_RESP);

}/*WDI_ProcessDelSTAReq*/


/*==========================================================================
                 SECURITY REQUEST PROCESSING API
==========================================================================*/
/**
 @brief Process Set BSS Key Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetBssKeyReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_SetBSSKeyReqParamsType*  pwdiSetBSSKeyParams;
  WDI_SetBSSKeyRspCb           wdiSetBSSKeyRspCb;
  wpt_uint8                    ucCurrentBSSSesIdx  = 0;
  WDI_BSSSessionType*          pBSSSes             = NULL;
  wpt_uint8*                   pSendBuffer         = NULL;
  wpt_uint16                   usDataOffset        = 0;
  wpt_uint16                   usSendSize          = 0;
  WDI_Status                   wdiStatus           = WDI_STATUS_SUCCESS;
  tSetBssKeyReqMsg             halSetBssKeyReqMsg  = {{0}};
  wpt_uint8                    keyIndex            = 0;
  wpt_uint8                    i;

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

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiSetBSSKeyParams = (WDI_SetBSSKeyReqParamsType*)pEventData->pEventData;
  wdiSetBSSKeyRspCb   = (WDI_SetBSSKeyRspCb)pEventData->pCBfnc;
  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made
  ------------------------------------------------------------------------*/
  ucCurrentBSSSesIdx = WDI_FindAssocSessionByBSSIdx( pWDICtx,
                           pwdiSetBSSKeyParams->wdiBSSKeyInfo.ucBssIdx,
                          &pBSSSes);

  if ( NULL == pBSSSes )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "%s: Association sequence for this BSS does not yet exist. ucBssIdx %d", 
              __func__, pwdiSetBSSKeyParams->wdiBSSKeyInfo.ucBssIdx);

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Check if this BSS is being currently processed or queued,
    if queued - queue the new request as well
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "%s: Association sequence for this BSS exists but currently queued. ucBssIdx %d",
              __func__, pwdiSetBSSKeyParams->wdiBSSKeyInfo.ucBssIdx);

    wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return wdiStatus;
  }


  wpalMutexRelease(&pWDICtx->wptMutex);
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_BSS_KEY_REQ,
                        sizeof(halSetBssKeyReqMsg.setBssKeyParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halSetBssKeyReqMsg.setBssKeyParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in set bss key req %p %p %p",
                pEventData, pwdiSetBSSKeyParams, wdiSetBSSKeyRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-----------------------------------------------------------------------
    Copy the Key parameters into the HAL message
  -----------------------------------------------------------------------*/

  halSetBssKeyReqMsg.setBssKeyParams.bssIdx = ucCurrentBSSSesIdx;

  halSetBssKeyReqMsg.setBssKeyParams.encType =
             WDI_2_HAL_ENC_TYPE (pwdiSetBSSKeyParams->wdiBSSKeyInfo.wdiEncType);

  halSetBssKeyReqMsg.setBssKeyParams.numKeys =
                                  pwdiSetBSSKeyParams->wdiBSSKeyInfo.ucNumKeys;

  for(keyIndex = 0; keyIndex < pwdiSetBSSKeyParams->wdiBSSKeyInfo.ucNumKeys ;
                                                                 keyIndex++)
  {
    halSetBssKeyReqMsg.setBssKeyParams.key[keyIndex].keyId =
                      pwdiSetBSSKeyParams->wdiBSSKeyInfo.aKeys[keyIndex].keyId;
    halSetBssKeyReqMsg.setBssKeyParams.key[keyIndex].unicast =
                     pwdiSetBSSKeyParams->wdiBSSKeyInfo.aKeys[keyIndex].unicast;
    halSetBssKeyReqMsg.setBssKeyParams.key[keyIndex].keyDirection =
                pwdiSetBSSKeyParams->wdiBSSKeyInfo.aKeys[keyIndex].keyDirection;

    if(WDI_getHostWlanFeatCaps(DISA) && WDI_getFwWlanFeatCaps(DISA))
    {
      for (i = 0; i < WDI_MAX_KEY_RSC_LEN; i++)
      {
        halSetBssKeyReqMsg.setBssKeyParams.key[keyIndex].keyRsc[i] =
            ~(pwdiSetBSSKeyParams->wdiBSSKeyInfo.aKeys[keyIndex].keyRsc[i]);
      }

      for (i = 0; i < WDI_MAX_KEY_LENGTH; i++)
      {
        halSetBssKeyReqMsg.setBssKeyParams.key[keyIndex].key[i] =
             ~(pwdiSetBSSKeyParams->wdiBSSKeyInfo.aKeys[keyIndex].key[i]);
      }

      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
             "%s: Negated Keys", __func__);
    }
    else
    {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
             "%s: No change in Keys", __func__);
      wpalMemoryCopy(halSetBssKeyReqMsg.setBssKeyParams.key[keyIndex].keyRsc,
                     pwdiSetBSSKeyParams->wdiBSSKeyInfo.aKeys[keyIndex].keyRsc,
                     WDI_MAX_KEY_RSC_LEN);
      wpalMemoryCopy(halSetBssKeyReqMsg.setBssKeyParams.key[keyIndex].key,
                     pwdiSetBSSKeyParams->wdiBSSKeyInfo.aKeys[keyIndex].key,
                     WDI_MAX_KEY_LENGTH);
    }
    halSetBssKeyReqMsg.setBssKeyParams.key[keyIndex].paeRole =
                     pwdiSetBSSKeyParams->wdiBSSKeyInfo.aKeys[keyIndex].paeRole;
    halSetBssKeyReqMsg.setBssKeyParams.key[keyIndex].keyLength =
                   pwdiSetBSSKeyParams->wdiBSSKeyInfo.aKeys[keyIndex].keyLength;
  }

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                    &halSetBssKeyReqMsg.setBssKeyParams,
                    sizeof(halSetBssKeyReqMsg.setBssKeyParams));

  pWDICtx->wdiReqStatusCB     = pwdiSetBSSKeyParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiSetBSSKeyParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Set BSS Key Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiSetBSSKeyRspCb, pEventData->pUserData,
                       WDI_SET_BSS_KEY_RESP);

}/*WDI_ProcessSetBssKeyReq*/

/**
 @brief Process Remove BSS Key Request function (called when Main
        FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessRemoveBssKeyReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_RemoveBSSKeyReqParamsType*  pwdiRemoveBSSKeyParams;
  WDI_RemoveBSSKeyRspCb           wdiRemoveBSSKeyRspCb;
  wpt_uint8                       ucCurrentBSSSesIdx     = 0;
  WDI_BSSSessionType*             pBSSSes                = NULL;
  wpt_uint8*                      pSendBuffer            = NULL;
  wpt_uint16                      usDataOffset           = 0;
  wpt_uint16                      usSendSize             = 0;
  WDI_Status                      wdiStatus              = WDI_STATUS_SUCCESS;
  tRemoveBssKeyReqMsg             halRemoveBssKeyReqMsg  = {{0}};
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiRemoveBSSKeyParams = (WDI_RemoveBSSKeyReqParamsType*)pEventData->pEventData;
  wdiRemoveBSSKeyRspCb   = (WDI_RemoveBSSKeyRspCb)pEventData->pCBfnc;
  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made
  ------------------------------------------------------------------------*/
  ucCurrentBSSSesIdx = WDI_FindAssocSessionByBSSIdx( pWDICtx,
                           pwdiRemoveBSSKeyParams->wdiKeyInfo.ucBssIdx,
                          &pBSSSes);

  if ( NULL == pBSSSes )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "%s: Association sequence for this BSS does not yet exist. ucBssIdx %d", 
              __func__, pwdiRemoveBSSKeyParams->wdiKeyInfo.ucBssIdx);

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Check if this BSS is being currently processed or queued,
    if queued - queue the new request as well
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "%s: Association sequence for this BSS exists but currently queued. ucBssIdx %d",
              __func__, pwdiRemoveBSSKeyParams->wdiKeyInfo.ucBssIdx);

    wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return wdiStatus;
  }


  wpalMutexRelease(&pWDICtx->wptMutex);

  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_RMV_BSS_KEY_REQ,
                        sizeof(halRemoveBssKeyReqMsg.removeBssKeyParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halRemoveBssKeyReqMsg.removeBssKeyParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in set bss key req %p %p %p",
                pEventData, pwdiRemoveBSSKeyParams, wdiRemoveBSSKeyRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  /*-----------------------------------------------------------------------
    Copy the Key parameters into the HAL message
  -----------------------------------------------------------------------*/
  halRemoveBssKeyReqMsg.removeBssKeyParams.bssIdx = ucCurrentBSSSesIdx;

  halRemoveBssKeyReqMsg.removeBssKeyParams.encType =
      WDI_2_HAL_ENC_TYPE (pwdiRemoveBSSKeyParams->wdiKeyInfo.wdiEncType);

  halRemoveBssKeyReqMsg.removeBssKeyParams.keyId = pwdiRemoveBSSKeyParams->wdiKeyInfo.ucKeyId;

  halRemoveBssKeyReqMsg.removeBssKeyParams.wepType =
      WDI_2_HAL_WEP_TYPE(pwdiRemoveBSSKeyParams->wdiKeyInfo.wdiWEPType);

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                    &halRemoveBssKeyReqMsg.removeBssKeyParams,
                    sizeof(halRemoveBssKeyReqMsg.removeBssKeyParams));

  pWDICtx->wdiReqStatusCB     = pwdiRemoveBSSKeyParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiRemoveBSSKeyParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Remove BSS Key Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiRemoveBSSKeyRspCb, pEventData->pUserData,
                       WDI_RMV_BSS_KEY_RESP);
}/*WDI_ProcessRemoveBssKeyReq*/

/**
 @brief Process Set STA KeyRequest function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetStaKeyReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_SetSTAKeyReqParamsType*  pwdiSetSTAKeyParams;
  WDI_SetSTAKeyRspCb           wdiSetSTAKeyRspCb;
  WDI_BSSSessionType*          pBSSSes             = NULL;
  wpt_uint8*                   pSendBuffer         = NULL;
  wpt_uint16                   usDataOffset        = 0;
  wpt_uint16                   usSendSize          = 0;
  WDI_Status                   wdiStatus           = WDI_STATUS_SUCCESS;
  wpt_macAddr                  macBSSID;
  wpt_uint8                    ucCurrentBSSSesIdx;
  tSetStaKeyReqMsg             halSetStaKeyReqMsg  = {{0}};
  wpt_uint8                    keyIndex            = 0;
  wpt_uint8                    i;

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

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

   pwdiSetSTAKeyParams = (WDI_SetSTAKeyReqParamsType*)pEventData->pEventData;
   wdiSetSTAKeyRspCb   = (WDI_SetSTAKeyRspCb)pEventData->pCBfnc;
  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made and identify WDI session
  ------------------------------------------------------------------------*/
  if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx,
                                  pwdiSetSTAKeyParams->wdiKeyInfo.ucSTAIdx,
                                  &macBSSID))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                "This station does not exist in the WDI Station Table %d",
                pwdiSetSTAKeyParams->wdiKeyInfo.ucSTAIdx);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_FAILURE;
  }

  ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes);
  if ( NULL == pBSSSes )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, 
              "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, 
              __func__, MAC_ADDR_ARRAY(macBSSID));

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Check if this BSS is being currently processed or queued,
    if queued - queue the new request as well
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR,
              __func__, MAC_ADDR_ARRAY(macBSSID));

    wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return wdiStatus;
  }


  wpalMutexRelease(&pWDICtx->wptMutex);
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_STA_KEY_REQ,
                        sizeof(halSetStaKeyReqMsg.setStaKeyParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halSetStaKeyReqMsg.setStaKeyParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in set bss key req %p %p %p",
                pEventData, pwdiSetSTAKeyParams, wdiSetSTAKeyRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  /*-----------------------------------------------------------------------
    Copy the STA Key parameters into the HAL message
  -----------------------------------------------------------------------*/
  halSetStaKeyReqMsg.setStaKeyParams.encType =
      WDI_2_HAL_ENC_TYPE (pwdiSetSTAKeyParams->wdiKeyInfo.wdiEncType);

  halSetStaKeyReqMsg.setStaKeyParams.wepType =
      WDI_2_HAL_WEP_TYPE (pwdiSetSTAKeyParams->wdiKeyInfo.wdiWEPType );

  halSetStaKeyReqMsg.setStaKeyParams.staIdx = pwdiSetSTAKeyParams->wdiKeyInfo.ucSTAIdx;

  halSetStaKeyReqMsg.setStaKeyParams.defWEPIdx = pwdiSetSTAKeyParams->wdiKeyInfo.ucDefWEPIdx;

  halSetStaKeyReqMsg.setStaKeyParams.singleTidRc = pwdiSetSTAKeyParams->wdiKeyInfo.ucSingleTidRc;

  for(keyIndex = 0; keyIndex < pwdiSetSTAKeyParams->wdiKeyInfo.ucNumKeys ;
                                                                 keyIndex++)
  {
    halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].keyId =
                      pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].keyId;
    halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].unicast =
                     pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].unicast;
    halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].keyDirection =
                pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].keyDirection;

    if(WDI_getHostWlanFeatCaps(DISA) && WDI_getFwWlanFeatCaps(DISA))
    {
      for (i = 0; i < WDI_MAX_KEY_RSC_LEN; i++)
      {
        halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].keyRsc[i] =
             ~(pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].keyRsc[i]);
      }

      for (i = 0; i< WDI_MAX_KEY_LENGTH; i++)
      {
        halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].key[i] =
             ~(pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].key[i]);
      }

      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
             "%s: Negated Keys", __func__);
    }
    else
    {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
             "%s: No change in Keys", __func__);
      wpalMemoryCopy(halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].keyRsc,
                     pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].keyRsc,
                     WDI_MAX_KEY_RSC_LEN);
      wpalMemoryCopy(halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].key,
                     pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].key,
                     WDI_MAX_KEY_LENGTH);
    }
    halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].paeRole =
                     pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].paeRole;
    halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].keyLength =
                   pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].keyLength;
  }

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                    &halSetStaKeyReqMsg.setStaKeyParams,
                    sizeof(halSetStaKeyReqMsg.setStaKeyParams));

  pWDICtx->wdiReqStatusCB     = pwdiSetSTAKeyParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiSetSTAKeyParams->pUserData;
  wpalMemoryZero(&halSetStaKeyReqMsg, sizeof(halSetStaKeyReqMsg));
  /*-------------------------------------------------------------------------
    Send Set STA Key Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiSetSTAKeyRspCb, pEventData->pUserData,
                       WDI_SET_STA_KEY_RESP);

}/*WDI_ProcessSetSTAKeyReq*/

/**
 @brief Process Remove STA Key Request function (called when
        Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessRemoveStaKeyReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_RemoveSTAKeyReqParamsType*  pwdiRemoveSTAKeyParams;
  WDI_RemoveSTAKeyRspCb           wdiRemoveSTAKeyRspCb;
  WDI_BSSSessionType*             pBSSSes                = NULL;
  wpt_uint8*                      pSendBuffer            = NULL;
  wpt_uint16                      usDataOffset           = 0;
  wpt_uint16                      usSendSize             = 0;
  WDI_Status                      wdiStatus              = WDI_STATUS_SUCCESS;
  wpt_macAddr                     macBSSID;
  wpt_uint8                       ucCurrentBSSSesIdx;
  tRemoveStaKeyReqMsg             halRemoveStaKeyReqMsg  = {{0}};
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
 if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiRemoveSTAKeyParams = (WDI_RemoveSTAKeyReqParamsType*)pEventData->pEventData;
  wdiRemoveSTAKeyRspCb   = (WDI_RemoveSTAKeyRspCb)pEventData->pCBfnc;
  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made and identify WDI session
  ------------------------------------------------------------------------*/
  if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx,
                             pwdiRemoveSTAKeyParams->wdiKeyInfo.ucSTAIdx,
                             &macBSSID))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                "This station does not exist in the WDI Station Table %d",
                pwdiRemoveSTAKeyParams->wdiKeyInfo.ucSTAIdx);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_FAILURE;
  }

  ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes);
  if ( NULL == pBSSSes )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, 
              "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, 
              __func__, MAC_ADDR_ARRAY(macBSSID));

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Check if this BSS is being currently processed or queued,
    if queued - queue the new request as well
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, 
              __func__, MAC_ADDR_ARRAY(macBSSID));

    wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return wdiStatus;
  }



  wpalMutexRelease(&pWDICtx->wptMutex);
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_RMV_STA_KEY_REQ,
                        sizeof(halRemoveStaKeyReqMsg.removeStaKeyParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halRemoveStaKeyReqMsg.removeStaKeyParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in set bss key req %p %p %p",
                pEventData, pwdiRemoveSTAKeyParams, wdiRemoveSTAKeyRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-----------------------------------------------------------------------
    Copy the Key parameters into the HAL message
  -----------------------------------------------------------------------*/

  halRemoveStaKeyReqMsg.removeStaKeyParams.staIdx =
      pwdiRemoveSTAKeyParams->wdiKeyInfo.ucSTAIdx;

  halRemoveStaKeyReqMsg.removeStaKeyParams.encType =
      WDI_2_HAL_ENC_TYPE (pwdiRemoveSTAKeyParams->wdiKeyInfo.wdiEncType);

  halRemoveStaKeyReqMsg.removeStaKeyParams.keyId =
      pwdiRemoveSTAKeyParams->wdiKeyInfo.ucKeyId;

  halRemoveStaKeyReqMsg.removeStaKeyParams.unicast =
      pwdiRemoveSTAKeyParams->wdiKeyInfo.ucUnicast;

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                    &halRemoveStaKeyReqMsg.removeStaKeyParams,
                    sizeof(halRemoveStaKeyReqMsg.removeStaKeyParams));

  pWDICtx->wdiReqStatusCB     = pwdiRemoveSTAKeyParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiRemoveSTAKeyParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Remove STA Key Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiRemoveSTAKeyRspCb, pEventData->pUserData,
                       WDI_RMV_STA_KEY_RESP);

}/*WDI_ProcessRemoveSTAKeyReq*/

/**
 @brief Process Set STA KeyRequest function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetStaBcastKeyReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_SetSTAKeyReqParamsType*  pwdiSetSTAKeyParams;
  WDI_SetSTAKeyRspCb           wdiSetSTAKeyRspCb;
  WDI_BSSSessionType*          pBSSSes             = NULL;
  wpt_uint8*                   pSendBuffer         = NULL;
  wpt_uint16                   usDataOffset        = 0;
  wpt_uint16                   usSendSize          = 0;
  WDI_Status                   wdiStatus           = WDI_STATUS_SUCCESS;
  wpt_macAddr                  macBSSID;
  wpt_uint8                    ucCurrentBSSSesIdx;
  tSetStaKeyReqMsg             halSetStaKeyReqMsg  = {{0}};
  wpt_uint8                    keyIndex            = 0;
  wpt_uint8                    i;

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

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

   pwdiSetSTAKeyParams = (WDI_SetSTAKeyReqParamsType*)pEventData->pEventData;
   wdiSetSTAKeyRspCb   = (WDI_SetSTAKeyRspCb)pEventData->pCBfnc;
  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made and identify WDI session
  ------------------------------------------------------------------------*/
  if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx,
                                  pwdiSetSTAKeyParams->wdiKeyInfo.ucSTAIdx,
                                  &macBSSID))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                "This station does not exist in the WDI Station Table %d",
                pwdiSetSTAKeyParams->wdiKeyInfo.ucSTAIdx);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_FAILURE;
  }

  ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes);
  if ( NULL == pBSSSes )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR,
              __func__, MAC_ADDR_ARRAY(macBSSID));

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Check if this BSS is being currently processed or queued,
    if queued - queue the new request as well
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR,
              __func__, MAC_ADDR_ARRAY(macBSSID));

    wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return wdiStatus;
  }


  wpalMutexRelease(&pWDICtx->wptMutex);
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_STA_KEY_REQ,
                        sizeof(halSetStaKeyReqMsg.setStaKeyParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halSetStaKeyReqMsg.setStaKeyParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in set bss key req %p %p %p",
                pEventData, pwdiSetSTAKeyParams, wdiSetSTAKeyRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  /*-----------------------------------------------------------------------
    Copy the STA Key parameters into the HAL message
  -----------------------------------------------------------------------*/
  halSetStaKeyReqMsg.setStaKeyParams.encType =
      WDI_2_HAL_ENC_TYPE (pwdiSetSTAKeyParams->wdiKeyInfo.wdiEncType);

  halSetStaKeyReqMsg.setStaKeyParams.wepType =
      WDI_2_HAL_WEP_TYPE (pwdiSetSTAKeyParams->wdiKeyInfo.wdiWEPType );

  halSetStaKeyReqMsg.setStaKeyParams.staIdx = pwdiSetSTAKeyParams->wdiKeyInfo.ucSTAIdx;

  halSetStaKeyReqMsg.setStaKeyParams.defWEPIdx = pwdiSetSTAKeyParams->wdiKeyInfo.ucDefWEPIdx;

  halSetStaKeyReqMsg.setStaKeyParams.singleTidRc = pwdiSetSTAKeyParams->wdiKeyInfo.ucSingleTidRc;

  for(keyIndex = 0; keyIndex < pwdiSetSTAKeyParams->wdiKeyInfo.ucNumKeys ;
                                                                 keyIndex++)
  {
    halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].keyId =
                      pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].keyId;
    halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].unicast =
                     pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].unicast;
    halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].keyDirection =
                pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].keyDirection;

    if(WDI_getHostWlanFeatCaps(DISA) && WDI_getFwWlanFeatCaps(DISA))
    {
      for (i = 0; i < WDI_MAX_KEY_RSC_LEN; i++)
      {
        halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].keyRsc[i] =
             ~(pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].keyRsc[i]);
      }

      for (i = 0; i< WDI_MAX_KEY_LENGTH; i++)
      {
        halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].key[i] =
             ~(pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].key[i]);
      }

      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
             "%s: Negated Keys", __func__);
    }
    else
    {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
             "%s: No change in Keys", __func__);
      wpalMemoryCopy(halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].keyRsc,
                     pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].keyRsc,
                     WDI_MAX_KEY_RSC_LEN);
      wpalMemoryCopy(halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].key,
                     pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].key,
                     WDI_MAX_KEY_LENGTH);
    }
    halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].paeRole =
                     pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].paeRole;
    halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].keyLength =
                   pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].keyLength;
  }
  wpalMemoryCopy( pSendBuffer+usDataOffset,
                    &halSetStaKeyReqMsg.setStaKeyParams,
                    sizeof(halSetStaKeyReqMsg.setStaKeyParams));

  pWDICtx->wdiReqStatusCB     = pwdiSetSTAKeyParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiSetSTAKeyParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Set STA Key Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiSetSTAKeyRspCb, pEventData->pUserData,
                       WDI_SET_STA_KEY_RESP);

}/*WDI_ProcessSetSTABcastKeyReq*/

/**
 @brief Process Remove STA Key Request function (called when
        Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessRemoveStaBcastKeyReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_RemoveSTAKeyReqParamsType*  pwdiRemoveSTABcastKeyParams;
  WDI_RemoveSTAKeyRspCb           wdiRemoveSTAKeyRspCb;
  WDI_BSSSessionType*             pBSSSes                = NULL;
  wpt_uint8*                      pSendBuffer            = NULL;
  wpt_uint16                      usDataOffset           = 0;
  wpt_uint16                      usSendSize             = 0;
  WDI_Status                      wdiStatus              = WDI_STATUS_SUCCESS;
  wpt_macAddr                     macBSSID;
  wpt_uint8                       ucCurrentBSSSesIdx;
  tRemoveStaKeyReqMsg             halRemoveStaBcastKeyReqMsg = {{0}};
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
 if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiRemoveSTABcastKeyParams = (WDI_RemoveSTAKeyReqParamsType*)pEventData->pEventData;
  wdiRemoveSTAKeyRspCb   = (WDI_RemoveSTAKeyRspCb)pEventData->pCBfnc;
  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made and identify WDI session
  ------------------------------------------------------------------------*/
  if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx,
                             pwdiRemoveSTABcastKeyParams->wdiKeyInfo.ucSTAIdx,
                             &macBSSID))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                "This station does not exist in the WDI Station Table %d",
                pwdiRemoveSTABcastKeyParams->wdiKeyInfo.ucSTAIdx);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_FAILURE;
  }

  ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes);
  if ( NULL == pBSSSes )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, 
              "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, 
              __func__, MAC_ADDR_ARRAY(macBSSID));

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Check if this BSS is being currently processed or queued,
    if queued - queue the new request as well
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, 
               __func__, MAC_ADDR_ARRAY(macBSSID));

    wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return wdiStatus;
  }



  wpalMutexRelease(&pWDICtx->wptMutex);
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_RMV_STA_BCAST_KEY_REQ,
                        sizeof(halRemoveStaBcastKeyReqMsg.removeStaKeyParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halRemoveStaBcastKeyReqMsg.removeStaKeyParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in set bss key req %p %p %p",
                pEventData, pwdiRemoveSTABcastKeyParams, wdiRemoveSTAKeyRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-----------------------------------------------------------------------
    Copy the Key parameters into the HAL message
  -----------------------------------------------------------------------*/

  halRemoveStaBcastKeyReqMsg.removeStaKeyParams.staIdx =
      pwdiRemoveSTABcastKeyParams->wdiKeyInfo.ucSTAIdx;

  halRemoveStaBcastKeyReqMsg.removeStaKeyParams.encType =
      WDI_2_HAL_ENC_TYPE (pwdiRemoveSTABcastKeyParams->wdiKeyInfo.wdiEncType);

  halRemoveStaBcastKeyReqMsg.removeStaKeyParams.keyId =
      pwdiRemoveSTABcastKeyParams->wdiKeyInfo.ucKeyId;

  halRemoveStaBcastKeyReqMsg.removeStaKeyParams.unicast =
      pwdiRemoveSTABcastKeyParams->wdiKeyInfo.ucUnicast;

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                    &halRemoveStaBcastKeyReqMsg.removeStaKeyParams,
                    sizeof(halRemoveStaBcastKeyReqMsg.removeStaKeyParams));

  pWDICtx->wdiReqStatusCB     = pwdiRemoveSTABcastKeyParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiRemoveSTABcastKeyParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Remove STA Key Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiRemoveSTAKeyRspCb, pEventData->pUserData,
                       WDI_RMV_STA_KEY_RESP);

}/*WDI_ProcessRemoveSTABcastKeyReq*/

/*==========================================================================
                   QOS and BA PROCESSING REQUEST API
==========================================================================*/
/**
 @brief Process Add TSpec Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessAddTSpecReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_AddTSReqParamsType*  pwdiAddTSParams;
  WDI_AddTsRspCb           wdiAddTSRspCb;
  wpt_uint8                ucCurrentBSSSesIdx  = 0;
  WDI_BSSSessionType*      pBSSSes             = NULL;
  wpt_uint8*               pSendBuffer         = NULL;
  wpt_uint16               usDataOffset        = 0;
  wpt_uint16               usSendSize          = 0;
  WDI_Status               wdiStatus           = WDI_STATUS_SUCCESS;
  wpt_macAddr              macBSSID;
  tAddTsParams             halAddTsParams      = {0};

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

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiAddTSParams = (WDI_AddTSReqParamsType*)pEventData->pEventData;
  wdiAddTSRspCb   = (WDI_AddTsRspCb)pEventData->pCBfnc;
  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made and identify WDI session
  ------------------------------------------------------------------------*/
  if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx,
                                        pwdiAddTSParams->wdiTsInfo.ucSTAIdx,
                                        &macBSSID))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                "This station does not exist in the WDI Station Table %d",
                pwdiAddTSParams->wdiTsInfo.ucSTAIdx);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_FAILURE;
  }

  ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes);
  if ( NULL == pBSSSes )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, 
              "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, 
              __func__, MAC_ADDR_ARRAY(macBSSID));

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Check if this BSS is being currently processed or queued,
    if queued - queue the new request as well
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR,
              __func__, MAC_ADDR_ARRAY(macBSSID));

    wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return wdiStatus;
  }

  wpalMutexRelease(&pWDICtx->wptMutex);
  /*-----------------------------------------------------------------------
    Get message buffer
    ! TO DO : proper conversion into the HAL Message Request Format
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_ADD_TS_REQ,
                                                    sizeof(halAddTsParams),
                                                    &pSendBuffer, &usDataOffset,
                                                    &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halAddTsParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in set bss key req %p %p %p",
                pEventData, pwdiAddTSParams, wdiAddTSRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  halAddTsParams.staIdx = pwdiAddTSParams->wdiTsInfo.ucSTAIdx;
  halAddTsParams.tspecIdx = pwdiAddTSParams->wdiTsInfo.ucTspecIdx;

  //TSPEC IE
  halAddTsParams.tspec.type = pwdiAddTSParams->wdiTsInfo.wdiTspecIE.ucType;
  halAddTsParams.tspec.length = pwdiAddTSParams->wdiTsInfo.wdiTspecIE.ucLength;
  halAddTsParams.tspec.nomMsduSz =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.usNomMsduSz;
  halAddTsParams.tspec.maxMsduSz =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.usMaxMsduSz;
  halAddTsParams.tspec.minSvcInterval =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.uMinSvcInterval;
  halAddTsParams.tspec.maxSvcInterval =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.uMaxSvcInterval;
  halAddTsParams.tspec.inactInterval =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.uInactInterval;
  halAddTsParams.tspec.suspendInterval =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.uSuspendInterval;
  halAddTsParams.tspec.svcStartTime =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.uSvcStartTime;
  halAddTsParams.tspec.minDataRate =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.uMinDataRate;
  halAddTsParams.tspec.meanDataRate =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.uMeanDataRate;
  halAddTsParams.tspec.peakDataRate =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.uPeakDataRate;
  halAddTsParams.tspec.maxBurstSz =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.uMaxBurstSz;
  halAddTsParams.tspec.delayBound =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.uDelayBound;
  halAddTsParams.tspec.minPhyRate =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.uMinPhyRate;
  halAddTsParams.tspec.surplusBw =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.usSurplusBw;
  halAddTsParams.tspec.mediumTime =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.usMediumTime;

  //TSPEC IE : TS INFO : TRAFFIC
  halAddTsParams.tspec.tsinfo.traffic.ackPolicy =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiTraffic.accessPolicy;
  halAddTsParams.tspec.tsinfo.traffic.userPrio =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiTraffic.userPrio;
  halAddTsParams.tspec.tsinfo.traffic.psb =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiTraffic.psb;
  halAddTsParams.tspec.tsinfo.traffic.aggregation =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiTraffic.aggregation;
  halAddTsParams.tspec.tsinfo.traffic.direction =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiTraffic.direction;
  halAddTsParams.tspec.tsinfo.traffic.tsid =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiTraffic.tsid;
  halAddTsParams.tspec.tsinfo.traffic.trafficType =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiTraffic.trafficType;

  //TSPEC IE : TS INFO : SCHEDULE
  halAddTsParams.tspec.tsinfo.schedule.rsvd =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiSchedule.rsvd;
  halAddTsParams.tspec.tsinfo.schedule.schedule =
     pwdiAddTSParams->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiSchedule.schedule;

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halAddTsParams,
                  sizeof(halAddTsParams));

  pWDICtx->wdiReqStatusCB     = pwdiAddTSParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiAddTSParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Add TS Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiAddTSRspCb, pEventData->pUserData,
                       WDI_ADD_TS_RESP);
}/*WDI_ProcessAddTSpecReq*/


/**
 @brief Process Del TSpec Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessDelTSpecReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_DelTSReqParamsType*      pwdiDelTSParams;
  WDI_DelTsRspCb               wdiDelTSRspCb;
  wpt_uint8                    ucCurrentBSSSesIdx  = 0;
  WDI_BSSSessionType*          pBSSSes             = NULL;
  wpt_uint8*                   pSendBuffer         = NULL;
  wpt_uint16                   usDataOffset        = 0;
  wpt_uint16                   usSendSize          = 0;
  WDI_Status                   wdiStatus           = WDI_STATUS_SUCCESS;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiDelTSParams = (WDI_DelTSReqParamsType*)pEventData->pEventData;
  wdiDelTSRspCb   = (WDI_DelTsRspCb)pEventData->pCBfnc;

  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made
  ------------------------------------------------------------------------*/
  ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx,
                           pwdiDelTSParams->wdiDelTSInfo.macBSSID,
                          &pBSSSes);

  if ( NULL == pBSSSes )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, 
            "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, 
            __func__, MAC_ADDR_ARRAY(pwdiDelTSParams->wdiDelTSInfo.macBSSID));
    
    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Check if this BSS is being currently processed or queued,
    if queued - queue the new request as well
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, 
              __func__, MAC_ADDR_ARRAY(pwdiDelTSParams->wdiDelTSInfo.macBSSID));

    wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return wdiStatus;
  }


  wpalMutexRelease(&pWDICtx->wptMutex);
  /*-----------------------------------------------------------------------
    Get message buffer
    ! TO DO : proper conversion into the HAL Message Request Format
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_DEL_TS_REQ,
                        sizeof(pwdiDelTSParams->wdiDelTSInfo),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(pwdiDelTSParams->wdiDelTSInfo) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in set bss key req %p %p %p",
                pEventData, pwdiDelTSParams, wdiDelTSRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &pwdiDelTSParams->wdiDelTSInfo,
                  sizeof(pwdiDelTSParams->wdiDelTSInfo));

  pWDICtx->wdiReqStatusCB     = pwdiDelTSParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiDelTSParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Del TS Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiDelTSRspCb, pEventData->pUserData, WDI_DEL_TS_RESP);
}/*WDI_ProcessDelTSpecReq*/

/**
 @brief Process Update EDCA Params Request function (called when
        Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessUpdateEDCAParamsReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_UpdateEDCAParamsType*    pwdiUpdateEDCAParams;
  WDI_UpdateEDCAParamsRspCb    wdiUpdateEDCARspCb;
  wpt_uint8                    ucCurrentBSSSesIdx  = 0;
  WDI_BSSSessionType*          pBSSSes             = NULL;
  wpt_uint8*                   pSendBuffer         = NULL;
  wpt_uint16                   usDataOffset         = 0;
  wpt_uint16                   usSendSize           = 0;
  WDI_Status                   wdiStatus;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiUpdateEDCAParams = (WDI_UpdateEDCAParamsType*)pEventData->pEventData;
  wdiUpdateEDCARspCb   = (WDI_UpdateEDCAParamsRspCb)pEventData->pCBfnc;
  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made
  ------------------------------------------------------------------------*/
  ucCurrentBSSSesIdx = WDI_FindAssocSessionByBSSIdx( pWDICtx,
                           pwdiUpdateEDCAParams->wdiEDCAInfo.ucBssIdx,
                          &pBSSSes);

  if ( NULL == pBSSSes )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
            "%s: Association sequence for this BSS does not yet exist. ucBssIdx %d", 
            __func__, pwdiUpdateEDCAParams->wdiEDCAInfo.ucBssIdx);

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Check if this BSS is being currently processed or queued,
    if queued - queue the new request as well
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "%s: Association sequence for this BSS exists but currently queued. ucBssIdx %d",
              __func__, pwdiUpdateEDCAParams->wdiEDCAInfo.ucBssIdx);

    wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return wdiStatus;
  }


  wpalMutexRelease(&pWDICtx->wptMutex);
  /*-----------------------------------------------------------------------
    Get message buffer
    ! TO DO : proper conversion into the HAL Message Request Format
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_UPD_EDCA_PRMS_REQ,
                        sizeof(pwdiUpdateEDCAParams->wdiEDCAInfo),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(pwdiUpdateEDCAParams->wdiEDCAInfo) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in set bss key req %p %p %p",
                pEventData, pwdiUpdateEDCAParams, wdiUpdateEDCARspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &pwdiUpdateEDCAParams->wdiEDCAInfo,
                  sizeof(pwdiUpdateEDCAParams->wdiEDCAInfo));

  pWDICtx->wdiReqStatusCB     = pwdiUpdateEDCAParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiUpdateEDCAParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Update EDCA Params Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiUpdateEDCARspCb, pEventData->pUserData,
                       WDI_UPD_EDCA_PRMS_RESP);
}/*WDI_ProcessUpdateEDCAParamsReq*/

/**
 @brief Process Add BA Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessAddBASessionReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_AddBASessionReqParamsType*  pwdiAddBASessionParams;
  WDI_AddBASessionRspCb           wdiAddBASessionRspCb;
  wpt_uint8                       ucCurrentBSSSesIdx  = 0;
  WDI_BSSSessionType*             pBSSSes             = NULL;
  wpt_uint8*                      pSendBuffer         = NULL;
  wpt_uint16                      usDataOffset        = 0;
  wpt_uint16                      usSendSize          = 0;
  WDI_Status                      wdiStatus           = WDI_STATUS_SUCCESS;
  wpt_macAddr                     macBSSID;

  tAddBASessionReqMsg             halAddBASessionReq;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiAddBASessionParams =
                  (WDI_AddBASessionReqParamsType*)pEventData->pEventData;
  wdiAddBASessionRspCb =
                  (WDI_AddBASessionRspCb)pEventData->pCBfnc;
  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made
  ------------------------------------------------------------------------*/
  if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx,
                   pwdiAddBASessionParams->wdiBASessionInfoType.ucSTAIdx,
                   &macBSSID))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                "This station does not exist in the WDI Station Table %d",
                pwdiAddBASessionParams->wdiBASessionInfoType.ucSTAIdx);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_FAILURE;
  }


  ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes);

  if ( NULL == pBSSSes )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, 
          "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, 
          __func__, MAC_ADDR_ARRAY(macBSSID));
      
    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Check if this BSS is being currently processed or queued,
    if queued - queue the new request as well
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, 
               __func__, MAC_ADDR_ARRAY(macBSSID));

    wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return wdiStatus;
  }


  wpalMutexRelease(&pWDICtx->wptMutex);
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                        WDI_ADD_BA_SESSION_REQ,
                        sizeof(halAddBASessionReq.addBASessionParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize <
            (usDataOffset + sizeof(halAddBASessionReq.addBASessionParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in Add BA session req %p %p %p",
                pEventData, pwdiAddBASessionParams, wdiAddBASessionRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  halAddBASessionReq.addBASessionParams.staIdx =
                  pwdiAddBASessionParams->wdiBASessionInfoType.ucSTAIdx;
  wpalMemoryCopy(halAddBASessionReq.addBASessionParams.peerMacAddr,
                  pwdiAddBASessionParams->wdiBASessionInfoType.macPeerAddr,
                  WDI_MAC_ADDR_LEN);
  halAddBASessionReq.addBASessionParams.baTID =
                  pwdiAddBASessionParams->wdiBASessionInfoType.ucBaTID;
  halAddBASessionReq.addBASessionParams.baPolicy =
                  pwdiAddBASessionParams->wdiBASessionInfoType.ucBaPolicy;
  halAddBASessionReq.addBASessionParams.baBufferSize =
                  pwdiAddBASessionParams->wdiBASessionInfoType.usBaBufferSize;
  halAddBASessionReq.addBASessionParams.baTimeout =
                  pwdiAddBASessionParams->wdiBASessionInfoType.usBaTimeout;
  halAddBASessionReq.addBASessionParams.baSSN =
                  pwdiAddBASessionParams->wdiBASessionInfoType.usBaSSN;
  halAddBASessionReq.addBASessionParams.baDirection =
                  pwdiAddBASessionParams->wdiBASessionInfoType.ucBaDirection;

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halAddBASessionReq.addBASessionParams,
                  sizeof(halAddBASessionReq.addBASessionParams));

  pWDICtx->wdiReqStatusCB     = pwdiAddBASessionParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiAddBASessionParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Start Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiAddBASessionRspCb, pEventData->pUserData,
                        WDI_ADD_BA_SESSION_RESP);
}/*WDI_ProcessAddBASessionReq*/

/**
 @brief Process Del BA Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessDelBAReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_DelBAReqParamsType*      pwdiDelBAParams;
  WDI_DelBARspCb               wdiDelBARspCb;
  wpt_uint8                    ucCurrentBSSSesIdx  = 0;
  WDI_BSSSessionType*          pBSSSes             = NULL;
  wpt_uint8*                   pSendBuffer         = NULL;
  wpt_uint16                   usDataOffset        = 0;
  wpt_uint16                   usSendSize          = 0;
  WDI_Status                   wdiStatus           = WDI_STATUS_SUCCESS;
  wpt_macAddr                  macBSSID;
  tDelBAParams                 halDelBAparam;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiDelBAParams = (WDI_DelBAReqParamsType*)pEventData->pEventData;
  wdiDelBARspCb   = (WDI_DelBARspCb)pEventData->pCBfnc;
  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made
  ------------------------------------------------------------------------*/
  if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx,
                                     pwdiDelBAParams->wdiBAInfo.ucSTAIdx,
                                     &macBSSID))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                "This station does not exist in the WDI Station Table %d",
                pwdiDelBAParams->wdiBAInfo.ucSTAIdx);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_FAILURE;
  }

  ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes);

  if ( NULL == pBSSSes )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, 
            "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, 
            __func__, MAC_ADDR_ARRAY(macBSSID));

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Check if this BSS is being currently processed or queued,
    if queued - queue the new request as well
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR,
              __func__, MAC_ADDR_ARRAY(macBSSID));

    wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return wdiStatus;
  }

  wpalMutexRelease(&pWDICtx->wptMutex);
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_DEL_BA_REQ,
                        sizeof(halDelBAparam),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halDelBAparam) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer for DEL BA req %p %p %p",
                pEventData, pwdiDelBAParams, wdiDelBARspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  halDelBAparam.staIdx = pwdiDelBAParams->wdiBAInfo.ucSTAIdx;
  halDelBAparam.baTID = pwdiDelBAParams->wdiBAInfo.ucBaTID;
  halDelBAparam.baDirection = pwdiDelBAParams->wdiBAInfo.ucBaDirection;

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halDelBAparam,
                  sizeof(halDelBAparam));

  pWDICtx->wdiReqStatusCB     = pwdiDelBAParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiDelBAParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Start Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiDelBARspCb, pEventData->pUserData, WDI_DEL_BA_RESP);
}/*WDI_ProcessDelBAReq*/

#ifdef FEATURE_WLAN_ESE

WDI_Status
WDI_ProcessTSMStatsReq
( 
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_TSMStatsReqParamsType*  pwdiTSMParams;
  WDI_TsmRspCb                wdiTSMRspCb;
  wpt_uint8                   ucCurrentBSSSesIdx   = 0; 
  WDI_BSSSessionType*         pBSSSes              = NULL;
  wpt_uint8*                  pSendBuffer          = NULL; 
  wpt_uint16                  usDataOffset         = 0;
  wpt_uint16                  usSendSize           = 0;
  WDI_Status                  wdiStatus            = WDI_STATUS_SUCCESS; 
  tTsmStatsParams             halTsmStatsReqParams = {0};
  
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
       Sanity check 
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE; 
  }

  pwdiTSMParams = (WDI_TSMStatsReqParamsType*)pEventData->pEventData;
  wdiTSMRspCb   = (WDI_TsmRspCb)pEventData->pCBfnc;
  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request 
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, pwdiTSMParams->wdiTsmStatsParamsInfo.bssid, &pBSSSes); 
  if ( NULL == pBSSSes ) 
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, 
            "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, 
            __func__, MAC_ADDR_ARRAY(pwdiTSMParams->wdiTsmStatsParamsInfo.bssid));

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED; 
  }

  /*------------------------------------------------------------------------
    Check if this BSS is being currently processed or queued,
    if queued - queue the new request as well 
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR,
              __func__, MAC_ADDR_ARRAY(pwdiTSMParams->wdiTsmStatsParamsInfo.bssid));

    wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); 
    wpalMutexRelease(&pWDICtx->wptMutex);
    return wdiStatus; 
  }

  wpalMutexRelease(&pWDICtx->wptMutex);
  /*-----------------------------------------------------------------------
    Get message buffer
    ! TO DO : proper conversion into the HAL Message Request Format 
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_TSM_STATS_REQ, 
                                                    sizeof(halTsmStatsReqParams), 
                                                    &pSendBuffer, &usDataOffset,                                                     &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halTsmStatsReqParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Unable to get send buffer in set bss key req %p %p %p",
                pEventData, pwdiTSMParams, wdiTSMRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE; 
  }

  halTsmStatsReqParams.tsmTID = pwdiTSMParams->wdiTsmStatsParamsInfo.ucTid;
  wpalMemoryCopy(halTsmStatsReqParams.bssId,
                 pwdiTSMParams->wdiTsmStatsParamsInfo.bssid,
                 WDI_MAC_ADDR_LEN);
  wpalMemoryCopy( pSendBuffer+usDataOffset, 
                  &halTsmStatsReqParams, 
                  sizeof(halTsmStatsReqParams)); 

  pWDICtx->wdiReqStatusCB     = pwdiTSMParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiTSMParams->pUserData; 

  /*-------------------------------------------------------------------------
    Send TSM Stats Request to HAL 
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, 
                       wdiTSMRspCb, pEventData->pUserData,
                       WDI_TSM_STATS_RESP); 
}/*WDI_ProcessTSMStatsReq*/

#endif


/**
 @brief Process Flush AC Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessFlushAcReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_FlushAcReqParamsType*    pwdiFlushAcParams = NULL;
   WDI_FlushAcRspCb             wdiFlushAcRspCb;
   wpt_uint8*                   pSendBuffer         = NULL;
   wpt_uint16                   usDataOffset        = 0;
   wpt_uint16                   usSendSize          = 0;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
       ( NULL == pEventData->pCBfnc ))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   pwdiFlushAcParams = (WDI_FlushAcReqParamsType*)pEventData->pEventData;
   wdiFlushAcRspCb   = (WDI_FlushAcRspCb)pEventData->pCBfnc;
   /*-----------------------------------------------------------------------
     Get message buffer
     ! TO DO : proper conversion into the HAL Message Request Format
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_FLUSH_AC_REQ,
                         sizeof(pwdiFlushAcParams->wdiFlushAcInfo),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(pwdiFlushAcParams->wdiFlushAcInfo) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "Unable to get send buffer in set bss key req %p %p %p",
                 pEventData, pwdiFlushAcParams, wdiFlushAcRspCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wpalMemoryCopy( pSendBuffer+usDataOffset,
                   &pwdiFlushAcParams->wdiFlushAcInfo,
                   sizeof(pwdiFlushAcParams->wdiFlushAcInfo));

   pWDICtx->wdiReqStatusCB     = pwdiFlushAcParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiFlushAcParams->pUserData;

   /*-------------------------------------------------------------------------
     Send Start Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiFlushAcRspCb, pEventData->pUserData, WDI_FLUSH_AC_RESP);
}/*WDI_ProcessFlushAcReq*/

/**
 @brief Process BT AMP event Request function (called when Main
        FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessBtAmpEventReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_BtAmpEventParamsType*    pwdiBtAmpEventParams = NULL;
   WDI_BtAmpEventRspCb          wdiBtAmpEventRspCb;
   wpt_uint8*                   pSendBuffer         = NULL;
   wpt_uint16                   usDataOffset        = 0;
   wpt_uint16                   usSendSize          = 0;

   tBtAmpEventMsg               haltBtAmpEventMsg;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
       ( NULL == pEventData->pCBfnc ))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   pwdiBtAmpEventParams = (WDI_BtAmpEventParamsType*)pEventData->pEventData;
   wdiBtAmpEventRspCb   = (WDI_BtAmpEventRspCb)pEventData->pCBfnc;
   /*-----------------------------------------------------------------------
     Get message buffer
     ! TO DO : proper conversion into the HAL Message Request Format
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_BTAMP_EVENT_REQ,
                         sizeof(haltBtAmpEventMsg.btAmpEventParams),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(haltBtAmpEventMsg.btAmpEventParams) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "Unable to get send buffer in BT AMP event req %p %p %p",
                 pEventData, pwdiBtAmpEventParams, wdiBtAmpEventRspCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   haltBtAmpEventMsg.btAmpEventParams.btAmpEventType =
      pwdiBtAmpEventParams->wdiBtAmpEventInfo.ucBtAmpEventType;
   wpalMemoryCopy( pSendBuffer+usDataOffset,
                   &haltBtAmpEventMsg.btAmpEventParams,
                   sizeof(haltBtAmpEventMsg.btAmpEventParams));

   pWDICtx->wdiReqStatusCB     = pwdiBtAmpEventParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiBtAmpEventParams->pUserData;

   /*-------------------------------------------------------------------------
     Send Start Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiBtAmpEventRspCb, pEventData->pUserData, WDI_BTAMP_EVENT_RESP);
}/*WDI_ProcessBtAmpEventReq*/

/**
 @brief Process Add STA self Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessAddSTASelfReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_AddSTASelfReqParamsType*          pwdiAddSTASelfReqParams;
  WDI_AddSTASelfParamsRspCb             wdiAddSTASelfReqRspCb;
  wpt_uint8*                            pSendBuffer         = NULL;
  wpt_uint16                            usDataOffset        = 0;
  wpt_uint16                            usSendSize          = 0;
  tAddStaSelfParams_V1                  halAddSTASelfParams;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData) ||
      ( NULL == pEventData->pCBfnc))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiAddSTASelfReqParams =
    (WDI_AddSTASelfReqParamsType*)pEventData->pEventData;
  wdiAddSTASelfReqRspCb =
    (WDI_AddSTASelfParamsRspCb)pEventData->pCBfnc;
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                        WDI_ADD_STA_SELF_REQ,
                        sizeof(tAddStaSelfParams_V1),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(tAddStaSelfParams_V1) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in ADD STA SELF REQ %p %p %p",
     pEventData, pwdiAddSTASelfReqParams, wdiAddSTASelfReqRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /* Cache the request for response processing */
  wpalMemoryCopy(&pWDICtx->wdiCacheAddSTASelfReq, pwdiAddSTASelfReqParams,
                 sizeof(pWDICtx->wdiCacheAddSTASelfReq));

  wpalMemoryCopy(halAddSTASelfParams.selfMacAddr,
                   pwdiAddSTASelfReqParams->wdiAddSTASelfInfo.selfMacAddr, 6);
  halAddSTASelfParams.iface_persona = HAL_IFACE_UNKNOWN;
  if (pwdiAddSTASelfReqParams->wdiAddSTASelfInfo.currDeviceMode == VOS_STA_MODE)
  {
      halAddSTASelfParams.iface_persona = HAL_IFACE_STA_MODE;
  }
  else if ((pwdiAddSTASelfReqParams->wdiAddSTASelfInfo.currDeviceMode ==
                          VOS_P2P_CLIENT_MODE) ||
          (pwdiAddSTASelfReqParams->wdiAddSTASelfInfo.currDeviceMode ==
                          VOS_P2P_DEVICE))
  {
      halAddSTASelfParams.iface_persona = HAL_IFACE_P2P_MODE;
  }
  wpalMemoryCopy( pSendBuffer+usDataOffset, &halAddSTASelfParams,
                                         sizeof(tAddStaSelfParams_V1));

  pWDICtx->wdiReqStatusCB     = pwdiAddSTASelfReqParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiAddSTASelfReqParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Update Probe Resp Template Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiAddSTASelfReqRspCb, pEventData->pUserData,
                       WDI_ADD_STA_SELF_RESP);
}/*WDI_ProcessAddSTASelfReq*/



/**
 @brief Process Del Sta Self Request function (called when Main
        FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessDelSTASelfReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_DelSTASelfReqParamsType*      pwdiDelStaSelfReqParams;
  WDI_DelSTASelfRspCb               wdiDelStaSelfRspCb;
  wpt_uint8*                   pSendBuffer         = NULL;
  wpt_uint16                   usDataOffset        = 0;
  wpt_uint16                   usSendSize          = 0;
  tDelStaSelfParams            halSetDelSelfSTAParams;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiDelStaSelfReqParams =
                 (WDI_DelSTASelfReqParamsType*)pEventData->pEventData;
  wdiDelStaSelfRspCb      = (WDI_DelSTASelfRspCb)pEventData->pCBfnc;

   /*-----------------------------------------------------------------------
     Get message buffer
     ! TO DO : proper conversion into the HAL Message Request Format
   -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_DEL_STA_SELF_REQ,
                         sizeof(pwdiDelStaSelfReqParams->wdiDelStaSelfInfo),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
    ( usSendSize <
         (usDataOffset + sizeof(pwdiDelStaSelfReqParams->wdiDelStaSelfInfo) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "Unable to get send buffer in Del Sta Self req %p %p %p",
                 pEventData, pwdiDelStaSelfReqParams, wdiDelStaSelfRspCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
  }

  wpalMemoryCopy(halSetDelSelfSTAParams.selfMacAddr,
                   pwdiDelStaSelfReqParams->wdiDelStaSelfInfo.selfMacAddr, 6) ;

  wpalMemoryCopy( pSendBuffer+usDataOffset, &halSetDelSelfSTAParams,
                                         sizeof(tDelStaSelfParams));

  pWDICtx->wdiReqStatusCB     = pwdiDelStaSelfReqParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiDelStaSelfReqParams->pUserData;

  /*-------------------------------------------------------------------------
     Send Start Request to HAL
   -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiDelStaSelfRspCb, pEventData->pUserData,
                                                     WDI_DEL_STA_SELF_RESP);

}

#ifdef FEATURE_OEM_DATA_SUPPORT
/**
 @brief Process Start Oem Data Request function (called when Main 
        FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessStartOemDataReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_oemDataReqParamsType*    pwdiOemDataReqParams = NULL;
  WDI_oemDataRspCb             wdiOemDataRspCb;
  wpt_uint8*                   pSendBuffer         = NULL; 
  wpt_uint16                   usDataOffset        = 0;
  wpt_uint16                   usSendSize          = 0;
  wpt_uint16                   reqLen;
  tStartOemDataReqParams*      halStartOemDataReqParams;

  /*-------------------------------------------------------------------------
  Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
  }

  pwdiOemDataReqParams = (WDI_oemDataReqParamsType*)pEventData->pEventData;
  wdiOemDataRspCb   = (WDI_oemDataRspCb)pEventData->pCBfnc;

  /*-----------------------------------------------------------------------
     Get message buffer
   -----------------------------------------------------------------------*/

  reqLen = sizeof(tStartOemDataReqParams);

  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, 
                         WDI_START_OEM_DATA_REQ, reqLen,
                              &pSendBuffer, &usDataOffset, &usSendSize))||
        (usSendSize < (usDataOffset + reqLen)))
  {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "Unable to get send buffer in Start Oem Data req %p %p %p",
                 pEventData, pwdiOemDataReqParams, wdiOemDataRspCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
  }

  //copying WDI OEM DATA REQ PARAMS to shared memory
  halStartOemDataReqParams = (tStartOemDataReqParams *)(pSendBuffer + usDataOffset );

  wpalMemoryCopy(&halStartOemDataReqParams->selfMacAddr, &pwdiOemDataReqParams->wdiOemDataReqInfo.selfMacAddr, sizeof(wpt_macAddr));
  wpalMemoryCopy(&halStartOemDataReqParams->oemDataReq, &pwdiOemDataReqParams->wdiOemDataReqInfo.oemDataReq, OEM_DATA_REQ_SIZE);

  pWDICtx->wdiReqStatusCB     = pwdiOemDataReqParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiOemDataReqParams->pUserData; 

  /*-------------------------------------------------------------------------
    Send Start Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, 
                        wdiOemDataRspCb, pEventData->pUserData, 
                                            WDI_START_OEM_DATA_RESP); 
}/*WDI_ProcessStartOemDataReq*/
#endif

/**
 @brief Process Host Resume Request function (called when Main
        FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessHostResumeReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_ResumeParamsType*          pwdiHostResumeParams = NULL;
  WDI_HostResumeEventRspCb       wdiHostResumeRspCb;
  wpt_uint8*                     pSendBuffer         = NULL;
  wpt_uint16                     usDataOffset        = 0;
  wpt_uint16                     usSendSize          = 0;
  tHalWlanHostResumeReqParam     halResumeReqParams;

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

  /*-------------------------------------------------------------------------
  Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "%s: Invalid parameters ",__func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
  }

   pwdiHostResumeParams = (WDI_ResumeParamsType*)pEventData->pEventData;
   wdiHostResumeRspCb   = (WDI_HostResumeEventRspCb)pEventData->pCBfnc;

  /*-----------------------------------------------------------------------
     Get message buffer
   -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                         WDI_HOST_RESUME_REQ, sizeof(halResumeReqParams),
                              &pSendBuffer, &usDataOffset, &usSendSize))||
        (usSendSize < (usDataOffset + sizeof(halResumeReqParams))))
  {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "Unable to get send buffer in Start Oem Data req %p %p %p",
                 pEventData, pwdiHostResumeParams, wdiHostResumeRspCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
  }

  halResumeReqParams.configuredMcstBcstFilterSetting =
     pwdiHostResumeParams->wdiResumeParams.ucConfiguredMcstBcstFilterSetting;

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halResumeReqParams,
                  sizeof(halResumeReqParams));

  pWDICtx->wdiReqStatusCB     = pwdiHostResumeParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiHostResumeParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Start Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiHostResumeRspCb, pEventData->pUserData,
                                            WDI_HOST_RESUME_RESP);
}/*WDI_ProcessHostResumeReq*/

/**
 @brief Process set Tx Per Tracking Parameters Request function (called
        when Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetTxPerTrackingReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_SetTxPerTrackingReqParamsType* pwdiSetTxPerTrackingReqParams = NULL;
   WDI_SetTxPerTrackingRspCb          pwdiSetTxPerTrackingRspCb = NULL;
   wpt_uint8*               pSendBuffer         = NULL;
   wpt_uint16               usDataOffset        = 0;
   wpt_uint16               usSendSize          = 0;
   tHalTxPerTrackingReqParam     halTxPerTrackingReqParam;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
       ( NULL == pEventData->pCBfnc ))
   {
       WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters ",__func__);
       WDI_ASSERT(0);
       return WDI_STATUS_E_FAILURE;
   }

   pwdiSetTxPerTrackingReqParams = (WDI_SetTxPerTrackingReqParamsType*)pEventData->pEventData;
   pwdiSetTxPerTrackingRspCb   = (WDI_SetTxPerTrackingRspCb)pEventData->pCBfnc;

   /*-----------------------------------------------------------------------
     Get message buffer
     ! TO DO : proper conversion into the HAL Message Request Format
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_TX_PER_TRACKING_REQ,
                         sizeof(halTxPerTrackingReqParam),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(halTxPerTrackingReqParam) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in set tx per tracking req %p %p %p",
                  pEventData, pwdiSetTxPerTrackingReqParams, pwdiSetTxPerTrackingRspCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   halTxPerTrackingReqParam.ucTxPerTrackingEnable = pwdiSetTxPerTrackingReqParams->wdiTxPerTrackingParam.ucTxPerTrackingEnable;
   halTxPerTrackingReqParam.ucTxPerTrackingPeriod = pwdiSetTxPerTrackingReqParams->wdiTxPerTrackingParam.ucTxPerTrackingPeriod;
   halTxPerTrackingReqParam.ucTxPerTrackingRatio = pwdiSetTxPerTrackingReqParams->wdiTxPerTrackingParam.ucTxPerTrackingRatio;
   halTxPerTrackingReqParam.uTxPerTrackingWatermark = pwdiSetTxPerTrackingReqParams->wdiTxPerTrackingParam.uTxPerTrackingWatermark;

   wpalMemoryCopy( pSendBuffer+usDataOffset,
                   &halTxPerTrackingReqParam,
                   sizeof(halTxPerTrackingReqParam));

   pWDICtx->wdiReqStatusCB     = pwdiSetTxPerTrackingReqParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiSetTxPerTrackingReqParams->pUserData;

   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        pwdiSetTxPerTrackingRspCb, pEventData->pUserData, WDI_SET_TX_PER_TRACKING_RESP);
}/*WDI_ProcessSetTxPerTrackingReq*/

/*=========================================================================
                             Indications
=========================================================================*/

/**
 @brief Process Suspend Indications function (called when Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessHostSuspendInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_SuspendParamsType          *pSuspendIndParams;
  wpt_uint8*                     pSendBuffer         = NULL;
  wpt_uint16                     usDataOffset        = 0;
  wpt_uint16                     usSendSize          = 0;
  WDI_Status                     wdiStatus;
  tHalWlanHostSuspendIndParam    halWlanSuspendIndparams;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
     Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ))
  {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "%s: Invalid parameters in Suspend ind",__func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
  }

  pSuspendIndParams = (WDI_SuspendParamsType *)pEventData->pEventData;

   /*-----------------------------------------------------------------------
     Get message buffer
   -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                         WDI_HOST_SUSPEND_IND,
                     sizeof(halWlanSuspendIndparams),
                     &pSendBuffer, &usDataOffset, &usSendSize))||
        (usSendSize < (usDataOffset + sizeof(halWlanSuspendIndparams))))
  {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in Suspend Ind ");
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
  }

  halWlanSuspendIndparams.configuredMcstBcstFilterSetting =
       pSuspendIndParams->wdiSuspendParams.ucConfiguredMcstBcstFilterSetting;

  halWlanSuspendIndparams.activeSessionCount =
       WDI_GetActiveSessionsCount(pWDICtx, NULL, eWLAN_PAL_TRUE);

  wpalMemoryCopy( pSendBuffer+usDataOffset, &halWlanSuspendIndparams,
                                         sizeof(tHalWlanHostSuspendIndParam));

  /*-------------------------------------------------------------------------
    Send Suspend Request to HAL
  -------------------------------------------------------------------------*/
  pWDICtx->wdiReqStatusCB     = pSuspendIndParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pSuspendIndParams->pUserData;

  wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize);
  return  ( wdiStatus != WDI_STATUS_SUCCESS )?wdiStatus:WDI_STATUS_SUCCESS_SYNC;
}/*WDI_ProcessHostSuspendInd*/



/**
 @brief Process Traffic Stats Indications function (called when Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
              pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessTrafficStatsInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_TrafficStatsIndType*       pTrafficStatsIndParams;
  wpt_uint8*                     pSendBuffer         = NULL;
  wpt_uint16                     usDataOffset        = 0;
  wpt_uint16                     usSendSize          = 0;
  WDI_Status                     wdiStatus;
  tStatsClassBIndParams*         pStatsClassBIndParams;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
     Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ))
  {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "%s: Invalid parameters in Traffic Stats ind",__func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
  }

  pTrafficStatsIndParams = (WDI_TrafficStatsIndType *)pEventData->pEventData;

  if(pTrafficStatsIndParams->length != sizeof(tStaStatsClassB)*(HAL_NUM_STA))
  {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "%s: Invalid parameters in Traffic Stats ind",__func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
  }

   /*-----------------------------------------------------------------------
     Get message buffer
   -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                         WDI_TRAFFIC_STATS_IND,
                     sizeof(tStatsClassBIndParams),
                     &pSendBuffer, &usDataOffset, &usSendSize))||
        (usSendSize < (usDataOffset + sizeof(tStatsClassBIndParams))))
  {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
                  "Unable to get send buffer in Traffic Stats Ind ");
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
  }

  pStatsClassBIndParams = (tStatsClassBIndParams*)(pSendBuffer+usDataOffset);

  pStatsClassBIndParams->duration = pTrafficStatsIndParams->duration;

  wpalMemoryCopy(pStatsClassBIndParams->staStatsClassB,
                 pTrafficStatsIndParams->pTrafficStats,
                 pTrafficStatsIndParams->length);

  /*-------------------------------------------------------------------------
    Send Suspend Request to HAL
  -------------------------------------------------------------------------*/
  pWDICtx->wdiReqStatusCB     = pTrafficStatsIndParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pTrafficStatsIndParams->pUserData;

  wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize);
  return  ( wdiStatus != WDI_STATUS_SUCCESS )?wdiStatus:WDI_STATUS_SUCCESS_SYNC;
}/*WDI_ProcessTrafficStatsInd*/

#ifdef WLAN_FEATURE_11W
/**
 @brief Process Exclude Unencrypted Indications function (called
        when Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
              pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessExcludeUnencryptInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_ExcludeUnencryptIndType*       pWDIExcUnencIndParams;
  wpt_uint8*                     pSendBuffer         = NULL;
  wpt_uint16                     usDataOffset        = 0;
  wpt_uint16                     usSendSize          = 0;
  WDI_Status                     wdiStatus;
  tHalWlanExcludeUnEncryptedIndParam* pHalExcUnencIndParams;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
     Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ))
  {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "%s: Invalid parameters in Exclude Unencrypted ind",__func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
  }

  pWDIExcUnencIndParams = (WDI_ExcludeUnencryptIndType *)pEventData->pEventData;

  /*-----------------------------------------------------------------------
     Get message buffer
   -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                         WDI_EXCLUDE_UNENCRYPTED_IND,
                     sizeof(tHalWlanExcludeUnEncryptedIndParam),
                     &pSendBuffer, &usDataOffset, &usSendSize))||
        (usSendSize < (usDataOffset + sizeof(tHalWlanExcludeUnEncryptedIndParam))))
  {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
                  "Unable to get send buffer in Exclude Unencrypted Ind ");
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
  }

  pHalExcUnencIndParams = (tHalWlanExcludeUnEncryptedIndParam*)(pSendBuffer+usDataOffset);

  pHalExcUnencIndParams->bDot11ExcludeUnencrypted = pWDIExcUnencIndParams->bExcludeUnencrypt;

  wpalMemoryCopy(pHalExcUnencIndParams->bssId,
                 pWDIExcUnencIndParams->bssid, WDI_MAC_ADDR_LEN);

  /*-------------------------------------------------------------------------
    Send Suspend Request to HAL
  -------------------------------------------------------------------------*/
  pWDICtx->wdiReqStatusCB     = pWDIExcUnencIndParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pWDIExcUnencIndParams->pUserData;

  wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize);
  return  ( wdiStatus != WDI_STATUS_SUCCESS )?wdiStatus:WDI_STATUS_SUCCESS_SYNC;
}/*WDI_ProcessExcludeUnencryptInd*/
#endif

/**
 @brief Process Add Periodic Tx Pattern Indication function (called when
           Main FSM allows it)

 @param pWDICtx:         pointer to the WLAN DAL context
        pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessAddPeriodicTxPtrnInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_AddPeriodicTxPtrnParamsType   *pAddPeriodicTxPtrnParams;
  wpt_uint8*                     pSendBuffer         = NULL;
  wpt_uint16                     usDataOffset        = 0;
  wpt_uint16                     usSendSize          = 0;
  WDI_Status                     wdiStatus;
  tHalAddPeriodicTxPtrn          *halAddPeriodicTxPtrn;
  wpt_uint8                      selfStaIdx          = 0;

  /*-------------------------------------------------------------------------
     Sanity check
  -------------------------------------------------------------------------*/
  if ((NULL == pEventData) || (NULL == pEventData->pEventData))
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "%s: Invalid parameters in AddPeriodicTxPtrnInd!", __func__);
    WDI_ASSERT(0);
    return WDI_STATUS_E_FAILURE;
  }

  pAddPeriodicTxPtrnParams =
    (WDI_AddPeriodicTxPtrnParamsType *)pEventData->pEventData;

   /*------------------------------------------------------------------------
     Get message buffer
   ------------------------------------------------------------------------*/
  if ((WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(pWDICtx,
       WDI_ADD_PERIODIC_TX_PATTERN_IND, sizeof(tHalAddPeriodicTxPtrn),
       &pSendBuffer, &usDataOffset, &usSendSize))||
       (usSendSize < (usDataOffset + sizeof(tHalAddPeriodicTxPtrn))))
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "%s: Unable to get send buffer in AddPeriodicTxPtrnInd!",
               __func__);
    WDI_ASSERT(0);
    return WDI_STATUS_E_FAILURE;
  }

  halAddPeriodicTxPtrn = (tHalAddPeriodicTxPtrn *)(pSendBuffer + usDataOffset);

  if (WDI_STATUS_SUCCESS != WDI_STATableFindStaidByAddr(pWDICtx,
      pAddPeriodicTxPtrnParams->wdiAddPeriodicTxPtrnParams.macAddr,
      &selfStaIdx))
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "%s: Failed to get selfStaIdx!", __func__);
    wpalMemoryFree(pSendBuffer);

    return WDI_STATUS_E_FAILURE;
  }

  halAddPeriodicTxPtrn->selfStaIdx = selfStaIdx;
  halAddPeriodicTxPtrn->ucPtrnId =
    pAddPeriodicTxPtrnParams->wdiAddPeriodicTxPtrnParams.ucPtrnId;
  halAddPeriodicTxPtrn->usPtrnSize =
    pAddPeriodicTxPtrnParams->wdiAddPeriodicTxPtrnParams.ucPtrnSize;
  halAddPeriodicTxPtrn->uPtrnIntervalMs =
    pAddPeriodicTxPtrnParams->wdiAddPeriodicTxPtrnParams.usPtrnIntervalMs;

  wpalMemoryCopy(halAddPeriodicTxPtrn->ucPattern,
    pAddPeriodicTxPtrnParams->wdiAddPeriodicTxPtrnParams.ucPattern,
    pAddPeriodicTxPtrnParams->wdiAddPeriodicTxPtrnParams.ucPtrnSize);

  /*-------------------------------------------------------------------------
    Send Indication to HAL
  -------------------------------------------------------------------------*/
  pWDICtx->wdiReqStatusCB     = pAddPeriodicTxPtrnParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pAddPeriodicTxPtrnParams->pUserData;

  wdiStatus = WDI_SendIndication(pWDICtx, pSendBuffer, usSendSize);

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
             "%s: Sent WLAN_HAL_ADD_PERIODIC_TX_PTRN_IND to HAL.", __func__);

  return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus : WDI_STATUS_SUCCESS_SYNC;
} /* WDI_ProcessAddPeriodicTxPtrnInd */

/**
 @brief Process Delete Periodic Tx Pattern Indication function (called when
           Main FSM allows it)

 @param pWDICtx:         pointer to the WLAN DAL context
        pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessDelPeriodicTxPtrnInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_DelPeriodicTxPtrnParamsType   *pDelPeriodicTxPtrnParams;
  wpt_uint8*                     pSendBuffer         = NULL;
  wpt_uint16                     usDataOffset        = 0;
  wpt_uint16                     usSendSize          = 0;
  WDI_Status                     wdiStatus;
  tHalDelPeriodicTxPtrn          *halDelPeriodicTxPtrn;
  wpt_uint8                      selfStaIdx          = 0;

  /*-------------------------------------------------------------------------
     Sanity check
  -------------------------------------------------------------------------*/
  if ((NULL == pEventData) || (NULL == pEventData->pEventData))
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "%s: Invalid parameters in DelPeriodicTxPtrnInd!", __func__);
    WDI_ASSERT(0);
    return WDI_STATUS_E_FAILURE;
  }

  pDelPeriodicTxPtrnParams =
    (WDI_DelPeriodicTxPtrnParamsType *)pEventData->pEventData;

   /*------------------------------------------------------------------------
     Get message buffer
   ------------------------------------------------------------------------*/
  if ((WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(pWDICtx,
       WDI_DEL_PERIODIC_TX_PATTERN_IND, sizeof(tHalDelPeriodicTxPtrn),
       &pSendBuffer, &usDataOffset, &usSendSize))||
       (usSendSize < (usDataOffset + sizeof(tHalDelPeriodicTxPtrn))))
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "%s: Unable to get send buffer in DelPeriodicTxPtrnInd!",
               __func__);
    WDI_ASSERT(0);
    return WDI_STATUS_E_FAILURE;
  }

  halDelPeriodicTxPtrn = (tHalDelPeriodicTxPtrn *)(pSendBuffer + usDataOffset);

  if (WDI_STATUS_SUCCESS != WDI_STATableFindStaidByAddr(pWDICtx,
      pDelPeriodicTxPtrnParams->wdiDelPeriodicTxPtrnParams.macAddr,
      &selfStaIdx))
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "%s: Failed to get selfStaIdx!", __func__);
    wpalMemoryFree(pSendBuffer);

    return WDI_STATUS_E_FAILURE;
  }

  halDelPeriodicTxPtrn->selfStaIdx = selfStaIdx;
  halDelPeriodicTxPtrn->uPatternIdBitmap =
    pDelPeriodicTxPtrnParams->wdiDelPeriodicTxPtrnParams.ucPatternIdBitmap;

  /*-------------------------------------------------------------------------
    Send Indication to HAL
  -------------------------------------------------------------------------*/
  pWDICtx->wdiReqStatusCB     = pDelPeriodicTxPtrnParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pDelPeriodicTxPtrnParams->pUserData;

  wdiStatus = WDI_SendIndication(pWDICtx, pSendBuffer, usSendSize);

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
             "%s: Sent WLAN_HAL_DEL_PERIODIC_TX_PTRN_IND to HAL.", __func__);

  return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus : WDI_STATUS_SUCCESS_SYNC;
} /* WDI_ProcessDelPeriodicTxPtrnInd */

/*==========================================================================
                  MISC CONTROL PROCESSING REQUEST API
==========================================================================*/
/**
 @brief Process Channel Switch Request function (called when
        Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessChannelSwitchReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_SwitchChReqParamsType*   pwdiSwitchChParams;
  WDI_SwitchChRspCb            wdiSwitchChRspCb;
  wpt_uint8*                   pSendBuffer         = NULL;
  wpt_uint16                   usDataOffset        = 0;
  wpt_uint16                   usSendSize          = 0;
  tSwitchChannelReqMsg         halSwitchChannelReq = {{0}};
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiSwitchChParams = (WDI_SwitchChReqParamsType*)pEventData->pEventData;
  wdiSwitchChRspCb   = (WDI_SwitchChRspCb)pEventData->pCBfnc;
  /*-----------------------------------------------------------------------
    Get message buffer
    ! TO DO : proper conversion into the HAL Message Request Format
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_CH_SWITCH_REQ,
                        sizeof(halSwitchChannelReq.switchChannelParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halSwitchChannelReq.switchChannelParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in channel switch req %p %p %p",
                pEventData, pwdiSwitchChParams, wdiSwitchChRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  halSwitchChannelReq.switchChannelParams.channelNumber =
                       pwdiSwitchChParams->wdiChInfo.ucChannel;
#ifndef WLAN_FEATURE_VOWIFI
  halSwitchChannelReq.switchChannelParams.localPowerConstraint =
                       pwdiSwitchChParams->wdiChInfo.ucLocalPowerConstraint;
#endif
  halSwitchChannelReq.switchChannelParams.secondaryChannelOffset =
                       pwdiSwitchChParams->wdiChInfo.wdiSecondaryChannelOffset;

#ifdef WLAN_FEATURE_VOWIFI
  halSwitchChannelReq.switchChannelParams.maxTxPower
                            = pwdiSwitchChParams->wdiChInfo.cMaxTxPower;
  wpalMemoryCopy(halSwitchChannelReq.switchChannelParams.selfStaMacAddr,
                  pwdiSwitchChParams->wdiChInfo.macSelfStaMacAddr,
                  WDI_MAC_ADDR_LEN);
  wpalMemoryCopy(halSwitchChannelReq.switchChannelParams.bssId,
                  pwdiSwitchChParams->wdiChInfo.macBSSId,
                  WDI_MAC_ADDR_LEN);
#endif
  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halSwitchChannelReq.switchChannelParams,
                  sizeof(halSwitchChannelReq.switchChannelParams));

  pWDICtx->wdiReqStatusCB     = pwdiSwitchChParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiSwitchChParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Switch Channel Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiSwitchChRspCb, pEventData->pUserData, WDI_CH_SWITCH_RESP);
}/*WDI_ProcessChannelSwitchReq*/

/**
 @brief Process Channel Switch Request function (called when
        Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status WDI_ProcessChannelSwitchReq_V1
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_SwitchChReqParamsType_V1*   pwdiSwitchChParams;
  WDI_SwitchChRspCb_V1            wdiSwitchChRspCb;
  wpt_uint8*                   pSendBuffer         = NULL;
  wpt_uint16                   usDataOffset        = 0;
  wpt_uint16                   usSendSize          = 0;
  tSwitchChannelReqMsg_V1      halSwitchChannelReq = {{0}};
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiSwitchChParams = (WDI_SwitchChReqParamsType_V1*)pEventData->pEventData;
  wdiSwitchChRspCb   = (WDI_SwitchChRspCb_V1)pEventData->pCBfnc;
  /*-----------------------------------------------------------------------
    Get message buffer
    ! TO DO : proper conversion into the HAL Message Request Format
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
            WDI_CH_SWITCH_REQ_V1,
            sizeof(halSwitchChannelReq.switchChannelParams_V1),
            &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset +
        sizeof(halSwitchChannelReq.switchChannelParams_V1) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in channel switch req %p %p %p",
                pEventData, pwdiSwitchChParams, wdiSwitchChRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  halSwitchChannelReq.switchChannelParams_V1.channelSwitchSrc =
        pwdiSwitchChParams->wdiChInfo.channelSwitchSrc;

  halSwitchChannelReq.switchChannelParams_V1.channelNumber =
                       pwdiSwitchChParams->wdiChInfo.ucChannel;
#ifndef WLAN_FEATURE_VOWIFI
  halSwitchChannelReq.switchChannelParams_V1.localPowerConstraint =
                       pwdiSwitchChParams->wdiChInfo.ucLocalPowerConstraint;
#endif
  halSwitchChannelReq.switchChannelParams_V1.secondaryChannelOffset =
                pwdiSwitchChParams->wdiChInfo.wdiSecondaryChannelOffset;

#ifdef WLAN_FEATURE_VOWIFI
  halSwitchChannelReq.switchChannelParams_V1.maxTxPower
                            = pwdiSwitchChParams->wdiChInfo.cMaxTxPower;
  wpalMemoryCopy(halSwitchChannelReq.switchChannelParams_V1.selfStaMacAddr,
                  pwdiSwitchChParams->wdiChInfo.macSelfStaMacAddr,
                  WDI_MAC_ADDR_LEN);
  wpalMemoryCopy(halSwitchChannelReq.switchChannelParams_V1.bssId,
                  pwdiSwitchChParams->wdiChInfo.macBSSId,
                  WDI_MAC_ADDR_LEN);
#endif
  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halSwitchChannelReq.switchChannelParams_V1,
                  sizeof(halSwitchChannelReq.switchChannelParams_V1));

  pWDICtx->wdiReqStatusCB     = pwdiSwitchChParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiSwitchChParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Switch Channel Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                         wdiSwitchChRspCb, pEventData->pUserData,
                         WDI_CH_SWITCH_RESP_V1);
}/*WDI_ProcessChannelSwitchReq_V1*/

/**
 @brief Process Config STA Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessConfigStaReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_ConfigSTAReqParamsType*  pwdiConfigSTAParams;
  WDI_ConfigSTARspCb           wdiConfigSTARspCb;
  wpt_uint8                    ucCurrentBSSSesIdx  = 0;
  WDI_BSSSessionType*          pBSSSes             = NULL;
  wpt_uint8*                   pSendBuffer         = NULL;
  wpt_uint16                   usDataOffset        = 0;
  wpt_uint16                   usSendSize          = 0;
  WDI_Status                   wdiStatus           = WDI_STATUS_SUCCESS;

  tConfigStaReqMsg             halConfigStaReqMsg;
  wpt_uint16                   uMsgSize            = 0;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wpalMemoryZero(&halConfigStaReqMsg, sizeof(tConfigStaReqMsg));
  pwdiConfigSTAParams = (WDI_ConfigSTAReqParamsType*)pEventData->pEventData;
  wdiConfigSTARspCb   = (WDI_ConfigSTARspCb)pEventData->pCBfnc;
  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made
  ------------------------------------------------------------------------*/
  ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx,
                           pwdiConfigSTAParams->wdiReqInfo.macBSSID,
                          &pBSSSes);

  if ( NULL == pBSSSes )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, 
          "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, 
          __func__, MAC_ADDR_ARRAY(pwdiConfigSTAParams->wdiReqInfo.macBSSID));

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Check if this BSS is being currently processed or queued,
    if queued - queue the new request as well
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, 
              __func__, MAC_ADDR_ARRAY(pwdiConfigSTAParams->wdiReqInfo.macBSSID));

    wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return wdiStatus;
  }

  wpalMutexRelease(&pWDICtx->wptMutex);
  
  /* Allocation of StaReqMsg Memory Based on Firmware Capabilities */
#ifdef WLAN_FEATURE_11AC
  if (WDI_getFwWlanFeatCaps(DOT11AC))
     uMsgSize = sizeof(halConfigStaReqMsg.uStaParams.configStaParams_V1); // Version-1 For 11AC
  else
#endif
     uMsgSize = sizeof(halConfigStaReqMsg.uStaParams.configStaParams); // Version-0 Default

  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_CONFIG_STA_REQ,
                        uMsgSize,
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + uMsgSize )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in config sta req %p %p %p",
                pEventData, pwdiConfigSTAParams, wdiConfigSTARspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*Copy the station context*/
  WDI_CopyWDIStaCtxToHALStaCtx( &halConfigStaReqMsg.uStaParams.configStaParams,
                                &pwdiConfigSTAParams->wdiReqInfo);

  if(pwdiConfigSTAParams->wdiReqInfo.wdiSTAType == WDI_STA_ENTRY_SELF)
  {
    /* Need to fill in the self STA Index */
    if ( WDI_STATUS_SUCCESS !=
         WDI_STATableFindStaidByAddr(pWDICtx,
                                     pwdiConfigSTAParams->wdiReqInfo.macSTA,
                                     (wpt_uint8*)&halConfigStaReqMsg.uStaParams.configStaParams.staIdx ))
    {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  MAC_ADDRESS_STR
                  ": This station does not exist in the WDI Station Table",
                MAC_ADDR_ARRAY(pwdiConfigSTAParams->wdiReqInfo.macSTA));
      wpalMutexRelease(&pWDICtx->wptMutex);
      wpalMemoryFree(pSendBuffer);
      return WDI_STATUS_E_FAILURE;
    }
  }
  else
  {
  /* Need to fill in the STA Index to invalid, since at this point we have not
     yet received it from HAL */
    halConfigStaReqMsg.uStaParams.configStaParams.staIdx = pwdiConfigSTAParams->wdiReqInfo.staIdx;
  }

  /* Need to fill in the BSS index */
  halConfigStaReqMsg.uStaParams.configStaParams.bssIdx = pBSSSes->ucBSSIdx;
  
  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halConfigStaReqMsg.uStaParams,
                  uMsgSize);

  pWDICtx->wdiReqStatusCB     = pwdiConfigSTAParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiConfigSTAParams->pUserData;

  wpalMemoryCopy( &pWDICtx->wdiCachedConfigStaReq,
                  pwdiConfigSTAParams,
                  sizeof(pWDICtx->wdiCachedConfigStaReq));

  /*-------------------------------------------------------------------------
    Send Config STA Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiConfigSTARspCb, pEventData->pUserData, WDI_CONFIG_STA_RESP);
}/*WDI_ProcessConfigStaReq*/


/**
 @brief Process Set Link State Request function (called when
        Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetLinkStateReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_SetLinkReqParamsType*    pwdiSetLinkParams;
  WDI_SetLinkStateRspCb        wdiSetLinkRspCb;
  wpt_uint8                    ucCurrentBSSSesIdx  = 0;
  WDI_BSSSessionType*          pBSSSes             = NULL;
  wpt_uint8*                   pSendBuffer         = NULL;
  wpt_uint16                   usDataOffset        = 0;
  wpt_uint16                   usSendSize          = 0;
  WDI_Status                   wdiStatus           = WDI_STATUS_SUCCESS;
  tLinkStateParams             halLinkStateReqMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiSetLinkParams = (WDI_SetLinkReqParamsType*)pEventData->pEventData;
  wdiSetLinkRspCb   = (WDI_SetLinkStateRspCb)pEventData->pCBfnc;
  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made
  ------------------------------------------------------------------------*/
  ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx,
                           pwdiSetLinkParams->wdiLinkInfo.macBSSID,
                          &pBSSSes);

  if ( NULL == pBSSSes )
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, 
     "%s: Set link request received outside association session. macBSSID " MAC_ADDRESS_STR, 
     __func__, MAC_ADDR_ARRAY(pwdiSetLinkParams->wdiLinkInfo.macBSSID));
  }
  else
  {
    /*------------------------------------------------------------------------
      Check if this BSS is being currently processed or queued,
      if queued - queue the new request as well
    ------------------------------------------------------------------------*/
    if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued )
    {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, 
                __func__, MAC_ADDR_ARRAY(pwdiSetLinkParams->wdiLinkInfo.macBSSID));

      wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData);
      wpalMutexRelease(&pWDICtx->wptMutex);
      return wdiStatus;
    }
  }
  /* If the link is set to enter IDLE - the Session allocated for this BSS
     will be deleted on the Set Link State response coming from HAL
   - cache the request for response processing */
  wpalMemoryCopy(&pWDICtx->wdiCacheSetLinkStReq, pwdiSetLinkParams,
                 sizeof(pWDICtx->wdiCacheSetLinkStReq));

  wpalMutexRelease(&pWDICtx->wptMutex);
  /*-----------------------------------------------------------------------
    Get message buffer
    ! TO DO : proper conversion into the HAL Message Request Format
  -----------------------------------------------------------------------*/

  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_LINK_ST_REQ,
                        sizeof(halLinkStateReqMsg),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halLinkStateReqMsg) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in set bss key req %p %p %p",
                pEventData, pwdiSetLinkParams, wdiSetLinkRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wpalMemoryCopy(halLinkStateReqMsg.bssid,
                 pwdiSetLinkParams->wdiLinkInfo.macBSSID, WDI_MAC_ADDR_LEN);

  wpalMemoryCopy(halLinkStateReqMsg.selfMacAddr,
                 pwdiSetLinkParams->wdiLinkInfo.macSelfStaMacAddr, WDI_MAC_ADDR_LEN);

  halLinkStateReqMsg.state =
     WDI_2_HAL_LINK_STATE(pwdiSetLinkParams->wdiLinkInfo.wdiLinkState);

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halLinkStateReqMsg,
                  sizeof(halLinkStateReqMsg));

  pWDICtx->wdiReqStatusCB     = pwdiSetLinkParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiSetLinkParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Set Link State Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiSetLinkRspCb, pEventData->pUserData, WDI_SET_LINK_ST_RESP);
}/*WDI_ProcessSetLinkStateReq*/


/**
 @brief Process Get Stats Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessGetStatsReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_GetStatsReqParamsType*   pwdiGetStatsParams;
  WDI_GetStatsRspCb            wdiGetStatsRspCb;
  wpt_uint8*                   pSendBuffer         = NULL;
  wpt_uint16                   usDataOffset        = 0;
  wpt_uint16                   usSendSize          = 0;
  wpt_uint8                    ucCurrentBSSSesIdx  = 0;
  WDI_BSSSessionType*          pBSSSes             = NULL;
  wpt_macAddr                  macBSSID;
  WDI_Status                   wdiStatus           = WDI_STATUS_SUCCESS;
  tHalStatsReqMsg              halStatsReqMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData) ||
      ( NULL == pEventData->pCBfnc ) )
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiGetStatsParams = (WDI_GetStatsReqParamsType*)pEventData->pEventData;
  wdiGetStatsRspCb   = (WDI_GetStatsRspCb)pEventData->pCBfnc;

  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made
  ------------------------------------------------------------------------*/
  if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx,
                        pwdiGetStatsParams->wdiGetStatsParamsInfo.ucSTAIdx,
                        &macBSSID))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                "This station does not exist in the WDI Station Table %d",
                pwdiGetStatsParams->wdiGetStatsParamsInfo.ucSTAIdx);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_FAILURE;
  }

  ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes);
  if ( NULL == pBSSSes )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, 
        "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, 
        __func__, MAC_ADDR_ARRAY(macBSSID));

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Check if this BSS is being currently processed or queued,
    if queued - queue the new request as well
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, 
              __func__, MAC_ADDR_ARRAY(macBSSID));

    wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return wdiStatus;
  }


  wpalMutexRelease(&pWDICtx->wptMutex);

  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_GET_STATS_REQ,
                        sizeof(halStatsReqMsg.statsReqParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halStatsReqMsg.statsReqParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in set bss key req %p %p %p",
                pEventData, pwdiGetStatsParams, wdiGetStatsRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  halStatsReqMsg.statsReqParams.staId =
                  pwdiGetStatsParams->wdiGetStatsParamsInfo.ucSTAIdx;
  halStatsReqMsg.statsReqParams.statsMask =
                  pwdiGetStatsParams->wdiGetStatsParamsInfo.uStatsMask;
  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halStatsReqMsg.statsReqParams,
                  sizeof(halStatsReqMsg.statsReqParams));

  pWDICtx->wdiReqStatusCB     = pwdiGetStatsParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiGetStatsParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Get STA Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiGetStatsRspCb, pEventData->pUserData, WDI_GET_STATS_RESP);
}/*WDI_ProcessGetStatsReq*/

#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
/**
 @brief Process Get Roam Rssi Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessGetRoamRssiReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_GetRoamRssiReqParamsType*   pwdiGetRoamRssiParams;
  WDI_GetStatsRspCb            wdiGetStatsRspCb;
  wpt_uint8*                   pSendBuffer         = NULL;
  wpt_uint16                   usDataOffset        = 0;
  wpt_uint16                   usSendSize          = 0;
  wpt_uint8                    ucCurrentBSSSesIdx  = 0;
  WDI_BSSSessionType*          pBSSSes             = NULL;
  wpt_macAddr                  macBSSID;
  WDI_Status                   wdiStatus           = WDI_STATUS_SUCCESS;
  tHalGetRoamRssiReqMsg        halRssiRoamReqMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData) ||
      ( NULL == pEventData->pCBfnc ) )
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiGetRoamRssiParams = (WDI_GetRoamRssiReqParamsType*)pEventData->pEventData;
  wdiGetStatsRspCb   = (WDI_GetStatsRspCb)pEventData->pCBfnc;

  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made
  ------------------------------------------------------------------------*/
  if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx,
                        pwdiGetRoamRssiParams->wdiGetRoamRssiParamsInfo.ucSTAIdx,
                        &macBSSID))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                "This station does not exist in the WDI Station Table %d",
                pwdiGetRoamRssiParams->wdiGetRoamRssiParamsInfo.ucSTAIdx);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_FAILURE;
  }

  ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes);
  if ( NULL == pBSSSes )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
        "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR,
        __func__, MAC_ADDR_ARRAY(macBSSID));

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Check if this BSS is being currently processed or queued,
    if queued - queue the new request as well
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR,
              __func__, MAC_ADDR_ARRAY(macBSSID));

    wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return wdiStatus;
  }

  wpalMutexRelease(&pWDICtx->wptMutex);

  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_GET_ROAM_RSSI_REQ,
                        sizeof(halRssiRoamReqMsg.roamRssiReqParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halRssiRoamReqMsg.roamRssiReqParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in set bss key req %p %p %p",
                pEventData, pwdiGetRoamRssiParams, wdiGetStatsRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  halRssiRoamReqMsg.roamRssiReqParams.staId =
                  pwdiGetRoamRssiParams->wdiGetRoamRssiParamsInfo.ucSTAIdx;
  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halRssiRoamReqMsg.roamRssiReqParams,
                  sizeof(halRssiRoamReqMsg.roamRssiReqParams));

  pWDICtx->wdiReqStatusCB     = pwdiGetRoamRssiParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiGetRoamRssiParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Get STA Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiGetStatsRspCb, pEventData->pUserData, WDI_GET_ROAM_RSSI_RESP);
}/*WDI_ProcessGetRoamRssiReq*/
#endif

/**
 @brief Process Update Cfg Request function (called when Main
        FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessUpdateCfgReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_UpdateCfgReqParamsType*  pwdiUpdateCfgParams = NULL;
  WDI_UpdateCfgRspCb           wdiUpdateCfgRspCb = NULL;

  wpt_uint8*                   pSendBuffer         = NULL;
  wpt_uint16                   usDataOffset         = 0;
  wpt_uint16                   usSendSize          = 0;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiUpdateCfgParams = (WDI_UpdateCfgReqParamsType*)pEventData->pEventData;
  wdiUpdateCfgRspCb   = (WDI_UpdateCfgRspCb)pEventData->pCBfnc;

  /*-----------------------------------------------------------------------
    Get message buffer
    ! TO DO : proper conversion into the HAL Message Request Format
  -----------------------------------------------------------------------*/

  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_UPDATE_CFG_REQ,
                        pwdiUpdateCfgParams->uConfigBufferLen + sizeof(wpt_uint32),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset +  pwdiUpdateCfgParams->uConfigBufferLen)))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in set bss key req %p %p %p",
                pEventData, pwdiUpdateCfgParams, wdiUpdateCfgRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &pwdiUpdateCfgParams->uConfigBufferLen,
                  sizeof(wpt_uint32));
  wpalMemoryCopy( pSendBuffer+usDataOffset+sizeof(wpt_uint32),
                  pwdiUpdateCfgParams->pConfigBuffer,
                  pwdiUpdateCfgParams->uConfigBufferLen);

  pWDICtx->wdiReqStatusCB     = pwdiUpdateCfgParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiUpdateCfgParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Update Cfg Request to HAL
  -------------------------------------------------------------------------*/

  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiUpdateCfgRspCb, pEventData->pUserData, WDI_UPDATE_CFG_RESP);

}/*WDI_ProcessUpdateCfgReq*/


/**
 @brief Process Add BA Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessAddBAReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_AddBAReqParamsType*  pwdiAddBAParams;
  WDI_AddBARspCb           wdiAddBARspCb;
  wpt_uint8                ucCurrentBSSSesIdx  = 0;
  WDI_BSSSessionType*      pBSSSes             = NULL;
  wpt_uint8*               pSendBuffer         = NULL;
  wpt_uint16               usDataOffset        = 0;
  wpt_uint16               usSendSize          = 0;
  WDI_Status               wdiStatus           = WDI_STATUS_SUCCESS;
  wpt_macAddr              macBSSID;

  tAddBAReqMsg             halAddBAReq;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiAddBAParams = (WDI_AddBAReqParamsType*)pEventData->pEventData;
  wdiAddBARspCb   = (WDI_AddBARspCb)pEventData->pCBfnc;

  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made
  ------------------------------------------------------------------------*/
  if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx,
                                  pwdiAddBAParams->wdiBAInfoType.ucSTAIdx,
                                  &macBSSID))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                "This station does not exist in the WDI Station Table %d",
                pwdiAddBAParams->wdiBAInfoType.ucSTAIdx);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_FAILURE;
  }

  ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes);
  if ( NULL == pBSSSes )
  {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, 
            "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, 
            __func__, MAC_ADDR_ARRAY(macBSSID));

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Check if this BSS is being currently processed or queued,
    if queued - queue the new request as well
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, 
              __func__, MAC_ADDR_ARRAY(macBSSID));

    wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return wdiStatus;
  }


  wpalMutexRelease(&pWDICtx->wptMutex);
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_ADD_BA_REQ,
                        sizeof(halAddBAReq.addBAParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize <
            (usDataOffset + sizeof(halAddBAReq.addBAParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in Add BA req %p %p %p",
                pEventData, pwdiAddBAParams, wdiAddBARspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  halAddBAReq.addBAParams.baSessionID =
                             pwdiAddBAParams->wdiBAInfoType.ucBaSessionID;
  halAddBAReq.addBAParams.winSize = pwdiAddBAParams->wdiBAInfoType.ucWinSize;
#ifdef FEATURE_ON_CHIP_REORDERING
  halAddBAReq.addBAParams.isReorderingDoneOnChip =
                       pwdiAddBAParams->wdiBAInfoType.bIsReorderingDoneOnChip;
#endif

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halAddBAReq.addBAParams,
                  sizeof(halAddBAReq.addBAParams));

  pWDICtx->wdiReqStatusCB     = pwdiAddBAParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiAddBAParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Start Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiAddBARspCb, pEventData->pUserData,
                        WDI_ADD_BA_RESP);
}/*WDI_ProcessAddBAReq*/



/**
 @brief Process Trigger BA Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessTriggerBAReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_TriggerBAReqParamsType*  pwdiTriggerBAParams;
  WDI_TriggerBARspCb           wdiTriggerBARspCb;
  wpt_uint8                    ucCurrentBSSSesIdx  = 0;
  WDI_BSSSessionType*          pBSSSes             = NULL;
  wpt_uint8*                   pSendBuffer         = NULL;
  wpt_uint16                   usDataOffset        = 0;
  wpt_uint16                   usSendSize          = 0;
  WDI_Status                   wdiStatus           = WDI_STATUS_SUCCESS;
  wpt_uint16                   index;
  wpt_macAddr                  macBSSID;

  tTriggerBAReqMsg               halTriggerBAReq;
  tTriggerBaReqCandidate*        halTriggerBACandidate;
  WDI_TriggerBAReqCandidateType* wdiTriggerBACandidate;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiTriggerBAParams = (WDI_TriggerBAReqParamsType*)pEventData->pEventData;
  wdiTriggerBARspCb = (WDI_TriggerBARspCb)pEventData->pCBfnc;
  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made
  ------------------------------------------------------------------------*/
  if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx,
                                  pwdiTriggerBAParams->wdiTriggerBAInfoType.ucSTAIdx,
                                  &macBSSID))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                "This station does not exist in the WDI Station Table %d",
                pwdiTriggerBAParams->wdiTriggerBAInfoType.ucSTAIdx);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_FAILURE;
  }

  ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes);
  if ( NULL == pBSSSes )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, 
        "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, 
        __func__, MAC_ADDR_ARRAY(macBSSID));

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Check if this BSS is being currently processed or queued,
    if queued - queue the new request as well
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, 
              __func__, MAC_ADDR_ARRAY(macBSSID));

    wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return wdiStatus;
  }


  wpalMutexRelease(&pWDICtx->wptMutex);
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                  WDI_TRIGGER_BA_REQ,
                  sizeof(halTriggerBAReq.triggerBAParams) +
                  (sizeof(tTriggerBaReqCandidate) *
                  pwdiTriggerBAParams->wdiTriggerBAInfoType.usBACandidateCnt),
                  &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize <
            (usDataOffset + sizeof(halTriggerBAReq.triggerBAParams)+
               (sizeof(tTriggerBaReqCandidate) *
               pwdiTriggerBAParams->wdiTriggerBAInfoType.usBACandidateCnt) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in Trigger BA req %p %p %p",
                pEventData, pwdiTriggerBAParams, wdiTriggerBARspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  halTriggerBAReq.triggerBAParams.baSessionID =
                  pwdiTriggerBAParams->wdiTriggerBAInfoType.ucBASessionID;
  halTriggerBAReq.triggerBAParams.baCandidateCnt =
                  pwdiTriggerBAParams->wdiTriggerBAInfoType.usBACandidateCnt;

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halTriggerBAReq.triggerBAParams,
                  sizeof(halTriggerBAReq.triggerBAParams));

  wdiTriggerBACandidate =
    (WDI_TriggerBAReqCandidateType*)(pwdiTriggerBAParams + 1);
  halTriggerBACandidate = (tTriggerBaReqCandidate*)(pSendBuffer+usDataOffset+
                                 sizeof(halTriggerBAReq.triggerBAParams));

  for(index = 0 ; index < halTriggerBAReq.triggerBAParams.baCandidateCnt ;
                                                                     index++)
  {
    halTriggerBACandidate->staIdx = wdiTriggerBACandidate->ucSTAIdx;
    halTriggerBACandidate->tidBitmap = wdiTriggerBACandidate->ucTidBitmap;
    halTriggerBACandidate++;
    wdiTriggerBACandidate++;
  }

  pWDICtx->wdiReqStatusCB     = pwdiTriggerBAParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiTriggerBAParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Start Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiTriggerBARspCb, pEventData->pUserData,
                        WDI_TRIGGER_BA_RESP);
}/*WDI_ProcessTriggerBAReq*/



/**
 @brief Process Update Beacon Params  Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessUpdateBeaconParamsReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_UpdateBeaconParamsType*  pwdiUpdateBeaconParams;
  WDI_UpdateBeaconParamsRspCb  wdiUpdateBeaconParamsRspCb;
  wpt_uint8*                   pSendBuffer         = NULL;
  wpt_uint16                   usDataOffset        = 0;
  wpt_uint16                   usSendSize          = 0;
  tUpdateBeaconParams          halUpdateBeaconParams;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData) ||
      ( NULL == pEventData->pCBfnc))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiUpdateBeaconParams = (WDI_UpdateBeaconParamsType*)pEventData->pEventData;
  wdiUpdateBeaconParamsRspCb = (WDI_UpdateBeaconParamsRspCb)pEventData->pCBfnc;
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_UPD_BCON_PRMS_REQ,
                        sizeof(halUpdateBeaconParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halUpdateBeaconParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in set bss key req %p %p %p",
                pEventData, pwdiUpdateBeaconParams, wdiUpdateBeaconParamsRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*BSS Index of the BSS*/
  halUpdateBeaconParams.bssIdx =
    pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucBssIdx;
  /*shortPreamble mode. HAL should update all the STA rates when it
    receives this message*/
  halUpdateBeaconParams.fShortPreamble =
    pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucfShortPreamble;
  /* short Slot time.*/
  halUpdateBeaconParams.fShortSlotTime =
    pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucfShortSlotTime;
  /* Beacon Interval */
  halUpdateBeaconParams.beaconInterval =
    pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.usBeaconInterval;

  /*Protection related */
  halUpdateBeaconParams.llaCoexist =
    pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucllaCoexist;
  halUpdateBeaconParams.llbCoexist =
    pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucllbCoexist;
  halUpdateBeaconParams.llgCoexist =
    pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucllgCoexist;
  halUpdateBeaconParams.ht20MhzCoexist  =
    pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucHt20MhzCoexist;
  halUpdateBeaconParams.llnNonGFCoexist =
    pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucllnNonGFCoexist;
  halUpdateBeaconParams.fLsigTXOPProtectionFullSupport =
    pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucfLsigTXOPProtectionFullSupport;
  halUpdateBeaconParams.fRIFSMode =
    pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucfRIFSMode;
  halUpdateBeaconParams.paramChangeBitmap =
    pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.usChangeBitmap;

  wpalMemoryCopy( pSendBuffer+usDataOffset, &halUpdateBeaconParams,
                  sizeof(halUpdateBeaconParams));

  pWDICtx->wdiReqStatusCB     = pwdiUpdateBeaconParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiUpdateBeaconParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Del TS Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiUpdateBeaconParamsRspCb, pEventData->pUserData, WDI_UPD_BCON_PRMS_RESP);
}/*WDI_ProcessUpdateBeaconParamsReq*/



/**
 @brief Process Send Beacon template  Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSendBeaconParamsReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_SendBeaconParamsType*    pwdiSendBeaconParams;
  WDI_SendBeaconParamsRspCb    wdiSendBeaconParamsRspCb;
  wpt_uint8*                   pSendBuffer         = NULL;
  wpt_uint16                   usDataOffset        = 0;
  wpt_uint16                   usSendSize          = 0;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  tSendBeaconReqMsg            halSendBeaconReq;
  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiSendBeaconParams = (WDI_SendBeaconParamsType*)pEventData->pEventData;
  wdiSendBeaconParamsRspCb   = (WDI_SendBeaconParamsRspCb)pEventData->pCBfnc;
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SND_BCON_REQ,
                        sizeof(halSendBeaconReq.sendBeaconParam),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halSendBeaconReq.sendBeaconParam) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in send beacon req %p %p %p",
                pEventData, pwdiSendBeaconParams, wdiSendBeaconParamsRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wpalMemoryCopy(halSendBeaconReq.sendBeaconParam.bssId,
                  pwdiSendBeaconParams->wdiSendBeaconParamsInfo.macBSSID,
                  WDI_MAC_ADDR_LEN);
  halSendBeaconReq.sendBeaconParam.beaconLength =
                  pwdiSendBeaconParams->wdiSendBeaconParamsInfo.beaconLength;
  wpalMemoryCopy(halSendBeaconReq.sendBeaconParam.beacon,
                  pwdiSendBeaconParams->wdiSendBeaconParamsInfo.beacon,
                  pwdiSendBeaconParams->wdiSendBeaconParamsInfo.beaconLength);
  halSendBeaconReq.sendBeaconParam.timIeOffset =
                  pwdiSendBeaconParams->wdiSendBeaconParamsInfo.timIeOffset;
  /* usP2PIeOffset should be atleast greater than timIeOffset */
  if ((pwdiSendBeaconParams->wdiSendBeaconParamsInfo.usP2PIeOffset != 0 ) &&
          (pwdiSendBeaconParams->wdiSendBeaconParamsInfo.usP2PIeOffset <
           pwdiSendBeaconParams->wdiSendBeaconParamsInfo.timIeOffset))
  {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Invalid usP2PIeOffset %hu",
              pwdiSendBeaconParams->wdiSendBeaconParamsInfo.usP2PIeOffset);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
  }

  halSendBeaconReq.sendBeaconParam.p2pIeOffset =
                  pwdiSendBeaconParams->wdiSendBeaconParamsInfo.usP2PIeOffset;

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halSendBeaconReq.sendBeaconParam,
                  sizeof(halSendBeaconReq.sendBeaconParam));

  pWDICtx->wdiReqStatusCB     = pwdiSendBeaconParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiSendBeaconParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Del TS Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiSendBeaconParamsRspCb, pEventData->pUserData, WDI_SND_BCON_RESP);
}/*WDI_ProcessSendBeaconParamsReq*/

/**
 @brief Process Update Beacon Params  Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessUpdateProbeRspTemplateReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_UpdateProbeRspTemplateParamsType*  pwdiUpdateProbeRespTmplParams;
  WDI_UpdateProbeRspTemplateRspCb        wdiUpdateProbeRespTmplRspCb;
  wpt_uint8*                             pSendBuffer         = NULL;
  wpt_uint16                             usDataOffset        = 0;
  wpt_uint16                             usSendSize          = 0;
  tSendProbeRespReqParams                halUpdateProbeRspTmplParams;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData) ||
      ( NULL == pEventData->pCBfnc))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiUpdateProbeRespTmplParams =
    (WDI_UpdateProbeRspTemplateParamsType*)pEventData->pEventData;
  wdiUpdateProbeRespTmplRspCb =
    (WDI_UpdateProbeRspTemplateRspCb)pEventData->pCBfnc;
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_UPD_PROBE_RSP_TEMPLATE_REQ,
                        sizeof(halUpdateProbeRspTmplParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halUpdateProbeRspTmplParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in set bss key req %p %p %p",
     pEventData, pwdiUpdateProbeRespTmplParams, wdiUpdateProbeRespTmplRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wpalMemoryCopy(halUpdateProbeRspTmplParams.bssId,
                 pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo.macBSSID,
                 WDI_MAC_ADDR_LEN);

  halUpdateProbeRspTmplParams.probeRespTemplateLen =
    pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo.uProbeRespTemplateLen;

  wpalMemoryCopy(halUpdateProbeRspTmplParams.pProbeRespTemplate,
    pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo.pProbeRespTemplate,
                 BEACON_TEMPLATE_SIZE);


  wpalMemoryCopy(halUpdateProbeRspTmplParams.ucProxyProbeReqValidIEBmap,
           pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo.uaProxyProbeReqValidIEBmap,
                 WDI_PROBE_REQ_BITMAP_IE_LEN);

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halUpdateProbeRspTmplParams,
                  sizeof(halUpdateProbeRspTmplParams));

  pWDICtx->wdiReqStatusCB     = pwdiUpdateProbeRespTmplParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiUpdateProbeRespTmplParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Update Probe Resp Template Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiUpdateProbeRespTmplRspCb, pEventData->pUserData,
                       WDI_UPD_PROBE_RSP_TEMPLATE_RESP);
}/*WDI_ProcessUpdateProbeRspTemplateReq*/

/**
 @brief Process NV blob download function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessNvDownloadReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{

  WDI_NvDownloadReqParamsType*  pwdiNvDownloadReqParams = NULL;
  WDI_NvDownloadRspCb      wdiNvDownloadRspCb = NULL;

  /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == (pwdiNvDownloadReqParams =
                 (WDI_NvDownloadReqParamsType*)pEventData->pEventData)) ||
      ( NULL == (wdiNvDownloadRspCb =
                (WDI_NvDownloadRspCb)pEventData->pCBfnc)))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);
    WDI_ASSERT(0);
    return WDI_STATUS_E_FAILURE;
  }

  /*Intialize the Nv Blob Info */
  pWDICtx->wdiNvBlobInfo.usTotalFragment =
                TOTALFRAGMENTS(pwdiNvDownloadReqParams->wdiBlobInfo.uBlobSize);

  /*cache the wdi nv request message here if the the first fragment
   * To issue the request to HAL for the next fragment */
  if( 0 == pWDICtx->wdiNvBlobInfo.usCurrentFragment)
  {
    wpalMemoryCopy(&pWDICtx->wdiCachedNvDownloadReq,
                 pwdiNvDownloadReqParams,
                 sizeof(pWDICtx->wdiCachedNvDownloadReq)); 

    pWDICtx->pfncRspCB = pEventData->pCBfnc;
    pWDICtx->pRspCBUserData = pEventData->pUserData;
  }

  return WDI_SendNvBlobReq(pWDICtx,pEventData);
}

/**
 @brief Process Set Max Tx Power Request function (called when Main
        FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status WDI_ProcessSetMaxTxPowerReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_SetMaxTxPowerParamsType*      pwdiSetMaxTxPowerParams = NULL;
  WDA_SetMaxTxPowerRspCb            wdiSetMaxTxPowerRspCb;
  wpt_uint8*                        pSendBuffer         = NULL;
  wpt_uint16                        usDataOffset        = 0;
  wpt_uint16                        usSendSize          = 0;
  tSetMaxTxPwrReq                   halSetMaxTxPower;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  pwdiSetMaxTxPowerParams =
    (WDI_SetMaxTxPowerParamsType*)pEventData->pEventData;
  wdiSetMaxTxPowerRspCb =
    (WDA_SetMaxTxPowerRspCb)pEventData->pCBfnc;

  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_MAX_TX_POWER_REQ,
                        sizeof(halSetMaxTxPower.setMaxTxPwrParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halSetMaxTxPower.setMaxTxPwrParams)
)))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Unable to get Set Max Tx Power req %p %p %p",
                pEventData, pwdiSetMaxTxPowerParams, wdiSetMaxTxPowerRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wpalMemoryCopy(halSetMaxTxPower.setMaxTxPwrParams.bssId,
                  pwdiSetMaxTxPowerParams->wdiMaxTxPowerInfo.macBSSId,
                  WDI_MAC_ADDR_LEN);

  wpalMemoryCopy(halSetMaxTxPower.setMaxTxPwrParams.selfStaMacAddr,
                  pwdiSetMaxTxPowerParams->wdiMaxTxPowerInfo.macSelfStaMacAddr,
                  WDI_MAC_ADDR_LEN);
  halSetMaxTxPower.setMaxTxPwrParams.power =
                  pwdiSetMaxTxPowerParams->wdiMaxTxPowerInfo.ucPower;

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halSetMaxTxPower.setMaxTxPwrParams,
                  sizeof(halSetMaxTxPower.setMaxTxPwrParams));

  pWDICtx->wdiReqStatusCB     = pwdiSetMaxTxPowerParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiSetMaxTxPowerParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Del TS Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiSetMaxTxPowerRspCb, pEventData->pUserData,
                                                      WDI_SET_MAX_TX_POWER_RESP);

}

/*
 @brief Process Set Max Tx Power Per Band Request function (called when Main
        FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status WDI_ProcessSetMaxTxPowerPerBandReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_SetMaxTxPowerPerBandParamsType*    pwdiSetMaxTxPowerPerBandParams = NULL;
  WDA_SetMaxTxPowerPerBandRspCb          wdiSetMaxTxPowerPerBandRspCb;
  wpt_uint8*                             pSendBuffer         = NULL;
  wpt_uint16                             usDataOffset        = 0;
  wpt_uint16                             usSendSize          = 0;
  tpSetMaxTxPwrPerBandParams             phalSetMxTxPwrPerBand = NULL;
  WDI_Status                             rValue = WDI_STATUS_SUCCESS;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  pwdiSetMaxTxPowerPerBandParams = \
  (WDI_SetMaxTxPowerPerBandParamsType*)pEventData->pEventData;

  wdiSetMaxTxPowerPerBandRspCb = \
  (WDA_SetMaxTxPowerPerBandRspCb)pEventData->pCBfnc;

  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/

  rValue = WDI_GetMessageBuffer(pWDICtx,
                                WDI_SET_MAX_TX_POWER_PER_BAND_REQ,
                                sizeof(tSetMaxTxPwrPerBandParams),
                                &pSendBuffer, &usDataOffset, &usSendSize);

  if ((WDI_STATUS_SUCCESS != rValue)|| (usSendSize <
      (usDataOffset + sizeof(tSetMaxTxPwrPerBandParams))))
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
                "Unable to get Set Max Tx Power Per Band req %p %p %p",
                pEventData, pwdiSetMaxTxPowerPerBandParams,
                wdiSetMaxTxPowerPerBandRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }


  phalSetMxTxPwrPerBand = (tpSetMaxTxPwrPerBandParams)(pSendBuffer + usDataOffset);
  phalSetMxTxPwrPerBand->bandInfo = \
  pwdiSetMaxTxPowerPerBandParams->wdiMaxTxPowerPerBandInfo.bandInfo;

  phalSetMxTxPwrPerBand->power = \
  pwdiSetMaxTxPowerPerBandParams->wdiMaxTxPowerPerBandInfo.ucPower;

  pWDICtx->wdiReqStatusCB     = pwdiSetMaxTxPowerPerBandParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiSetMaxTxPowerPerBandParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Set Max Tx Power Per Band Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg(pWDICtx, pSendBuffer, usSendSize,
                      wdiSetMaxTxPowerPerBandRspCb, pEventData->pUserData,
                      WDI_SET_MAX_TX_POWER_PER_BAND_RSP);
}

/**
 @brief Process Set Tx Power Request function (called when Main
        FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status WDI_ProcessSetTxPowerReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_SetTxPowerParamsType*      pwdiSetTxPowerParams = NULL;
  WDA_SetTxPowerRspCb            wdiSetTxPowerRspCb;
  wpt_uint8*                     pSendBuffer          = NULL;
  wpt_uint16                     usDataOffset         = 0;
  wpt_uint16                     usSendSize           = 0;
  tSetTxPwrReqParams            *halSetTxPower       = NULL;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiSetTxPowerParams =
    (WDI_SetTxPowerParamsType*)pEventData->pEventData;
  wdiSetTxPowerRspCb =
    (WDA_SetTxPowerRspCb)pEventData->pCBfnc;

  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_TX_POWER_REQ,
                        sizeof(tSetTxPwrReqParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(tSetTxPwrReqParams)
  )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "Unable to get Set Max Tx Power req %p %p %p",
                 pEventData, pwdiSetTxPowerParams, wdiSetTxPowerRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  halSetTxPower = (tSetTxPwrReqParams *)(pSendBuffer + usDataOffset);
  halSetTxPower->txPower = pwdiSetTxPowerParams->wdiTxPowerInfo.ucPower;
  halSetTxPower->bssIdx  = pwdiSetTxPowerParams->wdiTxPowerInfo.bssIdx;

  pWDICtx->wdiReqStatusCB     = pwdiSetTxPowerParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiSetTxPowerParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Set Tx Power Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiSetTxPowerRspCb, pEventData->pUserData,
                       WDI_SET_TX_POWER_RESP);
}

/**
 @brief Process P2P Notice Of Absence Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessP2PGONOAReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_SetP2PGONOAReqParamsType*          pwdiP2PGONOAReqParams;
  WDI_SetP2PGONOAReqParamsRspCb          wdiP2PGONOAReqRspCb;
  wpt_uint8*                             pSendBuffer         = NULL;
  wpt_uint16                             usDataOffset        = 0;
  wpt_uint16                             usSendSize          = 0;
  tSetP2PGONOAParams                     halSetP2PGONOAParams;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData) ||
      ( NULL == pEventData->pCBfnc))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiP2PGONOAReqParams =
    (WDI_SetP2PGONOAReqParamsType*)pEventData->pEventData;
  wdiP2PGONOAReqRspCb =
    (WDI_SetP2PGONOAReqParamsRspCb)pEventData->pCBfnc;
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                        WDI_P2P_GO_NOTICE_OF_ABSENCE_REQ,
                        sizeof(halSetP2PGONOAParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halSetP2PGONOAParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in set P2P GO NOA REQ %p %p %p",
     pEventData, pwdiP2PGONOAReqParams, wdiP2PGONOAReqRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  halSetP2PGONOAParams.opp_ps =
                           pwdiP2PGONOAReqParams->wdiP2PGONOAInfo.ucOpp_ps;
  halSetP2PGONOAParams.ctWindow =
                           pwdiP2PGONOAReqParams->wdiP2PGONOAInfo.uCtWindow;
  halSetP2PGONOAParams.count = pwdiP2PGONOAReqParams->wdiP2PGONOAInfo.ucCount;
  halSetP2PGONOAParams.duration =
                           pwdiP2PGONOAReqParams->wdiP2PGONOAInfo.uDuration;
  halSetP2PGONOAParams.interval =
                           pwdiP2PGONOAReqParams->wdiP2PGONOAInfo.uInterval;
  halSetP2PGONOAParams.single_noa_duration =
                 pwdiP2PGONOAReqParams->wdiP2PGONOAInfo.uSingle_noa_duration;
  halSetP2PGONOAParams.psSelection =
                   pwdiP2PGONOAReqParams->wdiP2PGONOAInfo.ucPsSelection;

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halSetP2PGONOAParams,
                  sizeof(halSetP2PGONOAParams));

  pWDICtx->wdiReqStatusCB     = pwdiP2PGONOAReqParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiP2PGONOAReqParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Update Probe Resp Template Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiP2PGONOAReqRspCb, pEventData->pUserData,
                       WDI_P2P_GO_NOTICE_OF_ABSENCE_RESP);
}/*WDI_ProcessP2PGONOAReq*/

#ifdef FEATURE_WLAN_TDLS

/**
 @brief Process P2P Notice Of Absence Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessTdlsLinkEstablishReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_SetTDLSLinkEstablishReqParamsType* pwdiTDLSLinkEstablishReqParams;
  WDI_SetTDLSLinkEstablishReqParamsRspCb wdiTDLSLinkEstablishReqRspCb;
  wpt_uint8*                             pSendBuffer         = NULL;
  wpt_uint16                             usDataOffset        = 0;
  wpt_uint16                             usSendSize          = 0;

  tTDLSLinkEstablishedType               halSetTDLSLinkEstablishParams;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData) ||
      ( NULL == pEventData->pCBfnc))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  pwdiTDLSLinkEstablishReqParams =
    (WDI_SetTDLSLinkEstablishReqParamsType*)pEventData->pEventData;
  wdiTDLSLinkEstablishReqRspCb =
    (WDI_SetTDLSLinkEstablishReqParamsRspCb)pEventData->pCBfnc;


  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                        WDI_TDLS_LINK_ESTABLISH_REQ,
                        sizeof(halSetTDLSLinkEstablishParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halSetTDLSLinkEstablishParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in set P2P GO NOA REQ %p %p %p",
     pEventData, pwdiTDLSLinkEstablishReqParams, wdiTDLSLinkEstablishReqRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  halSetTDLSLinkEstablishParams.staIdx =
                           pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.uStaIdx;
  halSetTDLSLinkEstablishParams.bIsResponder =
                           pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.uIsResponder;
  halSetTDLSLinkEstablishParams.acVOUAPSDFlag =
   (pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.uUapsdQueues & 0x08) >> 3;
  halSetTDLSLinkEstablishParams.acVIUAPSDFlag =
   (pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.uUapsdQueues & 0x04) >> 2;
  halSetTDLSLinkEstablishParams.acBKUAPSDFlag =
   (pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.uUapsdQueues & 0x02) >> 1;
  halSetTDLSLinkEstablishParams.acBEUAPSDFlag =
   pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.uUapsdQueues & 0x01;
  halSetTDLSLinkEstablishParams.aAck = 0;
  halSetTDLSLinkEstablishParams.maxServicePeriodLength = (pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.uMaxSp & 0x03);
  halSetTDLSLinkEstablishParams.moreDataAck = 0;
  halSetTDLSLinkEstablishParams.TPUBufferStaSupport =  pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.uIsBufSta;
  halSetTDLSLinkEstablishParams.tdlsOffChannelSupport =
                             pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.uIsOffChannelSupported;

  wpalMemoryCopy( halSetTDLSLinkEstablishParams.validChannels,
                  pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.validChannels,
                  pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.validChannelsLen);
  halSetTDLSLinkEstablishParams.validChannelsLen =
                             pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.validChannelsLen;

  wpalMemoryCopy( halSetTDLSLinkEstablishParams.validOperClasses,
                  pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.validOperClasses,
                  pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.validOperClassesLen);
  halSetTDLSLinkEstablishParams.validOperClassesLen =
                             pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.validOperClassesLen;

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halSetTDLSLinkEstablishParams,
                  sizeof(halSetTDLSLinkEstablishParams));

  pWDICtx->wdiReqStatusCB     = pwdiTDLSLinkEstablishReqParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiTDLSLinkEstablishReqParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Update Probe Resp Template Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiTDLSLinkEstablishReqRspCb, pEventData->pUserData,
                       WDI_TDLS_LINK_ESTABLISH_REQ_RESP);
  return 0;
}/*WDI_ProcessTdlsLinkEstablishReq*/


/**
 @brief sends the channel switch command to f/w (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessTdlsChanSwitchReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_SetTDLSChanSwitchReqParamsType* pwdiTDLSChanSwitchReqParams;
  WDI_SetTDLSChanSwitchReqParamsRspCb wdiTDLSChanSwitchReqRspCb;
  wpt_uint8*                             pSendBuffer         = NULL;
  wpt_uint16                             usDataOffset        = 0;
  wpt_uint16                             usSendSize          = 0;
  //WDI_Status                             wdiStatus;
  tTDLSChanSwitchReqType                  halSetTDLSChanSwitchParams;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  pwdiTDLSChanSwitchReqParams =
    (WDI_SetTDLSChanSwitchReqParamsType*)pEventData->pEventData;
  wdiTDLSChanSwitchReqRspCb =
    (WDI_SetTDLSChanSwitchReqParamsRspCb)pEventData->pCBfnc;

  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                        WDI_TDLS_CHAN_SWITCH_REQ,
                        sizeof(halSetTDLSChanSwitchParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halSetTDLSChanSwitchParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in Channel Switch REQ %p %p %p",
               pEventData, pwdiTDLSChanSwitchReqParams, wdiTDLSChanSwitchReqRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  halSetTDLSChanSwitchParams.staIdx =
    pwdiTDLSChanSwitchReqParams->wdiTDLSChanSwitchReqInfo.staIdx;
  halSetTDLSChanSwitchParams.isOffchannelInitiator =
    pwdiTDLSChanSwitchReqParams->wdiTDLSChanSwitchReqInfo.isOffchannelInitiator;
  halSetTDLSChanSwitchParams.targetOperClass =
    pwdiTDLSChanSwitchReqParams->wdiTDLSChanSwitchReqInfo.targetOperClass;
  halSetTDLSChanSwitchParams.targetChannel =
    pwdiTDLSChanSwitchReqParams->wdiTDLSChanSwitchReqInfo.targetChannel;
  halSetTDLSChanSwitchParams.secondaryChannelOffset =
    pwdiTDLSChanSwitchReqParams->wdiTDLSChanSwitchReqInfo.secondaryChannelOffset;
  wpalMemoryCopy( pSendBuffer+usDataOffset,
                   &halSetTDLSChanSwitchParams,
                   sizeof(halSetTDLSChanSwitchParams));

  pWDICtx->wdiReqStatusCB     = NULL;
  pWDICtx->pReqStatusUserData = NULL;

  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiTDLSChanSwitchReqRspCb, pEventData->pUserData,
                       WDI_TDLS_CHAN_SWITCH_REQ_RESP);
}/*WDI_ProcessTdlsChanSwitchReq*/

#endif /*FEATURE_WLAN_TDLS*/



/**
 @brief    Function to handle the ack from DXE once the power
           state is set.
 @param    None

 @see
 @return void
*/
void
WDI_SetPowerStateCb
(
   wpt_status status,
   unsigned int dxePhyAddr,
   void      *pContext
)
{
   wpt_status              wptStatus;
   WDI_ControlBlockType *pCB = NULL;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
   /*
    * Trigger the event to bring the Enter BMPS req function to come
    * out of wait
*/
   if( NULL != pContext )
   {
      pCB = (WDI_ControlBlockType *)pContext;
   }
   else
   {
      //put an error msg
      pCB = &gWDICb;
   }

   if(eWLAN_PAL_STATUS_SUCCESS == status )
   {
      pCB->dxeRingsEmpty = eWLAN_PAL_TRUE;
   }
   else
   {
      pCB->dxeRingsEmpty = eWLAN_PAL_FALSE;
   }
   pCB->dxePhyAddr = dxePhyAddr;
   wptStatus  = wpalEventSet(&pCB->setPowerStateEvent);
   if ( eWLAN_PAL_STATUS_SUCCESS !=  wptStatus )
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "Failed to set an event");

      WDI_ASSERT(0);
   }
   return;
}


/**
 @brief Process Enter IMPS Request function (called when
        Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessEnterImpsReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   wpt_status               wptStatus; 
   WDI_EnterImpsRspCb       wdiEnterImpsRspCb = NULL;
   wpt_uint8*               pSendBuffer         = NULL;
   wpt_uint16               usDataOffset        = 0;
   wpt_uint16               usSendSize          = 0;
   WDI_EnterImpsReqParamsType*  pwdiEnterImpsReqParams = NULL;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if ((NULL == pEventData ) ||
       (NULL == (wdiEnterImpsRspCb = (WDI_EnterImpsRspCb)pEventData->pCBfnc)) ||
       (NULL == (pwdiEnterImpsReqParams =
                  (WDI_EnterImpsReqParamsType*)pEventData->pEventData)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      goto failRequest;
   }

   /*-----------------------------------------------------------------------
     Get message buffer
     ! TO DO : proper conversion into the HAL Message Request Format
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_ENTER_IMPS_REQ,
                                                     0,
                                                     &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "Unable to get send buffer in Enter IMPS req %p %p",
                 pEventData, wdiEnterImpsRspCb);
      WDI_ASSERT(0);
      goto failRequest;
   }

   /* Reset the event to be not signalled */
   wptStatus = wpalEventReset(&pWDICtx->setPowerStateEvent);
   if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) 
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "WDI Init failed to reset an event");

      WDI_ASSERT(0);
      goto fail;
   }

   // notify DTS that we are entering IMPS
   wptStatus = WDTS_SetPowerState(pWDICtx, WDTS_POWER_STATE_IMPS, WDI_SetPowerStateCb);
   if( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) {
        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                "WDTS_SetPowerState returned with status %d when trying to notify DTS that host is entering IMPS", wptStatus);
        WDI_ASSERT(0);
        goto fail;
    }

   /*
    * Wait for the event to be set once the ACK comes back from DXE
    */
   wptStatus = wpalEventWait(&pWDICtx->setPowerStateEvent, 
                             WDI_SET_POWER_STATE_TIMEOUT);
   if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) 
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "WDI Init failed to wait on an event");

      WDTS_SetPowerState(pWDICtx, WDTS_POWER_STATE_FULL, NULL);
      WDI_ASSERT(0);
      goto fail;
   }

   if (pWDICtx->dxeRingsEmpty == eWLAN_PAL_FALSE)
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                "%s: DXE Rings not empty, cannot enter IMPS",__func__);

      goto fail;
   }

   pWDICtx->wdiReqStatusCB     = pwdiEnterImpsReqParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiEnterImpsReqParams->pUserData;
   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiEnterImpsRspCb, pEventData->pUserData, WDI_ENTER_IMPS_RESP);

fail:
   // Release the message buffer so we don't leak
   wpalMemoryFree(pSendBuffer);

failRequest:
   //WDA should have failure check to avoid the memory leak
   return WDI_STATUS_E_FAILURE;
}/*WDI_ProcessEnterImpsReq*/

/**
 @brief Process Exit IMPS Request function (called when
        Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessExitImpsReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_ExitImpsRspCb        wdiExitImpsRspCb = NULL;
   wpt_uint8*               pSendBuffer         = NULL;
   wpt_uint16               usDataOffset        = 0;
   wpt_uint16               usSendSize          = 0;
   WDI_ExitImpsReqParamsType *pwdiExitImpsReqParams = NULL;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (wdiExitImpsRspCb   = (WDI_ExitImpsRspCb)pEventData->pCBfnc)) ||
        (NULL == (pwdiExitImpsReqParams =
                 (WDI_ExitImpsReqParamsType*)pEventData->pEventData)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   /*-----------------------------------------------------------------------
     Get message buffer
     ! TO DO : proper conversion into the HAL Message Request Format
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_EXIT_IMPS_REQ,
                                                     0,
                                                     &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "Unable to get send buffer in Exit IMPS req %p %p",
                 pEventData, wdiExitImpsRspCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }
   pWDICtx->wdiReqStatusCB = pwdiExitImpsReqParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiExitImpsReqParams->pUserData;
   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiExitImpsRspCb, pEventData->pUserData, WDI_EXIT_IMPS_RESP);
}/*WDI_ProcessExitImpsReq*/

/**
 @brief Process Enter BMPS Request function (called when Main
        FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessEnterBmpsReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_EnterBmpsReqParamsType*  pwdiEnterBmpsReqParams = NULL;
   WDI_EnterBmpsRspCb           wdiEnterBmpsRspCb = NULL;
   wpt_uint8*               pSendBuffer         = NULL;
   wpt_uint16               usDataOffset        = 0;
   wpt_uint16               usSendSize          = 0;
   tHalEnterBmpsReqParams   enterBmpsReq;
   wpt_status               wptStatus; 

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

  /*-------------------------------------------------------------------------
     Sanity check
  -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiEnterBmpsReqParams = (WDI_EnterBmpsReqParamsType*)pEventData->pEventData)) ||
       ( NULL == (wdiEnterBmpsRspCb   = (WDI_EnterBmpsRspCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      goto failRequest;
   }

   /*-----------------------------------------------------------------------
     Get message buffer
     ! TO DO : proper conversion into the HAL Message Request Format
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_ENTER_BMPS_REQ,
                         sizeof(enterBmpsReq),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(enterBmpsReq) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "Unable to get send buffer in Enter BMPS req %p %p %p",
                 pEventData, pwdiEnterBmpsReqParams, wdiEnterBmpsRspCb);
      WDI_ASSERT(0);
      goto failRequest;
   }

   /* Reset the event to be not signalled */
   wptStatus = wpalEventReset(&pWDICtx->setPowerStateEvent);
   if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus )
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "WDI Init failed to reset an event");

      WDI_ASSERT(0);
      goto fail;
   }

   // notify DTS that we are entering BMPS
   wptStatus = WDTS_SetPowerState(pWDICtx, WDTS_POWER_STATE_BMPS, WDI_SetPowerStateCb);
   if( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) 
   {
        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                "WDTS_SetPowerState returned with status %d when trying to notify DTS that we are entering BMPS", wptStatus);
        WDI_ASSERT(0);
        goto fail;
    }

/*
    * Wait for the event to be set once the ACK comes back from DXE
    */
   wptStatus = wpalEventWait(&pWDICtx->setPowerStateEvent, 
                             WDI_SET_POWER_STATE_TIMEOUT);
   if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus )
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "WDI Init failed to wait on an event");

      WDTS_SetPowerState(pWDICtx, WDTS_POWER_STATE_FULL, NULL);
      WDI_ASSERT(0);
      goto fail;
   }

   pWDICtx->bInBmps = eWLAN_PAL_TRUE;

   enterBmpsReq.bssIdx = pwdiEnterBmpsReqParams->wdiEnterBmpsInfo.ucBssIdx;
   enterBmpsReq.tbtt = pwdiEnterBmpsReqParams->wdiEnterBmpsInfo.uTbtt;
   enterBmpsReq.dtimCount = pwdiEnterBmpsReqParams->wdiEnterBmpsInfo.ucDtimCount;
   enterBmpsReq.dtimPeriod = pwdiEnterBmpsReqParams->wdiEnterBmpsInfo.ucDtimPeriod;

   // For ESE and 11R Roaming
   enterBmpsReq.rssiFilterPeriod = pwdiEnterBmpsReqParams->wdiEnterBmpsInfo.rssiFilterPeriod;
   enterBmpsReq.numBeaconPerRssiAverage = pwdiEnterBmpsReqParams->wdiEnterBmpsInfo.numBeaconPerRssiAverage;
   enterBmpsReq.bRssiFilterEnable = pwdiEnterBmpsReqParams->wdiEnterBmpsInfo.bRssiFilterEnable;

   wpalMemoryCopy( pSendBuffer+usDataOffset, 
                   &enterBmpsReq, 
                   sizeof(enterBmpsReq)); 

   pWDICtx->wdiReqStatusCB     = pwdiEnterBmpsReqParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiEnterBmpsReqParams->pUserData;

   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiEnterBmpsRspCb, pEventData->pUserData, WDI_ENTER_BMPS_RESP);

fail:
   // Release the message buffer so we don't leak
   wpalMemoryFree(pSendBuffer);

failRequest:
   //WDA should have failure check to avoid the memory leak
   return WDI_STATUS_E_FAILURE;
}/*WDI_ProcessEnterBmpsReq*/

/**
 @brief Process Exit BMPS Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessExitBmpsReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_ExitBmpsReqParamsType*  pwdiExitBmpsReqParams = NULL;
   WDI_ExitBmpsRspCb           wdiExitBmpsRspCb = NULL;
   wpt_uint8*               pSendBuffer         = NULL;
   wpt_uint16               usDataOffset        = 0;
   wpt_uint16               usSendSize          = 0;
   tHalExitBmpsReqParams    exitBmpsReq;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiExitBmpsReqParams = (WDI_ExitBmpsReqParamsType*)pEventData->pEventData)) ||
       ( NULL == (wdiExitBmpsRspCb   = (WDI_ExitBmpsRspCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   /*-----------------------------------------------------------------------
     Get message buffer
     ! TO DO : proper conversion into the HAL Message Request Format
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_EXIT_BMPS_REQ,
                         sizeof(exitBmpsReq),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(exitBmpsReq) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "Unable to get send buffer in Exit BMPS req %p %p %p",
                 pEventData, pwdiExitBmpsReqParams, wdiExitBmpsRspCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }
   exitBmpsReq.sendDataNull = pwdiExitBmpsReqParams->wdiExitBmpsInfo.ucSendDataNull;

   exitBmpsReq.bssIdx = pwdiExitBmpsReqParams->wdiExitBmpsInfo.bssIdx;

   wpalMemoryCopy( pSendBuffer+usDataOffset, 
                   &exitBmpsReq, 
                   sizeof(exitBmpsReq)); 

   pWDICtx->wdiReqStatusCB     = pwdiExitBmpsReqParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiExitBmpsReqParams->pUserData;

   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiExitBmpsRspCb, pEventData->pUserData, WDI_EXIT_BMPS_RESP);
}/*WDI_ProcessExitBmpsReq*/

/**
 @brief Process Enter UAPSD Request function (called when Main
        FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessEnterUapsdReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_EnterUapsdReqParamsType*  pwdiEnterUapsdReqParams = NULL;
   WDI_EnterUapsdRspCb           wdiEnterUapsdRspCb = NULL;
   wpt_uint8*               pSendBuffer         = NULL;
   wpt_uint16               usDataOffset        = 0;
   wpt_uint16               usSendSize          = 0;
   tUapsdReqParams          enterUapsdReq;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiEnterUapsdReqParams = (WDI_EnterUapsdReqParamsType*)pEventData->pEventData)) ||
       ( NULL == (wdiEnterUapsdRspCb   = (WDI_EnterUapsdRspCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   /*-----------------------------------------------------------------------
     Get message buffer
     ! TO DO : proper conversion into the HAL Message Request Format
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_ENTER_UAPSD_REQ,
                         sizeof(enterUapsdReq),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(enterUapsdReq) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "Unable to get send buffer in Enter UAPSD req %p %p %p",
                 pEventData, pwdiEnterUapsdReqParams, wdiEnterUapsdRspCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   enterUapsdReq.beDeliveryEnabled  = pwdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucBeDeliveryEnabled;
   enterUapsdReq.beTriggerEnabled   = pwdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucBeTriggerEnabled;
   enterUapsdReq.bkDeliveryEnabled  = pwdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucBkDeliveryEnabled;
   enterUapsdReq.bkTriggerEnabled   = pwdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucBkTriggerEnabled;
   enterUapsdReq.viDeliveryEnabled  = pwdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucViDeliveryEnabled;
   enterUapsdReq.viTriggerEnabled   = pwdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucViTriggerEnabled;
   enterUapsdReq.voDeliveryEnabled  = pwdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucVoDeliveryEnabled;
   enterUapsdReq.voTriggerEnabled   = pwdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucVoTriggerEnabled;
   enterUapsdReq.bssIdx             = pwdiEnterUapsdReqParams->wdiEnterUapsdInfo.bssIdx;

   wpalMemoryCopy( pSendBuffer+usDataOffset,
                   &enterUapsdReq,
                   sizeof(enterUapsdReq));

   pWDICtx->wdiReqStatusCB     = pwdiEnterUapsdReqParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiEnterUapsdReqParams->pUserData;

   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiEnterUapsdRspCb, pEventData->pUserData, WDI_ENTER_UAPSD_RESP);
}/*WDI_ProcessEnterUapsdReq*/

/**
 @brief Process Exit UAPSD Request function (called when
        Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessExitUapsdReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_ExitUapsdRspCb       wdiExitUapsdRspCb = NULL;
   wpt_uint8*               pSendBuffer         = NULL;
   wpt_uint16               usDataOffset        = 0;
   wpt_uint16               usSendSize          = 0;
   WDI_ExitUapsdReqParamsType *pExitUapsdparams;
   wpt_uint8                bssIdx = 0;

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

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pExitUapsdparams = (WDI_ExitUapsdReqParamsType *)pEventData->pEventData)) ||
       ( NULL == (wdiExitUapsdRspCb   = (WDI_ExitUapsdRspCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   /*-----------------------------------------------------------------------
     Get message buffer
     ! TO DO : proper conversion into the HAL Message Request Format
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_EXIT_UAPSD_REQ,
                                                     sizeof(wpt_uint8),
                                                     &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(wpt_uint8))))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "Unable to get send buffer in Exit UAPSD req %p %p",
                 pEventData, wdiExitUapsdRspCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   bssIdx = pExitUapsdparams->wdiExitUapsdInfo.bssIdx;

   wpalMemoryCopy( pSendBuffer+usDataOffset,
                   &bssIdx,
                   sizeof(wpt_uint8));

   pWDICtx->wdiReqStatusCB     = pExitUapsdparams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pExitUapsdparams->pUserData;

   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiExitUapsdRspCb, pEventData->pUserData, WDI_EXIT_UAPSD_RESP);
}/*WDI_ProcessExitUapsdReq*/

/**
 @brief Process Set UAPSD params Request function (called when
        Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetUapsdAcParamsReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_SetUapsdAcParamsReqParamsType*  pwdiSetUapsdAcParams = NULL;
  WDI_SetUapsdAcParamsCb              wdiSetUapsdAcParamsCb = NULL;
  wpt_uint8*               pSendBuffer         = NULL;
  wpt_uint16               usDataOffset        = 0;
  wpt_uint16               usSendSize          = 0;
  tUapsdInfo               uapsdAcParamsReq;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == (pwdiSetUapsdAcParams = (WDI_SetUapsdAcParamsReqParamsType*)pEventData->pEventData)) ||
      ( NULL == (wdiSetUapsdAcParamsCb   = (WDI_SetUapsdAcParamsCb)pEventData->pCBfnc)))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-----------------------------------------------------------------------
    Get message buffer
    ! TO DO : proper conversion into the HAL Message Request Format
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_UAPSD_PARAM_REQ,
                        sizeof(uapsdAcParamsReq),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(uapsdAcParamsReq) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in Set UAPSD params req %p %p %p",
                pEventData, pwdiSetUapsdAcParams, wdiSetUapsdAcParamsCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  uapsdAcParamsReq.ac = pwdiSetUapsdAcParams->wdiUapsdInfo.ucAc;
  uapsdAcParamsReq.staidx = pwdiSetUapsdAcParams->wdiUapsdInfo.ucSTAIdx;
  uapsdAcParamsReq.up = pwdiSetUapsdAcParams->wdiUapsdInfo.ucUp;
  uapsdAcParamsReq.delayInterval = pwdiSetUapsdAcParams->wdiUapsdInfo.uDelayInterval;
  uapsdAcParamsReq.srvInterval = pwdiSetUapsdAcParams->wdiUapsdInfo.uSrvInterval;
  uapsdAcParamsReq.susInterval = pwdiSetUapsdAcParams->wdiUapsdInfo.uSusInterval;

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &uapsdAcParamsReq,
                  sizeof(uapsdAcParamsReq));

  pWDICtx->wdiReqStatusCB     = pwdiSetUapsdAcParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiSetUapsdAcParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Get STA Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiSetUapsdAcParamsCb, pEventData->pUserData, WDI_SET_UAPSD_PARAM_RESP);
}/*WDI_ProcessSetUapsdAcParamsReq*/

/**
 @brief Process update UAPSD params Request function (called
        when Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessUpdateUapsdParamsReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_UpdateUapsdReqParamsType*  pwdiUpdateUapsdReqParams = NULL;
   WDI_UpdateUapsdParamsCb        wdiUpdateUapsdParamsCb = NULL;
   wpt_uint8*               pSendBuffer         = NULL;
   wpt_uint16               usDataOffset        = 0;
   wpt_uint16               usSendSize          = 0;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiUpdateUapsdReqParams = (WDI_UpdateUapsdReqParamsType*)pEventData->pEventData)) ||
       ( NULL == (wdiUpdateUapsdParamsCb   = (WDI_UpdateUapsdParamsCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   /*-----------------------------------------------------------------------
     Get message buffer
     ! TO DO : proper conversion into the HAL Message Request Format
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_UPDATE_UAPSD_PARAM_REQ,
                         sizeof(pwdiUpdateUapsdReqParams->wdiUpdateUapsdInfo),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(pwdiUpdateUapsdReqParams->wdiUpdateUapsdInfo) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "Unable to get send buffer in Update UAPSD params req %p %p %p",
                 pEventData, pwdiUpdateUapsdReqParams, wdiUpdateUapsdParamsCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wpalMemoryCopy( pSendBuffer+usDataOffset,
                   &pwdiUpdateUapsdReqParams->wdiUpdateUapsdInfo,
                   sizeof(pwdiUpdateUapsdReqParams->wdiUpdateUapsdInfo));

   pWDICtx->wdiReqStatusCB     = pwdiUpdateUapsdReqParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiUpdateUapsdReqParams->pUserData;

   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiUpdateUapsdParamsCb, pEventData->pUserData, WDI_UPDATE_UAPSD_PARAM_RESP);
}/*WDI_ProcessUpdateUapsdParamsReq*/

/**
 @brief Process Configure RXP filter Request function (called
        when Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessConfigureRxpFilterReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_ConfigureRxpFilterReqParamsType*  pwdiRxpFilterParams = NULL;
  WDI_ConfigureRxpFilterCb              wdiConfigureRxpFilterCb = NULL;
  wpt_uint8*               pSendBuffer         = NULL;
  wpt_uint16               usDataOffset        = 0;
  wpt_uint16               usSendSize          = 0;
  tHalConfigureRxpFilterReqParams     halRxpFilterParams;

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

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == (pwdiRxpFilterParams = (WDI_ConfigureRxpFilterReqParamsType*)pEventData->pEventData)) ||
      ( NULL == (wdiConfigureRxpFilterCb   = (WDI_ConfigureRxpFilterCb)pEventData->pCBfnc)))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

   /*-----------------------------------------------------------------------
     Get message buffer
   -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_CONFIGURE_RXP_FILTER_REQ,
                        sizeof(halRxpFilterParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halRxpFilterParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in Set UAPSD params req %p %p %p",
                pEventData, pwdiRxpFilterParams, wdiConfigureRxpFilterCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  halRxpFilterParams.setMcstBcstFilterSetting =
      pwdiRxpFilterParams->wdiRxpFilterParam.ucSetMcstBcstFilterSetting;
  halRxpFilterParams.setMcstBcstFilter =
      pwdiRxpFilterParams->wdiRxpFilterParam.ucSetMcstBcstFilter;

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halRxpFilterParams,
                  sizeof(halRxpFilterParams));

  pWDICtx->wdiReqStatusCB     = pwdiRxpFilterParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiRxpFilterParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Get STA Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiConfigureRxpFilterCb, pEventData->pUserData, WDI_CONFIGURE_RXP_FILTER_RESP);
}/*WDI_ProcessConfigureRxpFilterReq*/

/**
 @brief Process set beacon filter Request function (called
        when Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetBeaconFilterReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_BeaconFilterReqParamsType*  pwdiBeaconFilterParams = NULL;
   WDI_SetBeaconFilterCb           wdiBeaconFilterCb = NULL;
   wpt_uint8*               pSendBuffer         = NULL;
   wpt_uint16               usDataOffset        = 0;
   wpt_uint16               usSendSize          = 0;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiBeaconFilterParams = (WDI_BeaconFilterReqParamsType*)pEventData->pEventData)) ||
       ( NULL == (wdiBeaconFilterCb   = (WDI_SetBeaconFilterCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   /*-----------------------------------------------------------------------
     Get message buffer
     ! TO DO : proper conversion into the HAL Message Request Format
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_BEACON_FILTER_REQ,
                         sizeof(pwdiBeaconFilterParams->wdiBeaconFilterInfo) + pwdiBeaconFilterParams->wdiBeaconFilterInfo.usIeNum * sizeof(tBeaconFilterIe),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(pwdiBeaconFilterParams->wdiBeaconFilterInfo) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "Unable to get send buffer in Set beacon filter req %p %p %p",
                 pEventData, pwdiBeaconFilterParams, wdiBeaconFilterCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wpalMemoryCopy( pSendBuffer+usDataOffset,
                   &pwdiBeaconFilterParams->wdiBeaconFilterInfo,
                   sizeof(pwdiBeaconFilterParams->wdiBeaconFilterInfo));
   wpalMemoryCopy( pSendBuffer+usDataOffset+sizeof(pwdiBeaconFilterParams->wdiBeaconFilterInfo),
                   &pwdiBeaconFilterParams->aFilters[0],
                   pwdiBeaconFilterParams->wdiBeaconFilterInfo.usIeNum * sizeof(tBeaconFilterIe));

   pWDICtx->wdiReqStatusCB     = pwdiBeaconFilterParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiBeaconFilterParams->pUserData;

   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiBeaconFilterCb, pEventData->pUserData, WDI_SET_BEACON_FILTER_RESP);
}/*WDI_ProcessSetBeaconFilterReq*/

/**
 @brief Process remove beacon filter Request function (called
        when Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessRemBeaconFilterReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_RemBeaconFilterReqParamsType*  pwdiBeaconFilterParams = NULL;
   WDI_RemBeaconFilterCb              wdiBeaconFilterCb = NULL;
   wpt_uint8*               pSendBuffer         = NULL;
   wpt_uint16               usDataOffset        = 0;
   wpt_uint16               usSendSize          = 0;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiBeaconFilterParams = (WDI_RemBeaconFilterReqParamsType*)pEventData->pEventData)) ||
       ( NULL == (wdiBeaconFilterCb   = (WDI_RemBeaconFilterCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   /*-----------------------------------------------------------------------
     Get message buffer
     ! TO DO : proper conversion into the HAL Message Request Format
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_REM_BEACON_FILTER_REQ,
                         sizeof(pwdiBeaconFilterParams->wdiBeaconFilterInfo),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(pwdiBeaconFilterParams->wdiBeaconFilterInfo) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in remove beacon filter req %p %p %p",
                  pEventData, pwdiBeaconFilterParams, wdiBeaconFilterCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wpalMemoryCopy( pSendBuffer+usDataOffset,
                   &pwdiBeaconFilterParams->wdiBeaconFilterInfo,
                   sizeof(pwdiBeaconFilterParams->wdiBeaconFilterInfo));

   pWDICtx->wdiReqStatusCB     = pwdiBeaconFilterParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiBeaconFilterParams->pUserData;

   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiBeaconFilterCb, pEventData->pUserData, WDI_REM_BEACON_FILTER_RESP);
}

/**
 @brief Process set RSSI thresholds Request function (called
        when Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetRSSIThresholdsReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_SetRSSIThresholdsReqParamsType*  pwdiRSSIThresholdsParams = NULL;
   WDI_SetRSSIThresholdsCb              wdiRSSIThresholdsCb = NULL;
   wpt_uint8*               pSendBuffer         = NULL;
   wpt_uint16               usDataOffset        = 0;
   wpt_uint16               usSendSize          = 0;
   tHalRSSIThresholds       rssiThresholdsReq;
   WDI_Status               ret_status = 0;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiRSSIThresholdsParams = (WDI_SetRSSIThresholdsReqParamsType*)pEventData->pEventData)) ||
       ( NULL == (wdiRSSIThresholdsCb   = (WDI_SetRSSIThresholdsCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   /*-----------------------------------------------------------------------
     Get message buffer
     ! TO DO : proper conversion into the HAL Message Request Format
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_RSSI_THRESHOLDS_REQ,
                         sizeof(rssiThresholdsReq),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(rssiThresholdsReq) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in remove beacon filter req %p %p %p",
                  pEventData, pwdiRSSIThresholdsParams, wdiRSSIThresholdsCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   rssiThresholdsReq.bReserved10 =
      pwdiRSSIThresholdsParams->wdiRSSIThresholdsInfo.bReserved10;
   rssiThresholdsReq.bRssiThres1NegNotify =
      pwdiRSSIThresholdsParams->wdiRSSIThresholdsInfo.bRssiThres1NegNotify;
   rssiThresholdsReq.bRssiThres1PosNotify =
      pwdiRSSIThresholdsParams->wdiRSSIThresholdsInfo.bRssiThres1PosNotify;
   rssiThresholdsReq.bRssiThres2NegNotify =
      pwdiRSSIThresholdsParams->wdiRSSIThresholdsInfo.bRssiThres2NegNotify;
   rssiThresholdsReq.bRssiThres2PosNotify =
      pwdiRSSIThresholdsParams->wdiRSSIThresholdsInfo.bRssiThres2PosNotify;
   rssiThresholdsReq.bRssiThres3NegNotify =
      pwdiRSSIThresholdsParams->wdiRSSIThresholdsInfo.bRssiThres3NegNotify;
   rssiThresholdsReq.bRssiThres3PosNotify =
      pwdiRSSIThresholdsParams->wdiRSSIThresholdsInfo.bRssiThres3PosNotify;
   rssiThresholdsReq.ucRssiThreshold1 =
      pwdiRSSIThresholdsParams->wdiRSSIThresholdsInfo.ucRssiThreshold1;
   rssiThresholdsReq.ucRssiThreshold2 =
      pwdiRSSIThresholdsParams->wdiRSSIThresholdsInfo.ucRssiThreshold2;
   rssiThresholdsReq.ucRssiThreshold3 =
      pwdiRSSIThresholdsParams->wdiRSSIThresholdsInfo.ucRssiThreshold3;

   wpalMemoryCopy( pSendBuffer+usDataOffset,
                   &rssiThresholdsReq,
                   sizeof(rssiThresholdsReq));

   pWDICtx->wdiReqStatusCB     = pwdiRSSIThresholdsParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiRSSIThresholdsParams->pUserData;

   /*-------------------------------------------------------------------------
     Send Set threshold req to HAL 
   -------------------------------------------------------------------------*/
   if ((ret_status = WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, 
                        wdiRSSIThresholdsCb, pEventData->pUserData, WDI_SET_RSSI_THRESHOLDS_RESP)) == WDI_STATUS_SUCCESS)
   {
      // When we are in idle state WDI_STARTED_ST and we receive indication for threshold
      // req. Then as a result of processing the threshold cross ind, we trigger
      // a Set threshold req, then we need to indicate to WDI that it needs to 
      // go to busy state as a result of the indication as we sent a req in the 
      // same WDI context.
      // Hence expected state transition is to busy.
      pWDICtx->ucExpectedStateTransition =  WDI_BUSY_ST;
   }

   return ret_status;
}

/**
 @brief Process set RSSI thresholds Request function (called
        when Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessHostOffloadReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_HostOffloadReqParamsType*  pwdiHostOffloadParams = NULL;
   WDI_HostOffloadCb              wdiHostOffloadCb = NULL;
   wpt_uint8*               pSendBuffer         = NULL;
   wpt_uint16               usDataOffset        = 0;
   wpt_uint16               usSendSize          = 0;
   tHalHostOffloadReq       hostOffloadParams;
   tHalNSOffloadParams      nsOffloadParams;
   wpt_uint8                ucCurrentBSSSesIdx  = 0;
   WDI_BSSSessionType*      pBSSSes = NULL;

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

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiHostOffloadParams = (WDI_HostOffloadReqParamsType*)pEventData->pEventData)) ||
       ( NULL == (wdiHostOffloadCb   = (WDI_HostOffloadCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      goto failRequest;
   }

   /*-----------------------------------------------------------------------
     Get message buffer
     ! TO DO : proper conversion into the HAL Message Request Format
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_HOST_OFFLOAD_REQ,
                         sizeof(hostOffloadParams)+sizeof(nsOffloadParams),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(hostOffloadParams) + sizeof(nsOffloadParams) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in host offload req %p %p %p",
                  pEventData, pwdiHostOffloadParams, wdiHostOffloadCb);
      WDI_ASSERT(0);
      goto failRequest;
   }

   ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, 
                            pwdiHostOffloadParams->wdiHostOffloadInfo.bssId, 
                            &pBSSSes);
   if ( NULL == pBSSSes )
   {
       WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 " %s : Association for this BSSID does not exist " MAC_ADDRESS_STR,
                 __func__, MAC_ADDR_ARRAY(pwdiHostOffloadParams->wdiHostOffloadInfo.bssId));
       goto fail;
   }

   hostOffloadParams.offloadType = pwdiHostOffloadParams->wdiHostOffloadInfo.ucOffloadType;
   hostOffloadParams.enableOrDisable = pwdiHostOffloadParams->wdiHostOffloadInfo.ucEnableOrDisable;

   if( HAL_IPV4_ARP_REPLY_OFFLOAD == hostOffloadParams.offloadType )
   {
      // ARP Offload
      wpalMemoryCopy(hostOffloadParams.params.hostIpv4Addr,
                     pwdiHostOffloadParams->wdiHostOffloadInfo.params.aHostIpv4Addr,
                     4);
   }
   else
   {
      // NS Offload
      wpalMemoryCopy(hostOffloadParams.params.hostIpv6Addr,
                     pwdiHostOffloadParams->wdiHostOffloadInfo.params.aHostIpv6Addr,
                     16);

#ifdef WLAN_NS_OFFLOAD
        // copy pwdiHostOffloadParams->wdiNsOffloadParams into nsOffloadParams
        wpalMemoryCopy(nsOffloadParams.srcIPv6Addr,
                        pwdiHostOffloadParams->wdiNsOffloadParams.srcIPv6Addr,
                        16);
        wpalMemoryCopy(nsOffloadParams.selfIPv6Addr,
                        pwdiHostOffloadParams->wdiNsOffloadParams.selfIPv6Addr,
                        16);
        wpalMemoryCopy(nsOffloadParams.targetIPv6Addr1,
                        pwdiHostOffloadParams->wdiNsOffloadParams.targetIPv6Addr1,
                        16);
        wpalMemoryCopy(nsOffloadParams.targetIPv6Addr2,
                        pwdiHostOffloadParams->wdiNsOffloadParams.targetIPv6Addr2,
                        16);
        wpalMemoryCopy(nsOffloadParams.selfMacAddr,
                        pwdiHostOffloadParams->wdiNsOffloadParams.selfMacAddr,
                        6);
        nsOffloadParams.srcIPv6AddrValid =
            pwdiHostOffloadParams->wdiNsOffloadParams.srcIPv6AddrValid;

        nsOffloadParams.targetIPv6Addr1Valid =
            pwdiHostOffloadParams->wdiNsOffloadParams.targetIPv6Addr1Valid;

        nsOffloadParams.targetIPv6Addr2Valid =
            pwdiHostOffloadParams->wdiNsOffloadParams.targetIPv6Addr2Valid;

        nsOffloadParams.slotIndex =
            pwdiHostOffloadParams->wdiNsOffloadParams.slotIdx;

#endif // WLAN_NS_OFFLOAD
   }

   nsOffloadParams.bssIdx = pBSSSes->ucBSSIdx;

   // copy hostOffloadParams into pSendBuffer
   wpalMemoryCopy( pSendBuffer+usDataOffset, 
                   &hostOffloadParams, 
                   sizeof(hostOffloadParams)); 

   if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION) )
   {
        // copy nsOffloadParams into pSendBuffer
        wpalMemoryCopy( pSendBuffer+usDataOffset+sizeof(hostOffloadParams), 
                       &nsOffloadParams, 
                       sizeof(nsOffloadParams)); 
    }
    else
    {
#ifdef WLAN_NS_OFFLOAD
        if( HAL_IPV6_NS_OFFLOAD == hostOffloadParams.offloadType )
        {
            // copy nsOffloadParams into pSendBuffer
            wpalMemoryCopy( pSendBuffer+usDataOffset+sizeof(hostOffloadParams), 
                       &nsOffloadParams, 
                       sizeof(nsOffloadParams)); 
        }
#endif
     }

   pWDICtx->wdiReqStatusCB     = pwdiHostOffloadParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiHostOffloadParams->pUserData;

   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiHostOffloadCb, pEventData->pUserData, WDI_HOST_OFFLOAD_RESP);

fail:
   // Release the message buffer so we don't leak
   wpalMemoryFree(pSendBuffer);

failRequest:
   //WDA should have failure check to avoid the memory leak
   return WDI_STATUS_E_FAILURE;
}/*WDI_ProcessHostOffloadReq*/

/**
 @brief Process Keep Alive Request function (called
        when Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessKeepAliveReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_KeepAliveReqParamsType*  pwdiKeepAliveParams = NULL;
   WDI_KeepAliveCb              wdiKeepAliveCb = NULL;
   wpt_uint8*               pSendBuffer         = NULL;
   wpt_uint16               usDataOffset        = 0;
   wpt_uint16               usSendSize          = 0;
   tHalKeepAliveReq         keepAliveReq;
   wpt_uint8                ucCurrentBSSSesIdx  = 0;
   WDI_BSSSessionType*      pBSSSes = NULL;

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

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiKeepAliveParams = (WDI_KeepAliveReqParamsType*)pEventData->pEventData)) ||
       ( NULL == (wdiKeepAliveCb   = (WDI_KeepAliveCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
               "Invalid parameters in Keep Alive req");
      WDI_ASSERT(0);
      goto failRequest;
   }

   /*-----------------------------------------------------------------------
     Get message buffer
     ! TO DO : proper conversion into the HAL Message Request Format
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_KEEP_ALIVE_REQ,
                         sizeof(keepAliveReq),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(keepAliveReq) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
                  "Unable to get send buffer in keep alive req %p %p %p",
                  pEventData, pwdiKeepAliveParams, wdiKeepAliveCb);
      WDI_ASSERT(0);
      goto failRequest;
   }

   ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, 
                            pwdiKeepAliveParams->wdiKeepAliveInfo.bssId, 
                            &pBSSSes);
   if ( NULL == pBSSSes )
   {
       WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 " %s : Association for this BSSID does not exist",__func__);
       goto fail;
   }

   keepAliveReq.packetType = pwdiKeepAliveParams->wdiKeepAliveInfo.ucPacketType;
   keepAliveReq.timePeriod = pwdiKeepAliveParams->wdiKeepAliveInfo.ucTimePeriod;

   keepAliveReq.bssIdx = pBSSSes->ucBSSIdx;

   if(pwdiKeepAliveParams->wdiKeepAliveInfo.ucPacketType == 2)
   {
   wpalMemoryCopy(keepAliveReq.hostIpv4Addr,
                     pwdiKeepAliveParams->wdiKeepAliveInfo.aHostIpv4Addr,
                     HAL_IPV4_ADDR_LEN);
   wpalMemoryCopy(keepAliveReq.destIpv4Addr,
                     pwdiKeepAliveParams->wdiKeepAliveInfo.aDestIpv4Addr,
                     HAL_IPV4_ADDR_LEN);
   wpalMemoryCopy(keepAliveReq.destMacAddr,
                     pwdiKeepAliveParams->wdiKeepAliveInfo.aDestMacAddr,
                     HAL_MAC_ADDR_LEN);
   }

   wpalMemoryCopy( pSendBuffer+usDataOffset,
                   &keepAliveReq,
                   sizeof(keepAliveReq));

   WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_INFO,
               "Process keep alive req %zu", sizeof(keepAliveReq));

   WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_INFO,
               "Process keep alive req time period %d",
               keepAliveReq.timePeriod);

   pWDICtx->wdiReqStatusCB     = pwdiKeepAliveParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiKeepAliveParams->pUserData;

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_INFO,
                  "Sending keep alive req to HAL");

   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiKeepAliveCb, pEventData->pUserData, WDI_KEEP_ALIVE_RESP);

fail:
   // Release the message buffer so we don't leak
   wpalMemoryFree(pSendBuffer);

failRequest:
   //WDA should have failure check to avoid the memory leak
   return WDI_STATUS_E_FAILURE;
}/*WDI_ProcessKeepAliveReq*/


/**
 @brief Process Wowl add bc ptrn Request function (called
        when Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessWowlAddBcPtrnReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_WowlAddBcPtrnReqParamsType*  pwdiWowlAddBcPtrnParams = NULL;
   WDI_WowlAddBcPtrnCb              wdiWowlAddBcPtrnCb = NULL;
   wpt_uint8*               pSendBuffer         = NULL;
   wpt_uint16               usDataOffset        = 0;
   wpt_uint16               usSendSize          = 0;
   tHalWowlAddBcastPtrn     wowlAddBcPtrnReq;
   wpt_uint8                ucCurrentBSSSesIdx  = 0;
   WDI_BSSSessionType*        pBSSSes = NULL;

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

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiWowlAddBcPtrnParams = (WDI_WowlAddBcPtrnReqParamsType*)pEventData->pEventData)) ||
       ( NULL == (wdiWowlAddBcPtrnCb   = (WDI_WowlAddBcPtrnCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      goto failRequest;
   }

   /*-----------------------------------------------------------------------
     Get message buffer
     ! TO DO : proper conversion into the HAL Message Request Format
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_WOWL_ADD_BC_PTRN_REQ,
                         sizeof(wowlAddBcPtrnReq),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(wowlAddBcPtrnReq) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in Wowl add bc ptrn req %p %p %p",
                  pEventData, pwdiWowlAddBcPtrnParams, wdiWowlAddBcPtrnCb);
      WDI_ASSERT(0);
      goto failRequest;
   }

   ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, 
                            pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.bssId, 
                            &pBSSSes);
   if ( NULL == pBSSSes )
   {
       WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 " %s : Association for this BSSID does not exist",__func__);
       goto fail;
   }

   wowlAddBcPtrnReq.ucPatternId =
      pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternId;
   wowlAddBcPtrnReq.ucPatternByteOffset =
      pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternByteOffset;
   wowlAddBcPtrnReq.ucPatternMaskSize =
      pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternMaskSize;
   wowlAddBcPtrnReq.ucPatternSize =
      pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternSize;

   if (pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternSize <= HAL_WOWL_BCAST_PATTERN_MAX_SIZE)
   {
       wpalMemoryCopy(wowlAddBcPtrnReq.ucPattern,
                      pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPattern,
                      pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternSize);
       wpalMemoryCopy(wowlAddBcPtrnReq.ucPatternMask,
                      pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternMask,
                      pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternMaskSize);
   }
   else
   {
       wpalMemoryCopy(wowlAddBcPtrnReq.ucPattern,
                      pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPattern,
                      HAL_WOWL_BCAST_PATTERN_MAX_SIZE);
       wpalMemoryCopy(wowlAddBcPtrnReq.ucPatternMask,
                      pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternMask,
                      HAL_WOWL_BCAST_PATTERN_MAX_SIZE);

       wpalMemoryCopy(wowlAddBcPtrnReq.ucPattern,
                      pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPattern,
                      pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternMaskSize - HAL_WOWL_BCAST_PATTERN_MAX_SIZE);
       wpalMemoryCopy(wowlAddBcPtrnReq.ucPatternMask,
                      pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternMask,
                      pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternMaskSize - HAL_WOWL_BCAST_PATTERN_MAX_SIZE);
   }

   wowlAddBcPtrnReq.bssIdx  = pBSSSes->ucBSSIdx;

   wpalMemoryCopy( pSendBuffer+usDataOffset, 
                   &wowlAddBcPtrnReq, 
                   sizeof(wowlAddBcPtrnReq)); 

   pWDICtx->wdiReqStatusCB     = pwdiWowlAddBcPtrnParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiWowlAddBcPtrnParams->pUserData;

   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiWowlAddBcPtrnCb, pEventData->pUserData, WDI_WOWL_ADD_BC_PTRN_RESP);
fail:
   // Release the message buffer so we don't leak
   wpalMemoryFree(pSendBuffer);

failRequest:
   //WDA should have failure check to avoid the memory leak
   return WDI_STATUS_E_FAILURE;
}/*WDI_ProcessWowlAddBcPtrnReq*/

/**
 @brief Process Wowl delete bc ptrn Request function (called
        when Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessWowlDelBcPtrnReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_WowlDelBcPtrnReqParamsType*  pwdiWowlDelBcPtrnParams = NULL;
   WDI_WowlDelBcPtrnCb              wdiWowlDelBcPtrnCb = NULL;
   wpt_uint8*               pSendBuffer         = NULL;
   wpt_uint16               usDataOffset        = 0;
   wpt_uint16               usSendSize          = 0;
   tHalWowlDelBcastPtrn     wowlDelBcPtrnReq;
   wpt_uint8                ucCurrentBSSSesIdx  = 0;
   WDI_BSSSessionType*        pBSSSes = NULL;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiWowlDelBcPtrnParams = (WDI_WowlDelBcPtrnReqParamsType*)pEventData->pEventData)) ||
       ( NULL == (wdiWowlDelBcPtrnCb   = (WDI_WowlDelBcPtrnCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      goto failRequest;
   }

   /*-----------------------------------------------------------------------
     Get message buffer
     ! TO DO : proper conversion into the HAL Message Request Format
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_WOWL_DEL_BC_PTRN_REQ,
                         sizeof(wowlDelBcPtrnReq),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(wowlDelBcPtrnReq) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in Wowl del bc ptrn req %p %p %p",
                  pEventData, pwdiWowlDelBcPtrnParams, wdiWowlDelBcPtrnCb);
      WDI_ASSERT(0);
      goto failRequest;
   }

    ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, 
                               pwdiWowlDelBcPtrnParams->wdiWowlDelBcPtrnInfo.bssId, 
                               &pBSSSes);
   if ( NULL == pBSSSes )
   {
       WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                    " %s : Association for this BSSID does not exist",__func__);
       goto fail;
   }

   wowlDelBcPtrnReq.ucPatternId =
      pwdiWowlDelBcPtrnParams->wdiWowlDelBcPtrnInfo.ucPatternId;

   wowlDelBcPtrnReq.bssIdx = pBSSSes->ucBSSIdx;

   wpalMemoryCopy( pSendBuffer+usDataOffset,
                   &wowlDelBcPtrnReq,
                   sizeof(wowlDelBcPtrnReq));

   pWDICtx->wdiReqStatusCB     = pwdiWowlDelBcPtrnParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiWowlDelBcPtrnParams->pUserData;

   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiWowlDelBcPtrnCb, pEventData->pUserData, WDI_WOWL_DEL_BC_PTRN_RESP);

fail:
   // Release the message buffer so we don't leak
   wpalMemoryFree(pSendBuffer);

failRequest:
   //WDA should have failure check to avoid the memory leak
   return WDI_STATUS_E_FAILURE;
}/*WDI_ProcessWowlDelBcPtrnReq*/

/**
 @brief Process Wowl enter Request function (called
        when Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessWowlEnterReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_WowlEnterReqParamsType*  pwdiWowlEnterParams = NULL;
   WDI_WowlEnterReqCb           wdiWowlEnterCb = NULL;
   wpt_uint8*               pSendBuffer         = NULL;
   wpt_uint16               usDataOffset        = 0;
   wpt_uint16               usSendSize          = 0;
   tHalWowlEnterParams      wowlEnterReq;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiWowlEnterParams = (WDI_WowlEnterReqParamsType*)pEventData->pEventData)) ||
       ( NULL == (wdiWowlEnterCb   = (WDI_WowlEnterReqCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   /*-----------------------------------------------------------------------
     Get message buffer
     ! TO DO : proper conversion into the HAL Message Request Format
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_WOWL_ENTER_REQ,
                         sizeof(wowlEnterReq),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(wowlEnterReq) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in Wowl enter req %p %p %p",
                  pEventData, pwdiWowlEnterParams, wdiWowlEnterCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wpalMemoryZero(&wowlEnterReq, sizeof(tHalWowlEnterParams));

   wowlEnterReq.ucMagicPktEnable =
      pwdiWowlEnterParams->wdiWowlEnterInfo.ucMagicPktEnable;
   wowlEnterReq.ucPatternFilteringEnable =
      pwdiWowlEnterParams->wdiWowlEnterInfo.ucPatternFilteringEnable;
   wowlEnterReq.ucUcastPatternFilteringEnable =
      pwdiWowlEnterParams->wdiWowlEnterInfo.ucUcastPatternFilteringEnable;
   wowlEnterReq.ucWowChnlSwitchRcv =
      pwdiWowlEnterParams->wdiWowlEnterInfo.ucWowChnlSwitchRcv;
   wowlEnterReq.ucWowDeauthRcv =
      pwdiWowlEnterParams->wdiWowlEnterInfo.ucWowDeauthRcv;
   wowlEnterReq.ucWowDisassocRcv =
      pwdiWowlEnterParams->wdiWowlEnterInfo.ucWowDisassocRcv;
   wowlEnterReq.ucWowMaxMissedBeacons =
      pwdiWowlEnterParams->wdiWowlEnterInfo.ucWowMaxMissedBeacons;
   wowlEnterReq.ucWowMaxSleepUsec =
      pwdiWowlEnterParams->wdiWowlEnterInfo.ucWowMaxSleepUsec;

#ifdef WLAN_WAKEUP_EVENTS
   wowlEnterReq.ucWoWEAPIDRequestEnable = 
      pwdiWowlEnterParams->wdiWowlEnterInfo.ucWoWEAPIDRequestEnable;

   wowlEnterReq.ucWoWEAPOL4WayEnable =
      pwdiWowlEnterParams->wdiWowlEnterInfo.ucWoWEAPOL4WayEnable;

   wowlEnterReq.ucWowNetScanOffloadMatch = 
      pwdiWowlEnterParams->wdiWowlEnterInfo.ucWowNetScanOffloadMatch;

   wowlEnterReq.ucWowGTKRekeyError = 
      pwdiWowlEnterParams->wdiWowlEnterInfo.ucWowGTKRekeyError;

   wowlEnterReq.ucWoWBSSConnLoss = 
      pwdiWowlEnterParams->wdiWowlEnterInfo.ucWoWBSSConnLoss;
#endif // WLAN_WAKEUP_EVENTS

   wowlEnterReq.bssIdx = pwdiWowlEnterParams->wdiWowlEnterInfo.bssIdx;

   wpalMemoryCopy(wowlEnterReq.magicPtrn,
                  pwdiWowlEnterParams->wdiWowlEnterInfo.magicPtrn,
                  sizeof(tSirMacAddr));

   wpalMemoryCopy( pSendBuffer+usDataOffset,
                   &wowlEnterReq,
                   sizeof(wowlEnterReq));

   pWDICtx->wdiReqStatusCB     = pwdiWowlEnterParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiWowlEnterParams->pUserData;

   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiWowlEnterCb, pEventData->pUserData, WDI_WOWL_ENTER_RESP);
}/*WDI_ProcessWowlEnterReq*/

/**
 @brief Process Wowl exit Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessWowlExitReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_WowlExitReqCb           wdiWowlExitCb = NULL;
   WDI_WowlExitReqParamsType*  pwdiWowlExitParams = NULL;
   wpt_uint8*               pSendBuffer         = NULL;
   wpt_uint16               usDataOffset        = 0;
   wpt_uint16               usSendSize          = 0;
   tHalWowlExitParams       wowlExitparams;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiWowlExitParams = (WDI_WowlExitReqParamsType *)pEventData->pEventData)) ||
       ( NULL == (wdiWowlExitCb   = (WDI_WowlExitReqCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   /*-----------------------------------------------------------------------
     Get message buffer
     ! TO DO : proper conversion into the HAL Message Request Format
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_WOWL_EXIT_REQ,
                                                     sizeof(wowlExitparams),
                                                     &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(wowlExitparams))))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "Unable to get send buffer in Wowl Exit req %p %p",
                 pEventData, wdiWowlExitCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wowlExitparams.bssIdx = pwdiWowlExitParams->wdiWowlExitInfo.bssIdx;

   wpalMemoryCopy( pSendBuffer+usDataOffset,
                   &wowlExitparams,
                   sizeof(wowlExitparams));
   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiWowlExitCb, pEventData->pUserData, WDI_WOWL_EXIT_RESP);
}/*WDI_ProcessWowlExitReq*/

/**
 @brief Process Configure Apps Cpu Wakeup State Request function
        (called when Main FSM allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessConfigureAppsCpuWakeupStateReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_ConfigureAppsCpuWakeupStateReqParamsType*  pwdiAppsCpuWakeupStateParams = NULL;
   WDI_ConfigureAppsCpuWakeupStateCb              wdiConfigureAppsCpuWakeupStateCb = NULL;
   wpt_uint8*               pSendBuffer         = NULL;
   wpt_uint16               usDataOffset        = 0;
   wpt_uint16               usSendSize          = 0;
   tHalConfigureAppsCpuWakeupStateReqParams  halCfgAppsCpuWakeupStateReqParams;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiAppsCpuWakeupStateParams = (WDI_ConfigureAppsCpuWakeupStateReqParamsType*)pEventData->pEventData)) ||
       ( NULL == (wdiConfigureAppsCpuWakeupStateCb   = (WDI_ConfigureAppsCpuWakeupStateCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   /*-----------------------------------------------------------------------
     Get message buffer
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_REQ,
                         sizeof(halCfgAppsCpuWakeupStateReqParams),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(pwdiAppsCpuWakeupStateParams->bIsAppsAwake) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "Unable to get send buffer in Apps CPU Wakeup State req %p %p %p",
                 pEventData, pwdiAppsCpuWakeupStateParams, wdiConfigureAppsCpuWakeupStateCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   halCfgAppsCpuWakeupStateReqParams.isAppsCpuAwake =
                           pwdiAppsCpuWakeupStateParams->bIsAppsAwake;

   wpalMemoryCopy( pSendBuffer+usDataOffset,
                   &halCfgAppsCpuWakeupStateReqParams,
                   sizeof(halCfgAppsCpuWakeupStateReqParams));

   pWDICtx->wdiReqStatusCB     = pwdiAppsCpuWakeupStateParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiAppsCpuWakeupStateParams->pUserData;

   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiConfigureAppsCpuWakeupStateCb, pEventData->pUserData,
                        WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_RESP);
}/*WDI_ProcessConfigureAppsCpuWakeupStateReq*/

#ifdef WLAN_FEATURE_VOWIFI_11R
/**
 @brief Process Aggregated Add TSpec Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessAggrAddTSpecReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_AggrAddTSReqParamsType*  pwdiAggrAddTSParams;
  WDI_AggrAddTsRspCb           wdiAggrAddTSRspCb;
  wpt_uint8                ucCurrentBSSSesIdx  = 0;
  WDI_BSSSessionType*      pBSSSes             = NULL;
  wpt_uint8*               pSendBuffer         = NULL;
  wpt_uint16               usDataOffset        = 0;
  wpt_uint16               usSendSize          = 0;
  WDI_Status               wdiStatus           = WDI_STATUS_SUCCESS;
  wpt_macAddr              macBSSID;
  tAggrAddTsReq            halAggrAddTsReq;
  int i;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  wpalMemoryFill( &halAggrAddTsReq, sizeof(tAggrAddTsReq), 0 );
  pwdiAggrAddTSParams = (WDI_AggrAddTSReqParamsType*)pEventData->pEventData;
  wdiAggrAddTSRspCb   = (WDI_AggrAddTsRspCb)pEventData->pCBfnc;
  /*-------------------------------------------------------------------------
    Check to see if we are in the middle of an association, if so queue, if
    not it means it is free to process request
  -------------------------------------------------------------------------*/
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made and identify WDI session
  ------------------------------------------------------------------------*/
  if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx,
                                        pwdiAggrAddTSParams->wdiAggrTsInfo.ucSTAIdx,
                                        &macBSSID))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                "This station does not exist in the WDI Station Table %d",
                pwdiAggrAddTSParams->wdiAggrTsInfo.ucSTAIdx);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_FAILURE;
  }

  ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes);
  if ( NULL == pBSSSes )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, 
        "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, 
        __func__, MAC_ADDR_ARRAY(macBSSID));

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Check if this BSS is being currently processed or queued,
    if queued - queue the new request as well
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR,
              __func__, MAC_ADDR_ARRAY(macBSSID));

    wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return wdiStatus;
  }

  wpalMutexRelease(&pWDICtx->wptMutex);
  /*-----------------------------------------------------------------------
    Get message buffer
    ! TO DO : proper conversion into the HAL Message Request Format
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_AGGR_ADD_TS_REQ,
                        sizeof(tAggrAddTsParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(tAggrAddTsParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in set bss key req %p %p %p",
                pEventData, pwdiAggrAddTSParams, wdiAggrAddTSRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  halAggrAddTsReq.aggrAddTsParam.staIdx =
     pwdiAggrAddTSParams->wdiAggrTsInfo.ucSTAIdx;
  halAggrAddTsReq.aggrAddTsParam.tspecIdx =
     pwdiAggrAddTSParams->wdiAggrTsInfo.ucTspecIdx;

  for( i = 0; i < WLAN_HAL_MAX_AC; i++ )
  {
     halAggrAddTsReq.aggrAddTsParam.tspec[i].type =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].ucType;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].length =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].ucLength;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].tsinfo.traffic.ackPolicy =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic.
        ackPolicy;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].tsinfo.traffic.accessPolicy =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic.
        accessPolicy;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].tsinfo.traffic.userPrio =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic.
        userPrio;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].tsinfo.traffic.psb =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic.
        psb;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].tsinfo.traffic.aggregation =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic.
        aggregation;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].tsinfo.traffic.direction =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic.
        direction;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].tsinfo.traffic.tsid =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic.
        trafficType;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].tsinfo.traffic.tsid =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic.
        trafficType;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].tsinfo.schedule.rsvd =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiSchedule.rsvd;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].tsinfo.schedule.schedule =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiSchedule.schedule;


     halAggrAddTsReq.aggrAddTsParam.tspec[i].nomMsduSz =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].usNomMsduSz;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].maxMsduSz =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].usMaxMsduSz;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].minSvcInterval =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].uMinSvcInterval;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].maxSvcInterval =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].uMaxSvcInterval;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].inactInterval =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].uInactInterval;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].suspendInterval =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].uSuspendInterval;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].svcStartTime =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].uSvcStartTime;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].minDataRate =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].uMinDataRate;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].meanDataRate =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].uMeanDataRate;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].peakDataRate =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].uPeakDataRate;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].maxBurstSz =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].uMaxBurstSz;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].delayBound =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].uDelayBound;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].minPhyRate =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].uMinPhyRate;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].surplusBw =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].usSurplusBw;
     halAggrAddTsReq.aggrAddTsParam.tspec[i].mediumTime =
        pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].usMediumTime;
  }

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halAggrAddTsReq,
                  sizeof(halAggrAddTsReq));

  pWDICtx->wdiReqStatusCB     = pwdiAggrAddTSParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiAggrAddTSParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Add TS Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiAggrAddTSRspCb, pEventData->pUserData,
                       WDI_AGGR_ADD_TS_RESP);
}/*WDI_ProcessAggrAddTSpecReq*/
#endif /* WLAN_FEATURE_VOWIFI_11R */

/**
 @brief Process Shutdown Request function (called when Main FSM
        allows it)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessShutdownReq
(
 WDI_ControlBlockType*  pWDICtx,
 WDI_EventInfoType*     pEventData
 )
{
   wpt_status              wptStatus;


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

   /*-------------------------------------------------------------------------
     Sanity check
     -------------------------------------------------------------------------*/
   if ( NULL == pEventData )
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
            "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wpalMutexAcquire(&pWDICtx->wptMutex);


   gWDIInitialized = eWLAN_PAL_FALSE;
   /*! TO DO: stop the data services */
   if ( eDRIVER_TYPE_MFG != pWDICtx->driverMode )
   {
      /*Stop the STA Table !UT- check this logic again
        It is safer to do it here than on the response - because a stop is imminent*/
      WDI_STATableStop(pWDICtx);

      /* Stop Transport Driver, DXE */
      WDTS_Stop(pWDICtx);
   }

   /*Clear all pending request*/
   WDI_ClearPendingRequests(pWDICtx);
   /* Close Data transport*/
   /* FTM mode does not open Data Path */
   if ( eDRIVER_TYPE_MFG != pWDICtx->driverMode )
   {
      WDTS_Close(pWDICtx);
   }
   /*Close the STA Table !UT- check this logic again*/
   WDI_STATableClose(pWDICtx);
   /*close the PAL */
   wptStatus = wpalClose(pWDICtx->pPALContext);
   if ( eWLAN_PAL_STATUS_SUCCESS !=  wptStatus )
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
            "Failed to wpal Close %d", wptStatus);
      WDI_ASSERT(0);
   }

   /*Transition back to init state*/
   WDI_STATE_TRANSITION( pWDICtx, WDI_INIT_ST);

   wpalMutexRelease(&pWDICtx->wptMutex);

   /*Make sure the expected state is properly defaulted to Init*/
   pWDICtx->ucExpectedStateTransition = WDI_INIT_ST;


   return WDI_STATUS_SUCCESS;
}/*WDI_ProcessShutdownReq*/

/*========================================================================
          Main DAL Control Path Response Processing API
========================================================================*/

/**
 @brief Process Start Response function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessStartRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_StartRspParamsType   wdiRspParams;
  WDI_StartRspCb           wdiStartRspCb = NULL;

  tHalMacStartRspParams*   startRspParams;

#ifndef HAL_SELF_STA_PER_BSS
  WDI_AddStaParams         wdiAddSTAParam = {0};
#endif
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  wdiStartRspCb = (WDI_StartRspCb)pWDICtx->pfncRspCB;
  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData) ||
      ( NULL == wdiStartRspCb ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  if ( sizeof(tHalMacStartRspParams) > pEventData->uEventDataSize )
  {
     // not enough data was received
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                 "Invalid response length in Start Resp Expect %zx Rcvd %x",
                 sizeof(tHalMacStartRspParams), pEventData->uEventDataSize);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
    Unpack HAL Response Message - the header was already extracted by the
    main Response Handling procedure
  -------------------------------------------------------------------------*/
  startRspParams = (tHalMacStartRspParams *) pEventData->pEventData;

  wdiRspParams.ucMaxBssids   = startRspParams->ucMaxBssids;
  wdiRspParams.ucMaxStations = startRspParams->ucMaxStations;
  wdiRspParams.wlanCompiledVersion.major = WLAN_HAL_VER_MAJOR;
  wdiRspParams.wlanCompiledVersion.minor = WLAN_HAL_VER_MINOR;
  wdiRspParams.wlanCompiledVersion.version = WLAN_HAL_VER_VERSION;
  wdiRspParams.wlanCompiledVersion.revision = WLAN_HAL_VER_REVISION;
  wdiRspParams.wlanReportedVersion.major =
                               startRspParams->wcnssWlanVersion.major;
  wdiRspParams.wlanReportedVersion.minor =
                               startRspParams->wcnssWlanVersion.minor;
  wdiRspParams.wlanReportedVersion.version =
                               startRspParams->wcnssWlanVersion.version;
  wdiRspParams.wlanReportedVersion.revision =
                               startRspParams->wcnssWlanVersion.revision;
  wpalMemoryCopy(wdiRspParams.wcnssSoftwareVersion,
          startRspParams->wcnssCrmVersionString,
          sizeof(wdiRspParams.wcnssSoftwareVersion));
  wpalMemoryCopy(wdiRspParams.wcnssHardwareVersion,
          startRspParams->wcnssWlanVersionString,
          sizeof(wdiRspParams.wcnssHardwareVersion));
  wdiRspParams.wdiStatus     = WDI_HAL_2_WDI_STATUS(startRspParams->status);

  /*Save the HAL Version*/
  pWDICtx->wlanVersion = wdiRspParams.wlanReportedVersion; 

  wpalMutexAcquire(&pWDICtx->wptMutex);
  if ( WDI_STATUS_SUCCESS == wdiRspParams.wdiStatus  )
  {
    pWDICtx->ucExpectedStateTransition =  WDI_STARTED_ST;

    /*Cache the start response for further use*/
    wpalMemoryCopy( &pWDICtx->wdiCachedStartRspParams ,
                  &wdiRspParams,
                  sizeof(pWDICtx->wdiCachedStartRspParams));

  }
  else
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
               "Failed to start device with status %s(%d)",
               WDI_getHALStatusMsgString(startRspParams->status),
               startRspParams->status);

    /*Set the expected state transition to stopped - because the start has
      failed*/
    pWDICtx->ucExpectedStateTransition =  WDI_STOPPED_ST;

    wpalMutexRelease(&pWDICtx->wptMutex);

     /*Notify UMAC*/
    wdiStartRspCb( &wdiRspParams, pWDICtx->pRspCBUserData);

    WDI_DetectedDeviceError(pWDICtx, wdiRspParams.wdiStatus);
    wpalWlanReload();

    /*Although the response is an error - it was processed by our function
    so as far as the caller is concerned this is a succesful reponse processing*/
    return WDI_STATUS_SUCCESS;
  }

  wpalMutexRelease(&pWDICtx->wptMutex);

  if(eDRIVER_TYPE_MFG == pWDICtx->driverMode)
  {
    /* FTM mode does not need to execute below */
    /* Notify UMAC */
    wdiStartRspCb( &wdiRspParams, pWDICtx->pRspCBUserData);
    return WDI_STATUS_SUCCESS;
  }

  /* START the Data transport */
  WDTS_startTransport(pWDICtx);

  /*Start the STA Table !- check this logic again*/
  WDI_STATableStart(pWDICtx);

#ifndef HAL_SELF_STA_PER_BSS
  /* Store the Self STA Index */
  pWDICtx->ucSelfStaId = halStartRspMsg.startRspParams.selfStaIdx;

  pWDICtx->usSelfStaDpuId = wdiRspParams.usSelfStaDpuId;
  wpalMemoryCopy(pWDICtx->macSelfSta, wdiRspParams.macSelfSta,
                 WDI_MAC_ADDR_LEN);

  /* At this point add the self-STA */

  /*! TO DO: wdiAddSTAParam.bcastMgmtDpuSignature */
  /* !TO DO: wdiAddSTAParam.bcastDpuSignature */
  /*! TO DO: wdiAddSTAParam.dpuSig */
  /*! TO DO: wdiAddSTAParam.ucWmmEnabled */
  /*! TO DO: wdiAddSTAParam.ucHTCapable */
  /*! TO DO: wdiAddSTAParam.ucRmfEnabled */

  //all DPU indices are the same for self STA
  wdiAddSTAParam.bcastDpuIndex = wdiRspParams.usSelfStaDpuId;
  wdiAddSTAParam.bcastMgmtDpuIndex = wdiRspParams.usSelfStaDpuId;
  wdiAddSTAParam.dpuIndex = wdiRspParams.usSelfStaDpuId;
  wpalMemoryCopy(wdiAddSTAParam.staMacAddr, wdiRspParams.macSelfSta,
                 WDI_MAC_ADDR_LEN);
  wdiAddSTAParam.ucStaType = WDI_STA_ENTRY_SELF; /* 0 - self */
  wdiAddSTAParam.ucSTAIdx = halStartRspMsg.startRspParams.selfStaIdx;

  /* Note: Since we don't get an explicit config STA request for self STA, we
     add the self STA upon receiving the Start response message. But the
     self STA entry in the table is deleted when WDI gets an explicit delete STA
     request */
  (void)WDI_STATableAddSta(pWDICtx,&wdiAddSTAParam);
#endif

  /*Notify UMAC*/
  wdiStartRspCb( &wdiRspParams, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessStartRsp*/


/**
 @brief Process Stop Response function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessStopRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status          wdiStatus;
  WDI_StopRspCb       wdiStopRspCb = NULL;

  tHalMacStopRspMsg   halMacStopRspMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  wdiStopRspCb = (WDI_StopRspCb)pWDICtx->pfncRspCB;
  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData) ||
      ( NULL == wdiStopRspCb ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  if ( sizeof(halMacStopRspMsg) < pEventData->uEventDataSize )
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Invalid response length in Stop Resp %u",
                pEventData->uEventDataSize);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
    Unpack HAL Response Message - the header was already extracted by the
    main Response Handling procedure
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halMacStopRspMsg.stopRspParams,
                  pEventData->pEventData,
                  sizeof(halMacStopRspMsg.stopRspParams));

  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halMacStopRspMsg.stopRspParams.status);

  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*--------------------------------------------------------------------------
    Check to see if the stop went OK
  --------------------------------------------------------------------------*/
  if ( WDI_STATUS_SUCCESS != wdiStatus  )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
               "Failed to stop the device with status %s (%d)",
               WDI_getHALStatusMsgString(halMacStopRspMsg.stopRspParams.status),
               halMacStopRspMsg.stopRspParams.status);

    WDI_DetectedDeviceError( pWDICtx, WDI_ERR_BASIC_OP_FAILURE);
    wpalWlanReload();

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_FAILURE;
  }

  pWDICtx->ucExpectedStateTransition = WDI_STOPPED_ST;

  /*Transition now as WDI may get preempted imediately after it sends
  up the Stop Response and it will not get to process the state transition
  from Main Rsp function*/
  WDI_STATE_TRANSITION( pWDICtx, pWDICtx->ucExpectedStateTransition);
  wpalMutexRelease(&pWDICtx->wptMutex);

  /*! TO DO: - STOP the Data transport */

  /*Notify UMAC*/
  wdiStopRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessStopRsp*/

/**
 @brief Process Close Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessCloseRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  /*There is no close response comming from HAL - function just kept for
  simmetry */
  WDI_ASSERT(0);
  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessCloseRsp*/


/*============================================================================
                      SCAN RESPONSE PROCESSING API
============================================================================*/

/**
 @brief Process Init Scan Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessInitScanRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status            wdiStatus;
  WDI_InitScanRspCb     wdiInitScanRspCb;
  tHalInitScanRspMsg    halInitScanRspMsg;
  wpt_status            wptStatus;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiInitScanRspCb = (WDI_InitScanRspCb)pWDICtx->pfncRspCB;
  if( NULL == wdiInitScanRspCb)
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                 "%s: call back function is NULL", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
    Unpack HAL Response Message - the header was already extracted by the
    main Response Handling procedure
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halInitScanRspMsg.initScanRspParams,
                  pEventData->pEventData,
                  sizeof(halInitScanRspMsg.initScanRspParams));

  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halInitScanRspMsg.initScanRspParams.status);

  if (pWDICtx->bInBmps && (WDI_STATUS_SUCCESS == wdiStatus))
  {
     // notify DTS that we are entering Full power
     wptStatus = WDTS_SetPowerState(pWDICtx, WDTS_POWER_STATE_FULL, NULL);
     if( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) {
        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                "WDTS_SetPowerState returned with status %d when trying to notify DTS that host is entering Full Power state", wptStatus);
        WDI_ASSERT(0);
    }
  }
  else if (WDI_STATUS_SUCCESS != wdiStatus)
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "Error returned WDI_ProcessInitScanRspi:%d BMPS%d",
               wdiStatus, pWDICtx->bInBmps);
  }

  /*Notify UMAC*/
  wdiInitScanRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessInitScanRsp*/


/**
 @brief Process Start Scan Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessStartScanRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_StartScanRspParamsType   wdiStartScanParams;
  WDI_StartScanRspCb           wdiStartScanRspCb;

  tHalStartScanRspMsg          halStartScanRspMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiStartScanRspCb = (WDI_StartScanRspCb)pWDICtx->pfncRspCB;
  if( NULL == wdiStartScanRspCb)
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                 "%s: call back function is NULL", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halStartScanRspMsg.startScanRspParams,
                  pEventData->pEventData,
                  sizeof(halStartScanRspMsg.startScanRspParams));

  wdiStartScanParams.wdiStatus   =   WDI_HAL_2_WDI_STATUS(
                             halStartScanRspMsg.startScanRspParams.status);
#ifdef WLAN_FEATURE_VOWIFI
  wdiStartScanParams.ucTxMgmtPower =
                             halStartScanRspMsg.startScanRspParams.txMgmtPower;
  wpalMemoryCopy( wdiStartScanParams.aStartTSF,
                  halStartScanRspMsg.startScanRspParams.startTSF,
                  2);
#endif

  if ( eHAL_STATUS_SUCCESS != halStartScanRspMsg.startScanRspParams.status )
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Start scan failed with status %s (%d)",
              WDI_getHALStatusMsgString(halStartScanRspMsg.startScanRspParams.status),
              halStartScanRspMsg.startScanRspParams.status);
     /* send the status to UMAC, don't return from here*/
  }

  /*Notify UMAC*/
  wdiStartScanRspCb( &wdiStartScanParams, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;

}/*WDI_ProcessStartScanRsp*/


/**
 @brief Process End Scan Response function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessEndScanRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status            wdiStatus;
  tHalEndScanRspMsg     halEndScanRspMsg;
  WDI_EndScanRspCb      wdiEndScanRspCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiEndScanRspCb = (WDI_EndScanRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halEndScanRspMsg.endScanRspParams,
                  pEventData->pEventData,
                  sizeof(halEndScanRspMsg.endScanRspParams));

  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halEndScanRspMsg.endScanRspParams.status);

  if ( eHAL_STATUS_SUCCESS != halEndScanRspMsg.endScanRspParams.status )
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
              "End Scan failed with status %s (%d )",
              WDI_getHALStatusMsgString(halEndScanRspMsg.endScanRspParams.status),
              halEndScanRspMsg.endScanRspParams.status);
     /* send the status to UMAC, don't return from here*/
  }

  /*Notify UMAC*/
  wdiEndScanRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessEndScanRsp*/


/**
 @brief Process Finish Scan Response function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessFinishScanRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status            wdiStatus;
  WDI_FinishScanRspCb   wdiFinishScanRspCb;

  tHalFinishScanRspMsg  halFinishScanRspMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiFinishScanRspCb = (WDI_FinishScanRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( (void *)&halFinishScanRspMsg.finishScanRspParams.status,
                  pEventData->pEventData,
                  sizeof(halFinishScanRspMsg.finishScanRspParams.status));

  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halFinishScanRspMsg.finishScanRspParams.status);

  WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
              "Finish scan response reported status: %d",
              halFinishScanRspMsg.finishScanRspParams.status);

  if (( eHAL_STATUS_SUCCESS != halFinishScanRspMsg.finishScanRspParams.status )&&
      ( eHAL_STATUS_NOTIFY_BSS_FAIL  != halFinishScanRspMsg.finishScanRspParams.status ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Finish Scan failed with status %s (%d)",
              WDI_getHALStatusMsgString(halFinishScanRspMsg.finishScanRspParams.status),
              halFinishScanRspMsg.finishScanRspParams.status);
     /* send the status to UMAC, don't return from here*/
  }

  /*Notify UMAC*/
  wdiFinishScanRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessFinishScanRsp*/

/**
 @brief Process Join Response function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessJoinRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status                    wdiStatus;
  WDI_JoinRspCb                 wdiJoinRspCb;
  WDI_BSSSessionType*           pBSSSes             = NULL;

  tHalJoinRspMsg                halJoinRspMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) ||
      ( NULL == pWDICtx->pfncRspCB ) ||
      ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiJoinRspCb = (WDI_JoinRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halJoinRspMsg.joinRspParams,
                  pEventData->pEventData,
                  sizeof(halJoinRspMsg.joinRspParams));

  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halJoinRspMsg.joinRspParams.status);

  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*-----------------------------------------------------------------------
    Join response can only be received for an existing assoc that
    is current and in progress
    -----------------------------------------------------------------------*/
  if (( !WDI_VALID_SESSION_IDX(pWDICtx->ucCurrentBSSSesIdx )) ||
      ( eWLAN_PAL_FALSE == pWDICtx->bAssociationInProgress ))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "%s: Association sequence for this BSS does not yet exist (bssIdx %d) or "
              "association no longer in progress %d - mysterious HAL response",
              __func__, pWDICtx->ucCurrentBSSSesIdx, pWDICtx->bAssociationInProgress);

    WDI_DetectedDeviceError( pWDICtx, WDI_ERR_BASIC_OP_FAILURE);
    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  pBSSSes = &pWDICtx->aBSSSessions[pWDICtx->ucCurrentBSSSesIdx];

  /*-----------------------------------------------------------------------
    Join Response is only allowed in init state
  -----------------------------------------------------------------------*/
  if ( WDI_ASSOC_JOINING_ST != pBSSSes->wdiAssocState)
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Join only allowed in Joining state - failure state is %d "
              "strange HAL response", pBSSSes->wdiAssocState);

    WDI_DetectedDeviceError( pWDICtx, WDI_ERR_BASIC_OP_FAILURE);

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }


  /*-----------------------------------------------------------------------
    If assoc has failed the current session will be deleted
  -----------------------------------------------------------------------*/
  if ( WDI_STATUS_SUCCESS != wdiStatus )
  {
    /*Association was failed by HAL - remove session*/
    WDI_DeleteSession(pWDICtx, pBSSSes);

    /*Association no longer in progress  */
    pWDICtx->bAssociationInProgress = eWLAN_PAL_FALSE;

    /*Association no longer in progress - prepare pending assoc for processing*/
    WDI_DequeueAssocRequest(pWDICtx);

  }
  else
  {
    /*Transition to state Joining - this may be redundant as we are supposed
      to be in this state already - but just to be safe*/
    pBSSSes->wdiAssocState = WDI_ASSOC_JOINING_ST;
  }

  wpalMutexRelease(&pWDICtx->wptMutex);

  /*Notify UMAC*/
  wdiJoinRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessJoinRsp*/


/**
 @brief Process Config BSS Response function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessConfigBSSRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_ConfigBSSRspParamsType    wdiConfigBSSParams;
  WDI_ConfigBSSRspCb            wdiConfigBSSRspCb;
  wpt_uint8                     ucCurrentBSSSesIdx  = 0;
  WDI_BSSSessionType*           pBSSSes             = NULL;

  tConfigBssRspMsg              halConfigBssRspMsg;
  WDI_AddStaParams              wdiBcastAddSTAParam = {0};
  WDI_AddStaParams              wdiAddSTAParam = {0};

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

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiConfigBSSRspCb = (WDI_ConfigBSSRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halConfigBssRspMsg.configBssRspParams,
                   pEventData->pEventData,
                   sizeof(halConfigBssRspMsg.configBssRspParams));

  wdiConfigBSSParams.wdiStatus = WDI_HAL_2_WDI_STATUS(
                            halConfigBssRspMsg.configBssRspParams.status);
  if(WDI_STATUS_SUCCESS == wdiConfigBSSParams.wdiStatus)
  {
    wpalMemoryCopy( wdiConfigBSSParams.macBSSID,
                    pWDICtx->wdiCachedConfigBssReq.wdiReqInfo.macBSSID,
                    WDI_MAC_ADDR_LEN);

    wdiConfigBSSParams.ucBSSIdx = halConfigBssRspMsg.configBssRspParams.bssIdx;

    wdiConfigBSSParams.ucBcastSig =
       halConfigBssRspMsg.configBssRspParams.bcastDpuSignature;

    wdiConfigBSSParams.ucUcastSig =
       halConfigBssRspMsg.configBssRspParams.ucastDpuSignature;

    wdiConfigBSSParams.ucSTAIdx = halConfigBssRspMsg.configBssRspParams.bssStaIdx;

  #ifdef WLAN_FEATURE_VOWIFI
    wdiConfigBSSParams.ucTxMgmtPower =
                               halConfigBssRspMsg.configBssRspParams.txMgmtPower;
  #endif
     wpalMemoryCopy( wdiConfigBSSParams.macSTA,
                     halConfigBssRspMsg.configBssRspParams.staMac,
                     WDI_MAC_ADDR_LEN );

    wpalMutexAcquire(&pWDICtx->wptMutex);
    /*------------------------------------------------------------------------
      Find the BSS for which the request is made
    ------------------------------------------------------------------------*/
    ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx,
                                               wdiConfigBSSParams.macBSSID,
                                              &pBSSSes);

    /*-----------------------------------------------------------------------
      Config BSS response can only be received for an existing assoc that
      is current and in progress
      -----------------------------------------------------------------------*/
    if ( NULL == pBSSSes )
    {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                "Association sequence for this BSS does not yet exist "
                "- mysterious HAL response");

      WDI_DetectedDeviceError( pWDICtx, WDI_ERR_BASIC_OP_FAILURE);

      wpalMutexRelease(&pWDICtx->wptMutex);
      return WDI_STATUS_E_NOT_ALLOWED;
    }

    /*Save data for this BSS*/
    pBSSSes->wdiBssType = pWDICtx->wdiCachedConfigBssReq.wdiReqInfo.wdiBSSType;
    pBSSSes->ucBSSIdx = halConfigBssRspMsg.configBssRspParams.bssIdx;
    pBSSSes->bcastDpuIndex     =
      halConfigBssRspMsg.configBssRspParams.bcastDpuDescIndx;
    pBSSSes->bcastDpuSignature =
      halConfigBssRspMsg.configBssRspParams.bcastDpuSignature;
    pBSSSes->bcastMgmtDpuIndex =
      halConfigBssRspMsg.configBssRspParams.mgmtDpuDescIndx;
    pBSSSes->bcastMgmtDpuSignature =
      halConfigBssRspMsg.configBssRspParams.mgmtDpuSignature;
    pBSSSes->ucRmfEnabled      =
      pWDICtx->wdiCachedConfigBssReq.wdiReqInfo.ucRMFEnabled;
    pBSSSes->bcastStaIdx =
       halConfigBssRspMsg.configBssRspParams.bssBcastStaIdx;

    /* !TO DO: Shuould we be updating the RMF Capability of self STA here? */

    /*-------------------------------------------------------------------------
        Add Peer STA
      -------------------------------------------------------------------------*/
    wdiAddSTAParam.ucSTAIdx = halConfigBssRspMsg.configBssRspParams.bssStaIdx;
    wdiAddSTAParam.dpuIndex = halConfigBssRspMsg.configBssRspParams.dpuDescIndx;
    wdiAddSTAParam.dpuSig   = halConfigBssRspMsg.configBssRspParams.ucastDpuSignature;

     /*This info can be retrieved from the cached initial request*/
    wdiAddSTAParam.ucWmmEnabled =
        pWDICtx->wdiCachedConfigBssReq.wdiReqInfo.wdiSTAContext.ucWMMEnabled;
    wdiAddSTAParam.ucHTCapable  =
        pWDICtx->wdiCachedConfigBssReq.wdiReqInfo.wdiSTAContext.ucHTCapable;
    wdiAddSTAParam.ucStaType    =
        pWDICtx->wdiCachedConfigBssReq.wdiReqInfo.wdiSTAContext.wdiSTAType;

     /* MAC Address of STA */
    wpalMemoryCopy(wdiAddSTAParam.staMacAddr,
                   halConfigBssRspMsg.configBssRspParams.staMac,
                   WDI_MAC_ADDR_LEN);

    wpalMemoryCopy(wdiAddSTAParam.macBSSID,
                   pWDICtx->wdiCachedConfigBssReq.wdiReqInfo.wdiSTAContext.macBSSID ,
                   WDI_MAC_ADDR_LEN);

    /*Add BSS specific parameters*/
    wdiAddSTAParam.bcastMgmtDpuIndex     =
        halConfigBssRspMsg.configBssRspParams.mgmtDpuDescIndx;
    wdiAddSTAParam.bcastMgmtDpuSignature =
        halConfigBssRspMsg.configBssRspParams.mgmtDpuSignature;
    wdiAddSTAParam.bcastDpuIndex         =
        halConfigBssRspMsg.configBssRspParams.bcastDpuDescIndx;
    wdiAddSTAParam.bcastDpuSignature     =
        halConfigBssRspMsg.configBssRspParams.bcastDpuSignature;
    wdiAddSTAParam.ucRmfEnabled          =
        pWDICtx->wdiCachedConfigBssReq.wdiReqInfo.ucRMFEnabled;
    wdiAddSTAParam.ucBSSIdx =
       halConfigBssRspMsg.configBssRspParams.bssIdx;

    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
                "Add STA to the table index: %d", wdiAddSTAParam.ucSTAIdx );

    WDI_STATableAddSta(pWDICtx,&wdiAddSTAParam);
    /*-------------------------------------------------------------------------
        Add Broadcast STA only in AP mode
      -------------------------------------------------------------------------*/
    if( pWDICtx->wdiCachedConfigBssReq.wdiReqInfo.ucOperMode ==
        WDI_BSS_OPERATIONAL_MODE_AP || pBSSSes->wdiBssType == WDI_IBSS_MODE)
    {
       WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
                  "Add BCAST STA to table for index: %d",
                  halConfigBssRspMsg.configBssRspParams.bssBcastStaIdx );

       wpalMemoryCopy( &wdiBcastAddSTAParam, &wdiAddSTAParam,
                       sizeof(WDI_AddStaParams) );

       WDI_AddBcastSTAtoSTATable( pWDICtx, &wdiBcastAddSTAParam,
                                  halConfigBssRspMsg.configBssRspParams.bssBcastStaIdx );
    }
    wpalMutexRelease(&pWDICtx->wptMutex);
  }
  else
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                  "Config BSS RSP failed with status : %s(%d)",
                  WDI_getHALStatusMsgString(
                  halConfigBssRspMsg.configBssRspParams.status),
                  halConfigBssRspMsg.configBssRspParams.status);


    /*Association was failed by HAL - remove session*/
    WDI_DeleteSession(pWDICtx, pBSSSes);

    /*Association no longer in progress  */
    pWDICtx->bAssociationInProgress = eWLAN_PAL_FALSE;

    /*Association no longer in progress - prepare pending assoc for processing*/
    WDI_DequeueAssocRequest(pWDICtx);

  }

  /*Notify UMAC*/
  wdiConfigBSSRspCb( &wdiConfigBSSParams, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessConfigBSSRsp*/


/**
 @brief Process Del BSS Response function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessDelBSSRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_DelBSSRspParamsType       wdiDelBSSParams;
  WDI_DelBSSRspCb               wdiDelBSSRspCb;
  wpt_uint8                     ucCurrentBSSSesIdx  = 0;
  WDI_BSSSessionType*           pBSSSes             = NULL;

  tDeleteBssRspMsg              halDelBssRspMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiDelBSSRspCb = (WDI_DelBSSRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halDelBssRspMsg.deleteBssRspParams,
                  pEventData->pEventData,
                  sizeof(halDelBssRspMsg.deleteBssRspParams));


  wdiDelBSSParams.wdiStatus   =   WDI_HAL_2_WDI_STATUS(
                                 halDelBssRspMsg.deleteBssRspParams.status);

  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made
  ------------------------------------------------------------------------*/
  ucCurrentBSSSesIdx = WDI_FindAssocSessionByBSSIdx( pWDICtx,
                             halDelBssRspMsg.deleteBssRspParams.bssIdx,
                             &pBSSSes);

  /*-----------------------------------------------------------------------
    Del BSS response can only be received for an existing assoc that
    is current and in progress
    -----------------------------------------------------------------------*/
  if ( NULL == pBSSSes )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Association sequence for this BSS does not yet exist or "
              "association no longer in progress - mysterious HAL response");

    WDI_DetectedDeviceError( pWDICtx, WDI_ERR_BASIC_OP_FAILURE);

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*Extract BSSID for the response to UMAC*/
  wpalMemoryCopy(wdiDelBSSParams.macBSSID,
                 pBSSSes->macBSSID, WDI_MAC_ADDR_LEN);

  wdiDelBSSParams.ucBssIdx = halDelBssRspMsg.deleteBssRspParams.bssIdx;

  /*-----------------------------------------------------------------------
    The current session will be deleted
  -----------------------------------------------------------------------*/
  WDI_DeleteSession(pWDICtx, pBSSSes);


  /* Delete the BCAST STA entry from the STA table if SAP/GO session is deleted */
  if(WDI_INFRA_AP_MODE == pBSSSes->wdiBssType ||
     pBSSSes->wdiBssType == WDI_IBSS_MODE)
  {
    (void)WDI_STATableDelSta( pWDICtx, pBSSSes->bcastStaIdx );
  }

   /* Delete the STA's in this BSS */
  WDI_STATableBSSDelSta(pWDICtx, halDelBssRspMsg.deleteBssRspParams.bssIdx);

  wpalMutexRelease(&pWDICtx->wptMutex);

  /*Notify UMAC*/
  wdiDelBSSRspCb( &wdiDelBSSParams, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessDelBSSRsp*/

/**
 @brief Process Post Assoc Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessPostAssocRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_PostAssocRspParamsType    wdiPostAssocParams;
  WDI_PostAssocRspCb            wdiPostAssocRspCb;
  wpt_uint8                     ucCurrentBSSSesIdx     = 0;
  WDI_BSSSessionType*           pBSSSes                = NULL;
  tPostAssocRspMsg              halPostAssocRspMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiPostAssocRspCb = (WDI_PostAssocRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halPostAssocRspMsg.postAssocRspParams,
                   pEventData->pEventData,
                   sizeof(halPostAssocRspMsg.postAssocRspParams));

  /*Extract the Post Assoc STA Params */

  wdiPostAssocParams.staParams.ucSTAIdx   =
    halPostAssocRspMsg.postAssocRspParams.configStaRspParams.staIdx;
  wdiPostAssocParams.staParams.ucUcastSig =
    halPostAssocRspMsg.postAssocRspParams.configStaRspParams.ucUcastSig;
  wdiPostAssocParams.staParams.ucBcastSig =
    halPostAssocRspMsg.postAssocRspParams.configStaRspParams.ucBcastSig;

 wdiPostAssocParams.wdiStatus =
    WDI_HAL_2_WDI_STATUS(halPostAssocRspMsg.postAssocRspParams.configStaRspParams.status);

 /*Copy the MAC addresses from the cached storage in the WDI CB as they are not
   included in the response */
  wpalMemoryCopy( wdiPostAssocParams.staParams.macSTA,
                  pWDICtx->wdiCachedPostAssocReq.wdiSTAParams.macSTA,
                  WDI_MAC_ADDR_LEN);

  /* Extract Post Assoc BSS Params */

  wpalMemoryCopy( wdiPostAssocParams.bssParams.macBSSID,
                  pWDICtx->wdiCachedPostAssocReq.wdiBSSParams.macBSSID,
                  WDI_MAC_ADDR_LEN);

  /*Copy the MAC addresses from the cached storage in the WDI CB as they are not
   included in the response */
  wpalMemoryCopy( wdiPostAssocParams.bssParams.macSTA,
                  pWDICtx->wdiCachedPostAssocReq.wdiBSSParams.wdiSTAContext
                  .macSTA, WDI_MAC_ADDR_LEN);

  wdiPostAssocParams.bssParams.ucBcastSig =
     halPostAssocRspMsg.postAssocRspParams.configStaRspParams.ucBcastSig;

  wdiPostAssocParams.bssParams.ucUcastSig =
     halPostAssocRspMsg.postAssocRspParams.configStaRspParams.ucUcastSig;

  wdiPostAssocParams.bssParams.ucBSSIdx =
     halPostAssocRspMsg.postAssocRspParams.configBssRspParams.bssIdx;

  wdiPostAssocParams.bssParams.ucSTAIdx =
     halPostAssocRspMsg.postAssocRspParams.configBssRspParams.bssStaIdx;

  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Find the BSS for which the request is made
  ------------------------------------------------------------------------*/
  ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx,
                                             wdiPostAssocParams.bssParams.
                                             macBSSID, &pBSSSes);

  /*-----------------------------------------------------------------------
    Post assoc response can only be received for an existing assoc that
    is current and in progress
    -----------------------------------------------------------------------*/
  if (( NULL == pBSSSes ) ||
      ( ucCurrentBSSSesIdx != pWDICtx->ucCurrentBSSSesIdx ) ||
      ( eWLAN_PAL_FALSE == pWDICtx->bAssociationInProgress ))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Association sequence for this BSS does not yet exist or "
              "association no longer in progress - mysterious HAL response");

    WDI_DetectedDeviceError( pWDICtx, WDI_ERR_BASIC_OP_FAILURE);

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*-----------------------------------------------------------------------
    Post Assoc Request is only allowed in Joining state
  -----------------------------------------------------------------------*/
  if ( WDI_ASSOC_JOINING_ST != pBSSSes->wdiAssocState)
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Post Assoc not allowed before JOIN - failing request "
              "strange HAL response");

    WDI_DetectedDeviceError( pWDICtx, WDI_ERR_BASIC_OP_FAILURE);

    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*-----------------------------------------------------------------------
    If assoc has failed the current session will be deleted
  -----------------------------------------------------------------------*/
  if ( WDI_STATUS_SUCCESS != wdiPostAssocParams.wdiStatus )
  {
    /*Association was failed by HAL - remove session*/
    WDI_DeleteSession(pWDICtx, pBSSSes);
  }
  else
  {
    /*Transition to state POST Assoc*/
    pBSSSes->wdiAssocState = WDI_ASSOC_POST_ST;

    /*Save DPU Info*/
    pBSSSes->bcastMgmtDpuIndex     =
      halPostAssocRspMsg.postAssocRspParams.configBssRspParams.mgmtDpuDescIndx;
    pBSSSes->bcastMgmtDpuSignature =
      halPostAssocRspMsg.postAssocRspParams.configBssRspParams.mgmtDpuSignature;
    pBSSSes->bcastDpuIndex         =
      halPostAssocRspMsg.postAssocRspParams.configBssRspParams.bcastDpuDescIndx;
    pBSSSes->bcastDpuSignature     =
      halPostAssocRspMsg.postAssocRspParams.configBssRspParams.bcastDpuSignature;

    pBSSSes->ucBSSIdx              =
      halPostAssocRspMsg.postAssocRspParams.configBssRspParams.bssIdx;
  }

  /*Association no longer in progress  */
  pWDICtx->bAssociationInProgress = eWLAN_PAL_FALSE;

  /*Association no longer in progress - prepare pending assoc for processing*/
  WDI_DequeueAssocRequest(pWDICtx);

  wpalMutexRelease(&pWDICtx->wptMutex);

  /*Notify UMAC*/
  wdiPostAssocRspCb( &wdiPostAssocParams, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessPostAssocRsp*/

/**
 @brief Process Del STA Rsp function (called when a response is
        being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessDelSTARsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_DelSTARspParamsType   wdiDelSTARsp;
  WDI_DelSTARspCb           wdiDelSTARspCb;
  wpt_uint8                 staType;
  tDeleteStaRspMsg          halDelStaRspMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiDelSTARspCb = (WDI_DelSTARspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halDelStaRspMsg.delStaRspParams,
                  pEventData->pEventData,
                  sizeof(halDelStaRspMsg.delStaRspParams));

  wdiDelSTARsp.ucSTAIdx    = halDelStaRspMsg.delStaRspParams.staId;
  wdiDelSTARsp.wdiStatus   =
    WDI_HAL_2_WDI_STATUS(halDelStaRspMsg.delStaRspParams.status);

  WDI_STATableGetStaType(pWDICtx, wdiDelSTARsp.ucSTAIdx, &staType);

  /* If the DEL STA request is for self STA do not delete it - Really weird!!What happens in concurrency */
  if(staType == WDI_STA_ENTRY_SELF)
  {
    WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable;

    /* At this point add the self-STA */

    /*! TO DO: wdiAddSTAParam.ucWmmEnabled */
    /*! TO DO: wdiAddSTAParam.ucHTCapable */
    /*! TO DO: wdiAddSTAParam.ucRmfEnabled */

#define WDI_DPU_SELF_STA_DEFAULT_IDX 0
#define WDI_DPU_SELF_STA_DEFAULT_SIG 0

    //all DPU indices are the same for self STA
    pSTATable[wdiDelSTARsp.ucSTAIdx].dpuIndex = WDI_DPU_SELF_STA_DEFAULT_IDX;
    pSTATable[wdiDelSTARsp.ucSTAIdx].bcastDpuIndex = WDI_DPU_SELF_STA_DEFAULT_IDX;
    pSTATable[wdiDelSTARsp.ucSTAIdx].bcastMgmtDpuIndex = WDI_DPU_SELF_STA_DEFAULT_IDX;
    pSTATable[wdiDelSTARsp.ucSTAIdx].bcastDpuSignature = WDI_DPU_SELF_STA_DEFAULT_SIG;
    pSTATable[wdiDelSTARsp.ucSTAIdx].bcastMgmtDpuSignature = WDI_DPU_SELF_STA_DEFAULT_SIG;
    pSTATable[wdiDelSTARsp.ucSTAIdx].dpuSig = WDI_DPU_SELF_STA_DEFAULT_SIG;

    pSTATable[wdiDelSTARsp.ucSTAIdx].bssIdx = WDI_BSS_INVALID_IDX;
  }
  else
  {
    //Delete the station in the table
    WDI_STATableDelSta( pWDICtx, wdiDelSTARsp.ucSTAIdx);
  }

  /*Notify UMAC*/
  wdiDelSTARspCb( &wdiDelSTARsp, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessDelSTARsp*/


/*==========================================================================
                   Security Response Processing Functions
==========================================================================*/

/**
 @brief Process Set BSS Key Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetBssKeyRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status            wdiStatus;
  eHalStatus            halStatus;
  WDI_SetBSSKeyRspCb    wdiSetBSSKeyRspCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiSetBSSKeyRspCb = (WDI_SetBSSKeyRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  halStatus = *((eHalStatus*)pEventData->pEventData);
  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  if ( eHAL_STATUS_SUCCESS != halStatus )
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Set BSS Key failed with status %s (%d)",
              WDI_getHALStatusMsgString(halStatus),
              halStatus);
     /* send the status to UMAC, don't return from here*/
  }

  /*Notify UMAC*/
  wdiSetBSSKeyRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessSetBssKeyRsp*/

/**
 @brief Process Remove BSS Key Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessRemoveBssKeyRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status              wdiStatus;
  eHalStatus              halStatus;
  WDI_RemoveBSSKeyRspCb   wdiRemoveBSSKeyRspCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiRemoveBSSKeyRspCb = (WDI_RemoveBSSKeyRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  halStatus = *((eHalStatus*)pEventData->pEventData);
  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  if ( eHAL_STATUS_SUCCESS != halStatus )
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Remove BSS Key failed with status %s (%d )",
              WDI_getHALStatusMsgString(halStatus),
              halStatus);
     /* send the status to UMAC, don't return from here*/
  }

  /*Notify UMAC*/
  wdiRemoveBSSKeyRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessSetBssKeyRsp*/


/**
 @brief Process Set STA Key Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetStaKeyRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status            wdiStatus;
  eHalStatus            halStatus;
  WDI_SetSTAKeyRspCb    wdiSetSTAKeyRspCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiSetSTAKeyRspCb = (WDI_SetSTAKeyRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  halStatus = *((eHalStatus*)pEventData->pEventData);
  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  if ( eHAL_STATUS_SUCCESS != halStatus )
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Set STA Key failed with status %s (%d)",
              WDI_getHALStatusMsgString(halStatus),
              halStatus);
     /* send the status to UMAC, don't return from here*/
  }

  /*Notify UMAC*/
  wdiSetSTAKeyRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessSetSTAKeyRsp*/

/**
 @brief Process Remove STA Key Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessRemoveStaKeyRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status              wdiStatus;
  eHalStatus              halStatus;
  WDI_RemoveSTAKeyRspCb   wdiRemoveSTAKeyRspCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiRemoveSTAKeyRspCb = (WDI_RemoveSTAKeyRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  halStatus = *((eHalStatus*)pEventData->pEventData);
  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  if ( eHAL_STATUS_SUCCESS != halStatus )
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Remove STA Key failed with status %s (%d)",
              WDI_getHALStatusMsgString(halStatus),
              halStatus);
     /* send the status to UMAC, don't return from here*/
  }

  /*Notify UMAC*/
  wdiRemoveSTAKeyRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessRemoveStaKeyRsp*/

/**
 @brief Process Set STA Bcast Key Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetStaBcastKeyRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status            wdiStatus;
  eHalStatus            halStatus;
  WDI_SetSTAKeyRspCb    wdiSetSTABcastKeyRspCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiSetSTABcastKeyRspCb = (WDI_SetSTAKeyRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halStatus,
                  pEventData->pEventData,
                  sizeof(halStatus));

  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  if ( eHAL_STATUS_SUCCESS != halStatus )
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Set STA Key failed with status %s (%d)",
              WDI_getHALStatusMsgString(halStatus),
              halStatus);
     /* send the status to UMAC, don't return from here*/
  }

  /*Notify UMAC*/
  wdiSetSTABcastKeyRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessSetSTABcastKeyRsp*/

/**
 @brief Process Remove STA Bcast Key Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessRemoveStaBcastKeyRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status              wdiStatus;
  eHalStatus              halStatus;
  WDI_RemoveSTAKeyRspCb   wdiRemoveSTABcastKeyRspCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiRemoveSTABcastKeyRspCb = (WDI_RemoveSTAKeyRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halStatus,
                  pEventData->pEventData,
                  sizeof(halStatus));

  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  if ( eHAL_STATUS_SUCCESS != halStatus )
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Remove STA Key failed with status %s (%d)",
              WDI_getHALStatusMsgString(halStatus),
              halStatus);
     /* send the status to UMAC, don't return from here*/
  }

  /*Notify UMAC*/
  wdiRemoveSTABcastKeyRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessRemoveStaBcastKeyRsp*/


/*==========================================================================
                   QoS and BA Response Processing Functions
==========================================================================*/

/**
 @brief Process Add TSpec Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessAddTSpecRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status       wdiStatus;
  eHalStatus       halStatus;
  WDI_AddTsRspCb   wdiAddTsRspCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiAddTsRspCb = (WDI_AddTsRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  halStatus = *((eHalStatus*)pEventData->pEventData);
  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  /*Notify UMAC*/
  wdiAddTsRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessAddTSpecRsp*/



#ifdef WLAN_FEATURE_LINK_LAYER_STATS

WDI_Status
WDI_ProcessLLStatsSetRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_LLStatsSetRspCb   wdiLLStatsSetRspCb;

  WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
              "%s: Enter ", __func__);
  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiLLStatsSetRspCb = (WDI_LLStatsSetRspCb)pWDICtx->pfncRspCB;

  wdiLLStatsSetRspCb((void *) pEventData->pEventData, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}

WDI_Status
WDI_ProcessLLStatsGetRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_LLStatsGetRspCb   wdiLLStatsGetRspCb;

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
              "%s: Enter ", __func__);

  wdiLLStatsGetRspCb = (WDI_LLStatsGetRspCb)pWDICtx->pfncRspCB;

  wdiLLStatsGetRspCb((void *) pEventData->pEventData, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}

WDI_Status
WDI_ProcessLLStatsClearRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_LLStatsClearRspCb   wdiLLStatsClearRspCb;

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
              "%s: CLEAR RESPONSE CALL BACK", __func__);
  wdiLLStatsClearRspCb = (WDI_LLStatsClearRspCb)pWDICtx->pfncRspCB;

  wdiLLStatsClearRspCb((void *) pEventData->pEventData, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}
#endif /* WLAN_FEATURE_LINK_LAYER_STATS */

/**
 @brief Process Del TSpec Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessDelTSpecRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status       wdiStatus;
  eHalStatus       halStatus;
  WDI_DelTsRspCb   wdiDelTsRspCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiDelTsRspCb = (WDI_DelTsRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  halStatus = *((eHalStatus*)pEventData->pEventData);
  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  /*Notify UMAC*/
  wdiDelTsRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessDelTSpecRsp*/

/**
 @brief Process Update EDCA Parameters Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessUpdateEDCAParamsRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status       wdiStatus;
  eHalStatus       halStatus;
  WDI_UpdateEDCAParamsRspCb   wdiUpdateEDCAParamsRspCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiUpdateEDCAParamsRspCb = (WDI_UpdateEDCAParamsRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  halStatus = *((eHalStatus*)pEventData->pEventData);
  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  /*Notify UMAC*/
  wdiUpdateEDCAParamsRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessUpdateEDCAParamsRsp*/


/**
 @brief Process Add BA Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessAddBASessionRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_AddBASessionRspCb   wdiAddBASessionRspCb;

  tAddBASessionRspParams        halBASessionRsp;
  WDI_AddBASessionRspParamsType wdiBASessionRsp;


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

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiAddBASessionRspCb = (WDI_AddBASessionRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halBASessionRsp,
                  pEventData->pEventData,
                  sizeof(halBASessionRsp));

  wdiBASessionRsp.wdiStatus = WDI_HAL_2_WDI_STATUS(halBASessionRsp.status);

  if ( WDI_STATUS_SUCCESS == wdiBASessionRsp.wdiStatus )
  {
    wdiBASessionRsp.ucBaDialogToken = halBASessionRsp.baDialogToken;
    wdiBASessionRsp.ucBaTID = halBASessionRsp.baTID;
    wdiBASessionRsp.ucBaBufferSize = halBASessionRsp.baBufferSize;
    wdiBASessionRsp.usBaSessionID = halBASessionRsp.baSessionID;
    wdiBASessionRsp.ucWinSize = halBASessionRsp.winSize;
    wdiBASessionRsp.ucSTAIdx = halBASessionRsp.STAID;
    wdiBASessionRsp.usBaSSN = halBASessionRsp.SSN;
  }

  /*Notify UMAC*/
  wdiAddBASessionRspCb( &wdiBASessionRsp, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessAddSessionBARsp*/


/**
 @brief Process Del BA Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessDelBARsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status       wdiStatus;
  eHalStatus       halStatus;
  WDI_DelBARspCb   wdiDelBARspCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiDelBARspCb = (WDI_DelBARspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  halStatus = *((eHalStatus*)pEventData->pEventData);
  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  if ( eHAL_STATUS_SUCCESS == halStatus )
  {
    /*! TO DO: I should notify the DAL Data Path that the BA was deleted*/
  }

  /*Notify UMAC*/
  wdiDelBARspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessDelBARsp*/

#ifdef FEATURE_WLAN_ESE
/**
 @brief Process TSM Stats Rsp function (called when a response
        is being received over the bus from HAL)
 
 @param  pWDICtx:         pointer to the WLAN DAL context 
         pEventData:      pointer to the event information structure 
  
 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessTsmStatsRsp
( 
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_TsmRspCb          wdiTsmStatsRspCb;
  tTsmStatsRspMsg       halTsmStatsRspMsg; 
  WDI_TSMStatsRspParamsType  wdiTsmStatsRspParams;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check 
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE; 
  }

  wdiTsmStatsRspCb = (WDI_TsmRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Unpack HAL Response Message - the header was already extracted by the
    main Response Handling procedure 
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halTsmStatsRspMsg.tsmStatsRspParams, 
                  pEventData->pEventData, 
                  sizeof(halTsmStatsRspMsg.tsmStatsRspParams));

  wdiTsmStatsRspParams.UplinkPktQueueDly = halTsmStatsRspMsg.tsmStatsRspParams.UplinkPktQueueDly;
  wpalMemoryCopy( wdiTsmStatsRspParams.UplinkPktQueueDlyHist,
                  halTsmStatsRspMsg.tsmStatsRspParams.UplinkPktQueueDlyHist,
                  sizeof(halTsmStatsRspMsg.tsmStatsRspParams.UplinkPktQueueDlyHist)/
                  sizeof(halTsmStatsRspMsg.tsmStatsRspParams.UplinkPktQueueDlyHist[0]));
  wdiTsmStatsRspParams.UplinkPktTxDly = halTsmStatsRspMsg.tsmStatsRspParams.UplinkPktTxDly;
  wdiTsmStatsRspParams.UplinkPktLoss = halTsmStatsRspMsg.tsmStatsRspParams.UplinkPktLoss;
  wdiTsmStatsRspParams.UplinkPktCount = halTsmStatsRspMsg.tsmStatsRspParams.UplinkPktCount;
  wdiTsmStatsRspParams.RoamingCount = halTsmStatsRspMsg.tsmStatsRspParams.RoamingCount;
  wdiTsmStatsRspParams.RoamingDly = halTsmStatsRspMsg.tsmStatsRspParams.RoamingDly;
  wdiTsmStatsRspParams.wdiStatus   =   WDI_HAL_2_WDI_STATUS(
                             halTsmStatsRspMsg.tsmStatsRspParams.status);

  /*Notify UMAC*/
  wdiTsmStatsRspCb( &wdiTsmStatsRspParams, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS; 
}/*WDI_ProcessTsmStatsRsp*/

#endif



/**
 @brief Process Flush AC Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessFlushAcRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status       wdiStatus;
  eHalStatus       halStatus;
  WDI_FlushAcRspCb wdiFlushAcRspCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiFlushAcRspCb = (WDI_FlushAcRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halStatus,
                  pEventData->pEventData,
                  sizeof(halStatus));

  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  /*Notify UMAC*/
  wdiFlushAcRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessFlushAcRsp*/

/**
 @brief Process BT AMP event Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessBtAmpEventRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_Status       wdiStatus;
   eHalStatus       halStatus;
   WDI_BtAmpEventRspCb wdiBtAmpEventRspCb;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wdiBtAmpEventRspCb = (WDI_BtAmpEventRspCb)pWDICtx->pfncRspCB;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   wpalMemoryCopy( &halStatus,
                   pEventData->pEventData,
                   sizeof(halStatus));

   wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

   /*Notify UMAC*/
   wdiBtAmpEventRspCb( wdiStatus, pWDICtx->pRspCBUserData);

   return WDI_STATUS_SUCCESS;
}/*WDI_ProcessBtAmpEventRsp*/


/**
 @brief Process ADD STA SELF Rsp function (called
        when a response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessAddSTASelfRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_AddSTASelfRspParamsType  wdiAddSTASelfParams;
  WDI_AddSTASelfParamsRspCb    wdiAddSTASelfReqParamsRspCb;
  tAddStaSelfRspMsg            halAddStaSelfRsp;
  WDI_AddStaParams             wdiAddSTAParam = {0};
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiAddSTASelfReqParamsRspCb =
                         (WDI_AddSTASelfParamsRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halAddStaSelfRsp.addStaSelfRspParams,
                  pEventData->pEventData,
                  sizeof(halAddStaSelfRsp.addStaSelfRspParams));


  wdiAddSTASelfParams.wdiStatus   =
    WDI_HAL_2_WDI_STATUS(halAddStaSelfRsp.addStaSelfRspParams.status);

  wdiAddSTASelfParams.ucSTASelfIdx   =
    halAddStaSelfRsp.addStaSelfRspParams.selfStaIdx;
  wdiAddSTASelfParams.dpuIdx =
    halAddStaSelfRsp.addStaSelfRspParams.dpuIdx;
  wdiAddSTASelfParams.dpuSignature =
    halAddStaSelfRsp.addStaSelfRspParams.dpuSignature;

  wpalMemoryCopy(wdiAddSTASelfParams.macSelfSta,
                 pWDICtx->wdiCacheAddSTASelfReq.wdiAddSTASelfInfo.selfMacAddr,
                 WDI_MAC_ADDR_LEN);


#ifdef HAL_SELF_STA_PER_BSS

  /* At this point add the self-STA */

  /*! TO DO: wdiAddSTAParam.ucWmmEnabled */
  /*! TO DO: wdiAddSTAParam.ucHTCapable */
  /*! TO DO: wdiAddSTAParam.ucRmfEnabled */

  //all DPU indices are the same for self STA

  /*DPU Information*/
  wdiAddSTAParam.dpuIndex              = wdiAddSTASelfParams.dpuIdx;
  wdiAddSTAParam.dpuSig                = wdiAddSTASelfParams.dpuSignature;
  wdiAddSTAParam.bcastDpuSignature     = wdiAddSTASelfParams.dpuSignature;
  wdiAddSTAParam.bcastMgmtDpuSignature = wdiAddSTASelfParams.dpuSignature;
  wdiAddSTAParam.bcastDpuIndex         = wdiAddSTASelfParams.dpuIdx;
  wdiAddSTAParam.bcastMgmtDpuIndex     = wdiAddSTASelfParams.dpuIdx;

  wpalMemoryCopy(wdiAddSTAParam.staMacAddr, wdiAddSTASelfParams.macSelfSta,
                 WDI_MAC_ADDR_LEN);

  wdiAddSTAParam.ucStaType = WDI_STA_ENTRY_SELF; /* 0 - self */
  wdiAddSTAParam.ucSTAIdx = wdiAddSTASelfParams.ucSTASelfIdx;

  if(halAddStaSelfRsp.addStaSelfRspParams.status
     != eHAL_STATUS_ADD_STA_SELF_IGNORED_REF_COUNT_NOT_ZERO)
  {
     (void)WDI_STATableAddSta(pWDICtx,&wdiAddSTAParam);
  }
#endif

  /*Notify UMAC*/
  wdiAddSTASelfReqParamsRspCb( &wdiAddSTASelfParams, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessAddSTASelfRsp*/



/**
 @brief WDI_ProcessDelSTASelfRsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessDelSTASelfRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_DelSTASelfRspParamsType     wdiDelStaSelfRspParams;
  WDI_DelSTASelfRspCb             wdiDelStaSelfRspCb;
  tDelStaSelfRspParams            delStaSelfRspParams;
  wpt_uint8                       ucStaIdx;

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

  /*-------------------------------------------------------------------------
    Sanity check
    -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);
    WDI_ASSERT(0);
    return WDI_STATUS_E_FAILURE;
  }

  wdiDelStaSelfRspCb = (WDI_DelSTASelfRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
    -------------------------------------------------------------------------*/

  wpalMemoryCopy( &delStaSelfRspParams,
                        (wpt_uint8*)pEventData->pEventData,
                              sizeof(tDelStaSelfRspParams));

  wdiDelStaSelfRspParams.wdiStatus   =
    WDI_HAL_2_WDI_STATUS(delStaSelfRspParams.status);

  /* delStaSelfRspParams.status is not
   eHAL_STATUS_DEL_STA_SELF_IGNORED_REF_COUNT_NOT_ZERO*/
  if( eHAL_STATUS_SUCCESS == delStaSelfRspParams.status )
  {
    WDI_Status wdiStatus;
    wdiStatus = WDI_STATableFindStaidByAddr(pWDICtx,
                               delStaSelfRspParams.selfMacAddr,
                               &ucStaIdx);
    if(WDI_STATUS_E_FAILURE == wdiStatus)
    {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: Unable to extract the STA Idx ", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
    }
    WDI_STATableDelSta(pWDICtx, ucStaIdx);
  }

  /*Notify UMAC*/
  wdiDelStaSelfRspCb(&wdiDelStaSelfRspParams, (void*) pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}

#ifdef FEATURE_OEM_DATA_SUPPORT
/**
 @brief Start Oem Data Rsp function (called when a 
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/

WDI_Status
WDI_ProcessStartOemDataRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_oemDataRspCb           wdiOemDataRspCb;
  WDI_oemDataRspParamsType*  wdiOemDataRspParams;
  tStartOemDataRspParams*    halStartOemDataRspParams;

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiOemDataRspCb = (WDI_oemDataRspCb)pWDICtx->pfncRspCB;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
  halStartOemDataRspParams = (tStartOemDataRspParams *)pEventData->pEventData;


  //It is the responsibility of the application code to check for failure
  //conditions!

  //Allocate memory for WDI OEM DATA RSP structure
  wdiOemDataRspParams = wpalMemoryAllocate(sizeof(WDI_oemDataRspParamsType)) ;

  if(NULL == wdiOemDataRspParams)
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
            "Failed to allocate memory in OEM DATA Response %p %p %p ",
                pWDICtx, pEventData, pEventData->pEventData);
    WDI_ASSERT(0);
    return WDI_STATUS_E_FAILURE;
  }

  /* Populate WDI structure members */
  wpalMemoryCopy(wdiOemDataRspParams->oemDataRsp, halStartOemDataRspParams->oemDataRsp, OEM_DATA_RSP_SIZE);

  /*Notify UMAC*/
  wdiOemDataRspCb(wdiOemDataRspParams, pWDICtx->pRspCBUserData);

  //Free memory allocated for WDI OEM_DATA MEAS RSP structure
  wpalMemoryFree(wdiOemDataRspParams);

  return WDI_STATUS_SUCCESS;
}/*WDI_PrcoessStartOemDataRsp*/
#endif

/*===========================================================================
           Miscellaneous Control Response Processing API
===========================================================================*/

/**
 @brief Process Channel Switch Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessChannelSwitchRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_SwitchCHRspParamsType   wdiSwitchChRsp;
  WDI_SwitchChRspCb           wdiChSwitchRspCb;
  tSwitchChannelRspParams     halSwitchChannelRsp;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiChSwitchRspCb = (WDI_SwitchChRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halSwitchChannelRsp,
                  (wpt_uint8*)pEventData->pEventData,
                  sizeof(halSwitchChannelRsp));

  wdiSwitchChRsp.wdiStatus   =
               WDI_HAL_2_WDI_STATUS(halSwitchChannelRsp.status);
  wdiSwitchChRsp.ucChannel = halSwitchChannelRsp.channelNumber;

#ifdef WLAN_FEATURE_VOWIFI
  wdiSwitchChRsp.ucTxMgmtPower =  halSwitchChannelRsp.txMgmtPower;
#endif

  /*Notify UMAC*/
  wdiChSwitchRspCb( &wdiSwitchChRsp, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessChannelSwitchRsp*/

/**
 @brief Process Channel Switch Rsp function (called when a response
        is being received over the bus from HAL against
        WDI_ProcessChannelSwitchReq_V1)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/

WDI_Status
WDI_ProcessChannelSwitchRsp_V1
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_SwitchChRspParamsType_V1   wdiSwitchChRsp;
  WDI_SwitchChRspCb_V1          wdiChSwitchRspCb;
  tSwitchChannelRspParams_V1        halSwitchChannelRsp;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiChSwitchRspCb = (WDI_SwitchChRspCb_V1)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halSwitchChannelRsp,
                  (wpt_uint8*)pEventData->pEventData,
                  sizeof(halSwitchChannelRsp));

  wdiSwitchChRsp.wdiStatus   =
               WDI_HAL_2_WDI_STATUS(halSwitchChannelRsp.status);
  wdiSwitchChRsp.ucChannel = halSwitchChannelRsp.channelNumber;

#ifdef WLAN_FEATURE_VOWIFI
  wdiSwitchChRsp.ucTxMgmtPower =  halSwitchChannelRsp.txMgmtPower;
#endif

  wdiSwitchChRsp.channelSwitchSrc = halSwitchChannelRsp.channelSwitchSrc;
  if (( NULL == wdiChSwitchRspCb ) )
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                   "%s: ### Call back function is null", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  /*Notify UMAC*/
  wdiChSwitchRspCb( &wdiSwitchChRsp, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessChannelSwitchRsp_V1*/

/**
 @brief Process Config STA Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessConfigStaRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_ConfigSTARspParamsType    wdiCfgSTAParams;
  WDI_ConfigSTARspCb            wdiConfigSTARspCb;
  WDI_AddStaParams              wdiAddSTAParam;

  WDI_BSSSessionType*           pBSSSes             = NULL;
  wpt_uint8                     ucCurrentBSSSesIdx  = 0;

  tConfigStaRspMsg              halConfigStaRsp;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiConfigSTARspCb = (WDI_ConfigSTARspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halConfigStaRsp.configStaRspParams,
                  pEventData->pEventData,
                  sizeof(halConfigStaRsp.configStaRspParams));


  wdiCfgSTAParams.ucSTAIdx    = halConfigStaRsp.configStaRspParams.staIdx;
  wdiCfgSTAParams.ucBssIdx    = halConfigStaRsp.configStaRspParams.bssIdx;
  wdiCfgSTAParams.ucUcastSig  = halConfigStaRsp.configStaRspParams.ucUcastSig;
  wdiCfgSTAParams.ucBcastSig  = halConfigStaRsp.configStaRspParams.ucBcastSig;
  wdiCfgSTAParams.ucMgmtSig   = halConfigStaRsp.configStaRspParams.ucMgmtSig;

   /* MAC Address of STA - take from cache as it does not come back in the
   response*/
   wpalMemoryCopy( wdiCfgSTAParams.macSTA,
          pWDICtx->wdiCachedConfigStaReq.wdiReqInfo.macSTA,
          WDI_MAC_ADDR_LEN);

  wdiCfgSTAParams.wdiStatus   =
    WDI_HAL_2_WDI_STATUS(halConfigStaRsp.configStaRspParams.status);

  wdiCfgSTAParams.ucDpuIndex = halConfigStaRsp.configStaRspParams.dpuIndex;
  wdiCfgSTAParams.ucBcastDpuIndex = halConfigStaRsp.configStaRspParams.bcastDpuIndex;
  wdiCfgSTAParams.ucBcastMgmtDpuIdx = halConfigStaRsp.configStaRspParams.bcastMgmtDpuIdx;

  if ( WDI_STATUS_SUCCESS == wdiCfgSTAParams.wdiStatus )
  {
    if ( WDI_ADD_STA == pWDICtx->wdiCachedConfigStaReq.wdiReqInfo.wdiAction )
    {
      /* ADD STA to table */
      wdiAddSTAParam.ucSTAIdx = halConfigStaRsp.configStaRspParams.staIdx;
      wdiAddSTAParam.dpuSig   = halConfigStaRsp.configStaRspParams.ucUcastSig;
      wdiAddSTAParam.dpuIndex = halConfigStaRsp.configStaRspParams.dpuIndex;

      /*This info can be retrieved from the cached initial request*/
      wdiAddSTAParam.ucWmmEnabled =
        pWDICtx->wdiCachedConfigStaReq.wdiReqInfo.ucWMMEnabled;
      wdiAddSTAParam.ucHTCapable  =
        pWDICtx->wdiCachedConfigStaReq.wdiReqInfo.ucHTCapable;
      wdiAddSTAParam.ucStaType    =
        pWDICtx->wdiCachedConfigStaReq.wdiReqInfo.wdiSTAType;
      wdiAddSTAParam.ucRmfEnabled =
        pWDICtx->wdiCachedConfigStaReq.wdiReqInfo.ucRMFEnabled;

      /* MAC Address of STA */
      wpalMemoryCopy(wdiAddSTAParam.staMacAddr,
                     pWDICtx->wdiCachedConfigStaReq.wdiReqInfo.macSTA,
                     WDI_MAC_ADDR_LEN);

      wpalMemoryCopy(wdiAddSTAParam.macBSSID,
                     pWDICtx->wdiCachedConfigStaReq.wdiReqInfo.macBSSID ,
                     WDI_MAC_ADDR_LEN);

      ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx,
                    pWDICtx->wdiCachedConfigStaReq.wdiReqInfo.macBSSID,
                    &pBSSSes);

      if ( NULL == pBSSSes )
      {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                  "Association for this BSSID is not in place");

        WDI_ASSERT(0);
        return WDI_STATUS_E_NOT_ALLOWED;
      }

      /*Add BSS specific parameters*/
      wdiAddSTAParam.bcastMgmtDpuIndex =
         halConfigStaRsp.configStaRspParams.bcastMgmtDpuIdx;
      wdiAddSTAParam.bcastMgmtDpuSignature =
         halConfigStaRsp.configStaRspParams.ucMgmtSig;
      wdiAddSTAParam.bcastDpuIndex  =
         halConfigStaRsp.configStaRspParams.bcastDpuIndex;
      wdiAddSTAParam.bcastDpuSignature =
         halConfigStaRsp.configStaRspParams.ucBcastSig;
      wdiAddSTAParam.ucBSSIdx              = ucCurrentBSSSesIdx;

      WDI_STATableAddSta(pWDICtx,&wdiAddSTAParam);
    }
    if( WDI_UPDATE_STA == pWDICtx->wdiCachedConfigStaReq.wdiReqInfo.wdiAction )
    {
       WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable;

       pSTATable[halConfigStaRsp.configStaRspParams.staIdx].bcastDpuIndex =
          halConfigStaRsp.configStaRspParams.bcastDpuIndex;
       pSTATable[halConfigStaRsp.configStaRspParams.staIdx].bcastDpuSignature =
          halConfigStaRsp.configStaRspParams.ucBcastSig;
       pSTATable[halConfigStaRsp.configStaRspParams.staIdx].bcastMgmtDpuIndex =
          halConfigStaRsp.configStaRspParams.bcastMgmtDpuIdx;
       pSTATable[halConfigStaRsp.configStaRspParams.staIdx].bcastMgmtDpuSignature =
          halConfigStaRsp.configStaRspParams.ucMgmtSig;
       pSTATable[halConfigStaRsp.configStaRspParams.staIdx].bssIdx =
          halConfigStaRsp.configStaRspParams.bssIdx;
       pSTATable[halConfigStaRsp.configStaRspParams.staIdx].dpuIndex =
          halConfigStaRsp.configStaRspParams.dpuIndex;
       pSTATable[halConfigStaRsp.configStaRspParams.staIdx].dpuSig =
          halConfigStaRsp.configStaRspParams.ucUcastSig;
    }
  }

  /*Notify UMAC*/
  wdiConfigSTARspCb( &wdiCfgSTAParams, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessConfigStaRsp*/


/**
 @brief Process Set Link State Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetLinkStateRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status              wdiStatus;
  eHalStatus              halStatus;
  WDI_SetLinkStateRspCb   wdiSetLinkStateRspCb;

  WDI_BSSSessionType*     pBSSSes              = NULL;
  wpt_uint8               ucCurrentBSSSesIdx   = 0;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiSetLinkStateRspCb = (WDI_SetLinkStateRspCb)pWDICtx->pfncRspCB;

  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*If the link is being transitioned to idle - the BSS is to be deleted
  - this type of ending a session is possible when UMAC has failed an
  - association session during Join*/
  if ( WDI_LINK_IDLE_STATE ==
       pWDICtx->wdiCacheSetLinkStReq.wdiLinkInfo.wdiLinkState )
  {
    /*------------------------------------------------------------------------
      Find the BSS for which the request is made
    ------------------------------------------------------------------------*/
    ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx,
                        pWDICtx->wdiCacheSetLinkStReq.wdiLinkInfo.macBSSID,
                        &pBSSSes);

    /*-----------------------------------------------------------------------
      Del BSS response can only be received for an existing assoc that
      is current and in progress
      -----------------------------------------------------------------------*/
    if ( NULL == pBSSSes )
    {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
                "Set link response received outside association session");
    }
    else
    {
      /* For BT AMP roles no need to delete the sessions if assoc fails. There
      will be del BSS coming after this to stop the beaconing & cleaning up the
      sessions*/
      if(( WDI_BTAMP_STA_MODE != pBSSSes->wdiBssType )&&
         ( WDI_BTAMP_AP_MODE != pBSSSes->wdiBssType ))
      {
         /*-----------------------------------------------------------------------
           The current session will be deleted
         -----------------------------------------------------------------------*/
         WDI_DeleteSession(pWDICtx, pBSSSes);

         /*-----------------------------------------------------------------------
           Check to see if this association is in progress - if so disable the
           flag as this has ended
         -----------------------------------------------------------------------*/
         if ( ucCurrentBSSSesIdx == pWDICtx->ucCurrentBSSSesIdx )
         {
           /*Association no longer in progress  */
           pWDICtx->bAssociationInProgress = eWLAN_PAL_FALSE;
           /*Association no longer in progress - prepare pending assoc for processing*/
           WDI_DequeueAssocRequest(pWDICtx);
         }
      }
    }
  }
  /* If the link state has been set to POST ASSOC, reset the "association in
     progress" flag */
  if ( WDI_LINK_POSTASSOC_STATE ==
       pWDICtx->wdiCacheSetLinkStReq.wdiLinkInfo.wdiLinkState )
  {
     pWDICtx->bAssociationInProgress = eWLAN_PAL_FALSE;
     WDI_DequeueAssocRequest(pWDICtx);
  }

  wpalMutexRelease(&pWDICtx->wptMutex);

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halStatus,
                  pEventData->pEventData,
                  sizeof(halStatus));

  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  /*Notify UMAC*/
  wdiSetLinkStateRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessSetLinkStateRsp*/

/**
 @brief Process Get Stats Rsp function (called when a response is
        being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessGetStatsRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_GetStatsRspParamsType   *wdiGetStatsRsp;
  WDI_GetStatsRspCb           wdiGetStatsRspCb;
  tHalStatsRspParams*         pHalStatsRspParams;

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

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  pHalStatsRspParams = (tHalStatsRspParams *)pEventData->pEventData;

  /*allocate the stats response buffer */
  wdiGetStatsRsp = (WDI_GetStatsRspParamsType *)wpalMemoryAllocate(
              pHalStatsRspParams->msgLen - sizeof(tHalStatsRspParams)
              + sizeof(WDI_GetStatsRspParamsType));

  if(NULL == wdiGetStatsRsp)
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
                "Failed to allocate memory in Get Stats Response %p %p %p ",
                 pWDICtx, pEventData, pEventData->pEventData);
    WDI_ASSERT(0);
    return WDI_STATUS_E_FAILURE;
  }

  wdiGetStatsRspCb = (WDI_GetStatsRspCb)pWDICtx->pfncRspCB;

  wpalMemoryZero(wdiGetStatsRsp, pHalStatsRspParams->msgLen);
  wdiGetStatsRsp->usMsgType  = pHalStatsRspParams->msgType;
  wdiGetStatsRsp->usMsgLen   = pHalStatsRspParams->msgLen;
  wdiGetStatsRsp->wdiStatus  = WDI_HAL_2_WDI_STATUS(pHalStatsRspParams->status);
  wdiGetStatsRsp->ucSTAIdx   = pHalStatsRspParams->staId;
  wdiGetStatsRsp->uStatsMask = pHalStatsRspParams->statsMask;

  /* copy the stats from buffer at the end of the tHalStatsRspParams message */
  wpalMemoryCopy(wdiGetStatsRsp + 1,
   (wpt_uint8*)pEventData->pEventData + sizeof(tHalStatsRspParams),
   pHalStatsRspParams->msgLen - sizeof(tHalStatsRspParams));

  /*Notify UMAC*/
  wdiGetStatsRspCb( wdiGetStatsRsp, pWDICtx->pRspCBUserData);

  wpalMemoryFree(wdiGetStatsRsp);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessGetStatsRsp*/

#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
/**
 @brief Process Get Roam Rssi Rsp function (called when a response is
        being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessGetRoamRssiRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_GetRoamRssiRspParamsType   wdiGetRoamRssiRsp;
  WDI_GetRoamRssiRspCb           wdiGetRoamRssiRspCb;
  tHalGetRoamRssiRspMsg          halRoamRssiRspParams;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiGetRoamRssiRspCb = (WDI_GetRoamRssiRspCb)pWDICtx->pfncRspCB;
  if(NULL == wdiGetRoamRssiRspCb)
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                 "%s: call back function is NULL", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halRoamRssiRspParams.roamRssiRspParams,
                  pEventData->pEventData,
                  sizeof(halRoamRssiRspParams.roamRssiRspParams));

  wdiGetRoamRssiRsp.wdiStatus  = WDI_HAL_2_WDI_STATUS(halRoamRssiRspParams.roamRssiRspParams.status);
  wdiGetRoamRssiRsp.ucSTAIdx   = halRoamRssiRspParams.roamRssiRspParams.staId;
  wdiGetRoamRssiRsp.rssi = halRoamRssiRspParams.roamRssiRspParams.rssi;

  /*Notify UMAC*/
  wdiGetRoamRssiRspCb( &wdiGetRoamRssiRsp, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessGetRoamRssiRsp*/
#endif


/**
 @brief Process Update Cfg Rsp function (called when a response is
        being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessUpdateCfgRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status           wdiStatus;
  eHalStatus           halStatus;
  WDI_UpdateCfgRspCb   wdiUpdateCfgRspCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiUpdateCfgRspCb = (WDI_UpdateCfgRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  halStatus = *((eHalStatus*)pEventData->pEventData);
  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  /*Notify UMAC*/
  wdiUpdateCfgRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessUpdateCfgRsp*/



/**
 @brief Process Add BA Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessAddBARsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_AddBARspCb          wdiAddBARspCb;

  tAddBARspParams         halAddBARsp;
  WDI_AddBARspinfoType    wdiAddBARsp;

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

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiAddBARspCb = (WDI_AddBARspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halAddBARsp,
                  pEventData->pEventData,
                  sizeof(halAddBARsp));

  wdiAddBARsp.wdiStatus = WDI_HAL_2_WDI_STATUS(halAddBARsp.status);

  if ( WDI_STATUS_SUCCESS == wdiAddBARsp.wdiStatus )
  {
    wdiAddBARsp.ucBaDialogToken = halAddBARsp.baDialogToken;
  }

  /*Notify UMAC*/
  wdiAddBARspCb( &wdiAddBARsp, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessAddSessionBARsp*/

/**
 @brief Process Add BA Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessTriggerBARsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_TriggerBARspCb      wdiTriggerBARspCb;

  tTriggerBARspParams*           halTriggerBARsp;
  tTriggerBaRspCandidate*        halBaCandidate;
  WDI_TriggerBARspParamsType*    wdiTriggerBARsp;
  WDI_TriggerBARspCandidateType* wdiTriggerBARspCandidate;
  wpt_uint16                     index;
  wpt_uint16                     TidIndex;
  WDI_Status                     halTriggerBARspStatus;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiTriggerBARspCb = (WDI_TriggerBARspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  halTriggerBARsp = (tTriggerBARspParams *)pEventData->pEventData;

  halTriggerBARspStatus = WDI_HAL_2_WDI_STATUS(halTriggerBARsp->status);

  if ( WDI_STATUS_SUCCESS == halTriggerBARspStatus)
  {
    wdiTriggerBARsp = wpalMemoryAllocate(sizeof(WDI_TriggerBARspParamsType) +
                      halTriggerBARsp->baCandidateCnt *
                      sizeof(WDI_TriggerBARspCandidateType));

    if(NULL == wdiTriggerBARsp)
    {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Failed to allocate memory in Trigger BA Response %p %p %p ",
                   pWDICtx, pEventData, pEventData->pEventData);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
    }

    wdiTriggerBARsp->wdiStatus = halTriggerBARspStatus;

    wdiTriggerBARsp->usBaCandidateCnt = halTriggerBARsp->baCandidateCnt;
    wpalMemoryCopy(wdiTriggerBARsp->macBSSID,
                                 halTriggerBARsp->bssId , WDI_MAC_ADDR_LEN);

    wdiTriggerBARspCandidate = (WDI_TriggerBARspCandidateType*)(wdiTriggerBARsp + 1);
    halBaCandidate = (tTriggerBaRspCandidate*)(halTriggerBARsp + 1);

    for(index = 0; index < wdiTriggerBARsp->usBaCandidateCnt; index++)
    {
      wpalMemoryCopy(wdiTriggerBARspCandidate->macSTA,
                                  halBaCandidate->staAddr, WDI_MAC_ADDR_LEN);
      for(TidIndex = 0; TidIndex < STA_MAX_TC; TidIndex++)
      {
        wdiTriggerBARspCandidate->wdiBAInfo[TidIndex].fBaEnable =
                            halBaCandidate->baInfo[TidIndex].fBaEnable;
        wdiTriggerBARspCandidate->wdiBAInfo[TidIndex].startingSeqNum =
                            halBaCandidate->baInfo[TidIndex].startingSeqNum;
      }
      wdiTriggerBARspCandidate++;
      halBaCandidate++;
    }
  }
  else
  {
    wdiTriggerBARsp = wpalMemoryAllocate(sizeof(WDI_TriggerBARspParamsType));

    if(NULL == wdiTriggerBARsp)
    {
       WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Failed to allocate memory in Trigger BA Response %p %p %p ",
                   pWDICtx, pEventData, pEventData->pEventData);
       WDI_ASSERT(0);
       return WDI_STATUS_E_FAILURE;
    }

    wdiTriggerBARsp->wdiStatus = halTriggerBARspStatus;

  }

  /*Notify UMAC*/
  wdiTriggerBARspCb( wdiTriggerBARsp, pWDICtx->pRspCBUserData);

  wpalMemoryFree(wdiTriggerBARsp);
  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessAddSessionBARsp*/

/**
 @brief Process Update Beacon Params Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessUpdateBeaconParamsRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status       wdiStatus;
  eHalStatus       halStatus;
  WDI_UpdateBeaconParamsRspCb   wdiUpdateBeaconParamsRspCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiUpdateBeaconParamsRspCb = (WDI_UpdateBeaconParamsRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halStatus,
                  pEventData->pEventData,
                  sizeof(halStatus));

  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  /*Notify UMAC*/
  wdiUpdateBeaconParamsRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessUpdateBeaconParamsRsp*/

/**
 @brief Process Send Beacon template Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSendBeaconParamsRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status       wdiStatus;
  eHalStatus       halStatus;
  WDI_SendBeaconParamsRspCb   wdiSendBeaconParamsRspCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiSendBeaconParamsRspCb = (WDI_SendBeaconParamsRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halStatus,
                  pEventData->pEventData,
                  sizeof(halStatus));

  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  /*Notify UMAC*/
  wdiSendBeaconParamsRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessSendBeaconParamsRsp*/


/**
 @brief Process Update Probe Resp Template Rsp function (called
        when a response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessUpdateProbeRspTemplateRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status       wdiStatus;
  eHalStatus       halStatus;
  WDI_UpdateProbeRspTemplateRspCb   wdiUpdProbeRspTemplRspCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiUpdProbeRspTemplRspCb = (WDI_UpdateProbeRspTemplateRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halStatus,
                  pEventData->pEventData,
                  sizeof(halStatus));

  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  /*Notify UMAC*/
  wdiUpdProbeRspTemplRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessUpdateProbeRspTemplateRsp*/

  /**
 @brief Process Set Max Tx Power Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetMaxTxPowerRsp
(
  WDI_ControlBlockType*          pWDICtx,
  WDI_EventInfoType*             pEventData
)
{
  tSetMaxTxPwrRspMsg             halTxpowerrsp;

  WDI_SetMaxTxPowerRspMsg        wdiSetMaxTxPowerRspMsg;

  WDA_SetMaxTxPowerRspCb         wdiReqStatusCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiReqStatusCb = (WDA_SetMaxTxPowerRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halTxpowerrsp.setMaxTxPwrRspParams,
                           pEventData->pEventData,
                           sizeof(halTxpowerrsp.setMaxTxPwrRspParams));

  if ( eHAL_STATUS_SUCCESS != halTxpowerrsp.setMaxTxPwrRspParams.status )
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Error status returned in Set Max Tx Power Response ");
     return WDI_STATUS_E_FAILURE;
  }

  wdiSetMaxTxPowerRspMsg.wdiStatus =
         WDI_HAL_2_WDI_STATUS(halTxpowerrsp.setMaxTxPwrRspParams.status);
  wdiSetMaxTxPowerRspMsg.ucPower  = halTxpowerrsp.setMaxTxPwrRspParams.power;

  /*Notify UMAC*/
  wdiReqStatusCb( &wdiSetMaxTxPowerRspMsg, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}

  /**
 @brief Process Set Tx Power Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetTxPowerRsp
(
  WDI_ControlBlockType*          pWDICtx,
  WDI_EventInfoType*             pEventData
)
{
  tSetTxPwrRspMsg             halTxpowerrsp;
  WDI_SetTxPowerRspMsg        wdiSetTxPowerRspMsg;
  WDA_SetTxPowerRspCb         wdiReqStatusCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiReqStatusCb = (WDA_SetTxPowerRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy(&halTxpowerrsp.setTxPwrRspParams,
                 pEventData->pEventData,
                 sizeof(halTxpowerrsp.setTxPwrRspParams));

  if (eHAL_STATUS_SUCCESS != halTxpowerrsp.setTxPwrRspParams.status)
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "Error status returned in Set Tx Power Response ");
     WDI_DetectedDeviceError(pWDICtx, WDI_ERR_BASIC_OP_FAILURE);
     return WDI_STATUS_E_FAILURE;
  }

  wdiSetTxPowerRspMsg.wdiStatus =
         WDI_HAL_2_WDI_STATUS(halTxpowerrsp.setTxPwrRspParams.status);

  /*Notify UMAC*/
  wdiReqStatusCb(&wdiSetTxPowerRspMsg, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}

/**
 @brief Process Set Max Tx Power Per Band Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetMaxTxPowerPerBandRsp
(
   WDI_ControlBlockType*          pWDICtx,
   WDI_EventInfoType*             pEventData
)
{
   tSetMaxTxPwrPerBandRspMsg      halMaxTxPowerPerBandRsp;
   WDI_SetMaxTxPowerPerBandRspMsg wdiSetTxPowerPerBandRspMsg;
   WDA_SetMaxTxPowerPerBandRspCb  wdiReqStatusCb;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
    -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData))
   {
       WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
       WDI_ASSERT(0);
       return WDI_STATUS_E_FAILURE;
   }

   wdiReqStatusCb = (WDA_SetMaxTxPowerPerBandRspCb)pWDICtx->pfncRspCB;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   wpalMemoryCopy(&halMaxTxPowerPerBandRsp.setMaxTxPwrPerBandRspParams,
                  pEventData->pEventData,
                  sizeof(halMaxTxPowerPerBandRsp.setMaxTxPwrPerBandRspParams));

   if (eHAL_STATUS_SUCCESS !=
       halMaxTxPowerPerBandRsp.setMaxTxPwrPerBandRspParams.status)
   {
       WPAL_TRACE(eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
                  "Error status returned in Set Max Tx Power Per Band Response");
       return WDI_STATUS_E_FAILURE;
   }

   wdiSetTxPowerPerBandRspMsg.wdiStatus =
         WDI_HAL_2_WDI_STATUS(
         halMaxTxPowerPerBandRsp.setMaxTxPwrPerBandRspParams.status);

   /* Notify UMAC */
   wdiReqStatusCb(&wdiSetTxPowerPerBandRspMsg, pWDICtx->pRspCBUserData);

   return WDI_STATUS_SUCCESS;
}

#ifdef FEATURE_WLAN_TDLS
/**
 @brief Process TDLS Link Establish Rsp function (called
        when a response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessLinkEstablishReqRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  eHalStatus       halStatus;
  WDI_SetTDLSLinkEstablishReqParamsRspCb   wdiTDLSLinkEstablishReqParamsRspCb;
  tTDLSLinkEstablishedRespMsg  halTdlsLinkEstablishedRespMsg;
  WDI_SetTdlsLinkEstablishReqResp    wdiSetTdlsLinkEstablishReqResp;

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

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
  Extract indication and send it to UMAC
 -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halTdlsLinkEstablishedRespMsg.TDLSLinkEstablishedRespParams,
                  pEventData->pEventData,
                  sizeof(halTdlsLinkEstablishedRespMsg.TDLSLinkEstablishedRespParams) );

  wdiTDLSLinkEstablishReqParamsRspCb = (WDI_SetTDLSLinkEstablishReqParamsRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halStatus,
                  pEventData->pEventData,
                  sizeof(halStatus));

  wdiSetTdlsLinkEstablishReqResp.wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);
  wdiSetTdlsLinkEstablishReqResp.uStaIdx   =   halTdlsLinkEstablishedRespMsg.TDLSLinkEstablishedRespParams.staIdx;

  /*Notify UMAC*/
  wdiTDLSLinkEstablishReqParamsRspCb( &wdiSetTdlsLinkEstablishReqResp, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessLinkEstablishReqRsp*/



/**
 @brief Process TDLS Chan switch Rsp function (called
        when a response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessChanSwitchReqRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  eHalStatus       halStatus;
  WDI_SetTDLSChanSwitchReqParamsRspCb   wdiTDLSChanSwitchReqParamsRspCb;
  tTDLSChanSwitchRespMsg                halTdlsChanSwitchRespMsg;
  WDI_SetTdlsChanSwitchReqResp          wdiSetTdlsChanSwitchReqResp;

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

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
  Extract indication and send it to UMAC
 -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halTdlsChanSwitchRespMsg.tdlsChanSwitchRespParams,
                  pEventData->pEventData,
                  sizeof(halTdlsChanSwitchRespMsg.tdlsChanSwitchRespParams) );

  wdiTDLSChanSwitchReqParamsRspCb = (WDI_SetTDLSChanSwitchReqParamsRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halStatus,
                  pEventData->pEventData,
                  sizeof(halStatus));

  wdiSetTdlsChanSwitchReqResp.wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);
  wdiSetTdlsChanSwitchReqResp.uStaIdx   =  halTdlsChanSwitchRespMsg.tdlsChanSwitchRespParams.staIdx;

  /*Notify UMAC*/
  wdiTDLSChanSwitchReqParamsRspCb( &wdiSetTdlsChanSwitchReqResp, pWDICtx->pRspCBUserData );

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessChanSwitchReqRsp*/



#endif

/**
 @brief Process P2P Group Owner Notice Of Absense Rsp function (called
        when a response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessP2PGONOARsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status       wdiStatus;
  eHalStatus       halStatus;
  WDI_SetP2PGONOAReqParamsRspCb   wdiP2PGONOAReqParamsRspCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiP2PGONOAReqParamsRspCb = (WDI_SetP2PGONOAReqParamsRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halStatus,
                  pEventData->pEventData,
                  sizeof(halStatus));

  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  /*Notify UMAC*/
  wdiP2PGONOAReqParamsRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessP2PGONOARsp*/
/**
 @brief Process Enter IMPS Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessEnterImpsRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status           wdiStatus;
  eHalStatus           halStatus;
  WDI_EnterImpsRspCb   wdiEnterImpsRspCb;
  wpt_status wptStatus;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiEnterImpsRspCb = (WDI_EnterImpsRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  halStatus = *((eHalStatus*)pEventData->pEventData);

  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  /* If IMPS req failed, riva is not power collapsed Put the DXE in FULL state. 
   * Other module states are taken care by PMC.
   * TODO: How do we take care of the case where IMPS is success, but riva power collapse fails??
   */
  if (wdiStatus != WDI_STATUS_SUCCESS) {

     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                "WDI Process Enter IMPS RSP failed With HAL Status Code: %d",
                halStatus);
     /* Call Back is not required as we are putting the DXE in FULL
      * and riva is already in full (IMPS RSP Failed)*/
     wptStatus = WDTS_SetPowerState(pWDICtx, WDTS_POWER_STATE_FULL, NULL);
     
     if( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) {
          WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                "WDTS_SetPowerState returned with status %d when trying to notify DTS that host is entering Full Power state", wptStatus);
          WDI_ASSERT(0);
     }
  }
  /*Notify UMAC*/
  wdiEnterImpsRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessEnterImpsRsp*/

/**
 @brief Process Exit IMPS Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessExitImpsRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status           wdiStatus;
  eHalStatus           halStatus;
  WDI_ExitImpsRspCb    wdiExitImpsRspCb;
  wpt_status           wptStatus;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiExitImpsRspCb = (WDI_ExitImpsRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  halStatus = *((eHalStatus*)pEventData->pEventData);
  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  if (halStatus != eHAL_STATUS_SUCCESS)
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                "%s: Exit IMPS response is a failure with halStatus %d", __func__, halStatus);

  // notify DTS that we are entering Full power
  wptStatus = WDTS_SetPowerState(pWDICtx, WDTS_POWER_STATE_FULL, NULL);
  if( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) 
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                "WDTS_SetPowerState returned with status %d when trying to notify DTS that host is entering Full Power state", wptStatus);
    WDI_ASSERT(0);
  }
  /*Notify UMAC*/
  wdiExitImpsRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessExitImpsRsp*/

/**
 @brief Process Enter BMPS Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessEnterBmpsRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  eHalStatus           halStatus = eHAL_STATUS_FAILURE;
  tHalEnterBmpsRspParams halEnterBmpsRsp;
  WDI_EnterBmpsRspCb     wdiEnterBmpsRspCb;
  WDI_EnterBmpsRspParamsType wdiEnterBmpsRspparams;
  wpt_status             wptStatus;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
  if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION))
  {
        wpalMemoryCopy( &halEnterBmpsRsp,
                       pEventData->pEventData,
                       sizeof(halEnterBmpsRsp));

        //Used to print debug message
        halStatus = halEnterBmpsRsp.status;
        wdiEnterBmpsRspparams.wdiStatus = WDI_HAL_2_WDI_STATUS(halEnterBmpsRsp.status);
        wdiEnterBmpsRspparams.bssIdx = halEnterBmpsRsp.bssIdx;
   }
   else
   {
       halStatus = *((eHalStatus*)pEventData->pEventData);
       wdiEnterBmpsRspparams.wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus);
   }

  wdiEnterBmpsRspCb = (WDI_EnterBmpsRspCb)pWDICtx->pfncRspCB;

  /* If BMPS req failed, riva is not power collapsed put the DXE in FULL state. 
   * Other module states are taken care by PMC.
   * TODO: How do we take care of the case where BMPS is success, but riva power collapse fails??
   */
   if (wdiEnterBmpsRspparams.wdiStatus != WDI_STATUS_SUCCESS) 
   {  

       WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                  "WDI Process Enter BMPS RSP failed With HAL Status Code: %d",
                  halStatus); 
       /* Call Back is not required as we are putting the DXE in FULL
        * and riva is already in FULL (BMPS RSP Failed)*/
       wptStatus = WDTS_SetPowerState(pWDICtx, WDTS_POWER_STATE_FULL, NULL);
       if( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) 
       {
           WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                "WDTS_SetPowerState returned with status %d when trying to notify DTS that host is entering Full Power state", wptStatus);
           WDI_ASSERT(0);
       }
       pWDICtx->bInBmps = eWLAN_PAL_FALSE;
   }
  
  /*Notify UMAC*/
  wdiEnterBmpsRspCb( &wdiEnterBmpsRspparams, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessEnterBmpsRsp*/

/**
 @brief Process Exit BMPS Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessExitBmpsRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  eHalStatus           halStatus;
  WDI_ExitBmpsRspCb   wdiExitBmpsRspCb;
  tHalExitBmpsRspParams halExitBmpsRsp;
  WDI_ExitBmpsRspParamsType wdiExitBmpsRspParams;
  wpt_status                wptStatus;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiExitBmpsRspCb = (WDI_ExitBmpsRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  
  if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION))
  {
      wpalMemoryCopy( &halExitBmpsRsp,
                   pEventData->pEventData,
                   sizeof(halExitBmpsRsp));

      wdiExitBmpsRspParams.wdiStatus = WDI_HAL_2_WDI_STATUS(halExitBmpsRsp.status);
      wdiExitBmpsRspParams.bssIdx = halExitBmpsRsp.bssIdx;
  }
  else
  {
      halStatus = *((eHalStatus*)pEventData->pEventData);
      wdiExitBmpsRspParams.wdiStatus =  WDI_HAL_2_WDI_STATUS(halStatus);
  }

  // notify DTS that we are entering Full power
  wptStatus = WDTS_SetPowerState(pWDICtx, WDTS_POWER_STATE_FULL, NULL);
  if( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) 
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                "WDTS_SetPowerState returned with status %d when trying to notify DTS that host is entering Full Power state", wptStatus);
    WDI_ASSERT(0);
  }
  pWDICtx->bInBmps = eWLAN_PAL_FALSE;

  /*Notify UMAC*/
  wdiExitBmpsRspCb( &wdiExitBmpsRspParams, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessExitBmpsRsp*/

/**
 @brief Process Enter UAPSD Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessEnterUapsdRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  eHalStatus           halStatus;
  tUapsdRspParams halEnterUapsdRsp;
  WDI_EnterUapsdRspCb   wdiEnterUapsdRspCb;
  WDI_EnterUapsdRspParamsType wdiEnterUapsdRspParams;

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

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiEnterUapsdRspCb = (WDI_EnterUapsdRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION))
  {
    wpalMemoryCopy( &halEnterUapsdRsp,
                   pEventData->pEventData,
                   sizeof(halEnterUapsdRsp));

    wdiEnterUapsdRspParams.wdiStatus = WDI_HAL_2_WDI_STATUS(halEnterUapsdRsp.status);
    wdiEnterUapsdRspParams.bssIdx = halEnterUapsdRsp.bssIdx;
  }
  else
  {
      halStatus = *((eHalStatus*)pEventData->pEventData);
      wdiEnterUapsdRspParams.wdiStatus  =  WDI_HAL_2_WDI_STATUS(halStatus);
  }

  if(WDI_STATUS_SUCCESS == wdiEnterUapsdRspParams.wdiStatus)
  {
   // Set the DPU routing flag to the FW WQ, all the TX frames would be now pushed
   // from DPU to the FW-WQ (5) in UAPSD. FW would be in data path, monitoring
   // the traffic to decide when to suspend the trigger frames when there is no traffic
   // activity on the trigger enabled ACs
   pWDICtx->ucDpuRF = BMUWQ_FW_DPU_TX;

#ifdef WLAN_PERF
   // Increment the BD signature to refresh the fast path BD utilization
   pWDICtx->uBdSigSerialNum++;
#endif
  }

  /*Notify UMAC*/
  wdiEnterUapsdRspCb( &wdiEnterUapsdRspParams, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessEnterUapsdRsp*/

/**
 @brief Process Exit UAPSD Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessExitUapsdRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  eHalStatus           halStatus;
  WDI_ExitUapsdRspCb   wdiExitUapsdRspCb;
  tHalExitUapsdRspParams halExitUapsdRsp;
  WDI_ExitUapsdRspParamsType wdiExitUapsdRspParams; 
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiExitUapsdRspCb = (WDI_ExitUapsdRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION))
  {
    wpalMemoryCopy( &halExitUapsdRsp,
                   pEventData->pEventData,
                   sizeof(halExitUapsdRsp));
      
    wdiExitUapsdRspParams.wdiStatus = WDI_HAL_2_WDI_STATUS(halExitUapsdRsp.status);
    wdiExitUapsdRspParams.bssIdx = halExitUapsdRsp.bssIdx;
  }
  else
  {
      halStatus = *((eHalStatus*)pEventData->pEventData);
      wdiExitUapsdRspParams.wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);
  }
   // Restore back the DPU routing flag in the TxBD, for DPU to push the TxBDs to BTQM
   // directly instead of the FW WQ.
   pWDICtx->ucDpuRF = BMUWQ_BTQM_TX_MGMT;

#ifdef WLAN_PERF
   // Increment the BD signature to refresh the fast path BD utilization
   pWDICtx->uBdSigSerialNum++;
#endif

  /*Notify UMAC*/
  wdiExitUapsdRspCb( &wdiExitUapsdRspParams, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessExitUapsdRsp*/

/**
 @brief Process set UAPSD params Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetUapsdAcParamsRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status           wdiStatus;
  eHalStatus           halStatus;
  WDI_SetUapsdAcParamsCb   wdiSetUapsdAcParamsCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiSetUapsdAcParamsCb = (WDI_SetUapsdAcParamsCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  halStatus = *((eHalStatus*)pEventData->pEventData);
  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  /*Notify UMAC*/
  wdiSetUapsdAcParamsCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessSetUapsdAcParamsRsp*/

/**
 @brief Process update UAPSD params Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessUpdateUapsdParamsRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status           wdiStatus;
  eHalStatus           halStatus;
  WDI_UpdateUapsdParamsCb   wdiUpdateUapsdParamsCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiUpdateUapsdParamsCb = (WDI_UpdateUapsdParamsCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  halStatus = *((eHalStatus*)pEventData->pEventData);
  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  /*Notify UMAC*/
  wdiUpdateUapsdParamsCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessUpdateUapsdParamsRsp*/

/**
 @brief Process Configure RXP filter Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessConfigureRxpFilterRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status           wdiStatus;
  eHalStatus           halStatus;
  WDI_ConfigureRxpFilterCb   wdiConfigureRxpFilterCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiConfigureRxpFilterCb = (WDI_ConfigureRxpFilterCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  halStatus = *((eHalStatus*)pEventData->pEventData);
  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  /*Notify UMAC*/
  wdiConfigureRxpFilterCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessConfigureRxpFilterRsp*/

/**
 @brief Process Set beacon filter Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetBeaconFilterRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_Status           wdiStatus;
   eHalStatus           halStatus;
   WDI_SetBeaconFilterCb   wdiBeaconFilterCb;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wdiBeaconFilterCb = (WDI_SetBeaconFilterCb)pWDICtx->pfncRspCB;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   halStatus = *((eHalStatus*)pEventData->pEventData);
   wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

   /*Notify UMAC*/
   wdiBeaconFilterCb( wdiStatus, pWDICtx->pRspCBUserData);

   return WDI_STATUS_SUCCESS;
}/*WDI_ProcessSetBeaconFilterRsp*/

/**
 @brief Process remove beacon filter Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessRemBeaconFilterRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_Status           wdiStatus;
   eHalStatus           halStatus;
   WDI_RemBeaconFilterCb   wdiBeaconFilterCb;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wdiBeaconFilterCb = (WDI_RemBeaconFilterCb)pWDICtx->pfncRspCB;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   halStatus = *((eHalStatus*)pEventData->pEventData);
   wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

   /*Notify UMAC*/
   wdiBeaconFilterCb( wdiStatus, pWDICtx->pRspCBUserData);

   return WDI_STATUS_SUCCESS;
}/*WDI_ProcessRemBeaconFilterRsp*/

/**
 @brief Process set RSSI thresholds Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetRSSIThresoldsRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_Status           wdiStatus;
   eHalStatus           halStatus;
   WDI_SetRSSIThresholdsCb   wdiRSSIThresholdsCb;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wdiRSSIThresholdsCb = (WDI_SetRSSIThresholdsCb)pWDICtx->pfncRspCB;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   halStatus = *((eHalStatus*)pEventData->pEventData);
   wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

   /*Notify UMAC*/
   wdiRSSIThresholdsCb( wdiStatus, pWDICtx->pRspCBUserData);

   return WDI_STATUS_SUCCESS;
}/*WDI_ProcessSetRSSIThresoldsRsp*/

/**
 @brief Process host offload Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessHostOffloadRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_Status           wdiStatus;
   eHalStatus           halStatus;
   WDI_HostOffloadCb    wdiHostOffloadCb;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wdiHostOffloadCb = (WDI_HostOffloadCb)pWDICtx->pfncRspCB;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   halStatus = *((eHalStatus*)pEventData->pEventData);
   wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

   /*Notify UMAC*/
   wdiHostOffloadCb( wdiStatus, pWDICtx->pRspCBUserData);

   return WDI_STATUS_SUCCESS;
}/*WDI_ProcessHostOffloadRsp*/

/**
 @brief Process keep alive Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessKeepAliveRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_Status           wdiStatus;
   eHalStatus           halStatus;
   WDI_KeepAliveCb      wdiKeepAliveCb;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
   WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_INFO,
               "Received WDI_ProcessKeepAliveRsp Callback from HAL");


   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wdiKeepAliveCb = (WDI_KeepAliveCb)pWDICtx->pfncRspCB;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   halStatus = *((eHalStatus*)pEventData->pEventData);
   wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

   /*Notify UMAC*/
   wdiKeepAliveCb( wdiStatus, pWDICtx->pRspCBUserData);

   return WDI_STATUS_SUCCESS;
}/*WDI_ProcessKeepAliveRsp*/

/**
 @brief Process wowl add ptrn Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessWowlAddBcPtrnRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   eHalStatus           halStatus;
   WDI_WowlAddBcPtrnCb    wdiWowlAddBcPtrnCb;
   tHalAddWowlBcastPtrnRspParams halAddWowlBcastPtrRsp;
   WDI_WowlAddBcPtrnRspParamsType wdiWowlAddBcPtrRsp;

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

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wdiWowlAddBcPtrnCb = (WDI_WowlAddBcPtrnCb)pWDICtx->pfncRspCB;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION))
   {
     wpalMemoryCopy( &halAddWowlBcastPtrRsp,
                    pEventData->pEventData,
                    sizeof(halAddWowlBcastPtrRsp));

     wdiWowlAddBcPtrRsp.wdiStatus = 
                   WDI_HAL_2_WDI_STATUS(halAddWowlBcastPtrRsp.status);
   }
   else
   {
       halStatus = *((eHalStatus*)pEventData->pEventData);
       wdiWowlAddBcPtrRsp.wdiStatus = 
                          WDI_HAL_2_WDI_STATUS(halStatus);
   }

   /*Notify UMAC*/
   wdiWowlAddBcPtrnCb( &wdiWowlAddBcPtrRsp, pWDICtx->pRspCBUserData);

   return WDI_STATUS_SUCCESS;
}/*WDI_ProcessWowlAddBcPtrnRsp*/

/**
 @brief Process wowl delete ptrn Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessWowlDelBcPtrnRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   eHalStatus           halStatus;
   WDI_WowlDelBcPtrnCb    wdiWowlDelBcPtrnCb;
   tHalDelWowlBcastPtrnRspParams halDelWowlBcastPtrRsp;
   WDI_WowlDelBcPtrnRspParamsType wdiWowlDelBcstPtrRsp;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wdiWowlDelBcPtrnCb = (WDI_WowlDelBcPtrnCb)pWDICtx->pfncRspCB;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION))
   {
        wpalMemoryCopy( &halDelWowlBcastPtrRsp,
                    pEventData->pEventData,
                    sizeof(halDelWowlBcastPtrRsp));

        wdiWowlDelBcstPtrRsp.wdiStatus = 
                       WDI_HAL_2_WDI_STATUS(halDelWowlBcastPtrRsp.status);
   }
   else
   {
       halStatus = *((eHalStatus*)pEventData->pEventData);
       wdiWowlDelBcstPtrRsp.wdiStatus  =   WDI_HAL_2_WDI_STATUS(halStatus);
   }
   /*Notify UMAC*/
   wdiWowlDelBcPtrnCb( &wdiWowlDelBcstPtrRsp, pWDICtx->pRspCBUserData);

   return WDI_STATUS_SUCCESS;
}/*WDI_ProcessWowlDelBcPtrnRsp*/

/**
 @brief Process wowl enter Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessWowlEnterRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   eHalStatus           halStatus;
   WDI_WowlEnterReqCb   wdiWowlEnterCb;
   WDI_WowlEnterRspParamsType  wdiwowlEnterRsp;
   tHalEnterWowlRspParams  halEnterWowlRspParams;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wdiWowlEnterCb = (WDI_WowlEnterReqCb)pWDICtx->pfncRspCB;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION))
   {
      wpalMemoryCopy( &halEnterWowlRspParams,
                   (wpt_uint8*)pEventData->pEventData,
                   sizeof(halEnterWowlRspParams));

       wdiwowlEnterRsp.bssIdx = halEnterWowlRspParams.bssIdx;
       wdiwowlEnterRsp.status =
                WDI_HAL_2_WDI_STATUS(halEnterWowlRspParams.status);
   }
   else
   {
       halStatus = *((eHalStatus*)pEventData->pEventData);
       wdiwowlEnterRsp.status   =   WDI_HAL_2_WDI_STATUS(halStatus);
   }
   /*Notify UMAC*/
   wdiWowlEnterCb( &wdiwowlEnterRsp, pWDICtx->pRspCBUserData);

   return WDI_STATUS_SUCCESS;
}/*WDI_ProcessWowlEnterRsp*/

/**
 @brief Process wowl exit Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessWowlExitRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   eHalStatus           halStatus;
   WDI_WowlExitReqCb   wdiWowlExitCb;
   tHalExitWowlRspParams halExitWowlRspParams;
   WDI_WowlExitRspParamsType wdiWowlExitRsp;

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

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wdiWowlExitCb = (WDI_WowlExitReqCb)pWDICtx->pfncRspCB;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION))
    {
         wpalMemoryCopy( &halExitWowlRspParams,
                      pEventData->pEventData,
                      sizeof(halExitWowlRspParams));

        wdiWowlExitRsp.status = WDI_HAL_2_WDI_STATUS(halExitWowlRspParams.status);
        wdiWowlExitRsp.bssIdx = halExitWowlRspParams.bssIdx;

   }
   else
   {
       halStatus = *((eHalStatus*)pEventData->pEventData);
       wdiWowlExitRsp.status  =   WDI_HAL_2_WDI_STATUS(halStatus);
   }
   /*Notify UMAC*/
   wdiWowlExitCb( &wdiWowlExitRsp, pWDICtx->pRspCBUserData);

   return WDI_STATUS_SUCCESS;
}/*WDI_ProcessWowlExitRsp*/

/**
 @brief Process Configure Apps CPU wakeup State Rsp function
        (called when a response is being received over the bus
        from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessConfigureAppsCpuWakeupStateRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_Status           wdiStatus;
   eHalStatus           halStatus;
   WDI_ConfigureAppsCpuWakeupStateCb   wdiConfigureAppsCpuWakeupStateCb;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wdiConfigureAppsCpuWakeupStateCb = (WDI_ConfigureAppsCpuWakeupStateCb)pWDICtx->pfncRspCB;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   halStatus = *((eHalStatus*)pEventData->pEventData);
   wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

   /*Notify UMAC*/
   wdiConfigureAppsCpuWakeupStateCb( wdiStatus, pWDICtx->pRspCBUserData);

   return WDI_STATUS_SUCCESS;
}/*WDI_ProcessConfigureAppsCpuWakeupStateRsp*/


/**
 @brief Process Nv download(called when a response
        is being received over the bus from HAL,will check if the responce is )

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessNvDownloadRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{

  WDI_NvDownloadRspCb    wdiNvDownloadRspCb;
  tHalNvImgDownloadRspParams halNvDownloadRsp;
  WDI_NvDownloadRspInfoType wdiNvDownloadRsp;

  /*-------------------------------------------------------------------------
   Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
    ( NULL == pEventData->pEventData))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);
    WDI_ASSERT(0);
    return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halNvDownloadRsp,
                  pEventData->pEventData,
                  sizeof(halNvDownloadRsp));

  wdiNvDownloadRsp.wdiStatus = WDI_HAL_2_WDI_STATUS(halNvDownloadRsp.status);

  if((wdiNvDownloadRsp.wdiStatus == WDI_STATUS_SUCCESS) &&
    (pWDICtx->wdiNvBlobInfo.usCurrentFragment !=
         pWDICtx->wdiNvBlobInfo.usTotalFragment ))
  {
    WDI_NvDownloadReq(&pWDICtx->wdiCachedNvDownloadReq,
       (WDI_NvDownloadRspCb)pWDICtx->pfncRspCB, pWDICtx->pRspCBUserData);
  }
  else
  {
    /*Reset the Nv related global information in WDI context information */
    pWDICtx->wdiNvBlobInfo.usTotalFragment = 0;
    pWDICtx->wdiNvBlobInfo.usFragmentSize = 0;
    pWDICtx->wdiNvBlobInfo.usCurrentFragment = 0;
    /*call WDA callback function for last fragment */
    wdiNvDownloadRspCb = (WDI_NvDownloadRspCb)pWDICtx->pfncRspCB;
    wdiNvDownloadRspCb( &wdiNvDownloadRsp, pWDICtx->pRspCBUserData);
  }

  return WDI_STATUS_SUCCESS;
}
#ifdef WLAN_FEATURE_VOWIFI_11R
/**
 @brief Process Add TSpec Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessAggrAddTSpecRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status            wdiStatus;
  tAggrAddTsRspParams   aggrAddTsRsp;
  WDI_AggrAddTsRspCb    wdiAggrAddTsRspCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiAggrAddTsRspCb = (WDI_AddTsRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &aggrAddTsRsp,
                  pEventData->pEventData,
                  sizeof(aggrAddTsRsp));

  /* What is the difference between status0 and status1? */
  wdiStatus   =   WDI_HAL_2_WDI_STATUS(aggrAddTsRsp.status0);

  /*Notify UMAC*/
  wdiAggrAddTsRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessAddTSpecRsp*/
#endif /* WLAN_FEATURE_VOWIFI_11R */

/**
 @brief WDI_ProcessHostResumeRsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessHostResumeRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_SuspendResumeRspParamsType     wdiResumeRspParams;
  WDI_HostResumeEventRspCb           wdiHostResumeRspCb;
  tHalHostResumeRspParams            hostResumeRspMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
    -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);
    WDI_ASSERT(0);
    return WDI_STATUS_E_FAILURE;
  }

  wdiHostResumeRspCb = (WDI_HostResumeEventRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
    -------------------------------------------------------------------------*/

  wpalMemoryCopy( &hostResumeRspMsg,
      (wpt_uint8*)pEventData->pEventData,
      sizeof(hostResumeRspMsg));

  wdiResumeRspParams.wdiStatus   =
    WDI_HAL_2_WDI_STATUS(hostResumeRspMsg.status);

  /*Notify UMAC*/
  wdiHostResumeRspCb(&wdiResumeRspParams, (void*) pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}

/**
 @brief Process Set Tx PER Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetTxPerTrackingRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status           wdiStatus;
  eHalStatus           halStatus;
  WDI_SetTxPerTrackingRspCb   pwdiSetTxPerTrackingRspCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiSetTxPerTrackingRspCb = (WDI_SetTxPerTrackingRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  halStatus = *((eHalStatus*)pEventData->pEventData);
  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  /*Notify UMAC*/
  pwdiSetTxPerTrackingRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessSetTxPerTrackingRsp*/

/*==========================================================================
                        Indications from HAL
 ==========================================================================*/
/**
 @brief Process Low RSSI Indication function (called when an
        indication of this kind is being received over the bus
        from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessLowRSSIInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_LowLevelIndType  wdiInd;
  tHalRSSINotificationIndMsg   halRSSINotificationIndMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
    Extract indication and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( (void *)&halRSSINotificationIndMsg.rssiNotificationParams,
                  pEventData->pEventData,
                  sizeof(tHalRSSINotification));

  /*Fill in the indication parameters*/
  wdiInd.wdiIndicationType = WDI_RSSI_NOTIFICATION_IND; 
  wdiInd.wdiIndicationData.wdiLowRSSIInfo.bRssiThres1PosCross =
     halRSSINotificationIndMsg.rssiNotificationParams.bRssiThres1PosCross;
  wdiInd.wdiIndicationData.wdiLowRSSIInfo.bRssiThres1NegCross =
     halRSSINotificationIndMsg.rssiNotificationParams.bRssiThres1NegCross;
  wdiInd.wdiIndicationData.wdiLowRSSIInfo.bRssiThres2PosCross =
     halRSSINotificationIndMsg.rssiNotificationParams.bRssiThres2PosCross;
  wdiInd.wdiIndicationData.wdiLowRSSIInfo.bRssiThres2NegCross =
     halRSSINotificationIndMsg.rssiNotificationParams.bRssiThres2NegCross;
  wdiInd.wdiIndicationData.wdiLowRSSIInfo.bRssiThres3PosCross =
     halRSSINotificationIndMsg.rssiNotificationParams.bRssiThres3PosCross;
  wdiInd.wdiIndicationData.wdiLowRSSIInfo.bRssiThres3NegCross =
     halRSSINotificationIndMsg.rssiNotificationParams.bRssiThres3NegCross;
  wdiInd.wdiIndicationData.wdiLowRSSIInfo.avgRssi =
     halRSSINotificationIndMsg.rssiNotificationParams.avgRssi;

  if ( pWDICtx->wdiLowLevelIndCB )
  {
    /*Notify UMAC of indication*/
    pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
  }

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessLowRSSIInd*/


/**
 @brief Process Missed Beacon Indication function (called when
        an indication of this kind is being received over the
        bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessMissedBeaconInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status           wdiStatus;
  eHalStatus           halStatus;
  WDI_LowLevelIndType  wdiInd;
  tpHalMissedBeaconIndParams halMissedBeaconIndParams;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  halMissedBeaconIndParams = (tpHalMissedBeaconIndParams)pEventData->pEventData;
  /*-------------------------------------------------------------------------
    Extract indication and send it to UMAC
  -------------------------------------------------------------------------*/
  /*! TO DO: Parameters need to be unpacked according to HAL struct*/
  halStatus = *((eHalStatus*)pEventData->pEventData);
  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  /*Fill in the indication parameters*/
  wdiInd.wdiIndicationType = WDI_MISSED_BEACON_IND;
  wdiInd.wdiIndicationData.wdiMissedBeaconInd.bssIdx =
                                       halMissedBeaconIndParams->bssIdx;
  if ( pWDICtx->wdiLowLevelIndCB )
  {
    /*Notify UMAC*/
    pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
  }

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessMissedBeaconInd*/


/**
 @brief Process Unk Addr Frame Indication function (called when
        an indication of this kind is being received over the
        bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessUnkAddrFrameInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status           wdiStatus;
  eHalStatus           halStatus;
  WDI_LowLevelIndType  wdiInd;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
    Extract indication and send it to UMAC
  -------------------------------------------------------------------------*/
  /*! TO DO: Parameters need to be unpacked according to HAL struct*/
  halStatus = *((eHalStatus*)pEventData->pEventData);
  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  /*Fill in the indication parameters*/
  wdiInd.wdiIndicationType = WDI_UNKNOWN_ADDR2_FRAME_RX_IND;
  /* ! TO DO - fill in from HAL struct:
    wdiInd.wdiIndicationData.wdiUnkAddr2FrmInfo*/

  if ( pWDICtx->wdiLowLevelIndCB )
  {
    /*Notify UMAC*/
    pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
  }

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessUnkAddrFrameInd*/


/**
 @brief Process MIC Failure Indication function (called when an
        indication of this kind is being received over the bus
        from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessMicFailureInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_LowLevelIndType  wdiInd;
  tpSirMicFailureInd   pHalMicFailureInd;

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

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pHalMicFailureInd = (tpSirMicFailureInd)pEventData->pEventData;
  /*-------------------------------------------------------------------------
    Extract indication and send it to UMAC
  -------------------------------------------------------------------------*/

  /*Fill in the indication parameters*/
  wdiInd.wdiIndicationType = WDI_MIC_FAILURE_IND;
  wpalMemoryCopy(wdiInd.wdiIndicationData.wdiMICFailureInfo.bssId,
                 pHalMicFailureInd->bssId, WDI_MAC_ADDR_LEN);
  wpalMemoryCopy(wdiInd.wdiIndicationData.wdiMICFailureInfo.macSrcAddr,
                 pHalMicFailureInd->info.srcMacAddr, WDI_MAC_ADDR_LEN);
  wpalMemoryCopy(wdiInd.wdiIndicationData.wdiMICFailureInfo.macTaAddr,
                 pHalMicFailureInd->info.taMacAddr, WDI_MAC_ADDR_LEN);
  wpalMemoryCopy(wdiInd.wdiIndicationData.wdiMICFailureInfo.macDstAddr,
                 pHalMicFailureInd->info.dstMacAddr, WDI_MAC_ADDR_LEN);
  wdiInd.wdiIndicationData.wdiMICFailureInfo.ucMulticast =
                 pHalMicFailureInd->info.multicast;
  wdiInd.wdiIndicationData.wdiMICFailureInfo.ucIV1 =
                 pHalMicFailureInd->info.IV1;
  wdiInd.wdiIndicationData.wdiMICFailureInfo.keyId=
                 pHalMicFailureInd->info.keyId;
  wpalMemoryCopy(wdiInd.wdiIndicationData.wdiMICFailureInfo.TSC,
                 pHalMicFailureInd->info.TSC,WDI_CIPHER_SEQ_CTR_SIZE);
  wpalMemoryCopy(wdiInd.wdiIndicationData.wdiMICFailureInfo.macRxAddr,
                 pHalMicFailureInd->info.rxMacAddr, WDI_MAC_ADDR_LEN);

  if ( pWDICtx->wdiLowLevelIndCB )
  {
    /*Notify UMAC*/
    pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
  }

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessMicFailureInd*/


/**
 @brief Process Fatal Failure Indication function (called when
        an indication of this kind is being received over the
        bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessFatalErrorInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status           wdiStatus;
  eHalStatus           halStatus;
  WDI_LowLevelIndType  wdiInd;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
    Extract indication and send it to UMAC
  -------------------------------------------------------------------------*/

  /*! TO DO: Parameters need to be unpacked according to HAL struct*/
  halStatus = *((eHalStatus*)pEventData->pEventData);
  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Fatal failure received from device %d ", halStatus );

  /*Fill in the indication parameters*/
  wdiInd.wdiIndicationType             = WDI_FATAL_ERROR_IND;
  wdiInd.wdiIndicationData.usErrorCode = WDI_ERR_DEV_INTERNAL_FAILURE;

  if ( pWDICtx->wdiLowLevelIndCB )
  {
    /*Notify UMAC*/
    pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
  }

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessFatalErrorInd*/

/**
 @brief Process Delete STA Indication function (called when
        an indication of this kind is being received over the
        bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessDelSTAInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  tDeleteStaContextParams    halDelSTACtx;
  WDI_LowLevelIndType        wdiInd;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
    Extract indication and send it to UMAC
  -------------------------------------------------------------------------*/

  /* Parameters need to be unpacked according to HAL struct*/
  wpalMemoryCopy( &halDelSTACtx,
                  pEventData->pEventData,
                  sizeof(halDelSTACtx));

  /*Fill in the indication parameters*/
  wdiInd.wdiIndicationType             = WDI_DEL_STA_IND;

  wpalMemoryCopy(wdiInd.wdiIndicationData.wdiDeleteSTAIndType.macADDR2,
                 halDelSTACtx.addr2, WDI_MAC_ADDR_LEN);
  wpalMemoryCopy(wdiInd.wdiIndicationData.wdiDeleteSTAIndType.macBSSID,
                 halDelSTACtx.bssId, WDI_MAC_ADDR_LEN);

  wdiInd.wdiIndicationData.wdiDeleteSTAIndType.usAssocId =
    halDelSTACtx.assocId;
  wdiInd.wdiIndicationData.wdiDeleteSTAIndType.ucSTAIdx  =
    halDelSTACtx.staId;
  wdiInd.wdiIndicationData.wdiDeleteSTAIndType.wptReasonCode =
    halDelSTACtx.reasonCode;

  if ( pWDICtx->wdiLowLevelIndCB )
  {
    /*Notify UMAC*/
    pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
  }

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessDelSTAInd*/

/**
*@brief Process Coex Indication function (called when
        an indication of this kind is being received over the
        bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessCoexInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_LowLevelIndType  wdiInd;
  tCoexIndMsg          halCoexIndMsg;
  wpt_uint32           index;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT( 0 );
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
    Extract indication and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halCoexIndMsg.coexIndParams,
                  pEventData->pEventData,
                  sizeof(halCoexIndMsg.coexIndParams) );

  /*Fill in the indication parameters*/
  wdiInd.wdiIndicationType = WDI_COEX_IND;
  wdiInd.wdiIndicationData.wdiCoexInfo.coexIndType = halCoexIndMsg.coexIndParams.coexIndType;
  for (index = 0; index < WDI_COEX_IND_DATA_SIZE; index++)
  {
    wdiInd.wdiIndicationData.wdiCoexInfo.coexIndData[index] = halCoexIndMsg.coexIndParams.coexIndData[index];
  }

  // DEBUG
  WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_INFO,
              "[COEX WDI] Coex Ind Type (%x) data (%x %x %x %x)",
              wdiInd.wdiIndicationData.wdiCoexInfo.coexIndType,
              wdiInd.wdiIndicationData.wdiCoexInfo.coexIndData[0],
              wdiInd.wdiIndicationData.wdiCoexInfo.coexIndData[1],
              wdiInd.wdiIndicationData.wdiCoexInfo.coexIndData[2],
              wdiInd.wdiIndicationData.wdiCoexInfo.coexIndData[3] );

  if ( pWDICtx->wdiLowLevelIndCB )
  {
    /*Notify UMAC*/
    pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
  }

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessCoexInd*/

/**
*@brief Process Tx Complete Indication function (called when
        an indication of this kind is being received over the
        bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessTxCompleteInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_LowLevelIndType  wdiInd;
  tTxComplIndMsg       halTxComplIndMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT( 0 );
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
    Extract indication and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halTxComplIndMsg.txComplParams,
                  pEventData->pEventData,
                  sizeof(halTxComplIndMsg.txComplParams) );

  /*Fill in the indication parameters*/
  wdiInd.wdiIndicationType = WDI_TX_COMPLETE_IND;

  wpalMemoryCopy( &wdiInd.wdiIndicationData,
                  &halTxComplIndMsg.txComplParams,
                  sizeof(WDI_TxBDStatus) );

  if ( pWDICtx->wdiLowLevelIndCB )
  {
    /*Notify UMAC*/
    pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
  }

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessTxCompleteInd*/
#ifdef FEATURE_WLAN_TDLS
/**
*@brief Process TDLS Indication function (called when
        an indication of this kind is being received over the
        bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessTdlsInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_LowLevelIndType  wdiInd;
  tTdlsIndMsg       halTdlsIndMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
  Sanity check
 -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT( 0 );
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
  Extract indication and send it to UMAC
 -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halTdlsIndMsg.tdlsIndParams,
                  pEventData->pEventData,
                  sizeof(halTdlsIndMsg.tdlsIndParams) );

  /*Fill in the indication parameters*/
  wdiInd.wdiIndicationType = WDI_TDLS_IND;

  wdiInd.wdiIndicationData.wdiTdlsIndInfo.status
                          = halTdlsIndMsg.tdlsIndParams.status;

  wdiInd.wdiIndicationData.wdiTdlsIndInfo.staIdx
                          = halTdlsIndMsg.tdlsIndParams.staIdx;

  wdiInd.wdiIndicationData.wdiTdlsIndInfo.reasonCode
                          = halTdlsIndMsg.tdlsIndParams.reasonCode;

  wdiInd.wdiIndicationData.wdiTdlsIndInfo.assocId
                          = halTdlsIndMsg.tdlsIndParams.assocId;
  /*Notify UMAC*/
  pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessTdlsInd*/
#endif
/**
*@brief Process Noa Start Indication function (called when
        an indication of this kind is being received over the
        bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessP2pNoaStartInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_LowLevelIndType  wdiInd;
  tNoaStartIndMsg       halNoaStartIndMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
  Sanity check
 -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT( 0 );
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
  Extract indication and send it to UMAC
 -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halNoaStartIndMsg.noaStartIndParams,
                  pEventData->pEventData,
                  sizeof(halNoaStartIndMsg.noaStartIndParams) );

  /*Fill in the indication parameters*/
  wdiInd.wdiIndicationType = WDI_P2P_NOA_START_IND;

  wdiInd.wdiIndicationData.wdiP2pNoaStartInfo.status
                          = halNoaStartIndMsg.noaStartIndParams.status;

  wdiInd.wdiIndicationData.wdiP2pNoaStartInfo.bssIdx
                          = halNoaStartIndMsg.noaStartIndParams.bssIdx;

  /*Notify UMAC*/
  pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessNoaAttrInd*/

/**
*@brief Process Noa Attr Indication function (called when
        an indication of this kind is being received over the
        bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessP2pNoaAttrInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_LowLevelIndType  wdiInd;
  tNoaAttrIndMsg       halNoaAttrIndMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT( 0 );
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
    Extract indication and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halNoaAttrIndMsg.noaAttrIndParams,
                  pEventData->pEventData,
                  sizeof(halNoaAttrIndMsg.noaAttrIndParams) );

  /*Fill in the indication parameters*/
  wdiInd.wdiIndicationType = WDI_P2P_NOA_ATTR_IND;

  wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.status
                          = halNoaAttrIndMsg.noaAttrIndParams.status;

  wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.ucIndex
                          = halNoaAttrIndMsg.noaAttrIndParams.index;
  wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.ucOppPsFlag
                          = halNoaAttrIndMsg.noaAttrIndParams.oppPsFlag;
  wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.usCtWin
                          = halNoaAttrIndMsg.noaAttrIndParams.ctWin;

  wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.usNoa1IntervalCnt
                          = halNoaAttrIndMsg.noaAttrIndParams.uNoa1IntervalCnt;
  wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.uslNoa1Duration
                          = halNoaAttrIndMsg.noaAttrIndParams.uNoa1Duration;
  wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.uslNoa1Interval
                             = halNoaAttrIndMsg.noaAttrIndParams.uNoa1Interval;
  wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.uslNoa1StartTime
                          = halNoaAttrIndMsg.noaAttrIndParams.uNoa1StartTime;

  wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.usNoa2IntervalCnt
                          = halNoaAttrIndMsg.noaAttrIndParams.uNoa2IntervalCnt;
  wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.uslNoa2Duration
                          = halNoaAttrIndMsg.noaAttrIndParams.uNoa2Duration;
  wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.uslNoa2Interval
                          = halNoaAttrIndMsg.noaAttrIndParams.uNoa2Interval;
  wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.uslNoa2StartTime
                          = halNoaAttrIndMsg.noaAttrIndParams.uNoa2StartTime;

  if ( pWDICtx->wdiLowLevelIndCB )
  {
    /*Notify UMAC*/
    pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
  }

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessNoaAttrInd*/

/**
 @brief Process Tx PER Hit Indication function (called when
        an indication of this kind is being received over the
        bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessTxPerHitInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_LowLevelIndType  wdiInd;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Extract indication and send it to UMAC
  -------------------------------------------------------------------------*/
  /*Fill in the indication parameters*/
  wdiInd.wdiIndicationType = WDI_TX_PER_HIT_IND;

  if ( pWDICtx->wdiLowLevelIndCB )
  {
    /*Notify UMAC*/
    pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
  }

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessTxPerHitInd*/

/**
 @brief Process Periodic Tx Pattern Fw Indication function

 @param pWDICtx:         pointer to the WLAN DAL context
        pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessPeriodicTxPtrnFwInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_LowLevelIndType  wdiInd;

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if ((NULL == pWDICtx) || (NULL == pEventData) ||
      (NULL == pEventData->pEventData))
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
    Extract indication and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy(&(wdiInd.wdiIndicationData.wdiPeriodicTxPtrnFwInd),
                 (tHalPeriodicTxPtrnFwInd *)pEventData->pEventData,
                 sizeof(tHalPeriodicTxPtrnFwInd));

  if (pWDICtx->wdiLowLevelIndCB)
  {
    /*Notify UMAC*/
    pWDICtx->wdiLowLevelIndCB(&wdiInd, pWDICtx->pIndUserData);
  }

  return WDI_STATUS_SUCCESS;
}

/**
 @brief WDI_ProcessFTMCommandReq
        Process FTM Command, simply route to HAL

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessFTMCommandReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_FTMCommandReqType  *ftmCommandReq = NULL;
  wpt_uint8              *ftmCommandBuffer = NULL;
  wpt_uint16              dataOffset;
  wpt_uint16              bufferSize;
  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))

  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  ftmCommandReq = (WDI_FTMCommandReqType *)pEventData->pEventData;

  /* Get MSG Buffer */
  WDI_GetMessageBuffer(pWDICtx,
                       WDI_FTM_CMD_REQ,
                       ftmCommandReq->bodyLength,
                       &ftmCommandBuffer,
                       &dataOffset,
                       &bufferSize);

  wpalMemoryCopy(ftmCommandBuffer + dataOffset,
                 ftmCommandReq->FTMCommandBody,
                 ftmCommandReq->bodyLength);

  /* Send MSG */
  return WDI_SendMsg(pWDICtx,
                     ftmCommandBuffer,
                     bufferSize,
                     pEventData->pCBfnc,
                     pEventData->pUserData,
                     WDI_FTM_CMD_RESP);
}

/**
 @brief WDI_ProcessFTMCommandRsp
        Process FTM Command Response from HAL, simply route to HDD FTM

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessFTMCommandRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_FTMCommandRspCb   ftmCMDRspCb;
  tProcessPttRspParams *ftmCMDRspData = NULL;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  ftmCMDRspCb = (WDI_FTMCommandRspCb)pWDICtx->pfncRspCB;

  ftmCMDRspData = (tProcessPttRspParams *)pEventData->pEventData;

  wpalMemoryCopy((void *)pWDICtx->ucFTMCommandRspBuffer,
                 (void *)&ftmCMDRspData->pttMsgBuffer,
                 ftmCMDRspData->pttMsgBuffer.msgBodyLength);

  /*Notify UMAC*/
  ftmCMDRspCb((void *)pWDICtx->ucFTMCommandRspBuffer, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}
/**
 @brief WDI_ProcessHalDumpCmdReq
        Process hal dump Command, simply route to HAL

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessHALDumpCmdReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_HALDumpCmdReqParamsType*  pwdiHALDumpCmdParams = NULL;
  WDI_HALDumpCmdRspCb           wdiHALDumpCmdRspCb = NULL;
  wpt_uint16               usDataOffset        = 0;
  wpt_uint16               usSendSize          = 0;
  tHalDumpCmdReqMsg        halDumpCmdReqMsg;
  wpt_uint8*               pSendBuffer         = NULL;

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiHALDumpCmdParams = (WDI_HALDumpCmdReqParamsType*)pEventData->pEventData;
  wdiHALDumpCmdRspCb   = (WDI_HALDumpCmdRspCb)pEventData->pCBfnc;

  /* Copying the HAL DUMP Command Information HAL Structure*/
  halDumpCmdReqMsg.dumpCmdReqParams.argument1 =
                pwdiHALDumpCmdParams->wdiHALDumpCmdInfoType.command;
  halDumpCmdReqMsg.dumpCmdReqParams.argument2 =
                pwdiHALDumpCmdParams->wdiHALDumpCmdInfoType.argument1;
  halDumpCmdReqMsg.dumpCmdReqParams.argument3 =
                pwdiHALDumpCmdParams->wdiHALDumpCmdInfoType.argument2;
  halDumpCmdReqMsg.dumpCmdReqParams.argument4 =
                pwdiHALDumpCmdParams->wdiHALDumpCmdInfoType.argument3;
  halDumpCmdReqMsg.dumpCmdReqParams.argument5 =
                pwdiHALDumpCmdParams->wdiHALDumpCmdInfoType.argument4;

  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_HAL_DUMP_CMD_REQ,
                        sizeof(halDumpCmdReqMsg.dumpCmdReqParams),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize <
            (usDataOffset + sizeof(halDumpCmdReqMsg.dumpCmdReqParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in HAL Dump Command req %p %p %p",
                pEventData, pwdiHALDumpCmdParams, wdiHALDumpCmdRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halDumpCmdReqMsg.dumpCmdReqParams,
                  sizeof(halDumpCmdReqMsg.dumpCmdReqParams));

  pWDICtx->wdiReqStatusCB     = pwdiHALDumpCmdParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiHALDumpCmdParams->pUserData;

  /*-------------------------------------------------------------------------
    Send Start Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiHALDumpCmdRspCb, pEventData->pUserData,
                        WDI_HAL_DUMP_CMD_RESP);
}

/**
 @brief WDI_ProcessHalDumpCmdRsp
        Process hal Dump Command Response from HAL, simply route to HDD

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessHALDumpCmdRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_HALDumpCmdRspCb     wdiHALDumpCmdRspCb;
  tHalDumpCmdRspParams   halDumpCmdRspParams;
  WDI_HALDumpCmdRspParamsType wdiHALDumpCmdRsp;

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiHALDumpCmdRspCb = (WDI_HALDumpCmdRspCb)pWDICtx->pfncRspCB;

  /*Initialize the WDI Response structure */
  wdiHALDumpCmdRsp.usBufferLen = 0;
  wdiHALDumpCmdRsp.pBuffer = NULL;

  wpalMemoryCopy( &halDumpCmdRspParams, 
                 pEventData->pEventData, 
                 sizeof(tHalDumpCmdRspParams));

  wdiHALDumpCmdRsp.wdiStatus   =
              WDI_HAL_2_WDI_STATUS(halDumpCmdRspParams.status);

  if (( wdiHALDumpCmdRsp.wdiStatus  ==  WDI_STATUS_SUCCESS) &&
      (halDumpCmdRspParams.rspLength != 0))
  {
      /* Copy the response data */
      wdiHALDumpCmdRsp.usBufferLen = halDumpCmdRspParams.rspLength;
      wdiHALDumpCmdRsp.pBuffer = wpalMemoryAllocate(halDumpCmdRspParams.rspLength);

      wpalMemoryCopy( wdiHALDumpCmdRsp.pBuffer,
                  &halDumpCmdRspParams.rspBuffer, 
                  halDumpCmdRspParams.rspLength);
  }

  /*Notify UMAC*/
  wdiHALDumpCmdRspCb(&wdiHALDumpCmdRsp, pWDICtx->pRspCBUserData);

  if(wdiHALDumpCmdRsp.pBuffer != NULL)
  {
    /* Free the allocated buffer */
    wpalMemoryFree(wdiHALDumpCmdRsp.pBuffer);
  }
  return WDI_STATUS_SUCCESS;
}

/*==========================================================================
                     CONTRL TRANSPORT INTERACTION

    Callback function registered with the control transport - for receiving
    notifications and packets
==========================================================================*/
/**
 @brief    This callback is invoked by the control transport
   when it wishes to send up a notification like the ones
   mentioned above.

 @param

    wctsHandle:       handle to the control transport service
    wctsEvent:        the event being notified
    wctsNotifyCBData: the callback data of the user

 @see  WCTS_OpenTransport

 @return None
*/
void
WDI_NotifyMsgCTSCB
(
  WCTS_HandleType        wctsHandle,
  WCTS_NotifyEventType   wctsEvent,
  void*                  wctsNotifyCBData
)
{
  WDI_ControlBlockType*  pWDICtx = (WDI_ControlBlockType*)wctsNotifyCBData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  if (NULL == pWDICtx )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);
    WDI_ASSERT(0);
    return;
  }

  if (WDI_CONTROL_BLOCK_MAGIC != pWDICtx->magic)
  {
    /* callback presumably occurred after close */
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid control block", __func__);
    return;
  }

  if ( WCTS_EVENT_OPEN == wctsEvent )
  {
    /*Flag must be set atomically as it is checked from incoming request
      functions*/
    wpalMutexAcquire(&pWDICtx->wptMutex);
    pWDICtx->bCTOpened   = eWLAN_PAL_TRUE;

    /*Nothing to do - so try to dequeue any pending request that may have
     occurred while we were trying to establish this*/
    WDI_DequeuePendingReq(pWDICtx);
    wpalMutexRelease(&pWDICtx->wptMutex);
  }
  else if  ( WCTS_EVENT_CLOSE == wctsEvent )
  {
    /*Flag must be set atomically as it is checked from incoming request
      functions*/
    wpalMutexAcquire(&pWDICtx->wptMutex);
    pWDICtx->bCTOpened   = eWLAN_PAL_FALSE;

    /*No other request will be processed from now on - fail all*/
    WDI_ClearPendingRequests(pWDICtx);
    wpalMutexRelease(&pWDICtx->wptMutex);

    /*Notify that the Control Channel is closed */
    wpalEventSet(&pWDICtx->wctsActionEvent);
  }

}/*WDI_NotifyMsgCTSCB*/


/**
 @brief    This callback is invoked by the control transport
           when it wishes to send up a packet received over the
           bus.

 @param

    wctsHandle:  handle to the control transport service
    pMsg:        the packet
    uLen:        the packet length
    wctsRxMsgCBData: the callback data of the user

 @see  WCTS_OpenTransport

 @return None
*/
void
WDI_RXMsgCTSCB
(
  WCTS_HandleType       wctsHandle,
  void*                 pMsg,
  wpt_uint32            uLen,
  void*                 wctsRxMsgCBData
)
{
  tHalMsgHeader          *pHalMsgHeader;
  WDI_EventInfoType      wdiEventData;
  WDI_ControlBlockType*  pWDICtx = (WDI_ControlBlockType*)wctsRxMsgCBData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /*------------------------------------------------------------------------
    Sanity check
  ------------------------------------------------------------------------*/
  if ((NULL == pWDICtx ) || ( NULL == pMsg ) ||
      ( uLen < sizeof(tHalMsgHeader)))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);
    WDI_ASSERT(0);
    return;
  }

  if (WDI_CONTROL_BLOCK_MAGIC != pWDICtx->magic)
  {
    /* callback presumably occurred after close */
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid control block", __func__);
    return;
  }

  /*The RX Callback is expected to be serialized in the proper control thread
    context - so no serialization is necessary here
    ! - revisit this assumption */

  pHalMsgHeader = (tHalMsgHeader *)pMsg;

  if ( uLen != pHalMsgHeader->msgLen )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Invalid packet received from HAL - catastrophic failure");
    WDI_DetectedDeviceError( pWDICtx, WDI_ERR_INVALID_RSP_FMT);
    wpalWlanReload();

    return;
  }

  wdiEventData.wdiResponse = HAL_2_WDI_RSP_TYPE( pHalMsgHeader->msgType );

  /*The message itself starts after the header*/
  wdiEventData.pEventData     = (wpt_uint8*)pMsg + sizeof(tHalMsgHeader);
  wdiEventData.uEventDataSize = pHalMsgHeader->msgLen - sizeof(tHalMsgHeader);
  wdiEventData.pCBfnc         = gWDICb.pfncRspCB;
  wdiEventData.pUserData      = gWDICb.pRspCBUserData;


  if ( wdiEventData.wdiResponse ==  pWDICtx->wdiExpectedResponse )
  {
    /*Stop the timer as the response was received */
    /*!UT - check for potential race conditions between stop and response */
    wpalTimerStop(&pWDICtx->wptResponseTimer);
  }
  /* Check if we receive a response message which is not expected */
  else if ( wdiEventData.wdiResponse < WDI_HAL_IND_MIN )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
               "Received response %s (%d) when expecting %s (%d) - catastrophic failure",
               WDI_getRespMsgString(wdiEventData.wdiResponse),
               wdiEventData.wdiResponse,
               WDI_getRespMsgString(pWDICtx->wdiExpectedResponse),
               pWDICtx->wdiExpectedResponse);

    if (gWDICb.bEnableSSR == false)
    {
       WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
            "SSR is not enabled on WDI timeout");
       WDI_DetectedDeviceError(pWDICtx, WDI_ERR_BASIC_OP_FAILURE);
       return;
    }
    wpalWcnssResetIntr();
    /* if this timer fires, it means Riva did not receive the FIQ */
    wpalTimerStart(&pWDICtx->ssrTimer, WDI_SSR_TIMEOUT);

    return;
  }

  WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_INFO,
           "Rx smth from HAL: %d", wdiEventData.wdiResponse);

  /*Post response event to the state machine*/
  WDI_PostMainEvent(pWDICtx, WDI_RESPONSE_EVENT, &wdiEventData);

}/*WDI_RXMsgCTSCB*/


/*========================================================================
         Internal Helper Routines
========================================================================*/

/**
 @brief WDI_CleanCB - internal helper routine used to clean the
        WDI Main Control Block

 @param pWDICtx - pointer to the control block

 @return Result of the function call
*/
WPT_INLINE WDI_Status
WDI_CleanCB
(
  WDI_ControlBlockType*  pWDICtx
)
{
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /*Clean the WDI Control Block*/
  wpalMemoryZero( pWDICtx, sizeof(*pWDICtx));

  pWDICtx->uGlobalState  = WDI_MAX_ST;
  pWDICtx->ucMaxBssids   = WDI_MAX_SUPPORTED_BSS;
  pWDICtx->ucMaxStations = WDI_MAX_SUPPORTED_STAS;

  WDI_ResetAssocSessions( pWDICtx );

  return WDI_STATUS_SUCCESS;
}/*WDI_CleanCB*/


/**
 @brief Process request helper function


 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WPT_INLINE WDI_Status
WDI_ProcessRequest
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*!! Skip sanity check as this is called from the FSM functionss which
    already checked these pointers*/

  if (( pEventData->wdiRequest < WDI_MAX_UMAC_IND ) &&
      ( NULL != pfnReqProcTbl[pEventData->wdiRequest] ))
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
              "Calling request processing function for req %s (%d) %p",
              WDI_getReqMsgString(pEventData->wdiRequest),
              pEventData->wdiRequest, pfnReqProcTbl[pEventData->wdiRequest]);
    return pfnReqProcTbl[pEventData->wdiRequest](pWDICtx, pEventData);
  }
  else
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Operation %d is not yet implemented ",
               pEventData->wdiRequest);
    return WDI_STATUS_E_NOT_IMPLEMENT;
  }
}/*WDI_ProcessRequest*/


/**
 @brief Get message helper function - it allocates memory for a
        message that is to be sent to HAL accross the bus and
        prefixes it with a send message header

 @param  pWDICtx:         pointer to the WLAN DAL context
         wdiReqType:      type of the request being sent
         uBufferLen:      message buffer len
         pMsgBuffer:      resulting allocated buffer
         pusDataOffset:    offset in the buffer where the caller
         can start copying its message data
         puBufferSize:    the resulting buffer size (offset+buff
         len)

 @see
 @return Result of the function call
*/
WDI_Status
WDI_GetMessageBuffer
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_RequestEnumType    wdiReqType,
  wpt_uint16             usBufferLen,
  wpt_uint8**            pMsgBuffer,
  wpt_uint16*            pusDataOffset,
  wpt_uint16*            pusBufferSize
)
{
  tHalMsgHeader  halMsgHeader;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*!! No sanity check here as we trust the called - ! check this assumption
    again*/

  /*-------------------------------------------------------------------------
     Try to allocate message buffer from PAL
  -------------------------------------------------------------------------*/
  *pusBufferSize = sizeof(halMsgHeader) + usBufferLen;
  *pMsgBuffer   = (wpt_uint8*)wpalMemoryAllocate(*pusBufferSize);
  if ( NULL ==  *pMsgBuffer )
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "Unable to allocate message buffer for req %s (%d)",
               WDI_getReqMsgString(wdiReqType),
               wdiReqType);
     WDI_ASSERT(0);
     return WDI_STATUS_MEM_FAILURE;
  }

  /*-------------------------------------------------------------------------
     Fill in the message header
  -------------------------------------------------------------------------*/
  halMsgHeader.msgType = WDI_2_HAL_REQ_TYPE(wdiReqType);
  /* Fill msgVersion */
#ifdef WLAN_FEATURE_11AC
  if (WDI_getFwWlanFeatCaps(DOT11AC))
     halMsgHeader.msgVersion = WLAN_HAL_MSG_VERSION1; 
  else
#endif
     halMsgHeader.msgVersion = WLAN_HAL_MSG_VERSION0;

  halMsgHeader.msgLen  = sizeof(halMsgHeader) + usBufferLen;
  *pusDataOffset       = sizeof(halMsgHeader);
  wpalMemoryCopy(*pMsgBuffer, &halMsgHeader, sizeof(halMsgHeader));

  return WDI_STATUS_SUCCESS;
}/*WDI_GetMessageBuffer*/


/**
 @brief Send message helper function - sends a message over the
        bus using the control tranport and saves some info in
        the CB

 @param  pWDICtx:         pointer to the WLAN DAL context
         pSendBuffer:     buffer to be sent

         usSendSize          size of the buffer to be sent
         pRspCb:            response callback - save in the WDI
         CB
         pUserData:         user data associated with the
         callback
         wdiExpectedResponse: the code of the response that is
         expected to be rx-ed for this request

 @see
 @return Result of the function call
*/
WDI_Status
WDI_SendMsg
(
  WDI_ControlBlockType*  pWDICtx,
  wpt_uint8*             pSendBuffer,
  wpt_uint32             usSendSize,
  void*                  pRspCb,
  void*                  pUserData,
  WDI_ResponseEnumType   wdiExpectedResponse
)
{
  WDI_Status wdiStatus = WDI_STATUS_SUCCESS;
  wpt_uint32 ret;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /*------------------------------------------------------------------------
    Save needed info in the CB
  ------------------------------------------------------------------------*/
  pWDICtx->pRspCBUserData      = pUserData;
  pWDICtx->pfncRspCB           = pRspCb;
  pWDICtx->wdiExpectedResponse = wdiExpectedResponse;

   /*-----------------------------------------------------------------------
     Call the CTS to send this message over - free message afterwards
     - notify transport failure
     Note: CTS is reponsible for freeing the message buffer.
   -----------------------------------------------------------------------*/
   ret = WCTS_SendMessage(pWDICtx->wctsHandle, (void*)pSendBuffer, usSendSize);
   if ((eWLAN_PAL_STATUS_SUCCESS != ret) &&
       (eWLAN_PAL_STATUS_E_RESOURCES != ret))
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                "Failed to send message with expected response %s (%d)"
                " over the bus - catastrophic failure",
                WDI_getRespMsgString(pWDICtx->wdiExpectedResponse),
                pWDICtx->wdiExpectedResponse);

     wdiStatus = (ret == eWLAN_PAL_STATUS_E_FAILURE) ?
                  WDI_STATUS_DEV_INTERNAL_FAILURE : WDI_STATUS_E_FAILURE;
   }
   else
   {
     /* even when message was placed in CTS deferred Q, we will treat it
        success but log this info
      */
     if (eWLAN_PAL_STATUS_E_RESOURCES == ret)
     {
       WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                  "WDI_SendMsg: message placed in CTS deferred Q, expected "
                  "response %s (%d)",
                  WDI_getRespMsgString(pWDICtx->wdiExpectedResponse),
                  pWDICtx->wdiExpectedResponse);
       WDI_ASSERT(0);
     }
   }

  /*Check if originator provided a request status callback*/
   if ( NULL != pWDICtx->wdiReqStatusCB )
   {
     /*Inform originator whether request went through or not*/
     WDI_ReqStatusCb callback = pWDICtx->wdiReqStatusCB; 
     void *callbackContext = pWDICtx->pReqStatusUserData; 
     pWDICtx->wdiReqStatusCB = NULL;
     pWDICtx->pReqStatusUserData = NULL;
     callback(wdiStatus, callbackContext);
     
     /*For WDI requests which have registered a request callback,
     inform the WDA caller of the same via setting the return value
     (wdiStatus) to WDI_STATUS_PENDING. This makes sure that WDA doesnt
     end up repeating the functonality in the req callback  for the
     WDI_STATUS_E_FAILURE case*/
     if (wdiStatus != WDI_STATUS_SUCCESS)
     {
       wdiStatus = WDI_STATUS_PENDING;
     }
   }

  if ( wdiStatus == WDI_STATUS_SUCCESS )
  {
   /*Start timer for the expected response */
   wpalTimerStart(&pWDICtx->wptResponseTimer, WDI_RESPONSE_TIMEOUT);

   /*cache current timestamp for debugging */
   pWDICtx->uTimeStampRspTmrStart = wpalGetSystemTime();
   pWDICtx->uArchTimeStampRspTmrStart = wpalGetArchCounterTime();
  }
  else
  {
     /*Inform upper stack layers that a transport fatal error occurred*/
     WDI_DetectedDeviceError(pWDICtx, WDI_ERR_TRANSPORT_FAILURE);
  }

  return wdiStatus;

}/*WDI_SendMsg*/



/**
 @brief Send indication helper function - sends a message over
        the bus using the control transport and saves some info
        in the CB

 @param  pWDICtx:         pointer to the WLAN DAL context
         pSendBuffer:     buffer to be sent
         usSendSize: size of the buffer to be sent

 @see
 @return Result of the function call
*/
WDI_Status
WDI_SendIndication
(
  WDI_ControlBlockType*  pWDICtx,
  wpt_uint8*             pSendBuffer,
  wpt_uint32             usSendSize
)
{
   wpt_uint32 uStatus ;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

   /*-----------------------------------------------------------------------
     Call the CTS to send this message over
     Note: CTS is reponsible for freeing the message buffer.
   -----------------------------------------------------------------------*/
   uStatus = WCTS_SendMessage( pWDICtx->wctsHandle,
                               (void*)pSendBuffer, usSendSize );

   /*Inform Upper MAC about the outcome of the request*/
   if ( NULL != pWDICtx->wdiReqStatusCB )
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
                "Send indication status : %d", uStatus);

      /* even if CTS placed indication into its deferred Q, we treat it
       * as success and let CTS drain its queue as per smd interrupt to CTS
       */
      pWDICtx->wdiReqStatusCB( ((uStatus != eWLAN_PAL_STATUS_SUCCESS) && (uStatus != eWLAN_PAL_STATUS_E_RESOURCES)) ? WDI_STATUS_E_FAILURE: WDI_STATUS_SUCCESS,
                               pWDICtx->pReqStatusUserData);
   }

   /*If sending of the message failed - it is considered catastrophic and
     indicates an error with the device*/
   if (( eWLAN_PAL_STATUS_SUCCESS != uStatus) &&
       ( eWLAN_PAL_STATUS_E_RESOURCES != uStatus))

   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                "Failed to send indication over the bus - catastrophic failure");

      WDI_DetectedDeviceError( pWDICtx, WDI_ERR_TRANSPORT_FAILURE);
      return WDI_STATUS_E_FAILURE;
   }

   return WDI_STATUS_SUCCESS;
}/*WDI_SendIndication*/


/**
 @brief WDI_DetectedDeviceError - called internally by DAL when
        it has detected a failure in the device

 @param  pWDICtx:        pointer to the WLAN DAL context
         usErrorCode:    error code detected by WDI or received
                         from HAL

 @see
 @return None
*/
void
WDI_DetectedDeviceError
(
  WDI_ControlBlockType*  pWDICtx,
  wpt_uint16             usErrorCode
)
{
  WDI_LowLevelIndType  wdiInd;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
            "Device Error detected code: %d - transitioning to stopped state",
            usErrorCode);

  pWDICtx->DeviceErrorReason = VOS_RETURN_ADDRESS;

  wpalMutexAcquire(&pWDICtx->wptMutex);

  WDI_STATableStop(pWDICtx);

  WDI_ResetAssocSessions(pWDICtx);

  /*Set the expected state transition to stopped - because the device
  experienced a failure*/
  pWDICtx->ucExpectedStateTransition =  WDI_STOPPED_ST;

  /*Transition to stopped to fail all incomming requests from this point on*/
  WDI_STATE_TRANSITION( pWDICtx, WDI_STOPPED_ST);

  WDI_ClearPendingRequests(pWDICtx);

  /*TO DO: -  there should be an attempt to reset the device here*/

  wpalMutexRelease(&pWDICtx->wptMutex);

  /*------------------------------------------------------------------------
    Notify UMAC if a handler is registered
  ------------------------------------------------------------------------*/
  if (pWDICtx->wdiLowLevelIndCB)
  {
     wdiInd.wdiIndicationType             = WDI_FATAL_ERROR_IND;
     wdiInd.wdiIndicationData.usErrorCode = usErrorCode;

     pWDICtx->wdiLowLevelIndCB( &wdiInd,  pWDICtx->pIndUserData);
  }
}/*WDI_DetectedDeviceError*/

/**
 @brief    This callback is invoked by the wpt when a timer that
           we started on send message has expire - this should
           never happen - it means device is stuck and cannot
           reply - trigger catastrophic failure
 @param

    pUserData: the callback data of the user (ptr to WDI CB)

 @see
 @return None
*/
void
WDI_ResponseTimerCB
(
  void *pUserData
)
{
  WDI_ControlBlockType*  pWDICtx = (WDI_ControlBlockType*)pUserData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  if (NULL == pWDICtx)
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);
    WDI_ASSERT(0);
    return;
  }

  /*cache current timestamp for debugging */
  pWDICtx->uTimeStampRspTmrExp = wpalGetSystemTime();
  pWDICtx->uArchTimeStampRspTmrExp = wpalGetArchCounterTime();

  /* If response timer is running at this time that means this timer
   * event is not for the last request but rather last-to-last request and
   * this timer event has come after we recevied respone for last-to-last
   * message
   */
  if (VOS_TIMER_STATE_RUNNING == wpalTimerGetCurStatus(&pWDICtx->wptResponseTimer))
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
               "WDI_ResponseTimerCB: timer in running state on timer event, "
               "ignore tmr event, timeStampTmrStart: %u, timeStampTmrExp: %u",
               pWDICtx->uTimeStampRspTmrStart, pWDICtx->uTimeStampRspTmrExp);
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
               "uArchTimeStampTmrStart: %llu seconds, "
               "uArchTimeStampTmrExp: %llu seconds",
               pWDICtx->uArchTimeStampRspTmrStart,
               pWDICtx->uArchTimeStampRspTmrExp);

    return;
  }

  if (WDI_MAX_RESP != pWDICtx->wdiExpectedResponse)
  {

    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
            "Timeout occurred while waiting for %s (%d) message from device "
            " - catastrophic failure, timeStampTmrStart: %u, timeStampTmrExp: %u",
            WDI_getRespMsgString(pWDICtx->wdiExpectedResponse),
            pWDICtx->wdiExpectedResponse, pWDICtx->uTimeStampRspTmrStart,
            pWDICtx->uTimeStampRspTmrExp);
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                "uArchTimeStampTmrStart: %llu seconds, "
                "uArchTimeStampTmrExp: %llu seconds",
                pWDICtx->uArchTimeStampRspTmrStart,
                pWDICtx->uArchTimeStampRspTmrExp);

    /* WDI timeout means Riva is not responding or SMD communication to Riva
     * is not happening. The only possible way to recover from this error
     * is to initiate SSR from APPS.
     * There is also an option to re-enable wifi, which will eventually
     * trigger SSR
     */
    if (gWDICb.bEnableSSR == false)
    {
       WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
            "SSR is not enabled on WDI timeout");
       WDI_DetectedDeviceError(pWDICtx, WDI_ERR_BASIC_OP_FAILURE);
       return;
    }
#ifndef WDI_RE_ENABLE_WIFI_ON_WDI_TIMEOUT
    wpalWcnssResetIntr();
    if(wpalIslogPInProgress())
    {
      if(wpalIsSsrPanicOnFailure())
          wpalDevicePanic();
    } else {
       /* if this timer fires, it means Riva did not receive the FIQ */
       wpalTimerStart(&pWDICtx->ssrTimer, WDI_SSR_TIMEOUT);
    }
#else
    WDI_DetectedDeviceError(pWDICtx, WDI_ERR_BASIC_OP_FAILURE);
    wpalWlanReload();
#endif
  }
  else
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "Timeout occurred but not waiting for any response %d "
                 "timeStampTmrStart: %u, timeStampTmrExp: %u",
                 pWDICtx->wdiExpectedResponse, pWDICtx->uTimeStampRspTmrStart,
                 pWDICtx->uTimeStampRspTmrExp);
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                "uArchTimeStampTmrStart: %llu seconds, "
                "uArchTimeStampTmrExp: %llu seconds",
                pWDICtx->uArchTimeStampRspTmrStart,
                pWDICtx->uArchTimeStampRspTmrExp);

  }

  return; 

}/*WDI_ResponseTimerCB*/


/**
 @brief Process response helper function


 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WPT_INLINE WDI_Status
WDI_ProcessResponse
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /* Skip sanity check as this is called from the FSM functions which
    already checked these pointers
    ! - revisit this assumption */
  if (( pEventData->wdiResponse < WDI_MAX_RESP ) &&
      ( NULL != pfnRspProcTbl[pEventData->wdiResponse] ))
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
              "Calling response processing function for resp %s (%d) %p",
              WDI_getRespMsgString(pEventData->wdiResponse),
              pEventData->wdiResponse, pfnRspProcTbl[pEventData->wdiResponse]);
    return pfnRspProcTbl[pEventData->wdiResponse](pWDICtx, pEventData);
  }
  else
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Operation %d is not yet implemented ",
              pEventData->wdiResponse);
    return WDI_STATUS_E_NOT_IMPLEMENT;
  }
}/*WDI_ProcessResponse*/


/*=========================================================================
                   QUEUE SUPPORT UTILITY FUNCTIONS
=========================================================================*/

/**
 @brief    Utility function used by the DAL Core to help queue a
           request that cannot be processed right away.
 @param

    pWDICtx: - pointer to the WDI control block
    pEventData: - pointer to the evnt info that needs to be
    queued

 @see
 @return Result of the operation
*/
WDI_Status
WDI_QueuePendingReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  wpt_list_node*      pNode;
  WDI_EventInfoType*  pEventDataQueue = wpalMemoryAllocate(sizeof(*pEventData));
  void*               pEventInfo = NULL;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  if ( NULL ==  pEventDataQueue )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Cannot allocate memory for queueing");
    WDI_ASSERT(0);
    return WDI_STATUS_MEM_FAILURE;
  }

  pEventDataQueue->pCBfnc          = pEventData->pCBfnc;
  pEventDataQueue->pUserData       = pEventData->pUserData;
  pEventDataQueue->uEventDataSize  = pEventData->uEventDataSize;
  pEventDataQueue->wdiRequest      = pEventData->wdiRequest;
  pEventDataQueue->wdiResponse     = pEventData->wdiResponse;

  if( pEventData->uEventDataSize != 0 && pEventData->pEventData != NULL )
  {
     pEventInfo = wpalMemoryAllocate(pEventData->uEventDataSize);

     if ( NULL ==  pEventInfo )
     {
       WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "Cannot allocate memory for queueing event data info");
       WDI_ASSERT(0);
       wpalMemoryFree(pEventDataQueue);
       return WDI_STATUS_MEM_FAILURE;
     }

     wpalMemoryCopy(pEventInfo, pEventData->pEventData, pEventData->uEventDataSize);

  }
  pEventDataQueue->pEventData = pEventInfo;

  /*Send wpt a pointer to the node (this is the 1st element in the event data)*/
  pNode = (wpt_list_node*)pEventDataQueue;

  if (eWLAN_PAL_STATUS_E_FAILURE ==
            wpal_list_insert_back(&(pWDICtx->wptPendingQueue), pNode))
  {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                "pEventDataQueue wpal_list_insert_back failed");
      WDI_ASSERT(0);
      wpalMemoryFree(pEventDataQueue);
      wpalMemoryFree(pEventInfo);
      return WDI_STATUS_MEM_FAILURE;
  }

  return WDI_STATUS_SUCCESS;
}/*WDI_QueuePendingReq*/

/**
 @brief    Callback function for serializing queued message
           processing in the control context
 @param

    pMsg - pointer to the message

 @see
 @return Result of the operation
*/
void
WDI_PALCtrlMsgCB
(
 wpt_msg *pMsg
)
{
  WDI_EventInfoType*     pEventData = NULL;
  WDI_ControlBlockType*  pWDICtx    = NULL;
  WDI_Status             wdiStatus;
  WDI_ReqStatusCb        pfnReqStatusCB;
  void*                  pUserData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  if (( NULL == pMsg )||
      ( NULL == (pEventData = (WDI_EventInfoType*)pMsg->ptr)) ||
      ( NULL == (pWDICtx  = (WDI_ControlBlockType*)pMsg->pContext )))
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "Invalid message received on serialize ctrl context API");
    WDI_ASSERT(0);
    return;
  }

  /*Access to the global state must be locked */
  wpalMutexAcquire(&pWDICtx->wptMutex);

  /*Transition back to the state that we had before serialization
  - serialization transitions us to BUSY to stop any incomming requests
  */
  WDI_STATE_TRANSITION( pWDICtx, pMsg->val);
  wpalMutexRelease(&pWDICtx->wptMutex);

  /*-----------------------------------------------------------------------
     Check to see what type of event we are serializing
     - responses are never expected to come through here
  -----------------------------------------------------------------------*/
  switch ( pEventData->wdiRequest )
  {

  case WDI_STOP_REQ:      
      wdiStatus = WDI_PostMainEvent(&gWDICb, WDI_STOP_EVENT, pEventData);
      break;

  case WDI_NV_DOWNLOAD_REQ:
      // When WDI State is WDI_STARTED_ST, send WDI request message with event type WDI_REQUEST_EVENT.
      // In this case, because this request is called from response process, we could call WDI_ProcessRequest() directly.
      if (pWDICtx->uGlobalState == WDI_STARTED_ST)  
      {
        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
                 "%s: WDI_NV_DOWNLOAD_REQ called in WDI_STARTED_ST - send with WDI_REQUEST_EVENT", __func__);
        wdiStatus = WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, pEventData);
      }
      else
      {
        wdiStatus = WDI_PostMainEvent(&gWDICb, WDI_START_EVENT, pEventData);
      }
      
      break;

  default: 
    wdiStatus = WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, pEventData);
    break;
  }/*switch ( pEventData->wdiRequest )*/

  if (!(WDI_STATUS_SUCCESS == wdiStatus || WDI_STATUS_PENDING == wdiStatus
     || WDI_STATUS_SUCCESS_SYNC == wdiStatus))
  {
    WDI_ExtractRequestCBFromEvent(pEventData, &pfnReqStatusCB, &pUserData);

    if ( NULL != pfnReqStatusCB )
    {
      /*Fail the request*/
      pfnReqStatusCB( wdiStatus, pUserData);
    }
  }

  /* Free data - that was allocated when queueing*/
  if( pEventData != NULL )
  {
     if( pEventData->pEventData != NULL )
     {
        wpalMemoryFree(pEventData->pEventData);
     }
     wpalMemoryFree(pEventData);
  }

  if( pMsg != NULL )
  {
     wpalMemoryFree(pMsg);
  }

}/*WDI_PALCtrlMsgCB*/

/**
 @brief    Utility function used by the DAL Core to help dequeue
           and schedule for execution a pending request
 @param

    pWDICtx: - pointer to the WDI control block
    pEventData: - pointer to the evnt info that needs to be
    queued

 @see
 @return Result of the operation
*/
WDI_Status
WDI_DequeuePendingReq
(
  WDI_ControlBlockType*  pWDICtx
)
{
  wpt_list_node*      pNode      = NULL;
  WDI_EventInfoType*  pEventData;
  wpt_msg*            palMsg;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  wpal_list_remove_front(&(pWDICtx->wptPendingQueue), &pNode);

  if ( NULL ==  pNode )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "List is empty - return");
    return WDI_STATUS_SUCCESS;
  }

  /*The node actually points to the 1st element inside the Event Data struct -
    just cast it back to the struct*/
  pEventData = (WDI_EventInfoType*)pNode;

  /*Serialize processing in the control thread
     !TO DO: - check to see if these are all the messages params that need
     to be filled in*/
  palMsg = wpalMemoryAllocate(sizeof(wpt_msg));

  if ( NULL ==  palMsg )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI_DequeuePendingReq: Cannot allocate memory for palMsg.");
    WDI_ASSERT(0);
    return WDI_STATUS_MEM_FAILURE;
  }
  palMsg->pContext = pWDICtx;
  palMsg->callback = WDI_PALCtrlMsgCB;
  palMsg->ptr      = pEventData;

  /*Save the global state as we need it on the other side*/
  palMsg->val      = pWDICtx->uGlobalState;
  palMsg->type     = 0;

  /*Transition back to BUSY as we need to handle a queued request*/
  WDI_STATE_TRANSITION( pWDICtx, WDI_BUSY_ST);

  wpalPostCtrlMsg(pWDICtx->pPALContext, palMsg);

  return WDI_STATUS_PENDING;
}/*WDI_DequeuePendingReq*/


/**
 @brief    Utility function used by the DAL Core to help queue
           an association request that cannot be processed right
           away.- The assoc requests will be queued by BSSID
 @param

    pWDICtx: - pointer to the WDI control block
    pEventData: pointer to the evnt info that needs to be queued
    macBSSID: bssid

 @see
 @return Result of the operation
*/
WDI_Status
WDI_QueueNewAssocRequest
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData,
  wpt_macAddr            macBSSID
)
{
  wpt_uint8 i;
  WDI_BSSSessionType*     pSession = NULL;
  wpt_list_node*          pNode;
  WDI_EventInfoType*      pEventDataQueue;
  void*                   pEventInfo;
  WDI_NextSessionIdType*  pSessionIdElement;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */


  /*------------------------------------------------------------------------
      Search for a session that matches the BSSID
    ------------------------------------------------------------------------*/
  for ( i = 0; i < WDI_MAX_BSS_SESSIONS; i++ )
  {
     if ( eWLAN_PAL_FALSE == pWDICtx->aBSSSessions[i].bInUse )
     {
       /*Found an empty session*/
       pSession = &pWDICtx->aBSSSessions[i];
       break;
     }
  }

  if ( i >=  WDI_MAX_BSS_SESSIONS )
  {
    /*Cannot find any empty sessions*/
    return WDI_STATUS_E_FAILURE;
  }

  /*------------------------------------------------------------------------
    Fill in the BSSID for this session and set the usage flag
  ------------------------------------------------------------------------*/
  wpalMemoryCopy(pWDICtx->aBSSSessions[i].macBSSID, macBSSID, WDI_MAC_ADDR_LEN);
  pWDICtx->aBSSSessions[i].bInUse = eWLAN_PAL_TRUE;

  /*------------------------------------------------------------------------
    Allocate memory for this and place it in the queue
  ------------------------------------------------------------------------*/
  pEventDataQueue = (WDI_EventInfoType*)wpalMemoryAllocate(sizeof(WDI_EventInfoType));
  if ( NULL == pEventDataQueue )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "%s: Cannot allocate memory for queue node", __func__);
    WDI_ASSERT(0);
    return WDI_STATUS_MEM_FAILURE;
  }

  pSessionIdElement = (WDI_NextSessionIdType*)wpalMemoryAllocate(sizeof(WDI_NextSessionIdType));
  if ( NULL == pSessionIdElement )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "%s: Cannot allocate memory for session ID", __func__);
    WDI_ASSERT(0);
    wpalMemoryFree(pEventDataQueue);
    return WDI_STATUS_MEM_FAILURE;
  }

  pEventInfo = wpalMemoryAllocate(pEventData->uEventDataSize);
  if ( NULL == pEventInfo )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "%s: Cannot allocate memory for event data info", __func__);
    WDI_ASSERT(0);
    wpalMemoryFree(pSessionIdElement);
    wpalMemoryFree(pEventDataQueue);
    return WDI_STATUS_MEM_FAILURE;
  }

  pEventDataQueue->pCBfnc          = pEventData->pCBfnc;
  pEventDataQueue->pUserData       = pEventData->pUserData;
  pEventDataQueue->uEventDataSize  = pEventData->uEventDataSize;
  pEventDataQueue->wdiRequest      = pEventData->wdiRequest;
  pEventDataQueue->wdiResponse     = pEventData->wdiResponse;

  wpalMemoryCopy(pEventInfo, pEventData->pEventData, pEventData->uEventDataSize);
  pEventDataQueue->pEventData = pEventInfo;

  /*Send wpt a pointer to the node (this is the 1st element in the event data)*/
  pNode = (wpt_list_node*)pEventDataQueue;

  /*This association is currently being queued*/
  pSession->bAssocReqQueued = eWLAN_PAL_TRUE;

  if (eWLAN_PAL_STATUS_E_FAILURE ==
            wpal_list_insert_back(&(pSession->wptPendingQueue), pNode))
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
           "%s: pEventDataQueue wpal_list_insert_back failed", __func__);
    WDI_ASSERT(0);
    wpalMemoryFree(pSessionIdElement);
    wpalMemoryFree(pEventDataQueue);
    wpalMemoryFree(pEventInfo);
    return WDI_STATUS_MEM_FAILURE;
  }

  /*We need to maintain a separate list that keeps track of the order in which
  the new assoc requests are being queued such that we can start processing
  them in the order that they had arrived*/
  pSessionIdElement->ucIndex = i;
  pNode = (wpt_list_node*)pSessionIdElement;

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
       "Queueing up new assoc session : %d ", pSessionIdElement->ucIndex);
  if (eWLAN_PAL_STATUS_E_FAILURE ==
         wpal_list_insert_back(&pWDICtx->wptPendingAssocSessionIdQueue, pNode))
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
           "%s: pSessionIdElement wpal_list_insert_back failed", __func__);
    WDI_ASSERT(0);
    wpalMemoryFree(pSessionIdElement);
    wpalMemoryFree(pEventDataQueue);
    wpalMemoryFree(pEventInfo);
    return WDI_STATUS_MEM_FAILURE;
  }

  /*Return pending as this is what the status of the request is since it has
    been queued*/
  return WDI_STATUS_PENDING;
}/*WDI_QueueNewAssocRequest*/

/**
 @brief    Utility function used by the DAL Core to help queue
           an association request that cannot be processed right
           away.- The assoc requests will be queued by BSSID
 @param

    pWDICtx: - pointer to the WDI control block
    pSession: - session in which to queue
    pEventData: pointer to the event info that needs to be
    queued

 @see
 @return Result of the operation
*/
WDI_Status
WDI_QueueAssocRequest
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_BSSSessionType*    pSession,
  WDI_EventInfoType*     pEventData
)
{
  wpt_list_node*      pNode;
  WDI_EventInfoType*  pEventDataQueue;
  void*               pEventInfo;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
      Sanity check
    ------------------------------------------------------------------------*/
  if (( NULL == pSession ) || ( NULL == pWDICtx ))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);

    return WDI_STATUS_E_FAILURE;
  }

  /*------------------------------------------------------------------------
    Allocate memory for this and place it in the queue
  ------------------------------------------------------------------------*/
  pEventDataQueue = (WDI_EventInfoType*)wpalMemoryAllocate(sizeof(WDI_EventInfoType));
  if ( NULL ==  pEventDataQueue )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "%s: Cannot allocate memory for queueing", __func__);
    WDI_ASSERT(0);
    return WDI_STATUS_MEM_FAILURE;
  }

  pEventInfo = wpalMemoryAllocate(pEventData->uEventDataSize);
  if ( NULL ==  pEventInfo )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "%s: Cannot allocate memory for queueing event data info",
               __func__);
    WDI_ASSERT(0);
    wpalMemoryFree(pEventDataQueue);
    return WDI_STATUS_MEM_FAILURE;
  }

  pEventDataQueue->pCBfnc          = pEventData->pCBfnc;
  pEventDataQueue->pUserData       = pEventData->pUserData;
  pEventDataQueue->uEventDataSize  = pEventData->uEventDataSize;
  pEventDataQueue->wdiRequest      = pEventData->wdiRequest;
  pEventDataQueue->wdiResponse     = pEventData->wdiResponse;
  pEventDataQueue->pEventData      = pEventInfo;

  wpalMemoryCopy(pEventInfo, pEventData->pEventData, pEventData->uEventDataSize);

  /*Send wpt a pointer to the node (this is the 1st element in the event data)*/
  pNode = (wpt_list_node*)pEventDataQueue;

  /*This association is currently being queued*/
  pSession->bAssocReqQueued = eWLAN_PAL_TRUE;

  if (eWLAN_PAL_STATUS_E_FAILURE ==
          wpal_list_insert_back(&(pSession->wptPendingQueue), pNode))
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "%s: Cannot allocate memory for queueing event data info",
               __func__);
    WDI_ASSERT(0);
    wpalMemoryFree(pEventDataQueue);
    wpalMemoryFree(pEventInfo);
    return WDI_STATUS_MEM_FAILURE;
  }

  /*The result of this operation is pending because the request has been
    queued and it will be processed at a later moment in time */
  return WDI_STATUS_PENDING;
}/*WDI_QueueAssocRequest*/

/**
 @brief    Utility function used by the DAL Core to help dequeue
           an association request that was pending
           The request will be queued up in front of the main
           pending queue for imediate processing
 @param

    pWDICtx: - pointer to the WDI control block


 @see
 @return Result of the operation
*/
WDI_Status
WDI_DequeueAssocRequest
(
  WDI_ControlBlockType*  pWDICtx
)
{
  wpt_list_node*          pNode = NULL;
  WDI_NextSessionIdType*  pSessionIdElement;
  WDI_BSSSessionType*     pSession;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
      Sanity check
    ------------------------------------------------------------------------*/
  if ( NULL == pWDICtx )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);

    return WDI_STATUS_E_FAILURE;
  }

  /*------------------------------------------------------------------------
    An association has been completed => a new association can occur
    Check to see if there are any pending associations ->
    If so , transfer all the pending requests into the busy queue for
    processing
    These requests have arrived prior to the requests in the busy queue
    (bc they needed to be processed in order to be placed in this queue)
    => they will be placed at the front of the busy queue
  ------------------------------------------------------------------------*/
  wpal_list_remove_front(&(pWDICtx->wptPendingAssocSessionIdQueue), &pNode);

  if ( NULL ==  pNode )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "List is empty - return");
    return WDI_STATUS_SUCCESS;
  }

  /*The node actually points to the 1st element inside the Session Id struct -
    just cast it back to the struct*/
  pSessionIdElement = (WDI_NextSessionIdType*)pNode;

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
       "Dequeueing new assoc session : %d ", pSessionIdElement->ucIndex);

  if ( pSessionIdElement->ucIndex < WDI_MAX_BSS_SESSIONS )
  {
      pSession = &pWDICtx->aBSSSessions[pSessionIdElement->ucIndex];

      /*Transfer all the pending requests in this assoc queue to
      the front of the main waiting queue for subsequent execution*/
      wpal_list_remove_back(&(pSession->wptPendingQueue), &pNode);
      while ( NULL !=  pNode )
      {
        /*Place it in front of the main pending list*/
        wpal_list_insert_front( &(pWDICtx->wptPendingQueue), &pNode);
        wpal_list_remove_back(&(pSession->wptPendingQueue), &pNode);
      }
      pSession->bAssocReqQueued = eWLAN_PAL_FALSE;
  }
  else
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
              "Invalid session id queued up for assoc");
     WPAL_ASSERT(0);
     wpalMemoryFree(pSessionIdElement);
     return WDI_STATUS_E_FAILURE;
  }

  /*Clean this up as it is no longer needed in order to prevent memory leak*/
  wpalMemoryFree(pSessionIdElement);
  return WDI_STATUS_SUCCESS;
}/*WDI_DequeueAssocRequest*/

/**
 @brief    Utility function used by the DAL Core to clear any
           pending requests - all req cb will be called with
           failure and the queue will be emptied.
 @param

    pWDICtx: - pointer to the WDI control block

 @see
 @return Result of the operation
*/
WDI_Status
WDI_ClearPendingRequests
(
  WDI_ControlBlockType*  pWDICtx
)
{
  wpt_list_node*      pNode = NULL;
  WDI_EventInfoType*  pEventDataQueue = NULL;
  WDI_ReqStatusCb     pfnReqStatusCB;
  void*               pUserData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  wpal_list_remove_front(&(pWDICtx->wptPendingQueue), &pNode);

  /*------------------------------------------------------------------------
    Go through all the requests and fail them - this will only be called
    when device is being stopped or an error was detected - either case the
    pending requests can no longer be sent down to HAL
  ------------------------------------------------------------------------*/
  while( pNode )
  {
      /*The node actually points to the 1st element inside the Event Data struct -
    just cast it back to the struct*/
    pEventDataQueue = (WDI_EventInfoType*)pNode;

    WDI_ExtractRequestCBFromEvent(pEventDataQueue, &pfnReqStatusCB, &pUserData);
    if ( NULL != pfnReqStatusCB )
    {
      /*Fail the request*/
      pfnReqStatusCB( WDI_STATUS_E_FAILURE, pUserData);
    }
    /* Free data - that was allocated when queueing */
    if ( pEventDataQueue->pEventData != NULL )
    {
      wpalMemoryFree(pEventDataQueue->pEventData);
    }
    wpalMemoryFree(pEventDataQueue);

    if (wpal_list_remove_front(&(pWDICtx->wptPendingQueue), &pNode) !=  eWLAN_PAL_STATUS_SUCCESS)
    {
        break;
    }
  }

  return WDI_STATUS_SUCCESS;
}/*WDI_ClearPendingRequests*/

/**
 @brief Helper routine used to init the BSS Sessions in the WDI control block


 @param  pWDICtx:       pointer to the WLAN DAL context

 @see
*/
void
WDI_ResetAssocSessions
(
  WDI_ControlBlockType*   pWDICtx
)
{
  wpt_uint8 i;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /*-------------------------------------------------------------------------
    No Sanity check
  -------------------------------------------------------------------------*/
  for ( i = 0; i < WDI_MAX_BSS_SESSIONS; i++ )
  {
    wpalMemoryZero( &pWDICtx->aBSSSessions[i], sizeof(WDI_BSSSessionType) );
    pWDICtx->aBSSSessions[i].wdiAssocState = WDI_ASSOC_INIT_ST;
    pWDICtx->aBSSSessions[i].bcastStaIdx = WDI_STA_INVALID_IDX;
    pWDICtx->aBSSSessions[i].ucBSSIdx = WDI_BSS_INVALID_IDX;
  }
}/*WDI_ResetAssocSessions*/

/**
 @brief Helper routine used to find a session based on the BSSID


 @param  pWDICtx:       pointer to the WLAN DAL context
         macBSSID:      BSSID of the session
         pSession:      pointer to the session (if found)

 @see
 @return Index of the session in the array
*/
wpt_uint8
WDI_FindAssocSession
(
  WDI_ControlBlockType*   pWDICtx,
  wpt_macAddr             macBSSID,
  WDI_BSSSessionType**    ppSession
)
{
  wpt_uint8 i;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if ( NULL == ppSession )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);
     return WDI_MAX_BSS_SESSIONS;
  }

  *ppSession = NULL;

  /*------------------------------------------------------------------------
      Search for a session that matches the BSSID
    ------------------------------------------------------------------------*/
  for ( i = 0; i < WDI_MAX_BSS_SESSIONS; i++ )
  {
     if ( (pWDICtx->aBSSSessions[i].bInUse == eWLAN_PAL_TRUE) && 
          (eWLAN_PAL_TRUE == 
                wpalMemoryCompare(pWDICtx->aBSSSessions[i].macBSSID, macBSSID,
                WDI_MAC_ADDR_LEN)) )
     {
       /*Found the session*/
       *ppSession = &pWDICtx->aBSSSessions[i];
       return i;
     }
  }

  return i;
}/*WDI_FindAssocSession*/

/**
 @brief Helper routine used to find a session based on the BSSID


 @param  pWDICtx:   pointer to the WLAN DAL context
         ucBSSIdx:  BSS Index of the session
         ppSession: out pointer to the session (if found)

 @see
 @return Index of the session in the array
*/
wpt_uint8
WDI_FindAssocSessionByBSSIdx
(
  WDI_ControlBlockType*   pWDICtx,
  wpt_uint16              ucBSSIdx,
  WDI_BSSSessionType**    ppSession
)
{
  wpt_uint8 i;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if ( NULL == ppSession )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);
     return WDI_MAX_BSS_SESSIONS;
  }

  *ppSession = NULL;

  /*------------------------------------------------------------------------
      Search for a session that matches the BSSID
    ------------------------------------------------------------------------*/
  for ( i = 0; i < WDI_MAX_BSS_SESSIONS; i++ )
  {
     if ( ucBSSIdx == pWDICtx->aBSSSessions[i].ucBSSIdx )
     {
       /*Found the session*/
       *ppSession = &pWDICtx->aBSSSessions[i];
       return i;
     }
  }

  return i;
}/*WDI_FindAssocSessionByBSSIdx*/

/**
 @brief Helper routine used to find a session based on the BSSID


 @param  pWDICtx:   pointer to the WLAN DAL context
         ucBSSIdx:  BSS Index of the session
         ppSession: out pointer to the session (if found)

 @see
 @return Index of the session in the array
*/
wpt_uint8
WDI_FindAssocSessionByIdx
(
  WDI_ControlBlockType*   pWDICtx,
  wpt_uint16              usIdx,
  WDI_BSSSessionType**    ppSession
)
{
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if ( NULL == ppSession || usIdx >= WDI_MAX_BSS_SESSIONS )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);
     return WDI_MAX_BSS_SESSIONS;
  }

  /*Found the session*/
  *ppSession = &pWDICtx->aBSSSessions[usIdx];

  return usIdx;

}/*WDI_FindAssocSessionByBSSIdx*/

/**
 @brief Helper routine used to find an empty session in the WDI
        CB


 @param  pWDICtx:       pointer to the WLAN DAL context
         pSession:      pointer to the session (if found)

 @see
 @return Index of the session in the array
*/
wpt_uint8
WDI_FindEmptySession
(
  WDI_ControlBlockType*   pWDICtx,
  WDI_BSSSessionType**    ppSession
)
{
  wpt_uint8 i;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
   /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if ( NULL == ppSession )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);
     return WDI_MAX_BSS_SESSIONS;
  }

  *ppSession = NULL;

  /*------------------------------------------------------------------------
      Search for a session that it is not in use
    ------------------------------------------------------------------------*/
  for ( i = 0; i < WDI_MAX_BSS_SESSIONS; i++ )
  {
     if ( ! pWDICtx->aBSSSessions[i].bInUse )
     {
       /*Found a session*/
       *ppSession = &pWDICtx->aBSSSessions[i];
       return i;
     }
  }

  return i;
}/*WDI_FindEmptySession*/


/**
 @brief Helper routine used to get the total count of active
        sessions


 @param  pWDICtx:       pointer to the WLAN DAL context
         macBSSID:      pointer to BSSID. If NULL, get all the session.
                        If not NULL, count ActiveSession by excluding (TRUE) or including (FALSE) skipBSSID.
         skipBSSID:     if TRUE, get all the sessions except matching to macBSSID. If FALSE, get all session.
                        This argument is ignored if macBSSID is NULL.
 @see
 @return Number of sessions in use
*/
wpt_uint8
WDI_GetActiveSessionsCount
(
  WDI_ControlBlockType*   pWDICtx,
  wpt_macAddr             macBSSID,
  wpt_boolean             skipBSSID
)
{
  wpt_uint8 i, ucCount = 0;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /*------------------------------------------------------------------------
      Count all sessions in use
    ------------------------------------------------------------------------*/
  for ( i = 0; i < WDI_MAX_BSS_SESSIONS; i++ )
  {
    if ( macBSSID && skipBSSID &&
        (eWLAN_PAL_TRUE ==
                wpalMemoryCompare(pWDICtx->aBSSSessions[i].macBSSID, macBSSID,
                WDI_MAC_ADDR_LEN)))
    {
      continue;
    }
    else if ( pWDICtx->aBSSSessions[i].bInUse )
    {
       ucCount++;
    }
  }

  return ucCount;
}/*WDI_GetActiveSessionsCount*/

/**
 @brief Helper routine used to delete session in the WDI
        CB


 @param  pWDICtx:       pointer to the WLAN DAL context
         pSession:      pointer to the session (if found)

 @see
 @return Index of the session in the array
*/
void
WDI_DeleteSession
(
  WDI_ControlBlockType*   pWDICtx,
  WDI_BSSSessionType*     ppSession
)
{
   /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if ( NULL == ppSession )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);
     return ;
  }

  /*------------------------------------------------------------------------
      Reset the entries int session
    ------------------------------------------------------------------------*/
  wpal_list_destroy(&ppSession->wptPendingQueue);
  wpalMemoryZero(ppSession,  sizeof(*ppSession));
  ppSession->wdiAssocState = WDI_ASSOC_INIT_ST;
  ppSession->bInUse        = eWLAN_PAL_FALSE;
  ppSession->wdiBssType    = WDI_INFRASTRUCTURE_MODE;
  wpal_list_init(&ppSession->wptPendingQueue);

}/*WDI_DeleteSession*/

/**
 @brief    Utility function to add the broadcast STA to the the STA table.
 The bcast STA ID is assigned by HAL and must be valid.
 @param

    WDI_AddStaParams: - pointer to the WDI Add STA params
    usBcastStaIdx: - Broadcast STA index passed by HAL

 @see
 @return void
*/
void
WDI_AddBcastSTAtoSTATable
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_AddStaParams *     staParams,
  wpt_uint16             usBcastStaIdx
)
{
  WDI_AddStaParams              wdiAddSTAParam = {0};
  wpt_macAddr  bcastMacAddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /*---------------------------------------------------------------------
    Sanity check
  ---------------------------------------------------------------------*/
  if ( NULL == staParams )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);

    return;
  }

  wdiAddSTAParam.bcastDpuIndex = staParams->bcastDpuIndex;
  wdiAddSTAParam.bcastDpuSignature = staParams->bcastDpuSignature;
  wdiAddSTAParam.bcastMgmtDpuIndex = staParams->bcastMgmtDpuIndex;
  wdiAddSTAParam.bcastMgmtDpuSignature = staParams->bcastMgmtDpuSignature;
  wdiAddSTAParam.dpuIndex = staParams->dpuIndex;
  wdiAddSTAParam.dpuSig = staParams->dpuSig;
  wpalMemoryCopy( wdiAddSTAParam.macBSSID, staParams->macBSSID,
                  WDI_MAC_ADDR_LEN );
  wpalMemoryCopy( wdiAddSTAParam.staMacAddr, bcastMacAddr, WDI_MAC_ADDR_LEN );
  wdiAddSTAParam.ucBSSIdx = staParams->ucBSSIdx;
  wdiAddSTAParam.ucHTCapable = staParams->ucHTCapable;
  wdiAddSTAParam.ucRmfEnabled = staParams->ucRmfEnabled;
  wdiAddSTAParam.ucStaType = WDI_STA_ENTRY_BCAST;
  wdiAddSTAParam.ucWmmEnabled = staParams->ucWmmEnabled;
  wdiAddSTAParam.ucSTAIdx = usBcastStaIdx;

  (void)WDI_STATableAddSta(pWDICtx,&wdiAddSTAParam);
}

/**
 @brief NV blob will be divided into fragments of size 4kb and
 Sent to HAL

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
 */

WDI_Status WDI_SendNvBlobReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{

  tHalNvImgDownloadReqMsg    halNvImgDownloadParam;
  wpt_uint8*                 pSendBuffer   = NULL;
  wpt_uint16                 usDataOffset  = 0;
  wpt_uint16                 usSendSize    = 0;
  wpt_uint16                 usCurrentFragmentSize =0;
  wpt_uint8*                 pSrcBuffer = NULL;
  WDI_NvDownloadReqParamsType*  pwdiNvDownloadReqParams =NULL ;
  WDI_NvDownloadRspCb      wdiNvDownloadRspCb;

  wdiNvDownloadRspCb = (WDI_NvDownloadRspCb)pEventData->pCBfnc;
  WDI_ASSERT(NULL != wdiNvDownloadRspCb);
  pwdiNvDownloadReqParams = (WDI_NvDownloadReqParamsType*)pEventData->pEventData;

  /* Sanity Check is done by the caller */
  pSrcBuffer =(wpt_uint8 *) pwdiNvDownloadReqParams->wdiBlobInfo.pBlobAddress;

  /* Update the current  Fragment Number */
  pWDICtx->wdiNvBlobInfo.usCurrentFragment += 1;

  /*Update the HAL REQ structure */
  /*HAL maintaining the fragment count as 0,1,2...n where at WDI it is represented as 1,2,3.. n*/
  halNvImgDownloadParam.nvImageReqParams.fragNumber =
                                     pWDICtx->wdiNvBlobInfo.usCurrentFragment-1;

  /*    Divide the NV Image to size of 'FRAGMENT_SIZE' fragments and send it to HAL.
       If the size of the Image is less than 'FRAGMENT_SIZE' then in one iteration total
       image will be sent to HAL*/

  if(pWDICtx->wdiNvBlobInfo.usTotalFragment
                         == pWDICtx->wdiNvBlobInfo.usCurrentFragment)
  {
    /*     Taking care of boundry condition */
    if( !(usCurrentFragmentSize =
                 pwdiNvDownloadReqParams->wdiBlobInfo.uBlobSize%FRAGMENT_SIZE ))
      usCurrentFragmentSize = FRAGMENT_SIZE;

    /*Update the HAL REQ structure */
    halNvImgDownloadParam.nvImageReqParams.isLastFragment = 1;
    halNvImgDownloadParam.nvImageReqParams.nvImgBufferSize= usCurrentFragmentSize;

  }
  else
  {
    usCurrentFragmentSize = FRAGMENT_SIZE;

    /*Update the HAL REQ structure */
    halNvImgDownloadParam.nvImageReqParams.isLastFragment =0;
    halNvImgDownloadParam.nvImageReqParams.nvImgBufferSize = usCurrentFragmentSize;
  }

  /*-----------------------------------------------------------------------
   Get message buffer
   -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,WDI_NV_DOWNLOAD_REQ,
         sizeof(halNvImgDownloadParam.nvImageReqParams)+ usCurrentFragmentSize,
                    &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize <
           (usDataOffset + sizeof(halNvImgDownloadParam.nvImageReqParams) + usCurrentFragmentSize )))
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
         "Unable to get send buffer in NV Download req %p %p ",
         pEventData, pwdiNvDownloadReqParams);
    WDI_ASSERT(0);
    return WDI_STATUS_E_FAILURE;
  }

  /* Copying the Hal NV download REQ structure */
  wpalMemoryCopy(pSendBuffer + usDataOffset ,
    &halNvImgDownloadParam.nvImageReqParams ,sizeof(tHalNvImgDownloadReqParams));

  /* Appending the NV image fragment */
  wpalMemoryCopy(pSendBuffer + usDataOffset + sizeof(tHalNvImgDownloadReqParams),
        (void *)(pSrcBuffer + halNvImgDownloadParam.nvImageReqParams.fragNumber * FRAGMENT_SIZE),
                  usCurrentFragmentSize);

  pWDICtx->wdiReqStatusCB     = pwdiNvDownloadReqParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiNvDownloadReqParams->pUserData;

  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                           wdiNvDownloadRspCb, pEventData->pUserData,
                           WDI_NV_DOWNLOAD_RESP);

}
/*============================================================================
  Helper inline functions for
 ============================================================================*/
/**
 @brief Helper routine used to find a session based on the BSSID
 @param  pContext:   pointer to the WLAN DAL context
 @param  pDPContext:   pointer to the Datapath context

 @see
 @return
*/
WPT_INLINE void
WDI_DS_AssignDatapathContext (void *pContext, void *pDPContext)
{
   WDI_ControlBlockType *pCB = (WDI_ControlBlockType *)pContext;

   pCB->pDPContext = pDPContext;
   return;
}

/**
 @brief Helper routine used to find a session based on the BSSID


 @param  pContext:   pointer to the WLAN DAL context

 @see
 @return pointer to Datapath context
*/
WPT_INLINE void *
WDI_DS_GetDatapathContext (void *pContext)
{
   WDI_ControlBlockType *pCB = (WDI_ControlBlockType *)pContext;
   return pCB->pDPContext;
}
/**
 @brief Helper routine used to find a session based on the BSSID


 @param  pContext:   pointer to the WLAN DAL context
 @param  pDTDriverContext:   pointer to the Transport Driver context

 @see
 @return void
*/
WPT_INLINE void
WDT_AssignTransportDriverContext (void *pContext, void *pDTDriverContext)
{
   WDI_ControlBlockType *pCB = (WDI_ControlBlockType *)pContext;

   pCB->pDTDriverContext = pDTDriverContext;
   return;
}

/**
 @brief Helper routine used to find a session based on the BSSID


 @param  pWDICtx:   pointer to the WLAN DAL context

 @see
 @return pointer to datapath context
*/
WPT_INLINE void *
WDT_GetTransportDriverContext (void *pContext)
{
   WDI_ControlBlockType *pCB = (WDI_ControlBlockType *)pContext;
   return(pCB->pDTDriverContext);
}

/*============================================================================
  Helper inline converters
 ============================================================================*/
/*Convert WDI driver type into HAL driver type*/
WPT_STATIC WPT_INLINE WDI_Status
WDI_HAL_2_WDI_STATUS
(
  eHalStatus halStatus
)
{
  /*Lightweight function - no sanity checks and no unecessary code to increase
    the chances of getting inlined*/
  switch(  halStatus )
  {
  case eHAL_STATUS_SUCCESS:
  case eHAL_STATUS_ADD_STA_SELF_IGNORED_REF_COUNT_NOT_ZERO:
  case eHAL_STATUS_DEL_STA_SELF_IGNORED_REF_COUNT_NOT_ZERO:
    return WDI_STATUS_SUCCESS;
  case eHAL_STATUS_FAILURE:
    return WDI_STATUS_E_FAILURE;
  case eHAL_STATUS_FAILED_ALLOC:
    return WDI_STATUS_MEM_FAILURE;
   /*The rest of the HAL error codes must be kept hidden from the UMAC as
     they refer to specific internal modules of our device*/
  default:
    return WDI_STATUS_DEV_INTERNAL_FAILURE;
  }

  return WDI_STATUS_E_FAILURE;
}/*WDI_HAL_2_WDI_STATUS*/

/*Convert WDI request type into HAL request type*/
WPT_STATIC WPT_INLINE tHalHostMsgType
WDI_2_HAL_REQ_TYPE
(
  WDI_RequestEnumType    wdiReqType
)
{
   /*Lightweight function - no sanity checks and no unecessary code to increase
    the chances of getting inlined*/
  switch(  wdiReqType )
  {
  case WDI_START_REQ:
    return WLAN_HAL_START_REQ;
  case WDI_STOP_REQ:
    return WLAN_HAL_STOP_REQ;
  case WDI_INIT_SCAN_REQ:
    return WLAN_HAL_INIT_SCAN_REQ;
  case WDI_START_SCAN_REQ:
    return WLAN_HAL_START_SCAN_REQ;
  case WDI_END_SCAN_REQ:
    return WLAN_HAL_END_SCAN_REQ;
  case WDI_FINISH_SCAN_REQ:
    return WLAN_HAL_FINISH_SCAN_REQ;
  case WDI_JOIN_REQ:
    return WLAN_HAL_JOIN_REQ;
  case WDI_CONFIG_BSS_REQ:
    return WLAN_HAL_CONFIG_BSS_REQ;
  case WDI_DEL_BSS_REQ:
    return WLAN_HAL_DELETE_BSS_REQ;
  case WDI_POST_ASSOC_REQ:
    return WLAN_HAL_POST_ASSOC_REQ;
  case WDI_DEL_STA_REQ:
    return WLAN_HAL_DELETE_STA_REQ;
  case WDI_SET_BSS_KEY_REQ:
    return WLAN_HAL_SET_BSSKEY_REQ;
  case WDI_RMV_BSS_KEY_REQ:
    return WLAN_HAL_RMV_BSSKEY_REQ;
  case WDI_SET_STA_KEY_REQ:
    return WLAN_HAL_SET_STAKEY_REQ;
  case WDI_RMV_STA_KEY_REQ:
    return WLAN_HAL_RMV_STAKEY_REQ;
  case WDI_SET_STA_BCAST_KEY_REQ:
    return WLAN_HAL_SET_BCASTKEY_REQ;
  case WDI_RMV_STA_BCAST_KEY_REQ:
    //Some conflict in the old code - check this: return WLAN_HAL_RMV_BCASTKEY_REQ;
    return WLAN_HAL_RMV_STAKEY_REQ;
  case WDI_ADD_TS_REQ:
    return WLAN_HAL_ADD_TS_REQ;
  case WDI_DEL_TS_REQ:
    return WLAN_HAL_DEL_TS_REQ;
  case WDI_UPD_EDCA_PRMS_REQ:
    return WLAN_HAL_UPD_EDCA_PARAMS_REQ;
  case WDI_ADD_BA_REQ:
    return WLAN_HAL_ADD_BA_REQ;
  case WDI_DEL_BA_REQ:
    return WLAN_HAL_DEL_BA_REQ; 
#ifdef FEATURE_WLAN_ESE
  case WDI_TSM_STATS_REQ:
    return WLAN_HAL_TSM_STATS_REQ; 
#endif
  case WDI_CH_SWITCH_REQ:
    return WLAN_HAL_CH_SWITCH_REQ;
  case WDI_CONFIG_STA_REQ:
    return WLAN_HAL_CONFIG_STA_REQ;
  case WDI_SET_LINK_ST_REQ:
    return WLAN_HAL_SET_LINK_ST_REQ;
  case WDI_GET_STATS_REQ:
    return WLAN_HAL_GET_STATS_REQ;
  case WDI_UPDATE_CFG_REQ:
    return WLAN_HAL_UPDATE_CFG_REQ;
  case WDI_ADD_BA_SESSION_REQ:
    return WLAN_HAL_ADD_BA_SESSION_REQ;
  case WDI_TRIGGER_BA_REQ:
    return WLAN_HAL_TRIGGER_BA_REQ;
  case WDI_UPD_BCON_PRMS_REQ:
    return WLAN_HAL_UPDATE_BEACON_REQ;
  case WDI_SND_BCON_REQ:
    return WLAN_HAL_SEND_BEACON_REQ;
  case WDI_UPD_PROBE_RSP_TEMPLATE_REQ:
    return WLAN_HAL_UPDATE_PROBE_RSP_TEMPLATE_REQ;
   case WDI_SET_MAX_TX_POWER_REQ:
    return WLAN_HAL_SET_MAX_TX_POWER_REQ;
  case WDI_SET_MAX_TX_POWER_PER_BAND_REQ:
    return WLAN_HAL_SET_MAX_TX_POWER_PER_BAND_REQ;
   case WDI_SET_TX_POWER_REQ:
    return WLAN_HAL_SET_TX_POWER_REQ;
  case WDI_P2P_GO_NOTICE_OF_ABSENCE_REQ:
    return WLAN_HAL_SET_P2P_GONOA_REQ;
#ifdef FEATURE_WLAN_TDLS
  case WDI_TDLS_LINK_ESTABLISH_REQ:
    return WLAN_HAL_TDLS_LINK_ESTABLISHED_REQ;
  case WDI_TDLS_CHAN_SWITCH_REQ:
    return WLAN_HAL_TDLS_CHAN_SWITCH_REQ;
#endif
  case WDI_ENTER_IMPS_REQ:
    return WLAN_HAL_ENTER_IMPS_REQ;
  case WDI_EXIT_IMPS_REQ:
    return WLAN_HAL_EXIT_IMPS_REQ;
  case WDI_ENTER_BMPS_REQ:
    return WLAN_HAL_ENTER_BMPS_REQ;
  case WDI_EXIT_BMPS_REQ:
    return WLAN_HAL_EXIT_BMPS_REQ;
  case WDI_ENTER_UAPSD_REQ:
    return WLAN_HAL_ENTER_UAPSD_REQ;
  case WDI_EXIT_UAPSD_REQ:
    return WLAN_HAL_EXIT_UAPSD_REQ;
  case WDI_SET_UAPSD_PARAM_REQ:
    return WLAN_HAL_SET_UAPSD_AC_PARAMS_REQ;
  case WDI_UPDATE_UAPSD_PARAM_REQ:
    return WLAN_HAL_UPDATE_UAPSD_PARAM_REQ;
  case WDI_CONFIGURE_RXP_FILTER_REQ:
    return WLAN_HAL_CONFIGURE_RXP_FILTER_REQ;
  case WDI_SET_BEACON_FILTER_REQ:
    return WLAN_HAL_ADD_BCN_FILTER_REQ;
  case WDI_REM_BEACON_FILTER_REQ:
    return WLAN_HAL_REM_BCN_FILTER_REQ;
  case WDI_SET_RSSI_THRESHOLDS_REQ:
    return WLAN_HAL_SET_RSSI_THRESH_REQ;
  case WDI_HOST_OFFLOAD_REQ:
    return WLAN_HAL_HOST_OFFLOAD_REQ;
  case WDI_WOWL_ADD_BC_PTRN_REQ:
    return WLAN_HAL_ADD_WOWL_BCAST_PTRN;
  case WDI_WOWL_DEL_BC_PTRN_REQ:
    return WLAN_HAL_DEL_WOWL_BCAST_PTRN;
  case WDI_WOWL_ENTER_REQ:
    return WLAN_HAL_ENTER_WOWL_REQ;
  case WDI_WOWL_EXIT_REQ:
    return WLAN_HAL_EXIT_WOWL_REQ;
  case WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_REQ:
    return WLAN_HAL_CONFIGURE_APPS_CPU_WAKEUP_STATE_REQ;
   case WDI_NV_DOWNLOAD_REQ:
    return WLAN_HAL_DOWNLOAD_NV_REQ;
  case WDI_FLUSH_AC_REQ:
    return WLAN_HAL_TL_HAL_FLUSH_AC_REQ;
  case WDI_BTAMP_EVENT_REQ:
    return WLAN_HAL_SIGNAL_BTAMP_EVENT_REQ;
#ifdef WLAN_FEATURE_VOWIFI_11R
  case WDI_AGGR_ADD_TS_REQ:
     return WLAN_HAL_AGGR_ADD_TS_REQ;
#endif /* WLAN_FEATURE_VOWIFI_11R */
  case WDI_FTM_CMD_REQ:
    return WLAN_HAL_PROCESS_PTT_REQ;
  case WDI_ADD_STA_SELF_REQ:
    return WLAN_HAL_ADD_STA_SELF_REQ;
  case WDI_DEL_STA_SELF_REQ:
    return WLAN_HAL_DEL_STA_SELF_REQ;
#ifdef FEATURE_OEM_DATA_SUPPORT
  case WDI_START_OEM_DATA_REQ:
    return WLAN_HAL_START_OEM_DATA_REQ;
#endif /* FEATURE_OEM_DATA_SUPPORT */
  case WDI_HOST_RESUME_REQ:
    return WLAN_HAL_HOST_RESUME_REQ;
  case WDI_HOST_SUSPEND_IND:
    return WLAN_HAL_HOST_SUSPEND_IND;
  case WDI_TRAFFIC_STATS_IND:
    return WLAN_HAL_CLASS_B_STATS_IND;
#ifdef WLAN_FEATURE_11W
  case WDI_EXCLUDE_UNENCRYPTED_IND:
    return WLAN_HAL_EXCLUDE_UNENCRYPTED_IND;
#endif
  case WDI_KEEP_ALIVE_REQ:
    return WLAN_HAL_KEEP_ALIVE_REQ;
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
  case WDI_ROAM_SCAN_OFFLOAD_REQ:
    return WLAN_ROAM_SCAN_OFFLOAD_REQ;
#endif
#ifdef FEATURE_WLAN_SCAN_PNO
  case WDI_SET_PREF_NETWORK_REQ:
    return WLAN_HAL_SET_PREF_NETWORK_REQ;
  case WDI_SET_RSSI_FILTER_REQ:
    return WLAN_HAL_SET_RSSI_FILTER_REQ;
  case WDI_UPDATE_SCAN_PARAMS_REQ:
    return WLAN_HAL_UPDATE_SCAN_PARAM_REQ;
#endif // FEATURE_WLAN_SCAN_PNO
  case WDI_SET_TX_PER_TRACKING_REQ:
    return WLAN_HAL_SET_TX_PER_TRACKING_REQ;
#ifdef WLAN_FEATURE_PACKET_FILTERING
  case WDI_8023_MULTICAST_LIST_REQ:
    return WLAN_HAL_8023_MULTICAST_LIST_REQ;
  case WDI_RECEIVE_FILTER_SET_FILTER_REQ:
    return WLAN_HAL_SET_PACKET_FILTER_REQ;
  case WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ:
    return WLAN_HAL_PACKET_FILTER_MATCH_COUNT_REQ;
  case WDI_RECEIVE_FILTER_CLEAR_FILTER_REQ:
    return WLAN_HAL_CLEAR_PACKET_FILTER_REQ;
#endif // WLAN_FEATURE_PACKET_FILTERING
  case WDI_HAL_DUMP_CMD_REQ:
    return WLAN_HAL_DUMP_COMMAND_REQ;
#ifdef WLAN_FEATURE_GTK_OFFLOAD
  case WDI_GTK_OFFLOAD_REQ:
    return WLAN_HAL_GTK_OFFLOAD_REQ;
  case WDI_GTK_OFFLOAD_GETINFO_REQ:
    return WLAN_HAL_GTK_OFFLOAD_GETINFO_REQ;
#endif /* WLAN_FEATURE_GTK_OFFLOAD */

  case WDI_INIT_SCAN_CON_REQ:
    return WLAN_HAL_INIT_SCAN_CON_REQ; 
  case WDI_SET_POWER_PARAMS_REQ:
    return WLAN_HAL_SET_POWER_PARAMS_REQ; 
  case WDI_SET_TM_LEVEL_REQ:
    return WLAN_HAL_SET_THERMAL_MITIGATION_REQ; 
  case WDI_FEATURE_CAPS_EXCHANGE_REQ:
    return WLAN_HAL_FEATURE_CAPS_EXCHANGE_REQ;
#ifdef WLAN_FEATURE_11AC
  case WDI_UPDATE_VHT_OP_MODE_REQ:
    return WLAN_HAL_UPDATE_VHT_OP_MODE_REQ;
#endif
  case WDI_GET_ROAM_RSSI_REQ:
    return WLAN_HAL_GET_ROAM_RSSI_REQ;
  case WDI_DHCP_START_IND:
    return WLAN_HAL_DHCP_START_IND;
  case WDI_DHCP_STOP_IND:
    return WLAN_HAL_DHCP_STOP_IND;
#ifdef FEATURE_WLAN_LPHB
   case WDI_LPHB_CFG_REQ:
      return WLAN_HAL_LPHB_CFG_REQ;
#endif /* FEATURE_WLAN_LPHB */
  case WDI_ADD_PERIODIC_TX_PATTERN_IND:
    return WLAN_HAL_ADD_PERIODIC_TX_PTRN_IND;
  case WDI_DEL_PERIODIC_TX_PATTERN_IND:
    return WLAN_HAL_DEL_PERIODIC_TX_PTRN_IND;

#ifdef FEATURE_WLAN_BATCH_SCAN
  case WDI_SET_BATCH_SCAN_REQ:
       return WLAN_HAL_BATCHSCAN_SET_REQ;
  case WDI_STOP_BATCH_SCAN_IND:
       return WLAN_HAL_BATCHSCAN_STOP_IND;
  case WDI_TRIGGER_BATCH_SCAN_RESULT_IND:
       return WLAN_HAL_BATCHSCAN_TRIGGER_RESULT_IND;
#endif
  case WDI_RATE_UPDATE_IND:
    return WLAN_HAL_RATE_UPDATE_IND;
  case WDI_START_HT40_OBSS_SCAN_IND:
       return WLAN_HAL_START_HT40_OBSS_SCAN_IND;
  case WDI_STOP_HT40_OBSS_SCAN_IND:
       return WLAN_HAL_STOP_HT40_OBSS_SCAN_IND;
  case WDI_UPDATE_CHAN_REQ:
    return WLAN_HAL_UPDATE_CHANNEL_LIST_REQ;
  case WDI_CH_SWITCH_REQ_V1:
       return WLAN_HAL_CH_SWITCH_V1_REQ;
  case WDI_GET_BCN_MISS_RATE_REQ:
    return WLAN_HAL_GET_BCN_MISS_RATE_REQ;

#ifdef WLAN_FEATURE_LINK_LAYER_STATS
  case WDI_LL_STATS_SET_REQ:
       return WLAN_HAL_LL_SET_STATS_REQ;
  case WDI_LL_STATS_GET_REQ:
       return WLAN_HAL_LL_GET_STATS_REQ;
  case WDI_LL_STATS_CLEAR_REQ:
       return WLAN_HAL_LL_CLEAR_STATS_REQ;
#endif
#ifdef WLAN_FEATURE_EXTSCAN
  case WDI_EXTSCAN_START_REQ:
       return WLAN_HAL_EXT_SCAN_START_REQ;
  case WDI_EXTSCAN_STOP_REQ:
       return WLAN_HAL_EXT_SCAN_STOP_REQ;
  case WDI_EXTSCAN_GET_CACHED_RESULTS_REQ:
       return WLAN_HAL_EXT_SCAN_GET_SCAN_REQ;
  case WDI_EXTSCAN_GET_CAPABILITIES_REQ:
       return WLAN_HAL_EXT_SCAN_GET_CAP_REQ;
  case WDI_EXTSCAN_SET_BSSID_HOTLIST_REQ:
       return WLAN_HAL_BSSID_HOTLIST_SET_REQ;
  case WDI_EXTSCAN_RESET_BSSID_HOTLIST_REQ:
       return WLAN_HAL_BSSID_HOTLIST_RESET_REQ;
  case WDI_EXTSCAN_SET_SSID_HOTLIST_REQ:
       return WLAN_HAL_SSID_HOTLIST_SET_REQ;
  case WDI_EXTSCAN_RESET_SSID_HOTLIST_REQ:
       return WLAN_HAL_SSID_HOTLIST_RESET_REQ;
  case WDI_HIGH_PRIORITY_DATA_INFO_IND:
       return WLAN_HAL_HIGH_PRIORITY_DATA_INFO_REQ;
#endif /* WLAN_FEATURE_EXTSCAN */
  case WDI_SPOOF_MAC_ADDR_REQ:
       return WLAN_HAL_MAC_SPOOFED_SCAN_REQ;
  case WDI_GET_FW_STATS_REQ:
       return WLAN_HAL_FW_STATS_REQ;
  case WDI_ENCRYPT_MSG_REQ:
       return WLAN_HAL_ENCRYPT_DATA_REQ;
  case WDI_FW_LOGGING_INIT_REQ:
       return WLAN_HAL_FW_LOGGING_INIT_REQ;
  case WDI_GET_FRAME_LOG_REQ:
       return WLAN_HAL_GET_FRAME_LOG_REQ;
  case WDI_NAN_REQUEST:
       return WLAN_HAL_NAN_REQ;
  case WDI_SET_RTS_CTS_HTVHT_IND:
       return WLAN_HAL_SET_RTS_CTS_HTVHT_IND;
  case WDI_MON_START_REQ:
       return WLAN_HAL_ENABLE_MONITOR_MODE_REQ;
  case WDI_MON_STOP_REQ:
       return WLAN_HAL_DISABLE_MONITOR_MODE_REQ;
  case WDI_FW_LOGGING_DXE_DONE_IND:
       return WLAN_HAL_FW_LOGGING_DXE_DONE_IND;
  case WDI_FATAL_EVENT_LOGGING_REQ:
       return WLAN_HAL_FATAL_EVENT_LOGGING_REQ;
  case WDI_SEND_FREQ_RANGE_CONTROL_IND:
       return WLAN_HAL_SEND_FREQ_RANGE_CONTROL_IND;
  case WDI_FWR_MEM_DUMP_REQ:
       return WLAN_HAL_FW_MEMORY_DUMP_REQ;
  case WDI_START_RSSI_MONITOR_REQ:
       return WLAN_HAL_START_RSSI_MONITORING_REQ;
  case WDI_STOP_RSSI_MONITOR_REQ:
       return WLAN_HAL_STOP_RSSI_MONITORING_REQ;
  case WDI_WIFI_CONFIG_SET_REQ:
       return WLAN_HAL_WIFI_CONFIG_SET_PARAMS_REQ;
  case WDI_START_OEM_DATA_REQ_IND_NEW:
       return WLAN_HAL_START_OEM_DATA_REQ_IND_NEW;
  case WDI_ANTENNA_DIVERSITY_SELECTION_REQ:
       return WLAN_HAL_ANTENNA_DIVERSITY_SELECTION_REQ;
  default:
    return WLAN_HAL_MSG_MAX;
  }

}/*WDI_2_HAL_REQ_TYPE*/

/*Convert WDI response type into HAL response type*/
WPT_STATIC WPT_INLINE WDI_ResponseEnumType
HAL_2_WDI_RSP_TYPE
(
  tHalHostMsgType halMsg
)
{
  /*Lightweight function - no sanity checks and no unecessary code to increase
    the chances of getting inlined*/
  switch(  halMsg )
  {
  case WLAN_HAL_START_RSP:
    return WDI_START_RESP;
  case WLAN_HAL_STOP_RSP:
    return WDI_STOP_RESP;
  case WLAN_HAL_INIT_SCAN_RSP:
    return WDI_INIT_SCAN_RESP;
  case WLAN_HAL_START_SCAN_RSP:
    return WDI_START_SCAN_RESP;
  case WLAN_HAL_END_SCAN_RSP:
    return WDI_END_SCAN_RESP;
  case WLAN_HAL_FINISH_SCAN_RSP:
    return WDI_FINISH_SCAN_RESP;
  case WLAN_HAL_CONFIG_STA_RSP:
    return WDI_CONFIG_STA_RESP;
  case WLAN_HAL_DELETE_STA_RSP:
    return WDI_DEL_STA_RESP;
  case WLAN_HAL_CONFIG_BSS_RSP:
    return WDI_CONFIG_BSS_RESP;
  case WLAN_HAL_DELETE_BSS_RSP:
    return WDI_DEL_BSS_RESP;
  case WLAN_HAL_JOIN_RSP:
    return WDI_JOIN_RESP;
  case WLAN_HAL_POST_ASSOC_RSP:
    return WDI_POST_ASSOC_RESP;
  case WLAN_HAL_SET_BSSKEY_RSP:
    return WDI_SET_BSS_KEY_RESP;
  case WLAN_HAL_SET_STAKEY_RSP:
    return WDI_SET_STA_KEY_RESP;
  case WLAN_HAL_RMV_BSSKEY_RSP:
    return WDI_RMV_BSS_KEY_RESP;
  case WLAN_HAL_RMV_STAKEY_RSP:
    return WDI_RMV_STA_KEY_RESP;
  case WLAN_HAL_SET_BCASTKEY_RSP:
    return WDI_SET_STA_BCAST_KEY_RESP;
  //Some conflict in the old code - check this: case WLAN_HAL_RMV_BCASTKEY_RSP:
  //  return WDI_RMV_STA_BCAST_KEY_RESP;
  case WLAN_HAL_ADD_TS_RSP:
    return WDI_ADD_TS_RESP;
  case WLAN_HAL_DEL_TS_RSP:
    return WDI_DEL_TS_RESP;
  case WLAN_HAL_UPD_EDCA_PARAMS_RSP:
    return WDI_UPD_EDCA_PRMS_RESP;
  case WLAN_HAL_ADD_BA_RSP:
    return WDI_ADD_BA_RESP;
  case WLAN_HAL_DEL_BA_RSP:
    return WDI_DEL_BA_RESP;
#ifdef FEATURE_WLAN_ESE
  case WLAN_HAL_TSM_STATS_RSP:
    return WDI_TSM_STATS_RESP;
#endif
  case WLAN_HAL_CH_SWITCH_RSP:
    return WDI_CH_SWITCH_RESP;
  case WLAN_HAL_SET_LINK_ST_RSP:
    return WDI_SET_LINK_ST_RESP;
  case WLAN_HAL_GET_STATS_RSP:
    return WDI_GET_STATS_RESP;
  case WLAN_HAL_UPDATE_CFG_RSP:
    return WDI_UPDATE_CFG_RESP;
  case WLAN_HAL_ADD_BA_SESSION_RSP:
    return WDI_ADD_BA_SESSION_RESP;
  case WLAN_HAL_TRIGGER_BA_RSP:
    return WDI_TRIGGER_BA_RESP;
  case WLAN_HAL_UPDATE_BEACON_RSP:
    return WDI_UPD_BCON_PRMS_RESP;
  case WLAN_HAL_SEND_BEACON_RSP:
    return WDI_SND_BCON_RESP;
  case WLAN_HAL_UPDATE_PROBE_RSP_TEMPLATE_RSP:
    return WDI_UPD_PROBE_RSP_TEMPLATE_RESP;
  /*Indications*/
  case WLAN_HAL_RSSI_NOTIFICATION_IND:
    return WDI_HAL_RSSI_NOTIFICATION_IND;
  case WLAN_HAL_MISSED_BEACON_IND:
    return WDI_HAL_MISSED_BEACON_IND;
  case WLAN_HAL_UNKNOWN_ADDR2_FRAME_RX_IND:
    return WDI_HAL_UNKNOWN_ADDR2_FRAME_RX_IND;
  case WLAN_HAL_MIC_FAILURE_IND:
    return WDI_HAL_MIC_FAILURE_IND;
  case WLAN_HAL_FATAL_ERROR_IND:
    return WDI_HAL_FATAL_ERROR_IND;
  case WLAN_HAL_DELETE_STA_CONTEXT_IND:
    return WDI_HAL_DEL_STA_IND;
  case WLAN_HAL_COEX_IND:
    return WDI_HAL_COEX_IND;
  case WLAN_HAL_OTA_TX_COMPL_IND:
    return WDI_HAL_TX_COMPLETE_IND;
  case WLAN_HAL_P2P_NOA_ATTR_IND:
    return WDI_HAL_P2P_NOA_ATTR_IND;
  case WLAN_HAL_P2P_NOA_START_IND:
    return WDI_HAL_P2P_NOA_START_IND;
  case WLAN_HAL_DEL_BA_IND:
    return WDI_HAL_DEL_BA_IND;
  case WLAN_HAL_TX_PER_HIT_IND:
    return WDI_HAL_TX_PER_HIT_IND;
  case WLAN_HAL_SET_MAX_TX_POWER_RSP:
    return WDI_SET_MAX_TX_POWER_RESP;
  case WLAN_HAL_SET_MAX_TX_POWER_PER_BAND_RSP:
    return WDI_SET_MAX_TX_POWER_PER_BAND_RSP;
  case WLAN_HAL_SET_TX_POWER_RSP:
    return WDI_SET_TX_POWER_RESP;
  case WLAN_HAL_SET_P2P_GONOA_RSP:
    return WDI_P2P_GO_NOTICE_OF_ABSENCE_RESP;
#ifdef FEATURE_WLAN_TDLS
  case WLAN_HAL_TDLS_LINK_ESTABLISHED_RSP:
    return WDI_TDLS_LINK_ESTABLISH_REQ_RESP;
  case WLAN_HAL_TDLS_CHAN_SWITCH_RSP:
    return WDI_TDLS_CHAN_SWITCH_REQ_RESP;
  case WLAN_HAL_TDLS_IND:
    return WDI_HAL_TDLS_IND;
#endif
  case WLAN_HAL_ENTER_IMPS_RSP:
    return WDI_ENTER_IMPS_RESP;
  case WLAN_HAL_EXIT_IMPS_RSP:
    return WDI_EXIT_IMPS_RESP;
  case WLAN_HAL_ENTER_BMPS_RSP:
    return WDI_ENTER_BMPS_RESP;
  case WLAN_HAL_EXIT_BMPS_RSP:
    return WDI_EXIT_BMPS_RESP;
  case WLAN_HAL_ENTER_UAPSD_RSP:
    return WDI_ENTER_UAPSD_RESP;
  case WLAN_HAL_EXIT_UAPSD_RSP:
    return WDI_EXIT_UAPSD_RESP;
  case WLAN_HAL_SET_UAPSD_AC_PARAMS_RSP:
    return WDI_SET_UAPSD_PARAM_RESP;
  case WLAN_HAL_UPDATE_UAPSD_PARAM_RSP:
    return WDI_UPDATE_UAPSD_PARAM_RESP;
  case WLAN_HAL_CONFIGURE_RXP_FILTER_RSP:
    return WDI_CONFIGURE_RXP_FILTER_RESP;
  case WLAN_HAL_ADD_BCN_FILTER_RSP:
    return WDI_SET_BEACON_FILTER_RESP;
  case WLAN_HAL_REM_BCN_FILTER_RSP:
    return WDI_REM_BEACON_FILTER_RESP;
  case WLAN_HAL_SET_RSSI_THRESH_RSP:
    return WDI_SET_RSSI_THRESHOLDS_RESP;
  case WLAN_HAL_HOST_OFFLOAD_RSP:
    return WDI_HOST_OFFLOAD_RESP;
  case WLAN_HAL_ADD_WOWL_BCAST_PTRN_RSP:
    return WDI_WOWL_ADD_BC_PTRN_RESP;
  case WLAN_HAL_DEL_WOWL_BCAST_PTRN_RSP:
    return WDI_WOWL_DEL_BC_PTRN_RESP;
  case WLAN_HAL_ENTER_WOWL_RSP:
    return WDI_WOWL_ENTER_RESP;
  case WLAN_HAL_EXIT_WOWL_RSP:
    return WDI_WOWL_EXIT_RESP;
  case WLAN_HAL_CONFIGURE_APPS_CPU_WAKEUP_STATE_RSP:
    return WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_RESP;
  case WLAN_HAL_DOWNLOAD_NV_RSP:
    return WDI_NV_DOWNLOAD_RESP;
  case WLAN_HAL_TL_HAL_FLUSH_AC_RSP:
    return WDI_FLUSH_AC_RESP;
  case WLAN_HAL_SIGNAL_BTAMP_EVENT_RSP:
    return WDI_BTAMP_EVENT_RESP;
  case WLAN_HAL_PROCESS_PTT_RSP:
    return  WDI_FTM_CMD_RESP;
  case WLAN_HAL_ADD_STA_SELF_RSP:
    return WDI_ADD_STA_SELF_RESP;
case WLAN_HAL_DEL_STA_SELF_RSP:
    return WDI_DEL_STA_SELF_RESP;
#ifdef FEATURE_OEM_DATA_SUPPORT
  case WLAN_HAL_START_OEM_DATA_RSP:
    return WDI_START_OEM_DATA_RESP;
#endif /* FEATURE_OEM_DATA_SUPPORT */
  case WLAN_HAL_HOST_RESUME_RSP:
    return WDI_HOST_RESUME_RESP;
  case WLAN_HAL_KEEP_ALIVE_RSP:
    return WDI_KEEP_ALIVE_RESP;
#ifdef FEATURE_WLAN_SCAN_PNO
  case WLAN_HAL_SET_PREF_NETWORK_RSP:
    return WDI_SET_PREF_NETWORK_RESP;
  case WLAN_HAL_SET_RSSI_FILTER_RSP:
    return WDI_SET_RSSI_FILTER_RESP;
  case WLAN_HAL_UPDATE_SCAN_PARAM_RSP:
    return WDI_UPDATE_SCAN_PARAMS_RESP;
  case WLAN_HAL_PREF_NETW_FOUND_IND:
    return WDI_HAL_PREF_NETWORK_FOUND_IND;
#endif // FEATURE_WLAN_SCAN_PNO
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
  case WLAN_ROAM_SCAN_OFFLOAD_RSP:
    return WDI_ROAM_SCAN_OFFLOAD_RESP;
#endif
  case WLAN_HAL_SET_TX_PER_TRACKING_RSP:
    return WDI_SET_TX_PER_TRACKING_RESP;
#ifdef WLAN_FEATURE_PACKET_FILTERING
  case WLAN_HAL_8023_MULTICAST_LIST_RSP:
    return WDI_8023_MULTICAST_LIST_RESP;
  case WLAN_HAL_SET_PACKET_FILTER_RSP:
    return WDI_RECEIVE_FILTER_SET_FILTER_RESP;
  case WLAN_HAL_PACKET_FILTER_MATCH_COUNT_RSP:
    return WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_RESP;
  case WLAN_HAL_CLEAR_PACKET_FILTER_RSP:
    return WDI_RECEIVE_FILTER_CLEAR_FILTER_RESP;
#endif // WLAN_FEATURE_PACKET_FILTERING

  case WLAN_HAL_DUMP_COMMAND_RSP:
    return WDI_HAL_DUMP_CMD_RESP;
  case WLAN_HAL_SET_POWER_PARAMS_RSP:
    return WDI_SET_POWER_PARAMS_RESP;
#ifdef WLAN_FEATURE_VOWIFI_11R
  case WLAN_HAL_AGGR_ADD_TS_RSP:
    return WDI_AGGR_ADD_TS_RESP;
#endif

#ifdef WLAN_FEATURE_GTK_OFFLOAD
  case WLAN_HAL_GTK_OFFLOAD_RSP:
    return WDI_GTK_OFFLOAD_RESP;
  case WLAN_HAL_GTK_OFFLOAD_GETINFO_RSP:
    return WDI_GTK_OFFLOAD_GETINFO_RESP;
#endif /* WLAN_FEATURE_GTK_OFFLOAD */
#ifdef WLAN_WAKEUP_EVENTS
  case WLAN_HAL_WAKE_REASON_IND:
    return WDI_HAL_WAKE_REASON_IND;
#endif // WLAN_WAKEUP_EVENTS

  case WLAN_HAL_SET_THERMAL_MITIGATION_RSP:
    return WDI_SET_TM_LEVEL_RESP;
  case WLAN_HAL_FEATURE_CAPS_EXCHANGE_RSP:
      return WDI_FEATURE_CAPS_EXCHANGE_RESP;
#ifdef WLAN_FEATURE_11AC
  case WLAN_HAL_UPDATE_VHT_OP_MODE_RSP:
      return WDI_UPDATE_VHT_OP_MODE_RESP;
#endif
#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
  case WLAN_HAL_GET_ROAM_RSSI_RSP:
    return WDI_GET_ROAM_RSSI_RESP;
#endif

#ifdef FEATURE_WLAN_LPHB
  case WLAN_HAL_LPHB_IND:
    return WDI_HAL_LPHB_IND;
  case WLAN_HAL_LPHB_CFG_RSP:
    return WDI_LPHB_CFG_RESP;
#endif /* FEATURE_WLAN_LPHB */

  case WLAN_HAL_IBSS_PEER_INACTIVITY_IND:
    return WDI_HAL_IBSS_PEER_INACTIVITY_IND;
  case WLAN_HAL_PERIODIC_TX_PTRN_FW_IND:
    return WDI_HAL_PERIODIC_TX_PTRN_FW_IND;

#ifdef FEATURE_WLAN_BATCH_SCAN
  case WLAN_HAL_BATCHSCAN_SET_RSP:
    return WDI_SET_BATCH_SCAN_RESP;
  case WLAN_HAL_BATCHSCAN_RESULT_IND:
    return WDI_BATCHSCAN_RESULT_IND;
#endif // FEATURE_WLAN_BATCH_SCAN

#ifdef FEATURE_WLAN_CH_AVOID
  case WLAN_HAL_AVOID_FREQ_RANGE_IND:
    return WDI_HAL_CH_AVOID_IND;
#endif /* FEATURE_WLAN_CH_AVOID */
  case WLAN_HAL_UPDATE_CHANNEL_LIST_RSP:
    return WDI_UPDATE_CHAN_RESP;
  case WLAN_HAL_PRINT_REG_INFO_IND:
    return  WDI_PRINT_REG_INFO_IND;
  case WLAN_HAL_CH_SWITCH_V1_RSP:
    return WDI_CH_SWITCH_RESP_V1;
  case WLAN_HAL_GET_BCN_MISS_RATE_RSP:
    return WDI_GET_BCN_MISS_RATE_RSP;
#ifdef WLAN_FEATURE_LINK_LAYER_STATS
  case WLAN_HAL_LL_SET_STATS_RSP:
       return WDI_LL_STATS_SET_RSP;
  case WLAN_HAL_LL_GET_STATS_RSP:
       return WDI_LL_STATS_GET_RSP;
  case WLAN_HAL_LL_CLEAR_STATS_RSP:
       return WDI_LL_STATS_CLEAR_RSP;
  case WLAN_HAL_LL_NOTIFY_STATS:
       return WDI_HAL_LL_STATS_RESULTS_IND;
#endif
#ifdef WLAN_FEATURE_EXTSCAN
  case WLAN_HAL_EXT_SCAN_START_RSP:
       return WDI_EXTSCAN_START_RSP;
  case WLAN_HAL_EXT_SCAN_STOP_RSP:
       return WDI_EXTSCAN_STOP_RSP;
  case WLAN_HAL_EXT_SCAN_GET_CAP_RSP:
       return WDI_EXTSCAN_GET_CAPABILITIES_RSP;
  case WLAN_HAL_EXT_SCAN_GET_SCAN_RSP:
       return WDI_EXTSCAN_GET_CACHED_RESULTS_RSP;
  case WLAN_HAL_BSSID_HOTLIST_SET_RSP:
       return WDI_EXTSCAN_SET_HOTLIST_BSSID_RSP;
  case WLAN_HAL_BSSID_HOTLIST_RESET_RSP:
       return WDI_EXTSCAN_RESET_HOTLIST_BSSID_RSP;
  case WLAN_HAL_SSID_HOTLIST_SET_RSP:
       return WDI_EXTSCAN_SET_HOTLIST_SSID_RSP;
  case WLAN_HAL_SSID_HOTLIST_RESET_RSP:
       return WDI_EXTSCAN_RESET_HOTLIST_SSID_RSP;
  case WLAN_HAL_EXT_SCAN_PROGRESS_IND:
       return WDI_HAL_EXTSCAN_PROGRESS_IND;
  case WLAN_HAL_EXT_SCAN_RESULT_AVAILABLE_IND:
       return WDI_HAL_EXTSCAN_SCAN_AVAILABLE_IND;
  case WLAN_HAL_EXT_SCAN_RESULT_IND:
       return WDI_HAL_EXTSCAN_RESULT_IND;
  case WLAN_HAL_BSSID_HOTLIST_RESULT_IND:
       return WDI_HAL_EXTSCAN_BSSID_HOTLIST_RESULT_IND;
  case WLAN_HAL_SSID_HOTLIST_RESULT_IND:
       return WDI_HAL_EXTSCAN_SSID_HOTLIST_RESULT_IND;
#endif /* WLAN_FEATURE_EXTSCAN */
  case WLAN_HAL_MAC_SPOOFED_SCAN_RSP:
       return WDI_SPOOF_MAC_ADDR_RSP;
  case WLAN_HAL_FW_STATS_RSP:
       return WDI_GET_FW_STATS_RSP;
  case WLAN_HAL_ENCRYPT_DATA_RSP:
       return WDI_ENCRYPT_MSG_RSP;
  case WLAN_HAL_FW_LOGGING_INIT_RSP:
       return WDI_FW_LOGGING_INIT_RSP;
  case WLAN_HAL_GET_FRAME_LOG_RSP:
       return WDI_GET_FRAME_LOG_RSP;
  case WLAN_HAL_NAN_RSP:
       return WDI_NAN_RESPONSE;
  case WLAN_HAL_NAN_EVT:
       return WDI_HAL_NAN_EVENT;
  case WLAN_HAL_LOST_LINK_PARAMETERS_IND:
       return WDI_HAL_LOST_LINK_PARAMS_IND;
  case WLAN_HAL_ENABLE_MONITOR_MODE_RSP:
       return WDI_MON_START_RSP;
  case WLAN_HAL_DISABLE_MONITOR_MODE_RSP:
       return WDI_MON_STOP_RSP;
  case WLAN_HAL_FATAL_EVENT_LOGGING_RSP:
       return WDI_FATAL_EVENT_LOGGING_RSP;
  case WLAN_HAL_FW_MEMORY_DUMP_RSP:
       return WDI_FWR_MEM_DUMP_RSP;
  case WLAN_HAL_START_RSSI_MONITORING_RSP:
       return WDI_START_RSSI_MONITOR_RSP;
  case WLAN_HAL_STOP_RSSI_MONITORING_RSP:
       return WDI_STOP_RSSI_MONITOR_RSP;
  case WLAN_HAL_RSSI_MONITORING_IND:
       return WDI_HAL_RSSI_BREACHED_IND;
  case WLAN_HAL_WIFI_CONFIG_SET_PARAMS_RSP:
       return WDI_WIFI_CONFIG_SET_RSP;
#ifdef FEATURE_OEM_DATA_SUPPORT
  case WLAN_HAL_START_OEM_DATA_RSP_IND_NEW:
       return WDI_HAL_START_OEM_DATA_RSP_IND_NEW;
#endif /* FEATURE_OEM_DATA_SUPPORT */
  case WLAN_HAL_ANTENNA_DIVERSITY_SELECTION_RSP:
       return WDI_ANTENNA_DIVERSITY_SELECTION_RSP;
  default:
    return eDRIVER_TYPE_MAX;
  }

}/*HAL_2_WDI_RSP_TYPE*/


/*Convert WDI driver type into HAL driver type*/
WPT_STATIC WPT_INLINE tDriverType
WDI_2_HAL_DRV_TYPE
(
  WDI_DriverType wdiDriverType
)
{
  /*Lightweight function - no sanity checks and no unecessary code to increase
    the chances of getting inlined*/
  switch(  wdiDriverType )
  {
  case WDI_DRIVER_TYPE_PRODUCTION:
    return eDRIVER_TYPE_PRODUCTION;
  case WDI_DRIVER_TYPE_MFG:
    return eDRIVER_TYPE_MFG;
  case WDI_DRIVER_TYPE_DVT:
    return eDRIVER_TYPE_DVT;
  }

  return eDRIVER_TYPE_MAX;
}/*WDI_2_HAL_DRV_TYPE*/


/*Convert WDI stop reason into HAL stop reason*/
WPT_STATIC WPT_INLINE tHalStopType
WDI_2_HAL_STOP_REASON
(
  WDI_StopType wdiDriverType
)
{
  /*Lightweight function - no sanity checks and no unecessary code to increase
    the chances of getting inlined*/
  switch(  wdiDriverType )
  {
  case WDI_STOP_TYPE_SYS_RESET:
    return HAL_STOP_TYPE_SYS_RESET;
  case WDI_STOP_TYPE_SYS_DEEP_SLEEP:
    return HAL_STOP_TYPE_SYS_DEEP_SLEEP;
  case WDI_STOP_TYPE_RF_KILL:
    return HAL_STOP_TYPE_RF_KILL;
  }

  return HAL_STOP_TYPE_MAX;
}/*WDI_2_HAL_STOP_REASON*/


/*Convert WDI scan mode type into HAL scan mode type*/
WPT_STATIC WPT_INLINE eHalSysMode
WDI_2_HAL_SCAN_MODE
(
  WDI_ScanMode wdiScanMode
)
{
  /*Lightweight function - no sanity checks and no unecessary code to increase
    the chances of getting inlined*/
  switch(  wdiScanMode )
  {
  case WDI_SCAN_MODE_NORMAL:
    return eHAL_SYS_MODE_NORMAL;
  case WDI_SCAN_MODE_LEARN:
    return eHAL_SYS_MODE_LEARN;
  case WDI_SCAN_MODE_SCAN:
    return eHAL_SYS_MODE_SCAN;
  case WDI_SCAN_MODE_PROMISC:
    return eHAL_SYS_MODE_PROMISC; 
  case WDI_SCAN_MODE_SUSPEND_LINK:
    return eHAL_SYS_MODE_SUSPEND_LINK;
  case WDI_SCAN_MODE_ROAM_SCAN:
    return eHAL_SYS_MODE_ROAM_SCAN;
  case WDI_SCAN_MODE_ROAM_SUSPEND_LINK:
    return eHAL_SYS_MODE_ROAM_SUSPEND_LINK;
  }

  return eHAL_SYS_MODE_MAX;
}/*WDI_2_HAL_SCAN_MODE*/

/*Convert WDI sec ch offset into HAL sec ch offset type*/
WPT_STATIC WPT_INLINE ePhyChanBondState
WDI_2_HAL_SEC_CH_OFFSET
(
  WDI_HTSecondaryChannelOffset wdiSecChOffset
)
{
  /*Lightweight function - no sanity checks and no unecessary code to increase
    the chances of getting inlined*/
  switch(  wdiSecChOffset )
  {
  case WDI_SECONDARY_CHANNEL_OFFSET_NONE:
    return PHY_SINGLE_CHANNEL_CENTERED;
  case WDI_SECONDARY_CHANNEL_OFFSET_UP:
    return PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
  case WDI_SECONDARY_CHANNEL_OFFSET_DOWN:
    return PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
#ifdef WLAN_FEATURE_11AC
  case WDI_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
    return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED;
  case WDI_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
    return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED;
  case WDI_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
    return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED;
  case WDI_CHANNEL_20MHZ_LOW_40MHZ_LOW:
    return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW;
  case WDI_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
    return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW;
  case WDI_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
    return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH;
  case WDI_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
     return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH;
#endif
  default:
      break;
  }

  return PHY_CHANNEL_BONDING_STATE_MAX; 
}/*WDI_2_HAL_SEC_CH_OFFSET*/

/*Convert WDI BSS type into HAL BSS type*/
WPT_STATIC WPT_INLINE tSirBssType
WDI_2_HAL_BSS_TYPE
(
  WDI_BssType wdiBSSType
)
{
  /*Lightweight function - no sanity checks and no unecessary code to increase
    the chances of getting inlined*/
  switch(  wdiBSSType )
  {
  case WDI_INFRASTRUCTURE_MODE:
    return eSIR_INFRASTRUCTURE_MODE;
  case WDI_INFRA_AP_MODE:
    return eSIR_INFRA_AP_MODE;
  case WDI_IBSS_MODE:
    return eSIR_IBSS_MODE;
  case WDI_BTAMP_STA_MODE:
    return eSIR_BTAMP_STA_MODE;
  case WDI_BTAMP_AP_MODE:
    return eSIR_BTAMP_AP_MODE;
  case WDI_BSS_AUTO_MODE:
    return eSIR_AUTO_MODE;
  }

  return eSIR_DONOT_USE_BSS_TYPE;
}/*WDI_2_HAL_BSS_TYPE*/

/*Convert WDI NW type into HAL NW type*/
WPT_STATIC WPT_INLINE tSirNwType
WDI_2_HAL_NW_TYPE
(
  WDI_NwType wdiNWType
)
{
  /*Lightweight function - no sanity checks and no unecessary code to increase
    the chances of getting inlined*/
  switch(  wdiNWType )
  {
  case WDI_11A_NW_TYPE:
    return eSIR_11A_NW_TYPE;
  case WDI_11B_NW_TYPE:
    return eSIR_11B_NW_TYPE;
  case WDI_11G_NW_TYPE:
    return eSIR_11G_NW_TYPE;
  case WDI_11N_NW_TYPE:
    return eSIR_11N_NW_TYPE;
  }

  return eSIR_DONOT_USE_NW_TYPE;
}/*WDI_2_HAL_NW_TYPE*/

/*Convert WDI chanel bonding type into HAL cb type*/
WPT_STATIC WPT_INLINE ePhyChanBondState
WDI_2_HAL_CB_STATE
(
  WDI_PhyChanBondState wdiCbState
)
{
  /*Lightweight function - no sanity checks and no unecessary code to increase
    the chances of getting inlined*/
  switch ( wdiCbState )
  {
  case WDI_PHY_SINGLE_CHANNEL_CENTERED:
    return PHY_SINGLE_CHANNEL_CENTERED;
  case WDI_PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
    return PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
  case WDI_PHY_DOUBLE_CHANNEL_CENTERED:
    return PHY_DOUBLE_CHANNEL_CENTERED;
  case WDI_PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
    return PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
#ifdef WLAN_FEATURE_11AC
  case WDI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
    return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED;
  case WDI_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
    return PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED;
  case WDI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
    return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED;
  case WDI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
    return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW;
  case WDI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
    return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW;
  case WDI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
    return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH;
  case WDI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
    return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH;
#endif
  case WDI_MAX_CB_STATE:
  default:
    break;
  }

  return PHY_CHANNEL_BONDING_STATE_MAX;
}/*WDI_2_HAL_CB_STATE*/

/*Convert WDI chanel bonding type into HAL cb type*/
WPT_STATIC WPT_INLINE tSirMacHTOperatingMode
WDI_2_HAL_HT_OPER_MODE
(
  WDI_HTOperatingMode wdiHTOperMode
)
{
  /*Lightweight function - no sanity checks and no unecessary code to increase
    the chances of getting inlined*/
  switch ( wdiHTOperMode )
  {
  case WDI_HT_OP_MODE_PURE:
    return eSIR_HT_OP_MODE_PURE;
  case WDI_HT_OP_MODE_OVERLAP_LEGACY:
    return eSIR_HT_OP_MODE_OVERLAP_LEGACY;
  case WDI_HT_OP_MODE_NO_LEGACY_20MHZ_HT:
    return eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
  case WDI_HT_OP_MODE_MIXED:
    return eSIR_HT_OP_MODE_MIXED;
  }

  return eSIR_HT_OP_MODE_MAX;
}/*WDI_2_HAL_HT_OPER_MODE*/

/*Convert WDI mimo PS type into HAL mimo PS type*/
WPT_STATIC WPT_INLINE tSirMacHTMIMOPowerSaveState
WDI_2_HAL_MIMO_PS
(
  WDI_HTMIMOPowerSaveState wdiHTOperMode
)
{
  /*Lightweight function - no sanity checks and no unecessary code to increase
    the chances of getting inlined*/
  switch ( wdiHTOperMode )
  {
  case WDI_HT_MIMO_PS_STATIC:
    return eSIR_HT_MIMO_PS_STATIC;
  case WDI_HT_MIMO_PS_DYNAMIC:
    return eSIR_HT_MIMO_PS_DYNAMIC;
  case WDI_HT_MIMO_PS_NA:
    return eSIR_HT_MIMO_PS_NA;
  case WDI_HT_MIMO_PS_NO_LIMIT:
    return eSIR_HT_MIMO_PS_NO_LIMIT;
  }

  return eSIR_HT_MIMO_PS_MAX;
}/*WDI_2_HAL_MIMO_PS*/

/*Convert WDI ENC type into HAL ENC type*/
WPT_STATIC WPT_INLINE tAniEdType
WDI_2_HAL_ENC_TYPE
(
  WDI_EncryptType wdiEncType
)
{
  /*Lightweight function - no sanity checks and no unecessary code to increase
    the chances of getting inlined*/
  switch ( wdiEncType )
  {
  case WDI_ENCR_NONE:
    return eSIR_ED_NONE;

  case WDI_ENCR_WEP40:
    return eSIR_ED_WEP40;

  case WDI_ENCR_WEP104:
    return eSIR_ED_WEP104;

  case WDI_ENCR_TKIP:
    return eSIR_ED_TKIP;

  case WDI_ENCR_CCMP:
    return eSIR_ED_CCMP;

  case WDI_ENCR_AES_128_CMAC:
    return eSIR_ED_AES_128_CMAC;
#if defined(FEATURE_WLAN_WAPI)
  case WDI_ENCR_WPI:
    return eSIR_ED_WPI;
#endif
  default:
    return eSIR_ED_NOT_IMPLEMENTED;
  }

}/*WDI_2_HAL_ENC_TYPE*/

/*Convert WDI WEP type into HAL WEP type*/
WPT_STATIC WPT_INLINE tAniWepType
WDI_2_HAL_WEP_TYPE
(
  WDI_WepType  wdiWEPType
)
{
  /*Lightweight function - no sanity checks and no unecessary code to increase
    the chances of getting inlined*/
  switch ( wdiWEPType )
  {
  case WDI_WEP_STATIC:
    return eSIR_WEP_STATIC;

  case WDI_WEP_DYNAMIC:
    return eSIR_WEP_DYNAMIC;
  }

  return eSIR_WEP_MAX;
}/*WDI_2_HAL_WEP_TYPE*/

WPT_STATIC WPT_INLINE tSirLinkState
WDI_2_HAL_LINK_STATE
(
  WDI_LinkStateType  wdiLinkState
)
{
  /*Lightweight function - no sanity checks and no unecessary code to increase
    the chances of getting inlined*/
  switch ( wdiLinkState )
  {
  case WDI_LINK_IDLE_STATE:
    return eSIR_LINK_IDLE_STATE;

  case WDI_LINK_PREASSOC_STATE:
    return eSIR_LINK_PREASSOC_STATE;

  case WDI_LINK_POSTASSOC_STATE:
    return eSIR_LINK_POSTASSOC_STATE;

  case WDI_LINK_AP_STATE:
    return eSIR_LINK_AP_STATE;

  case WDI_LINK_IBSS_STATE:
    return eSIR_LINK_IBSS_STATE;

  case WDI_LINK_BTAMP_PREASSOC_STATE:
    return eSIR_LINK_BTAMP_PREASSOC_STATE;

  case WDI_LINK_BTAMP_POSTASSOC_STATE:
    return eSIR_LINK_BTAMP_POSTASSOC_STATE;

  case WDI_LINK_BTAMP_AP_STATE:
    return eSIR_LINK_BTAMP_AP_STATE;

  case WDI_LINK_BTAMP_STA_STATE:
    return eSIR_LINK_BTAMP_STA_STATE;

  case WDI_LINK_LEARN_STATE:
    return eSIR_LINK_LEARN_STATE;

  case WDI_LINK_SCAN_STATE:
    return eSIR_LINK_SCAN_STATE;

  case WDI_LINK_FINISH_SCAN_STATE:
    return eSIR_LINK_FINISH_SCAN_STATE;

  case WDI_LINK_INIT_CAL_STATE:
    return eSIR_LINK_INIT_CAL_STATE;

  case WDI_LINK_FINISH_CAL_STATE:
    return eSIR_LINK_FINISH_CAL_STATE;

  case WDI_LINK_LISTEN_STATE:
    return eSIR_LINK_LISTEN_STATE;

  case WDI_LINK_SEND_ACTION_STATE:
    return eSIR_LINK_SEND_ACTION_STATE;

  default:
    return eSIR_LINK_MAX;
  }
}

/*Translate a STA Context from WDI into HAL*/
WPT_STATIC WPT_INLINE
void
WDI_CopyWDIStaCtxToHALStaCtx
(
  tConfigStaParams*          phalConfigSta,
  WDI_ConfigStaReqInfoType*  pwdiConfigSta
)
{
   wpt_uint8 i;
#ifdef WLAN_FEATURE_11AC
   /* Get the Version 1 Handler */
   tConfigStaParams_V1* phalConfigSta_V1 = NULL;
   if (WDI_getFwWlanFeatCaps(DOT11AC))
   {
      phalConfigSta_V1 = (tConfigStaParams_V1*)phalConfigSta;
   }
#endif
   /*Lightweight function - no sanity checks and no unecessary code to increase
    the chances of getting inlined*/

  wpalMemoryCopy(phalConfigSta->bssId,
                  pwdiConfigSta->macBSSID, WDI_MAC_ADDR_LEN);

  wpalMemoryCopy(phalConfigSta->staMac,
                  pwdiConfigSta->macSTA, WDI_MAC_ADDR_LEN);

  phalConfigSta->assocId                 = pwdiConfigSta->usAssocId;
  phalConfigSta->staType                 = pwdiConfigSta->wdiSTAType;
  phalConfigSta->shortPreambleSupported  = pwdiConfigSta->ucShortPreambleSupported;
  phalConfigSta->listenInterval          = pwdiConfigSta->usListenInterval;
  phalConfigSta->wmmEnabled              = pwdiConfigSta->ucWMMEnabled;
  phalConfigSta->htCapable               = pwdiConfigSta->ucHTCapable;
  phalConfigSta->txChannelWidthSet       = pwdiConfigSta->ucTXChannelWidthSet;
  phalConfigSta->rifsMode                = pwdiConfigSta->ucRIFSMode;
  phalConfigSta->lsigTxopProtection      = pwdiConfigSta->ucLSIGTxopProtection;
  phalConfigSta->maxAmpduSize            = pwdiConfigSta->ucMaxAmpduSize;
  phalConfigSta->maxAmpduDensity         = pwdiConfigSta->ucMaxAmpduDensity;
  phalConfigSta->maxAmsduSize            = pwdiConfigSta->ucMaxAmsduSize;
  phalConfigSta->fShortGI40Mhz           = pwdiConfigSta->ucShortGI40Mhz;
  phalConfigSta->fShortGI20Mhz           = pwdiConfigSta->ucShortGI20Mhz;
  phalConfigSta->rmfEnabled              = pwdiConfigSta->ucRMFEnabled;
  phalConfigSta->action                  = pwdiConfigSta->wdiAction;
  phalConfigSta->uAPSD                   = pwdiConfigSta->ucAPSD;
  phalConfigSta->maxSPLen                = pwdiConfigSta->ucMaxSPLen;
  phalConfigSta->greenFieldCapable       = pwdiConfigSta->ucGreenFieldCapable;
  phalConfigSta->delayedBASupport        = pwdiConfigSta->ucDelayedBASupport;
  phalConfigSta->us32MaxAmpduDuration    = pwdiConfigSta->us32MaxAmpduDuratio;
  phalConfigSta->fDsssCckMode40Mhz       = pwdiConfigSta->ucDsssCckMode40Mhz;
  phalConfigSta->encryptType             = pwdiConfigSta->ucEncryptType;

  phalConfigSta->mimoPS = WDI_2_HAL_MIMO_PS(pwdiConfigSta->wdiMIMOPS);

  phalConfigSta->supportedRates.opRateMode =
                          pwdiConfigSta->wdiSupportedRates.opRateMode;
  for(i = 0; i < SIR_NUM_11B_RATES; i ++)
  {
     phalConfigSta->supportedRates.llbRates[i] =
                          pwdiConfigSta->wdiSupportedRates.llbRates[i];
  }
  for(i = 0; i < SIR_NUM_11A_RATES; i ++)
  {
     phalConfigSta->supportedRates.llaRates[i] =
                          pwdiConfigSta->wdiSupportedRates.llaRates[i];
  }
  for(i = 0; i < SIR_NUM_POLARIS_RATES; i ++)
  {
     phalConfigSta->supportedRates.aniLegacyRates[i] =
                          pwdiConfigSta->wdiSupportedRates.aLegacyRates[i];
  }
  phalConfigSta->supportedRates.aniEnhancedRateBitmap =
                          pwdiConfigSta->wdiSupportedRates.uEnhancedRateBitmap;
  for(i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i ++)
  {
     phalConfigSta->supportedRates.supportedMCSSet[i] =
                          pwdiConfigSta->wdiSupportedRates.aSupportedMCSSet[i];
  }
  phalConfigSta->supportedRates.rxHighestDataRate =
                          pwdiConfigSta->wdiSupportedRates.aRxHighestDataRate;

#ifdef WLAN_FEATURE_11AC
  if(phalConfigSta_V1 != NULL)
  {
     phalConfigSta_V1->supportedRates.vhtRxMCSMap = pwdiConfigSta->wdiSupportedRates.vhtRxMCSMap;
     phalConfigSta_V1->supportedRates.vhtRxHighestDataRate = pwdiConfigSta->wdiSupportedRates.vhtRxHighestDataRate;
     phalConfigSta_V1->supportedRates.vhtTxMCSMap = pwdiConfigSta->wdiSupportedRates.vhtTxMCSMap;
     phalConfigSta_V1->supportedRates.vhtTxHighestDataRate = pwdiConfigSta->wdiSupportedRates.vhtTxHighestDataRate;
  }
#endif

  phalConfigSta->p2pCapableSta = pwdiConfigSta->ucP2pCapableSta ;

#ifdef WLAN_FEATURE_11AC
  if(phalConfigSta_V1 != NULL)
  {
     phalConfigSta_V1->vhtCapable = pwdiConfigSta->ucVhtCapableSta;
     phalConfigSta_V1->vhtTxChannelWidthSet = pwdiConfigSta->ucVhtTxChannelWidthSet;
     phalConfigSta_V1->vhtTxBFEnabled = pwdiConfigSta->ucVhtTxBFEnabled;
     phalConfigSta_V1->vhtTxMUBformeeCapable = pwdiConfigSta->vhtTxMUBformeeCapable;
     phalConfigSta_V1->htLdpcEnabled = pwdiConfigSta->ucHtLdpcEnabled;
     phalConfigSta_V1->vhtLdpcEnabled = pwdiConfigSta->ucVhtLdpcEnabled;

  }
#endif
}/*WDI_CopyWDIStaCtxToHALStaCtx*/;

/*Translate a Rate set info from WDI into HAL*/
WPT_STATIC WPT_INLINE void
WDI_CopyWDIRateSetToHALRateSet
(
  tSirMacRateSet* pHalRateSet,
  WDI_RateSet*    pwdiRateSet
)
{
  wpt_uint8 i;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  pHalRateSet->numRates = ( pwdiRateSet->ucNumRates <= SIR_MAC_RATESET_EID_MAX )?
                            pwdiRateSet->ucNumRates:SIR_MAC_RATESET_EID_MAX;

  for ( i = 0; i < pHalRateSet->numRates; i++ )
  {
    pHalRateSet->rate[i] = pwdiRateSet->aRates[i];
  }

}/*WDI_CopyWDIRateSetToHALRateSet*/


/*Translate an EDCA Parameter Record from WDI into HAL*/
WPT_STATIC WPT_INLINE void
WDI_CopyWDIEDCAParamsToHALEDCAParams
(
  tSirMacEdcaParamRecord* phalEdcaParam,
  WDI_EdcaParamRecord*    pWDIEdcaParam
)
{
  /*Lightweight function - no sanity checks and no unecessary code to increase
    the chances of getting inlined*/

  phalEdcaParam->aci.rsvd   = pWDIEdcaParam->wdiACI.rsvd;
  phalEdcaParam->aci.aci    = pWDIEdcaParam->wdiACI.aci;
  phalEdcaParam->aci.acm    = pWDIEdcaParam->wdiACI.acm;
  phalEdcaParam->aci.aifsn  = pWDIEdcaParam->wdiACI.aifsn;

  phalEdcaParam->cw.max     = pWDIEdcaParam->wdiCW.max;
  phalEdcaParam->cw.min     = pWDIEdcaParam->wdiCW.min;
  phalEdcaParam->txoplimit  = pWDIEdcaParam->usTXOPLimit;
}/*WDI_CopyWDIEDCAParamsToHALEDCAParams*/


/*Copy a management frame header from WDI fmt into HAL fmt*/
WPT_STATIC WPT_INLINE void
WDI_CopyWDIMgmFrameHdrToHALMgmFrameHdr
(
  tSirMacMgmtHdr* pmacMgmtHdr,
  WDI_MacMgmtHdr* pwdiMacMgmtHdr
)
{
  pmacMgmtHdr->fc.protVer    =  pwdiMacMgmtHdr->fc.protVer;
  pmacMgmtHdr->fc.type       =  pwdiMacMgmtHdr->fc.type;
  pmacMgmtHdr->fc.subType    =  pwdiMacMgmtHdr->fc.subType;
  pmacMgmtHdr->fc.toDS       =  pwdiMacMgmtHdr->fc.toDS;
  pmacMgmtHdr->fc.fromDS     =  pwdiMacMgmtHdr->fc.fromDS;
  pmacMgmtHdr->fc.moreFrag   =  pwdiMacMgmtHdr->fc.moreFrag;
  pmacMgmtHdr->fc.retry      =  pwdiMacMgmtHdr->fc.retry;
  pmacMgmtHdr->fc.powerMgmt  =  pwdiMacMgmtHdr->fc.powerMgmt;
  pmacMgmtHdr->fc.moreData   =  pwdiMacMgmtHdr->fc.moreData;
  pmacMgmtHdr->fc.wep        =  pwdiMacMgmtHdr->fc.wep;
  pmacMgmtHdr->fc.order      =  pwdiMacMgmtHdr->fc.order;

  pmacMgmtHdr->durationLo =  pwdiMacMgmtHdr->durationLo;
  pmacMgmtHdr->durationHi =  pwdiMacMgmtHdr->durationHi;

  wpalMemoryCopy(pmacMgmtHdr->da,
                 pwdiMacMgmtHdr->da, 6);
  wpalMemoryCopy(pmacMgmtHdr->sa,
                 pwdiMacMgmtHdr->sa, 6);
  wpalMemoryCopy(pmacMgmtHdr->bssId,
                 pwdiMacMgmtHdr->bssId, 6);

  pmacMgmtHdr->seqControl.fragNum  =  pwdiMacMgmtHdr->seqControl.fragNum;
  pmacMgmtHdr->seqControl.seqNumLo =  pwdiMacMgmtHdr->seqControl.seqNumLo;
  pmacMgmtHdr->seqControl.seqNumHi =  pwdiMacMgmtHdr->seqControl.seqNumHi;

}/*WDI_CopyWDIMgmFrameHdrToHALMgmFrameHdr*/


/*Copy config bss parameters from WDI fmt into HAL fmt*/
WPT_STATIC WPT_INLINE void
WDI_CopyWDIConfigBSSToHALConfigBSS
(
  tConfigBssParams*         phalConfigBSS,
  WDI_ConfigBSSReqInfoType* pwdiConfigBSS
)
{

  wpt_uint8 keyIndex = 0;
#ifdef WLAN_FEATURE_11AC
  /* Get the Version 1 Handler */
  tConfigBssParams_V1* phalConfigBSS_V1 = NULL;
  if (WDI_getFwWlanFeatCaps(DOT11AC))
     phalConfigBSS_V1 = (tConfigBssParams_V1*)phalConfigBSS;
#endif

  wpalMemoryCopy( phalConfigBSS->bssId,
                  pwdiConfigBSS->macBSSID,
                  WDI_MAC_ADDR_LEN);

#ifdef HAL_SELF_STA_PER_BSS
  wpalMemoryCopy( phalConfigBSS->selfMacAddr,
                  pwdiConfigBSS->macSelfAddr,
                  WDI_MAC_ADDR_LEN);
#endif

  phalConfigBSS->bssType  = WDI_2_HAL_BSS_TYPE(pwdiConfigBSS->wdiBSSType);

  phalConfigBSS->operMode = pwdiConfigBSS->ucOperMode;
  phalConfigBSS->nwType   = WDI_2_HAL_NW_TYPE(pwdiConfigBSS->wdiNWType);

  phalConfigBSS->shortSlotTimeSupported =
     pwdiConfigBSS->ucShortSlotTimeSupported;
  phalConfigBSS->llaCoexist         = pwdiConfigBSS->ucllaCoexist;
  phalConfigBSS->llbCoexist         = pwdiConfigBSS->ucllbCoexist;
  phalConfigBSS->llgCoexist         = pwdiConfigBSS->ucllgCoexist;
  phalConfigBSS->ht20Coexist        = pwdiConfigBSS->ucHT20Coexist;
  phalConfigBSS->llnNonGFCoexist    = pwdiConfigBSS->ucllnNonGFCoexist;
  phalConfigBSS->fLsigTXOPProtectionFullSupport =
    pwdiConfigBSS->ucTXOPProtectionFullSupport;
  phalConfigBSS->fRIFSMode          = pwdiConfigBSS->ucRIFSMode;
  phalConfigBSS->beaconInterval     = pwdiConfigBSS->usBeaconInterval;
  phalConfigBSS->dtimPeriod         = pwdiConfigBSS->ucDTIMPeriod;
  phalConfigBSS->txChannelWidthSet  = pwdiConfigBSS->ucTXChannelWidthSet;
  phalConfigBSS->currentOperChannel = pwdiConfigBSS->ucCurrentOperChannel;
  phalConfigBSS->currentExtChannel  = pwdiConfigBSS->ucCurrentExtChannel;
  phalConfigBSS->action             = pwdiConfigBSS->wdiAction;
  phalConfigBSS->htCapable          = pwdiConfigBSS->ucHTCapable;
  phalConfigBSS->obssProtEnabled    = pwdiConfigBSS->ucObssProtEnabled;
  phalConfigBSS->rmfEnabled         = pwdiConfigBSS->ucRMFEnabled;

  phalConfigBSS->htOperMode =
    WDI_2_HAL_HT_OPER_MODE(pwdiConfigBSS->wdiHTOperMod);

  phalConfigBSS->dualCTSProtection        = pwdiConfigBSS->ucDualCTSProtection;
  phalConfigBSS->ucMaxProbeRespRetryLimit = pwdiConfigBSS->ucMaxProbeRespRetryLimit;
  phalConfigBSS->bHiddenSSIDEn            = pwdiConfigBSS->bHiddenSSIDEn;
  phalConfigBSS->bProxyProbeRespEn        = pwdiConfigBSS->bProxyProbeRespEn;

#ifdef WLAN_FEATURE_VOWIFI
  phalConfigBSS->maxTxPower               = pwdiConfigBSS->cMaxTxPower;
#endif

  /*! Used 32 as magic number because that is how the ssid is declared inside the
   hal header - hal needs a macro for it */
  phalConfigBSS->ssId.length =
    (pwdiConfigBSS->wdiSSID.ucLength <= 32)?
    pwdiConfigBSS->wdiSSID.ucLength : 32;
  wpalMemoryCopy(phalConfigBSS->ssId.ssId,
                 pwdiConfigBSS->wdiSSID.sSSID,
                 phalConfigBSS->ssId.length);

  WDI_CopyWDIStaCtxToHALStaCtx( &phalConfigBSS->staContext,
                                &pwdiConfigBSS->wdiSTAContext);

  WDI_CopyWDIRateSetToHALRateSet( &phalConfigBSS->rateSet,
                                  &pwdiConfigBSS->wdiRateSet);

  phalConfigBSS->edcaParamsValid = pwdiConfigBSS->ucEDCAParamsValid;

  if(phalConfigBSS->edcaParamsValid)
  {
     WDI_CopyWDIEDCAParamsToHALEDCAParams( &phalConfigBSS->acbe,
                                        &pwdiConfigBSS->wdiBEEDCAParams);
     WDI_CopyWDIEDCAParamsToHALEDCAParams( &phalConfigBSS->acbk,
                                           &pwdiConfigBSS->wdiBKEDCAParams);
     WDI_CopyWDIEDCAParamsToHALEDCAParams( &phalConfigBSS->acvi,
                                           &pwdiConfigBSS->wdiVIEDCAParams);
     WDI_CopyWDIEDCAParamsToHALEDCAParams( &phalConfigBSS->acvo,
                                           &pwdiConfigBSS->wdiVOEDCAParams);
  }

  phalConfigBSS->halPersona = pwdiConfigBSS->ucPersona;

  phalConfigBSS->bSpectrumMgtEnable = pwdiConfigBSS->bSpectrumMgtEn;

#ifdef WLAN_FEATURE_VOWIFI_11R

  phalConfigBSS->extSetStaKeyParamValid =
     pwdiConfigBSS->bExtSetStaKeyParamValid;

  if( phalConfigBSS->extSetStaKeyParamValid )
  {
     /*-----------------------------------------------------------------------
       Copy the STA Key parameters into the HAL message
     -----------------------------------------------------------------------*/
     phalConfigBSS->extSetStaKeyParam.encType =
        WDI_2_HAL_ENC_TYPE (pwdiConfigBSS->wdiExtSetKeyParam.wdiEncType);

     phalConfigBSS->extSetStaKeyParam.wepType =
        WDI_2_HAL_WEP_TYPE (pwdiConfigBSS->wdiExtSetKeyParam.wdiWEPType );

     phalConfigBSS->extSetStaKeyParam.staIdx = pwdiConfigBSS->wdiExtSetKeyParam.ucSTAIdx;

     phalConfigBSS->extSetStaKeyParam.defWEPIdx = pwdiConfigBSS->wdiExtSetKeyParam.ucDefWEPIdx;

     phalConfigBSS->extSetStaKeyParam.singleTidRc = pwdiConfigBSS->wdiExtSetKeyParam.ucSingleTidRc;

     for(keyIndex = 0; keyIndex < pwdiConfigBSS->wdiExtSetKeyParam.ucNumKeys ;
          keyIndex++)
     {
        phalConfigBSS->extSetStaKeyParam.key[keyIndex].keyId =
           pwdiConfigBSS->wdiExtSetKeyParam.wdiKey[keyIndex].keyId;
        phalConfigBSS->extSetStaKeyParam.key[keyIndex].unicast =
           pwdiConfigBSS->wdiExtSetKeyParam.wdiKey[keyIndex].unicast;
        phalConfigBSS->extSetStaKeyParam.key[keyIndex].keyDirection =
           pwdiConfigBSS->wdiExtSetKeyParam.wdiKey[keyIndex].keyDirection;
        wpalMemoryCopy(phalConfigBSS->extSetStaKeyParam.key[keyIndex].keyRsc,
                       pwdiConfigBSS->wdiExtSetKeyParam.wdiKey[keyIndex].keyRsc,
                       WDI_MAX_KEY_RSC_LEN);
        phalConfigBSS->extSetStaKeyParam.key[keyIndex].paeRole =
           pwdiConfigBSS->wdiExtSetKeyParam.wdiKey[keyIndex].paeRole;
        phalConfigBSS->extSetStaKeyParam.key[keyIndex].keyLength =
           pwdiConfigBSS->wdiExtSetKeyParam.wdiKey[keyIndex].keyLength;
        wpalMemoryCopy(phalConfigBSS->extSetStaKeyParam.key[keyIndex].key,
                       pwdiConfigBSS->wdiExtSetKeyParam.wdiKey[keyIndex].key,
                       WDI_MAX_KEY_LENGTH);
     }
  }
  else/* phalConfigBSS->extSetStaKeyParamValid is not set */
  {
     wpalMemoryZero( &phalConfigBSS->extSetStaKeyParam,
                     sizeof(phalConfigBSS->extSetStaKeyParam) );
  }

#endif /*WLAN_FEATURE_VOWIFI_11R*/

#ifdef WLAN_FEATURE_11AC
  if(phalConfigBSS_V1 != NULL)
  {
      phalConfigBSS_V1->vhtCapable = pwdiConfigBSS->ucVhtCapableSta;
      phalConfigBSS_V1->vhtTxChannelWidthSet = pwdiConfigBSS->ucVhtTxChannelWidthSet;
  }
#endif

}/*WDI_CopyWDIConfigBSSToHALConfigBSS*/


/*Extract the request CB function and user data from a request structure
  pointed to by user data */
WPT_STATIC WPT_INLINE void
WDI_ExtractRequestCBFromEvent
(
  WDI_EventInfoType* pEvent,
  WDI_ReqStatusCb*   ppfnReqCB,
  void**             ppUserData
)
{
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  switch ( pEvent->wdiRequest )
  {
  case WDI_START_REQ:
    *ppfnReqCB   =  ((WDI_StartReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_StartReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_STOP_REQ:
    *ppfnReqCB   =  ((WDI_StopReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_StopReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_INIT_SCAN_REQ:
    *ppfnReqCB   =  ((WDI_InitScanReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_InitScanReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_START_SCAN_REQ:
    *ppfnReqCB   =  ((WDI_StartScanReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_StartScanReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_END_SCAN_REQ:
    *ppfnReqCB   =  ((WDI_EndScanReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_EndScanReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_FINISH_SCAN_REQ:
    *ppfnReqCB   =  ((WDI_FinishScanReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_FinishScanReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_JOIN_REQ:
    *ppfnReqCB   =  ((WDI_JoinReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_JoinReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_CONFIG_BSS_REQ:
    *ppfnReqCB   =  ((WDI_ConfigBSSReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_ConfigBSSReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_DEL_BSS_REQ:
    *ppfnReqCB   =  ((WDI_DelBSSReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_DelBSSReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_POST_ASSOC_REQ:
    *ppfnReqCB   =  ((WDI_PostAssocReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_PostAssocReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_DEL_STA_REQ:
    *ppfnReqCB   =  ((WDI_DelSTAReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_DelSTAReqParamsType*)pEvent->pEventData)->pUserData;
    break;

  case WDI_ADD_STA_SELF_REQ:
    *ppfnReqCB   =  ((WDI_AddSTASelfReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_AddSTASelfReqParamsType*)pEvent->pEventData)->pUserData;
    break;

  case WDI_DEL_STA_SELF_REQ:
    *ppfnReqCB   =  ((WDI_DelSTASelfReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_DelSTASelfReqParamsType*)pEvent->pEventData)->pUserData;
    break;

  case WDI_SET_BSS_KEY_REQ:
    *ppfnReqCB   =  ((WDI_SetBSSKeyReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_SetBSSKeyReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_RMV_BSS_KEY_REQ:
    *ppfnReqCB   =  ((WDI_RemoveBSSKeyReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_RemoveBSSKeyReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_SET_STA_KEY_REQ:
    *ppfnReqCB   =  ((WDI_SetSTAKeyReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_SetSTAKeyReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_RMV_STA_KEY_REQ:
    *ppfnReqCB   =  ((WDI_RemoveSTAKeyReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_RemoveSTAKeyReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_ADD_TS_REQ:
    *ppfnReqCB   =  ((WDI_AddTSReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_AddTSReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_DEL_TS_REQ:
    *ppfnReqCB   =  ((WDI_DelTSReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_DelTSReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_UPD_EDCA_PRMS_REQ:
    *ppfnReqCB   =  ((WDI_UpdateEDCAParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_UpdateEDCAParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_ADD_BA_SESSION_REQ:
    *ppfnReqCB   =  ((WDI_AddBASessionReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_AddBASessionReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_DEL_BA_REQ:
    *ppfnReqCB   =  ((WDI_DelBAReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_DelBAReqParamsType*)pEvent->pEventData)->pUserData;
    break;
#ifdef FEATURE_WLAN_ESE
   case WDI_TSM_STATS_REQ:
    *ppfnReqCB   =  ((WDI_TSMStatsReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_TSMStatsReqParamsType*)pEvent->pEventData)->pUserData;
     break;
#endif
  case WDI_CH_SWITCH_REQ:
    *ppfnReqCB   =  ((WDI_SwitchChReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_SwitchChReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_CH_SWITCH_REQ_V1:
    *ppfnReqCB   =  ((WDI_SwitchChReqParamsType_V1*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_SwitchChReqParamsType_V1*)pEvent->pEventData)->pUserData;
    break;
  case WDI_CONFIG_STA_REQ:
    *ppfnReqCB   =  ((WDI_ConfigSTAReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_ConfigSTAReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_SET_LINK_ST_REQ:
    *ppfnReqCB   =  ((WDI_SetLinkReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_SetLinkReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_GET_STATS_REQ:
    *ppfnReqCB   =  ((WDI_GetStatsReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_GetStatsReqParamsType*)pEvent->pEventData)->pUserData;
    break;
#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
  case WDI_GET_ROAM_RSSI_REQ:
    *ppfnReqCB   =  ((WDI_GetRoamRssiReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_GetRoamRssiReqParamsType*)pEvent->pEventData)->pUserData;
    break;
#endif
  case WDI_UPDATE_CFG_REQ:
    *ppfnReqCB   =  ((WDI_UpdateCfgReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_UpdateCfgReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_ADD_BA_REQ:
    *ppfnReqCB   =  ((WDI_AddBAReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_AddBAReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_TRIGGER_BA_REQ:
    *ppfnReqCB   =  ((WDI_TriggerBAReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_TriggerBAReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case  WDI_UPD_BCON_PRMS_REQ:
    *ppfnReqCB   =  ((WDI_UpdateBeaconParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_UpdateBeaconParamsType*)pEvent->pEventData)->pUserData;
     break;
  case  WDI_SND_BCON_REQ:
    *ppfnReqCB   =  ((WDI_SendBeaconParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_SendBeaconParamsType*)pEvent->pEventData)->pUserData;
     break;
  case  WDI_ENTER_BMPS_REQ:
    *ppfnReqCB   =  ((WDI_EnterBmpsReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_EnterBmpsReqParamsType*)pEvent->pEventData)->pUserData;
     break;
  case  WDI_EXIT_BMPS_REQ:
    *ppfnReqCB   =  ((WDI_ExitBmpsReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_ExitBmpsReqParamsType*)pEvent->pEventData)->pUserData;
     break;
  case  WDI_ENTER_IMPS_REQ:
    *ppfnReqCB   =  ((WDI_EnterImpsReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_EnterImpsReqParamsType*)pEvent->pEventData)->pUserData;
     break;
  case  WDI_ENTER_UAPSD_REQ:
    *ppfnReqCB   =  ((WDI_EnterUapsdReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_EnterUapsdReqParamsType*)pEvent->pEventData)->pUserData;
     break;
  case  WDI_EXIT_UAPSD_REQ:
    *ppfnReqCB   =  ((WDI_ExitUapsdReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_ExitUapsdReqParamsType*)pEvent->pEventData)->pUserData;
     break;
  case  WDI_SET_UAPSD_PARAM_REQ:
    *ppfnReqCB   =  ((WDI_SetUapsdAcParamsReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_SetUapsdAcParamsReqParamsType*)pEvent->pEventData)->pUserData;
     break;
  case  WDI_UPDATE_UAPSD_PARAM_REQ:
    *ppfnReqCB   =  ((WDI_UpdateUapsdReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_UpdateUapsdReqParamsType*)pEvent->pEventData)->pUserData;
     break;
  case  WDI_CONFIGURE_RXP_FILTER_REQ:
    *ppfnReqCB   =  ((WDI_ConfigureRxpFilterReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_ConfigureRxpFilterReqParamsType*)pEvent->pEventData)->pUserData;
     break;
  case  WDI_SET_BEACON_FILTER_REQ:
    *ppfnReqCB   =  ((WDI_BeaconFilterReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_BeaconFilterReqParamsType*)pEvent->pEventData)->pUserData;
     break;
  case  WDI_REM_BEACON_FILTER_REQ:
    *ppfnReqCB   =  ((WDI_RemBeaconFilterReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_RemBeaconFilterReqParamsType*)pEvent->pEventData)->pUserData;
     break;
  case  WDI_SET_RSSI_THRESHOLDS_REQ:
    *ppfnReqCB   =  ((WDI_SetRSSIThresholdsReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_SetRSSIThresholdsReqParamsType*)pEvent->pEventData)->pUserData;
     break;
  case  WDI_HOST_OFFLOAD_REQ:
    *ppfnReqCB   =  ((WDI_HostOffloadReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_HostOffloadReqParamsType*)pEvent->pEventData)->pUserData;
     break;
  case  WDI_WOWL_ADD_BC_PTRN_REQ:
    *ppfnReqCB   =  ((WDI_WowlAddBcPtrnReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_WowlAddBcPtrnReqParamsType*)pEvent->pEventData)->pUserData;
     break;
  case  WDI_WOWL_DEL_BC_PTRN_REQ:
    *ppfnReqCB   =  ((WDI_WowlDelBcPtrnReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_WowlDelBcPtrnReqParamsType*)pEvent->pEventData)->pUserData;
     break;
  case  WDI_WOWL_ENTER_REQ:
    *ppfnReqCB   =  ((WDI_WowlEnterReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_WowlEnterReqParamsType*)pEvent->pEventData)->pUserData;
     break;
  case  WDI_WOWL_EXIT_REQ:
    *ppfnReqCB   =  ((WDI_WowlExitReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_WowlExitReqParamsType*)pEvent->pEventData)->pUserData;
     break;
  case  WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_REQ:
    *ppfnReqCB   =  ((WDI_ConfigureAppsCpuWakeupStateReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_ConfigureAppsCpuWakeupStateReqParamsType*)pEvent->pEventData)->pUserData;
     break;
  case WDI_FLUSH_AC_REQ:
    *ppfnReqCB   =  ((WDI_FlushAcReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_FlushAcReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_BTAMP_EVENT_REQ:
    *ppfnReqCB   =  ((WDI_BtAmpEventParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_BtAmpEventParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_KEEP_ALIVE_REQ:
    *ppfnReqCB   =  ((WDI_KeepAliveReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_KeepAliveReqParamsType*)pEvent->pEventData)->pUserData;
    break;
#if defined FEATURE_WLAN_SCAN_PNO
  case WDI_SET_PREF_NETWORK_REQ:
    *ppfnReqCB   =  ((WDI_PNOScanReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_PNOScanReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_SET_RSSI_FILTER_REQ:
    *ppfnReqCB   =  ((WDI_SetRssiFilterReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_SetRssiFilterReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_UPDATE_SCAN_PARAMS_REQ:
    *ppfnReqCB   =  ((WDI_UpdateScanParamsInfoType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_UpdateScanParamsInfoType*)pEvent->pEventData)->pUserData;
    break;
#endif
  case WDI_SET_TX_PER_TRACKING_REQ:
    *ppfnReqCB   =  ((WDI_SetTxPerTrackingReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_SetTxPerTrackingReqParamsType*)pEvent->pEventData)->pUserData;
    break;
#if defined WLAN_FEATURE_PACKET_FILTERING
  case WDI_8023_MULTICAST_LIST_REQ:
    *ppfnReqCB   =  ((WDI_RcvFltPktSetMcListReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_RcvFltPktSetMcListReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_RECEIVE_FILTER_SET_FILTER_REQ:
    *ppfnReqCB   =  ((WDI_SetRcvPktFilterReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_SetRcvPktFilterReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ:
    *ppfnReqCB   =  ((WDI_RcvFltPktMatchCntReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_RcvFltPktMatchCntReqParamsType*)pEvent->pEventData)->pUserData;
    break;
  case WDI_RECEIVE_FILTER_CLEAR_FILTER_REQ:
    *ppfnReqCB   =  ((WDI_RcvFltPktClearReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_RcvFltPktClearReqParamsType*)pEvent->pEventData)->pUserData;
    break;
#endif
  case WDI_SET_POWER_PARAMS_REQ:
    *ppfnReqCB   =  ((WDI_SetPowerParamsReqParamsType*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_SetPowerParamsReqParamsType*)pEvent->pEventData)->pUserData;
    break;
#if defined WLAN_FEATURE_GTK_OFFLOAD
  case WDI_GTK_OFFLOAD_REQ:
    *ppfnReqCB   =  ((WDI_GtkOffloadReqMsg*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_GtkOffloadReqMsg*)pEvent->pEventData)->pUserData;
    break;
  case WDI_GTK_OFFLOAD_GETINFO_REQ:
    *ppfnReqCB   =  ((WDI_GtkOffloadGetInfoReqMsg*)pEvent->pEventData)->wdiReqStatusCB;
    *ppUserData  =  ((WDI_GtkOffloadGetInfoReqMsg*)pEvent->pEventData)->pUserData;
    break;
#endif

  default:
    *ppfnReqCB   =  NULL;
    *ppUserData  =  NULL;
      break;
  }
}/*WDI_ExtractRequestCBFromEvent*/


/**
 @brief WDI_IsHwFrameTxTranslationCapable checks to see if HW
        frame xtl is enabled for a particular STA.

 WDI_PostAssocReq must have been called.

 @param uSTAIdx: STA index

 @see WDI_PostAssocReq
 @return Result of the function call
*/
wpt_boolean
WDI_IsHwFrameTxTranslationCapable
(
  wpt_uint8 uSTAIdx
)
{
  /*!! FIX ME - this must eventually be per station - for now just feedback
    uma value*/
  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

#ifdef WLAN_SOFTAP_VSTA_FEATURE
  if (IS_VSTA_IDX(uSTAIdx))
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
              "STA %d is a Virtual STA, "
              "HW frame translation disabled", uSTAIdx);
    return eWLAN_PAL_FALSE;
  }
#endif

  return gWDICb.bFrameTransEnabled;
}/*WDI_IsHwFrameTxTranslationCapable*/


/**
 @brief WDI_IsSelfSTA - check if staid is self sta index


 @param  pWDICtx:   pointer to the WLAN DAL context
         ucSTAIdx:  station index

 @return Result of the function call
*/
wpt_boolean WDI_IsSelfSTA(  void*  pWDICtx, wpt_uint8 ucSTAIdx )
{
   wpt_uint8              ucSTAType;

   if( WDI_STATableGetStaType( (WDI_ControlBlockType*)pWDICtx,
                                ucSTAIdx,&ucSTAType) == WDI_STATUS_SUCCESS)
   {
        if( ucSTAType == WDI_STA_ENTRY_SELF )
           return eWLAN_PAL_TRUE;
   }

  return eWLAN_PAL_FALSE;
}



#ifdef FEATURE_WLAN_SCAN_PNO
/**
 @brief WDI_SetPreferredNetworkList

 @param pwdiPNOScanReqParams: the Set PNO as specified
                      by the Device Interface

        wdiPNOScanCb: callback for passing back the response
        of the Set PNO operation received from the
        device

        pUserData: user data will be passed back with the
        callback

 @return Result of the function call
*/
WDI_Status
WDI_SetPreferredNetworkReq
(
  WDI_PNOScanReqParamsType* pwdiPNOScanReqParams,
  WDI_PNOScanCb             wdiPNOScanCb,
  void*                      pUserData
)
{
   WDI_EventInfoType      wdiEventData = {{0}};
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_SET_PREF_NETWORK_REQ;
   wdiEventData.pEventData      = pwdiPNOScanReqParams;
   wdiEventData.uEventDataSize  = sizeof(*pwdiPNOScanReqParams);
   wdiEventData.pCBfnc          = wdiPNOScanCb;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}


/**
 @brief WDI_SetRssiFilterReq

 @param pwdiRssiFilterReqParams: the Set RSSI Filter as
                      specified by the Device Interface

        wdiRssiFilterCb: callback for passing back the response
        of the Set RSSI Filter operation received from the
        device

        pUserData: user data will be passed back with the
        callback

 @return Result of the function call
*/
WDI_Status
WDI_SetRssiFilterReq
(
  WDI_SetRssiFilterReqParamsType* pwdiRssiFilterReqParams,
  WDI_RssiFilterCb                wdiRssiFilterCb,
  void*                           pUserData
)
{
   WDI_EventInfoType      wdiEventData = {{0}};
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_SET_RSSI_FILTER_REQ;
   wdiEventData.pEventData      = pwdiRssiFilterReqParams;
   wdiEventData.uEventDataSize  = sizeof(*pwdiRssiFilterReqParams);
   wdiEventData.pCBfnc          = wdiRssiFilterCb;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}/*WDI_SetRssiFilterReq*/

/**
 @brief WDI_UpdateScanParamsReq

 @param pwdiUpdateScanParamsInfoType: the Update Scan Params as specified
                      by the Device Interface

        wdiUpdateScanParamsCb: callback for passing back the response
        of the Set PNO operation received from the
        device

        pUserData: user data will be passed back with the
        callback

 @return Result of the function call
*/
WDI_Status
WDI_UpdateScanParamsReq
(
  WDI_UpdateScanParamsInfoType* pwdiUpdateScanParamsInfoType,
  WDI_UpdateScanParamsCb        wdiUpdateScanParamsCb,
  void*                         pUserData
)
{
   WDI_EventInfoType      wdiEventData = {{0}};
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_UPDATE_SCAN_PARAMS_REQ;
   wdiEventData.pEventData      = pwdiUpdateScanParamsInfoType;
   wdiEventData.uEventDataSize  = sizeof(*pwdiUpdateScanParamsInfoType);
   wdiEventData.pCBfnc          = wdiUpdateScanParamsCb;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief Helper function to pack Set Preferred Network List
        Request parameters

 @param  pWDICtx:         pointer to the WLAN DAL context
         pwdiPNOScanReqParams:      pointer to the info received
         from upper layers
         ppSendBuffer, pSize - out pointers of the packed buffer
         and its size

 @return Result of the function call
*/

WDI_Status
WDI_PackPreferredNetworkList
(
  WDI_ControlBlockType*      pWDICtx,
  WDI_PNOScanReqParamsType*  pwdiPNOScanReqParams,
  wpt_uint8**                ppSendBuffer,
  wpt_uint16*                pSize
)
{
   wpt_uint8*                 pSendBuffer           = NULL;
   wpt_uint16                 usDataOffset          = 0;
   wpt_uint16                 usSendSize            = 0;
   tpPrefNetwListParams       pPrefNetwListParams   = NULL;
   wpt_uint8 i;
   /*-----------------------------------------------------------------------
     Get message buffer
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_PREF_NETWORK_REQ,
                         sizeof(tPrefNetwListParams),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(tPrefNetwListParams) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in Set PNO req %p",
                   pwdiPNOScanReqParams);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   pPrefNetwListParams = (tpPrefNetwListParams)(pSendBuffer + usDataOffset);

   /*-------------------------------------------------------------------------
     Fill prefNetwListParams from pwdiPNOScanReqParams->wdiPNOScanInfo
   -------------------------------------------------------------------------*/
   pPrefNetwListParams->enable  = 
     pwdiPNOScanReqParams->wdiPNOScanInfo.bEnable;
   pPrefNetwListParams->modePNO = 
     pwdiPNOScanReqParams->wdiPNOScanInfo.wdiModePNO;

   pPrefNetwListParams->ucNetworksCount = 
     (pwdiPNOScanReqParams->wdiPNOScanInfo.ucNetworksCount <
      WLAN_HAL_PNO_MAX_SUPP_NETWORKS)?
     pwdiPNOScanReqParams->wdiPNOScanInfo.ucNetworksCount :
      WLAN_HAL_PNO_MAX_SUPP_NETWORKS;

   WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
               "WDI SET PNO: Enable %d, Mode %d, Netw Count %d",
               pwdiPNOScanReqParams->wdiPNOScanInfo.bEnable,
               pwdiPNOScanReqParams->wdiPNOScanInfo.wdiModePNO,
               pwdiPNOScanReqParams->wdiPNOScanInfo.ucNetworksCount);

   for ( i = 0; i < pPrefNetwListParams->ucNetworksCount; i++ )
   {
     /*SSID of the BSS*/
     pPrefNetwListParams->aNetworks[i].ssId.length
        = pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].ssId.ucLength;

     wpalMemoryCopy( pPrefNetwListParams->aNetworks[i].ssId.ssId,
          pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].ssId.sSSID,
          pPrefNetwListParams->aNetworks[i].ssId.length);

     /*Authentication type for the network*/
     pPrefNetwListParams->aNetworks[i].authentication = 
       (tAuthType)pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].wdiAuth;

     /*Encryption type for the network*/
     pPrefNetwListParams->aNetworks[i].encryption = 
       (tEdType)pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].wdiEncryption;

     /*Indicate the channel on which the Network can be found
       0 - if all channels */
     pPrefNetwListParams->aNetworks[i].ucChannelCount =
       (pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].ucChannelCount <
        WLAN_HAL_PNO_MAX_NETW_CHANNELS)?
       pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].ucChannelCount :
        WLAN_HAL_PNO_MAX_NETW_CHANNELS;

     wpalMemoryCopy(pPrefNetwListParams->aNetworks[i].aChannels,
                    pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].aChannels,
                    pPrefNetwListParams->aNetworks[i].ucChannelCount);

     /*Indicates the RSSI threshold for the network to be considered*/
     pPrefNetwListParams->aNetworks[i].rssiThreshold =
       pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].rssiThreshold;

     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI SET PNO: SSID %d %s",
               pPrefNetwListParams->aNetworks[i].ssId.length,
               pPrefNetwListParams->aNetworks[i].ssId.ssId);
   }

   pPrefNetwListParams->scanTimers.ucScanTimersCount = 
     (pwdiPNOScanReqParams->wdiPNOScanInfo.scanTimers.ucScanTimersCount <
      WLAN_HAL_PNO_MAX_SCAN_TIMERS)?
     pwdiPNOScanReqParams->wdiPNOScanInfo.scanTimers.ucScanTimersCount :
      WLAN_HAL_PNO_MAX_SCAN_TIMERS;

   WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI SET PNO: Scan timers count %d 24G P %d 5G Probe %d",
               pPrefNetwListParams->scanTimers.ucScanTimersCount,
               pwdiPNOScanReqParams->wdiPNOScanInfo.us24GProbeSize,
               pwdiPNOScanReqParams->wdiPNOScanInfo.us5GProbeSize);

   for ( i = 0; i < pPrefNetwListParams->scanTimers.ucScanTimersCount; i++   )
   {
     pPrefNetwListParams->scanTimers.aTimerValues[i].uTimerValue  = 
       pwdiPNOScanReqParams->wdiPNOScanInfo.scanTimers.aTimerValues[i].uTimerValue;
     pPrefNetwListParams->scanTimers.aTimerValues[i].uTimerRepeat = 
       pwdiPNOScanReqParams->wdiPNOScanInfo.scanTimers.aTimerValues[i].uTimerRepeat;
   }

   /*Copy the probe template*/
   pPrefNetwListParams->us24GProbeSize = 
     (pwdiPNOScanReqParams->wdiPNOScanInfo.us24GProbeSize<
     WLAN_HAL_PNO_MAX_PROBE_SIZE)?
     pwdiPNOScanReqParams->wdiPNOScanInfo.us24GProbeSize:
     WLAN_HAL_PNO_MAX_PROBE_SIZE;

   wpalMemoryCopy(pPrefNetwListParams->a24GProbeTemplate, 
                  pwdiPNOScanReqParams->wdiPNOScanInfo.a24GProbeTemplate,
                  pPrefNetwListParams->us24GProbeSize); 

   pPrefNetwListParams->us5GProbeSize = 
     (pwdiPNOScanReqParams->wdiPNOScanInfo.us5GProbeSize <
     WLAN_HAL_PNO_MAX_PROBE_SIZE)?
     pwdiPNOScanReqParams->wdiPNOScanInfo.us5GProbeSize:
     WLAN_HAL_PNO_MAX_PROBE_SIZE;

   wpalMemoryCopy(pPrefNetwListParams->a5GProbeTemplate, 
                  pwdiPNOScanReqParams->wdiPNOScanInfo.a5GProbeTemplate,
                  pPrefNetwListParams->us5GProbeSize); 

   /*Set the output values*/
   *ppSendBuffer = pSendBuffer;
   *pSize        = usSendSize;

   return WDI_STATUS_SUCCESS;
}/*WDI_PackPreferredNetworkList*/

/**
 @brief Helper function to pack Set Preferred Network List
        Request parameters

 @param  pWDICtx:         pointer to the WLAN DAL context
         pwdiPNOScanReqParams:      pointer to the info received
         from upper layers
         ppSendBuffer, pSize - out pointers of the packed buffer
         and its size

 @return Result of the function call
*/

WDI_Status
WDI_PackPreferredNetworkListNew
(
  WDI_ControlBlockType*      pWDICtx,
  WDI_PNOScanReqParamsType*  pwdiPNOScanReqParams,
  wpt_uint8**                ppSendBuffer,
  wpt_uint16*                pSize
)
{
   wpt_uint8*                 pSendBuffer           = NULL;
   wpt_uint16                 usDataOffset          = 0;
   wpt_uint16                 usSendSize            = 0;
   tpPrefNetwListParamsNew    pPrefNetwListParams;
   wpt_uint8 i;

   /*-----------------------------------------------------------------------
     Get message buffer
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_PREF_NETWORK_REQ,
                         sizeof(tPrefNetwListParamsNew),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(tPrefNetwListParamsNew) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in Set PNO req %p",
                   pwdiPNOScanReqParams);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   pPrefNetwListParams = (tpPrefNetwListParamsNew)(pSendBuffer + usDataOffset);

   /*-------------------------------------------------------------------------
     Fill prefNetwListParams from pwdiPNOScanReqParams->wdiPNOScanInfo
   -------------------------------------------------------------------------*/
   pPrefNetwListParams->enable  = 
     pwdiPNOScanReqParams->wdiPNOScanInfo.bEnable;
   pPrefNetwListParams->modePNO = 
     pwdiPNOScanReqParams->wdiPNOScanInfo.wdiModePNO;

   pPrefNetwListParams->ucNetworksCount = 
     (pwdiPNOScanReqParams->wdiPNOScanInfo.ucNetworksCount <
      WLAN_HAL_PNO_MAX_SUPP_NETWORKS)?
     pwdiPNOScanReqParams->wdiPNOScanInfo.ucNetworksCount :
      WLAN_HAL_PNO_MAX_SUPP_NETWORKS;

   WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
               "WDI SET PNO: Enable %d, Mode %d, Netw Count %d",
               pwdiPNOScanReqParams->wdiPNOScanInfo.bEnable,
               pwdiPNOScanReqParams->wdiPNOScanInfo.wdiModePNO,
               pwdiPNOScanReqParams->wdiPNOScanInfo.ucNetworksCount);

   for ( i = 0; i < pPrefNetwListParams->ucNetworksCount; i++ )
   {
     /*SSID of the BSS*/
     pPrefNetwListParams->aNetworks[i].ssId.length
        = pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].ssId.ucLength;

     wpalMemoryCopy( pPrefNetwListParams->aNetworks[i].ssId.ssId,
          pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].ssId.sSSID,
          pPrefNetwListParams->aNetworks[i].ssId.length);

     /*Authentication type for the network*/
     pPrefNetwListParams->aNetworks[i].authentication = 
       (tAuthType)pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].wdiAuth;

     /*Encryption type for the network*/
     pPrefNetwListParams->aNetworks[i].encryption = 
       (tEdType)pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].wdiEncryption;

     /*SSID bcast type for the network*/
     pPrefNetwListParams->aNetworks[i].bcastNetworkType = 
       (tSSIDBcastType)pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].wdiBcastNetworkType;

     /*Indicate the channel on which the Network can be found
       0 - if all channels */
     pPrefNetwListParams->aNetworks[i].ucChannelCount = 
       pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].ucChannelCount;

     wpalMemoryCopy(pPrefNetwListParams->aNetworks[i].aChannels,
                    pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].aChannels,
                    pPrefNetwListParams->aNetworks[i].ucChannelCount);

     /*Indicates the RSSI threshold for the network to be considered*/
     pPrefNetwListParams->aNetworks[i].rssiThreshold =
       pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].rssiThreshold;

     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
               "WDI SET PNO: SSID %d %s",
               pPrefNetwListParams->aNetworks[i].ssId.length,
               pPrefNetwListParams->aNetworks[i].ssId.ssId);
   }

   pPrefNetwListParams->scanTimers.ucScanTimersCount = 
     (pwdiPNOScanReqParams->wdiPNOScanInfo.scanTimers.ucScanTimersCount <
      WLAN_HAL_PNO_MAX_SCAN_TIMERS)?
     pwdiPNOScanReqParams->wdiPNOScanInfo.scanTimers.ucScanTimersCount :
      WLAN_HAL_PNO_MAX_SCAN_TIMERS;

   WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
               "WDI SET PNO: Scan timers count %d 24G P %d 5G Probe %d",
               pPrefNetwListParams->scanTimers.ucScanTimersCount,
               pwdiPNOScanReqParams->wdiPNOScanInfo.us24GProbeSize,
               pwdiPNOScanReqParams->wdiPNOScanInfo.us5GProbeSize);

   for ( i = 0; i < pPrefNetwListParams->scanTimers.ucScanTimersCount; i++   )
   {
     pPrefNetwListParams->scanTimers.aTimerValues[i].uTimerValue  = 
       pwdiPNOScanReqParams->wdiPNOScanInfo.scanTimers.aTimerValues[i].uTimerValue;
     pPrefNetwListParams->scanTimers.aTimerValues[i].uTimerRepeat = 
       pwdiPNOScanReqParams->wdiPNOScanInfo.scanTimers.aTimerValues[i].uTimerRepeat;
   }

   /*Copy the probe template*/
   pPrefNetwListParams->us24GProbeSize = 
     (pwdiPNOScanReqParams->wdiPNOScanInfo.us24GProbeSize<
     WLAN_HAL_PNO_MAX_PROBE_SIZE)?
     pwdiPNOScanReqParams->wdiPNOScanInfo.us24GProbeSize:
     WLAN_HAL_PNO_MAX_PROBE_SIZE;

   wpalMemoryCopy(pPrefNetwListParams->a24GProbeTemplate, 
                  pwdiPNOScanReqParams->wdiPNOScanInfo.a24GProbeTemplate,
                  pPrefNetwListParams->us24GProbeSize); 

   pPrefNetwListParams->us5GProbeSize = 
     (pwdiPNOScanReqParams->wdiPNOScanInfo.us5GProbeSize <
     WLAN_HAL_PNO_MAX_PROBE_SIZE)?
     pwdiPNOScanReqParams->wdiPNOScanInfo.us5GProbeSize:
     WLAN_HAL_PNO_MAX_PROBE_SIZE;

   wpalMemoryCopy(pPrefNetwListParams->a5GProbeTemplate, 
                  pwdiPNOScanReqParams->wdiPNOScanInfo.a5GProbeTemplate,
                  pPrefNetwListParams->us5GProbeSize); 


   /*Set the output values*/
   *ppSendBuffer = pSendBuffer;
   *pSize        = usSendSize;

   return WDI_STATUS_SUCCESS;
}/*WDI_PackPreferredNetworkListNew*/

/**
 @brief Process Set Preferred Network List Request function

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetPreferredNetworkReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_PNOScanReqParamsType*  pwdiPNOScanReqParams  = NULL;
   WDI_PNOScanCb              wdiPNOScanCb          = NULL;
   wpt_uint8*                 pSendBuffer           = NULL;
   wpt_uint16                 usSendSize            = 0;
   WDI_Status                 wdiStatus;

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiPNOScanReqParams = (WDI_PNOScanReqParamsType*)pEventData->pEventData)) ||
       ( NULL == (wdiPNOScanCb   = (WDI_PNOScanCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   /*----------------------------------------------------------------------
     Avoid Enable PNO during any active session or an ongoing session
   ----------------------------------------------------------------------*/
   if ( (pwdiPNOScanReqParams->wdiPNOScanInfo.bEnable &&
        WDI_GetActiveSessionsCount(pWDICtx, NULL, eWLAN_PAL_FALSE)) )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "%s:(Active/Ongoing Session) - Fail request", __func__);

     return WDI_STATUS_E_FAILURE;
   }

   /*-------------------------------------------------------------------------
     Pack the PNO request structure based on version
   -------------------------------------------------------------------------*/
   if ( pWDICtx->wdiPNOVersion > 0 )
   {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
                  "%s: PNO new version %d ", __func__,
                  pWDICtx->wdiPNOVersion);

     wdiStatus = WDI_PackPreferredNetworkListNew( pWDICtx, pwdiPNOScanReqParams,
                                      &pSendBuffer, &usSendSize);
   }
   else
   {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
                  "%s: PNO old version %d ", __func__,
                  pWDICtx->wdiPNOVersion);

     wdiStatus = WDI_PackPreferredNetworkList( pWDICtx, pwdiPNOScanReqParams,
                                      &pSendBuffer, &usSendSize);
   }

   if (( WDI_STATUS_SUCCESS != wdiStatus )||
       ( NULL == pSendBuffer )||( 0 == usSendSize ))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: failed to pack request parameters", __func__);
      WDI_ASSERT(0);
      return wdiStatus;
   }

   pWDICtx->wdiReqStatusCB     = pwdiPNOScanReqParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiPNOScanReqParams->pUserData;

   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
               wdiPNOScanCb, pEventData->pUserData, WDI_SET_PREF_NETWORK_RESP);
}

/**
 @brief Process Set RSSI Filter Request function

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetRssiFilterReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_SetRssiFilterReqParamsType* pwdiRssiFilterReqParams = NULL;
   WDI_RssiFilterCb                wdiRssiFilterCb         = NULL;
   wpt_uint8*                      pSendBuffer             = NULL;
   wpt_uint16                      usDataOffset            = 0;
   wpt_uint16                      usSendSize              = 0;
   wpt_uint8                       ucRssiThreshold;

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiRssiFilterReqParams = (WDI_SetRssiFilterReqParamsType*)pEventData->pEventData)) ||
       ( NULL == (wdiRssiFilterCb   = (WDI_RssiFilterCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   /*-----------------------------------------------------------------------
     Get message buffer
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_RSSI_FILTER_REQ,
                         sizeof(ucRssiThreshold),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(ucRssiThreshold) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in Set PNO req %p %p %p",
                  pEventData, pwdiRssiFilterReqParams, wdiRssiFilterCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   ucRssiThreshold = pwdiRssiFilterReqParams->rssiThreshold;

   wpalMemoryCopy( pSendBuffer+usDataOffset,
                   &ucRssiThreshold,
                   sizeof(ucRssiThreshold));

   pWDICtx->wdiReqStatusCB     = pwdiRssiFilterReqParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiRssiFilterReqParams->pUserData;

   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiRssiFilterCb, pEventData->pUserData, WDI_SET_RSSI_FILTER_RESP);
}
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
/**
 @brief WDI_RoamScanOffloadReq

 @param pwdiRoamScanOffloadReqParams: the  LookupReq as specified
                      by the Device Interface

        wdiRoamOffloadScancb: callback for passing back the response
        of the Roam Candidate Lookup Req operation received from the
        device

        pUserData: user data will be passed back with the
        callback
 @return Result of the function call
*/
WDI_Status
WDI_RoamScanOffloadReq
(
  WDI_RoamScanOffloadReqParamsType* pwdiRoamScanOffloadReqParams,
  WDI_RoamOffloadScanCb                 wdiRoamOffloadScancb,
  void*                                 pUserData
)
{
   WDI_EventInfoType      wdiEventData = {{0}};
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_ROAM_SCAN_OFFLOAD_REQ;
   wdiEventData.pEventData      = pwdiRoamScanOffloadReqParams;
   wdiEventData.uEventDataSize  = sizeof(*pwdiRoamScanOffloadReqParams);
   wdiEventData.pCBfnc          = wdiRoamOffloadScancb;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

void
WDI_wdiEdTypeEncToEdTypeEnc(tEdType *EdType, WDI_EdType wdiEdType)
{
  switch (wdiEdType)
  {
    case WDI_ED_NONE:
         *EdType = eED_NONE;
          break;
    case WDI_ED_WEP40:
    case WDI_ED_WEP104:
         *EdType = eED_WEP;
          break;
    case WDI_ED_TKIP:
         *EdType = eED_TKIP;
          break;
    case WDI_ED_CCMP:
#ifdef WLAN_FEATURE_11W
    case WDI_ED_AES_128_CMAC:
#endif
         *EdType = eED_CCMP;
          break;
#ifdef FEATURE_WLAN_WAPI
    case WDI_ED_WPI:
         *EdType = eED_WPI;
          break;
#endif
    case WDI_ED_ANY:
         *EdType = eED_ANY;
          break;

    default:
         WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                     "%s: Unknown Encryption Type", __func__);
         break;
     }
}

/**
 @brief Helper function to pack Start Roam Candidate Lookup
        Request parameters

 @param  pWDICtx:                               pointer to the WLAN DAL context
         pwdiRoamScanOffloadReqParams:      pointer to the info received
         from upper layers
         ppSendBuffer, pSize - out pointers of the packed buffer
         and its size

 @return Result of the function call
*/

WDI_Status
WDI_PackRoamScanOffloadParams
(
  WDI_ControlBlockType*                 pWDICtx,
  WDI_RoamScanOffloadReqParamsType*     pwdiRoamScanOffloadReqParams,
  wpt_uint8**                           ppSendBuffer,
  wpt_uint16*                           pSize
)
{
   wpt_uint8*                 pSendBuffer                = NULL;
   wpt_uint16                 usDataOffset               = 0;
   wpt_uint16                 usSendSize                 = 0;
   tpRoamCandidateListParams  pRoamCandidateListParams   = NULL;
   wpt_uint8 i;
   /*-----------------------------------------------------------------------
     Get message buffer
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_ROAM_SCAN_OFFLOAD_REQ,
                         sizeof(tRoamCandidateListParams),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(tRoamCandidateListParams) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in Start Roam Candidate Lookup Req %p",
                   pwdiRoamScanOffloadReqParams);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }
   pRoamCandidateListParams = (tpRoamCandidateListParams)(pSendBuffer + usDataOffset);
   wpalMemoryZero(pRoamCandidateListParams, sizeof(tRoamCandidateListParams));
   pRoamCandidateListParams->RoamScanOffloadEnabled = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.RoamScanOffloadEnabled;
   wpalMemoryCopy(pRoamCandidateListParams->ConnectedNetwork.currAPbssid,
                  pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ConnectedNetwork.currAPbssid,
                  HAL_MAC_ADDR_LEN);
   pRoamCandidateListParams->ConnectedNetwork.authentication = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ConnectedNetwork.authentication;
   WDI_wdiEdTypeEncToEdTypeEnc(&pRoamCandidateListParams->ConnectedNetwork.encryption,
                               pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ConnectedNetwork.encryption);
   WDI_wdiEdTypeEncToEdTypeEnc(&pRoamCandidateListParams->ConnectedNetwork.mcencryption,
                               pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ConnectedNetwork.mcencryption);

   pRoamCandidateListParams->ConnectedNetwork.ssId.length
                = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ConnectedNetwork.ssId.ucLength;
   wpalMemoryCopy( pRoamCandidateListParams->ConnectedNetwork.ssId.ssId,
                   pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ConnectedNetwork.ssId.sSSID,
                   pRoamCandidateListParams->ConnectedNetwork.ssId.length);
   wpalMemoryCopy(pRoamCandidateListParams->ConnectedNetwork.ChannelCache,
                  pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ConnectedNetwork.ChannelCache,
                  pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ConnectedNetwork.ChannelCount );
   pRoamCandidateListParams->ConnectedNetwork.ChannelCount = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ConnectedNetwork.ChannelCount;
   pRoamCandidateListParams->ChannelCacheType = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ChannelCacheType ;
   pRoamCandidateListParams->LookupThreshold = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.LookupThreshold;
   pRoamCandidateListParams->RxSensitivityThreshold = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.RxSensitivityThreshold;
   pRoamCandidateListParams->RoamRssiDiff = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.RoamRssiDiff ;
   pRoamCandidateListParams->MAWCEnabled = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.MAWCEnabled ;
   pRoamCandidateListParams->Command = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.Command ;
   pRoamCandidateListParams->StartScanReason = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.StartScanReason ;
   pRoamCandidateListParams->NeighborScanTimerPeriod = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.NeighborScanTimerPeriod ;
   pRoamCandidateListParams->NeighborRoamScanRefreshPeriod = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.NeighborRoamScanRefreshPeriod ;
   pRoamCandidateListParams->NeighborScanChannelMinTime = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.NeighborScanChannelMinTime ;
   pRoamCandidateListParams->NeighborScanChannelMaxTime = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.NeighborScanChannelMaxTime ;
   pRoamCandidateListParams->EmptyRefreshScanPeriod = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.EmptyRefreshScanPeriod ;
   pRoamCandidateListParams->IsESEEnabled = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.IsESEEnabled ;
   wpalMemoryCopy(pRoamCandidateListParams->ValidChannelList,
                  pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ValidChannelList,
                  pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ValidChannelCount);
   pRoamCandidateListParams->ValidChannelCount = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ValidChannelCount;

   WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
              "Values are ssid = %s, RoamOffloadScan=%d,Command=%d,"
              "StartScanReason=%d,NeighborScanTimerPeriod=%d,"
              "NeighborRoamScanRefreshPeriod=%d,NeighborScanChannelMinTime=%d,"
              "NeighborScanChannelMaxTime = %d,EmptyRefreshScanPeriod=%d,"
              "mdiePresent=%d,MDID=%d, auth=%d, uce=%d, mce=%d, nProbes=%d,"
              "HomeAwayTime=%d",
              pRoamCandidateListParams->ConnectedNetwork.ssId.ssId,
              pRoamCandidateListParams->RoamScanOffloadEnabled,
              pRoamCandidateListParams->Command,
              pRoamCandidateListParams->StartScanReason,
              pRoamCandidateListParams->NeighborScanTimerPeriod,
              pRoamCandidateListParams->NeighborRoamScanRefreshPeriod,
              pRoamCandidateListParams->NeighborScanChannelMinTime,
              pRoamCandidateListParams->NeighborScanChannelMaxTime,
              pRoamCandidateListParams->EmptyRefreshScanPeriod,
              pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.MDID.mdiePresent,
                   pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.MDID.mobilityDomain,
              pRoamCandidateListParams->ConnectedNetwork.authentication,
              pRoamCandidateListParams->ConnectedNetwork.encryption,
                   pRoamCandidateListParams->ConnectedNetwork.mcencryption,
                   pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.nProbes,
                   pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.HomeAwayTime);
   pRoamCandidateListParams->us24GProbeSize =
           (pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.us24GProbeSize<
            WLAN_HAL_ROAM_SCAN_MAX_PROBE_SIZE)?
            pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.us24GProbeSize:
           WLAN_HAL_ROAM_SCAN_MAX_PROBE_SIZE;
   wpalMemoryCopy(pRoamCandidateListParams->a24GProbeTemplate,
                  pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.a24GProbeTemplate,
                  pRoamCandidateListParams->us24GProbeSize);
   pRoamCandidateListParams->us5GProbeSize =
           (pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.us5GProbeSize<
            WLAN_HAL_ROAM_SCAN_MAX_PROBE_SIZE)?
           pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.us5GProbeSize:
           WLAN_HAL_ROAM_SCAN_MAX_PROBE_SIZE;
   wpalMemoryCopy(pRoamCandidateListParams->a5GProbeTemplate,
                  pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.a5GProbeTemplate,
                  pRoamCandidateListParams->us5GProbeSize);
   pRoamCandidateListParams->MDID.mdiePresent = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.MDID.mdiePresent;
   pRoamCandidateListParams->MDID.mobilityDomain = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.MDID.mobilityDomain;
   pRoamCandidateListParams->nProbes =
           pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.nProbes;
   pRoamCandidateListParams->HomeAwayTime =
           pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.HomeAwayTime;
   WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,"Valid Channel List");
   for (i=0; i<pRoamCandidateListParams->ValidChannelCount ; i++)
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,"%d", pRoamCandidateListParams->ValidChannelList[i]);
   }


   /*Set the output values*/
   *ppSendBuffer = pSendBuffer;
   *pSize        = usSendSize;
   return WDI_STATUS_SUCCESS;
}/*WDI_PackRoamScanOffloadParams*/

/**
 @brief Process Start Roam Candidate Lookup Request function

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @return Result of the function call
*/
WDI_Status
WDI_ProcessRoamScanOffloadReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_RoamScanOffloadReqParamsType* pwdiRoamScanOffloadReqParams = NULL;
   WDI_RoamOffloadScanCb                 wdiRoamOffloadScancb  = NULL;
   wpt_uint8*                            pSendBuffer           = NULL;
   wpt_uint16                            usSendSize            = 0;
   WDI_Status                            wdiStatus;
   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiRoamScanOffloadReqParams = (WDI_RoamScanOffloadReqParamsType*)pEventData->pEventData)) ||
       ( NULL == (wdiRoamOffloadScancb   = (WDI_RoamOffloadScanCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   /*-------------------------------------------------------------------------
     Pack the Start Roam Candidate Lookup request structure based on version
   -------------------------------------------------------------------------*/
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
                  "%s: Packing Roam Candidate Lookup request ", __func__);

     wdiStatus = WDI_PackRoamScanOffloadParams( pWDICtx, pwdiRoamScanOffloadReqParams,
                                      &pSendBuffer, &usSendSize);

   if (( WDI_STATUS_SUCCESS != wdiStatus )||
       ( NULL == pSendBuffer )||( 0 == usSendSize ))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: failed to pack request parameters", __func__);
      WDI_ASSERT(0);
      return wdiStatus;
   }

   pWDICtx->wdiReqStatusCB     = pwdiRoamScanOffloadReqParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiRoamScanOffloadReqParams->pUserData;

   /*-------------------------------------------------------------------------
     Send WDI_ROAM_SCAN_OFFLOAD_REQ to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
               wdiRoamOffloadScancb, pEventData->pUserData, WDI_ROAM_SCAN_OFFLOAD_RESP);
}

/**
 @brief Process Start Roam Candidate Lookup Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessRoamScanOffloadRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_Status                   wdiStatus;
   eHalStatus                   halStatus;
   WDI_RoamOffloadScanCb        wdiRoamOffloadScancb = NULL;

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

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData ))
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wdiRoamOffloadScancb = (WDI_RoamOffloadScanCb)pWDICtx->pfncRspCB;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   halStatus = *((eHalStatus*)pEventData->pEventData);
   wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

   /*Notify UMAC*/
   wdiRoamOffloadScancb(wdiStatus, pWDICtx->pRspCBUserData);

   return WDI_STATUS_SUCCESS;
}/* WDI_ProcessRoamScanOffloadRsp  */
#endif

/**
 @brief Process Update Scan Params function

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_PackUpdateScanParamsReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_UpdateScanParamsInfoType* pwdiUpdateScanParams,
  wpt_uint8**                   ppSendBuffer,
  wpt_uint16*                   pSize
)
{
   wpt_uint8*                    pSendBuffer           = NULL;
   wpt_uint16                    usDataOffset          = 0;
   wpt_uint16                    usSendSize            = 0;
   tUpdateScanParams             updateScanParams = {0};


   WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_INFO,
               "Begin WDI Update Scan Parameters Old Style Params");
   /*-----------------------------------------------------------------------
     Get message buffer
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_UPDATE_SCAN_PARAMS_REQ,
                         sizeof(updateScanParams),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(updateScanParams) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in Update Scan Params req %p",
                   pwdiUpdateScanParams);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   //
   // Fill updateScanParams from pwdiUpdateScanParams->wdiUpdateScanParamsInfo
   //

   updateScanParams.b11dEnabled    = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.b11dEnabled;
   updateScanParams.b11dResolved   = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.b11dResolved;

   updateScanParams.ucChannelCount =
     (pwdiUpdateScanParams->wdiUpdateScanParamsInfo.ucChannelCount <
     WLAN_HAL_PNO_MAX_NETW_CHANNELS)?
     pwdiUpdateScanParams->wdiUpdateScanParamsInfo.ucChannelCount :
     WLAN_HAL_PNO_MAX_NETW_CHANNELS;

   wpalMemoryCopy( updateScanParams.aChannels,
                   pwdiUpdateScanParams->wdiUpdateScanParamsInfo.aChannels,
                   updateScanParams.ucChannelCount);


   updateScanParams.usActiveMinChTime  = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.usActiveMinChTime;
   updateScanParams.usActiveMaxChTime  = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.usActiveMaxChTime;
   updateScanParams.usPassiveMinChTime = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.usPassiveMinChTime;
   updateScanParams.usPassiveMaxChTime = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.usPassiveMaxChTime;
   updateScanParams.cbState            = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.cbState;

   wpalMemoryCopy( pSendBuffer+usDataOffset,
                   &updateScanParams,
                   sizeof(updateScanParams));

   pWDICtx->wdiReqStatusCB     = pwdiUpdateScanParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiUpdateScanParams->pUserData;

   WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_INFO,
               "End Update Scan Parameters Old Style");

   /*Set the output values*/
   *ppSendBuffer = pSendBuffer;
   *pSize        = usSendSize;

   return WDI_STATUS_SUCCESS;
}

/**
 @brief Process Update Scan Params function

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_PackUpdateScanParamsReqEx
(
  WDI_ControlBlockType*         pWDICtx,
  WDI_UpdateScanParamsInfoType* pwdiUpdateScanParams,
  wpt_uint8**                   ppSendBuffer,
  wpt_uint16*                   pSize
)
{
   wpt_uint8*                    pSendBuffer           = NULL;
   wpt_uint16                    usDataOffset          = 0;
   wpt_uint16                    usSendSize            = 0;
   tUpdateScanParamsEx           updateScanParams = {0};


   /*-----------------------------------------------------------------------
     Get message buffer
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_UPDATE_SCAN_PARAMS_REQ,
                         sizeof(updateScanParams),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(updateScanParams) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in Update Scan Params Ex req %p",
                  pwdiUpdateScanParams);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   //
   // Fill updateScanParams from pwdiUpdateScanParams->wdiUpdateScanParamsInfo
   //

   updateScanParams.b11dEnabled    = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.b11dEnabled;
   updateScanParams.b11dResolved   = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.b11dResolved;

   updateScanParams.ucChannelCount =
     (pwdiUpdateScanParams->wdiUpdateScanParamsInfo.ucChannelCount <
     WLAN_HAL_PNO_MAX_NETW_CHANNELS_EX)?
     pwdiUpdateScanParams->wdiUpdateScanParamsInfo.ucChannelCount :
     WLAN_HAL_PNO_MAX_NETW_CHANNELS_EX;

   wpalMemoryCopy( updateScanParams.aChannels,
                   pwdiUpdateScanParams->wdiUpdateScanParamsInfo.aChannels,
                   updateScanParams.ucChannelCount);


   updateScanParams.usActiveMinChTime  = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.usActiveMinChTime;
   updateScanParams.usActiveMaxChTime  = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.usActiveMaxChTime;
   updateScanParams.usPassiveMinChTime = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.usPassiveMinChTime;
   updateScanParams.usPassiveMaxChTime = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.usPassiveMaxChTime;
   updateScanParams.cbState            = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.cbState;

   wpalMemoryCopy( pSendBuffer+usDataOffset,
                   &updateScanParams,
                   sizeof(updateScanParams));

   pWDICtx->wdiReqStatusCB     = pwdiUpdateScanParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiUpdateScanParams->pUserData;

   /*Set the output values*/
   *ppSendBuffer = pSendBuffer;
   *pSize        = usSendSize;

   return WDI_STATUS_SUCCESS;
}

/**
 @brief Process Update Scan Params function

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessUpdateScanParamsReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_UpdateScanParamsInfoType* pwdiUpdateScanParams  = NULL;
   WDI_UpdateScanParamsCb        wdiUpdateScanParamsCb = NULL;
   wpt_uint8*                    pSendBuffer           = NULL;
   wpt_uint16                    usSendSize            = 0;
   WDI_Status                    wdiStatus;

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiUpdateScanParams = (WDI_UpdateScanParamsInfoType*)pEventData->pEventData)) ||
       ( NULL == (wdiUpdateScanParamsCb   = (WDI_UpdateScanParamsCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_INFO,
               "Begin WDI Update Scan Parameters");

   //
   // Fill updateScanParams from pwdiUpdateScanParams->wdiUpdateScanParamsInfo
   //
   if ( pWDICtx->wlanVersion.revision < 1 ) 
   {
     wdiStatus = WDI_PackUpdateScanParamsReq( pWDICtx, pwdiUpdateScanParams,
                                  &pSendBuffer, &usSendSize);
   }
   else
   {
     wdiStatus = WDI_PackUpdateScanParamsReqEx( pWDICtx, pwdiUpdateScanParams,
                                  &pSendBuffer, &usSendSize);
   }
   
   if(WDI_STATUS_SUCCESS != wdiStatus)
   {
        //memory allocation failed
        return WDI_STATUS_E_FAILURE;
   }

   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiUpdateScanParamsCb, pEventData->pUserData, 
                        WDI_UPDATE_SCAN_PARAMS_RESP);
}

/**
 @brief Process Update Channel Params function

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessUpdateChannelParamsReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_UpdateChReqParamsType     *pwdiUpdateChanListParams  = NULL;
   WDI_UpdateChannelRspCb        wdiUpdateChanParamsCb = NULL;
   wpt_uint8*                    pSendBuffer           = NULL;
   wpt_uint16                    usDataOffset          = 0;
   wpt_uint16                    usSendSize            = 0;
   tUpdateChannelReqType         *updateChannelParams;
   wpt_uint32                    usUpdateChanParamSize;
   wpt_uint8                     num_channels = 0;

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiUpdateChanListParams = (WDI_UpdateChReqParamsType*)pEventData->pEventData)) ||
       ( NULL == (wdiUpdateChanParamsCb = (WDI_UpdateChannelRspCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }
   num_channels = pwdiUpdateChanListParams->wdiUpdateChanParams.numchan;
   usUpdateChanParamSize =  sizeof(tUpdateChannelReqType);

   /*-----------------------------------------------------------------------
     Get message buffer
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                   WDI_UPDATE_CHAN_REQ, usUpdateChanParamSize,
                   &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + usUpdateChanParamSize)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in Update Channel Params req %p",
                   pwdiUpdateChanListParams);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }
   updateChannelParams = (tUpdateChannelReqType *)(pSendBuffer + usDataOffset);

   updateChannelParams->numChan = num_channels;
   wpalMemoryCopy(&updateChannelParams->chanParam,
           pwdiUpdateChanListParams->wdiUpdateChanParams.pchanParam,
           sizeof(WDI_UpdateChannelReqinfoType) * num_channels);

   pWDICtx->wdiReqStatusCB     = pwdiUpdateChanListParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiUpdateChanListParams->pUserData;

   /*-------------------------------------------------------------------------
     Send Update channel request to fw
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg(pWDICtx, pSendBuffer, usSendSize,
                        wdiUpdateChanParamsCb, pEventData->pUserData,
                        WDI_UPDATE_CHAN_RESP);
}

/**
 @brief Process Preferred Network Found Indication function

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessPrefNetworkFoundInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_LowLevelIndType   wdiInd;
  tpPrefNetwFoundParams pNetwFoundParams;
  wpt_uint32 msgsize;


  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT( 0 );
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
    Extract indication and send it to UMAC
  -------------------------------------------------------------------------*/
  pNetwFoundParams = (tpPrefNetwFoundParams)(pEventData->pEventData);

  msgsize = sizeof(tPrefNetwFoundParams) + pNetwFoundParams->frameLength;
  wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.pData =
      (wpt_uint8 *)wpalMemoryAllocate(msgsize);

  if (NULL == wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.pData)
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: fail to allocate memory", __func__);
     return WDI_STATUS_MEM_FAILURE;
  }

  wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.ssId.ucLength =
     (pNetwFoundParams->ssId.length < 32 )?
      pNetwFoundParams->ssId.length : 32;
  wpalMemoryCopy( wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.ssId.sSSID,
      pNetwFoundParams->ssId.ssId,
      wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.ssId.ucLength);
  wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.rssi = pNetwFoundParams->rssi;
  wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.frameLength =
      pNetwFoundParams->frameLength;
  wpalMemoryCopy( wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.pData,
      (wpt_uint8 *)pEventData->pEventData + sizeof(tPrefNetwFoundParams),
      pNetwFoundParams->frameLength);

  /*Fill in the indication parameters*/
  wdiInd.wdiIndicationType = WDI_PREF_NETWORK_FOUND_IND;

  // DEBUG
  WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
              "[PNO WDI] PREF_NETWORK_FOUND_IND Type (%d) data (SSID=%.*s, LENGTH=%u,  RSSI=%u)",
              wdiInd.wdiIndicationType,
              wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.ssId.ucLength,
              wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.ssId.sSSID,
              wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.ssId.ucLength,
              wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.rssi );

  if ( pWDICtx->wdiLowLevelIndCB )
  {
    /*Notify UMAC*/
    pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
  }

  return WDI_STATUS_SUCCESS;
}

/**
 @brief Process PNO Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetPreferredNetworkRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_Status           wdiStatus;
   eHalStatus           halStatus;
   WDI_PNOScanCb       wdiPNOScanCb   = NULL;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData ))
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }


   wdiPNOScanCb = (WDI_PNOScanCb)pWDICtx->pfncRspCB;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   halStatus = *((eHalStatus*)pEventData->pEventData);
   wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

   /*Notify UMAC*/
   wdiPNOScanCb(wdiStatus, pWDICtx->pRspCBUserData);

   return WDI_STATUS_SUCCESS;
}/*WDI_ProcessSetPreferredNetworkRsp*/

/**
 @brief Process RSSI Filter Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetRssiFilterRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_Status           wdiStatus;
   eHalStatus           halStatus;
   WDI_RssiFilterCb     wdiRssiFilterCb;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData ))
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wdiRssiFilterCb = (WDI_RssiFilterCb)pWDICtx->pfncRspCB;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   halStatus = *((eHalStatus*)pEventData->pEventData);
   wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

   /*Notify UMAC*/
   wdiRssiFilterCb(wdiStatus, pWDICtx->pRspCBUserData);

   return WDI_STATUS_SUCCESS;
}/*WDI_ProcessSetRssiFilterRsp*/

/**
 @brief Process Update Scan Params Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessUpdateScanParamsRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_Status             wdiStatus;
   tUpdateScanParamsResp  halUpdScanParams;
   WDI_UpdateScanParamsCb wdiUpdateScanParamsCb   = NULL;
   wpt_uint32             uStatus;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData ))
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
              "%s: Process UPD scan params ptr : %p",
              __func__, pEventData->pEventData);

  wdiUpdateScanParamsCb = (WDI_UpdateScanParamsCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
  wpalMemoryCopy( (void *)&halUpdScanParams.status,
                  pEventData->pEventData,
                  sizeof(halUpdScanParams.status));

  uStatus  = halUpdScanParams.status;

  /*Extract PNO version - 1st bit of the status */
  pWDICtx->wdiPNOVersion = (uStatus & WDI_PNO_VERSION_MASK)? 1:0;

  /*Remove version bit*/
  uStatus = uStatus & ( ~(WDI_PNO_VERSION_MASK));

  wdiStatus   =   WDI_HAL_2_WDI_STATUS(uStatus);

  WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_INFO,
              "UPD Scan Parameters rsp with status: %d",
              halUpdScanParams.status);

  /*Notify UMAC*/
  wdiUpdateScanParamsCb(wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}
#endif // FEATURE_WLAN_SCAN_PNO

#ifdef WLAN_FEATURE_PACKET_FILTERING
WDI_Status
WDI_8023MulticastListReq
(
  WDI_RcvFltPktSetMcListReqParamsType*  pwdiRcvFltPktSetMcListReqInfo,
  WDI_8023MulticastListCb               wdi8023MulticastListCallback,
  void*                                 pUserData
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
             "%s", __func__);

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_8023_MULTICAST_LIST_REQ;
   wdiEventData.pEventData      = pwdiRcvFltPktSetMcListReqInfo;
   wdiEventData.uEventDataSize  = sizeof(*pwdiRcvFltPktSetMcListReqInfo);
   wdiEventData.pCBfnc          = wdi8023MulticastListCallback;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

WDI_Status
WDI_ReceiveFilterSetFilterReq
(
  WDI_SetRcvPktFilterReqParamsType* pwdiSetRcvPktFilterReqInfo,
  WDI_ReceiveFilterSetFilterCb      wdiReceiveFilterSetFilterCallback,
  void*                             pUserData
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
             "%s",__func__);

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_RECEIVE_FILTER_SET_FILTER_REQ;
   wdiEventData.pEventData      = pwdiSetRcvPktFilterReqInfo;
   wdiEventData.uEventDataSize  = sizeof(*pwdiSetRcvPktFilterReqInfo) +
                                  (pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.numFieldParams - 1)
                                  * sizeof(WDI_RcvPktFilterFieldParams);
   wdiEventData.pCBfnc          = wdiReceiveFilterSetFilterCallback;
   wdiEventData.pUserData       = pUserData;


   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

WDI_Status
WDI_FilterMatchCountReq
(
  WDI_RcvFltPktMatchCntReqParamsType* pwdiRcvFltPktMatchCntReqInfo,
  WDI_FilterMatchCountCb              wdiFilterMatchCountCallback,
  void*                               pUserData
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
             "%s",__func__);

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ;
   wdiEventData.pEventData      = pwdiRcvFltPktMatchCntReqInfo;
   wdiEventData.uEventDataSize  = sizeof(*pwdiRcvFltPktMatchCntReqInfo);
   wdiEventData.pCBfnc          = wdiFilterMatchCountCallback;
   wdiEventData.pUserData       = pUserData;


   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

WDI_Status
WDI_ReceiveFilterClearFilterReq
(
  WDI_RcvFltPktClearReqParamsType*  pwdiRcvFltPktClearReqInfo,
  WDI_ReceiveFilterClearFilterCb    wdiReceiveFilterClearFilterCallback,
  void*                             pUserData
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
             "%s",__func__);

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_RECEIVE_FILTER_CLEAR_FILTER_REQ;
   wdiEventData.pEventData      = pwdiRcvFltPktClearReqInfo;
   wdiEventData.uEventDataSize  = sizeof(*pwdiRcvFltPktClearReqInfo);
   wdiEventData.pCBfnc          = wdiReceiveFilterClearFilterCallback;
   wdiEventData.pUserData       = pUserData;


   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief Process 8023 Multicast List Request function

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_Process8023MulticastListReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_RcvFltPktSetMcListReqParamsType* pwdiFltPktSetMcListReqParamsType  = NULL;
   WDI_8023MulticastListCb    wdi8023MulticastListCb = NULL;
   wpt_uint8*                 pSendBuffer           = NULL;
   wpt_uint16                 usDataOffset          = 0;
   wpt_uint16                 usSendSize            = 0;
   tpHalRcvFltMcAddrListType  pRcvFltMcAddrListType;
   wpt_uint8                  i;
   wpt_uint8                  ucCurrentBSSSesIdx = 0;
   WDI_BSSSessionType*        pBSSSes = NULL;

   WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
             "%s",__func__);

   pRcvFltMcAddrListType = wpalMemoryAllocate(sizeof(tHalRcvFltMcAddrListType)) ;
   if( NULL == pRcvFltMcAddrListType )
   {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                 "Failed to alloc in WDI_Process8023MulticastListReq");
     return WDI_STATUS_E_FAILURE; 
   }

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiFltPktSetMcListReqParamsType =
       (WDI_RcvFltPktSetMcListReqParamsType*)pEventData->pEventData)) ||
       ( NULL == (wdi8023MulticastListCb =
       (WDI_8023MulticastListCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      wpalMemoryFree(pRcvFltMcAddrListType);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, 
                            pwdiFltPktSetMcListReqParamsType->mcAddrList.bssId, 
                            &pBSSSes);  
   if ( NULL == pBSSSes )
   {
       WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 " %s : Association for this BSSID does not exist",__func__);
       wpalMemoryFree(pRcvFltMcAddrListType);   
       return WDI_STATUS_E_FAILURE; 
   }

   /*-----------------------------------------------------------------------
     Get message buffer
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                         WDI_8023_MULTICAST_LIST_REQ,
                         sizeof(tHalRcvFltMcAddrListType),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(tHalRcvFltMcAddrListType))))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in "
                  "WDI_Process8023MulticastListReq() %p %p %p",
                  pEventData, pwdiFltPktSetMcListReqParamsType,
                  wdi8023MulticastListCb);
      wpalMemoryFree(pRcvFltMcAddrListType);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   pRcvFltMcAddrListType->cMulticastAddr = 
       pwdiFltPktSetMcListReqParamsType->mcAddrList.ulMulticastAddrCnt;
   for( i = 0; i < pRcvFltMcAddrListType->cMulticastAddr; i++ )
   {
      wpalMemoryCopy(pRcvFltMcAddrListType->multicastAddr[i],
                 pwdiFltPktSetMcListReqParamsType->mcAddrList.multicastAddr[i],
                 sizeof(tSirMacAddr));
   }

   pRcvFltMcAddrListType->bssIdx = pBSSSes->ucBSSIdx;
   wpalMemoryCopy( pSendBuffer+usDataOffset, 
                   pRcvFltMcAddrListType, 
                   sizeof(tHalRcvFltMcAddrListType)); 

   pWDICtx->wdiReqStatusCB     = pwdiFltPktSetMcListReqParamsType->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiFltPktSetMcListReqParamsType->pUserData;


   wpalMemoryFree(pRcvFltMcAddrListType);
   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdi8023MulticastListCb, pEventData->pUserData,
                        WDI_8023_MULTICAST_LIST_RESP);
}

/**
 @brief Process Receive Filter Set Filter Request function

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessReceiveFilterSetFilterReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_SetRcvPktFilterReqParamsType* pwdiSetRcvPktFilterReqInfo  = NULL;
   WDI_ReceiveFilterSetFilterCb      wdiReceiveFilterSetFilterCb = NULL;
   wpt_uint8*                 pSendBuffer           = NULL;
   wpt_uint16                 usDataOffset          = 0;
   wpt_uint16                 usSendSize            = 0;
   wpt_uint32                 usRcvPktFilterCfgSize;
   tHalRcvPktFilterCfgType    *pRcvPktFilterCfg = NULL;
   wpt_uint8                  i;
   wpt_uint8                  ucCurrentBSSSesIdx = 0;
   WDI_BSSSessionType*        pBSSSes = NULL;
   tHalSessionizedRcvPktFilterCfgType *pSessRcvPktFilterCfg = NULL;
   wpt_uint32                 usSessRcvPktFilterCfgSize;

   WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
             "%s",__func__);

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiSetRcvPktFilterReqInfo =
       (WDI_SetRcvPktFilterReqParamsType*)pEventData->pEventData)) ||
       ( NULL == (wdiReceiveFilterSetFilterCb =
       (WDI_ReceiveFilterSetFilterCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, 
                            pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.bssId, 
                            &pBSSSes);  
   if ( NULL == pBSSSes )
   {
       WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 " %s : Association for this BSSID does not exist",__func__);
       return WDI_STATUS_E_FAILURE; 
   }

   if( WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION) )
   {

        usSessRcvPktFilterCfgSize = sizeof(tHalSessionizedRcvPktFilterCfgType) + 
            ((pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.numFieldParams - 1)
             * sizeof(tHalSessionizedRcvPktFilterCfgType));

       pSessRcvPktFilterCfg = (tHalSessionizedRcvPktFilterCfgType *)wpalMemoryAllocate(
                                                   usSessRcvPktFilterCfgSize);

       if(NULL == pSessRcvPktFilterCfg)
       {
         WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Failed to allocate memory for "
                 "tHalRcvPktFilterCfgType: %p %p %p ",
                 __func__, pWDICtx, pEventData, pEventData->pEventData);
         WDI_ASSERT(0);
         return WDI_STATUS_E_FAILURE;
       }

       wpalMemoryZero(pSessRcvPktFilterCfg, usSessRcvPktFilterCfgSize);
       
        /*-----------------------------------------------------------------------
          Get message buffer
        -----------------------------------------------------------------------*/

       if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_RECEIVE_FILTER_SET_FILTER_REQ,
                              usSessRcvPktFilterCfgSize,
                              &pSendBuffer, &usDataOffset, &usSendSize))||
            ( usSendSize < (usDataOffset + usSessRcvPktFilterCfgSize)))
        {
           WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                       "Unable to get send buffer in "
                       "WDI_ProcessReceiveFilterSetFilterReq() %p %p %p",
                       pEventData, pwdiSetRcvPktFilterReqInfo,
                       wdiReceiveFilterSetFilterCb);
           WDI_ASSERT(0);
           wpalMemoryFree(pSessRcvPktFilterCfg);
           return WDI_STATUS_E_FAILURE;
        }

        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                   "UsData Off %d UsSend %d cfg %p",usDataOffset,
                   usSendSize,pSessRcvPktFilterCfg);
       
        pSessRcvPktFilterCfg->filterId = pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.filterId;
        pSessRcvPktFilterCfg->filterType = pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.filterType;
        pSessRcvPktFilterCfg->numParams = pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.numFieldParams;
        pSessRcvPktFilterCfg->coleasceTime = pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.coalesceTime;

        pSessRcvPktFilterCfg->bssIdx = pBSSSes->ucBSSIdx;

        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                   "Out: FID %d FT %d",pSessRcvPktFilterCfg->filterId,
                   pSessRcvPktFilterCfg->filterType);
        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                   "NParams %d CT %d",pSessRcvPktFilterCfg->numParams, 
                   pSessRcvPktFilterCfg->coleasceTime);
       
        for ( i = 0; i < pSessRcvPktFilterCfg->numParams; i++ )
        {
            pSessRcvPktFilterCfg->paramsData[i].protocolLayer =
                pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].protocolLayer;
            pSessRcvPktFilterCfg->paramsData[i].cmpFlag =
                pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].cmpFlag;
            pSessRcvPktFilterCfg->paramsData[i].dataOffset =
                pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].dataOffset;
             pSessRcvPktFilterCfg->paramsData[i].dataLength =
                 pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].dataLength;
       
            wpalMemoryCopy(&pSessRcvPktFilterCfg->paramsData[i].compareData,
                         &pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].compareData,
                         8);
            wpalMemoryCopy(&pSessRcvPktFilterCfg->paramsData[i].dataMask,
                         &pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].dataMask,
                         8);
       
           WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                "Out:Proto %d Comp Flag %d",
                pSessRcvPktFilterCfg->paramsData[i].protocolLayer,
                pSessRcvPktFilterCfg->paramsData[i].cmpFlag);

           WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                "Data Offset %d Data Len %d",
                pSessRcvPktFilterCfg->paramsData[i].dataOffset,
                pSessRcvPktFilterCfg->paramsData[i].dataLength);
       
           WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                "CData: %d:%d:%d:%d:%d:%d",
                pSessRcvPktFilterCfg->paramsData[i].compareData[0],
                pSessRcvPktFilterCfg->paramsData[i].compareData[1],
                pSessRcvPktFilterCfg->paramsData[i].compareData[2],
                pSessRcvPktFilterCfg->paramsData[i].compareData[3],
                pSessRcvPktFilterCfg->paramsData[i].compareData[4],
                pSessRcvPktFilterCfg->paramsData[i].compareData[5]);
       
           WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                "MData: %d:%d:%d:%d:%d:%d",
                pSessRcvPktFilterCfg->paramsData[i].dataMask[0],
                pSessRcvPktFilterCfg->paramsData[i].dataMask[1],
                pSessRcvPktFilterCfg->paramsData[i].dataMask[2],
                pSessRcvPktFilterCfg->paramsData[i].dataMask[3],
                pSessRcvPktFilterCfg->paramsData[i].dataMask[4],
                pSessRcvPktFilterCfg->paramsData[i].dataMask[5]);
        }
       
        wpalMemoryCopy( pSendBuffer+usDataOffset,
                        pSessRcvPktFilterCfg,
                        usSessRcvPktFilterCfgSize);
       
       
        pWDICtx->wdiReqStatusCB     = pwdiSetRcvPktFilterReqInfo->wdiReqStatusCB;
        pWDICtx->pReqStatusUserData = pwdiSetRcvPktFilterReqInfo->pUserData;

        wpalMemoryFree(pSessRcvPktFilterCfg);

   }
   /*If SLM_SESSIONIZATION is not supported then do this */
   else
   {
       usRcvPktFilterCfgSize = sizeof(tHalRcvPktFilterCfgType) + 
            ((pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.numFieldParams - 1)
            * sizeof(tHalRcvPktFilterParams));

      pRcvPktFilterCfg = (tHalRcvPktFilterCfgType *)wpalMemoryAllocate(
                                              usRcvPktFilterCfgSize);

      if(NULL == pRcvPktFilterCfg)
      {
            WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Failed to allocate memory for "
                "tHalRcvPktFilterCfgType: %p %p %p ",
                __func__, pWDICtx, pEventData, pEventData->pEventData);
            WDI_ASSERT(0);
            return WDI_STATUS_E_FAILURE;
      }

      wpalMemoryZero(pRcvPktFilterCfg, usRcvPktFilterCfgSize);

       /*-----------------------------------------------------------------------
         Get message buffer
       -----------------------------------------------------------------------*/
        if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_RECEIVE_FILTER_SET_FILTER_REQ,
                         usRcvPktFilterCfgSize,
                         &pSendBuffer, &usDataOffset, &usSendSize))||
            ( usSendSize < (usDataOffset + usRcvPktFilterCfgSize)))
        {
              WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in "
                  "WDI_ProcessReceiveFilterSetFilterReq() %p %p %p",
                  pEventData, pwdiSetRcvPktFilterReqInfo,
                  wdiReceiveFilterSetFilterCb);
              WDI_ASSERT(0);
              wpalMemoryFree(pRcvPktFilterCfg);
              return WDI_STATUS_E_FAILURE;
        }

       WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
              "UsData Off %d UsSend %d cfg %d",usDataOffset,
              usSendSize,usRcvPktFilterCfgSize);

       pRcvPktFilterCfg->filterId = pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.filterId;
       pRcvPktFilterCfg->filterType = pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.filterType;
       pRcvPktFilterCfg->numParams = pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.numFieldParams;
       pRcvPktFilterCfg->coalesceTime = pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.coalesceTime;

       WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
              "Out: FID %d FT %d",pRcvPktFilterCfg->filterId,
              pRcvPktFilterCfg->filterType);
       WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
              "NParams %d CT %d",pRcvPktFilterCfg->numParams, 
              pRcvPktFilterCfg->coalesceTime);

       for ( i = 0; i < pRcvPktFilterCfg->numParams; i++ )
       {
           pRcvPktFilterCfg->paramsData[i].protocolLayer =
               pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].protocolLayer;
           pRcvPktFilterCfg->paramsData[i].cmpFlag =
               pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].cmpFlag;
           pRcvPktFilterCfg->paramsData[i].dataOffset =
               pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].dataOffset;
           pRcvPktFilterCfg->paramsData[i].dataLength =
               pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].dataLength;

           wpalMemoryCopy(&pRcvPktFilterCfg->paramsData[i].compareData,
                    &pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].compareData,
                    8);
           wpalMemoryCopy(&pRcvPktFilterCfg->paramsData[i].dataMask,
                    &pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].dataMask,
                    8);

          WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
           "Out:Proto %d Comp Flag %d",
           pRcvPktFilterCfg->paramsData[i].protocolLayer,
           pRcvPktFilterCfg->paramsData[i].cmpFlag);

          WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
               "Data Offset %d Data Len %d",
               pRcvPktFilterCfg->paramsData[i].dataOffset,
               pRcvPktFilterCfg->paramsData[i].dataLength);

          WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
               "CData: %d:%d:%d:%d:%d:%d",
               pRcvPktFilterCfg->paramsData[i].compareData[0],
               pRcvPktFilterCfg->paramsData[i].compareData[1],
               pRcvPktFilterCfg->paramsData[i].compareData[2],
               pRcvPktFilterCfg->paramsData[i].compareData[3],
               pRcvPktFilterCfg->paramsData[i].compareData[4],
               pRcvPktFilterCfg->paramsData[i].compareData[5]);

          WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "MData: %d:%d:%d:%d:%d:%d",
               pRcvPktFilterCfg->paramsData[i].dataMask[0],
               pRcvPktFilterCfg->paramsData[i].dataMask[1],
               pRcvPktFilterCfg->paramsData[i].dataMask[2],
               pRcvPktFilterCfg->paramsData[i].dataMask[3],
               pRcvPktFilterCfg->paramsData[i].dataMask[4],
               pRcvPktFilterCfg->paramsData[i].dataMask[5]);
        }

       wpalMemoryCopy( pSendBuffer+usDataOffset,
                   pRcvPktFilterCfg,
                   usRcvPktFilterCfgSize);


       pWDICtx->wdiReqStatusCB     = pwdiSetRcvPktFilterReqInfo->wdiReqStatusCB;
       pWDICtx->pReqStatusUserData = pwdiSetRcvPktFilterReqInfo->pUserData;

       WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
                 "%s",__func__);
       wpalMemoryFree(pRcvPktFilterCfg);
  }
   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiReceiveFilterSetFilterCb, pEventData->pUserData,
                        WDI_RECEIVE_FILTER_SET_FILTER_RESP);
}

/**
 @brief Process Packet Filter Match Count Request function

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessFilterMatchCountReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_RcvFltPktMatchCntReqParamsType*    pwdiRcvFltPktMatchCntReqParamsType =
                                                                         NULL;
   WDI_FilterMatchCountCb                 wdiFilterMatchCountCb              =
                                                                         NULL;
   wpt_uint8*                             pSendBuffer           = NULL;
   wpt_uint16                             usDataOffset          = 0;
   wpt_uint16                             usSendSize            = 0;
   tHalRcvFltPktMatchCntReqParams         rcvFltPktMatchCntReqParam = {0};
   wpt_uint8                ucCurrentBSSSesIdx  = 0;
   WDI_BSSSessionType*        pBSSSes = NULL;

   WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
             "%s",__func__);

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiRcvFltPktMatchCntReqParamsType =
       (WDI_RcvFltPktMatchCntReqParamsType*)pEventData->pEventData)) ||
       ( NULL == (wdiFilterMatchCountCb =
       (WDI_FilterMatchCountCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, 
                               pwdiRcvFltPktMatchCntReqParamsType->bssId, 
                               &pBSSSes);
   if ( NULL == pBSSSes )
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                    " %s : Association for this BSSID does not exist",__func__);
          return WDI_STATUS_E_FAILURE; 
   }

   /*-----------------------------------------------------------------------
     Get message buffer
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                         WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ,
                         sizeof(tHalRcvFltPktMatchCntReqParams),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(tHalRcvFltPktMatchCntReqParams))))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in "
                  "WDI_ProcessFilterMatchCountReq() %p %p %p",
                  pEventData, pwdiRcvFltPktMatchCntReqParamsType,
                  wdiFilterMatchCountCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   rcvFltPktMatchCntReqParam.bssIdx = pBSSSes->ucBSSIdx;
   wpalMemoryCopy( pSendBuffer+usDataOffset,
                   &rcvFltPktMatchCntReqParam,
                   sizeof(rcvFltPktMatchCntReqParam));

   //
   // Don't need to fill send buffer other than header
   //
   pWDICtx->wdiReqStatusCB     = pwdiRcvFltPktMatchCntReqParamsType->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiRcvFltPktMatchCntReqParamsType->pUserData;


   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiFilterMatchCountCb,
                        pEventData->pUserData,
                        WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_RESP);
}

/**
 @brief Process Receive Filter Clear Filter Request function

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessReceiveFilterClearFilterReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_RcvFltPktClearReqParamsType* pwdiRcvFltPktClearReqParamsType = NULL;
   WDI_ReceiveFilterClearFilterCb   wdiRcvFltPktClearFilterCb       = NULL;
   wpt_uint8*                       pSendBuffer           = NULL;
   wpt_uint16                       usDataOffset          = 0;
   wpt_uint16                       usSendSize            = 0;
   tHalRcvFltPktClearParam          rcvFltPktClearParam;
   wpt_uint8                        ucCurrentSessionId = 0;
   WDI_BSSSessionType*              pBSSSes = NULL;

   WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
             "%s",__func__);

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiRcvFltPktClearReqParamsType =
       (WDI_RcvFltPktClearReqParamsType*)pEventData->pEventData)) ||
       ( NULL == (wdiRcvFltPktClearFilterCb =
       (WDI_ReceiveFilterClearFilterCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   ucCurrentSessionId = WDI_FindAssocSession( pWDICtx, 
                            pwdiRcvFltPktClearReqParamsType->filterClearParam.bssId, 
                            &pBSSSes);  
   if ( NULL == pBSSSes )
   {
       WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 " %s : Association for this BSSID does not exist",__func__);
       return WDI_STATUS_E_FAILURE; 
   }

   /*-----------------------------------------------------------------------
     Get message buffer
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                         WDI_RECEIVE_FILTER_CLEAR_FILTER_REQ,
                         sizeof(tHalRcvFltPktClearParam),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(tHalRcvFltPktClearParam))))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in "
                  "WDI_ProcessReceiveFilterClearFilterReq() %p %p %p",
                  pEventData, pwdiRcvFltPktClearReqParamsType,
                  wdiRcvFltPktClearFilterCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }


   rcvFltPktClearParam.status = pwdiRcvFltPktClearReqParamsType->
                                                    filterClearParam.status;
   rcvFltPktClearParam.filterId = pwdiRcvFltPktClearReqParamsType->
                                                    filterClearParam.filterId;

   rcvFltPktClearParam.bssIdx = pBSSSes->ucBSSIdx;
   wpalMemoryCopy( pSendBuffer+usDataOffset,
                   &rcvFltPktClearParam,
                   sizeof(rcvFltPktClearParam));

   pWDICtx->wdiReqStatusCB     = pwdiRcvFltPktClearReqParamsType->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiRcvFltPktClearReqParamsType->pUserData;


   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiRcvFltPktClearFilterCb, pEventData->pUserData,
                        WDI_RECEIVE_FILTER_CLEAR_FILTER_RESP);
}

/**
 @brief Process 8023 Multicast List Response function

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_Process8023MulticastListRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   eHalStatus           halStatus;
   WDI_8023MulticastListCb wdi8023MulticastListCb;
   tHalRcvFltPktSetMcListRspType halRcvFltPktSetMcListRsp;
   WDI_RcvFltPktSetMcListRspParamsType  wdiRcvFltPktSetMcListRspInfo;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
             "%s",__func__);

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData ))
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wdi8023MulticastListCb = (WDI_8023MulticastListCb)pWDICtx->pfncRspCB;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION))
   {
        wpalMemoryCopy( &halRcvFltPktSetMcListRsp,
                   pEventData->pEventData,
                   sizeof(halRcvFltPktSetMcListRsp));

       wdiRcvFltPktSetMcListRspInfo.wdiStatus =   
                       WDI_HAL_2_WDI_STATUS(halRcvFltPktSetMcListRsp.status);
       wdiRcvFltPktSetMcListRspInfo.bssIdx =   
                       halRcvFltPktSetMcListRsp.bssIdx;
   }
   else
   {
       halStatus = *((eHalStatus*)pEventData->pEventData);
       wdiRcvFltPktSetMcListRspInfo.wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus);
   }

   /*Notify UMAC*/
   wdi8023MulticastListCb(&wdiRcvFltPktSetMcListRspInfo, pWDICtx->pRspCBUserData);

   return WDI_STATUS_SUCCESS;
}

/**
 @brief Process Set Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessReceiveFilterSetFilterRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   eHalStatus           halStatus;
   WDI_ReceiveFilterSetFilterCb wdiReceiveFilterSetFilterCb;
   tHalSetPktFilterRspParams    halSetPktFilterRspParams;
   WDI_SetRcvPktFilterRspParamsType wdiSetRcvPktFilterRspInfo;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
          "%s",__func__);

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData ))
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wdiReceiveFilterSetFilterCb = (WDI_ReceiveFilterSetFilterCb)pWDICtx->
                                                                   pfncRspCB;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION))
   {
        wpalMemoryCopy( &halSetPktFilterRspParams,
                    pEventData->pEventData,
                    sizeof(halSetPktFilterRspParams));

       wdiSetRcvPktFilterRspInfo.bssIdx = halSetPktFilterRspParams.bssIdx;
       wdiSetRcvPktFilterRspInfo.wdiStatus = WDI_HAL_2_WDI_STATUS(halSetPktFilterRspParams.status);
    }
   else
    {
       halStatus = *((eHalStatus*)pEventData->pEventData);
       wdiSetRcvPktFilterRspInfo.wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);
    }
   /*Notify UMAC*/
   wdiReceiveFilterSetFilterCb(&wdiSetRcvPktFilterRspInfo, pWDICtx->pRspCBUserData);

   return WDI_STATUS_SUCCESS;
}

/**
 @brief Process Packet Filter Match Count Response function

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessFilterMatchCountRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   eHalStatus           halStatus;
   WDI_FilterMatchCountCb   wdiFilterMatchCountCb;
   tHalRcvFltPktMatchRspParams  halRcvFltrPktMatachRsp;
   WDI_RcvFltPktMatchCntRspParamsType wdiRcvFltPktMatchRspParams;

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

   WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
             "%s",__func__);

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData ))
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wdiFilterMatchCountCb = (WDI_FilterMatchCountCb)pWDICtx->pfncRspCB;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION))
   {
        wpalMemoryCopy( &halRcvFltrPktMatachRsp,
                   pEventData->pEventData,
                   sizeof(halRcvFltrPktMatachRsp));
            
       wdiRcvFltPktMatchRspParams.wdiStatus = WDI_HAL_2_WDI_STATUS(halRcvFltrPktMatachRsp.status);
       wdiRcvFltPktMatchRspParams.bssIdx = halRcvFltrPktMatachRsp.bssIdx;
   }
   else
   {
       halStatus = *((eHalStatus*)pEventData->pEventData);
       wdiRcvFltPktMatchRspParams.wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);
   }

   /*Notify UMAC*/
   wdiFilterMatchCountCb(&wdiRcvFltPktMatchRspParams, pWDICtx->pRspCBUserData);

   return WDI_STATUS_SUCCESS;
}

/**
 @brief Process Receive Filter Clear Filter Response function

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessReceiveFilterClearFilterRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   eHalStatus           halStatus;
   WDI_ReceiveFilterClearFilterCb wdiReceiveFilterClearFilterCb;
   tHalRcvFltPktClearParam  halRcvFltPktClearRspMsg;
   WDI_RcvFltPktClearRspParamsType wdiRcvFltPktClearRspParamsType;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
             "%s",__func__);

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData ))
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wdiReceiveFilterClearFilterCb = (WDI_ReceiveFilterClearFilterCb)pWDICtx->
                                                                 pfncRspCB;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION))
   {
       wpalMemoryCopy( &halRcvFltPktClearRspMsg,
                   pEventData->pEventData,
                   sizeof(halRcvFltPktClearRspMsg));

       wdiRcvFltPktClearRspParamsType.wdiStatus =   
                       WDI_HAL_2_WDI_STATUS(halRcvFltPktClearRspMsg.status);
       wdiRcvFltPktClearRspParamsType.bssIdx =   
                       halRcvFltPktClearRspMsg.bssIdx;
   }
   else
   {
       halStatus = *((eHalStatus*)pEventData->pEventData);
       wdiRcvFltPktClearRspParamsType.wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);
    }

   /*Notify UMAC*/
   wdiReceiveFilterClearFilterCb(&wdiRcvFltPktClearRspParamsType, pWDICtx->pRspCBUserData);

   return WDI_STATUS_SUCCESS;
}
#endif // WLAN_FEATURE_PACKET_FILTERING

/**
 @brief Process Shutdown Rsp function
        There is no shutdown response comming from HAL
        - function just kept for simmetry

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessShutdownRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  /*There is no shutdown response comming from HAL - function just kept for
  simmetry */
  WDI_ASSERT(0);
  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessShutdownRsp*/

/**
 @brief WDI_SetPowerParamsReq

 @param pwdiPowerParamsReqParams: the Set Power Params as
                      specified by the Device Interface

        wdiPowerParamsCb: callback for passing back the response
        of the Set Power Params operation received from the
        device

        pUserData: user data will be passed back with the
        callback

 @return Result of the function call
*/
WDI_Status
WDI_SetPowerParamsReq
(
  WDI_SetPowerParamsReqParamsType* pwdiPowerParamsReqParams,
  WDI_SetPowerParamsCb             wdiPowerParamsCb,
  void*                            pUserData
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_SET_POWER_PARAMS_REQ;
   wdiEventData.pEventData      = pwdiPowerParamsReqParams;
   wdiEventData.uEventDataSize  = sizeof(*pwdiPowerParamsReqParams);
   wdiEventData.pCBfnc          = wdiPowerParamsCb;
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}/*WDI_SetPowerParamsReq*/

/**
 @brief Process Set Power Params Request function

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetPowerParamsReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_SetPowerParamsReqParamsType* pwdiPowerParamsReqParams = NULL;
   WDI_SetPowerParamsCb             wdiPowerParamsCb         = NULL;
   wpt_uint8*                       pSendBuffer              = NULL;
   wpt_uint16                       usDataOffset             = 0;
   wpt_uint16                       usSendSize               = 0;
   tSetPowerParamsType              powerParams;

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiPowerParamsReqParams = (WDI_SetPowerParamsReqParamsType*)pEventData->pEventData)) ||
       ( NULL == (wdiPowerParamsCb   = (WDI_SetPowerParamsCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   /*-----------------------------------------------------------------------
     Get message buffer
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_POWER_PARAMS_REQ,
                         sizeof(powerParams),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(powerParams) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in Set PNO req %p %p %p",
                  pEventData, pwdiPowerParamsReqParams, wdiPowerParamsCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

  /*  Ignore DTIM */
  powerParams.uIgnoreDTIM =
    pwdiPowerParamsReqParams->wdiSetPowerParamsInfo.uIgnoreDTIM;

  /*DTIM Period*/
  powerParams.uDTIMPeriod =
    pwdiPowerParamsReqParams->wdiSetPowerParamsInfo.uDTIMPeriod;

  /* Listen Interval */
  powerParams.uListenInterval=
    pwdiPowerParamsReqParams->wdiSetPowerParamsInfo.uListenInterval;

  /* Broadcast Multicas Filter  */
  powerParams.uBcastMcastFilter =
    pwdiPowerParamsReqParams->wdiSetPowerParamsInfo.uBcastMcastFilter;

  /* Beacon Early Termination */
  powerParams.uEnableBET =
    pwdiPowerParamsReqParams->wdiSetPowerParamsInfo.uEnableBET;

  /* Beacon Early Termination Interval */
  powerParams.uBETInterval =
    pwdiPowerParamsReqParams->wdiSetPowerParamsInfo.uBETInterval;

  /* MAX LI for modulated DTIM */
  powerParams.uMaxLIModulatedDTIM =
  pwdiPowerParamsReqParams->wdiSetPowerParamsInfo.uMaxLIModulatedDTIM;

   wpalMemoryCopy( pSendBuffer+usDataOffset,
                   &powerParams,
                   sizeof(powerParams));

   pWDICtx->wdiReqStatusCB     = pwdiPowerParamsReqParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiPowerParamsReqParams->pUserData;

   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiPowerParamsCb, pEventData->pUserData, WDI_SET_POWER_PARAMS_RESP);
}

/**
 @brief Process Power Params Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetPowerParamsRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_Status           wdiStatus;
   eHalStatus           halStatus;
   WDI_SetPowerParamsCb             wdiPowerParamsCb;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData ))
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wdiPowerParamsCb = (WDI_SetPowerParamsCb)pWDICtx->pfncRspCB;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   halStatus = *((eHalStatus*)pEventData->pEventData);
   wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

   /*Notify UMAC*/
   wdiPowerParamsCb(wdiStatus, pWDICtx->pRspCBUserData);

   return WDI_STATUS_SUCCESS;
}/*WDI_ProcessSetPowerParamsRsp*/

/**
 @brief WDI_dhcpStartInd
        Host will send an event to the FW when DHCP is initiated

 @param
        WDI_DHCPInd: DHCP Indication
 @see
 @return Result of the function call
*/
WDI_Status
WDI_dhcpStartInd
(
  WDI_DHCPInd *wdiDHCPInd
)
{
   WDI_EventInfoType   wdiEventData;

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

      return WDI_STATUS_E_NOT_ALLOWED;
   }

   wdiEventData.wdiRequest      = WDI_DHCP_START_IND;
   wdiEventData.pEventData      = wdiDHCPInd;
   wdiEventData.uEventDataSize  = sizeof(WDI_DHCPInd);
   wdiEventData.pCBfnc          = NULL;
   wdiEventData.pUserData       = NULL;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}


/**
 @brief WDI_dhcpStopInd
        Host will send an event to the FW when DHCP is completed

 @param
        WDI_DHCPInd: DHCP Indication
 @see
 @return Result of the function call
*/
WDI_Status
WDI_dhcpStopInd
(
  WDI_DHCPInd *wdiDHCPInd
)
{
   WDI_EventInfoType   wdiEventData;

   /*------------------------------------------------------------------------
     Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

      return WDI_STATUS_E_NOT_ALLOWED;
   }

   wdiEventData.wdiRequest      = WDI_DHCP_STOP_IND;
   wdiEventData.pEventData      = wdiDHCPInd;
   wdiEventData.uEventDataSize  = sizeof(WDI_DHCPInd);
   wdiEventData.pCBfnc          = NULL;
   wdiEventData.pUserData       = NULL;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}


/**
 @brief Process DHCP Start Indication message and post it to HAL

 @param  pWDICtx:    pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessDHCPStartInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  wpt_uint8*              pSendBuffer        = NULL;
  wpt_uint16              usDataOffset       = 0;
  wpt_uint16              usSendSize         = 0;
  wpt_uint16              usLen              = 0;
  WDI_DHCPInd*            pwdiDHCPInd        = NULL;
  tDHCPInfo*              pDHCPInfo;
  WDI_Status              wdiStatus;


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

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
         "%s", __func__);

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  pwdiDHCPInd = (WDI_DHCPInd*)pEventData->pEventData;
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/

  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                        WDI_DHCP_START_IND,
                        sizeof(tDHCPInfo),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + usLen )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
              "Unable to get send buffer in DHCP Start req %p ",
                pEventData);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pDHCPInfo = (tDHCPInfo*)(pSendBuffer+usDataOffset);
  pDHCPInfo->device_mode = pwdiDHCPInd->device_mode;
  wpalMemoryCopy(pDHCPInfo->macAddr, pwdiDHCPInd->macAddr,
                                        WDI_MAC_ADDR_LEN);

  pWDICtx->pReqStatusUserData = NULL;
  pWDICtx->pfncRspCB = NULL;

 /*-------------------------------------------------------------------------
    Send DHCP Start Indication to HAL
  -------------------------------------------------------------------------*/
  wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize);
  return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC;
}/*WDI_ProcessDHCPStartInd*/

/**
 @brief Process DHCP Stop indication message and post it to HAL

 @param  pWDICtx:    pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessDHCPStopInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  wpt_uint8*              pSendBuffer        = NULL;
  wpt_uint16              usDataOffset       = 0;
  wpt_uint16              usSendSize         = 0;
  wpt_uint16              usLen              = 0;
  WDI_DHCPInd*            pwdiDHCPInd        = NULL;
  tDHCPInfo*              pDHCPInfo;
  WDI_Status              wdiStatus;

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

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
         "%s", __func__);

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/

  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  pwdiDHCPInd = (WDI_DHCPInd*)pEventData->pEventData;
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/

  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                        WDI_DHCP_STOP_IND,
                        sizeof(tDHCPInfo),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + usLen )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
              "Unable to get send buffer in DHCP Start req %p ",
                pEventData);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pDHCPInfo = (tDHCPInfo*)(pSendBuffer+usDataOffset);
  pDHCPInfo->device_mode = pwdiDHCPInd->device_mode;
  wpalMemoryCopy(pDHCPInfo->macAddr, pwdiDHCPInd->macAddr,
                                        WDI_MAC_ADDR_LEN);

  pWDICtx->pReqStatusUserData = NULL;
  pWDICtx->pfncRspCB = NULL;
 /*-------------------------------------------------------------------------
    Send DHCP Stop indication to HAL
  -------------------------------------------------------------------------*/
  wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize);
  return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC;

}/*WDI_ProcessDHCPStopInd*/


#ifdef WLAN_FEATURE_GTK_OFFLOAD
/**
 @brief WDI_GTKOffloadReq will be called when the upper MAC 
        wants to set GTK Rekey Counter while in power save. Upon
        the call of this API the WLAN DAL will pack and send a
        HAL GTK offload request message to the lower RIVA
        sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state. 

 WDI_PostAssocReq must have been called.

 @param pwdiGtkOffloadParams: the GTK offload as specified 
                      by the Device Interface
  
        wdiGtkOffloadCb: callback for passing back the response
        of the GTK offload operation received from the device
  
        pUserData: user data will be passed back with the
        callback 
  
 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status 
WDI_GTKOffloadReq
(
  WDI_GtkOffloadReqMsg*      pwdiGtkOffloadReqMsg,
  WDI_GtkOffloadCb           wdiGtkOffloadCb,
  void*                      pUserData
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check 
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED; 
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_GTK_OFFLOAD_REQ;
   wdiEventData.pEventData      = pwdiGtkOffloadReqMsg; 
   wdiEventData.uEventDataSize  = sizeof(*pwdiGtkOffloadReqMsg);
   wdiEventData.pCBfnc          = wdiGtkOffloadCb; 
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}


/**
 @brief WDI_GTKOffloadGetInfoReq will be called when the upper 
          MAC wants to get GTK Rekey Counter while in power save.
          Upon the call of this API the WLAN DAL will pack and
          send a HAL GTK offload request message to the lower RIVA
        sub-system if DAL is in state STARTED.

        In state BUSY this request will be queued. Request won't
        be allowed in any other state. 

 WDI_PostAssocReq must have been called.

 @param pwdiGtkOffloadGetInfoReqMsg: the GTK Offload 
                        Information Message as specified by the
                        Device Interface
  
          wdiGtkOffloadGetInfoCb: callback for passing back the
          response of the GTK offload operation received from the
          device
  
        pUserData: user data will be passed back with the
        callback 
  
 @see WDI_PostAssocReq
 @return Result of the function call
*/
WDI_Status 
WDI_GTKOffloadGetInfoReq
(
  WDI_GtkOffloadGetInfoReqMsg*  pwdiGtkOffloadGetInfoReqMsg,
  WDI_GtkOffloadGetInfoCb       wdiGtkOffloadGetInfoCb,
  void*                          pUserData
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
     Sanity Check 
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED; 
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   wdiEventData.wdiRequest      = WDI_GTK_OFFLOAD_GETINFO_REQ;
   wdiEventData.pEventData      = pwdiGtkOffloadGetInfoReqMsg; 
   wdiEventData.uEventDataSize  = sizeof(*pwdiGtkOffloadGetInfoReqMsg);
   wdiEventData.pCBfnc          = wdiGtkOffloadGetInfoCb; 
   wdiEventData.pUserData       = pUserData;

   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}


/**
 @brief Process set GTK Offload Request function 
 
 @param  pWDICtx:         pointer to the WLAN DAL context 
         pEventData:      pointer to the event information structure 
  
 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessGTKOffloadReq
( 
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_GtkOffloadReqMsg*    pwdiGtkOffloadReqMsg = NULL;
   WDI_GtkOffloadCb         wdiGtkOffloadCb      = NULL;
   wpt_uint8*               pSendBuffer          = NULL; 
   wpt_uint16               usDataOffset         = 0;
   wpt_uint16               usSendSize           = 0;
   tHalGtkOffloadReqParams  gtkOffloadReqParams = {0};
   wpt_uint8                ucCurrentSessionId = 0;
   WDI_BSSSessionType*      pBSSSes = NULL;

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

   /*-------------------------------------------------------------------------
     Sanity check 
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiGtkOffloadReqMsg = (WDI_GtkOffloadReqMsg*)pEventData->pEventData)) ||
       ( NULL == (wdiGtkOffloadCb   = (WDI_GtkOffloadCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      goto failRequest;
   }

   /*-----------------------------------------------------------------------
     Get message buffer
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_GTK_OFFLOAD_REQ, 
                         sizeof(gtkOffloadReqParams),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(gtkOffloadReqParams) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in GTK offload req %p %p %p",
                  pEventData, pwdiGtkOffloadReqMsg, wdiGtkOffloadCb);
      WDI_ASSERT(0);
      goto failRequest;
   }

   //
   // Fill gtkOffloadReqParams from pwdiGtkOffloadReqMsg->gtkOffloadReqParams
   //
   ucCurrentSessionId = WDI_FindAssocSession( pWDICtx, 
                               pwdiGtkOffloadReqMsg->gtkOffloadReqParams.bssId, 
                               &pBSSSes);  
   if ( NULL == pBSSSes )
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                    " %s : Association for this BSSID does not exist", __func__);
      goto fail;
   }

   gtkOffloadReqParams.bssIdx = pBSSSes->ucBSSIdx;
   
   gtkOffloadReqParams.ulFlags = pwdiGtkOffloadReqMsg->gtkOffloadReqParams.ulFlags;
   // Copy KCK
   wpalMemoryCopy(&(gtkOffloadReqParams.aKCK[0]), &(pwdiGtkOffloadReqMsg->gtkOffloadReqParams.aKCK[0]), 16);
   // Copy KEK
   wpalMemoryCopy(&(gtkOffloadReqParams.aKEK[0]), &(pwdiGtkOffloadReqMsg->gtkOffloadReqParams.aKEK[0]), 16);
   // Copy KeyReplayCounter
   wpalMemoryCopy(&(gtkOffloadReqParams.ullKeyReplayCounter), &(pwdiGtkOffloadReqMsg->gtkOffloadReqParams.ullKeyReplayCounter), sizeof(v_U64_t));

   wpalMemoryCopy( pSendBuffer+usDataOffset, 
                   &gtkOffloadReqParams, 
                   sizeof(gtkOffloadReqParams)); 

   pWDICtx->wdiReqStatusCB     = pwdiGtkOffloadReqMsg->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiGtkOffloadReqMsg->pUserData; 

   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL 
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, 
                        wdiGtkOffloadCb, pEventData->pUserData, WDI_GTK_OFFLOAD_RESP); 

fail:
   // Release the message buffer so we don't leak
   wpalMemoryFree(pSendBuffer);

failRequest:
   //WDA should have failure check to avoid the memory leak
   return WDI_STATUS_E_FAILURE;
}


/**
 @brief Process GTK Offload Get Information Request function
 
 @param  pWDICtx:         pointer to the WLAN DAL context 
         pEventData:      pointer to the event information structure 
  
 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessGTKOffloadGetInfoReq
( 
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_GtkOffloadGetInfoReqMsg*     pwdiGtkOffloadGetInfoReqMsg = NULL;
   WDI_GtkOffloadGetInfoCb          wdiGtkOffloadGetInfoCb      = NULL;
   wpt_uint8*                       pSendBuffer           = NULL; 
   wpt_uint16                       usDataOffset          = 0;
   wpt_uint16                       usSendSize            = 0;
   tHalGtkOffloadGetInfoReqParams   halGtkOffloadGetInfoReqParams;
   wpt_uint8                        ucCurrentSessionId = 0;
   WDI_BSSSessionType*              pBSSSes = NULL;

   /*-------------------------------------------------------------------------
     Sanity check 
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiGtkOffloadGetInfoReqMsg = (WDI_GtkOffloadGetInfoReqMsg*)pEventData->pEventData)) ||
       ( NULL == (wdiGtkOffloadGetInfoCb = (WDI_GtkOffloadGetInfoCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      goto failRequest;
   }

   /*-----------------------------------------------------------------------
     Get message buffer
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_GTK_OFFLOAD_GETINFO_REQ, 
                         sizeof(halGtkOffloadGetInfoReqParams),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < ( usDataOffset + sizeof(halGtkOffloadGetInfoReqParams))))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in WDI_ProcessGTKOffloadGetInfoReq() %p %p %p",
                  pEventData, pwdiGtkOffloadGetInfoReqMsg, wdiGtkOffloadGetInfoCb);
      WDI_ASSERT(0);
      goto failRequest;
   }
   ucCurrentSessionId = WDI_FindAssocSession( pWDICtx, 
                               pwdiGtkOffloadGetInfoReqMsg->WDI_GtkOffloadGetInfoReqParams.bssId, 
                               &pBSSSes);  
   if ( NULL == pBSSSes )
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                    " %s : Association for this BSSID does not exist",__func__);
      goto fail;
   }
   halGtkOffloadGetInfoReqParams.bssIdx = pBSSSes->ucBSSIdx;

   //
   // Don't need to fill send buffer other than header
   //
   wpalMemoryCopy( pSendBuffer+usDataOffset, 
                   &halGtkOffloadGetInfoReqParams, 
                   sizeof(halGtkOffloadGetInfoReqParams)); 

   pWDICtx->wdiReqStatusCB     = pwdiGtkOffloadGetInfoReqMsg->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiGtkOffloadGetInfoReqMsg->pUserData; 

   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL 
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, 
                        wdiGtkOffloadGetInfoCb, pEventData->pUserData, WDI_GTK_OFFLOAD_GETINFO_RESP); 
fail:
   // Release the message buffer so we don't leak
   wpalMemoryFree(pSendBuffer);

failRequest:
   //WDA should have failure check to avoid the memory leak
   return WDI_STATUS_E_FAILURE;
}

/**
 @brief Process host offload Rsp function (called when a
        response is being received over the bus from HAL)
 
 @param  pWDICtx:         pointer to the WLAN DAL context 
         pEventData:      pointer to the event information structure 
  
 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessGtkOffloadRsp
( 
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   eHalStatus           halStatus;
   WDI_GtkOffloadCb    wdiGtkOffloadCb   = NULL;
   tHalGtkOffloadRspParams halGtkOffloadRspParams;
   WDI_GtkOffloadRspParams  wdiGtkOffloadRsparams;

   /*-------------------------------------------------------------------------
     Sanity check 
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE; 
   }

   wdiGtkOffloadCb = (WDI_GtkOffloadCb)pWDICtx->pfncRspCB;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION))
   {
        wpalMemoryCopy( &halGtkOffloadRspParams,
                   pEventData->pEventData,
                   sizeof(halGtkOffloadRspParams));

       wdiGtkOffloadRsparams.ulStatus =   
                       WDI_HAL_2_WDI_STATUS(halGtkOffloadRspParams.ulStatus);
       wdiGtkOffloadRsparams.bssIdx =   
                       halGtkOffloadRspParams.bssIdx;
   }
   else
   {
       halStatus = *((eHalStatus*)pEventData->pEventData);
       wdiGtkOffloadRsparams.ulStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);
   }

   /*Notify UMAC*/
   wdiGtkOffloadCb( &wdiGtkOffloadRsparams, pWDICtx->pRspCBUserData);

   return WDI_STATUS_SUCCESS; 
}

/**
 @brief Process GTK Offload Get Information Response function
 
 @param  pWDICtx:         pointer to the WLAN DAL context 
         pEventData:      pointer to the event information structure 
  
 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessGTKOffloadGetInfoRsp
( 
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   eHalStatus           halStatus;
   WDI_GtkOffloadGetInfoCb   wdiGtkOffloadGetInfoCb = NULL;
   tHalGtkOffloadGetInfoRspParams halGtkOffloadGetInfoRspParams;
   WDI_GtkOffloadGetInfoRspParams wdiGtkOffloadGetInfoRsparams;
   WDI_BSSSessionType*              pBSSSes = NULL;


   /*-------------------------------------------------------------------------
     Sanity check 
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData ))
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE; 
   }

   wdiGtkOffloadGetInfoCb = (WDI_GtkOffloadGetInfoCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION))
   {
       wpalMemoryCopy( &halGtkOffloadGetInfoRspParams,
                   pEventData->pEventData,
                   sizeof(halGtkOffloadGetInfoRspParams));

       wdiGtkOffloadGetInfoRsparams.ulStatus =   
                       WDI_HAL_2_WDI_STATUS(halGtkOffloadGetInfoRspParams.ulStatus);
       wdiGtkOffloadGetInfoRsparams.ullKeyReplayCounter = 
                       halGtkOffloadGetInfoRspParams.ullKeyReplayCounter;
       wdiGtkOffloadGetInfoRsparams.ulTotalRekeyCount = 
                       halGtkOffloadGetInfoRspParams.ulTotalRekeyCount;
       wdiGtkOffloadGetInfoRsparams.ulGTKRekeyCount = 
                       halGtkOffloadGetInfoRspParams.ulGTKRekeyCount;
       wdiGtkOffloadGetInfoRsparams.ulIGTKRekeyCount = 
                       halGtkOffloadGetInfoRspParams.ulIGTKRekeyCount;

       wpalMutexAcquire(&pWDICtx->wptMutex);
       WDI_FindAssocSessionByBSSIdx(pWDICtx, halGtkOffloadGetInfoRspParams.bssIdx,
                       &pBSSSes);

       if ( NULL == pBSSSes )
       {
           WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                    "Association sequence for this BSS does not exist or "
                    "association no longer in progress - mysterious HAL response");
           wpalMutexRelease(&pWDICtx->wptMutex);
           return WDI_STATUS_E_NOT_ALLOWED;
       }

       wpalMemoryCopy(wdiGtkOffloadGetInfoRsparams.bssId, pBSSSes->macBSSID,
                       sizeof (wpt_macAddr));
       wpalMutexRelease(&pWDICtx->wptMutex);
    }
   else
    {
       halStatus = *((eHalStatus*)pEventData->pEventData);
       wdiGtkOffloadGetInfoRsparams.ulStatus   =   WDI_HAL_2_WDI_STATUS(halStatus); 
    }
   /*Notify UMAC*/
   //wdiUpdateScanParamsCb(wdiStatus, pWDICtx->pRspCBUserData);
   //wdiReceiveFilterClearFilterCb(wdiStatus, pWDICtx->pRspCBUserData);
   wdiGtkOffloadGetInfoCb(&wdiGtkOffloadGetInfoRsparams, pWDICtx->pRspCBUserData);

   return WDI_STATUS_SUCCESS; 
}
#endif // WLAN_FEATURE_GTK_OFFLOAD

#ifdef WLAN_WAKEUP_EVENTS
WDI_Status
WDI_ProcessWakeReasonInd
( 
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_LowLevelIndType *pWdiInd;
  tpWakeReasonParams pWakeReasonParams;
  wpt_uint32 allocSize = 0;

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
            "+%s", __func__);

  /*-------------------------------------------------------------------------
    Sanity check 
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT( 0 );
     return WDI_STATUS_E_FAILURE; 
  }

  /*-------------------------------------------------------------------------
    Extract indication and send it to UMAC
  -------------------------------------------------------------------------*/
  pWakeReasonParams = (tpWakeReasonParams)(pEventData->pEventData);
  
  allocSize = sizeof(WDI_LowLevelIndType) + (pWakeReasonParams->ulStoredDataLen - 1);

  //Allocate memory for WDI_WakeReasonIndType structure
  pWdiInd = wpalMemoryAllocate(allocSize) ;

  if(NULL == pWdiInd)
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
            "%s: Failed to allocate memory for WDI_WakeReasonIndType: %p %p %p ",
                __func__, pWDICtx, pEventData, pEventData->pEventData);
    WDI_ASSERT(0);
    return WDI_STATUS_E_FAILURE; 
  }

  wpalMemoryZero(pWdiInd, allocSize);

  /* Fill in the indication parameters*/
  // Fill wdiInd.wdiIndicationData.wakeReasonInd structure from wakeReasonInd.wakeReasonParams
  pWdiInd->wdiIndicationType = WDI_WAKE_REASON_IND; 
  pWdiInd->wdiIndicationData.wdiWakeReasonInd.ulReason = pWakeReasonParams->ulReason;
  pWdiInd->wdiIndicationData.wdiWakeReasonInd.ulReasonArg = pWakeReasonParams->ulReasonArg;
  pWdiInd->wdiIndicationData.wdiWakeReasonInd.ulStoredDataLen = pWakeReasonParams->ulStoredDataLen;
  pWdiInd->wdiIndicationData.wdiWakeReasonInd.ulActualDataLen = pWakeReasonParams->ulActualDataLen;    
  wpalMemoryCopy( (void *)&(pWdiInd->wdiIndicationData.wdiWakeReasonInd.aDataStart[0]), 
                  &(pWakeReasonParams->aDataStart[0]), 
                  pWakeReasonParams->ulStoredDataLen);


  if ( pWDICtx->wdiLowLevelIndCB )
  {
    /*Notify UMAC*/
    pWDICtx->wdiLowLevelIndCB( pWdiInd, pWDICtx->pIndUserData );
  }
  
  //Free memory allocated for WDI_WakeReasonIndType structure
  wpalMemoryFree(pWdiInd);

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
            "-%s", __func__);

  return WDI_STATUS_SUCCESS; 
}
#endif // WLAN_WAKEUP_EVENTS

void WDI_GetWcnssCompiledApiVersion
(
  WDI_WlanVersionType     *pWcnssApiVersion
)
{
    pWcnssApiVersion->major    = WLAN_HAL_VER_MAJOR;
    pWcnssApiVersion->minor    = WLAN_HAL_VER_MINOR;
    pWcnssApiVersion->version  = WLAN_HAL_VER_VERSION;
    pWcnssApiVersion->revision = WLAN_HAL_VER_REVISION;
}

/**
 @brief Process Set TM Level Rsp function (called when a
        response is being received over the bus from HAL)
 
 @param  pWDICtx:         pointer to the WLAN DAL context 
         pEventData:      pointer to the event information structure 
  
 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetTmLevelRsp
( 
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_Status           wdiStatus;
   eHalStatus           halStatus;
   WDI_SetTmLevelCb     wdiSetTmLevelCb;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check 
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData ))
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE; 
   }

   wdiSetTmLevelCb = (WDI_SetPowerParamsCb)pWDICtx->pfncRspCB; 

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   halStatus = *((eHalStatus*)pEventData->pEventData);
   wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus); 

   /*Notify UMAC*/
   wdiSetTmLevelCb(wdiStatus, pWDICtx->pRspCBUserData);

   return WDI_STATUS_SUCCESS; 
}/*WDI_ProcessSetTmLevelRsp*/

/**
 @brief Process Set Thermal Mitigation level Changed request
 
 @param  pWDICtx:         pointer to the WLAN DAL context 
         pEventData:      pointer to the event information structure 
  
 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetTmLevelReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_SetTmLevelReqType           *pwdiSetTmLevelReq = NULL;
   WDI_SetTmLevelCb                 wdiSetTmLevelCb   = NULL;
   wpt_uint8*                       pSendBuffer       = NULL; 
   wpt_uint16                       usDataOffset      = 0;
   wpt_uint16                       usSendSize        = 0;
   tSetThermalMitgationType         halTmMsg;

   /*-------------------------------------------------------------------------
     Sanity check 
   -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiSetTmLevelReq = (WDI_SetTmLevelReqType*)pEventData->pEventData)) ||
       ( NULL == (wdiSetTmLevelCb   = (WDI_SetTmLevelCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE; 
   }

   /*-----------------------------------------------------------------------
     Get message buffer
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_TM_LEVEL_REQ, 
                         sizeof(halTmMsg),
                         &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(halTmMsg) )))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in Set PNO req %p %p %p",
                  pEventData, pwdiSetTmLevelReq, wdiSetTmLevelCb);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE; 
   }

   halTmMsg.thermalMitMode = pwdiSetTmLevelReq->tmMode;
   halTmMsg.thermalMitLevel = pwdiSetTmLevelReq->tmLevel;

   wpalMemoryCopy( pSendBuffer+usDataOffset, 
                   &halTmMsg, 
                   sizeof(halTmMsg)); 

   pWDICtx->pReqStatusUserData = pwdiSetTmLevelReq->pUserData; 
   pWDICtx->pfncRspCB = NULL;
   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL 
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, 
                        wdiSetTmLevelCb, pEventData->pUserData, WDI_SET_TM_LEVEL_RESP); 
}

/* Fill the value from the global features enabled array to the global capabilities
 * bitmap struct 
 */
static void 
FillAllFeatureCaps(tWlanFeatCaps *fCaps, placeHolderInCapBitmap *enabledFeat, wpt_int8 len)
{
   wpt_int8 i;
   for (i=0; i<len; i++)
   {
      setFeatCaps(fCaps, enabledFeat[i]);
   }
}

/**
 @brief WDI_featureCapsExchangeReq
        Post feature capability bitmap exchange event.
        Host will send its own capability to FW in this req and 
        expect FW to send its capability back as a bitmap in Response
 
 @param 
  
        wdiFeatureCapsExchangeCb: callback called on getting the response.
        It is kept to mantain similarity between WDI reqs and if needed, can
        be used in future. Currently, It is set to NULL
  
        pUserData: user data will be passed back with the
        callback 
  
 @see
 @return Result of the function call
*/
WDI_Status
WDI_featureCapsExchangeReq
(
  WDI_featureCapsExchangeCb     wdiFeatureCapsExchangeCb,
  void*                         pUserData
)
{
   WDI_EventInfoType   wdiEventData;
   wpt_int32           fCapsStructSize;
   
   /*------------------------------------------------------------------------
     Sanity Check 
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request");
   
      return WDI_STATUS_E_NOT_ALLOWED; 
   }

   /* Allocate memory separately for global variable carrying FW caps */
   fCapsStructSize = sizeof(tWlanFeatCaps);
   gpHostWlanFeatCaps = wpalMemoryAllocate(fCapsStructSize);
   if ( NULL ==  gpHostWlanFeatCaps )
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "Cannot allocate memory for host capability info");
      WDI_ASSERT(0);
      return WDI_STATUS_MEM_FAILURE;
   }

   wpalMemoryZero(gpHostWlanFeatCaps, fCapsStructSize);
   
   /*------------------------------------------------------------------------
   Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
   FillAllFeatureCaps(gpHostWlanFeatCaps, supportEnabledFeatures,
      (sizeof(supportEnabledFeatures)/sizeof(supportEnabledFeatures[0])));
   WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_INFO,
      "Host caps %x %x %x %x",
      gpHostWlanFeatCaps->featCaps[0],
      gpHostWlanFeatCaps->featCaps[1],
      gpHostWlanFeatCaps->featCaps[2],
      gpHostWlanFeatCaps->featCaps[3]
   );
   WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_INFO, "Host Capability");
   WDI_TraceHostFWCapabilities(gpHostWlanFeatCaps->featCaps);
   wdiEventData.wdiRequest      = WDI_FEATURE_CAPS_EXCHANGE_REQ;
   wdiEventData.pEventData      = gpHostWlanFeatCaps; 
   wdiEventData.uEventDataSize  = fCapsStructSize; 
   wdiEventData.pCBfnc          = wdiFeatureCapsExchangeCb; 
   wdiEventData.pUserData       = pUserData;
   
   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief Disable Active mode offload in Host
 
 @param  void
 @see
 @return void
*/
void
WDI_disableCapablityFeature(wpt_uint8 feature_index)
{
   supportEnabledFeatures[feature_index] = 0;
   return;
}

/**
 @brief Process Host-FW Capability Exchange Request function
 
 @param  pWDICtx:         pointer to the WLAN DAL context 
         pEventData:      pointer to the event information structure 
  
 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessFeatureCapsExchangeReq
( 
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  wpt_uint8*              pSendBuffer        = NULL; 
  wpt_uint16              usDataOffset       = 0;
  wpt_uint16              usSendSize         = 0;
  wpt_uint16              usLen              = 0; 

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

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
         "%s", __func__);

  /*-------------------------------------------------------------------------
    Sanity check 
  -------------------------------------------------------------------------*/
  /* Call back function is NULL since not required for cap exchange req */
  if (( NULL == pEventData ) ||
      ( NULL == (tWlanFeatCaps *)pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE; 
  }

  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  usLen = sizeof(tWlanFeatCaps);

  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                        WDI_FEATURE_CAPS_EXCHANGE_REQ, 
                        usLen,
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + usLen )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
              "Unable to get send buffer in feat caps exchange req %p %p",
                pEventData, (tWlanFeatCaps *)pEventData->pEventData);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE; 
  }

  WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_INFO,
       "Host Caps - %x %x %x %x",
      ((tWlanFeatCaps *)pEventData->pEventData)->featCaps[0],
      ((tWlanFeatCaps *)pEventData->pEventData)->featCaps[1],
      ((tWlanFeatCaps *)pEventData->pEventData)->featCaps[2],
      ((tWlanFeatCaps *)pEventData->pEventData)->featCaps[3]
    );

  /* Copy host caps after the offset in the send buffer */  
  wpalMemoryCopy( pSendBuffer+usDataOffset, 
                  (tWlanFeatCaps *)pEventData->pEventData, 
                  usLen); 

  /*-------------------------------------------------------------------------
    Send Start Request to HAL 
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, 
                       (WDI_StartRspCb)pEventData->pCBfnc,
                       pEventData->pUserData, WDI_FEATURE_CAPS_EXCHANGE_RESP);
  
}/*WDI_ProcessFeatureCapsExchangeReq*/

/**
 @brief Process Host-FW Capability Exchange Response function
 
 @param  pWDICtx:         pointer to the WLAN DAL context 
         pEventData:      pointer to the event information structure 
  
 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessFeatureCapsExchangeRsp
( 
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_featureCapsExchangeCb    wdiFeatureCapsExchangeCb;   
   wpt_int32                   fCapsStructSize;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
          "%s", __func__);

   /*-------------------------------------------------------------------------
     Sanity check 
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData ))
   {
      /* It will go here when riva is old (doesn't understand this msg) and host is new */
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE; 
   }

   /* Allocate memory separately for global variable carrying FW caps */
   fCapsStructSize = sizeof(tWlanFeatCaps);
   gpFwWlanFeatCaps = wpalMemoryAllocate(fCapsStructSize);   
   if ( NULL ==  gpFwWlanFeatCaps )
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "Cannot allocate memory for host capability info");
      WDI_ASSERT(0);
      return WDI_STATUS_MEM_FAILURE;
   }

   /*-------------------------------------------------------------------------
     Unpack HAL Response Message - the header was already extracted by the
     main Response Handling procedure 
   -------------------------------------------------------------------------*/   
   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/

   wpalMemoryCopy(gpFwWlanFeatCaps,(tWlanFeatCaps *) pEventData -> pEventData,
                    fCapsStructSize);
   WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_INFO,
      "FW caps %x %x %x %x",
      gpFwWlanFeatCaps->featCaps[0],
      gpFwWlanFeatCaps->featCaps[1],
      gpFwWlanFeatCaps->featCaps[2],
      gpFwWlanFeatCaps->featCaps[3]
   );

   WPAL_TRACE(  eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_INFO, "Firmware Capability");
   WDI_TraceHostFWCapabilities(gpFwWlanFeatCaps->featCaps);
   wdiFeatureCapsExchangeCb = (WDI_featureCapsExchangeCb) pWDICtx -> pfncRspCB; 

   /*Notify UMAC - there is no callback right now but can be used in future if reqd */
   if (wdiFeatureCapsExchangeCb != NULL)
      wdiFeatureCapsExchangeCb(NULL, NULL);

   return WDI_STATUS_SUCCESS; 
}

#ifdef WLAN_FEATURE_11AC
WDI_Status
WDI_ProcessUpdateVHTOpModeRsp
( 
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_UpdateVHTOpModeCb   wdiVHTOpModeCb = NULL;
   WDI_Status           wdiStatus;
   eHalStatus           halStatus;
   
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }
   wdiVHTOpModeCb = (WDI_UpdateVHTOpModeCb)pEventData->pCBfnc;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   halStatus = *((eHalStatus*)pEventData->pEventData);
   wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

   /*Notify UMAC*/
   wdiVHTOpModeCb( wdiStatus, pEventData->pUserData);

   return WDI_STATUS_SUCCESS; 
}
#endif
/**
 @brief WDI_getHostWlanFeatCaps
        WDI API that returns whether the feature passed to it as enum value in
        "placeHolderInCapBitmap" is supported by Host or not. It uses WDI global
        variable storing host capability bitmap to find this. This can be used by
        other moduels to decide certain things like call different APIs based on
        whether a particular feature is supported.
 
 @param 
  
        feat_enum_value: enum value for the feature as in placeHolderInCapBitmap in wlan_hal_msg.h.

 @see
 @return 
        0 - if the feature is NOT supported in host
        any non-zero value - if the feature is SUPPORTED in host.
*/
wpt_uint8 WDI_getHostWlanFeatCaps(wpt_uint8 feat_enum_value)
{
   wpt_uint8 featSupported = 0;
   if (gpHostWlanFeatCaps != NULL)
   {
      getFeatCaps(gpHostWlanFeatCaps, feat_enum_value, featSupported);
   }
   else
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
        "Caps exchange feature NOT supported. Return NOT SUPPORTED for %u feature", feat_enum_value);
   }
   return featSupported;
}

/**
 @brief WDI_getFwWlanFeatCaps
        WDI API that returns whether the feature passed to it as enum value in
        "placeHolderInCapBitmap" is supported by FW or not. It uses WDI global
        variable storing host capability bitmap to find this. This can be used by
        other moduels to decide certain things like call different APIs based on
        whether a particular feature is supported.
 
 @param 
  
        feat_enum_value: enum value for the feature as in placeHolderInCapBitmap
                                    in wlan_hal_msg.h.

 @see
 @return 
        0 - if the feature is NOT supported in FW
        any non-zero value - if the feature is SUPPORTED in FW.
*/
wpt_uint8 WDI_getFwWlanFeatCaps(wpt_uint8 feat_enum_value)
{
    wpt_uint8 featSupported = 0;
    if (gpFwWlanFeatCaps != NULL)
    {
      getFeatCaps(gpFwWlanFeatCaps, feat_enum_value, featSupported);
    }
    else
    {
       WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
         "Caps exchange feature NOT supported. Return NOT SUPPORTED for %u feature", feat_enum_value);
    }
    return featSupported;
}

wpt_uint8 WDI_selectCbMode( wpt_uint8 channel, wpt_uint8 ChannelBW )
{
  /* 5gHz Channel */
  if( channel >= 34 && channel <= 165 )
  {
    if( ChannelBW == 80 && WDI_getFwWlanFeatCaps(DOT11AC) )
    {
      if ( channel== 36 || channel == 52 || channel == 100 ||
            channel == 116 || channel == 149 )
      {
            return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW;
      }
      else if ( channel == 40 || channel == 56 || channel == 104 ||
            channel == 120 || channel == 153 )
      {
         return  PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW;
      }
      else if ( channel == 44 || channel == 60 || channel == 108 ||
            channel == 124 || channel == 157 )
      {
         return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH;
      }
      else if ( channel == 48 || channel == 64 || channel == 112 ||
            channel == 128 || channel == 144 || channel == 161 )
      {
         return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH;
      }
      else if ( channel == 165 )
      {
         return PHY_SINGLE_CHANNEL_CENTERED;
      }
     }

    else
    {
      if ( channel== 40 || channel == 48 || channel == 56 ||
            channel == 64 || channel == 104 || channel == 112 ||
            channel == 120 || channel == 128 || channel == 136 ||
            channel == 144 || channel == 153 || channel == 161 )
      {
         return PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
      }
      else if ( channel== 36 || channel == 44 || channel == 52 ||
            channel == 60 || channel == 100 || channel == 108 ||
            channel == 116 || channel == 124 || channel == 132 ||
            channel == 140 || channel == 149 || channel == 157 )
      {
         return PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
      }
      else if ( channel == 165 )
      {
         return PHY_SINGLE_CHANNEL_CENTERED;
      }
    }
   }

   /* 2.4Ghz Channel */
   if( ChannelBW == 40 && WDI_getFwWlanFeatCaps(HT40_OBSS_SCAN) )
   {
      if (channel >= 1 && channel <= 7)
         return PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
      else if (channel >= 8 && channel <= 13)
         return PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
      else if (channel ==14)
         return PHY_SINGLE_CHANNEL_CENTERED;
   }
  return PHY_SINGLE_CHANNEL_CENTERED;
}

#ifdef WLAN_FEATURE_11AC
WDI_Status
WDI_ProcessUpdateVHTOpModeReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_UpdateVHTOpMode*    pwdiVHTOpModeParams = NULL;
  WDI_UpdateVHTOpModeCb   wdiVHTOpModeCb = NULL;
  wpt_uint8*              pSendBuffer        = NULL; 
  wpt_uint16              usDataOffset       = 0;
  wpt_uint16              usSendSize         = 0;

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

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
         "%s", __func__);

  /*-------------------------------------------------------------------------
    Sanity check 
  -------------------------------------------------------------------------*/
   if (( NULL == pEventData ) ||
       ( NULL == (pwdiVHTOpModeParams = (WDI_UpdateVHTOpMode*)pEventData->pEventData)) ||
       ( NULL == (wdiVHTOpModeCb   = (WDI_UpdateVHTOpModeCb)pEventData->pCBfnc)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }
  
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_UPDATE_VHT_OP_MODE_REQ,
                        sizeof(WDI_UpdateVHTOpMode),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(WDI_UpdateVHTOpMode) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in update vht opMode req");
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
            "pwdiVHTOpModeParams->opMode=%d, pwdiVHTOpModeParams->staId=%d", pwdiVHTOpModeParams->opMode, pwdiVHTOpModeParams->staId);

  wpalMemoryCopy( pSendBuffer+usDataOffset, pwdiVHTOpModeParams,
                  sizeof(WDI_UpdateVHTOpMode));

  /*-------------------------------------------------------------------------
    Send Start Request to HAL 
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, 
                       wdiVHTOpModeCb,
                       pEventData->pUserData, WDI_UPDATE_VHT_OP_MODE_RESP);

}

WDI_Status
WDI_UpdateVHTOpModeReq
(
  WDI_UpdateVHTOpMode    *pData,
  WDI_UpdateVHTOpModeCb  wdiUpdateVHTOpModeCb,
  void*                  pUserData
)
{
  WDI_EventInfoType      wdiEventData;

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_UPDATE_VHT_OP_MODE_REQ;
  wdiEventData.pEventData      = pData;
  wdiEventData.uEventDataSize  = sizeof(WDI_UpdateVHTOpMode); 
  wdiEventData.pCBfnc          = wdiUpdateVHTOpModeCb;
  wdiEventData.pUserData       = pUserData;
  
  WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
            "pData->opMode=%d, pData->staId=%d", pData->opMode, pData->staId);

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

} 
#endif

/**
 @brief WDI_TransportChannelDebug -
    Display DXE Channel debugging information
    User may request to display DXE channel snapshot
    Or if host driver detects any abnormal stcuk may display
        
 @param  displaySnapshot : Display DXE snapshot option
 @param  debugFlags      : Enable stall detect features
                           defined by WPAL_DeviceDebugFlags
                           These features may effect
                           data performance.
 @see
 @return none
*/
void WDI_TransportChannelDebug
(
   wpt_boolean  displaySnapshot,
   wpt_uint8    debugFlags
)
{
   WDTS_ChannelDebug(displaySnapshot, debugFlags);
   return;
}

/**
 @brief WDI_TransportKickDxe -
    Request Kick DXE when HDD TX time out happen

 @param  none
 @see
 @return none
*/
void WDI_TransportKickDxe()
{
   WDTS_ChannelKickDxe();
   return;
}

/**
 @brief WDI_SsrTimerCB
    Callback function for SSR timer, if this is called then the graceful
    shutdown for Riva did not happen.

 @param  pUserData : user data to timer

 @see
 @return none
*/
void
WDI_SsrTimerCB
(
  void *pUserData
)
{
  WDI_ControlBlockType*  pWDICtx = (WDI_ControlBlockType*)pUserData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  if (NULL == pWDICtx )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);
    WDI_ASSERT(0);
    return;
  }
  wpalRivaSubystemRestart();

  return;

}/*WDI_SsrTimerCB*/

/**
 @brief WDI_SetEnableSSR -
    This API is called to enable/disable SSR on WDI timeout.

 @param  enableSSR : enable/disable SSR

 @see
 @return none
*/
void WDI_SetEnableSSR(wpt_boolean  enableSSR)
{
   gWDICb.bEnableSSR = enableSSR;
}


#ifdef FEATURE_WLAN_LPHB
/**
 @brief WDI_ProcessLphbInd -
    This function will be invoked when FW detects low power
    heart beat failure

 @param  pWDICtx : wdi context
         pEventData : indication data
 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessLphbInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_LowLevelIndType  wdiInd;
  tHalLowPowerHeartBeatIndParam lphbIndicationParam;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
  Sanity check
 -------------------------------------------------------------------------*/
  if ((NULL == pWDICtx) || (NULL == pEventData) ||
      (NULL == pEventData->pEventData))
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
  Extract indication and send it to UMAC
 -------------------------------------------------------------------------*/
   wpalMemoryCopy(&lphbIndicationParam,
                  pEventData->pEventData,
                  sizeof(tHalLowPowerHeartBeatIndParam));

  wdiInd.wdiIndicationType = WDI_LPHB_IND;
  wdiInd.wdiIndicationData.wdiLPHBTimeoutInd.bssIdx =
               lphbIndicationParam.bssIdx;
  wdiInd.wdiIndicationData.wdiLPHBTimeoutInd.sessionIdx =
               lphbIndicationParam.sessionIdx;
  wdiInd.wdiIndicationData.wdiLPHBTimeoutInd.protocolType =
               lphbIndicationParam.protocolType;
  wdiInd.wdiIndicationData.wdiLPHBTimeoutInd.eventReason =
               lphbIndicationParam.eventReason;
  /*Notify UMAC*/
  if (pWDICtx->wdiLowLevelIndCB)
  {
    pWDICtx->wdiLowLevelIndCB(&wdiInd, pWDICtx->pIndUserData);
  }

  return WDI_STATUS_SUCCESS;
}

/**
 @brief WDI_ProcessLphbCfgRsp -
    LPHB configuration response from FW

 @param  pWDICtx : wdi context
         pEventData : indication data

 @see
 @return Result of the function call
*/
WDI_Status WDI_ProcessLphbCfgRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_Status           wdiStatus;
   eHalStatus           halStatus;
   WDI_LphbCfgCb        wdiLphbCfgCb;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*-------------------------------------------------------------------------
     Sanity check
   -------------------------------------------------------------------------*/
   if ((NULL == pWDICtx) || (NULL == pEventData) ||
       (NULL == pEventData->pEventData))
   {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
   }

   wdiLphbCfgCb = (WDI_LphbCfgCb)pWDICtx->pfncRspCB;

   /*-------------------------------------------------------------------------
     Extract response and send it to UMAC
   -------------------------------------------------------------------------*/
   halStatus = *((eHalStatus*)pEventData->pEventData);
   wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus);

   WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "LPHB Cfg Rsp Return status %d", wdiStatus);
   /*Notify UMAC*/
   if (NULL != wdiLphbCfgCb)
   {
      wdiLphbCfgCb(wdiStatus, pWDICtx->pRspCBUserData);
   }

   return WDI_STATUS_SUCCESS;
}

/**
 @brief WDI_ProcessLPHBConfReq -
    LPHB configuration request to FW

 @param  pWDICtx : wdi context
         pEventData : indication data

 @see
 @return none
*/
WDI_Status WDI_ProcessLPHBConfReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_LPHBReq                   *pLphbReqParams;
  WDI_Status                     wdiStatus;
  wpt_uint8*                     pSendBuffer        = NULL;
  wpt_uint16                     usDataOffset       = 0;
  wpt_uint16                     usSendSize         = 0;
  tHalLowPowerHeartBeatReq      *halLphbReqRarams;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
     Sanity check
  -------------------------------------------------------------------------*/
  if ((NULL == pEventData) || (NULL == pEventData->pEventData))
  {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "%s: Invalid parameters in Suspend ind",__func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
  }

  pLphbReqParams = (WDI_LPHBReq *)pEventData->pEventData;

   /*-----------------------------------------------------------------------
     Get message buffer
   -----------------------------------------------------------------------*/
  if ((WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(pWDICtx,
                              WDI_LPHB_CFG_REQ,
                              sizeof(tHalLowPowerHeartBeatReqMsg),
                              &pSendBuffer, &usDataOffset, &usSendSize))||
      (usSendSize < (usDataOffset + sizeof(tHalLowPowerHeartBeatReqMsg))))
  {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                  "Unable to get send buffer in LPHB Ind ");
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
  }

  halLphbReqRarams = (tHalLowPowerHeartBeatReq *)(pSendBuffer + usDataOffset);
  wpalMemoryZero(halLphbReqRarams, sizeof(tHalLowPowerHeartBeatReq));

  halLphbReqRarams->lowPowerHeartBeatCmdType =
                     (tANI_U16)(++pLphbReqParams->cmd);
  switch ((tANI_U16)pLphbReqParams->cmd)
  {
    case WDI_LPHB_SET_EN_PARAMS_INDID:
      halLphbReqRarams->sessionIdx =
                                pLphbReqParams->params.lphbEnableReq.session;
      halLphbReqRarams->options.control.heartBeatEnable =
                                pLphbReqParams->params.lphbEnableReq.enable;
      halLphbReqRarams->options.control.heartBeatType =
                                pLphbReqParams->params.lphbEnableReq.item;
      break;

    case WDI_LPHB_SET_TCP_PARAMS_INDID:
      halLphbReqRarams->sessionIdx =
                                pLphbReqParams->params.lphbTcpParamReq.session;
      halLphbReqRarams->options.tcpParams.timeOutSec =
                                pLphbReqParams->params.lphbTcpParamReq.timeout;
      wpalMemoryCopy(&halLphbReqRarams->options.tcpParams.hostIpv4Addr,
                     &pLphbReqParams->params.lphbTcpParamReq.dev_ip,
                     sizeof(v_U32_t));
      wpalMemoryCopy(&halLphbReqRarams->options.tcpParams.destIpv4Addr,
                     &pLphbReqParams->params.lphbTcpParamReq.srv_ip,
                     sizeof(v_U32_t));

      wpalMemoryCopy(halLphbReqRarams->options.tcpParams.gatewayMacAddr,
                     pLphbReqParams->params.lphbTcpParamReq.gateway_mac,
                     WDI_MAC_ADDR_LEN);

      halLphbReqRarams->options.tcpParams.hostPort =
                                pLphbReqParams->params.lphbTcpParamReq.src_port;
      halLphbReqRarams->options.tcpParams.destPort =
                                pLphbReqParams->params.lphbTcpParamReq.dst_port;
      halLphbReqRarams->options.tcpParams.timePeriodSec =
                                pLphbReqParams->params.lphbTcpParamReq.timePeriodSec;
      halLphbReqRarams->options.tcpParams.tcpSn =
                                pLphbReqParams->params.lphbTcpParamReq.tcpSn;
      break;

    case WDI_LPHB_SET_TCP_PKT_FILTER_INDID:
      halLphbReqRarams->sessionIdx =
                               pLphbReqParams->params.lphbTcpFilterReq.session;
      halLphbReqRarams->options.tcpUdpFilter.offset =
                               pLphbReqParams->params.lphbTcpFilterReq.offset;
      halLphbReqRarams->options.tcpUdpFilter.filterLength =
                               pLphbReqParams->params.lphbTcpFilterReq.length;
      wpalMemoryCopy(halLphbReqRarams->options.tcpUdpFilter.filter,
                     pLphbReqParams->params.lphbTcpFilterReq.filter,
                     WDI_LPHB_FILTER_LEN);
      break;

    case WDI_LPHB_SET_UDP_PARAMS_INDID:
      halLphbReqRarams->sessionIdx =
                                pLphbReqParams->params.lphbUdpParamReq.session;
      halLphbReqRarams->options.udpParams.timeOutSec =
                                pLphbReqParams->params.lphbUdpParamReq.timeout;
      halLphbReqRarams->options.udpParams.timePeriodSec =
                                pLphbReqParams->params.lphbUdpParamReq.interval;
      wpalMemoryCopy(&halLphbReqRarams->options.udpParams.hostIpv4Addr,
                     &pLphbReqParams->params.lphbUdpParamReq.dev_ip,
                     sizeof(v_U32_t));
      wpalMemoryCopy(&halLphbReqRarams->options.udpParams.destIpv4Addr,
                     &pLphbReqParams->params.lphbUdpParamReq.srv_ip,
                     sizeof(v_U32_t));

      wpalMemoryCopy(halLphbReqRarams->options.udpParams.gatewayMacAddr,
                     pLphbReqParams->params.lphbUdpParamReq.gateway_mac,
                     WDI_MAC_ADDR_LEN);

      halLphbReqRarams->options.udpParams.hostPort =
                                pLphbReqParams->params.lphbUdpParamReq.src_port;
      halLphbReqRarams->options.udpParams.destPort =
                                pLphbReqParams->params.lphbUdpParamReq.dst_port;
      break;

    case WDI_LPHB_SET_UDP_PKT_FILTER_INDID:
      halLphbReqRarams->sessionIdx =
                                pLphbReqParams->params.lphbUdpFilterReq.session;
      halLphbReqRarams->options.tcpUdpFilter.offset =
                                pLphbReqParams->params.lphbUdpFilterReq.offset;
      halLphbReqRarams->options.tcpUdpFilter.filterLength =
                                pLphbReqParams->params.lphbUdpFilterReq.length;
      wpalMemoryCopy(halLphbReqRarams->options.tcpUdpFilter.filter,
                     pLphbReqParams->params.lphbUdpFilterReq.filter,
                     WDI_LPHB_FILTER_LEN);
      break;

    case WDI_LPHB_SET_NETWORK_INFO_INDID:
      /* NA */
      break;

    default:
      break;
  }

  /*-------------------------------------------------------------------------
    Send Suspend Request to HAL
  -------------------------------------------------------------------------*/
  pWDICtx->pfncRspCB          = pEventData->pCBfnc;
  pWDICtx->pReqStatusUserData = pEventData->pUserData;

  wdiStatus = WDI_SendMsg(pWDICtx, pSendBuffer,
                          usSendSize, pWDICtx->pfncRspCB,
                          pWDICtx->pReqStatusUserData,
                          WDI_LPHB_CFG_RESP);

  return wdiStatus;
}

/**
 @brief WDI_LPHBConfReq -
    LPHB configuration request API

 @param  lphbconfParam : configuration parameter
         usrData : client context
         lphbCfgCb : callback function pointer

 @see
 @return Success or fail status code
*/
WDI_Status WDI_LPHBConfReq(void *lphbconfParam,
                           void *usrData, WDI_LphbCfgCb lphbCfgCb)
{
  WDI_EventInfoType      wdiEventData;

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if (eWLAN_PAL_FALSE == gWDIInitialized)
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_LPHB_CFG_REQ;
  wdiEventData.pEventData      = lphbconfParam;
  wdiEventData.uEventDataSize  = sizeof(WDI_LPHBReq);
  wdiEventData.pCBfnc          = lphbCfgCb;
  wdiEventData.pUserData       = usrData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}
#endif /* FEATURE_WLAN_LPHB */

/**
  @brief WDI_ProcessIbssPeerInactivityInd
  Process peer inactivity indication coming from HAL

  @param pWDICtx: pointer to the WLAN DAL context
         pEventData: pointer to the event information structure
  @see
  @return Result of the function call
*/
WDI_Status
WDI_ProcessIbssPeerInactivityInd
(
   WDI_ControlBlockType* pWDICtx,
   WDI_EventInfoType* pEventData
)
{
   WDI_LowLevelIndType  wdiInd;
   tIbssPeerInactivityIndMsg halIbssIndMsg;

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

   /*-------------------------------------------------------------------------
   Sanity check
   -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData ))
   {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT( 0 );
     return WDI_STATUS_E_FAILURE;
   }

   /*-------------------------------------------------------------------------
   Extract indication and send it to UMAC
   -------------------------------------------------------------------------*/
   wpalMemoryCopy( &halIbssIndMsg.ibssPeerInactivityIndParams,
                  pEventData->pEventData,
                  sizeof(halIbssIndMsg.ibssPeerInactivityIndParams) );

   /*Fill in the indication parameters*/
   wdiInd.wdiIndicationType = WDI_IBSS_PEER_INACTIVITY_IND;

   wdiInd.wdiIndicationData.wdiIbssPeerInactivityInd.bssIdx
                          = halIbssIndMsg.ibssPeerInactivityIndParams.bssIdx;

   wdiInd.wdiIndicationData.wdiIbssPeerInactivityInd.staIdx
                          = halIbssIndMsg.ibssPeerInactivityIndParams.staIdx;

   wpalMemoryCopy(wdiInd.wdiIndicationData.wdiIbssPeerInactivityInd.staMacAddr,
                 halIbssIndMsg.ibssPeerInactivityIndParams.staAddr,
                 sizeof(tSirMacAddr));

   /*Notify UMAC*/
   pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );

   return WDI_STATUS_SUCCESS;

} /*WDI_ProcessIbssPeerInactivityInd*/

/**
*@brief WDI_RateUpdateInd will be called when the upper MAC
        requests the device to set rates.


 @param wdiRateUpdateIndParams:


 @see
 @return Result of the function call
*/
WDI_Status
WDI_RateUpdateInd
(
    WDI_RateUpdateIndParams  *wdiRateUpdateIndParams
)
{
   WDI_EventInfoType      wdiEventData;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
    Sanity Check
   ------------------------------------------------------------------------*/
   if ( eWLAN_PAL_FALSE == gWDIInitialized )
   {
       WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                  "WDI API call before module is initialized - Fail request");

       return WDI_STATUS_E_NOT_ALLOWED;
   }

   /*------------------------------------------------------------------------
     Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
    wdiEventData.wdiRequest      = WDI_RATE_UPDATE_IND;
    wdiEventData.pEventData      = wdiRateUpdateIndParams;
    wdiEventData.uEventDataSize  = sizeof(WDI_RateUpdateIndParams);
    wdiEventData.pCBfnc          = NULL;
    wdiEventData.pUserData       = NULL;

    return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/* WDI_RateUpdateInd */

/**
 @brief Process Rate Update Indication and post it to HAL

 @param  pWDICtx:    pointer to the WLAN DAL context
         pEventData: pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessRateUpdateInd
(
    WDI_ControlBlockType*  pWDICtx,
    WDI_EventInfoType*     pEventData
)
{
    wpt_uint8*              pSendBuffer        = NULL;
    wpt_uint16              usDataOffset       = 0;
    wpt_uint16              usSendSize         = 0;
    WDI_RateUpdateIndParams *pwdiRateUpdateInd = NULL;
    tHalRateUpdateInd       *pRateUpdateInd;
    WDI_Status              wdiStatus;

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

    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
           "%s", __func__);

    /*-------------------------------------------------------------------------
      Sanity check
    -------------------------------------------------------------------------*/
    if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ))
    {
       WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                   "%s: Invalid parameters", __func__);
       WDI_ASSERT(0);
       return WDI_STATUS_E_FAILURE;
    }
    pwdiRateUpdateInd = (WDI_RateUpdateIndParams *)pEventData->pEventData;
    /*-----------------------------------------------------------------------
      Get message buffer
    -----------------------------------------------------------------------*/

    if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                          WDI_RATE_UPDATE_IND,
                          sizeof(tHalRateUpdateParams),
                          &pSendBuffer, &usDataOffset, &usSendSize))||
                          ( usSendSize < (usDataOffset +
                                 sizeof(tHalRateUpdateParams) )))
    {
       WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
                "Unable to get send buffer in Rate Update Indication %p ",
                  pEventData);
       WDI_ASSERT(0);
       return WDI_STATUS_E_FAILURE;
    }

    pRateUpdateInd = (tHalRateUpdateInd *)pSendBuffer;

    /* Copy the bssid */
    wpalMemoryCopy(pRateUpdateInd->halRateUpdateParams.bssid,
                     pwdiRateUpdateInd->bssid, WDI_MAC_ADDR_LEN);

    /* Copy the tx flags */
    pRateUpdateInd->halRateUpdateParams.ucastDataRateTxFlag =
                             pwdiRateUpdateInd->ucastDataRateTxFlag;
    pRateUpdateInd->halRateUpdateParams.reliableMcastDataRateTxFlag =
                             pwdiRateUpdateInd->reliableMcastDataRateTxFlag;
    pRateUpdateInd->halRateUpdateParams.mcastDataRate24GHzTxFlag =
                             pwdiRateUpdateInd->mcastDataRate24GHzTxFlag;
    pRateUpdateInd->halRateUpdateParams.mcastDataRate5GHzTxFlag =
                             pwdiRateUpdateInd->mcastDataRate5GHzTxFlag;

    /* Copy the tx rates */
    pRateUpdateInd->halRateUpdateParams.ucastDataRate =
                             pwdiRateUpdateInd->ucastDataRate;
    pRateUpdateInd->halRateUpdateParams.reliableMcastDataRate =
                             pwdiRateUpdateInd->reliableMcastDataRate;
    pRateUpdateInd->halRateUpdateParams.mcastDataRate24GHz =
                             pwdiRateUpdateInd->mcastDataRate24GHz;
    pRateUpdateInd->halRateUpdateParams.mcastDataRate5GHz =
                             pwdiRateUpdateInd->mcastDataRate5GHz;

    /*-------------------------------------------------------------------------
     Send Rate Update Indication to HAL
    -------------------------------------------------------------------------*/
    pWDICtx->wdiReqStatusCB     = pwdiRateUpdateInd->wdiReqStatusCB;
    pWDICtx->pReqStatusUserData = pwdiRateUpdateInd->pUserData;

    wdiStatus = WDI_SendIndication(pWDICtx, pSendBuffer, usSendSize);

    return (wdiStatus != WDI_STATUS_SUCCESS) ?
                 wdiStatus : WDI_STATUS_SUCCESS_SYNC;

} /* WDI_ProcessRateUpdateInd */

#ifdef FEATURE_WLAN_BATCH_SCAN
/**
 @brief Process stop batch indication from WDA

 @param pWDICtx:         pointer to the WLAN DAL context
        pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessStopBatchScanInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  wpt_uint8*                pSendBuffer        = NULL;
  wpt_uint16                usDataOffset       = 0;
  wpt_uint16                usSendSize         = 0;
  WDI_Status                wdiStatus;
  tHalBatchScanStopIndParam *pHalInd           = NULL;
  WDI_StopBatchScanIndType  *pWdiInd           = NULL;


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

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
         "%s", __func__);

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/

  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  pWdiInd = (WDI_StopBatchScanIndType *)pEventData->pEventData;
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/

  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                        WDI_STOP_BATCH_SCAN_IND,
                        sizeof(tHalBatchScanStopIndParam),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(tHalBatchScanStopIndParam))))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
              "Unable to get send buffer in stop batch scan ind %p ",
                pEventData);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pHalInd = (tHalBatchScanStopIndParam *)(pSendBuffer + usDataOffset);
  pHalInd->param = pWdiInd->param;

  pWDICtx->pReqStatusUserData = NULL;
  pWDICtx->pfncRspCB = NULL;
  /*-------------------------------------------------------------------------
    Send Stop batch scan indication to HAL
  -------------------------------------------------------------------------*/
  wdiStatus =  WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize);
  return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC;
}

/**
 @brief This API is called to trigger batch scan results from FW

 @param pWDICtx:         pointer to the WLAN DAL context
        pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessTriggerBatchScanResultInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status                        wdiStatus;
  wpt_uint8*                        pSendBuffer        = NULL;
  wpt_uint16                        usDataOffset       = 0;
  wpt_uint16                        usSendSize         = 0;
  tHalBatchScanTriggerResultParam   *pHalInd           = NULL;
  WDI_TriggerBatchScanResultIndType *pWdiInd           = NULL;


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

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
         "%s", __func__);

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/

  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  pWdiInd = (WDI_TriggerBatchScanResultIndType *)pEventData->pEventData;
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/

  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                        WDI_TRIGGER_BATCH_SCAN_RESULT_IND,
                        sizeof(tHalBatchScanTriggerResultParam),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(tHalBatchScanTriggerResultParam))))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
              "Unable to get send buffer in stop batch scan ind %p ",
                pEventData);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pHalInd = (tHalBatchScanTriggerResultParam *)(pSendBuffer + usDataOffset);
  pHalInd->param = pWdiInd->param;

  pWDICtx->pReqStatusUserData = NULL;
  pWDICtx->pfncRspCB = NULL;
  /*-------------------------------------------------------------------------
    Send trigger batch scan result indication to HAL
  -------------------------------------------------------------------------*/
  wdiStatus =  WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize);
  return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC;
}


/**
 @brief Process set batch scan response from FW

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSetBatchScanRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
    WDI_SetBatchScanCb   wdiSetBatchScanCb;
    WDI_SetBatchScanRspType *pSetBatchScanRsp;

    tHalBatchScanSetRspParam *pHalSetBatchScanRsp;
    /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

    /*sanity check*/
    if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }

    wdiSetBatchScanCb = (WDI_SetBatchScanCb)pWDICtx->pfncRspCB;
    if ( NULL == wdiSetBatchScanCb)
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
            "%s: call back function is NULL", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }

    pSetBatchScanRsp = wpalMemoryAllocate(sizeof(WDI_SetBatchScanRspType));

    if (NULL == pSetBatchScanRsp)
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
            "Failed to allocate memory in set batch scan response %p %p %p ",
            pWDICtx, pEventData, pEventData->pEventData);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }

    /* extract response and send it to UMAC */
    pHalSetBatchScanRsp = (tHalBatchScanSetRspParam *)pEventData->pEventData;

    pSetBatchScanRsp->nScansToBatch = pHalSetBatchScanRsp->supportedMscan;

    /* Notify UMAC */
    wdiSetBatchScanCb(pSetBatchScanRsp, pWDICtx->pRspCBUserData);

    wpalMemoryFree(pSetBatchScanRsp);

    return WDI_STATUS_SUCCESS;
}/* WDI_ProcessSetBatchScanRsp */

/**
 @brief Process batch scan result indication from FW

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessBatchScanResultInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
    void *pBatchScanResultInd;
    WDI_LowLevelIndType wdiInd;
    /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

    /* sanity check */
    if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: Invalid parameters", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }

    /* extract response and send it to UMAC */
    pBatchScanResultInd = (void *)pEventData->pEventData;

    /* Fill in the indication parameters */
    wdiInd.wdiIndicationType = WDI_BATCH_SCAN_RESULT_IND;

    wdiInd.wdiIndicationData.pBatchScanResult = pBatchScanResultInd;

    /* Notify UMAC */
    if (pWDICtx->wdiLowLevelIndCB)
    {
        pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
    }
    else
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: WDILowLevelIndCb is null", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }

    return WDI_STATUS_SUCCESS;
} /*End of WDI_ProcessBatchScanResultInd*/

#ifdef WLAN_FEATURE_LINK_LAYER_STATS
/**
 @brief Process Link Layer Statistics Result indication from FW

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessLinkLayerStatsResultsInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
    void *pLinkLayerStatsInd;
    WDI_LLstatsResultsType *halLLStatsResults;
    wpt_macAddr  macAddr;
    WDI_LowLevelIndType wdiInd;
    /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

    VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                "%s: Event RESULTS Indication", __func__);

    /* sanity check */
    if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: Invalid parameters", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }

    /* extract response and send it to UMAC */
    pLinkLayerStatsInd = (void *)pEventData->pEventData;

    /* Fill in the indication parameters */
    wdiInd.wdiIndicationType = WDI_LL_STATS_RESULTS_IND;

    wdiInd.wdiIndicationData.wdiLinkLayerStatsResults.pLinkLayerStatsResults
           = pLinkLayerStatsInd;

    halLLStatsResults = (WDI_LLstatsResultsType *) pLinkLayerStatsInd;


   /* Need to fill in the MAC address */
   if ( WDI_STATUS_SUCCESS !=
         WDI_STATableGetStaMacAddr(pWDICtx,
                                halLLStatsResults->iface_id,
                                &macAddr))
   {
     VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                 " ifaceId: %u does not exist in the WDI Station Table",
                 halLLStatsResults->iface_id);

     return WDI_STATUS_E_FAILURE;
   }
   wpalMemoryCopy(wdiInd.wdiIndicationData.wdiLinkLayerStatsResults.macAddr,
                    macAddr, WDI_MAC_ADDR_LEN);

   VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
      "ifaceId: %u, macAddr: %pM \n", halLLStatsResults->iface_id,
           wdiInd.wdiIndicationData.wdiLinkLayerStatsResults.macAddr);

    /* Notify UMAC */
    if (pWDICtx->wdiLowLevelIndCB)
    {
        pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
    }
    else
    {
        VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                 "%s: WDILowLevelIndCb is null", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }

    return WDI_STATUS_SUCCESS;
} /* End of WDI_ProcessLinkLayerStatsResultsInd */
#endif /* WLAN_FEATURE_LINK_LAYER_STATS */

/**
 @brief WDI_ProcessSetBatchScanReq -
    Set batch scan request to FW

 @param  pWDICtx : wdi context
         pEventData : indication data

 @see
 @return none
*/
WDI_Status WDI_ProcessSetBatchScanReq
(
    WDI_ControlBlockType*  pWDICtx,
    WDI_EventInfoType*     pEventData
)
{
    WDI_SetBatchScanReqType *pWdiReq;
    WDI_Status               wdiStatus;
    wpt_uint8*               pSendBuffer        = NULL;
    wpt_uint16               usDataOffset       = 0;
    wpt_uint16               usSendSize         = 0;
    tHalBatchScanSetParams  *pHalReq;
    /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

    /*sanity check*/
    if ((NULL == pEventData) || (NULL == pEventData->pEventData))
    {
        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
            "%s: Invalid parameters in set batch scan request", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }


    pWdiReq = (WDI_SetBatchScanReqType *)pEventData->pEventData;


    /*get message buffer*/
    if ((WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(pWDICtx,
                              WDI_SET_BATCH_SCAN_REQ,
                              sizeof(tHalBatchScanSetParams),
                              &pSendBuffer, &usDataOffset, &usSendSize))||
      (usSendSize < (usDataOffset + sizeof(tHalBatchScanSetParams))))
    {
        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_ERROR,
            "Unable to get send buffer for SET_BATCH_SCAN_REQ ");
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }

    pHalReq = (tHalBatchScanSetParams *)(pSendBuffer + usDataOffset);

    pHalReq->rtt = pWdiReq->rtt;
    pHalReq->rfBand = pWdiReq->rfBand;
    pHalReq->bestNetworks = pWdiReq->bestNetwork;
    pHalReq->scanInterval = pWdiReq->scanFrequency;
    pHalReq->numScan2Batch = pWdiReq->numberOfScansToBatch;

    /*send set batch scan request to fw*/
    pWDICtx->pfncRspCB          = pEventData->pCBfnc;
    pWDICtx->pReqStatusUserData = pEventData->pUserData;

    wdiStatus = WDI_SendMsg(pWDICtx, pSendBuffer,
                          usSendSize, pWDICtx->pfncRspCB,
                          pWDICtx->pReqStatusUserData,
                          WDI_SET_BATCH_SCAN_RESP);

    return wdiStatus;
}

/**
 @brief WDI_SetBatchScanReq
    This API is called to set batch scan request in FW

 @param pBatchScanReqParam : pointer to set batch scan re param
        usrData : Client context
        setBatchScanRspCb : set batch scan resp callback
 @see
 @return SUCCESS or FAIL
*/
WDI_Status WDI_SetBatchScanReq
(
    void *pBatchScanReqParam,
    void *usrData,
    WDI_SetBatchScanCb setBatchScanRspCb
)
{
    WDI_EventInfoType      wdiEventData;

    /*sanity check*/
    if (eWLAN_PAL_FALSE == gWDIInitialized)
    {
        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
            "WDI API call before module is initialized - Fail request");

        return WDI_STATUS_E_NOT_ALLOWED;
    }

    /* fill in event data and post to the main FSM */
    wdiEventData.wdiRequest      = WDI_SET_BATCH_SCAN_REQ;
    wdiEventData.pEventData      = pBatchScanReqParam;
    wdiEventData.uEventDataSize  = sizeof(WDI_SetBatchScanReqType);
    wdiEventData.pCBfnc          = setBatchScanRspCb;
    wdiEventData.pUserData       = usrData;

    return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief WDI_StopbatchScanInd: Send stop batch scan indication to FW

 @param None

 @see

 @return Status of the request
*/
WDI_Status
WDI_StopBatchScanInd(WDI_StopBatchScanIndType *pWdiReq)
{
  WDI_EventInfoType      wdiEventData;

  /*-------------------------------------------------------------------------
    Sanity Check
   ------------------------------------------------------------------------*/
  if (eWLAN_PAL_FALSE == gWDIInitialized)
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "WDI API call before module is initialized - Fail request!");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*-------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
   ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_STOP_BATCH_SCAN_IND;
  wdiEventData.pEventData      = pWdiReq;
  wdiEventData.uEventDataSize  = sizeof(WDI_StopBatchScanIndType);
  wdiEventData.pCBfnc          = NULL;
  wdiEventData.pUserData       = NULL;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief WDI_TriggerBatchScanResultInd
    This API is called to pull batch scan result from FW

 @param pWdiReq : pointer to get batch scan ind param
 @see
 @return SUCCESS or FAIL
*/
WDI_Status WDI_TriggerBatchScanResultInd
(
    WDI_TriggerBatchScanResultIndType *pWdiReq
)
{
    WDI_EventInfoType      wdiEventData;
    /*-------------------------------------------------------------------------
      Sanity Check
    ------------------------------------------------------------------------*/
    if (eWLAN_PAL_FALSE == gWDIInitialized)
    {
        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
             "WDI API call before module is initialized - Fail request!");

        return WDI_STATUS_E_NOT_ALLOWED;
    }

    /*-------------------------------------------------------------------------
      Fill in Event data and post to the Main FSM
     ------------------------------------------------------------------------*/
    wdiEventData.wdiRequest      = WDI_TRIGGER_BATCH_SCAN_RESULT_IND;
    wdiEventData.pEventData      = pWdiReq;
    wdiEventData.uEventDataSize  = sizeof(WDI_TriggerBatchScanResultIndType);
    wdiEventData.pCBfnc          = NULL;
    wdiEventData.pUserData       = NULL;

    return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}
#endif /*FEATURE_WLAN_BATCH_SCAN*/

/**
 @brief Process Update Channel Rsp function (called when a response is
        being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessUpdateChanRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status           wdiStatus;
  eHalStatus           halStatus;
  WDI_UpdateChannelRspCb   wdiUpdateChanRspCb;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiUpdateChanRspCb = (WDI_UpdateChannelRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  halStatus = *((eHalStatus*)pEventData->pEventData);
  wdiStatus   =   WDI_HAL_2_WDI_STATUS(halStatus);

  wdiUpdateChanRspCb( wdiStatus, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessUpdateChanRsp*/

#ifdef FEATURE_WLAN_CH_AVOID
/**
 @brief v -WDI_ProcessChAvoidInd


 @param  pWDICtx : wdi context
         pEventData : indication data
 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessChAvoidInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_LowLevelIndType  wdiInd;
  tHalAvoidFreqRangeIndParams chAvoidIndicationParam;
  wpt_uint16           rangeLoop;
  wpt_uint32           dataSize;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
  Sanity check
 -------------------------------------------------------------------------*/
  if ((NULL == pWDICtx) || (NULL == pEventData) ||
      (NULL == pEventData->pEventData))
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  dataSize = sizeof(tHalAvoidFreqRangeIndParams);
  if (dataSize > pEventData->uEventDataSize)
    dataSize = pEventData->uEventDataSize;

  /*-------------------------------------------------------------------------
  Extract indication and send it to UMAC
 -------------------------------------------------------------------------*/
  wpalMemoryCopy(&chAvoidIndicationParam,
                 pEventData->pEventData,
                 dataSize);

  /* Avoid Over flow */
  if (WLAN_HAL_MAX_AVOID_FREQ_RANGE < chAvoidIndicationParam.avoidCnt)
     chAvoidIndicationParam.avoidCnt = WLAN_HAL_MAX_AVOID_FREQ_RANGE;

  wdiInd.wdiIndicationType = WDI_CH_AVOID_IND;
  wdiInd.wdiIndicationData.wdiChAvoidInd.avoidRangeCount =
               chAvoidIndicationParam.avoidCnt;
  wpalMemoryCopy((void *)wdiInd.wdiIndicationData.wdiChAvoidInd.avoidFreqRange,
                 (void *)chAvoidIndicationParam.avoidRange,
                 wdiInd.wdiIndicationData.wdiChAvoidInd.avoidRangeCount *
                 sizeof(WDI_ChAvoidFreqType));
  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
          "%s: band count %d", __func__,
          wdiInd.wdiIndicationData.wdiChAvoidInd.avoidRangeCount);
  for (rangeLoop = 0; rangeLoop < chAvoidIndicationParam.avoidCnt; rangeLoop++)
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
          "%s: srart freq %d, end freq %d", __func__,
          wdiInd.wdiIndicationData.wdiChAvoidInd.avoidFreqRange[rangeLoop].startFreq,
          wdiInd.wdiIndicationData.wdiChAvoidInd.avoidFreqRange[rangeLoop].endFreq);
  }

  /*Notify UMAC*/
  if (pWDICtx->wdiLowLevelIndCB)
  {
    pWDICtx->wdiLowLevelIndCB(&wdiInd, pWDICtx->pIndUserData);
  }

  return WDI_STATUS_SUCCESS;
}

#endif /* FEATURE_WLAN_CH_AVOID */

/**
 @brief Process OBSS Start scan result indication

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessHT40OBSSScanInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  wpt_uint8*              pSendBuffer        = NULL;
  wpt_uint16              usDataOffset       = 0;
  wpt_uint16              usSendSize         = 0;
  wpt_uint16              usLen              = 0;
  WDI_HT40ObssScanIndType *pwdiHT40OBSSScanInd = NULL;
  WDI_HT40ObssScanParamsType  *pwdiHT40OBSSScanParams = NULL;
  tHT40ObssScanIndType*      pHT40ObssScanInd = NULL;
  WDI_Status wdiStatus = WDI_STATUS_SUCCESS;

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

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
         "%s", __func__);

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  pwdiHT40OBSSScanParams = (WDI_HT40ObssScanParamsType*)pEventData->pEventData;

  pwdiHT40OBSSScanInd = &pwdiHT40OBSSScanParams->wdiHT40ObssScanParam;
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/

  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                        WDI_START_HT40_OBSS_SCAN_IND,
                        sizeof(tHT40ObssScanIndType),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + usLen )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
              "Unable to get send buffer in HT40 OBSS Start req %p ",
                pEventData);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  pHT40ObssScanInd = (tHT40ObssScanIndType*)(pSendBuffer+usDataOffset);
  pHT40ObssScanInd->cmdType = pwdiHT40OBSSScanInd->cmdType;
  pHT40ObssScanInd->scanType = pwdiHT40OBSSScanInd->scanType;
  pHT40ObssScanInd->OBSSScanPassiveDwellTime =
         pwdiHT40OBSSScanInd->OBSSScanPassiveDwellTime;
  pHT40ObssScanInd->OBSSScanActiveDwellTime =
         pwdiHT40OBSSScanInd->OBSSScanActiveDwellTime;
  pHT40ObssScanInd->BSSChannelWidthTriggerScanInterval =
         pwdiHT40OBSSScanInd->BSSChannelWidthTriggerScanInterval;
  pHT40ObssScanInd->OBSSScanPassiveTotalPerChannel =
         pwdiHT40OBSSScanInd->OBSSScanPassiveTotalPerChannel;
  pHT40ObssScanInd->OBSSScanActiveTotalPerChannel =
         pwdiHT40OBSSScanInd->OBSSScanActiveTotalPerChannel;
  pHT40ObssScanInd->BSSWidthChannelTransitionDelayFactor =
         pwdiHT40OBSSScanInd->BSSWidthChannelTransitionDelayFactor;
  pHT40ObssScanInd->OBSSScanActivityThreshold =
         pwdiHT40OBSSScanInd->OBSSScanActivityThreshold;
  pHT40ObssScanInd->selfStaIdx =
         pwdiHT40OBSSScanInd->selfStaIdx;
  pHT40ObssScanInd->bssIdx =
         pwdiHT40OBSSScanInd->bssIdx;
  pHT40ObssScanInd->currentOperatingClass =
         pwdiHT40OBSSScanInd->currentOperatingClass;
  pHT40ObssScanInd->fortyMHZIntolerent =
         pwdiHT40OBSSScanInd->fortyMHZIntolerent;
  pHT40ObssScanInd->channelCount =
         pwdiHT40OBSSScanInd->channelCount;

  wpalMemoryCopy(pHT40ObssScanInd->channels, pwdiHT40OBSSScanInd->channels,
                                        WDI_ROAM_SCAN_MAX_CHANNELS);
  pHT40ObssScanInd->ieFieldLen =
         pwdiHT40OBSSScanInd->ieFieldLen;

  wpalMemoryCopy(pHT40ObssScanInd->ieField, pwdiHT40OBSSScanInd->ieField,
                                        WDI_ROAM_SCAN_MAX_PROBE_SIZE);
  pWDICtx->pReqStatusUserData = NULL;
  pWDICtx->pfncRspCB = NULL;

  pWDICtx->wdiReqStatusCB     = pwdiHT40OBSSScanParams->wdiReqStatusCB;
  pWDICtx->pReqStatusUserData = pwdiHT40OBSSScanParams->pUserData;

 /*-------------------------------------------------------------------------
    Send OBSS Start Indication to HAL
  -------------------------------------------------------------------------*/
  wdiStatus =  WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize);
  return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC;

} /*End of WDI_ProcessHT40OBSSStartScanInd*/


/**
 @brief wdi_HT40OBSSScanInd
    This API is called to start OBSS scan

 @param pWdiReq : pointer to get  ind param
 @see
 @return SUCCESS or FAIL
*/
WDI_Status WDI_HT40OBSSScanInd
(
    WDI_HT40ObssScanParamsType *pWdiReq
)
{
    WDI_EventInfoType      wdiEventData;

    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
         "%s", __func__);
    /*-------------------------------------------------------------------------
      Sanity Check
    ------------------------------------------------------------------------*/
    if (eWLAN_PAL_FALSE == gWDIInitialized)
    {
        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
             "WDI API call before module is initialized - Fail request!");

        return WDI_STATUS_E_NOT_ALLOWED;
    }

    /*-------------------------------------------------------------------------
      Fill in Event data and post to the Main FSM
     ------------------------------------------------------------------------*/
    wdiEventData.wdiRequest      = WDI_START_HT40_OBSS_SCAN_IND;
    wdiEventData.pEventData      = pWdiReq;
    wdiEventData.uEventDataSize  = sizeof(WDI_HT40ObssScanParamsType);
    wdiEventData.pCBfnc          = NULL;
    wdiEventData.pUserData       = NULL;


    return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief Process OBSS Stop scan result

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessHT40OBSSStopScanInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  wpt_uint8*              pSendBuffer        = NULL;
  wpt_uint16              usDataOffset       = 0;
  wpt_uint16              usSendSize         = 0;
  wpt_uint16              usLen              = 0;
  wpt_uint8               *wdiBssIdx         = 0;
  tANI_U8                 *bssIdx            = 0;
  WDI_Status              wdiStatus = WDI_STATUS_SUCCESS;

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

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
         "%s", __func__);

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  bssIdx = (wpt_uint8*)pEventData->pEventData;
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/

  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                        WDI_STOP_HT40_OBSS_SCAN_IND,
                        sizeof(tANI_U8),
                        &pSendBuffer, &usDataOffset, &usSendSize))||
      ( usSendSize < (usDataOffset + usLen )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
              "Unable to get send buffer in HT40 OBSS Start req %p ",
                pEventData);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  bssIdx = (tANI_U8*)pSendBuffer+usDataOffset;
  bssIdx = wdiBssIdx;

  pWDICtx->pReqStatusUserData = NULL;
  pWDICtx->pfncRspCB = NULL;

 /*-------------------------------------------------------------------------
    Send DHCP Start Indication to HAL
  -------------------------------------------------------------------------*/
  wdiStatus =  WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize);
  return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC;
} /*End of WDI_ProcessHT40OBSSStopScanInd*/

/**
 @brief WDI_HT40OBSSStopScanInd
    This API is called to start OBSS scan
 @param pWdiReq : pointer to get  ind param
 @see
 @return SUCCESS or FAIL
*/
WDI_Status WDI_HT40OBSSStopScanInd
(
    wpt_uint8 bssIdx
)
{
    WDI_EventInfoType      wdiEventData;

    /*-------------------------------------------------------------------------
      Sanity Check
    ------------------------------------------------------------------------*/
    if (eWLAN_PAL_FALSE == gWDIInitialized)
    {
        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
             "WDI API call before module is initialized - Fail request!");

        return WDI_STATUS_E_NOT_ALLOWED;
    }

    /*-------------------------------------------------------------------------
      Fill in Event data and post to the Main FSM
     ------------------------------------------------------------------------*/
    wdiEventData.wdiRequest      = WDI_STOP_HT40_OBSS_SCAN_IND;
    wdiEventData.pEventData      = &bssIdx;
    wdiEventData.uEventDataSize  = sizeof(wpt_uint8);
    wdiEventData.pCBfnc          = NULL;
    wdiEventData.pUserData       = NULL;

    return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

WDI_Status
WDI_printRegInfo
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   tHalRegDebugInfo *pRegTable;
   tHalRegDebugInfoParams *pRegParams;
   uint32 cnt=0;

   WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
                  "%s: ", __func__);
    /*-------------------------------------------------------------------------
     Sanity check
    -------------------------------------------------------------------------*/
   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
       ( NULL == pEventData->pEventData))
   {
       WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
       WDI_ASSERT(0);
       return WDI_STATUS_E_FAILURE;
   }

   pRegParams  = (tHalRegDebugInfoParams *)pEventData->pEventData;

   WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
          "%s: regCount: %x scenario: %x reasonCode: %x", __func__,
           pRegParams->regCount, pRegParams->scenario, pRegParams->reasonCode);

   pRegTable = (tHalRegDebugInfo *)(pRegParams+1); //data starts after regParams

   if (pRegParams->regCount <= 0)
   {
       WPAL_TRACE (eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                   "%s incorrect parameters passed", __func__);
       return WDI_STATUS_E_FAILURE;
   }

   while(pRegParams->regCount--)
   {
       WPAL_TRACE (eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                   "%x: %x", pRegTable[cnt].regAddr, pRegTable[cnt].regValue);
       cnt++;
   }

   return WDI_STATUS_SUCCESS;
}

/*
 * FUNCTION: WDI_delBaInd
 * send the delBA to peer.
 */

WDI_Status
WDI_delBaInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData

)
{
  tHalWlanDelBaIndMsg    halDelBaInd;
  WDI_LowLevelIndType    wdiInd;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
        Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
       WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                  "%s: Invalid parameters", __func__);
       WDI_ASSERT(0);
       return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
        Extract indication and send it to UMAC
  -------------------------------------------------------------------------*/

  /* Parameters need to be unpacked according to HAL struct*/
  wpalMemoryCopy( &halDelBaInd,
                  pEventData->pEventData,
                  sizeof(halDelBaInd));

  /*Fill in the indication parameters*/
  wdiInd.wdiIndicationType = WDI_DEL_BA_IND;

  wdiInd.wdiIndicationData.wdiDeleteBAInd.staIdx = halDelBaInd.staIdx;
  wpalMemoryCopy(wdiInd.wdiIndicationData.wdiDeleteBAInd.peerMacAddr,
                            halDelBaInd.peerMacAddr, WDI_MAC_ADDR_LEN);

  wdiInd.wdiIndicationData.wdiDeleteBAInd.baTID = halDelBaInd.baTID;
  wdiInd.wdiIndicationData.wdiDeleteBAInd.baDirection = halDelBaInd.baDirection;
  wdiInd.wdiIndicationData.wdiDeleteBAInd.reasonCode = halDelBaInd.reasonCode;

  wpalMemoryCopy(wdiInd.wdiIndicationData.wdiDeleteBAInd.bssId,
                            halDelBaInd.bssId, WDI_MAC_ADDR_LEN);
  if ( pWDICtx->wdiLowLevelIndCB )
  {
        /*Notify UMAC*/
        pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
  }

  return WDI_STATUS_SUCCESS;


}

/*
 * FUNCTION: WDI_ProcessGetBcnMissRateRsp
 * send the response to PE with beacon miss count
 * received from WDI.
 */
WDI_Status
WDI_ProcessGetBcnMissRateRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_GetBcnMissRateCb        wdiGetBcnMissRateCb;
  tpHalBcnMissRateRspParams    pHalBcnMissRateRsp;

  WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
                 "In %s",__func__);
 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pHalBcnMissRateRsp = (tHalBcnMissRateRspParams *)pEventData->pEventData;
  wdiGetBcnMissRateCb = (WDI_GetBcnMissRateCb)pWDICtx->pfncRspCB;

  /*Notify UMAC*/
  wdiGetBcnMissRateCb(pHalBcnMissRateRsp->status,
                      pHalBcnMissRateRsp->bcnMissCnt, pWDICtx->pRspCBUserData);
  return WDI_STATUS_SUCCESS;
}

/*
 * FUNCTION: WDI_ProcessGetBcnMissRateReq
 * Request to WDI to get missed beacon rate.
 */
WDI_Status
WDI_ProcessGetBcnMissRateReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  wpt_uint8*                   pSendBuffer         = NULL;
  wpt_uint16                   usDataOffset        = 0;
  wpt_uint16                   usSendSize          = 0;
  wpt_uint8                    ucCurrentBSSSesIdx  = 0;
  WDI_BSSSessionType*          pBSSSes             = NULL;
  WDI_GetBcnMissRateCb        *wdiGetBcnMissRateCb;
  tHalBcnMissRateReqParams    halBcnMissRateReq;

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

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData) ||
      ( NULL == pEventData->pCBfnc ) )
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiGetBcnMissRateCb   = (WDI_GetBcnMissRateCb *)pEventData->pCBfnc;

  wpalMutexAcquire(&pWDICtx->wptMutex);

  ucCurrentBSSSesIdx = WDI_FindAssocSession(pWDICtx,
                                            pEventData->pEventData, &pBSSSes);
  if ( NULL == pBSSSes )
  {
    WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
        "%s: Association sequence for this BSS does not yet exist. macBSSID"
         MAC_ADDRESS_STR, __func__,
         MAC_ADDR_ARRAY((wpt_uint8 *)(pEventData->pEventData)));
    wpalMutexRelease(&pWDICtx->wptMutex);
    return WDI_STATUS_E_NOT_ALLOWED;
  }
  wpalMutexRelease(&pWDICtx->wptMutex);

  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(
                                  pWDICtx, WDI_GET_BCN_MISS_RATE_REQ,
                                  sizeof(tHalBcnMissRateReqParams),
                                 &pSendBuffer, &usDataOffset, &usSendSize)) ||
      ( usSendSize < (usDataOffset + sizeof(tHalBcnMissRateReqParams))))
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                "Unable to get send buffer in get WDI_GET_BCN_MISS_RATE_REQ %p",
                pEventData);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pWDICtx->wdiReqStatusCB = NULL;
  pWDICtx->pReqStatusUserData = pEventData->pUserData;

  halBcnMissRateReq.bssIdx = ucCurrentBSSSesIdx;

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halBcnMissRateReq,
                  sizeof(tHalBcnMissRateReqParams));
  /*-------------------------------------------------------------------------
    Send Get STA Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, wdiGetBcnMissRateCb,
                       pEventData->pUserData, WDI_GET_BCN_MISS_RATE_RSP);
}

/**
 @brief WDI_GetBcnMissRate

 @param pUserData: user data will be passed back with the
        callback
        WDI_GetBcnMissRateCb: callback for passing back the response
        of the get stats operation received from the device
        bssid: bssid, to send bssIdx to FW

 @return SUCCESS or FAIL
*/
WDI_Status WDI_GetBcnMissRate( void *pUserData,
                                WDI_GetBcnMissRateCb wdiGetBcnMissRateCb,
                                tANI_U8 *bssid )
{
    WDI_EventInfoType      wdiEventData;

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

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

    return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_GET_BCN_MISS_RATE_REQ;
  wdiEventData.pEventData      = bssid;
  wdiEventData.uEventDataSize  = sizeof(tSirMacAddr);
  wdiEventData.pCBfnc          = wdiGetBcnMissRateCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/*
 * FUNCTION: WDI_ProcessGetFwStatsRsp
 * send the response with FW stats asked.
 */
WDI_Status
       WDI_ProcessGetFwStatsRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_FWStatsGetRspCb        wdiGetFwstatsCb;
  tpHalfwStatsRspParams      pHalFwstatsRsp;
  WDI_FWStatsResults         fwStats;

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

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  pHalFwstatsRsp = (tHalfwStatsRspParams *)pEventData->pEventData;
  wdiGetFwstatsCb = (WDI_FWStatsGetRspCb) pWDICtx->pfncRspCB;

  if(pHalFwstatsRsp->length)
  {
     switch( pHalFwstatsRsp->type )
     {
        case FW_UBSP_STATS:
        {
             ubspFwStats *ubspStatsfromFw;

             fwStats.type = pHalFwstatsRsp->type;
             ubspStatsfromFw = (ubspFwStats *) pHalFwstatsRsp->data;
             fwStats.wdiFwStatsData.ubspStats.ubsp_enter_cnt =
                                             ubspStatsfromFw->ubsp_enter_cnt;
             fwStats.wdiFwStatsData.ubspStats.ubsp_jump_ddr_cnt =
                                          ubspStatsfromFw->ubsp_jump_ddr_cnt;
        }
        break;
        default:
        {
             WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
               "%s: No handling for stats type %d", __func__,
               pHalFwstatsRsp->type);
             wdiGetFwstatsCb(WDI_STATUS_E_FAILURE,
                    NULL, pWDICtx->pRspCBUserData);
             return WDI_STATUS_E_FAILURE;
        }
     }
     wdiGetFwstatsCb(WDI_STATUS_SUCCESS, &fwStats , pWDICtx->pRspCBUserData);
  }
  else
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
            "%s: Length = 0 for type %d return failure ", __func__,
              pHalFwstatsRsp->type);
     wdiGetFwstatsCb(WDI_STATUS_E_FAILURE,
                      NULL, pWDICtx->pRspCBUserData);
     return WDI_STATUS_E_FAILURE;
  }
  return WDI_STATUS_SUCCESS;
}

/*
 * FUNCTION: WDI_ProcessGetFwStatsReq
 * Request to WDI to get FW Stats.
 */
WDI_Status
       WDI_ProcessGetFwStatsReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  wpt_uint8*                   pSendBuffer         = NULL;
  wpt_uint16                   usDataOffset        = 0;
  wpt_uint16                   usSendSize          = 0;
  WDI_FWStatsGetRspCb          *wdiGetFwstatsCb;
  tHalfwStatsReqParams         halFwStatsReq;

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

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData) ||
      ( NULL == pEventData->pCBfnc ) )
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiGetFwstatsCb   = (WDI_FWStatsGetRspCb *)pEventData->pCBfnc;

  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(
                                  pWDICtx, WDI_GET_FW_STATS_REQ,
                                  sizeof(tHalfwStatsReqParams),
                                 &pSendBuffer, &usDataOffset, &usSendSize)) ||
      ( usSendSize < (usDataOffset + sizeof(tHalfwStatsReqParams))))
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                "Unable to get send buffer in get WDI_GET_FW_STAS_REQ %p",
                pEventData);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pWDICtx->wdiReqStatusCB = NULL;
  pWDICtx->pReqStatusUserData = pEventData->pEventData;
  halFwStatsReq.type = *((wpt_uint32 *)(pEventData->pEventData));
  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  &halFwStatsReq,
                  sizeof(tHalfwStatsReqParams));
  /*-------------------------------------------------------------------------
    Send Get STA Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, wdiGetFwstatsCb,
                       pEventData->pUserData, WDI_GET_FW_STATS_RSP);
}

#ifdef WLAN_FEATURE_LINK_LAYER_STATS

/**
 @brief WDI_LLStatsSetReq
    This API is called to set link layer stats request in FW

 @param pwdiLLStatsSetReqParams : pointer to set link layer request params
        wdiLLStatsSetRspCb : set link layer stats resp callback
        usrData : Client context
 @see
 @return SUCCESS or FAIL
*/
WDI_Status
WDI_LLStatsSetReq(WDI_LLStatsSetReqType* pwdiLLStatsSetReqParams,
                           WDI_LLStatsSetRspCb   wdiLLStatsSetRspCb,
                           void*                   pUserData)
{
   WDI_EventInfoType      wdiEventData;

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
     VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
  }

  wdiEventData.wdiRequest      = WDI_LL_STATS_SET_REQ;
  wdiEventData.pEventData      = pwdiLLStatsSetReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiLLStatsSetReqParams);
  wdiEventData.pCBfnc          = wdiLLStatsSetRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief WDI_ProcessLLStatsSetReq -
    Set Link Layer Stats request to FW

 @param  pWDICtx : wdi context
         pEventData : indication data

 @see
 @return none
*/
WDI_Status
WDI_ProcessLLStatsSetReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_LLStatsSetReqType* pwdiLLStatsSetReqParams;
  WDI_LLStatsSetRspCb wdiLLStatsSetCb;
  wpt_uint8*               pSendBuffer         = NULL;
  wpt_uint16               usSendSize          = 0;
  wpt_uint16               usDataOffset        = 0;
  tHalMacLlSetStatsReqParams halLLStatsSetParams;

  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiLLStatsSetReqParams = (WDI_LLStatsSetReqType*)pEventData->pEventData;
  wdiLLStatsSetCb   = (WDI_LLStatsSetRspCb)pEventData->pCBfnc;

  /*-----------------------------------------------------------------------
    Get message buffer
    ! TO DO : proper conversion into the HAL Message Request Format
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(
                                        pWDICtx,
                                        WDI_LL_STATS_SET_REQ,
                                        sizeof(tHalMacLlSetStatsReqParams),
                                        &pSendBuffer, &usDataOffset,
                                        &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halLLStatsSetParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in %s %p %p %p", __func__,
                pEventData, pwdiLLStatsSetReqParams, wdiLLStatsSetCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }


  /* Need to fill in the self STA Index */
  if ( WDI_STATUS_SUCCESS !=
  WDI_STATableFindStaidByAddr(pWDICtx,
                              pwdiLLStatsSetReqParams->macAddr,
                              &halLLStatsSetParams.sta_id))
  {
    VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                MAC_ADDRESS_STR
                ": This station does not exist in the WDI Station Table",
                MAC_ADDR_ARRAY(pwdiLLStatsSetReqParams->macAddr));

    wpalMemoryFree(pSendBuffer);
    return WDI_STATUS_E_FAILURE;
  }

  halLLStatsSetParams.req_id = pwdiLLStatsSetReqParams->reqId;
  halLLStatsSetParams.mpdu_size_threshold =
      pwdiLLStatsSetReqParams->mpduSizeThreshold;
  halLLStatsSetParams.aggressive_statistics_gathering =
      pwdiLLStatsSetReqParams->aggressiveStatisticsGathering;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  " halLLStatsSetParams.req_id = %u",
                  halLLStatsSetParams.req_id);
  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  " halLLStatsSetParams.sta_id = %u",
                  halLLStatsSetParams.sta_id);
  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  " halLLStatsSetParams.mpdu_size_threshold = %u",
                  halLLStatsSetParams.mpdu_size_threshold);
  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  " halLLStatsSetParams.aggressive_statistics_gathering = %u",
                  halLLStatsSetParams.aggressive_statistics_gathering);

  wpalMemoryCopy(pSendBuffer+usDataOffset,
                  &halLLStatsSetParams,
                  sizeof(halLLStatsSetParams));

  pWDICtx->pReqStatusUserData = pEventData->pUserData;

  /*-------------------------------------------------------------------------
    Send Clear Link Layer Stats Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiLLStatsSetCb, pEventData->pUserData,
                       WDI_LL_STATS_SET_RSP);
}

/**
 @brief WDI_LLStatsGetReq
    This API is called to get link layer stats request in FW

 @param pwdiLLStatsGetReqParams : pointer to set link layer request params
        wdiLLStatsGetRspCb : get link layer stats resp callback
        usrData : Client context
 @see
 @return SUCCESS or FAIL
*/
WDI_Status
WDI_LLStatsGetReq(WDI_LLStatsGetReqType* pwdiLLStatsGetReqParams,
                           WDI_LLStatsGetRspCb   wdiLLStatsGetRspCb,
                           void*                   pUserData)
{
   WDI_EventInfoType      wdiEventData;

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
  }

  wdiEventData.wdiRequest      = WDI_LL_STATS_GET_REQ;
  wdiEventData.pEventData      = pwdiLLStatsGetReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiLLStatsGetReqParams);
  wdiEventData.pCBfnc          = wdiLLStatsGetRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief WDI_ProcessLLStatsGetReq -
    Get Link Layer Stats request to FW

 @param  pWDICtx : wdi context
         pEventData : indication data

 @see
 @return none
*/
WDI_Status
WDI_ProcessLLStatsGetReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_LLStatsGetReqType* pwdiLLStatsGetReqParams;
  WDI_LLStatsGetRspCb wdiLLStatsGetCb;
  wpt_uint8*               pSendBuffer         = NULL;
  wpt_uint16               usSendSize          = 0;
  wpt_uint16               usDataOffset        = 0;
  tHalMacLlGetStatsReqParams halLLStatsGetParams;

  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiLLStatsGetReqParams = (WDI_LLStatsGetReqType*)pEventData->pEventData;
  wdiLLStatsGetCb   = (WDI_LLStatsGetRspCb)pEventData->pCBfnc;

  /*-----------------------------------------------------------------------
    Get message buffer
    ! TO DO : proper conversion into the HAL Message Request Format
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(
                                            pWDICtx,
                                            WDI_LL_STATS_GET_REQ,
                                            sizeof(tHalMacLlGetStatsReqParams),
                                            &pSendBuffer, &usDataOffset,
                                             &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halLLStatsGetParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in %s %p %p %p", __func__,
                pEventData, pwdiLLStatsGetReqParams, wdiLLStatsGetCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  /* Need to fill in the self STA Index */
  if ( WDI_STATUS_SUCCESS !=
  WDI_STATableFindStaidByAddr(pWDICtx,
                              pwdiLLStatsGetReqParams->macAddr,
                &halLLStatsGetParams.sta_id))
  {
    VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                MAC_ADDRESS_STR
                ": This station does not exist in the WDI Station Table",
                MAC_ADDR_ARRAY(pwdiLLStatsGetReqParams->macAddr));

    wpalMemoryFree(pSendBuffer);
    return WDI_STATUS_E_FAILURE;
  }

  halLLStatsGetParams.req_id = pwdiLLStatsGetReqParams->reqId;
  halLLStatsGetParams.param_id_mask = pwdiLLStatsGetReqParams->paramIdMask;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  " halLLStatsGetParams.req_id = %u",
                  halLLStatsGetParams.req_id);
  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  " halLLStatsGetParams.staId = %u",
                  halLLStatsGetParams.sta_id);
  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  " halLLStatsGetParams.Mask = %u",
                  halLLStatsGetParams.param_id_mask);

  wpalMemoryCopy(pSendBuffer+usDataOffset,
                  &halLLStatsGetParams,
                  sizeof(halLLStatsGetParams));

  pWDICtx->pReqStatusUserData = pEventData->pUserData;

  /*-------------------------------------------------------------------------
    Send Clear Link Layer Stats Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiLLStatsGetCb, pEventData->pUserData,
                       WDI_LL_STATS_GET_RSP);
}

/**
 @brief WDI_LLStatsClearReq
    This API is called to clear link layer stats request in FW

 @param pwdiLLStatsClearReqParams : pointer to clear link layer request params
        wdiLLStatsSetRspCb : clear link layer stats resp callback
        usrData : Client context
 @see
 @return SUCCESS or FAIL
*/
WDI_Status
WDI_LLStatsClearReq(WDI_LLStatsClearReqType* pwdiLLStatsClearReqParams,
                           WDI_LLStatsClearRspCb   wdiLLStatsClearRspCb,
                           void*                   pUserData)
{
   WDI_EventInfoType      wdiEventData;

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
  }

  wdiEventData.wdiRequest      = WDI_LL_STATS_CLEAR_REQ;
  wdiEventData.pEventData      = pwdiLLStatsClearReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiLLStatsClearReqParams);
  wdiEventData.pCBfnc          = wdiLLStatsClearRspCb;
  wdiEventData.pUserData       = pUserData;

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
  "%s:%d Enter", __func__, __LINE__);

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief WDI_ProcessLLStatsClearReq -
    Clear Link Layer Stats request to FW

 @param  pWDICtx : wdi context
         pEventData : indication data

 @see
 @return none
*/
WDI_Status
WDI_ProcessLLStatsClearReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_LLStatsClearReqType* pwdiLLStatsClearReqParams;
  WDI_LLStatsClearRspCb wdiLLStatsClearCb;
  wpt_uint8*               pSendBuffer         = NULL;
  wpt_uint16               usSendSize          = 0;
  wpt_uint16               usDataOffset        = 0;
  tHalMacLlClearStatsReqParams halLLStatsClearParams;

  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiLLStatsClearReqParams = (WDI_LLStatsClearReqType*)pEventData->pEventData;
  wdiLLStatsClearCb   = (WDI_LLStatsClearRspCb)pEventData->pCBfnc;

  /*-----------------------------------------------------------------------
    Get message buffer
    ! TO DO : proper conversion into the HAL Message Request Format
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(
                                          pWDICtx,
                                          WDI_LL_STATS_CLEAR_REQ,
                                          sizeof(tHalMacLlClearStatsReqParams),
                                          &pSendBuffer, &usDataOffset,
                                          &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halLLStatsClearParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in %s %p %p %p", __func__,
                pEventData, pwdiLLStatsClearReqParams, wdiLLStatsClearCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  /* Need to fill in the self STA Index */
  if ( WDI_STATUS_SUCCESS !=
  WDI_STATableFindStaidByAddr(pWDICtx,
                              pwdiLLStatsClearReqParams->macAddr,
                &halLLStatsClearParams.sta_id))
  {
    VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                MAC_ADDRESS_STR
                ": This station does not exist in the WDI Station Table",
                MAC_ADDR_ARRAY(pwdiLLStatsClearReqParams->macAddr));

    wpalMemoryFree(pSendBuffer);
    return WDI_STATUS_E_FAILURE;
  }

  halLLStatsClearParams.req_id = pwdiLLStatsClearReqParams->reqId;
  halLLStatsClearParams.stats_clear_req_mask =
                    pwdiLLStatsClearReqParams->statsClearReqMask;
  halLLStatsClearParams.stop_req = pwdiLLStatsClearReqParams->stopReq;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
        "%s:HAL req_id = %d", __func__, halLLStatsClearParams.req_id);
  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
        "%s: HAL sta_id = %d", __func__, halLLStatsClearParams.sta_id);
  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
        "%s: HAL stats_clear_req_mask = 0x%X", __func__,
                            halLLStatsClearParams.stats_clear_req_mask);
  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
        "%s: HAL stop_req = %d", __func__, halLLStatsClearParams.stop_req);

  wpalMemoryCopy(pSendBuffer+usDataOffset,
                  &halLLStatsClearParams,
                  sizeof(halLLStatsClearParams));

  pWDICtx->pReqStatusUserData = pEventData->pUserData;

  /*-------------------------------------------------------------------------
    Send Clear Link Layer Stats Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiLLStatsClearCb, pEventData->pUserData,
                       WDI_LL_STATS_CLEAR_RSP);
}
#endif /* WLAN_FEATURE_LINK_LAYER_STATS */

WDI_Status WDI_FWStatsGetReq( void* pUserData,
                   WDI_FWStatsGetRspCb          wdiFWStatsGetRspCb,
                   wpt_uint32                   stats)
{
  WDI_EventInfoType         wdiEventData;

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
       WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
            "WDI API call before module is initialized - Fail request");
       return WDI_STATUS_E_NOT_ALLOWED;
  }
  /*------------------------------------------------------------------------
      Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_GET_FW_STATS_REQ;
  wdiEventData.pEventData      = (void *)&stats;
  wdiEventData.uEventDataSize  = sizeof(wpt_uint32);
  wdiEventData.pCBfnc          = wdiFWStatsGetRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}

WDI_Status
WDI_MonStartReq(WDI_MonStartReqType* pwdiMonStartReqParams,
                           WDI_MonModeRspCb   wdiMonModeRspCb,
                           void*                   pUserData)
{
   WDI_EventInfoType      wdiEventData;

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
         "%s", __func__);

  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
     VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
  }

  wdiEventData.wdiRequest      = WDI_MON_START_REQ;
  wdiEventData.pEventData      = pwdiMonStartReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiMonStartReqParams);
  wdiEventData.pCBfnc          = wdiMonModeRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

WDI_Status
WDI_ProcessMonStartReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_MonStartReqType* pwdiMonStartReqParams;
  WDI_MonModeRspCb wdiMonStartCb;
  wpt_uint8*               pSendBuffer         = NULL;
  wpt_uint16               usSendSize          = 0;
  wpt_uint16               usDataOffset        = 0;
  tHalEnableMonitorModeReqParams  halEnableMonitorModeParams;

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
         "%s", __func__);

  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiMonStartReqParams = (WDI_MonStartReqType*)pEventData->pEventData;
  wdiMonStartCb   = (WDI_MonModeRspCb)pEventData->pCBfnc;

  /*-----------------------------------------------------------------------
    Get message buffer
    ! TO DO : proper conversion into the HAL Message Request Format
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(
                                        pWDICtx,
                                        WDI_MON_START_REQ,
                                        sizeof(tHalEnableMonitorModeReqParams),
                                        &pSendBuffer, &usDataOffset,
                                        &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halEnableMonitorModeParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in %s %p %p %p", __func__,
                pEventData, pwdiMonStartReqParams, wdiMonStartCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

 halEnableMonitorModeParams.channelNumber = pwdiMonStartReqParams->ChannelNo;
 halEnableMonitorModeParams.cbState = WDI_selectCbMode(pwdiMonStartReqParams->ChannelNo,
                                                       pwdiMonStartReqParams->ChannelBW);
 halEnableMonitorModeParams.maxAmpduLen = 0x1FFFF;
 halEnableMonitorModeParams.maxMpduInAmpduLen = 0xF20-0x4C;
 halEnableMonitorModeParams.crcCheckEnabled = pwdiMonStartReqParams->crcCheckEnabled;
 halEnableMonitorModeParams.numMacFilters = pwdiMonStartReqParams->numOfMacFilters;
 wpalMemoryCopy(halEnableMonitorModeParams.macFilters[0].macAddr,
                pwdiMonStartReqParams->mmFilters[0].macAddr,
                sizeof( wpt_macAddr ));
 halEnableMonitorModeParams.macFilters[0].isA1filteringNeeded = pwdiMonStartReqParams->mmFilters[0].isA1filter;
 halEnableMonitorModeParams.macFilters[0].isA2filteringNeeded = pwdiMonStartReqParams->mmFilters[0].isA2filter;
 halEnableMonitorModeParams.macFilters[0].isA3filteringNeeded = pwdiMonStartReqParams->mmFilters[0].isA3filter;
 halEnableMonitorModeParams.typeSubtypeBitmap = pwdiMonStartReqParams->typeSubtypeBitmap;

 wpalMemoryCopy(pSendBuffer+usDataOffset,
                  &halEnableMonitorModeParams,
                  sizeof(halEnableMonitorModeParams));

 pWDICtx->pReqStatusUserData = pEventData->pUserData;

 return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                      wdiMonStartCb, pEventData->pUserData,
                      WDI_MON_START_RSP);
}

WDI_Status
WDI_ProcessMonStartRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_MonModeRspCb   wdiMonStartRspCb;

  WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "%s: Enter ", __func__);
  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiMonStartRspCb = (WDI_MonModeRspCb)pWDICtx->pfncRspCB;

  wdiMonStartRspCb((void *) pEventData->pEventData, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}

WDI_Status
WDI_MonStopReq(WDI_MonModeRspCb wdiMonModeRspCb,
               void*                 pUserData)
{
   WDI_EventInfoType      wdiEventData;

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
         "%s", __func__);

  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
     VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
  }

  wdiEventData.wdiRequest      = WDI_MON_STOP_REQ;
  wdiEventData.pEventData      = NULL;
  wdiEventData.uEventDataSize  = sizeof(NULL);
  wdiEventData.pCBfnc          = wdiMonModeRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

WDI_Status
WDI_ProcessMonStopReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_MonModeRspCb         wdiMonStopCb;
  wpt_uint8*               pSendBuffer         = NULL;
  wpt_uint16               usSendSize          = 0;
  wpt_uint16               usDataOffset        = 0;
  wpt_uint8                resetConfiguration;

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
         "%s", __func__);

  if (( NULL == pEventData ) || ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiMonStopCb   = (WDI_MonModeRspCb)pEventData->pCBfnc;

  /*-----------------------------------------------------------------------
    Get message buffer
    ! TO DO : proper conversion into the HAL Message Request Format
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(
                                        pWDICtx,
                                        WDI_MON_STOP_REQ,
                                        sizeof(wpt_uint8),
                                        &pSendBuffer, &usDataOffset,
                                        &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(wpt_uint8) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in %s %p %p", __func__,
                pEventData, wdiMonStopCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

 wpalMemoryCopy(pSendBuffer+usDataOffset,
                  &resetConfiguration,
                  sizeof(wpt_uint8));

 pWDICtx->pReqStatusUserData = pEventData->pUserData;

 return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                      wdiMonStopCb, pEventData->pUserData,
                      WDI_MON_STOP_RSP);
}

WDI_Status
WDI_ProcessMonStopRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_MonModeRspCb   wdiMonStopRspCb;

  WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "%s: Enter ", __func__);
  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiMonStopRspCb = (WDI_MonModeRspCb)pWDICtx->pfncRspCB;

  wdiMonStopRspCb(pWDICtx->pRspCBUserData, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}

#ifdef WLAN_FEATURE_EXTSCAN

/**
 @brief Process EXTSCAN BUffer full indication from FW

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessEXTScanProgressInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
    WDI_LowLevelIndType wdiInd;
    /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

    VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                "%s: ", __func__);

    /* sanity check */
    if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: Invalid parameters", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }

    /* Fill in the indication parameters */
    wdiInd.wdiIndicationType = WDI_EXTSCAN_PROGRESS_IND;

    /* extract response and send it to UMAC */
    wdiInd.wdiIndicationData.pEXTScanIndData = (void *)pEventData->pEventData;

    /* Notify UMAC */
    if (pWDICtx->wdiLowLevelIndCB)
    {
        pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
    }
    else
    {
        VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                 "%s: WDILowLevelIndCb is null", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }
    return WDI_STATUS_SUCCESS;

} /* End of WDI_ProcessEXTScanProgressInd */


/**
 @brief Process EXTScan Scan Available indication from FW

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessEXTScanScanAvailableInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
    WDI_LowLevelIndType wdiInd;
    /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

    VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                "%s: ", __func__);

    /* sanity check */
    if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: Invalid parameters", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }



    /* Fill in the indication parameters */
    wdiInd.wdiIndicationType = WDI_EXTSCAN_SCAN_AVAILABLE_IND;

    /* extract response and send it to UMAC */
    wdiInd.wdiIndicationData.pEXTScanIndData = (void *)pEventData->pEventData;

    /* Notify UMAC */
    if (pWDICtx->wdiLowLevelIndCB)
    {
        pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
    }
    else
    {
        VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                 "%s: WDILowLevelIndCb is null", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }
    return WDI_STATUS_SUCCESS;
} /* End of WDI_ProcessEXTScanScanDoneInd */

/**
 @brief Process EXTScan Result Indication indication from FW

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessEXTScanResultInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
    WDI_LowLevelIndType wdiInd;
    /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

    VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                "%s: ", __func__);

    /* sanity check */
    if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: Invalid parameters", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }

    /* Fill in the indication parameters */
    wdiInd.wdiIndicationType = WDI_EXTSCAN_SCAN_RESULT_IND;

    /* extract response and send it to UMAC */
    wdiInd.wdiIndicationData.pEXTScanIndData = (void *)pEventData->pEventData;

    /* Notify UMAC */
    if (pWDICtx->wdiLowLevelIndCB)
    {
        pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
    }
    else
    {
        VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                 "%s: WDILowLevelIndCb is null", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }
    return WDI_STATUS_SUCCESS;
} /* End of WDI_ProcessEXTScanResultInd  */

/**
 @brief Process EXTScan BSSID Hotlist Result Indication indication from FW

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessEXTScanBssidHotListResultInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
    WDI_LowLevelIndType wdiInd;
    /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

    VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                "%s: ", __func__);

    /* sanity check */
    if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: Invalid parameters", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }

    /* Fill in the indication parameters */
    wdiInd.wdiIndicationType = WDI_EXTSCAN_BSSID_HOTLIST_RESULT_IND;

    /* extract response and send it to UMAC */
    wdiInd.wdiIndicationData.pEXTScanIndData = (void *)pEventData->pEventData;

    /* Notify UMAC */
    if (pWDICtx->wdiLowLevelIndCB)
    {
        pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
    }
    else
    {
        VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                 "%s: WDILowLevelIndCb is null", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }
    return WDI_STATUS_SUCCESS;
} /* End of WDI_ProcessEXTScanBssidHotListResultInd  */

/**
 @brief Process EXTScan SSID Hotlist Result Indication indication from FW

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessEXTScanSsidHotListResultInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
    WDI_LowLevelIndType wdiInd;
    /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

    VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                "%s: ", __func__);

    /* sanity check */
    if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: Invalid parameters", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }

    /* Fill in the indication parameters */
    wdiInd.wdiIndicationType = WDI_EXTSCAN_SSID_HOTLIST_RESULT_IND;

    /* extract response and send it to UMAC */
    wdiInd.wdiIndicationData.pEXTScanIndData = (void *)pEventData->pEventData;

    /* Notify UMAC */
    if (pWDICtx->wdiLowLevelIndCB)
    {
        pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
    }
    else
    {
        VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                 "%s: WDILowLevelIndCb is null", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }
    return WDI_STATUS_SUCCESS;
} /* End of WDI_ProcessEXTScanSsidHotListResultInd  */


/**
 @brief WDI_EXTScanGetCapabilitiesReq

 @param WDI_EXTScanGetCapabilitiesReqParams: Req parameter for the FW
        WDI_EXTScanGetCapabilitiesRspCb: callback for passing back the response
        of the Req operation received from the device
        pUserData: user data will be passed back with the callback

 @return SUCCESS or FAIL
*/
WDI_Status
WDI_EXTScanGetCapabilitiesReq(
     WDI_EXTScanGetCapabilitiesReqParams* pwdiEXTScanGetCapabilitiesReqParams,
     WDI_EXTScanGetCapabilitiesRspCb  wdiEXTScanGetCapabilitiesRspCb,
     void*   pUserData)
{
   WDI_EventInfoType      wdiEventData;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d ",__func__, __LINE__);
  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
     VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
  }

  wdiEventData.wdiRequest      = WDI_EXTSCAN_GET_CAPABILITIES_REQ;
  wdiEventData.pEventData      = pwdiEXTScanGetCapabilitiesReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiEXTScanGetCapabilitiesReqParams);
  wdiEventData.pCBfnc          = wdiEXTScanGetCapabilitiesRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief WDI_ProcessEXTScanGetCapabilitiesReq -
    Extended Scan Get Capability request to FW

 @param  pWDICtx : wdi context
         pEventData : indication data

 @see
 @return none
*/
WDI_Status
WDI_ProcessEXTScanGetCapabilitiesReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_EXTScanGetCapabilitiesReqParams* pwdiEXTScanGetCapabilitiesReqParams;
  WDI_EXTScanGetCapabilitiesRspCb wdiEXTScanGetCapabilitiesRspCb;
  wpt_uint8*               pSendBuffer         = NULL;
  wpt_uint16               usSendSize          = 0;
  wpt_uint16               usDataOffset        = 0;
  tHalExtScanGetCapReq     halEXTScanGetCapReqParams;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d Enter",__func__, __LINE__);

  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiEXTScanGetCapabilitiesReqParams =
      (WDI_EXTScanGetCapabilitiesReqParams* )pEventData->pEventData;
  wdiEXTScanGetCapabilitiesRspCb   =
      (WDI_EXTScanGetCapabilitiesRspCb)pEventData->pCBfnc;

  /*-----------------------------------------------------------------------
    Get message buffer
    ! TO DO : proper conversion into the HAL Message Request Format
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(
                                        pWDICtx,
                                        WDI_EXTSCAN_GET_CAPABILITIES_REQ,
                                        sizeof(halEXTScanGetCapReqParams),
                                        &pSendBuffer, &usDataOffset,
                                        &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halEXTScanGetCapReqParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in %s %p %p %p", __func__,
                pEventData, pwdiEXTScanGetCapabilitiesReqParams,
                wdiEXTScanGetCapabilitiesRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  halEXTScanGetCapReqParams.requestId =
                    pwdiEXTScanGetCapabilitiesReqParams->requestId;
  halEXTScanGetCapReqParams.sessionId =
                    pwdiEXTScanGetCapabilitiesReqParams->sessionId;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  " requestId %u "
                  " sessionId %u ",
                  halEXTScanGetCapReqParams.requestId,
                  halEXTScanGetCapReqParams.sessionId);

  wpalMemoryCopy(pSendBuffer+usDataOffset,
                  &halEXTScanGetCapReqParams,
                  sizeof(halEXTScanGetCapReqParams));

  pWDICtx->pReqStatusUserData = pEventData->pUserData;


  /*-------------------------------------------------------------------------
    Send EXTScan Stop Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiEXTScanGetCapabilitiesRspCb, pEventData->pUserData,
                       WDI_EXTSCAN_GET_CAPABILITIES_RSP);
}

/**
 @brief WDI_EXTScanGetCachedResultsReq

 @param WDI_EXTScanGetCachedResultsReqParams: Req parameter for the FW
        WDI_EXTScanGetCachedResultsRspCb: callback for passing back the response
        of the Req operation received from the device
        pUserData: user data will be passed back with the callback

 @return SUCCESS or FAIL
*/

WDI_Status
WDI_EXTScanGetCachedResultsReq(
     WDI_EXTScanGetCachedResultsReqParams* pwdiEXTScanGetCachedResultsReqParams,
     WDI_EXTScanGetCachedResultsRspCb  wdiEXTScanGetCachedResultsRspCb,
     void*                   pUserData)
{
   WDI_EventInfoType      wdiEventData;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d Enter",__func__, __LINE__);
  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
     VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
  }

  wdiEventData.wdiRequest      = WDI_EXTSCAN_GET_CACHED_RESULTS_REQ;
  wdiEventData.pEventData      = pwdiEXTScanGetCachedResultsReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiEXTScanGetCachedResultsReqParams);
  wdiEventData.pCBfnc          = wdiEXTScanGetCachedResultsRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief WDI_ProcessEXTScanGetCachedResultsReq -
    Extended Scan Get Cached Result request to FW

 @param  pWDICtx : wdi context
         pEventData : indication data

 @see
 @return none
*/
WDI_Status
WDI_ProcessEXTScanGetCachedResultsReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_EXTScanGetCachedResultsReqParams* pwdiEXTScanGetCachedResultsReqParams;
  WDI_EXTScanGetCachedResultsRspCb wdiEXTScanGetCachedResultsCb;
  wpt_uint8*               pSendBuffer         = NULL;
  wpt_uint16               usSendSize          = 0;
  wpt_uint16               usDataOffset        = 0;
  tHalExtScanGetScanReq      halEXTScanGetScanReqParams;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d Enter",__func__, __LINE__);

  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiEXTScanGetCachedResultsReqParams =
      (WDI_EXTScanGetCachedResultsReqParams*)pEventData->pEventData;
  wdiEXTScanGetCachedResultsCb   =
      (WDI_EXTScanGetCachedResultsRspCb)pEventData->pCBfnc;

  /*-----------------------------------------------------------------------
    Get message buffer
    ! TO DO : proper conversion into the HAL Message Request Format
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(
                                        pWDICtx,
                                        WDI_EXTSCAN_GET_CACHED_RESULTS_REQ,
                                        sizeof(tHalExtScanGetScanReq),
                                        &pSendBuffer, &usDataOffset,
                                        &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halEXTScanGetScanReqParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in %s %p %p %p", __func__,
                pEventData, pwdiEXTScanGetCachedResultsReqParams,
                wdiEXTScanGetCachedResultsCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  halEXTScanGetScanReqParams.requestId =
                    pwdiEXTScanGetCachedResultsReqParams->requestId;
  halEXTScanGetScanReqParams.sessionId =
                    pwdiEXTScanGetCachedResultsReqParams->sessionId;
  halEXTScanGetScanReqParams.flush =
                    pwdiEXTScanGetCachedResultsReqParams->flush;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  " requestId %u "
                  " sessionId %u "
                  " flush %u ",
                  halEXTScanGetScanReqParams.requestId,
                  halEXTScanGetScanReqParams.sessionId,
                  halEXTScanGetScanReqParams.flush);

  wpalMemoryCopy(pSendBuffer+usDataOffset,
                  &halEXTScanGetScanReqParams,
                  sizeof(halEXTScanGetScanReqParams));

  pWDICtx->pReqStatusUserData = pEventData->pUserData;


  /*-------------------------------------------------------------------------
    Send EXTScan Stop Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiEXTScanGetCachedResultsCb, pEventData->pUserData,
                       WDI_EXTSCAN_GET_CACHED_RESULTS_RSP);
}

/**
 @brief WDI_EXTScanStopReq

 @param WDI_EXTScanStopReqParams: Req parameter for the FW
        WDI_EXTScanStopRspCb: callback for passing back the response
        of the Req operation received from the device
        pUserData: user data will be passed back with the callback

 @return SUCCESS or FAIL
*/
WDI_Status
WDI_EXTScanStopReq(WDI_EXTScanStopReqParams* pwdiEXTScanStopReqParams,
                           WDI_EXTScanStopRspCb   wdiEXTScanStopRspCb,
                           void*                   pUserData)
{
   WDI_EventInfoType      wdiEventData;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d ",__func__, __LINE__);
  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
     VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
  }

  wdiEventData.wdiRequest      = WDI_EXTSCAN_STOP_REQ;
  wdiEventData.pEventData      = pwdiEXTScanStopReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiEXTScanStopReqParams);
  wdiEventData.pCBfnc          = wdiEXTScanStopRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief WDI_ProcessEXTScanStopReq -
    Extended Scan Stop request to FW

 @param  pWDICtx : wdi context
         pEventData : indication data

 @see
 @return none
*/
WDI_Status
WDI_ProcessEXTScanStopReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_EXTScanStopReqParams* pwdiEXTScanStopReqParams;
  WDI_EXTScanStopRspCb wdiEXTScanStopCb;
  wpt_uint8*               pSendBuffer         = NULL;
  wpt_uint16               usSendSize          = 0;
  wpt_uint16               usDataOffset        = 0;
  tHalExtScanStopReq halEXTScanStopReqParams;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d ",__func__, __LINE__);

  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiEXTScanStopReqParams = (WDI_EXTScanStopReqParams*)pEventData->pEventData;
  wdiEXTScanStopCb   = (WDI_EXTScanStopRspCb)pEventData->pCBfnc;

  /*-----------------------------------------------------------------------
    Get message buffer
    ! TO DO : proper conversion into the HAL Message Request Format
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(
                                        pWDICtx,
                                        WDI_EXTSCAN_STOP_REQ,
                                        sizeof(tHalExtScanStopReq),
                                        &pSendBuffer, &usDataOffset,
                                        &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(halEXTScanStopReqParams) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in %s %p %p %p", __func__,
                pEventData, pwdiEXTScanStopReqParams, wdiEXTScanStopCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  halEXTScanStopReqParams.requestId =
                    pwdiEXTScanStopReqParams->requestId;
  halEXTScanStopReqParams.sessionId =
                    pwdiEXTScanStopReqParams->sessionId;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  " halEXTScanStopReqParams.requestId %u "
                  " halEXTScanStopReqParams.sessionId %u ",
                  halEXTScanStopReqParams.requestId,
                  halEXTScanStopReqParams.sessionId);

  wpalMemoryCopy(pSendBuffer+usDataOffset,
                  &halEXTScanStopReqParams,
                  sizeof(halEXTScanStopReqParams));

  pWDICtx->pReqStatusUserData = pEventData->pUserData;


  /*-------------------------------------------------------------------------
    Send EXTScan Stop Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiEXTScanStopCb, pEventData->pUserData,
                       WDI_EXTSCAN_STOP_RSP);
}

/**
 @brief WDI_EXTScanStartReq

 @param WDI_EXTScanStartReqParams: Req parameter for the FW
        WDI_EXTScanStartRspCb: callback for passing back the response
        of the Req operation received from the device
        pUserData: user data will be passed back with the callback

 @return SUCCESS or FAIL
*/
WDI_Status
WDI_EXTScanStartReq(WDI_EXTScanStartReqParams* pwdiEXTScanStartReqParams,
                  WDI_EXTScanStartRspCb   wdiEXTScanStartRspCb,
                           void*                   pUserData)
{
   WDI_EventInfoType      wdiEventData;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d Enter",__func__, __LINE__);
  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
     VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
  }

  wdiEventData.wdiRequest      = WDI_EXTSCAN_START_REQ;
  wdiEventData.pEventData      = pwdiEXTScanStartReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiEXTScanStartReqParams);
  wdiEventData.pCBfnc          = wdiEXTScanStartRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief WDI_ProcessEXTScanStartReq -
    Extended Scan Start Request to FW

 @param  pWDICtx : wdi context
         pEventData : indication data

 @see
 @return none
*/
WDI_Status
WDI_ProcessEXTScanStartReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_EXTScanStartReqParams* pwdiEXTScanStartReqParams;
  WDI_EXTScanStartRspCb wdiEXTScanStartCb;
  wpt_uint8*               pSendBuffer         = NULL;
  wpt_uint16               usSendSize          = 0;
  wpt_uint16               usDataOffset        = 0;
  tpHalExtScanStartReq pHalExtScanStartReqParams;
  int i = 0;
  int j = 0;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d Enter",__func__, __LINE__);

  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiEXTScanStartReqParams =
                (WDI_EXTScanStartReqParams*)pEventData->pEventData;
  wdiEXTScanStartCb   = (WDI_EXTScanStartRspCb)pEventData->pCBfnc;

  /*-----------------------------------------------------------------------
    Get message buffer
    ! TO DO : proper conversion into the HAL Message Request Format
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(
                                        pWDICtx,
                                        WDI_EXTSCAN_START_REQ,
                                        sizeof(tHalExtScanStartReq),
                                        &pSendBuffer, &usDataOffset,
                                        &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(tHalExtScanStartReq) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in %s %p %p %p", __func__,
                pEventData, pwdiEXTScanStartReqParams, wdiEXTScanStartCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pHalExtScanStartReqParams =
      (tpHalExtScanStartReq ) (pSendBuffer + usDataOffset);

  pHalExtScanStartReqParams->basePeriod = pwdiEXTScanStartReqParams->basePeriod;
  pHalExtScanStartReqParams->maxApPerScan =
                                    pwdiEXTScanStartReqParams->maxAPperScan;
  pHalExtScanStartReqParams->reportThresholdPercent =
                                pwdiEXTScanStartReqParams->reportThresholdPercent;
  pHalExtScanStartReqParams->reportThresholdNumScans =
                                pwdiEXTScanStartReqParams->reportThresholdNumScans;
  pHalExtScanStartReqParams->requestId = pwdiEXTScanStartReqParams->requestId;
  pHalExtScanStartReqParams->sessionId = pwdiEXTScanStartReqParams->sessionId;
  pHalExtScanStartReqParams->numBuckets = pwdiEXTScanStartReqParams->numBuckets;
  pHalExtScanStartReqParams->homeAwayTime = pwdiEXTScanStartReqParams->homeAwayTime;

  for( i = 0; i < WDI_WLAN_EXTSCAN_MAX_BUCKETS ; i++ )
  {
      pHalExtScanStartReqParams->bucketData[i].bucketId =
                      pwdiEXTScanStartReqParams->buckets[i].bucket;
      pHalExtScanStartReqParams->bucketData[i].channelBand =
                      pwdiEXTScanStartReqParams->buckets[i].band;
      pHalExtScanStartReqParams->bucketData[i].period =
                      pwdiEXTScanStartReqParams->buckets[i].period;
      pHalExtScanStartReqParams->bucketData[i].reportEvents =
                      pwdiEXTScanStartReqParams->buckets[i].reportEvents;
      pHalExtScanStartReqParams->bucketData[i].max_period =
                      pwdiEXTScanStartReqParams->buckets[i].max_period;
      pHalExtScanStartReqParams->bucketData[i].exponent =
                      pwdiEXTScanStartReqParams->buckets[i].exponent;
      pHalExtScanStartReqParams->bucketData[i].step_count =
                      pwdiEXTScanStartReqParams->buckets[i].step_count;
      pHalExtScanStartReqParams->bucketData[i].numChannels =
                      pwdiEXTScanStartReqParams->buckets[i].numChannels;

      for( j = 0; j< WDI_WLAN_EXTSCAN_MAX_CHANNELS; j++)
      {
          pHalExtScanStartReqParams->bucketData[i].channelList[j].channel =
              pwdiEXTScanStartReqParams->buckets[i].channels[j].channel;
          pHalExtScanStartReqParams->bucketData[i].channelList[j].dwellTimeMs =
              pwdiEXTScanStartReqParams->buckets[i].channels[j].dwellTimeMs;
          pHalExtScanStartReqParams->bucketData[i].channelList[j].passive =
              pwdiEXTScanStartReqParams->buckets[i].channels[j].passive;
      }

  }


  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
          " basePeriod %u maxApPerScan %u reportThresholdPercent %u"
          "reportThresholdNumScans %u requestId %u"
          " sessionId %u numBuckets%u homeAwayTime %u",
          pHalExtScanStartReqParams->basePeriod,
          pHalExtScanStartReqParams->maxApPerScan,
          pHalExtScanStartReqParams->reportThresholdPercent,
          pHalExtScanStartReqParams->reportThresholdNumScans,
          pHalExtScanStartReqParams->requestId,
          pHalExtScanStartReqParams->sessionId,
          pHalExtScanStartReqParams->numBuckets,
          pHalExtScanStartReqParams->homeAwayTime);

  for( i = 0; i < pHalExtScanStartReqParams->numBuckets ; i++ )
  {
      VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO ,
              " %d) bucketId %u  channelBand %u period %u "
              " reportEvents %u numChannels %u "
              "max_period %u exponent %u step_count %u",i,
      pHalExtScanStartReqParams->bucketData[i].bucketId,
      pHalExtScanStartReqParams->bucketData[i].channelBand,
      pHalExtScanStartReqParams->bucketData[i].period,
      pHalExtScanStartReqParams->bucketData[i].reportEvents,
      pHalExtScanStartReqParams->bucketData[i].numChannels,
      pHalExtScanStartReqParams->bucketData[i].max_period,
      pHalExtScanStartReqParams->bucketData[i].exponent,
      pHalExtScanStartReqParams->bucketData[i].step_count);

      for( j = 0; j< pHalExtScanStartReqParams->bucketData[i].numChannels; j++)
      {
        VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                "%d) channel %u dwellTimeMs %u passive %u ",j,
          pHalExtScanStartReqParams->bucketData[i].channelList[j].channel,
          pHalExtScanStartReqParams->bucketData[i].channelList[j].dwellTimeMs,
          pHalExtScanStartReqParams->bucketData[i].channelList[j].passive);
      }

  }

  pWDICtx->pReqStatusUserData = pEventData->pUserData;

  /*-------------------------------------------------------------------------
    Send EXTSCAN Start Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiEXTScanStartCb, pEventData->pUserData,
                       WDI_EXTSCAN_START_RSP);
}

/**
 @brief WDI_EXTScanSetBSSIDHotlistReq

 @param WDI_EXTScanSetBSSIDHotlistReqParams: Req parameter for the FW
        WDI_EXTScanSetBSSIDHotlistRspCb: callback for passing back the response
        of the Req operation received from the device
        pUserData: user data will be passed back with the callback

 @return SUCCESS or FAIL
*/
WDI_Status
WDI_EXTScanSetBSSIDHotlistReq(
      WDI_EXTScanSetBSSIDHotlistReqParams* pwdiEXTScanSetBSSIDHotlistReqParams,
      WDI_EXTScanSetBSSIDHotlistRspCb  wdiEXTScanSetBSSIDHotlistRspCb,
      void*                   pUserData)
{
   WDI_EventInfoType      wdiEventData;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d Enter ",__func__, __LINE__);
  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
     VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
  }

  wdiEventData.wdiRequest      = WDI_EXTSCAN_SET_BSSID_HOTLIST_REQ;
  wdiEventData.pEventData      = pwdiEXTScanSetBSSIDHotlistReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiEXTScanSetBSSIDHotlistReqParams);
  wdiEventData.pCBfnc          = wdiEXTScanSetBSSIDHotlistRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief WDI_ProcessEXTScanSetBSSIDHotlistReq -
    Extended Scan Set BSSSID Hotlist Request to FW

 @param  pWDICtx : wdi context
         pEventData : indication data

 @see
 @return none
*/
WDI_Status
WDI_ProcessEXTScanSetBSSIDHotlistReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_EXTScanSetBSSIDHotlistReqParams* pwdiEXTScanSetBSSIDHotlistReqParams;
  WDI_EXTScanSetBSSIDHotlistRspCb  wdiEXTScanSetBSSIDHotlistRspCb;
  wpt_uint8*               pSendBuffer         = NULL;
  wpt_uint16               usSendSize          = 0;
  wpt_uint16               usDataOffset        = 0;
  tpHalBssidHotlistSetReq  pHalBssidHotlistSetReqParams;
  int i;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d Enter",__func__, __LINE__);

  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiEXTScanSetBSSIDHotlistReqParams =
      (WDI_EXTScanSetBSSIDHotlistReqParams *)pEventData->pEventData;
  wdiEXTScanSetBSSIDHotlistRspCb   =
      (WDI_EXTScanSetBSSIDHotlistRspCb)pEventData->pCBfnc;

  /*-----------------------------------------------------------------------
    Get message buffer
    ! TO DO : proper conversion into the HAL Message Request Format
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(
                                        pWDICtx,
                                        WDI_EXTSCAN_SET_BSSID_HOTLIST_REQ,
                                        sizeof(tHalBssidHotlistSetReq),
                                        &pSendBuffer, &usDataOffset,
                                        &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(tHalBssidHotlistSetReq) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in %s %p %p %p", __func__,
                pEventData, pwdiEXTScanSetBSSIDHotlistReqParams,
                wdiEXTScanSetBSSIDHotlistRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  pHalBssidHotlistSetReqParams =
      (tpHalBssidHotlistSetReq) (pSendBuffer + usDataOffset);

  pHalBssidHotlistSetReqParams->requestId =
                    pwdiEXTScanSetBSSIDHotlistReqParams->requestId;

  pHalBssidHotlistSetReqParams->sessionId =
                    pwdiEXTScanSetBSSIDHotlistReqParams->sessionId;

  pHalBssidHotlistSetReqParams->lostBssidSampleSize =
                    pwdiEXTScanSetBSSIDHotlistReqParams->lostBssidSampleSize;

  pHalBssidHotlistSetReqParams->numBssid =
                    pwdiEXTScanSetBSSIDHotlistReqParams->numBssid;

  for( i = 0; i < WLAN_HAL_EXT_SCAN_MAX_HOTLIST_APS; i++){

    wpalMemoryCopy(pHalBssidHotlistSetReqParams->ap[i].bssid,
              pwdiEXTScanSetBSSIDHotlistReqParams->ap[i].bssid,
                            WDI_MAC_ADDR_LEN);

    pHalBssidHotlistSetReqParams->ap[i].lowRssiThreshold =
       pwdiEXTScanSetBSSIDHotlistReqParams->ap[i].low;

    pHalBssidHotlistSetReqParams->ap[i].highRssiThreshold =
        pwdiEXTScanSetBSSIDHotlistReqParams->ap[i].high;

  }

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
          "ReqID %u sessionId %u numBssid %u lostBssidSampleSize: %u",
      pHalBssidHotlistSetReqParams->requestId,
      pHalBssidHotlistSetReqParams->sessionId,
      pHalBssidHotlistSetReqParams->numBssid,
      pHalBssidHotlistSetReqParams->lostBssidSampleSize);

  for( i = 0; i < pHalBssidHotlistSetReqParams->numBssid; i++){

    VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
         "%s %d %d) BSSID: %pM lowRssiThreshold %d highRssiThreshold %d",
            __func__, __LINE__, i,
            pHalBssidHotlistSetReqParams->ap[i].bssid,
            pHalBssidHotlistSetReqParams->ap[i].lowRssiThreshold,
            pHalBssidHotlistSetReqParams->ap[i].highRssiThreshold);

  }

  pWDICtx->pReqStatusUserData = pEventData->pUserData;


  /*-------------------------------------------------------------------------
    Send EXTScan Stop Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiEXTScanSetBSSIDHotlistRspCb, pEventData->pUserData,
                       WDI_EXTSCAN_SET_HOTLIST_BSSID_RSP);
}

/**
 @brief WDI_EXTScanResetBSSIDHotlistReq

 @param WDI_EXTScanResetBSSIDHotlistReqParams: Req parameter for the FW
        WDI_EXTScanResetBSSIDHotlistRspCb: callback for passing back the response
        of the Req operation received from the device
        pUserData: user data will be passed back with the callback

 @return SUCCESS or FAIL
*/
WDI_Status
WDI_EXTScanResetBSSIDHotlistReq(
   WDI_EXTScanResetBSSIDHotlistReqParams* pwdiEXTScanResetBSSIDHotlistReqParams,
   WDI_EXTScanResetBSSIDHotlistRspCb  wdiEXTScanResetBSSIDHotlistRspCb,
   void*                   pUserData)
{
   WDI_EventInfoType      wdiEventData;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d",__func__, __LINE__);
  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
     VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
  }

  wdiEventData.wdiRequest      = WDI_EXTSCAN_RESET_BSSID_HOTLIST_REQ;
  wdiEventData.pEventData      = pwdiEXTScanResetBSSIDHotlistReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiEXTScanResetBSSIDHotlistReqParams);
  wdiEventData.pCBfnc          = wdiEXTScanResetBSSIDHotlistRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief WDI_ProcessEXTScanResetBSSIDHotlistReq -
    Extended Scan reset BSSID hotlist Request to FW

 @param  pWDICtx : wdi context
         pEventData : indication data

 @see
 @return none
*/
WDI_Status
WDI_ProcessEXTScanResetBSSIDHotlistReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_EXTScanResetBSSIDHotlistReqParams* pwdiEXTScanResetBSSIDHotlistReqParams;
  WDI_EXTScanResetBSSIDHotlistRspCb  wdiEXTScanResetBSSIDHotlistRspCb;
  wpt_uint8*               pSendBuffer         = NULL;
  wpt_uint16               usSendSize          = 0;
  wpt_uint16               usDataOffset        = 0;
  tpHalHotlistResetReq     pHalHotlistResetReqParams;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d",__func__, __LINE__);

  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiEXTScanResetBSSIDHotlistReqParams =
      (WDI_EXTScanResetBSSIDHotlistReqParams *)pEventData->pEventData;
  wdiEXTScanResetBSSIDHotlistRspCb   =
      (WDI_EXTScanResetBSSIDHotlistRspCb)pEventData->pCBfnc;

  /*-----------------------------------------------------------------------
    Get message buffer
    ! TO DO : proper conversion into the HAL Message Request Format
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(
                                        pWDICtx,
                                        WDI_EXTSCAN_RESET_BSSID_HOTLIST_REQ,
                                        sizeof(tHalHotlistResetReq),
                                        &pSendBuffer, &usDataOffset,
                                        &usSendSize))||
     ( usSendSize < (usDataOffset + sizeof(tHalHotlistResetReq) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in %s %p %p %p", __func__,
                pEventData, pwdiEXTScanResetBSSIDHotlistReqParams,
                wdiEXTScanResetBSSIDHotlistRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  pHalHotlistResetReqParams =
      (tpHalHotlistResetReq) (pSendBuffer+usDataOffset);

  pHalHotlistResetReqParams->requestId =
                    pwdiEXTScanResetBSSIDHotlistReqParams->requestId;

  pWDICtx->pReqStatusUserData = pEventData->pUserData;

  /*-------------------------------------------------------------------------
    Send EXTScan Stop Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiEXTScanResetBSSIDHotlistRspCb, pEventData->pUserData,
                       WDI_EXTSCAN_RESET_HOTLIST_BSSID_RSP);
}


/**
 @brief WDI_EXTScanSetSSIDHotlistReq

 @param WDI_EXTScanSetSSIDHotlistReqParams: Req parameter for the FW
        WDI_EXTScanSetSSIDHotlistRspCb: callback for passing back the response
        of the Req operation received from the device
        pUserData: user data will be passed back with the callback

 @return SUCCESS or FAIL
*/
WDI_Status
WDI_EXTScanSetSSIDHotlistReq(
      WDI_EXTScanSetSSIDHotlistReqParams* pwdiEXTScanSetSSIDHotlistReqParams,
      WDI_EXTScanSetSSIDHotlistRspCb  wdiEXTScanSetSSIDHotlistRspCb,
      void*                   pUserData)
{
   WDI_EventInfoType      wdiEventData;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d Enter ",__func__, __LINE__);
  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
     VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
  }

  wdiEventData.wdiRequest      = WDI_EXTSCAN_SET_SSID_HOTLIST_REQ;
  wdiEventData.pEventData      = pwdiEXTScanSetSSIDHotlistReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiEXTScanSetSSIDHotlistReqParams);
  wdiEventData.pCBfnc          = wdiEXTScanSetSSIDHotlistRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief WDI_ProcessEXTScanSetSSIDHotlistReq -
    Extended Scan Set SSSID Hotlist Request to FW

 @param  pWDICtx : wdi context
         pEventData : indication data

 @see
 @return none
*/
WDI_Status
WDI_ProcessEXTScanSetSSIDHotlistReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_EXTScanSetSSIDHotlistReqParams* pwdiEXTScanSetSSIDHotlistReqParams;
  WDI_EXTScanSetSSIDHotlistRspCb  wdiEXTScanSetSSIDHotlistRspCb;
  wpt_uint8*               pSendBuffer         = NULL;
  wpt_uint16               usSendSize          = 0;
  wpt_uint16               usDataOffset        = 0;
  tpHalSsidHotlistSetReq   pHalSsidHotlistSetReqParams;
  int i;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d Enter",__func__, __LINE__);

  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiEXTScanSetSSIDHotlistReqParams =
      (WDI_EXTScanSetSSIDHotlistReqParams *)pEventData->pEventData;
  wdiEXTScanSetSSIDHotlistRspCb   =
      (WDI_EXTScanSetSSIDHotlistRspCb)pEventData->pCBfnc;

  /*-----------------------------------------------------------------------
    Get message buffer
    ! TO DO : proper conversion into the HAL Message Request Format
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(
                                        pWDICtx,
                                        WDI_EXTSCAN_SET_SSID_HOTLIST_REQ,
                                        sizeof(tHalSsidHotlistSetReq),
                                        &pSendBuffer, &usDataOffset,
                                        &usSendSize))||
      ( usSendSize < (usDataOffset + sizeof(tHalSsidHotlistSetReq) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in %s %p %p %p", __func__,
                pEventData, pwdiEXTScanSetSSIDHotlistReqParams,
                wdiEXTScanSetSSIDHotlistRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  pHalSsidHotlistSetReqParams =
      (tpHalSsidHotlistSetReq) (pSendBuffer + usDataOffset);

  pHalSsidHotlistSetReqParams->requestId =
                    pwdiEXTScanSetSSIDHotlistReqParams->requestId;

  pHalSsidHotlistSetReqParams->sessionId =
                    pwdiEXTScanSetSSIDHotlistReqParams->sessionId;

  pHalSsidHotlistSetReqParams->lostSsidSampleSize =
                    pwdiEXTScanSetSSIDHotlistReqParams->lostSsidSampleSize;;

  pHalSsidHotlistSetReqParams->numSsid =
                    pwdiEXTScanSetSSIDHotlistReqParams->numSsid;

  for( i = 0; i < pHalSsidHotlistSetReqParams->numSsid; i++){

    wpalMemoryZero(pHalSsidHotlistSetReqParams->ssid[i].ssid, 33);
    wpalMemoryCopy(pHalSsidHotlistSetReqParams->ssid[i].ssid,
              pwdiEXTScanSetSSIDHotlistReqParams->ssid[i].ssid.sSSID,
              pwdiEXTScanSetSSIDHotlistReqParams->ssid[i].ssid.ucLength);

    pHalSsidHotlistSetReqParams->ssid[i].lowRssiThreshold =
       pwdiEXTScanSetSSIDHotlistReqParams->ssid[i].lowRssiThreshold;

    pHalSsidHotlistSetReqParams->ssid[i].highRssiThreshold =
        pwdiEXTScanSetSSIDHotlistReqParams->ssid[i].highRssiThreshold;

    pHalSsidHotlistSetReqParams->ssid[i].band =
        pwdiEXTScanSetSSIDHotlistReqParams->ssid[i].band;
  }

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
          "ReqID %u sessionId %u numSsid %u lost_ssid_sample_size: %u",
      pHalSsidHotlistSetReqParams->requestId,
      pHalSsidHotlistSetReqParams->sessionId,
      pHalSsidHotlistSetReqParams->numSsid,
      pHalSsidHotlistSetReqParams->lostSsidSampleSize);

  for( i = 0; i < pHalSsidHotlistSetReqParams->numSsid; i++){

    VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
         "%s %d %d) SSID = %s lowRssiThreshold %d highRssiThreshold %d band: %d",
            __func__, __LINE__, i,
            pHalSsidHotlistSetReqParams->ssid[i].ssid,
            pHalSsidHotlistSetReqParams->ssid[i].lowRssiThreshold,
            pHalSsidHotlistSetReqParams->ssid[i].highRssiThreshold,
            pHalSsidHotlistSetReqParams->ssid[i].band);
  }

  pWDICtx->pReqStatusUserData = pEventData->pUserData;


  /*-------------------------------------------------------------------------
    Send EXTScan Stop Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiEXTScanSetSSIDHotlistRspCb, pEventData->pUserData,
                       WDI_EXTSCAN_SET_HOTLIST_SSID_RSP);
}

/**
 @brief WDI_EXTScanResetSSIDHotlistReq

 @param WDI_EXTScanResetSSIDHotlistReqParams: Req parameter for the FW
        WDI_EXTScanResetSSIDHotlistRspCb: callback for passing back the response
        of the Req operation received from the device
        pUserData: user data will be passed back with the callback

 @return SUCCESS or FAIL
*/
WDI_Status
WDI_EXTScanResetSSIDHotlistReq(
   WDI_EXTScanResetSSIDHotlistReqParams* pwdiEXTScanResetSSIDHotlistReqParams,
   WDI_EXTScanResetSSIDHotlistRspCb  wdiEXTScanResetSSIDHotlistRspCb,
   void*                   pUserData)
{
   WDI_EventInfoType      wdiEventData;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d",__func__, __LINE__);
  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
     VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
  }

  wdiEventData.wdiRequest      = WDI_EXTSCAN_RESET_SSID_HOTLIST_REQ;
  wdiEventData.pEventData      = pwdiEXTScanResetSSIDHotlistReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiEXTScanResetSSIDHotlistReqParams);
  wdiEventData.pCBfnc          = wdiEXTScanResetSSIDHotlistRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief WDI_ProcessEXTScanResetSSIDHotlistReq -
    Extended Scan reset SSID hotlist Request to FW

 @param  pWDICtx : wdi context
         pEventData : indication data

 @see
 @return none
*/
WDI_Status
WDI_ProcessEXTScanResetSSIDHotlistReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_EXTScanResetSSIDHotlistReqParams* pwdiEXTScanResetSSIDHotlistReqParams;
  WDI_EXTScanResetSSIDHotlistRspCb  wdiEXTScanResetSSIDHotlistRspCb;
  wpt_uint8*               pSendBuffer         = NULL;
  wpt_uint16               usSendSize          = 0;
  wpt_uint16               usDataOffset        = 0;
  tpHalSsidHotlistResetReq     pHalSsidHotlistResetReqParams;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d",__func__, __LINE__);

  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
      ( NULL == pEventData->pCBfnc ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pwdiEXTScanResetSSIDHotlistReqParams =
      (WDI_EXTScanResetSSIDHotlistReqParams *)pEventData->pEventData;
  wdiEXTScanResetSSIDHotlistRspCb   =
      (WDI_EXTScanResetSSIDHotlistRspCb)pEventData->pCBfnc;

  /*-----------------------------------------------------------------------
    Get message buffer
    ! TO DO : proper conversion into the HAL Message Request Format
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(
                                        pWDICtx,
                                        WDI_EXTSCAN_RESET_SSID_HOTLIST_REQ,
                                        sizeof(tHalSsidHotlistResetReq),
                                        &pSendBuffer, &usDataOffset,
                                        &usSendSize))||
     ( usSendSize < (usDataOffset + sizeof(tHalSsidHotlistResetReq) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in %s %p %p %p", __func__,
                pEventData, pwdiEXTScanResetSSIDHotlistReqParams,
                wdiEXTScanResetSSIDHotlistRspCb);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  pHalSsidHotlistResetReqParams =
      (tpHalSsidHotlistResetReq) (pSendBuffer+usDataOffset);

  pHalSsidHotlistResetReqParams->requestId =
                    pwdiEXTScanResetSSIDHotlistReqParams->requestId;

  pWDICtx->pReqStatusUserData = pEventData->pUserData;

  /*-------------------------------------------------------------------------
    Send RESET_HOTLIST_SSID Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                       wdiEXTScanResetSSIDHotlistRspCb, pEventData->pUserData,
                       WDI_EXTSCAN_RESET_HOTLIST_SSID_RSP);
}


/**
 @brief WDI_HighPriorityDataInfoInd

 @param pHighPriorityDataInfoIndParams: Req parameter for the FW

 @return SUCCESS or FAIL
*/
WDI_Status
WDI_HighPriorityDataInfoInd
(
   WDI_HighPriorityDataInfoIndParams* pHighPriorityDataInfoIndParams
)
{
   WDI_EventInfoType      wdiEventData;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d",__func__, __LINE__);
  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
     VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
  }

  wdiEventData.wdiRequest      = WDI_HIGH_PRIORITY_DATA_INFO_IND;
  wdiEventData.pEventData      = pHighPriorityDataInfoIndParams;
  wdiEventData.uEventDataSize  = sizeof(*pHighPriorityDataInfoIndParams);
  wdiEventData.pCBfnc          = NULL;
  wdiEventData.pUserData       = NULL;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief WDI_ProcessHighPriorityDataInfoInd -
    Send WFD indication to FW

 @param  pWDICtx : wdi context
         pEventData : indication data

 @see
 @return none
*/
WDI_Status
WDI_ProcessHighPriorityDataInfoInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_HighPriorityDataInfoIndParams* pHighPriorityDataInfoIndParams;
  wpt_uint8*               pSendBuffer         = NULL;
  wpt_uint16               usSendSize          = 0;
  wpt_uint16               usDataOffset        = 0;
  tpHalHighPriorityDataInfoInd     pHalHighPriorityDataInfoIndParams;
  WDI_Status wdiStatus = WDI_STATUS_SUCCESS;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d",__func__, __LINE__);

  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
           ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pHighPriorityDataInfoIndParams =
      (WDI_HighPriorityDataInfoIndParams *)pEventData->pEventData;

  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(
                                        pWDICtx,
                                        WDI_HIGH_PRIORITY_DATA_INFO_IND,
                                        sizeof(tHalHighPriorityDataInfoInd),
                                        &pSendBuffer, &usDataOffset,
                                        &usSendSize))||
     ( usSendSize < (usDataOffset + sizeof(tHalHighPriorityDataInfoInd) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in %s %p %p", __func__,
                pEventData, pHighPriorityDataInfoIndParams);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  pHalHighPriorityDataInfoIndParams =
      (tpHalHighPriorityDataInfoInd) (pSendBuffer+usDataOffset);

  pHalHighPriorityDataInfoIndParams->pause =
                    pHighPriorityDataInfoIndParams->pause;

  pWDICtx->pReqStatusUserData = NULL;
  pWDICtx->pfncRspCB = NULL;

  /*-------------------------------------------------------------------------
    Send HIGH_PRIORITY_DATA_INFO Request to HAL
  -------------------------------------------------------------------------*/
  wdiStatus =  WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize);
  return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC;
}

/**
 @brief Process Extended Scan Start Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessEXTScanStartRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_EXTScanStartRspCb   wdiEXTScanStartRspCb;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d",__func__, __LINE__);
  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiEXTScanStartRspCb = (WDI_EXTScanStartRspCb)pWDICtx->pfncRspCB;
  if ( NULL == wdiEXTScanStartRspCb)
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Callback function Invalid", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiEXTScanStartRspCb((void *)pEventData->pEventData, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}


/**
 @brief Process Extended Scan Stop Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessEXTScanStopRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_EXTScanStopRspCb   wdiEXTScanStopRspCb;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d",__func__, __LINE__);


  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiEXTScanStopRspCb = (WDI_EXTScanStartRspCb)pWDICtx->pfncRspCB;
  if ( NULL == wdiEXTScanStopRspCb)
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Callback function Invalid", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiEXTScanStopRspCb((void *) pEventData->pEventData, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}

/**
 @brief Process Extended Scan Get Cached Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessEXTScanGetCachedResultsRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_EXTScanGetCachedResultsRspCb   wdiEXTScanGetCachedResultsRspCb;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d Enter",__func__, __LINE__);


  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiEXTScanGetCachedResultsRspCb = (WDI_EXTScanStartRspCb)pWDICtx->pfncRspCB;
  if ( NULL == wdiEXTScanGetCachedResultsRspCb)
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Callback function Invalid", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiEXTScanGetCachedResultsRspCb(
          (void *) pEventData->pEventData, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}

/**
 @brief Process Extended Scan Get Capabilityu Rsp function (called when a response
        is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessEXTScanGetCapabilitiesRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_EXTScanGetCapabilitiesRspCb   wdiEXTScanGetCapabilitiesRspCb;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d ",__func__, __LINE__);


  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiEXTScanGetCapabilitiesRspCb =
                (WDI_EXTScanGetCapabilitiesRspCb)pWDICtx->pfncRspCB;
  if ( NULL == wdiEXTScanGetCapabilitiesRspCb)
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Callback function Invalid", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiEXTScanGetCapabilitiesRspCb(
          (void *) pEventData->pEventData, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}

/**
 @brief Process Extended Scan Set hotlist BSSID Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessEXTScanSetHotlistBSSIDRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_EXTScanSetBSSIDHotlistRspCb   wdiEXTScanSetBSSIDHotlistRspCb;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d ",__func__, __LINE__);


  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiEXTScanSetBSSIDHotlistRspCb =
                (WDI_EXTScanSetBSSIDHotlistRspCb)pWDICtx->pfncRspCB;
  if ( NULL == wdiEXTScanSetBSSIDHotlistRspCb)
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Callback function Invalid", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiEXTScanSetBSSIDHotlistRspCb(
          (void *) pEventData->pEventData, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}

/**
 @brief Process Extended Scan Reset Hotlist BSSID Rsp function (called
        when a response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessEXTScanResetHotlistBSSIDRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_EXTScanResetBSSIDHotlistRspCb   wdiEXTScanResetBSSIDHotlistRspCb;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d ",__func__, __LINE__);


  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiEXTScanResetBSSIDHotlistRspCb =
                (WDI_EXTScanResetBSSIDHotlistRspCb)pWDICtx->pfncRspCB;
  if ( NULL == wdiEXTScanResetBSSIDHotlistRspCb)
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Callback function Invalid", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiEXTScanResetBSSIDHotlistRspCb(
          (void *) pEventData->pEventData, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}

/**
 @brief Process Extended Scan Set hotlist SSID Rsp function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessEXTScanSetHotlistSSIDRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_EXTScanSetSSIDHotlistRspCb   wdiEXTScanSetSSIDHotlistRspCb;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d ",__func__, __LINE__);


  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiEXTScanSetSSIDHotlistRspCb =
                (WDI_EXTScanSetSSIDHotlistRspCb)pWDICtx->pfncRspCB;
  if ( NULL == wdiEXTScanSetSSIDHotlistRspCb)
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Callback function Invalid", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiEXTScanSetSSIDHotlistRspCb(
          (void *) pEventData->pEventData, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}


/**
 @brief Process Extended Scan Reset Hotlist BSSID Rsp function (called
        when a response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessEXTScanResetHotlistSSIDRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_EXTScanResetSSIDHotlistRspCb   wdiEXTScanResetSSIDHotlistRspCb;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d ",__func__, __LINE__);


  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiEXTScanResetSSIDHotlistRspCb =
                (WDI_EXTScanResetSSIDHotlistRspCb)pWDICtx->pfncRspCB;
  if ( NULL == wdiEXTScanResetSSIDHotlistRspCb)
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Callback function Invalid", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiEXTScanResetSSIDHotlistRspCb(
          (void *) pEventData->pEventData, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}
#endif /* WLAN_FEATURE_EXTSCAN */

/**
 @brief WDI_SetSpoofMacAddrReq: Send Spoof Mac Addr request to FW

 @param None

 @see

 @return Status of the request
*/
WDI_Status
WDI_SetSpoofMacAddrReq
(
  WDI_SpoofMacAddrInfoType*      pWdiReq,
  WDI_SetSpoofMacAddrRspCb       spoofMacAddrRspCb,
  void*                          pUserData)
{
    WDI_EventInfoType      wdiEventData;

    /*-------------------------------------------------------------------------
      Sanity Check
      ------------------------------------------------------------------------*/
    if (eWLAN_PAL_FALSE == gWDIInitialized)
    {
        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                "WDI API call before module is initialized - Fail request!");

        return WDI_STATUS_E_NOT_ALLOWED;
    }

    /*-------------------------------------------------------------------------
      Fill in Event data and post to the Main FSM
      ------------------------------------------------------------------------*/
    wdiEventData.wdiRequest      = WDI_SPOOF_MAC_ADDR_REQ;
    wdiEventData.pEventData      = pWdiReq;
    wdiEventData.uEventDataSize  = sizeof(WDI_SpoofMacAddrInfoType);
    wdiEventData.pCBfnc          = spoofMacAddrRspCb;
    wdiEventData.pUserData       = pUserData;

    return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief Process SpoofMacAddr Request

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSpoofMacAddrReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
    WDI_SpoofMacAddrInfoType*      wdiSpoofMacAddr;
    wpt_uint8*                     pSendBuffer  = NULL;
    wpt_uint16                     usDataOffset = 0;
    wpt_uint16                     usSendSize   = 0;
    WDI_Status                     wdiStatus;
    tMacSpoofedScanReqMsg          halWlanSpoofMacAddr;
    WDI_SetSpoofMacAddrRspCb       wdiMacAddrSpoofCb;


    VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
            "%s: %d Enter",__func__, __LINE__);

    /*-------------------------------------------------------------------------
      Sanity check
      -------------------------------------------------------------------------*/
    if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
            ( NULL == pEventData->pEventData))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }
    wdiSpoofMacAddr = (WDI_SpoofMacAddrInfoType *)pEventData->pEventData;

    /*-----------------------------------------------------------------------
      Get message buffer
      -----------------------------------------------------------------------*/
    if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                    WDI_SPOOF_MAC_ADDR_REQ,
                    sizeof(halWlanSpoofMacAddr.tMacSpoofedScanReqParams),
                    &pSendBuffer, &usDataOffset, &usSendSize))||
            (usSendSize < (usDataOffset +
            sizeof(halWlanSpoofMacAddr.tMacSpoofedScanReqParams))))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
                "Unable to get send buffer in Process Spoof Mac Addr Req");
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }

    wpalMemoryCopy(halWlanSpoofMacAddr.tMacSpoofedScanReqParams.macAddr,
            wdiSpoofMacAddr->macAddr,
            sizeof(halWlanSpoofMacAddr.tMacSpoofedScanReqParams.macAddr));

    wdiMacAddrSpoofCb   = (WDI_SetSpoofMacAddrRspCb)pEventData->pCBfnc;

    wpalMemoryCopy( pSendBuffer+usDataOffset,
        &halWlanSpoofMacAddr.tMacSpoofedScanReqParams,
        sizeof(halWlanSpoofMacAddr.tMacSpoofedScanReqParams));

    /*-------------------------------------------------------------------------
      Send Suspend Request to HAL
      -------------------------------------------------------------------------*/
    wdiStatus = WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
    wdiMacAddrSpoofCb, pEventData->pUserData, WDI_SPOOF_MAC_ADDR_RSP);

    return  wdiStatus;
}

/**
 @brief Process Spoof Mac Address Rsp function
        (called when a response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessSpoofMacAddrRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  tMacSpoofedScanResp          halRsp;
  WDI_SetSpoofMacAddrRspCb     wdiSpoofMacAddrRspCb;
  WDI_SpoofMacAddrRspParamType wdiSpoofMacAddrRsp;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d Enter",__func__, __LINE__);

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  wdiSpoofMacAddrRspCb = (WDI_SetSpoofMacAddrRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halRsp,
                  pEventData->pEventData, sizeof(halRsp));

  wdiSpoofMacAddrRsp.wdiStatus = WDI_HAL_2_WDI_STATUS(halRsp.status);

  /*Notify UMAC*/
  wdiSpoofMacAddrRspCb(
          &wdiSpoofMacAddrRsp, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}

/**
 @brief Process Get Frame Log Rsp function
        (called when a response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessGetFrameLogRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  tGetFrameLogResp            halRsp;
  WDI_GetFrameLogRspCb        wdiGetFrameLogRspCb;
  WDI_GetFrameLogRspParamType wdiGetFrameLogRsp;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d Enter",__func__, __LINE__);

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiGetFrameLogRspCb = (WDI_GetFrameLogRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halRsp,
                  pEventData->pEventData, sizeof(halRsp));

  wdiGetFrameLogRsp.wdiStatus = WDI_HAL_2_WDI_STATUS(halRsp.status);

  /*Notify UMAC*/
  wdiGetFrameLogRspCb( &wdiGetFrameLogRsp, pWDICtx->pRspCBUserData );

  return WDI_STATUS_SUCCESS;
}

/**
 @brief Process RssiMonitorStartReq Request

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessRssiMonitorStartReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
    WDI_RssiMonitorReqInfoType*    wdiRssiMonitorStartReq;
    wpt_uint8*                     pSendBuffer  = NULL;
    wpt_uint16                     usDataOffset = 0;
    wpt_uint16                     usSendSize   = 0;
    WDI_Status                     wdiStatus;
    tHalStartRssimonitoringReq     halStartRssiMonitorReq;
    WDI_RssiMonitorStartRspCb      wdiRssiMonitorStartReqCb;


    VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                                          "%s: %d Enter",__func__, __LINE__);

    /*-------------------------------------------------------------------------
      Sanity check
      ------------------------------------------------------------------------*/
    if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
            ( NULL == pEventData->pEventData))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }

    wdiRssiMonitorStartReq = (WDI_RssiMonitorReqInfoType *)pEventData->pEventData;

    /*-----------------------------------------------------------------------
      Get message buffer
      -----------------------------------------------------------------------*/
    if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                    WDI_START_RSSI_MONITOR_REQ,
                    sizeof(halStartRssiMonitorReq.startRssiMonitoringReqParams),
                    &pSendBuffer, &usDataOffset, &usSendSize))||
                    (usSendSize < (usDataOffset +
                    sizeof(halStartRssiMonitorReq.startRssiMonitoringReqParams))))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
                "Unable to get send buffer in GetFrameLog Req");
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }

    halStartRssiMonitorReq.startRssiMonitoringReqParams.request_id =
            wdiRssiMonitorStartReq->requestId;

    halStartRssiMonitorReq.startRssiMonitoringReqParams.min_rssi =
            wdiRssiMonitorStartReq->minRssi;

    halStartRssiMonitorReq.startRssiMonitoringReqParams.max_rssi =
            wdiRssiMonitorStartReq->maxRssi;
    wpalMemoryCopy(halStartRssiMonitorReq.startRssiMonitoringReqParams.bssId,
            &(wdiRssiMonitorStartReq->currentBssId),
            sizeof(halStartRssiMonitorReq.startRssiMonitoringReqParams.bssId));

    wdiRssiMonitorStartReqCb = (WDI_RssiMonitorStartRspCb)pEventData->pCBfnc;

    wpalMemoryCopy(pSendBuffer+usDataOffset,
                   &halStartRssiMonitorReq.startRssiMonitoringReqParams,
                   sizeof(halStartRssiMonitorReq.startRssiMonitoringReqParams));

    /*-------------------------------------------------------------------------
      Send Suspend Request to HAL
      ------------------------------------------------------------------------*/
    wdiStatus = WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
        wdiRssiMonitorStartReqCb, pEventData->pUserData, WDI_START_RSSI_MONITOR_RSP);

    return  wdiStatus;
}


/**
 @brief Process FWLoggingInit Request

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessRssiMonitorStopReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
    WDI_RssiMonitorReqInfoType*    wdiRssiMonitorStopReq;
    wpt_uint8*                     pSendBuffer  = NULL;
    wpt_uint16                     usDataOffset = 0;
    wpt_uint16                     usSendSize   = 0;
    WDI_Status                     wdiStatus;
    tHalStopRssimonitoringReq      halStopRssiMonitorReq;
    WDI_RssiMonitorStopRspCb       wdiRssiMonitorStopReqCb;


    VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                                          "%s: %d Enter",__func__, __LINE__);

    /*-------------------------------------------------------------------------
      Sanity check
      ------------------------------------------------------------------------*/
    if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
            ( NULL == pEventData->pEventData))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }
    wdiRssiMonitorStopReq = (WDI_RssiMonitorReqInfoType *)pEventData->pEventData;

    /*-----------------------------------------------------------------------
      Get message buffer
      -----------------------------------------------------------------------*/
    if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                    WDI_STOP_RSSI_MONITOR_REQ,
                    sizeof(halStopRssiMonitorReq.stopRssiMonitoringParams),
                    &pSendBuffer, &usDataOffset, &usSendSize))||
            (usSendSize < (usDataOffset +
            sizeof(halStopRssiMonitorReq.stopRssiMonitoringParams))))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
                "Unable to get send buffer in GetFrameLog Req");
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }

    halStopRssiMonitorReq.stopRssiMonitoringParams.request_id =
            wdiRssiMonitorStopReq->requestId;

    wpalMemoryCopy(halStopRssiMonitorReq.stopRssiMonitoringParams.bssId,
            &(wdiRssiMonitorStopReq->currentBssId),
            sizeof(halStopRssiMonitorReq.stopRssiMonitoringParams.bssId));

    wdiRssiMonitorStopReqCb = (WDI_RssiMonitorStopRspCb)pEventData->pCBfnc;

    wpalMemoryCopy(pSendBuffer+usDataOffset,
                   &halStopRssiMonitorReq.stopRssiMonitoringParams,
                   sizeof(halStopRssiMonitorReq.stopRssiMonitoringParams));

    /*-------------------------------------------------------------------------
      Send Suspend Request to HAL
      ------------------------------------------------------------------------*/
    wdiStatus = WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
    wdiRssiMonitorStopReqCb, pEventData->pUserData, WDI_STOP_RSSI_MONITOR_RSP);

    return  wdiStatus;
}

/**
 @brief Process MgmtFrame Logging Init Rsp function
        (called when a response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessRssiMonitorStopRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  tHalStopRssimonitoringRspParams    halRsp;
  WDI_RssiMonitorStopRspCb          wdiRssiMonitorStopRspCb;
  WDI_RssiMonitorStopRspParamType   wdiRssiMonitorStopRsp;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d Enter",__func__, __LINE__);

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  wdiRssiMonitorStopRspCb = (WDI_RssiMonitorStopRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halRsp, pEventData->pEventData, sizeof(halRsp));

  wdiRssiMonitorStopRsp.status = WDI_HAL_2_WDI_STATUS(halRsp.status);

  /*Notify UMAC*/
  wdiRssiMonitorStopRspCb( &wdiRssiMonitorStopRsp, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}


/**
 @brief Process MgmtFrame Logging Init Rsp function
        (called when a response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessRssiMonitorStartRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  tHalStartRssimonitoringRspParams              halRsp;
  WDI_RssiMonitorStartRspCb          wdiRssiMonitorStartRspCb;
  WDI_RssiMonitorStartRspParamType   wdiRssiMonitorStartRsp;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d Enter",__func__, __LINE__);

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  wdiRssiMonitorStartRspCb = (WDI_RssiMonitorStopRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halRsp, pEventData->pEventData, sizeof(halRsp));

  wdiRssiMonitorStartRsp.status = WDI_HAL_2_WDI_STATUS(halRsp.status);

  /*Notify UMAC*/
  wdiRssiMonitorStartRspCb( &wdiRssiMonitorStartRsp, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}

/**
 @brief Process FWLoggingInit Request

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessGetFrameLogReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
    WDI_GetFrameLogReqInfoType*    wdiGetFrameLogReq;
    wpt_uint8*                     pSendBuffer  = NULL;
    wpt_uint16                     usDataOffset = 0;
    wpt_uint16                     usSendSize   = 0;
    WDI_Status                     wdiStatus;
    tGetFrameLogReqMsg             halGetFrameLogReq;
    WDI_FWLoggingInitRspCb         wdiGetFrameLogRspCb;


    VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                                          "%s: %d Enter",__func__, __LINE__);

    /*-------------------------------------------------------------------------
      Sanity check
      ------------------------------------------------------------------------*/
    if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
            ( NULL == pEventData->pEventData))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }

    wdiGetFrameLogReq = (WDI_GetFrameLogReqInfoType *)pEventData->pEventData;

    /*-----------------------------------------------------------------------
      Get message buffer
      -----------------------------------------------------------------------*/
    if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                    WDI_GET_FRAME_LOG_REQ,
                    sizeof(halGetFrameLogReq.tGetFrameLogReqParams),
                    &pSendBuffer, &usDataOffset, &usSendSize))||
            (usSendSize < (usDataOffset +
            sizeof(halGetFrameLogReq.tGetFrameLogReqParams))))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
                "Unable to get send buffer in GetFrameLog Req");
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }

    halGetFrameLogReq.tGetFrameLogReqParams.flags =
                       wdiGetFrameLogReq->flags;

    wdiGetFrameLogRspCb = (WDI_FWLoggingInitRspCb)pEventData->pCBfnc;

    wpalMemoryCopy( pSendBuffer+usDataOffset,
                                    &halGetFrameLogReq.tGetFrameLogReqParams,
                              sizeof(halGetFrameLogReq.tGetFrameLogReqParams));

    /*-------------------------------------------------------------------------
      Send Suspend Request to HAL
      ------------------------------------------------------------------------*/
    wdiStatus = WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
    wdiGetFrameLogRspCb, pEventData->pUserData, WDI_GET_FRAME_LOG_RSP);

    return  wdiStatus;
}
/**
 @brief Process MgmtFrame Logging Init Rsp function
        (called when a response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessFWFrameLoggingInitRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  tFWLoggingInitResp              halRsp;
  WDI_FWLoggingInitRspCb          wdiFWFrameLoggingInitRspCb;
  WDI_FWLoggingInitRspParamType   wdiFWLogginginitRsp;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d Enter",__func__, __LINE__);

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  wdiFWFrameLoggingInitRspCb = (WDI_FWLoggingInitRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halRsp, pEventData->pEventData, sizeof(halRsp));

  wdiFWLogginginitRsp.status = WDI_HAL_2_WDI_STATUS(halRsp.status);
  wdiFWLogginginitRsp.fw_mem_dump_max_size = halRsp.fw_dump_max_size;

  /*Notify UMAC*/
  wdiFWFrameLoggingInitRspCb( &wdiFWLogginginitRsp, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}

/**
 @brief Process Fwr Mem Dump Rsp function
        (called when a response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
    WDI_ProcessFwrMemDumpRsp

(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  tHalFwMemoryDumpRespMsg      halRsp;
  WDI_FwrMemDumpRspCb          wdiFwrMemDumpRspCb;
  WDI_FwrMemDumpRsp            wdiFwrMemDumpRsp;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d Enter",__func__, __LINE__);

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  wdiFwrMemDumpRspCb = (WDI_FwrMemDumpRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy( &halRsp.tFwMemoryDumpResp, pEventData->pEventData, sizeof(halRsp.tFwMemoryDumpResp));

  wdiFwrMemDumpRsp.dump_status = WDI_HAL_2_WDI_STATUS(halRsp.tFwMemoryDumpResp.status);

  /*Notify UMAC*/
  wdiFwrMemDumpRspCb( &wdiFwrMemDumpRsp, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}

WDI_Status
WDI_ProcessFWLoggingDXEdoneInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  wpt_uint8*  pSendBuffer = NULL;
  wpt_uint16  usDataOffset = 0;
  wpt_uint16  usSendSize = 0;
  tFWLoggingDxeDoneInd  *FWLoggingDxeDoneIndParams;
  WDI_DS_LoggingSessionType *pLoggingSession;
  WDI_Status wdiStatus = WDI_STATUS_SUCCESS;
  wpt_uint32 *pLogType;


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

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
               "%s", __func__);

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (NULL == pEventData ||
      NULL == pEventData->pEventData)
  {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
             "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
  }
  pLogType = (wpt_uint32 *)pEventData->pEventData;

  pLoggingSession = (WDI_DS_LoggingSessionType *)
                       WDI_DS_GetLoggingSession(WDI_DS_GetDatapathContext(
                                                  (void *)pWDICtx));
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/

  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                                     WDI_FW_LOGGING_DXE_DONE_IND,
                                      sizeof(tFWLoggingDxeDoneInd),
                          &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(tFWLoggingDxeDoneInd) )))
  {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
              "Unable to get send buffer in RTS CTS ind %p ",
               pEventData);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
  }
  FWLoggingDxeDoneIndParams =
           (tFWLoggingDxeDoneInd*)(pSendBuffer + usDataOffset);

  wpalMemoryCopy(&FWLoggingDxeDoneIndParams->logBuffAddress,
                 &pLoggingSession->logBuffAddress, MAX_NUM_OF_BUFFER *
                 sizeof(FWLoggingDxeDoneIndParams->logBuffAddress[0]));

  FWLoggingDxeDoneIndParams->status = pLoggingSession->status;
  FWLoggingDxeDoneIndParams->doneIndicationForSource = (wpt_uint16)*pLogType;

  wpalMemoryCopy(&FWLoggingDxeDoneIndParams->logBuffLength,
                 &pLoggingSession->logBuffLength, MAX_NUM_OF_BUFFER *
                 sizeof(FWLoggingDxeDoneIndParams->logBuffLength[0]));

  pWDICtx->pReqStatusUserData = NULL;
  pWDICtx->pfncRspCB = NULL;
  /*-------------------------------------------------------------------------
    Send FW_LOGGING_DXE_DONE_IND Indication to HAL
  -------------------------------------------------------------------------*/
  wdiStatus =  WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize);
  return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC;
}


/**
 @brief Process Fatal Event Logs Rsp function
        (called when a response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessFatalEventLogsRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
    tHalFatalEventLoggingRspParams           halRsp;
    WDI_FatalEventLogsRspCb                 wdiFatalEventLogsRspCb;
    WDI_FatalEventLogsRspParamType          wdiFatalEventLogsRsp;

    VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                    "%s: %d Enter",__func__, __LINE__);

    /*-------------------------------------------------------------------------
      Sanity check
    -------------------------------------------------------------------------*/
    if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
        ( NULL == pEventData->pEventData))
    {
       WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                   "%s: Invalid parameters", __func__);
       WDI_ASSERT(0);
       return WDI_STATUS_E_FAILURE;
    }
    wdiFatalEventLogsRspCb = (WDI_FatalEventLogsRspCb)pWDICtx->pfncRspCB;

    /*-------------------------------------------------------------------------
      Extract response and send it to UMAC
    -------------------------------------------------------------------------*/
    wpalMemoryCopy( &halRsp, pEventData->pEventData, sizeof(halRsp));

    wdiFatalEventLogsRsp.wdiStatus = WDI_HAL_2_WDI_STATUS(halRsp.status);

    /*Notify UMAC*/
    wdiFatalEventLogsRspCb( &wdiFatalEventLogsRsp,
                                  pWDICtx->pRspCBUserData);

    return WDI_STATUS_SUCCESS;
}

/**
 @brief Process FatalEventLogs Request

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/

WDI_Status
WDI_ProcessFatalEventLogsReq

(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
    WDI_FatalEventLogsReqInfoType*     wdiFatalEventLogsReq;
    wpt_uint8*                         pSendBuffer  = NULL;
    wpt_uint16                         usDataOffset = 0;
    wpt_uint16                         usSendSize   = 0;
    WDI_Status                         wdiStatus;
    tHalFatalEventLoggingReqMsg        halFatalEventLoggingReq;
    WDI_FatalEventLogsRspCb            wdiFatalEventLogsRspCb;


    VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
            "%s: %d Enter",__func__, __LINE__);

    /*-------------------------------------------------------------------------
      Sanity check
      ------------------------------------------------------------------------*/
    if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
            ( NULL == pEventData->pEventData))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }
    wdiFatalEventLogsReq =
                     (WDI_FatalEventLogsReqInfoType *)pEventData->pEventData;

    /*-----------------------------------------------------------------------
      Get message buffer
      -----------------------------------------------------------------------*/
    if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                    WDI_FATAL_EVENT_LOGGING_REQ,
                    sizeof(halFatalEventLoggingReq.tFatalEventLoggingReqParams),
                    &pSendBuffer, &usDataOffset, &usSendSize))||
            (usSendSize < (usDataOffset +
            sizeof(halFatalEventLoggingReq.tFatalEventLoggingReqParams))))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
                "Unable to get send buffer in Fatal Event Req");
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }
    halFatalEventLoggingReq.tFatalEventLoggingReqParams.reasonCode =
                                    wdiFatalEventLogsReq->reason_code;

    wdiFatalEventLogsRspCb   = (WDI_FatalEventLogsRspCb)pEventData->pCBfnc;

    wpalMemoryCopy( pSendBuffer+usDataOffset,
                    &halFatalEventLoggingReq.tFatalEventLoggingReqParams,
                    sizeof(halFatalEventLoggingReq.tFatalEventLoggingReqParams));

    /*-------------------------------------------------------------------------
      Send Mgmt Logging Init Request to HAL
      ------------------------------------------------------------------------*/
    wdiStatus = WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                             wdiFatalEventLogsRspCb, pEventData->pUserData,
                             WDI_FATAL_EVENT_LOGGING_RSP);

    return  wdiStatus;


}


/**
 @brief Process FWLoggingInit Request

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessFWLoggingInitReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
    WDI_FWLoggingInitReqInfoType*      wdiFWLoggingInitReq;
    wpt_uint8*                         pSendBuffer  = NULL;
    wpt_uint16                         usDataOffset = 0;
    wpt_uint16                         usSendSize   = 0;
    WDI_Status                         wdiStatus;
    tHalFWLoggingInitReqMsg            halFWLoggingInitReq;
    WDI_FWLoggingInitRspCb             wdiFWLoggingInitRspCb;


    VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
            "%s: %d Enter",__func__, __LINE__);

    /*-------------------------------------------------------------------------
      Sanity check
      ------------------------------------------------------------------------*/
    if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
            ( NULL == pEventData->pEventData))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }
    wdiFWLoggingInitReq =
                     (WDI_FWLoggingInitReqInfoType *)pEventData->pEventData;

    /*-----------------------------------------------------------------------
      Get message buffer
      -----------------------------------------------------------------------*/
    if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                    WDI_FW_LOGGING_INIT_REQ,
                    sizeof(halFWLoggingInitReq.tFWLoggingInitReqParams),
                    &pSendBuffer, &usDataOffset, &usSendSize))||
            (usSendSize < (usDataOffset +
            sizeof(halFWLoggingInitReq.tFWLoggingInitReqParams))))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
                "Unable to get send buffer in Process Mgmt Logging Init Req");
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }

    halFWLoggingInitReq.tFWLoggingInitReqParams.enableFlag=
                                    wdiFWLoggingInitReq->enableFlag;
    halFWLoggingInitReq.tFWLoggingInitReqParams.frameSize=
                                    wdiFWLoggingInitReq->frameSize;
    halFWLoggingInitReq.tFWLoggingInitReqParams.frameType=
                                    wdiFWLoggingInitReq->frameType;
    halFWLoggingInitReq.tFWLoggingInitReqParams.bufferMode=
                                    wdiFWLoggingInitReq->bufferMode;
    halFWLoggingInitReq.tFWLoggingInitReqParams.continuousFrameLogging=
                                    wdiFWLoggingInitReq->continuousFrameLogging;
    halFWLoggingInitReq.tFWLoggingInitReqParams.minLogBuffSize=
                                    wdiFWLoggingInitReq->minLogBufferSize;
    halFWLoggingInitReq.tFWLoggingInitReqParams.maxLogBuffSize=
                                    wdiFWLoggingInitReq->maxLogBufferSize;
    halFWLoggingInitReq.tFWLoggingInitReqParams.logMailBoxAddr=
            (tANI_U64)(uintptr_t)(WDI_DS_GetLoggingMbPhyAddr(pWDICtx));
    halFWLoggingInitReq.tFWLoggingInitReqParams.logMailBoxVer=
            MAILBOX_VERSION_V1;

    wdiFWLoggingInitRspCb   = (WDI_FWLoggingInitRspCb)pEventData->pCBfnc;

    wpalMemoryCopy( pSendBuffer+usDataOffset,
                    &halFWLoggingInitReq.tFWLoggingInitReqParams,
                    sizeof(halFWLoggingInitReq.tFWLoggingInitReqParams));

    /*-------------------------------------------------------------------------
      Send Mgmt Logging Init Request to HAL
      ------------------------------------------------------------------------*/
    wdiStatus = WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                             wdiFWLoggingInitRspCb, pEventData->pUserData,
                             WDI_FW_LOGGING_INIT_RSP);

    return  wdiStatus;
}

/**
 @brief Process FwrMemDumpReq Request

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
    WDI_ProcessFwrMemDumpReq

(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
    WDI_FwrMemDumpReqType *            wdiFwrMemDumpReq;
    wpt_uint8*                         pSendBuffer  = NULL;
    wpt_uint16                         usDataOffset = 0;
    wpt_uint16                         usSendSize   = 0;
    WDI_Status                         wdiStatus;
    tHalFwMemoryDumpReqMsg             halFwrMemDumpReq;
    WDI_FwrMemDumpRspCb                wdiFwrMemDumpRspCb;

    VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
            "%s: %d Enter",__func__, __LINE__);

    /*-------------------------------------------------------------------------
      Sanity check
      ------------------------------------------------------------------------*/
    if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
            ( NULL == pEventData->pEventData))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                "%s: Invalid parameters", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }

    wdiFwrMemDumpReq = (WDI_FwrMemDumpReqType *)pEventData->pEventData;

    /*-----------------------------------------------------------------------
      Get message buffer
      -----------------------------------------------------------------------*/
    if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                    WDI_FWR_MEM_DUMP_REQ,
                    sizeof(halFwrMemDumpReq.tFwMemoryDumpReqParam),
                    &pSendBuffer, &usDataOffset, &usSendSize))||
            (usSendSize < (usDataOffset +
            sizeof(halFwrMemDumpReq.tFwMemoryDumpReqParam))))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
                "Unable to get send buffer in Process Fwr Mem Dump Req");
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }

    wdiFwrMemDumpRspCb   = (WDI_FwrMemDumpRspCb)pEventData->pCBfnc;
    wpalMemoryCopy( pSendBuffer+usDataOffset,
                    &halFwrMemDumpReq.tFwMemoryDumpReqParam,
                    sizeof(halFwrMemDumpReq.tFwMemoryDumpReqParam));

    /*-------------------------------------------------------------------------
        Send Fwr Mem Dump Request to HAL
      ------------------------------------------------------------------------*/
    wdiStatus = WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                             wdiFwrMemDumpRspCb, pEventData->pUserData,
                             WDI_FWR_MEM_DUMP_RSP);
    return  wdiStatus;
}

/**
 @brief WDI_EncryptMsgReq

 @param pwdiEncryptMsgParams: Req parameter for the FW
        wdiEncryptMsgCbRsp: callback for passing back the response
        of the Req operation received from the device
        pUserData: user data will be passed back with the callback

 @return SUCCESS or FAIL
*/
WDI_Status
WDI_EncryptMsgReq(void* pwdiEncryptMsgParams,
        WDI_EncryptMsgRspCb wdiEncryptMsgCbRsp,
        void*                   pUserData)
{
  WDI_EventInfoType      wdiEventData;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
          "%s: %d Enter" ,__func__, __LINE__);
  /*------------------------------------------------------------------------
    Sanity Check
    ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
      VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

      return WDI_STATUS_E_NOT_ALLOWED;
  }

  wdiEventData.wdiRequest      = WDI_ENCRYPT_MSG_REQ;
  wdiEventData.pEventData      = pwdiEncryptMsgParams;
  wdiEventData.uEventDataSize  = sizeof(wpt_pkt80211);
  wdiEventData.pCBfnc          = wdiEncryptMsgCbRsp;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/*
 * FUNCTION: WDI_ProcessEncryptMsgReq
 * Request to WDI to encrypt the given message.
 *
 * @param  pWDICtx:         pointer to the WLAN DAL context
 *         pEventData:      pointer to the event information structure
 *
 * @return Result of the function call
 */

WDI_Status
WDI_ProcessEncryptMsgReq
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  wpt_uint8*                   pSendBuffer         = NULL;
  wpt_uint16                   usDataOffset        = 0;
  wpt_uint16                   usSendSize          = 0;
  WDI_EncryptMsgRspCb*         wdiEncMsgCb;
  tSetEncryptedDataParams     *pHalEncryptDataReq;
  wpt_pkt80211 *pkt = NULL;

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData) ||
      ( NULL == pEventData->pCBfnc ) )
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiEncMsgCb = (WDI_EncryptMsgRspCb*)pEventData->pCBfnc;

  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(
                                  pWDICtx, WDI_ENCRYPT_MSG_REQ,
                                  sizeof(tSetEncryptedDataReqMsg),
                                 &pSendBuffer, &usDataOffset, &usSendSize)) ||
      ( usSendSize < (usDataOffset + sizeof(tSetEncryptedDataReqMsg))))
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                "Unable to get send buffer in get WDI_ENCRYPT_MSG_REQ %p",
                pEventData);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pWDICtx->wdiReqStatusCB = NULL;
  pWDICtx->pReqStatusUserData = pEventData->pUserData;
  pkt = (wpt_pkt80211 *)pEventData->pEventData;

  pHalEncryptDataReq = &((tSetEncryptedDataReqMsg *)(pSendBuffer))->encryptedDataParams;
  wpalMemoryZero(pHalEncryptDataReq, sizeof(tSetEncryptedDataParams));

  wpalMemoryCopy(&pHalEncryptDataReq->macHeader, &pkt->macHeader, 32);

  pHalEncryptDataReq->encParams.keyParams.key[0].keyId =
      pkt->encParams.keyParams.key[0].keyId;

  wpalMemoryCopy(&pHalEncryptDataReq->encParams.keyParams.key[0].key[0],
          &pkt->encParams.keyParams.key[0].key[0], 16);

  wpalMemoryCopy(&pHalEncryptDataReq->encParams.pn, &pkt->encParams.pn, 6);

  pHalEncryptDataReq->data.length = pkt->data.length;
  wpalMemoryCopy(&pHalEncryptDataReq->data.data[0], &pkt->data.data[0], pkt->data.length);

  /*-------------------------------------------------------------------------
    Send Get STA Request to HAL
  -------------------------------------------------------------------------*/
  return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, wdiEncMsgCb,
                       pEventData->pUserData, WDI_ENCRYPT_MSG_RSP);
}

/*
 * FUNCTION: WDI_ProcessEncryptMsgRsp
 * Receives the encrypted message from the firmware
 * @param  pWDICtx:         pointer to the WLAN DAL context
 *         pEventData:      pointer to the event information structure
 *
 * @return Result of the function call
 */
WDI_Status
WDI_ProcessEncryptMsgRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  tpSetEncryptedDataRspParams pSetEncryptedDataRsp;
  WDI_EncryptMsgRspCb wdiEncryptMsgRspCb;

  WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
                 "In %s",__func__);

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pSetEncryptedDataRsp = (tpSetEncryptedDataRspParams)pEventData->pEventData;

  wdiEncryptMsgRspCb = (WDI_EncryptMsgRspCb)pWDICtx->pfncRspCB;

  wdiEncryptMsgRspCb(WDI_STATUS_SUCCESS,
          pEventData->pEventData,
          pWDICtx->pRspCBUserData);
  return WDI_STATUS_SUCCESS;
}

WDI_Status
WDI_NanRequest
(
   WDI_NanRequestType         *pwdiNanRequest,
   void                       *usrData
)
{
  WDI_EventInfoType      wdiEventData;

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
              "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
  }

  WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
              "WDI_NanRequest %zu %d", sizeof(*pwdiNanRequest),
              pwdiNanRequest->request_data_len);

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_NAN_REQUEST;
  wdiEventData.pEventData      = pwdiNanRequest;
  wdiEventData.uEventDataSize  = sizeof(*pwdiNanRequest)
                                 + pwdiNanRequest->request_data_len;
  wdiEventData.pUserData       = usrData;
  wdiEventData.pCBfnc          = NULL;


  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

WDI_Status
WDI_ProcessNanRequest
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_NanRequestType               *pwdiNanRequest   = NULL;
  wpt_uint8*                       pSendBuffer       = NULL;
  wpt_uint16                       usDataOffset      = 0;
  wpt_uint16                       usSendSize        = 0;

  WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
              "WDI_ProcessNanRequest");

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) ||
      ( NULL == (pwdiNanRequest = (WDI_NanRequestType*)pEventData->pEventData)))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __FUNCTION__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS
        != WDI_GetMessageBuffer( pWDICtx,
                                 WDI_NAN_REQUEST,
                                 pwdiNanRequest->request_data_len,
                                 &pSendBuffer,
                                 &usDataOffset,
                                 &usSendSize))||
      ( usSendSize < (usDataOffset + pwdiNanRequest->request_data_len)))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                 "Unable to get send buffer in NAN request %p %p",
                 pEventData, pwdiNanRequest);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wpalMemoryCopy( pSendBuffer+usDataOffset,
                  pwdiNanRequest->request_data,
                  pwdiNanRequest->request_data_len);

  pWDICtx->pReqStatusUserData = NULL;
  pWDICtx->pfncRspCB = NULL;
  vos_mem_free( pEventData->pUserData);

  /*-------------------------------------------------------------------------
    Send NAN Request to HAL
  -------------------------------------------------------------------------*/
  return WDI_SendMsg( pWDICtx,
                      pSendBuffer,
                      usSendSize,
                      NULL,
                      NULL,
                      WDI_NAN_RESPONSE);
}

/**
 @brief Process NAN Response function (called when a
        response is being received over the bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessNanResponse
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_Status wdiStatus;
  eHalStatus halStatus;

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  halStatus = *((eHalStatus*)pEventData->pEventData);
  wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus);

  WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
          "%s : Received NAN response, status : %d", __FUNCTION__, wdiStatus);

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessNanResponse*/


/**
 @brief Process NAN Event function (called when
        an indication is being received over the
        bus from HAL)

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessNanEvent
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_LowLevelIndType  wdiInd;

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

  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData ))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT( 0 );
     return WDI_STATUS_E_FAILURE;
  }

  WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
          "%s: Received NAN event", __func__);
  /*-------------------------------------------------------------------------
    Extract indication and send it to UMAC
  -------------------------------------------------------------------------*/
  wdiInd.wdiIndicationType = WDI_NAN_EVENT_IND;
  wdiInd.wdiIndicationData.wdiNanEvent.event_data_len =
      pEventData->uEventDataSize;
  wdiInd.wdiIndicationData.wdiNanEvent.event_data =
      pEventData->pEventData;

  /*Notify UMAC*/
  pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );

  return WDI_STATUS_SUCCESS;
}/*WDI_ProcessNanEvent*/


WDI_Status
WDI_Process_RssiBreachedInd
(
    WDI_ControlBlockType*  pWDICtx,
    WDI_EventInfoType*     pEventData
)
{
  WDI_LowLevelIndType  wdiInd;
  tHalRssiMonitorIndParams halRssiBreachedInd;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
     Sanity check
    -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
    Extract indication and send it to UMAC
   -------------------------------------------------------------------------*/
  wpalMemoryCopy(  &halRssiBreachedInd,
                   pEventData->pEventData,
                   sizeof(halRssiBreachedInd));


  /*Fill in the indication parameters*/
  wdiInd.wdiIndicationType = WDI_RSSI_BREACHED_IND;
  wpalMemoryCopy((void *)&wdiInd.wdiIndicationData.wdiRssiBreachedInd,
                 (void *)&halRssiBreachedInd,
                 sizeof(WDI_RssiBreachedIndType));
  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
          "%s: session_id %d, rssi : %d, bssId: " MAC_ADDRESS_STR" ", __func__,
           wdiInd.wdiIndicationData.wdiRssiBreachedInd.request_id,
           wdiInd.wdiIndicationData.wdiRssiBreachedInd.rssi,
           MAC_ADDR_ARRAY(wdiInd.wdiIndicationData.wdiRssiBreachedInd.bssId));
  /*Notify UMAC*/
  if (pWDICtx->wdiLowLevelIndCB)
  {
    pWDICtx->wdiLowLevelIndCB(&wdiInd, pWDICtx->pIndUserData);
  }

  return WDI_STATUS_SUCCESS;

}


WDI_Status
WDI_Process_LostLinkParamInd
(
    WDI_ControlBlockType*  pWDICtx,
    WDI_EventInfoType*     pEventData
)
{
  WDI_LowLevelIndType  wdiInd;
  tHalLostLinkParametersIndParams halLostLinkParamInd;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
     Sanity check
    -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  /*-------------------------------------------------------------------------
    Extract indication and send it to UMAC
   -------------------------------------------------------------------------*/
  wpalMemoryCopy( (void *)&halLostLinkParamInd,
                   pEventData->pEventData,
                   sizeof(tHalLostLinkParametersIndParams));


  /*Fill in the indication parameters*/
  wdiInd.wdiIndicationType = WDI_LOST_LINK_PARAMS_IND;
  wpalMemoryCopy((void *)&wdiInd.wdiIndicationData.wdiLostLinkParamsInd,
                 (void *)&halLostLinkParamInd,
                 sizeof(WDI_LostLinkParamsIndType));
  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
          "%s: bssIdx %d, rssi : %d, selfMacAddr: " MAC_ADDRESS_STR", linkFlCnt: %d,"
          "linkFlTx : %d,lastDataRate : %d", __func__,
           wdiInd.wdiIndicationData.wdiLostLinkParamsInd.bssIdx,
           wdiInd.wdiIndicationData.wdiLostLinkParamsInd.rssi,
           MAC_ADDR_ARRAY(wdiInd.wdiIndicationData.wdiLostLinkParamsInd.selfMacAddr),
           wdiInd.wdiIndicationData.wdiLostLinkParamsInd.linkFlCnt,
           wdiInd.wdiIndicationData.wdiLostLinkParamsInd.linkFlTx,
           wdiInd.wdiIndicationData.wdiLostLinkParamsInd.lastDataRate);
  /*Notify UMAC*/
  if (pWDICtx->wdiLowLevelIndCB)
  {
    pWDICtx->wdiLowLevelIndCB(&wdiInd, pWDICtx->pIndUserData);
  }

  return WDI_STATUS_SUCCESS;

}

WDI_Status
WDI_ProcessSetRtsCtsHtvhtInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  wpt_uint8*  pSendBuffer = NULL;
  wpt_uint16  usDataOffset = 0;
  wpt_uint16  usSendSize = 0;
  wpt_uint32  *rtsCtsVal;
  tHalRtsCtsHtvhtIndParams  *rtsCtsHtvhtIndParams;
  WDI_Status wdiStatus = WDI_STATUS_SUCCESS;


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

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
               "%s", __func__);

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ))
  {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
             "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
  }
  rtsCtsVal = (wpt_uint32*)pEventData->pEventData;
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/

  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                                     WDI_SET_RTS_CTS_HTVHT_IND,
                                      sizeof(tHalRtsCtsHtvhtIndParams),
                          &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(tHalRtsCtsHtvhtIndParams) )))
  {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
              "Unable to get send buffer in RTS CTS ind %p ",
               pEventData);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
  }
  rtsCtsHtvhtIndParams =
           (tHalRtsCtsHtvhtIndParams*)(pSendBuffer + usDataOffset);
  rtsCtsHtvhtIndParams->rtsCtsValue = *rtsCtsVal;

  pWDICtx->pReqStatusUserData = NULL;
  pWDICtx->pfncRspCB = NULL;
  /*-------------------------------------------------------------------------
    Send SET_RTS_CTS_HTVHT Indication to HAL
  -------------------------------------------------------------------------*/
  wdiStatus =  WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize);
  return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC;
}

WDI_Status
WDI_SetRtsCtsHTVhtInd
(
    wpt_uint32 rtsCtsVal
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
   Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "WDI API call before module is initialized - Fail request");
      return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_SET_RTS_CTS_HTVHT_IND;
  wdiEventData.pEventData      = (void *) &rtsCtsVal;
  wdiEventData.uEventDataSize  = sizeof(wpt_uint32);
  wdiEventData.pCBfnc          = NULL;
  wdiEventData.pUserData       = NULL;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

}/* WDI_SetRtsCtsHTVhtInd */

WDI_Status
WDI_ProcessEnableDisableCAEventInd
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  wpt_uint8*  pSendBuffer = NULL;
  wpt_uint16  usDataOffset = 0;
  wpt_uint16  usSendSize = 0;
  wpt_uint32  *val;
  tHalAvoidFreqRangeCtrlParam  *avoidFreqRangeCtrlParam;
  WDI_Status wdiStatus = WDI_STATUS_SUCCESS;


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

  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
               "%s", __func__);

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ))
  {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
             "%s: Invalid parameters", __func__);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
  }
  val = (wpt_uint32*)pEventData->pEventData;
  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/

  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                                     WDI_SEND_FREQ_RANGE_CONTROL_IND,
                                      sizeof(tHalAvoidFreqRangeCtrlParam),
                          &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset + sizeof(tHalAvoidFreqRangeCtrlParam) )))
  {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
              "Unable to get send buffer in Channel Avoidance Ind %p ",
               pEventData);
      WDI_ASSERT(0);
      return WDI_STATUS_E_FAILURE;
  }
  avoidFreqRangeCtrlParam =
           (tHalAvoidFreqRangeCtrlParam*)(pSendBuffer + usDataOffset);
  avoidFreqRangeCtrlParam->status = *val;

  pWDICtx->pReqStatusUserData = NULL;
  pWDICtx->pfncRspCB = NULL;
  /*-------------------------------------------------------------------------
    Send AVOID_FREQ_RANGE_CONTROL_IND Indication to HAL
  -------------------------------------------------------------------------*/
  wdiStatus =  WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize);
  return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC;
}

WDI_Status
WDI_EnableDisableCAEventInd
(
    wpt_uint32 val
)
{
  WDI_EventInfoType      wdiEventData;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*------------------------------------------------------------------------
   Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "WDI API call before module is initialized - Fail request");
      return WDI_STATUS_E_NOT_ALLOWED;
  }

  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_SEND_FREQ_RANGE_CONTROL_IND;
  wdiEventData.pEventData      = (void *) &val;
  wdiEventData.uEventDataSize  = sizeof(wpt_uint32);
  wdiEventData.pCBfnc          = NULL;
  wdiEventData.pUserData       = NULL;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);

} /* WDI_EnableDisableCAEventInd */

/**
 @brief WDI_WifiConfigSetReq
    This API is called to set WifiConfig params request in FW

 @param pwdiWifiConfigSetReqParams : pointer to set WifiCofig request params
        wdiWifiConfigSetRspCb : WifiConfig stats resp callback
        usrData : Client context
 @see
 @return SUCCESS or FAIL
*/
WDI_Status
WDI_WifiConfigSetReq(WDI_WifiConfigSetReqType* pwdiWifConfigSetReqParams,
                           WDI_WifiConfigSetRspCb   wdiWifiConfigSetRspCb,
                           void*                   pUserData)
{
   WDI_EventInfoType      wdiEventData;

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
     VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
  }

  wdiEventData.wdiRequest      = WDI_WIFI_CONFIG_SET_REQ;
  wdiEventData.pEventData      = pwdiWifConfigSetReqParams;
  wdiEventData.uEventDataSize  = sizeof(*pwdiWifConfigSetReqParams);
  wdiEventData.pCBfnc          = wdiWifiConfigSetRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief WDI_ProcessWifiConfigReq -
    Set WifiConfig request to FW

 @param  pWDICtx : wdi context
         pEventData : indication data

 @see
 @return none
*/
   WDI_Status
   WDI_ProcessWifiConfigReq
   (
     WDI_ControlBlockType*  pWDICtx,
     WDI_EventInfoType*     pEventData
   )
   {
     WDI_WifiConfigSetReqType* pwdiWifiConfigSetReqParams;
     WDI_WifiConfigSetRspCb wdiWifiConfigSetRspCb;
     wpt_uint8*               pSendBuffer         = NULL;
     wpt_uint16               usSendSize          = 0;
     wpt_uint16               usDataOffset        = 0;
     tSetWifiConfigParamsReq halWifiConfigSetParams;

     if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
         ( NULL == pEventData->pCBfnc ))
     {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                    "%s: Invalid parameters", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
     }
     pwdiWifiConfigSetReqParams = (WDI_WifiConfigSetReqType*)pEventData->pEventData;
     wdiWifiConfigSetRspCb   = (WDI_WifiConfigSetRspCb)pEventData->pCBfnc;

     /*-----------------------------------------------------------------------
       Get message buffer
       ! TO DO : proper conversion into the HAL Message Request Format
     -----------------------------------------------------------------------*/
     if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(
                                           pWDICtx,
                                           WDI_WIFI_CONFIG_SET_REQ,
                                           sizeof(halWifiConfigSetParams.wifiConfigParams),
                                           &pSendBuffer, &usDataOffset,
                                           &usSendSize))||
         ( usSendSize < (usDataOffset + sizeof(halWifiConfigSetParams.wifiConfigParams) )))
     {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
                 "Unable to get send buffer in %s %p %p %p", __func__,
                   pEventData, pwdiWifiConfigSetReqParams, wdiWifiConfigSetRspCb);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
     }

     halWifiConfigSetParams.wifiConfigParams.paramType = pwdiWifiConfigSetReqParams->paramType;
     halWifiConfigSetParams.wifiConfigParams.paramValue =
         pwdiWifiConfigSetReqParams->paramValue;
     vos_mem_copy(halWifiConfigSetParams.wifiConfigParams.bssid, &(pwdiWifiConfigSetReqParams->bssId),
                                            sizeof(tSirMacAddr));

     wpalMemoryCopy(pSendBuffer+usDataOffset,
                     &halWifiConfigSetParams.wifiConfigParams,
                     sizeof(halWifiConfigSetParams.wifiConfigParams));

     pWDICtx->pReqStatusUserData = pEventData->pUserData;

     /*-------------------------------------------------------------------------
       Send Clear Link Layer Stats Request to HAL
     -------------------------------------------------------------------------*/
     return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                          wdiWifiConfigSetRspCb, pEventData->pUserData,
                          WDI_WIFI_CONFIG_SET_RSP);
   }

WDI_Status
WDI_ProcessWificonfigSetRsp
( WDI_ControlBlockType* pWDICtx,
  WDI_EventInfoType* pEventData )

{
  tHalSetWifiConfigRspParams    halRsp;
  WDI_WifiConfigSetRspCb        wdiWifiConfigSetRspCb;
  WDI_WifconfigSetRsp           wdiWifconfigSetRsp;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                  "%s: %d Enter",__func__, __LINE__);

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  wdiWifiConfigSetRspCb = (WDI_WifiConfigSetRspCb)pWDICtx->pfncRspCB;

  /*-------------------------------------------------------------------------
    Extract response and send it to UMAC
  -------------------------------------------------------------------------*/
  wpalMemoryCopy(&halRsp, pEventData->pEventData, sizeof(halRsp));

  wdiWifconfigSetRsp.wificonfigset_status = WDI_HAL_2_WDI_STATUS(halRsp.status);

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                     "WifiConfig RSP status = %d",
                     wdiWifconfigSetRsp.wificonfigset_status);
  /*Notify UMAC*/
  wdiWifiConfigSetRspCb( &wdiWifconfigSetRsp, pWDICtx->pRspCBUserData);

  return WDI_STATUS_SUCCESS;
}

#ifdef FEATURE_OEM_DATA_SUPPORT

/**
 @brief WDI_StartOemDataReqIndNew

 @param pOemDataReqNewConfig: Req parameter for the FW

 @return SUCCESS or FAIL
*/
WDI_Status
WDI_StartOemDataReqIndNew
(
   WDI_OemDataReqNewConfig *pOemDataReqNewConfig
)
{
   WDI_EventInfoType      wdiEventData;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                  "%s: %d",__func__, __LINE__);
  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
     VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                "WDI API call before module is initialized - Fail request");

     return WDI_STATUS_E_NOT_ALLOWED;
  }

  wdiEventData.wdiRequest      = WDI_START_OEM_DATA_REQ_IND_NEW;
  wdiEventData.pEventData      = pOemDataReqNewConfig;
  wdiEventData.uEventDataSize  = sizeof(*pOemDataReqNewConfig);
  wdiEventData.pCBfnc          = NULL;
  wdiEventData.pUserData       = NULL;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}

/**
 @brief WDI_ProcessStartOemDataReqIndNew -
    Send OEM Data request new indication to FW

 @param  pWDICtx : wdi context
         pEventData : indication data

 @see
 @return none
*/
WDI_Status
WDI_ProcessStartOemDataReqIndNew
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
  WDI_OemDataReqNewConfig* wdiOemDataReqNewConfig;
  wpt_uint8*               pSendBuffer         = NULL;
  wpt_uint16               usSendSize          = 0;
  wpt_uint16               usDataOffset        = 0;
  tpStartOemDataReqParamsNew   pHalStartOemDataReqParamsNew;
  WDI_Status wdiStatus = WDI_STATUS_SUCCESS;

  VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                  "%s: %d",__func__, __LINE__);

  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
           ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  wdiOemDataReqNewConfig =
      (WDI_OemDataReqNewConfig *)pEventData->pEventData;

  /*-----------------------------------------------------------------------
    Get message buffer
  -----------------------------------------------------------------------*/
  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(
                                        pWDICtx,
                                        WDI_START_OEM_DATA_REQ_IND_NEW,
                                        sizeof(*pHalStartOemDataReqParamsNew),
                                        &pSendBuffer, &usDataOffset,
                                        &usSendSize))||
     ( usSendSize < (usDataOffset + sizeof(*pHalStartOemDataReqParamsNew) )))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
              "Unable to get send buffer in %s %p %p", __func__,
                pEventData, wdiOemDataReqNewConfig);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }

  pHalStartOemDataReqParamsNew =
      (tpStartOemDataReqParamsNew) (pSendBuffer + usDataOffset);

  wpalMemoryCopy(pHalStartOemDataReqParamsNew,
                 wdiOemDataReqNewConfig,
                 sizeof(*pHalStartOemDataReqParamsNew));

  VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
          "%s: selfMacAddr: " MAC_ADDRESS_STR" ", __func__,
           MAC_ADDR_ARRAY(pHalStartOemDataReqParamsNew->selfMacAddr));

  pWDICtx->pReqStatusUserData = NULL;
  pWDICtx->pfncRspCB = NULL;

  /*-------------------------------------------------------------------------
    Send WDI_START_OEM_DATA_REQ_IND_NEW Request to HAL
  -------------------------------------------------------------------------*/
  wdiStatus =  WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize);
  return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC;
}

/**
 @brief Process OemDataRsp New Indication indication from FW

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessStartOemDataRspIndNew
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
    WDI_LowLevelIndType wdiInd;
    /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

    VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                "%s: ", __func__);

    /* sanity check */
    if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: Invalid parameters", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }

    /* Fill in the indication parameters */
    wdiInd.wdiIndicationType = WDI_START_OEM_DATA_RSP_IND_NEW;

    wdiInd.wdiIndicationData.wdiOemDataRspNew.pOemRspNewIndData =
                                                (void *)pEventData->pEventData;
    wdiInd.wdiIndicationData.wdiOemDataRspNew.OemRspNewLen =
                                                    pEventData->uEventDataSize;
    /* Notify UMAC */
    if (pWDICtx->wdiLowLevelIndCB)
    {
        pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
    }
    else
    {
        VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                 "%s: WDILowLevelIndCb is null", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }
    return WDI_STATUS_SUCCESS;
} /* End of WDI_ProcessEXTScanResultInd  */

/**
 @brief Process Current Antenna Index information from FW

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessGetCurrentAntennaIndexRsp
(
  WDI_ControlBlockType*  pWDICtx,
  WDI_EventInfoType*     pEventData
)
{
   WDI_AntennaDivSelRspCb wdiGetCurrentAntennaIndexRspCb;
   tHalAntennaDiversitySelectionRspParams *pHalAntDivSelRsp;

  /*-------------------------------------------------------------------------
    Sanity check
  -------------------------------------------------------------------------*/
  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
      ( NULL == pEventData->pEventData))
  {
     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
                 "%s: Invalid parameters", __func__);
     WDI_ASSERT(0);
     return WDI_STATUS_E_FAILURE;
  }
  pHalAntDivSelRsp =
  (tHalAntennaDiversitySelectionRspParams*)pEventData->pEventData;
  wdiGetCurrentAntennaIndexRspCb = (WDI_AntennaDivSelRspCb)pWDICtx->pfncRspCB;

  if (pHalAntDivSelRsp->status != 0)
  {
      wdiGetCurrentAntennaIndexRspCb(WDI_STATUS_E_FAILURE,
                      (void *)pHalAntDivSelRsp, pWDICtx->pRspCBUserData);
  }
  else
  {
      wdiGetCurrentAntennaIndexRspCb(WDI_STATUS_SUCCESS,
                                     (void *)pHalAntDivSelRsp,
                                     pWDICtx->pRspCBUserData);
  }

  return WDI_STATUS_SUCCESS;
}

/**
 @brief Process Get Current Antenna Index request command

 @param  pWDICtx:         pointer to the WLAN DAL context
         pEventData:      pointer to the event information structure

 @see
 @return Result of the function call
*/
WDI_Status
WDI_ProcessGetCurrentAntennaIndex
(
    WDI_ControlBlockType*  pWDICtx,
    WDI_EventInfoType*     pEventData
)
{
    wpt_uint8*  pSendBuffer = NULL;
    wpt_uint16  usDataOffset = 0;
    wpt_uint16  usSendSize = 0;
    tHalAntennaDiversitySelectionReqParams halAntDivSelReq;
    WDI_AntennaDivSelRspCb wdiGetCurrentAntennaIndexRspCb;

    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
               "%s", __func__);

    /*-------------------------------------------------------------------------
       Sanity check
     -------------------------------------------------------------------------*/
    if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) ||
        ( NULL == pEventData->pCBfnc ))
    {
        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                    "%s: Invalid parameters", __func__);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }
    wdiGetCurrentAntennaIndexRspCb = (WDI_AntennaDivSelRspCb)pEventData->pCBfnc;

    if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
                                WDI_ANTENNA_DIVERSITY_SELECTION_REQ,
                                sizeof(tHalAntennaDiversitySelectionReqParams),
                                &pSendBuffer, &usDataOffset, &usSendSize))||
       ( usSendSize < (usDataOffset +
         sizeof(tHalAntennaDiversitySelectionReqParams) )))
    {
           WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                       "Unable to get send buffer in GetCurrentAntennaIndex %p",
                       pEventData);
        WDI_ASSERT(0);
        return WDI_STATUS_E_FAILURE;
    }
    pWDICtx->wdiReqStatusCB = NULL;
    pWDICtx->pReqStatusUserData = pEventData->pEventData;
    halAntDivSelReq.reserved = *((wpt_uint32 *)(pEventData->pEventData));
    wpalMemoryCopy( pSendBuffer+usDataOffset,
                    &halAntDivSelReq,
                    sizeof(tHalAntennaDiversitySelectionReqParams));

   /*-------------------------------------------------------------------------
     Send Get STA Request to HAL
   -------------------------------------------------------------------------*/
   return  WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
                        wdiGetCurrentAntennaIndexRspCb,
                        pEventData->pUserData,
                        WDI_ANTENNA_DIVERSITY_SELECTION_RSP);
}

/**
 @brief WDI_GetCurrentAntennaIndex

 @param pOemDataReqNewConfig: Req parameter for the FW

 @return SUCCESS or FAIL
*/
WDI_Status
WDI_GetCurrentAntennaIndex
(
  void *pUserData,
  WDI_AntennaDivSelRspCb wdiAntennaDivSelRspCb,
  wpt_uint32 reserved
)
{
   WDI_EventInfoType      wdiEventData;

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

  /*------------------------------------------------------------------------
    Sanity Check
  ------------------------------------------------------------------------*/
  if ( eWLAN_PAL_FALSE == gWDIInitialized )
  {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "WDI API call before module is initialized - Fail request");
      return WDI_STATUS_E_NOT_ALLOWED;
  }
  /*------------------------------------------------------------------------
    Fill in Event data and post to the Main FSM
  ------------------------------------------------------------------------*/
  wdiEventData.wdiRequest      = WDI_ANTENNA_DIVERSITY_SELECTION_REQ;
  wdiEventData.pEventData      = (void *)&reserved;
  wdiEventData.uEventDataSize  = sizeof(wpt_uint32);
  wdiEventData.pCBfnc          = wdiAntennaDivSelRspCb;
  wdiEventData.pUserData       = pUserData;

  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}
#endif
