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

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




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

  \file  wlan_hdd_main.c

  \brief WLAN Host Device Driver implementation


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

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

                       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
  --------    ---    --------------------------------------------------------
  04/5/09     Shailender     Created module.
  02/24/10    Sudhir.S.Kohalli  Added to support param for SoftAP module
  06/03/10    js - Added support to hostapd driven deauth/disassoc/mic failure
  ==========================================================================*/

/*--------------------------------------------------------------------------
  Include Files
  ------------------------------------------------------------------------*/
//#include <wlan_qct_driver.h>
#include <wlan_hdd_includes.h>
#include <vos_api.h>
#include <vos_sched.h>
#include <linux/etherdevice.h>
#include <linux/firmware.h>
#ifdef ANI_BUS_TYPE_PLATFORM
#include <linux/wcnss_wlan.h>
#endif //ANI_BUS_TYPE_PLATFORM
#ifdef ANI_BUS_TYPE_PCI
#include "wcnss_wlan.h"
#endif /* ANI_BUS_TYPE_PCI */
#include <wlan_hdd_tx_rx.h>
#include <palTimer.h>
#include <wniApi.h>
#include <wlan_nlink_srv.h>
#include <wlan_btc_svc.h>
#include <wlan_hdd_cfg.h>
#include <wlan_ptt_sock_svc.h>
#include <wlan_logging_sock_svc.h>
#include <wlan_hdd_wowl.h>
#include <wlan_hdd_misc.h>
#include <wlan_hdd_wext.h>
#ifdef WLAN_BTAMP_FEATURE
#include <bap_hdd_main.h>
#include <bapInternal.h>
#endif // WLAN_BTAMP_FEATURE
#include "wlan_hdd_trace.h"
#include "vos_types.h"
#include "vos_trace.h"
#include <linux/wireless.h>
#include <net/cfg80211.h>
#include <linux/inetdevice.h>
#include <net/addrconf.h>
#include "wlan_hdd_cfg80211.h"
#include "wlan_hdd_p2p.h"
#include <linux/rtnetlink.h>
int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
#include "sapApi.h"
#include <linux/semaphore.h>
#include <linux/ctype.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
#include <soc/qcom/subsystem_restart.h>
#else
#include <mach/subsystem_restart.h>
#endif
#include <wlan_hdd_hostapd.h>
#include <wlan_hdd_softap_tx_rx.h>
#include "cfgApi.h"
#include "wlan_hdd_dev_pwr.h"
#ifdef WLAN_BTAMP_FEATURE
#include "bap_hdd_misc.h"
#endif
#include "wlan_qct_pal_trace.h"
#include "qwlan_version.h"
#include "wlan_qct_wda.h"
#ifdef FEATURE_WLAN_TDLS
#include "wlan_hdd_tdls.h"
#endif
#include "wlan_hdd_debugfs.h"
#include "sapInternal.h"
#include "wlan_hdd_request_manager.h"

#ifdef MODULE
#define WLAN_MODULE_NAME  module_name(THIS_MODULE)
#else
#define WLAN_MODULE_NAME  "wlan"
#endif

#ifdef TIMER_MANAGER
#define TIMER_MANAGER_STR " +TIMER_MANAGER"
#else
#define TIMER_MANAGER_STR ""
#endif

#ifdef MEMORY_DEBUG
#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
#else
#define MEMORY_DEBUG_STR ""
#endif
#define MAX_WAIT_FOR_ROC_COMPLETION 3
/* the Android framework expects this param even though we don't use it */
#define BUF_LEN 20
static char fwpath_buffer[BUF_LEN];
static struct kparam_string fwpath = {
   .string = fwpath_buffer,
   .maxlen = BUF_LEN,
};

static char *country_code;
static int   enable_11d = -1;
static int   enable_dfs_chan_scan = -1;

#ifndef MODULE
static int wlan_hdd_inited;
#endif

/*
 * spinlock for synchronizing asynchronous request/response
 * (full description of use in wlan_hdd_main.h)
 */
DEFINE_SPINLOCK(hdd_context_lock);

/*
 * The rate at which the driver sends RESTART event to supplicant
 * once the function 'vos_wlanRestart()' is called
 *
 */
#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000  /* 5 second */
#define WLAN_HDD_RESTART_RETRY_MAX_CNT  5     /* 5 retries */

/*
 * Size of Driver command strings from upper layer
 */
#define SIZE_OF_SETROAMMODE             11    /* size of SETROAMMODE */
#define SIZE_OF_GETROAMMODE             11    /* size of GETROAMMODE */

#ifdef WLAN_FEATURE_RMC
/*
 * Ibss prop IE from command will be of size:
 * size  = sizeof(oui) + sizeof(oui_data) + 1(Element ID) + 1(EID Length)
 * OUI_DATA should be at least 3 bytes long
 */
#define WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH (3)
#endif

#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
#define TID_MIN_VALUE 0
#define TID_MAX_VALUE 15
static VOS_STATUS  hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
                                         tAniTrafStrmMetrics* pTsmMetrics);
static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
                                     tCsrEseBeaconReq *pEseBcnReq);
#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */

/*
 * Maximum buffer size used for returning the data back to user space
 */
#define WLAN_MAX_BUF_SIZE 1024
#define WLAN_PRIV_DATA_MAX_LEN    8192

/*
 * When ever we need to print IBSSPEERINFOALL for morethan 16 STA
 * we will split the printing.
 */
#define NUM_OF_STA_DATA_TO_PRINT 16

#ifdef WLAN_FEATURE_RMC
#define WLAN_NLINK_CESIUM 30
#endif

//wait time for beacon miss rate.
#define BCN_MISS_RATE_TIME 500

/*
 * Android DRIVER command structures
 */
struct android_wifi_reassoc_params {
	unsigned char bssid[18];
	int channel;
};

static vos_wake_lock_t wlan_wake_lock;

/* set when SSR is needed after unload */
static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;

//internal function declaration
static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);

#ifdef WLAN_FEATURE_RMC
static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo);

static int hdd_open_cesium_nl_sock(void);
static void hdd_close_cesium_nl_sock(void);
static struct sock *cesium_nl_srv_sock;
static v_U16_t cesium_pid;

static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
                                          tANI_U8 *tx_fail_count,
                                          tANI_U16 *pid);

static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg);

#endif /* WLAN_FEATURE_RMC */
void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
void hdd_set_wlan_suspend_mode(bool suspend);
void hdd_set_vowifi_mode(hdd_context_t *hdd_ctx, bool enable);

v_U16_t hdd_select_queue(struct net_device *dev,
    struct sk_buff *skb
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
    , void *accel_priv
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
    , select_queue_fallback_t fallback
#endif
);

#ifdef WLAN_FEATURE_PACKET_FILTERING
static void hdd_set_multicast_list(struct net_device *dev);
#endif

void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);

#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
                              tANI_U8 *pChannel, tANI_U8 *pDwellTime,
                              tANI_U8 **pBuf, tANI_U8 *pBufLen);
static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
				tANI_U8 *pTargetApBssid, tANI_U8 *pChannel);
#endif

/* Store WLAN driver info in a global variable such that crash debugger
   can extract it from driver debug symbol and crashdump for post processing */
tANI_U8 g_wlan_driver[ ] = "pronto_driver";

#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */

static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
const char * hdd_device_modetoString(v_U8_t device_mode)
{
   switch(device_mode)
   {
       CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
       CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
       CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
       CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
       CASE_RETURN_STRING( WLAN_HDD_MONITOR);
       CASE_RETURN_STRING( WLAN_HDD_FTM );
       CASE_RETURN_STRING( WLAN_HDD_IBSS );
       CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
       default:
           return "device_mode Unknown";
   }
}

static int __hdd_netdev_notifier_call(struct notifier_block * nb,
                                         unsigned long state,
                                         void *ndev)
{
   struct net_device *dev = ndev;
   hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
   hdd_context_t *pHddCtx;
#ifdef WLAN_BTAMP_FEATURE
   VOS_STATUS status;
#endif
   long result;

   //Make sure that this callback corresponds to our device.
   if ((strncmp(dev->name, "wlan", 4)) &&
      (strncmp(dev->name, "p2p", 3)))
      return NOTIFY_DONE;

   if (!dev->ieee80211_ptr)
      return NOTIFY_DONE;

   if (NULL == pAdapter)
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
      VOS_ASSERT(0);
      return NOTIFY_DONE;
   }

   pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
   if (NULL == pHddCtx)
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
      VOS_ASSERT(0);
      return NOTIFY_DONE;
   }
   if (pHddCtx->isLogpInProgress)
      return NOTIFY_DONE;


   hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
          __func__, dev->name, state);

   switch (state) {
   case NETDEV_REGISTER:
        break;

   case NETDEV_UNREGISTER:
        break;

   case NETDEV_UP:
        break;

   case NETDEV_DOWN:
        break;

   case NETDEV_CHANGE:
        if(TRUE == pAdapter->isLinkUpSvcNeeded)
           complete(&pAdapter->linkup_event_var);
        break;

   case NETDEV_GOING_DOWN:
        result = wlan_hdd_scan_abort(pAdapter);
        if (result < 0)
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                       "%s: Timeout occurred while waiting for abortscan %ld",
                        __func__, result);
        }
        else
        {
           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
               "%s: Scan Abort Successful" , __func__);
        }
#ifdef WLAN_BTAMP_FEATURE
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
        status = WLANBAP_StopAmp();
        if(VOS_STATUS_SUCCESS != status )
        {
           pHddCtx->isAmpAllowed = VOS_TRUE;
           hddLog(VOS_TRACE_LEVEL_FATAL,
                  "%s: Failed to stop AMP", __func__);
        }
        else
        {
           //a state m/c implementation in PAL is TBD to avoid this delay
           msleep(500);
           if ( pHddCtx->isAmpAllowed )
           {
                WLANBAP_DeregisterFromHCI();
                pHddCtx->isAmpAllowed = VOS_FALSE;
           }
        }
#endif //WLAN_BTAMP_FEATURE
        break;

   default:
        break;
   }

   return NOTIFY_DONE;
}

static int hdd_netdev_notifier_call(struct notifier_block * nb,
                                         unsigned long state,
                                         void *ndev)
{
    int ret;
    vos_ssr_protect(__func__);
    ret = __hdd_netdev_notifier_call( nb, state, ndev);
    vos_ssr_unprotect(__func__);
    return ret;
}

struct notifier_block hdd_netdev_notifier = {
   .notifier_call = hdd_netdev_notifier_call,
};

/*---------------------------------------------------------------------------
 *   Function definitions
 *-------------------------------------------------------------------------*/
void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
//variable to hold the insmod parameters
static int con_mode;
#ifndef MODULE
/* current con_mode - used only for statically linked driver
 * con_mode is changed by userspace to indicate a mode change which will
 * result in calling the module exit and init functions. The module
 * exit function will clean up based on the value of con_mode prior to it
 * being changed by userspace. So curr_con_mode records the current con_mode 
 * for exit when con_mode becomes the next mode for init
 */
static int curr_con_mode;
#endif

#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
/**
 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
 * @hdd_ctx: hdd global context
 *
 * Return: none
 */
static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
{
    uint8_t i;

    mutex_init(&hdd_ctx->op_ctx.op_lock);
    for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
    {
        hdd_ctx->op_ctx.op_table[i].request_id = 0;
        hdd_ctx->op_ctx.op_table[i].pattern_id = i;
    }
}
#else
static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
{
}
#endif

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

  \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable

  Called immediately after the cfg.ini is read in order to configure
  the desired trace levels.

  \param  - moduleId - module whose trace level is being configured
  \param  - bitmask - bitmask of log levels to be enabled

  \return - void

  --------------------------------------------------------------------------*/
static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
{
   wpt_tracelevel level;

   /* if the bitmask is the default value, then a bitmask was not
      specified in cfg.ini, so leave the logging level alone (it
      will remain at the "compiled in" default value) */
   if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
   {
      return;
   }

   /* a mask was specified.  start by disabling all logging */
   vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);

   /* now cycle through the bitmask until all "set" bits are serviced */
   level = VOS_TRACE_LEVEL_FATAL;
   while (0 != bitmask)
   {
      if (bitmask & 1)
      {
         vos_trace_setValue(moduleId, level, 1);
      }
      level++;
      bitmask >>= 1;
   }
}


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

  \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable

  Called immediately after the cfg.ini is read in order to configure
  the desired trace levels in the WDI.

  \param  - moduleId - module whose trace level is being configured
  \param  - bitmask - bitmask of log levels to be enabled

  \return - void

  --------------------------------------------------------------------------*/
static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
{
   wpt_tracelevel level;

   /* if the bitmask is the default value, then a bitmask was not
      specified in cfg.ini, so leave the logging level alone (it
      will remain at the "compiled in" default value) */
   if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
   {
      return;
   }

   /* a mask was specified.  start by disabling all logging */
   wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);

   /* now cycle through the bitmask until all "set" bits are serviced */
   level = eWLAN_PAL_TRACE_LEVEL_FATAL;
   while (0 != bitmask)
   {
      if (bitmask & 1)
      {
         wpalTraceSetLevel(moduleId, level, 1);
      }
      level++;
      bitmask >>= 1;
   }
}

/*
 * FUNCTION: wlan_hdd_validate_context
 * This function is used to check the HDD context
 */
int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
{

    if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                "%s: HDD context is Null", __func__);
        return -ENODEV;
    }

    if (pHddCtx->isLogpInProgress)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  "%s: LOGP %s. Ignore!!", __func__,
                    vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
                    ?"failed":"in Progress");
        return -EAGAIN;
    }

    if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
        return -EAGAIN;
    }
    return 0;
}
#ifdef CONFIG_ENABLE_LINUX_REG
void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
{
   hdd_adapter_t *pAdapter = NULL;
   hdd_station_ctx_t *pHddStaCtx = NULL;
   eCsrPhyMode phyMode;
   hdd_config_t *cfg_param = NULL;

   if (NULL == pHddCtx)
   {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
               "HDD Context is null !!");
       return ;
   }

   pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
   if (NULL == pAdapter)
   {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
               "pAdapter is null !!");
       return ;
   }

   pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
   if (NULL == pHddStaCtx)
   {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
               "pHddStaCtx is null !!");
       return ;
   }

   cfg_param = pHddCtx->cfg_ini;
   if (NULL == cfg_param)
   {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
               "cfg_params not available !!");
       return ;
   }

   phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));

   if (!pHddCtx->isVHT80Allowed)
   {
       if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
           (eCSR_DOT11_MODE_11ac == phyMode) ||
           (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
       {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                    "Setting phymode to 11n!!");
           sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
       }
   }
   else
   {
       /*New country Supports 11ac as well resetting value back from .ini*/
       sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
             hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
       return ;
   }

   if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
       ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
        (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
   {
       VOS_STATUS vosStatus;

       // need to issue a disconnect to CSR.
       INIT_COMPLETION(pAdapter->disconnect_comp_var);
       vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
                          pAdapter->sessionId,
                          eCSR_DISCONNECT_REASON_UNSPECIFIED );

       if (VOS_STATUS_SUCCESS == vosStatus)
       {
           long ret;

           ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
                 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
           if (0 >= ret)
               hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
                                ret);
       }

   }
}
#else
void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
{
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    hdd_config_t *cfg_param;
    eCsrPhyMode phyMode;
    long ret;

    if (NULL == pHddCtx)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                "HDD Context is null !!");
        return ;
    }

    cfg_param = pHddCtx->cfg_ini;

    if (NULL == cfg_param)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                "cfg_params not available !!");
        return ;
    }

    phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));

    if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
    {
        if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
            (eCSR_DOT11_MODE_11ac == phyMode) ||
            (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
        {
             VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                     "Setting phymode to 11n!!");
            sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
        }
    }
    else
    {
        /*New country Supports 11ac as well resetting value back from .ini*/
        sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
              hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
        return ;
    }

    if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
        ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
         (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
    {
        VOS_STATUS vosStatus;

        // need to issue a disconnect to CSR.
        INIT_COMPLETION(pAdapter->disconnect_comp_var);
        vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
                           pAdapter->sessionId,
                           eCSR_DISCONNECT_REASON_UNSPECIFIED );

        if (VOS_STATUS_SUCCESS == vosStatus)
        {
            ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
                  msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
            if (ret <= 0)
            {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                    "wait on disconnect_comp_var is failed %ld", ret);
            }
        }

    }
}
#endif //CONFIG_ENABLE_LINUX_REG

void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
{
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    hdd_config_t *cfg_param;

    if (NULL == pHddCtx)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                "HDD Context is null !!");
        return ;
    }

    cfg_param = pHddCtx->cfg_ini;

    if (NULL == cfg_param)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                "cfg_params not available !!");
        return ;
    }

    if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
        pHddCtx->disable_dfs_flag == TRUE)
    {
       /*New country doesn't support DFS */
       sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
    }

}

#ifdef WLAN_FEATURE_RMC
static int hdd_parse_setrmcenable_command(tANI_U8 *pValue, tANI_U8 *pRmcEnable)
{
    tANI_U8 *inPtr = pValue;
    int tempInt;
    int v = 0;
    char buf[32];
    *pRmcEnable = 0;

    inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
    /*no argument after the command*/
    if (NULL == inPtr)
    {
        return 0;
    }

    /*no space after the command*/
    else if (SPACE_ASCII_VALUE != *inPtr)
    {
        return 0;
    }

    /*removing empty spaces*/
    while ((SPACE_ASCII_VALUE  == *inPtr) && ('\0' !=  *inPtr)) inPtr++;

    /*no argument followed by spaces*/
    if ('\0' == *inPtr)
    {
        return 0;
    }

    /* getting the first argument which enables or disables RMC
         * for input IP v4 address*/
    sscanf(inPtr, "%31s ", buf);
    v = kstrtos32(buf, 10, &tempInt);
    if ( v < 0)
    {
       return -EINVAL;
    }

    *pRmcEnable = tempInt;

    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
       "ucRmcEnable: %d", *pRmcEnable);

    return 0;
}

/* Function header left blank Intentionally */
static int hdd_parse_setrmcactionperiod_command(tANI_U8 *pValue,
           tANI_U32 *pActionPeriod)
{
    tANI_U8 *inPtr = pValue;
    int tempInt;
    int v = 0;
    char buf[32];
    *pActionPeriod = 0;

    inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
    /*no argument after the command*/
    if (NULL == inPtr)
    {
        return -EINVAL;
    }

    /*no space after the command*/
    else if (SPACE_ASCII_VALUE != *inPtr)
    {
        return -EINVAL;
    }

    /*removing empty spaces*/
    while ((SPACE_ASCII_VALUE  == *inPtr) && ('\0' !=  *inPtr)) inPtr++;

    /*no argument followed by spaces*/
    if ('\0' == *inPtr)
    {
        return 0;
    }

    /* getting the first argument which enables or disables RMC
         * for input IP v4 address*/
    sscanf(inPtr, "%31s ", buf);
    v = kstrtos32(buf, 10, &tempInt);
    if ( v < 0)
    {
       return -EINVAL;
    }

    /* Range checking for passed paramter */
    if (tempInt < WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN ||
        tempInt > WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX)
    {
       return -EINVAL;
    }

    *pActionPeriod = tempInt;

    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
       "uActionPeriod: %d", *pActionPeriod);

    return 0;
}

/**
 * hdd_set_vowifi_mode() - Process VOWIFI command.
 * @hdd_ctx: context handler
 * @enable: Value to be sent as a part of the VOWIFI command
 *
 * Invoke the SME api if station is connected in 2.4 GHz band.
 * Also start split scan if VOWIFIMODE and dynamic split scan
 * both are enabled.

 * Return: void
 */
void hdd_set_vowifi_mode(hdd_context_t *hdd_ctx, bool enable)
{
    tANI_U8 sta_chan;

    if (!hdd_ctx->cfg_ini) {
        hddLog(LOGE, "cfg_ini got NULL");
        return;
    }

    sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);

    if (CSR_IS_CHANNEL_24GHZ(sta_chan))
        sme_set_vowifi_mode(hdd_ctx->hHal, enable);
    else
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
               "VoWiFi command rejected as not connected in 2.4GHz");

    if (enable && hdd_ctx->cfg_ini->dynSplitscan) {
        hdd_ctx->is_vowifi_enabled = true;
        hdd_ctx->issplitscan_enabled = TRUE;
        sme_enable_disable_split_scan(hdd_ctx->hHal,
                    hdd_ctx->cfg_ini->nNumStaChanCombinedConc,
                    hdd_ctx->cfg_ini->nNumP2PChanCombinedConc);
    } else {
        hdd_ctx->is_vowifi_enabled = false;
    }
}

/* Function header left blank Intentionally */
static int hdd_parse_setrmcrate_command(tANI_U8 *pValue,
           tANI_U32 *pRate, tTxrateinfoflags *pTxFlags)
{
    tANI_U8 *inPtr = pValue;
    int tempInt;
    int v = 0;
    char buf[32];
    *pRate = 0;
    *pTxFlags = 0;

    inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
    /*no argument after the command*/
    if (NULL == inPtr)
    {
        return -EINVAL;
    }

    /*no space after the command*/
    else if (SPACE_ASCII_VALUE != *inPtr)
    {
        return -EINVAL;
    }

    /*removing empty spaces*/
    while ((SPACE_ASCII_VALUE  == *inPtr) && ('\0' !=  *inPtr)) inPtr++;

    /*no argument followed by spaces*/
    if ('\0' == *inPtr)
    {
        return 0;
    }

    /*
     * getting the first argument which sets multicast rate.
     */
    sscanf(inPtr, "%31s ", buf);
    v = kstrtos32(buf, 10, &tempInt);
    if ( v < 0)
        {
       return -EINVAL;
        }

    /*
     * Validate the multicast rate.
     */
    switch (tempInt)
        {
        default:
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
            "Unsupported rate: %d", tempInt);
            return -EINVAL;
        case 0:
        case 6:
        case 9:
        case 12:
        case 18:
        case 24:
        case 36:
        case 48:
        case 54:
            *pTxFlags = eHAL_TX_RATE_LEGACY;
            *pRate = tempInt * 10;
            break;
        case 65:
            *pTxFlags = eHAL_TX_RATE_HT20;
            *pRate = tempInt * 10;
            break;
        case 72:
            *pTxFlags = eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;
            *pRate = 722; /* fractional rate 72.2 Mbps */
            break;
    }

    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
       "Rate: %d", *pRate);

    return 0;
}

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

  \brief hdd_cfg80211_get_ibss_peer_info_cb() - Callback function for IBSS
  Peer Info request

  This is an asynchronous callback function from SME when the peer info
  is received

  \pUserData -> Adapter private data
  \pPeerInfoRsp -> Peer info response

  \return - 0 for success non-zero for failure
  --------------------------------------------------------------------------*/
static void
hdd_cfg80211_get_ibss_peer_info_cb(v_VOID_t *pUserData, v_VOID_t *pPeerInfoRsp)
{
   hdd_adapter_t *pAdapter = (hdd_adapter_t *)pUserData;
   tSirPeerInfoRspParams *pPeerInfo = (tSirPeerInfoRspParams *)pPeerInfoRsp;
   hdd_station_ctx_t *pStaCtx;
   v_U8_t   i;

   /*Sanity check*/
   if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
        {
      hddLog(LOGE,
         FL("invalid adapter or adapter has invalid magic"));
      return;
   }

   pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
   if (NULL != pStaCtx && NULL != pPeerInfo &&
       eHAL_STATUS_SUCCESS == pPeerInfo->status)
   {
      pStaCtx->ibss_peer_info.status = pPeerInfo->status;
      pStaCtx->ibss_peer_info.numIBSSPeers = pPeerInfo->numPeers;

      /* Paranoia check */
      if (pPeerInfo->numPeers < HDD_MAX_NUM_IBSS_STA)
      {
         for (i = 0; i < pPeerInfo->numPeers; i++)
         {
            memcpy(&pStaCtx->ibss_peer_info.ibssPeerList[i],
                   &pPeerInfo->peerInfoParams[i],
                   sizeof(hdd_ibss_peer_info_params_t));
         }
         hddLog(LOG1,
            FL("Peer Info copied in HDD"));
      }
      else
      {
         hddLog(LOGE,
               FL(" Number of peers %d returned is more than limit %d"),
               pPeerInfo->numPeers, HDD_MAX_NUM_IBSS_STA);
      }
   }
   else
   {
      hddLog(LOG1,
           FL("peerInfo returned is NULL"));
   }

   complete(&pAdapter->ibss_peer_info_comp);
}

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

  \brief hdd_cfg80211_get_ibss_peer_info_all() -

  Request function to get IBSS peer info from lower layers

  \pAdapter -> Adapter context

  \return - 0 for success non-zero for failure
  --------------------------------------------------------------------------*/
static
VOS_STATUS hdd_cfg80211_get_ibss_peer_info_all(hdd_adapter_t *pAdapter)
{
   tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
   long status;
   VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;

   INIT_COMPLETION(pAdapter->ibss_peer_info_comp);

   retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
                                    hdd_cfg80211_get_ibss_peer_info_cb,
                                    VOS_TRUE, 0xFF);

   if (VOS_STATUS_SUCCESS == retStatus)
   {
      status = wait_for_completion_interruptible_timeout
               (&pAdapter->ibss_peer_info_comp,
                msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));

      /* status will be 0 if timed out */
      if (status <= 0)
      {
         hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
                __func__, status);
         retStatus = VOS_STATUS_E_FAILURE;
         return retStatus;
      }
   }
   else
   {
      hddLog(VOS_TRACE_LEVEL_WARN,
             "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
   }

   return retStatus;
}

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

  \brief hdd_cfg80211_get_ibss_peer_info() -

  Request function to get IBSS peer info from lower layers

  \pAdapter -> Adapter context
  \staIdx -> Sta index for which the peer info is requested

  \return - 0 for success non-zero for failure
  --------------------------------------------------------------------------*/
static VOS_STATUS
hdd_cfg80211_get_ibss_peer_info(hdd_adapter_t *pAdapter, v_U8_t staIdx)
{
    long status;
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;

    INIT_COMPLETION(pAdapter->ibss_peer_info_comp);

    retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
                                     hdd_cfg80211_get_ibss_peer_info_cb,
                                     VOS_FALSE, staIdx);

    if (VOS_STATUS_SUCCESS == retStatus)
    {
       status = wait_for_completion_interruptible_timeout
                (&pAdapter->ibss_peer_info_comp,
                msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));

       /* status = 0 on timeout */
       if (status <= 0)
       {
          hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
                  __func__, status);
          retStatus = VOS_STATUS_E_FAILURE;
          return retStatus;
       }
    }
    else
    {
       hddLog(VOS_TRACE_LEVEL_WARN,
              "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
    }

    return retStatus;
}

/* Function header left blank Intentionally */
VOS_STATUS
hdd_parse_get_ibss_peer_info(tANI_U8 *pValue, v_MACADDR_t *pPeerMacAddr)
{
    tANI_U8 *inPtr = pValue;
    inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);

    /*no argument after the command*/
    if (NULL == inPtr)
    {
        return VOS_STATUS_E_FAILURE;;
    }

    /*no space after the command*/
    else if (SPACE_ASCII_VALUE != *inPtr)
    {
        return VOS_STATUS_E_FAILURE;;
    }

    /*removing empty spaces*/
    while ((SPACE_ASCII_VALUE  == *inPtr) && ('\0' !=  *inPtr) ) inPtr++;

    /*no argument followed by spaces*/
    if ('\0' == *inPtr)
    {
        return VOS_STATUS_E_FAILURE;;
    }

    /*getting the first argument ie the peer mac address */
    if (inPtr[2] != ':' || inPtr[5] != ':' || inPtr[8] != ':' ||
        inPtr[11] != ':' || inPtr[14] != ':')
    {
       return VOS_STATUS_E_FAILURE;;
    }
    sscanf(inPtr, "%2x:%2x:%2x:%2x:%2x:%2x",
                  (unsigned int *)&pPeerMacAddr->bytes[0],
                  (unsigned int *)&pPeerMacAddr->bytes[1],
                  (unsigned int *)&pPeerMacAddr->bytes[2],
                  (unsigned int *)&pPeerMacAddr->bytes[3],
                  (unsigned int *)&pPeerMacAddr->bytes[4],
                  (unsigned int *)&pPeerMacAddr->bytes[5]);

    /* The command buffer seems to be fine */
    return VOS_STATUS_SUCCESS;
}

/* Function header left blank Intentionally */
static int hdd_parse_set_ibss_oui_data_command(tANI_U8 *command, tANI_U8 *ie,
                                               tANI_U32 limit)
{
   tANI_U8 len;
   tANI_U8 data;

   /* skip white space */
   while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
   {
      command++;
      limit--;
   }

   /* skip element id  and element length */
   len = 2;

   /* extract oui */
   while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
          (limit > 1))
   {
      /* Convert ASCII to decimal */
      data = ((*command -'0') << 4) | (*(command + 1) - '0');
      ie[len++] = data;
      command += 2;
      limit -= 2;
   }

   /* skip white space */
   while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
   {
      command++;
      limit--;
   }

   /* extract data */
   while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
         (limit > 1))
   {
      /* Convert ASCII to decimal */
      data = ((*command -'0') << 4) | (*(command + 1) - '0');
      ie[len++] = data;
      command += 2;
      limit -= 2;
   }

   /* fill element id and element length */
   ie[0] = IE_EID_VENDOR;
   ie[1] = len - 2;

   return len;
}

static tANI_U32 hdd_find_ibss_wpa_ie_pos(tANI_U8 *addIePtr, tANI_U32 addIeLen)
{
   tANI_U32 ieLenPresent = 0;
   int left = addIeLen;
   v_U8_t *ptr = addIePtr;
   v_U8_t elem_id,elem_len;

   while(left >= 2)
   {
      elem_id  =  ptr[0];
      elem_len =  ptr[1];
      left -= 2;
      if(elem_len > left)
      {
         hddLog(LOGE,
             FL("****Invalid elem_len=%d left=%d*****"),
                                           elem_len,left);
         return 0;
      }
      if ((elem_id == IE_EID_VENDOR) &&
               (left >= WPA_OUI_TYPE_SIZE))
      {
         if (!memcmp(&ptr[2], WPA_OUI_TYPE,
                          WPA_OUI_TYPE_SIZE))
         {
             ieLenPresent += elem_len + 2;
             return ieLenPresent;
         }
      }
      ieLenPresent += (elem_len + 2);
      left -= elem_len;
      ptr += (elem_len + 2);
    }
    return 0;
}

#endif /* WLAN_FEATURE_RMC */

#ifdef FEATURE_WLAN_BATCH_SCAN

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

  \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
                                               input string

  This function extracts assigned integer from string in below format:
  "STRING=10" : extracts integer 10 from this string

  \param  - pInPtr Pointer to input string
  \param  - base  Base for string to int conversion(10 for decimal 16 for hex)
  \param  - pOutPtr Pointer to variable in which extracted integer needs to be
            assigned
  \param  - pLastArg to tell whether it is last arguement in input string or
            not

  \return - NULL for failure cases
            pointer to next arguement in input string for success cases
  --------------------------------------------------------------------------*/
static tANI_U8 *
hdd_extract_assigned_int_from_str
(
    tANI_U8 *pInPtr,
    tANI_U8 base,
    tANI_U32 *pOutPtr,
    tANI_U8 *pLastArg
)
{
    int tempInt;
    int v = 0;
    char buf[32];
    int val = 0;
    *pLastArg = FALSE;

    pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
    if (NULL == pInPtr)
    {
        return NULL;
    }

    pInPtr++;

    while ((SPACE_ASCII_VALUE  == *pInPtr) && ('\0' !=  *pInPtr)) pInPtr++;

    val = sscanf(pInPtr, "%32s ", buf);
    if (val < 0 && val > strlen(pInPtr))
    {
        return NULL;
    }
    pInPtr += val;
    v = kstrtos32(buf, base, &tempInt);
    if (v < 0)
    {
        return NULL;
    }
    if (tempInt < 0)
    {
        tempInt = 0;
    }
    *pOutPtr = tempInt;

    pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
    if (NULL == pInPtr)
    {
        *pLastArg = TRUE;
        return NULL;
    }
    while ((SPACE_ASCII_VALUE  == *pInPtr) && ('\0' !=  *pInPtr)) pInPtr++;

    return pInPtr;
}

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

  \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
                                                input string

  This function extracts assigned character from string in below format:
  "STRING=A" : extracts char 'A' from this string

  \param  - pInPtr Pointer to input string
  \param  - pOutPtr Pointer to variable in which extracted char needs to be
            assigned
  \param  - pLastArg to tell whether it is last arguement in input string or
            not

  \return - NULL for failure cases
            pointer to next arguement in input string for success cases
  --------------------------------------------------------------------------*/
static tANI_U8 *
hdd_extract_assigned_char_from_str
(
    tANI_U8 *pInPtr,
    tANI_U8 *pOutPtr,
    tANI_U8 *pLastArg
)
{
    *pLastArg = FALSE;

    pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
    if (NULL == pInPtr)
    {
        return NULL;
    }

    pInPtr++;

    while ((SPACE_ASCII_VALUE  == *pInPtr) && ('\0' !=  *pInPtr)) pInPtr++;

    *pOutPtr = *pInPtr;

    pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
    if (NULL == pInPtr)
    {
        *pLastArg = TRUE;
        return NULL;
    }
    while ((SPACE_ASCII_VALUE  == *pInPtr) && ('\0' !=  *pInPtr)) pInPtr++;

    return pInPtr;
}


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

  \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command

  This function parses set batch scan command in below format:
  WLS_BATCHING_SET <space> followed by below arguements
  "SCANFREQ=XX"   : Optional defaults to 30 sec
  "MSCAN=XX"      : Required number of scans to attempt to batch
  "BESTN=XX"      : Best Network (RSSI) defaults to 16
  "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
                    A. implies  only 5 GHz , B. implies only 2.4GHz
  "RTT=X"         : optional defaults to 0
  returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
  error

  For example input commands:
  1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
     translated into set batch scan with following parameters:
     a) Frequence 60 seconds
     b) Batch 10 scans together
     c) Best RSSI to be 20
     d) 5GHz band only
     e) RTT is equal to 0

  \param  - pValue Pointer to input channel list
  \param  - pHddSetBatchScanReq Pointer to HDD batch scan request structure

  \return - 0 for success non-zero for failure

  --------------------------------------------------------------------------*/
static int
hdd_parse_set_batchscan_command
(
    tANI_U8 *pValue,
    tSirSetBatchScanReq *pHddSetBatchScanReq
)
{
    tANI_U8 *inPtr = pValue;
    tANI_U8 val = 0;
    tANI_U8 lastArg = 0;
    tANI_U32 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
    tANI_U32 nMscan;
    tANI_U32 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
    tANI_U8  ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
    tANI_U32 nRtt = 0;
    tANI_U32 temp;

    /*go to space after WLS_BATCHING_SET command*/
    inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
    /*no argument after the command*/
    if (NULL == inPtr)
    {
        return -EINVAL;
    }

    /*no space after the command*/
    else if (SPACE_ASCII_VALUE != *inPtr)
    {
        return -EINVAL;
    }

    /*removing empty spaces*/
    while ((SPACE_ASCII_VALUE  == *inPtr) && ('\0' !=  *inPtr)) inPtr++;

    /*no argument followed by spaces*/
    if ('\0' == *inPtr)
    {
        return -EINVAL;
    }

    /*check and parse SCANFREQ*/
    if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
    {
        inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
                    &temp, &lastArg);

        if (0 != temp)
        {
           nScanFreq = temp;
        }

        if ( (NULL == inPtr) || (TRUE == lastArg))
        {
            return -EINVAL;
        }
    }

    /*check and parse MSCAN*/
    if ((strncmp(inPtr, "MSCAN", 5) == 0))
    {
        inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
                    &nMscan, &lastArg);

        if (0 == nMscan)
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "invalid MSCAN=%d", nMscan);
            return -EINVAL;
        }

        if (TRUE == lastArg)
        {
            goto done;
        }
        else if (NULL == inPtr)
        {
            return -EINVAL;
        }
    }
    else
    {
        return -EINVAL;
    }

    /*check and parse BESTN*/
    if ((strncmp(inPtr, "BESTN", 5) == 0))
    {
        inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
                    &temp, &lastArg);

        if (0 != temp)
        {
           nBestN = temp;
        }

        if (TRUE == lastArg)
        {
            goto done;
        }
        else if (NULL == inPtr)
        {
            return -EINVAL;
        }
    }

    /*check and parse CHANNEL*/
    if ((strncmp(inPtr, "CHANNEL", 7) == 0))
    {
        inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);

        if (('A' == val) || ('a' == val))
        {
            ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
        }
        else if (('B' == val) || ('b' == val))
        {
            ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
        }
        else
        {
            ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
        }

        if (TRUE == lastArg)
        {
            goto done;
        }
        else if (NULL == inPtr)
        {
            return -EINVAL;
        }
    }

    /*check and parse RTT*/
    if ((strncmp(inPtr, "RTT", 3) == 0))
    {
        inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
                    &nRtt, &lastArg);
        if (TRUE == lastArg)
        {
            goto done;
        }
        if (NULL == inPtr)
        {
            return -EINVAL;
        }
    }


done:

    pHddSetBatchScanReq->scanFrequency = nScanFreq;
    pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
    pHddSetBatchScanReq->bestNetwork = nBestN;
    pHddSetBatchScanReq->rfBand = ucRfBand;
    pHddSetBatchScanReq->rtt = nRtt;

    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
      "Received WLS_BATCHING_SET with SCANFREQ=%d "
      "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
      pHddSetBatchScanReq->scanFrequency,
      pHddSetBatchScanReq->numberOfScansToBatch,
      pHddSetBatchScanReq->bestNetwork,
      pHddSetBatchScanReq->rfBand,
      pHddSetBatchScanReq->rtt);

    return 0;
}/*End of hdd_parse_set_batchscan_command*/

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

  \brief hdd_set_batch_scan_req_callback () - This function is called after
     receiving set batch scan response from FW and it saves set batch scan
     response data FW to HDD context and sets the completion event on
     which hdd_ioctl is waiting

  \param  - callbackContext Pointer to HDD adapter
  \param  - pRsp Pointer to set batch scan response data received from FW

  \return - nothing

  --------------------------------------------------------------------------*/
static void hdd_set_batch_scan_req_callback
(
    void *callbackContext,
    tSirSetBatchScanRsp *pRsp
)
{
    hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
    tSirSetBatchScanRsp *pHddSetBatchScanRsp;

    /*sanity check*/
    if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Invalid pAdapter magic", __func__);
        VOS_ASSERT(0);
        return;
    }
    pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;

    /*save set batch scan response*/
    pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;

    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
      "Received set batch scan rsp from FW with nScansToBatch=%d",
      pHddSetBatchScanRsp->nScansToBatch);

    pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
    complete(&pAdapter->hdd_set_batch_scan_req_var);

    return;
}/*End of hdd_set_batch_scan_req_callback*/


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

  \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
     info in hdd batch scan response queue

  \param  - pAdapter Pointer to hdd adapter
  \param  - pAPMetaInfo Pointer to access point meta info
  \param  - scanId scan ID of batch scan response
  \param  - isLastAp tells whether AP is last AP in batch scan response or not

  \return - nothing

  --------------------------------------------------------------------------*/
static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
      tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
{
    tHddBatchScanRsp *pHead;
    tHddBatchScanRsp *pNode;
    tHddBatchScanRsp *pPrev;
    tHddBatchScanRsp *pTemp;
    tANI_U8 ssidLen;

    /*head of hdd batch scan response queue*/
    pHead = pAdapter->pBatchScanRsp;

    pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
    if (NULL == pNode)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Could not allocate memory", __func__);
        VOS_ASSERT(0);
        return;
    }

    vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
        sizeof(pNode->ApInfo.bssid));
    ssidLen = strlen(pApMetaInfo->ssid);
    if (SIR_MAX_SSID_SIZE < ssidLen)
    {
       /*invalid scan result*/
       vos_mem_free(pNode);
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
          "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
       return;
    }
    vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
    /*null terminate ssid*/
    pNode->ApInfo.ssid[ssidLen] = '\0';
    pNode->ApInfo.ch = pApMetaInfo->ch;
    pNode->ApInfo.rssi = pApMetaInfo->rssi;
    pNode->ApInfo.age = pApMetaInfo->timestamp;
    pNode->ApInfo.batchId = scanId;
    pNode->ApInfo.isLastAp = isLastAp;

    pNode->pNext = NULL;
    if (NULL == pHead)
    {
         pAdapter->pBatchScanRsp = pNode;
    }
    else
    {
        pTemp = pHead;
        while (NULL != pTemp)
        {
            pPrev = pTemp;
            pTemp = pTemp->pNext;
        }
        pPrev->pNext = pNode;
    }

    return;
}/*End of hdd_populate_batch_scan_rsp_queue*/

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

  \brief hdd_batch_scan_result_ind_callback () - This function is called after
     receiving batch scan response indication from FW. It saves get batch scan
     response data in HDD batch scan response queue. This callback sets the
     completion event on which hdd_ioctl is waiting only after getting complete
     batch scan response data from FW

  \param  - callbackContext Pointer to HDD adapter
  \param  - pRsp Pointer to get batch scan response data received from FW

  \return - nothing

  --------------------------------------------------------------------------*/
static void hdd_batch_scan_result_ind_callback
(
    void *callbackContext,
    void *pRsp
)
{
    v_BOOL_t                     isLastAp;
    tANI_U32                     numApMetaInfo;
    tANI_U32                     numNetworkInScanList;
    tANI_U32                     numberScanList;
    tANI_U32                     nextScanListOffset;
    tANI_U32                     nextApMetaInfoOffset;
    hdd_adapter_t*               pAdapter;
    tpSirBatchScanList           pScanList;
    tpSirBatchScanNetworkInfo    pApMetaInfo;
    tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
    tSirSetBatchScanReq          *pReq;

    pAdapter = (hdd_adapter_t *)callbackContext;
    /*sanity check*/
    if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Invalid pAdapter magic", __func__);
        VOS_ASSERT(0);
        return;
    }

    /*initialize locals*/
    pReq = &pAdapter->hddSetBatchScanReq;
    pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
    isLastAp = FALSE;
    numApMetaInfo = 0;
    numNetworkInScanList = 0;
    numberScanList = 0;
    nextScanListOffset = 0;
    nextApMetaInfoOffset = 0;
    pScanList = NULL;
    pApMetaInfo = NULL;

    if ((NULL == pBatchScanRsp) || (NULL == pReq))
    {
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
            "%s: pBatchScanRsp is %pK pReq %pK", __func__, pBatchScanRsp, pReq);
            isLastAp = TRUE;
         goto done;
    }

    pAdapter->numScanList = numberScanList =  pBatchScanRsp->numScanLists;
    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
        "Batch scan rsp: numberScalList %d", numberScanList);

    if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
    {
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
             "%s: numberScanList %d", __func__, numberScanList);
         isLastAp = TRUE;
         goto done;
    }

    while (numberScanList)
    {
        pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
                                          nextScanListOffset);
        if (NULL == pScanList)
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
              "%s: pScanList is %pK", __func__, pScanList);
            isLastAp = TRUE;
           goto done;
        }
        numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
            "Batch scan rsp: numApMetaInfo %d scanId %d",
            numApMetaInfo, pScanList->scanId);

        if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
              "%s: numApMetaInfo %d", __func__, numApMetaInfo);
            isLastAp = TRUE;
           goto done;
        }

        /*Initialize next AP meta info offset for next scan list*/
        nextApMetaInfoOffset = 0;

        while (numApMetaInfo)
        {
            pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
                                                nextApMetaInfoOffset);
            if (NULL == pApMetaInfo)
            {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: pApMetaInfo is %pK", __func__, pApMetaInfo);
                isLastAp = TRUE;
                goto done;
            }
            /*calculate AP age*/
            pApMetaInfo->timestamp =
                pBatchScanRsp->timestamp - pApMetaInfo->timestamp;

            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
                      "%s: bssId "MAC_ADDRESS_STR
                      " ch %d rssi %d timestamp %d", __func__,
                      MAC_ADDR_ARRAY(pApMetaInfo->bssid),
                      pApMetaInfo->ch, pApMetaInfo->rssi,
                      pApMetaInfo->timestamp);

            /*mark last AP in batch scan response*/
            if ((TRUE == pBatchScanRsp->isLastResult) &&
                (1 == numberScanList) && (1 == numApMetaInfo))
            {
               isLastAp = TRUE;
            }

            mutex_lock(&pAdapter->hdd_batch_scan_lock);
            /*store batch scan repsonse in hdd queue*/
            hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
                pScanList->scanId, isLastAp);
            mutex_unlock(&pAdapter->hdd_batch_scan_lock);

            nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
            numApMetaInfo--;
        }

        nextScanListOffset +=  ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
                                + (sizeof(tSirBatchScanNetworkInfo)
                                * numNetworkInScanList));
        numberScanList--;
    }

done:

    /*notify hdd_ioctl only if complete batch scan rsp is received and it was
      requested from hdd_ioctl*/
    if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
        (TRUE == isLastAp))
    {
        pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
        complete(&pAdapter->hdd_get_batch_scan_req_var);
    }

    return;
}/*End of hdd_batch_scan_result_ind_callback*/

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

  \brief hdd_format_batch_scan_rsp () - This function formats batch scan
     response as per batch scan FR request format by putting proper markers

  \param  - pDest pointer to destination buffer
  \param  - cur_len current length
  \param  - tot_len total remaining size which can be written to user space
  \param  - pApMetaInfo Pointer to get batch scan response AP meta info
  \param  - pAdapter Pointer to HDD adapter

  \return - ret no of characters written

  --------------------------------------------------------------------------*/
static tANI_U32
hdd_format_batch_scan_rsp
(
    tANI_U8 *pDest,
    tANI_U32 cur_len,
    tANI_U32 tot_len,
    tHddBatchScanRsp *pApMetaInfo,
    hdd_adapter_t* pAdapter
)
{
   tANI_U32 ret = 0;
   tANI_U32 rem_len = 0;
   tANI_U8  temp_len = 0;
   tANI_U8  temp_total_len = 0;
   tANI_U8  temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
   tANI_U8  *pTemp = temp;

   /*Batch scan reponse needs to be returned to user space in
     following format:
     "scancount=X\n" where X is the number of scans in current batch
     batch
     "trunc\n" optional present if current scan truncated
     "bssid=XX:XX:XX:XX:XX:XX\n"
     "ssid=XXXX\n"
     "freq=X\n" frequency in Mhz
     "level=XX\n"
     "age=X\n" ms
     "dist=X\n" cm (-1 if not available)
     "errror=X\n" (-1if not available)
     "====\n" (end of ap marker)
     "####\n" (end of scan marker)
     "----\n" (end of results)*/
     /*send scan result in above format to user space based on
       available length*/
   /*The GET response may have more data than the driver can return in its
     buffer. In that case the buffer should be filled to the nearest complete
     scan, ending with "%%%%".Subsequent callsshould return the remaining data
     starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
     The final buffer should end with "----\n"*/

   /*sanity*/
   if (cur_len > tot_len)
   {
       VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
          "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
       return 0;
   }
   else
   {
      rem_len = (tot_len - cur_len);
   }

   /*end scan marker*/
   if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
   {
       temp_len = snprintf(pTemp, sizeof(temp), "####\n");
       pTemp += temp_len;
       temp_total_len += temp_len;
   }

   /*bssid*/
   temp_len = snprintf(pTemp, sizeof(temp),
                "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
                pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
                pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
                pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
   pTemp += temp_len;
   temp_total_len += temp_len;

   /*ssid*/
   temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
                 pApMetaInfo->ApInfo.ssid);
   pTemp += temp_len;
   temp_total_len += temp_len;

   /*freq*/
   temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
                 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
   pTemp += temp_len;
   temp_total_len += temp_len;

   /*level*/
   temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
                  pApMetaInfo->ApInfo.rssi);
   pTemp += temp_len;
   temp_total_len += temp_len;

   /*age*/
   temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
                  pApMetaInfo->ApInfo.age);
   pTemp += temp_len;
   temp_total_len += temp_len;

   /*dist*/
   temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
   pTemp += temp_len;
   temp_total_len += temp_len;

   /*error*/
   temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
   pTemp += temp_len;
   temp_total_len += temp_len;

   /*end AP marker*/
   temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
   pTemp += temp_len;
   temp_total_len += temp_len;

   /*last AP in batch scan response*/
   if(TRUE == pApMetaInfo->ApInfo.isLastAp)
   {
       /*end scan marker*/
       temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
       pTemp += temp_len;
       temp_total_len += temp_len;

       /*end batch scan result marker*/
       temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
       pTemp += temp_len;
       temp_total_len += temp_len;

   }

   if (temp_total_len < rem_len)
   {
       ret = temp_total_len + 1;
       strlcpy(pDest, temp, ret);
       pAdapter->isTruncated = FALSE;
   }
   else
   {
      pAdapter->isTruncated = TRUE;
      if (rem_len >= strlen("%%%%"))
      {
          ret = snprintf(pDest, sizeof(temp), "%%%%");
      }
      else
      {
          ret = 0;
      }
   }

   return ret;

}/*End of hdd_format_batch_scan_rsp*/

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

  \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
     buffer starting with head of hdd batch scan response queue

  \param - pAdapter Pointer to HDD adapter
  \param - pDest Pointer to user data buffer
  \param - cur_len current offset in user buffer
  \param - rem_len remaining  no of bytes in user buffer

  \return - number of bytes written in user buffer

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

tANI_U32 hdd_populate_user_batch_scan_rsp
(
    hdd_adapter_t* pAdapter,
    tANI_U8  *pDest,
    tANI_U32 cur_len,
    tANI_U32 rem_len
)
{
    tHddBatchScanRsp *pHead;
    tHddBatchScanRsp *pPrev;
    tANI_U32 len;

    pAdapter->isTruncated = FALSE;

    /*head of hdd batch scan response queue*/
    pHead = pAdapter->pBatchScanRsp;
    while (pHead)
    {
         len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
                   pAdapter);
         pDest += len;
         pDest--;
         cur_len += len;
         if(TRUE == pAdapter->isTruncated)
         {
              /*result is truncated return rest of scan rsp in next req*/
              cur_len = rem_len;
              break;
         }
         pPrev = pHead;
         pHead = pHead->pNext;
         pAdapter->pBatchScanRsp  = pHead;
         if (TRUE == pPrev->ApInfo.isLastAp)
         {
             pAdapter->prev_batch_id = 0;
         }
         else
         {
             pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
         }
         vos_mem_free(pPrev);
         pPrev = NULL;
   }

   return cur_len;
}/*End of hdd_populate_user_batch_scan_rsp*/

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

  \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
     scan response data from HDD queue to user space
     It does following in detail:
     a) if HDD has enough data in its queue then it 1st copies data to user
        space and then send get batch scan indication message to FW. In this
        case it does not wait on any event and batch scan response data will
        be populated in HDD response queue in MC thread context after receiving
        indication from FW
     b) else send get batch scan indication message to FW and wait on an event
        which will be set once HDD receives complete batch scan response from
        FW and then this function returns batch scan response to user space

  \param  - pAdapter Pointer to HDD adapter
  \param  - pPrivData Pointer to priv_data

  \return - 0 for success -EFAULT for failure

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

int hdd_return_batch_scan_rsp_to_user
(
    hdd_adapter_t* pAdapter,
    hdd_priv_data_t *pPrivData,
    tANI_U8 *command
)
{
    tANI_U8    *pDest;
    tANI_U32   count = 0;
    tANI_U32   len = 0;
    tANI_U32   cur_len = 0;
    tANI_U32   rem_len = 0;
    eHalStatus halStatus;
    unsigned long rc;
    tSirTriggerBatchScanResultInd *pReq;

    pReq = &pAdapter->hddTriggerBatchScanResultInd;
    pReq->param = 0;/*batch scan client*/
    pDest = (tANI_U8 *)(command + pPrivData->used_len);
    pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;

    cur_len = pPrivData->used_len;
    if (pPrivData->total_len > pPrivData->used_len)
    {
        rem_len = pPrivData->total_len - pPrivData->used_len;
    }
    else
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
            "%s: Invalid user data buffer total_len %d used_len %d",
            __func__, pPrivData->total_len, pPrivData->used_len);
        return -EFAULT;
    }

    mutex_lock(&pAdapter->hdd_batch_scan_lock);
    len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
                 cur_len, rem_len);
    mutex_unlock(&pAdapter->hdd_batch_scan_lock);

    /*enough scan result available in cache to return to user space or
      scan result needs to be fetched 1st from fw and then return*/
    if (len == cur_len)
    {
        pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
        halStatus = sme_TriggerBatchScanResultInd(
                        WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
                        pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
                        pAdapter);
        if ( eHAL_STATUS_SUCCESS == halStatus )
        {
            if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
            {
                INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
                rc = wait_for_completion_timeout(
                     &pAdapter->hdd_get_batch_scan_req_var,
                     msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
                if (0 >= rc)
                {
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                           "%s: wait on hdd_get_batch_scan_req_var failed %ld",
                             __func__, rc);
                    return -EFAULT;
                }
            }

            len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
                      "scancount=%u\n", pAdapter->numScanList);
            pDest += len;
            cur_len += len;

            mutex_lock(&pAdapter->hdd_batch_scan_lock);
            len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
                 cur_len, rem_len);
            mutex_unlock(&pAdapter->hdd_batch_scan_lock);

            count = 0;
            len = (len - pPrivData->used_len);
            pDest = (command + pPrivData->used_len);
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
               "NEW BATCH SCAN RESULT:");
            while(count < len)
            {
                printk("%c", *(pDest + count));
                count++;
            }
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
               "%s: copy %d data to user buffer", __func__, len);
            if (copy_to_user(pPrivData->buf, pDest, len))
            {
                VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 "%s: failed to copy data to user buffer", __func__);
                return -EFAULT;
            }
        }
        else
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "sme_GetBatchScanScan  returned failure halStatus %d",
                halStatus);
             return -EINVAL;
        }
    }
    else
    {
        count = 0;
        len = (len - pPrivData->used_len);
        pDest = (command + pPrivData->used_len);
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
            "REMAINING TRUNCATED BATCH SCAN RESULT:");
        while(count < len)
        {
            printk("%c", *(pDest + count));
            count++;
        }
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
           "%s: copy %d data to user buffer", __func__, len);
        if (copy_to_user(pPrivData->buf, pDest, len))
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
               "%s: failed to copy data to user buffer", __func__);
            return -EFAULT;
        }
    }

   return 0;
} /*End of hdd_return_batch_scan_rsp_to_user*/

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

  \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
     IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
     WLS_BATCHING VERSION
     WLS_BATCHING SET
     WLS_BATCHING GET
     WLS_BATCHING STOP

  \param  - pAdapter Pointer to HDD adapter
  \param  - pPrivdata Pointer to priv_data
  \param  - command Pointer to command

  \return - 0 for success -EFAULT for failure

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

int hdd_handle_batch_scan_ioctl
(
    hdd_adapter_t *pAdapter,
    hdd_priv_data_t *pPrivdata,
    tANI_U8 *command
)
{
    int ret = 0;
    hdd_context_t *pHddCtx;

    ENTER();

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    ret = wlan_hdd_validate_context(pHddCtx);
    if (ret)
    {
        goto exit;
    }

    if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
    {
         char    extra[32];
         tANI_U8 len = 0;
         tANI_U8 version = HDD_BATCH_SCAN_VERSION;

         if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
         {
             VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
              "%s: Batch scan feature is not supported by FW", __func__);
             ret = -EINVAL;
             goto exit;
         }

         len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
                   version);
         if (copy_to_user(pPrivdata->buf, &extra, len + 1))
         {
              VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 "%s: failed to copy data to user buffer", __func__);
              ret = -EFAULT;
              goto exit;
         }
         ret = HDD_BATCH_SCAN_VERSION;
    }
    else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
    {
         int                 status;
         tANI_U8             *value = (command + 16);
         eHalStatus          halStatus;
         unsigned long       rc;
         tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
         tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;

         if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
         {
              VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "%s: Batch scan feature is not supported by FW", __func__);
              ret = -EINVAL;
              goto exit;
         }

         if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
             (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
             (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
             (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
         {
             VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "Received WLS_BATCHING SET command in invalid mode %s (%d) "
                "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
                 hdd_device_modetoString(pAdapter->device_mode),
                 pAdapter->device_mode);
             ret = -EINVAL;
             goto exit;
         }

         status = hdd_parse_set_batchscan_command(value, pReq);
         if (status)
         {
             VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "Invalid WLS_BATCHING SET command");
             ret = -EINVAL;
             goto exit;
         }


         pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
         halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
                          pAdapter->sessionId, hdd_set_batch_scan_req_callback,
                          pAdapter);

         if ( eHAL_STATUS_SUCCESS == halStatus )
         {
             char extra[32];
             tANI_U8 len = 0;
             tANI_U8 mScan = 0;

             VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                "sme_SetBatchScanReq  returned success halStatus %d",
                halStatus);
             if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
             {
                 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
                 rc = wait_for_completion_timeout(
                      &pAdapter->hdd_set_batch_scan_req_var,
                      msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
                 if (0 == rc)
                 {
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                    "%s: Timeout waiting for set batch scan to complete",
                    __func__);
                    ret = -EINVAL;
                    goto exit;
                 }
             }
             if ( !pRsp->nScansToBatch )
             {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                    "%s: Received set batch scan failure response from FW",
                     __func__);
                ret = -EINVAL;
                goto exit;
             }
             /*As per the Batch Scan Framework API we should return the MIN of
               either MSCAN or the max # of scans firmware can cache*/
             mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);

             pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;

             VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "%s: request MSCAN %d response MSCAN %d ret %d",
                __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
             len = scnprintf(extra, sizeof(extra), "%d", mScan);
             if (copy_to_user(pPrivdata->buf, &extra, len + 1))
             {
                 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                    "%s: failed to copy MSCAN value to user buffer", __func__);
                 ret = -EFAULT;
                 goto exit;
             }
         }
         else
         {
             VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "sme_SetBatchScanReq  returned failure halStatus %d",
                halStatus);
             ret = -EINVAL;
             goto exit;
         }
    }
    else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
    {
         eHalStatus halStatus;
         tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
         pInd->param = 0;

         if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
         {
              VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "%s: Batch scan feature is not supported by FW", __func__);
              ret = -EINVAL;
              goto exit;
         }

         if (eHDD_BATCH_SCAN_STATE_STARTED !=  pAdapter->batchScanState)
         {
              VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                "Batch scan is not yet enabled batch scan state %d",
                pAdapter->batchScanState);
              ret = -EINVAL;
              goto exit;
         }

         mutex_lock(&pAdapter->hdd_batch_scan_lock);
         hdd_deinit_batch_scan(pAdapter);
         mutex_unlock(&pAdapter->hdd_batch_scan_lock);

         pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;

         halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
                          pAdapter->sessionId);
         if ( eHAL_STATUS_SUCCESS == halStatus )
         {
             ret = 0;
             VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                "sme_StopBatchScanInd  returned success halStatus %d",
                halStatus);
         }
         else
         {
             VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "sme_StopBatchScanInd  returned failure halStatus %d",
                halStatus);
             ret = -EINVAL;
             goto exit;
         }
    }
    else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
    {
          tANI_U32 remain_len;

          if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
          {
              VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "%s: Batch scan feature is not supported by FW", __func__);
              ret = -EINVAL;
              goto exit;
          }

          if (eHDD_BATCH_SCAN_STATE_STARTED !=  pAdapter->batchScanState)
          {
              VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                "Batch scan is not yet enabled could not return results"
                "Batch Scan state %d",
                pAdapter->batchScanState);
              ret = -EINVAL;
              goto exit;
          }

          pPrivdata->used_len = 16;
          remain_len = pPrivdata->total_len - pPrivdata->used_len;
          if (remain_len < pPrivdata->total_len)
          {
              /*Clear previous batch scan response data if any*/
              vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
          }
          else
          {
              VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "Invalid total length from user space can't fetch batch"
                " scan response total_len %d used_len %d remain len %d",
                pPrivdata->total_len, pPrivdata->used_len, remain_len);
              ret = -EINVAL;
              goto exit;
          }
          ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
    }

exit:
    EXIT();
    return ret;
}


#endif/*End of FEATURE_WLAN_BATCH_SCAN*/

#if  defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
/**
 * hdd_assign_handoff_src_reassoc - Set handoff source as REASSOC
 *                                  to Handoff request
 * @handoffInfo: Pointer to Handoff request
 * @src: enum of handoff_src
 * Return: None
 */
#ifndef QCA_WIFI_ISOC
static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
					*handoffInfo, handoff_src src)
{
	handoffInfo->src = src;
}
#else
static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
					*handoffInfo, handoff_src src)
{
}
#endif

/**
 * hdd_reassoc() - perform a user space-directed reassoc
 *
 * @pAdapter: Adapter upon which the command was received
 * @bssid: BSSID with which to reassociate
 * @channel: channel upon which to reassociate
 * @src:      The source for the trigger of this action
 *
 * Return: 0 for success non-zero for failure
 */
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
			const tANI_U8 channel, const handoff_src src)
{
	hdd_station_ctx_t *pHddStaCtx;
	tCsrHandoffRequest handoffInfo;
	hdd_context_t *pHddCtx = NULL;
	pHddCtx = WLAN_HDD_GET_CTX(pAdapter);

	pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

	/* if not associated, no need to proceed with reassoc */
	if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
		hddLog(LOG1, FL("Not associated"));
		return -EINVAL;
	}

	/* if the target bssid is same as currently associated AP,
	   then no need to proceed with reassoc */
	if (!memcmp(bssid, pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr))) {
		hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
		return -EINVAL;
	}

	/* Check channel number is a valid channel number */
	if (VOS_STATUS_SUCCESS !=
		wlan_hdd_validate_operation_channel(pAdapter, channel)) {
		hddLog(LOGE, FL("Invalid Channel %d"), channel);
		return -EINVAL;
	}

	/* Proceed with reassoc */
	handoffInfo.channel = channel;
	hdd_assign_handoff_src_reassoc(&handoffInfo, src);
	memcpy(handoffInfo.bssid, bssid, sizeof(tSirMacAddr));
	sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
	return 0;
}
#else
int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
			const tANI_U8 channel, const handoff_src src)
{
	return -EPERM;
}
#endif

/**
 * hdd_parse_reassoc_v1() - parse version 1 of the REASSOC command
 *     This function parses the v1 REASSOC command with the format
 *     REASSOC xx:xx:xx:xx:xx:xx CH where "xx:xx:xx:xx:xx:xx" is the
 *     Hex-ASCII representation of the BSSID and CH is the ASCII
 *     representation of the channel. For example
 *     REASSOC 00:0a:0b:11:22:33 48
 *
 * @pAdapter: Adapter upon which the command was received
 * @command: ASCII text command that was received
 *
 * Return: 0 for success non-zero for failure
 */
static int
hdd_parse_reassoc_v1(hdd_adapter_t *pAdapter, const char *command)
{
	tANI_U8 channel = 0;
	tSirMacAddr bssid;
	int ret;

	ret = hdd_parse_reassoc_command_v1_data(command, bssid, &channel);
	if (ret)
		hddLog(LOGE, FL("Failed to parse reassoc command data"));
	else
		ret = hdd_reassoc(pAdapter, bssid, channel, REASSOC);

	return ret;
}

/**
 * hdd_parse_reassoc_v2() - parse version 2 of the REASSOC command
 *     This function parses the v2 REASSOC command with the format
 *     REASSOC <android_wifi_reassoc_params>
 *
 * @pAdapter: Adapter upon which the command was received
 * @command: command that was received, ASCII command followed
 *                    by binary data
 * @total_len: Total length of the command received
 *
 * Return: 0 for success non-zero for failure
 */
static int
hdd_parse_reassoc_v2(hdd_adapter_t *pAdapter, const char *command,
		     int total_len)
{
	struct android_wifi_reassoc_params params;
	tSirMacAddr bssid;
	int ret;

	if (total_len < sizeof(params) + 8) {
		hddLog(LOGE, FL("Invalid command length"));
		return -EINVAL;
	}

	/* The params are located after "REASSOC " */
	memcpy(&params, command + 8, sizeof(params));

	if (!mac_pton(params.bssid, (u8 *)&bssid)) {
		hddLog(LOGE, FL("MAC address parsing failed"));
		ret = -EINVAL;
	} else {
		ret = hdd_reassoc(pAdapter, bssid, params.channel, REASSOC);
	}
	return ret;
}

/**
 * hdd_parse_reassoc() - parse the REASSOC command
 *    There are two different versions of the REASSOC command.Version 1
 *    of the command contains a parameter list that is ASCII characters
 *    whereas version 2 contains a combination of ASCII and binary
 *    payload.  Determine if a version 1 or a version 2 command is being
 *    parsed by examining the parameters, and then dispatch the parser
 *    that is appropriate for the command.
 *
 *  @pAdapter: Adapter upon which the command was received
 *  @command: command that was received
 *  @total_len: Total length of the command received
 *
 *  Return: 0 for success non-zero for failure
 */
static int
hdd_parse_reassoc(hdd_adapter_t *pAdapter, const char *command, int total_len)
{
	int ret;

	/*
	 * both versions start with "REASSOC"
	 * v1 has a bssid and channel # as an ASCII string
	 *    REASSOC xx:xx:xx:xx:xx:xx CH
	 * v2 has a C struct
	 *    REASSOC <binary c struct>
	 *
	 * The first field in the v2 struct is also the bssid in ASCII.
	 * But in the case of a v2 message the BSSID is NUL-terminated.
	 * Hence we can peek at that offset to see if this is V1 or V2
	 * REASSOC xx:xx:xx:xx:xx:xx*
	 *           1111111111222222
	 * 01234567890123456789012345
	 */

	if (total_len < 26) {
		hddLog(LOGE, FL("Invalid command (total_len=%d)"), total_len);
		return -EINVAL;
	}

	if (command[25])
		ret = hdd_parse_reassoc_v1(pAdapter, command);
	else
		ret = hdd_parse_reassoc_v2(pAdapter, command, total_len);

	return ret;
}
#endif  /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE FEATURE_WLAN_LFR */

struct bcn_miss_rate_priv {
	int bcn_miss_rate;
};

/**
 * get_bcn_miss_rate_cb() callback invoked on receiving beacon miss
 * rate from firmware
 * @status: Status of get beacon miss rate operation
 * @bcnMissRate: Beacon miss rate
 * @context: Context passed while registering callback
 *
 * This function is invoked by WDA layer on receiving
 * WDI_GET_BCN_MISS_RATE_RSP
 *
 * Return: None
 */
static void get_bcn_miss_rate_cb(VOS_STATUS status, int bcnMissRate,
				 void *context)
{
	struct hdd_request *request;
	struct bcn_miss_rate_priv *priv;

	request = hdd_request_get(context);
	if (!request) {
		hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
		return;
	}

	priv = hdd_request_priv(request);

	if (VOS_STATUS_SUCCESS == status)
		priv->bcn_miss_rate = bcnMissRate;
	else
		hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));

	hdd_request_complete(request);
	hdd_request_put(request);

	return;
}

struct fw_stats_priv {
	tSirFwStatsResult *fw_stats;
};

/**
 * hdd_fw_stats_cb() callback invoked on receiving firmware stats
 * from firmware
 * @status: Status of get firmware stats operation
 * @fwStatsResult: firmware stats
 * @context: Context passed while registering callback
 *
 * This function is invoked by WDA layer on receiving
 * WDI_GET_FW_STATS_RSP
 *
 * Return: None
 */
static void hdd_fw_stats_cb(VOS_STATUS status,
     tSirFwStatsResult *fwStatsResult, void *context)
{
	struct hdd_request *request;
	struct fw_stats_priv *priv;

	hddLog(VOS_TRACE_LEVEL_INFO, FL("with status = %d"),status);

	request = hdd_request_get(context);
	if (!request) {
		hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
		return;
	}
	priv = hdd_request_priv(request);

	if (VOS_STATUS_SUCCESS == status)
		*priv->fw_stats = *fwStatsResult;
	else
		priv->fw_stats = NULL;

	hdd_request_complete(request);
	hdd_request_put(request);
	return;
}

/*
 *hdd_parse_setmaxtxpower_command() - HDD Parse MAXTXPOWER command
 *@pValue Pointer to MAXTXPOWER command
 *@pTxPower Pointer to tx power
 *
 *This function parses the MAXTXPOWER command passed in the format
 *  MAXTXPOWER<space>X(Tx power in dbm)
 *  For example input commands:
 *  1) MAXTXPOWER -8 -> This is translated into set max TX power to -8 dbm
 *  2) MAXTXPOWER -23 -> This is translated into set max TX power to -23 dbm
 *
 *return - 0 for success non-zero for failure
 */
static int hdd_parse_setmaxtxpower_command(unsigned char *pValue, int *pTxPower)
{
	unsigned char *inPtr = pValue;
	int tempInt;
	int v = 0;
	*pTxPower = 0;

	inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
	/* no argument after the command */
	if (NULL == inPtr)
		return -EINVAL;
	/* no space after the command */
	else if (SPACE_ASCII_VALUE != *inPtr)
		return -EINVAL;

	/* removing empty spaces */
	while ((SPACE_ASCII_VALUE  == *inPtr) && ('\0' !=  *inPtr)) inPtr++;

	/* no argument followed by spaces */
	if ('\0' == *inPtr)
		return 0;

	v = kstrtos32(inPtr, 10, &tempInt);

	/* Range checking for passed parameter */
	if ((tempInt < HDD_MIN_TX_POWER) || (tempInt > HDD_MAX_TX_POWER))
		return -EINVAL;

	*pTxPower = tempInt;

	VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
		"SETMAXTXPOWER: %d", *pTxPower);

	return 0;
}

static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
{
    int ret = 0;

    if (!pCfg || !command || !extra || !len)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
             "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
        ret = -EINVAL;
        return ret;
    }

    if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
    {
        *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
                (int)pCfg->nActiveMaxChnTime);
        return ret;
    }
    else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
    {
        *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
                (int)pCfg->nActiveMinChnTime);
        return ret;
    }
    else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
    {
        *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
                (int)pCfg->nPassiveMaxChnTime);
        return ret;
    }
    else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
    {
        *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
                (int)pCfg->nPassiveMinChnTime);
        return ret;
    }
    else if (strncmp(command, "GETDWELLTIME", 12) == 0)
    {
        *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
                (int)pCfg->nActiveMaxChnTime);
        return ret;
    }
    else
    {
        ret = -EINVAL;
    }

    return ret;
}

/**
 * hdd_btc_get_dwell_time() - Get BTC dwell time parameters
 * @pCfg: Pointer to HDD context
 * @command: ASCII text command that is received
 * @extra: Pointer to copy data sent to user
 * @n: size of 'extra' buffer
 * @len: length copied to 'extra' buffer
 *
 * Driver commands:
 * wpa_cli DRIVER BTCGETDWELLTIME ESCO MAX
 * wpa_cli DRIVER BTCGETDWELLTIME ESCO MIN
 * wpa_cli DRIVER BTCGETDWELLTIME SCO MAX
 * wpa_cli DRIVER BTCGETDWELLTIME SCO MIN
 *
 * Return: 0 for success non-zero for failure
 */

static int hdd_btc_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command,
                                  char *extra, tANI_U8 n, tANI_U8 *len)
{
    int ret = 0;

    if (!pCfg || !command || !extra || !len)
    {
        hddLog(LOGE, FL("Argument passsed for BTCGETDWELLTIME is incorrect"));
        ret = -EINVAL;
        return ret;
    }

    if (strncmp(command, "BTCGETDWELLTIME ESCO MAX", 24) == 0)
    {
        *len = scnprintf(extra, n, "BTCGETDWELLTIME ESCO MAX %u\n",
                (int)pCfg->max_chntime_btc_esco);
        return ret;
    }
    else if (strncmp(command, "BTCGETDWELLTIME ESCO MIN", 24) == 0)
    {
        *len = scnprintf(extra, n, "BTCGETDWELLTIME ESCO MIN %u\n",
                (int)pCfg->min_chntime_btc_esco);
        return ret;
    }
    else if (strncmp(command, "BTCGETDWELLTIME SCO MAX", 23) == 0)
    {
        *len = scnprintf(extra, n, "BTCGETDWELLTIME SCO MAX %u\n",
                (int)pCfg->max_chntime_btc_sco);
        return ret;
    }
    else if (strncmp(command, "BTCGETDWELLTIME SCO MIN", 23) == 0)
    {
        *len = scnprintf(extra, n, "BTCGETDWELLTIME SCO MIN %u\n",
                (int)pCfg->min_chntime_btc_sco);
        return ret;
    }
    else
    {
        ret = -EINVAL;
    }

    return ret;
}

int hdd_drv_cmd_validate(tANI_U8 *command, int len)
{
	if (command[len] != ' ')
		return -EINVAL;

	return 0;
}

#ifdef WLAN_AP_STA_CONCURRENCY

/**
 * hdd_conc_get_dwell_time() - Get concurrency dwell time parameters
 * @pCfg: Pointer to HDD context
 * @command: ASCII text command that is received
 * @extra: Pointer to copy data sent to user
 * @n: size of 'extra' buffer
 * @len: length copied to 'extra' buffer
 *
 * Driver commands:
 * wpa_cli DRIVER CONCGETDWELLTIME ACTIVE MAX
 * wpa_cli DRIVER CONCGETDWELLTIME ACTIVE MIN
 * wpa_cli DRIVER CONCGETDWELLTIME PASSIVE MAX
 * wpa_cli DRIVER CONCGETDWELLTIME PASSIVE MIN
 *
 * Return: 0 for success non-zero for failure
 */

static int hdd_conc_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command,
                                   char *extra, tANI_U8 n, tANI_U8 *len)
{
    int ret = 0;

    if (!pCfg || !command || !extra || !len)
    {
        hddLog(LOGE, FL("Argument passsed for CONCGETDWELLTIME is incorrect"));
        ret = -EINVAL;
        return ret;
    }

    if (strncmp(command, "CONCGETDWELLTIME ACTIVE MAX", 27) == 0)
    {
        *len = scnprintf(extra, n, "CONCGETDWELLTIME ACTIVE MAX %u\n",
                (int)pCfg->nActiveMaxChnTimeConc);
        return ret;
    }
    else if (strncmp(command, "CONCGETDWELLTIME ACTIVE MIN", 27) == 0)
    {
        *len = scnprintf(extra, n, "CONCGETDWELLTIME ACTIVE MIN %u\n",
                (int)pCfg->nActiveMinChnTimeConc);
        return ret;
    }
    else if (strncmp(command, "CONCGETDWELLTIME PASSIVE MAX", 28) == 0)
    {
        *len = scnprintf(extra, n, "CONCGETDWELLTIME PASSIVE MAX %u\n",
                (int)pCfg->nPassiveMaxChnTimeConc);
        return ret;
    }
    else if (strncmp(command, "CONCGETDWELLTIME PASSIVE MIN", 28) == 0)
    {
        *len = scnprintf(extra, n, "CONCGETDWELLTIME PASSIVE MIN %u\n",
                (int)pCfg->nPassiveMinChnTimeConc);
        return ret;
    }
    else
    {
        ret = -EINVAL;
    }

    return ret;
}

/**
 * hdd_conc_set_dwell_time() - Set concurrency dwell time parameters
 * @pAdapter: Adapter upon which the command was received
 * @command: ASCII text command that is received
 *
 * Driver commands:
 * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MAX <value>
 * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MIN <value>
 * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MAX <value
 * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MIN <value>
 *
 * Return: 0 for success non-zero for failure
 */

static int hdd_conc_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
{
    tHalHandle hHal;
    hdd_config_t *pCfg;
    tANI_U8 *value = command;
    int val = 0, ret = 0, temp = 0;
    tSmeConfigParams smeConfig;

    if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
        || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
    {
        hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME is incorrect"));
        ret = -EINVAL;
        return ret;
    }

    vos_mem_zero(&smeConfig, sizeof(smeConfig));
    sme_GetConfigParam(hHal, &smeConfig);

    if (strncmp(command, "CONCSETDWELLTIME ACTIVE MAX", 27) == 0 )
    {
        if (hdd_drv_cmd_validate(command, 27)) {
            hddLog(LOGE, FL("Invalid driver command"));
            return -EINVAL;
        }

        value = value + 28;
        temp = kstrtou32(value, 10, &val);
        if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MIN ||
                         val > CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MAX)
        {
            hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME ACTIVE MAX is incorrect"));
            ret = -EFAULT;
            return ret;
        }
        pCfg->nActiveMaxChnTimeConc = val;
        smeConfig.csrConfig.nActiveMaxChnTimeConc = val;
        sme_UpdateConfig(hHal, &smeConfig);
    }
    else if (strncmp(command, "CONCSETDWELLTIME ACTIVE MIN", 27) == 0)
    {
        if (hdd_drv_cmd_validate(command, 27)) {
            hddLog(LOGE, FL("Invalid driver command"));
            return -EINVAL;
        }

        value = value + 28;
        temp = kstrtou32(value, 10, &val);
        if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MIN  ||
                        val > CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MAX)
        {
            hddLog(LOGE, FL("Argument passsed for CONCSETDWELLTIME ACTIVE MIN is incorrect"));
            ret = -EFAULT;
            return ret;
        }
        pCfg->nActiveMinChnTimeConc = val;
        smeConfig.csrConfig.nActiveMinChnTimeConc = val;
        sme_UpdateConfig(hHal, &smeConfig);
    }
    else if (strncmp(command, "CONCSETDWELLTIME PASSIVE MAX", 28) == 0)
    {
        if (hdd_drv_cmd_validate(command, 28)) {
            hddLog(LOGE, FL("Invalid driver command"));
            return -EINVAL;
        }

        value = value + 29;
        temp = kstrtou32(value, 10, &val);
        if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MIN ||
                         val > CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MAX)
        {
            hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME PASSIVE MAX is incorrect"));
            ret = -EFAULT;
            return ret;
        }
        pCfg->nPassiveMaxChnTimeConc = val;
        smeConfig.csrConfig.nPassiveMaxChnTimeConc = val;
        sme_UpdateConfig(hHal, &smeConfig);
    }
    else if (strncmp(command, "CONCSETDWELLTIME PASSIVE MIN", 28) == 0)
    {
        if (hdd_drv_cmd_validate(command, 28)) {
            hddLog(LOGE, FL("Invalid driver command"));
            return -EINVAL;
        }

        value = value + 29;
        temp = kstrtou32(value, 10, &val);
        if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MIN ||
                         val > CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MAX )
        {
            hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME PASSIVE MIN is incorrect"));
            ret = -EFAULT;
            return ret;
        }
        pCfg->nPassiveMinChnTimeConc = val;
        smeConfig.csrConfig.nPassiveMinChnTimeConc = val;
        sme_UpdateConfig(hHal, &smeConfig);
    }
    else
    {
        ret = -EINVAL;
    }

    return ret;
}

#endif

/**
 * hdd_btc_set_dwell_time() - Set BTC dwell time parameters
 * @pAdapter: Adapter upon which the command was received
 * @command: ASCII text command that is received
 *
 * Driver commands:
 * wpa_cli DRIVER BTCSETDWELLTIME ESCO MAX <value>
 * wpa_cli DRIVER BTCSETDWELLTIME ESCO MIN <value>
 * wpa_cli DRIVER BTCSETDWELLTIME SCO MAX <value>
 * wpa_cli DRIVER BTCSETDWELLTIME SCO MIN <value>
 *
 * Return: 0 for success non-zero for failure
 */

static int hdd_btc_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
{
    tHalHandle hHal;
    hdd_config_t *pCfg;
    tANI_U8 *value = command;
    int val = 0, ret = 0, temp = 0;
    tSmeConfigParams smeConfig;

    if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
        || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
    {
        hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME is incorrect"));
        ret = -EINVAL;
        return ret;
    }

    vos_mem_zero(&smeConfig, sizeof(smeConfig));
    sme_GetConfigParam(hHal, &smeConfig);

    if (strncmp(command, "BTCSETDWELLTIME ESCO MAX", 24) == 0)
    {
        if (hdd_drv_cmd_validate(command, 24)) {
          hddLog(LOGE, FL("Invalid driver command"));
            return -EINVAL;
        }

        value = value + 25;
        temp = kstrtou32(value, 10, &val);
        if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MIN ||
                         val > CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MAX)
        {
            hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME ESCO MAX is incorrect"));
            ret = -EFAULT;
            return ret;
        }
        pCfg->max_chntime_btc_esco = val;
        smeConfig.csrConfig.max_chntime_btc_esco = val;
        sme_UpdateConfig(hHal, &smeConfig);
    }
    else if (strncmp(command, "BTCSETDWELLTIME ESCO MIN", 24) == 0)
    {
        if (hdd_drv_cmd_validate(command, 24)) {
            hddLog(LOGE, FL("Invalid driver command"));
            return -EINVAL;
        }

        value = value + 25;
        temp = kstrtou32(value, 10, &val);
        if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MIN ||
                        val > CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MAX)
        {
            hddLog(LOGE, FL("Argument passsed for BTCSETDWELLTIME ESCO MIN is incorrect"));
            ret = -EFAULT;
            return ret;
        }
        pCfg->min_chntime_btc_esco = val;
        smeConfig.csrConfig.min_chntime_btc_esco = val;
        sme_UpdateConfig(hHal, &smeConfig);
    }
    else if (strncmp(command, "BTCSETDWELLTIME SCO MAX", 23) == 0)
    {
        if (hdd_drv_cmd_validate(command, 23)) {
            hddLog(LOGE, FL("Invalid driver command"));
            return -EINVAL;
        }

        value = value + 24;
        temp = kstrtou32(value, 10, &val);
        if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MIN ||
                         val > CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MAX)
        {
            hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME SCO MAX is incorrect"));
            ret = -EFAULT;
            return ret;
        }
        pCfg->max_chntime_btc_sco = val;
        smeConfig.csrConfig.max_chntime_btc_sco = val;
        sme_UpdateConfig(hHal, &smeConfig);
    }
    else if (strncmp(command, "BTCSETDWELLTIME SCO MIN", 23) == 0)
    {
        if (hdd_drv_cmd_validate(command, 23)) {
            hddLog(LOGE, FL("Invalid driver command"));
            return -EINVAL;
        }

        value = value + 24;
        temp = kstrtou32(value, 10, &val);
        if (temp != 0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MIN ||
                         val > CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MAX)
        {
            hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME SCO MIN is incorrect"));
            ret = -EFAULT;
            return ret;
        }
        pCfg->min_chntime_btc_sco = val;
        smeConfig.csrConfig.min_chntime_btc_sco = val;
        sme_UpdateConfig(hHal, &smeConfig);
    }
    else
    {
        ret = -EINVAL;
    }

    return ret;
}

static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
{
    tHalHandle hHal;
    hdd_config_t *pCfg;
    tANI_U8 *value = command;
    int val = 0, ret = 0, temp = 0;
    tSmeConfigParams smeConfig;

    if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
        || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
         "%s: argument passed for SETDWELLTIME is incorrect", __func__);
        ret = -EINVAL;
        return ret;
    }

    vos_mem_zero(&smeConfig, sizeof(smeConfig));
    sme_GetConfigParam(hHal, &smeConfig);

    if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
    {
        if (hdd_drv_cmd_validate(command, 23))
            return -EINVAL;

        value = value + 24;
        temp = kstrtou32(value, 10, &val);
        if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
                         val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
             "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
            ret = -EFAULT;
            return ret;
        }
        pCfg->nActiveMaxChnTime = val;
        smeConfig.csrConfig.nActiveMaxChnTime = val;
        sme_UpdateConfig(hHal, &smeConfig);
    }
    else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
    {
        if (hdd_drv_cmd_validate(command, 23))
            return -EINVAL;

        value = value + 24;
        temp = kstrtou32(value, 10, &val);
        if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN  ||
                        val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
             "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
            ret = -EFAULT;
            return ret;
        }
        pCfg->nActiveMinChnTime = val;
        smeConfig.csrConfig.nActiveMinChnTime = val;
        sme_UpdateConfig(hHal, &smeConfig);
    }
    else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
    {
        if (hdd_drv_cmd_validate(command, 24))
            return -EINVAL;

        value = value + 25;
        temp = kstrtou32(value, 10, &val);
        if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
                         val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
             "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
            ret = -EFAULT;
            return ret;
        }
        pCfg->nPassiveMaxChnTime = val;
        smeConfig.csrConfig.nPassiveMaxChnTime = val;
        sme_UpdateConfig(hHal, &smeConfig);
    }
    else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
    {
        if (hdd_drv_cmd_validate(command, 24))
            return -EINVAL;

        value = value + 25;
        temp = kstrtou32(value, 10, &val);
        if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
                         val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
             "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
            ret = -EFAULT;
            return ret;
        }
        pCfg->nPassiveMinChnTime = val;
        smeConfig.csrConfig.nPassiveMinChnTime = val;
        sme_UpdateConfig(hHal, &smeConfig);
    }
    else if (strncmp(command, "SETDWELLTIME", 12) == 0)
    {
        if (hdd_drv_cmd_validate(command, 12))
            return -EINVAL;

        value = value + 13;
        temp = kstrtou32(value, 10, &val);
        if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
                         val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
             "%s: argument passed for SETDWELLTIME is incorrect", __func__);
            ret = -EFAULT;
            return ret;
        }
        pCfg->nActiveMaxChnTime = val;
        smeConfig.csrConfig.nActiveMaxChnTime = val;
        sme_UpdateConfig(hHal, &smeConfig);
    }
    else
    {
        ret = -EINVAL;
    }

    return ret;
}
static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
                                                                 tANI_U8 cmd_len)
{
    tANI_U8 *value;
    tANI_U8 fcc_constraint;

    eHalStatus status;
    int ret = 0;
    value =  cmd + cmd_len + 1;

    ret = kstrtou8(value, 10, &fcc_constraint);
    if ((ret < 0) || (fcc_constraint > 1)) {
       /*
        *  If the input value is greater than max value of datatype,
        *  then also it is a failure
        */
        hddLog(VOS_TRACE_LEVEL_ERROR,
        "%s: value out of range", __func__);
        return -EINVAL;
    }

    status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint,
                                     pHddCtx->scan_info.mScanPending);
    if (status != eHAL_STATUS_SUCCESS)
        ret = -EPERM;

    return ret;
}

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

  \brief hdd_enable_disable_ca_event() - When Host sends IOCTL (enabled),
         FW will send *ONE* CA ind to Host(even though it is duplicate).
         When Host send IOCTL (disable), FW doesn't perform any action.
         Whenever any change in CA *and* WLAN is in SAP/P2P-GO mode, FW
         sends CA ind to host. (regard less of IOCTL status)
  \param  - pHddCtx - HDD context
  \param  - command - command received from framework
  \param  - cmd_len - len of the command

  \return - 0 on success, appropriate error values on failure.

  --------------------------------------------------------------------------*/
int hdd_enable_disable_ca_event(hdd_context_t *pHddCtx, tANI_U8* command, tANI_U8 cmd_len)
{
   tANI_U8 set_value;
   int ret = 0;
   eHalStatus status;

   ret = wlan_hdd_validate_context(pHddCtx);
   if (0 != ret)
   {
       ret = -EINVAL;
       goto exit;
   }

   if (pHddCtx->cfg_ini->gOptimizeCAevent == 0)
   {
       hddLog(VOS_TRACE_LEVEL_ERROR, "Enable gOptimizeCAevent"
             " ini param to control channel avooidance indication");
       ret = 0;
       goto exit;
   }

   set_value = command[cmd_len + 1] - '0';
   status = sme_enableDisableChanAvoidIndEvent(pHddCtx->hHal, set_value);
   if (status != eHAL_STATUS_SUCCESS)
   {
       hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to send"
             " enableDisableChanAoidance command to SME\n", __func__);
       ret = -EINVAL;
   }

exit:
   return ret;
}

/**
 * wlan_hdd_fastreassoc_handoff_request() - Post Handoff request to SME
 * @pHddCtx: Pointer to the HDD context
 * @channel: channel to reassociate
 * @targetApBssid: Target AP/BSSID to reassociate
 *
 * Return: None
 */
#if defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) && !defined(QCA_WIFI_ISOC)
static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
				uint8_t channel, tSirMacAddr targetApBssid)
{
	tCsrHandoffRequest handoffInfo;
	handoffInfo.channel = channel;
	handoffInfo.src = FASTREASSOC;
	vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
	sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
}
#else
static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
				uint8_t channel, tSirMacAddr targetApBssid)
{
}
#endif

/**
 * csr_fastroam_neighbor_ap_event() - Function to trigger scan/roam
 * @pAdapter: Pointer to HDD adapter
 * @channel: Channel to scan/roam
 * @targetApBssid: BSSID to roam
 *
 * Return: None
 */
#ifdef QCA_WIFI_ISOC
static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
				uint8_t channel, tSirMacAddr targetApBssid)
{
	smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
			&targetApBssid[0], eSME_ROAM_TRIGGER_SCAN, channel);
}
#else
static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
				uint8_t channel, tSirMacAddr targetApBssid)
{
}
#endif

/**
 * wlan_hdd_handle_fastreassoc() - Handle fastreassoc command
 * @pAdapter: pointer to hdd adapter
 * @command: pointer to the command received
 *
 * Return: VOS_STATUS enum
 */
static VOS_STATUS wlan_hdd_handle_fastreassoc(hdd_adapter_t *pAdapter,
						uint8_t *command)
{
	tANI_U8 *value = command;
	tANI_U8 channel = 0;
	tSirMacAddr targetApBssid;
	hdd_station_ctx_t *pHddStaCtx = NULL;
	hdd_context_t *pHddCtx = NULL;
	int ret;
	tCsrRoamModifyProfileFields mod_profile_fields;
	uint32_t roam_id = 0;
	pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
	pHddCtx = WLAN_HDD_GET_CTX(pAdapter);

	/* if not associated, no need to proceed with reassoc */
	if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
		hddLog(LOG1, FL("Not associated!"));
		return eHAL_STATUS_FAILURE;
	}

	ret = hdd_parse_reassoc_command_v1_data(value, targetApBssid, &channel);
	if (ret) {
		hddLog(LOGE, FL("Failed to parse reassoc command data"));
		return eHAL_STATUS_FAILURE;
	}

	/* if the target bssid is same as currently associated AP,
	   then no need to proceed with reassoc */
	if (vos_mem_compare(targetApBssid,
				pHddStaCtx->conn_info.bssId,
				sizeof(tSirMacAddr))) {
		sme_GetModifyProfileFields(pHddCtx->hHal, pAdapter->sessionId,
						&mod_profile_fields);
		sme_RoamReassoc(pHddCtx->hHal, pAdapter->sessionId, NULL,
				mod_profile_fields, &roam_id, 1);
		hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
		return eHAL_STATUS_SUCCESS;
	}

	/* Check channel number is a valid channel number */
	if (VOS_STATUS_SUCCESS !=
		wlan_hdd_validate_operation_channel(pAdapter, channel)) {
		hddLog(LOGE, FL("Invalid Channel [%d]"), channel);
		return eHAL_STATUS_FAILURE;
	}

	/* Proceed with reassoc */
	wlan_hdd_fastreassoc_handoff_request(pHddCtx, channel, targetApBssid);

	/* Proceed with scan/roam */
	csr_fastroam_neighbor_ap_event(pAdapter, channel, targetApBssid);

	return eHAL_STATUS_SUCCESS;
}

/**
 * hdd_assign_reassoc_handoff - Set handoff source as REASSOC
 * @handoffInfo: Pointer to the csr Handoff Request.
 *
 * Return: None
 */
#ifndef QCA_WIFI_ISOC
static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
{
	handoffInfo->src = REASSOC;
}
#else
static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
{
}
#endif

/**
 * wlan_hdd_free_cache_channels() - Free the cache channels list
 * @hdd_ctx: Pointer to HDD context
 *
 * Return: None
 */

static void wlan_hdd_free_cache_channels(hdd_context_t *hdd_ctx)
{
	if(!hdd_ctx || !hdd_ctx->original_channels)
		return;

	mutex_lock(&hdd_ctx->cache_channel_lock);
	hdd_ctx->original_channels->num_channels = 0;
	vos_mem_free(hdd_ctx->original_channels->channel_info);
	hdd_ctx->original_channels->channel_info = NULL;
	vos_mem_free(hdd_ctx->original_channels);
	hdd_ctx->original_channels = NULL;
	mutex_unlock(&hdd_ctx->cache_channel_lock);
}

/**
 * hdd_alloc_chan_cache() - Allocate the memory to cache the channel
 * info for the channels received in command SET_DISABLE_CHANNEL_LIST
 * @hdd_ctx: Pointer to HDD context
 * @num_chan: Number of channels for which memory needs to
 * be allocated
 *
 * Return: 0 on success and error code on failure
 */

int hdd_alloc_chan_cache(hdd_context_t *hdd_ctx, int num_chan)
{
	hdd_ctx->original_channels =
			vos_mem_malloc(sizeof(struct hdd_cache_channels));
	if (!hdd_ctx->original_channels) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       "In %s, VOS_MALLOC_ERR", __func__);
		return -EINVAL;
	}
	hdd_ctx->original_channels->num_channels = num_chan;
	hdd_ctx->original_channels->channel_info =
					vos_mem_malloc(num_chan *
					sizeof(struct hdd_cache_channel_info));
	if (!hdd_ctx->original_channels->channel_info) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       "In %s, VOS_MALLOC_ERR", __func__);
		hdd_ctx->original_channels->num_channels = 0;
		vos_mem_free(hdd_ctx->original_channels);
		hdd_ctx->original_channels = NULL;
		return -ENOMEM;
	}
	return 0;

}


int hdd_parse_disable_chan_cmd(hdd_adapter_t *adapter, tANI_U8 *ptr)
{
	v_PVOID_t pvosGCtx = vos_get_global_context(VOS_MODULE_ID_HDD, NULL);
	hdd_context_t *hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, pvosGCtx);
	tANI_U8 *param;
	int j, tempInt, ret = 0, i, num_channels;
	int parsed_channels[MAX_CHANNEL];
	bool is_command_repeated = false;

	if (NULL == pvosGCtx) {
		hddLog(VOS_TRACE_LEVEL_FATAL,
		       "VOS Global Context is NULL");
		return -EINVAL;
	}

	if (NULL == hdd_ctx) {
		hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
		return -EINVAL;
	}

	param = strchr(ptr, ' ');
	/*no argument after the command*/
	if (NULL == param)
		return -EINVAL;

	/*no space after the command*/
	else if (SPACE_ASCII_VALUE != *param)
		return -EINVAL;

	param++;

	/*removing empty spaces*/
	while ((SPACE_ASCII_VALUE  == *param) && ('\0' !=  *param))
		param++;

	/*no argument followed by spaces*/
	if ('\0' == *param)
		return -EINVAL;

	/*getting the first argument ie the number of channels*/
	if (sscanf(param, "%d ", &tempInt) != 1) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       "%s: Cannot get number of channels from input",
		       __func__);
		return -EINVAL;
	}

	if (tempInt < 0 || tempInt > MAX_CHANNEL) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       "%s: Invalid Number of channel received", __func__);
		return -EINVAL;
	}

	hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
	       "%s: Number of channel to disable are: %d",
	       __func__, tempInt);

	if (!tempInt) {
		if (!wlan_hdd_restore_channels(hdd_ctx)) {
			/*
			 * Free the cache channels only when the command is
			 * received with num channels as 0
			 */
			wlan_hdd_free_cache_channels(hdd_ctx);
		}
		return 0;
	}

	mutex_lock(&hdd_ctx->cache_channel_lock);
	if (!hdd_ctx->original_channels) {
		if (hdd_alloc_chan_cache(hdd_ctx, tempInt)) {
			ret = -ENOMEM;
			goto mem_alloc_failed;
		}
	} else if (hdd_ctx->original_channels->num_channels != tempInt) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       "%s, Invalid No of channel provided in the list",
		       __func__);
			ret = -EINVAL;
			is_command_repeated = true;
			goto parse_failed;
	} else {
		is_command_repeated = true;
	}

	num_channels = tempInt;

	for (j = 0; j < num_channels; j++) {
		/*
		 * param pointing to the beginning of first space
		 * after number of channels
		 */
		param = strpbrk(param, " ");
		/*no channel list after the number of channels argument*/
		if (NULL == param) {
			hddLog(VOS_TRACE_LEVEL_ERROR,
			       "%s, Invalid No of channel provided in the list",
			       __func__);
			ret = -EINVAL;
			goto parse_failed;
		}

		param++;

		/*removing empty space*/
		while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
			param++;

		if ('\0' == *param) {
			hddLog(VOS_TRACE_LEVEL_ERROR,
			       "%s, No channel is provided in the list",
				__func__);
			ret = -EINVAL;
			goto parse_failed;

		}

		if (sscanf(param, "%d ", &tempInt) != 1) {
			hddLog(VOS_TRACE_LEVEL_ERROR,
			       "%s: Cannot read channel number",
			       __func__);
			ret = -EINVAL;
			goto parse_failed;

		}

		if (!IS_CHANNEL_VALID(tempInt)) {
			hddLog(VOS_TRACE_LEVEL_ERROR,
			       "%s: Invalid channel number received",
			       __func__);
			ret = -EINVAL;
			goto parse_failed;

		}

		hddLog(VOS_TRACE_LEVEL_INFO, "%s: channel[%d] = %d", __func__,
		       j, tempInt);

		parsed_channels[j] = tempInt;
	}

	/*extra arguments check*/
	param = strchr(param, ' ');
	if (NULL != param) {
		while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
			param++;

		if ('\0' !=  *param) {
			hddLog(VOS_TRACE_LEVEL_ERROR,
			       "%s: Invalid argument received", __func__);
			ret = -EINVAL;
			goto parse_failed;
		}
	}

	/*
	 * If command is received first time, cache the channels to
	 * be disabled else compare the channels received in the
	 * command with the cached channels, if channel list matches
	 * return success otherewise return failure.
	 */
	 if (!is_command_repeated)
		for (j = 0; j < num_channels; j++)
			hdd_ctx->original_channels->
					channel_info[j].channel_num =
							parsed_channels[j];
	else {
		for (i = 0; i < num_channels; i++) {
			for (j = 0; j < num_channels; j++)
				if (hdd_ctx->original_channels->
						channel_info[i].channel_num ==
							parsed_channels[j])
					break;
			if (j == num_channels) {
				ret = -EINVAL;
				goto parse_failed;
			}
		}
		ret = 0;
	}

mem_alloc_failed:
	mutex_unlock(&hdd_ctx->cache_channel_lock);
	EXIT();

	return ret;

parse_failed:
	mutex_unlock(&hdd_ctx->cache_channel_lock);
	if (!is_command_repeated)
		wlan_hdd_free_cache_channels(hdd_ctx);
	EXIT();
	return ret;

}

int hdd_get_disable_ch_list(hdd_context_t *hdd_ctx, tANI_U8 *buf,
			    uint32_t buf_len)
{
	struct hdd_cache_channel_info *ch_list;
	unsigned char i, num_ch;
	int len = 0;

	mutex_lock(&hdd_ctx->cache_channel_lock);
	if (hdd_ctx->original_channels &&
	    hdd_ctx->original_channels->num_channels &&
	    hdd_ctx->original_channels->channel_info) {
		num_ch = hdd_ctx->original_channels->num_channels;

		len = scnprintf(buf, buf_len, "%s %hhu",
				"GET_DISABLE_CHANNEL_LIST", num_ch);

		ch_list = hdd_ctx->original_channels->channel_info;

		for (i = 0; (i < num_ch) && (len < buf_len-1); i++) {
			len += scnprintf(buf + len, buf_len - len,
			" %d", ch_list[i].channel_num);
		}
	}
	mutex_unlock(&hdd_ctx->cache_channel_lock);

	return len;
}

static int hdd_driver_command(hdd_adapter_t *pAdapter,
                              hdd_priv_data_t *ppriv_data)
{
   hdd_priv_data_t priv_data;
   tANI_U8 *command = NULL;
   hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
   hdd_scaninfo_t *pScanInfo = NULL;
   int ret = 0;
   int status;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
   struct cfg80211_mgmt_tx_params params;
#endif

   ENTER();
   /*
    * Note that valid pointers are provided by caller
    */

   /* copy to local struct to avoid numerous changes to legacy code */
   priv_data = *ppriv_data;

   if (priv_data.total_len <= 0  ||
       priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
   {
       hddLog(VOS_TRACE_LEVEL_WARN,
              "%s:invalid priv_data.total_len(%d)!!!", __func__,
              priv_data.total_len);
       ret = -EINVAL;
       goto exit;
   }
   status = wlan_hdd_validate_context(pHddCtx);
   if (0 != status)
   {
       ret = -EINVAL;
       goto exit;
   }
   /* Allocate +1 for '\0' */
   command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
   if (!command)
   {
       hddLog(VOS_TRACE_LEVEL_ERROR,
              "%s: failed to allocate memory", __func__);
       ret = -ENOMEM;
       goto exit;
   }

   if (copy_from_user(command, priv_data.buf, priv_data.total_len))
   {
       ret = -EFAULT;
       goto exit;
   }

   /* Make sure the command is NUL-terminated */
   command[priv_data.total_len] = '\0';

   /* at one time the following block of code was conditional. braces
    * have been retained to avoid re-indenting the legacy code
    */
   {
       hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;

       VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);

       if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
       {
           MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                            TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
                            pAdapter->sessionId, (unsigned)
                            (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
                             *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
                             *(pHddCtx->p2pDeviceAddress.bytes+4)<<8  |
                             *(pHddCtx->p2pDeviceAddress.bytes+5))));
           if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
                                                           sizeof(tSirMacAddr)))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                  "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
           }
       }
       else if(strncmp(command, "SETBAND", 7) == 0)
       {
           tANI_U8 *ptr = command ;

           ret = hdd_drv_cmd_validate(command, 7);
           if (ret)
               goto exit;

           /* Change band request received */

           /* First 8 bytes will have "SETBAND " and
            * 9 byte will have band setting value */
           VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                    "%s: SetBandCommand Info  comm %s UL %d, TL %d", __func__, command, priv_data.used_len, priv_data.total_len);
           if(VOS_FTM_MODE != hdd_get_conparam())
           {
               /* Change band request received */
               ret = hdd_setBand_helper(pAdapter->dev, ptr);
               if(ret < 0)
                   VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                       "%s: failed to set band ret=%d", __func__, ret);
           }
       }
       else if(strncmp(command, "SETWMMPS", 8) == 0)
       {
           tANI_U8 *ptr = command;

           ret = hdd_drv_cmd_validate(command, 8);
           if (ret)
               goto exit;

           ret = hdd_wmmps_helper(pAdapter, ptr);
       }

       else if(strncmp(command, "TDLSSCAN", 8) == 0)
       {
           tANI_U8 *ptr  = command;

           ret = hdd_drv_cmd_validate(command, 8);
           if (ret)
               goto exit;

           ret = hdd_set_tdls_scan_type(pAdapter, ptr);
       }

       else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
       {
           char *country_code;

           ret = hdd_drv_cmd_validate(command, 7);
           if (ret)
               goto exit;

           country_code = command + 8;

           INIT_COMPLETION(pAdapter->change_country_code);
           hdd_checkandupdate_dfssetting(pAdapter, country_code);
#ifndef CONFIG_ENABLE_LINUX_REG
           hdd_checkandupdate_phymode(pAdapter, country_code);
#endif
           ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
                  (void *)(tSmeChangeCountryCallback)
                    wlan_hdd_change_country_code_callback,
                     country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
           if (eHAL_STATUS_SUCCESS == ret)
           {
               ret = wait_for_completion_interruptible_timeout(
                       &pAdapter->change_country_code,
                            msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
               if (0 >= ret)
               {
                   hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
                   __func__, ret);
               }
           }
           else
           {
               VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
                 "%s: SME Change Country code fail ret=%d", __func__, ret);
               ret = -EINVAL;
           }

       }
       /*
          command should be a string having format
          SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
       */
       else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
       {
           tANI_U8 *ptr = command;

           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      " Received Command to Set Preferred Channels for SAP in %s", __func__);

           ret = sapSetPreferredChannel(ptr);
       }

       else if (strncmp(command, "VOWIFIMODE", 10) == 0)
       {
           tANI_U8 *ptr;

           ret = hdd_drv_cmd_validate(command, 10);
           if (ret)
               goto exit;

           VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                   "Received Command for VOWIFI mode in %s", __func__);

           ptr = (tANI_U8*)command + 11;
           hdd_set_vowifi_mode(pHddCtx, *ptr - '0');
        }

       else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
       {
           int suspend = 0;
           tANI_U8 *ptr;

           ret = hdd_drv_cmd_validate(command, 14);
           if (ret)
               goto exit;

           ptr = (tANI_U8*)command + 15;

           suspend = *ptr - '0';
            MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                             TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
                             pAdapter->sessionId, suspend));
           hdd_set_wlan_suspend_mode(suspend);
       }
#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
       else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
       {
           tANI_U8 *value = command;
           tANI_S8 rssi = 0;
           tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
           eHalStatus status = eHAL_STATUS_SUCCESS;

           ret = hdd_drv_cmd_validate(command, 14);
           if (ret)
               goto exit;

           /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
           value = value + 15;

           /* Convert the value from ascii to integer */
           ret = kstrtos8(value, 10, &rssi);
           if (ret < 0)
           {
               /* If the input value is greater than max value of datatype, then also
                  kstrtou8 fails */
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
                      __func__,
                      CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
                      CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
               ret = -EINVAL;
               goto exit;
           }

           lookUpThreshold = abs(rssi);

           if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
               (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "Neighbor lookup threshold value %d is out of range"
                      " (Min: %d Max: %d)", lookUpThreshold,
                      CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
                      CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
               ret = -EINVAL;
               goto exit;
           }

           MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                            TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
                            pAdapter->sessionId, lookUpThreshold));
           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "%s: Received Command to Set Roam trigger"
                      " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);

           pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
           status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
           if (eHAL_STATUS_SUCCESS != status)
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Failed to set roam trigger, try again", __func__);
               ret = -EPERM;
               goto exit;
           }

           /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
           pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
           sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
       }
       else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
       {
           tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
           int rssi = (-1) * lookUpThreshold;
           char extra[32];
           tANI_U8 len = 0;
           MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                            TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
                            pAdapter->sessionId, lookUpThreshold));
           len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
           len = VOS_MIN(priv_data.total_len, len + 1);
           if (copy_to_user(priv_data.buf, &extra, len))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto exit;
           }
       }
       else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
       {
           tANI_U8 *value = command;
           tANI_U8 roamScanPeriod = 0;
           tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;

           ret = hdd_drv_cmd_validate(command, 17);
           if (ret)
               goto exit;

           /* input refresh period is in terms of seconds */
           /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
           value = value + 18;
           /* Convert the value from ascii to integer */
           ret = kstrtou8(value, 10, &roamScanPeriod);
           if (ret < 0)
           {
               /* If the input value is greater than max value of datatype, then also
                  kstrtou8 fails */
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
                      __func__,
                      (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
                      (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
               ret = -EINVAL;
               goto exit;
           }

           if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
               (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "Roam scan period value %d is out of range"
                      " (Min: %d Max: %d)", roamScanPeriod,
                      (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
                      (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
               ret = -EINVAL;
               goto exit;
              }
           MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                            TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
                            pAdapter->sessionId, roamScanPeriod));
           neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;

           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "%s: Received Command to Set roam scan period"
                      " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);

           pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
           sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
       }
       else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
       {
           tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
           char extra[32];
           tANI_U8 len = 0;

           MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                            TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
                            pAdapter->sessionId, nEmptyScanRefreshPeriod));
           len = scnprintf(extra, sizeof(extra), "%s %d",
                   "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
           /* Returned value is in units of seconds */
           len = VOS_MIN(priv_data.total_len, len + 1);
           if (copy_to_user(priv_data.buf, &extra, len)) {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto exit;
           }
       }
       else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
       {
           tANI_U8 *value = command;
           tANI_U8 roamScanRefreshPeriod = 0;
           tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;

           ret = hdd_drv_cmd_validate(command, 24);
           if (ret)
               goto exit;

           /* input refresh period is in terms of seconds */
           /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
           value = value + 25;

           /* Convert the value from ascii to integer */
           ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
           if (ret < 0)
           {
               /* If the input value is greater than max value of datatype, then also
                  kstrtou8 fails */
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
                      __func__,
                      (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
                      (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
               ret = -EINVAL;
               goto exit;
           }

           if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
               (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "Neighbor scan results refresh period value %d is out of range"
                      " (Min: %d Max: %d)", roamScanRefreshPeriod,
                      (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
                      (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
               ret = -EINVAL;
               goto exit;
           }
           neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;

           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "%s: Received Command to Set roam scan refresh period"
                      " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);

           pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
           sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
       }
       else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
       {
           tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
           char extra[32];
           tANI_U8 len = 0;

           len = scnprintf(extra, sizeof(extra), "%s %d",
                   "GETROAMSCANREFRESHPERIOD", (value/1000));
           /* Returned value is in units of seconds */
           len = VOS_MIN(priv_data.total_len, len + 1);
           if (copy_to_user(priv_data.buf, &extra, len)) {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto exit;
           }
       }
#ifdef FEATURE_WLAN_LFR
       /* SETROAMMODE */
       else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
       {
           tANI_U8 *value = command;
	   tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;

	   if (pHddCtx->concurrency_mode == VOS_STA_MON) {
	       hddLog(LOGE,
	      FL("Roaming is always disabled in STA + MON concurrency"));
	       ret = -EINVAL;
	      goto exit;
	   }

           ret = hdd_drv_cmd_validate(command, SIZE_OF_SETROAMMODE);
           if (ret)
               goto exit;

	   /* Move pointer to ahead of SETROAMMODE<delimiter> */
	   value = value + SIZE_OF_SETROAMMODE + 1;

	   /* Convert the value from ascii to integer */
	   ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
	   if (ret < 0)
	   {
	      /* If the input value is greater than max value of datatype, then also
		  kstrtou8 fails */
	      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
		   "%s: kstrtou8 failed range [%d - %d]", __func__,
		   CFG_LFR_FEATURE_ENABLED_MIN,
		   CFG_LFR_FEATURE_ENABLED_MAX);
              ret = -EINVAL;
	      goto exit;
	   }
           if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
	       (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
           {
              VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			"Roam Mode value %d is out of range"
			" (Min: %d Max: %d)", roamMode,
			CFG_LFR_FEATURE_ENABLED_MIN,
			CFG_LFR_FEATURE_ENABLED_MAX);
	      ret = -EINVAL;
	      goto exit;
	   }

	   VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
		   "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
           /*
	    * Note that
	    *     SETROAMMODE 0 is to enable LFR while
	    *     SETROAMMODE 1 is to disable LFR, but
	    *     NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
	    *     So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
	    */
	   if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
	       roamMode = CFG_LFR_FEATURE_ENABLED_MAX;    /* Roam enable */
	   else
	       roamMode = CFG_LFR_FEATURE_ENABLED_MIN;    /* Roam disable */

	   pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
           sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
       }
       /* GETROAMMODE */
       else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
       {
	   tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
	   char extra[32];
	   tANI_U8 len = 0;

           /*
            * roamMode value shall be inverted because the sementics is different.
            */
           if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
	       roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
           else
	       roamMode = CFG_LFR_FEATURE_ENABLED_MIN;

	   len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
           len = VOS_MIN(priv_data.total_len, len + 1);
	   if (copy_to_user(priv_data.buf, &extra, len)) {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto exit;
	   }
       }
#endif
#endif
#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
       else if (strncmp(command, "SETROAMDELTA", 12) == 0)
       {
           tANI_U8 *value = command;
           tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;

           ret = hdd_drv_cmd_validate(command, 12);
           if (ret)
               goto exit;

           /* Move pointer to ahead of SETROAMDELTA<delimiter> */
           value = value + 13;
           /* Convert the value from ascii to integer */
           ret = kstrtou8(value, 10, &roamRssiDiff);
           if (ret < 0)
           {
               /* If the input value is greater than max value of datatype, then also
                  kstrtou8 fails */
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: kstrtou8 failed range [%d - %d]", __func__,
                      CFG_ROAM_RSSI_DIFF_MIN,
                      CFG_ROAM_RSSI_DIFF_MAX);
               ret = -EINVAL;
               goto exit;
           }

           if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
               (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "Roam rssi diff value %d is out of range"
                      " (Min: %d Max: %d)", roamRssiDiff,
                      CFG_ROAM_RSSI_DIFF_MIN,
                      CFG_ROAM_RSSI_DIFF_MAX);
               ret = -EINVAL;
               goto exit;
           }

           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);

           pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
           sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
       }
       else if (strncmp(command, "GETROAMDELTA", 12) == 0)
       {
           tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
           char extra[32];
           tANI_U8 len = 0;

           MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                            TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
                            pAdapter->sessionId, roamRssiDiff));
           len = scnprintf(extra, sizeof(extra), "%s %d",
                   command, roamRssiDiff);
           len = VOS_MIN(priv_data.total_len, len + 1);
           if (copy_to_user(priv_data.buf, &extra, len)) {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto exit;
           }
       }
#endif
#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
       else if (strncmp(command, "GETBAND", 7) == 0)
       {
           int band = -1;
           char extra[32];
           tANI_U8 len = 0;
           hdd_getBand_helper(pHddCtx, &band);

           MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                            TRACE_CODE_HDD_GETBAND_IOCTL,
                            pAdapter->sessionId, band));
           len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
           len = VOS_MIN(priv_data.total_len, len + 1);
           if (copy_to_user(priv_data.buf, &extra, len)) {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto exit;
           }
       }
       else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
       {
           tANI_U8 *value = command;
           tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
           tANI_U8 numChannels = 0;
           eHalStatus status = eHAL_STATUS_SUCCESS;

           status = hdd_parse_channellist(value, ChannelList, &numChannels);
           if (eHAL_STATUS_SUCCESS != status)
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Failed to parse channel list information", __func__);
               ret = -EINVAL;
               goto exit;
           }

           MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                            TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
                            pAdapter->sessionId, numChannels));
           if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: number of channels (%d) supported exceeded max (%d)", __func__,
                   numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
               ret = -EINVAL;
               goto exit;
           }
           status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
                                                  numChannels);
           if (eHAL_STATUS_SUCCESS != status)
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Failed to update channel list information", __func__);
               ret = -EINVAL;
               goto exit;
           }
       }
       else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
       {
           tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
           tANI_U8 numChannels = 0;
           tANI_U8 j = 0;
           char extra[128] = {0};
           int len;

           if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
                                              ChannelList, &numChannels ))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                  "%s: failed to get roam scan channel list", __func__);
               ret = -EFAULT;
               goto exit;
           }
           MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                            TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
                            pAdapter->sessionId, numChannels));
           /* output channel list is of the format
           [Number of roam scan channels][Channel1][Channel2]... */
           /* copy the number of channels in the 0th index */
           len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
           for (j = 0; (j < numChannels) && len <= sizeof(extra); j++)
           {
               len += scnprintf(extra + len, sizeof(extra) - len, " %d",
                       ChannelList[j]);
           }

           len = VOS_MIN(priv_data.total_len, len + 1);
           if (copy_to_user(priv_data.buf, &extra, len))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto exit;
           }
       }
       else if (strncmp(command, "GETCCXMODE", 10) == 0)
       {
           tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
           char extra[32];
           tANI_U8 len = 0;

           /* Check if the features OKC/ESE/11R are supported simultaneously,
              then this operation is not permitted (return FAILURE) */
           if (eseMode &&
               hdd_is_okc_mode_enabled(pHddCtx) &&
               sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                  "%s: OKC/ESE/11R are supported simultaneously"
                  " hence this operation is not permitted!", __func__);
               ret = -EPERM;
               goto exit;
           }

           len = scnprintf(extra, sizeof(extra), "%s %d",
                   "GETCCXMODE", eseMode);
           len = VOS_MIN(priv_data.total_len, len + 1);
           if (copy_to_user(priv_data.buf, &extra, len))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto exit;
           }
       }
       else if (strncmp(command, "GETOKCMODE", 10) == 0)
       {
           tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
           char extra[32];
           tANI_U8 len = 0;

           /* Check if the features OKC/ESE/11R are supported simultaneously,
              then this operation is not permitted (return FAILURE) */
           if (okcMode &&
               sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
               sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                  "%s: OKC/ESE/11R are supported simultaneously"
                  " hence this operation is not permitted!", __func__);
               ret = -EPERM;
               goto exit;
           }

           len = scnprintf(extra, sizeof(extra), "%s %d",
                   "GETOKCMODE", okcMode);
           len = VOS_MIN(priv_data.total_len, len + 1);
           if (copy_to_user(priv_data.buf, &extra, len))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto exit;
           }
       }
       else if (strncmp(command, "GETFASTROAM", 11) == 0)
       {
           tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
           char extra[32];
           tANI_U8 len = 0;

           len = scnprintf(extra, sizeof(extra), "%s %d",
                   "GETFASTROAM", lfrMode);
           len = VOS_MIN(priv_data.total_len, len + 1);
           if (copy_to_user(priv_data.buf, &extra, len))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto exit;
           }
       }
       else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
       {
           tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
           char extra[32];
           tANI_U8 len = 0;

           len = scnprintf(extra, sizeof(extra), "%s %d",
                   "GETFASTTRANSITION", ft);
           len = VOS_MIN(priv_data.total_len, len + 1);
           if (copy_to_user(priv_data.buf, &extra, len))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto exit;
           }
       }
       else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
       {
           tANI_U8 *value = command;
           tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;

           ret = hdd_drv_cmd_validate(command, 25);
           if (ret)
               goto exit;

           /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
           value = value + 26;
           /* Convert the value from ascii to integer */
           ret = kstrtou8(value, 10, &minTime);
           if (ret < 0)
           {
               /* If the input value is greater than max value of datatype, then also
                  kstrtou8 fails */
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: kstrtou8 failed range [%d - %d]", __func__,
                      CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
                      CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
               ret = -EINVAL;
               goto exit;
           }
           if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
               (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "scan min channel time value %d is out of range"
                      " (Min: %d Max: %d)", minTime,
                      CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
                      CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
               ret = -EINVAL;
               goto exit;
           }

           MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                            TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
                            pAdapter->sessionId, minTime));
           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "%s: Received Command to change channel min time = %d", __func__, minTime);

           pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
           sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
       }
       else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
       {
           tANI_U8 *value = command;
           tANI_U8 channel = 0;
           tANI_U8 dwellTime = 0;
           tANI_U8 bufLen = 0;
           tANI_U8 *buf = NULL;
           tSirMacAddr targetApBssid;
           eHalStatus status = eHAL_STATUS_SUCCESS;
           struct ieee80211_channel chan;
           tANI_U8 finalLen = 0;
           tANI_U8 *finalBuf = NULL;
           tANI_U8 temp = 0;
           u64 cookie;
           hdd_station_ctx_t *pHddStaCtx = NULL;
           pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

           /* if not associated, no need to send action frame */
           if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
           {
               VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
               ret = -EINVAL;
               goto exit;
           }

           status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
                                                     &dwellTime, &buf, &bufLen);
           if (eHAL_STATUS_SUCCESS != status)
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Failed to parse send action frame data", __func__);
               ret = -EINVAL;
               goto exit;
           }

           /* if the target bssid is different from currently associated AP,
              then no need to send action frame */
           if (VOS_TRUE != vos_mem_compare(targetApBssid,
                                           pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
           {
               VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
               ret = -EINVAL;
               vos_mem_free(buf);
               buf = NULL;
               goto exit;
           }

           /* if the channel number is different from operating channel then
              no need to send action frame */
           if (channel != pHddStaCtx->conn_info.operationChannel)
           {
               VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                         "%s: channel(%d) is different from operating channel(%d)",
                         __func__, channel, pHddStaCtx->conn_info.operationChannel);
               ret = -EINVAL;
               vos_mem_free(buf);
               buf = NULL;
               goto exit;
           }
           chan.center_freq = sme_ChnToFreq(channel);

           finalLen = bufLen + 24;
           finalBuf = vos_mem_malloc(finalLen);
           if (NULL == finalBuf)
           {
               VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
               ret = -ENOMEM;
               vos_mem_free(buf);
               buf = NULL;
               goto exit;
           }
           vos_mem_zero(finalBuf, finalLen);

           /* Fill subtype */
           temp = SIR_MAC_MGMT_ACTION << 4;
           vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));

           /* Fill type */
           temp = SIR_MAC_MGMT_FRAME;
           vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));

           /* Fill destination address (bssid of the AP) */
           vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));

           /* Fill source address (STA mac address) */
           vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));

           /* Fill BSSID (AP mac address) */
           vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));

           /* Fill received buffer from 24th address */
           vos_mem_copy(finalBuf + 24, buf, bufLen);

           /* done with the parsed buffer */
           vos_mem_free(buf);
           buf = NULL;

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
           params.chan = &chan;
           params.offchan = 0;
           params.wait = dwellTime;
           params.buf = finalBuf;
           params.len = finalLen;
           params.no_cck = 1;
           params.dont_wait_for_ack = 1;
           ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, &params, &cookie);
#else
           wlan_hdd_mgmt_tx( NULL,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
                       &(pAdapter->wdev),
#else
                       pAdapter->dev,
#endif
                       &chan, 0,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
                       NL80211_CHAN_HT20, 1,
#endif
                       dwellTime, finalBuf, finalLen,  1,
                       1, &cookie );
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/
           vos_mem_free(finalBuf);
       }
       else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
       {
           tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
           char extra[32];
           tANI_U8 len = 0;

           /* value is interms of msec */
           len = scnprintf(extra, sizeof(extra), "%s %d",
                   "GETROAMSCANCHANNELMINTIME", val);
           MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                            TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
                            pAdapter->sessionId, val));
           len = VOS_MIN(priv_data.total_len, len + 1);
           if (copy_to_user(priv_data.buf, &extra, len))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto exit;
           }
       }
       else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
       {
           tANI_U8 *value = command;
           tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;

           ret = hdd_drv_cmd_validate(command, 18);
           if (ret)
               goto exit;

           /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
           value = value + 19;
           /* Convert the value from ascii to integer */
           ret = kstrtou16(value, 10, &maxTime);
           if (ret < 0)
           {
               /* If the input value is greater than max value of datatype, then also
                  kstrtou16 fails */
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: kstrtou16 failed range [%d - %d]", __func__,
                      CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
                      CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
               ret = -EINVAL;
               goto exit;
           }

           if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
               (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "lfr mode value %d is out of range"
                      " (Min: %d Max: %d)", maxTime,
                      CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
                      CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
               ret = -EINVAL;
               goto exit;
           }

           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "%s: Received Command to change channel max time = %d", __func__, maxTime);

           pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
           sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
       }
       else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
       {
           tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
           char extra[32];
           tANI_U8 len = 0;

           /* value is interms of msec */
           len = scnprintf(extra, sizeof(extra), "%s %d",
                   "GETSCANCHANNELTIME", val);
           len = VOS_MIN(priv_data.total_len, len + 1);
           if (copy_to_user(priv_data.buf, &extra, len))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto exit;
           }
       }
       else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
       {
           tANI_U8 *value = command;
           tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;

           ret = hdd_drv_cmd_validate(command, 15);
           if (ret)
               goto exit;

           /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
           value = value + 16;
           /* Convert the value from ascii to integer */
           ret = kstrtou16(value, 10, &val);
           if (ret < 0)
           {
               /* If the input value is greater than max value of datatype, then also
                  kstrtou16 fails */
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: kstrtou16 failed range [%d - %d]", __func__,
                      CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
                      CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
               ret = -EINVAL;
               goto exit;
           }

           if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
               (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "scan home time value %d is out of range"
                      " (Min: %d Max: %d)", val,
                      CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
                      CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
               ret = -EINVAL;
               goto exit;
           }

           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "%s: Received Command to change scan home time = %d", __func__, val);

           pHddCtx->cfg_ini->nNeighborScanPeriod = val;
           sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
       }
       else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
       {
           tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
           char extra[32];
           tANI_U8 len = 0;

           /* value is interms of msec */
           len = scnprintf(extra, sizeof(extra), "%s %d",
                   "GETSCANHOMETIME", val);
           len = VOS_MIN(priv_data.total_len, len + 1);
           if (copy_to_user(priv_data.buf, &extra, len))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto exit;
           }
       }
       else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
       {
           tANI_U8 *value = command;
           tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;

           ret = hdd_drv_cmd_validate(command, 16);
           if (ret)
               goto exit;

           /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
           value = value + 17;
           /* Convert the value from ascii to integer */
           ret = kstrtou8(value, 10, &val);
           if (ret < 0)
           {
               /* If the input value is greater than max value of datatype, then also
                  kstrtou8 fails */
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: kstrtou8 failed range [%d - %d]", __func__,
                      CFG_ROAM_INTRA_BAND_MIN,
                      CFG_ROAM_INTRA_BAND_MAX);
               ret = -EINVAL;
               goto exit;
           }

           if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
               (val > CFG_ROAM_INTRA_BAND_MAX))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "intra band mode value %d is out of range"
                      " (Min: %d Max: %d)", val,
                      CFG_ROAM_INTRA_BAND_MIN,
                      CFG_ROAM_INTRA_BAND_MAX);
               ret = -EINVAL;
               goto exit;
           }
           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "%s: Received Command to change intra band = %d", __func__, val);

           pHddCtx->cfg_ini->nRoamIntraBand = val;
           sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
       }
       else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
       {
           tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
           char extra[32];
           tANI_U8 len = 0;

           /* value is interms of msec */
           len = scnprintf(extra, sizeof(extra), "%s %d",
                   "GETROAMINTRABAND", val);
           len = VOS_MIN(priv_data.total_len, len + 1);
           if (copy_to_user(priv_data.buf, &extra, len))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto exit;
           }
       }
       else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
       {
           tANI_U8 *value = command;
           tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;

           ret = hdd_drv_cmd_validate(command, 14);
           if (ret)
               goto exit;

           /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
           value = value + 15;
           /* Convert the value from ascii to integer */
           ret = kstrtou8(value, 10, &nProbes);
           if (ret < 0)
           {
               /* If the input value is greater than max value of datatype, then also
                  kstrtou8 fails */
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: kstrtou8 failed range [%d - %d]", __func__,
                      CFG_ROAM_SCAN_N_PROBES_MIN,
                      CFG_ROAM_SCAN_N_PROBES_MAX);
               ret = -EINVAL;
               goto exit;
           }

           if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
               (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "NProbes value %d is out of range"
                      " (Min: %d Max: %d)", nProbes,
                      CFG_ROAM_SCAN_N_PROBES_MIN,
                      CFG_ROAM_SCAN_N_PROBES_MAX);
               ret = -EINVAL;
               goto exit;
           }

           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "%s: Received Command to Set nProbes = %d", __func__, nProbes);

           pHddCtx->cfg_ini->nProbes = nProbes;
           sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
       }
       else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
       {
           tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
           char extra[32];
           tANI_U8 len = 0;

           len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
           len = VOS_MIN(priv_data.total_len, len + 1);
           if (copy_to_user(priv_data.buf, &extra, len)) {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto exit;
           }
       }
       else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
       {
           tANI_U8 *value = command;
           tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;

           ret = hdd_drv_cmd_validate(command, 19);
           if (ret)
               goto exit;

           /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
           /* input value is in units of msec */
           value = value + 20;
           /* Convert the value from ascii to integer */
           ret = kstrtou16(value, 10, &homeAwayTime);
           if (ret < 0)
           {
               /* If the input value is greater than max value of datatype, then also
                  kstrtou8 fails */
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: kstrtou8 failed range [%d - %d]", __func__,
                      CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
                      CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
               ret = -EINVAL;
               goto exit;
           }

           if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
               (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "homeAwayTime value %d is out of range"
                      " (Min: %d Max: %d)", homeAwayTime,
                      CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
                      CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
               ret = -EINVAL;
               goto exit;
           }

           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
           if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
           {
               pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
               sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
           }
       }
       else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
       {
           tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
           char extra[32];
           tANI_U8 len = 0;

           len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
           len = VOS_MIN(priv_data.total_len, len + 1);
           if (copy_to_user(priv_data.buf, &extra, len)) {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto exit;
           }
       }
       else if (strncmp(command, "REASSOC", 7) == 0)
       {
           ret = hdd_drv_cmd_validate(command, 7);
           if (ret)
               goto exit;

           ret = hdd_parse_reassoc(pAdapter, command, priv_data.total_len);
           if (!ret)
               goto exit;
       }
       else if (strncmp(command, "SETWESMODE", 10) == 0)
       {
           tANI_U8 *value = command;
           tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;

           ret = hdd_drv_cmd_validate(command, 10);
           if (ret)
               goto exit;

           /* Move pointer to ahead of SETWESMODE<delimiter> */
           value = value + 11;
           /* Convert the value from ascii to integer */
           ret = kstrtou8(value, 10, &wesMode);
           if (ret < 0)
           {
               /* If the input value is greater than max value of datatype, then also
                  kstrtou8 fails */
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: kstrtou8 failed range [%d - %d]", __func__,
                      CFG_ENABLE_WES_MODE_NAME_MIN,
                      CFG_ENABLE_WES_MODE_NAME_MAX);
               ret = -EINVAL;
               goto exit;
           }

           if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
               (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "WES Mode value %d is out of range"
                      " (Min: %d Max: %d)", wesMode,
                      CFG_ENABLE_WES_MODE_NAME_MIN,
                      CFG_ENABLE_WES_MODE_NAME_MAX);
               ret = -EINVAL;
               goto exit;
           }
           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);

           pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
           sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
       }
       else if (strncmp(command, "GETWESMODE", 10) == 0)
       {
           tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
           char extra[32];
           tANI_U8 len = 0;

           len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
           len = VOS_MIN(priv_data.total_len, len + 1);
           if (copy_to_user(priv_data.buf, &extra, len)) {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto exit;
           }
       }
#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
#ifdef FEATURE_WLAN_LFR
       else if (strncmp(command, "SETFASTROAM", 11) == 0)
       {
           tANI_U8 *value = command;
           tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;

           if (pHddCtx->concurrency_mode == VOS_STA_MON) {
               hddLog(LOGE,
                FL("Roaming is always disabled in STA + MON concurrency"));
               ret = -EINVAL;
               goto exit;
           }

           ret = hdd_drv_cmd_validate(command, 11);
           if (ret)
               goto exit;

           /* Move pointer to ahead of SETFASTROAM<delimiter> */
           value = value + 12;
           /* Convert the value from ascii to integer */
           ret = kstrtou8(value, 10, &lfrMode);
           if (ret < 0)
           {
               /* If the input value is greater than max value of datatype, then also
                  kstrtou8 fails */
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: kstrtou8 failed range [%d - %d]", __func__,
                      CFG_LFR_FEATURE_ENABLED_MIN,
                      CFG_LFR_FEATURE_ENABLED_MAX);
               ret = -EINVAL;
               goto exit;
           }

           if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
               (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "lfr mode value %d is out of range"
                      " (Min: %d Max: %d)", lfrMode,
                      CFG_LFR_FEATURE_ENABLED_MIN,
                      CFG_LFR_FEATURE_ENABLED_MAX);
               ret = -EINVAL;
               goto exit;
           }

           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "%s: Received Command to change lfr mode = %d", __func__, lfrMode);

           pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
           sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
       }
#endif
#ifdef WLAN_FEATURE_VOWIFI_11R
       else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
       {
           tANI_U8 *value = command;
           tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;

           ret = hdd_drv_cmd_validate(command, 17);
           if (ret)
               goto exit;

           /* Move pointer to ahead of SETFASTROAM<delimiter> */
           value = value + 18;
           /* Convert the value from ascii to integer */
           ret = kstrtou8(value, 10, &ft);
           if (ret < 0)
           {
               /* If the input value is greater than max value of datatype, then also
                  kstrtou8 fails */
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: kstrtou8 failed range [%d - %d]", __func__,
                      CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
                      CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
               ret = -EINVAL;
               goto exit;
           }

           if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
               (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "ft mode value %d is out of range"
                      " (Min: %d Max: %d)", ft,
                      CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
                      CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
               ret = -EINVAL;
               goto exit;
           }

           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "%s: Received Command to change ft mode = %d", __func__, ft);

           pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
           sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
       }
       else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
       {
           tANI_U8 *value = command;
           tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;

           ret = hdd_drv_cmd_validate(command, 14);
           if (ret)
               goto exit;

           /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
           value = value + 15;
           /* Convert the value from ascii to integer */
           ret = kstrtou8(value, 10, &dfsScanMode);
           if (ret < 0)
           {
               /* If the input value is greater than max value of
                               datatype, then also kstrtou8 fails
                          */
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: kstrtou8 failed range [%d - %d]", __func__,
                      CFG_ENABLE_DFS_CHNL_SCAN_MIN,
                      CFG_ENABLE_DFS_CHNL_SCAN_MAX);
               ret = -EINVAL;
               goto exit;
           }

           if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
               (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "dfsScanMode value %d is out of range"
                      " (Min: %d Max: %d)", dfsScanMode,
                      CFG_ENABLE_DFS_CHNL_SCAN_MIN,
                      CFG_ENABLE_DFS_CHNL_SCAN_MAX);
               ret = -EINVAL;
               goto exit;
           }
           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "%s: Received Command to Set DFS Scan Mode = %d",
                      __func__, dfsScanMode);

           ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
       }
       else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
       {
           tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
           char extra[32];
           tANI_U8 len = 0;

           len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
           len = VOS_MIN(priv_data.total_len, len + 1);
           if (copy_to_user(priv_data.buf, &extra, len))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto exit;
           }
       }
       else if (strncmp(command, "FASTREASSOC", 11) == 0)
       {
           ret = wlan_hdd_handle_fastreassoc(pAdapter, command);
           if (!ret)
               goto exit;
       }
#endif
#ifdef FEATURE_WLAN_ESE
       else if (strncmp(command, "SETCCXMODE", 10) == 0)
       {
           tANI_U8 *value = command;
           tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;

           ret = hdd_drv_cmd_validate(command, 10);
           if (ret)
               goto exit;

           /* Check if the features OKC/ESE/11R are supported simultaneously,
              then this operation is not permitted (return FAILURE) */
           if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
               hdd_is_okc_mode_enabled(pHddCtx) &&
               sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                  "%s: OKC/ESE/11R are supported simultaneously"
                  " hence this operation is not permitted!", __func__);
               ret = -EPERM;
               goto exit;
           }

           /* Move pointer to ahead of SETCCXMODE<delimiter> */
           value = value + 11;
           /* Convert the value from ascii to integer */
           ret = kstrtou8(value, 10, &eseMode);
           if (ret < 0)
           {
               /* If the input value is greater than max value of datatype, then also
                  kstrtou8 fails */
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: kstrtou8 failed range [%d - %d]", __func__,
                      CFG_ESE_FEATURE_ENABLED_MIN,
                      CFG_ESE_FEATURE_ENABLED_MAX);
               ret = -EINVAL;
               goto exit;
           }
           if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
               (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "Ese mode value %d is out of range"
                      " (Min: %d Max: %d)", eseMode,
                      CFG_ESE_FEATURE_ENABLED_MIN,
                      CFG_ESE_FEATURE_ENABLED_MAX);
               ret = -EINVAL;
               goto exit;
           }
           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "%s: Received Command to change ese mode = %d", __func__, eseMode);

           pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
           sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
       }
#endif
       else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
       {
           tANI_U8 *value = command;
           tANI_BOOLEAN roamScanControl = 0;

           ret = hdd_drv_cmd_validate(command, 18);
           if (ret)
               goto exit;

           /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
           value = value + 19;
           /* Convert the value from ascii to integer */
           ret = kstrtou8(value, 10, &roamScanControl);
           if (ret < 0)
           {
               /* If the input value is greater than max value of datatype, then also
                  kstrtou8 fails */
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: kstrtou8 failed ", __func__);
               ret = -EINVAL;
               goto exit;
           }

           if (0 != roamScanControl)
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "roam scan control invalid value = %d",
                      roamScanControl);
               ret = -EINVAL;
               goto exit;
           }
           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);

           sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
       }
#ifdef FEATURE_WLAN_OKC
       else if (strncmp(command, "SETOKCMODE", 10) == 0)
       {
           tANI_U8 *value = command;
           tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;

           ret = hdd_drv_cmd_validate(command, 10);
           if (ret)
               goto exit;

           /* Check if the features OKC/ESE/11R are supported simultaneously,
              then this operation is not permitted (return FAILURE) */
           if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
               hdd_is_okc_mode_enabled(pHddCtx) &&
               sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                  "%s: OKC/ESE/11R are supported simultaneously"
                  " hence this operation is not permitted!", __func__);
               ret = -EPERM;
               goto exit;
           }

           /* Move pointer to ahead of SETOKCMODE<delimiter> */
           value = value + 11;
           /* Convert the value from ascii to integer */
           ret = kstrtou8(value, 10, &okcMode);
           if (ret < 0)
           {
               /* If the input value is greater than max value of datatype, then also
                  kstrtou8 fails */
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: kstrtou8 failed range [%d - %d]", __func__,
                      CFG_OKC_FEATURE_ENABLED_MIN,
                      CFG_OKC_FEATURE_ENABLED_MAX);
               ret = -EINVAL;
               goto exit;
           }

           if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
               (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "Okc mode value %d is out of range"
                      " (Min: %d Max: %d)", okcMode,
                      CFG_OKC_FEATURE_ENABLED_MIN,
                      CFG_OKC_FEATURE_ENABLED_MAX);
               ret = -EINVAL;
               goto exit;
           }

           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "%s: Received Command to change okc mode = %d", __func__, okcMode);

           pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
       }
#endif  /* FEATURE_WLAN_OKC */
       else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
       {
           tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
           char extra[32];
           tANI_U8 len = 0;

           len = scnprintf(extra, sizeof(extra), "%s %d",
                   command, roamScanControl);
           len = VOS_MIN(priv_data.total_len, len + 1);
           if (copy_to_user(priv_data.buf, &extra, len)) {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto exit;
           }
       }
#ifdef WLAN_FEATURE_PACKET_FILTERING
       else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
       {
           tANI_U8 filterType = 0;
           tANI_U8 *value = command;

           ret = hdd_drv_cmd_validate(command, 21);
           if (ret)
               goto exit;

           /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
           value = value + 22;

           /* Convert the value from ascii to integer */
           ret = kstrtou8(value, 10, &filterType);
           if (ret < 0)
           {
               /* If the input value is greater than max value of datatype,
                * then also kstrtou8 fails
                */
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: kstrtou8 failed range ", __func__);
               ret = -EINVAL;
               goto exit;
           }

           if (filterType != 0 && filterType != 1)
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: Accepted Values are 0 and 1 ", __func__);
               ret = -EINVAL;
               goto exit;
           }
           wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
                   pAdapter->sessionId);
       }
#endif
       else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
       {
           char *dhcpPhase;
           int ret;

           ret = hdd_drv_cmd_validate(command, 10);
           if (ret)
               goto exit;

           dhcpPhase = command + 11;
           if ('1' == *dhcpPhase)
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                         FL("send DHCP START indication"));

               pHddCtx->btCoexModeSet = TRUE;

               ret = wlan_hdd_scan_abort(pAdapter);
               if (ret < 0)
               {
                   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      FL("failed to abort existing scan %d"), ret);
               }

               sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
                                pAdapter->sessionId);
           }
           else if ('2' == *dhcpPhase)
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                         FL("send DHCP STOP indication"));

               pHddCtx->btCoexModeSet = FALSE;

               sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
                               pAdapter->sessionId);
           }
       }
       else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
       {
           hddLog(LOG1,
                FL("making default scan to ACTIVE"));
           pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
       }
       else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
       {
           hddLog(LOG1,
                FL("making default scan to PASSIVE"));
           pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
       }
       else if (strncmp(command, "GETDWELLTIME", 12) == 0)
       {
           hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
           char extra[32];
           tANI_U8 len = 0;

           memset(extra, 0, sizeof(extra));
           ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
           len = VOS_MIN(priv_data.total_len, len + 1);
           if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto exit;
           }
           ret = len;
       }
       else if (strncmp(command, "SETDWELLTIME", 12) == 0)
       {
           ret = hdd_set_dwell_time(pAdapter, command);
       }
       else if (strncmp(command, "BTCGETDWELLTIME", 15) == 0)
       {
           hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
           char extra[32];
           tANI_U8 len = 0;

           if (hdd_drv_cmd_validate(command, 15)) {
               hddLog(LOGE, FL("Invalid driver command"));
               return -EINVAL;
           }

           memset(extra, 0, sizeof(extra));
           ret = hdd_btc_get_dwell_time(pCfg, command, extra,
                                        sizeof(extra), &len);
           len = VOS_MIN(priv_data.total_len, len + 1);
           if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
               hddLog(LOGE, FL("Failed to copy data to user buffer"));
               ret = -EFAULT;
               goto exit;
           }
           ret = len;
       }
       else if (strncmp(command, "BTCSETDWELLTIME", 15) == 0)
       {
           if (hdd_drv_cmd_validate(command, 15)) {
               hddLog(LOGE, FL("Invalid driver command"));
               return -EINVAL;
           }
           ret = hdd_btc_set_dwell_time(pAdapter, command);
       }
#ifdef WLAN_AP_STA_CONCURRENCY
       else if (strncmp(command, "CONCGETDWELLTIME", 16) == 0)
       {
           hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
           char extra[32];
           tANI_U8 len = 0;

           if (hdd_drv_cmd_validate(command, 16)) {
               hddLog(LOGE, FL("Invalid driver command"));
               return -EINVAL;
           }

           memset(extra, 0, sizeof(extra));
           ret = hdd_conc_get_dwell_time(pCfg, command, extra,
                                         sizeof(extra), &len);
           len = VOS_MIN(priv_data.total_len, len + 1);
           if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
               hddLog(LOGE, FL("Failed to copy data to user buffer"));
               ret = -EFAULT;
               goto exit;
           }
           ret = len;
       }
       else if (strncmp(command, "CONCSETDWELLTIME", 16) == 0)
       {
           if (hdd_drv_cmd_validate(command, 16)) {
               hddLog(LOGE, FL("Invalid driver command"));
               return -EINVAL;
           }
           ret = hdd_conc_set_dwell_time(pAdapter, command);
       }
#endif
       else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
       {
           tANI_U8 filterType = 0;
           tANI_U8 *value;

           ret = hdd_drv_cmd_validate(command, 8);
           if (ret)
               goto exit;

           value = command + 9;

           /* Convert the value from ascii to integer */
           ret = kstrtou8(value, 10, &filterType);
           if (ret < 0)
           {
               /* If the input value is greater than max value of datatype,
                * then also kstrtou8 fails
                */
              VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                              "%s: kstrtou8 failed range ", __func__);
              ret = -EINVAL;
              goto exit;
           }
           if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
               (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
                      " 2-Sink ", __func__);
               ret = -EINVAL;
               goto exit;
           }
           //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
           pHddCtx->drvr_miracast = filterType;
           pScanInfo =  &pHddCtx->scan_info;
           if (filterType && pScanInfo != NULL &&
               pHddCtx->scan_info.mScanPending)
           {
              /*Miracast Session started. Abort Scan */
              VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
               "%s, Aborting Scan For Miracast",__func__);
              hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
                                 eCSR_SCAN_ABORT_DEFAULT);
           }
           hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
           sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
        }
       else if (strncmp(command, "SETMCRATE", 9) == 0)
       {
           tANI_U8 *value = command;
           int      targetRate;
           tSirRateUpdateInd *rateUpdate;
           eHalStatus status;

           ret = hdd_drv_cmd_validate(command, 9);
           if (ret)
               goto exit;

           /* Only valid for SAP mode */
           if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
           {
               VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: SAP mode is not running", __func__);
               ret = -EFAULT;
               goto exit;
           }

           /* Move pointer to ahead of SETMCRATE<delimiter> */
           /* input value is in units of hundred kbps */
           value = value + 10;
           /* Convert the value from ascii to integer, decimal base */
           ret = kstrtouint(value, 10, &targetRate);

           rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
           if (NULL == rateUpdate)
           {
              hddLog(VOS_TRACE_LEVEL_ERROR,
                     "%s: SETMCRATE indication alloc fail", __func__);
              ret = -EFAULT;
              goto exit;
           }
           vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));

           VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                     "MC Target rate %d", targetRate);
           /* Ignore unicast */
           rateUpdate->ucastDataRate = -1;
           rateUpdate->mcastDataRate24GHz = targetRate;
           rateUpdate->mcastDataRate5GHz = targetRate;
           rateUpdate->mcastDataRate24GHzTxFlag = 0;
           rateUpdate->mcastDataRate5GHzTxFlag = 0;
           status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
           if (eHAL_STATUS_SUCCESS != status)
           {
              hddLog(VOS_TRACE_LEVEL_ERROR,
                     "%s: SET_MC_RATE failed", __func__);
              vos_mem_free(rateUpdate);
              ret = -EFAULT;
              goto exit;
           }
       }
       else if (strncmp(command, "MAXTXPOWER", 10) == 0)
       {
           int status;
           int txPower;
           eHalStatus smeStatus;
           tANI_U8 *value = command;
           tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
           tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};

           status = hdd_parse_setmaxtxpower_command(value, &txPower);
           if (status)
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                          "Invalid MAXTXPOWER command ");
               ret = -EINVAL;
               goto exit;
           }

           hddLog(VOS_TRACE_LEVEL_INFO, "max tx power %d selfMac: "
                        MAC_ADDRESS_STR " bssId: " MAC_ADDRESS_STR " ",
                        txPower, MAC_ADDR_ARRAY(selfMac),
                        MAC_ADDR_ARRAY(bssid));
           smeStatus = sme_SetMaxTxPower((tHalHandle)(pHddCtx->hHal),
                                         bssid, selfMac, txPower) ;
           if( smeStatus !=  eHAL_STATUS_SUCCESS )
           {
               hddLog(VOS_TRACE_LEVEL_ERROR, "%s:Set max tx power failed",
                      __func__);
               ret = -EINVAL;
               goto exit;
           }

            hddLog(VOS_TRACE_LEVEL_INFO, "%s: Set max tx power success",
                   __func__);
       }
#ifdef FEATURE_WLAN_BATCH_SCAN
       else if (strncmp(command, "WLS_BATCHING", 12) == 0)
       {
           ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
       }
#endif
#ifdef WLAN_FEATURE_RMC
       else if ((strncasecmp(command, "SETIBSSBEACONOUIDATA", 20) == 0) &&
                (WLAN_HDD_IBSS == pAdapter->device_mode))
       {
           int i = 0;
           tANI_U8 *ibss_ie;
           tANI_U32 command_len;
           tANI_U8 *value = command;
           tHalHandle hHal = pHddCtx->hHal;
           tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
           tANI_U32 ibss_ie_length;
           tANI_U32 len, present;
           tANI_U8 *addIE;
           tANI_U8 *addIEData;

           hddLog(LOG1,
                     FL(" received command %s"),((char *) value));
           /* validate argument of command */
           if (strlen(value) <= 21)
           {
               hddLog(LOGE,
                   FL("No arguements in command length %zu"), strlen(value));
              ret = -EFAULT;
              goto exit;
           }

           /* moving to arguments of commands */
           value = value + 21;
           command_len = strlen(value);

           /* oui_data can't be less than 3 bytes */
           if (command_len <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH))
           {
               hddLog(LOGE,
                     FL("Invalid SETIBSSBEACONOUIDATA command length %d"),
                     command_len);
              ret = -EFAULT;
              goto exit;
           }
           ibss_ie = vos_mem_malloc(command_len);
           if (!ibss_ie) {
               hddLog(LOGE,
                     FL("Could not allocate memory for command length %d"),
                     command_len);
              ret = -ENOMEM;
              goto exit;
           }
           vos_mem_zero(ibss_ie, command_len);

           ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie,
                                                                  command_len);
           if (ibss_ie_length < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
               hddLog(LOGE, FL("Could not parse command %s return length %d"),
                     value, ibss_ie_length);
                 ret = -EFAULT;
              vos_mem_free(ibss_ie);
                 goto exit;
              }

           hddLog(LOG1, FL("ibss_ie length %d ibss_ie:"), ibss_ie_length);
           while (i < ibss_ie_length)
              hddLog(LOG1, FL("0x%x"), ibss_ie[i++]);

           /* Populate Vendor IE in Beacon */
           if ((ccmCfgGetInt(hHal,
                             WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
                             &present)) != eHAL_STATUS_SUCCESS)
           {
              hddLog(LOGE,
                FL("unable to ftch WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
              ret = -EFAULT;
              vos_mem_free(ibss_ie);
              goto exit;
           }

           addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
           if (!addIE) {
              hddLog(LOGE,
                     FL("Could not allocate memory for command length %d"),
                     command_len);
              vos_mem_free(ibss_ie);
              ret = -ENOMEM;
              goto exit;
           }
           vos_mem_zero(addIE, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);

           if (present)
           {
              if ((wlan_cfgGetStrLen(pMac,
                      WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &len)) != eSIR_SUCCESS)
              {
                 hddLog(LOGE,
                   FL("unable to fetch WNI_CFG_PROBE_RSP_BCN_ADDNIE_LEN"));
                 ret = -EFAULT;
                 vos_mem_free(ibss_ie);
                 vos_mem_free(addIE);
                 goto exit;
              }

              if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
                ((len + ibss_ie_length) <=
                                    WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN))
              {
                 if ((ccmCfgGetStr(hHal,
                        WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, &len))
                        != eHAL_STATUS_SUCCESS)
                 {
                    hddLog(LOGE,
                      FL("unable to fetch WNI_PROBE_RSP_BCN_ADDNIE_DATA"));
                    ret = -EFAULT;
                    vos_mem_free(ibss_ie);
                    vos_mem_free(addIE);
                    goto exit;
                 }
                 else
                 {
                    /* Curruntly only WPA IE is added before Vendor IE
                     * so we can blindly place the Vendor IE after WPA
                     * IE. If no WPA IE found replace all with Vendor IE.
                     */
                    len = hdd_find_ibss_wpa_ie_pos(addIE, len);
                 }
              }
              else
              {
                 hddLog(LOGE,
                    FL("IE len exceed limit len %d,ibss_ie_length %d "),
                    len, ibss_ie_length);
                 ret = -EFAULT;
                 vos_mem_free(addIE);
                 vos_mem_free(ibss_ie);
                 goto exit;
              }
           }
           else {
              len = 0;
           }

           vos_mem_copy (addIE + len , ibss_ie, ibss_ie_length);
           len += ibss_ie_length;

           if (ccmCfgSetStr(hHal,
               WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, len, NULL,
               eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
           {
              hddLog(LOGE,
                  FL("unable to set WNI_CFG_PRBE_RSP_BCN_ADDNIE_DATA"));
              ret = -EFAULT;
              vos_mem_free(ibss_ie);
              vos_mem_free(addIE);
              goto exit;
           }
           vos_mem_free(addIE);
           if (ccmCfgSetInt(hHal,
               WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
               eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
           {
              hddLog(LOGE,
                 FL("unble to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
              ret = -EFAULT;
              vos_mem_free(ibss_ie);
              goto exit;
           }

           /* Populate Vendor IE in probe resp */
           if ((ccmCfgGetInt(hHal,
                             WNI_CFG_PROBE_RSP_ADDNIE_FLAG,
                             &present)) != eHAL_STATUS_SUCCESS)
           {
               hddLog(LOGE,
                   FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
               ret = -EFAULT;
               vos_mem_free(ibss_ie);
               goto exit;
           }

           addIEData = vos_mem_malloc(WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
           if (!addIEData) {
              hddLog(LOGE,
                     FL("Could not allocate memory for command length %d"),
                     command_len);
              vos_mem_free(ibss_ie);
              ret = -ENOMEM;
              goto exit;
           }
           vos_mem_zero(addIEData, WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);

           if (present) {
              if (eSIR_SUCCESS != wlan_cfgGetStrLen(pMac,
                                      WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &len)) {
                 hddLog(LOGE,
                     FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
                 ret = -EFAULT;
                 vos_mem_free(ibss_ie);
                 vos_mem_free(addIEData);
                 goto exit;
              }
              if (len < WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && len &&
                 (ibss_ie_length + len) <=
                                   WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN) {

                 if ((ccmCfgGetStr(hHal,
                         WNI_CFG_PROBE_RSP_ADDNIE_DATA1, addIEData, &len))
                         != eHAL_STATUS_SUCCESS) {
                    hddLog(LOGE,
                     FL("unable fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
                    ret = -EFAULT;
                    vos_mem_free(ibss_ie);
                    vos_mem_free(addIEData);
                    goto exit;
                 }
                 else {
                    /* Curruntly only WPA IE is added before Vendor IE
                     * so we can blindly place the Vendor IE after WPA
                     * IE. If no WPA IE found replace all with Vendor IE.
                     */
                    len = hdd_find_ibss_wpa_ie_pos(addIEData, len);
                 }
              }
              else
              {
                 hddLog(LOGE,
                    FL("IE len exceed limit len %d,ibss_ie_length %d "),
                    len, ibss_ie_length);
                 ret = -EFAULT;
                 vos_mem_free(addIEData);
                 vos_mem_free(ibss_ie);
                 goto exit;
              }
           } /* probe rsp ADD IE present */
           else {
              /* probe rsp add IE is not present */
              len = 0;
           }

           vos_mem_copy(addIEData +len , ibss_ie, ibss_ie_length);
           len += ibss_ie_length;

           vos_mem_free(ibss_ie);

           if (ccmCfgSetStr(hHal,
                               WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
                               (tANI_U8*)(addIEData),
                               len, NULL,
                               eANI_BOOLEAN_FALSE)
                               == eHAL_STATUS_FAILURE) {
              hddLog(LOGE,
                  FL("unable to copy to WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
              ret = -EFAULT;
              vos_mem_free(addIEData);
              goto exit;
           }
           vos_mem_free(addIEData);
           if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
                            WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
                           eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
           {
              hddLog(LOGE,
                  FL("unable to copy WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
              ret = -EFAULT;
              goto exit;
           }
        }
       else if (strncasecmp(command, "SETRMCENABLE", 12) == 0)
       {
          tANI_U8 *value = command;
          tANI_U8 ucRmcEnable = 0;
          int  status;

          if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
              (WLAN_HDD_SOFTAP != pAdapter->device_mode))
          {
             VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "Received SETRMCENABLE command in invalid mode %d "
                "SETRMCENABLE command is only allowed in IBSS or SOFTAP mode",
                pAdapter->device_mode);
             ret = -EINVAL;
             goto exit;
          }

          status = hdd_parse_setrmcenable_command(value, &ucRmcEnable);
          if (status)
          {
             VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "Invalid SETRMCENABLE command ");
             ret = -EINVAL;
             goto exit;
          }

          VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
               "%s: ucRmcEnable %d ", __func__, ucRmcEnable);

          if (TRUE == ucRmcEnable)
          {
              status = sme_EnableRMC( (tHalHandle)(pHddCtx->hHal),
                         pAdapter->sessionId );
          }
          else if(FALSE == ucRmcEnable)
          {
              status = sme_DisableRMC( (tHalHandle)(pHddCtx->hHal),
                         pAdapter->sessionId );
          }
          else
          {
             VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "Invalid SETRMCENABLE command %d", ucRmcEnable);
             ret = -EINVAL;
             goto exit;
          }

          if (VOS_STATUS_SUCCESS != status)
          {
              VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 "%s: SETRMC %d failed status %d", __func__, ucRmcEnable,
                 status);
              ret = -EINVAL;
              goto exit;
          }
       }
       else if (strncasecmp(command, "SETRMCACTIONPERIOD", 18) == 0)
       {
          tANI_U8 *value = command;
          tANI_U32 uActionPeriod = 0;
          int  status;

          if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
              (WLAN_HDD_SOFTAP != pAdapter->device_mode))
          {
             VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "Received SETRMC command in invalid mode %d "
                "SETRMC command is only allowed in IBSS or SOFTAP mode",
                pAdapter->device_mode);
             ret = -EINVAL;
             goto exit;
          }

          status = hdd_parse_setrmcactionperiod_command(value, &uActionPeriod);
          if (status)
          {
             VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "Invalid SETRMCACTIONPERIOD command ");
             ret = -EINVAL;
             goto exit;
          }

          VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
               "%s: uActionPeriod %d ", __func__, uActionPeriod);

          if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
                 uActionPeriod, NULL, eANI_BOOLEAN_FALSE))
          {
              VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 "%s: Could not set SETRMCACTIONPERIOD %d", __func__, uActionPeriod);
              ret = -EINVAL;
              goto exit;
          }

      }
      else if (strncasecmp(command, "GETIBSSPEERINFOALL", 18) == 0)
      {
         /* Peer Info All Command */
         int status = eHAL_STATUS_SUCCESS;
         hdd_station_ctx_t *pHddStaCtx = NULL;
         char *extra = NULL;
         int idx = 0, length = 0;
         v_MACADDR_t *macAddr;
         v_U32_t txRateMbps = 0, numOfBytestoPrint = 0;

         if (WLAN_HDD_IBSS == pAdapter->device_mode)
         {
            pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
         }
         else
         {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "%s: pAdapter is not valid for this device mode",
                      __func__);
            ret = -EINVAL;
            goto exit;
         }

         VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                 "%s: Received GETIBSSPEERINFOALL Command", __func__);


         /* Handle the command */
         status = hdd_cfg80211_get_ibss_peer_info_all(pAdapter);
         if (VOS_STATUS_SUCCESS == status)
         {
            /* The variable extra needed to be allocated on the heap since
             * amount of memory required to copy the data for 32 devices
             * exceeds the size of 1024 bytes of default stack size. On
             * 64 bit devices, the default max stack size of 2048 bytes
             */
            extra = kmalloc(WLAN_MAX_BUF_SIZE, GFP_KERNEL);

            if (NULL == extra)
            {
               VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                         "%s:kmalloc failed", __func__);
               ret = -EINVAL;
               goto exit;
            }

            /* Copy number of stations */
            length = scnprintf( extra, WLAN_MAX_BUF_SIZE, "%d ",
                             pHddStaCtx->ibss_peer_info.numIBSSPeers);
            numOfBytestoPrint = length;
            for (idx = 0; idx < pHddStaCtx->ibss_peer_info.numIBSSPeers; idx++)
            {
               macAddr =
                       hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
                                         pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
               if (NULL != macAddr)
               {
                  txRateMbps =
                     ((pHddStaCtx->ibss_peer_info.ibssPeerList[idx].txRate)*500*1000)/1000000;

                  length += scnprintf( (extra + length), WLAN_MAX_BUF_SIZE - length,
                                  "%02x:%02x:%02x:%02x:%02x:%02x %d %d ",
                                  macAddr->bytes[0], macAddr->bytes[1], macAddr->bytes[2],
                                  macAddr->bytes[3], macAddr->bytes[4], macAddr->bytes[5],
                                  (int)txRateMbps,
                                  (int)pHddStaCtx->ibss_peer_info.ibssPeerList[idx].rssi);
               }
               else
               {
                  VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                             "%s: MAC ADDR is NULL for staIdx: %d", __func__,
                             pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
               }

               /*
                * VOS_TRACE() macro has limitation of 512 bytes for the print
                * buffer. Hence printing the data in two chunks. The first chunk
                * will have the data for 16 devices and the second chunk will
                * have the rest.
                */
               if (idx < NUM_OF_STA_DATA_TO_PRINT)
               {
                   numOfBytestoPrint = length;
               }
            }

            /*
             * Copy the data back into buffer, if the data to copy is
             * morethan 512 bytes than we will split the data and do
             * it in two shots
             */
            if (copy_to_user(priv_data.buf, extra, numOfBytestoPrint))
            {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                          "%s: Copy into user data buffer failed ", __func__);
               ret = -EFAULT;
               kfree(extra);
               goto exit;
            }
            priv_data.buf[numOfBytestoPrint] = '\0';
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
                      "%s", priv_data.buf);

            if (length > numOfBytestoPrint)
            {
                if (copy_to_user(priv_data.buf + numOfBytestoPrint,
                                 extra + numOfBytestoPrint,
                                 length - numOfBytestoPrint + 1))
                {
                    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                              "%s: Copy into user data buffer failed ", __func__);
                    ret = -EFAULT;
                    kfree(extra);
                    goto exit;
                }
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
                          "%s", &priv_data.buf[numOfBytestoPrint]);
            }

            /* Free temporary buffer */
            kfree(extra);
         }

         else
         {
            /* Command failed, log error */
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: GETIBSSPEERINFOALL command failed with status code %d",
                      __func__, status);
            ret = -EINVAL;
            goto exit;
         }
         ret = 0;
      }
      else if(strncasecmp(command, "GETIBSSPEERINFO", 15) == 0)
      {
         /* Peer Info <Peer Addr> command */
         tANI_U8 *value = command;
         VOS_STATUS status;
         hdd_station_ctx_t *pHddStaCtx = NULL;
         char extra[128] = { 0 };
         v_U32_t length = 0;
         v_U8_t staIdx = 0;
         v_U32_t txRateMbps = 0;
         v_MACADDR_t peerMacAddr;

         if (WLAN_HDD_IBSS == pAdapter->device_mode)
         {
            pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
         }
         else
         {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "%s: pAdapter is not valid for this device mode",
                      __func__);
            ret = -EINVAL;
            goto exit;
         }

         /* if there are no peers, no need to continue with the command */
         VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                 "%s: Received GETIBSSPEERINFO Command", __func__);

         if (eConnectionState_IbssConnected != pHddStaCtx->conn_info.connState)
         {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "%s:No IBSS Peers coalesced", __func__);
            ret = -EINVAL;
            goto exit;
         }

         /* Parse the incoming command buffer */
         status = hdd_parse_get_ibss_peer_info(value, &peerMacAddr);
         if (VOS_STATUS_SUCCESS != status)
         {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: Invalid GETIBSSPEERINFO command", __func__);
            ret = -EINVAL;
            goto exit;
         }

         /* Get station index for the peer mac address */
         hdd_Ibss_GetStaId(pHddStaCtx, &peerMacAddr, &staIdx);

         if (staIdx > HDD_MAX_NUM_IBSS_STA)
         {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: Invalid StaIdx %d returned", __func__, staIdx);
            ret = -EINVAL;
            goto exit;
         }

         /* Handle the command */
         status = hdd_cfg80211_get_ibss_peer_info(pAdapter, staIdx);
         if (VOS_STATUS_SUCCESS == status)
         {
            v_U32_t txRate = pHddStaCtx->ibss_peer_info.ibssPeerList[0].txRate;
            txRateMbps = (txRate * 500 * 1000)/1000000;

            length = scnprintf( extra, sizeof(extra), "%d %d", (int)txRateMbps,
                            (int)pHddStaCtx->ibss_peer_info.ibssPeerList[0].rssi);

            /* Copy the data back into buffer */
            if (copy_to_user(priv_data.buf, &extra, length+ 1))
            {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: copy data to user buffer failed GETIBSSPEERINFO command",
                  __func__);
               ret = -EFAULT;
               goto exit;
            }
         }
         else
         {
            /* Command failed, log error */
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: GETIBSSPEERINFO command failed with status code %d",
                      __func__, status);
            ret = -EINVAL;
            goto exit;
         }

         /* Success ! */
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
                   "%s", priv_data.buf);
         ret = 0;
       }
       else if (strncasecmp(command, "SETRMCTXRATE", 12) == 0)
       {
          tANI_U8 *value = command;
          tANI_U32 uRate = 0;
          tTxrateinfoflags txFlags = 0;
          tSirRateUpdateInd *rateUpdateParams;
          int  status;

          if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
              (WLAN_HDD_SOFTAP != pAdapter->device_mode))
           {
              VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "Received SETRMCTXRATE command in invalid mode %d "
                "SETRMC command is only allowed in IBSS or SOFTAP mode",
                pAdapter->device_mode);
              ret = -EINVAL;
              goto exit;
           }

          status = hdd_parse_setrmcrate_command(value, &uRate, &txFlags);
          if (status)
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "Invalid SETRMCTXRATE command ");
               ret = -EINVAL;
               goto exit;
           }

          rateUpdateParams = vos_mem_malloc(sizeof(tSirRateUpdateInd));
          if (NULL == rateUpdateParams)
           {
             ret = -EINVAL;
             goto exit;
           }

          VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
               "%s: uRate %d ", __func__, uRate);

          vos_mem_zero(rateUpdateParams, sizeof(tSirRateUpdateInd ));

          /* -1 implies ignore this param */
          rateUpdateParams->ucastDataRate = -1;

          /*
           * Fill the user specifieed RMC rate param
           * and the derived tx flags.
           */
          rateUpdateParams->rmcDataRate = uRate;
          rateUpdateParams->rmcDataRateTxFlag = txFlags;

          status = sme_SendRateUpdateInd((tHalHandle)(pHddCtx->hHal), rateUpdateParams);
       }
       else if (strncasecmp(command, "SETIBSSTXFAILEVENT", 18) == 0 )
       {
           char *value;
           tANI_U8 tx_fail_count = 0;
           tANI_U16 pid = 0;

           value = command;

           ret = hdd_ParseIBSSTXFailEventParams(value, &tx_fail_count, &pid);

           if (0 != ret)
           {
              hddLog(VOS_TRACE_LEVEL_INFO,
                     "%s: Failed to parse SETIBSSTXFAILEVENT arguments",
                     __func__);
              goto exit;
           }

           hddLog(VOS_TRACE_LEVEL_INFO, "%s: tx_fail_cnt=%hhu, pid=%hu",
                   __func__, tx_fail_count, pid);

           if (0 == tx_fail_count)
           {
               // Disable TX Fail Indication
               if (eHAL_STATUS_SUCCESS  ==
                   sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
                                                 tx_fail_count,
                                                 NULL))
               {
                   cesium_pid = 0;
           }
               else
               {
                   VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                             "%s: failed to disable TX Fail Event ", __func__);
                   ret = -EINVAL;
       }
           }
           else
       {
               if (eHAL_STATUS_SUCCESS  ==
                   sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
                                                 tx_fail_count,
                                           (void*)hdd_tx_fail_ind_callback))
               {
                   cesium_pid = pid;
                   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                             "%s: Registered Cesium pid %u", __func__,
                             cesium_pid);
       }
               else
               {
                   VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                             "%s: Failed to enable TX Fail Monitoring", __func__);
                   ret = -EINVAL;
               }
           }
       }

#endif /* WLAN_FEATURE_RMC */
#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
       else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
       {
           tANI_U8 *value = command;
           tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
           tANI_U8 numChannels = 0;
           eHalStatus status = eHAL_STATUS_SUCCESS;

           status = hdd_parse_channellist(value, ChannelList, &numChannels);
           if (eHAL_STATUS_SUCCESS != status)
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Failed to parse channel list information", __func__);
               ret = -EINVAL;
               goto exit;
           }

           if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: number of channels (%d) supported exceeded max (%d)", __func__,
                   numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
               ret = -EINVAL;
               goto exit;
           }
           status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
                                                  ChannelList,
                                                  numChannels);
           if (eHAL_STATUS_SUCCESS != status)
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Failed to update channel list information", __func__);
               ret = -EINVAL;
               goto exit;
           }
       }
       else if (strncmp(command, "GETTSMSTATS", 11) == 0)
       {
           tANI_U8            *value = command;
           char                extra[128] = {0};
           int                 len = 0;
           tANI_U8             tid = 0;
           hdd_station_ctx_t  *pHddStaCtx = NULL;
           tAniTrafStrmMetrics tsmMetrics;
           pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

           ret = hdd_drv_cmd_validate(command, 11);
           if (ret)
               goto exit;

           /* if not associated, return error */
           if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
           {
               VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
               ret = -EINVAL;
               goto exit;
           }

           /* Move pointer to ahead of GETTSMSTATS<delimiter> */
           value = value + 12;
           /* Convert the value from ascii to integer */
           ret = kstrtou8(value, 10, &tid);
           if (ret < 0)
           {
               /* If the input value is greater than max value of datatype, then also
                  kstrtou8 fails */
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: kstrtou8 failed range [%d - %d]", __func__,
                      TID_MIN_VALUE,
                      TID_MAX_VALUE);
               ret = -EINVAL;
               goto exit;
           }

           if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "tid value %d is out of range"
                      " (Min: %d Max: %d)", tid,
                      TID_MIN_VALUE,
                      TID_MAX_VALUE);
               ret = -EINVAL;
               goto exit;
           }

           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "%s: Received Command to get tsm stats tid = %d", __func__, tid);

           if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to get tsm stats", __func__);
               ret = -EFAULT;
               goto exit;
           }

           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                          "UplinkPktQueueDly(%d)\n"
                          "UplinkPktQueueDlyHist[0](%d)\n"
                          "UplinkPktQueueDlyHist[1](%d)\n"
                          "UplinkPktQueueDlyHist[2](%d)\n"
                          "UplinkPktQueueDlyHist[3](%d)\n"
                          "UplinkPktTxDly(%u)\n"
                          "UplinkPktLoss(%d)\n"
                          "UplinkPktCount(%d)\n"
                          "RoamingCount(%d)\n"
                          "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
                          tsmMetrics.UplinkPktQueueDlyHist[0],
                          tsmMetrics.UplinkPktQueueDlyHist[1],
                          tsmMetrics.UplinkPktQueueDlyHist[2],
                          tsmMetrics.UplinkPktQueueDlyHist[3],
                          tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
                          tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);

           /* Output TSM stats is of the format
                   GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
                   eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
           len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
                  tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
                  tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
                  tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
                  tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
                  tsmMetrics.RoamingDly);

           len = VOS_MIN(priv_data.total_len, len + 1);
           if (copy_to_user(priv_data.buf, &extra, len)) {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto exit;
           }
       }
       else if (strncmp(command, "SETCCKMIE", 9) == 0)
       {
           tANI_U8 *value = command;
           tANI_U8 *cckmIe = NULL;
           tANI_U8 cckmIeLen = 0;
           eHalStatus status = eHAL_STATUS_SUCCESS;

           status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
           if (eHAL_STATUS_SUCCESS != status)
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Failed to parse cckm ie data", __func__);
               ret = -EINVAL;
               goto exit;
           }

           if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: CCKM Ie input length is more than max[%d]", __func__,
                  DOT11F_IE_RSN_MAX_LEN);
               vos_mem_free(cckmIe);
               cckmIe = NULL;
               ret = -EINVAL;
               goto exit;
           }
           sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
           vos_mem_free(cckmIe);
           cckmIe = NULL;
       }
       else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
       {
           tANI_U8 *value = command;
           tCsrEseBeaconReq eseBcnReq;
           eHalStatus status = eHAL_STATUS_SUCCESS;

           status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
           if (eHAL_STATUS_SUCCESS != status)
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Failed to parse ese beacon req", __func__);
               ret = -EINVAL;
               goto exit;
           }
           if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
               hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
               hdd_indicateEseBcnReportNoResults (pAdapter,
                                      eseBcnReq.bcnReq[0].measurementToken,
                                      0x02,  //BIT(1) set for measurement done
                                      0);    // no BSS
               goto exit;
           }

           status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
           if (eHAL_STATUS_SUCCESS != status)
           {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
               ret = -EINVAL;
               goto exit;
           }
       }
#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
       else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
       {
           eHalStatus status;
           char buf[32], len;
           void *cookie;
           struct hdd_request *request;
           struct bcn_miss_rate_priv *priv;
           static const struct hdd_request_params params = {
               .priv_size = sizeof(*priv),
               .timeout_ms = WLAN_WAIT_TIME_STATS,
           };

           hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

           if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
           {
               hddLog(VOS_TRACE_LEVEL_WARN,
                    FL("GETBCNMISSRATE: STA is not in connected state"));
               ret = -1;
               goto exit;
           }
           request = hdd_request_alloc(&params);
           if (!request) {
               hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
               ret = -ENOMEM;
               goto exit;
           }
           cookie = hdd_request_cookie(request);
           priv = hdd_request_priv(request);
           priv->bcn_miss_rate = -1;

           status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
                                       pAdapter->sessionId,
                                       (void *)get_bcn_miss_rate_cb,
                                       cookie);
           if( eHAL_STATUS_SUCCESS != status)
           {
               hddLog(VOS_TRACE_LEVEL_INFO,
                    FL("GETBCNMISSRATE: fail to post WDA cmd"));
                ret = -EINVAL;
                goto free_bcn_miss_rate_req;
           }

           ret = hdd_request_wait_for_response(request);
           if(ret)
           {
               hddLog(VOS_TRACE_LEVEL_ERROR,
                         FL("failed to wait on bcnMissRateComp %d"), ret);

               ret = -EINVAL;
               goto free_bcn_miss_rate_req;
           }

           hddLog(VOS_TRACE_LEVEL_INFO,
                  FL("GETBCNMISSRATE: bcnMissRate: %d"), priv->bcn_miss_rate);

           if (priv->bcn_miss_rate == -1) {
               ret = -EFAULT;
               goto free_bcn_miss_rate_req;
           }

           len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d",
                          priv->bcn_miss_rate);
           if (copy_to_user(priv_data.buf, &buf, len + 1))
           {
               hddLog(VOS_TRACE_LEVEL_ERROR,
                     "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto free_bcn_miss_rate_req;
           }
           ret = len;

free_bcn_miss_rate_req:
           hdd_request_put(request);
       }
#ifdef FEATURE_WLAN_TDLS
       else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
           tANI_U8 *value = command;
           int set_value;

           ret = hdd_drv_cmd_validate(command, 26);
           if (ret)
               goto exit;

           /* Move pointer to ahead of TDLSOFFCH*/
           value += 26;
           if (!(sscanf(value, "%d", &set_value))) {
               VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                               FL("No input identified"));
               ret = -EINVAL;
               goto exit;
           }

           VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                     "%s: Tdls offchannel offset:%d",
                     __func__, set_value);
           ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
           if (ret < 0)
           {
               ret = -EINVAL;
               goto exit;
           }

       } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
           tANI_U8 *value = command;
           int set_value;

           ret = hdd_drv_cmd_validate(command, 18);
           if (ret)
               goto exit;

           /* Move pointer to ahead of tdlsoffchnmode*/
           value += 18;
           ret = sscanf(value, "%d", &set_value);
           if (ret != 1) {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                           FL("No input identified"));
               ret = -EINVAL;
               goto exit;
           }
           VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                     "%s: Tdls offchannel mode:%d",
                     __func__, set_value);
           ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
           if (ret < 0)
           {
               ret = -EINVAL;
               goto exit;
           }
       } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
           tANI_U8 *value = command;
           int set_value;

           ret = hdd_drv_cmd_validate(command, 14);
           if (ret)
               goto exit;

           /* Move pointer to ahead of TDLSOFFCH*/
           value += 14;
           ret = sscanf(value, "%d", &set_value);
           if (ret != 1) {
              VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                     "Wrong value is given for hdd_set_tdls_offchannel");
               ret = -EINVAL;
               goto exit;
           }

           VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                     "%s: Tdls offchannel num: %d",
                     __func__, set_value);
           ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
           if (ret < 0)
           {
               ret = -EINVAL;
               goto exit;
           }
       }
#endif
       else if (strncmp(command, "GETFWSTATS", 10) == 0)
       {
           eHalStatus status;
           char *buf = NULL;
           char len;
           tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp),
                             *fw_stats_result;
           tANI_U8 *ptr = command;
           int stats;
           void *cookie;
           struct hdd_request *request;
           struct fw_stats_priv *priv;
           static const struct hdd_request_params params = {
               .priv_size = sizeof(*priv),
               .timeout_ms = WLAN_WAIT_TIME_STATS,
           };

           ret = hdd_drv_cmd_validate(command, 10);
           if (ret)
               goto exit;

           stats = *(ptr + 11) - '0';
           hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
           if (!IS_FEATURE_FW_STATS_ENABLE)
           {
               hddLog(VOS_TRACE_LEVEL_INFO,
                     FL("Get Firmware stats feature not supported"));
               ret = -EINVAL;
               goto exit;
           }

           if (FW_STATS_MAX <= stats || 0 >= stats)
           {
               hddLog(VOS_TRACE_LEVEL_INFO,
                        FL(" stats %d not supported"),stats);
               ret = -EINVAL;
               goto exit;
           }

           request = hdd_request_alloc(&params);
           if (!request) {
               hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
               ret = -ENOMEM;
               goto exit;
           }
           cookie = hdd_request_cookie(request);

           status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
                                   cookie, hdd_fw_stats_cb);
           if (eHAL_STATUS_SUCCESS != status)
           {
               hddLog(VOS_TRACE_LEVEL_ERROR,
                       FL(" fail to post WDA cmd status = %d"), status);
               ret = -EINVAL;
               hdd_request_put(request);
               goto exit;
           }
           ret = hdd_request_wait_for_response(request);
           if (ret)
           {
               hddLog(VOS_TRACE_LEVEL_ERROR,
                        FL("failed to wait on GwtFwstats"));
               ret = -EINVAL;
               hdd_request_put(request);
               goto exit;
           }

           priv = hdd_request_priv(request);
           fw_stats_result = priv->fw_stats;
           fwStatsRsp->type = 0;
           if (NULL != fw_stats_result)
           {
               switch (fw_stats_result->type )
               {
                   case FW_UBSP_STATS:
                   {
                       tSirUbspFwStats *stats =
                               &fwStatsRsp->fwStatsData.ubspStats;
                       memcpy(fwStatsRsp, fw_stats_result,
                              sizeof(tSirFwStatsResult));
                       hddLog(VOS_TRACE_LEVEL_INFO,
                              FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
                                 stats->ubsp_enter_cnt,
                                 stats->ubsp_jump_ddr_cnt);
                   }
                   break;

                   default:
                   {
                       hddLog(VOS_TRACE_LEVEL_ERROR,
                              FL("No handling for stats type %d"),
                                 fw_stats_result->type);
                   }
               }
           }
           hdd_request_put(request);

           if (fwStatsRsp->type)
           {
               buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
               if (!buf)
               {
                 hddLog(VOS_TRACE_LEVEL_ERROR,
                       FL(" failed to allocate memory"));
                 ret = -ENOMEM;
                 goto exit;
               }
               switch( fwStatsRsp->type )
               {
                   case FW_UBSP_STATS:
                   {
                        len = snprintf(buf, FW_STATE_RSP_LEN,
                              "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
                              fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
                              fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
                   }
                   break;
                   default:
                   {
                        hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
                        ret = -EFAULT;
                        kfree(buf);
                        goto exit;
                   }
               }
               if (copy_to_user(priv_data.buf, buf, len + 1))
               {
                   hddLog(VOS_TRACE_LEVEL_ERROR,
                      FL(" failed to copy data to user buffer"));
                   ret = -EFAULT;
                   kfree(buf);
                   goto exit;
               }
               ret = len;
               kfree(buf);
           }
           else
           {
               hddLog(VOS_TRACE_LEVEL_ERROR,
                   FL("failed to fetch the stats"));
               ret = -EFAULT;
               goto exit;
           }
       }
       else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
       {
           ret = hdd_drv_cmd_validate(command, 15);
           if (ret)
               goto exit;

          /*
           * this command wld be called by user-space when it detects WLAN
           * ON after airplane mode is set. When APM is set, WLAN turns off.
           * But it can be turned back on. Otherwise; when APM is turned back
           * off, WLAN wld turn back on. So at that point the command is
           * expected to come down. 0 means disable, 1 means enable. The
           * constraint is removed when parameter 1 is set or different
           * country code is set
           */
           ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
       }
       else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
       {
           ret = hdd_drv_cmd_validate(command, 16);
           if (ret)
               goto exit;

           ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
       }
       /*
        * command should be a string having format
        * SET_DISABLE_CHANNEL_LIST <num of channels>
        * <channels separated by spaces>
        */
       else if (strncmp(command, "SET_DISABLE_CHANNEL_LIST", 24) == 0) {
            tANI_U8 *ptr = command;
            ret = hdd_drv_cmd_validate(command, 24);
            if (ret)
                goto exit;

            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                " Received Command to disable Channels %s",
                __func__);
            ret = hdd_parse_disable_chan_cmd(pAdapter, ptr);
            if (ret)
                goto exit;
       }
       else if (strncmp(command, "GET_DISABLE_CHANNEL_LIST", 24) == 0) {
            char extra[512] = {0};
            int max_len, copied_length;

            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                " Received Command to get disable Channels list %s",
                __func__);

            max_len = VOS_MIN(priv_data.total_len, sizeof(extra));
            copied_length = hdd_get_disable_ch_list(pHddCtx, extra, max_len);
            if (copied_length == 0) {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                          FL("disable channel list are not yet programed"));
                ret = -EINVAL;
                goto exit;
            }

            if (copy_to_user(priv_data.buf, &extra, copied_length + 1)) {
                VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                          "%s: failed to copy data to user buffer", __func__);
               ret = -EFAULT;
               goto exit;
            }

            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      FL("data:%s"), extra);
       }
       else {
           MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                            TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
                            pAdapter->sessionId, 0));
           hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
                   command);
       }
   }
exit:
   EXIT();
   if (command)
   {
       kfree(command);
   }
   return ret;
}

#ifdef CONFIG_COMPAT
static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
{
   struct {
      compat_uptr_t buf;
      int used_len;
      int total_len;
   } compat_priv_data;
   hdd_priv_data_t priv_data;
   int ret = 0;

   /*
    * Note that pAdapter and ifr have already been verified by caller,
    * and HDD context has also been validated
    */
   if (copy_from_user(&compat_priv_data, ifr->ifr_data,
                      sizeof(compat_priv_data))) {
       ret = -EFAULT;
       goto exit;
   }
   priv_data.buf = compat_ptr(compat_priv_data.buf);
   priv_data.used_len = compat_priv_data.used_len;
   priv_data.total_len = compat_priv_data.total_len;
   ret = hdd_driver_command(pAdapter, &priv_data);
 exit:
   return ret;
}
#else /* CONFIG_COMPAT */
static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
{
   /* will never be invoked */
   return 0;
}
#endif /* CONFIG_COMPAT */

static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
{
   hdd_priv_data_t priv_data;
   int ret = 0;

   /*
    * Note that pAdapter and ifr have already been verified by caller,
    * and HDD context has also been validated
    */
   if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
       ret = -EFAULT;
   } else {
      ret = hdd_driver_command(pAdapter, &priv_data);
   }
   return ret;
}

int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
   hdd_adapter_t *pAdapter;
   hdd_context_t *pHddCtx;
   int ret;

   ENTER();

   pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
   if (NULL == pAdapter) {
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                 "%s: HDD adapter context is Null", __func__);
      ret = -ENODEV;
      goto exit;
   }
   if (dev != pAdapter->dev) {
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                 "%s: HDD adapter/dev inconsistency", __func__);
      ret = -ENODEV;
      goto exit;
   }

   if ((!ifr) || (!ifr->ifr_data)) {
      ret = -EINVAL;
      goto exit;
   }

   pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
   ret = wlan_hdd_validate_context(pHddCtx);
   if (ret) {
      ret = -EBUSY;
      goto exit;
   }

   switch (cmd) {
   case (SIOCDEVPRIVATE + 1):
      if (is_compat_task())
         ret = hdd_driver_compat_ioctl(pAdapter, ifr);
      else
         ret = hdd_driver_ioctl(pAdapter, ifr);
      break;
   default:
      hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
             __func__, cmd);
      ret = -EINVAL;
      break;
   }
 exit:
   EXIT();
   return ret;
}

int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __hdd_ioctl(dev, ifr, cmd);
    vos_ssr_unprotect(__func__);

    return ret;
}

int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
  return 0;
}

#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
/**---------------------------------------------------------------------------

  \brief hdd_parse_ese_beacon_req() - Parse ese beacon request

  This function parses the ese beacon request passed in the format
  CCXBEACONREQ<space><Number of fields><space><Measurement token>
  <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
  <space>Scan Mode N<space>Meas Duration N
  if the Number of bcn req fields (N) does not match with the actual number of fields passed
  then take N.
  <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
  For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
  This function does not take care of removing duplicate channels from the list

  \param  - pValue Pointer to data
  \param  - pEseBcnReq output pointer to store parsed ie information

  \return - 0 for success non-zero for failure

  --------------------------------------------------------------------------*/
static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
                                     tCsrEseBeaconReq *pEseBcnReq)
{
    tANI_U8 *inPtr = pValue;
    uint8_t input = 0;
    uint32_t tempInt = 0;
    int j = 0, i = 0, v = 0;
    char buf[32];

    inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
    /*no argument after the command*/
    if (NULL == inPtr)
    {
        return -EINVAL;
    }
    /*no space after the command*/
    else if (SPACE_ASCII_VALUE != *inPtr)
    {
        return -EINVAL;
    }

    /*removing empty spaces*/
    while ((SPACE_ASCII_VALUE  == *inPtr) && ('\0' !=  *inPtr)) inPtr++;

    /*no argument followed by spaces*/
    if ('\0' == *inPtr) return -EINVAL;

    /*getting the first argument ie measurement token*/
    v = sscanf(inPtr, "%31s ", buf);
    if (1 != v) return -EINVAL;

    v = kstrtos8(buf, 10, &input);
    if ( v < 0) return -EINVAL;

    input = VOS_MIN(input, SIR_ESE_MAX_MEAS_IE_REQS);
    pEseBcnReq->numBcnReqIe = input;

    hddLog(LOG1, "Number of Bcn Req Ie fields: %d", pEseBcnReq->numBcnReqIe);


    for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
    {
        for (i = 0; i < 4; i++)
        {
            /*inPtr pointing to the beginning of first space after number of ie fields*/
            inPtr = strpbrk( inPtr, " " );
            /*no ie data after the number of ie fields argument*/
            if (NULL == inPtr) return -EINVAL;

            /*removing empty space*/
            while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;

            /*no ie data after the number of ie fields argument and spaces*/
            if ( '\0' == *inPtr ) return -EINVAL;

            v = sscanf(inPtr, "%31s ", buf);
            if (1 != v) return -EINVAL;

            v = kstrtou32(buf, 10, &tempInt);
            if (v < 0) return -EINVAL;

            switch (i)
            {
                case 0:  /* Measurement token */
                if (!tempInt)
                {
                   VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                             "Invalid Measurement Token: %u", tempInt);
                   return -EINVAL;
                }
                pEseBcnReq->bcnReq[j].measurementToken = tempInt;
                break;

                case 1:  /* Channel number */
                if ((!tempInt) ||
                    (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
                {
                   VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                             "Invalid Channel Number: %u", tempInt);
                   return -EINVAL;
                }
                pEseBcnReq->bcnReq[j].channel = tempInt;
                break;

                case 2:  /* Scan mode */
                if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
                {
                   VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                             "Invalid Scan Mode(%u) Expected{0|1|2}", tempInt);
                   return -EINVAL;
                }
                pEseBcnReq->bcnReq[j].scanMode= tempInt;
                break;

                case 3:  /* Measurement duration */
                if (((!tempInt) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
                    ((pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
                {
                   VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                             "Invalid Measurement Duration: %u", tempInt);
                   return -EINVAL;
                }
                pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
                break;
            }
        }
    }

    for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                   "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
                   j,
                   pEseBcnReq->bcnReq[j].measurementToken,
                   pEseBcnReq->bcnReq[j].channel,
                   pEseBcnReq->bcnReq[j].scanMode,
                   pEseBcnReq->bcnReq[j].measurementDuration);
    }

    return VOS_STATUS_SUCCESS;
}

struct tsm_priv {
	tAniTrafStrmMetrics tsm_metrics;
};

static void hdd_get_tsm_stats_cb(tAniTrafStrmMetrics tsm_metrics,
				 const tANI_U32 sta_id, void *context )
{
	struct hdd_request *request;
	struct tsm_priv *priv;

	ENTER();

	request = hdd_request_get(context);
	if (!request) {
		hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
		return;
	}

	priv = hdd_request_priv(request);
	priv->tsm_metrics = tsm_metrics;

	hdd_request_complete(request);
	hdd_request_put(request);

	EXIT();
}

static VOS_STATUS  hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
                                         tAniTrafStrmMetrics* pTsmMetrics)
{
   hdd_station_ctx_t *pHddStaCtx = NULL;
   eHalStatus         hstatus;
   VOS_STATUS         vstatus = VOS_STATUS_SUCCESS;
   hdd_context_t     *pHddCtx = NULL;
   int ret;
   void *cookie;
   struct hdd_request *request;
   struct tsm_priv *priv;
   static const struct hdd_request_params params = {
        .priv_size = sizeof(*priv),
        .timeout_ms = WLAN_WAIT_TIME_STATS,
   };

   if (NULL == pAdapter)
   {
       hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
       return VOS_STATUS_E_FAULT;
   }

   pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
   pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

   request = hdd_request_alloc(&params);
   if (!request) {
           hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
           return VOS_STATUS_E_NOMEM;
   }
   cookie = hdd_request_cookie(request);

   /* query tsm stats */
   hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_get_tsm_stats_cb,
                         pHddStaCtx->conn_info.staId[ 0 ],
                         pHddStaCtx->conn_info.bssId,
                         cookie, pHddCtx->pvosContext, tid);

   if (eHAL_STATUS_SUCCESS != hstatus)
   {
      hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
             __func__);
      vstatus = VOS_STATUS_E_FAULT;
   }
   else
   {
      /* request was sent -- wait for the response */
      ret = hdd_request_wait_for_response(request);
      if (ret) {
         hddLog(VOS_TRACE_LEVEL_ERROR,
                "SME timeout while retrieving statistics");
         vstatus = VOS_STATUS_E_TIMEOUT;
      } else {
         priv = hdd_request_priv(request);
         *pTsmMetrics = priv->tsm_metrics;
      }
   }

   hdd_request_put(request);

   return vstatus;
}
#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */

#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
{
    eCsrBand band = -1;
    sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
    switch (band)
    {
        case eCSR_BAND_ALL:
            *pBand = WLAN_HDD_UI_BAND_AUTO;
            break;

        case eCSR_BAND_24:
            *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
            break;

        case eCSR_BAND_5G:
            *pBand = WLAN_HDD_UI_BAND_5_GHZ;
            break;

        default:
            hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
            *pBand = -1;
            break;
    }
}

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

  \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data

  This function parses the send action frame data passed in the format
  SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>

  \param  - pValue Pointer to input data
  \param  - pTargetApBssid Pointer to target Ap bssid
  \param  - pChannel Pointer to the Target AP channel
  \param  - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
  \param  - pBuf Pointer to data
  \param  - pBufLen Pointer to data length

  \return - 0 for success non-zero for failure

  --------------------------------------------------------------------------*/
VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
                                            tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
{
    tANI_U8 *inPtr = pValue;
    tANI_U8 *dataEnd;
    int tempInt;
    int j = 0;
    int i = 0;
    int v = 0;
    tANI_U8 tempBuf[32];
    tANI_U8 tempByte = 0;
    /* 12 hexa decimal digits, 5 ':' and '\0' */
    tANI_U8 macAddress[18];

    inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
    /*no argument after the command*/
    if (NULL == inPtr)
    {
        return -EINVAL;
    }

    /*no space after the command*/
    else if (SPACE_ASCII_VALUE != *inPtr)
    {
        return -EINVAL;
    }

    /*removing empty spaces*/
    while ((SPACE_ASCII_VALUE  == *inPtr) && ('\0' !=  *inPtr) ) inPtr++;

    /*no argument followed by spaces*/
    if ('\0' == *inPtr)
    {
        return -EINVAL;
    }

    v = sscanf(inPtr, "%17s", macAddress);
    if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
             "Invalid MAC address or All hex inputs are not read (%d)", v);
        return -EINVAL;
    }

    pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
    pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
    pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
    pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
    pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
    pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);

    /* point to the next argument */
    inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
    /*no argument after the command*/
    if (NULL == inPtr) return -EINVAL;

    /*removing empty spaces*/
    while ((SPACE_ASCII_VALUE  == *inPtr) && ('\0' !=  *inPtr) ) inPtr++;

    /*no argument followed by spaces*/
    if ('\0' == *inPtr)
    {
        return -EINVAL;
    }

    /*getting the next argument ie the channel number */
    v = sscanf(inPtr, "%31s ", tempBuf);
    if (1 != v) return -EINVAL;

    v = kstrtos32(tempBuf, 10, &tempInt);
    if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
     return -EINVAL;

    *pChannel = tempInt;

    /* point to the next argument */
    inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
    /*no argument after the command*/
    if (NULL == inPtr) return -EINVAL;
    /*removing empty spaces*/
    while ((SPACE_ASCII_VALUE  == *inPtr) && ('\0' !=  *inPtr) ) inPtr++;

    /*no argument followed by spaces*/
    if ('\0' == *inPtr)
    {
        return -EINVAL;
    }

    /*getting the next argument ie the dwell time */
    v = sscanf(inPtr, "%31s ", tempBuf);
    if (1 != v) return -EINVAL;

    v = kstrtos32(tempBuf, 10, &tempInt);
    if ( v < 0 || tempInt < 0) return -EINVAL;

    *pDwellTime = tempInt;

    /* point to the next argument */
    inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
    /*no argument after the command*/
    if (NULL == inPtr) return -EINVAL;
    /*removing empty spaces*/
    while ((SPACE_ASCII_VALUE  == *inPtr) && ('\0' !=  *inPtr) ) inPtr++;

    /*no argument followed by spaces*/
    if ('\0' == *inPtr)
    {
        return -EINVAL;
    }

    /* find the length of data */
    dataEnd = inPtr;
    while(('\0' !=  *dataEnd) )
    {
        dataEnd++;
    }
    *pBufLen = dataEnd - inPtr ;
    if ( *pBufLen <= 0)  return -EINVAL;

    /* Allocate the number of bytes based on the number of input characters
       whether it is even or odd.
       if the number of input characters are even, then we need N/2 byte.
       if the number of input characters are odd, then we need do (N+1)/2 to
       compensate rounding off.
       For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
       If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
    *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
    if (NULL == *pBuf)
    {
        hddLog(VOS_TRACE_LEVEL_FATAL,
           "%s: vos_mem_alloc failed ", __func__);
        return -EINVAL;
    }

    /* the buffer received from the upper layer is character buffer,
       we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
       for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
       and f0 in 3rd location */
    for (i = 0, j = 0; j < *pBufLen; j += 2)
    {
        if( j+1 == *pBufLen)
        {
             tempByte = hdd_parse_hex(inPtr[j]);
        }
        else
        {
              tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
        }
        (*pBuf)[i++] = tempByte;
    }
    *pBufLen = i;
    return VOS_STATUS_SUCCESS;
}

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

  \brief hdd_parse_channellist() - HDD Parse channel list

  This function parses the channel list passed in the format
  SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
  if the Number of channels (N) does not match with the actual number of channels passed
  then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
  For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
  If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
  This function does not take care of removing duplicate channels from the list

  \param  - pValue Pointer to input channel list
  \param  - ChannelList Pointer to local output array to record channel list
  \param  - pNumChannels Pointer to number of roam scan channels

  \return - 0 for success non-zero for failure

  --------------------------------------------------------------------------*/
VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
{
    tANI_U8 *inPtr = pValue;
    int tempInt;
    int j = 0;
    int v = 0;
    char buf[32];

    inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
    /*no argument after the command*/
    if (NULL == inPtr)
    {
        return -EINVAL;
    }

    /*no space after the command*/
    else if (SPACE_ASCII_VALUE != *inPtr)
    {
        return -EINVAL;
    }

    /*removing empty spaces*/
    while ((SPACE_ASCII_VALUE  == *inPtr) && ('\0' !=  *inPtr)) inPtr++;

    /*no argument followed by spaces*/
    if ('\0' == *inPtr)
    {
        return -EINVAL;
    }

    /*getting the first argument ie the number of channels*/
    v = sscanf(inPtr, "%31s ", buf);
    if (1 != v) return -EINVAL;

    v = kstrtos32(buf, 10, &tempInt);
    if ((v < 0) ||
        (tempInt <= 0) ||
        (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
    {
       return -EINVAL;
    }

    *pNumChannels = tempInt;

    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
               "Number of channels are: %d", *pNumChannels);

    for (j = 0; j < (*pNumChannels); j++)
    {
        /*inPtr pointing to the beginning of first space after number of channels*/
        inPtr = strpbrk( inPtr, " " );
        /*no channel list after the number of channels argument*/
        if (NULL == inPtr)
        {
            if (0 != j)
            {
                *pNumChannels = j;
                return VOS_STATUS_SUCCESS;
            }
            else
            {
                return -EINVAL;
            }
        }

        /*removing empty space*/
        while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;

        /*no channel list after the number of channels argument and spaces*/
        if ( '\0' == *inPtr )
        {
            if (0 != j)
            {
                *pNumChannels = j;
                return VOS_STATUS_SUCCESS;
            }
            else
            {
                return -EINVAL;
            }
        }

        v = sscanf(inPtr, "%31s ", buf);
        if (1 != v) return -EINVAL;

        v = kstrtos32(buf, 10, &tempInt);
        if ((v < 0) ||
            (tempInt <= 0) ||
            (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
        {
           return -EINVAL;
        }
        pChannelList[j] = tempInt;

        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
                   "Channel %d added to preferred channel list",
                   pChannelList[j] );
    }

    return VOS_STATUS_SUCCESS;
}


/**
 * hdd_parse_reassoc_command_v1_data() - HDD Parse reassoc command data
 *    This function parses the reasoc command data passed in the format
 *    REASSOC<space><bssid><space><channel>
 *
 * @pValue: Pointer to input data (its a NUL terminated string)
 * @pTargetApBssid: Pointer to target Ap bssid
 * @pChannel: Pointer to the Target AP channel
 *
 * Return: 0 for success non-zero for failure
 */
static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
				tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
{
    const tANI_U8 *inPtr = pValue;
    int tempInt;
    int v = 0;
    tANI_U8 tempBuf[32];
    /* 12 hexa decimal digits, 5 ':' and '\0' */
    tANI_U8 macAddress[18];

    inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
    /*no argument after the command*/
    if (NULL == inPtr)
    {
        return -EINVAL;
    }

    /*no space after the command*/
    else if (SPACE_ASCII_VALUE != *inPtr)
    {
        return -EINVAL;
    }

    /*removing empty spaces*/
    while ((SPACE_ASCII_VALUE  == *inPtr) && ('\0' !=  *inPtr) ) inPtr++;

    /*no argument followed by spaces*/
    if ('\0' == *inPtr)
    {
        return -EINVAL;
    }

    v = sscanf(inPtr, "%17s", macAddress);
    if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
             "Invalid MAC address or All hex inputs are not read (%d)", v);
        return -EINVAL;
    }

    pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
    pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
    pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
    pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
    pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
    pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);

    /* point to the next argument */
    inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
    /*no argument after the command*/
    if (NULL == inPtr) return -EINVAL;

    /*removing empty spaces*/
    while ((SPACE_ASCII_VALUE  == *inPtr) && ('\0' !=  *inPtr) ) inPtr++;

    /*no argument followed by spaces*/
    if ('\0' == *inPtr)
    {
        return -EINVAL;
    }

    /*getting the next argument ie the channel number */
    v = sscanf(inPtr, "%31s ", tempBuf);
    if (1 != v) return -EINVAL;

    v = kstrtos32(tempBuf, 10, &tempInt);
    if ((v < 0) ||
        (tempInt < 0) ||
        (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
    {
        return -EINVAL;
    }

    *pChannel = tempInt;
    return VOS_STATUS_SUCCESS;
}

#endif

#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
/**---------------------------------------------------------------------------

  \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE

  This function parses the SETCCKM IE command
  SETCCKMIE<space><ie data>

  \param  - pValue Pointer to input data
  \param  - pCckmIe Pointer to output cckm Ie
  \param  - pCckmIeLen Pointer to output cckm ie length

  \return - 0 for success non-zero for failure

  --------------------------------------------------------------------------*/
VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
                                 tANI_U8 *pCckmIeLen)
{
    tANI_U8 *inPtr = pValue;
    tANI_U8 *dataEnd;
    int      j = 0;
    int      i = 0;
    tANI_U8  tempByte = 0;

    inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
    /*no argument after the command*/
    if (NULL == inPtr)
    {
        return -EINVAL;
    }

    /*no space after the command*/
    else if (SPACE_ASCII_VALUE != *inPtr)
    {
        return -EINVAL;
    }

    /*removing empty spaces*/
    while ((SPACE_ASCII_VALUE  == *inPtr) && ('\0' !=  *inPtr) ) inPtr++;

    /*no argument followed by spaces*/
    if ('\0' == *inPtr)
    {
        return -EINVAL;
    }

    /* find the length of data */
    dataEnd = inPtr;
    while(('\0' !=  *dataEnd) )
    {
        dataEnd++;
        ++(*pCckmIeLen);
    }
    if ( *pCckmIeLen <= 0)  return -EINVAL;

    /* Allocate the number of bytes based on the number of input characters
       whether it is even or odd.
       if the number of input characters are even, then we need N/2 byte.
       if the number of input characters are odd, then we need do (N+1)/2 to
       compensate rounding off.
       For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
       If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
    *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
    if (NULL == *pCckmIe)
    {
        hddLog(VOS_TRACE_LEVEL_FATAL,
           "%s: vos_mem_alloc failed ", __func__);
        return -EINVAL;
    }
    vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
    /* the buffer received from the upper layer is character buffer,
       we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
       for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
       and f0 in 3rd location */
    for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
    {
        tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
        (*pCckmIe)[i++] = tempByte;
    }
    *pCckmIeLen = i;

    return VOS_STATUS_SUCCESS;
}
#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */

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

  \brief hdd_is_valid_mac_address() - Validate MAC address

  This function validates whether the given MAC address is valid or not
  Expected MAC address is of the format XX:XX:XX:XX:XX:XX
  where X is the hexa decimal digit character and separated by ':'
  This algorithm works even if MAC address is not separated by ':'

  This code checks given input string mac contains exactly 12 hexadecimal digits.
  and a separator colon : appears in the input string only after
  an even number of hex digits.

  \param  - pMacAddr pointer to the input MAC address
  \return - 1 for valid and 0 for invalid

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

v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
{
    int xdigit = 0;
    int separator = 0;
    while (*pMacAddr)
    {
        if (isxdigit(*pMacAddr))
        {
            xdigit++;
        }
        else if (':' == *pMacAddr)
        {
            if (0 == xdigit || ((xdigit / 2) - 1) != separator)
                break;

            ++separator;
        }
        else
        {
            separator = -1;
            /* Invalid MAC found */
            return 0;
        }
        ++pMacAddr;
    }
    return (xdigit == 12 && (separator == 5 || separator == 0));
}

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

  \brief __hdd_open() - HDD Open function

  \param  - dev Pointer to net_device structure

  \return - 0 for success non-zero for failure

  --------------------------------------------------------------------------*/
int __hdd_open(struct net_device *dev)
{
   hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
   hdd_context_t *pHddCtx;
   hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
   VOS_STATUS status;
   v_BOOL_t in_standby = TRUE;

   if (NULL == pAdapter) 
   {
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
         "%s: pAdapter is Null", __func__);
      return -ENODEV;
   }
   
   pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
   MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
                    pAdapter->sessionId, pAdapter->device_mode));
   if (NULL == pHddCtx)
   {
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
         "%s: HDD context is Null", __func__);
      return -ENODEV;
   }

   status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
   while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
   {
      if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
      {
         hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
                __func__);
         in_standby = FALSE;
         break;
      }
      else
      {
         status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
         pAdapterNode = pNext;
      }
   }
 
   if (TRUE == in_standby)
   {
       if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
       {
           hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring " 
                   "wlan out of power save", __func__);
           return -EINVAL;
       }
   }
   
   set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
   if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) 
   {
       VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                 "%s: Enabling Tx Queues", __func__);
       /* Enable TX queues only when we are connected */
       hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
       netif_tx_start_all_queues(dev);
   }

   return 0;
}

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

  \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR

  This is called in response to ifconfig up

  \param  - dev Pointer to net_device structure

  \return - 0 for success non-zero for failure

  --------------------------------------------------------------------------*/
int hdd_open(struct net_device *dev)
{
   int ret;

   vos_ssr_protect(__func__);
   ret = __hdd_open(dev);
   vos_ssr_unprotect(__func__);

   return ret;
}

int __hdd_mon_open (struct net_device *dev)
{
   hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
   hdd_adapter_t *sta_adapter;
   hdd_context_t *hdd_ctx;

   if(pAdapter == NULL) {
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
         "%s: HDD adapter context is Null", __func__);
      return -EINVAL;
   }

   if (vos_get_concurrency_mode() != VOS_STA_MON)
       return 0;

   hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
   if (wlan_hdd_validate_context(hdd_ctx))
       return -EINVAL;

   sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
   if (!sta_adapter) {
       hddLog(LOGE, FL("No valid STA interface"));
       return -EINVAL;
   }

   if (!test_bit(DEVICE_IFACE_OPENED, &sta_adapter->event_flags)) {
       hddLog(LOGE, FL("STA Interface is not OPENED"));
       return -EINVAL;
   }

   set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);

   return 0;
}

int hdd_mon_open (struct net_device *dev)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __hdd_mon_open(dev);
    vos_ssr_unprotect(__func__);

    return ret;
}

int __hdd_mon_stop (struct net_device *dev)
{
	hdd_adapter_t *mon_adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	hdd_context_t *hdd_ctx;

	if (vos_get_concurrency_mode() != VOS_STA_MON)
		return 0;

	if(!mon_adapter) {
		hddLog(LOGE, FL("HDD adapter is Null"));
		return -EINVAL;
	}

	hdd_ctx = WLAN_HDD_GET_CTX(mon_adapter);
	if (wlan_hdd_validate_context(hdd_ctx))
		return -EINVAL;

	if (!test_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags)) {
		hddLog(LOGE, FL("NETDEV Interface is not OPENED"));
		return -ENODEV;
	}

	clear_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags);
	hdd_stop_adapter(hdd_ctx, mon_adapter, VOS_FALSE);

	return 0;
}

int hdd_mon_stop(struct net_device *dev)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __hdd_mon_stop(dev);
	vos_ssr_unprotect(__func__);

	return ret;
}

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

  \brief __hdd_stop() - HDD stop function

  \param  - dev Pointer to net_device structure

  \return - 0 for success non-zero for failure

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

int __hdd_stop (struct net_device *dev)
{
   int ret = 0;
   hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
   hdd_context_t *pHddCtx;
   hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
   VOS_STATUS status;
   v_BOOL_t enter_standby = TRUE;
   
   ENTER();
   if (NULL == pAdapter)
   {
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
         "%s: pAdapter is Null", __func__);
      return -ENODEV;
   }
   MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
                    pAdapter->sessionId, pAdapter->device_mode));

   pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
   ret = wlan_hdd_validate_context(pHddCtx);
   if (ret)
   {
      return ret;
   }

   /* Nothing to be done if the interface is not opened */
   if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
   {
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 "%s: NETDEV Interface is not OPENED", __func__);
      return -ENODEV;
   }

   if (pHddCtx->concurrency_mode == VOS_STA_MON) {
       /*
        * In STA + Monitor mode concurrency, no point in running
        * capture on monitor interface, when STA interface is stopped
        */
       wlan_hdd_stop_mon(pHddCtx, true);
   }

   /* Make sure the interface is marked as closed */
   clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
   hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);

   /* Disable TX on the interface, after this hard_start_xmit() will not
    * be called on that interface
    */
   hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
   netif_tx_disable(pAdapter->dev);

   /* Mark the interface status as "down" for outside world */
   netif_carrier_off(pAdapter->dev);

   /* The interface is marked as down for outside world (aka kernel)
    * But the driver is pretty much alive inside. The driver needs to
    * tear down the existing connection on the netdev (session)
    * cleanup the data pipes and wait until the control plane is stabilized
    * for this interface. The call also needs to wait until the above
    * mentioned actions are completed before returning to the caller.
    * Notice that the hdd_stop_adapter is requested not to close the session
    * That is intentional to be able to scan if it is a STA/P2P interface
    */
   hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
#ifdef FEATURE_WLAN_TDLS
   mutex_lock(&pHddCtx->tdls_lock);
#endif
   /* DeInit the adapter. This ensures datapath cleanup as well */
   hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
#ifdef FEATURE_WLAN_TDLS
   mutex_unlock(&pHddCtx->tdls_lock);
#endif
   /* SoftAP ifaces should never go in power save mode
      making sure same here. */
   if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
                 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
      )
   {
      /* SoftAP mode, so return from here */
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
         "%s: In SAP MODE", __func__);
      EXIT();
      return 0;
   }
   /* Find if any iface is up. If any iface is up then can't put device to
    * sleep/power save mode
    */
   status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
   while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
   {
      if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
      {
         hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
                "put device to sleep", __func__);
         enter_standby = FALSE;
         break;
      }
      else
      {
         status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
         pAdapterNode = pNext;
      }
   }

   if (TRUE == enter_standby)
   {
       hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down " 
                 "entering standby", __func__);
       if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
       {
           /*log and return success*/
           hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
                   "wlan in power save", __func__);
       }
   }
   
   EXIT();
   return 0;
}

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

  \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR

  This is called in response to ifconfig down

  \param  - dev Pointer to net_device structure

  \return - 0 for success non-zero for failure
-----------------------------------------------------------------------------*/
int hdd_stop (struct net_device *dev)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __hdd_stop(dev);
    vos_ssr_unprotect(__func__);

    return ret;
}

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

  \brief __hdd_uninit() - HDD uninit function

  \param  - dev Pointer to net_device structure

  \return - void

  --------------------------------------------------------------------------*/
static void __hdd_uninit (struct net_device *dev)
{
   hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
   hdd_context_t *pHddCtx;
   ENTER();

   do
   {
      if (NULL == pAdapter)
      {
         hddLog(VOS_TRACE_LEVEL_FATAL,
                "%s: NULL pAdapter", __func__);
         break;
      }

      if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
      {
         hddLog(VOS_TRACE_LEVEL_FATAL,
                "%s: Invalid magic", __func__);
         break;
      }
      pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
      if (NULL == pHddCtx)
      {
         hddLog(VOS_TRACE_LEVEL_FATAL,
                "%s: NULL pHddCtx", __func__);
         break;
      }

      if (dev != pAdapter->dev)
      {
         hddLog(VOS_TRACE_LEVEL_FATAL,
                "%s: Invalid device reference", __func__);
         /* we haven't validated all cases so let this go for now */
      }
#ifdef FEATURE_WLAN_TDLS
      mutex_lock(&pHddCtx->tdls_lock);
#endif
      hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
#ifdef FEATURE_WLAN_TDLS
      mutex_unlock(&pHddCtx->tdls_lock);
#endif

      /* after uninit our adapter structure will no longer be valid */
      pAdapter->dev = NULL;
      pAdapter->magic = 0;
      pAdapter->pHddCtx = NULL;
   } while (0);

   EXIT();
}

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

  \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR

  This is called during the netdev unregister to uninitialize all data
associated with the device

  \param  - dev Pointer to net_device structure

  \return - void

  --------------------------------------------------------------------------*/
static void hdd_uninit (struct net_device *dev)
{
   vos_ssr_protect(__func__);
   __hdd_uninit(dev);
   vos_ssr_unprotect(__func__);
}

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

  \brief hdd_release_firmware() -

   This function calls the release firmware API to free the firmware buffer.

  \param  - pFileName Pointer to the File Name.
                  pCtx - Pointer to the adapter .


  \return - 0 for success, non zero for failure

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

VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
{
   VOS_STATUS status = VOS_STATUS_SUCCESS;
   hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
   ENTER();


   if (!strcmp(WLAN_FW_FILE, pFileName)) {
   
       hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);

       if(pHddCtx->fw) {
          release_firmware(pHddCtx->fw);
          pHddCtx->fw = NULL;
       }
       else
          status = VOS_STATUS_E_FAILURE;
   }
   else if (!strcmp(WLAN_NV_FILE,pFileName)) {
       if(pHddCtx->nv) {
          release_firmware(pHddCtx->nv);
          pHddCtx->nv = NULL;
       }
       else
          status = VOS_STATUS_E_FAILURE;

   }

   EXIT();
   return status;
}

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

  \brief hdd_request_firmware() -

   This function reads the firmware file using the request firmware
   API and returns the the firmware data and the firmware file size.

  \param  - pfileName - Pointer to the file name.
              - pCtx - Pointer to the adapter .
              - ppfw_data - Pointer to the pointer of the firmware data.
              - pSize - Pointer to the file size.

  \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure

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


VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
{
   int status;
   VOS_STATUS retval = VOS_STATUS_SUCCESS;
   hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
   ENTER();

   if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {

       status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);

       if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
           hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
                  __func__, pfileName);
           retval = VOS_STATUS_E_FAILURE;
       }

       else {
         *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
         *pSize = pHddCtx->fw->size;
          hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
                 __func__, *pSize);
       }
   }
   else if(!strcmp(WLAN_NV_FILE, pfileName)) {

       status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);

       if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
           hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
                  __func__, pfileName);
           retval = VOS_STATUS_E_FAILURE;
       }

       else {
         *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
         *pSize = pHddCtx->nv->size;
          hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
                 __func__, *pSize);
       }
   }

   EXIT();
   return retval;
}
/**---------------------------------------------------------------------------
     \brief hdd_full_pwr_cbk() - HDD full power callbackfunction

      This is the function invoked by SME to inform the result of a full power
      request issued by HDD

     \param  - callbackcontext - Pointer to cookie
               status - result of request

     \return - None

--------------------------------------------------------------------------*/
void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
{
   hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;

   hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
   if(&pHddCtx->full_pwr_comp_var)
   {
      complete(&pHddCtx->full_pwr_comp_var);
   }
}

#ifdef WLAN_FEATURE_RMC
static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo)
{
   int payload_len;
   struct sk_buff *skb;
   struct nlmsghdr *nlh;
   v_U8_t *data;

   payload_len = ETH_ALEN;

   if (0 == cesium_pid)
   {
      hddLog(VOS_TRACE_LEVEL_ERROR, "%s: cesium process not registered",
             __func__);
      return;
   }

   if ((skb = nlmsg_new(payload_len,GFP_ATOMIC)) == NULL)
   {
      hddLog(VOS_TRACE_LEVEL_ERROR,
             "%s: nlmsg_new() failed for msg size[%d]",
             __func__, NLMSG_SPACE(payload_len));
      return;
   }

   nlh = nlmsg_put(skb, cesium_pid, seqNo, 0, payload_len, NLM_F_REQUEST);

   if (NULL == nlh)
   {
      hddLog(VOS_TRACE_LEVEL_ERROR,
             "%s: nlmsg_put() failed for msg size[%d]",
             __func__, NLMSG_SPACE(payload_len));

      kfree_skb(skb);
      return;
   }

   data = nlmsg_data(nlh);
   memcpy(data, MacAddr, ETH_ALEN);

   if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0)
   {
      hddLog(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_unicast() failed for msg size[%d]",
                                       __func__, NLMSG_SPACE(payload_len));
   }

   return;
}

/**---------------------------------------------------------------------------
     \brief hdd_ParseuserParams - return a pointer to the next argument

     \return - status

--------------------------------------------------------------------------*/
static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg)
{
   tANI_U8 *pVal;

   pVal = strchr(pValue, ' ');

   if (NULL == pVal)
   {
      /* no argument remains */
      return -EINVAL;
   }
   else if (SPACE_ASCII_VALUE != *pVal)
   {
      /* no space after the current argument */
      return -EINVAL;
   }

   pVal++;

   /* remove empty spaces */
   while ((SPACE_ASCII_VALUE  == *pVal) && ('\0' !=  *pVal))
   {
      pVal++;
   }

   /* no argument followed by spaces */
   if ('\0' == *pVal)
   {
      return -EINVAL;
   }

   *ppArg = pVal;

   return 0;
}

/**----------------------------------------------------------------------------
     \brief hdd_ParseIBSSTXFailEventParams - Parse params for SETIBSSTXFAILEVENT

     \return - status

------------------------------------------------------------------------------*/
static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
                                          tANI_U8 *tx_fail_count,
                                          tANI_U16 *pid)
{
   tANI_U8 *param = NULL;
   int ret;

   ret = hdd_ParseUserParams(pValue, &param);

   if (0 == ret && NULL != param)
   {
      if (1 != sscanf(param, "%hhu", tx_fail_count))
      {
         ret = -EINVAL;
         goto done;
      }
   }
   else
   {
      goto done;
   }

   if (0 == *tx_fail_count)
   {
      *pid = 0;
      goto done;
   }

   pValue = param;
   pValue++;

   ret = hdd_ParseUserParams(pValue, &param);

   if (0 == ret)
   {
      if (1 != sscanf(param, "%hu", pid))
      {
         ret = -EINVAL;
         goto done;
      }
   }
   else
   {
      goto done;
   }

done:
   return ret;
}

static int hdd_open_cesium_nl_sock()
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
   struct netlink_kernel_cfg cfg = {
          .groups = WLAN_NLINK_MCAST_GRP_ID,
          .input = NULL
          };
#endif
   int ret = 0;

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
   cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
                                              THIS_MODULE,
#endif
                                              &cfg);
#else
   cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
                                        WLAN_NLINK_MCAST_GRP_ID, NULL, NULL, THIS_MODULE);
#endif

   if (cesium_nl_srv_sock == NULL)
   {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 "NLINK:  cesium netlink_kernel_create failed");
       ret = -ECONNREFUSED;
   }

   return ret;
}

static void hdd_close_cesium_nl_sock()
{
   if (NULL != cesium_nl_srv_sock)
   {
      netlink_kernel_release(cesium_nl_srv_sock);
      cesium_nl_srv_sock = NULL;
   }
}
#endif /* WLAN_FEATURE_RMC */
/**---------------------------------------------------------------------------

    \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function

     This is the function invoked by SME to inform the result of BMPS
     request issued by HDD

    \param  - callbackcontext - Pointer to cookie
               status - result of request

    \return - None

--------------------------------------------------------------------------*/
void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
{

   struct completion *completion_var = (struct completion*) callbackContext;

   hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
   if(completion_var != NULL)
   {
      complete(completion_var);
   }
}

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

  \brief hdd_get_cfg_file_size() -

   This function reads the configuration file using the request firmware
   API and returns the configuration file size.

  \param  - pCtx - Pointer to the adapter .
              - pFileName - Pointer to the file name.
              - pBufSize - Pointer to the buffer size.

  \return - 0 for success, non zero for failure

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

VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
{
   int status;
   hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;

   ENTER();

   status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);

   if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
      status = VOS_STATUS_E_FAILURE;
   }
   else {
      *pBufSize = pHddCtx->fw->size;
      hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
      release_firmware(pHddCtx->fw);
      pHddCtx->fw = NULL;
   }

   EXIT();
   return VOS_STATUS_SUCCESS;
}

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

  \brief hdd_read_cfg_file() -

   This function reads the configuration file using the request firmware
   API and returns the cfg data and the buffer size of the configuration file.

  \param  - pCtx - Pointer to the adapter .
              - pFileName - Pointer to the file name.
              - pBuffer - Pointer to the data buffer.
              - pBufSize - Pointer to the buffer size.

  \return - 0 for success, non zero for failure

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

VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
    v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
{
   int status;
   hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;

   ENTER();

   status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);

   if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
      return VOS_STATUS_E_FAILURE;
   }
   else {
      if(*pBufSize != pHddCtx->fw->size) {
         hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
             "file size", __func__);
         release_firmware(pHddCtx->fw);
         pHddCtx->fw = NULL;
         return VOS_STATUS_E_FAILURE;
      }
        else {
         if(pBuffer) {
            vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
         }
         release_firmware(pHddCtx->fw);
         pHddCtx->fw = NULL;
        }
   }

   EXIT();

   return VOS_STATUS_SUCCESS;
}

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

  \brief __hdd_set_mac_address() -

   This function sets the user specified mac address using
   the command ifconfig wlanX hw ether <mac adress>.

  \param  - dev - Pointer to the net device.
              - addr - Pointer to the sockaddr.
  \return - 0 for success, non zero for failure

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

static int __hdd_set_mac_address(struct net_device *dev, void *addr)
{
   hdd_adapter_t *pAdapter;
   hdd_context_t *pHddCtx;
   struct sockaddr *psta_mac_addr = addr;
   eHalStatus halStatus = eHAL_STATUS_SUCCESS;
   int ret = 0;

   ENTER();
   pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
   if (NULL == pAdapter)
   {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 "%s: Adapter is NULL",__func__);
       return -EINVAL;
   }
   pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
   ret = wlan_hdd_validate_context(pHddCtx);
   if (0 != ret)
   {
       return ret;
   }

   memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
   memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);

   EXIT();
   return halStatus;
}

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

  \brief hdd_set_mac_address() -

   Wrapper function to protect __hdd_set_mac_address() function from ssr

  \param  - dev - Pointer to the net device.
              - addr - Pointer to the sockaddr.
  \return - 0 for success, non zero for failure

  --------------------------------------------------------------------------*/
static int hdd_set_mac_address(struct net_device *dev, void *addr)
{
   int ret;

   vos_ssr_protect(__func__);
   ret = __hdd_set_mac_address(dev, addr);
   vos_ssr_unprotect(__func__);

   return ret;
}

tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
{
   int i;
   for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
   {
      if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
         break;
   }

   if( VOS_MAX_CONCURRENCY_PERSONA == i)
      return NULL;

   pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
   return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
}

void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
{
   int i;
   for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
   {
      if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
      {
         pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
         break;
      } 
   }
   return;
}

#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
  static struct net_device_ops wlan_drv_ops = {
      .ndo_open = hdd_open,
      .ndo_stop = hdd_stop,
      .ndo_uninit = hdd_uninit,
      .ndo_start_xmit = hdd_hard_start_xmit,
      .ndo_tx_timeout = hdd_tx_timeout,
      .ndo_get_stats = hdd_stats,
      .ndo_do_ioctl = hdd_ioctl,
      .ndo_set_mac_address = hdd_set_mac_address,
      .ndo_select_queue    = hdd_select_queue,
#ifdef WLAN_FEATURE_PACKET_FILTERING
#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
      .ndo_set_rx_mode = hdd_set_multicast_list,
#else
      .ndo_set_multicast_list = hdd_set_multicast_list,
#endif //LINUX_VERSION_CODE
#endif
 };
 static struct net_device_ops wlan_mon_drv_ops = {
      .ndo_open = hdd_mon_open,
      .ndo_stop = hdd_mon_stop,
      .ndo_uninit = hdd_uninit,
      .ndo_start_xmit = hdd_mon_hard_start_xmit,  
      .ndo_tx_timeout = hdd_tx_timeout,
      .ndo_get_stats = hdd_stats,
      .ndo_do_ioctl = hdd_mon_ioctl,
      .ndo_set_mac_address = hdd_set_mac_address,
 };

#endif

void hdd_set_station_ops( struct net_device *pWlanDev )
{
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
      pWlanDev->netdev_ops = &wlan_drv_ops;
#else
      pWlanDev->open = hdd_open;
      pWlanDev->stop = hdd_stop;
      pWlanDev->uninit = hdd_uninit;
      pWlanDev->hard_start_xmit = NULL;
      pWlanDev->tx_timeout = hdd_tx_timeout;
      pWlanDev->get_stats = hdd_stats;
      pWlanDev->do_ioctl = hdd_ioctl;
      pWlanDev->set_mac_address = hdd_set_mac_address;
#endif
}

void  hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
{
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
     wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
 #else
     pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
 #endif
}

static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
{
   struct net_device *pWlanDev = NULL;
   hdd_adapter_t *pAdapter = NULL;
   /*
    * cfg80211 initialization and registration....
    */ 
   pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
                              NET_NAME_UNKNOWN,
#endif
                              ether_setup, NUM_TX_QUEUES);
   if(pWlanDev != NULL)
   {

      //Save the pointer to the net_device in the HDD adapter
      pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );

      vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );

      pAdapter->dev = pWlanDev;
      pAdapter->pHddCtx = pHddCtx; 
      pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
      spin_lock_init(&pAdapter->lock_for_active_session);

#ifdef FEATURE_WLAN_BATCH_SCAN
      pAdapter->pBatchScanRsp = NULL;
      pAdapter->numScanList = 0;
      pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
      pAdapter->prev_batch_id = 0;
      mutex_init(&pAdapter->hdd_batch_scan_lock);
#endif

      pAdapter->isLinkUpSvcNeeded = FALSE; 
      pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
      //Init the net_device structure
      strlcpy(pWlanDev->name, name, IFNAMSIZ);

      vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
      vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
      pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
      pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;

      hdd_set_station_ops( pAdapter->dev );

      pWlanDev->destructor = free_netdev;
      pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
      pAdapter->wdev.wiphy = pHddCtx->wiphy;  
      pAdapter->wdev.netdev =  pWlanDev;
      /* set pWlanDev's parent to underlying device */
      SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);

      hdd_wmm_init( pAdapter );
   }

   return pAdapter;
}

VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
{
   struct net_device *pWlanDev = pAdapter->dev;
   //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
   //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
   //eHalStatus halStatus = eHAL_STATUS_SUCCESS;

   if( rtnl_lock_held )
   {
     if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
         if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
         {
            hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
            return VOS_STATUS_E_FAILURE;            
         }
      }
      if (register_netdevice(pWlanDev))
      {
         hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
         return VOS_STATUS_E_FAILURE;         
      }
   }
   else
   {
      if(register_netdev(pWlanDev))
      {
         hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
         return VOS_STATUS_E_FAILURE;         
      }
   }
   set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);

   return VOS_STATUS_SUCCESS;
}

static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
{
   hdd_adapter_t *pAdapter = pContext;

   if (NULL == pAdapter)
   {
      hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
      return eHAL_STATUS_INVALID_PARAMETER;
   }

   if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
   {
      hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
      return eHAL_STATUS_NOT_INITIALIZED;
   }

   clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);

#ifndef WLAN_OPEN_SOURCE
   /* need to make sure all of our scheduled work has completed.
    * This callback is called from MC thread context, so it is safe to
    * to call below flush workqueue API from here.
    *
    * Even though this is called from MC thread context, if there is a faulty
    * work item in the system, that can hang this call forever.  So flushing
    * this global work queue is not safe; and now we make sure that
    * individual work queues are stopped correctly. But the cancel work queue
    * is a GPL only API, so the proprietary  version of the driver would still
    * rely on the global work queue flush.
    */
   flush_scheduled_work();
#endif

   /* We can be blocked while waiting for scheduled work to be
    * flushed, and the adapter structure can potentially be freed, in
    * which case the magic will have been reset.  So make sure the
    * magic is still good, and hence the adapter structure is still
    * valid, before signaling completion */
   if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
   {
      complete(&pAdapter->session_close_comp_var);
   }

   return eHAL_STATUS_SUCCESS;
}
/**
 * hdd_close_tx_queues() - close tx queues
 * @hdd_ctx: hdd global context
 *
 * Return: None
 */
static void hdd_close_tx_queues(hdd_context_t *hdd_ctx)
{
   VOS_STATUS status;
   hdd_adapter_t *adapter;
   hdd_adapter_list_node_t *adapter_node = NULL, *next_adapter = NULL;
   /* Not validating hdd_ctx as it's already done by the caller */
   ENTER();
   status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
   while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
      adapter = adapter_node->pAdapter;
      if (adapter && adapter->dev) {
          netif_tx_disable (adapter->dev);
          netif_carrier_off(adapter->dev);
      }
      status = hdd_get_next_adapter(hdd_ctx, adapter_node,
                                    &next_adapter);
      adapter_node = next_adapter;
   }
   EXIT();
}

VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
{
   struct net_device *pWlanDev = pAdapter->dev;
   hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
   hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
   eHalStatus halStatus = eHAL_STATUS_SUCCESS;
   VOS_STATUS status = VOS_STATUS_E_FAILURE;
   long rc = 0;

   spin_lock_init( &pAdapter->sta_hash_lock);
   pAdapter->is_sta_id_hash_initialized = VOS_FALSE;

   INIT_COMPLETION(pAdapter->session_open_comp_var);
   sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
   //Open a SME session for future operation
   halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
         (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
   if ( !HAL_STATUS_SUCCESS( halStatus ) )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,
             "sme_OpenSession() failed with status code %08d [x%08x]",
                                                 halStatus, halStatus );
      status = VOS_STATUS_E_FAILURE;
      goto error_sme_open;
   }
   
   //Block on a completion variable. Can't wait forever though.
   rc = wait_for_completion_timeout(
                        &pAdapter->session_open_comp_var,
                        msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
   if (rc <= 0)
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,
             "Session is not opened within timeout period code %ld", rc );
      status = VOS_STATUS_E_FAILURE;
      goto error_sme_open;
   }

   // Register wireless extensions
   if( eHAL_STATUS_SUCCESS !=  (halStatus = hdd_register_wext(pWlanDev)))
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,
              "hdd_register_wext() failed with status code %08d [x%08x]",
                                                   halStatus, halStatus );
      status = VOS_STATUS_E_FAILURE;
      goto error_register_wext;
   }

   //Safe to register the hard_start_xmit function again
   #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
      wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
   #else
      pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
   #endif

   //Set the Connection State to Not Connected
   hddLog(VOS_TRACE_LEVEL_INFO,
            "%s: Set HDD connState to eConnectionState_NotConnected",
                   __func__);
   pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;

   //Set the default operation channel
   pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;

   /* Make the default Auth Type as OPEN*/
   pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;

   if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,
            "hdd_init_tx_rx() failed with status code %08d [x%08x]",
                            status, status );
      goto error_init_txrx;
   }

   set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);

   if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,
            "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
                            status, status );
      goto error_wmm_init;
   }

   set_bit(WMM_INIT_DONE, &pAdapter->event_flags);

   return VOS_STATUS_SUCCESS;

error_wmm_init:
   clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
   hdd_deinit_tx_rx(pAdapter);
error_init_txrx:
   hdd_UnregisterWext(pWlanDev);
error_register_wext:
   if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
   {
      INIT_COMPLETION(pAdapter->session_close_comp_var);
      if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
                                    pAdapter->sessionId, FALSE, VOS_TRUE,
                                    hdd_smeCloseSessionCallback, pAdapter))
      {
         unsigned long rc;

         //Block on a completion variable. Can't wait forever though.
         rc = wait_for_completion_timeout(
                          &pAdapter->session_close_comp_var,
                          msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
         if (rc <= 0)
             hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("Session is not opened within timeout period code %ld"), rc);
      }
}
error_sme_open:
   return status;
}

void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
{
   hdd_cfg80211_state_t *cfgState;

   cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );

   if( NULL != cfgState->buf )
   {
      long rc;
      INIT_COMPLETION(pAdapter->tx_action_cnf_event);
      rc = wait_for_completion_interruptible_timeout(
                     &pAdapter->tx_action_cnf_event,
                     msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
      if (rc <= 0)
      {
          VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
                  , __func__, rc);

          // Inform tx status as FAILURE to upper layer and free cfgState->buf
          hdd_sendActionCnf( pAdapter, FALSE );
      }
   }
   return;
}

void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
{
   ENTER();
   switch ( pAdapter->device_mode )
   {
      case WLAN_HDD_IBSS:
      {
         if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
         {
            hdd_ibss_deinit_tx_rx( pAdapter );
            clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
         }
      }
      case WLAN_HDD_INFRA_STATION:
      case WLAN_HDD_P2P_CLIENT:
      case WLAN_HDD_P2P_DEVICE:
      {
         if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
         {
            hdd_deinit_tx_rx( pAdapter );
            clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
         }

         if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
         {
            hdd_wmm_adapter_close( pAdapter );
            clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
         }

         hdd_cleanup_actionframe(pHddCtx, pAdapter);
         break;
      }

      case WLAN_HDD_SOFTAP:
      case WLAN_HDD_P2P_GO:
      {

         if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
         {
            hdd_wmm_adapter_close( pAdapter );
            clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
         }

         hdd_cleanup_actionframe(pHddCtx, pAdapter);

         hdd_unregister_hostapd(pAdapter, rtnl_held);
         /* set con_mode to STA only when no SAP concurrency mode */
         if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
             hdd_set_conparam(0);
         break;
      }

      case WLAN_HDD_MONITOR:
      {
         if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
         {
            hdd_deinit_tx_rx( pAdapter );
            clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
         }
         break;
      }


      default:
      break;
   }

   EXIT();
}

void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
{
   struct net_device *pWlanDev = NULL;

   ENTER();
   if (NULL == pAdapter)
   {
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 "%s: HDD adapter is Null", __func__);
      return;
   }

   pWlanDev = pAdapter->dev;

#ifdef FEATURE_WLAN_BATCH_SCAN
   if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
     || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
     || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
     || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
     )
   {
      if (pAdapter)
      {
          if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
          {
              hdd_deinit_batch_scan(pAdapter);
          }
      }
   }
#endif

   if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
      if( rtnl_held )
      {
         unregister_netdevice(pWlanDev);
      }
      else
      {
         unregister_netdev(pWlanDev);
      }
      // note that the pAdapter is no longer valid at this point
      // since the memory has been reclaimed
   }

   EXIT();
}

void hdd_set_pwrparams(hdd_context_t *pHddCtx)
{
   VOS_STATUS status;
   hdd_adapter_t *pAdapter = NULL;
   hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;

   status =  hdd_get_front_adapter ( pHddCtx, &pAdapterNode );

   /*loop through all adapters.*/
   while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
   {
       pAdapter = pAdapterNode->pAdapter;
       if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
         && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )

       {  // we skip this registration for modes other than STA and P2P client modes.
           status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
           pAdapterNode = pNext;
           continue;
       }

       //Apply Dynamic DTIM For P2P
       //Only if ignoreDynamicDtimInP2pMode is not set in ini
      if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
           pHddCtx->cfg_ini->enableModulatedDTIM) &&
          ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
          ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
          !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
          (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
          (eConnectionState_Associated ==
          (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
          (pHddCtx->cfg_ini->fIsBmpsEnabled))
      {
           tSirSetPowerParamsReq powerRequest = { 0 };

           powerRequest.uIgnoreDTIM = 1;
           powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;

           if (pHddCtx->cfg_ini->enableModulatedDTIM)
           {
               powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
               powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
           }
           else
           {
               powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
           }

           /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
            * specified during Enter/Exit BMPS when LCD off*/
            ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
                       NULL, eANI_BOOLEAN_FALSE);
            ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
                       NULL, eANI_BOOLEAN_FALSE);

           /* switch to the DTIM specified in cfg.ini */
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                "Switch to DTIM %d Listen interval %d",
                powerRequest.uDTIMPeriod,
                powerRequest.uListenInterval);
            sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
            break;

      }

      status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
      pAdapterNode = pNext;
    }
}

void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
{
   /*Switch back to DTIM 1*/
   tSirSetPowerParamsReq powerRequest = { 0 };

   powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
   powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
   powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;

   /* Update ignoreDTIM and ListedInterval in CFG with default values */
   ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
                    NULL, eANI_BOOLEAN_FALSE);
   ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
                    NULL, eANI_BOOLEAN_FALSE);

   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  "Switch to DTIM%d",powerRequest.uListenInterval);
   sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);

}

VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
{
   VOS_STATUS status = VOS_STATUS_SUCCESS;
   if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
   {
       hddLog( LOGE, FL("Wlan Unload in progress"));
       return VOS_STATUS_E_PERM;
   }

   if (wlan_hdd_check_monitor_state(pHddCtx)) {
       hddLog(LOG1, FL("Monitor mode is started, cannot enable BMPS"));
       return VOS_STATUS_SUCCESS;
   }

   if(pHddCtx->cfg_ini->fIsBmpsEnabled)
   {
      sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
   }

   if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
   {
      sme_StartAutoBmpsTimer(pHddCtx->hHal); 
   }

   if (pHddCtx->cfg_ini->fIsImpsEnabled)
   {
      sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
   }

   return status;
}

VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
{
   hdd_adapter_t *pAdapter = NULL;
   eHalStatus halStatus;
   VOS_STATUS status = VOS_STATUS_E_INVAL;
   v_BOOL_t disableBmps = FALSE;
   v_BOOL_t disableImps = FALSE;
   
   switch(session_type)
   {
       case WLAN_HDD_INFRA_STATION:
       case WLAN_HDD_SOFTAP:
       case WLAN_HDD_P2P_CLIENT:
       case WLAN_HDD_P2P_GO:
          //Exit BMPS -> Is Sta/P2P Client is already connected
          pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
          if((NULL != pAdapter)&&
              hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
          {
             disableBmps = TRUE;
          }

          pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
          if((NULL != pAdapter)&&
              hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
          {
             disableBmps = TRUE;
          }

          //Exit both Bmps and Imps incase of Go/SAP Mode
          if((WLAN_HDD_SOFTAP == session_type) ||
              (WLAN_HDD_P2P_GO == session_type))
          {
             disableBmps = TRUE;
             disableImps = TRUE;
          }

          if(TRUE == disableImps)
          {
             if (pHddCtx->cfg_ini->fIsImpsEnabled)
             {
                sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
             }
          }

          if(TRUE == disableBmps)
          {
             if(pHddCtx->cfg_ini->fIsBmpsEnabled)
             {
                 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);

                 if(eHAL_STATUS_SUCCESS != halStatus)
                 {
                    status = VOS_STATUS_E_FAILURE;
                    hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
                    VOS_ASSERT(0);
                    return status;
                 }
              }

              if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
              {
                 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);

                 if(eHAL_STATUS_SUCCESS != halStatus)
                 {
                    status = VOS_STATUS_E_FAILURE;
                    hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
                    VOS_ASSERT(0);
                    return status;
                 }
              }
          }

          if((TRUE == disableBmps) ||
              (TRUE == disableImps))
          {
              /* Now, get the chip into Full Power now */
              INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
              halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
                                   pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);

              if(halStatus != eHAL_STATUS_SUCCESS)
              {
                 if(halStatus == eHAL_STATUS_PMC_PENDING)
                 {
                    long ret;
                    //Block on a completion variable. Can't wait forever though
                    ret = wait_for_completion_interruptible_timeout(
                                   &pHddCtx->full_pwr_comp_var,
                                    msecs_to_jiffies(1000));
                    if (ret <= 0)
                    {
                        hddLog(VOS_TRACE_LEVEL_ERROR,
                               "%s: wait on full_pwr_comp_var failed %ld",
                               __func__, ret);
                    }
                 }
                 else
                 {
                    status = VOS_STATUS_E_FAILURE;
                    hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
                    VOS_ASSERT(0);
                    return status;
                 }
              }

              status = VOS_STATUS_SUCCESS;
          }

          break;
   }
   return status;
}

void hdd_mon_post_msg_cb(void *context)
{
	struct hdd_request *request;

	request = hdd_request_get(context);
	if (!request) {
		hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
		return;
	}

	hdd_request_complete(request);
	hdd_request_put(request);
}


void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
 {
    hdd_mon_ctx_t *pMonCtx = NULL;

    spin_lock_init(&pAdapter->sta_hash_lock);
    pAdapter->is_sta_id_hash_initialized = VOS_FALSE;

    pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
    pMonCtx->state = 0;
    pMonCtx->ChannelNo = 1;
    pMonCtx->ChannelBW = 20;
    pMonCtx->crcCheckEnabled = 1;
    pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
    pMonCtx->is80211to803ConReq = 1;
    pMonCtx->numOfMacFilters = 0;
 }


hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
                                 const char *iface_name, tSirMacAddr macAddr,
                                 tANI_U8 rtnl_held )
{
   hdd_adapter_t *pAdapter = NULL;
   hdd_adapter_list_node_t *pHddAdapterNode = NULL;
   VOS_STATUS status = VOS_STATUS_E_FAILURE;
   VOS_STATUS exitbmpsStatus;
   v_CONTEXT_t pVosContext = NULL;

   /* No need to check for NULL, reaching this step
    * means vos context is initialized
    */
   pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);

   hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);

   if(macAddr == NULL)
   {
         /* Not received valid macAddr */
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 "%s:Unable to add virtual intf: Not able to get"
                             "valid mac address",__func__);
         return NULL;
   }

   //Disable BMPS incase of Concurrency
   exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);

   if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
   {
      //Fail to Exit BMPS
      hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
      VOS_ASSERT(0);
      return NULL;
   }

   switch(session_type)
   {
      case WLAN_HDD_INFRA_STATION:
      case WLAN_HDD_P2P_CLIENT:
      case WLAN_HDD_P2P_DEVICE:
      {
         pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );

         if( NULL == pAdapter )
         {
            hddLog(VOS_TRACE_LEVEL_FATAL,
              FL("failed to allocate adapter for session %d"), session_type);
            return NULL;
         }

#ifdef FEATURE_WLAN_TDLS
         /* A Mutex Lock is introduced while changing/initializing the mode to
          * protect the concurrent access for the Adapters by TDLS module.
          */
          mutex_lock(&pHddCtx->tdls_lock);
#endif

         pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
                                  NL80211_IFTYPE_P2P_CLIENT:
                                  NL80211_IFTYPE_STATION;

         pAdapter->device_mode = session_type;
#ifdef FEATURE_WLAN_TDLS
         mutex_unlock(&pHddCtx->tdls_lock);
#endif

         hdd_initialize_adapter_common(pAdapter);
         status = hdd_init_station_mode( pAdapter );
         if( VOS_STATUS_SUCCESS != status )
            goto err_free_netdev;

         status = hdd_register_interface( pAdapter, rtnl_held );
         if( VOS_STATUS_SUCCESS != status )
         {
#ifdef FEATURE_WLAN_TDLS
            mutex_lock(&pHddCtx->tdls_lock);
#endif
            hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
#ifdef FEATURE_WLAN_TDLS
            mutex_unlock(&pHddCtx->tdls_lock);
#endif
            goto err_free_netdev;
         }

         // Workqueue which gets scheduled in IPv4 notification callback.
         vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);

#ifdef WLAN_NS_OFFLOAD
         // Workqueue which gets scheduled in IPv6 notification callback.
         vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
#endif
         //Stop the Interface TX queue.
         hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
         netif_tx_disable(pAdapter->dev);
         //netif_tx_disable(pWlanDev);
         netif_carrier_off(pAdapter->dev);

         if (WLAN_HDD_P2P_CLIENT == session_type ||
                 WLAN_HDD_P2P_DEVICE == session_type)
         {
             /* Initialize the work queue to defer the
              * back to back RoC request */
             vos_init_delayed_work(&pAdapter->roc_work,
                     hdd_p2p_roc_work_queue);
         }

         break;
      }

      case WLAN_HDD_P2P_GO:
      case WLAN_HDD_SOFTAP:
      {
         pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
         if( NULL == pAdapter )
         {
            hddLog(VOS_TRACE_LEVEL_FATAL,
              FL("failed to allocate adapter for session %d"), session_type);
            return NULL;
         }

         pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
                                  NL80211_IFTYPE_AP:
                                  NL80211_IFTYPE_P2P_GO;
         pAdapter->device_mode = session_type;

         hdd_initialize_adapter_common(pAdapter);
         status = hdd_init_ap_mode(pAdapter, false);
         if( VOS_STATUS_SUCCESS != status )
            goto err_free_netdev;

         status = hdd_sta_id_hash_attach(pAdapter);
         if (VOS_STATUS_SUCCESS != status)
         {
             hddLog(VOS_TRACE_LEVEL_FATAL,
                    FL("failed to attach hash for session %d"), session_type);
             hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
             goto err_free_netdev;
         }

         status = hdd_register_hostapd( pAdapter, rtnl_held );
         if( VOS_STATUS_SUCCESS != status )
         {
            hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
            goto err_free_netdev;
         }
         hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
         netif_tx_disable(pAdapter->dev);
         netif_carrier_off(pAdapter->dev);

         hdd_set_conparam( 1 );

         // Workqueue which gets scheduled in IPv4 notification callback.
         vos_init_work(&pAdapter->ipv4NotifierWorkQueue,
                       hdd_ipv4_notifier_work_queue);

#ifdef WLAN_NS_OFFLOAD
         // Workqueue which gets scheduled in IPv6 notification callback.
         vos_init_work(&pAdapter->ipv6NotifierWorkQueue,
                       hdd_ipv6_notifier_work_queue);
#endif

         if (WLAN_HDD_P2P_GO == session_type)
         {
             /* Initialize the work queue to
              * defer the back to back RoC request */
             INIT_DELAYED_WORK(&pAdapter->roc_work,
                     hdd_p2p_roc_work_queue);
         }

         break;
      }
      case WLAN_HDD_MONITOR:
      {
         pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
         if( NULL == pAdapter )
         {
            hddLog(VOS_TRACE_LEVEL_FATAL,
              FL("failed to allocate adapter for session %d"), session_type);
            return NULL;
         }

         pAdapter->device_mode = session_type;
         pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;

         // Register wireless extensions
         if( VOS_STATUS_SUCCESS !=  (status = hdd_register_wext(pAdapter->dev)))
         {
              hddLog(VOS_TRACE_LEVEL_FATAL,
                   "hdd_register_wext() failed with status code %08d [x%08x]",
                                                      status, status );
              status = VOS_STATUS_E_FAILURE;
         }

#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
         pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
#else
         pAdapter->dev->open = hdd_mon_open;
         pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
         pAdapter->dev->stop = hdd_mon_stop;
         pAdapter->dev->do_ioctl = hdd_mon_ioctl;
#endif
         hdd_init_mon_mode( pAdapter );
         hdd_initialize_adapter_common(pAdapter);
         hdd_init_tx_rx( pAdapter );

         if (VOS_MONITOR_MODE != hdd_get_conparam())
             WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );

         set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
         status = hdd_register_interface( pAdapter, rtnl_held );
         //Stop the Interface TX queue.
         netif_tx_disable(pAdapter->dev);
         netif_carrier_off(pAdapter->dev);
      }
         break;
      case WLAN_HDD_FTM:
      {
         pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );

         if( NULL == pAdapter )
         {
            hddLog(VOS_TRACE_LEVEL_FATAL,
              FL("failed to allocate adapter for session %d"), session_type);
             return NULL;
         }

         /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
          * message while loading driver in FTM mode. */
         pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
         pAdapter->device_mode = session_type;
         status = hdd_register_interface( pAdapter, rtnl_held );

         hdd_initialize_adapter_common(pAdapter);
         hdd_init_tx_rx( pAdapter );

         //Stop the Interface TX queue.
         hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
         netif_tx_disable(pAdapter->dev);
         netif_carrier_off(pAdapter->dev);
      }
         break;
      default:
      {
         hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
           __func__, session_type);
         VOS_ASSERT(0);
         return NULL;
      }
   }

   if( VOS_STATUS_SUCCESS == status )
   {
      //Add it to the hdd's session list.
      pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
      if( NULL == pHddAdapterNode )
      {
         status = VOS_STATUS_E_NOMEM;
      }
      else
      {
         pHddAdapterNode->pAdapter = pAdapter;
         status = hdd_add_adapter_back ( pHddCtx, 
                                         pHddAdapterNode );
      }
   }

   if( VOS_STATUS_SUCCESS != status )
   {
      if( NULL != pAdapter )
      {
         hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
         pAdapter = NULL;   
      }
      if( NULL != pHddAdapterNode )
      {
         vos_mem_free( pHddAdapterNode );
      }

      goto resume_bmps;
   }

   if(VOS_STATUS_SUCCESS == status)
   {
      wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
      //Initialize the WoWL service
      if(!hdd_init_wowl(pAdapter))
      {
          hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
          goto err_free_netdev;
      }
      //Initialize the TSF capture data
      wlan_hdd_tsf_init(pAdapter);
   }
   return pAdapter;

err_free_netdev:
   wlan_hdd_release_intf_addr( pHddCtx,
                               pAdapter->macAddressCurrent.bytes );
   free_netdev(pAdapter->dev);

resume_bmps:
   //If bmps disabled enable it
   if(VOS_STATUS_SUCCESS == exitbmpsStatus)
   {
       if (pHddCtx->hdd_wlan_suspended)
       {
           hdd_set_pwrparams(pHddCtx);
       }
       hdd_enable_bmps_imps(pHddCtx);
   }
   return NULL;
}

VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
                              tANI_U8 rtnl_held )
{
   hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
   VOS_STATUS status;

   status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
   if( VOS_STATUS_SUCCESS != status )
   {
      hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
          __func__, status);
      return status;
   }

   while ( pCurrent->pAdapter != pAdapter )
   {
      status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
      if( VOS_STATUS_SUCCESS != status )
         break;

      pCurrent = pNext;
   }
   pAdapterNode = pCurrent;
   if( VOS_STATUS_SUCCESS == status )
   {
      wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
      hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );

#ifdef FEATURE_WLAN_TDLS

      /* A Mutex Lock is introduced while changing/initializing the mode to
       * protect the concurrent access for the Adapters by TDLS module.
       */
       mutex_lock(&pHddCtx->tdls_lock);
#endif

      hdd_remove_adapter( pHddCtx, pAdapterNode );
      vos_mem_free( pAdapterNode );
      pAdapterNode = NULL;

#ifdef FEATURE_WLAN_TDLS
       mutex_unlock(&pHddCtx->tdls_lock);
#endif


      /* If there is a single session of STA/P2P client, re-enable BMPS */
      if ((!vos_concurrent_open_sessions_running()) &&
           ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
           (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
      {
          if (pHddCtx->hdd_wlan_suspended)
          {
              hdd_set_pwrparams(pHddCtx);
          }
          hdd_enable_bmps_imps(pHddCtx);
      }

      return VOS_STATUS_SUCCESS;
   }

   return VOS_STATUS_E_FAILURE;
}

VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
{
   hdd_adapter_list_node_t *pHddAdapterNode;
   VOS_STATUS status;

   ENTER();

   do
   {
      status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
      if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
      {
         hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
         vos_mem_free( pHddAdapterNode );
      }
   }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
   
   EXIT();

   return VOS_STATUS_SUCCESS;
}

void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
{
    v_U8_t addIE[1] = {0};

    if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
                            WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
                            eANI_BOOLEAN_FALSE) )
    {
        hddLog(LOGE,
           "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
    }

    if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
                            WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
                            eANI_BOOLEAN_FALSE) )
    {
        hddLog(LOGE,
           "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
    }

    if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
                            WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
                            eANI_BOOLEAN_FALSE) )
    {
        hddLog(LOGE,
           "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
    }
}

VOS_STATUS hdd_cleanup_ap_events(hdd_adapter_t *adapter)
{
#ifdef DHCP_SERVER_OFFLOAD
    vos_event_destroy(&adapter->dhcp_status.vos_event);
#endif
#ifdef MDNS_OFFLOAD
    vos_event_destroy(&adapter->mdns_status.vos_event);
#endif
    return VOS_STATUS_SUCCESS;
}

int wlan_hdd_stop_mon(hdd_context_t *hdd_ctx, bool wait)
{
	hdd_adapter_t *adapter;
	hdd_mon_ctx_t *mon_ctx;
	void (*func_ptr)(void *context) = NULL;
	int ret = 0;
	void *cookie = NULL;
	struct hdd_request *request;
	static const struct hdd_request_params params = {
		.priv_size = 0,
		.timeout_ms = MON_MODE_MSG_TIMEOUT,
	};

	adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
	if (!adapter) {
		hddLog(LOGE, FL("Invalid STA + MON mode"));
		return -EINVAL;
	}

	mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(adapter);
	if (!mon_ctx)
		return 0;

	if (mon_ctx->state != MON_MODE_START)
		return 0;

	mon_ctx->state = MON_MODE_STOP;
	if (wait) {
		func_ptr = hdd_mon_post_msg_cb;
		request = hdd_request_alloc(&params);
		if (!request) {
			hddLog(VOS_TRACE_LEVEL_ERROR,
				FL("Request allocation failure"));
			return -ENOMEM;
		}
		cookie = hdd_request_cookie(request);
	}

	/*
	 * If func_ptr is NULL, on receiving WDI_MON_START_RSP or
	 * WDI_MON_STOP_RSP hdd_mon_post_msg_cb() won't be invoked
	 * and so uninitialized cookie won't be accessed.
	 */
	if (VOS_STATUS_SUCCESS != wlan_hdd_mon_postMsg(cookie,
						       mon_ctx,
						       func_ptr)) {
		hddLog(LOGE, FL("failed to stop MON MODE"));
		ret =  -EINVAL;
	}

	if (!wait)
		goto bmps_roaming;

	if (!ret)
		ret = hdd_request_wait_for_response(request);
	hdd_request_put(request);
	if (ret) {
		hddLog(LOGE,
			FL("timeout on stop monitor mode completion %d"), ret);
		return -EINVAL;
	}

bmps_roaming:
	hddLog(LOG1, FL("Enable BMPS"));
	hdd_enable_bmps_imps(hdd_ctx);
	hdd_restore_roaming(hdd_ctx);

	return 0;
}

bool wlan_hdd_check_monitor_state(hdd_context_t *hdd_ctx)
{
	hdd_adapter_t *mon_adapter;
	hdd_mon_ctx_t *mon_ctx;

	if (hdd_ctx->concurrency_mode != VOS_STA_MON)
		return false;

	mon_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
	if (!mon_adapter) {
		hddLog(LOGE, FL("Invalid concurrency mode"));
		return false;
	}

	mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(mon_adapter);
	if (mon_ctx->state == MON_MODE_START)
		return true;

	return false;
}

int wlan_hdd_check_and_stop_mon(hdd_adapter_t *sta_adapter, bool wait)
{
	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(sta_adapter);

	if ((sta_adapter->device_mode != WLAN_HDD_INFRA_STATION) ||
	    !wlan_hdd_check_monitor_state(hdd_ctx))
		return 0;

	if (wlan_hdd_stop_mon(hdd_ctx, wait))
		return -EINVAL;

	return 0;
}

void hdd_disable_roaming(hdd_context_t *hdd_ctx)
{
	if (!hdd_ctx)
		return;

	if (!hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled) {
		hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;
		return;
	}

	hddLog(LOG1, FL("Disable driver and firmware roaming"));

	hdd_ctx->roaming_ini_original =
		hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled;

	hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
					CFG_LFR_FEATURE_ENABLED_MIN;

	sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
					      CFG_LFR_FEATURE_ENABLED_MIN);
}

void hdd_restore_roaming(hdd_context_t *hdd_ctx)
{
	if (!hdd_ctx->roaming_ini_original)
		return;

	hddLog(LOG1, FL("Enable driver and firmware roaming"));

	hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
			CFG_LFR_FEATURE_ENABLED_MAX;

	hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;

	sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
					CFG_LFR_FEATURE_ENABLED_MAX);
}

VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
                             const v_BOOL_t bCloseSession )
{
   eHalStatus halStatus = eHAL_STATUS_SUCCESS;
   hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
   hdd_scaninfo_t *pScanInfo = NULL;
   union iwreq_data wrqu;
   v_U8_t retry = 0;
   long ret;
   VOS_STATUS status;

   if (pHddCtx->isLogpInProgress) {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                       "%s:LOGP in Progress. Ignore!!!",__func__);
       return VOS_STATUS_E_FAILURE;
   }

   ENTER();

   pScanInfo =  &pHddCtx->scan_info;
   switch(pAdapter->device_mode)
   {
      case WLAN_HDD_IBSS:
          if ( VOS_TRUE == bCloseSession )
          {
              status = hdd_sta_id_hash_detach(pAdapter);
              if (status != VOS_STATUS_SUCCESS)
              hddLog(VOS_TRACE_LEVEL_ERROR,
                  FL("sta id hash detach failed"));
          }

      case WLAN_HDD_INFRA_STATION:
      case WLAN_HDD_P2P_CLIENT:
      case WLAN_HDD_P2P_DEVICE:
      {
         hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
#ifdef FEATURE_WLAN_TDLS
         mutex_lock(&pHddCtx->tdls_lock);
         wlan_hdd_tdls_exit(pAdapter, TRUE);
         mutex_unlock(&pHddCtx->tdls_lock);
#endif
         if( hdd_connIsConnected(pstation) ||
             (pstation->conn_info.connState == eConnectionState_Connecting) )
         {
            /*
             * Indicate sme of disconnect so that in progress connection
             * or preauth can be aborted.
             */
            sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
                            pAdapter->sessionId);
            INIT_COMPLETION(pAdapter->disconnect_comp_var);
            if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
                halStatus = sme_RoamDisconnect(pHddCtx->hHal,
                                             pAdapter->sessionId,
                                             eCSR_DISCONNECT_REASON_IBSS_LEAVE);
            else
                halStatus = sme_RoamDisconnect(pHddCtx->hHal,
                                            pAdapter->sessionId, 
                                            eCSR_DISCONNECT_REASON_UNSPECIFIED);
            /* Success implies disconnect command got queued up successfully
             * Or cmd not queued as scan for SSID is in progress
             */
            if((eHAL_STATUS_SUCCESS == halStatus) ||
               (eHAL_STATUS_CMD_NOT_QUEUED == halStatus))
            {
               ret = wait_for_completion_interruptible_timeout(
                          &pAdapter->disconnect_comp_var,
                           msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
               if (ret <= 0 &&
                   (eHAL_STATUS_CMD_NOT_QUEUED != halStatus))
               {
                   hddLog(VOS_TRACE_LEVEL_ERROR,
                          "%s: wait on disconnect_comp_var failed %ld",
                           __func__, ret);
               }
            }
            else
            {
                hddLog(LOGE, "%s: failed to post disconnect event to SME",
                         __func__);
            }
            memset(&wrqu, '\0', sizeof(wrqu));
            wrqu.ap_addr.sa_family = ARPHRD_ETHER;
            memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
            wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
         }
         else if(pstation->conn_info.connState ==
                    eConnectionState_Disconnecting)
         {
             ret = wait_for_completion_interruptible_timeout(
                   &pAdapter->disconnect_comp_var,
                   msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
             if (ret <= 0)
             {
                 hddLog(VOS_TRACE_LEVEL_ERROR,
                 FL("wait on disconnect_comp_var failed %ld"), ret);
             }
         }
         if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
         {
            wlan_hdd_scan_abort(pAdapter);
         }
       if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
                   (pAdapter->device_mode != WLAN_HDD_IBSS))
       {
          while (pAdapter->is_roc_inprogress)
          {
              VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                         "%s: ROC in progress for session %d!!!",
                         __func__, pAdapter->sessionId);
              // waiting for ROC to expire
               msleep(500);
              /* In GO present case , if retry exceeds 3,
                 it means something went wrong. */
               if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
               {
                  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                            "%s: ROC completion is not received.!!!", __func__);
                  if (eHAL_STATUS_SUCCESS !=
                      sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
                                                     pAdapter->sessionId ))
                  {
                      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                              FL("Failed to Cancel Remain on Channel"));
                  }
                  wait_for_completion_interruptible_timeout(
                                       &pAdapter->cancel_rem_on_chan_var,
                                       msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
                  break;
               }
            }
          vos_flush_delayed_work(&pAdapter->roc_work);
       }
#ifdef WLAN_NS_OFFLOAD
         vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
#endif

         vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);

         /* It is possible that the caller of this function does not
          * wish to close the session
          */
         if (VOS_TRUE == bCloseSession &&
              test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
         {
            INIT_COMPLETION(pAdapter->session_close_comp_var);
            if (eHAL_STATUS_SUCCESS ==
                    sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, FALSE,
                      VOS_FALSE, hdd_smeCloseSessionCallback, pAdapter))
            {
               unsigned long ret;

               //Block on a completion variable. Can't wait forever though.
               ret = wait_for_completion_timeout(
                     &pAdapter->session_close_comp_var,
                     msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
               if ( 0 >= ret)
               {
                  hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
                        __func__, ret);
               }
            }
         }
      }
         break;

      case WLAN_HDD_SOFTAP:
      case WLAN_HDD_P2P_GO:
          if ( VOS_TRUE == bCloseSession )
          {
              status = hdd_sta_id_hash_detach(pAdapter);
              if (status != VOS_STATUS_SUCCESS)
              hddLog(VOS_TRACE_LEVEL_ERROR,
                  FL("sta id hash detach failed"));
          }

         //Any softap specific cleanup here...
         hdd_cleanup_ap_events(pAdapter);
         if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
            while (pAdapter->is_roc_inprogress) {
               VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                         "%s: ROC in progress for session %d!!!",
                         __func__, pAdapter->sessionId);
               msleep(500);
               if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
                  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                            "%s: ROC completion is not received.!!!", __func__);
                  WLANSAP_CancelRemainOnChannel(
                                     (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
                  wait_for_completion_interruptible_timeout(
                                       &pAdapter->cancel_rem_on_chan_var,
                                       msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
                  break;
               }
            }

            vos_flush_delayed_work(&pAdapter->roc_work);
         }
#ifdef SAP_AUTH_OFFLOAD
         if (pHddCtx->cfg_ini->enable_sap_auth_offload)
             hdd_set_sap_auth_offload(pAdapter, FALSE);
#endif
         mutex_lock(&pHddCtx->sap_lock);
         if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags)) 
         {
            VOS_STATUS status;
            hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);

            //Stop Bss.
            status = WLANSAP_StopBss(pHddCtx->pvosContext);
            if (VOS_IS_STATUS_SUCCESS(status))
            {
               hdd_hostapd_state_t *pHostapdState = 
                  WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);

               status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
   
               if (!VOS_IS_STATUS_SUCCESS(status))
               {
                  hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
                         __func__, status);
               }
            }
            else
            {
               hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
            }
            clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
            wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);

            if (eHAL_STATUS_FAILURE ==
                ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
                             0, NULL, eANI_BOOLEAN_FALSE))
            {
               hddLog(LOGE,
                      "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
                      __func__);
            }

            if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
                     WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
                     eANI_BOOLEAN_FALSE) )
            {
               hddLog(LOGE,
                     "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
            }

            // Reset WNI_CFG_PROBE_RSP Flags
            wlan_hdd_reset_prob_rspies(pAdapter);
            kfree(pAdapter->sessionCtx.ap.beacon);
            pAdapter->sessionCtx.ap.beacon = NULL;
         }
         mutex_unlock(&pHddCtx->sap_lock);

#ifdef WLAN_NS_OFFLOAD
         vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
#endif
         vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);

         break;

      case WLAN_HDD_MONITOR:
          if (VOS_MONITOR_MODE != hdd_get_conparam())
              wlan_hdd_stop_mon(pHddCtx, true);
          break;

      default:
         break;
   }

   EXIT();
   return VOS_STATUS_SUCCESS;
}

/**
 * wlan_hdd_restart_sap() - to restart SAP in driver internally
 * @ap_adapter: - Pointer to SAP hdd_adapter_t structure
 *
 * wlan_hdd_restart_sap first delete SAP and do cleanup.
 * After that WLANSAP_StartBss start re-start process of SAP.
 *
 * Return: None
 */
static void wlan_hdd_restart_sap(hdd_adapter_t *ap_adapter)
{
    hdd_ap_ctx_t *pHddApCtx;
    hdd_hostapd_state_t *pHostapdState;
    VOS_STATUS vos_status;
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(ap_adapter);
#ifdef USE_CFG80211_DEL_STA_V2
    struct station_del_parameters delStaParams;
#endif
    tsap_Config_t *pConfig;

    pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
    pConfig = &pHddApCtx->sapConfig;

    mutex_lock(&pHddCtx->sap_lock);
    if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
#ifdef USE_CFG80211_DEL_STA_V2
        delStaParams.mac = NULL;
        delStaParams.subtype = SIR_MAC_MGMT_DEAUTH >> 4;
        delStaParams.reason_code = eCsrForcedDeauthSta;
        wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
                                      &delStaParams);
#else
        wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
                                      NULL);
#endif
        hdd_cleanup_actionframe(pHddCtx, ap_adapter);

        pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
        vos_event_reset(&pHostapdState->vosEvent);

        if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
            vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
                                               10000);
            if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
                hddLog(LOGE, FL("SAP Stop Failed"));
                goto end;
            }
        }
        clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
        wlan_hdd_decr_active_session(pHddCtx, ap_adapter->device_mode);
        hddLog(LOG1, FL("SAP Stop Success"));

        if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
            hddLog(LOGE, FL("SAP Not able to set AP IEs"));
            goto end;
        }

        if (WLANSAP_StartBss(pHddCtx->pvosContext, hdd_hostapd_SAPEventCB,
            pConfig, (v_PVOID_t)ap_adapter->dev) != VOS_STATUS_SUCCESS) {
            hddLog(LOGE, FL("SAP Start Bss fail"));
            goto end;
        }

        hddLog(LOG1, FL("Waiting for SAP to start"));
        vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
        if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
            hddLog(LOGE, FL("SAP Start failed"));
            goto end;
        }
        hddLog(LOG1, FL("SAP Start Success"));
        set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
        wlan_hdd_incr_active_session(pHddCtx, ap_adapter->device_mode);
        pHostapdState->bCommit = TRUE;
        if (!VOS_IS_STATUS_SUCCESS(hdd_dhcp_mdns_offload(ap_adapter))) {
            hddLog(VOS_TRACE_LEVEL_ERROR, FL("DHCP/MDNS offload Failed!!"));
            vos_event_reset(&pHostapdState->vosEvent);
            if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
                vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
                                                   10000);
                if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
                    hddLog(LOGE, FL("SAP Stop Failed"));
                    goto end;
                }
            }
        }
    }
end:
    mutex_unlock(&pHddCtx->sap_lock);
    return;
}

/**
 * __hdd_sap_restart_handle() - to handle restarting of SAP
 * @work: name of the work
 *
 * Purpose of this function is to trigger sap start. this function
 * will be called from workqueue.
 *
 * Return: void.
 */
static void __hdd_sap_restart_handle(struct work_struct *work)
{
    hdd_adapter_t *sap_adapter;
    hdd_context_t *hdd_ctx = container_of(work,
                                          hdd_context_t,
                                          sap_start_work);
    if (0 != wlan_hdd_validate_context(hdd_ctx)) {
        vos_ssr_unprotect(__func__);
        return;
    }
    sap_adapter = hdd_get_adapter(hdd_ctx,
                                  WLAN_HDD_SOFTAP);
    if (sap_adapter == NULL) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  FL("sap_adapter is NULL"));
        vos_ssr_unprotect(__func__);
        return;
    }

    if (hdd_ctx->is_ch_avoid_in_progress) {
        sap_adapter->sessionCtx.ap.sapConfig.channel = AUTO_CHANNEL_SELECT;
        wlan_hdd_restart_sap(sap_adapter);
        hdd_change_ch_avoidance_status(hdd_ctx, false);
    }
    if (hdd_ctx->cfg_ini->enable_sap_auth_offload)
        wlan_hdd_restart_sap(sap_adapter);
}

/**
 * hdd_sap_restart_handle() - to handle restarting of SAP
 * @work: name of the work
 *
 * Purpose of this function is to trigger sap start. this function
 * will be called from workqueue.
 *
 * Return: void.
 */
static void hdd_sap_restart_handle(struct work_struct *work)
{
    vos_ssr_protect(__func__);
    __hdd_sap_restart_handle(work);
    vos_ssr_unprotect(__func__);
}


/**
 * __hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
 * @work: name of the work
 *
 * Purpose of this function is to force SCC using ECSA. This function
 * will be called from workqueue.
 *
 * Return: void.
 */
static void
__hdd_force_scc_with_ecsa_handle(struct work_struct *work)
{
    hdd_adapter_t *sap_adapter;
    hdd_station_ctx_t *sta_ctx;
    hdd_adapter_t *sta_adapter;
    ptSapContext sap_ctx = NULL;
    v_CONTEXT_t vos_ctx;
    tANI_U8 target_channel;
    tsap_Config_t *sap_config;
    bool sta_sap_scc_on_dfs_chan;
    eNVChannelEnabledType chan_state;
    hdd_context_t *hdd_ctx = container_of(to_delayed_work(work),
                                          hdd_context_t,
                                          ecsa_chan_change_work);

    if (wlan_hdd_validate_context(hdd_ctx))
        return;

    sap_adapter = hdd_get_adapter(hdd_ctx,
                                  WLAN_HDD_SOFTAP);
    if (!sap_adapter) {
        hddLog(LOGE, FL("sap_adapter is NULL"));
        return;
    }

    vos_ctx = hdd_ctx->pvosContext;
    if (!vos_ctx) {
        hddLog(LOGE, FL("vos_ctx is NULL"));
        return;
    }

    sap_ctx = VOS_GET_SAP_CB(vos_ctx);
    if (!sap_ctx) {
        hddLog(LOGE, FL("sap_ctx is NULL"));
        return;
    }

    sap_config = &sap_adapter->sessionCtx.ap.sapConfig;

    sta_sap_scc_on_dfs_chan = hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_ctx);

    sta_adapter = hdd_get_adapter(hdd_ctx,
                                  WLAN_HDD_INFRA_STATION);
    if (!sta_adapter) {
        hddLog(LOGE, FL("sta_adapter is NULL"));
        return;
    }

    if (wlansap_chk_n_set_chan_change_in_progress(sap_ctx))
        return;
    INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);

    sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
    if (sta_ctx->conn_info.connState != eConnectionState_Associated) {
        if (sta_ctx->conn_info.connState == eConnectionState_NotConnected) {
            chan_state = vos_nv_getChannelEnabledState(sap_ctx->channel);
            hddLog(LOG1, FL("sta not in connected state %d, sta_sap_scc_on_dfs_chan %d, chan_state %d"),
                   sta_ctx->conn_info.connState, sta_sap_scc_on_dfs_chan,
                   chan_state);
            if (sta_sap_scc_on_dfs_chan &&
                (chan_state == NV_CHANNEL_DFS)) {
               hddLog(LOGE, FL("Switch SAP to user configured channel"));
               target_channel = sap_config->user_config_channel;
               goto switch_channel;
            }
        }
        goto abort;
    }

    target_channel = sta_ctx->conn_info.operationChannel;
switch_channel:
    hddLog(LOGE, FL("Switch SAP to %d channel"),
           target_channel);
    if (!wlansap_set_channel_change(vos_ctx, target_channel, true))
        return;

abort:
   wlansap_reset_chan_change_in_progress(sap_ctx);
   complete(&sap_ctx->ecsa_info.chan_switch_comp);
}

/**
 * hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
 * @work: name of the work
 *
 * Purpose of this function is to force SCC using ECSA. This function
 * will be called from workqueue.
 *
 * Return: void.
 */
static void
hdd_force_scc_with_ecsa_handle(struct work_struct *work)
{
    vos_ssr_protect(__func__);
    __hdd_force_scc_with_ecsa_handle(work);
    vos_ssr_unprotect(__func__);
}

int hdd_wait_for_ecsa_complete(hdd_context_t *hdd_ctx)
{
    int ret;
    ptSapContext sap_ctx = NULL;
    v_CONTEXT_t vos_ctx;

    vos_ctx = hdd_ctx->pvosContext;
    if (!vos_ctx) {
        hddLog(LOGE, FL("vos_ctx is NULL"));
        return 0;
    }

    sap_ctx = VOS_GET_SAP_CB(vos_ctx);
    if (!sap_ctx) {
        hddLog(LOG1, FL("sap_ctx is NULL"));
        return 0;
    }
    if(!sap_ctx->isSapSessionOpen) {
        hddLog(LOG1, FL("sap session not opened, SAP in state %d"),
               sap_ctx->sapsMachine);
        return 0;
    }

    if (!wlansap_get_change_in_progress(sap_ctx)) {
       hddLog(LOG1, FL("channel switch not in progress"));
       return 0;
    }
    ret = wait_for_completion_timeout(&sap_ctx->ecsa_info.chan_switch_comp,
                                  msecs_to_jiffies(HDD_SAP_CHAN_CNG_WAIT_TIME));
    if (!ret)
    {
        hddLog(LOGE, FL("Timeout waiting for SAP channel switch"));
        return ret;
    }

    return 0;
}


/**
 * hdd_is_sta_sap_scc_allowed_on_dfs_chan() - check if sta+sap scc allowed on
 * dfs chan
 * @hdd_ctx: pointer to hdd context
 *
 * This function used to check if sta+sap scc allowed on DFS channel.
 *
 * Return: None
 */
bool hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_context_t *hdd_ctx)
{
    if (hdd_ctx->cfg_ini->force_scc_with_ecsa &&
            hdd_ctx->cfg_ini->sta_sap_scc_on_dfs_chan)
        return true;
    else
        return false;
}

VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
{
   hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
   VOS_STATUS status;
   hdd_adapter_t      *pAdapter;

   ENTER();

   status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );

   while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
   {
      pAdapter = pAdapterNode->pAdapter;

      hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );

      status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
      pAdapterNode = pNext;
   }

   EXIT();

   return VOS_STATUS_SUCCESS;
}


#ifdef FEATURE_WLAN_BATCH_SCAN
/**---------------------------------------------------------------------------

  \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
   structures

  \param  - pAdapter Pointer to HDD adapter

  \return - None

  --------------------------------------------------------------------------*/
void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
{
    tHddBatchScanRsp *pNode;
    tHddBatchScanRsp *pPrev;

    if (NULL == pAdapter)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: Adapter context is Null", __func__);
        return;
    }

    pNode = pAdapter->pBatchScanRsp;
    while (pNode)
    {
        pPrev = pNode;
        pNode = pNode->pNext;
        vos_mem_free((v_VOID_t * )pPrev);
    }

    pAdapter->pBatchScanRsp = NULL;
    pAdapter->numScanList = 0;
    pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
    pAdapter->prev_batch_id = 0;

    return;
}
#endif


VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
{
   hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
   VOS_STATUS status;
   hdd_adapter_t *pAdapter;

   ENTER();

   status =  hdd_get_front_adapter ( pHddCtx, &pAdapterNode );

   while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
   {
      pAdapter = pAdapterNode->pAdapter;
      hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
      netif_tx_disable(pAdapter->dev);

      if (pHddCtx->cfg_ini->sap_internal_restart &&
              pAdapter->device_mode == WLAN_HDD_SOFTAP) {
          hddLog(LOG1, FL("driver supports sap restart"));
          vos_flush_work(&pHddCtx->sap_start_work);
          hdd_sap_indicate_disconnect_for_sta(pAdapter);
          hdd_cleanup_actionframe(pHddCtx, pAdapter);
          hdd_softap_deinit_tx_rx(pAdapter, true);
          hdd_sap_destroy_timers(pAdapter);
      } else {
          netif_carrier_off(pAdapter->dev);
      }

      pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;

      if (pAdapter->device_mode == WLAN_HDD_MONITOR)
          pAdapter->sessionCtx.monitor.state = MON_MODE_STOP;

      hdd_deinit_tx_rx(pAdapter);

      if(pAdapter->device_mode == WLAN_HDD_IBSS )
         hdd_ibss_deinit_tx_rx(pAdapter);

      status = hdd_sta_id_hash_detach(pAdapter);
      if (status != VOS_STATUS_SUCCESS)
          hddLog(VOS_TRACE_LEVEL_ERROR,
                 FL("sta id hash detach failed for session id %d"),
                 pAdapter->sessionId);

      wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);

      if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
      {
          hdd_wmm_adapter_close( pAdapter );
          clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
      }

      if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
      {
          clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
      }

#ifdef FEATURE_WLAN_BATCH_SCAN
      if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
      {
          hdd_deinit_batch_scan(pAdapter);
      }
#endif

#ifdef FEATURE_WLAN_TDLS
      mutex_lock(&pHddCtx->tdls_lock);
      wlan_hdd_tdls_exit(pAdapter, TRUE);
      mutex_unlock(&pHddCtx->tdls_lock);
#endif
      status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
      pAdapterNode = pNext;
   }

   EXIT();

   return VOS_STATUS_SUCCESS;
}

/**
 * hdd_get_bss_entry() - Get the bss entry matching the chan, bssid and ssid
 * @wiphy: wiphy
 * @channel: channel of the BSS to find
 * @bssid: bssid of the BSS to find
 * @ssid: ssid of the BSS to find
 * @ssid_len: ssid len of of the BSS to find
 *
 * The API is a wrapper to get bss from kernel matching the chan,
 * bssid and ssid
 *
 * Return: Void
 */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \
    && !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)

struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
      struct ieee80211_channel *channel,
      const u8 *bssid,
      const u8 *ssid, size_t ssid_len)
{
   return cfg80211_get_bss(wiphy, channel, bssid,
           ssid, ssid_len,
           WLAN_CAPABILITY_ESS,
           WLAN_CAPABILITY_ESS);
}
#else
struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
      struct ieee80211_channel *channel,
      const u8 *bssid,
      const u8 *ssid, size_t ssid_len)
{
   return cfg80211_get_bss(wiphy, channel, bssid,
           ssid, ssid_len,
           IEEE80211_BSS_TYPE_ESS,
           IEEE80211_PRIVACY_ANY);
}
#endif

#if defined(CFG80211_CONNECT_BSS) || \
	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) || \
	defined (CFG80211_CONNECT_TIMEOUT_REASON_CODE)
/**
 * hdd_connect_bss() - helper function to send connection status to supplicant
 * @dev: network device
 * @bssid: bssid to which we want to associate
 * @bss: information about connected bss
 * @req_ie: Request Information Element
 * @req_ie_len: len of the req IE
 * @resp_ie: Response IE
 * @resp_ie_len: len of ht response IE
 * @status: status
 * @gfp: Kernel Flag
 *
 * This is a helper function to send connection status to supplicant
 * and gets invoked from wrapper API
 *
 * Return: Void
 */
static void hdd_connect_bss(struct net_device *dev,
    const u8 *bssid,
    struct cfg80211_bss *bss,
    const u8 *req_ie,
    size_t req_ie_len,
    const u8 *resp_ie,
    size_t resp_ie_len,
    u16 status,
    gfp_t gfp)
{
   cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
        resp_ie, resp_ie_len, status, gfp, NL80211_TIMEOUT_UNSPECIFIED);
}
#else
/**
 * hdd_connect_bss() - helper function to send connection status to supplicant
 * @dev: network device
 * @bssid: bssid to which we want to associate
 * @bss: information about connected bss
 * @req_ie: Request Information Element
 * @req_ie_len: len of the req IE
 * @resp_ie: Response IE
 * @resp_ie_len: len of ht response IE
 * @status: status
 * @gfp: Kernel Flag
 *
 * This is a helper function to send connection status to supplicant
 * and gets invoked from wrapper API
 *
 * Return: Void
 */
static void hdd_connect_bss(struct net_device *dev,
    const u8 *bssid,
    struct cfg80211_bss *bss,
    const u8 *req_ie,
    size_t req_ie_len,
    const u8 *resp_ie,
    size_t resp_ie_len,
    u16 status,
    gfp_t gfp)
{
   cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
        resp_ie, resp_ie_len, status, gfp);
}
#endif

/**
 * hdd_connect_result() - API to send connection status to supplicant
 * @dev: network device
 * @bssid: bssid to which we want to associate
 * @roam_info: information about connected bss
 * @req_ie: Request Information Element
 * @req_ie_len: len of the req IE
 * @resp_ie: Response IE
 * @resp_ie_len: len of ht response IE
 * @status: status
 * @gfp: Kernel Flag
 *
 * The API is a wrapper to send connection status to supplicant
 *
 * Return: Void
 */
void hdd_connect_result(struct net_device *dev,
    const u8 *bssid,
    tCsrRoamInfo *roam_info,
    const u8 *req_ie,
    size_t req_ie_len,
    const u8 *resp_ie,
    size_t resp_ie_len,
    u16 status,
    gfp_t gfp)
{
   hdd_adapter_t *padapter = (hdd_adapter_t *) netdev_priv(dev);
   struct cfg80211_bss *bss = NULL;

   if (WLAN_STATUS_SUCCESS == status) {
       struct ieee80211_channel *chan;
       int freq;
       int chan_no = roam_info->pBssDesc->channelId;;

       if (chan_no <= 14)
           freq = ieee80211_channel_to_frequency(chan_no,
                  HDD_NL80211_BAND_2GHZ);
       else
           freq = ieee80211_channel_to_frequency(chan_no,
                  HDD_NL80211_BAND_5GHZ);

       chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
       bss = hdd_get_bss_entry(padapter->wdev.wiphy,
              chan, bssid,
              roam_info->u.pConnectedProfile->SSID.ssId,
              roam_info->u.pConnectedProfile->SSID.length);
   }

   hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie, resp_ie_len,
                   status, gfp);
}
#else
/**
 * hdd_connect_result() - API to send connection status to supplicant
 * @dev: network device
 * @bssid: bssid to which we want to associate
 * @roam_info: information about connected bss
 * @req_ie: Request Information Element
 * @req_ie_len: len of the req IE
 * @resp_ie: Response IE
 * @resp_ie_len: len of ht response IE
 * @status: status
 * @gfp: Kernel Flag
 *
 * The API is a wrapper to send connection status to supplicant
 *
 * Return: Void
 */
void hdd_connect_result(struct net_device *dev,
   const u8 *bssid,
   tCsrRoamInfo *roam_info,
   const u8 *req_ie,
   size_t req_ie_len,
   const u8 * resp_ie,
   size_t resp_ie_len,
   u16 status,
   gfp_t gfp)
{
   cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
         resp_ie, resp_ie_len, status, gfp);
}
#endif

VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
{
   hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
   VOS_STATUS status;
   hdd_adapter_t      *pAdapter;
   eConnectionState  connState;
   v_CONTEXT_t pVosContext;

   ENTER();

   status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );

   while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
   {
      pAdapter = pAdapterNode->pAdapter;

      hdd_wmm_init( pAdapter );

      switch(pAdapter->device_mode)
      {
         case WLAN_HDD_INFRA_STATION:
         case WLAN_HDD_P2P_CLIENT:
         case WLAN_HDD_P2P_DEVICE:

            connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;

            hdd_init_station_mode(pAdapter);
            /* Open the gates for HDD to receive Wext commands */
            pAdapter->isLinkUpSvcNeeded = FALSE; 
            pHddCtx->scan_info.mScanPending = FALSE;
            pHddCtx->scan_info.waitScanResult = FALSE;

            //Trigger the initial scan
            if (!pHddCtx->isLogpInProgress)
                hdd_wlan_initial_scan(pAdapter);

            //Indicate disconnect event to supplicant if associated previously
            if (eConnectionState_Associated == connState ||
                eConnectionState_IbssConnected == connState )
            {
               union iwreq_data wrqu;
               memset(&wrqu, '\0', sizeof(wrqu));
               wrqu.ap_addr.sa_family = ARPHRD_ETHER;
               memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
               wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
               pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;

               /* indicate disconnected event to nl80211 */
               wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, false,
                                                     WLAN_REASON_UNSPECIFIED);
            }
            else if (eConnectionState_Connecting == connState)
            {
              /*
               * Indicate connect failure to supplicant if we were in the
               * process of connecting
               */
               hdd_connect_result(pAdapter->dev, NULL, NULL,
                                       NULL, 0, NULL, 0,
                                       WLAN_STATUS_ASSOC_DENIED_UNSPEC,
                                       GFP_KERNEL);
            }
            break;

         case WLAN_HDD_SOFTAP:
            if (pHddCtx->cfg_ini->sap_internal_restart) {
                hdd_init_ap_mode(pAdapter, true);
                status = hdd_sta_id_hash_attach(pAdapter);
                if (VOS_STATUS_SUCCESS != status)
                {
                    hddLog(VOS_TRACE_LEVEL_FATAL,
                         FL("failed to attach hash for"));
                }
            }
            break;

         case WLAN_HDD_P2P_GO:
            hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
                                                       __func__);
            cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
            break;

         case WLAN_HDD_MONITOR:
            pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);

            hddLog(VOS_TRACE_LEVEL_INFO, FL("[SSR] monitor mode"));
            if (!pVosContext) {
                hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos context is NULL"));
                break;
            }

            hdd_init_tx_rx(pAdapter);
            WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk);
            break;

         default:
            break;
      }

      status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
      pAdapterNode = pNext;
   }

   EXIT();

   return VOS_STATUS_SUCCESS;
}

VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
{
   hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
   hdd_adapter_t *pAdapter;
   VOS_STATUS status;
   v_U32_t roamId;
   long ret;

   ENTER();

   status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );

   while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
   {
      pAdapter = pAdapterNode->pAdapter;

      if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
             (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
      {
         hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
         hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);

         hddLog(VOS_TRACE_LEVEL_INFO,
            "%s: Set HDD connState to eConnectionState_NotConnected",
                   __func__);
         spin_lock_bh(&pAdapter->lock_for_active_session);
         if (eConnectionState_Associated ==  pHddStaCtx->conn_info.connState)
         {
             wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
         }
         pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
         spin_unlock_bh(&pAdapter->lock_for_active_session);
         init_completion(&pAdapter->disconnect_comp_var);
         sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
                             eCSR_DISCONNECT_REASON_UNSPECIFIED);

         ret = wait_for_completion_interruptible_timeout(
                                &pAdapter->disconnect_comp_var,
                                msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
         if (0 >= ret)
             hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
                     __func__, ret);

         pWextState->roamProfile.csrPersona = pAdapter->device_mode; 
         pHddCtx->isAmpAllowed = VOS_FALSE;
         sme_RoamConnect(pHddCtx->hHal,
                         pAdapter->sessionId, &(pWextState->roamProfile),
                         &roamId); 
      }

      status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
      pAdapterNode = pNext;
   }

   EXIT();

   return VOS_STATUS_SUCCESS;
}

void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
{
   hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
   VOS_STATUS status;
   hdd_adapter_t *pAdapter;
   hdd_station_ctx_t *pHddStaCtx;
   hdd_ap_ctx_t *pHddApCtx;
   hdd_hostapd_state_t * pHostapdState;
   tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
   v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
   const char *p2pMode = "DEV";
   const char *ccMode = "Standalone";

   status =  hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
   while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
   {
      pAdapter = pAdapterNode->pAdapter;
      switch (pAdapter->device_mode) {
      case WLAN_HDD_INFRA_STATION:
          pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
          if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
              staChannel = pHddStaCtx->conn_info.operationChannel;
              memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
          }
          break;
      case WLAN_HDD_P2P_CLIENT:
          pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
          if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
              p2pChannel = pHddStaCtx->conn_info.operationChannel;
              memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
              p2pMode = "CLI";
          }
          break;
      case WLAN_HDD_P2P_GO:
          pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
          pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
          if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
              p2pChannel = pHddApCtx->operatingChannel;
              memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
          }
          p2pMode = "GO";
          break;
      case WLAN_HDD_SOFTAP:
          pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
          pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
          if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
              apChannel = pHddApCtx->operatingChannel;
              memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
          }
          break;
      default:
          break;
      }
      status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
      pAdapterNode = pNext;
   }
   if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
       ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
   }
   hddLog(VOS_TRACE_LEVEL_ERROR, "wlan(%d) " MAC_ADDRESS_STR " %s",
	  staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
   if (p2pChannel > 0) {
       hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
                     p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
   }
   if (apChannel > 0) {
       hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
                     apChannel, MAC_ADDR_ARRAY(apBssid));
   }

   if (p2pChannel > 0 && apChannel > 0) {
        hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
   }
}

bool hdd_is_ssr_required( void)
{
    return (isSsrRequired == HDD_SSR_REQUIRED);
}

/* Once SSR is disabled then it cannot be set. */
void hdd_set_ssr_required( e_hdd_ssr_required value)
{
    if (HDD_SSR_DISABLED == isSsrRequired)
        return;

    isSsrRequired = value;
}

void hdd_set_pre_close( hdd_context_t *pHddCtx)
{
   sme_PreClose(pHddCtx->hHal);
}

VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
                                  hdd_adapter_list_node_t** ppAdapterNode)
{
    VOS_STATUS status;
    spin_lock_bh(&pHddCtx->hddAdapters.lock);
    status =  hdd_list_peek_front ( &pHddCtx->hddAdapters,
                   (hdd_list_node_t**) ppAdapterNode );
    spin_unlock_bh(&pHddCtx->hddAdapters.lock);
    return status;
}

VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
                                 hdd_adapter_list_node_t* pAdapterNode,
                                 hdd_adapter_list_node_t** pNextAdapterNode)
{
    VOS_STATUS status;
    spin_lock_bh(&pHddCtx->hddAdapters.lock);
    status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
                                  (hdd_list_node_t*) pAdapterNode,
                                  (hdd_list_node_t**)pNextAdapterNode );

    spin_unlock_bh(&pHddCtx->hddAdapters.lock);
    return status;
}

VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
                               hdd_adapter_list_node_t* pAdapterNode)
{
    VOS_STATUS status;
    spin_lock_bh(&pHddCtx->hddAdapters.lock);
    status =  hdd_list_remove_node ( &pHddCtx->hddAdapters,
                                     &pAdapterNode->node );
    spin_unlock_bh(&pHddCtx->hddAdapters.lock);
    return status;
}

VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
                                     hdd_adapter_list_node_t** ppAdapterNode)
{
    VOS_STATUS status;
    spin_lock_bh(&pHddCtx->hddAdapters.lock);
    status =  hdd_list_remove_front( &pHddCtx->hddAdapters,
                   (hdd_list_node_t**) ppAdapterNode );
    spin_unlock_bh(&pHddCtx->hddAdapters.lock);
    return status;
}

VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
                                 hdd_adapter_list_node_t* pAdapterNode)
{
    VOS_STATUS status;
    spin_lock_bh(&pHddCtx->hddAdapters.lock);
    status =  hdd_list_insert_back ( &pHddCtx->hddAdapters,
                   (hdd_list_node_t*) pAdapterNode );
    spin_unlock_bh(&pHddCtx->hddAdapters.lock);
    return status;
}

VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
                                  hdd_adapter_list_node_t* pAdapterNode)
{
    VOS_STATUS status;
    spin_lock_bh(&pHddCtx->hddAdapters.lock);
    status =  hdd_list_insert_front ( &pHddCtx->hddAdapters,
                   (hdd_list_node_t*) pAdapterNode );
    spin_unlock_bh(&pHddCtx->hddAdapters.lock);
    return status;
}

hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
                                            tSirMacAddr macAddr )
{
   hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
   hdd_adapter_t *pAdapter;
   VOS_STATUS status;

   status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );

   while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
   {
      pAdapter = pAdapterNode->pAdapter;

      if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
                                       macAddr, sizeof(tSirMacAddr) ) )
      {
         return pAdapter;
      }
      status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
      pAdapterNode = pNext;
   }

   return NULL;

} 

hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
{
   hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
   hdd_adapter_t *pAdapter;
   VOS_STATUS status;

   status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );

   while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
   {
      pAdapter = pAdapterNode->pAdapter;

      if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
          IFNAMSIZ ) )
      {
         return pAdapter;
      }
      status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
      pAdapterNode = pNext;
   }

   return NULL;

} 

hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
                                        tANI_U32 sme_session_id )
{
    hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
    hdd_adapter_t *pAdapter;
    VOS_STATUS vos_status;


    vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);

    while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
    {
        pAdapter = pAdapterNode->pAdapter;

        if (pAdapter->sessionId == sme_session_id)
            return pAdapter;

        vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
        pAdapterNode = pNext;
    }

    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
            "%s: sme_session_id %d does not exist with host",
            __func__, sme_session_id);

    return NULL;
}

hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
{
   hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
   hdd_adapter_t *pAdapter;
   VOS_STATUS status;

   status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );

   while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
   {
      pAdapter = pAdapterNode->pAdapter;

      if( pAdapter && (mode == pAdapter->device_mode) )
      {
         return pAdapter;
      }
      status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
      pAdapterNode = pNext;
   }

   return NULL;

} 

//Remove this function later
hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
{
   hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
   hdd_adapter_t *pAdapter;
   VOS_STATUS status;

   status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );

   while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
   {
      pAdapter = pAdapterNode->pAdapter;

      if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
      {
         return pAdapter;
      }

      status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
      pAdapterNode = pNext;
   }

   return NULL;

} 

/**---------------------------------------------------------------------------
  
  \brief hdd_get_operating_channel() -

   This API returns the operating channel of the requested device mode 
   
  \param  - pHddCtx - Pointer to the HDD context.
              - mode - Device mode for which operating channel is required
                suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
                                 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
  \return - channel number. "0" id the requested device is not found OR it is not connected. 
  --------------------------------------------------------------------------*/
v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
{
   hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
   VOS_STATUS status;
   hdd_adapter_t      *pAdapter;
   v_U8_t operatingChannel = 0;

   status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );

   while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
   {
      pAdapter = pAdapterNode->pAdapter;

      if( mode == pAdapter->device_mode )
      {
        switch(pAdapter->device_mode)
        {
          case WLAN_HDD_INFRA_STATION:
          case WLAN_HDD_P2P_CLIENT: 
            if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
              operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
            break;
          case WLAN_HDD_SOFTAP:
          case WLAN_HDD_P2P_GO:
            /*softap connection info */
            if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags)) 
              operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
            break;
          default:
            break;
        }

        break; //Found the device of interest. break the loop
      }

      status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
      pAdapterNode = pNext;
   }
   return operatingChannel;
}

#ifdef WLAN_FEATURE_PACKET_FILTERING
/**---------------------------------------------------------------------------

  \brief __hdd_set_multicast_list() -

  This used to set the multicast address list.

  \param  - dev - Pointer to the WLAN device.
  - skb - Pointer to OS packet (sk_buff).
  \return - success/fail

  --------------------------------------------------------------------------*/
static void __hdd_set_multicast_list(struct net_device *dev)
{
   hdd_adapter_t *pAdapter;
   hdd_context_t *pHddCtx;
   int mc_count;
   int i = 0, ret = 0;
   struct netdev_hw_addr *ha;

   ENTER();

   pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
   if (NULL == pAdapter)
   {
      hddLog(VOS_TRACE_LEVEL_ERROR,
            "%s: Adapter context is Null", __func__);
      return;
   }
   pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
   ret = wlan_hdd_validate_context(pHddCtx);
   if (0 != ret)
   {
       return;
   }
   if (dev->flags & IFF_ALLMULTI)
   {
      hddLog(VOS_TRACE_LEVEL_INFO,
            "%s: allow all multicast frames", __func__);
      pAdapter->mc_addr_list.mc_cnt = 0;
   }
   else
   {
      mc_count = netdev_mc_count(dev);
      hddLog(VOS_TRACE_LEVEL_INFO,
            "%s: mc_count = %u", __func__, mc_count);
      if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
      {
         hddLog(VOS_TRACE_LEVEL_INFO,
               "%s: No free filter available; allow all multicast frames", __func__);
         pAdapter->mc_addr_list.mc_cnt = 0;
         return;
      }

      pAdapter->mc_addr_list.mc_cnt = mc_count;

      netdev_for_each_mc_addr(ha, dev) {
         if (i == mc_count)
            break;
         memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
         memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
         hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
               __func__, i,
               MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
         i++;
      }
   }

   if (pHddCtx->hdd_wlan_suspended)
   {
       /*
        * Configure the Mcast address list to FW
        * If wlan is already in suspend mode
        */
       wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
   }
   EXIT();
   return;
}

static void hdd_set_multicast_list(struct net_device *dev)
{
   vos_ssr_protect(__func__);
   __hdd_set_multicast_list(dev);
   vos_ssr_unprotect(__func__);
}
#endif

/**---------------------------------------------------------------------------
  
  \brief hdd_select_queue() - 

   This function is registered with the Linux OS for network
   core to decide which queue to use first.
   
  \param  - dev - Pointer to the WLAN device.
              - skb - Pointer to OS packet (sk_buff).
  \return - ac, Queue Index/access category corresponding to UP in IP header 
  
  --------------------------------------------------------------------------*/
v_U16_t hdd_select_queue(struct net_device *dev,
    struct sk_buff *skb
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
    , void *accel_priv
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
    , select_queue_fallback_t fallback
#endif
)
{
   return hdd_wmm_select_queue(dev, skb);
}


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

  \brief hdd_wlan_initial_scan() -

   This function triggers the initial scan

  \param  - pAdapter - Pointer to the HDD adapter.

  --------------------------------------------------------------------------*/
void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
{
   tCsrScanRequest scanReq;
   tCsrChannelInfo channelInfo;
   eHalStatus halStatus;
   tANI_U32 scanId;
   hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);

   vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
   vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
   scanReq.BSSType = eCSR_BSS_TYPE_ANY;

   if(sme_Is11dSupported(pHddCtx->hHal))
   {
      halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
      if ( HAL_STATUS_SUCCESS( halStatus ) )
      {
         scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
         if( !scanReq.ChannelInfo.ChannelList )
         {
            hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
            vos_mem_free(channelInfo.ChannelList);
            channelInfo.ChannelList = NULL;
            return;
         }
         vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
            channelInfo.numOfChannels);
         scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
         vos_mem_free(channelInfo.ChannelList);
         channelInfo.ChannelList = NULL;
      }

      scanReq.scanType = eSIR_PASSIVE_SCAN;
      scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
      scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
      scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
   }
   else
   {
      scanReq.scanType = eSIR_ACTIVE_SCAN;
      scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
      scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
      scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
   }

   halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
   if ( !HAL_STATUS_SUCCESS( halStatus ) )
   {
      hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
         __func__, halStatus );
   }

   if(sme_Is11dSupported(pHddCtx->hHal))
        vos_mem_free(scanReq.ChannelInfo.ChannelList);
}

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

  \brief hdd_full_power_callback() - HDD full power callback function

  This is the function invoked by SME to inform the result of a full power
  request issued by HDD

  \param  - callbackcontext - Pointer to cookie
  \param  - status - result of request

  \return - None

  --------------------------------------------------------------------------*/
static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
{
   struct statsContext *pContext = callbackContext;

   hddLog(VOS_TRACE_LEVEL_INFO,
          "%s: context = %pK, status = %d", __func__, pContext, status);

   if (NULL == callbackContext)
   {
      hddLog(VOS_TRACE_LEVEL_ERROR,
             "%s: Bad param, context [%pK]",
             __func__, callbackContext);
      return;
   }

   /* there is a race condition that exists between this callback
      function and the caller since the caller could time out either
      before or while this code is executing.  we use a spinlock to
      serialize these actions */
   spin_lock(&hdd_context_lock);

   if (POWER_CONTEXT_MAGIC != pContext->magic)
   {
      /* the caller presumably timed out so there is nothing we can do */
      spin_unlock(&hdd_context_lock);
      hddLog(VOS_TRACE_LEVEL_WARN,
             "%s: Invalid context, magic [%08x]",
              __func__, pContext->magic);
      return;
   }

   /* context is valid so caller is still waiting */

   /* paranoia: invalidate the magic */
   pContext->magic = 0;

   /* notify the caller */
   complete(&pContext->completion);

   /* serialization is complete */
   spin_unlock(&hdd_context_lock);
}

void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
{
   pMonCtx->typeSubtypeBitmap = 0;
   if( type%10 ) /* Management Packets */
     pMonCtx->typeSubtypeBitmap |= 0xFFFF;
   type/=10;
   if( type%10 ) /* Control Packets */
     pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
   type/=10;
   if( type%10 ) /* Data Packets */
     pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
}

VOS_STATUS wlan_hdd_mon_postMsg(void *context, hdd_mon_ctx_t *pMonCtx,
                                void* callback)
{
    vos_msg_t    monMsg;
    tSirMonModeReq *pMonModeReq;

    if (MON_MODE_START == pMonCtx->state)
        monMsg.type = WDA_MON_START_REQ;
    else if (MON_MODE_STOP == pMonCtx->state)
        monMsg.type = WDA_MON_STOP_REQ;
    else {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                FL("invalid monitor state %d"), pMonCtx->state);
        return VOS_STATUS_E_FAILURE;
    }

    pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
    if (pMonModeReq == NULL) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                FL("fail to allocate memory for monitor mode req"));
        return VOS_STATUS_E_FAILURE;
    }

    pMonModeReq->context = context;
    pMonModeReq->data = pMonCtx;
    pMonModeReq->callback = callback;

    monMsg.reserved = 0;
    monMsg.bodyptr = pMonModeReq;
    monMsg.bodyval = 0;

    if (VOS_STATUS_SUCCESS != vos_mq_post_message(
        VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
        hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
        vos_mem_free(pMonModeReq);
    }
    return VOS_STATUS_SUCCESS;
}

void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
{
    VOS_STATUS vosStatus;
    v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
    hdd_mon_ctx_t *pMonCtx = NULL;
    int ret;
    void *cookie;
    struct hdd_request *request;
    static const struct hdd_request_params params = {
        .priv_size = 0,
        .timeout_ms = MON_MODE_MSG_TIMEOUT,
    };

    hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
    if(pAdapter == NULL || pVosContext == NULL)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
        return ;
    }

    pMonCtx =  WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
    if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
        pMonCtx->state = MON_MODE_STOP;
        request = hdd_request_alloc(&params);
        if (!request) {
            hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
            return;
        }
        cookie = hdd_request_cookie(request);

        if (VOS_STATUS_SUCCESS !=
                      wlan_hdd_mon_postMsg(cookie, pMonCtx,
                                           hdd_mon_post_msg_cb)) {
             VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                       FL("failed to post MON MODE REQ"));
             pMonCtx->state = MON_MODE_START;
             goto req_put;
        }

        ret = hdd_request_wait_for_response(request);
        if (ret)
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                    FL("timeout on monitor mode completion %d"), ret);

req_put:
        hdd_request_put(request);
    }

   hdd_UnregisterWext(pAdapter->dev);

   vos_mon_stop( pVosContext );

   vosStatus = vos_sched_close( pVosContext );
   if (!VOS_IS_STATUS_SUCCESS(vosStatus))    {
      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
         "%s: Failed to close VOSS Scheduler",__func__);
      VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
   }

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

   vos_close(pVosContext);

   #ifdef WLAN_KD_READY_NOTIFIER
       nl_srv_exit(pHddCtx->ptt_pid);
   #else
       nl_srv_exit();
   #endif

   hdd_close_all_adapters( pHddCtx );
}
/**
 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
 * @ wiphy: the wiphy to validate against
 *
 * Return: void
 */
void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
{
    int i =0;
    for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
    {
        if (NULL != wiphy->bands[i] &&
                (NULL != wiphy->bands[i]->channels))
        {
            vos_mem_free(wiphy->bands[i]->channels);
            wiphy->bands[i]->channels = NULL;
        }
    }
}
/**---------------------------------------------------------------------------

  \brief hdd_wlan_exit() - HDD WLAN exit function

  This is the driver exit point (invoked during rmmod)

  \param  - pHddCtx - Pointer to the HDD Context

  \return - None

  --------------------------------------------------------------------------*/
void hdd_wlan_exit(hdd_context_t *pHddCtx)
{
   eHalStatus halStatus;
   v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
   VOS_STATUS vosStatus;
   struct wiphy *wiphy = pHddCtx->wiphy;
   hdd_adapter_t* pAdapter = NULL;
   struct statsContext powerContext;
   long lrc;
   hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;

   ENTER();


   if (VOS_MONITOR_MODE == hdd_get_conparam())
   {
      hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
      wlan_hdd_mon_close(pHddCtx);
      goto free_hdd_ctx;
   }
   else if (VOS_FTM_MODE != hdd_get_conparam())
   {
      // Unloading, restart logic is no more required.
      wlan_hdd_restart_deinit(pHddCtx);

#ifdef FEATURE_WLAN_TDLS
      /* At the time of driver unloading; if tdls connection is present;
       * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
       * wlan_hdd_tdls_find_peer always checks for valid context;
       * as load/unload in progress there can be a race condition.
       * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
       * when tdls state is enabled.
       * As soon as driver set load/unload flag; tdls flag also needs
       * to be disabled so that hdd_rx_packet_cbk won't call
       * wlan_hdd_tdls_find_peer.
       */
      wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE,
                             HDD_SET_TDLS_MODE_SOURCE_USER);
#endif

      vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
      while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
      {
         pAdapter = pAdapterNode->pAdapter;
         if (NULL != pAdapter)
         {
            /* Disable TX on the interface, after this hard_start_xmit() will
             * not be called on that interface
             */
            hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
            netif_tx_disable(pAdapter->dev);

            /* Mark the interface status as "down" for outside world */
            netif_carrier_off(pAdapter->dev);

            /* DeInit the adapter. This ensures that all data packets
             * are freed.
             */
#ifdef FEATURE_WLAN_TDLS
            mutex_lock(&pHddCtx->tdls_lock);
#endif
            hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
#ifdef FEATURE_WLAN_TDLS
            mutex_unlock(&pHddCtx->tdls_lock);
#endif
            vos_flush_delayed_work(&pHddCtx->scan_ctxt.scan_work);

            wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);

            if (WLAN_HDD_INFRA_STATION ==  pAdapter->device_mode ||
                WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
                WLAN_HDD_MONITOR == pAdapter->device_mode)
            {
                if (WLAN_HDD_INFRA_STATION ==  pAdapter->device_mode ||
                    WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
                    wlan_hdd_cfg80211_deregister_frames(pAdapter);

                hdd_UnregisterWext(pAdapter->dev);
            }

         }
         vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
         pAdapterNode = pNext;
      }

      // Cancel any outstanding scan requests.  We are about to close all
      // of our adapters, but an adapter structure is what SME passes back
      // to our callback function. Hence if there are any outstanding scan
      // requests then there is a race condition between when the adapter
      // is closed and when the callback is invoked.We try to resolve that
      // race condition here by canceling any outstanding scans before we
      // close the adapters.
      // Note that the scans may be cancelled in an asynchronous manner,
      // so ideally there needs to be some kind of synchronization. Rather
      // than introduce a new synchronization here, we will utilize the
      // fact that we are about to Request Full Power, and since that is
      // synchronized, the expectation is that by the time Request Full
      // Power has completed all scans will be cancelled.
      if (pHddCtx->scan_info.mScanPending)
      {
          if(NULL != pAdapter)
          {
             hddLog(VOS_TRACE_LEVEL_INFO,
                    FL("abort scan mode: %d sessionId: %d"),
                       pAdapter->device_mode,
                       pAdapter->sessionId);
          }
          hdd_abort_mac_scan(pHddCtx,
                             pHddCtx->scan_info.sessionId,
                             eCSR_SCAN_ABORT_DEFAULT);
      }
   }
   else
   {
      hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
      if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
      {
         INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
              "%s: in middle of FTM START", __func__);
         lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
                                          msecs_to_jiffies(20000));
         if(!lrc)
         {
              VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
              "%s: timedout on ftmStartCmpVar fatal error", __func__);
         }
      }
      wlan_hdd_ftm_close(pHddCtx);
      goto free_hdd_ctx;
   }

   /* DeRegister with platform driver as client for Suspend/Resume */
   vosStatus = hddDeregisterPmOps(pHddCtx);
   if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
      VOS_ASSERT(0);
   }

   vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
   if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
   }

   //Stop the traffic monitor timer
   if ((pHddCtx->cfg_ini->dynSplitscan) && (VOS_TIMER_STATE_RUNNING ==
        vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
   {
        vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
   }

   // Destroy the traffic monitor timer
   if ((pHddCtx->cfg_ini->dynSplitscan) &&
       (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
                         &pHddCtx->tx_rx_trafficTmr))))
   {
       hddLog(VOS_TRACE_LEVEL_ERROR,
           "%s: Cannot deallocate Traffic monitor timer", __func__);
   }

   if (VOS_TIMER_STATE_RUNNING ==
                      vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
       vos_timer_stop(&pHddCtx->delack_timer);
   }

   if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
                                   &pHddCtx->delack_timer))) {
       hddLog(VOS_TRACE_LEVEL_ERROR,
            "%s: Cannot deallocate Bus bandwidth timer", __func__);
   }

   if (VOS_TIMER_STATE_RUNNING ==
                 vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) {
       vos_timer_stop(&pHddCtx->tdls_source_timer);
   }

   vos_set_snoc_high_freq_voting(false);

   vos_timer_destroy(&pHddCtx->tdls_source_timer);

   //Disable IMPS/BMPS as we do not want the device to enter any power
   //save mode during shutdown
   sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
   sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
   sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);

   //Ensure that device is in full power as we will touch H/W during vos_Stop
   init_completion(&powerContext.completion);
   powerContext.magic = POWER_CONTEXT_MAGIC;

   halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
                                    &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);

   if (eHAL_STATUS_SUCCESS != halStatus)
   {
      if (eHAL_STATUS_PMC_PENDING == halStatus)
      {
         /* request was sent -- wait for the response */
         lrc = wait_for_completion_interruptible_timeout(
                                      &powerContext.completion,
                                      msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
         if (lrc <= 0)
         {
            hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
                   __func__, (0 == lrc) ? "timeout" : "interrupt");
         }
      }
      else
      {
         hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: Request for Full Power failed, status %d",
                __func__, halStatus);
         /* continue -- need to clean up as much as possible */
      }
   }
   if ((eHAL_STATUS_SUCCESS == halStatus) ||
       (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
   {
       /* This will issue a dump command which will clean up
          BTQM queues and unblock MC thread */
       vos_fwDumpReq(274, 0, 0, 0, 0, 1);
   }

   /* either we never sent a request, we sent a request and received a
      response or we sent a request and timed out.  if we never sent a
      request or if we sent a request and got a response, we want to
      clear the magic out of paranoia.  if we timed out there is a
      race condition such that the callback function could be
      executing at the same time we are. of primary concern is if the
      callback function had already verified the "magic" but had not
      yet set the completion variable when a timeout occurred. we
      serialize these activities by invalidating the magic while
      holding a shared spinlock which will cause us to block if the
      callback is currently executing */
   spin_lock(&hdd_context_lock);
   powerContext.magic = 0;
   spin_unlock(&hdd_context_lock);

   /* If Device is shutdown, no point for SME to wait for responses
      from device. Pre Close SME */
   if(wcnss_device_is_shutdown())
   {
      sme_PreClose(pHddCtx->hHal);
   }
   hdd_debugfs_exit(pHddCtx);

#ifdef WLAN_NS_OFFLOAD
   hddLog(LOG1, FL("Unregister IPv6 notifier"));
   unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
#endif
   hddLog(LOG1, FL("Unregister IPv4 notifier"));
   unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);

   // Unregister the Net Device Notifier
   unregister_netdevice_notifier(&hdd_netdev_notifier);
   
   hdd_stop_all_adapters( pHddCtx );

#ifdef WLAN_BTAMP_FEATURE
   vosStatus = WLANBAP_Stop(pVosContext);
   if (!VOS_IS_STATUS_SUCCESS(vosStatus))
   {
       VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
               "%s: Failed to stop BAP",__func__);
   }
#endif //WLAN_BTAMP_FEATURE

   //Stop all the modules
   vosStatus = vos_stop( pVosContext );
   if (!VOS_IS_STATUS_SUCCESS(vosStatus))
   {
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
         "%s: Failed to stop VOSS",__func__);
      VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
      if (isSsrPanicOnFailure())
          VOS_BUG(0);
   }

   //This requires pMac access, Call this before vos_close().
   hdd_unregister_mcast_bcast_filter(pHddCtx);

   //Close the scheduler before calling vos_close to make sure no thread is 
   // scheduled after the each module close is called i.e after all the data 
   // structures are freed.
   vosStatus = vos_sched_close( pVosContext );
   if (!VOS_IS_STATUS_SUCCESS(vosStatus))    {
      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
         "%s: Failed to close VOSS Scheduler",__func__);
      VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
   }
#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
   /* Destroy the wake lock */
   vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
#endif
   /* Destroy the wake lock */
   vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);

#ifdef CONFIG_ENABLE_LINUX_REG
   vosStatus = vos_nv_close();
   if (!VOS_IS_STATUS_SUCCESS(vosStatus))
   {
      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
          "%s: Failed to close NV", __func__);
      VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
   }
#endif

   //Close VOSS
   //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
   vos_close(pVosContext);

   //Close Watchdog
   if(pHddCtx->cfg_ini->fIsLogpEnabled)
      vos_watchdog_close(pVosContext);

   //Clean up HDD Nlink Service
   send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);

   hdd_close_tx_queues(pHddCtx);
   wlan_free_fwr_mem_dump_buffer();
   memdump_deinit();

#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
   if (pHddCtx->cfg_ini->wlanLoggingEnable)
   {
       wlan_logging_sock_deactivate_svc();
   }
#endif

#ifdef WLAN_KD_READY_NOTIFIER
   nl_srv_exit(pHddCtx->ptt_pid);
#else
   nl_srv_exit();
#endif /* WLAN_KD_READY_NOTIFIER */

#ifdef WLAN_FEATURE_RMC
   hdd_close_cesium_nl_sock();
#endif /* WLAN_FEATURE_RMC */

   hdd_close_all_adapters( pHddCtx );

   vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
   vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
   vos_flush_work(&pHddCtx->sap_start_work);

free_hdd_ctx:
   /* free the power on lock from platform driver */
   if (free_riva_power_on_lock("wlan"))
   {
      hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
                                           __func__);
   }

    /* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */
    wlan_hdd_free_cache_channels(pHddCtx);

   //Free up dynamically allocated members inside HDD Adapter
   if (pHddCtx->cfg_ini)
   {
       kfree(pHddCtx->cfg_ini);
       pHddCtx->cfg_ini= NULL;
   }

   hdd_request_manager_deinit();

   /* FTM/MONITOR mode, WIPHY did not registered
      If un-register here, system crash will happen */
   if (!(VOS_FTM_MODE == hdd_get_conparam() ||
            VOS_MONITOR_MODE == hdd_get_conparam()))
   {
      wiphy_unregister(wiphy) ;
      hdd_wlan_free_wiphy_channels(wiphy);
   }
   wiphy_free(wiphy) ;
   if (hdd_is_ssr_required())
   {
       /* WDI timeout had happened during unload, so SSR is needed here */
       subsystem_restart("wcnss");
       msleep(5000);
   }
   hdd_set_ssr_required (VOS_FALSE);
}


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

  \brief hdd_update_config_from_nv() - Function to update the contents of
         the running configuration with parameters taken from NV storage

  \param  - pHddCtx - Pointer to the HDD global context

  \return - VOS_STATUS_SUCCESS if successful

  --------------------------------------------------------------------------*/
static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
{
   v_BOOL_t itemIsValid = VOS_FALSE;
   VOS_STATUS status;
   v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
   v_U8_t      macLoop;

   /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
   status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
   if(status != VOS_STATUS_SUCCESS)
   {
      hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
       return VOS_STATUS_E_FAILURE;
   }

   if (itemIsValid == VOS_TRUE) 
   {
        hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
      status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
                                          VOS_MAX_CONCURRENCY_PERSONA);
        if(status != VOS_STATUS_SUCCESS)
        {
         /* Get MAC from NV fail, not update CFG info
          * INI MAC value will be used for MAC setting */
         hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
            return VOS_STATUS_E_FAILURE;
        }

      /* If first MAC is not valid, treat all others are not valid
       * Then all MACs will be got from ini file */
      if(vos_is_macaddr_zero(&macFromNV[0]))
      {
         /* MAC address in NV file is not configured yet */
         hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
         return VOS_STATUS_E_INVAL;
   }

      /* Get MAC address from NV, update CFG info */
      for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
      {
         if(vos_is_macaddr_zero(&macFromNV[macLoop]))
         {
            hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
            /* This MAC is not valid, skip it
             * This MAC will be got from ini file */
         }
         else
         {
            vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
                         (v_U8_t *)&macFromNV[macLoop].bytes[0],
                   VOS_MAC_ADDR_SIZE);
         }
      }
   }
   else
   {
      hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
      return VOS_STATUS_E_FAILURE;
   }


   return VOS_STATUS_SUCCESS;
}

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

  \brief hdd_post_voss_start_config() - HDD post voss start config helper

  \param  - pAdapter - Pointer to the HDD

  \return - None

  --------------------------------------------------------------------------*/
VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
{
   eHalStatus halStatus;
   v_U32_t listenInterval;
   tANI_U32    ignoreDtim;


   // Send ready indication to the HDD.  This will kick off the MAC
   // into a 'running' state and should kick off an initial scan.
   halStatus = sme_HDDReadyInd( pHddCtx->hHal );
   if ( !HAL_STATUS_SUCCESS( halStatus ) )
   {
      hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
          "code %08d [x%08x]",__func__, halStatus, halStatus );
      return VOS_STATUS_E_FAILURE;
   }

   // Set default LI and ignoreDtim into HDD context,
   // otherwise under some race condition, HDD will set 0 LI value into RIVA,
   // And RIVA will crash
   wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
   pHddCtx->hdd_actual_LI_value = listenInterval;
   wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
   pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;


   return VOS_STATUS_SUCCESS;
}

/* wake lock APIs for HDD */
void hdd_prevent_suspend(uint32_t reason)
{

    vos_wake_lock_acquire(&wlan_wake_lock, reason);

}

void hdd_allow_suspend(uint32_t reason)
{

    vos_wake_lock_release(&wlan_wake_lock, reason);

}

void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
{

    vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
                                      reason);

}

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

  \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
                                                                 information between Host and Riva

  This function gets reported version of FW
  It also finds the version of Riva headers used to compile the host
  It compares the above two and prints a warning if they are different
  It gets the SW and HW version string
  Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
  indicating the features they support through a bitmap

  \param  - pHddCtx - Pointer to HDD context

  \return -  void

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

void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
{

   tSirVersionType versionCompiled;
   tSirVersionType versionReported;
   tSirVersionString versionString;
   tANI_U8 fwFeatCapsMsgSupported = 0;
   VOS_STATUS vstatus;

   memset(&versionCompiled, 0, sizeof(versionCompiled));
   memset(&versionReported, 0, sizeof(versionReported));

   /* retrieve and display WCNSS version information */
   do {

      vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
                                                &versionCompiled);
      if (!VOS_IS_STATUS_SUCCESS(vstatus))
      {
         hddLog(VOS_TRACE_LEVEL_FATAL,
                "%s: unable to retrieve WCNSS WLAN compiled version",
                __func__);
         break;
      }

      vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
                                                &versionReported);
      if (!VOS_IS_STATUS_SUCCESS(vstatus))
      {
         hddLog(VOS_TRACE_LEVEL_FATAL,
                "%s: unable to retrieve WCNSS WLAN reported version",
                __func__);
         break;
      }

      if ((versionCompiled.major != versionReported.major) ||
          (versionCompiled.minor != versionReported.minor) ||
          (versionCompiled.version != versionReported.version) ||
          (versionCompiled.revision != versionReported.revision))
      {
         pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
                "Host expected %u.%u.%u.%u\n",
                WLAN_MODULE_NAME,
                (int)versionReported.major,
                (int)versionReported.minor,
                (int)versionReported.version,
                (int)versionReported.revision,
                (int)versionCompiled.major,
                (int)versionCompiled.minor,
                (int)versionCompiled.version,
                (int)versionCompiled.revision);
      }
      else
      {
         pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
                 WLAN_MODULE_NAME,
                 (int)versionReported.major,
                 (int)versionReported.minor,
                 (int)versionReported.version,
                 (int)versionReported.revision);
      }

      vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
                                            versionString,
                                            sizeof(versionString));
      if (!VOS_IS_STATUS_SUCCESS(vstatus))
      {
         hddLog(VOS_TRACE_LEVEL_FATAL,
                "%s: unable to retrieve WCNSS software version string",
                __func__);
         break;
      }

      pr_info("%s: WCNSS software version %s\n",
              WLAN_MODULE_NAME, versionString);
      vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));

      vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
                                            versionString,
                                            sizeof(versionString));
      if (!VOS_IS_STATUS_SUCCESS(vstatus))
      {
         hddLog(VOS_TRACE_LEVEL_FATAL,
                "%s: unable to retrieve WCNSS hardware version string",
                __func__);
         break;
      }

      pr_info("%s: WCNSS hardware version %s\n",
              WLAN_MODULE_NAME, versionString);

      /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message 
         2.Host-FW capability exchange message  is only present on riva 1.1 so 
            send the message only if it the riva is 1.1
            minor numbers for different riva branches:
                0 -> (1.0)Mainline Build
                1 -> (1.1)Mainline Build
                2->(1.04) Stability Build
       */
      if (((versionReported.major>0) || (versionReported.minor>1) || 
         ((versionReported.minor>=1) && (versionReported.version>=1)))
         && ((versionReported.major == 1) && (versionReported.minor >= 1)))
         fwFeatCapsMsgSupported = 1;
 
      if (fwFeatCapsMsgSupported)
      {
#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
         if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
            sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
#endif
         /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
         if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
         {
            sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
         }

         sme_featureCapsExchange(pHddCtx->hHal);
      }

   } while (0);

}
void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
{
       struct sk_buff *skb;
       struct nlmsghdr *nlh;
       tAniMsgHdr *ani_hdr;
       int flags = GFP_KERNEL;
       void *nl_data = NULL;

       if (in_interrupt() || irqs_disabled() || in_atomic())
           flags = GFP_ATOMIC;

       skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);

       if(skb == NULL) {
               VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                               "%s: alloc_skb failed", __func__);
               return;
       }

       nlh = (struct nlmsghdr *)skb->data;
       nlh->nlmsg_pid = 0;  /* from kernel */
       nlh->nlmsg_flags = 0;
       nlh->nlmsg_seq = 0;
       nlh->nlmsg_type = WLAN_NL_MSG_SVC;

       ani_hdr = NLMSG_DATA(nlh);
       ani_hdr->type = type;

       switch(type) {
               case WLAN_SVC_SAP_RESTART_IND:
                       ani_hdr->length = 0;
                       nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
                       skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
                       break;
               case WLAN_SVC_WLAN_TP_IND:
                        ani_hdr->length = len;
                        nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)
                                                                       + len));
                        nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
                        memcpy(nl_data, data, len);
                        skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
                        break;
               case WLAN_MSG_RPS_ENABLE_IND:
                        ani_hdr->length = len;
                        nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
                        nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
                        memcpy(nl_data, data, len);
                        skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
                        break;
               default:
                       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                       "Attempt to send unknown nlink message %d", type);
                       kfree_skb(skb);
                       return;
       }

    nl_srv_bcast(skb);

    return;
}

/**
 * hdd_request_tcp_delack() - Find the Delack value based on RX packet
 * @pHddCtx: Valid Global HDD context pointer
 * @rx_packets: Number of RX packet in perticular time
 *
 * Based on the RX packet this function calculate  next value of tcp delack.
 * This function compare rx packet value to high and low threshold limit.
 *
 * Return: void
 */
void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets)
{
    /* average of rx_packets and prev_rx is taken so that
       bus width doesnot fluctuate much */
    uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2;
    TP_IND_TYPE next_rx_level = pHddCtx->cur_rx_level;

    pHddCtx->prev_rx = rx_packets;
    if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh)
        next_rx_level = TP_IND_HIGH;
    else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow)
        next_rx_level = TP_IND_LOW;

    hdd_set_delack_value(pHddCtx, next_rx_level);
}

#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x)))

/**
 * hdd_tcp_delack_compute_function() - get link status
 * @priv: Valid Global HDD context pointer
 *
 * This function find number of RX packet during timer life span.
 * It request tcp delack with number of RX packet and re-configure delack timer
 * for tcpDelAckComputeInterval timer interval.
 *
 * Return: void
 */
void hdd_tcp_delack_compute_function(void *priv)
{
    hdd_context_t *pHddCtx = (hdd_context_t *)priv;
    hdd_adapter_t *pAdapter = NULL;
    v_U32_t rx_packets = 0;
    hdd_adapter_list_node_t *pAdapterNode = NULL;
    VOS_STATUS status = 0;

    for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
          NULL != pAdapterNode && VOS_STATUS_SUCCESS == status;
          status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) {
        if ((pAdapter = pAdapterNode->pAdapter) == NULL)
             continue;

        rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets,
                    pAdapter->prev_rx_packets);
        pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
    }

    hdd_request_tcp_delack(pHddCtx, rx_packets);

    vos_timer_start(&pHddCtx->delack_timer,
            pHddCtx->cfg_ini->tcpDelAckComputeInterval);
}

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

  \brief hdd_is_5g_supported() - HDD function to know if hardware supports  5GHz

  \param  - pHddCtx - Pointer to the hdd context

  \return -  true if hardware supports 5GHz

  --------------------------------------------------------------------------*/
boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
{
   /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
    * then hardware support 5Ghz.
   */
   if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
   {
      hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
      return true;
   }
   else
   {
      hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
                    __func__);
      return false;
   }
}

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

  \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
                                              generate function

  This is generate the random mac address for WLAN interface

  \param  - pHddCtx  - Pointer to HDD context
            idx      - Start interface index to get auto
                       generated mac addr.
            mac_addr - Mac address

  \return -  0 for success, < 0 for failure

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

static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
                                            int idx, v_MACADDR_t mac_addr)
{
   int i;
   unsigned int serialno;
   serialno = wcnss_get_serial_number();

   if (0 != serialno)
   {
      /* MAC address has 3 bytes of OUI so we have a maximum of 3
         bytes of the serial number that can be used to generate
         the other 3 bytes of the MAC address.  Mask off all but
         the lower 3 bytes (this will also make sure we don't
         overflow in the next step) */
      serialno &= 0x00FFFFFF;

      /* we need a unique address for each session */
      serialno *= VOS_MAX_CONCURRENCY_PERSONA;

      /* autogen other Mac addresses */
      for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
      {
         /* start with the entire default address */
         pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
         /* then replace the lower 3 bytes */
         pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
         pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
         pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;

		if (0 == memcmp(&pHddCtx->cfg_ini->intfMacAddr[i].bytes[0],
				&mac_addr.bytes[0], VOS_MAC_ADDR_SIZE))
			pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] +=
				VOS_MAX_CONCURRENCY_PERSONA;

         serialno++;
         hddLog(VOS_TRACE_LEVEL_ERROR,
                   "%s: Derived Mac Addr: "
                   MAC_ADDRESS_STR, __func__,
                   MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
      }

   }
   else
   {
      hddLog(LOGE, FL("Failed to Get Serial NO"));
      return -1;
   }
   return 0;
}

int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
{
    VOS_STATUS status;
    v_CONTEXT_t pVosContext= NULL;
    hdd_adapter_t *pAdapter= NULL;

    pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);

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

   status = vos_nv_open();
   if (!VOS_IS_STATUS_SUCCESS(status))
   {
       /* NV module cannot be initialized */
       hddLog( VOS_TRACE_LEVEL_FATAL,
                "%s: vos_nv_open failed", __func__);
       return VOS_STATUS_E_FAILURE;
   }

   status = vos_init_wiphy_from_nv_bin();
   if (!VOS_IS_STATUS_SUCCESS(status))
   {
       /* NV module cannot be initialized */
       hddLog( VOS_TRACE_LEVEL_FATAL,
               "%s: vos_init_wiphy failed", __func__);
       goto err_vos_nv_close;
   }

   status = vos_open( &pVosContext, pHddCtx->parent_dev);
   if ( !VOS_IS_STATUS_SUCCESS( status ))
   {
      hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
      goto err_vos_nv_close;
   }

   status = vos_mon_start( pVosContext );
   if ( !VOS_IS_STATUS_SUCCESS( status ) )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
      goto err_vosclose;
   }

   WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
   WDA_featureCapsExchange(pVosContext);
   wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);

   pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
         wlan_hdd_get_intf_addr(pHddCtx), FALSE );
   if( pAdapter == NULL )
   {
      hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
      goto err_close_adapter;
   }

   //Initialize the nlink service
   if(nl_srv_init() != 0)
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
      goto err_close_adapter;
   }
   return VOS_STATUS_SUCCESS;

err_close_adapter:
   hdd_close_all_adapters( pHddCtx );
   vos_mon_stop( pVosContext );
err_vosclose:
   status = vos_sched_close( pVosContext );
   if (!VOS_IS_STATUS_SUCCESS(status))    {
      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
         "%s: Failed to close VOSS Scheduler", __func__);
      VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
   }
   vos_close(pVosContext );

err_vos_nv_close:
   vos_nv_close();

return status;
}
/**---------------------------------------------------------------------------

  \brief hdd_11d_scan_done - callback to be executed when 11d scan is
                             completed to flush out the scan results

  11d scan is done during driver load and is a passive scan on all
  channels supported by the device, 11d scans may find some APs on
  frequencies which are forbidden to be used in the regulatory domain
  the device is operating in. If these APs are notified to the supplicant
  it may try to connect to these APs, thus flush out all the scan results
  which are present in SME after 11d scan is done.

  \return -  eHalStatus

  --------------------------------------------------------------------------*/
static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
                         tANI_U32 scanId, eCsrScanStatus status)
{
    ENTER();

    sme_ScanFlushResult(halHandle, 0);

    EXIT();

    return eHAL_STATUS_SUCCESS;
}
/**---------------------------------------------------------------------------

  \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
                                       logging is completed successfully.

  \return -  None

  --------------------------------------------------------------------------*/
void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
{
   hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;

   if (NULL == pHddCtx)
   {
      hddLog(VOS_TRACE_LEVEL_ERROR,
                 "%s: HDD context is NULL",__func__);
      return;
   }

   if ((pRsp->status == VOS_STATUS_SUCCESS) &&
       (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
   {
      hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
      pHddCtx->mgmt_frame_logging = TRUE;
   }
   else
   {
      hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
      pHddCtx->mgmt_frame_logging = FALSE;
      return;
   }

   /*Check feature supported by FW*/
   if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
   {
      //Store fwr mem dump size given by firmware.
      wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
   }
   else
   {
      wlan_store_fwr_mem_dump_size(0);
   }


}
/**---------------------------------------------------------------------------

  \brief hdd_init_frame_logging - function to initialize frame logging.
                            Currently only Mgmt Frames are logged in both TX
                            and Rx direction and are sent to userspace
                            application using logger thread when queried.

  \return -  None

  --------------------------------------------------------------------------*/
void hdd_init_frame_logging(hdd_context_t* pHddCtx)
{
   eHalStatus halStatus = eHAL_STATUS_FAILURE;
   tSirFWLoggingInitParam wlanFWLoggingInitParam = {0};

   if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
       TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
   {
       hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
       return;
   }

   hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
               pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
               pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
               pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
               pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");

   if (pHddCtx->cfg_ini->enableFWLogging ||
                 pHddCtx->cfg_ini->enableContFWLogging)
   {
      wlanFWLoggingInitParam.enableFlag |= WLAN_QXDM_LOG_EN;
   }

   if (pHddCtx->cfg_ini->enableMgmtLogging)
   {
      wlanFWLoggingInitParam.enableFlag |= WLAN_FRAME_LOG_EN;
   }
   if (pHddCtx->cfg_ini->enableBMUHWtracing)
   {
      wlanFWLoggingInitParam.enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
   }
   if(pHddCtx->cfg_ini->enableFwrMemDump &&
      (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
   {
      wlanFWLoggingInitParam.enableFlag |= WLAN_FW_MEM_DUMP_EN;
   }
   if( wlanFWLoggingInitParam.enableFlag == 0 )
   {
      hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
      return;
   }
   wlanFWLoggingInitParam.frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
   wlanFWLoggingInitParam.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
   wlanFWLoggingInitParam.bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
   wlanFWLoggingInitParam.continuousFrameLogging =
                              pHddCtx->cfg_ini->enableContFWLogging;

   wlanFWLoggingInitParam.enableFlag &= ~WLAN_DPU_TXP_LOG_EN;

   wlanFWLoggingInitParam.minLogBufferSize =
                              pHddCtx->cfg_ini->minLoggingBufferSize;
   wlanFWLoggingInitParam.maxLogBufferSize =
                              pHddCtx->cfg_ini->maxLoggingBufferSize;
   wlanFWLoggingInitParam.fwlogInitCallback = hdd_init_frame_logging_done;
   wlanFWLoggingInitParam.fwlogInitCbContext= pHddCtx;

   halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, &wlanFWLoggingInitParam);

   if (eHAL_STATUS_SUCCESS != halStatus)
   {
       hddLog(LOGE, FL("sme_InitMgmtFrameLogging failed, returned %d"),
            halStatus);
   }

   return;
}

static void hdd_dp_util_send_rps_ind(hdd_context_t  *hdd_ctxt)
{
    hdd_adapter_t *adapter;
    hdd_adapter_list_node_t *adapter_node, *next;
    VOS_STATUS status = VOS_STATUS_SUCCESS;
    struct wlan_rps_data rps_data;
    int count;

    if(!hdd_ctxt->cfg_ini->rps_mask)
    {
      return;
    }

    for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
    {
       rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
    }

    rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;

    hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
             rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
                 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);

    status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);

    while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
    {
        adapter = adapter_node->pAdapter;
        if (NULL != adapter) {
               strlcpy(rps_data.ifname, adapter->dev->name,
                                        sizeof(rps_data.ifname));
          wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
                   (void *)&rps_data,sizeof(rps_data));
        }
        status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
        adapter_node = next;
   }
}

void wlan_hdd_schedule_defer_scan(struct work_struct *work)
{
    scan_context_t *scan_ctx =
          container_of(work, scan_context_t, scan_work.work);

    if (NULL == scan_ctx)
    {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 FL("scan_ctx is NULL"));
        return;
    }

    if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
        return;

    scan_ctx->attempt++;

    wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
                           scan_ctx->dev,
#endif
                           scan_ctx->scan_request);
}

int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx,
                            struct wiphy *wiphy,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
                            struct net_device *dev,
#endif
                            struct cfg80211_scan_request *request)
{
    scan_context_t *scan_ctx;

    ENTER();
    if (0 != (wlan_hdd_validate_context(pHddCtx)))
    {
        return -1;
    }

    scan_ctx = &pHddCtx->scan_ctxt;

    scan_ctx->wiphy = wiphy;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
    scan_ctx->dev = dev;
#endif

    scan_ctx->scan_request = request;

    EXIT();
    return 0;
}

void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx,
                                struct wiphy *wiphy,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
                                struct net_device *dev,
#endif
                                struct cfg80211_scan_request *request,
                                unsigned long delay)
{
    if (TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic)
    {
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
        wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, dev, request);
#else
        wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, request);
#endif
        pHddCtx->scan_ctxt.attempt = 0;
        pHddCtx->scan_ctxt.magic = TDLS_CTX_MAGIC;
    }
    schedule_delayed_work(&pHddCtx->scan_ctxt.scan_work, delay);
}

void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx)
{
    scan_ctx->magic = 0;
    scan_ctx->attempt = 0;
    scan_ctx->reject = 0;
    scan_ctx->scan_request = NULL;

    return;
}

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

  \brief hdd_wlan_startup() - HDD init function

  This is the driver startup code executed once a WLAN device has been detected

  \param  - dev - Pointer to the underlying device

  \return -  0 for success, < 0 for failure

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

int hdd_wlan_startup(struct device *dev )
{
   VOS_STATUS status;
   hdd_adapter_t *pAdapter = NULL;
   hdd_adapter_t *pP2pAdapter = NULL;
   hdd_context_t *pHddCtx = NULL;
   v_CONTEXT_t pVosContext= NULL;
#ifdef WLAN_BTAMP_FEATURE
   VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
   WLANBAP_ConfigType btAmpConfig;
   hdd_config_t *pConfig;
#endif
   int ret;
   struct wiphy *wiphy;
   v_MACADDR_t mac_addr;

   ENTER();
   /*
    * cfg80211: wiphy allocation
    */
   wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;

   if(wiphy == NULL)
   {
      hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
      return -EIO;
   }
   pHddCtx = wiphy_priv(wiphy);

   //Initialize the adapter context to zeros.
   vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));

   pHddCtx->wiphy = wiphy;
   hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
   pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;

   vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);

   /* register for riva power on lock to platform driver
    * Locking power early to ensure FW doesn't reset by kernel while
    * host driver is busy initializing itself */
   if (req_riva_power_on_lock("wlan"))
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
                                     __func__);
      goto err_free_hdd_context;
   }

   /*Get vos context here bcoz vos_open requires it*/
   pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);

   if(pVosContext == NULL)
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
      goto err_free_hdd_context;
   }

   //Save the Global VOSS context in adapter context for future.
   pHddCtx->pvosContext = pVosContext;

   //Save the adapter context in global context for future.
   ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;

   pHddCtx->parent_dev = dev;
   pHddCtx->last_scan_reject_session_id = 0xFF;
   pHddCtx->last_scan_reject_reason = 0;
   pHddCtx->last_scan_reject_timestamp = 0;
   pHddCtx->scan_reject_cnt = 0;

   init_completion(&pHddCtx->full_pwr_comp_var);
   init_completion(&pHddCtx->standby_comp_var);
   init_completion(&pHddCtx->req_bmps_comp_var);
   init_completion(&pHddCtx->scan_info.scan_req_completion_event);
   init_completion(&pHddCtx->scan_info.abortscan_event_var);
   init_completion(&pHddCtx->wiphy_channel_update_event);
   init_completion(&pHddCtx->ssr_comp_var);
   init_completion(&pHddCtx->mc_sus_event_var);
   init_completion(&pHddCtx->tx_sus_event_var);
   init_completion(&pHddCtx->rx_sus_event_var);


   hdd_init_ll_stats_ctx(pHddCtx);
   hdd_init_nud_stats_ctx(pHddCtx);

#ifdef CONFIG_ENABLE_LINUX_REG
   init_completion(&pHddCtx->linux_reg_req);
#else
   init_completion(&pHddCtx->driver_crda_req);
#endif

#ifdef WLAN_FEATURE_EXTSCAN
   init_completion(&pHddCtx->ext_scan_context.response_event);
#endif /* WLAN_FEATURE_EXTSCAN */

   spin_lock_init(&pHddCtx->schedScan_lock);
   vos_spin_lock_init(&pHddCtx->sap_update_info_lock);

   hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );

   vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
                                hdd_processSpoofMacAddrRequest);
   vos_init_work(&pHddCtx->sap_start_work, hdd_sap_restart_handle);
   vos_init_delayed_work(&pHddCtx->ecsa_chan_change_work,
                                hdd_force_scc_with_ecsa_handle);

#ifdef FEATURE_WLAN_TDLS
   /* tdls_lock is initialized before an hdd_open_adapter ( which is
    * invoked by other instances also) to protect the concurrent
    * access for the Adapters by TDLS module.
    */
   mutex_init(&pHddCtx->tdls_lock);
#endif
   mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
   mutex_init(&pHddCtx->wmmLock);

   hdd_init_offloaded_packets_ctx(pHddCtx);
   /* By default Strict Regulatory For FCC should be false */

   pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
   // Load all config first as TL config is needed during vos_open
   pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
   if(pHddCtx->cfg_ini == NULL)
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
      goto err_free_hdd_context;
   }

   hdd_request_manager_init();

   vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));

   // Read and parse the qcom_cfg.ini file
   status = hdd_parse_config_ini( pHddCtx );
   if ( VOS_STATUS_SUCCESS != status )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
             __func__, WLAN_INI_FILE);
      goto err_config;
   }
#ifdef MEMORY_DEBUG
   if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
      vos_mem_init();

   hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
          __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
#endif

   /* INI has been read, initialise the configuredMcastBcastFilter with
    * INI value as this will serve as the default value
    */
   pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
   hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
                   pHddCtx->cfg_ini->mcastBcastFilterSetting);

   if (false == hdd_is_5g_supported(pHddCtx))
   {
      //5Ghz is not supported.
      if (1 != pHddCtx->cfg_ini->nBandCapability)
      {
         hddLog(VOS_TRACE_LEVEL_INFO,
                "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
         pHddCtx->cfg_ini->nBandCapability = 1;
      }
   }

   /* If SNR Monitoring is enabled, FW has to parse all beacons
    * for calcaluting and storing the average SNR, so set Nth beacon
    * filter to 1 to enable FW to parse all the beaocons
    */
   if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
   {
      /* The log level is deliberately set to WARN as overriding
       * nthBeaconFilter to 1 will increase power cosumption and this
       * might just prove helpful to detect the power issue.
       */
      hddLog(VOS_TRACE_LEVEL_WARN,
             "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
      pHddCtx->cfg_ini->nthBeaconFilter = 1;
   }
   /*
    * cfg80211: Initialization  ...
    */
   if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,
              "%s: wlan_hdd_cfg80211_init return failure", __func__);
      goto err_config;
   }

   // Update VOS trace levels based upon the cfg.ini
   hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
                        pHddCtx->cfg_ini->vosTraceEnableBAP);
   hdd_vos_trace_enable(VOS_MODULE_ID_TL,
                        pHddCtx->cfg_ini->vosTraceEnableTL);
   hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
                        pHddCtx->cfg_ini->vosTraceEnableWDI);
   hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
                        pHddCtx->cfg_ini->vosTraceEnableHDD);
   hdd_vos_trace_enable(VOS_MODULE_ID_SME,
                        pHddCtx->cfg_ini->vosTraceEnableSME);
   hdd_vos_trace_enable(VOS_MODULE_ID_PE,
                        pHddCtx->cfg_ini->vosTraceEnablePE);
   hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
                         pHddCtx->cfg_ini->vosTraceEnablePMC);
   hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
                        pHddCtx->cfg_ini->vosTraceEnableWDA);
   hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
                        pHddCtx->cfg_ini->vosTraceEnableSYS);
   hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
                        pHddCtx->cfg_ini->vosTraceEnableVOSS);
   hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
                        pHddCtx->cfg_ini->vosTraceEnableSAP);
   hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
                        pHddCtx->cfg_ini->vosTraceEnableHDDSAP);

   // Update WDI trace levels based upon the cfg.ini
   hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
                        pHddCtx->cfg_ini->wdiTraceEnableDAL);
   hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
                        pHddCtx->cfg_ini->wdiTraceEnableCTL);
   hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
                        pHddCtx->cfg_ini->wdiTraceEnableDAT);
   hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
                        pHddCtx->cfg_ini->wdiTraceEnablePAL);

   if (VOS_FTM_MODE == hdd_get_conparam())
   {
      if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
      {
          hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
          goto err_free_hdd_context;
      }
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
      pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
      vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
      return VOS_STATUS_SUCCESS;
   }

   if( VOS_MONITOR_MODE == hdd_get_conparam())
   {
       if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
       {
          hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
          goto err_free_hdd_context;
       }
       hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
       pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
       vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
       return VOS_STATUS_SUCCESS;
   }

   //Open watchdog module
   if(pHddCtx->cfg_ini->fIsLogpEnabled)
   {
      status = vos_watchdog_open(pVosContext,
         &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));

      if(!VOS_IS_STATUS_SUCCESS( status ))
      {
         hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
         goto err_config;
      }
   }

   pHddCtx->isLogpInProgress = FALSE;
   vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);

#ifdef CONFIG_ENABLE_LINUX_REG
   /* initialize the NV module. This is required so that
      we can initialize the channel information in wiphy
      from the NV.bin data. The channel information in
      wiphy needs to be initialized before wiphy registration */

   status = vos_nv_open();
   if (!VOS_IS_STATUS_SUCCESS(status))
   {
       /* NV module cannot be initialized */
       hddLog( VOS_TRACE_LEVEL_FATAL,
                "%s: vos_nv_open failed", __func__);
       goto err_wdclose;
   }

   status = vos_init_wiphy_from_nv_bin();
   if (!VOS_IS_STATUS_SUCCESS(status))
   {
       /* NV module cannot be initialized */
       hddLog( VOS_TRACE_LEVEL_FATAL,
               "%s: vos_init_wiphy failed", __func__);
       goto err_vos_nv_close;
   }

#endif
   //Initialize the nlink service
   if(nl_srv_init() != 0)
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
      goto err_vos_nv_close;
   }

#ifdef WLAN_KD_READY_NOTIFIER
   pHddCtx->kd_nl_init = 1;
#endif /* WLAN_KD_READY_NOTIFIER */

   vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
   status = vos_open( &pVosContext, pHddCtx->parent_dev);
   if ( !VOS_IS_STATUS_SUCCESS( status ))
   {
      hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
      goto err_nl_srv;
   }

   pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );

   if ( NULL == pHddCtx->hHal )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
      goto err_vosclose;
   }

   status = vos_preStart( pHddCtx->pvosContext );
   if ( !VOS_IS_STATUS_SUCCESS( status ) )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
      goto err_vosclose;
   }

   if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
   {
      pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
      hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
             __func__, enable_dfs_chan_scan);
   }
   if (0 == enable_11d || 1 == enable_11d)
   {
      pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
      hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
             __func__, enable_11d);
   }

   /* Note that the vos_preStart() sequence triggers the cfg download.
      The cfg download must occur before we update the SME config
      since the SME config operation must access the cfg database */
   status = hdd_set_sme_config( pHddCtx );

   if ( VOS_STATUS_SUCCESS != status )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
      goto err_vosclose;
   }

   /* In the integrated architecture we update the configuration from
      the INI file and from NV before vOSS has been started so that
      the final contents are available to send down to the cCPU   */

   // Apply the cfg.ini to cfg.dat
   if (FALSE == hdd_update_config_dat(pHddCtx))
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
      goto err_vosclose;
   }

   // Get mac addr from platform driver
   ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);

   if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
   {
      /* Store the mac addr for first interface */
      pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;

      hddLog(VOS_TRACE_LEVEL_ERROR,
             "%s: WLAN Mac Addr: "
             MAC_ADDRESS_STR, __func__,
             MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));

      /* Here, passing Arg2 as 1 because we do not want to change the
         last 3 bytes (means non OUI bytes) of first interface mac
         addr.
       */
      if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
      {
         hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: Failed to generate wlan interface mac addr "
                "using MAC from ini file ", __func__);
      }
   }
   else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
   {
      // Apply the NV to cfg.dat
      /* Prima Update MAC address only at here */
#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
      /* There was not a valid set of MAC Addresses in NV.  See if the
         default addresses were modified by the cfg.ini settings.  If so,
         we'll use them, but if not, we'll autogenerate a set of MAC
         addresses based upon the device serial number */

      static const v_MACADDR_t default_address =
         {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};

      if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
                   sizeof(default_address)))
      {
         /* cfg.ini has the default address, invoke autogen logic */

         /* Here, passing Arg2 as 0 because we want to change the
            last 3 bytes (means non OUI bytes) of all the interfaces
            mac addr.
          */
         if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
                                                            default_address))
         {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                   "%s: Failed to generate wlan interface mac addr "
                   "using MAC from ini file " MAC_ADDRESS_STR, __func__,
                   MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
         }
      }
      else
#endif //WLAN_AUTOGEN_MACADDR_FEATURE
      {
         hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: Invalid MAC address in NV, using MAC from ini file "
                MAC_ADDRESS_STR, __func__,
                MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
      }
   }
   {
      eHalStatus halStatus;

      /* Set the MAC Address Currently this is used by HAL to
       * add self sta. Remove this once self sta is added as
       * part of session open.
       */
      halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
                             (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
                             sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );

      if (!HAL_STATUS_SUCCESS( halStatus ))
      {
         hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
                "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
         goto err_vosclose;
      }
   }

   /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
     Note: Firmware image will be read and downloaded inside vos_start API */
   status = vos_start( pHddCtx->pvosContext );
   if ( !VOS_IS_STATUS_SUCCESS( status ) )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
      if (isSsrPanicOnFailure())
          VOS_BUG(0);
      goto err_vosclose;
   }

#ifdef FEATURE_WLAN_CH_AVOID
    /* Plug in avoid channel notification callback
     * This should happen before ADD_SELF_STA
     * FW will send first IND with ADD_SELF_STA REQ from host */

    /* check the Channel Avoidance is enabled */
   if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
   {
       sme_AddChAvoidCallback(pHddCtx->hHal,
                              hdd_hostapd_ch_avoid_cb);
   }
#endif /* FEATURE_WLAN_CH_AVOID */

   /* Exchange capability info between Host and FW and also get versioning info from FW */
   hdd_exchange_version_and_caps(pHddCtx);

#ifdef CONFIG_ENABLE_LINUX_REG
   status = wlan_hdd_init_channels(pHddCtx);
   if ( !VOS_IS_STATUS_SUCCESS( status ) )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
             __func__);
      goto err_vosstop;
   }
#endif

   status = hdd_post_voss_start_config( pHddCtx );
   if ( !VOS_IS_STATUS_SUCCESS( status ) )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed", 
         __func__);
      goto err_vosstop;
   }

#ifndef CONFIG_ENABLE_LINUX_REG
   wlan_hdd_cfg80211_update_reg_info( wiphy );

   /* registration of wiphy dev with cfg80211 */
   if (0 > wlan_hdd_cfg80211_register(wiphy))
   {
       hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
       goto err_vosstop;
   }
#endif

#ifdef CONFIG_ENABLE_LINUX_REG
   /* registration of wiphy dev with cfg80211 */
   if (0 > wlan_hdd_cfg80211_register(wiphy))
   {
       hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
       goto err_vosstop;
   }

   status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
   if ( !VOS_IS_STATUS_SUCCESS( status ) )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
             __func__);
      goto err_unregister_wiphy;
   }
#endif

   wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);

   if (VOS_STA_SAP_MODE == hdd_get_conparam())
   {
     pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d", 
         wlan_hdd_get_intf_addr(pHddCtx), FALSE );
   }
   else
   {
     pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
         wlan_hdd_get_intf_addr(pHddCtx), FALSE );
     if (pAdapter != NULL)
     {
         if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
         {
               vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
                       pHddCtx->cfg_ini->intfMacAddr[0].bytes,
                       sizeof(tSirMacAddr));

                /* Generate the P2P Device Address.  This consists of the device's
                 * primary MAC address with the locally administered bit set.
                */
                pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
         }
         else
         {
             tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
             if (p2p_dev_addr != NULL)
             {
                 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
                             p2p_dev_addr, VOS_MAC_ADDR_SIZE);
             }
             else
             {
                   hddLog(VOS_TRACE_LEVEL_FATAL,
                           "%s: Failed to allocate mac_address for p2p_device",
                   __func__);
                   goto err_close_adapter;
             }
         }

         pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
                           &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
         if ( NULL == pP2pAdapter )
         {
             hddLog(VOS_TRACE_LEVEL_FATAL,
                "%s: Failed to do hdd_open_adapter for P2P Device Interface",
                __func__);
             goto err_close_adapter;
         }
     }
   }

   if( pAdapter == NULL )
   {
      hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
      goto err_close_adapter;
   }

   if (country_code)
   {
      eHalStatus ret;
      INIT_COMPLETION(pAdapter->change_country_code);
      hdd_checkandupdate_dfssetting(pAdapter, country_code);
#ifndef CONFIG_ENABLE_LINUX_REG
      hdd_checkandupdate_phymode(pAdapter, country_code);
#endif
      ret = sme_ChangeCountryCode(pHddCtx->hHal,
                                  (void *)(tSmeChangeCountryCallback)
                                  wlan_hdd_change_country_code_callback,
                                  country_code,
                                  pAdapter, pHddCtx->pvosContext,
                                  eSIR_TRUE, eSIR_TRUE);
      if (eHAL_STATUS_SUCCESS == ret)
      {
         ret = wait_for_completion_interruptible_timeout(
                       &pAdapter->change_country_code,
                       msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));

         if (0 >= ret)
         {
            VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                      "%s: SME while setting country code timed out", __func__);
         }
      }
      else
      {
         VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                   "%s: SME Change Country code from module param fail ret=%d",
                   __func__, ret);
      }
   }

#ifdef WLAN_BTAMP_FEATURE
   vStatus = WLANBAP_Open(pVosContext);
   if(!VOS_IS_STATUS_SUCCESS(vStatus))
   {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
        "%s: Failed to open BAP",__func__);
      goto err_close_adapter;
   }

   vStatus = BSL_Init(pVosContext);
   if(!VOS_IS_STATUS_SUCCESS(vStatus))
   {
     VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
        "%s: Failed to Init BSL",__func__);
     goto err_bap_close;
   }
   vStatus = WLANBAP_Start(pVosContext);
   if (!VOS_IS_STATUS_SUCCESS(vStatus))
   {
       VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
               "%s: Failed to start TL",__func__);
       goto err_bap_close;
   }

   pConfig = pHddCtx->cfg_ini;
   btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
   status = WLANBAP_SetConfig(&btAmpConfig);

#endif //WLAN_BTAMP_FEATURE

   /*
    * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
    * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
    * which is greater than 0xf. So the below check is safe to make
    * sure that there is no entry for UapsdMask in the ini
    */
   if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
   {
       if(IS_DYNAMIC_WMM_PS_ENABLED)
       {
           hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
                     __func__);
           pHddCtx->cfg_ini->UapsdMask =
                   CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
       }
       else
       {
           hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
                     __func__);
           pHddCtx->cfg_ini->UapsdMask =
                   CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
       }
   }

#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
   if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
   {
      hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
      pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
      sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
                       pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
   }
#endif

   wlan_hdd_tdls_init(pHddCtx);

   wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);

   vos_init_delayed_work(&pHddCtx->scan_ctxt.scan_work,
                         wlan_hdd_schedule_defer_scan);

   sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);

   /* Register with platform driver as client for Suspend/Resume */
   status = hddRegisterPmOps(pHddCtx);
   if ( !VOS_IS_STATUS_SUCCESS( status ) )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
#ifdef WLAN_BTAMP_FEATURE
      goto err_bap_stop;
#else
      goto err_close_adapter; 
#endif //WLAN_BTAMP_FEATURE
   }

   /* Open debugfs interface */
   if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
   {
      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                 "%s: hdd_debugfs_init failed!", __func__);
   }

   /* Register TM level change handler function to the platform */
   status = hddDevTmRegisterNotifyCallback(pHddCtx);
   if ( !VOS_IS_STATUS_SUCCESS( status ) )
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
      goto err_unregister_pmops;
   }

   // register net device notifier for device change notification
   ret = register_netdevice_notifier(&hdd_netdev_notifier);

   if(ret < 0)
   {
      hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
      goto err_unregister_pmops;
   }

   //Initialize the BTC service
   if(btc_activate_service(pHddCtx) != 0)
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
      goto err_reg_netdev;
   }

#ifdef FEATURE_OEM_DATA_SUPPORT
   //Initialize the OEM service
   if (oem_activate_service(pHddCtx) != 0)
   {
       hddLog(VOS_TRACE_LEVEL_FATAL,
              "%s: oem_activate_service failed", __func__);
       goto err_btc_activate_service;
   }
#endif

#ifdef PTT_SOCK_SVC_ENABLE
   //Initialize the PTT service
   if(ptt_sock_activate_svc(pHddCtx) != 0)
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
      goto err_oem_activate_service;
   }
#endif

#ifdef WLAN_FEATURE_RMC
   if (hdd_open_cesium_nl_sock() < 0)
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__);
      goto err_ptt_sock_activate_svc;
   }
#endif

#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
   if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
   {
       if(wlan_logging_sock_activate_svc(
                   pHddCtx->cfg_ini->wlanLoggingFEToConsole,
                   pHddCtx->cfg_ini->wlanLoggingNumBuf,
                   pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
                   pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
       {
           hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
                   " failed", __func__);
           goto err_open_cesium_nl_sock;
       }
       //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
       //EAPOL and DHCP
       if (!pHddCtx->cfg_ini->gEnableDebugLog)
           pHddCtx->cfg_ini->gEnableDebugLog =
           VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
           VOS_PKT_PROTO_TYPE_ARP;
   }

   if (pHddCtx->cfg_ini->wlanLoggingEnable &&
               (pHddCtx->cfg_ini->enableFWLogging ||
                pHddCtx->cfg_ini->enableMgmtLogging ||
                pHddCtx->cfg_ini->enableContFWLogging ||
                pHddCtx->cfg_ini->enableFwrMemDump )
                )
   {
       hdd_init_frame_logging(pHddCtx);
   }
   else
   {
       hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
   }

#endif

#ifdef SAP_AUTH_OFFLOAD
   if (!sme_IsFeatureSupportedByFW(SAP_OFFLOADS))
   {
       hddLog(VOS_TRACE_LEVEL_INFO, FL(" SAP AUTH OFFLOAD not supp by FW"));
       pHddCtx->cfg_ini->enable_sap_auth_offload = 0;
   }
#endif

   if (vos_is_multicast_logging())
       wlan_logging_set_log_level();

   hdd_register_mcast_bcast_filter(pHddCtx);
   if (VOS_STA_SAP_MODE != hdd_get_conparam())
   {
      /* Action frame registered in one adapter which will
       * applicable to all interfaces 
       */
      wlan_hdd_cfg80211_register_frames(pAdapter);
   }

   mutex_init(&pHddCtx->sap_lock);
   mutex_init(&pHddCtx->roc_lock);

#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
   /* Initialize the wake lcok */
   vos_wake_lock_init(&pHddCtx->rx_wake_lock,
           "qcom_rx_wakelock");

#endif
   /* Initialize the wake lcok */
   vos_wake_lock_init(&pHddCtx->sap_wake_lock,
           "qcom_sap_wakelock");


   vos_event_init(&pHddCtx->scan_info.scan_finished_event);
   pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;

   pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
   vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
   hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);

#ifdef FEATURE_WLAN_SCAN_PNO
   /*SME must send channel update configuration to RIVA*/
   sme_UpdateChannelConfig(pHddCtx->hHal);
#endif
   /* Send the update default channel list to the FW*/
   sme_UpdateChannelList(pHddCtx->hHal);

   /* Fwr capabilities received, Set the Dot11 mode */
   sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
       hdd_cfg_xlate_to_csr_phy_mode(pHddCtx->cfg_ini->dot11Mode));
   sme_SetDefDot11Mode(pHddCtx->hHal);

#ifndef CONFIG_ENABLE_LINUX_REG
   /*updating wiphy so that regulatory user hints can be processed*/
   if (wiphy)
   {
       regulatory_hint(wiphy, "00");
   }
#endif
   // Initialize the restart logic
   wlan_hdd_restart_init(pHddCtx);

   if (pHddCtx->cfg_ini->fIsLogpEnabled) {
       vos_wdthread_init_timer_work(vos_process_wd_timer);
       /* Initialize the timer to detect thread stuck issues */
       vos_thread_stuck_timer_init(
               &((VosContextType*)pVosContext)->vosWatchdog);
   }

   //Register the traffic monitor timer now
   if ( pHddCtx->cfg_ini->dynSplitscan)
   {
       vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
                     VOS_TIMER_TYPE_SW,
                     hdd_tx_rx_pkt_cnt_stat_timer_handler,
                     (void *)pHddCtx);
   }
   wlan_hdd_cfg80211_nan_init(pHddCtx);

   mutex_init(&pHddCtx->cur_rx_level_lock);
   vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW,
                             hdd_tcp_delack_compute_function,(void *)pHddCtx);
   vos_timer_init(&pHddCtx->tdls_source_timer, VOS_TIMER_TYPE_SW,
                  wlan_hdd_change_tdls_mode, (void *)pHddCtx);

#ifdef WLAN_FEATURE_EXTSCAN
    sme_EXTScanRegisterCallback(pHddCtx->hHal,
            wlan_hdd_cfg80211_extscan_callback,
                           pHddCtx);
#endif /* WLAN_FEATURE_EXTSCAN */

#ifdef FEATURE_OEM_DATA_SUPPORT
    sme_OemDataRegisterCallback(pHddCtx->hHal,
            wlan_hdd_cfg80211_oemdata_callback,
                           pHddCtx);
#endif /* FEATURE_OEM_DATA_SUPPORT */

   sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
#ifdef WLAN_NS_OFFLOAD
   // Register IPv6 notifier to notify if any change in IP
   // So that we can reconfigure the offload parameters
   pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
   ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
   if (ret)
   {
      hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
   }
   else
   {
      hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
   }
#endif

   vos_mem_set((uint8_t *)&pHddCtx->bad_sta, HDD_MAX_STA_COUNT, 0);

   // Register IPv4 notifier to notify if any change in IP
   // So that we can reconfigure the offload parameters
   pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
   ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
   if (ret)
   {
      hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
   }
   else
   {
      hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
   }
   /*Fw mem dump procfs initialization*/
   memdump_init();
   hdd_dp_util_send_rps_ind(pHddCtx);

   pHddCtx->is_ap_mode_wow_supported =
              sme_IsFeatureSupportedByFW(SAP_MODE_WOW);

   pHddCtx->is_fatal_event_log_sup =
      sme_IsFeatureSupportedByFW(FATAL_EVENT_LOGGING);
   hddLog(VOS_TRACE_LEVEL_INFO, FL("FATAL_EVENT_LOGGING: %d"),
          pHddCtx->is_fatal_event_log_sup);

   hdd_assoc_registerFwdEapolCB(pVosContext);

   mutex_init(&pHddCtx->cache_channel_lock);
   goto success;

err_open_cesium_nl_sock:
#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
   hdd_close_cesium_nl_sock();
#endif

err_ptt_sock_activate_svc:
#ifdef PTT_SOCK_SVC_ENABLE
   ptt_sock_deactivate_svc(pHddCtx);
#endif

err_oem_activate_service:
#ifdef FEATURE_OEM_DATA_SUPPORT
   oem_deactivate_service();
#endif

err_btc_activate_service:
   btc_deactivate_service();

err_reg_netdev:
   unregister_netdevice_notifier(&hdd_netdev_notifier);

err_unregister_pmops:
   hddDevTmUnregisterNotifyCallback(pHddCtx);
   hddDeregisterPmOps(pHddCtx);

   hdd_debugfs_exit(pHddCtx);

#ifdef WLAN_BTAMP_FEATURE
err_bap_stop:
  WLANBAP_Stop(pVosContext);
#endif

#ifdef WLAN_BTAMP_FEATURE
err_bap_close:
   WLANBAP_Close(pVosContext);
#endif

err_close_adapter:
   hdd_close_all_adapters( pHddCtx );
#ifdef CONFIG_ENABLE_LINUX_REG
err_unregister_wiphy:
#endif
   wiphy_unregister(wiphy) ;
   hdd_wlan_free_wiphy_channels(wiphy);

err_vosstop:
   vos_stop(pVosContext);

err_vosclose:
   status = vos_sched_close( pVosContext );
   if (!VOS_IS_STATUS_SUCCESS(status))    {
      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
         "%s: Failed to close VOSS Scheduler", __func__);
      VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
   }
   vos_close(pVosContext );

err_nl_srv:
#ifdef WLAN_KD_READY_NOTIFIER
   nl_srv_exit(pHddCtx->ptt_pid);
#else
   nl_srv_exit();
#endif /* WLAN_KD_READY_NOTIFIER */
err_vos_nv_close:

#ifdef CONFIG_ENABLE_LINUX_REG
   vos_nv_close();

#endif

err_wdclose:
   if(pHddCtx->cfg_ini->fIsLogpEnabled)
      vos_watchdog_close(pVosContext);

err_config:
   hdd_request_manager_deinit();
   kfree(pHddCtx->cfg_ini);
   pHddCtx->cfg_ini= NULL;

err_free_hdd_context:
   hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
   free_riva_power_on_lock("wlan");
   wiphy_free(wiphy) ;
   //kfree(wdev) ;
   VOS_BUG(1);

   if (hdd_is_ssr_required())
   {
       /* WDI timeout had happened during load, so SSR is needed here */
       subsystem_restart("wcnss");
       msleep(5000);
   }
   hdd_set_ssr_required (VOS_FALSE);

   return -EIO;

success:
   EXIT();
   return 0;
}

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

  \brief hdd_driver_init() - Core Driver Init Function

   This is the driver entry point - called in different timeline depending
   on whether the driver is statically or dynamically linked

  \param  - None

  \return - 0 for success, non zero for failure

  --------------------------------------------------------------------------*/
static int hdd_driver_init( void)
{
   VOS_STATUS status;
   v_CONTEXT_t pVosContext = NULL;
   struct device *dev = NULL;
   int ret_status = 0;
#ifdef HAVE_WCNSS_CAL_DOWNLOAD
   int max_retries = 0;
#endif
#ifdef HAVE_CBC_DONE
   int max_cbc_retries = 0;
#endif

#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
   wlan_logging_sock_init_svc();
#endif

   ENTER();

   vos_wake_lock_init(&wlan_wake_lock, "wlan");

   pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
           QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);

#ifdef ANI_BUS_TYPE_PCI

   dev = wcnss_wlan_get_device();

#endif // ANI_BUS_TYPE_PCI

#ifdef ANI_BUS_TYPE_PLATFORM

#ifdef HAVE_WCNSS_CAL_DOWNLOAD
   /* wait until WCNSS driver downloads NV */
   while (!wcnss_device_ready() && 10 >= ++max_retries) {
       msleep(1000);
   }

   if (max_retries >= 10) {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
      vos_wake_lock_destroy(&wlan_wake_lock);
#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
      wlan_logging_sock_deinit_svc();
#endif

      return -ENODEV;
   }
#endif

#ifdef HAVE_CBC_DONE
   while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
       msleep(1000);
   }
   if (max_cbc_retries >= 10) {
      hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
   }
#endif

   dev = wcnss_wlan_get_device();
#endif // ANI_BUS_TYPE_PLATFORM


   do {
      if (NULL == dev) {
         hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
         ret_status = -1;
         break;
   }

#ifdef TIMER_MANAGER
      vos_timer_manager_init();
#endif

      /* Preopen VOSS so that it is ready to start at least SAL */
      status = vos_preOpen(&pVosContext);

   if (!VOS_IS_STATUS_SUCCESS(status))
   {
         hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
         ret_status = -1;
         break;
   }

   hddTraceInit();
   hdd_register_debug_callback();

#ifndef MODULE
      /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
       */
      hdd_set_conparam((v_UINT_t)con_mode);
#endif

      // Call our main init function
      if (hdd_wlan_startup(dev))
      {
         hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
                __func__);
         vos_preClose( &pVosContext );
         ret_status = -1;
         break;
      }

   } while (0);

   if (0 != ret_status)
   {
#ifdef TIMER_MANAGER
      vos_timer_exit();
#endif
#ifdef MEMORY_DEBUG
      vos_mem_exit();
#endif
      vos_wake_lock_destroy(&wlan_wake_lock);
#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
      wlan_logging_sock_deinit_svc();
#endif

      pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
   }
   else
   {
      //Send WLAN UP indication to Nlink Service
      send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);

      pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
   }

   EXIT();

   return ret_status;
}

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

  \brief hdd_module_init() - Init Function

   This is the driver entry point (invoked when module is loaded using insmod)

  \param  - None

  \return - 0 for success, non zero for failure

  --------------------------------------------------------------------------*/
#ifdef MODULE
static int __init hdd_module_init ( void)
{
   return hdd_driver_init();
}
#else /* #ifdef MODULE */
static int __init hdd_module_init ( void)
{
   /* Driver initialization is delayed to fwpath_changed_handler */
   return 0;
}
#endif /* #ifdef MODULE */


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

  \brief hdd_driver_exit() - Exit function

  This is the driver exit point (invoked when module is unloaded using rmmod
  or con_mode was changed by userspace)

  \param  - None

  \return - None

  --------------------------------------------------------------------------*/
static void hdd_driver_exit(void)
{
   hdd_context_t *pHddCtx = NULL;
   v_CONTEXT_t pVosContext = NULL;
   v_REGDOMAIN_t regId;
   unsigned long rc = 0;

   pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);

   //Get the global vos context
   pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);

   if(!pVosContext)
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
      goto done;
   }

   //Get the HDD context.
   pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );

   if(!pHddCtx)
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
   }
   else if (VOS_MONITOR_MODE == hdd_get_conparam())
   {
       hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
       pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
       vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
       hdd_wlan_exit(pHddCtx);
       vos_preClose( &pVosContext );
      goto done;
   }
   else
   {
      /* We wait for active entry threads to exit from driver
       * by waiting until rtnl_lock is available.
       */
      rtnl_lock();
      rtnl_unlock();

      INIT_COMPLETION(pHddCtx->ssr_comp_var);
      if ((pHddCtx->isLogpInProgress) && (FALSE ==
                  vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
              "%s:SSR  in Progress; block rmmod !!!", __func__);
         rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
                                          msecs_to_jiffies(30000));
         if(!rc)
         {
              VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
              "%s:SSR timedout, fatal error", __func__);
              VOS_BUG(0);
         }
      }

      pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
      vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);

       /* Driver Need to send country code 00 in below condition
        * 1) If gCountryCodePriority is set to 1; and last country
        * code set is through 11d. This needs to be done in case
        * when NV country code is 00.
        * This Needs to be done as when kernel store last country
        * code and if stored  country code is not through 11d,
        * in sme_HandleChangeCountryCodeByUser we will disable 11d
        * in next load/unload as soon as we get any country through
        * 11d. In sme_HandleChangeCountryCodeByUser
        * pMsg->countryCode will be last countryCode and
        * pMac->scan.countryCode11d will be country through 11d so
        * due to mismatch driver will disable 11d.
        *
        */

        if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
              pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority  &&
              sme_Is11dSupported(pHddCtx->hHal)))
        {
            hddLog(VOS_TRACE_LEVEL_INFO,
                     FL("CountryCode 00 is being set while unloading driver"));
            vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
        }

        //Do all the cleanup before deregistering the driver
        hdd_wlan_exit(pHddCtx);
   }

   vos_preClose( &pVosContext );

#ifdef TIMER_MANAGER
   vos_timer_exit();
#endif
#ifdef MEMORY_DEBUG
   vos_mem_exit();
#endif

#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
   wlan_logging_sock_deinit_svc();
#endif

done:
   vos_wake_lock_destroy(&wlan_wake_lock);

   pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
}

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

  \brief hdd_module_exit() - Exit function

  This is the driver exit point (invoked when module is unloaded using rmmod)

  \param  - None

  \return - None

  --------------------------------------------------------------------------*/
static void __exit hdd_module_exit(void)
{
   hdd_driver_exit();
}

#ifdef MODULE
static int fwpath_changed_handler(const char *kmessage,
                                  const struct kernel_param *kp)
{
   return param_set_copystring(kmessage, kp);
}

static int con_mode_handler(const char *kmessage,
                            const struct kernel_param *kp)
{
   return param_set_int(kmessage, kp);
}
#else /* #ifdef MODULE */
/**---------------------------------------------------------------------------

  \brief kickstart_driver

   This is the driver entry point
   - delayed driver initialization when driver is statically linked
   - invoked when module parameter fwpath is modified from userspace to signal
     initializing the WLAN driver or when con_mode is modified from userspace
     to signal a switch in operating mode

  \return - 0 for success, non zero for failure

  --------------------------------------------------------------------------*/
static int kickstart_driver(void)
{
   int ret_status;

   if (!wlan_hdd_inited) {
      ret_status = hdd_driver_init();
      wlan_hdd_inited = ret_status ? 0 : 1;
      return ret_status;
   }

   hdd_driver_exit();

   msleep(200);

   ret_status = hdd_driver_init();
   wlan_hdd_inited = ret_status ? 0 : 1;
   return ret_status;
}

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

  \brief fwpath_changed_handler() - Handler Function

   Handle changes to the fwpath parameter

  \return - 0 for success, non zero for failure

  --------------------------------------------------------------------------*/
static int fwpath_changed_handler(const char *kmessage,
                                  const struct kernel_param *kp)
{
   int ret;

   ret = param_set_copystring(kmessage, kp);
   if (0 == ret)
      ret = kickstart_driver();
   return ret;
}

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

  \brief con_mode_handler() -

  Handler function for module param con_mode when it is changed by userspace
  Dynamically linked - do nothing
  Statically linked - exit and init driver, as in rmmod and insmod

  \param  -

  \return -

  --------------------------------------------------------------------------*/
static int con_mode_handler(const char *kmessage,
                            const struct kernel_param *kp)
{
   int ret;

   ret = param_set_int(kmessage, kp);
   if (0 == ret)
      ret = kickstart_driver();
   return ret;
}
#endif /* #ifdef MODULE */

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

  \brief hdd_get_conparam() -

  This is the driver exit point (invoked when module is unloaded using rmmod)

  \param  - None

  \return - tVOS_CON_MODE

  --------------------------------------------------------------------------*/
tVOS_CON_MODE hdd_get_conparam ( void )
{
#ifdef MODULE
    return (tVOS_CON_MODE)con_mode;
#else
    return (tVOS_CON_MODE)curr_con_mode;
#endif
}
void hdd_set_conparam ( v_UINT_t newParam )
{
  con_mode = newParam;
#ifndef MODULE
  curr_con_mode = con_mode;
#endif
}
/**---------------------------------------------------------------------------

  \brief hdd_softap_sta_deauth() - function

  This to take counter measure to handle deauth req from HDD

  \param  - pAdapter - Pointer to the HDD

  \param  - enable - boolean value

  \return - None

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

VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
                                 struct tagCsrDelStaParams *pDelStaParams)
{
    v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
    VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
    struct hdd_cache_sta_info *cache_sta_info;
    ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);

    ENTER();

    hddLog(LOG1, "hdd_softap_sta_deauth:(%pK, false)",
           (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);

    if (!pSapCtx) {
        hddLog(LOGE, "sap context is NULL");
        return vosStatus;
    }

    cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
                                           pDelStaParams->peerMacAddr);
    if (cache_sta_info) {
        cache_sta_info->reason_code = pDelStaParams->reason_code;
        cache_sta_info->rx_rate =
                wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
        WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
                             &cache_sta_info->rssi);
    }

    //Ignore request to deauth bcmc station
    if (pDelStaParams->peerMacAddr[0] & 0x1)
       return vosStatus;

    vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);

    EXIT();
    return vosStatus;
}

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

  \brief hdd_del_all_sta() - function

  This function removes all the stations associated on stopping AP/P2P GO.

  \param  - pAdapter - Pointer to the HDD

  \return - None

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

int hdd_del_all_sta(hdd_adapter_t *pAdapter)
{
    v_U16_t i;
    VOS_STATUS vos_status;
    v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
    ptSapContext pSapCtx = NULL;
    pSapCtx = VOS_GET_SAP_CB(pVosContext);
    if(pSapCtx == NULL){
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  FL("psapCtx is NULL"));
        return 1;
    }
    ENTER();

    hddLog(VOS_TRACE_LEVEL_INFO,
           "%s: Delete all STAs associated.",__func__);
    if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
     || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
       )
    {
        for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
        {
            if ((pSapCtx->aStaInfo[i].isUsed) &&
                (!pSapCtx->aStaInfo[i].isDeauthInProgress))
            {
                struct tagCsrDelStaParams delStaParams;

                WLANSAP_PopulateDelStaParams(
                            pSapCtx->aStaInfo[i].macAddrSTA.bytes,
                            eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
                            SIR_MAC_MGMT_DEAUTH >> 4,
                            &delStaParams);
                vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
                if (VOS_IS_STATUS_SUCCESS(vos_status))
                    pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
            }
        }
    }

    EXIT();
    return 0;
}

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

  \brief hdd_softap_sta_disassoc() - function

  This to take counter measure to handle deauth req from HDD

  \param  - pAdapter - Pointer to the HDD

  \param  - enable - boolean value

  \return - None

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

void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
{
    v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
    struct hdd_cache_sta_info *cache_sta_info;
    ptSapContext  pSapCtx = VOS_GET_SAP_CB(pVosContext);

    ENTER();

    hddLog( LOGE, "hdd_softap_sta_disassoc:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);

    if (!pSapCtx) {
        hddLog(LOGE, "sap context is NULL");
        return ;
    }

    //Ignore request to disassoc bcmc station
    if( pDestMacAddress[0] & 0x1 )
       return;

    cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
                                           pDestMacAddress);
    if (cache_sta_info) {
        cache_sta_info->reason_code = eSIR_MAC_DEAUTH_LEAVING_BSS_REASON;
        cache_sta_info->rx_rate =
                wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
        WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
                             &cache_sta_info->rssi);
    }

    WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
}

void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
{
    v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;

    ENTER();

    hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);

    WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
}

/**---------------------------------------------------------------------------
 *
 *   \brief hdd_get__concurrency_mode() -
 *
 *
 *   \param  - None
 *
 *   \return - CONCURRENCY MODE
 *
 * --------------------------------------------------------------------------*/
tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
{
    v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
    hdd_context_t *pHddCtx;

    if (NULL != pVosContext)
    {
       pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
       if (NULL != pHddCtx)
       {
          return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
       }
    }

    /* we are in an invalid state :( */
    hddLog(LOGE, "%s: Invalid context", __func__);
    return VOS_STA;
}
v_BOOL_t
wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
{
     hdd_adapter_t *pAdapter = NULL;

     pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
     if (pAdapter == NULL)
     {
         hddLog(VOS_TRACE_LEVEL_INFO,
                FL("GO doesn't exist"));
         return TRUE;
     }
     if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
     {
          hddLog(VOS_TRACE_LEVEL_INFO,
                 FL("GO started"));
          return TRUE;
     }
     else
          /* wait till GO changes its interface to p2p device */
          hddLog(VOS_TRACE_LEVEL_INFO,
                 FL("Del_bss called, avoid apps suspend"));
          return FALSE;

}
/* Decide whether to allow/not the apps power collapse. 
 * Allow apps power collapse if we are in connected state.
 * if not, allow only if we are in IMPS  */
v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
{
    tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
    tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
    tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
    hdd_config_t *pConfig = pHddCtx->cfg_ini;
    hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; 
    hdd_adapter_t *pAdapter = NULL; 
    VOS_STATUS status;
    tVOS_CONCURRENCY_MODE concurrent_state = 0;

    if (VOS_STA_SAP_MODE == hdd_get_conparam())
        return TRUE;

    concurrent_state = hdd_get_concurrency_mode();

    if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
          !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
        return FALSE;
#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE

    if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) || 
        (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
        (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
        return TRUE;
#endif

    /*loop through all adapters. TBD fix for Concurrency */
    status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
    while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
    {
        pAdapter = pAdapterNode->pAdapter;
        if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
          || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
        {
            if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
                 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
                  &&  pmcState != STOPPED && pmcState != STANDBY &&
                      pmcState != WOWL)) ||
                 (eANI_BOOLEAN_TRUE == scanRspPending) ||
                 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
            {
                if(pmcState == FULL_POWER &&
                   sme_IsCoexScoIndicationSet(pHddCtx->hHal))
                {
                    /*
                     * When SCO indication comes from Coex module , host will
                     * enter in to full power mode, but this should not prevent
                     * apps processor power collapse.
                     */
                    hddLog(LOG1,
                       FL("Allow apps power collapse"
                          "even when sco indication is set"));
                    return TRUE;
                }
                hddLog( LOGE, "%s: do not allow APPS power collapse-"
                        "pmcState = %d scanRspPending = %d "
                        "inMiddleOfRoaming = %d connected = %d",
                        __func__, pmcState, scanRspPending,
                        inMiddleOfRoaming, hdd_connIsConnected(
                        WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )));
                wlan_hdd_get_tdls_stats(pAdapter);
               return FALSE;
            }
        }
        status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
        pAdapterNode = pNext;
    }
    return TRUE;
}

/* Decides whether to send suspend notification to Riva
 * if any adapter is in BMPS; then it is required */
v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
{
    tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
    hdd_config_t *pConfig = pHddCtx->cfg_ini;

    if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
    {
        return TRUE;
    }
    return FALSE;
}

void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
{
   switch(mode)
   {
       case VOS_STA_MODE:
       case VOS_P2P_CLIENT_MODE:
       case VOS_P2P_GO_MODE:
       case VOS_STA_SAP_MODE:
       case VOS_MONITOR_MODE:
            pHddCtx->concurrency_mode |= (1 << mode);
            pHddCtx->no_of_open_sessions[mode]++;
            break;
       default:
            break;
   }
   hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
          "Number of open sessions for mode %d = %d"),
           pHddCtx->concurrency_mode, mode,
           pHddCtx->no_of_open_sessions[mode]);
}


void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
{
   switch(mode)
   {
       case VOS_STA_MODE:
       case VOS_P2P_CLIENT_MODE:
       case VOS_P2P_GO_MODE:
       case VOS_STA_SAP_MODE:
       case VOS_MONITOR_MODE:
            pHddCtx->no_of_open_sessions[mode]--;
            if (!(pHddCtx->no_of_open_sessions[mode]))
                pHddCtx->concurrency_mode &= (~(1 << mode));
            break;
       default:
            break;
   }
   hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
          "Number of open sessions for mode %d = %d"),
          pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);

}
/**---------------------------------------------------------------------------
 *
 *   \brief wlan_hdd_incr_active_session()
 *
 *   This function increments the number of active sessions
 *   maintained per device mode
 *   Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
 *   Incase of SAP/P2P GO upon bss start it is incremented
 *
 *   \param  pHddCtx - HDD Context
 *   \param  mode    - device mode
 *
 *   \return - None
 *
 * --------------------------------------------------------------------------*/
void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
{
   switch (mode) {
   case VOS_STA_MODE:
   case VOS_P2P_CLIENT_MODE:
   case VOS_P2P_GO_MODE:
   case VOS_STA_SAP_MODE:
        pHddCtx->no_of_active_sessions[mode]++;
        break;
   default:
        hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
        break;
   }
   hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
                                mode,
                                pHddCtx->no_of_active_sessions[mode]);
}

/**---------------------------------------------------------------------------
 *
 *   \brief wlan_hdd_decr_active_session()
 *
 *   This function decrements the number of active sessions
 *   maintained per device mode
 *   Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
 *   Incase of SAP/P2P GO upon bss stop it is decremented
 *
 *   \param  pHddCtx - HDD Context
 *   \param  mode    - device mode
 *
 *   \return - None
 *
 * --------------------------------------------------------------------------*/
void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
{

   switch (mode) {
   case VOS_STA_MODE:
   case VOS_P2P_CLIENT_MODE:
   case VOS_P2P_GO_MODE:
   case VOS_STA_SAP_MODE:
        if (pHddCtx->no_of_active_sessions[mode] > 0)
            pHddCtx->no_of_active_sessions[mode]--;
        else
            hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
                                     "is already Zero"));
        break;
   default:
        hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
        break;
   }
   hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
                                mode,
                                pHddCtx->no_of_active_sessions[mode]);
}

/**---------------------------------------------------------------------------
 *
 *   \brief wlan_hdd_restart_init
 *
 *   This function initalizes restart timer/flag. An internal function.
 *
 *   \param  - pHddCtx
 *
 *   \return - None
 *             
 * --------------------------------------------------------------------------*/

static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
{
   /* Initialize */
   pHddCtx->hdd_restart_retries = 0;
   atomic_set(&pHddCtx->isRestartInProgress, 0);
   vos_timer_init(&pHddCtx->hdd_restart_timer, 
                     VOS_TIMER_TYPE_SW, 
                     wlan_hdd_restart_timer_cb,
                     pHddCtx);
}
/**---------------------------------------------------------------------------
 *
 *   \brief wlan_hdd_restart_deinit
 *
 *   This function cleans up the resources used. An internal function.
 *
 *   \param  - pHddCtx
 *
 *   \return - None
 *             
 * --------------------------------------------------------------------------*/

static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
{
 
   VOS_STATUS vos_status;
   /* Block any further calls */
   atomic_set(&pHddCtx->isRestartInProgress, 1);
   /* Cleanup */
   vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
   if (!VOS_IS_STATUS_SUCCESS(vos_status))
          hddLog(LOGE, FL("Failed to stop HDD restart timer"));
   vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
   if (!VOS_IS_STATUS_SUCCESS(vos_status))
          hddLog(LOGE, FL("Failed to destroy HDD restart timer"));

}

/**---------------------------------------------------------------------------
 *
 *   \brief wlan_hdd_framework_restart
 *
 *   This function uses a cfg80211 API to start a framework initiated WLAN
 *   driver module unload/load.
 *
 *   Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
 *
 *
 *   \param  - pHddCtx
 *
 *   \return - VOS_STATUS_SUCCESS: Success
 *             VOS_STATUS_E_EMPTY: Adapter is Empty
 *             VOS_STATUS_E_NOMEM: No memory

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

static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx) 
{
   VOS_STATUS status = VOS_STATUS_SUCCESS;
   hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
   int len = (sizeof (struct ieee80211_mgmt));
   struct ieee80211_mgmt *mgmt = NULL; 
   
   /* Prepare the DEAUTH managment frame with reason code */
   mgmt =  kzalloc(len, GFP_KERNEL);
   if(mgmt == NULL) 
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, 
            "%s: memory allocation failed (%d bytes)", __func__, len);
      return VOS_STATUS_E_NOMEM;
   }
   mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;

   /* Iterate over all adapters/devices */
   status =  hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
   if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
   {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 FL("fail to get adapter: %pK %d"), pAdapterNode, status);
       goto end;
   }

   do 
   {
      if(pAdapterNode->pAdapter &&
           WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, 
               "restarting the driver(intf:\'%s\' mode:%d :try %d)",
               pAdapterNode->pAdapter->dev->name,
               pAdapterNode->pAdapter->device_mode,
               pHddCtx->hdd_restart_retries + 1);
         /* 
          * CFG80211 event to restart the driver
          * 
          * 'cfg80211_send_unprot_deauth' sends a 
          * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state 
          * of SME(Linux Kernel) state machine.
          *
          * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
          * the driver.
          *
          */

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
         cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
#else
         cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );  
#endif
      }
      status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
      pAdapterNode = pNext;
   } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));

   end:
   /* Free the allocated management frame */
   kfree(mgmt);

   /* Retry until we unload or reach max count */
   if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT) 
      vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);

   return status;

}
/**---------------------------------------------------------------------------
 *
 *   \brief wlan_hdd_restart_timer_cb
 *
 *   Restart timer callback. An internal function.
 *
 *   \param  - User data:
 *
 *   \return - None
 *             
 * --------------------------------------------------------------------------*/

void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
{
   hdd_context_t *pHddCtx = usrDataForCallback;
   wlan_hdd_framework_restart(pHddCtx);
   return;

}


/**---------------------------------------------------------------------------
 *
 *   \brief wlan_hdd_restart_driver
 *
 *   This function sends an event to supplicant to restart the WLAN driver. 
 *   
 *   This function is called from vos_wlanRestart.
 *
 *   \param  - pHddCtx
 *
 *   \return - VOS_STATUS_SUCCESS: Success
 *             VOS_STATUS_E_EMPTY: Adapter is Empty
 *             VOS_STATUS_E_ALREADY: Request already in progress

 * --------------------------------------------------------------------------*/
VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx) 
{
   VOS_STATUS status = VOS_STATUS_SUCCESS;

   /* A tight check to make sure reentrancy */
   if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
            "%s: WLAN restart is already in progress", __func__);

      return VOS_STATUS_E_ALREADY;
   }
   /* Send reset FIQ to WCNSS to invoke SSR. */
#ifdef HAVE_WCNSS_RESET_INTR
   wcnss_reset_fiq(TRUE);
#endif
 
   return status;
}

/**
 * hdd_get_total_sessions() -  provide total number of active sessions
 * @pHddCtx: Valid Global HDD context pointer
 *
 * This function iterates through pAdaptors and find the number of all active
 * sessions. This active sessions includes connected sta, p2p client and number
 * of client connected to sap/p2p go.
 *
 * Return:  Total number of active sessions.
 */
v_U8_t  hdd_get_total_sessions(hdd_context_t *pHddCtx)
{
    v_U8_t active_session = 0;
    hdd_station_ctx_t *pHddStaCtx;
    hdd_adapter_list_node_t *pAdapterNode, *pNext;
    hdd_adapter_t *pAdapter;
    VOS_STATUS status;

    status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
    while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
        pAdapter = pAdapterNode->pAdapter;
        switch (pAdapter->device_mode) {
        case VOS_STA_MODE:
        case VOS_P2P_CLIENT_MODE:
            pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
            if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
               active_session += 1;
            break;
        case VOS_STA_SAP_MODE:
        case VOS_P2P_GO_MODE:
           active_session += hdd_softap_get_connected_sta(pAdapter);
           break;
        default:
           break;
        }

        status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
        pAdapterNode = pNext;
    }

    return active_session;
}

/**
 * hdd_set_delack_value() - Set delack value
 * @pHddCtx: Valid Global HDD context pointer
 * @next_rx_level: Value to set for delack
 *
 * This function compare  present value and  next value of delack. If the both
 * are diffrent then it sets next value .
 *
 * Return: void.
 */
void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level)
{
    if (pHddCtx->cur_rx_level != next_rx_level) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
               "%s: TCP DELACK trigger level %d",
               __func__, next_rx_level);
        mutex_lock(&pHddCtx->cur_rx_level_lock);
        pHddCtx->cur_rx_level = next_rx_level;
        mutex_unlock(&pHddCtx->cur_rx_level_lock);
        wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &next_rx_level,
                                                       sizeof(next_rx_level));
    }
}

/**
 * hdd_set_default_stop_delack_timer() - Start delack timer
 * @pHddCtx: Valid Global HDD context pointer
 *
 * This function stop delack timer and set delack value to default..
 *
 * Return: void.
 */

void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx)
{
    if (VOS_TIMER_STATE_RUNNING !=
                            vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
               "%s: Can not stop timer", __func__);
        return;
    }

    vos_timer_stop(&pHddCtx->delack_timer);
    hdd_set_delack_value(pHddCtx, TP_IND_LOW);
}

/**
 * hdd_start_delack_timer() - Start delack timer
 * @pHddCtx: Valid Global HDD context pointer
 *
 * This function starts the delack timer for tcpDelAckComputeInterval time
 * interval.The default timer value is 2 second.
 *
 * Return: void.
 */
void hdd_start_delack_timer(hdd_context_t *pHddCtx)
{
    if (VOS_TIMER_STATE_RUNNING ==
                            vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
              "%s: Timer is already running", __func__);
        return;
    }

    vos_timer_start(&pHddCtx->delack_timer,
                                pHddCtx->cfg_ini->tcpDelAckComputeInterval);
}

/**
 * hdd_update_prev_rx_packet_count() - Update previous rx packet count
 * @pHddCtx: Valid Global HDD context pointer
 *
 * This function updates the prev_rx_packets count from the corresponding
 * pAdapter states. This prev_rx_packets will diffed with the packet count
 * at the end of delack timer. That can give number of RX packet is spacific
 * time.
 *
 * Return: void.
 */
void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx)
{
    hdd_adapter_list_node_t *pAdapterNode, *pNext;
    hdd_adapter_t *pAdapter;
    VOS_STATUS status;

    status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
    while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
        pAdapter = pAdapterNode->pAdapter;
        pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
        status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
        pAdapterNode = pNext;
    }
}

/**
 * hdd_manage_delack_timer() - start\stop delack timer
 * @pHddCtx: Valid Global HDD context pointer
 *
 * This function check the number of concerent session present, it starts the
 * delack timer if only one session is present.
 * In the case of BT_COEX and TDLS mode it blindly stop delack functionality.
 *
 * Return: void.
 */
void hdd_manage_delack_timer(hdd_context_t *pHddCtx)
{
    uint8_t sessions;

    if (!pHddCtx->cfg_ini->enable_delack) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
               "%s: TCP DELACK is not enabled", __func__);
        return;
    }

    /* Blindly stop timer of BTCOEX and TDLS Session is up */
    if (pHddCtx->mode != 0) {
        hdd_set_default_stop_delack_timer(pHddCtx);
        return;
    }

    sessions = hdd_get_total_sessions(pHddCtx);
    if (sessions == 1) {
        hdd_update_prev_rx_packet_count(pHddCtx);
        hdd_start_delack_timer(pHddCtx);
    } else {
        hdd_set_default_stop_delack_timer(pHddCtx);
    }
}

/**---------------------------------------------------------------------------
 *
 *   \brief wlan_hdd_init_channels
 *
 *   This function is used to initialize the channel list in CSR
 *
 *   This function is called from hdd_wlan_startup
 *
 *   \param  - pHddCtx: HDD context
 *
 *   \return - VOS_STATUS_SUCCESS: Success
 *             VOS_STATUS_E_FAULT: Failure reported by SME

 * --------------------------------------------------------------------------*/
static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
{
   eHalStatus status;

   status = sme_InitChannels(pHddCtx->hHal);
   if (HAL_STATUS_SUCCESS(status))
   {
      return VOS_STATUS_SUCCESS;
   }
   else
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
             __func__, status);
      return VOS_STATUS_E_FAULT;
   }
}

#ifdef CONFIG_ENABLE_LINUX_REG
VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
{
   eHalStatus status;

   status = sme_InitChannelsForCC(pHddCtx->hHal, init);
   if (HAL_STATUS_SUCCESS(status))
   {
      return VOS_STATUS_SUCCESS;
   }
   else
   {
      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
             __func__, status);
      return VOS_STATUS_E_FAULT;
   }
}
#endif
/*
 * API to find if there is any STA or P2P-Client is connected
 */
VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
{
    return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
}


/*
 * API to find if the firmware will send logs using DXE channel
 */
v_U8_t hdd_is_fw_logging_enabled(void)
{
    hdd_context_t *pHddCtx;

    pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
                              vos_get_global_context(VOS_MODULE_ID_HDD, NULL));

    return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
}

/*
 * API to find if the firmware will send trace logs using DXE channel
 */
v_U8_t hdd_is_fw_ev_logging_enabled(void)
{
    hdd_context_t *pHddCtx;

    pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
                              vos_get_global_context(VOS_MODULE_ID_HDD, NULL));

    return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
}
/*
 * API to find if there is any session connected
 */
VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
{
    return sme_is_any_session_connected(pHddCtx->hHal);
}


int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
{
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    hdd_scaninfo_t *pScanInfo = NULL;
    long status = 0;
    tSirAbortScanStatus abortScanStatus;

    pScanInfo = &pHddCtx->scan_info;
    INIT_COMPLETION(pScanInfo->abortscan_event_var);
    if (pScanInfo->mScanPending)
    {
        abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
                                             eCSR_SCAN_ABORT_DEFAULT);
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  FL("abortScanStatus: %d"), abortScanStatus);

        /* If there is active scan command lets wait for the completion else
         * there is no need to wait as scan command might be in the SME pending
         * command list.
         */
        if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
        {
            status = wait_for_completion_timeout(
                           &pScanInfo->abortscan_event_var,
                           msecs_to_jiffies(5000));
            if (0 >= status)
            {
               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Timeout or Interrupt occurred while waiting for abort"
                  "scan, status- %ld", __func__, status);
                return -ETIMEDOUT;
            }
        }
        else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      FL("hdd_abort_mac_scan failed"));
            return -VOS_STATUS_E_FAILURE;
        }
    }
    return 0;
}

/**
 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
 * user space
 * @frame_ind: Management frame data to be informed.
 *
 * This function is used to indicate management frame to
 * user space
 *
 * Return: None
 *
 */
void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
{
   hdd_context_t *hdd_ctx = NULL;
   hdd_adapter_t *adapter = NULL;
   v_CONTEXT_t vos_context = NULL;

   /* Get the global VOSS context.*/
   vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
   if (!vos_context) {
      hddLog(LOGE, FL("Global VOS context is Null"));
      return;
   }
   /* Get the HDD context.*/
   hdd_ctx =
      (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );

   if (0 != wlan_hdd_validate_context(hdd_ctx))
   {
       return;
   }
   adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
                                          frame_ind->sessionId);

   if ((NULL != adapter) &&
        (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
      __hdd_indicate_mgmt_frame(adapter,
                             frame_ind->frameLen,
                             frame_ind->frameBuf,
                             frame_ind->frameType,
                             frame_ind->rxChan,
                             frame_ind->rxRssi);
    return;

}

VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
{
    hdd_adapter_t *pAdapter;
    hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
    VOS_STATUS vosStatus;

    vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
    while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
    {
        pAdapter = pAdapterNode->pAdapter;
        if (NULL != pAdapter)
        {
            if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
                WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
                WLAN_HDD_P2P_GO == pAdapter->device_mode)
            {
                hddLog(LOG1, FL("abort ROC deviceMode: %d"),
                                 pAdapter->device_mode);
                if (VOS_STATUS_SUCCESS !=
                       wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
                {
                    hddLog(LOGE, FL("failed to abort ROC"));
                    return VOS_STATUS_E_FAILURE;
                }
            }
        }
        vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
        pAdapterNode = pNext;
    }
    return VOS_STATUS_SUCCESS;
}

hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
{
    hdd_adapter_t *pAdapter;
    hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
    hdd_cfg80211_state_t *cfgState;
    hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
    VOS_STATUS vosStatus;

    vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
    while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
    {
        pAdapter = pAdapterNode->pAdapter;
        if (NULL != pAdapter)
        {
            cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
            pRemainChanCtx = cfgState->remain_on_chan_ctx;
            if (pRemainChanCtx)
                break;
        }
        vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
        pAdapterNode = pNext;
    }
    return pRemainChanCtx;
}

/**
 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
 *
 * @pHddCtx: HDD context within host driver
 * @dfsScanMode: dfsScanMode passed from ioctl
 *
 */

VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
                                   tANI_U8 dfsScanMode)
{
    hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
    hdd_adapter_t *pAdapter;
    VOS_STATUS vosStatus;
    hdd_station_ctx_t *pHddStaCtx;
    eHalStatus status = eHAL_STATUS_SUCCESS;

    if(!pHddCtx)
    {
       hddLog(LOGE, FL("HDD context is Null"));
       return eHAL_STATUS_FAILURE;
    }

    if (pHddCtx->scan_info.mScanPending)
    {
        hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
               pHddCtx->scan_info.sessionId);
        hdd_abort_mac_scan(pHddCtx,
                           pHddCtx->scan_info.sessionId,
                           eCSR_SCAN_ABORT_DEFAULT);
    }

    if (!dfsScanMode)
    {
        vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
        while ((NULL != pAdapterNode) &&
               (VOS_STATUS_SUCCESS == vosStatus))
        {
            pAdapter = pAdapterNode->pAdapter;

            if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
            {
                pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

                if(!pHddStaCtx)
                {
                   hddLog(LOGE, FL("HDD STA context is Null"));
                   return eHAL_STATUS_FAILURE;
                }

                /* if STA is already connected on DFS channel,
                                disconnect immediately*/
                if (hdd_connIsConnected(pHddStaCtx) &&
                    (NV_CHANNEL_DFS ==
                     vos_nv_getChannelEnabledState(
                         pHddStaCtx->conn_info.operationChannel)))
                {
                    status = sme_RoamDisconnect(pHddCtx->hHal,
                             pAdapter->sessionId,
                             eCSR_DISCONNECT_REASON_UNSPECIFIED);
                    hddLog(LOG1, FL("Client connected on DFS channel %d,"
                           "sme_RoamDisconnect returned with status: %d"
                           "for sessionid: %d"), pHddStaCtx->conn_info.
                            operationChannel, status, pAdapter->sessionId);
                }
            }

            vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
                                              &pNext);
            pAdapterNode = pNext;
        }
    }

    sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
    sme_UpdateDFSRoamMode(pHddCtx->hHal,
                         (dfsScanMode != DFS_CHNL_SCAN_DISABLED));

    status = sme_HandleDFSChanScan(pHddCtx->hHal);
    if (!HAL_STATUS_SUCCESS(status))
    {
         hddLog(LOGE,
                FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
         return status;
    }

    return status;
}

static int hdd_log2_ceil(unsigned value)
{
    /* need to switch to unsigned math so that negative values
     * will right-shift towards 0 instead of -1
     */
    unsigned tmp = value;
    int log2 = -1;

    if (value == 0)
        return 0;

    while (tmp) {
        log2++;
        tmp >>= 1;
    }
    if (1U << log2 != value)
        log2++;

    return log2;
}

/**
 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
 * @pAdapter: adapter handle
 *
 * Return: vos status
 */
VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
{
    int hash_elem, log2, i;

    spin_lock_bh( &pAdapter->sta_hash_lock);
    if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
        spin_unlock_bh( &pAdapter->sta_hash_lock);
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: hash already attached for session id %d",
                  __func__, pAdapter->sessionId);
        return VOS_STATUS_SUCCESS;
    }
    spin_unlock_bh( &pAdapter->sta_hash_lock);

    hash_elem = WLAN_MAX_STA_COUNT;
    hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
    log2 = hdd_log2_ceil(hash_elem);
    hash_elem = 1 << log2;

    pAdapter->sta_id_hash.mask = hash_elem - 1;
    pAdapter->sta_id_hash.idx_bits = log2;
    pAdapter->sta_id_hash.bins =
        vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
    if (!pAdapter->sta_id_hash.bins) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: malloc failed for session %d",
                  __func__, pAdapter->sessionId);
        return VOS_STATUS_E_NOMEM;
    }

    for (i = 0; i < hash_elem; i++)
        hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);

    spin_lock_bh( &pAdapter->sta_hash_lock);
    pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
    spin_unlock_bh( &pAdapter->sta_hash_lock);
    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
              "%s: Station ID Hash attached for session id %d",
              __func__, pAdapter->sessionId);

    return VOS_STATUS_SUCCESS;
}

/**
 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
 * @pAdapter: adapter handle
 *
 * Return: vos status
 */
VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
{
    int hash_elem, i;
    v_SIZE_t size;

    spin_lock_bh( &pAdapter->sta_hash_lock);
    if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
        spin_unlock_bh( &pAdapter->sta_hash_lock);
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  "%s: hash not initialized for session id %d",
                  __func__, pAdapter->sessionId);
        return VOS_STATUS_SUCCESS;
    }

    pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
    spin_unlock_bh( &pAdapter->sta_hash_lock);

    hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;

    /* free all station info*/
    for (i = 0; i < hash_elem; i++) {
        hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
        if (size != 0) {
            VOS_STATUS status;
            hdd_staid_hash_node_t *sta_info_node = NULL;
            hdd_staid_hash_node_t *next_node = NULL;
            status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
                                           (hdd_list_node_t**) &sta_info_node );

            while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
            {
                status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
                                               &sta_info_node->node);
                vos_mem_free(sta_info_node);

                status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
                                            (hdd_list_node_t*)sta_info_node,
                                            (hdd_list_node_t**)&next_node);
                sta_info_node = next_node;
            }
        }
    }

    vos_mem_free(pAdapter->sta_id_hash.bins);
    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
              "%s: Station ID Hash detached for session id %d",
              __func__, pAdapter->sessionId);
    return VOS_STATUS_SUCCESS;
}

/**
 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
 * @pAdapter: adapter handle
 * @mac_addr_in: input mac address
 *
 * Return: index derived from mac address
 */
int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
                               v_MACADDR_t *mac_addr_in)
{
    uint16 index;
    struct hdd_align_mac_addr_t * mac_addr =
                     (struct hdd_align_mac_addr_t *)mac_addr_in;

    index = mac_addr->bytes_ab ^
            mac_addr->bytes_cd ^ mac_addr->bytes_ef;
    index ^= index >> pAdapter->sta_id_hash.idx_bits;
    index &= pAdapter->sta_id_hash.mask;
    return index;
}

/**
 * hdd_sta_id_hash_add_entry() - add entry in hash
 * @pAdapter: adapter handle
 * @sta_id: station id
 * @mac_addr: mac address
 *
 * Return: vos status
 */
VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
                                    v_U8_t sta_id, v_MACADDR_t *mac_addr)
{
    uint16 index;
    hdd_staid_hash_node_t *sta_info_node = NULL;

    index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
    sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
    if (!sta_info_node) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: malloc failed", __func__);
        return VOS_STATUS_E_NOMEM;
    }

    sta_info_node->sta_id = sta_id;
    vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));

    spin_lock_bh( &pAdapter->sta_hash_lock);
    if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
        spin_unlock_bh( &pAdapter->sta_hash_lock);
        vos_mem_free(sta_info_node);
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  "%s: hash is not initialized for session id %d",
                  __func__, pAdapter->sessionId);
        return VOS_STATUS_E_FAILURE;
    }

    hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
                           (hdd_list_node_t*) sta_info_node );
    spin_unlock_bh( &pAdapter->sta_hash_lock);
    return VOS_STATUS_SUCCESS;
}

/**
 * hdd_sta_id_hash_remove_entry() - remove entry from hash
 * @pAdapter: adapter handle
 * @sta_id: station id
 * @mac_addr: mac address
 *
 * Return: vos status
 */
VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
                                       v_U8_t sta_id, v_MACADDR_t *mac_addr)
{
    uint16 index;
    VOS_STATUS status;
    hdd_staid_hash_node_t *sta_info_node = NULL;
    hdd_staid_hash_node_t *next_node = NULL;

    spin_lock_bh( &pAdapter->sta_hash_lock);
    if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
        spin_unlock_bh( &pAdapter->sta_hash_lock);
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: hash is not initialized for session id %d",
                  __func__, pAdapter->sessionId);
        return VOS_STATUS_E_FAILURE;
    }

    index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
    status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
                                   (hdd_list_node_t**) &sta_info_node );

    while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
    {
        if (sta_info_node->sta_id == sta_id) {
            status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
                                       &sta_info_node->node);
            vos_mem_free(sta_info_node);
            break;
        }
        status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
                (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
        sta_info_node = next_node;
    }
    spin_unlock_bh( &pAdapter->sta_hash_lock);
    return status;
}

/**
 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
 * @pAdapter: adapter handle
 * @mac_addr_in: mac address
 *
 * Return: station id
 */
int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
                                  v_MACADDR_t *mac_addr_in)
{
    uint8 is_found = 0;
    uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
    uint16 index;
    VOS_STATUS status;
    hdd_staid_hash_node_t *sta_info_node = NULL;
    hdd_staid_hash_node_t *next_node = NULL;

    spin_lock_bh( &pAdapter->sta_hash_lock);
    if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
        spin_unlock_bh( &pAdapter->sta_hash_lock);
        hddLog(VOS_TRACE_LEVEL_INFO,
                  FL("hash is not initialized for session id %d"),
                  pAdapter->sessionId);
        return HDD_WLAN_INVALID_STA_ID;
    }

    index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
    status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
                                   (hdd_list_node_t**) &sta_info_node );

    while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
    {
        if (vos_mem_compare(&sta_info_node->mac_addr,
                            mac_addr_in, sizeof(v_MACADDR_t))) {
            is_found = 1;
            sta_id = sta_info_node->sta_id;
            break;
        }
        status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
                                     (hdd_list_node_t*)sta_info_node,
                                     (hdd_list_node_t**)&next_node);
        sta_info_node = next_node;
    }
    spin_unlock_bh( &pAdapter->sta_hash_lock);
    return sta_id;
}

/*FW memory dump feature*/
/**
 * This structure hold information about the /proc file
 *
 */
static struct proc_dir_entry *proc_file, *proc_dir;

/**
 * memdump_read() - perform read operation in memory dump proc file
 *
 * @file  - handle for the proc file.
 * @buf   - pointer to user space buffer.
 * @count - number of bytes to be read.
 * @pos   - offset in the from buffer.
 *
 * This function performs read operation for the memory dump proc file.
 *
 * Return: number of bytes read on success, error code otherwise.
 */
static ssize_t memdump_read(struct file *file, char __user *buf,
                    size_t count, loff_t *pos)
{
    int status;
    hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
    size_t ret_count;
    loff_t bytes_left;
    ENTER();

    hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
    status = wlan_hdd_validate_context(hdd_ctx);
    if (0 != status) {
        return -EINVAL;
    }

    if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
        hddLog(LOGE, FL("Current mem dump request timed out/failed"));
        return -EINVAL;
    }

    /* run fs_read_handler in an atomic context*/
    vos_ssr_protect(__func__);
    ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos, &bytes_left);
    if(bytes_left == 0)
    {
        /*Free the fwr mem dump buffer */
        wlan_free_fwr_mem_dump_buffer();
        wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
        ret_count=0;
    }
    /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
    vos_ssr_unprotect(__func__);
    EXIT();
    return ret_count;
}

/**
 * struct memdump_fops - file operations for memory dump feature
 * @read - read function for memory dump operation.
 *
 * This structure initialize the file operation handle for memory
 * dump feature
 */
static const struct file_operations memdump_fops = {
    read: memdump_read
};

struct fw_mem_dump_priv {
	uint32_t status;
};

/*
* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
* To be passed by HDD to WDA and called upon receiving of response
* from firmware
* @fwMemDumpReqContext : memory dump request context
* @dump_rsp : dump response from HAL
* Returns none
*/
void wlan_hdd_fw_mem_dump_cb(void *context,
                         tAniFwrDumpRsp *dump_rsp)
{
	struct hdd_request *request;
	struct fw_mem_dump_priv *priv;

	request = hdd_request_get(context);
	if (!request) {
		hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
		return;
	}

	ENTER();

	priv = hdd_request_priv(request);
	priv->status = dump_rsp->dump_status;

	/* report the status to requesting function and free mem.*/
	if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
		hddLog(LOGE, FL("fw dump request declined by fwr"));
		//set the request completion variable
		hdd_request_complete(request);
		//Free the allocated fwr dump
		wlan_free_fwr_mem_dump_buffer();
		wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
	} else {
		hddLog(LOG1, FL("fw dump request accepted by fwr"));
		/* register the HDD callback which will be called by SVC */
		wlan_set_svc_fw_mem_dump_req_cb(
					(void*)wlan_hdd_fw_mem_dump_req_cb,
					context);
	}

	hdd_request_put(request);

	EXIT();
}

/**
 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
 *
 * This function removes file/dir under proc file system that was
 * processing firmware memory dump
 *
 * Return:  None
 */
static void memdump_procfs_remove(void)
{
    remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
    hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
           PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
    remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
    hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
}

/**
 * memdump_procfs_init() - Initialize procfs for memory dump
 *
 * @vos_ctx - Global vos context.
 *
 * This function create file under proc file system to be used later for
 * processing firmware memory dump
 *
 * Return:   0 on success, error code otherwise.
 */
static int memdump_procfs_init(void *vos_ctx)
{
    hdd_context_t *hdd_ctx;

    hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
    if (!hdd_ctx) {
        hddLog(LOGE , FL("Invalid HDD context"));
        return -EINVAL;
    }

    proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
    if (proc_dir == NULL) {
        remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
        hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
               PROCFS_MEMDUMP_DIR);
        return -ENOMEM;
    }

    proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
                                 S_IRUSR | S_IWUSR, proc_dir,
                                 &memdump_fops, hdd_ctx);
    if (proc_file == NULL) {
        remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
        hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
               PROCFS_MEMDUMP_NAME);
        return -ENOMEM;
    }

    hddLog(LOG1 , FL("/proc/%s/%s created"),
           PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);

    return 0;
}

/**
 * memdump_init() - Initialization function for memory dump feature
 *
 * This function creates proc file for memdump feature and registers
 * HDD callback function with SME.
 *
 * Return - 0 on success, error otherwise
 */
int memdump_init(void)
{
    hdd_context_t *hdd_ctx;
    void *vos_ctx;
    int status = 0;

    vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
    if (!vos_ctx) {
        hddLog(LOGE, FL("Invalid VOS context"));
        return -EINVAL;
    }

    hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
    if (!hdd_ctx) {
        hddLog(LOGE , FL("Invalid HDD context"));
        return -EINVAL;
    }

    status = memdump_procfs_init(vos_ctx);
    if (status) {
        hddLog(LOGE , FL("Failed to create proc file"));
        return status;
    }

    return 0;
}

/**
 * memdump_deinit() - De initialize memdump feature
 *
 * This function removes proc file created for memdump feature.
 *
 * Return: None
 */
int memdump_deinit(void)
{
    hdd_context_t *hdd_ctx;
    void *vos_ctx;

    vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
    if (!vos_ctx) {
        hddLog(LOGE, FL("Invalid VOS context"));
        return -EINVAL;
    }

    hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
    if(!hdd_ctx) {
        hddLog(LOGE , FL("Invalid HDD context"));
        return -EINVAL;
    }

    memdump_procfs_remove();
    return 0;
}

/**
 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
 * Return: HAL status
 */

int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
{
   tAniFwrDumpReq fw_mem_dump_req={0};
   eHalStatus status = eHAL_STATUS_FAILURE;
   int ret=0, dump_status;
   void *cookie;
   struct hdd_request *request;
   struct fw_mem_dump_priv *priv;
   static const struct hdd_request_params params = {
       .priv_size = sizeof(*priv),
       .timeout_ms = FW_MEM_DUMP_TIMEOUT_MS,
   };

   ENTER();

   /*Check whether a dump request is already going on
    *Caution this function will free previously held memory if new dump request is allowed*/
   if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
       hddLog(LOGE, FL("Fw memdump already in progress"));
       return -EBUSY;
   }
   //Allocate memory for fw mem dump buffer
   ret = wlan_fwr_mem_dump_buffer_allocation();
   if(ret == -EFAULT)
   {
      hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
      return ret;
   }
   if (0 != ret) {
       hddLog(LOGE, FL("Fwr mem Allocation failed"));
       return -ENOMEM;
   }

   request = hdd_request_alloc(&params);
   if (!request) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
        return VOS_STATUS_E_NOMEM;
   }
   cookie = hdd_request_cookie(request);

   fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
   fw_mem_dump_req.fwMemDumpReqContext = cookie;
   status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
   if(eHAL_STATUS_SUCCESS != status)
   {
       hddLog(VOS_TRACE_LEVEL_ERROR,
          "%s: fw_mem_dump_req failed ", __func__);
       wlan_free_fwr_mem_dump_buffer();
       ret = -EFAULT;
       goto cleanup;
   }
   /*wait for fw mem dump completion to send event to userspace*/
   ret = hdd_request_wait_for_response(request);
   if (ret)
   {
      hddLog(VOS_TRACE_LEVEL_ERROR,
          "%s: fw_mem_dump_req timeout %d ", __func__,ret);
      ret = -ETIMEDOUT;
   }else {
       priv = hdd_request_priv(request);
       dump_status = priv->status;
   }
cleanup:
   hdd_request_put(request);
   if(!ret && !dump_status)
      ret = -EFAULT;

   EXIT();
   return ret;
}

/**
 * HDD callback which will be called by SVC to indicate mem dump completion.
 */
void wlan_hdd_fw_mem_dump_req_cb(void *context)
{
	struct hdd_request *request;
	struct fw_mem_dump_priv *priv;

	request = hdd_request_get(context);
	if (!request) {
		hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
		return;
	}

	priv = hdd_request_priv(request);
	priv->status = true;

	hdd_request_complete(request);
	hdd_request_put(request);
}

void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
{
        if (NULL == pAdapter)
        {
            hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
            return;
        }
        init_completion(&pAdapter->session_open_comp_var);
        init_completion(&pAdapter->session_close_comp_var);
        init_completion(&pAdapter->disconnect_comp_var);
        init_completion(&pAdapter->linkup_event_var);
        init_completion(&pAdapter->cancel_rem_on_chan_var);
        init_completion(&pAdapter->rem_on_chan_ready_event);
        init_completion(&pAdapter->pno_comp_var);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
        init_completion(&pAdapter->offchannel_tx_event);
#endif
        init_completion(&pAdapter->tx_action_cnf_event);
#ifdef FEATURE_WLAN_TDLS
        init_completion(&pAdapter->tdls_add_station_comp);
        init_completion(&pAdapter->tdls_del_station_comp);
        init_completion(&pAdapter->tdls_mgmt_comp);
        init_completion(&pAdapter->tdls_link_establish_req_comp);
#endif

#ifdef WLAN_FEATURE_RMC
        init_completion(&pAdapter->ibss_peer_info_comp);
#endif /* WLAN_FEATURE_RMC */
        init_completion(&pAdapter->ula_complete);
        init_completion(&pAdapter->change_country_code);

#ifdef FEATURE_WLAN_BATCH_SCAN
        init_completion(&pAdapter->hdd_set_batch_scan_req_var);
        init_completion(&pAdapter->hdd_get_batch_scan_req_var);
#endif
        init_completion(&pAdapter->wlan_suspend_comp_var);

        return;
}

#ifdef MDNS_OFFLOAD

/**
 * hdd_mdns_enable_offload_done() - mdns enable offload response api
 * @padapter: holds adapter
 * @status: response status
 *
 * Return - None
 */
void hdd_mdns_enable_offload_done(void *padapter, VOS_STATUS status)
{
    hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;

    ENTER();

    if (NULL == adapter)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               "%s: adapter is NULL",__func__);
        return;
    }

    adapter->mdns_status.mdns_enable_status = status;
    vos_event_set(&adapter->mdns_status.vos_event);
    return;
}

/**
 * hdd_mdns_fqdn_offload_done() - mdns fqdn offload response api
 * @padapter: holds adapter
 * @status: responce status
 *
 * Return - None
 */
void hdd_mdns_fqdn_offload_done(void *padapter, VOS_STATUS status)
{
    hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;

    ENTER();

    if (NULL == adapter)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               "%s: adapter is NULL",__func__);
        return;
    }

    adapter->mdns_status.mdns_fqdn_status = status;
    return;
}

/**
 * hdd_mdns_resp_offload_done() - mdns resp offload response api
 * @padapter: holds adapter
 * @status: responce status
 *
 * Return - None
 */
void hdd_mdns_resp_offload_done(void *padapter, VOS_STATUS status)
{
    hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;

    ENTER();

    if (NULL == adapter)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               "%s: adapter is NULL",__func__);
        return;
    }

    adapter->mdns_status.mdns_resp_status = status;
    return;
}

/**
 * wlan_hdd_mdns_process_response_dname() - Process mDNS domain name
 * @response: Pointer to a struct hdd_mdns_resp_info
 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
 *
 * This function will pack the whole domain name without compression. It will
 * add the leading len for each field and add zero length octet to terminate
 * the domain name.
 *
 * Return: Return boolean. TRUE for success, FALSE for fail.
 */
static bool
wlan_hdd_mdns_process_response_dname(struct hdd_mdns_resp_info *response,
                     sir_mdns_resp_info resp_info)
{
    uint8_t  num;
    uint16_t idx;
    uint8_t len = 0;

    if ((response == NULL) || (response->data == NULL) ||
        (response->offset == NULL)) {
        hddLog(LOGE, FL("Either data or offset in response is NULL!"));
        return FALSE;
    }

    if ((resp_info == NULL) ||
        (resp_info->resp_len >= MAX_MDNS_RESP_LEN)) {
        hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
        return FALSE;
    }

    for (num = 0; num < response->num_entries; num++) {
        response->offset[num] =
                    resp_info->resp_len + MDNS_HEADER_LEN;
        idx = num * MAX_LEN_DOMAINNAME_FIELD;
        len = strlen((char *)&response->data[idx]);
        if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
            hddLog(LOGE, FL("resp_len exceeds %d!"),
                MAX_MDNS_RESP_LEN);
            return FALSE;
                }
        resp_info->resp_data[resp_info->resp_len] = len;
        resp_info->resp_len++;
        vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
                &response->data[idx], len);
        resp_info->resp_len += len;
    }

    /* The domain name terminates with the zero length octet */
    if (num == response->num_entries) {
        if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
            hddLog(LOGE, FL("resp_len exceeds %d!"),
                MAX_MDNS_RESP_LEN);
            return FALSE;
        }
        resp_info->resp_data[resp_info->resp_len] = 0;
        resp_info->resp_len++;
    }

    return TRUE;
}

/**
 * wlan_hdd_mdns_format_response_u16() - Form uint16_t response data
 * @value: The uint16_t value is formed to the struct tSirMDNSResponseInfo
 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
 *
 * Return: None
 */
static void wlan_hdd_mdns_format_response_u16(uint16_t value,
                          sir_mdns_resp_info resp_info)
{
    uint8_t val_u8;

    if ((resp_info == NULL) || (resp_info->resp_data == NULL))
        return;
    val_u8 = (value & 0xff00) >> 8;
    resp_info->resp_data[resp_info->resp_len++] = val_u8;
    val_u8 = value & 0xff;
    resp_info->resp_data[resp_info->resp_len++] = val_u8;
}

/**
 * wlan_hdd_mdns_format_response_u32() - Form uint32_t response data
 * @value: The uint32_t value is formed to the struct tSirMDNSResponseInfo
 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
 *
 * Return: None
 */
static void wlan_hdd_mdns_format_response_u32(uint32_t value,
                          sir_mdns_resp_info resp_info)
{
    uint8_t val_u8;

    if ((resp_info == NULL) || (resp_info->resp_data == NULL))
        return;
    val_u8 = (value & 0xff000000) >> 24;
    resp_info->resp_data[resp_info->resp_len++] = val_u8;
    val_u8 = (value & 0xff0000) >> 16;
    resp_info->resp_data[resp_info->resp_len++] = val_u8;
    val_u8 = (value & 0xff00) >> 8;
    resp_info->resp_data[resp_info->resp_len++] = val_u8;
    val_u8 = value & 0xff;
    resp_info->resp_data[resp_info->resp_len++] = val_u8;
}

/**
 * wlan_hdd_mdns_process_response_misc() - Process misc info in mDNS response
 * @resp_type: Response type for mDNS
 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
 *
 * This function will pack the response type, class and TTL (Time To Live).
 *
 * Return: Return boolean. TRUE for success, FALSE for fail.
 */
static bool wlan_hdd_mdns_process_response_misc(uint16_t resp_type,
                        sir_mdns_resp_info resp_info)
{
    uint16_t len;

    if (resp_info == NULL) {
        hddLog(LOGE, FL("resp_info is NULL!"));
        return FALSE;
    }

    len = resp_info->resp_len + (2 * sizeof(uint16_t) + sizeof(uint32_t));
    if (len >= MAX_MDNS_RESP_LEN) {
        hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
        return FALSE;
    }

    /* Fill Type, Class, TTL */
    wlan_hdd_mdns_format_response_u16(resp_type, resp_info);
    wlan_hdd_mdns_format_response_u16(MDNS_CLASS, resp_info);
    wlan_hdd_mdns_format_response_u32(MDNS_TTL, resp_info);

    return TRUE;
}

/**
 * wlan_hdd_mdns_compress_data() - Compress the domain name in mDNS response
 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
 * @response_dst: The response which domain name is compressed.
 * @response_src: The response which domain name is matched with response_dst.
 *                Its offset is used for data compression.
 * @num_matched: The number of matched entries between response_dst and
 *               response_src
 *
 * This function will form the different fields of domain name in response_dst
 * if any. Then use the offset of the matched domain name in response_src to
 * compress the matched domain name.
 *
 * Return: Return boolean. TRUE for success, FALSE for fail.
 */
static bool
wlan_hdd_mdns_compress_data(sir_mdns_resp_info resp_info,
                struct hdd_mdns_resp_info *response_dst,
                struct hdd_mdns_resp_info *response_src,
                uint8_t num_matched)
{
    uint8_t  num, num_diff;
    uint16_t value, idx;
    uint8_t len = 0;

    if ((response_src == NULL) || (response_dst == NULL) ||
        (resp_info == NULL)) {
        hddLog(LOGE, FL("response info is NULL!"));
        return FALSE;
    }

    if (response_dst->num_entries < num_matched) {
        hddLog(LOGE, FL("num_entries is less than num_matched!"));
        return FALSE;
    }

    if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
        hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
        return FALSE;
    }

    num_diff = response_dst->num_entries - num_matched;
    if ((num_diff > 0) && (response_dst->data == NULL)) {
        hddLog(LOGE, FL("response_dst->data is NULL!"));
        return FALSE;
    }

    /*
    * Handle the unmatched string at the beginning
    * Store the length of octets and the octets
    */
    for (num = 0; num < num_diff; num++) {
        response_dst->offset[num] =
            resp_info->resp_len + MDNS_HEADER_LEN;
        idx = num * MAX_LEN_DOMAINNAME_FIELD;
        len = strlen((char *)&response_dst->data[idx]);
        if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
            hddLog(LOGE, FL("resp_len exceeds %d!"),
                MAX_MDNS_RESP_LEN);
            return FALSE;
        }
        resp_info->resp_data[resp_info->resp_len] = len;
        resp_info->resp_len++;
        vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
            &response_dst->data[idx], len);
        resp_info->resp_len += len;
    }
    /*
    * Handle the matched string from the end
    * Just keep the offset and mask the leading two bit
    */
    if (response_src->num_entries >= num_matched) {
        num_diff = response_src->num_entries - num_matched;
        value = response_src->offset[num_diff];
        if (value > 0) {
            value |= 0xc000;
            if ((resp_info->resp_len + sizeof(uint16_t)) >=
                MAX_MDNS_RESP_LEN) {
                hddLog(LOGE, FL("resp_len exceeds %d!"),
                    MAX_MDNS_RESP_LEN);
                return FALSE;
            }
            wlan_hdd_mdns_format_response_u16(value, resp_info);
            return TRUE;
        }
    }
    return FALSE;
}

/**
 * wlan_hdd_mdns_reset_response() - Reset the response info
 * @response: The response which info is reset.
 *
 * Return: None
 */
static void wlan_hdd_mdns_reset_response(struct hdd_mdns_resp_info *response)
{
    if (response == NULL)
        return;
    response->num_entries = 0;
    response->data = NULL;
    response->offset = NULL;
}

/**
 * wlan_hdd_mdns_init_response() - Initialize the response info
 * @response: The response which info is initiatized.
 * @resp_dname: The domain name string which might be tokenized.
 *
 * This function will allocate the memory for both response->data and
 * response->offset. Besides, it will also tokenize the domain name to some
 * entries and fill response->num_entries with the num of entries.
 *
 * Return: Return boolean. TRUE for success, FALSE for fail.
 */
static bool wlan_hdd_mdns_init_response(struct hdd_mdns_resp_info *response,
                    uint8_t *resp_dname, char separator)
{
    uint16_t size;

    if ((resp_dname == NULL) || (response == NULL)) {
        hddLog(LOGE, FL("resp_dname or response is NULL!"));
        return FALSE;
    }

    size = MAX_NUM_FIELD_DOMAINNAME * MAX_LEN_DOMAINNAME_FIELD;
    response->data = vos_mem_malloc(size);
    if (response->data) {
        vos_mem_zero(response->data, size);
        if (VOS_STATUS_SUCCESS !=
            hdd_string_to_string_array((char *)resp_dname,
                        response->data,
                        separator,
                        &response->num_entries,
                        MAX_NUM_FIELD_DOMAINNAME,
                        MAX_LEN_DOMAINNAME_FIELD)) {
            hddLog(LOGE, FL("hdd_string_to_string_array fail!"));
            goto err_init_resp;
        }

        if ((response->num_entries > 0) &&
            (strlen((char *)&response->data[0]) > 0)) {
            size = sizeof(uint16_t) * response->num_entries;
            response->offset = vos_mem_malloc(size);
            if (response->offset) {
                vos_mem_zero(response->offset, size);
                return TRUE;
            }
        }
    }

err_init_resp:
    if (response->data)
        vos_mem_free(response->data);
    wlan_hdd_mdns_reset_response(response);
    return FALSE;
}

/**
 * wlan_hdd_mdns_find_entries_from_end() - Find the matched entries
 * @response1: The response info is used to be compared.
 * @response2: The response info is used to be compared.
 *
 * This function will find the matched entries from the end.
 *
 * Return: Return the number of the matched entries.
 */
static uint8_t
wlan_hdd_mdns_find_entries_from_end(struct hdd_mdns_resp_info *response1,
                    struct hdd_mdns_resp_info *response2)
{
    uint8_t  min, len1, i;
    uint16_t  num1, num2;
    uint8_t num_matched = 0;

    min = VOS_MIN(response1->num_entries, response2->num_entries);

    for (i = 1; i <= min; i++) {
        num1 = (response1->num_entries - i);
        num1 *= MAX_LEN_DOMAINNAME_FIELD;
        num2 = (response2->num_entries - i);
        num2 *= MAX_LEN_DOMAINNAME_FIELD;
        len1 = strlen((char *)&response1->data[num1]);

        if ((len1 == 0) ||
            (len1 != strlen((char *)&response2->data[num2])))
            break;
        if (memcmp(&response1->data[num1],
            &response2->data[num2], len1))
            break;
        else
            num_matched++;
    }

    return num_matched;
}

/**
 * wlan_hdd_mdns_find_max() - Find the maximum number of the matched entries
 * @matchedlist: Pointer to the array of struct hdd_mdns_resp_matched
 * @numlist: The number of the elements in the array matchedlist.
 *
 * Find the max number of the matched entries among the array matchedlist.
 *
 * Return: None
 */
static void wlan_hdd_mdns_find_max(struct hdd_mdns_resp_matched *matchedlist,
                   uint8_t numlist)
{
    int j;
    struct hdd_mdns_resp_matched tmp;

    /* At least two values are used for sorting */
    if ((numlist < 2) || (matchedlist == NULL)) {
        hddLog(LOGE, FL("At least two values are used for sorting!"));
        return;
    }

    for (j = 0; j < numlist-1; j++) {
        if (matchedlist[j].num_matched >
            matchedlist[j+1].num_matched) {
            vos_mem_copy(&tmp, &matchedlist[j],
                    sizeof(struct hdd_mdns_resp_matched));
            vos_mem_copy(&matchedlist[j], &matchedlist[j+1],
                    sizeof(struct hdd_mdns_resp_matched));
            vos_mem_copy(&matchedlist[j+1], &tmp,
                    sizeof(struct hdd_mdns_resp_matched));
        }
    }
}

/**
 * wlan_hdd_mdns_pack_response_type_a() - Pack Type A response
 * @ini_config: Pointer to the struct hdd_config_t
 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
 *
 * Type A response include QName, response type, class, TTL and Ipv4.
 *
 * Return: Return boolean. TRUE for success, FALSE for fail.
 */
static bool
wlan_hdd_mdns_pack_response_type_a(hdd_config_t *ini_config,
                   sir_mdns_resp_info resp_info,
                   struct hdd_mdns_resp_info *resptype_a)
{
    uint16_t value;
    uint32_t len;

    ENTER();
    if ((ini_config == NULL) || (resp_info == NULL) ||
        (resptype_a == NULL)) {
        hddLog(LOGE, FL("ini_config or response info is NULL!"));
        return FALSE;
    }

    /* No Type A response */
    if (strlen((char *)ini_config->mdns_resp_type_a) <= 0)
        return TRUE;

    /* Wrong response is assigned, just ignore this response */
    if (!wlan_hdd_mdns_init_response(resptype_a,
                    ini_config->mdns_resp_type_a, '.'))
        return TRUE;

    /* Process response domain name */
    if (!wlan_hdd_mdns_process_response_dname(resptype_a, resp_info)) {
        hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
            MDNS_TYPE_A);
        return FALSE;
    }

    /* Process response Type, Class, TTL */
    if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_A, resp_info)) {
        hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
            MDNS_TYPE_A);
        return FALSE;
    }

    /* Process response RDLength, RData */
    len = sizeof(uint16_t) + sizeof(uint32_t);
    len += resp_info->resp_len;
    if (len >= MAX_MDNS_RESP_LEN) {
        hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
        return FALSE;
    }
    value = sizeof(uint32_t);
    wlan_hdd_mdns_format_response_u16(value, resp_info);
    wlan_hdd_mdns_format_response_u32(ini_config->mdns_resp_type_a_ipv4,
                    resp_info);

    EXIT();
    return TRUE;
}

/**
 * wlan_hdd_mdns_pack_response_type_txt() - Pack Type Txt response
 * @ini_config: Pointer to the struct hdd_config_t
 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type txt
 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
 *
 * Type Txt response include QName, response type, class, TTL and text content.
 * Also, it will find the matched QName from resptype_A and compress the data.
 *
 * Return: Return boolean. TRUE for success, FALSE for fail.
 */
static bool
wlan_hdd_mdns_pack_response_type_txt(hdd_config_t *ini_config,
                     sir_mdns_resp_info resp_info,
                     struct hdd_mdns_resp_info *resptype_txt,
                     struct hdd_mdns_resp_info *resptype_a)
{
    uint8_t num_matched;
    uint8_t num;
    uint16_t idx;
    uint16_t value = 0;
    uint32_t len;
    uint32_t total_len;
    bool status;
    struct hdd_mdns_resp_info resptype_content;

    ENTER();

    if ((ini_config == NULL) || (resp_info == NULL) ||
        (resptype_txt == NULL)) {
        hddLog(LOGE, FL("ini_config or response info is NULL!"));
        return FALSE;
    }

    /* No Type Txt response */
    if (strlen((char *)ini_config->mdns_resp_type_txt) <= 0)
        return TRUE;

    /* Wrong response is assigned, just ignore this response */
    if (!wlan_hdd_mdns_init_response(resptype_txt,
                ini_config->mdns_resp_type_txt, '.'))
        return TRUE;

    /*
    * For data compression
    * Check if any strings are matched with Type A response
    */
    if (resptype_a && (resptype_a->num_entries > 0)) {
        num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_txt,
                                resptype_a);
        if (num_matched > 0) {
            if (!wlan_hdd_mdns_compress_data(resp_info,
                resptype_txt, resptype_a, num_matched)) {
                hddLog(LOGE, FL("Fail to compress mDNS "
                    "response (%d)!"), MDNS_TYPE_TXT);
                return FALSE;
            }
        } else {
            /*
            * num_matched is zero. Error!
            * At least ".local" is needed.
            */
            hddLog(LOGE, FL("No matched string! Fail to pack mDNS "
                    "response (%d)!"), MDNS_TYPE_TXT);
            return FALSE;
        }
    } else {
        /* no TypeA response, so show the whole data */
        if (!wlan_hdd_mdns_process_response_dname(resptype_txt,
                            resp_info)) {
            hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
                MDNS_TYPE_TXT);
            return FALSE;
        }
    }

    /* Process response Type, Class, TTL */
    if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_TXT, resp_info)) {
        hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
            MDNS_TYPE_TXT);
        return FALSE;
    }

    /*
    * Process response RDLength, RData.
    * TypeTxt RData include len.
    */
    status = wlan_hdd_mdns_init_response(&resptype_content,
                ini_config->mdns_resp_type_txt_content,
                '/');
    if (status == FALSE) {
        hddLog(LOGE, FL("wlan_hdd_mdns_init_response FAIL"));
        return FALSE;
    }

    for (num = 0; num < resptype_content.num_entries; num++) {
        idx = num * MAX_LEN_DOMAINNAME_FIELD;
        value += strlen((char *)&resptype_content.data[idx]);
    }

    /* content len is uint16_t */
    total_len = sizeof(uint16_t);
    total_len += resp_info->resp_len + value +
        resptype_content.num_entries;

    if (total_len >= MAX_MDNS_RESP_LEN) {
        hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
        return FALSE;
    }
    wlan_hdd_mdns_format_response_u16(value + resptype_content.num_entries,
                        resp_info);

    for (num = 0; num < resptype_content.num_entries; num++) {
        idx = num * MAX_LEN_DOMAINNAME_FIELD;
        len = strlen((char *)&resptype_content.data[idx]);
        resp_info->resp_data[resp_info->resp_len] = len;
        resp_info->resp_len++;

        vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
            &resptype_content.data[idx], len);

        resp_info->resp_len += len;
        hddLog(LOG1, FL("index = %d, len = %d, str = %s"),
            num, len, &resptype_content.data[idx]);
    }

    EXIT();
    return TRUE;
}

/**
 * wlan_hdd_mdns_pack_response_type_ptr_dname() - Pack Type PTR domain name
 * @ini_config: Pointer to the struct hdd_config_t
 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
 *                     domain name
 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
 *
 * The Type Ptr response include Type PTR domain name in its data field.
 * Also, it will find the matched QName from the existing resptype_ptr,
 * resptype_txt, resptype_a and then compress the data.
 *
 * Return: Return boolean. TRUE for success, FALSE for fail.
 */
static bool
wlan_hdd_mdns_pack_response_type_ptr_dname(hdd_config_t *ini_config,
                   sir_mdns_resp_info resp_info,
                   struct hdd_mdns_resp_info *resptype_ptr_dn,
                   struct hdd_mdns_resp_info *resptype_ptr,
                   struct hdd_mdns_resp_info *resptype_txt,
                   struct hdd_mdns_resp_info *resptype_a)
{
    uint8_t  num_matched, numlist, size;
    struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
    struct hdd_mdns_resp_info *resp;

    if ((ini_config == NULL) || (resp_info == NULL) ||
        (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
        hddLog(LOGE, FL("ini_config or response info is NULL!"));
        return FALSE;
    }

    /* No Type Ptr domain name response */
    if (strlen((char *)ini_config->mdns_resp_type_ptr_dname) <= 0)
        return TRUE;

    /* Wrong response is assigned, just ignore this response */
    if (!wlan_hdd_mdns_init_response(resptype_ptr_dn,
                ini_config->mdns_resp_type_ptr_dname, '.'))
        return TRUE;

    /*
    * For data compression
    * Check if any strings are matched with previous
    * response.
    */
    numlist = 0;
    size = (MAX_MDNS_RESP_TYPE-1);
    size *= sizeof(struct hdd_mdns_resp_matched);
    vos_mem_zero(matchedlist, size);
    num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr_dn,
                            resptype_ptr);
    if (num_matched > 0) {
        matchedlist[numlist].num_matched = num_matched;
        matchedlist[numlist].type = MDNS_TYPE_PTR;
        numlist++;
    }
    if (resptype_txt && (resptype_txt->num_entries > 0)) {
        num_matched = wlan_hdd_mdns_find_entries_from_end(
                    resptype_ptr_dn, resptype_txt);
        if (num_matched > 0) {
            matchedlist[numlist].num_matched = num_matched;
            matchedlist[numlist].type = MDNS_TYPE_TXT;
            numlist++;
        }
    }
    if (resptype_a && (resptype_a->num_entries > 0)) {
        num_matched = wlan_hdd_mdns_find_entries_from_end(
                    resptype_ptr_dn,resptype_a);
        if (num_matched > 0) {
            matchedlist[numlist].num_matched = num_matched;
            matchedlist[numlist].type = MDNS_TYPE_A;
            numlist++;
        }
    }
    if (numlist > 0) {
        if (numlist > 1)
            wlan_hdd_mdns_find_max(matchedlist, numlist);
        resp = NULL;
        switch (matchedlist[numlist-1].type) {
        case MDNS_TYPE_A:
            resp = resptype_a;
            break;
        case MDNS_TYPE_TXT:
            resp = resptype_txt;
            break;
        case MDNS_TYPE_PTR:
            resp = resptype_ptr;
            break;
        default:
            hddLog(LOGE, FL("Fail to compress mDNS response "
                    "(%d)!"), MDNS_TYPE_PTR_DNAME);
            return FALSE;
        }
        num_matched = matchedlist[numlist-1].num_matched;
        if (!wlan_hdd_mdns_compress_data(resp_info, resptype_ptr_dn,
                        resp, num_matched)) {
            hddLog(LOGE, FL("Fail to compress mDNS response "
                    "(%d)!"), MDNS_TYPE_PTR_DNAME);
            return FALSE;
        }
    } else {
        /* num = 0 -> no matched string */
        if (!wlan_hdd_mdns_process_response_dname(resptype_ptr_dn,
                            resp_info)) {
            hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
                    MDNS_TYPE_PTR_DNAME);
            return FALSE;
        }
    }

    return TRUE;
}

/**
 * wlan_hdd_mdns_pack_response_type_ptr() - Pack Type PTR response
 * @ini_config: Pointer to the struct hdd_config_t
 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
 *                     domain name
 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
 *
 * The Type Ptr response include QName, response type, class, TTL and
 * Type PTR domain name. Also, it will find the matched QName from the
 * existing resptype_txt, resptype_a and then compress the data.
 *
 * Return: Return boolean. TRUE for success, FALSE for fail.
 */
static bool
wlan_hdd_mdns_pack_response_type_ptr(hdd_config_t *ini_config,
                 sir_mdns_resp_info resp_info,
                 struct hdd_mdns_resp_info *resptype_ptr,
                 struct hdd_mdns_resp_info *resptype_ptr_dn,
                 struct hdd_mdns_resp_info *resptype_txt,
                 struct hdd_mdns_resp_info *resptype_a)
{
    uint8_t num_matched, num_matched1;
    uint16_t value;
    uint8_t val_u8;
    uint32_t offset_data_len, len;

    ENTER();
    if ((ini_config == NULL) || (resp_info == NULL) ||
        (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
        hddLog(LOGE, FL("ini_config or response info is NULL!"));
        return FALSE;
    }

    /* No Type Ptr response */
    if (strlen((char *)ini_config->mdns_resp_type_ptr) <= 0)
        return TRUE;

    /* Wrong response is assigned, just ignore this response */
    if (!wlan_hdd_mdns_init_response(resptype_ptr,
                    ini_config->mdns_resp_type_ptr, '.'))
        return TRUE;

    /*
    * For data compression
    * Check if any strings are matched with Type A response
    */
    num_matched  = 0;
    num_matched1 = 0;
    if (resptype_a && (resptype_a->num_entries > 0)) {
        num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr,
                                resptype_a);
    }
    if (resptype_txt && (resptype_txt->num_entries > 0)) {
        num_matched1 = wlan_hdd_mdns_find_entries_from_end(
                        resptype_ptr, resptype_txt);
    }
    if ((num_matched != num_matched1) ||
        ((num_matched > 0) && (num_matched1 > 0))) {
        if (num_matched >= num_matched1) {
            if (!wlan_hdd_mdns_compress_data(resp_info,
                resptype_ptr, resptype_a, num_matched)) {
                hddLog(LOGE, FL("Fail to compress mDNS "
                    "response (%d)!"), MDNS_TYPE_PTR);
                return FALSE;
            }
        } else {
            /* num_matched is less than num_matched1 */
            if (!wlan_hdd_mdns_compress_data(resp_info,
                resptype_ptr, resptype_txt, num_matched1)) {
                hddLog(LOGE, FL("Fail to compress mDNS "
                    "response (%d)!"), MDNS_TYPE_PTR);
                return FALSE;
            }
        }
    } else {
        /*
        * Both num_matched and num_matched1 are zero.
        * no TypeA & TypeTxt
        */
        if (!wlan_hdd_mdns_process_response_dname(resptype_ptr,
                            resp_info)) {
            hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
                MDNS_TYPE_PTR);
            return FALSE;
        }
    }

    /* Process response Type, Class, TTL */
    if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_PTR, resp_info)) {
        hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
            MDNS_TYPE_PTR);
        return FALSE;
    }

    /*
    * Process response RDLength, RData (Ptr domain name)
    * Save the offset of RData length
    */
    offset_data_len = resp_info->resp_len;
    resp_info->resp_len += sizeof(uint16_t);

    if (!wlan_hdd_mdns_pack_response_type_ptr_dname(ini_config, resp_info,
                        resptype_ptr_dn, resptype_ptr,
                        resptype_txt, resptype_a)) {
        return FALSE;
    }
    /* Set the RData length */
    len = offset_data_len + sizeof(uint16_t);
    if ((resptype_ptr_dn->num_entries > 0) &&
        (resp_info->resp_len > len)) {
        value = resp_info->resp_len - len;
        val_u8 = (value & 0xff00) >> 8;
        resp_info->resp_data[offset_data_len] = val_u8;
        val_u8 = value & 0xff;
        resp_info->resp_data[offset_data_len+1] = val_u8;
    } else {
        hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
            MDNS_TYPE_PTR);
        return FALSE;
    }

    EXIT();
    return TRUE;
}

/**
 * wlan_hdd_mdns_pack_response_type_srv_target()- Pack Type Service Target
 * @ini_config: Pointer to the struct hdd_config_t
 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
 *                      target
 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
 *                     domain name
 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
 *
 * The Type service target is one of the data field in the Type SRV response.
 * Also, it will find the matched QName from the existing resptype_srv,
 * resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and then compress
 * the data.
 *
 * Return: Return boolean. TRUE for success, FALSE for fail.
 */
static bool
wlan_hdd_mdns_pack_response_type_srv_target(hdd_config_t *ini_config,
                sir_mdns_resp_info resp_info,
                struct hdd_mdns_resp_info *resptype_srv_tgt,
                struct hdd_mdns_resp_info *resptype_srv,
                struct hdd_mdns_resp_info *resptype_ptr,
                struct hdd_mdns_resp_info *resptype_ptr_dn,
                struct hdd_mdns_resp_info *resptype_txt,
                struct hdd_mdns_resp_info *resptype_a)
{
    uint8_t  num_matched, num, size;
    struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
    struct hdd_mdns_resp_info *resp;

    if ((ini_config == NULL) || (resp_info == NULL) ||
        (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
        hddLog(LOGE, FL("ini_config or response info is NULL!"));
        return FALSE;
    }

    /* No Type Srv Target response */
    if (strlen((char *)ini_config->mdns_resp_type_srv_target) <= 0)
        return TRUE;

    /* Wrong response is assigned, just ignore this response */
    if (!wlan_hdd_mdns_init_response(resptype_srv_tgt,
                ini_config->mdns_resp_type_srv_target, '.'))
        return TRUE;

    /*
    * For data compression
    * Check if any strings are matched with previous response.
    */
    num = 0;
    size = (MAX_MDNS_RESP_TYPE-1);
    size *= sizeof(struct hdd_mdns_resp_matched);
    vos_mem_zero(matchedlist, size);
    num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv_tgt,
                            resptype_srv);
    if (num_matched > 0) {
        matchedlist[num].num_matched = num_matched;
        matchedlist[num].type = MDNS_TYPE_SRV;
        num++;
    }
    if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
        if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
            num_matched = wlan_hdd_mdns_find_entries_from_end(
                    resptype_srv_tgt, resptype_ptr_dn);
            if (num_matched > 0) {
                matchedlist[num].num_matched = num_matched;
                matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
                num++;
            }
        }
        num_matched = wlan_hdd_mdns_find_entries_from_end(
                    resptype_srv_tgt, resptype_ptr);
        if (num_matched > 0) {
            matchedlist[num].num_matched = num_matched;
            matchedlist[num].type = MDNS_TYPE_PTR;
            num++;
        }
    }
    if (resptype_txt && (resptype_txt->num_entries > 0)) {
        num_matched = wlan_hdd_mdns_find_entries_from_end(
                    resptype_srv_tgt, resptype_txt);
        if (num_matched > 0) {
            matchedlist[num].num_matched = num_matched;
            matchedlist[num].type = MDNS_TYPE_TXT;
            num++;
        }
    }
    if (resptype_a && (resptype_a->num_entries > 0)) {
        num_matched = wlan_hdd_mdns_find_entries_from_end(
                    resptype_srv_tgt, resptype_a);
        if (num_matched > 0) {
            matchedlist[num].num_matched = num_matched;
            matchedlist[num].type = MDNS_TYPE_A;
            num++;
        }
    }
    if (num > 0) {
        if (num > 1)
            wlan_hdd_mdns_find_max(matchedlist, num);
        resp = NULL;
        switch (matchedlist[num-1].type) {
        case MDNS_TYPE_A:
            resp = resptype_a;
            break;
        case MDNS_TYPE_TXT:
            resp = resptype_txt;
            break;
        case MDNS_TYPE_PTR:
            resp = resptype_ptr;
            break;
        case MDNS_TYPE_PTR_DNAME:
            resp = resptype_ptr_dn;
            break;
        case MDNS_TYPE_SRV:
            resp = resptype_srv;
            break;
        default:
            hddLog(LOGE, FL("Fail to compress mDNS response "
                    "(%d)!"), MDNS_TYPE_SRV_TARGET);
            return FALSE;
        }
        num_matched = matchedlist[num-1].num_matched;
        if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv_tgt,
                        resp, num_matched)) {
            hddLog(LOGE, FL("Fail to compress mDNS response "
                    "(%d)!"), MDNS_TYPE_SRV_TARGET);
            return FALSE;
        }
    } else {
        /* num = 0 -> no matched string */
        if (!wlan_hdd_mdns_process_response_dname(resptype_srv_tgt,
                            resp_info)) {
            hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
                    MDNS_TYPE_SRV_TARGET);
            return FALSE;
        }
    }

    return TRUE;
}

/**
 * wlan_hdd_mdns_pack_response_type_srv()- Pack Type Service response
 * @ini_config: Pointer to the struct hdd_config_t
 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
 *                      target
 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
 *                     domain name
 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
 *
 * The Type SRV (Service) response include QName, response type, class, TTL
 * and four kinds of data fields. Also, it will find the matched QName from
 * the existing resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and
 * then compress the data.
 *
 * Return: Return boolean. TRUE for success, FALSE for fail.
 */
static bool
wlan_hdd_mdns_pack_response_type_srv(hdd_config_t *ini_config,
                 sir_mdns_resp_info resp_info,
                 struct hdd_mdns_resp_info *resptype_srv,
                 struct hdd_mdns_resp_info *resptype_srv_tgt,
                 struct hdd_mdns_resp_info *resptype_ptr,
                 struct hdd_mdns_resp_info *resptype_ptr_dn,
                 struct hdd_mdns_resp_info *resptype_txt,
                 struct hdd_mdns_resp_info *resptype_a)
{
    uint8_t num_matched, num, size;
    uint16_t value;
    uint8_t val_u8;
    uint32_t offset_data_len, len;
    struct hdd_mdns_resp_info *resp;
    struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];

    ENTER();

    if ((ini_config == NULL) || (resp_info == NULL) ||
        (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
        hddLog(LOGE, FL("ini_config or response info is NULL!"));
        return FALSE;
    }

    /* No Type Srv response */
    if (strlen((char *)ini_config->mdns_resp_type_srv) <= 0)
        return TRUE;

    /* Wrong response is assigned, just ignore this response */
    if (!wlan_hdd_mdns_init_response(resptype_srv,
                    ini_config->mdns_resp_type_srv, '.'))
        return TRUE;

    /*
    * For data compression
    * Check if any strings are matched with Type A response
    */
    num = 0;
    size = (MAX_MDNS_RESP_TYPE-1);
    size *= sizeof(struct hdd_mdns_resp_matched);
    vos_mem_zero(matchedlist, size);
    if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
        if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
            num_matched = wlan_hdd_mdns_find_entries_from_end(
                            resptype_srv,
                            resptype_ptr_dn);
            if (num_matched > 0) {
                matchedlist[num].num_matched = num_matched;
                matchedlist[num].type =    MDNS_TYPE_PTR_DNAME;
                num++;
            }
        }
        num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
                                resptype_ptr);
        if (num_matched > 0) {
            matchedlist[num].num_matched = num_matched;
            matchedlist[num].type = MDNS_TYPE_PTR;
            num++;
        }
    }
    if (resptype_txt && (resptype_txt->num_entries > 0)) {
        num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
                                resptype_txt);
        if (num_matched > 0) {
            matchedlist[num].num_matched =num_matched;
            matchedlist[num].type = MDNS_TYPE_TXT;
            num++;
        }
    }
    if (resptype_a && (resptype_a->num_entries > 0)) {
        num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
                                resptype_a);
        if (num_matched > 0) {
            matchedlist[num].num_matched = num_matched;
            matchedlist[num].type = MDNS_TYPE_A;
            num++;
        }
    }
    if (num > 0) {
        if (num > 1)
            wlan_hdd_mdns_find_max(matchedlist, num);
        resp = NULL;
        switch (matchedlist[num-1].type) {
        case MDNS_TYPE_A:
            resp = resptype_a;
            break;
        case MDNS_TYPE_TXT:
            resp = resptype_txt;
            break;
        case MDNS_TYPE_PTR:
            resp = resptype_ptr;
            break;
        case MDNS_TYPE_PTR_DNAME:
            resp = resptype_ptr_dn;
            break;
        default:
            hddLog(LOGE, FL("Fail to compress mDNS response "
                    "(%d)!"), MDNS_TYPE_SRV);
            return FALSE;
        }
        num_matched = matchedlist[num-1].num_matched;
        if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv,
                        resp, num_matched)) {
            hddLog(LOGE, FL("Fail to compress mDNS response "
                    "(%d)!"), MDNS_TYPE_SRV);
            return FALSE;
        }
    } else {
        /* num = 0 -> no matched string */
        if (!wlan_hdd_mdns_process_response_dname(resptype_srv,
                            resp_info)) {
            hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
                    MDNS_TYPE_SRV);
            return FALSE;
        }
    }

    /* Process response Type, Class, TTL */
    if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_SRV, resp_info)) {
        hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
                    MDNS_TYPE_SRV);
        return FALSE;
    }

    /*
    * Process response RDLength, RData (Srv target name)
    * Save the offset of RData length
    */
    offset_data_len = resp_info->resp_len;
    resp_info->resp_len += sizeof(uint16_t);

    len = resp_info->resp_len + (3 * sizeof(uint16_t));
    if (len >= MAX_MDNS_RESP_LEN) {
        hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
        return FALSE;
    }

    /* set Srv Priority */
    value = ini_config->mdns_resp_type_srv_priority;
    wlan_hdd_mdns_format_response_u16(value, resp_info);
    /* set Srv Weight */
    value = ini_config->mdns_resp_type_srv_weight;
    wlan_hdd_mdns_format_response_u16(value, resp_info);
    /* set Srv Port */
    value = ini_config->mdns_resp_type_srv_port;
    wlan_hdd_mdns_format_response_u16(value, resp_info);

    if (!wlan_hdd_mdns_pack_response_type_srv_target(ini_config, resp_info,
                        resptype_srv_tgt, resptype_srv,
                        resptype_ptr, resptype_ptr_dn,
                        resptype_txt, resptype_a)) {
        return FALSE;
    }
    /* Set the RData length */
    len = offset_data_len + sizeof(uint16_t);
    if ((resptype_srv_tgt->num_entries > 0) &&
        (resp_info->resp_len > len)) {
        value = resp_info->resp_len - len;
        val_u8 = (value & 0xff00) >> 8;
        resp_info->resp_data[offset_data_len] = val_u8;
        val_u8 = value & 0xff;
        resp_info->resp_data[offset_data_len+1] = val_u8;
    } else {
        hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
            MDNS_TYPE_SRV);
        return FALSE;
    }

    EXIT();
    return TRUE;
}

/**
 * wlan_hdd_mdns_free_mem() - Free the allocated memory
 * @response: Pointer to the struct hdd_mdns_resp_info
 *
 * Return: None
 */
static void wlan_hdd_mdns_free_mem(struct hdd_mdns_resp_info *response)
{
    if (response && response->data)
        vos_mem_free(response->data);
    if (response && response->offset)
        vos_mem_free(response->offset);
}

/**
 * wlan_hdd_mdns_pack_response() - Pack mDNS response
 * @ini_config: Pointer to the struct hdd_config_t
 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
 *
 * This function will pack four types of responses (Type A, Type Txt, Type Ptr
 * and Type Service). Each response contains QName, response type, class, TTL
 * and data fields.
 *
 * Return: Return boolean. TRUE for success, FALSE for fail.
 */
static bool wlan_hdd_mdns_pack_response(hdd_config_t *ini_config,
                    sir_mdns_resp_info resp_info)
{
    struct hdd_mdns_resp_info resptype_a, resptype_txt;
    struct hdd_mdns_resp_info resptype_ptr, resptype_ptr_dn;
    struct hdd_mdns_resp_info resptype_srv, resptype_srv_tgt;
    uint32_t num_res_records = 0;
    bool status = FALSE;

    ENTER();

    wlan_hdd_mdns_reset_response(&resptype_a);
    wlan_hdd_mdns_reset_response(&resptype_txt);
    wlan_hdd_mdns_reset_response(&resptype_ptr);
    wlan_hdd_mdns_reset_response(&resptype_ptr_dn);
    wlan_hdd_mdns_reset_response(&resptype_srv);
    wlan_hdd_mdns_reset_response(&resptype_srv_tgt);

    resp_info->resp_len = 0;

    /* Process Type A response */
    if (!wlan_hdd_mdns_pack_response_type_a(ini_config, resp_info,
                        &resptype_a))
        goto err_resptype_a;

    if ((resptype_a.num_entries > 0) &&
        (strlen((char *)&resptype_a.data[0]) > 0))
        num_res_records++;

    /* Process Type TXT response */
    if (!wlan_hdd_mdns_pack_response_type_txt(ini_config, resp_info,
                          &resptype_txt, &resptype_a))
        goto err_resptype_txt;

    if ((resptype_txt.num_entries > 0) &&
        (strlen((char *)&resptype_txt.data[0]) > 0))
        num_res_records++;

    /* Process Type PTR response */
    if (!wlan_hdd_mdns_pack_response_type_ptr(ini_config, resp_info,
                      &resptype_ptr, &resptype_ptr_dn,
                      &resptype_txt, &resptype_a))
        goto err_resptype_ptr;

    if ((resptype_ptr.num_entries > 0) &&
        (strlen((char *)&resptype_ptr.data[0]) > 0))
        num_res_records++;

    /* Process Type SRV response */
    if (!wlan_hdd_mdns_pack_response_type_srv(ini_config, resp_info,
                      &resptype_srv, &resptype_srv_tgt,
                      &resptype_ptr, &resptype_ptr_dn,
                      &resptype_txt, &resptype_a))
        goto err_resptype_srv;

    if ((resptype_srv.num_entries > 0) &&
        (strlen((char *)&resptype_srv.data[0]) > 0))
        num_res_records++;

    resp_info->resourceRecord_count = num_res_records;
    hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
           "%s: Pack mDNS response data successfully!", __func__);
    status = TRUE;

err_resptype_srv:
    wlan_hdd_mdns_free_mem(&resptype_srv);
    wlan_hdd_mdns_free_mem(&resptype_srv_tgt);

err_resptype_ptr:
    wlan_hdd_mdns_free_mem(&resptype_ptr);
    wlan_hdd_mdns_free_mem(&resptype_ptr_dn);

err_resptype_txt:
    wlan_hdd_mdns_free_mem(&resptype_txt);

err_resptype_a:
    wlan_hdd_mdns_free_mem(&resptype_a);

    EXIT();
    return status;
}

/**
 * wlan_hdd_set_mdns_offload() - Enable mDNS offload
 * @hostapd_adapter: Pointer to the struct hdd_adapter_t
 *
 * This function will set FQDN/unique FQDN (full qualified domain name)
 * and the mDNS response. Then send them to SME.
 *
 * Return: Return boolean. TRUE for success, FALSE for fail.
 */
bool wlan_hdd_set_mdns_offload(hdd_adapter_t *hostapd_adapter)
{
    hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
    sir_mdns_offload_info mdns_offload_info;
    sir_mdns_fqdn_info mdns_fqdn_info;
    sir_mdns_resp_info mdns_resp_info;
    uint32_t fqdn_len, ufqdn_len;

    ENTER();

    /* 1. Prepare the MDNS fqdn request to send to SME */
    fqdn_len = strlen(hdd_ctx->cfg_ini->mdns_fqdn);
    ufqdn_len = strlen(hdd_ctx->cfg_ini->mdns_uniquefqdn);
    if ((fqdn_len == 0) && (ufqdn_len == 0)) {
        hddLog(LOGE, FL("No mDNS FQDN or UFQDN is assigned fqdn_len %d,"
                        "ufqdn_len %d!"), fqdn_len, ufqdn_len);
        return FALSE;
    }

    mdns_fqdn_info = vos_mem_malloc(sizeof(*mdns_fqdn_info));
    if (NULL == mdns_fqdn_info) {
        hddLog(LOGE, FL("could not allocate tSirMDNSFqdnInfo!"));
        return FALSE;
    }
    /* MDNS fqdn request */
    if (fqdn_len > 0) {
           vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
           mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
           mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_GENERAL;
           mdns_fqdn_info->fqdn_len = fqdn_len;
           mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
           mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
           vos_mem_copy(mdns_fqdn_info->fqdn_data,
                hdd_ctx->cfg_ini->mdns_fqdn,
                mdns_fqdn_info->fqdn_len);

        if (eHAL_STATUS_SUCCESS !=
            sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
            hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
            vos_mem_free(mdns_fqdn_info);
            return FALSE;
        }
    }
    /* MDNS unique fqdn request */
    if (ufqdn_len > 0) {
           vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
           mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
           mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_UNIQUE;
           mdns_fqdn_info->fqdn_len = ufqdn_len;
           mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
           mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
           vos_mem_copy(mdns_fqdn_info->fqdn_data,
                hdd_ctx->cfg_ini->mdns_uniquefqdn,
                mdns_fqdn_info->fqdn_len);
        if (eHAL_STATUS_SUCCESS !=
            sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
            hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
            vos_mem_free(mdns_fqdn_info);
            return FALSE;
        }
    }
    vos_mem_free(mdns_fqdn_info);

    /* 2. Prepare the MDNS response request to send to SME */
    mdns_resp_info = vos_mem_malloc(sizeof(*mdns_resp_info));
    if (NULL == mdns_resp_info) {
        hddLog(LOGE, FL("could not allocate tSirMDNSResponseInfo!"));
        return FALSE;
    }

    vos_mem_zero(mdns_resp_info, sizeof(*mdns_resp_info));
    mdns_resp_info->bss_idx = hostapd_adapter->sessionId;
    mdns_resp_info->mdns_resp_callback = hdd_mdns_resp_offload_done;
    mdns_resp_info->mdns_resp_cb_context = hostapd_adapter;
    if (!wlan_hdd_mdns_pack_response(hdd_ctx->cfg_ini, mdns_resp_info)) {
        hddLog(LOGE, FL("wlan_hdd_pack_mdns_response fail!"));
        vos_mem_free(mdns_resp_info);
        return FALSE;
    }
    if (eHAL_STATUS_SUCCESS !=
        sme_set_mdns_resp(hdd_ctx->hHal, mdns_resp_info)) {
        hddLog(LOGE, FL("sme_set_mdns_resp fail!"));
        vos_mem_free(mdns_resp_info);
        return FALSE;
    }
    vos_mem_free(mdns_resp_info);

    /* 3. Prepare the MDNS Enable request to send to SME */
    mdns_offload_info = vos_mem_malloc(sizeof(*mdns_offload_info));
    if (NULL == mdns_offload_info) {
        hddLog(LOGE, FL("could not allocate tSirMDNSOffloadInfo!"));
        return FALSE;
    }

    vos_mem_zero(mdns_offload_info, sizeof(*mdns_offload_info));

    mdns_offload_info->bss_idx = hostapd_adapter->sessionId;
    mdns_offload_info->enable = hdd_ctx->cfg_ini->enable_mdns_offload;
    mdns_offload_info->mdns_enable_callback = hdd_mdns_enable_offload_done;
    mdns_offload_info->mdns_enable_cb_context = hostapd_adapter;
    if (eHAL_STATUS_SUCCESS !=
        sme_set_mdns_offload(hdd_ctx->hHal, mdns_offload_info)) {
        hddLog(LOGE, FL("sme_set_mdns_offload fail!"));
        vos_mem_free(mdns_offload_info);
        return FALSE;
    }

    vos_mem_free(mdns_offload_info);
    hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
           "%s: enable mDNS offload successfully!", __func__);
    return TRUE;
}


#endif /* MDNS_OFFLOAD */

/**
 * wlan_hdd_start_sap() - This function starts bss of SAP.
 * @ap_adapter: SAP adapter
 *
 * This function will process the starting of sap adapter.
 *
 * Return: void.
 */
void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter)
{
	hdd_ap_ctx_t *hdd_ap_ctx;
	hdd_hostapd_state_t *hostapd_state;
	VOS_STATUS vos_status;
	hdd_context_t *hdd_ctx;
	tsap_Config_t *pConfig;

	if (NULL == ap_adapter) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
		FL("ap_adapter is NULL here"));
		return;
	}

	hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
	hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
	pConfig = &ap_adapter->sessionCtx.ap.sapConfig;

	mutex_lock(&hdd_ctx->sap_lock);
	if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
		goto end;

	if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
		hddLog(LOGE, FL("SAP Not able to set AP IEs"));
		goto end;
	}

	vos_event_reset(&hostapd_state->vosEvent);
	if (WLANSAP_StartBss(hdd_ctx->pvosContext, hdd_hostapd_SAPEventCB,
			&hdd_ap_ctx->sapConfig, (v_PVOID_t)ap_adapter->dev)
			!= VOS_STATUS_SUCCESS) {
		goto end;
	}

	VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
		FL("Waiting for SAP to start"));
	vos_status = vos_wait_single_event(&hostapd_state->vosEvent, 10000);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			FL("SAP Start failed"));
		goto end;
	}
	VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
		FL("SAP Start Success"));
	set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);

	wlan_hdd_incr_active_session(hdd_ctx, ap_adapter->device_mode);
	hostapd_state->bCommit = TRUE;

end:
	mutex_unlock(&hdd_ctx->sap_lock);
	return;
}

#ifdef WLAN_FEATURE_TSF

/**
 * hdd_tsf_cb() - handle tsf request callback
 *
 * @pcb_cxt: pointer to the hdd_contex
 * @ptsf: pointer to struct stsf
 *
 * Based on the request sent .
 *
 * Return: Describe the execute result of this routine
 */
static int hdd_tsf_cb(void *pcb_ctx, struct stsf *ptsf)
{
    hdd_context_t *hddctx;
    int status;
    hdd_adapter_t* adapter = (hdd_adapter_t*)pcb_ctx;

    if (pcb_ctx == NULL || ptsf == NULL) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("HDD context is not valid"));
        return -EINVAL;
    }

    hddctx = (hdd_context_t *)pcb_ctx;
    status = wlan_hdd_validate_context(hddctx);
    if (0 != status)
        return -EINVAL;

    if (NULL == adapter) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("failed to find adapter"));
        return -EINVAL;
    }

    hddLog(VOS_TRACE_LEVEL_INFO,
           FL("tsf cb handle event, device_mode is %d"),
           adapter->device_mode);

    /* copy the return value to hdd_tsf_ctx in adapter*/
    if (ptsf->tsf_req_status) {

        vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
        adapter->tsf_cap_ctx.tsf_get_state = TSF_NOT_RETURNED_BY_FW;
        adapter->tsf_cap_ctx.tsf_capture_state  = TSF_IDLE;
        vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
        vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);

        hddLog(VOS_TRACE_LEVEL_ERROR, FL("tsf req failure :%d"),
               ptsf->tsf_req_status);
        return ptsf->tsf_req_status;
    }
    /* If this is a get request.Store the tsf values in adapter. */
    if (!ptsf->set_tsf_req) {
        vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
        adapter->tsf_cap_ctx.tsf_low  = ptsf->tsf_low;
        adapter->tsf_cap_ctx.tsf_high = ptsf->tsf_high;
        adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
        adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
        vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);

        hddLog(VOS_TRACE_LEVEL_INFO,
               FL("hdd_get_tsf_cb sta=%u, tsf_low=%u, tsf_high=%u"),
                   adapter->sessionId, ptsf->tsf_low, ptsf->tsf_high);
    }
    else {
        vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
        adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
        adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
        vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
    }
    vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
    vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
    vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);

    /* free allocated mem */
    vos_mem_free(ptsf);

    return 0;
}

/**
 * hdd_capture_tsf() - capture tsf
 *
 * @adapter: pointer to adapter
 * @buf: pointer to upper layer buf
 * @len : the length of buf
 *
 * This function returns tsf value to uplayer.
 *
 * Return: Describe the execute result of this routine
 */
int hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
{
    int ret = 0;
    hdd_station_ctx_t *hdd_sta_ctx;
    hdd_context_t *hdd_ctx;
    tSirCapTsfParams cap_tsf_params;
    VOS_STATUS status;

    if (adapter == NULL || buf == NULL) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("invalid pointer"));
        return -EINVAL;
    }
    if (len != 1)
        return -EINVAL;

    hdd_ctx = WLAN_HDD_GET_CTX(adapter);

    if (wlan_hdd_validate_context(hdd_ctx)) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("invalid hdd ctx"));
        return -EINVAL;
    }
    if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
        adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
        hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
        if (hdd_sta_ctx->conn_info.connState !=
            eConnectionState_Associated) {

            hddLog(VOS_TRACE_LEVEL_INFO,
                   FL("failed to cap tsf, not connect with ap"));
            buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
            return ret;
        }
    }
    if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
         adapter->device_mode == WLAN_HDD_P2P_GO) &&
         !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
         hddLog(VOS_TRACE_LEVEL_INFO,
                FL("Soft AP / P2p GO not beaconing"));
         buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
         return ret;
    }
    if (adapter->tsf_cap_ctx.tsf_capture_state == TSF_CAP_STATE) {
        hddLog(VOS_TRACE_LEVEL_INFO,
               FL("current in capture state, pls reset"));
        buf[0] = TSF_CURRENT_IN_CAP_STATE;
    } else {
        hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
        buf[0] = TSF_RETURN;
        cap_tsf_params.session_id = adapter->sessionId;
        cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
        cap_tsf_params.tsf_rsp_cb_ctx = adapter;

        vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
        adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
        adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
        vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);

        ret = sme_capture_tsf_req(hdd_ctx->hHal, cap_tsf_params);

        if (ret != VOS_STATUS_SUCCESS) {
            hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
            buf[0] = TSF_CAPTURE_FAIL;
            vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
            adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
            vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
            return -EINVAL;
        }
        /* wait till we get a response from fw */
        status = vos_wait_single_event(&adapter->tsf_cap_ctx.
                                       tsf_capture_done_event,
                                       HDD_TSF_CAP_REQ_TIMEOUT);

        if (!VOS_IS_STATUS_SUCCESS(status)) {
             VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                       ("capture tsf vos wait for single_event failed!! %d"),
                       adapter->tsf_cap_ctx.tsf_get_state);

              vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
              adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
              vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);

             return -EINVAL;
        }
    }
    buf[0] = TSF_RETURN;
    hddLog(VOS_TRACE_LEVEL_INFO,
           FL("ioctl return cap tsf cmd, ret = %d"), ret);
    return ret;
}

/**
 * hdd_indicate_tsf() - return tsf to uplayer
 *
 * @adapter: pointer to adapter
 * @buf: pointer to uplayer buf
 * @len : the length of buf
 *
 * This function returns tsf value to uplayer.
 *
 * Return: Describe the execute result of this routine
 */
int hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
{
    int ret = 0;
    hdd_station_ctx_t *hdd_sta_ctx;
    hdd_context_t *hdd_ctx;
    tSirCapTsfParams cap_tsf_params;
    VOS_STATUS status;

    if (adapter == NULL || buf == NULL) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("invalid pointer"));
        return -EINVAL;
    }
    if (len != 3)
        return -EINVAL;

    buf [1] = 0;
    buf [2] = 0;
    hdd_ctx = WLAN_HDD_GET_CTX(adapter);

    if (wlan_hdd_validate_context(hdd_ctx)) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("invalid hdd ctx"));
        return -EINVAL;
    }
    if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
        adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
        hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
        if (hdd_sta_ctx->conn_info.connState !=
            eConnectionState_Associated) {

            hddLog(VOS_TRACE_LEVEL_INFO,
                   FL("failed to cap tsf, not connect with ap"));
            buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
            return ret;
        }
    }
    if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
         adapter->device_mode == WLAN_HDD_P2P_GO) &&
         !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
         hddLog(VOS_TRACE_LEVEL_INFO,
                FL("Soft AP / P2p GO not beaconing"));
         buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
         return ret;
    }

    if (adapter->tsf_cap_ctx.tsf_capture_state != TSF_CAP_STATE ||
        adapter->tsf_cap_ctx.tsf_get_state != TSF_CURRENT_IN_CAP_STATE ) {
        hddLog(VOS_TRACE_LEVEL_INFO,
        FL("Not in capture state,Enter capture state first"));
        buf[0] = TSF_GET_FAIL;
    } else {
        hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
        cap_tsf_params.session_id = adapter->sessionId;
        cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
        cap_tsf_params.tsf_rsp_cb_ctx = adapter;

        ret = sme_get_tsf_req(hdd_ctx->hHal, cap_tsf_params);

        if (ret != VOS_STATUS_SUCCESS) {
            hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
            buf[0] = TSF_CAPTURE_FAIL;
            vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
            adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
            vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
            return -EINVAL;
        }
        /* wait till we get a response from fw */
        status = vos_wait_single_event(&adapter->tsf_cap_ctx.
                                        tsf_capture_done_event,
                                        HDD_TSF_GET_REQ_TIMEOUT);

        if (!VOS_IS_STATUS_SUCCESS(status)) {
             VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                       ("capture tsf vos wait for single_event failed!! %d"),
                       status);

             vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
             adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
             vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
             return status;
        }
        buf[1] = adapter->tsf_cap_ctx.tsf_low;
        buf[2] = adapter->tsf_cap_ctx.tsf_high;

        hddLog(VOS_TRACE_LEVEL_INFO,
               FL("get tsf cmd,status=%u, tsf_low=%u, tsf_high=%u"),
               buf[0], buf[1], buf[2]);
    }
    hddLog(VOS_TRACE_LEVEL_INFO,
           FL("ioctl return cap tsf cmd, ret = %d"), ret);
    return ret;
}

void wlan_hdd_tsf_init(hdd_adapter_t *adapter)
{

    if (adapter == NULL) {
       hddLog(VOS_TRACE_LEVEL_ERROR,
              FL("TSF init on a null adapter!"));
       return;
   }

   adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
   adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
   vos_event_init(&adapter->tsf_cap_ctx.tsf_capture_done_event);
   vos_spin_lock_init(&adapter->tsf_cap_ctx.tsf_lock);
   adapter->tsf_cap_ctx.tsf_high = 0;
   adapter->tsf_cap_ctx.tsf_low = 0;
}

#endif

bool hdd_is_memdump_supported(void)
{
#ifdef WLAN_FEATURE_MEMDUMP
	return true;
#endif
	return false;
}

//Register the module init/exit functions
module_init(hdd_module_init);
module_exit(hdd_module_exit);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Qualcomm Atheros, Inc.");
MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");

static const struct kernel_param_ops con_mode_ops = {
	.set = con_mode_handler,
	.get = param_get_int,
};

static const struct kernel_param_ops fwpath_ops = {
	.set = fwpath_changed_handler,
	.get = param_get_string,
};

module_param_cb(con_mode, &con_mode_ops, &con_mode,
                    S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

module_param_cb(fwpath, &fwpath_ops, &fwpath,
                    S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

module_param(enable_dfs_chan_scan, int,
             S_IRUSR | S_IRGRP | S_IROTH);

module_param(enable_11d, int,
             S_IRUSR | S_IRGRP | S_IROTH);

module_param(country_code, charp,
             S_IRUSR | S_IRGRP | S_IROTH);
