/*
 * Copyright (c) 2012-2015 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
   ,FEATURE_NOT_SUPPORTED          //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
   ,FEATURE_NOT_SUPPORTED          //52
   ,MGMT_FRAME_LOGGING             //53
   ,ENHANCED_TXBD_COMPLETION       //54
   ,LOGGING_ENHANCEMENT            //55
   ,FEATURE_NOT_SUPPORTED          //56
   ,MEMORY_DUMP_SUPPORTED          //57
   ,PER_PKT_STATS_SUPPORTED        //58
};

/*-------------------------------------------------------------------------- 
   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 */
  /*-------------------------------------------------------------------------
    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 */

};


/*---------------------------------------------------------------------------
  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*/
  /*---------------------------------------------------------------------
    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 */
};


/*---------------------------------------------------------------------------
  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 );
    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);
    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;
#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;


                 }
                 *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

        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,
  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);
  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 )
  {
     // 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*/
  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;
  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;
  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_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;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*-------------------------------------------------------------------------
  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 indication and send it to UMAC
 -------------------------------------------------------------------------*/
  wpalMemoryCopy(&chAvoidIndicationParam,
                 pEventData->pEventData,
                 sizeof(tHalAvoidFreqRangeIndParams));

  /* 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));

  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 */
