/*
 * 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_hostapd.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.
  06/03/10    js - Added support to hostapd driven deauth/disassoc/mic failure
  ==========================================================================*/
/*--------------------------------------------------------------------------
  Include Files
  ------------------------------------------------------------------------*/

#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/wireless.h>
#include <linux/semaphore.h>
#include <linux/compat.h>
#include <vos_api.h>
#include <vos_sched.h>
#include <linux/etherdevice.h>
#include <wlan_hdd_includes.h>
#include <qc_sap_ioctl.h>
#include <wlan_hdd_hostapd.h>
#include <sapApi.h>
#include <sapInternal.h>
#include <wlan_qct_tl.h>
#include <wlan_hdd_softap_tx_rx.h>
#include <wlan_hdd_main.h>
#include <linux/netdevice.h>
#include <linux/mmc/sdio_func.h>
#include "wlan_nlink_common.h"
#include "wlan_hdd_p2p.h"
#ifdef IPA_OFFLOAD
#include <wlan_hdd_ipa.h>
#endif
#include "cfgApi.h"
#include "wni_cfg.h"
#include "wlan_hdd_misc.h"
#include <vos_utils.h>
#include "vos_cnss.h"
#include "tl_shim.h"

#include "wma.h"
#ifdef WLAN_DEBUG
#include "wma_api.h"
#endif
extern int process_wma_set_command(int sessid, int paramid,
                                   int sval, int vpdev);
#include "wlan_hdd_trace.h"
#include "vos_types.h"
#include "vos_trace.h"
#include "adf_trace.h"
#include "wlan_hdd_cfg.h"
#include <wlan_hdd_wowl.h>
#include "wlan_hdd_tsf.h"
#include "wlan_hdd_oemdata.h"

#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN
#include <vos_utils.h>
#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN

#define    IS_UP(_dev) \
    (((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
#define    IS_UP_AUTO(_ic) \
    (IS_UP((_ic)->ic_dev) && (_ic)->ic_roaming == IEEE80211_ROAMING_AUTO)
#define WE_WLAN_VERSION     1
#define WE_GET_STA_INFO_SIZE 30
/* WEXT limitation: MAX allowed buf len for any *
 * IW_PRIV_TYPE_CHAR is 2Kbytes *
 */
#define WE_SAP_MAX_STA_INFO 0x7FF

#define RC_2_RATE_IDX(_rc)        ((_rc) & 0x7)
#define HT_RC_2_STREAMS(_rc)    ((((_rc) & 0x78) >> 3) + 1)
#define RC_2_RATE_IDX_11AC(_rc)        ((_rc) & 0xf)
#define HT_RC_2_STREAMS_11AC(_rc)    ((((_rc) & 0x30) >> 4) + 1)

#define SAP_24GHZ_CH_COUNT (14)
#define ACS_SCAN_EXPIRY_TIMEOUT_S 4

/* EID byte + length byte + four byte WiFi OUI */
#define DOT11F_EID_HEADER_LEN (6)

/* Data rate 100KBPS based on IE Index */
struct index_data_rate_type {
	uint8_t   beacon_rate_index;
	uint16_t  supported_rate[4];
};

/*
 * 11B, 11G Rate table include Basic rate and Extended rate
 * The IDX field is the rate index
 * The HI field is the rate when RSSI is strong or being ignored
 * (in this case we report actual rate)
 * The MID field is the rate when RSSI is moderate
 * (in this case we cap 11b rates at 5.5 and 11g rates at 24)
 * The LO field is the rate when RSSI is low
 * (in this case we don't report rates, actual current rate used)
 */
static const struct index_data_rate_type supported_data_rate[] = {
	/* IDX     HI  HM  LM LO (RSSI-based index */
	{2,   { 10,  10, 10, 0} },
	{4,   { 20,  20, 10, 0} },
	{11,  { 55,  20, 10, 0} },
	{12,  { 60,  55, 20, 0} },
	{18,  { 90,  55, 20, 0} },
	{22,  {110,  55, 20, 0} },
	{24,  {120,  90, 60, 0} },
	{36,  {180, 120, 60, 0} },
	{44,  {220, 180, 60, 0} },
	{48,  {240, 180, 90, 0} },
	{66,  {330, 180, 90, 0} },
	{72,  {360, 240, 90, 0} },
	{96,  {480, 240, 120, 0} },
	{108, {540, 240, 120, 0} }
};

/* MCS Based rate table */
/* HT MCS parameters with Nss = 1 */
static struct index_data_rate_type supported_mcs_rate_nss1[] = {
	/* MCS  L20   L40   S20  S40 */
	{0,  { 65,  135,  72,  150} },
	{1,  { 130, 270,  144, 300} },
	{2,  { 195, 405,  217, 450} },
	{3,  { 260, 540,  289, 600} },
	{4,  { 390, 810,  433, 900} },
	{5,  { 520, 1080, 578, 1200} },
	{6,  { 585, 1215, 650, 1350} },
	{7,  { 650, 1350, 722, 1500} }
};

/* HT MCS parameters with Nss = 2 */
static struct index_data_rate_type supported_mcs_rate_nss2[] = {
	/* MCS  L20    L40   S20   S40 */
	{0,  {130,  270,  144,  300} },
	{1,  {260,  540,  289,  600} },
	{2,  {390,  810,  433,  900} },
	{3,  {520,  1080, 578,  1200} },
	{4,  {780,  1620, 867,  1800} },
	{5,  {1040, 2160, 1156, 2400} },
	{6,  {1170, 2430, 1300, 2700} },
	{7,  {1300, 2700, 1444, 3000} }
};

#ifdef WLAN_FEATURE_11AC
#define DATA_RATE_11AC_MCS_MASK    0x03

enum data_rate_11ac_max_mcs {
	DATA_RATE_11AC_MAX_MCS_7,
	DATA_RATE_11AC_MAX_MCS_8,
	DATA_RATE_11AC_MAX_MCS_9,
	DATA_RATE_11AC_MAX_MCS_NA
};

struct index_vht_data_rate_type {
	uint8_t   beacon_rate_index;
	uint16_t  supported_VHT80_rate[2];
	uint16_t  supported_VHT40_rate[2];
	uint16_t  supported_VHT20_rate[2];
};

/* MCS Based VHT rate table */
/* MCS parameters with Nss = 1*/
static struct index_vht_data_rate_type supported_vht_mcs_rate_nss1[] = {
	/* MCS  L80    S80     L40   S40    L20   S40*/
	{0,  {293,  325},  {135,  150},  {65,   72} },
	{1,  {585,  650},  {270,  300},  {130,  144} },
	{2,  {878,  975},  {405,  450},  {195,  217} },
	{3,  {1170, 1300}, {540,  600},  {260,  289} },
	{4,  {1755, 1950}, {810,  900},  {390,  433} },
	{5,  {2340, 2600}, {1080, 1200}, {520,  578} },
	{6,  {2633, 2925}, {1215, 1350}, {585,  650} },
	{7,  {2925, 3250}, {1350, 1500}, {650,  722} },
	{8,  {3510, 3900}, {1620, 1800}, {780,  867} },
	{9,  {3900, 4333}, {1800, 2000}, {780,  867} }
};

/*MCS parameters with Nss = 2*/
static struct index_vht_data_rate_type supported_vht_mcs_rate_nss2[] = {
	/* MCS  L80    S80     L40   S40    L20   S40*/
	{0,  {585,  650},  {270,  300},  {130,  144} },
	{1,  {1170, 1300}, {540,  600},  {260,  289} },
	{2,  {1755, 1950}, {810,  900},  {390,  433} },
	{3,  {2340, 2600}, {1080, 1200}, {520,  578} },
	{4,  {3510, 3900}, {1620, 1800}, {780,  867} },
	{5,  {4680, 5200}, {2160, 2400}, {1040, 1156} },
	{6,  {5265, 5850}, {2430, 2700}, {1170, 1300} },
	{7,  {5850, 6500}, {2700, 3000}, {1300, 1444} },
	{8,  {7020, 7800}, {3240, 3600}, {1560, 1733} },
	{9,  {7800, 8667}, {3600, 4000}, {1560, 1733} }
};
#endif /* WLAN_FEATURE_11AC */

/*---------------------------------------------------------------------------
 *   Function definitions
 *-------------------------------------------------------------------------*/

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

  \brief hdd_hostapd_channel_wakelock_init

  \param  - Pointer to HDD context

  \return - None

  --------------------------------------------------------------------------*/
void hdd_hostapd_channel_wakelock_init(hdd_context_t *pHddCtx)
{
    /* Initialize the wakelock */
    vos_wake_lock_init(&pHddCtx->sap_dfs_wakelock, "sap_dfs_wakelock");
    atomic_set(&pHddCtx->sap_dfs_ref_cnt, 0);
}

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

  \brief hdd_hostapd_channel_allow_suspend - Allow suspend in a channel.

            Called when,
                1. BSS stopped
                2. Channel switch

  \param  - pAdapter, channel

  \return - None

  --------------------------------------------------------------------------*/
void hdd_hostapd_channel_allow_suspend(hdd_adapter_t *pAdapter,
        u_int8_t channel)
{

    hdd_context_t *pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx);
    hdd_hostapd_state_t *pHostapdState =
        WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);

    hddLog(LOG1, FL("bssState: %d, channel: %d, dfs_ref_cnt: %d"),
            pHostapdState->bssState, channel,
            atomic_read(&pHddCtx->sap_dfs_ref_cnt));

    /* Return if BSS is already stopped */
    if (pHostapdState->bssState == BSS_STOP)
        return;

    /* Release wakelock when no more DFS channels are used */
    if (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channel)) {
        if (atomic_dec_and_test(&pHddCtx->sap_dfs_ref_cnt)) {
            hddLog(LOGE, FL("DFS: allowing suspend (chan %d)"), channel);
            vos_wake_lock_release(&pHddCtx->sap_dfs_wakelock,
                                  WIFI_POWER_EVENT_WAKELOCK_DFS);
            vos_runtime_pm_allow_suspend(pHddCtx->runtime_context.dfs);
        }
    }
}

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

  \brief hdd_hostapd_channel_prevent_suspend - Prevent suspend in a channel.

            Called when,
                1. BSS started
                2. Channel switch

  \param  - pAdapter, channel

  \return - None

  --------------------------------------------------------------------------*/
void hdd_hostapd_channel_prevent_suspend(hdd_adapter_t *pAdapter,
        u_int8_t channel)
{
    hdd_context_t *pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx);
    hdd_hostapd_state_t *pHostapdState =
        WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);

    hddLog(LOG1, FL("bssState: %d, channel: %d, dfs_ref_cnt: %d"),
            pHostapdState->bssState, channel,
            atomic_read(&pHddCtx->sap_dfs_ref_cnt));

    /* Return if BSS is already started && wakelock is acquired */
    if ((pHostapdState->bssState == BSS_START) &&
            (atomic_read(&pHddCtx->sap_dfs_ref_cnt) >= 1))
        return;

    /* Acquire wakelock if we have at least one DFS channel in use */
    if (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channel)) {
        if (atomic_inc_return(&pHddCtx->sap_dfs_ref_cnt) == 1) {
            hddLog(LOGE, FL("DFS: preventing suspend (chan %d)"), channel);
            vos_runtime_pm_prevent_suspend(pHddCtx->runtime_context.dfs);
            vos_wake_lock_acquire(&pHddCtx->sap_dfs_wakelock,
                                  WIFI_POWER_EVENT_WAKELOCK_DFS);
        }
    }
}

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

  \brief hdd_hostapd_channel_wakelock_deinit

  \param  - Pointer to HDD context

  \return - None

  --------------------------------------------------------------------------*/
void hdd_hostapd_channel_wakelock_deinit(hdd_context_t *pHddCtx)
{
    if (atomic_read(&pHddCtx->sap_dfs_ref_cnt)) {
        /* Release wakelock */
        vos_wake_lock_release(&pHddCtx->sap_dfs_wakelock,
                              WIFI_POWER_EVENT_WAKELOCK_DRIVER_EXIT);
        /* Reset the reference count */
        atomic_set(&pHddCtx->sap_dfs_ref_cnt, 0);
        hddLog(LOGE, FL("DFS: allowing suspend"));
    }

    /* Destroy lock */
    vos_wake_lock_destroy(&pHddCtx->sap_dfs_wakelock);
}

#ifdef FEATURE_WLAN_SUB_20_MHZ
/**
  * hdd_hostapd_sub20_channelwidth_can_switch() - check
  *	 channel width switch to 5/10M condition
  * @adapter: pointer to HDD context
  * @sub20_channel_width: 5MHz/10MHz channel width
  *
  * Return:  true or false
  */
bool hdd_hostapd_sub20_channelwidth_can_switch(
	hdd_adapter_t *adapter, uint32_t *sub20_channel_width)
{
	int i;
	int sta_count = 0;
	uint8_t sap_s20_caps;
	uint8_t sap_s20_config;
	uint8_t sta_s20_caps = SUB20_MODE_NONE;
	tHalHandle hal_ptr = WLAN_HDD_GET_HAL_CTX(adapter);
	tSmeConfigParams *sme_config;
	hdd_station_info_t *sta;
	hdd_ap_ctx_t *ap = WLAN_HDD_GET_AP_CTX_PTR(adapter);

	sme_config = vos_mem_malloc(sizeof(*sme_config));
	if (!sme_config) {
		hddLog(LOGE, FL("mem alloc failed for sme_config"));
		return false;
	}
	vos_mem_zero(sme_config, sizeof(*sme_config));

	sme_GetConfigParam(hal_ptr, sme_config);
	sap_s20_caps = sme_config->sub20_dynamic_channelwidth;
	sap_s20_config = sme_config->sub20_config_info;
	vos_mem_free(sme_config);
	if (sap_s20_caps == SUB20_MODE_NONE ||
	    sap_s20_config == CFG_SUB_20_CHANNEL_WIDTH_MANUAL) {
		hddLog(LOGE, FL("sub20 not switch"));
		return false;
	}

	spin_lock_bh(&adapter->staInfo_lock);
	for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
		sta = &adapter->aStaInfo[i];
		if (sta->isUsed && (ap->uBCStaId != i)) {
			sta_count++;
			sta_s20_caps |=
				sta->sub20_dynamic_channelwidth;
		}
	}
	spin_unlock_bh(&adapter->staInfo_lock);

	if (sta_count != 1) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       "%d STAs connected with sub20 Channelwidth %d",
		       sta_count, sta_s20_caps);
		return false;
	}

	*sub20_channel_width = sta_s20_caps & sap_s20_caps;

	if (*sub20_channel_width == (SUB20_MODE_5MHZ | SUB20_MODE_10MHZ))
		*sub20_channel_width = SUB20_MODE_10MHZ;

	if (*sub20_channel_width != 0)
		return true;
	else
		return false;
}

/**
  * hdd_hostapd_sub20_channelwidth_can_restore() - check
  *	 channel width switch to normal condition
  * @adapter: pointer to HDD context
  *
  * Return:  true or false
  */
bool hdd_hostapd_sub20_channelwidth_can_restore(
	hdd_adapter_t *adapter)
{
	int i;
	int sta_count = 0;
	uint8_t sap_s20_caps;
	uint8_t sta_s20_caps = SUB20_MODE_NONE;
	tHalHandle hal_ptr = WLAN_HDD_GET_HAL_CTX(adapter);
	tSmeConfigParams *sme_config;
	hdd_station_info_t *sta;
	hdd_ap_ctx_t *ap = WLAN_HDD_GET_AP_CTX_PTR(adapter);

	sme_config = vos_mem_malloc(sizeof(*sme_config));
	if (!sme_config) {
		hddLog(LOGE, FL("mem alloc failed for sme_config"));
		return false;
	}
	vos_mem_zero(sme_config, sizeof(*sme_config));
	sme_GetConfigParam(hal_ptr, sme_config);

	sap_s20_caps = sme_config->sub20_dynamic_channelwidth;
	vos_mem_free(sme_config);
	if (sap_s20_caps == SUB20_MODE_NONE) {
		hddLog(LOGE, FL("sub20 none"));
		return false;
	}
	spin_lock_bh(&adapter->staInfo_lock);
	for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
		sta = &adapter->aStaInfo[i];
		if (sta->isUsed && (ap->uBCStaId != i)) {
			sta_count++;
			sta_s20_caps |=
				sta->sub20_dynamic_channelwidth;
		}
	}
	spin_unlock_bh(&adapter->staInfo_lock);

	if (sta_count != 0) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       "%d STAs connected with sub20 Channelwidth %d",
		       sta_count, sta_s20_caps);
		return false;
	} else {
		return true;
	}
}

/**
  * hdd_sub20_channelwidth_can_set() - check
  * channel width manual switch to 5/10M condition
  * @adapter: pointer to HDD context
  * @sub20_channel_width: new channel width
  *
  * Return:  true or false
  */
bool hdd_sub20_channelwidth_can_set(
	hdd_adapter_t *adapter, uint32_t sub20_channel_width)
{
	int i;
	uint32_t sta_count = 0;
	uint8_t sap_s20_config;
	uint8_t sta_s20_caps = SUB20_MODE_10MHZ|SUB20_MODE_5MHZ;
	tHalHandle hal_ptr;
	tSmeConfigParams *sme_config;
	hdd_station_info_t *sta;
	hdd_ap_ctx_t *ap;
	bool channel_support_sub20 = true;
	enum phy_ch_width phy_sub20_channel_width = CH_WIDTH_INVALID;
	hdd_station_ctx_t *hddstactx;

	if (adapter == NULL) {
		hddLog(LOGE, FL("adapter NULL"));
		return false;
	}
	hal_ptr = WLAN_HDD_GET_HAL_CTX(adapter);
	ap = WLAN_HDD_GET_AP_CTX_PTR(adapter);

	sme_config = vos_mem_malloc(sizeof(*sme_config));
	if (!sme_config) {
		hddLog(LOGE, FL("mem alloc failed for sme_config"));
		return false;
	}
	vos_mem_zero(sme_config, sizeof(*sme_config));

	sme_GetConfigParam(hal_ptr, sme_config);
	sap_s20_config = sme_config->sub20_config_info;
	vos_mem_free(sme_config);
	sme_config = NULL;
	if (sap_s20_config != CFG_SUB_20_CHANNEL_WIDTH_MANUAL) {
		hddLog(LOGE, FL("ini unsupport manual set sub20"));
		return false;
	}

	switch (sub20_channel_width) {
	case SUB20_MODE_5MHZ:
		phy_sub20_channel_width = CH_WIDTH_5MHZ;
		break;
	case SUB20_MODE_10MHZ:
		phy_sub20_channel_width = CH_WIDTH_10MHZ;
		break;
	case SUB20_MODE_NONE:
		if (WLAN_HDD_SOFTAP == adapter->device_mode)
			return true;
		break;
	default:
		return false;
	}

	if (WLAN_HDD_INFRA_STATION == adapter->device_mode) {
		hddstactx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
		if (hddstactx == NULL) {
			hddLog(LOGE, FL("hdd hddstactx is null"));
			return false;
		}
		if (hdd_connIsConnected(hddstactx)) {
			hddLog(LOGE, FL("sta in Connected state!"));
			return false;
		}
		hddLog(LOGE, FL("sta can set sub20"));
		return true;
	}

	channel_support_sub20 =
	      vos_is_channel_support_sub20(ap->operatingChannel,
					   phy_sub20_channel_width,
					   0);
	if (!channel_support_sub20) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       FL("ch%d width%d unsupport by reg domain"),
		       ap->operatingChannel, phy_sub20_channel_width);
		return false;
	}

	spin_lock_bh(&adapter->staInfo_lock);
	for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
		sta = &adapter->aStaInfo[i];
		if (sta->isUsed && (ap->uBCStaId != i)) {
			sta_count++;
			sta_s20_caps &=
				sta->sub20_dynamic_channelwidth;
		}
	}
	spin_unlock_bh(&adapter->staInfo_lock);
	if (sta_count >= 1 && !(sta_s20_caps & sub20_channel_width)) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       "%d STAs connected with sub20 Channelwidth %d",
		       sta_count, sta_s20_caps);
		return false;
	}

	return true;
}

#endif

/**
 * __hdd_hostapd_open() - HDD Open function for hostapd interface
 * @dev: pointer to net device
 *
 * This is called in response to ifconfig up
 *
 * Return: 0 on success, error number otherwise
 */
static int __hdd_hostapd_open(struct net_device *dev)
{
   hdd_adapter_t *pAdapter = netdev_priv(dev);

   ENTER();

   MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                    TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST, NO_SESSION, 0));

   if (WLAN_HDD_GET_CTX(pAdapter)->isLoadInProgress ||
        WLAN_HDD_GET_CTX(pAdapter)->isUnloadInProgress)
   {
       hddLog(LOGE, FL("Driver load/unload in progress, ignore adapter open"));
       goto done;
   }

   //Enable all Tx queues
   hddLog(LOG1, FL("Enabling queues"));
   wlan_hdd_netif_queue_control(pAdapter,
        WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
        WLAN_CONTROL_PATH);
done:
   EXIT();
   return 0;
}

/**
 * hdd_hostapd_open() - SSR wrapper for __hdd_hostapd_open
 * @dev: pointer to net device
 *
 * Return: 0 on success, error number otherwise
 */
static int hdd_hostapd_open(struct net_device *dev)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __hdd_hostapd_open(dev);
	vos_ssr_unprotect(__func__);

	return ret;
}

/**
 * __hdd_hostapd_stop() - HDD stop function for hostapd interface
 * @dev: pointer to net_device
 *
 * This is called in response to ifconfig down
 *
 * Return: 0 on success, error number otherwise
 */
static int __hdd_hostapd_stop(struct net_device *dev)
{
   ENTER();

   if (NULL != dev) {
       hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
       //Stop all tx queues
       hddLog(LOG1, FL("Disabling queues"));
       wlan_hdd_netif_queue_control(adapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
            WLAN_CONTROL_PATH);
   }

   EXIT();
   return 0;
}

/**
 * hdd_hostapd_stop() - SSR wrapper for__hdd_hostapd_stop
 * @dev: pointer to net_device
 *
 * This is called in response to ifconfig down
 *
 * Return: 0 on success, error number otherwise
 */
int hdd_hostapd_stop(struct net_device *dev)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __hdd_hostapd_stop(dev);
	vos_ssr_unprotect(__func__);

	return ret;
}

/**
 * __hdd_hostapd_uninit() - HDD uninit function
 * @dev: pointer to net_device
 *
 * This is called during the netdev unregister to uninitialize all data
 * associated with the device
 *
 * Return: 0 on success, error number otherwise
 */
static void __hdd_hostapd_uninit(struct net_device *dev)
{
	hdd_adapter_t *adapter = netdev_priv(dev);
	hdd_context_t *hdd_ctx;

	ENTER();

	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
		hddLog(LOGE, FL("Invalid magic"));
		return;
	}

	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	if (NULL == hdd_ctx) {
		hddLog(LOGE, FL("NULL hdd_ctx"));
		return;
	}

	hdd_deinit_adapter(hdd_ctx, adapter, true);

	/* after uninit our adapter structure will no longer be valid */
	adapter->dev = NULL;
	adapter->magic = 0;

	EXIT();
}

/**
 * hdd_hostapd_uninit() - SSR wrapper for __hdd_hostapd_uninit
 * @dev: pointer to net_device
 *
 * Return: 0 on success, error number otherwise
 */
static void hdd_hostapd_uninit(struct net_device *dev)
{
	vos_ssr_protect(__func__);
	__hdd_hostapd_uninit(dev);
	vos_ssr_unprotect(__func__);
}

/**
 * __hdd_hostapd_change_mtu() - change mtu
 * @dev: pointer to net_device
 * @new_mtu: new mtu
 *
 * Return: 0 on success, error number otherwise
 */
static int __hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
{
    return 0;
}

/**
 * hdd_hostapd_change_mtu() - SSR wrapper for __hdd_hostapd_change_mtu
 * @dev: pointer to net_device
 * @new_mtu: new mtu
 *
 * Return: 0 on success, error number otherwise
 */
static int hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __hdd_hostapd_change_mtu(dev, new_mtu);
	vos_ssr_unprotect(__func__);

	return ret;
}

static int hdd_hostapd_driver_command(hdd_adapter_t *pAdapter,
                                      hdd_priv_data_t *priv_data)
{
   tANI_U8 *command = NULL;
   int ret = 0;

   if (VOS_FTM_MODE == hdd_get_conparam()) {
        hddLog(LOGE, FL("Command not allowed in FTM mode"));
        return -EINVAL;
   }

   /*
    * Note that valid pointers are provided by caller
    */

   ENTER();

   if (priv_data->total_len <= 0 ||
       priv_data->total_len > HOSTAPD_IOCTL_COMMAND_STRLEN_MAX)
   {
      /* below we allocate one more byte for command buffer.
       * To avoid addition overflow total_len should be
       * smaller than INT_MAX. */
      hddLog(VOS_TRACE_LEVEL_ERROR, "%s: integer out of range len %d",
             __func__, priv_data->total_len);
      ret = -EFAULT;
      goto exit;
   }

   /* Allocate +1 for '\0' */
   command = vos_mem_malloc((priv_data->total_len + 1));
   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';

   hddLog(VOS_TRACE_LEVEL_INFO,
          "***HOSTAPD*** : Received %s cmd from Wi-Fi GUI***", command);

   if (strncmp(command, "P2P_SET_NOA", 11) == 0)
   {
      hdd_setP2pNoa(pAdapter->dev, command);
   }
   else if (strncmp(command, "P2P_SET_PS", 10) == 0)
   {
      hdd_setP2pOpps(pAdapter->dev, command);
   }
   else if (strncmp(command, "MIRACAST", 8) == 0)
   {
       hddLog(VOS_TRACE_LEVEL_INFO, "%s: Received MIRACAST command", __func__);
       ret = hdd_drv_cmd_validate(command, 8);
       if (ret)
           goto exit;

       ret = hdd_set_miracast_mode(pAdapter, command);
   }
exit:
   if (command)
   {
      vos_mem_free(command);
   }
   EXIT();
   return ret;
}

#ifdef CONFIG_COMPAT
static int hdd_hostapd_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_hostapd_driver_command(pAdapter, &priv_data);
 exit:
   return ret;
}
#else /* CONFIG_COMPAT */
static int hdd_hostapd_driver_compat_ioctl(hdd_adapter_t *pAdapter,
                                           struct ifreq *ifr)
{
   /* will never be invoked */
   return 0;
}
#endif /* CONFIG_COMPAT */

static int hdd_hostapd_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_hostapd_driver_command(pAdapter, &priv_data);
   }
   return ret;
}

/**
 * __hdd_hostapd_ioctl() - hostapd ioctl
 * @dev: pointer to net_device
 * @ifr: pointer to ifreq structure
 * @cmd: command
 *
 * Return; 0 on success, error number otherwise
 */
static int __hdd_hostapd_ioctl(struct net_device *dev,
				struct ifreq *ifr, int cmd)
{
   hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
   hdd_context_t *pHddCtx;
   int ret;

   ENTER();

   if (dev != pAdapter->dev) {
      hddLog(VOS_TRACE_LEVEL_ERROR,
             "%s: HDD adapter/dev inconsistency", __func__);
      ret = -ENODEV;
      goto exit;
   }

   if ((!ifr) || (!ifr->ifr_data))
   {
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                FL("ifr or ifr->ifr_data is NULL"));
      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 (LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)) && defined(CONFIG_X86_64)
      if (in_compat_syscall())
#else
      if (is_compat_task())
#endif
         ret = hdd_hostapd_driver_compat_ioctl(pAdapter, ifr);
      else
         ret = hdd_hostapd_driver_ioctl(pAdapter, ifr);
      break;
   default:
      hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
             __func__, cmd);
      ret = -EINVAL;
      break;
   }
 exit:
   EXIT();
   return ret;
}

/**
 * hdd_hostapd_ioctl() - SSR wrapper for __hdd_hostapd_ioctl
 * @dev: pointer to net_device
 * @ifr: pointer to ifreq structure
 * @cmd: command
 *
 * Return; 0 on success, error number otherwise
 */
static int hdd_hostapd_ioctl(struct net_device *dev,
				struct ifreq *ifr, int cmd)
{
	int ret;

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

	return ret;
}


#ifdef QCA_HT_2040_COEX
VOS_STATUS hdd_set_sap_ht2040_mode(hdd_adapter_t *pHostapdAdapter,
                                   tANI_U8 channel_type)
{
    eHalStatus halStatus = eHAL_STATUS_FAILURE;
    v_PVOID_t hHal = NULL;

    VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
               "%s: change HT20/40 mode", __func__);

    if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode) {
        hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
        if ( NULL == hHal ) {
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
                       "%s: Hal ctx is null", __func__);
            return VOS_STATUS_E_FAULT;
        }
        halStatus = sme_SetHT2040Mode(hHal, pHostapdAdapter->sessionId,
                                      channel_type, eANI_BOOLEAN_TRUE);
        if (halStatus == eHAL_STATUS_FAILURE ) {
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
                       "%s: Failed to change HT20/40 mode", __func__);
            return VOS_STATUS_E_FAILURE;
        }
    }
    return VOS_STATUS_SUCCESS;
}
#endif

#ifdef FEATURE_WLAN_FORCE_SAP_SCC
/**---------------------------------------------------------------------------
  \brief hdd_restart_softap() -
   Restart SAP  on STA channel to support
   STA + SAP concurrency.

  --------------------------------------------------------------------------*/
void hdd_restart_softap(hdd_context_t *pHddCtx,
                        hdd_adapter_t *pHostapdAdapter)
{
   tHddAvoidFreqList   hdd_avoid_freq_list;

   /* generate vendor specific event */
   vos_mem_zero((void *)&hdd_avoid_freq_list, sizeof(tHddAvoidFreqList));
   hdd_avoid_freq_list.avoidFreqRange[0].startFreq =
        vos_chan_to_freq(pHostapdAdapter->sessionCtx.ap.operatingChannel);
   hdd_avoid_freq_list.avoidFreqRange[0].endFreq =
        vos_chan_to_freq(pHostapdAdapter->sessionCtx.ap.operatingChannel);
   hdd_avoid_freq_list.avoidFreqRangeCount = 1;
   wlan_hdd_send_avoid_freq_event(pHddCtx, &hdd_avoid_freq_list);
}
#endif /* FEATURE_WLAN_FORCE_SAP_SCC */

/**
 * __hdd_hostapd_set_mac_address() - set mac address
 * @dev: pointer to net_device
 * @addr: mac address
 *
 * This function sets the user specified mac address using
 * the command ifconfig wlanX hw ether <mac address>.
 *
 * Return: 0 on success, error number otherwise
 */
static int __hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
{
   struct sockaddr *psta_mac_addr = addr;
   hdd_adapter_t *adapter;
   hdd_context_t *hdd_ctx;
   int ret = 0;

   ENTER();

   adapter = WLAN_HDD_GET_PRIV_PTR(dev);
   hdd_ctx = WLAN_HDD_GET_CTX(adapter);
   ret = wlan_hdd_validate_context(hdd_ctx);
   if (0 != ret)
       return ret;

   memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
   EXIT();
   return 0;
}

/**
 * hdd_hostapd_set_mac_address() - set mac address
 * @dev: pointer to net_device
 * @addr: mac address
 *
 * Return: 0 on success, error number otherwise
 */
static int hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __hdd_hostapd_set_mac_address(dev, addr);
	vos_ssr_unprotect(__func__);

	return ret;
}

void hdd_hostapd_inactivity_timer_cb(v_PVOID_t usrDataForCallback)
{
    struct net_device *dev = (struct net_device *)usrDataForCallback;
    v_BYTE_t we_custom_event[64];
    union iwreq_data wrqu;
#ifdef DISABLE_CONCURRENCY_AUTOSAVE
    VOS_STATUS vos_status;
    hdd_adapter_t *pHostapdAdapter;
    hdd_ap_ctx_t *pHddApCtx;
#endif /*DISABLE_CONCURRENCY_AUTOSAVE */

    /* event_name space-delimiter driver_module_name */
    /* Format of the event is "AUTO-SHUT.indication" " " "module_name" */
    char * autoShutEvent = "AUTO-SHUT.indication" " "  KBUILD_MODNAME;
    int event_len = strlen(autoShutEvent) + 1; /* For the NULL at the end */

    ENTER();

#ifdef DISABLE_CONCURRENCY_AUTOSAVE
    if (vos_concurrent_open_sessions_running())
    {
       /*
              This timer routine is going to be called only when AP
              persona is up.
              If there are concurrent sessions running we do not want
              to shut down the Bss.Instead we run the timer again so
              that if Autosave is enabled next time and other session
              was down only then we bring down AP
             */
        pHostapdAdapter = netdev_priv(dev);
        if ((NULL == pHostapdAdapter) ||
            (WLAN_HDD_ADAPTER_MAGIC != pHostapdAdapter->magic))
        {
            hddLog(LOGE, FL("invalid adapter: %pK"), pHostapdAdapter);
            return;
        }
        pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
        vos_status = vos_timer_start(
         &pHddApCtx->hdd_ap_inactivity_timer,
         (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff
          * 1000);
        if (!VOS_IS_STATUS_SUCCESS(vos_status))
        {
            hddLog(LOGE, FL("Failed to init AP inactivity timer"));
        }
        EXIT();
        return;
    }
#endif /*DISABLE_CONCURRENCY_AUTOSAVE */
    memset(&we_custom_event, '\0', sizeof(we_custom_event));
    memcpy(&we_custom_event, autoShutEvent, event_len);

    memset(&wrqu, 0, sizeof(wrqu));
    wrqu.data.length = event_len;

    hddLog(LOG1, FL("Shutting down AP interface due to inactivity"));
    wireless_send_event(dev, IWEVCUSTOM, &wrqu, (char *)we_custom_event);

    EXIT();
}

#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN
//This function runs in the timer context of hdd_ap_chan_switch_timer.
void hdd_hostapd_chan_switch_cb(v_PVOID_t usrDataForCallback)
{
    hdd_adapter_t   *pHostapdAdapter = NULL;
    hdd_context_t   *pHddCtx = NULL;
    int             ret = 0;

    ENTER();

    if(usrDataForCallback)
    {
        pHostapdAdapter = (struct hdd_adapter_s *)usrDataForCallback;
    }
    else
    {
        hddLog(LOGE, FL("hdd_hostapd_chan_switch_cb NULL cb pointer!!\n"));
                EXIT();
        return;
    }
    pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);

    mutex_lock(&pHddCtx->ch_switch_ctx.sap_ch_sw_lock);
    if(pHddCtx->ch_switch_ctx.sap_chan_sw_pending)
    {
        vos_ssr_protect(__func__);
        ret = hdd_softap_set_channel_change(pHostapdAdapter->dev, pHddCtx->ch_switch_ctx.def_csa_channel_on_disc);
        vos_ssr_unprotect(__func__);
        if (ret)
        {
            hddLog(LOGE, FL("hdd_softap_set_channel_change failed!!"));
        }
        pHddCtx->ch_switch_ctx.sap_chan_sw_pending = 0;
    }
    mutex_unlock(&pHddCtx->ch_switch_ctx.sap_ch_sw_lock);

    EXIT();
}
#endif //#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN

static VOS_STATUS
hdd_change_mcc_go_beacon_interval(hdd_adapter_t *pHostapdAdapter)
{
    eHalStatus halStatus = eHAL_STATUS_FAILURE;
    v_PVOID_t hHal = NULL;

    VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
               "%s: UPDATE Beacon Params", __func__);

    if(VOS_STA_SAP_MODE == vos_get_conparam ( )){
        hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
        if ( NULL == hHal ){
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
                       "%s: Hal ctx is null", __func__);
            return VOS_STATUS_E_FAULT;
        }
        halStatus = sme_ChangeMCCBeaconInterval(hHal, pHostapdAdapter->sessionId);
        if(halStatus == eHAL_STATUS_FAILURE ){
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
                       "%s: Failed to update Beacon Params", __func__);
            return VOS_STATUS_E_FAILURE;
        }
    }
    return VOS_STATUS_SUCCESS;
}

void hdd_clear_all_sta(hdd_adapter_t *pHostapdAdapter, v_PVOID_t usrDataForCallback)
{
    v_U8_t staId = 0;
    struct net_device *dev;
    struct tagCsrDelStaParams delStaParams;
    dev = (struct net_device *)usrDataForCallback;

    hddLog(LOGE, FL("Clearing all the STA entry...."));
    for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
    {
        if ( pHostapdAdapter->aStaInfo[staId].isUsed &&
           ( staId != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId))
        {
             WLANSAP_PopulateDelStaParams(&pHostapdAdapter->aStaInfo[staId].macAddrSTA.bytes[0],
                                                    eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
                                                    (SIR_MAC_MGMT_DISASSOC >> 4),
                                                     &delStaParams);
            //Disconnect all the stations
            hdd_softap_sta_disassoc(pHostapdAdapter, &delStaParams);
        }
    }
}

static int hdd_stop_bss_link(hdd_adapter_t *pHostapdAdapter,
                             v_PVOID_t usrDataForCallback)
{
    struct net_device *dev;
    hdd_context_t     *pHddCtx = NULL;
    VOS_STATUS status = VOS_STATUS_SUCCESS;
    dev = (struct net_device *)usrDataForCallback;

    ENTER();

    pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
        return status;

    if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
    {
#ifdef WLAN_FEATURE_MBSSID
        status = WLANSAP_StopBss(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter));
#else
        status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext);
#endif
        if (VOS_IS_STATUS_SUCCESS(status))
            hddLog(LOGE, FL("Deleting SAP/P2P link!!!!!!"));

        clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
        wlan_hdd_decr_active_session(pHddCtx, pHostapdAdapter->device_mode);
    }
    if (pHddCtx->cfg_ini->apOBSSProtEnabled)
        vos_runtime_pm_allow_suspend(pHddCtx->runtime_context.obss);
    EXIT();
    return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
}

#ifdef SAP_AUTH_OFFLOAD
void hdd_set_sap_auth_offload(hdd_adapter_t *pHostapdAdapter,
                                     bool enabled)
{
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
    struct tSirSapOffloadInfo *sap_offload_info = NULL;

    /* Prepare the request to send to SME */
    sap_offload_info = vos_mem_malloc(sizeof(*sap_offload_info));
    if (NULL == sap_offload_info) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                  "%s: could not allocate tSirSapOffloadInfo!", __func__);
        return;
    }

    vos_mem_zero(sap_offload_info, sizeof(*sap_offload_info));

    sap_offload_info->vdev_id = pHostapdAdapter->sessionId;
    sap_offload_info->sap_auth_offload_enable =
        pHddCtx->cfg_ini->enable_sap_auth_offload && enabled;
    sap_offload_info->sap_auth_offload_sec_type =
        pHddCtx->cfg_ini->sap_auth_offload_sec_type;
    sap_offload_info->key_len =
        strlen(pHddCtx->cfg_ini->sap_auth_offload_key);

    if (sap_offload_info->sap_auth_offload_enable) {
        if (sap_offload_info->key_len < 8 ||
            sap_offload_info->key_len > WLAN_PSK_STRING_LENGTH) {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                   "%s: invalid key length(%d) of WPA security!", __func__,
                   sap_offload_info->key_len);
            goto end;
        }
    }

    vos_mem_copy(sap_offload_info->key,
                            pHddCtx->cfg_ini->sap_auth_offload_key,
                            sap_offload_info->key_len);
    if (eHAL_STATUS_SUCCESS !=
        sme_set_sap_auth_offload(pHddCtx->hHal, sap_offload_info)) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                  "%s: sme_set_sap_auth_offload fail!", __func__);
        goto end;
    }

    hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
           "%s: sme_set_sap_auth_offload successfully!", __func__);

end:
    vos_mem_free(sap_offload_info);
    return;
}


/**
 * hdd_set_client_block_info - get client block info from ini file
 * @padapter: hdd adapter pointer
 *
 * This function reads client block related info from ini file, these
 * configurations will be sent to fw through wmi.
 *
 * Return: 0 on success, otherwise error value
 */
int hdd_set_client_block_info(hdd_adapter_t *padapter)
{
	hdd_context_t *phddctx = WLAN_HDD_GET_CTX(padapter);
	struct sblock_info client_block_info;
	eHalStatus status;

	/* prepare the request to send to SME */
	client_block_info.vdev_id = padapter->sessionId;
	client_block_info.reconnect_cnt =
				phddctx->cfg_ini->connect_fail_count;

	client_block_info.con_fail_duration =
				phddctx->cfg_ini->connect_fail_duration;

	client_block_info.block_duration =
				phddctx->cfg_ini->connect_block_duration;

	status = sme_set_client_block_info(phddctx->hHal, &client_block_info);
	if (eHAL_STATUS_FAILURE == status) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
			"%s: sme_set_client_block_info!", __func__);
		return -EIO;
	}

	hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
		"%s: sme_set_client_block_info success!", __func__);

	return 0;
}
#endif /* SAP_AUTH_OFFLOAD */

/**
 * hdd_issue_stored_joinreq() - This function will trigger stations's
 *                              cached connect request to proceed.
 * @hdd_ctx: pointer to hdd context.
 * @sta_adapter: pointer to station adapter.
 *
 * This function will call SME to release station's stored/cached connect
 * request to proceed.
 *
 * Return: none.
 */
static void hdd_issue_stored_joinreq(hdd_adapter_t *sta_adapter,
                              hdd_context_t *hdd_ctx)
{
    tHalHandle hal_handle;
    uint32_t roam_id = 0;

    if (NULL == sta_adapter) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("Invalid station adapter, ignore issueing join req"));
        return;
    }
    hal_handle = WLAN_HDD_GET_HAL_CTX(sta_adapter);

    if (true ==  hdd_is_sta_connection_pending(hdd_ctx)) {
        MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                         TRACE_CODE_HDD_ISSUE_JOIN_REQ,
                         sta_adapter->sessionId, roam_id));
        if (VOS_STATUS_SUCCESS !=
              sme_issue_stored_joinreq(hal_handle,
                                       &roam_id,
                                       sta_adapter->sessionId)) {
            /* change back to NotAssociated */
            hdd_connSetConnectionState(sta_adapter,
                                       eConnectionState_NotConnected);
        }
        hdd_change_sta_conn_pending_status(hdd_ctx, false);
    }
}

/**
 * hdd_update_chandef() - Function to update channel width and center freq
 * @hostapd_adapter:	hostapd adapter
 * @chandef:		cfg80211 chan def
 * @cb_mode:		chan offset
 *
 * This function will be called to update channel width and center freq
 *
 * Return: None
 */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) || defined(WITH_BACKPORTS)
static inline void
hdd_update_chandef(hdd_adapter_t *hostapd_adapter,
		struct cfg80211_chan_def *chandef,
		ePhyChanBondState cb_mode)
{
	uint16_t   ch_width;
	hdd_ap_ctx_t *phdd_ap_ctx;
	uint8_t  center_chan, chan;

	phdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(hostapd_adapter);
	ch_width = phdd_ap_ctx->sapConfig.acs_cfg.ch_width;

	switch (ch_width) {
	case eHT_CHANNEL_WIDTH_20MHZ:
	case eHT_CHANNEL_WIDTH_40MHZ:
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
			"ch_width %d, won't update", ch_width);
		break;
	case eHT_CHANNEL_WIDTH_80MHZ:
		chan = vos_freq_to_chan(chandef->chan->center_freq);
		chandef->width = NL80211_CHAN_WIDTH_80;

		switch (cb_mode) {
		case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
		case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
			center_chan = chan + 2;
			break;
		case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
			center_chan = chan + 6;
			break;
		case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
		case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
			center_chan = chan - 2;
			break;
		case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
			center_chan = chan - 6;
			break;
		default:
			center_chan = chan;
			break;
		}

		chandef->center_freq1 = vos_chan_to_freq(center_chan);
		break;
	case eHT_CHANNEL_WIDTH_160MHZ:
	default:
		/* Todo, please add related codes if support 160MHZ or others */
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			"unsupport ch_width %d", ch_width);
		break;
	}

}
#else
static inline void
hdd_update_chandef(hdd_adapter_t *hostapd_adapter,
		struct cfg80211_chan_def *chandef,
		ePhyChanBondState cb_mode)
{
}
#endif

/**
 * hdd_chan_change_notify() - Function to notify hostapd about channel change
 * @hostapd_adapter	hostapd adapter
 * @dev:		Net device structure
 * @oper_chan:		New operating channel
 *
 * This function is used to notify hostapd about the channel change
 *
 * Return: Success on intimating userspace
 *
 */
VOS_STATUS hdd_chan_change_notify(hdd_adapter_t *hostapd_adapter,
		struct net_device *dev,
		uint8_t oper_chan)
{
	struct ieee80211_channel *chan;
	struct cfg80211_chan_def chandef;
	enum nl80211_channel_type channel_type;
	eCsrPhyMode phy_mode;
	ePhyChanBondState cb_mode;
	uint32_t freq;
	tHalHandle  hal = WLAN_HDD_GET_HAL_CTX(hostapd_adapter);

	if (NULL == hal) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
				"%s: hal is NULL", __func__);
		return VOS_STATUS_E_FAILURE;
	}

	freq = vos_chan_to_freq(oper_chan);

	chan = ieee80211_get_channel(hostapd_adapter->wdev.wiphy, freq);

	if (!chan) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
				"%s: Invalid input frequency for channel conversion",
				 __func__);
		return VOS_STATUS_E_FAILURE;
	}

#ifdef WLAN_FEATURE_MBSSID
	phy_mode = wlansap_get_phymode(WLAN_HDD_GET_SAP_CTX_PTR(hostapd_adapter));
#else
	phy_mode = wlansap_get_phymode(
			(WLAN_HDD_GET_CTX(hostapd_adapter))->pvosContext);
#endif

	if (oper_chan <= 14)
		cb_mode = sme_GetCBPhyStateFromCBIniValue(
				sme_GetChannelBondingMode24G(hal));
	else
		cb_mode = sme_GetCBPhyStateFromCBIniValue(
				sme_GetChannelBondingMode5G(hal));

	switch (phy_mode) {
	case eCSR_DOT11_MODE_11n:
	case eCSR_DOT11_MODE_11n_ONLY:
	case eCSR_DOT11_MODE_11ac:
	case eCSR_DOT11_MODE_11ac_ONLY:
		if (cb_mode == PHY_SINGLE_CHANNEL_CENTERED)
			channel_type = NL80211_CHAN_HT20;
		else if (cb_mode == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
			channel_type = NL80211_CHAN_HT40MINUS;
		else if (cb_mode == PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
			channel_type = NL80211_CHAN_HT40PLUS;
		else
			channel_type = NL80211_CHAN_HT40PLUS;
		break;
	default:
		channel_type = NL80211_CHAN_NO_HT;
		break;
	}

	VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
			"%s: phy_mode %d cb_mode %d chann_type %d oper_chan %d",
			__func__, phy_mode, cb_mode, channel_type, oper_chan);

	cfg80211_chandef_create(&chandef, chan, channel_type);

	if ((phy_mode == eCSR_DOT11_MODE_11ac) ||
	    (phy_mode == eCSR_DOT11_MODE_11ac_ONLY))
		hdd_update_chandef(hostapd_adapter, &chandef, cb_mode);

	cfg80211_ch_switch_notify(dev, &chandef);

	return VOS_STATUS_SUCCESS;
}

#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN
VOS_STATUS hdd_send_sap_event(struct net_device *dev,
                sta_sap_notifications event,
                struct wlan_sap_csa_info csa_info,
                struct wireless_dev *wdev)
{
    uint32_t freq = 0, ret;

    hdd_wlan_get_freq(csa_info.sta_channel, &freq);

    hddLog(LOG1, FL(" Set Freq %d Chan= %d"), freq, csa_info.sta_channel );

    vos_ssr_protect(__func__);
    ret = hdd_softap_set_channel_change(dev, csa_info.sta_channel);
    vos_ssr_unprotect(__func__);

    return ret;
}

VOS_STATUS hdd_sta_state_sap_notify(hdd_context_t *hdd_context,
                                sta_sap_notifications event,
                                struct wlan_sap_csa_info csa_info)
{
    /* Get the HostApd Adapter. If present proceed further.
     * Check the current state of SAP. If its in active state, get the channel in which it is running.
     * Verify the channel and band. Based on the event type, take a decision.
     * If it is a disconnection event and SAP is running in 2.4 band channel, no action should be taken.
     * If its a connection event and SAP needs to do a CSA to the HomeAP channel.
     */

    hdd_adapter_t *pHostapdAdapter = NULL;
    hdd_ap_ctx_t *pHddApCtx = NULL;
    hdd_hostapd_state_t *pHostapdState = NULL;
    VOS_STATUS status = VOS_STATUS_SUCCESS;
    tsap_Config_t *sap_config;
    uint32_t ret = 0;

    hddLog(LOGE, FL("%s Entry event = %d channel = %d"),
                        __func__, event, csa_info.sta_channel);

    if (!hdd_context) {
        hddLog(LOGE, FL("HDD context is NULL"));
                return VOS_STATUS_E_FAILURE;
    }

    ret = wlan_hdd_validate_context(hdd_context);

    if (ret != 0) {

        hddLog(LOGE, FL("%s Failed in hdd_validate_context ret=%d"), __func__, ret);
        return ret;
    }

    /*Get the Adapter of SAP*/
    pHostapdAdapter = hdd_get_adapter(hdd_context, WLAN_HDD_SOFTAP);

    if(!pHostapdAdapter)
    {
        hddLog(LOGE, FL("Hostapd adapter context is NULL"));
        return VOS_STATUS_E_FAILURE;
    }

    pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);

    pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);

    /*Verify the state*/
    if(pHostapdState->vosStatus != VOS_STATUS_SUCCESS ||
            pHostapdState->bssState != BSS_START)
    {
        hddLog(LOGE, FL("Invalid HostApd State vosStatus=%d bssState=%d"),
                    pHostapdState->vosStatus, pHostapdState->bssState);
        return VOS_STATUS_E_FAILURE;
    }

    switch(event)
    {
        case STA_NOTIFY_DISCONNECTED:
            {
                /* check for the operating channel
                 * If operating in 2.4, just ignore and return
                 * else start ACS & find the strongest signal channel and do initiate CSA to that channel.
                 */
                if((pHddApCtx->operatingChannel >= 1 && pHddApCtx->operatingChannel <= 14))
                {
                    hddLog(LOGE, FL("Hostapd is operating in 2.4Band Channel=%d, Avoid channel switch"),
                                        pHddApCtx->operatingChannel);
                }
                else
                {
		    sap_config = &((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->sapConfig);
		    if (VOS_IS_DFS_CH(pHddApCtx->operatingChannel) &&
				( VOS_IS_DFS_CH(sap_config->channel) ||
					(sap_config->channel == AUTO_CHANNEL_SELECT) )){
			hddLog(LOGE, FL("SAP CUR CH %d(DFS) Hostapd Conf CH=%d(%s) Switch to CH %d"),
					pHddApCtx->operatingChannel, pHddApCtx->operatingChannel,
				        (sap_config->channel == AUTO_CHANNEL_SELECT)?"AUTO":"DFS", 36);
                        hdd_context->ch_switch_ctx.def_csa_channel_on_disc = 36;
		    }else if (VOS_IS_DFS_CH(pHddApCtx->operatingChannel) &&
				!VOS_IS_DFS_CH(sap_config->channel)){
			hddLog(LOGE, FL("SAP CUR CH %d(DFS) Hostapd Conf CH=%d(Non-DFS) Switch to %d"),
					pHddApCtx->operatingChannel, sap_config->channel, sap_config->channel);
			hdd_context->ch_switch_ctx.def_csa_channel_on_disc = sap_config->channel; //channel from the hostapd
		    }else{
			    hddLog(LOGE, FL("SAP is operating in 5Ghz Band Non DFS Channel=%d, Avoid channel switch"),
					    pHddApCtx->operatingChannel);
			    return status;
		    }
		    mutex_lock(&hdd_context->ch_switch_ctx.sap_ch_sw_lock);
		    hdd_context->ch_switch_ctx.sap_chan_sw_pending = 1;
		    mutex_unlock(&hdd_context->ch_switch_ctx.sap_ch_sw_lock);

		    //Set the timer to initiate channel switch
		    if(hdd_context->ch_switch_ctx.chan_sw_timer_initialized == VOS_TRUE)
		    {
			    status = vos_timer_start(&hdd_context->ch_switch_ctx.hdd_ap_chan_switch_timer, 10000);
			    if(!VOS_IS_STATUS_SUCCESS(status))
			    {
				    hddLog(LOGE, FL("Failed to start AP channel switch timer!!"));
				    break;
			    }
		    }
		}
	    }
	    break;
	case STA_NOTIFY_CONNECTED:
	    {
		    //stop the channel switch timer first
		    if (hdd_context->ch_switch_ctx.hdd_ap_chan_switch_timer.state == VOS_TIMER_STATE_RUNNING)
		    {
			    status = vos_timer_stop(&hdd_context->ch_switch_ctx.hdd_ap_chan_switch_timer);
			    if(!VOS_IS_STATUS_SUCCESS(status))
			    {
				    hddLog(LOGE, FL("Failed to stop AP channel switch timer!!"));
				    break;
			    }
		    }
		    if(pHddApCtx->operatingChannel != csa_info.sta_channel)
		    {
			    mutex_lock(&hdd_context->ch_switch_ctx.sap_ch_sw_lock);
			    hddLog(LOGE, FL("Switching Hostapd to Station channel %d"), csa_info.sta_channel);
			    status = hdd_send_sap_event(pHostapdAdapter->dev,
					    event,
					    csa_info,
					    &pHostapdAdapter->wdev);
			    if(!VOS_IS_STATUS_SUCCESS(status))
			    {
				    hddLog(LOGE, FL("Failed to send channel switch event!!"));
				    mutex_unlock(&hdd_context->ch_switch_ctx.sap_ch_sw_lock);
				    break;
			    }
			    hdd_context->ch_switch_ctx.sap_chan_sw_pending = 0;
			    mutex_unlock(&hdd_context->ch_switch_ctx.sap_ch_sw_lock);
		    }
		    else
		    {
			    hddLog(LOGE, FL("Hostapd and Sta are operating in same channel : %d\n"),
					    pHddApCtx->operatingChannel);
		    }
	    }
	    break;
	case STA_NOTIFY_CSA:
	    {
		    mutex_lock(&hdd_context->ch_switch_ctx.sap_ch_sw_lock);
		    if(pHddApCtx->operatingChannel != csa_info.sta_channel)
		    {
			    if(!(hdd_context->ch_switch_ctx.is_ch_sw_through_sta_csa &&
						    hdd_context->ch_switch_ctx.csa_to_channel == csa_info.sta_channel))
			    {
				    hdd_context->ch_switch_ctx.is_ch_sw_through_sta_csa = VOS_TRUE;

				    hddLog(LOGE, FL("Switching Hostapd to Station channel %d"), csa_info.sta_channel);
				    status = hdd_send_sap_event(pHostapdAdapter->dev,
						    event,
						    csa_info,
						    &pHostapdAdapter->wdev);
				    if(!VOS_IS_STATUS_SUCCESS(status))
				    {
					    hddLog(LOGE, FL("Failed to send channel switch event!!"));
					    mutex_unlock(&hdd_context->ch_switch_ctx.sap_ch_sw_lock);
					    break;
				    }

				    hdd_context->ch_switch_ctx.csa_to_channel = csa_info.sta_channel;
			    }
			    else
			    {
				    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
						    "%s : CSA Sta interface for Channel %d is already notified",
						    __func__, csa_info.sta_channel);
			    }
		    }
		    else
		    {
			    hddLog(LOGE, FL("Hostapd and Sta are operating in same channel : %d\n"),
					    pHddApCtx->operatingChannel);
		    }
		    mutex_unlock(&hdd_context->ch_switch_ctx.sap_ch_sw_lock);
	    }
	    break;
	default:
	    {
		    hddLog(LOGE, FL("%s Invalid event %d"), __func__, event);
	    }
	    break;
    }

    hddLog(LOGE, FL("%s Exit ret = %d"), __func__, status);

    return status;
}
#endif //#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN
/**
 * hdd_send_radar_event() - Function to send radar events to user space
 * @hdd_context:	HDD context
 * @event:		Type of radar event
 * @dfs_info:		Structure containing DFS channel and country
 * @wdev:		Wireless device structure
 *
 * This function is used to send radar events such as CAC start, CAC
 * end etc., to userspace
 *
 * Return: Success on sending notifying userspace
 *
 */
VOS_STATUS hdd_send_radar_event(hdd_context_t *hdd_context,
				eSapHddEvent event,
				struct wlan_dfs_info dfs_info,
				struct wireless_dev *wdev)
{

	struct sk_buff *vendor_event;
	enum qca_nl80211_vendor_subcmds_index index;
	uint32_t freq, ret;
	uint32_t data_size;

	if (!hdd_context) {
		hddLog(LOGE, FL("HDD context is NULL"));
                return VOS_STATUS_E_FAILURE;
	}

	freq = vos_chan_to_freq(dfs_info.channel);

	switch (event) {
	case eSAP_DFS_CAC_START:
	    index =
		QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED_INDEX;
	    data_size = sizeof(uint32_t);
	    break;
	case eSAP_DFS_CAC_END:
	    index =
		QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED_INDEX;
	    data_size = sizeof(uint32_t);
	    break;
	case eSAP_DFS_RADAR_DETECT:
	    index =
		QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED_INDEX;
	    data_size = sizeof(uint32_t);
	    break;
	default:
	    return VOS_STATUS_E_FAILURE;
	}

	vendor_event = cfg80211_vendor_event_alloc(hdd_context->wiphy,
				wdev,
				data_size + NLMSG_HDRLEN,
				index,
				GFP_KERNEL);
	if (!vendor_event) {
		hddLog(LOGE,
		       FL("cfg80211_vendor_event_alloc failed for %d"), index);
		return VOS_STATUS_E_FAILURE;
	}

	ret = nla_put_u32(vendor_event, NL80211_ATTR_WIPHY_FREQ, freq);

	if (ret) {
		hddLog(LOGE, FL("NL80211_ATTR_WIPHY_FREQ put fail"));
		kfree_skb(vendor_event);
		return VOS_STATUS_E_FAILURE;
	}

	cfg80211_vendor_event(vendor_event, GFP_KERNEL);
	return VOS_STATUS_SUCCESS;
}

#ifdef CONFIG_CNSS
static VOS_STATUS hdd_wlan_get_dfs_nol(void *pdfs_list, u16 sdfs_list)
{
	int ret;

	/* get the dfs nol from cnss */
	ret = vos_wlan_get_dfs_nol(pdfs_list, sdfs_list);
	if (ret > 0) {
		hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
			"%s: Get %d bytes of dfs nol from cnss",
			__func__, ret);
		return VOS_STATUS_SUCCESS;
	} else {
		hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
			"%s: No dfs nol entry in CNSS, ret: %d",
			__func__, ret);
		return VOS_STATUS_E_FAULT;
	}
}
#else
static VOS_STATUS hdd_wlan_get_dfs_nol(void *pdfs_list, u16 sdfs_list)
{
	return VOS_STATUS_E_FAILURE;
}
#endif

#ifdef CONFIG_CNSS
static VOS_STATUS hdd_wlan_set_dfs_nol(const void *pdfs_list, u16 sdfs_list)
{
	int ret;

	/* set the dfs nol from cnss */
	ret = vos_wlan_set_dfs_nol(pdfs_list, sdfs_list);
	if (ret) {
		hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
			"%s: Failed to set dfs nol - ret: %d",
			__func__, ret);
	} else {
		hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
			"%s: Set %d bytes dfs nol to cnss",
			__func__, sdfs_list);
	}

	return VOS_STATUS_SUCCESS;
}
#else
static VOS_STATUS hdd_wlan_set_dfs_nol(const void *pdfs_list, u16 sdfs_list)
{
	return VOS_STATUS_E_FAILURE;
}
#endif

#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
/**
 * hdd_handle_acs_scan_event() - handle acs scan event for SAP
 * @sap_event: tpSap_Event
 * @adapter: hdd_adapter_t for SAP
 *
 * The function is to handle the eSAP_ACS_SCAN_SUCCESS_EVENT event.
 * It will update scan result to cfg80211 and start a timer to flush the
 * cached acs scan result.
 *
 * Return: VOS_STATUS_SUCCESS on success,
          other value on failure
 */
static VOS_STATUS hdd_handle_acs_scan_event(tpSap_Event sap_event,
		hdd_adapter_t *adapter)
{
	hdd_context_t *hdd_ctx;
	struct tsap_acs_scan_complete_event *comp_evt;
	VOS_STATUS vos_status;
	int chan_list_size;

	hdd_ctx = (hdd_context_t*)(adapter->pHddCtx);
	if (!hdd_ctx) {
		hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is null"));
		return VOS_STATUS_E_FAILURE;
	}
	comp_evt = &sap_event->sapevt.sap_acs_scan_comp;
	hdd_ctx->skip_acs_scan_status = eSAP_SKIP_ACS_SCAN;
	spin_lock(&hdd_ctx->acs_skip_lock);
	vos_mem_free(hdd_ctx->last_acs_channel_list);
	hdd_ctx->last_acs_channel_list = NULL;
	hdd_ctx->num_of_channels = 0;
	/* cache the previous ACS scan channel list .
	 * If the following OBSS scan chan list is covered by ACS chan list,
	 * we can skip OBSS Scan to save SAP starting total time.
	 */
	if (comp_evt->num_of_channels && comp_evt->channellist) {
		chan_list_size = comp_evt->num_of_channels *
			sizeof(comp_evt->channellist[0]);
		hdd_ctx->last_acs_channel_list = vos_mem_malloc(
			chan_list_size);
		if (hdd_ctx->last_acs_channel_list) {
			vos_mem_copy(hdd_ctx->last_acs_channel_list,
				comp_evt->channellist,
				chan_list_size);
			hdd_ctx->num_of_channels = comp_evt->num_of_channels;
		}
	}
	spin_unlock(&hdd_ctx->acs_skip_lock);
	/* Update ACS scan result to cfg80211. Then OBSS scan can reuse the
	 * scan result.
	 */
	if (wlan_hdd_cfg80211_update_bss(hdd_ctx->wiphy, adapter))
		hddLog(VOS_TRACE_LEVEL_INFO, FL("NO SCAN result"));

	hddLog(LOG1, FL("Reusing Last ACS scan result for %d sec"),
		ACS_SCAN_EXPIRY_TIMEOUT_S);
	vos_timer_stop( &hdd_ctx->skip_acs_scan_timer);
	vos_status = vos_timer_start( &hdd_ctx->skip_acs_scan_timer,
			ACS_SCAN_EXPIRY_TIMEOUT_S * 1000);
	if (!VOS_IS_STATUS_SUCCESS(vos_status))
		hddLog(LOGE, FL("Failed to start ACS scan expiry timer"));
	return VOS_STATUS_SUCCESS;
}
#else
static VOS_STATUS hdd_handle_acs_scan_event(tpSap_Event sap_event,
		hdd_adapter_t *adapter)
{
	return VOS_STATUS_SUCCESS;
}
#endif

/**
 * get_max_rate_vht() - calculate max rate for VHT mode
 * @nss: num of streams
 * @ch_width: channel width
 * @sgi: short gi
 * @vht_mcs_map: vht mcs map
 *
 * This function calculate max rate for VHT mode
 *
 * Return: max rate
 */
#ifdef WLAN_FEATURE_11AC
static int get_max_rate_vht(int nss, int ch_width, int sgi, int vht_mcs_map)
{
	struct index_vht_data_rate_type *supported_vht_mcs_rate;
	enum data_rate_11ac_max_mcs vht_max_mcs;
	int maxrate = 0;
	int maxidx = 0;

	if (nss == 1) {
		supported_vht_mcs_rate = supported_vht_mcs_rate_nss1;
	} else if (nss == 2) {
		supported_vht_mcs_rate = supported_vht_mcs_rate_nss2;
	} else {
		/* Not Supported */
		hddLog(VOS_TRACE_LEVEL_ERROR,
				"%s: nss %d not supported\n",
				__func__, nss);
		return maxrate;
	}

	vht_max_mcs =
		(enum data_rate_11ac_max_mcs)
		vht_mcs_map & DATA_RATE_11AC_MCS_MASK;

	if (vht_max_mcs == DATA_RATE_11AC_MAX_MCS_7) {
		maxidx = 7;
	} else if (vht_max_mcs == DATA_RATE_11AC_MAX_MCS_8) {
		maxidx = 8;
	} else if (vht_max_mcs == DATA_RATE_11AC_MAX_MCS_9) {
		if (ch_width == eHT_CHANNEL_WIDTH_20MHZ)
			/* MCS9 is not valid for VHT20 when nss=1,2 */
			maxidx = 8;
		else
			maxidx = 9;
	} else {
		hddLog(VOS_TRACE_LEVEL_ERROR,
				"%s: vht mcs map %x not supported\n",
				__func__,
				vht_mcs_map & DATA_RATE_11AC_MCS_MASK);
		return maxrate;
	}

	if (ch_width == eHT_CHANNEL_WIDTH_20MHZ) {
		maxrate =
		supported_vht_mcs_rate[maxidx].supported_VHT20_rate[sgi];
	} else if (ch_width == eHT_CHANNEL_WIDTH_40MHZ) {
		maxrate =
		supported_vht_mcs_rate[maxidx].supported_VHT40_rate[sgi];
	} else if (ch_width == eHT_CHANNEL_WIDTH_80MHZ) {
		maxrate =
		supported_vht_mcs_rate[maxidx].supported_VHT80_rate[sgi];
	} else {
		hddLog(VOS_TRACE_LEVEL_ERROR,
				"%s: ch_width %d not supported\n",
				__func__, ch_width);
		return maxrate;
	}

	return maxrate;
}
#else
static int get_max_rate_vht(int nss, int ch_width, int sgi, int vht_mcs_map)
{
	return 0;
}
#endif

/**
 * calculate_max_phy_rate() - calcuate maximum phy rate (kbps)
 * @mode: phymode: Legacy, 11a/b/g, HT, VHT
 * @nss: num of stream (maximum num is 2)
 * @ch_width: channel width
 * @sgi: short gi enabled or not
 * @supp_idx: max supported idx
 * @ext_idx: max extended idx
 * @ht_mcs_idx: max mcs index for HT
 * @vht_mcs_map: mcs map for VHT
 *
 * return: maximum phy rate in kbps
 * */
static int calcuate_max_phy_rate(int mode, int nss, int ch_width,
		int sgi, int supp_idx, int ext_idx, int ht_mcs_idx,
		int vht_mcs_map)
{
	struct index_data_rate_type *supported_mcs_rate;
	int maxidx = 12; /*default 6M mode*/
	int maxrate = 0, tmprate = 0;
	int i;

	/* check supported rates */
	if (supp_idx != 0xff && maxidx < supp_idx)
		maxidx = supp_idx;

	/* check extended rates */
	if (ext_idx != 0xff && maxidx < ext_idx)
		maxidx = ext_idx;

	for (i = 0;
		i < sizeof(supported_data_rate)/sizeof(supported_data_rate[0]);
		i++) {
		if (supported_data_rate[i].beacon_rate_index == maxidx)
			maxrate = supported_data_rate[i].supported_rate[0];
	}

	if (mode == SIR_SME_PHY_MODE_HT) {
		/* check for HT Mode */
		maxidx = ht_mcs_idx;
		if (nss == 1) {
			supported_mcs_rate = supported_mcs_rate_nss1;
		} else if (nss == 2) {
			supported_mcs_rate = supported_mcs_rate_nss2;
		} else {
			/* Not Supported */
			hddLog(VOS_TRACE_LEVEL_ERROR,
					"%s: nss %d not supported\n",
					__func__, nss);
			return maxrate;
		}

		if (ch_width == eHT_CHANNEL_WIDTH_20MHZ) {
			tmprate =
				supported_mcs_rate[maxidx].supported_rate[0];
			if (sgi)
			    tmprate =
				supported_mcs_rate[maxidx].supported_rate[2];
		} else if (ch_width == eHT_CHANNEL_WIDTH_40MHZ) {
			tmprate =
				supported_mcs_rate[maxidx].supported_rate[1];
			if (sgi)
			    tmprate =
				supported_mcs_rate[maxidx].supported_rate[3];
		} else {
			hddLog(VOS_TRACE_LEVEL_ERROR,
					"%s: invalid mode %d ch_width %d\n",
					__func__, mode, ch_width);
			return maxrate;
		}

		if (maxrate < tmprate)
			maxrate = tmprate;
	}

	if (mode == SIR_SME_PHY_MODE_VHT) {
		/* check for VHT Mode */
		tmprate = get_max_rate_vht(nss, ch_width, sgi, vht_mcs_map);
		if (maxrate < tmprate)
			maxrate = tmprate;
	}

	return maxrate;
}

static void hdd_fill_station_info(hdd_station_info_t *stainfo,
		tSap_StationAssocReassocCompleteEvent *event)
{
	stainfo->nss = event->chan_info.nss;
	stainfo->rate_flags = event->chan_info.rate_flags;
	stainfo->sub20_dynamic_channelwidth =
		event->chan_info.sub20_channelwidth;
	stainfo->ampdu = event->ampdu;
	stainfo->sgi_enable = event->sgi_enable;
	stainfo->tx_stbc = event->tx_stbc;
	stainfo->rx_stbc = event->rx_stbc;
	stainfo->ch_width = event->ch_width;
	stainfo->mode = event->mode;
	stainfo->max_supp_idx = event->max_supp_idx;
	stainfo->max_ext_idx = event->max_ext_idx;
	stainfo->max_mcs_idx = event->max_mcs_idx;
	stainfo->rx_mcs_map = event->rx_mcs_map;
	stainfo->tx_mcs_map = event->tx_mcs_map;
	stainfo->assoc_ts = vos_system_ticks();
	stainfo->max_phy_rate =
		calcuate_max_phy_rate(stainfo->mode,
				stainfo->nss,
				stainfo->ch_width,
				stainfo->sgi_enable,
				stainfo->max_supp_idx,
				stainfo->max_ext_idx,
				stainfo->max_mcs_idx,
				stainfo->rx_mcs_map);
	/* expect max_phy_rate report in kbps */
	stainfo->max_phy_rate *= 100;
	hddLog(VOS_TRACE_LEVEL_INFO,
			FL("cap %d %d %d %d %d %d %d %d %d %x %d"),
			stainfo->ampdu,
			stainfo->sgi_enable,
			stainfo->tx_stbc,
			stainfo->rx_stbc,
			stainfo->isQosEnabled,
			stainfo->ch_width,
			stainfo->mode,
			event->wmmEnabled,
			event->chan_info.nss,
			event->chan_info.rate_flags,
			stainfo->max_phy_rate);
	hddLog(VOS_TRACE_LEVEL_INFO,
			FL("rate info %d %d %d %d %d"),
			stainfo->max_supp_idx,
			stainfo->max_ext_idx,
			stainfo->max_mcs_idx,
			stainfo->rx_mcs_map,
			stainfo->tx_mcs_map);
}

VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCallback)
{
    hdd_adapter_t *pHostapdAdapter;
    hdd_ap_ctx_t *pHddApCtx;
    hdd_hostapd_state_t *pHostapdState;
    struct net_device *dev;
    eSapHddEvent sapEvent;
    union iwreq_data wrqu;
    v_BYTE_t *we_custom_event_generic = NULL;
    int we_event = 0;
    int i = 0;
    v_U8_t staId;
    VOS_STATUS vos_status;
    v_BOOL_t bWPSState;
    v_BOOL_t bAuthRequired = TRUE;
    tpSap_AssocMacAddr pAssocStasArray = NULL;
    char unknownSTAEvent[IW_CUSTOM_MAX+1];
    char maxAssocExceededEvent[IW_CUSTOM_MAX+1];
    v_BYTE_t we_custom_start_event[64];
    char *startBssEvent;
    hdd_context_t *pHddCtx;
    hdd_scaninfo_t *pScanInfo  = NULL;
    struct iw_michaelmicfailure msg;
    v_U8_t ignoreCAC = 0;
    hdd_config_t *cfg = NULL;
    struct wlan_dfs_info dfs_info;
    v_U8_t cc_len = WLAN_SVC_COUNTRY_CODE_LEN;
    hdd_adapter_t *con_sap_adapter;
    tSap_StationAssocReassocCompleteEvent *event;
    VOS_STATUS status = VOS_STATUS_SUCCESS;

    dev = (struct net_device *)usrDataForCallback;
    if (!dev)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "%s: usrDataForCallback is null", __func__);
        return VOS_STATUS_E_FAILURE;
    }

    pHostapdAdapter = netdev_priv(dev);

    if ((NULL == pHostapdAdapter) ||
        (WLAN_HDD_ADAPTER_MAGIC != pHostapdAdapter->magic))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                "invalid adapter or adapter has invalid magic");
        return VOS_STATUS_E_FAILURE;
    }

    pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
    pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);

    if (!pSapEvent)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "%s: pSapEvent is null", __func__);
        return VOS_STATUS_E_FAILURE;
    }

    sapEvent = pSapEvent->sapHddEventCode;
    memset(&wrqu, '\0', sizeof(wrqu));
    pHddCtx = (hdd_context_t*)(pHostapdAdapter->pHddCtx);

    if (!pHddCtx) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is null"));
        return VOS_STATUS_E_FAILURE;
    }

    cfg = pHddCtx->cfg_ini;

    if (!cfg) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD config is null"));
        return VOS_STATUS_E_FAILURE;
    }

    dfs_info.channel = pHddApCtx->operatingChannel;
    sme_GetCountryCode(pHddCtx->hHal, dfs_info.country_code, &cc_len);

    switch(sapEvent)
    {
        case eSAP_START_BSS_EVENT :
            hddLog(LOG1, FL("BSS configured status = %s, channel = %u, bc sta Id = %d"),
                            pSapEvent->sapevt.sapStartBssCompleteEvent.status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS",
                            pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel,
                              pSapEvent->sapevt.sapStartBssCompleteEvent.staId);

            pHostapdAdapter->sessionId =
                    pSapEvent->sapevt.sapStartBssCompleteEvent.sessionId;

            pHostapdState->vosStatus = pSapEvent->sapevt.sapStartBssCompleteEvent.status;
            vos_status = vos_event_set(&pHostapdState->vosEvent);

            if (!VOS_IS_STATUS_SUCCESS(vos_status) || pHostapdState->vosStatus)
            {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: startbss event failed!!"));
                goto stopbss;
            }
            else
            {
#ifdef FEATURE_WLAN_CH_AVOID
                sme_ChAvoidUpdateReq(pHddCtx->hHal);
#endif /* FEATURE_WLAN_CH_AVOID */

                pHddApCtx->uBCStaId = pSapEvent->sapevt.sapStartBssCompleteEvent.staId;

#ifdef QCA_LL_TX_FLOW_CT
                if (pHostapdAdapter->tx_flow_timer_initialized == VOS_FALSE)
                {
                    vos_timer_init(&pHostapdAdapter->tx_flow_control_timer,
                                   VOS_TIMER_TYPE_SW,
                                   hdd_tx_resume_timer_expired_handler,
                                   pHostapdAdapter);
                    pHostapdAdapter->tx_flow_timer_initialized = VOS_TRUE;
                }
                WLANTL_RegisterTXFlowControl(pHddCtx->pvosContext,
                                             hdd_tx_resume_cb,
                                             pHostapdAdapter->sessionId,
                                             (void *)pHostapdAdapter);
#endif

                //@@@ need wep logic here to set privacy bit
                vos_status = hdd_softap_Register_BC_STA(pHostapdAdapter, pHddApCtx->uPrivacy);
                if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
                    hddLog(LOGW, FL("Failed to register BC STA %d"), vos_status);
                    hdd_stop_bss_link(pHostapdAdapter, usrDataForCallback);
                }
            }
#ifdef IPA_OFFLOAD
            if (hdd_ipa_is_enabled(pHddCtx))
            {
                status = hdd_ipa_wlan_evt(pHostapdAdapter, pHddApCtx->uBCStaId,
                        WLAN_AP_CONNECT, pHostapdAdapter->dev->dev_addr);

                if (status)
                {
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                                     ("ERROR: WLAN_AP_CONNECT event failed!!"));
                    goto stopbss;
                }
            }
#endif

            if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
            {
                // AP Inactivity timer init and start
                vos_status = vos_timer_init( &pHddApCtx->hdd_ap_inactivity_timer, VOS_TIMER_TYPE_SW,
                                            hdd_hostapd_inactivity_timer_cb, (v_PVOID_t)dev );
                if (!VOS_IS_STATUS_SUCCESS(vos_status))
                   hddLog(LOGE, FL("Failed to init AP inactivity timer"));

                vos_status = vos_timer_start( &pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
                if (!VOS_IS_STATUS_SUCCESS(vos_status))
                   hddLog(LOGE, FL("Failed to init AP inactivity timer"));

            }
#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
            wlan_hdd_auto_shutdown_enable(pHddCtx, VOS_TRUE);
#endif
            pHddApCtx->operatingChannel = pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel;

            hdd_hostapd_channel_prevent_suspend(pHostapdAdapter,
                    pHddApCtx->operatingChannel);

            pHostapdState->bssState = BSS_START;

            /* Set default key index */
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                    "%s: default key index %hu", __func__,
                    pHddApCtx->wep_def_key_idx);

            sme_roam_set_default_key_index(
                    WLAN_HDD_GET_HAL_CTX(pHostapdAdapter),
                    pHostapdAdapter->sessionId,
                    pHddApCtx->wep_def_key_idx);

            //Set group key / WEP key every time when BSS is restarted
            if( pHddApCtx->groupKey.keyLength )
            {
                 status = WLANSAP_SetKeySta(
#ifdef WLAN_FEATURE_MBSSID
                               WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
#else
                               (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
#endif
                               &pHddApCtx->groupKey);
                 if (!VOS_IS_STATUS_SUCCESS(status))
                 {
                      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                             "%s: WLANSAP_SetKeySta failed", __func__);
                 }
            }
            else
            {
                for ( i = 0; i < CSR_MAX_NUM_KEY; i++ )
                {
                    if ( !pHddApCtx->wepKey[i].keyLength )
                          continue;

                    status = WLANSAP_SetKeySta(
#ifdef WLAN_FEATURE_MBSSID
                                WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
#else
                                (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
#endif
                                &pHddApCtx->wepKey[i]);
                    if (!VOS_IS_STATUS_SUCCESS(status))
                    {
                          VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                             "%s: WLANSAP_SetKeySta failed idx %d", __func__, i);
                    }
                }
           }

            SPIN_LOCK_BH(&pHddCtx->dfs_lock);
            pHddCtx->dfs_radar_found = VOS_FALSE;
            SPIN_UNLOCK_BH(&pHddCtx->dfs_lock);
            WLANSAP_Get_Dfs_Ignore_CAC(pHddCtx->hHal, &ignoreCAC);
            if ((NV_CHANNEL_DFS !=
                vos_nv_getChannelEnabledState(pHddApCtx->operatingChannel))
                || ignoreCAC
                || pHddCtx->dev_dfs_cac_status == DFS_CAC_ALREADY_DONE)
            {
                pHddApCtx->dfs_cac_block_tx = VOS_FALSE;
            } else {
                /*
                 * DFS requirement: Do not transmit during CAC.
                 * This flag will be reset when BSS starts
                 * (if not in a DFS channel) or CAC ends.
                 */
                pHddApCtx->dfs_cac_block_tx = VOS_TRUE;
            }

            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
                      "The value of dfs_cac_block_tx[%d] for ApCtx[%pK]",
                      pHddApCtx->dfs_cac_block_tx, pHddApCtx);

            if ((NV_CHANNEL_DFS ==
                vos_nv_getChannelEnabledState(pHddApCtx->operatingChannel)) &&
                (pHddCtx->cfg_ini->IsSapDfsChSifsBurstEnabled == 0))
            {

                VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                           "%s: Setting SIFS Burst disable for DFS channel %d",
                            __func__, pHddApCtx->operatingChannel);

                if (process_wma_set_command((int)pHostapdAdapter->sessionId,
                                            (int)WMI_PDEV_PARAM_BURST_ENABLE,
                                             0, PDEV_CMD))
                {
                    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                               "%s: Failed to Set SIFS Burst for DFS channel %d",
                                __func__, pHddApCtx->operatingChannel);
                }
            }

            //Fill the params for sending IWEVCUSTOM Event with SOFTAP.enabled
            startBssEvent = "SOFTAP.enabled";
            memset(&we_custom_start_event, '\0', sizeof(we_custom_start_event));
            memcpy(&we_custom_start_event, startBssEvent, strlen(startBssEvent));
            memset(&wrqu, 0, sizeof(wrqu));
            wrqu.data.length = strlen(startBssEvent);
            we_event = IWEVCUSTOM;
            we_custom_event_generic = we_custom_start_event;
            hdd_dump_concurrency_info(pHddCtx);
#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN
            if(pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
	    {
		    mutex_lock(&pHddCtx->ch_switch_ctx.sap_ch_sw_lock);
		    if(pHddCtx->ch_switch_ctx.is_ch_sw_through_sta_csa &&
				    (pHddApCtx->operatingChannel == pHddCtx->ch_switch_ctx.csa_to_channel)){
			    hddLog(LOG1, FL("Successfully Channel Switch is done to CH = %d"),
					    pHddApCtx->operatingChannel);
			    pHddCtx->ch_switch_ctx.is_ch_sw_through_sta_csa = VOS_FALSE;
		    }
		    mutex_unlock(&pHddCtx->ch_switch_ctx.sap_ch_sw_lock);
	    }
#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN
            break; //Event will be sent after Switch-Case stmt

        case eSAP_STOP_BSS_EVENT:
            hddLog(LOG1, FL("BSS stop status = %s"),pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
                             "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");

            hdd_set_sap_auth_offload(pHostapdAdapter, FALSE);

            hdd_hostapd_channel_allow_suspend(pHostapdAdapter,
                    pHddApCtx->operatingChannel);

            //Free up Channel List incase if it is set

            sapCleanupChannelList(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter));

            pHddApCtx->operatingChannel = 0; //Invalidate the channel info.
#ifdef IPA_OFFLOAD
            if (hdd_ipa_is_enabled(pHddCtx))
            {
                status = hdd_ipa_wlan_evt(pHostapdAdapter, pHddApCtx->uBCStaId,
                        WLAN_AP_DISCONNECT, pHostapdAdapter->dev->dev_addr);

                if (status)
                {
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                                  ("ERROR: WLAN_AP_DISCONNECT event failed!!"));
                    goto stopbss;
                }
            }
#endif
            /* reset the dfs_cac_status and dfs_cac_block_tx flag only when
             * the last BSS is stopped
             */
            con_sap_adapter = hdd_get_con_sap_adapter(pHostapdAdapter, true);
            if (!con_sap_adapter) {
                pHddApCtx->dfs_cac_block_tx = TRUE;
                pHddCtx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
            }
            if (pHddCtx->cfg_ini->conc_custom_rule2 &&
                (WLAN_HDD_P2P_GO == pHostapdAdapter->device_mode)) {

                hdd_adapter_t *sta_adapter = hdd_get_adapter(pHddCtx,
                                                WLAN_HDD_INFRA_STATION);
                hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
                       FL("P2PGO is going down now"));
                hdd_issue_stored_joinreq(sta_adapter, pHddCtx);
            }

            hddLog(VOS_TRACE_LEVEL_INFO,
                FL("bss_stop_reason=%d"), pHddApCtx->bss_stop_reason);
            if (pHddApCtx->bss_stop_reason != BSS_STOP_DUE_TO_MCC_SCC_SWITCH){
                /* when MCC to SCC switching happens, key storage should not be
                 * cleared due to hostapd will not repopulate the original keys
                 */
                pHddApCtx->groupKey.keyLength = 0;
                for (i = 0; i < CSR_MAX_NUM_KEY; i++)
                    pHddApCtx->wepKey[i].keyLength = 0;
            }

            /* clear the reason code in case BSS is stopped
             * in another place
             */
            pHddApCtx->bss_stop_reason = BSS_STOP_REASON_INVALID;
            goto stopbss;

        case eSAP_DFS_CAC_START:
            wlan_hdd_send_svc_nlink_msg(pHddCtx->radio_index,
                                        WLAN_SVC_DFS_CAC_START_IND,
                                        &dfs_info,
                                        sizeof(dfs_info));
            pHddCtx->dev_dfs_cac_status = DFS_CAC_IN_PROGRESS;
            if (VOS_STATUS_SUCCESS !=
                      hdd_send_radar_event(pHddCtx, eSAP_DFS_CAC_START,
                                           dfs_info, &pHostapdAdapter->wdev)) {
                      hddLog(LOGE, FL("Unable to indicate CAC start NL event"));
            } else {
                hddLog(VOS_TRACE_LEVEL_INFO,
                       FL("Sent CAC start to user space"));
            }
            pHddCtx->dfs_radar_found = VOS_FALSE;
            break;

        case eSAP_DFS_CAC_INTERRUPTED:
            /*
             * The CAC timer did not run completely and a radar was detected
             * during the CAC time. This new state will keep the tx path
             * blocked since we do not want any transmission on the DFS
             * channel. CAC end will only be reported here since the user
             * space applications are waiting on CAC end for their state
             * management.
             */
            if (VOS_STATUS_SUCCESS !=
                      hdd_send_radar_event(pHddCtx, eSAP_DFS_CAC_END,
                                           dfs_info, &pHostapdAdapter->wdev)) {
                      hddLog(LOGE,
                          FL("Unable to indicate CAC end (interrupted) event"));
            } else {
                hddLog(VOS_TRACE_LEVEL_INFO,
                    FL("Sent CAC end (interrupted) to user space"));
            }
            break;

        case eSAP_DFS_CAC_END:
            wlan_hdd_send_svc_nlink_msg(pHddCtx->radio_index,
                                        WLAN_SVC_DFS_CAC_END_IND,
                                        &dfs_info,
                                        sizeof(dfs_info));
            pHddApCtx->dfs_cac_block_tx = VOS_FALSE;
            pHddCtx->dev_dfs_cac_status = DFS_CAC_ALREADY_DONE;
            if (VOS_STATUS_SUCCESS !=
                      hdd_send_radar_event(pHddCtx, eSAP_DFS_CAC_END,
                                           dfs_info, &pHostapdAdapter->wdev)) {
                      hddLog(LOGE, FL("Unable to indicate CAC end NL event"));
            } else {
                hddLog(VOS_TRACE_LEVEL_INFO,
                       FL("Sent CAC end to user space"));
            }
            break;

        case eSAP_DFS_RADAR_DETECT:
            wlan_hdd_send_svc_nlink_msg(pHddCtx->radio_index,
                                        WLAN_SVC_DFS_RADAR_DETECT_IND,
                                        &dfs_info,
                                        sizeof(dfs_info));
            pHddCtx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
            if (VOS_STATUS_SUCCESS !=
                      hdd_send_radar_event(pHddCtx, eSAP_DFS_RADAR_DETECT,
                                           dfs_info, &pHostapdAdapter->wdev)) {
                      hddLog(LOGE, FL("Unable to indicate Radar detect NL event"));
            } else {
                hddLog(VOS_TRACE_LEVEL_INFO,
                       FL("Sent radar detected to user space"));
            }
            break;

        case eSAP_DFS_NO_AVAILABLE_CHANNEL:
            wlan_hdd_send_svc_nlink_msg(pHddCtx->radio_index,
                                        WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND,
                                        &dfs_info,
                                        sizeof(dfs_info));
            break;

        case eSAP_STA_SET_KEY_EVENT:
            /* TODO: forward the message to hostapd once implementation
               is done for now just print */
            hddLog(LOG1, FL("SET Key: configured status = %s"),pSapEvent->sapevt.sapStationSetKeyCompleteEvent.status ?
                            "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
            return VOS_STATUS_SUCCESS;
        case eSAP_STA_DEL_KEY_EVENT:
           /* TODO: forward the message to hostapd once implementation
              is done for now just print */
           hddLog(LOG1, FL("Event received %s"),"eSAP_STA_DEL_KEY_EVENT");
           return VOS_STATUS_SUCCESS;
        case eSAP_STA_MIC_FAILURE_EVENT:
        {
            memset(&msg, '\0', sizeof(msg));
            msg.src_addr.sa_family = ARPHRD_ETHER;
            memcpy(msg.src_addr.sa_data, &pSapEvent->sapevt.sapStationMICFailureEvent.staMac, sizeof(v_MACADDR_t));
            hddLog(LOG1, "MIC MAC "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(msg.src_addr.sa_data));
            if(pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE)
             msg.flags = IW_MICFAILURE_GROUP;
            else
             msg.flags = IW_MICFAILURE_PAIRWISE;
            memset(&wrqu, 0, sizeof(wrqu));
            wrqu.data.length = sizeof(msg);
            we_event = IWEVMICHAELMICFAILURE;
            we_custom_event_generic = (v_BYTE_t *)&msg;
        }
      /* inform mic failure to nl80211 */
        cfg80211_michael_mic_failure(dev,
                                     pSapEvent->sapevt.
                                     sapStationMICFailureEvent.staMac.bytes,
                                     ((pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE) ?
                                      NL80211_KEYTYPE_GROUP :
                                      NL80211_KEYTYPE_PAIRWISE),
                                     pSapEvent->sapevt.sapStationMICFailureEvent.keyId,
                                     pSapEvent->sapevt.sapStationMICFailureEvent.TSC,
                                     GFP_KERNEL);
            break;

        case eSAP_STA_ASSOC_EVENT:
        case eSAP_STA_REASSOC_EVENT:
            event = &pSapEvent->sapevt.sapStationAssocReassocCompleteEvent;
            wrqu.addr.sa_family = ARPHRD_ETHER;
            memcpy(wrqu.addr.sa_data, &event->staMac,
                sizeof(v_MACADDR_t));
            hddLog(LOG1, " associated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
            we_event = IWEVREGISTERED;

#ifdef WLAN_FEATURE_MBSSID
            WLANSAP_Get_WPS_State(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter), &bWPSState);
#else
            WLANSAP_Get_WPS_State((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, &bWPSState);
#endif

            if ( (eCSR_ENCRYPT_TYPE_NONE == pHddApCtx->ucEncryptType) ||
                 ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pHddApCtx->ucEncryptType ) ||
                 ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pHddApCtx->ucEncryptType ) )
            {
                bAuthRequired = FALSE;
            }

            if (bAuthRequired || bWPSState == eANI_BOOLEAN_TRUE )
            {
                vos_status = hdd_softap_RegisterSTA(pHostapdAdapter,
                                                    TRUE,
                                                    pHddApCtx->uPrivacy,
                                                    event->staId,
                                                    0,
                                                    0,
                                                    (v_MACADDR_t *)wrqu.addr.sa_data,
                                                    event->wmmEnabled);
                if (!VOS_IS_STATUS_SUCCESS(vos_status))
                     hddLog(LOGW, FL("Failed to register STA %d "MAC_ADDRESS_STR""),
                                     vos_status, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
            }
            else
            {
                vos_status = hdd_softap_RegisterSTA(pHostapdAdapter,
                                                    FALSE,
                                                    pHddApCtx->uPrivacy,
                                                    event->staId,
                                                    0,
                                                    0,
                                                    (v_MACADDR_t *)wrqu.addr.sa_data,
                                                    event->wmmEnabled);
                if (!VOS_IS_STATUS_SUCCESS(vos_status))
                    hddLog(LOGW, FL("Failed to register STA %d "MAC_ADDRESS_STR""),
                           vos_status, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
            }

            if (VOS_IS_STATUS_SUCCESS(vos_status)) {
                staId = event->staId;
                hdd_fill_station_info(&pHostapdAdapter->aStaInfo[staId],
                                      event);
                pHostapdAdapter->aStaInfo[staId].ecsa_capable =
                    pSapEvent->
                    sapevt.sapStationAssocReassocCompleteEvent.ecsa_capable;
            }

#ifdef IPA_OFFLOAD
            if (hdd_ipa_is_enabled(pHddCtx))
            {
                status = hdd_ipa_wlan_evt(pHostapdAdapter,
                   event->staId,
                   WLAN_CLIENT_CONNECT_EX,
                   event->staMac.bytes);
                if (status)
                {
                   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: WLAN_CLIENT_CONNECT_EX event failed!!"));
                   goto stopbss;
                }
            }
#endif
#ifdef QCA_PKT_PROTO_TRACE
            /* Peer associated, update into trace buffer */
            if (pHddCtx->cfg_ini->gEnableDebugLog)
            {
               vos_pkt_trace_buf_update("HA:ASSOC");
            }
#endif /* QCA_PKT_PROTO_TRACE */

            DPTRACE(adf_dp_trace_mgmt_pkt(ADF_DP_TRACE_MGMT_PACKET_RECORD,
                           pHostapdAdapter->sessionId,
                           ADF_PROTO_TYPE_MGMT, ADF_PROTO_MGMT_ASSOC));

#ifdef FEATURE_BUS_BANDWIDTH
            /* start timer in sap/p2p_go */
            if (pHddApCtx->bApActive == VOS_FALSE)
            {
                SPIN_LOCK_BH(&pHddCtx->bus_bw_lock);
                pHostapdAdapter->prev_tx_packets = pHostapdAdapter->stats.tx_packets;
                pHostapdAdapter->prev_rx_packets = pHostapdAdapter->stats.rx_packets;
                tlshim_get_intra_bss_fwd_pkts_count(
                       pHostapdAdapter->sessionId,
                       &pHostapdAdapter->prev_fwd_tx_packets,
                       &pHostapdAdapter->prev_fwd_rx_packets);
                pHostapdAdapter->prev_tx_bytes =
                        pHostapdAdapter->stats.tx_bytes;
                SPIN_UNLOCK_BH(&pHddCtx->bus_bw_lock);
                hdd_start_bus_bw_compute_timer(pHostapdAdapter);
            }
#endif
            pHddApCtx->bApActive = VOS_TRUE;
            // Stop AP inactivity timer
            if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_RUNNING)
            {
                vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer);
                if (!VOS_IS_STATUS_SUCCESS(vos_status))
                   hddLog(LOGE, FL("Failed to start AP inactivity timer"));
            }
#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
            wlan_hdd_auto_shutdown_enable(pHddCtx, VOS_FALSE);
#endif
            vos_wake_lock_timeout_acquire(&pHddCtx->sap_wake_lock,
                                          HDD_SAP_WAKE_LOCK_DURATION,
                                          WIFI_POWER_EVENT_WAKELOCK_SAP);
            {
               v_U16_t iesLen =  event->iesLen;

               if (iesLen <= MAX_ASSOC_IND_IE_LEN )
               {
                  struct station_info *stainfo;
                  stainfo = vos_mem_malloc(sizeof(*stainfo));
                  if (stainfo == NULL) {
                      hddLog(LOGE, FL("alloc station_info failed"));
                      return VOS_STATUS_E_NOMEM;
                  }
                  memset(stainfo, 0, sizeof(*stainfo));
                  stainfo->assoc_req_ies =
                     (const u8 *)&event->ies[0];
                  stainfo->assoc_req_ies_len = iesLen;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0))
                  /*
                   * After Kernel 4.0, it's no longer need to set
                   * STATION_INFO_ASSOC_REQ_IES flag, as it
                   * changed to use assoc_req_ies_len length to
                   * check the existance of request IE.
                   */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,31)) || defined(WITH_BACKPORTS)
                  stainfo->filled |= STATION_INFO_ASSOC_REQ_IES;
#endif
#endif
                  cfg80211_new_sta(dev,
                        (const u8 *)&event->staMac.bytes[0],
                        stainfo, GFP_KERNEL);
                  vos_mem_free(stainfo);
               }
               else
               {
                  hddLog(LOGE, FL(" Assoc Ie length is too long"));
               }
            }

            pScanInfo =  &pHostapdAdapter->scan_info;
            // Lets do abort scan to ensure smooth authentication for client
            if ((pScanInfo != NULL) && pScanInfo->mScanPending)
            {
                hdd_abort_mac_scan(pHddCtx, pHostapdAdapter->sessionId,
                                   eCSR_SCAN_ABORT_DEFAULT);
            }
            if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
            {
                /* send peer status indication to oem app */
                hdd_SendPeerStatusIndToOemApp(
                    &event->staMac,
                    ePeerConnected,
                    event->timingMeasCap,
                    pHostapdAdapter->sessionId,
                    &event->chan_info,
                    pHostapdAdapter->device_mode);
            }

            hdd_wlan_green_ap_add_sta(pHddCtx);

            if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP &&
                !bAuthRequired  && bWPSState == eANI_BOOLEAN_FALSE) {
                    uint32_t sub20_channelwidth;

                    if (hdd_hostapd_sub20_channelwidth_can_switch(
                         pHostapdAdapter, &sub20_channelwidth))
                            WLANSAP_set_sub20_channelwidth_with_csa(
                                WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
                                sub20_channelwidth);
            }
            break;
        case eSAP_STA_DISASSOC_EVENT:
            memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac,
                   sizeof(v_MACADDR_t));
            hddLog(LOG1, " disassociated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data));

            vos_status = vos_event_set(&pHostapdState->sta_disassoc_event);
            if (!VOS_IS_STATUS_SUCCESS(vos_status))
                hddLog(VOS_TRACE_LEVEL_ERROR,
                        "ERROR: Station deauth event reporting failed!!");

            if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason == eSAP_USR_INITATED_DISASSOC)
                hddLog(LOG1," User initiated disassociation");
            else
                hddLog(LOG1," MAC initiated disassociation");
            we_event = IWEVEXPIRED;
            vos_status = hdd_softap_GetStaId(pHostapdAdapter, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac, &staId);
            if (!VOS_IS_STATUS_SUCCESS(vos_status))
            {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, FL("ERROR: HDD Failed to find sta id!!"));
                return VOS_STATUS_E_FAILURE;
            }
#ifdef IPA_OFFLOAD
            if (!pHddCtx->isLogpInProgress && hdd_ipa_is_enabled(pHddCtx))
            {
                status = hdd_ipa_wlan_evt(pHostapdAdapter, staId, WLAN_CLIENT_DISCONNECT,
                pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac.bytes);

                if (status)
                {
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                        ("ERROR: WLAN_CLIENT_DISCONNECT event failed!!"));
                    goto stopbss;
                }
            }
#endif
#ifdef QCA_PKT_PROTO_TRACE
            /* Peer dis-associated, update into trace buffer */
            if (pHddCtx->cfg_ini->gEnableDebugLog)
            {
               vos_pkt_trace_buf_update("HA:DISASC");
            }
#endif /* QCA_PKT_PROTO_TRACE */

            DPTRACE(adf_dp_trace_mgmt_pkt(ADF_DP_TRACE_MGMT_PACKET_RECORD,
                           pHostapdAdapter->sessionId,
                           ADF_PROTO_TYPE_MGMT, ADF_PROTO_MGMT_DISASSOC));

            hdd_softap_DeregisterSTA(pHostapdAdapter, staId);

            pHddApCtx->bApActive = VOS_FALSE;
            SPIN_LOCK_BH( &pHostapdAdapter->staInfo_lock );
            for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
            {
                if (pHostapdAdapter->aStaInfo[i].isUsed && i != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId)
                {
                    pHddApCtx->bApActive = VOS_TRUE;
                    break;
                }
            }
            SPIN_UNLOCK_BH( &pHostapdAdapter->staInfo_lock );

            // Start AP inactivity timer if no stations associated with it
            if ((0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff))
            {
                if (pHddApCtx->bApActive == FALSE)
                {
                    if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_STOPPED)
                    {
                        vos_status = vos_timer_start(&pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000);
                        if (!VOS_IS_STATUS_SUCCESS(vos_status))
                            hddLog(LOGE, FL("Failed to init AP inactivity timer"));
                    }
                    else
                        VOS_ASSERT(vos_timer_getCurrentState(&pHddApCtx->hdd_ap_inactivity_timer) == VOS_TIMER_STATE_STOPPED);
                }
            }
#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
            wlan_hdd_auto_shutdown_enable(pHddCtx, VOS_TRUE);
#endif

            if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.statusCode ==
                             eSIR_SME_SAP_AUTH_OFFLOAD_PEER_UPDATE_STATUS) {
                /** eSIR_SME_SAP_AUTH_OFFLOAD_PEER_UPDATE_STATUS indicates:
                 * The existing sta connection needs to be updated instead
                 * of clean up the sta. This condition could only happens
                 * when Host SAP sleep with WOW and SAP Auth offload enabled.
                 */

                hddLog(LOG1,"SAP peer update sta:Id=%d, Mac="MAC_ADDRESS_STR,
                    pSapEvent->sapevt.sapStationDisassocCompleteEvent.staId,
                    MAC_ADDR_ARRAY(pSapEvent->sapevt.
                    sapStationDisassocCompleteEvent.staMac.bytes));
            } else {
                hddLog(LOG1,"SAP del sta: staId=%d, staMac="MAC_ADDRESS_STR,
                    pSapEvent->sapevt.sapStationDisassocCompleteEvent.staId,
                    MAC_ADDR_ARRAY(pSapEvent->sapevt.
                    sapStationDisassocCompleteEvent.staMac.bytes));

                cfg80211_del_sta(dev,
                    (const u8 *)&pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac.bytes[0],
                    GFP_KERNEL);
            }

            //Update the beacon Interval if it is P2P GO
            vos_status = hdd_change_mcc_go_beacon_interval(pHostapdAdapter);
            if (VOS_STATUS_SUCCESS != vos_status)
            {
                hddLog(LOGE, "%s: failed to update Beacon interval %d",
                       __func__, vos_status);
            }
            if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
            {
                /* send peer status indication to oem app */
                hdd_SendPeerStatusIndToOemApp(
                  &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac,
                  ePeerDisconnected, 0,
                  pHostapdAdapter->sessionId, NULL,
                  pHostapdAdapter->device_mode);
            }

#ifdef FEATURE_BUS_BANDWIDTH
            /*stop timer in sap/p2p_go */
            if (pHddApCtx->bApActive == FALSE)
            {
                SPIN_LOCK_BH(&pHddCtx->bus_bw_lock);
                pHostapdAdapter->prev_tx_packets = 0;
                pHostapdAdapter->prev_rx_packets = 0;
                pHostapdAdapter->prev_fwd_tx_packets = 0;
                pHostapdAdapter->prev_fwd_rx_packets = 0;
                pHostapdAdapter->prev_tx_bytes = 0;
                SPIN_UNLOCK_BH(&pHddCtx->bus_bw_lock);
                hdd_stop_bus_bw_compute_timer(pHostapdAdapter);
            }
#endif

            hdd_wlan_green_ap_del_sta(pHddCtx);

            break;
        case eSAP_WPS_PBC_PROBE_REQ_EVENT:
        {
                static const char * message ="MLMEWPSPBCPROBEREQ.indication";
                union iwreq_data wreq;

                down(&pHddApCtx->semWpsPBCOverlapInd);
                pHddApCtx->WPSPBCProbeReq.probeReqIELen = pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIELen;

                vos_mem_copy(pHddApCtx->WPSPBCProbeReq.probeReqIE, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIE,
                    pHddApCtx->WPSPBCProbeReq.probeReqIELen);

                vos_mem_copy(pHddApCtx->WPSPBCProbeReq.peerMacAddr, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.peerMacAddr, sizeof(v_MACADDR_t));
                hddLog(LOG1, "WPS PBC probe req "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pHddApCtx->WPSPBCProbeReq.peerMacAddr));
                memset(&wreq, 0, sizeof(wreq));
                wreq.data.length = strlen(message); // This is length of message
                wireless_send_event(dev, IWEVCUSTOM, &wreq, (char *)message);

                return VOS_STATUS_SUCCESS;
        }
        case eSAP_ASSOC_STA_CALLBACK_EVENT:
            pAssocStasArray = pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas;
            if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0)
            {   // List of associated stations
                for (i = 0; i < pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta; i++)
                {
                    hddLog(LOG1,"Associated Sta Num %d:assocId=%d, staId=%d, staMac="MAC_ADDRESS_STR,
                        i+1,
                        pAssocStasArray->assocId,
                        pAssocStasArray->staId,
                                    MAC_ADDR_ARRAY(pAssocStasArray->staMac.bytes));
                        pAssocStasArray++;
            }
            }
            vos_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas);// Release caller allocated memory here
            pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas = NULL;
            return VOS_STATUS_SUCCESS;
        case eSAP_REMAIN_CHAN_READY:
           hdd_remainChanReadyHandler( pHostapdAdapter );
           return VOS_STATUS_SUCCESS;
        case eSAP_UNKNOWN_STA_JOIN:
            snprintf(unknownSTAEvent, IW_CUSTOM_MAX, "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x",
                pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0],
                pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1],
                pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2],
                pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3],
                pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4],
                pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]);
            we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
            wrqu.data.pointer = unknownSTAEvent;
            wrqu.data.length = strlen(unknownSTAEvent);
            we_custom_event_generic = (v_BYTE_t *)unknownSTAEvent;
            hddLog(LOGE,"%s", unknownSTAEvent);
            break;

        case eSAP_MAX_ASSOC_EXCEEDED:
            snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX, "Peer %02x:%02x:%02x:%02x:%02x:%02x denied"
                    " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect"
                    " one or more devices to enable the new device connection",
                    pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0],
                    pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1],
                    pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2],
                    pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3],
                    pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4],
                    pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[5]);
            we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
            wrqu.data.pointer = maxAssocExceededEvent;
            wrqu.data.length = strlen(maxAssocExceededEvent);
            we_custom_event_generic = (v_BYTE_t *)maxAssocExceededEvent;
            hddLog(LOG1,"%s", maxAssocExceededEvent);
            break;
        case eSAP_STA_ASSOC_IND:
            return VOS_STATUS_SUCCESS;

        case eSAP_DISCONNECT_ALL_P2P_CLIENT:
            hddLog(LOG1, FL(" Disconnecting all the P2P Clients...."));
            hdd_clear_all_sta(pHostapdAdapter, usrDataForCallback);
            return VOS_STATUS_SUCCESS;

        case eSAP_MAC_TRIG_STOP_BSS_EVENT :
            vos_status = hdd_stop_bss_link(pHostapdAdapter, usrDataForCallback);
            if (!VOS_IS_STATUS_SUCCESS(vos_status))
                hddLog(LOGW, FL("hdd_stop_bss_link failed %d"), vos_status);

            return VOS_STATUS_SUCCESS;

        case eSAP_CHANNEL_CHANGE_EVENT:
            hddLog(LOG1, FL("Received eSAP_CHANNEL_CHANGE_EVENT event"));
            if (pHostapdState->bssState != BSS_STOP) {
                /* Prevent suspend for new channel */
                hdd_hostapd_channel_prevent_suspend(pHostapdAdapter,
                        pSapEvent->sapevt.sapChSelected.pri_ch);
                /* Allow suspend for old channel */
                hdd_hostapd_channel_allow_suspend(pHostapdAdapter,
                        pHddApCtx->operatingChannel);
            }
            /* SME/PE is already updated for new operation channel. So update
             * HDD layer also here. This resolves issue in AP-AP mode where
             * AP1 channel is changed due to RADAR then CAC is going on and
             * START_BSS on new channel has not come to HDD. At this case if
             * AP2 is start it needs current operation channel for MCC DFS
             * restiction
             */
            pHddApCtx->operatingChannel =
                 pSapEvent->sapevt.sapChSelected.pri_ch;
            pHddApCtx->sapConfig.acs_cfg.pri_ch =
                 pSapEvent->sapevt.sapChSelected.pri_ch;
            pHddApCtx->sapConfig.acs_cfg.ht_sec_ch =
                 pSapEvent->sapevt.sapChSelected.ht_sec_ch;
            pHddApCtx->sapConfig.acs_cfg.vht_seg0_center_ch =
                 pSapEvent->sapevt.sapChSelected.vht_seg0_center_ch;
            pHddApCtx->sapConfig.acs_cfg.vht_seg1_center_ch =
                 pSapEvent->sapevt.sapChSelected.vht_seg1_center_ch;
            pHddApCtx->sapConfig.acs_cfg.ch_width =
                 pSapEvent->sapevt.sapChSelected.ch_width;

            /* Indicate operating channel change to hostapd
             * only for non driver override acs
             */
            if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP &&
                                               pHddCtx->cfg_ini->force_sap_acs)
                return VOS_STATUS_SUCCESS;
            else
                return hdd_chan_change_notify(pHostapdAdapter, dev,
                           pSapEvent->sapevt.sapChSelected.pri_ch);
        case eSAP_ACS_SCAN_SUCCESS_EVENT:
            return hdd_handle_acs_scan_event(pSapEvent, pHostapdAdapter);
        case eSAP_DFS_NOL_GET:
            hddLog(VOS_TRACE_LEVEL_INFO,
                    FL("Received eSAP_DFS_NOL_GET event"));
            /* get the dfs nol from cnss */
            return hdd_wlan_get_dfs_nol(
                      pSapEvent->sapevt.sapDfsNolInfo.pDfsList,
                      pSapEvent->sapevt.sapDfsNolInfo.sDfsList);
        case eSAP_DFS_NOL_SET:
            hddLog(VOS_TRACE_LEVEL_INFO, FL("Received eSAP_DFS_NOL_SET event"));
            /* set the dfs nol to cnss */
            return hdd_wlan_set_dfs_nol(
                    pSapEvent->sapevt.sapDfsNolInfo.pDfsList,
                    pSapEvent->sapevt.sapDfsNolInfo.sDfsList);
        case eSAP_ACS_CHANNEL_SELECTED:
            hddLog(LOG1, FL("ACS Completed for wlan%d"),
                                              pHostapdAdapter->dev->ifindex);
            clear_bit(ACS_PENDING, &pHostapdAdapter->event_flags);
            clear_bit(ACS_IN_PROGRESS, &pHddCtx->g_event_flags);
            pHddApCtx->sapConfig.acs_cfg.pri_ch =
                 pSapEvent->sapevt.sapChSelected.pri_ch;
            pHddApCtx->sapConfig.acs_cfg.ht_sec_ch =
                 pSapEvent->sapevt.sapChSelected.ht_sec_ch;
            pHddApCtx->sapConfig.acs_cfg.vht_seg0_center_ch =
                 pSapEvent->sapevt.sapChSelected.vht_seg0_center_ch;
            pHddApCtx->sapConfig.acs_cfg.vht_seg1_center_ch =
                 pSapEvent->sapevt.sapChSelected.vht_seg1_center_ch;
            pHddApCtx->sapConfig.acs_cfg.ch_width =
                 pSapEvent->sapevt.sapChSelected.ch_width;
            /* send vendor event to hostapd only for hostapd based acs */
            if (!test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) {
                if (!pHddCtx->cfg_ini->force_sap_acs)
                    wlan_hdd_cfg80211_acs_ch_select_evt(pHostapdAdapter);
            } else {
                pHddApCtx->sapConfig.channel =
                    pHddApCtx->sapConfig.backup_channel;
            }

            return VOS_STATUS_SUCCESS;
        case eSAP_ECSA_CHANGE_CHAN_IND:
            hddLog(LOG1,
              FL("Channel change indication from peer for channel %d"),
                            pSapEvent->sapevt.sap_chan_cng_ind.new_chan);
            if (hdd_softap_set_channel_change(dev,
                 pSapEvent->sapevt.sap_chan_cng_ind.new_chan))
                return VOS_STATUS_E_FAILURE;
            else
                return VOS_STATUS_SUCCESS;
        default:
            hddLog(LOG1,"SAP message is not handled");
            goto stopbss;
            return VOS_STATUS_SUCCESS;
    }
    wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
    return VOS_STATUS_SUCCESS;

stopbss :
    {
        v_BYTE_t we_custom_event[64];
        char *stopBssEvent = "STOP-BSS.response";//17
        int event_len = strlen(stopBssEvent);

        hddLog(LOG1, FL("BSS stop status = %s"),
               pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
                            "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");

        /* Change the BSS state now since, as we are shutting things down,
         * we don't want interfaces to become re-enabled */
        pHostapdState->bssState = BSS_STOP;

        if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
        {
            if (VOS_TIMER_STATE_RUNNING == pHddApCtx->hdd_ap_inactivity_timer.state)
            {
                vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer);
                if (!VOS_IS_STATUS_SUCCESS(vos_status))
                    hddLog(LOGE, FL("Failed to stop AP inactivity timer"));
            }

            vos_status = vos_timer_destroy(&pHddApCtx->hdd_ap_inactivity_timer);
            if (!VOS_IS_STATUS_SUCCESS(vos_status))
                hddLog(LOGE, FL("Failed to Destroy AP inactivity timer"));
        }
#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
        wlan_hdd_auto_shutdown_enable(pHddCtx, VOS_TRUE);
#endif

        /* Stop the pkts from n/w stack as we are going to free all of
         * the TX WMM queues for all STAID's */

       /*
        * If channel avoidance is in progress means driver is performing SAP
        * restart. So don't do carrier off, which may lead framework to do
        * driver reload.
        */
        hddLog(LOG1, FL("ch avoid in progress: %d"),
                        pHddCtx->is_ch_avoid_in_progress);
        if (pHddCtx->is_ch_avoid_in_progress)
            wlan_hdd_netif_queue_control(pHostapdAdapter, WLAN_NETIF_TX_DISABLE,
                                         WLAN_CONTROL_PATH);
        else
            hdd_hostapd_stop(dev);

        /* reclaim all resources allocated to the BSS */
        vos_status = hdd_softap_stop_bss(pHostapdAdapter);
        if (!VOS_IS_STATUS_SUCCESS(vos_status))
            hddLog(LOGW, FL("hdd_softap_stop_bss failed %d"), vos_status);

        /* once the event is set, structure dev/pHostapdAdapter should
         * not be touched since they are now subject to being deleted
         * by another thread */
        if (eSAP_STOP_BSS_EVENT == sapEvent)
            vos_event_set(&pHostapdState->stop_bss_event);

        /* Notify user space that the BSS has stopped */
        memset(&we_custom_event, '\0', sizeof(we_custom_event));
        memcpy(&we_custom_event, stopBssEvent, event_len);
        memset(&wrqu, 0, sizeof(wrqu));
        wrqu.data.length = event_len;
        we_event = IWEVCUSTOM;
        we_custom_event_generic = we_custom_event;
        wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic);
        hdd_dump_concurrency_info(pHddCtx);
    }
    return VOS_STATUS_SUCCESS;
}

int hdd_softap_unpackIE(
                tHalHandle halHandle,
                eCsrEncryptionType *pEncryptType,
                eCsrEncryptionType *mcEncryptType,
                eCsrAuthType *pAuthType,
                v_BOOL_t *pMFPCapable,
                v_BOOL_t *pMFPRequired,
                u_int16_t gen_ie_len,
                u_int8_t *gen_ie )
{
    tDot11fIERSN dot11RSNIE;
    tDot11fIEWPA dot11WPAIE;

    tANI_U8 *pRsnIe;
    tANI_U16 RSNIeLen;

    if (NULL == halHandle)
    {
        hddLog(LOGE, FL("Error haHandle returned NULL"));
        return -EINVAL;
    }

    // Validity checks
    if ((gen_ie_len < VOS_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN)) ||
        (gen_ie_len > VOS_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)) )
        return -EINVAL;
    // Type check
    if ( gen_ie[0] ==  DOT11F_EID_RSN)
    {
        // Validity checks
        if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN ) ||
            (gen_ie_len > DOT11F_IE_RSN_MAX_LEN) )
        {
            return VOS_STATUS_E_FAILURE;
        }
        // Skip past the EID byte and length byte
        pRsnIe = gen_ie + 2;
        RSNIeLen = gen_ie_len - 2;
        // Unpack the RSN IE
        memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
        dot11fUnpackIeRSN((tpAniSirGlobal) halHandle,
                            pRsnIe,
                            RSNIeLen,
                            &dot11RSNIE);
        // Copy out the encryption and authentication types
        hddLog(LOG1, FL("%s: pairwise cipher suite count: %d"),
                __func__, dot11RSNIE.pwise_cipher_suite_count );
        hddLog(LOG1, FL("%s: authentication suite count: %d"),
                __func__, dot11RSNIE.akm_suite_count);
        /*Here we have followed the apple base code,
          but probably I suspect we can do something different*/
        //dot11RSNIE.akm_suite_count
        // Just translate the FIRST one
        *pAuthType =  hdd_TranslateRSNToCsrAuthType(dot11RSNIE.akm_suites[0]);
        //dot11RSNIE.pwise_cipher_suite_count
        *pEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.pwise_cipher_suites[0]);
        //dot11RSNIE.gp_cipher_suite_count
        *mcEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.gp_cipher_suite);
        // Set the PMKSA ID Cache for this interface
        *pMFPCapable = 0 != (dot11RSNIE.RSN_Cap[0] & 0x80);
        *pMFPRequired = 0 != (dot11RSNIE.RSN_Cap[0] & 0x40);
        // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
    } else
    if (gen_ie[0] == DOT11F_EID_WPA)
    {
        // Validity checks
        if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN ) ||
            (gen_ie_len > DOT11F_IE_WPA_MAX_LEN))
        {
            return VOS_STATUS_E_FAILURE;
        }
        // Skip past the EID byte and length byte - and four byte WiFi OUI
        pRsnIe = gen_ie + 2 + 4;
        RSNIeLen = gen_ie_len - (2 + 4);
        // Unpack the WPA IE
        memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
        dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
                            pRsnIe,
                            RSNIeLen,
                            &dot11WPAIE);
        // Copy out the encryption and authentication types
        hddLog(LOG1, FL("%s: WPA unicast cipher suite count: %d"),
                __func__, dot11WPAIE.unicast_cipher_count );
        hddLog(LOG1, FL("%s: WPA authentication suite count: %d"),
                __func__, dot11WPAIE.auth_suite_count);
        //dot11WPAIE.auth_suite_count
        // Just translate the FIRST one
        *pAuthType =  hdd_TranslateWPAToCsrAuthType(dot11WPAIE.auth_suites[0]);
        //dot11WPAIE.unicast_cipher_count
        *pEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.unicast_ciphers[0]);
        //dot11WPAIE.unicast_cipher_count
        *mcEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
        *pMFPCapable = VOS_FALSE;
        *pMFPRequired = VOS_FALSE;
    }
    else
    {
        hddLog(LOGW, FL("%s: gen_ie[0]: %d"), __func__, gen_ie[0]);
        return VOS_STATUS_E_FAILURE;
    }
    return VOS_STATUS_SUCCESS;
}

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

  \brief hdd_softap_set_channel_change() -
   This function to support SAP channel change with CSA IE
   set in the beacons.

  \param  - dev - Pointer to the net device.
          - target_channel - target channel number.
  \return - 0 for success, non zero for failure

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

int hdd_softap_set_channel_change(struct net_device *dev, int target_channel)
{
    VOS_STATUS status;
    int ret = 0;
    hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
    hdd_context_t *pHddCtx = NULL;
    hdd_adapter_t *sta_adapter = NULL;
    hdd_station_ctx_t *sta_ctx;

#ifndef WLAN_FEATURE_MBSSID
    v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
#endif

    pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
    ret = wlan_hdd_validate_context(pHddCtx);
    if (ret)
        return ret;

    sta_adapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
    /*
     * conc_custom_rule1:
     * Force SCC for SAP + STA
     * if STA is already connected then we shouldn't allow
     * channel switch in SAP interface
     */
    if (sta_adapter && pHddCtx->cfg_ini->conc_custom_rule1)
    {
        sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
        if (hdd_connIsConnected(sta_ctx))
        {
            hddLog(LOGE, FL("Channel switch not allowed after STA connection with conc_custom_rule1 enabled"));
            return -EBUSY;
        }
    }

    SPIN_LOCK_BH(&pHddCtx->dfs_lock);
    if (pHddCtx->dfs_radar_found == VOS_TRUE)
    {
        SPIN_UNLOCK_BH(&pHddCtx->dfs_lock);
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Channel switch in progress!!",
               __func__);
        ret = -EBUSY;
        return ret;
    }
    /*
     * Set the dfs_radar_found flag to mimic channel change
     * when a radar is found. This will enable synchronizing
     * SAP and HDD states similar to that of radar indication.
     * Suspend the netif queues to stop queuing Tx frames
     * from upper layers.  netif queues will be resumed
     * once the channel change is completed and SAP will
     * post eSAP_START_BSS_EVENT success event to HDD.
     */
    pHddCtx->dfs_radar_found = VOS_TRUE;

    SPIN_UNLOCK_BH(&pHddCtx->dfs_lock);
    /*
     * Post the Channel Change request to SAP.
     */
    status = WLANSAP_SetChannelChangeWithCsa(
#ifdef WLAN_FEATURE_MBSSID
                WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
#else
                pVosContext,
#endif
                (v_U32_t) target_channel);

    if (VOS_STATUS_SUCCESS != status)
    {
         hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: SAP set channel failed for channel = %d",
                 __func__, target_channel);
        /*
         * If channel change command fails then clear the
         * radar found flag and also restart the netif
         * queues.
         */

        SPIN_LOCK_BH(&pHddCtx->dfs_lock);
        pHddCtx->dfs_radar_found = VOS_FALSE;
        SPIN_UNLOCK_BH(&pHddCtx->dfs_lock);

        ret = -EINVAL;
    }

    return ret;
}

#ifdef FEATURE_WLAN_SUB_20_MHZ
/**
 * hdd_softap_set_channel_sub20_chanwidth_change() -This
 * function to support SAP channel change with CSA IE
 * set in the beacons.
 * @dev: Pointer to the net device
 * @chan_width: new sub20 channel width
 *
 * Return:  true or false
 */
int hdd_softap_set_channel_sub20_chanwidth_change(struct net_device *dev,
						  uint32_t chan_width)
{
	VOS_STATUS status;
	int ret;
	hdd_adapter_t *hostapd_adapter = (netdev_priv(dev));
	hdd_context_t *hdd_ctx_ptr;
	hdd_adapter_t *sta_adapter;
	hdd_station_ctx_t *sta_ctx;
	uint32_t sub20_chan_width;
	bool sub20_operate_permission;
	void *vos_ctx_ptr;

	hdd_ctx_ptr = WLAN_HDD_GET_CTX(hostapd_adapter);
	ret = wlan_hdd_validate_context(hdd_ctx_ptr);
	if (ret)
		return ret;

	sta_adapter = hdd_get_adapter(hdd_ctx_ptr, WLAN_HDD_INFRA_STATION);
	/*
	 * conc_custom_rule1:
	 * Force SCC for SAP + STA
	 * if STA is already connected then we shouldn't allow
	 * channel switch in SAP interface
	 */
	if (sta_adapter && hdd_ctx_ptr->cfg_ini->conc_custom_rule1) {
		sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
		if (hdd_connIsConnected(sta_ctx)) {
			hddLog(LOGE,
			       FL("sub20 chan switch not allowed"));
			return -EBUSY;
		}
	}

	switch (chan_width) {
	case NL80211_CHAN_WIDTH_5:
		sub20_chan_width = SUB20_MODE_5MHZ;
		break;
	case NL80211_CHAN_WIDTH_10:
		sub20_chan_width = SUB20_MODE_10MHZ;
		break;
	case NL80211_CHAN_WIDTH_20_NOHT:
		sub20_chan_width = SUB20_MODE_NONE;
		break;
	default:
		hddLog(LOGE, FL("invalid param %d"), chan_width);
		return -EINVAL;
	}

	sub20_operate_permission =
		hdd_sub20_channelwidth_can_set(hostapd_adapter,
					       sub20_chan_width);
	if (!sub20_operate_permission) {
		hddLog(LOGE, FL("can't set sub20_chan_width in curr chan"));
		return -EINVAL;
	}

	spin_lock_bh(&hdd_ctx_ptr->dfs_lock);
	if (hdd_ctx_ptr->dfs_radar_found == VOS_TRUE) {
		spin_unlock_bh(&hdd_ctx_ptr->dfs_lock);
		hddLog(LOGE,
		       FL("sub20 chan width switch in progress!!"));
		return -EBUSY;
	}
	/*
	 * Set the dfs_radar_found flag to mimic channel change
	 * when a radar is found. This will enable synchronizing
	 * SAP and HDD states similar to that of radar indication.
	 * Suspend the netif queues to stop queuing Tx frames
	 * from upper layers.  netif queues will be resumed
	 * once the channel change is completed and SAP will
	 * post eSAP_START_BSS_EVENT success event to HDD.
	 */
	hdd_ctx_ptr->dfs_radar_found = VOS_TRUE;
	spin_unlock_bh(&hdd_ctx_ptr->dfs_lock);

	vos_ctx_ptr = WLAN_HDD_GET_SAP_CTX_PTR(hostapd_adapter);
	status = WLANSAP_set_sub20_channelwidth_with_csa(vos_ctx_ptr,
							 sub20_chan_width);
	if (VOS_STATUS_SUCCESS != status) {
		hddLog(LOGE,
		       FL("sub20 chan width %d switch failed"),
		       sub20_chan_width);
		/*
		 * If channel change command fails then clear the
		 * radar found flag and also restart the netif
		 * queues.
		 */
		spin_lock_bh(&hdd_ctx_ptr->dfs_lock);
		hdd_ctx_ptr->dfs_radar_found = VOS_FALSE;
		spin_unlock_bh(&hdd_ctx_ptr->dfs_lock);

		ret = -EINVAL;
	}

	return ret;
}
#endif

/**
 * hdd_sap_get_chan_width() - get channel width of sap
 * @adapter: adapter being queried
 * @value: where to store the value
 *
 * Return: 0 on success, negative errno on failure
 */
static int hdd_sap_get_chan_width(hdd_adapter_t *adapter, int *value)
{
	void *pvosctx;
	uint32_t vht_channel_width = 0;
	hdd_context_t *hdd_ctx;
	hdd_hostapd_state_t *phostapdstate;

	ENTER();
	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	phostapdstate = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);

	if (phostapdstate->bssState != BSS_START) {
		*value = -EINVAL;
		return -EINVAL;
	}

#ifdef WLAN_FEATURE_MBSSID
	pvosctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter);
#else
	pvosctx = hdd_ctx->pvosContext;
#endif

	wlansap_get_chan_width(pvosctx, &vht_channel_width);
	*value = vht_channel_width;
	hddLog(LOGW, FL("chan_width = %d"), vht_channel_width);

	return 0;
}

int
static __iw_softap_set_ini_cfg(struct net_device *dev,
                          struct iw_request_info *info,
                          union iwreq_data *wrqu, char *extra)
{
    VOS_STATUS vstatus;
    int errno;
    hdd_adapter_t *adapter;
    hdd_context_t *hdd_ctx;
    char *value;
    size_t len;

    ENTER();

    adapter = netdev_priv(dev);
    if (adapter == NULL)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                                        "%s: adapter is NULL!", __func__);
        return -EINVAL;
    }

    hdd_ctx = WLAN_HDD_GET_CTX(adapter);
    errno = wlan_hdd_validate_context(hdd_ctx);
    if (errno != 0)
        return errno;

    /* ensure null termination */
    len = min_t(size_t, wrqu->data.length, QCSAP_IOCTL_MAX_STR_LEN);
    value = vos_mem_malloc(len + 1);
    if (!value)
        return -ENOMEM;

    vos_mem_copy(value, extra, len);
    value[len] = '\0';
    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
              "%s: Received data %s", __func__, value);

    vstatus = hdd_execute_global_config_command(hdd_ctx, value);
#ifdef WLAN_FEATURE_MBSSID
    if (vstatus == VOS_STATUS_E_PERM) {
        vstatus = hdd_execute_sap_dyn_config_command(adapter, value);
        if (vstatus == VOS_STATUS_SUCCESS)
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                   "%s: Stored in Dynamic SAP ini config", __func__);
    }
#endif
    vos_mem_free(value);

    EXIT();

    return vos_status_to_os_return(vstatus);
}

int
static iw_softap_set_ini_cfg(struct net_device *dev,
                             struct iw_request_info *info,
                             union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_softap_set_ini_cfg(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

int
static __iw_softap_get_ini_cfg(struct net_device *dev,
                             struct iw_request_info *info,
                             union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx;
    int ret = 0;

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    ret = wlan_hdd_validate_context(pHddCtx);
    if (ret != 0)
        return ret;

#ifdef WLAN_FEATURE_MBSSID
    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                   "%s: Printing Adapter MBSSID SAP Dyn INI Config", __func__);
    hdd_cfg_get_sap_dyn_config(pAdapter, extra, QCSAP_IOCTL_MAX_STR_LEN);
    /* Overwrite extra buffer with global ini config if need to return in buf */
#endif
    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                   "%s: Printing CLD global INI Config", __func__);
    hdd_cfg_get_global_config(pHddCtx, extra, QCSAP_IOCTL_MAX_STR_LEN);
    wrqu->data.length = strlen(extra)+1;

    return 0;
}

int
static iw_softap_get_ini_cfg(struct net_device *dev,
                             struct iw_request_info *info,
                             union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_softap_get_ini_cfg(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

static int __iw_softap_set_two_ints_getnone(struct net_device *dev,
                                            struct iw_request_info *info,
                                            union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx;
    int *value = (int *)extra;
    int sub_cmd = value[0];
    int ret = 0;

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    ret = wlan_hdd_validate_context(pHddCtx);
    if (ret != 0)
        goto out;

    switch(sub_cmd) {
#ifdef WLAN_DEBUG
    case QCSAP_IOCTL_SET_FW_CRASH_INJECT:
        hddLog(LOGE, "WE_SET_FW_CRASH_INJECT: %d %d", value[1], value[2]);
        if (!pHddCtx->cfg_ini->crash_inject_enabled) {
            hddLog(LOGE, "Crash Inject ini disabled, Ignore Crash Inject");
            return 0;
        }
        ret = process_wma_set_command_twoargs((int) pAdapter->sessionId,
                                           (int) GEN_PARAM_CRASH_INJECT,
                                           value[1], value[2], GEN_CMD);
        if (!ret)
            pHddCtx->isLogpInProgress = true;
        break;
#endif
    case QCSAP_IOCTL_DUMP_DP_TRACE_LEVEL:
        hddLog(LOG1, "WE_DUMP_DP_TRACE: %d %d",
            value[1], value[2]);
        if (value[1] == DUMP_DP_TRACE)
            adf_dp_trace_dump_all(value[2]);
        else if (value[1] == ENABLE_DP_TRACE_LIVE_MODE)
            adf_dp_trace_enable_live_mode();
        else if (value[1] == CLEAR_DP_TRACE_BUFFER)
            adf_dp_trace_clear_buffer();
        else
            hddLog(LOGE, "unexpected value for dump_dp_trace");
        break;
    default:
        hddLog(LOGE, "%s: Invalid IOCTL command %d", __func__, sub_cmd);
        break;
    }

out:
    return ret;
}

static int iw_softap_set_two_ints_getnone(struct net_device *dev,
                                          struct iw_request_info *info,
                                          union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_softap_set_two_ints_getnone(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

int
static __iw_softap_wowl_config_pattern(struct net_device *dev,
                                       struct iw_request_info *info,
                                       union iwreq_data *wrqu, char *extra)
{
    int sub_cmd;
    int ret = 0; /* success */
    char *pBuffer = NULL;
    hdd_adapter_t *pAdapter = (netdev_priv(dev));
    struct iw_point s_priv_data;

    if (!capable(CAP_NET_ADMIN)) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  FL("permission check failed"));
        return -EPERM;
    }

    if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                  "%s:LOGP in Progress. Ignore!!!", __func__);
        return -EBUSY;
    }

    /* helper function to get iwreq_data with compat handling. */
    if (hdd_priv_get_data(&s_priv_data, wrqu)) {
        return -EINVAL;
    }

    /* make sure all params are correctly passed to function */
    if ((NULL == s_priv_data.pointer) || (0 == s_priv_data.length)) {
        return -EINVAL;
    }

    sub_cmd = s_priv_data.flags;

    /* ODD number is used for set, copy data using copy_from_user */
    pBuffer = mem_alloc_copy_from_user_helper(s_priv_data.pointer,
                                              s_priv_data.length);
    if (NULL == pBuffer)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "mem_alloc_copy_from_user_helper fail");
        return -ENOMEM;
    }

    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
              "%s: Received length %d", __func__, s_priv_data.length);
    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
              "%s: Received data %s", __func__, pBuffer);

    switch(sub_cmd)
    {
    case WE_WOWL_ADD_PTRN:
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "ADD_PTRN");
        hdd_add_wowl_ptrn(pAdapter, pBuffer);
        break;
    case WE_WOWL_DEL_PTRN:
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "DEL_PTRN");
        hdd_del_wowl_ptrn(pAdapter, pBuffer);
        break;
    default:
        hddLog(LOGE, "%s: Invalid sub command %d", __func__, sub_cmd);
        ret = -EINVAL;
        break;
    }
    vos_mem_free(pBuffer);
    return ret;
}

int
static iw_softap_wowl_config_pattern(struct net_device *dev,
                                     struct iw_request_info *info,
                                     union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_softap_wowl_config_pattern(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

static void print_mac_list(v_MACADDR_t *macList, v_U8_t size)
{
    int i;
    v_BYTE_t *macArray;

    for (i = 0; i < size; i++) {
        macArray = (macList + i)->bytes;
        pr_info("** ACL entry %i - %02x:%02x:%02x:%02x:%02x:%02x \n",
                                          i, MAC_ADDR_ARRAY(macArray));
    }
    return;
}

static VOS_STATUS hdd_print_acl(hdd_adapter_t *pHostapdAdapter)
{
    eSapMacAddrACL acl_mode;
    v_MACADDR_t MacList[MAX_ACL_MAC_ADDRESS];
    v_U8_t listnum;
    v_PVOID_t pvosGCtx = NULL;

#ifdef WLAN_FEATURE_MBSSID
    pvosGCtx = WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter);
#else
    pvosGCtx = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
#endif
    vos_mem_zero(&MacList[0], sizeof(MacList));
    if (VOS_STATUS_SUCCESS == WLANSAP_GetACLMode(pvosGCtx, &acl_mode)) {
        pr_info("******** ACL MODE *********\n");
        switch (acl_mode) {
        case eSAP_ACCEPT_UNLESS_DENIED:
            pr_info("ACL Mode = ACCEPT_UNLESS_DENIED\n");
            break;
        case eSAP_DENY_UNLESS_ACCEPTED:
            pr_info("ACL Mode = DENY_UNLESS_ACCEPTED\n");
            break;
        case eSAP_SUPPORT_ACCEPT_AND_DENY:
            pr_info("ACL Mode = ACCEPT_AND_DENY\n");
            break;
        case eSAP_ALLOW_ALL:
            pr_info("ACL Mode = ALLOW_ALL\n");
            break;
        default:
            pr_info("Invalid SAP ACL Mode = %d\n", acl_mode);
            return VOS_STATUS_E_FAILURE;
        }
    } else {
        return VOS_STATUS_E_FAILURE;
    }

    if (VOS_STATUS_SUCCESS == WLANSAP_GetACLAcceptList(pvosGCtx,
                                                       &MacList[0], &listnum)) {
        pr_info("******* WHITE LIST ***********\n");
        if (listnum <= MAX_ACL_MAC_ADDRESS)
            print_mac_list(&MacList[0], listnum);
    } else {
        return VOS_STATUS_E_FAILURE;
    }

    if (VOS_STATUS_SUCCESS == WLANSAP_GetACLDenyList(pvosGCtx,
                                                     &MacList[0], &listnum)) {
        pr_info("******* BLACK LIST ***********\n");
        if (listnum <= MAX_ACL_MAC_ADDRESS)
            print_mac_list(&MacList[0], listnum);
    } else {
        return VOS_STATUS_E_FAILURE;
    }
    return VOS_STATUS_SUCCESS;
}

int
static __iw_softap_setparam(struct net_device *dev,
                            struct iw_request_info *info,
                            union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
    tHalHandle hHal;
    int *value = (int *)extra;
    int sub_cmd = value[0];
    int set_value = value[1];
    eHalStatus status;
    int ret = 0; /* success */
    v_CONTEXT_t pVosContext;
    hdd_context_t *pHddCtx = NULL;

    ENTER();

    if (NULL == pHostapdAdapter) {
       hddLog(LOGE, FL("hostapd Adapter is null"));
       return -EINVAL;
    }

    pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
    ret = wlan_hdd_validate_context(pHddCtx);
    if (0 != ret)
        return -EINVAL;

    hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
    if (!hHal) {
       hddLog(LOGE, FL("Hal ctx is null"));
       return -EINVAL;
    }

    if (VOS_STATUS_SUCCESS != sme_is_session_valid(hHal,
                               pHostapdAdapter->sessionId)) {
       hddLog(LOGE, FL("session id is not valid %d"),
                   pHostapdAdapter->sessionId);
       return -EINVAL;
    }
    pVosContext = pHddCtx->pvosContext;
    if (!pVosContext) {
       hddLog(LOGE, FL("Vos ctx is null"));
       return -EINVAL;
    }

    switch(sub_cmd)
    {
        case QCASAP_SET_RADAR_DBG:
            hddLog(LOG1, FL("QCASAP_SET_RADAR_DBG called with: value: %d"),
                   set_value);
            sme_enable_phy_error_logs(hHal, (bool) set_value);
            break;

        case QCSAP_PARAM_CLR_ACL:
            if (VOS_STATUS_SUCCESS != WLANSAP_ClearACL(
#ifdef WLAN_FEATURE_MBSSID
                 WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter)
#else
                 pVosContext
#endif
            ))
            {
               ret = -EIO;
            }
            break;

        case QCSAP_PARAM_ACL_MODE:
            if ((eSAP_ALLOW_ALL < (eSapMacAddrACL)set_value) ||
                (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL)set_value))
            {
                hddLog(LOGE, FL("Invalid ACL Mode value %d"), set_value);
                ret = -EINVAL;
            }
            else
            {
#ifdef WLAN_FEATURE_MBSSID
                WLANSAP_SetMode(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter), set_value);
#else
                WLANSAP_SetMode(pVosContext, set_value);
#endif

            }
            break;

        case QCSAP_PARAM_AUTO_CHANNEL:
            if (set_value == 0 || set_value == 1)
                (WLAN_HDD_GET_CTX(
                           pHostapdAdapter))->cfg_ini->force_sap_acs =
                                                                     set_value;
            else
                ret = -EINVAL;
            break;

        case QCSAP_PARAM_SET_CHANNEL_CHANGE:
		if ((WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)||
		   (WLAN_HDD_P2P_GO == pHostapdAdapter->device_mode)) {
			hddLog(LOG1, "SET Channel Change to new channel= %d",
					set_value);
			ret = hdd_softap_set_channel_change(dev, set_value);
		} else {
			hddLog(LOGE,
			  FL("Channel Change Failed, Device in test mode"));
			ret = -EINVAL;
		}
		break;

        case QCSAP_PARAM_MAX_ASSOC:
            if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value)
            {
                hddLog(LOGE, FL("Invalid setMaxAssoc value %d"), set_value);
                ret = -EINVAL;
            }
            else
            {
                if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value)
                {
                    hddLog(LOGW, FL("setMaxAssoc value %d higher than max allowed %d."
                                "Setting it to max allowed and continuing"),
                                set_value, WNI_CFG_ASSOC_STA_LIMIT_STAMAX);
                    set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX;
                }
                status = ccmCfgSetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT,
                                      set_value, NULL, eANI_BOOLEAN_FALSE);
                if ( status != eHAL_STATUS_SUCCESS )
                {
                    hddLog(LOGE, FL("setMaxAssoc failure, status %d"),
                            status);
                    ret = -EIO;
                }
            }
            break;

        case QCSAP_PARAM_HIDE_SSID:
            {
                eHalStatus status = eHAL_STATUS_SUCCESS;
                status = sme_HideSSID(hHal, pHostapdAdapter->sessionId, set_value);
                if(eHAL_STATUS_SUCCESS != status)
                {
                    hddLog(VOS_TRACE_LEVEL_ERROR,
                            "%s: QCSAP_PARAM_HIDE_SSID failed",
                            __func__);
                    return status;
                }
                break;
            }
        case QCSAP_PARAM_SET_MC_RATE:
            {
                tSirRateUpdateInd rateUpdate = {0};
                hdd_config_t *pConfig = pHddCtx->cfg_ini;

                hddLog(VOS_TRACE_LEVEL_INFO, "MC Target rate %d", set_value);
                memcpy(rateUpdate.bssid,
                       pHostapdAdapter->macAddressCurrent.bytes,
                       sizeof(tSirMacAddr));
                rateUpdate.nss = (pConfig->enable2x2 == 0) ? 0 : 1;
                rateUpdate.dev_mode = pHostapdAdapter->device_mode;
                rateUpdate.mcastDataRate24GHz = set_value;
                rateUpdate.mcastDataRate24GHzTxFlag = 1;
                rateUpdate.mcastDataRate5GHz = set_value;
                rateUpdate.bcastDataRate = -1;
                if (sme_SendRateUpdateInd(hHal, &rateUpdate) !=
                                                     eHAL_STATUS_SUCCESS) {
                    hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SET_MC_RATE failed",
                                                                  __func__);
                    ret = -1;
                }
                break;
            }

         case QCSAP_PARAM_SET_TXRX_FW_STATS:
             {
                  hddLog(LOG1, "QCSAP_PARAM_SET_TXRX_FW_STATS val %d", set_value);
                  ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                               (int)WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID,
                                               set_value, VDEV_CMD);
                  break;
             }
         /* Firmware debug log */
         case QCSAP_DBGLOG_LOG_LEVEL:
             {
                  hddLog(LOG1, "QCSAP_DBGLOG_LOG_LEVEL val %d", set_value);
                  ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                               (int)WMI_DBGLOG_LOG_LEVEL,
                                               set_value, DBG_CMD);
                  break;
             }

         case QCSAP_DBGLOG_VAP_ENABLE:
             {
                  hddLog(LOG1, "QCSAP_DBGLOG_VAP_ENABLE val %d", set_value);
                  ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                               (int)WMI_DBGLOG_VAP_ENABLE,
                                               set_value, DBG_CMD);
                  break;
             }

         case QCSAP_DBGLOG_VAP_DISABLE:
             {
                  hddLog(LOG1, "QCSAP_DBGLOG_VAP_DISABLE val %d", set_value);
                  ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                               (int)WMI_DBGLOG_VAP_DISABLE,
                                               set_value, DBG_CMD);
                  break;
             }

         case QCSAP_DBGLOG_MODULE_ENABLE:
             {
                  hddLog(LOG1, "QCSAP_DBGLOG_MODULE_ENABLE val %d", set_value);
                  ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                               (int)WMI_DBGLOG_MODULE_ENABLE,
                                               set_value, DBG_CMD);
                  break;
             }

         case QCSAP_DBGLOG_MODULE_DISABLE:
             {
                  hddLog(LOG1, "QCSAP_DBGLOG_MODULE_DISABLE val %d", set_value);
                  ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                               (int)WMI_DBGLOG_MODULE_DISABLE,
                                               set_value, DBG_CMD);
                  break;
             }

         case QCSAP_DBGLOG_MOD_LOG_LEVEL:
             {
                  hddLog(LOG1, "QCSAP_DBGLOG_MOD_LOG_LEVEL val %d", set_value);
                  ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                               (int)WMI_DBGLOG_MOD_LOG_LEVEL,
                                               set_value, DBG_CMD);
                  break;
             }

         case QCSAP_DBGLOG_TYPE:
             {
                  hddLog(LOG1, "QCSAP_DBGLOG_TYPE val %d", set_value);
                  ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                               (int)WMI_DBGLOG_TYPE,
                                               set_value, DBG_CMD);
                  break;
             }
         case QCSAP_DBGLOG_REPORT_ENABLE:
             {
                  hddLog(LOG1, "QCSAP_DBGLOG_REPORT_ENABLE val %d", set_value);
                  ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                               (int)WMI_DBGLOG_REPORT_ENABLE,
                                               set_value, DBG_CMD);
                  break;
             }
         case QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY:
             {
                  tVOS_CONCURRENCY_MODE concurrent_state = 0;
                  v_U8_t first_adapter_operating_channel = 0;
                  int ret = 0; /* success */
                  hddLog(LOG1, "%s: iwpriv cmd to set MCC latency with val: "
                          "%dms", __func__, set_value);
                  concurrent_state = hdd_get_concurrency_mode();
                  /**
                   * Check if concurrency mode is active.
                   * Need to modify this code to support MCC modes other than
                   * STA/P2P GO
                   */
                  if (concurrent_state == (VOS_STA | VOS_P2P_GO))
                  {
                      hddLog(LOG1, "%s: STA & P2P are both enabled", __func__);
                      /**
                       * The channel number and latency are formatted in
                       * a bit vector then passed on to WMA layer.
                       +**********************************************+
                       | bits 31-16 | bits 15-8         |  bits 7-0   |
                       | Unused     | latency - Chan. 1 |  channel no.|
                       +**********************************************+
                       */

                      /* Get the operating channel of the designated vdev */
                      first_adapter_operating_channel =
                                    hdd_get_operating_channel
                                    (
                                    pHostapdAdapter->pHddCtx,
                                    pHostapdAdapter->device_mode
                                    );
                      /* Move the time latency for the adapter to bits 15-8 */
                      set_value = set_value << 8;
                      /* Store the channel number at bits 7-0 of the bit vector
                       * as per the bit format above.
                       */
                      set_value = set_value | first_adapter_operating_channel;
                      /* Send command to WMA */
                      ret = process_wma_set_command
                                        (
                                        (int)pHostapdAdapter->sessionId,
                                        (int)WMA_VDEV_MCC_SET_TIME_LATENCY,
                                        set_value, VDEV_CMD
                                        );
                  }
                  else
                  {
                      hddLog(LOG1, "%s: MCC is not active. Exit w/o setting"
                              " latency", __func__);
                  }
                  break;
             }

         case QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA:
             {
                 hddLog(LOG1, "%s: iwpriv cmd to set MCC quota value %dms",
                         __func__, set_value);
                 ret = hdd_wlan_go_set_mcc_p2p_quota(pHostapdAdapter,
                                                     set_value);
                 break;
             }

         case QCASAP_TXRX_FWSTATS_RESET:
             {
                  hddLog(LOG1, "WE_TXRX_FWSTATS_RESET val %d", set_value);
                  if (set_value != WMA_FW_TXRX_FWSTATS_RESET) {
                      hddLog(LOGE, "Invalid arg %d in FWSTATS_RESET IOCTL",
                             set_value);
                      return -EINVAL;
                  }
                  ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                                (int)WMA_VDEV_TXRX_FWSTATS_RESET_CMDID,
                                                set_value, VDEV_CMD);
                  break;
             }

         case QCSAP_PARAM_RTSCTS:
            {
                ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                (int)WMI_VDEV_PARAM_ENABLE_RTSCTS,
                                set_value, VDEV_CMD);
                if (ret) {
                    hddLog(LOGE, "FAILED TO SET RTSCTS at SAP");
                    ret = -EIO;
                }
                break;
            }
        case QCASAP_SET_11N_RATE:
            {
                u_int8_t preamble = 0, nss = 0, rix = 0;
                tsap_Config_t *pConfig =
                        &pHostapdAdapter->sessionCtx.ap.sapConfig;

                hddLog(LOG1, "WMI_VDEV_PARAM_FIXED_RATE val %d", set_value);

                if (set_value != 0xff) {
                    rix = RC_2_RATE_IDX(set_value);
                    if (set_value & 0x80) {
                        if (pConfig->SapHw_mode == eCSR_DOT11_MODE_11b ||
                            pConfig->SapHw_mode == eCSR_DOT11_MODE_11b_ONLY ||
                            pConfig->SapHw_mode == eCSR_DOT11_MODE_11g ||
                            pConfig->SapHw_mode == eCSR_DOT11_MODE_11g_ONLY ||
                            pConfig->SapHw_mode == eCSR_DOT11_MODE_abg ||
                            pConfig->SapHw_mode == eCSR_DOT11_MODE_11a) {
                            hddLog(LOGE, "Not valid mode for HT");
                            ret = -EIO;
                            break;
                        }
                        preamble = WMI_RATE_PREAMBLE_HT;
                        nss = HT_RC_2_STREAMS(set_value) - 1;
                    } else if (set_value & 0x10) {
                        if (pConfig->SapHw_mode == eCSR_DOT11_MODE_11a) {
                            hddLog(VOS_TRACE_LEVEL_ERROR, "Not valid for cck");
                            ret = -EIO;
                            break;
                        }
                        preamble = WMI_RATE_PREAMBLE_CCK;
                        /* Enable Short preamble always for CCK except 1mbps */
                        if (rix != 0x3)
                            rix |= 0x4;
                    } else {
                        if (pConfig->SapHw_mode == eCSR_DOT11_MODE_11b ||
                            pConfig->SapHw_mode == eCSR_DOT11_MODE_11b_ONLY) {
                            hddLog(VOS_TRACE_LEVEL_ERROR, "Not valid for OFDM");
                            ret = -EIO;
                            break;
                        }
                        preamble = WMI_RATE_PREAMBLE_OFDM;
                    }

                    set_value = (preamble << 6) | (nss << 4) | rix;
                }
                hddLog(LOG1, "WMI_VDEV_PARAM_FIXED_RATE val %d rix %d "
                    "preamble %x nss %d", set_value, rix, preamble, nss);
                ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                              (int)WMI_VDEV_PARAM_FIXED_RATE,
                                              set_value, VDEV_CMD);
                break;
            }

        case QCASAP_SET_VHT_RATE:
            {
                u_int8_t preamble = 0, nss = 0, rix = 0;
                tsap_Config_t *pConfig =
                    &pHostapdAdapter->sessionCtx.ap.sapConfig;

                if (pConfig->SapHw_mode != eCSR_DOT11_MODE_11ac &&
                    pConfig->SapHw_mode != eCSR_DOT11_MODE_11ac_ONLY) {
                    hddLog(VOS_TRACE_LEVEL_ERROR,
                        "%s: SET_VHT_RATE error: SapHw_mode= 0x%x, ch = %d",
                        __func__, pConfig->SapHw_mode, pConfig->channel);
                    ret = -EIO;
                    break;
                }

                if (set_value != 0xff) {
                    rix = RC_2_RATE_IDX_11AC(set_value);
                    preamble = WMI_RATE_PREAMBLE_VHT;
                    nss = HT_RC_2_STREAMS_11AC(set_value) - 1;

                    set_value = (preamble << 6) | (nss << 4) | rix;
                }
                hddLog(LOG1, "WMI_VDEV_PARAM_FIXED_RATE val %d rix %d "
                    "preamble %x nss %d", set_value, rix, preamble, nss);

                ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                              (int)WMI_VDEV_PARAM_FIXED_RATE,
                                              set_value, VDEV_CMD);
                break;
            }

         case QCASAP_SHORT_GI:
             {
                  hddLog(LOG1, "QCASAP_SET_SHORT_GI val %d", set_value);

                  ret = sme_UpdateHTConfig(hHal, pHostapdAdapter->sessionId,
                                           WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ, /* same as 40MHZ */
                                           set_value);
                  if (ret)
                      hddLog(LOGE, "Failed to set ShortGI value ret(%d)", ret);
                  break;
             }

         case QCSAP_SET_AMPDU:
             {
                  hddLog(LOG1, "QCSAP_SET_AMPDU val %d", set_value);
                  ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                               (int)GEN_VDEV_PARAM_AMPDU,
                                               set_value, GEN_CMD);
                  break;
             }

         case QCSAP_SET_AMSDU:
             {
                  hddLog(LOG1, "QCSAP_SET_AMSDU val %d", set_value);
                  ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                               (int)GEN_VDEV_PARAM_AMSDU,
                                               set_value, GEN_CMD);
                  break;
             }
        case QCSAP_GTX_HT_MCS:
             {
                  hddLog(LOG1, "WMI_VDEV_PARAM_GTX_HT_MCS %d", set_value);
                  ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                         (int)WMI_VDEV_PARAM_GTX_HT_MCS,
                                         set_value, GTX_CMD);
                  break;
             }

        case QCSAP_GTX_VHT_MCS:
             {
                  hddLog(LOG1, "WMI_VDEV_PARAM_GTX_VHT_MCS %d", set_value);
                  ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                         (int)WMI_VDEV_PARAM_GTX_VHT_MCS,
                                         set_value, GTX_CMD);
                  break;
             }

       case QCSAP_GTX_USRCFG:
             {
                  hddLog(LOG1, "WMI_VDEV_PARAM_GTX_USR_CFG %d", set_value);
                  ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                         (int)WMI_VDEV_PARAM_GTX_USR_CFG,
                                         set_value, GTX_CMD);
                  break;
             }

        case QCSAP_GTX_THRE:
             {
                  hddLog(LOG1, "WMI_VDEV_PARAM_GTX_THRE %d", set_value);
                  ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                         (int)WMI_VDEV_PARAM_GTX_THRE,
                                         set_value, GTX_CMD);
                  break;
             }

        case QCSAP_GTX_MARGIN:
             {
                  hddLog(LOG1, "WMI_VDEV_PARAM_GTX_MARGIN %d", set_value);
                  ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                         (int)WMI_VDEV_PARAM_GTX_MARGIN,
                                         set_value, GTX_CMD);
                  break;
             }

        case QCSAP_GTX_STEP:
             {
                  hddLog(LOG1, "WMI_VDEV_PARAM_GTX_STEP %d", set_value);
                  ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                         (int)WMI_VDEV_PARAM_GTX_STEP,
                                         set_value, GTX_CMD);
                  break;
             }

        case QCSAP_GTX_MINTPC:
             {
                  hddLog(LOG1, "WMI_VDEV_PARAM_GTX_MINTPC %d", set_value);
                  ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                         (int)WMI_VDEV_PARAM_GTX_MINTPC,
                                         set_value, GTX_CMD);
                  break;
             }

        case QCSAP_GTX_BWMASK:
             {
                  hddLog(LOG1, "WMI_VDEV_PARAM_GTX_BWMASK %d", set_value);
                  ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                         (int)WMI_VDEV_PARAM_GTX_BW_MASK,
                                         set_value, GTX_CMD);
                  break;
             }



#ifdef QCA_PKT_PROTO_TRACE
         case QCASAP_SET_DEBUG_LOG:
             {
                  hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);

                  hddLog(LOG1, "QCASAP_SET_DEBUG_LOG val %d", set_value);
                  /* Trace buffer dump only */
                  if (VOS_PKT_TRAC_DUMP_CMD == set_value)
                  {
                      vos_pkt_trace_buf_dump();
                      break;
                  }
                  pHddCtx->cfg_ini->gEnableDebugLog = set_value;
                  break;
             }
#endif /* QCA_PKT_PROTO_TRACE */

        case QCASAP_SET_TM_LEVEL:
             {
                  hddLog(VOS_TRACE_LEVEL_INFO, "Set Thermal Mitigation Level %d",
                            set_value);
                  (void)sme_SetThermalLevel(hHal, set_value);
                  break;
             }


        case QCASAP_SET_DFS_IGNORE_CAC:
             {
                  hddLog(VOS_TRACE_LEVEL_INFO, "Set Dfs ignore CAC  %d",
                            set_value);

                  if (pHostapdAdapter->device_mode != WLAN_HDD_SOFTAP)
                       return -EINVAL;

                  ret = WLANSAP_Set_Dfs_Ignore_CAC(hHal, set_value);
                  break;
             }

        case QCASAP_SET_DFS_TARGET_CHNL:
             {
                  hddLog(VOS_TRACE_LEVEL_INFO, "Set Dfs target channel  %d",
                            set_value);

                  if (pHostapdAdapter->device_mode != WLAN_HDD_SOFTAP)
                       return -EINVAL;

                  ret = WLANSAP_Set_Dfs_Target_Chnl(hHal, set_value);
                  break;
             }


        case QCASAP_SET_DFS_NOL:
             WLANSAP_Set_DfsNol(
#ifdef WLAN_FEATURE_MBSSID
                     WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
#else
                     pVosContext,
#endif
                     (eSapDfsNolType)set_value
                     );
             break;

        case QCASAP_SET_RADAR_CMD:
            {
                hdd_context_t *pHddCtx =
                    WLAN_HDD_GET_CTX(pHostapdAdapter);
                v_U8_t ch =
                    (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->operatingChannel;
                v_BOOL_t isDfsch;

                isDfsch = (NV_CHANNEL_DFS ==
                                vos_nv_getChannelEnabledState(ch));

                hddLog(VOS_TRACE_LEVEL_INFO,
                       FL("Set QCASAP_SET_RADAR_CMD val %d"), set_value);

                if (!pHddCtx->dfs_radar_found && isDfsch) {
                    ret = process_wma_set_command(
                            (int)pHostapdAdapter->sessionId,
                            (int)WMA_VDEV_DFS_CONTROL_CMDID,
                            set_value, VDEV_CMD);
                } else {
                    hddLog(VOS_TRACE_LEVEL_ERROR,
                        FL("Ignore command due to "
                            "dfs_radar_found: %d, is_dfs_channel: %d"),
                        pHddCtx->dfs_radar_found, isDfsch);
                }
                break;
            }
        case QCASAP_TX_CHAINMASK_CMD:
            {
                hddLog(LOG1, "QCASAP_TX_CHAINMASK_CMD val %d", set_value);
                ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                        (int)WMI_PDEV_PARAM_TX_CHAIN_MASK,
                        set_value, PDEV_CMD);
                break;
            }

        case QCASAP_RX_CHAINMASK_CMD:
            {
                hddLog(LOG1, "QCASAP_RX_CHAINMASK_CMD val %d", set_value);
                ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                        (int)WMI_PDEV_PARAM_RX_CHAIN_MASK,
                        set_value, PDEV_CMD);
                break;
            }

        case QCASAP_NSS_CMD:
            {
                hddLog(LOG1, "QCASAP_NSS_CMD val %d", set_value);
                ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                        (int)WMI_VDEV_PARAM_NSS,
                        set_value, VDEV_CMD);
                break;
            }
#ifdef IPA_UC_OFFLOAD
	case QCSAP_IPA_UC_STAT:
	    {
		    /* If input value is non-zero get stats */
		    if (1 == set_value) {
			    hdd_ipa_uc_stat_request(pHostapdAdapter, set_value);
		    } else if (3 == set_value) {
			    hdd_ipa_uc_rt_debug_host_dump(pHddCtx);
		    } else if (4 == set_value) {
			    hdd_ipa_dump_info(pHddCtx);
		    } else {
			    /* place holder for stats clean up
			     * Stats clean not implemented yet on FW and IPA
			     */
		    }

		    return ret;
	    }
#endif /* IPA_UC_OFFLOAD */
        case QCASAP_SET_PHYMODE:
            {
                hdd_context_t *phddctx = WLAN_HDD_GET_CTX(pHostapdAdapter);

                ret = wlan_hdd_update_phymode(dev, hHal, set_value, phddctx);
                break;
            }
        case QCASAP_DUMP_STATS:
            {
                hddLog(LOG1, "QCASAP_DUMP_STATS val %d", set_value);
                hdd_wlan_dump_stats(pHostapdAdapter, set_value);
                break;
            }
        case QCASAP_CLEAR_STATS:
            {
                hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);

                hddLog(LOG1, FL("QCASAP_CLEAR_STATS val %d"), set_value);

                switch (set_value) {
                case WLAN_HDD_STATS:
                    memset(&pHostapdAdapter->stats, 0,
                                 sizeof(pHostapdAdapter->stats));
                    memset(&pHostapdAdapter->hdd_stats, 0,
                                 sizeof(pHostapdAdapter->hdd_stats));
                    break;
                case WLAN_HDD_NETIF_OPER_HISTORY:
                    wlan_hdd_clear_netif_queue_history(hdd_ctx);
                    break;
                default:
                    WLANTL_clear_datapath_stats(hdd_ctx->pvosContext,
                                                             set_value);
                }
                break;
            }

        case QCASAP_PARAM_LDPC:
            ret = hdd_set_ldpc(pHostapdAdapter, set_value);
            break;

        case QCASAP_PARAM_TX_STBC:
            ret = hdd_set_tx_stbc(pHostapdAdapter, set_value);
            break;

        case QCASAP_PARAM_RX_STBC:
            ret = hdd_set_rx_stbc(pHostapdAdapter, set_value);
            break;

        case QCSAP_SET_DEFAULT_AMPDU:
            hddLog(LOG1, "QCSAP_SET_DEFAULT_AMPDU val %d", set_value);
            ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                         (int)WMI_PDEV_PARAM_MAX_MPDUS_IN_AMPDU,
                                         set_value, PDEV_CMD);
            break;

        case QCSAP_ENABLE_RTS_BURSTING:
            hddLog(LOG1, "QCSAP_ENABLE_RTS_BURSTING val %d", set_value);
            ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                   (int)WMI_PDEV_PARAM_ENABLE_RTS_SIFS_BURSTING,
                                   set_value, PDEV_CMD);
            break;

        case QCSAP_ENABLE_DYNAMIC_BW:
           hddLog(LOG1, "QCSAP_ENABLE_DYNAMIC_BW val %d", set_value);
           ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
                                         (int)WMI_PDEV_PARAM_DYNAMIC_BW,
                                         set_value, PDEV_CMD);
            break;

        default:
            hddLog(LOGE, FL("Invalid setparam command %d value %d"),
                    sub_cmd, set_value);
            ret = -EINVAL;
            break;
    }
    EXIT();
    return ret;
}

/**
 * __iw_softap_get_three() - return three value to upper layer.
 *
 * @dev: pointer of net_device of this wireless card
 * @info: meta data about Request sent
 * @wrqu: include request info
 * @extra: buf used for in/out
 *
 * Return: execute result
 */
static int __iw_softap_get_three(struct net_device *dev,
			struct iw_request_info *info,
			union iwreq_data *wrqu, char *extra)
{
	uint32_t *value = (uint32_t *)extra;
	uint32_t sub_cmd = value[0];
	int ret = 0; /* success */

	hdd_adapter_t *padapter = WLAN_HDD_GET_PRIV_PTR(dev);

	switch (sub_cmd) {
	case QCSAP_GET_TSF:
		ret = hdd_indicate_tsf(padapter, value, 3);
		break;
	default:
		hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd);
		break;
	}
	return ret;
}


/**
 * iw_softap_get_three() - return three value to upper layer.
 *
 * @dev: pointer of net_device of this wireless card
 * @info: meta data about Request sent
 * @wrqu: include request info
 * @extra: buf used for in/Output
 *
 * Return: execute result
 */
static int iw_softap_get_three(struct net_device *dev,
			struct iw_request_info *info,
			union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_softap_get_three(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}


int
static iw_softap_setparam(struct net_device *dev,
                          struct iw_request_info *info,
                          union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_softap_setparam(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

int
static __iw_softap_getparam(struct net_device *dev,
                            struct iw_request_info *info,
                            union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
    int *value = (int *)extra;
    int sub_cmd = value[0];
    eHalStatus status;
    int ret;
    hdd_context_t *pHddCtx;

    ENTER();

    pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
    ret = wlan_hdd_validate_context(pHddCtx);
    if (0 != ret)
        return ret;

    if (VOS_STATUS_SUCCESS != sme_is_session_valid(hHal,
                               pHostapdAdapter->sessionId)) {
       hddLog(LOGE, FL("session id is not valid %d"),
                   pHostapdAdapter->sessionId);
       return -EINVAL;
    }
    switch (sub_cmd)
    {
    case QCSAP_PARAM_MAX_ASSOC:
        status = ccmCfgGetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, (tANI_U32 *)value);
        if (eHAL_STATUS_SUCCESS != status)
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      FL("failed to get WNI_CFG_ASSOC_STA_LIMIT from cfg %d"),status);
            ret = -EIO;
        }
        break;

    case QCSAP_PARAM_GET_WLAN_DBG:
        {
            vos_trace_display();
            *value = 0;
            break;
        }

    case QCSAP_PARAM_AUTO_CHANNEL:
        {
            *value = (WLAN_HDD_GET_CTX
                      (pHostapdAdapter))->cfg_ini->force_sap_acs;
            break;
        }

    case QCSAP_PARAM_RTSCTS:
        {
            *value = wma_cli_get_command(pHddCtx->pvosContext,
                                             (int)pHostapdAdapter->sessionId,
                                             (int)WMI_VDEV_PARAM_ENABLE_RTSCTS,
                                             VDEV_CMD);
            break;
        }

    case QCASAP_SHORT_GI:
        {
            *value = (int)sme_GetHTConfig(hHal,
                                          pHostapdAdapter->sessionId,
                                          WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ);
            break;
        }

    case QCSAP_GTX_HT_MCS:
        {
            hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_HT_MCS");
            *value = wma_cli_get_command(pHddCtx->pvosContext,
                                        (int)pHostapdAdapter->sessionId,
                                        (int)WMI_VDEV_PARAM_GTX_HT_MCS,
                                        GTX_CMD);
            break;
        }

    case QCSAP_GTX_VHT_MCS:
        {
            hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_VHT_MCS");
            *value = wma_cli_get_command(pHddCtx->pvosContext,
                                        (int)pHostapdAdapter->sessionId,
                                        (int)WMI_VDEV_PARAM_GTX_VHT_MCS,
                                        GTX_CMD);
            break;
        }

    case QCSAP_GTX_USRCFG:
        {
            hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_USR_CFG");
            *value = wma_cli_get_command(pHddCtx->pvosContext,
                                        (int)pHostapdAdapter->sessionId,
                                        (int)WMI_VDEV_PARAM_GTX_USR_CFG,
                                        GTX_CMD);
            break;
        }

    case QCSAP_GTX_THRE:
        {
            hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_THRE");
            *value = wma_cli_get_command(pHddCtx->pvosContext,
                                        (int)pHostapdAdapter->sessionId,
                                        (int)WMI_VDEV_PARAM_GTX_THRE,
                                        GTX_CMD);
            break;
        }

    case QCSAP_GTX_MARGIN:
        {
            hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_MARGIN");
            *value = wma_cli_get_command(pHddCtx->pvosContext,
                                        (int)pHostapdAdapter->sessionId,
                                        (int)WMI_VDEV_PARAM_GTX_MARGIN,
                                        GTX_CMD);
            break;
        }

    case QCSAP_GTX_STEP:
        {
            hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_STEP");
            *value = wma_cli_get_command(pHddCtx->pvosContext,
                                        (int)pHostapdAdapter->sessionId,
                                        (int)WMI_VDEV_PARAM_GTX_STEP,
                                        GTX_CMD);
            break;
        }

    case QCSAP_GTX_MINTPC:
        {
            hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_MINTPC");
            *value = wma_cli_get_command(pHddCtx->pvosContext,
                                        (int)pHostapdAdapter->sessionId,
                                        (int)WMI_VDEV_PARAM_GTX_MINTPC,
                                        GTX_CMD);
            break;
        }

    case QCSAP_GTX_BWMASK:
        {
            hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_BW_MASK");
            *value = wma_cli_get_command(pHddCtx->pvosContext,
                                        (int)pHostapdAdapter->sessionId,
                                        (int)WMI_VDEV_PARAM_GTX_BW_MASK,
                                        GTX_CMD);
            break;
        }

    case QCASAP_GET_DFS_NOL:
        {
            WLANSAP_Get_DfsNol(
#ifdef WLAN_FEATURE_MBSSID
                    WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter)
#else
                    pHddCtx->pvosContext
#endif
                    );
        }
        break;

    case QCSAP_GET_ACL:
        {
            hddLog(LOG1, FL("QCSAP_GET_ACL"));
            if (hdd_print_acl(pHostapdAdapter) != VOS_STATUS_SUCCESS) {
                hddLog(LOGE, FL("QCSAP_GET_ACL returned Error: not completed"));
            }
            *value = 0;
            break;
        }

    case QCASAP_TX_CHAINMASK_CMD:
        {
            hddLog(LOG1, "QCASAP_TX_CHAINMASK_CMD");
            *value = wma_cli_get_command(pHddCtx->pvosContext,
                    (int)pHostapdAdapter->sessionId,
                    (int)WMI_PDEV_PARAM_TX_CHAIN_MASK,
                    PDEV_CMD);
            break;
        }

    case QCASAP_RX_CHAINMASK_CMD:
        {
            hddLog(LOG1, "QCASAP_RX_CHAINMASK_CMD");
            *value = wma_cli_get_command(pHddCtx->pvosContext,
                    (int)pHostapdAdapter->sessionId,
                    (int)WMI_PDEV_PARAM_RX_CHAIN_MASK,
                    PDEV_CMD);
            break;
        }

    case QCASAP_NSS_CMD:
        {
            hddLog(LOG1, "QCASAP_NSS_CMD");
            *value = wma_cli_get_command(pHddCtx->pvosContext,
                        (int)pHostapdAdapter->sessionId,
                        (int)WMI_VDEV_PARAM_NSS,
                        VDEV_CMD);
            break;
        }
    case QCSAP_GET_DYNAMIC_BW:
        {
            *value = wma_cli_get_command(pHddCtx->pvosContext,
                                        (int)pHostapdAdapter->sessionId,
                                        (int)WMI_PDEV_PARAM_DYNAMIC_BW,
                                        PDEV_CMD);
            break;
        }
    case QCASAP_GET_TEMP_CMD:
        {
            hddLog(VOS_TRACE_LEVEL_INFO, "QCASAP_GET_TEMP_CMD");
            ret = wlan_hdd_get_temperature(pHostapdAdapter, wrqu, extra);
            break;
        }
    case QCSAP_GET_FW_STATUS:
        {
            hddLog(LOG1, "QCSAP_GET_FW_STATUS");
            *value = wlan_hdd_get_fw_state(pHostapdAdapter);
            break;
        }
    case QCSAP_CAP_TSF:
        {
            ret = hdd_capture_tsf(pHostapdAdapter, (uint32_t *)value, 1);
            break;
        }
    case QCASAP_PARAM_LDPC:
        ret = hdd_get_ldpc(pHostapdAdapter, value);
        break;

    case QCASAP_PARAM_TX_STBC:
        ret = hdd_get_tx_stbc(pHostapdAdapter, value);
        break;

    case QCASAP_PARAM_RX_STBC:
        ret = hdd_get_rx_stbc(pHostapdAdapter, value);
        break;

    case QCSAP_PARAM_CHAN_WIDTH:
        ret = hdd_sap_get_chan_width(pHostapdAdapter, value);
        break;
    default:
        hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd);
        ret = -EINVAL;
        break;
    }
    EXIT();
    return ret;
}

int
static iw_softap_getparam(struct net_device *dev,
                          struct iw_request_info *info,
                          union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_softap_getparam(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

/* Usage:
    BLACK_LIST  = 0
    WHITE_LIST  = 1
    ADD MAC = 0
    REMOVE MAC  = 1

    mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
    for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
    while using this ioctl

    Syntax:
    iwpriv softap.0 modify_acl
    <6 octet mac addr> <list type> <cmd type>

    Examples:
    eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list
    iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0
    eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list
    iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1
*/
static
int __iw_softap_modify_acl(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
    hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
#ifndef WLAN_FEATURE_MBSSID
    v_CONTEXT_t pVosContext = hdd_ctx->pvosContext;
#endif
    v_BYTE_t *value = (v_BYTE_t*)extra;
    v_U8_t pPeerStaMac[VOS_MAC_ADDR_SIZE];
    int listType, cmd, i;
    int ret;
    VOS_STATUS vos_status = VOS_STATUS_SUCCESS;

    ENTER();

    ret = wlan_hdd_validate_context(hdd_ctx);
    if (0 != ret)
        return ret;

#ifndef WLAN_FEATURE_MBSSID
    if (NULL == pVosContext) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Vos Context is NULL", __func__);
        return -EINVAL;
    }
#endif

    for (i=0; i<VOS_MAC_ADDR_SIZE; i++)
    {
        pPeerStaMac[i] = *(value+i);
    }
    listType = (int)(*(value+i));
    i++;
    cmd = (int)(*(value+i));

    hddLog(LOG1, "%s: SAP Modify ACL arg0 " MAC_ADDRESS_STR " arg1 %d arg2 %d",
            __func__, MAC_ADDR_ARRAY(pPeerStaMac), listType, cmd);

#ifdef WLAN_FEATURE_MBSSID
    vos_status = WLANSAP_ModifyACL(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter), pPeerStaMac,(eSapACLType)listType,(eSapACLCmdType)cmd);
#else
    vos_status = WLANSAP_ModifyACL(pVosContext, pPeerStaMac,(eSapACLType)listType,(eSapACLCmdType)cmd);
#endif
    if (!VOS_IS_STATUS_SUCCESS(vos_status))
    {
        hddLog(LOGE, FL("Modify ACL failed"));
        ret = -EIO;
    }
    EXIT();
    return ret;
}

static
int iw_softap_modify_acl(struct net_device *dev,
                         struct iw_request_info *info,
                         union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_softap_modify_acl(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

int
static __iw_softap_getchannel(struct net_device *dev,
                              struct iw_request_info *info,
                              union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
    hdd_context_t *hdd_ctx;
    int ret;
    int *value = (int *)extra;

    ENTER();

    hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
    ret = wlan_hdd_validate_context(hdd_ctx);
    if (0 != ret)
        return ret;

    *value = 0;
    if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
        *value = (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->operatingChannel;
    EXIT();
    return 0;
}

int
static iw_softap_getchannel(struct net_device *dev,
                            struct iw_request_info *info,
                            union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_softap_getchannel(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

int
static __iw_softap_set_max_tx_power(struct net_device *dev,
                        struct iw_request_info *info,
                        union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
    hdd_context_t *hdd_ctx;
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
    int *value = (int *)extra;
    int set_value;
    tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
    tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
    int ret;

    ENTER();

    if (NULL == value)
        return -ENOMEM;

    hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
    ret = wlan_hdd_validate_context(hdd_ctx);
    if (0 != ret)
        return ret;

    /* Assign correct slef MAC address */
    vos_mem_copy(bssid, pHostapdAdapter->macAddressCurrent.bytes,
                 VOS_MAC_ADDR_SIZE);
    vos_mem_copy(selfMac, pHostapdAdapter->macAddressCurrent.bytes,
                 VOS_MAC_ADDR_SIZE);

    set_value = value[0];
    if (eHAL_STATUS_SUCCESS != sme_SetMaxTxPower(hHal, bssid, selfMac, set_value))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
                __func__);
        return -EIO;
    }
    EXIT();
    return 0;
}

int
static iw_softap_set_max_tx_power(struct net_device *dev,
                                  struct iw_request_info *info,
                                  union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_softap_set_max_tx_power(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

int
static __iw_display_data_path_snapshot(struct net_device *dev,
                        struct iw_request_info *info,
                        union iwreq_data *wrqu, char *extra)
{

    /* Function initiating dumping states of
     *  HDD(WMM Tx Queues)
     *  TL State (with Per Client infor)
     *  DXE Snapshot (Called at the end of TL Snapshot)
     */
    hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));

    ENTER();

    hdd_wmm_tx_snapshot(pHostapdAdapter);
    WLANTL_TLDebugMessage(VOS_TRUE);
    EXIT();
    return 0;
}

int
static iw_display_data_path_snapshot(struct net_device *dev,
                                     struct iw_request_info *info,
                                     union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_display_data_path_snapshot(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

int
static __iw_softap_set_tx_power(struct net_device *dev,
                        struct iw_request_info *info,
                        union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
    hdd_context_t *hdd_ctx;
    int *value = (int *)extra;
    int set_value;
    tSirMacAddr bssid;
    int ret;

    ENTER();

    hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
    ret = wlan_hdd_validate_context(hdd_ctx);
    if (0 != ret)
        return ret;

    if (NULL == value)
        return -ENOMEM;

    vos_mem_copy(bssid, pHostapdAdapter->macAddressCurrent.bytes,
           VOS_MAC_ADDR_SIZE);

    set_value = value[0];
    if (eHAL_STATUS_SUCCESS != sme_SetTxPower(hHal, pHostapdAdapter->sessionId, bssid,
                                              pHostapdAdapter->device_mode,
                                              set_value))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting tx power failed",
                __func__);
        return -EIO;
    }
    EXIT();
    return 0;
}

int
static iw_softap_set_tx_power(struct net_device *dev,
                              struct iw_request_info *info,
                              union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_softap_set_tx_power(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0)

int
static __iw_softap_getassoc_stamacaddr(struct net_device *dev,
                        struct iw_request_info *info,
                        union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
    hdd_station_info_t *pStaInfo = pHostapdAdapter->aStaInfo;
    hdd_context_t *hdd_ctx;
    char *buf;
    int cnt = 0;
    int left;
    int ret;
    /* maclist_index must be u32 to match user space */
    u32 maclist_index;

    ENTER();

    hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
    ret = wlan_hdd_validate_context(hdd_ctx);
    if (0 != ret)
        return ret;

    /*
     * NOTE WELL: this is a "get" ioctl but it uses an even ioctl
     * number, and even numbered iocts are supposed to have "set"
     * semantics.  Hence the wireless extensions support in the kernel
     * won't correctly copy the result to user space, so the ioctl
     * handler itself must copy the data.  Output format is 32-bit
     * record length, followed by 0 or more 6-byte STA MAC addresses.
     *
     * Further note that due to the incorrect semantics, the "iwpriv"
     * user space application is unable to correctly invoke this API,
     * hence it is not registered in the hostapd_private_args.  This
     * API can only be invoked by directly invoking the ioctl() system
     * call.
     */

    /* Make sure user space allocated a reasonable buffer size */
    if (wrqu->data.length < sizeof(maclist_index)) {
        hddLog(LOG1, "%s: invalid userspace buffer", __func__);
        return -EINVAL;
    }

    /* allocate local buffer to build the response */
    buf = vos_mem_malloc(wrqu->data.length);
    if (!buf) {
        hddLog(LOG1, "%s: failed to allocate response buffer", __func__);
        return -ENOMEM;
    }

    /* start indexing beyond where the record count will be written */
    maclist_index = sizeof(maclist_index);
    left = wrqu->data.length - maclist_index;

    SPIN_LOCK_BH(&pHostapdAdapter->staInfo_lock);
    while ((cnt < WLAN_MAX_STA_COUNT) && (left >= VOS_MAC_ADDR_SIZE)) {
        if ((pStaInfo[cnt].isUsed) &&
            (!IS_BROADCAST_MAC(pStaInfo[cnt].macAddrSTA.bytes))) {
            memcpy(&buf[maclist_index], &(pStaInfo[cnt].macAddrSTA),
                   VOS_MAC_ADDR_SIZE);
            maclist_index += VOS_MAC_ADDR_SIZE;
            left -= VOS_MAC_ADDR_SIZE;
        }
        cnt++;
    }
    SPIN_UNLOCK_BH(&pHostapdAdapter->staInfo_lock);

    *((u32 *)buf) = maclist_index;
    wrqu->data.length = maclist_index;
    if (copy_to_user(wrqu->data.pointer, buf, maclist_index)) {
        hddLog(LOG1, "%s: failed to copy response to user buffer", __func__);
        ret = -EFAULT;
    }
    vos_mem_free(buf);
    EXIT();
    return ret;
}

int
static iw_softap_getassoc_stamacaddr(struct net_device *dev,
                                   struct iw_request_info *info,
                                   union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_softap_getassoc_stamacaddr(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

/* Usage:
    mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
    for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
    while using this ioctl

    Syntax:
    iwpriv softap.0 disassoc_sta <6 octet mac address>

    e.g.
    disassociate sta with mac addr 00:0a:f5:11:22:33 from softap
    iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33
*/

int
static __iw_softap_disassoc_sta(struct net_device *dev,
                        struct iw_request_info *info,
                        union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
    hdd_context_t *hdd_ctx;
    v_U8_t *peerMacAddr;
    struct tagCsrDelStaParams delStaParams;
    int ret;

    ENTER();

    if (!capable(CAP_NET_ADMIN)) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 FL("permission check failed"));
        return -EPERM;
    }

    hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
    ret = wlan_hdd_validate_context(hdd_ctx);
    if (0 != ret)
        return ret;

    /* iwpriv tool or framework calls this ioctl with
     * data passed in extra (less than 16 octets);
     */
    peerMacAddr = (v_U8_t *)(extra);

    hddLog(LOG1, "%s data "  MAC_ADDRESS_STR,
           __func__, MAC_ADDR_ARRAY(peerMacAddr));


    WLANSAP_PopulateDelStaParams(peerMacAddr,
                   eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
                   (SIR_MAC_MGMT_DISASSOC >> 4),
                   &delStaParams);

    hdd_softap_sta_disassoc(pHostapdAdapter, &delStaParams);
    EXIT();
    return 0;
}

int
static iw_softap_disassoc_sta(struct net_device *dev,
                              struct iw_request_info *info,
                              union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_softap_disassoc_sta(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

int
static __iw_softap_ap_stats(struct net_device *dev,
                        struct iw_request_info *info,
                        union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
    WLANTL_TRANSFER_STA_TYPE  statBuffer;
    char *pstatbuf;
    int len;

    ENTER();

    memset(&statBuffer, 0, sizeof(statBuffer));
    WLANSAP_GetStatistics((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
                           &statBuffer, (v_BOOL_t)wrqu->data.flags);

    pstatbuf = vos_mem_malloc(wrqu->data.length);
    if(NULL == pstatbuf) {
        hddLog(LOG1, "unable to allocate memory");
        return -ENOMEM;
    }
    len = snprintf(pstatbuf, wrqu->data.length,
                    "RUF=%d RMF=%d RBF=%d "
                    "RUB=%d RMB=%d RBB=%d "
                    "TUF=%d TMF=%d TBF=%d "
                    "TUB=%d TMB=%d TBB=%d",
                    (int)statBuffer.rxUCFcnt, (int)statBuffer.rxMCFcnt,
                    (int)statBuffer.rxBCFcnt, (int)statBuffer.rxUCBcnt,
                    (int)statBuffer.rxMCBcnt, (int)statBuffer.rxBCBcnt,
                    (int)statBuffer.txUCFcnt, (int)statBuffer.txMCFcnt,
                    (int)statBuffer.txBCFcnt, (int)statBuffer.txUCBcnt,
                    (int)statBuffer.txMCBcnt, (int)statBuffer.txBCBcnt);

    if (len >= wrqu->data.length) {
        hddLog(LOG1, "%s: Insufficient buffer:%d, %d",
            __func__, wrqu->data.length, len);
        vos_mem_free(pstatbuf);
        return -E2BIG;
    }
    if (copy_to_user((void *)wrqu->data.pointer, (void *)pstatbuf, len)) {
        hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
        vos_mem_free(pstatbuf);
        return -EFAULT;
    }
    wrqu->data.length = len;
    vos_mem_free(pstatbuf);
    EXIT();
    return 0;
}

int
static iw_softap_ap_stats(struct net_device *dev,
                          struct iw_request_info *info,
                          union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_softap_ap_stats(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

int
static __iw_get_char_setnone(struct net_device *dev,
                             struct iw_request_info *info,
                             union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    int sub_cmd = wrqu->data.flags;
    ENTER();
    if (NULL == WLAN_HDD_GET_CTX(pAdapter))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                                        "%s: HDD Context is NULL!", __func__);

        return -EINVAL;
    }

    if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                                  "%s:LOGP in Progress. Ignore!!!", __func__);
        return -EBUSY;
    }
    switch(sub_cmd)
    {
        case QCSAP_GET_STATS:
        {
            return hdd_wlan_get_stats(pAdapter, &(wrqu->data.length),
                               extra, WE_MAX_STR_LEN);
        }
    }
    return 0;
}

static int iw_get_char_setnone(struct net_device *dev,
                               struct iw_request_info *info,
                               union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_get_char_setnone(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

static int wlan_hdd_set_force_acs_ch_range(struct net_device *dev,
                          struct iw_request_info *info,
                          union iwreq_data *wrqu, char *extra)
{
	hdd_adapter_t *adapter = (netdev_priv(dev));
	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	int *value = (int *)extra;

	if (!capable(CAP_NET_ADMIN)) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			  FL("permission check failed"));
		return -EPERM;
	}

	if (wlan_hdd_validate_operation_channel(adapter, value[0]) !=
					 VOS_STATUS_SUCCESS ||
		wlan_hdd_validate_operation_channel(adapter, value[1]) !=
					 VOS_STATUS_SUCCESS) {
		return -EINVAL;
	} else {
		hdd_ctx->cfg_ini->force_sap_acs_st_ch = value[0];
		hdd_ctx->cfg_ini->force_sap_acs_end_ch = value[1];
	}

	return 0;
}

static int iw_softap_set_force_acs_ch_range(struct net_device *dev,
                                       struct iw_request_info *info,
                                       union iwreq_data *wrqu, char *extra)
{
	int ret;
	vos_ssr_protect(__func__);
	ret = wlan_hdd_set_force_acs_ch_range(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);
	return ret;
}

static int __iw_get_channel_list(struct net_device *dev,
                          struct iw_request_info *info,
                          union iwreq_data *wrqu, char *extra)
{
    v_U32_t num_channels = 0;
    v_U8_t i = 0;
    v_U8_t bandStartChannel = RF_CHAN_1;
    v_U8_t bandEndChannel = RF_CHAN_184;
    hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
    tpChannelListInfo channel_list = (tpChannelListInfo) extra;
    eCsrBand curBand = eCSR_BAND_ALL;
    hdd_context_t *hdd_ctx;
    int ret;
    int is_dfs_mode_enabled = 0;

    ENTER();

    hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
    ret = wlan_hdd_validate_context(hdd_ctx);
    if (0 != ret)
        return ret;

    if (eHAL_STATUS_SUCCESS != sme_GetFreqBand(hHal, &curBand))
    {
        hddLog(LOGE,FL("not able get the current frequency band"));
        return -EIO;
    }
    wrqu->data.length = sizeof(tChannelListInfo);
    ENTER();

    if (eCSR_BAND_24 == curBand)
    {
        bandStartChannel = RF_CHAN_1;
        bandEndChannel = RF_CHAN_14;
    }
    else if (eCSR_BAND_5G == curBand)
    {
        bandStartChannel = RF_CHAN_36;
        bandEndChannel = RF_CHAN_184;
    }
    if (curBand != eCSR_BAND_24) {
        if (hdd_ctx->cfg_ini->dot11p_mode) {
            bandEndChannel = RF_CHAN_184;
        } else {
            bandEndChannel = RF_CHAN_165;
        }
    }

    if (pHostapdAdapter->device_mode == WLAN_HDD_INFRA_STATION &&
            hdd_ctx->cfg_ini->enableDFSChnlScan) {
        is_dfs_mode_enabled = 1;
    } else if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP &&
            hdd_ctx->cfg_ini->enableDFSMasterCap) {
        is_dfs_mode_enabled = 1;
    }
    hddLog(LOG1, FL("curBand = %d, bandStartChannel = %hu, "
                "bandEndChannel = %hu is_dfs_mode_enabled  = %d "), curBand,
                bandStartChannel, bandEndChannel, is_dfs_mode_enabled);

    for( i = bandStartChannel; i <= bandEndChannel; i++ )
    {
        if ((NV_CHANNEL_ENABLE == regChannels[i].enabled) ||
            (is_dfs_mode_enabled &&
              NV_CHANNEL_DFS == regChannels[i].enabled))

        {
            channel_list->channels[num_channels] = rfChannels[i].channelNum;
            num_channels++;
        }
    }

    hddLog(LOG1,FL(" number of channels %d"), num_channels);

    channel_list->num_channels = num_channels;
    EXIT();

    return 0;
}

int iw_get_channel_list(struct net_device *dev,
                               struct iw_request_info *info,
                               union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_get_channel_list(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

static
int __iw_get_genie(struct net_device *dev,
                        struct iw_request_info *info,
                        union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
    hdd_context_t *hdd_ctx;
    int ret;
#ifndef WLAN_FEATURE_MBSSID
    v_CONTEXT_t pVosContext;
#endif
    VOS_STATUS status;
    v_U32_t length = DOT11F_IE_RSN_MAX_LEN;
    v_U8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];

    ENTER();

    hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
    ret = wlan_hdd_validate_context(hdd_ctx);
    if (0 != ret)
        return ret;

#ifndef WLAN_FEATURE_MBSSID
    pVosContext = hdd_ctx->pvosContext;
    if (NULL == pVosContext) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: vos context is not valid ", __func__);
        return -EINVAL;
    }
#endif

    // Actually retrieve the RSN IE from CSR.  (We previously sent it down in the CSR Roam Profile.)
    status = WLANSap_getstationIE_information(
#ifdef WLAN_FEATURE_MBSSID
                                   WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
#else
                                   pVosContext,
#endif
                                   &length,
                                   genIeBytes
                                   );
    if (VOS_STATUS_SUCCESS != status) {
        hddLog(LOGE, FL("failed to get sta ies"));
        return -EFAULT;
    }

    wrqu->data.length = length;
    if (length > DOT11F_IE_RSN_MAX_LEN) {
        hddLog(LOGE,
               FL("invalid buffer length length:%d"), length);
        return -E2BIG;
    }

    vos_mem_copy(extra, genIeBytes, length);

    hddLog(LOG1, FL("RSN IE of %d bytes returned"), wrqu->data.length);


    EXIT();
    return 0;
}

static
int iw_get_genie(struct net_device *dev,
                 struct iw_request_info *info,
                 union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_get_genie(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

static
int __iw_get_WPSPBCProbeReqIEs(struct net_device *dev,
                        struct iw_request_info *info,
                        union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
    sQcSapreq_WPSPBCProbeReqIES_t WPSPBCProbeReqIEs;
    hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
    hdd_context_t *hdd_ctx;
    int ret;

    ENTER();

    hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
    ret = wlan_hdd_validate_context(hdd_ctx);
    if (0 != ret)
        return ret;

    memset((void*)&WPSPBCProbeReqIEs, 0, sizeof(WPSPBCProbeReqIEs));

    WPSPBCProbeReqIEs.probeReqIELen = pHddApCtx->WPSPBCProbeReq.probeReqIELen;
    vos_mem_copy(&WPSPBCProbeReqIEs.probeReqIE,
                 pHddApCtx->WPSPBCProbeReq.probeReqIE,
                 WPSPBCProbeReqIEs.probeReqIELen);
    vos_mem_copy(&WPSPBCProbeReqIEs.macaddr,
                 pHddApCtx->WPSPBCProbeReq.peerMacAddr,
                 sizeof(v_MACADDR_t));
    if (copy_to_user(wrqu->data.pointer,
                     (void *)&WPSPBCProbeReqIEs,
                      sizeof(WPSPBCProbeReqIEs)))
    {
         hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
         return -EFAULT;
    }
    wrqu->data.length = 12 + WPSPBCProbeReqIEs.probeReqIELen;
    hddLog(LOG1, FL("Macaddress : "MAC_ADDRESS_STR),
           MAC_ADDR_ARRAY(WPSPBCProbeReqIEs.macaddr));
    up(&pHddApCtx->semWpsPBCOverlapInd);
    EXIT();
    return 0;
}

static
int iw_get_WPSPBCProbeReqIEs(struct net_device *dev,
                             struct iw_request_info *info,
                             union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_get_WPSPBCProbeReqIEs(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

/**
 * __iw_set_auth_hostap() - This function sets the auth type received
 *			from the wpa_supplicant.
 *
 * @dev - Pointer to the net device.
 * @info - Pointer to the iw_request_info.
 * @wrqu - Pointer to the iwreq_data.
 * @extra - Pointer to the data.
 *
 * Return: 0 for success, non zero for failure.
 */
static int
__iw_set_auth_hostap(struct net_device *dev,
			struct iw_request_info *info,
			union iwreq_data *wrqu, char *extra)
{
	hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
	hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
	hdd_context_t *hdd_ctx;
	int ret;

	ENTER();

	hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
	ret = wlan_hdd_validate_context(hdd_ctx);
	if (0 != ret)
		return ret;

	switch (wrqu->param.flags & IW_AUTH_INDEX) {
	case IW_AUTH_TKIP_COUNTERMEASURES:
		if (wrqu->param.value) {
			hddLog(LOG2,
				FL("Counter Measure started(%d)"),
				wrqu->param.value);
			pWextState->mTKIPCounterMeasures =
						TKIP_COUNTER_MEASURE_STARTED;
		} else {
			hddLog(LOG2,
				FL("Counter Measure stopped(%d)"),
				wrqu->param.value);
			pWextState->mTKIPCounterMeasures =
						TKIP_COUNTER_MEASURE_STOPED;
		}

		hdd_softap_tkip_mic_fail_counter_measure(pAdapter,
							 wrqu->param.value);
		break;

	default:
		hddLog(LOGW, FL("called with unsupported auth type %d"),
			wrqu->param.flags & IW_AUTH_INDEX);
		break;
	}

	EXIT();
	return 0;
}

/**
 * iw_set_auth_hostap() - Wrapper function to protect __iw_set_auth_hostap
 *			from the SSR.
 *
 * @dev - Pointer to the net device.
 * @info - Pointer to the iw_request_info.
 * @wrqu - Pointer to the iwreq_data.
 * @extra - Pointer to the data.
 *
 * Return: 0 for success, non zero for failure.
 */
static int
iw_set_auth_hostap(struct net_device *dev,
			struct iw_request_info *info,
			union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_set_auth_hostap(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

/**
 * __iw_set_ap_encodeext() - set ap encode
 *
 * @dev - Pointer to the net device.
 * @info - Pointer to the iw_request_info.
 * @wrqu - Pointer to the iwreq_data.
 * @extra - Pointer to the data.
 *
 * Return: 0 for success, non zero for failure.
 */
static int __iw_set_ap_encodeext(struct net_device *dev,
				 struct iw_request_info *info,
				 union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
#ifndef WLAN_FEATURE_MBSSID
    v_CONTEXT_t pVosContext;
#endif
    hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
    hdd_context_t *hdd_ctx;
    int ret;
    VOS_STATUS vstatus;
    struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
    v_U8_t groupmacaddr[VOS_MAC_ADDR_SIZE] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
    int key_index;
    struct iw_point *encoding = &wrqu->encoding;
    tCsrRoamSetKey  setKey;
//    tCsrRoamRemoveKey RemoveKey;
    int i;

    ENTER();

    hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
    ret = wlan_hdd_validate_context(hdd_ctx);
    if (0 != ret)
        return ret;

#ifndef WLAN_FEATURE_MBSSID
    pVosContext = hdd_ctx->pvosContext;
    if (NULL == pVosContext) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: pVosContext is NULL", __func__);
        return -EINVAL;
    }
#endif

    key_index = encoding->flags & IW_ENCODE_INDEX;

    key_index = encoding->flags & IW_ENCODE_INDEX;

    if(key_index > 0) {

         /*Convert from 1-based to 0-based keying*/
        key_index--;
    }
    if(!ext->key_len || ext->key_len > CSR_MAX_KEY_LEN) {
#if 0
      /*Set the encryption type to NONE*/
#if 0
       pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
#endif

         RemoveKey.keyId = key_index;
         if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
              /*Key direction for group is RX only*/
             vos_mem_copy(RemoveKey.peerMac,groupmacaddr, VOS_MAC_ADDR_SIZE);
         }
         else {
             vos_mem_copy(RemoveKey.peerMac,ext->addr.sa_data, VOS_MAC_ADDR_SIZE);
         }
         switch(ext->alg)
         {
           case IW_ENCODE_ALG_NONE:
              RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
              break;
           case IW_ENCODE_ALG_WEP:
              RemoveKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
              break;
           case IW_ENCODE_ALG_TKIP:
              RemoveKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
              break;
           case IW_ENCODE_ALG_CCMP:
              RemoveKey.encType = eCSR_ENCRYPT_TYPE_AES;
              break;
          default:
              RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE;
              break;
         }
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Remove key cipher_alg:%d key_len%d *pEncryptionType :%d",
                    __func__,(int)ext->alg,(int)ext->key_len,RemoveKey.encType);
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Peer Mac = "MAC_ADDRESS_STR,
                    __func__, MAC_ADDR_ARRAY(RemoveKey.peerMac));
          );
#ifdef WLAN_FEATURE_MBSSID
         vstatus = WLANSAP_DelKeySta( WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter), &RemoveKey );
#else
         vstatus = WLANSAP_DelKeySta( pVosContext, &RemoveKey );
#endif

         if ( vstatus != VOS_STATUS_SUCCESS )
         {
             VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "[%4d] WLANSAP_DeleteKeysSta returned ERROR status= %d",
                        __LINE__, vstatus );
             retval = -EINVAL;
         }
#endif
         return -EINVAL;

    }

    vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));

    setKey.keyId = key_index;
    setKey.keyLength = ext->key_len;

    vos_mem_copy(&setKey.Key[0],ext->key,ext->key_len);

    if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
      /*Key direction for group is RX only*/
       setKey.keyDirection = eSIR_RX_ONLY;
       vos_mem_copy(setKey.peerMac,groupmacaddr, VOS_MAC_ADDR_SIZE);
    }
    else {

       setKey.keyDirection =  eSIR_TX_RX;
       vos_mem_copy(setKey.peerMac,ext->addr.sa_data, VOS_MAC_ADDR_SIZE);
    }
    if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
    {
       setKey.keyDirection = eSIR_TX_DEFAULT;
       vos_mem_copy(setKey.peerMac,ext->addr.sa_data, VOS_MAC_ADDR_SIZE);
    }

    /*For supplicant pae role is zero*/
    setKey.paeRole = 0;

    switch(ext->alg)
    {
       case IW_ENCODE_ALG_NONE:
         setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
         break;

       case IW_ENCODE_ALG_WEP:
         setKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
         pHddApCtx->uPrivacy = 1;
         hddLog(LOG1, "(%s) uPrivacy=%d", __func__, pHddApCtx->uPrivacy);
         break;

       case IW_ENCODE_ALG_TKIP:
       {
          v_U8_t *pKey = &setKey.Key[0];

          setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;

          vos_mem_zero(pKey, CSR_MAX_KEY_LEN);

          /*Supplicant sends the 32bytes key in this order

                |--------------|----------|----------|
                |   Tk1        |TX-MIC    |  RX Mic  |
                |--------------|----------|----------|
                <---16bytes---><--8bytes--><--8bytes-->

                */
          /*Sme expects the 32 bytes key to be in the below order

                |--------------|----------|----------|
                |   Tk1        |RX-MIC    |  TX Mic  |
                |--------------|----------|----------|
                <---16bytes---><--8bytes--><--8bytes-->
               */
          /* Copy the Temporal Key 1 (TK1) */
          vos_mem_copy(pKey,ext->key,16);

         /*Copy the rx mic first*/
          vos_mem_copy(&pKey[16],&ext->key[24],8);

         /*Copy the tx mic */
          vos_mem_copy(&pKey[24],&ext->key[16],8);

       }
       break;

       case IW_ENCODE_ALG_CCMP:
          setKey.encType = eCSR_ENCRYPT_TYPE_AES;
          break;

       default:
          setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
          break;
    }

    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
          ("%s:EncryptionType:%d key_len:%d, KeyId:%d"), __func__, setKey.encType, setKey.keyLength,
            setKey.keyId);
    for(i=0; i< ext->key_len; i++)
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
          ("%02x"), setKey.Key[i]);

#ifdef WLAN_FEATURE_MBSSID
    vstatus = WLANSAP_SetKeySta( WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter), &setKey );
#else
    vstatus = WLANSAP_SetKeySta( pVosContext, &setKey );
#endif

    if ( vstatus != VOS_STATUS_SUCCESS )
    {
       VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "[%4d] WLANSAP_SetKeySta returned ERROR status= %d", __LINE__, vstatus );
       ret = -EINVAL;
    }

    EXIT();
    return ret;
}

/**
 * iw_set_ap_encodeext() - Wrapper function to protect __iw_set_ap_encodeext
 *			from the SSR.
 *
 * @dev - Pointer to the net device.
 * @info - Pointer to the iw_request_info.
 * @wrqu - Pointer to the iwreq_data.
 * @extra - Pointer to the data.
 *
 * Return: 0 for success, non zero for failure.
 */
static int iw_set_ap_encodeext(struct net_device *dev,
                               struct iw_request_info *info,
                               union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_set_ap_encodeext(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

/**
 * __iw_set_ap_mlme() - set ap mlme
 * @dev: pointer to net_device
 * @info: pointer to iw_request_info
 * @wrqu; pointer to iwreq_data
 * @extra: extra
 *
 * Return; 0 on success, error number otherwise
 */
static int __iw_set_ap_mlme(struct net_device *dev,
			    struct iw_request_info *info,
			    union iwreq_data *wrqu,
			    char *extra)
{
    return 0;
//    return status;
}

/**
 * iw_set_ap_mlme() - SSR wrapper for __iw_set_ap_mlme
 * @dev: pointer to net_device
 * @info: pointer to iw_request_info
 * @wrqu; pointer to iwreq_data
 * @extra: extra
 *
 * Return; 0 on success, error number otherwise
 */
static int iw_set_ap_mlme(struct net_device *dev,
			  struct iw_request_info *info,
			  union iwreq_data *wrqu,
			  char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_set_ap_mlme(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}


/**
 * __iw_get_ap_rts_threshold() - get ap rts threshold
 * @dev - Pointer to the net device.
 * @info - Pointer to the iw_request_info.
 * @wrqu - Pointer to the iwreq_data.
 * @extra - Pointer to the data.
 *
 * Return: 0 for success, non zero for failure.
 */
static int __iw_get_ap_rts_threshold(struct net_device *dev,
				     struct iw_request_info *info,
				     union iwreq_data *wrqu, char *extra)
{
	hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
	int ret;
	hdd_context_t *hdd_ctx;

	ENTER();

	hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
	ret = wlan_hdd_validate_context(hdd_ctx);
	if (0 != ret)
		return ret;

	ret = hdd_wlan_get_rts_threshold(pHostapdAdapter, wrqu);

	return ret;
}

/**
 * iw_get_ap_rts_threshold() - Wrapper function to protect
 *			__iw_get_ap_rts_threshold from the SSR.
 * @dev - Pointer to the net device.
 * @info - Pointer to the iw_request_info.
 * @wrqu - Pointer to the iwreq_data.
 * @extra - Pointer to the data.
 *
 * Return: 0 for success, non zero for failure.
 */
static int iw_get_ap_rts_threshold(struct net_device *dev,
				   struct iw_request_info *info,
				   union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_get_ap_rts_threshold(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

/**
 * __iw_get_ap_frag_threshold() - get ap fragmentation threshold
 * @dev - Pointer to the net device.
 * @info - Pointer to the iw_request_info.
 * @wrqu - Pointer to the iwreq_data.
 * @extra - Pointer to the data.
 *
 * Return: 0 for success, non zero for failure.
 */
static int __iw_get_ap_frag_threshold(struct net_device *dev,
				      struct iw_request_info *info,
				      union iwreq_data *wrqu, char *extra)
{
	hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
	hdd_context_t *hdd_ctx;
	int ret = 0;

	ENTER();

	hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
	ret = wlan_hdd_validate_context(hdd_ctx);
	if (0 != ret)
		return ret;

	ret = hdd_wlan_get_frag_threshold(pHostapdAdapter, wrqu);

	return ret;
}

/**
 * iw_get_ap_frag_threshold() - Wrapper function to protect
 *			__iw_get_ap_frag_threshold from the SSR.
 * @dev - Pointer to the net device.
 * @info - Pointer to the iw_request_info.
 * @wrqu - Pointer to the iwreq_data.
 * @extra - Pointer to the data.
 *
 * Return: 0 for success, non zero for failure.
 */
static int iw_get_ap_frag_threshold(struct net_device *dev,
				    struct iw_request_info *info,
				    union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_get_ap_frag_threshold(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

/**
 * __iw_get_ap_freq() - get ap frequency
 * @dev - Pointer to the net device.
 * @info - Pointer to the iw_request_info.
 * @wrqu - Pointer to the iwreq_data.
 * @extra - Pointer to the data.
 *
 * Return: 0 for success, non zero for failure.
 */
static int __iw_get_ap_freq(struct net_device *dev,
                            struct iw_request_info *info,
                            struct iw_freq *fwrq, char *extra)
{
   v_U32_t status = FALSE, channel = 0, freq = 0;
   hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
   hdd_context_t *hdd_ctx;
   tHalHandle hHal;
   hdd_hostapd_state_t *pHostapdState;
   hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
   int ret;

   ENTER();

   hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
   ret = wlan_hdd_validate_context(hdd_ctx);
   if (0 != ret)
       return ret;

   pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
   hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);

   if(pHostapdState->bssState == BSS_STOP )
   {
       if (ccmCfgGetInt(hHal, WNI_CFG_CURRENT_CHANNEL, &channel)
                                                  != eHAL_STATUS_SUCCESS)
       {
           return -EIO;
       }
       else
       {
          status = hdd_wlan_get_freq(channel, &freq);
          if( TRUE == status)
          {
              /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
               * iwlist & iwconfig command shows frequency into proper
               * format (2.412 GHz instead of 246.2 MHz)*/
              fwrq->m = freq;
              fwrq->e = MHZ;
          }
       }
    }
    else
    {
       channel = pHddApCtx->operatingChannel;
       status = hdd_wlan_get_freq(channel, &freq);
       if( TRUE == status)
       {
          /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
           * iwlist & iwconfig command shows frequency into proper
           * format (2.412 GHz instead of 246.2 MHz)*/
           fwrq->m = freq;
           fwrq->e = MHZ;
       }
    }
    EXIT();
    return 0;
}

/**
 * iw_get_ap_freq() - Wrapper function to protect
 *                    __iw_get_ap_freq from the SSR.
 * @dev - Pointer to the net device.
 * @info - Pointer to the iw_request_info.
 * @wrqu - Pointer to the iwreq_data.
 * @extra - Pointer to the data.
 *
 * Return: 0 for success, non zero for failure.
 */
static int iw_get_ap_freq(struct net_device *dev,
			  struct iw_request_info *info,
			  struct iw_freq *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_get_ap_freq(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

/**
 * __iw_get_mode() - get mode
 * @dev - Pointer to the net device.
 * @info - Pointer to the iw_request_info.
 * @wrqu - Pointer to the iwreq_data.
 * @extra - Pointer to the data.
 *
 * Return: 0 for success, non zero for failure.
 */
static int __iw_get_mode(struct net_device *dev,
                         struct iw_request_info *info,
                         union iwreq_data *wrqu,
                         char *extra)
{
    hdd_adapter_t *adapter;
    hdd_context_t *hdd_ctx;
    int ret;

    adapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_ctx = WLAN_HDD_GET_CTX(adapter);
    ret = wlan_hdd_validate_context(hdd_ctx);
    if (0 != ret)
        return ret;

    wrqu->mode = IW_MODE_MASTER;

    return ret;
}

/**
 * iw_get_mode() - Wrapper function to protect __iw_get_mode from the SSR.
 * @dev - Pointer to the net device.
 * @info - Pointer to the iw_request_info.
 * @wrqu - Pointer to the iwreq_data.
 * @extra - Pointer to the data.
 *
 * Return: 0 for success, non zero for failure.
 */
static int iw_get_mode(struct net_device *dev,
                       struct iw_request_info *info,
                       union iwreq_data *wrqu, char *extra)
{
        int ret;

        vos_ssr_protect(__func__);
        ret = __iw_get_mode(dev, info, wrqu, extra);
        vos_ssr_unprotect(__func__);

        return ret;
}


static int __iw_softap_stopbss(struct net_device *dev,
                             struct iw_request_info *info,
                             union iwreq_data *wrqu,
                             char *extra)
{
    hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
    VOS_STATUS status = VOS_STATUS_SUCCESS;
    hdd_context_t *pHddCtx;

    ENTER();

    pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
        return status;

    if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
    {
        hdd_hostapd_state_t *pHostapdState =
                       WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
        vos_event_reset(&pHostapdState->stop_bss_event);
#ifdef WLAN_FEATURE_MBSSID
        status = WLANSAP_StopBss(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter));
#else
        status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext);
#endif
        if (VOS_IS_STATUS_SUCCESS(status))
        {
            status = vos_wait_single_event(&pHostapdState->stop_bss_event,
                                           10000);
            if (!VOS_IS_STATUS_SUCCESS(status))
            {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                         ("%s: ERROR: HDD vos wait for single_event failed!!"),
                         __func__);
                VOS_ASSERT(0);
            }
        }
        clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
        wlan_hdd_decr_active_session(pHddCtx, pHostapdAdapter->device_mode);
    }
    if (pHddCtx->cfg_ini->apOBSSProtEnabled)
        vos_runtime_pm_allow_suspend(pHddCtx->runtime_context.obss);
    EXIT();
    return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
}

static int iw_softap_stopbss(struct net_device *dev,
                             struct iw_request_info *info,
                             union iwreq_data *wrqu,
                             char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_softap_stopbss(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

static int __iw_softap_version(struct net_device *dev,
                             struct iw_request_info *info,
                             union iwreq_data *wrqu,
                             char *extra)
{
    hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
    hdd_context_t *hdd_ctx;
    int ret;

    ENTER();

    hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
    ret = wlan_hdd_validate_context(hdd_ctx);
    if (0 != ret)
        return ret;

    hdd_wlan_get_version(pHostapdAdapter, wrqu, extra);
    EXIT();

    return ret;
}

static int iw_softap_version(struct net_device *dev,
                             struct iw_request_info *info,
                             union iwreq_data *wrqu,
                             char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_softap_version(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

static int
hdd_softap_get_sta_info(hdd_adapter_t *pAdapter, v_U8_t *pBuf, int buf_len)
{
    v_U8_t i;
    v_U8_t maxSta = 0;
    int len = 0;
    const char sta_info_header[] = "staId staAddress";
    hdd_context_t *pHddCtx;
    int ret;

    ENTER();

    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;

    len = snprintf(pBuf, buf_len, sta_info_header);
    if (len >= buf_len) {
        hddLog(LOGE, FL("Insufficient buffer:%d, %d"), buf_len, len);
        return -E2BIG;
    }
    pBuf += len;
    buf_len -= len;

    maxSta = pHddCtx->max_peers;

    for (i = 0; i <= maxSta; i++)
    {
        if (!pAdapter->aStaInfo[i].isUsed)
                continue;

        if (CHAN_HOP_ALL_BANDS_ENABLE &&
            (i == (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId))
                continue;

        if (WE_GET_STA_INFO_SIZE > buf_len)
                break;

        len = scnprintf(pBuf, buf_len,
                        "%d: %02x:%02x:%02x:%02x:%02x:%02x \t ecsa=%d\n",
                        pAdapter->aStaInfo[i].ucSTAId,
                        pAdapter->aStaInfo[i].macAddrSTA.bytes[0],
                        pAdapter->aStaInfo[i].macAddrSTA.bytes[1],
                        pAdapter->aStaInfo[i].macAddrSTA.bytes[2],
                        pAdapter->aStaInfo[i].macAddrSTA.bytes[3],
                        pAdapter->aStaInfo[i].macAddrSTA.bytes[4],
                        pAdapter->aStaInfo[i].macAddrSTA.bytes[5],
                        pAdapter->aStaInfo[i].ecsa_capable);

        if (len >= buf_len) {
                hddLog(LOGE, FL("Insufficient buffer:%d, %d"), buf_len, len);
                return -E2BIG;
        }
        pBuf += len;
        buf_len -= len;
    }
    EXIT();
    return 0;
}

static int __iw_softap_get_sta_info(struct net_device *dev,
                                    struct iw_request_info *info,
                                    union iwreq_data *wrqu,
                                    char *extra)
{
    hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
    hdd_context_t *hdd_ctx;
    int ret;

    ENTER();

    hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
    ret = wlan_hdd_validate_context(hdd_ctx);
    if (0 != ret)
        return ret;

    ret = hdd_softap_get_sta_info(pHostapdAdapter, extra, WE_SAP_MAX_STA_INFO);
    if (ret) {
       hddLog(VOS_TRACE_LEVEL_ERROR, "%s Failed!!!",__func__);
       return ret;
    }
    wrqu->data.length = strlen(extra);
    EXIT();
    return 0;
}

static int iw_softap_get_sta_info(struct net_device *dev,
                                  struct iw_request_info *info,
                                  union iwreq_data *wrqu,
                                  char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_softap_get_sta_info(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

/**
 * __iw_set_ap_genie() - set ap wpa/rsn ie
 *
 * @dev - Pointer to the net device.
 * @info - Pointer to the iw_request_info.
 * @wrqu - Pointer to the iwreq_data.
 * @extra - Pointer to the data.
 *
 * Return: 0 for success, non zero for failure.
 */
static int __iw_set_ap_genie(struct net_device *dev,
			     struct iw_request_info *info,
			     union iwreq_data *wrqu,
			     char *extra)
{

    hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
#ifndef WLAN_FEATURE_MBSSID
    v_CONTEXT_t pVosContext;
#endif
    eHalStatus halStatus= eHAL_STATUS_SUCCESS;
    u_int8_t *genie = (u_int8_t *)extra;
    hdd_context_t *hdd_ctx;
    int ret;

    ENTER();

    hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
    ret = wlan_hdd_validate_context(hdd_ctx);
    if (0 != ret)
        return ret;

#ifndef WLAN_FEATURE_MBSSID
    pVosContext = hdd_ctx->pvosContext;
    if (NULL == pVosContext) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "%s: VOS Context is NULL", __func__);
        return -EINVAL;
    }
#endif

    if(!wrqu->data.length)
    {
        EXIT();
        return 0;
    }

    if (wrqu->data.length > DOT11F_IE_RSN_MAX_LEN) {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
               "%s: WPARSN Ie input length is more than max[%d]", __func__,
                wrqu->data.length);
       return -EINVAL;
    }

    switch (genie[0])
    {
        case DOT11F_EID_WPA:
        case DOT11F_EID_RSN:
            if((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy == 0)
            {
                hdd_softap_Deregister_BC_STA(pHostapdAdapter);
                hdd_softap_Register_BC_STA(pHostapdAdapter, 1);
            }
            (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1;
#ifdef WLAN_FEATURE_MBSSID
            halStatus = WLANSAP_Set_WPARSNIes(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter), genie, wrqu->data.length);
#else
            halStatus = WLANSAP_Set_WPARSNIes(pVosContext, genie, wrqu->data.length);
#endif
            break;

        default:
            hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, genie[0]);
            halStatus = 0;
    }

    EXIT();
    return halStatus;
}

/**
 * iw_set_ap_genie() - Wrapper function to protect __iw_set_ap_genie
 *                      from the SSR.
 *
 * @dev - Pointer to the net device.
 * @info - Pointer to the iw_request_info.
 * @wrqu - Pointer to the iwreq_data.
 * @extra - Pointer to the data.
 *
 * Return: 0 for success, non zero for failure.
 */
static int
iw_set_ap_genie(struct net_device *dev,
		struct iw_request_info *info,
		union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_set_ap_genie(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}


VOS_STATUS  wlan_hdd_get_linkspeed_for_peermac(hdd_adapter_t *pAdapter,
                                               tSirMacAddr macAddress)
{
   eHalStatus hstatus;
   unsigned long rc;
   struct linkspeedContext context;
   tSirLinkSpeedInfo *linkspeed_req;

   if (NULL == pAdapter)
   {
      hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
      return VOS_STATUS_E_FAULT;
   }
   linkspeed_req = (tSirLinkSpeedInfo *)vos_mem_malloc(sizeof(*linkspeed_req));
   if (NULL == linkspeed_req)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                          "%s Request Buffer Alloc Fail", __func__);
      return VOS_STATUS_E_INVAL;
   }
   init_completion(&context.completion);
   context.pAdapter = pAdapter;
   context.magic = LINK_CONTEXT_MAGIC;

   vos_mem_copy(linkspeed_req->peer_macaddr, macAddress, sizeof(tSirMacAddr) );
   hstatus = sme_GetLinkSpeed( WLAN_HDD_GET_HAL_CTX(pAdapter),
                                  linkspeed_req,
                                  &context,
                                  hdd_GetLink_SpeedCB);
   if (eHAL_STATUS_SUCCESS != hstatus)
   {
      hddLog(VOS_TRACE_LEVEL_ERROR,
            "%s: Unable to retrieve statistics for link speed",
            __func__);
      vos_mem_free(linkspeed_req);
   }
   else
   {
      rc = wait_for_completion_timeout(&context.completion,
            msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
      if (!rc) {
         hddLog(VOS_TRACE_LEVEL_ERROR,
               "%s: SME timed out while retrieving link speed",
              __func__);
      }
   }

   /* 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);
   context.magic = 0;
   spin_unlock(&hdd_context_lock);
   return VOS_STATUS_SUCCESS;
}


static int
__iw_get_softap_linkspeed(struct net_device *dev, struct iw_request_info *info,
                        union iwreq_data *wrqu, char *extra)
{
   hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
   hdd_context_t *pHddCtx;
   char *pLinkSpeed = (char*)extra;
   char *pmacAddress;
   v_U32_t link_speed = 0;
   int len = sizeof(v_U32_t)+1;
   tSirMacAddr macAddress;
   VOS_STATUS status = VOS_STATUS_E_FAILURE;
   int rc, valid, i;

   ENTER();

   pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
   valid = wlan_hdd_validate_context(pHddCtx);
   if (0 != valid)
       return valid;

   hddLog(VOS_TRACE_LEVEL_INFO, "%s wrqu->data.length= %d\n", __func__, wrqu->data.length);

   if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1)
   {
      pmacAddress = vos_mem_malloc(MAC_ADDRESS_STR_LEN);
      if (NULL == pmacAddress) {
          hddLog(LOG1, "unable to allocate memory");
          return -ENOMEM;
      }
      if (copy_from_user((void *)pmacAddress,
          wrqu->data.pointer, MAC_ADDRESS_STR_LEN))
      {
          hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
          vos_mem_free(pmacAddress);
          return -EFAULT;
      }
      pmacAddress[MAC_ADDRESS_STR_LEN -1] = '\0';

      status = hdd_string_to_hex (pmacAddress, MAC_ADDRESS_STR_LEN, macAddress );
      vos_mem_free(pmacAddress);

      if (!VOS_IS_STATUS_SUCCESS(status ))
      {
         hddLog(VOS_TRACE_LEVEL_ERROR, FL("String to Hex conversion Failed"));
      }
   }
   /* If no mac address is passed and/or its length is less than 17,
    * link speed for first connected client will be returned.
    */
   if (wrqu->data.length < 17 || !VOS_IS_STATUS_SUCCESS(status )) {
      for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
          if (pHostapdAdapter->aStaInfo[i].isUsed &&
             (!vos_is_macaddr_broadcast(&pHostapdAdapter->aStaInfo[i].macAddrSTA))) {
             vos_copy_macaddr((v_MACADDR_t *)macAddress,
                               &pHostapdAdapter->aStaInfo[i].macAddrSTA);
             status = VOS_STATUS_SUCCESS;
             break;
          }
      }
   }
   if (!VOS_IS_STATUS_SUCCESS(status )) {
      hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid peer macaddress"));
      return -EINVAL;
   }
   status = wlan_hdd_get_linkspeed_for_peermac(pHostapdAdapter,
                                               macAddress);
   if (!VOS_IS_STATUS_SUCCESS(status ))
   {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve SME linkspeed"));
        return -EINVAL;
   }

   link_speed = pHostapdAdapter->ls_stats.estLinkSpeed;

   /* linkspeed in units of 500 kbps */
   link_speed = link_speed / 500;
   wrqu->data.length  = len;
   rc = snprintf(pLinkSpeed, len, "%u", link_speed);
   if ((rc < 0) || (rc >= len))
   {
       // encoding or length error?
       hddLog(VOS_TRACE_LEVEL_ERROR,FL("Unable to encode link speed"));
       return -EIO;
   }
   EXIT();
   return 0;
}

static int
iw_get_softap_linkspeed(struct net_device *dev, struct iw_request_info *info,
                        union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_get_softap_linkspeed(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

/**
 * hdd_get_rssi_cb() - get station's rssi callback
 * @sta_rssi: pointer of peer information
 * @context: get rssi callback context
 *
 * This function will fill rssi information to hostapd
 * adapter
 *
 */
void hdd_get_rssi_cb(struct sir_peer_info_resp *sta_rssi, void *context)
{
	struct statsContext *get_rssi_context;
	struct sir_peer_info *rssi_info;
	uint8_t peer_num;
	int i;
	int buf = 0;
	int length = 0;
	char *rssi_info_output;
	union iwreq_data *wrqu;

	if ((NULL == sta_rssi) || (NULL == context)) {

		hddLog(VOS_TRACE_LEVEL_ERROR,
			"%s: Bad param, sta_rssi [%pK] context [%pK]",
			__func__, sta_rssi, context);
		return;
	}

	spin_lock(&hdd_context_lock);
	/*
	 * 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
	 */
	get_rssi_context = context;
	if (PEER_INFO_CONTEXT_MAGIC !=
			get_rssi_context->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__,
			get_rssi_context->magic);
		return;
	}

	rssi_info_output = get_rssi_context->extra;
	wrqu = get_rssi_context->wrqu;
	peer_num = sta_rssi->count;
	rssi_info = sta_rssi->info;
	get_rssi_context->magic = 0;

	hddLog(LOG1, "%s : %d peers", __func__, peer_num);


	/*
	 * The iwpriv tool default print is before mac addr and rssi.
	 * Add '\n' before first rssi item to align the frist rssi item
	 * with others
	 *
	 * wlan     getRSSI:
	 * [macaddr1] [rssi1]
	 * [macaddr2] [rssi2]
	 * [macaddr3] [rssi3]
	 */
	length = scnprintf((rssi_info_output), WE_MAX_STR_LEN, "\n");
	for (i = 0; i < peer_num; i++) {
		buf = scnprintf
			(
			(rssi_info_output + length), WE_MAX_STR_LEN - length,
			"[%pM] [%d]\n",
			rssi_info[i].peer_macaddr,
			rssi_info[i].rssi
			);
			length += buf;
	}
	wrqu->data.length = length + 1;

	/* notify the caller */
	complete(&get_rssi_context->completion);

	/* serialization is complete */
	spin_unlock(&hdd_context_lock);
}

/**
 * wlan_hdd_get_peer_rssi() - get station's rssi
 * @adapter: hostapd interface
 * @macaddress: iwpriv request information
 * @wrqu: iwpriv command parameter
 * @extra
 *
 * This function will call sme_get_peer_info to get rssi
 *
 * Return: 0 on success, otherwise error value
 */
static int  wlan_hdd_get_peer_rssi(hdd_adapter_t *adapter,
					v_MACADDR_t macaddress,
					char *extra,
					union iwreq_data *wrqu)
{
	eHalStatus hstatus;
	int ret;
	struct statsContext context;
	struct sir_peer_info_req rssi_req;

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

	init_completion(&context.completion);
	context.magic = PEER_INFO_CONTEXT_MAGIC;
	context.extra = extra;
	context.wrqu = wrqu;

	vos_mem_copy(&(rssi_req.peer_macaddr), &macaddress,
				VOS_MAC_ADDR_SIZE);
	rssi_req.sessionid = adapter->sessionId;
	hstatus = sme_get_peer_info(WLAN_HDD_GET_HAL_CTX(adapter),
				rssi_req,
				&context,
				hdd_get_rssi_cb);
	if (eHAL_STATUS_SUCCESS != hstatus) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
			"%s: Unable to retrieve statistics for rssi",
			__func__);
		ret = -EFAULT;
	} else {
		if (!wait_for_completion_timeout(&context.completion,
				msecs_to_jiffies(WLAN_WAIT_TIME_STATS))) {
			hddLog(VOS_TRACE_LEVEL_ERROR,
				"%s: SME timed out while retrieving rssi",
				__func__);
			ret = -EFAULT;
		} else
			ret = 0;
	}
	/*
	 * 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);
	context.magic = 0;
	spin_unlock(&hdd_context_lock);
	return ret;
}

/**
 * __iw_get_peer_rssi() - get station's rssi
 * @dev: net device
 * @info: iwpriv request information
 * @wrqu: iwpriv command parameter
 * @extra
 *
 * This function will call wlan_hdd_get_peer_rssi
 * to get rssi
 *
 * Return: 0 on success, otherwise error value
 */
static int
__iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info,
			union iwreq_data *wrqu, char *extra)
{
	hdd_adapter_t *adapter = (netdev_priv(dev));
	hdd_context_t *hddctx;
	char macaddrarray[18];
	v_MACADDR_t macaddress = VOS_MAC_ADDR_BROADCAST_INITIALIZER;
	VOS_STATUS status = VOS_STATUS_E_FAILURE;
	int ret;

	ENTER();

	hddctx = WLAN_HDD_GET_CTX(adapter);
	ret = wlan_hdd_validate_context(hddctx);
	if (0 != ret)
		return ret;

	hddLog(VOS_TRACE_LEVEL_INFO, "%s wrqu->data.length= %d",
			__func__, wrqu->data.length);

	if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1) {

		if (copy_from_user(macaddrarray,
			wrqu->data.pointer, MAC_ADDRESS_STR_LEN - 1)) {

			hddLog(LOG1, "%s: failed to copy data to user buffer",
					__func__);
			return -EFAULT;
		}

		macaddrarray[MAC_ADDRESS_STR_LEN - 1] = '\0';
		hddLog(LOG1, "%s, %s",
				__func__, macaddrarray);

		status = hdd_string_to_hex(macaddrarray,
				MAC_ADDRESS_STR_LEN, macaddress.bytes );

		if (!VOS_IS_STATUS_SUCCESS(status)) {
			hddLog(VOS_TRACE_LEVEL_ERROR,
				FL("String to Hex conversion Failed"));
		}
	}

	return wlan_hdd_get_peer_rssi(adapter, macaddress, extra, wrqu);
}

/**
 * iw_get_peer_rssi() - get station's rssi
 * @dev: net device
 * @info: iwpriv request information
 * @wrqu: iwpriv command parameter
 * @extra
 *
 * This function will call __iw_get_peer_rssi
 *
 * Return: 0 on success, otherwise error value
 */
static int
iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info,
			union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_get_peer_rssi(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

static const iw_handler      hostapd_handler[] =
{
   (iw_handler) NULL,           /* SIOCSIWCOMMIT */
   (iw_handler) NULL,           /* SIOCGIWNAME */
   (iw_handler) NULL,           /* SIOCSIWNWID */
   (iw_handler) NULL,           /* SIOCGIWNWID */
   (iw_handler) NULL,           /* SIOCSIWFREQ */
   (iw_handler) iw_get_ap_freq,    /* SIOCGIWFREQ */
   (iw_handler) NULL,           /* SIOCSIWMODE */
   (iw_handler) iw_get_mode,    /* SIOCGIWMODE */
   (iw_handler) NULL,           /* SIOCSIWSENS */
   (iw_handler) NULL,           /* SIOCGIWSENS */
   (iw_handler) NULL,           /* SIOCSIWRANGE */
   (iw_handler) NULL,           /* SIOCGIWRANGE */
   (iw_handler) NULL,           /* SIOCSIWPRIV */
   (iw_handler) NULL,           /* SIOCGIWPRIV */
   (iw_handler) NULL,           /* SIOCSIWSTATS */
   (iw_handler) NULL,           /* SIOCGIWSTATS */
   (iw_handler) NULL,           /* SIOCSIWSPY */
   (iw_handler) NULL,           /* SIOCGIWSPY */
   (iw_handler) NULL,           /* SIOCSIWTHRSPY */
   (iw_handler) NULL,           /* SIOCGIWTHRSPY */
   (iw_handler) NULL,           /* SIOCSIWAP */
   (iw_handler) NULL,           /* SIOCGIWAP */
   (iw_handler) iw_set_ap_mlme,    /* SIOCSIWMLME */
   (iw_handler) NULL,           /* SIOCGIWAPLIST */
   (iw_handler) NULL,           /* SIOCSIWSCAN */
   (iw_handler) NULL,           /* SIOCGIWSCAN */
   (iw_handler) NULL,           /* SIOCSIWESSID */
   (iw_handler) NULL,           /* SIOCGIWESSID */
   (iw_handler) NULL,           /* SIOCSIWNICKN */
   (iw_handler) NULL,           /* SIOCGIWNICKN */
   (iw_handler) NULL,           /* -- hole -- */
   (iw_handler) NULL,           /* -- hole -- */
   (iw_handler) NULL,           /* SIOCSIWRATE */
   (iw_handler) NULL,           /* SIOCGIWRATE */
   (iw_handler) NULL,           /* SIOCSIWRTS */
   (iw_handler) iw_get_ap_rts_threshold,     /* SIOCGIWRTS */
   (iw_handler) NULL,           /* SIOCSIWFRAG */
   (iw_handler) iw_get_ap_frag_threshold,    /* SIOCGIWFRAG */
   (iw_handler) NULL,           /* SIOCSIWTXPOW */
   (iw_handler) NULL,           /* SIOCGIWTXPOW */
   (iw_handler) NULL,           /* SIOCSIWRETRY */
   (iw_handler) NULL,           /* SIOCGIWRETRY */
   (iw_handler) NULL,           /* SIOCSIWENCODE */
   (iw_handler) NULL,           /* SIOCGIWENCODE */
   (iw_handler) NULL,           /* SIOCSIWPOWER */
   (iw_handler) NULL,           /* SIOCGIWPOWER */
   (iw_handler) NULL,           /* -- hole -- */
   (iw_handler) NULL,           /* -- hole -- */
   (iw_handler) iw_set_ap_genie,     /* SIOCSIWGENIE */
   (iw_handler) NULL,           /* SIOCGIWGENIE */
   (iw_handler) iw_set_auth_hostap,    /* SIOCSIWAUTH */
   (iw_handler) NULL,           /* SIOCGIWAUTH */
   (iw_handler) iw_set_ap_encodeext,     /* SIOCSIWENCODEEXT */
   (iw_handler) NULL,           /* SIOCGIWENCODEEXT */
   (iw_handler) NULL,           /* SIOCSIWPMKSA */
};

/*
 * Note that the following ioctls were defined with semantics which
 * cannot be handled by the "iwpriv" userspace application and hence
 * they are not included in the hostapd_private_args array
 *     QCSAP_IOCTL_ASSOC_STA_MACADDR
 */

static const struct iw_priv_args hostapd_private_args[] = {
  { QCSAP_IOCTL_SETPARAM,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam" },
  { QCSAP_IOCTL_SETPARAM,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" },
  { QCSAP_PARAM_MAX_ASSOC,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMaxAssoc" },
   { QCSAP_PARAM_HIDE_SSID,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,  "hideSSID" },
   { QCSAP_PARAM_SET_MC_RATE,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,  "setMcRate" },
   { QCSAP_PARAM_SET_TXRX_FW_STATS,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,  "txrx_fw_stats" },
   { QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,  "setMccLatency" },
   { QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,  "setMccQuota" },
   { QCSAP_PARAM_AUTO_CHANNEL,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,  "setAutoChannel" },
   { QCSAP_PARAM_SET_CHANNEL_CHANGE,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,  "setChanChange" },

 /* Sub-cmds DBGLOG specific commands */
    {   QCSAP_DBGLOG_LOG_LEVEL ,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "dl_loglevel" },

    {   QCSAP_DBGLOG_VAP_ENABLE ,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "dl_vapon" },

    {   QCSAP_DBGLOG_VAP_DISABLE ,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "dl_vapoff" },

    {   QCSAP_DBGLOG_MODULE_ENABLE ,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "dl_modon" },

    {   QCSAP_DBGLOG_MODULE_DISABLE,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "dl_modoff" },

    {   QCSAP_DBGLOG_MOD_LOG_LEVEL,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "dl_mod_loglevel" },

    {   QCSAP_DBGLOG_TYPE,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "dl_type" },
    {   QCSAP_DBGLOG_REPORT_ENABLE,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "dl_report" },
    {   QCASAP_TXRX_FWSTATS_RESET,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "txrx_fw_st_rst" },
    {   QCSAP_PARAM_RTSCTS,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "enablertscts" },

    {   QCASAP_SET_11N_RATE,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "set11NRates" },

    {   QCASAP_SET_VHT_RATE,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "set11ACRates" },

    {   QCASAP_SHORT_GI,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "enable_short_gi" },

    {   QCSAP_SET_AMPDU,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "ampdu" },

    {   QCSAP_SET_AMSDU,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "amsdu" },

    {  QCSAP_GTX_HT_MCS,
       IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "gtxHTMcs" },

    {  QCSAP_GTX_VHT_MCS,
       IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "gtxVHTMcs" },

    {  QCSAP_GTX_USRCFG,
       IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "gtxUsrCfg" },

    {  QCSAP_GTX_THRE,
       IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "gtxThre" },

    {  QCSAP_GTX_MARGIN,
       IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "gtxMargin" },

    {  QCSAP_GTX_STEP,
       IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "gtxStep" },

    {  QCSAP_GTX_MINTPC,
       IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "gtxMinTpc" },

    {  QCSAP_GTX_BWMASK,
       IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "gtxBWMask" },

    { QCSAP_PARAM_CLR_ACL,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
      0,
      "setClearAcl" },

   {  QCSAP_PARAM_ACL_MODE,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
      0,
      "setAclMode" },

#ifdef QCA_PKT_PROTO_TRACE
    {   QCASAP_SET_DEBUG_LOG,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "setDbgLvl" },
#endif /* QCA_PKT_PROTO_TRACE */

    {   QCASAP_SET_TM_LEVEL,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "setTmLevel" },

    {   QCASAP_SET_DFS_IGNORE_CAC,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "setDfsIgnoreCAC" },

    {   QCASAP_SET_DFS_NOL,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "setdfsnol" },

    {   QCASAP_SET_DFS_TARGET_CHNL,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "setNextChnl" },

    {   QCASAP_SET_RADAR_CMD,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "setRadar" },
#ifdef IPA_UC_OFFLOAD
    {   QCSAP_IPA_UC_STAT,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "ipaucstat" },
#endif /* IPA_UC_OFFLOAD */

    {   QCASAP_TX_CHAINMASK_CMD,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "set_txchainmask" },

    {   QCASAP_RX_CHAINMASK_CMD,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "set_rxchainmask" },

    {   QCASAP_NSS_CMD,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "set_nss" },

    {   QCASAP_SET_PHYMODE,
        IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
        0,
        "setphymode" },

    {   QCASAP_DUMP_STATS,
        IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
        0,
        "dumpStats" },

    {   QCASAP_CLEAR_STATS,
        IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
        0,
        "clearStats" },
    {   QCASAP_PARAM_LDPC,
        IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
        0,
        "set_ldpc" },
    {   QCASAP_PARAM_TX_STBC,
        IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
        0,
        "set_tx_stbc" },
    {   QCASAP_PARAM_RX_STBC,
        IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
        0,
        "set_rx_stbc" },

    {   QCSAP_SET_DEFAULT_AMPDU,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "def_ampdu" },

    {   QCSAP_ENABLE_RTS_BURSTING,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "rts_bursting" },

    {   QCSAP_ENABLE_DYNAMIC_BW,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "cwmenable" },


  { QCSAP_IOCTL_GETPARAM, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "getparam" },
  { QCSAP_IOCTL_GETPARAM, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "" },
  { QCSAP_PARAM_MAX_ASSOC, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "getMaxAssoc" },
  { QCSAP_PARAM_GET_WLAN_DBG, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "getwlandbg" },
  { QCSAP_PARAM_AUTO_CHANNEL, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "getAutoChannel" },
  { QCSAP_GTX_BWMASK, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "get_gtxBWMask" },
  { QCSAP_GTX_MINTPC, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "get_gtxMinTpc" },
  { QCSAP_GTX_STEP, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "get_gtxStep" },
  { QCSAP_GTX_MARGIN, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "get_gtxMargin" },
  { QCSAP_GTX_THRE, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "get_gtxThre" },
  { QCSAP_GTX_USRCFG, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "get_gtxUsrCfg" },
  { QCSAP_GTX_VHT_MCS, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "get_gtxVHTMcs" },
  { QCSAP_GTX_HT_MCS, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "get_gtxHTMcs" },
  { QCASAP_SHORT_GI, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "get_short_gi" },
  { QCSAP_PARAM_RTSCTS, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "get_rtscts" },
  { QCASAP_GET_DFS_NOL, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "getdfsnol" },
  { QCSAP_GET_ACL, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "get_acl_list" },
  { QCASAP_PARAM_LDPC, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "get_ldpc" },
  { QCASAP_PARAM_TX_STBC, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "get_tx_stbc" },
  { QCASAP_PARAM_RX_STBC, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "get_rx_stbc" },
  { QCSAP_PARAM_CHAN_WIDTH, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "get_chwidth" },
#ifdef WLAN_FEATURE_TSF
  { QCSAP_CAP_TSF, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "cap_tsf" },
#endif
  { QCSAP_IOCTL_SET_NONE_GET_THREE, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,    "" },
#ifdef WLAN_FEATURE_TSF
  { QCSAP_GET_TSF, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,    "get_tsf" },
#endif
  { QCASAP_TX_CHAINMASK_CMD, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "get_txchainmask" },
  { QCASAP_RX_CHAINMASK_CMD, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "get_rxchainmask" },
  { QCSAP_GET_DYNAMIC_BW, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "get_cwmenable" },
  { QCASAP_NSS_CMD, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "get_nss" },
  { QCASAP_GET_TEMP_CMD, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "get_temp" },
  { QCSAP_GET_FW_STATUS, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "get_fwstate" },

  { QCSAP_IOCTL_GET_STAWPAIE,
      0,IW_PRIV_TYPE_BYTE |  DOT11F_IE_RSN_MAX_LEN, "get_staWPAIE" },
  { QCSAP_IOCTL_STOPBSS,
      IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0, "stopbss" },
  { QCSAP_IOCTL_VERSION, 0,
      IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "version" },
  { QCSAP_IOCTL_GET_STA_INFO, 0,
      IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info" },
  { QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES,
      IW_PRIV_TYPE_BYTE | sizeof(sQcSapreq_WPSPBCProbeReqIES_t) | IW_PRIV_SIZE_FIXED, 0, "getProbeReqIEs" },
  { QCSAP_IOCTL_GET_CHANNEL, 0,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel" },
  { QCSAP_IOCTL_DISASSOC_STA,
        IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6 , 0, "disassoc_sta" },
  { QCSAP_IOCTL_AP_STATS, 0,
        IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "ap_stats" },
   /* handler for main ioctl */
  { QCSAP_PRIV_GET_CHAR_SET_NONE, 0,
        IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,"" },
   /* handler for sub-ioctl */
  { QCSAP_GET_STATS, 0,
        IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "getStats" },
  { QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
        IW_PRIV_TYPE_CHAR | 18,
        IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed" },
  { QCSAP_IOCTL_PRIV_GET_RSSI,
        IW_PRIV_TYPE_CHAR | 18,
        IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "getRSSI" },
  { QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "" },
   /* handlers for sub-ioctl */
   {   WE_SET_WLAN_DBG,
       IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
       0,
       "setwlandbg" },

   {   WE_SET_SAP_CHANNELS,
       IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
       0,
       "setsapchannels" },

   /* handlers for sub-ioctl */
   {  WE_SET_DP_TRACE,
      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
      0,
      "set_dp_trace" },

   /* handlers for main ioctl */
   {   QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE,
       IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
       0,
       "" },

   /* handlers for sub-ioctl */
   {   WE_LOG_DUMP_CMD,
       IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
       0,
       "dump" },
   {   WE_P2P_NOA_CMD,
       IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
       0,
       "SetP2pPs" },
     /* handlers for sub ioctl */
    {
        WE_MCC_CONFIG_CREDENTIAL,
        IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
        0,
        "setMccCrdnl" },

     /* handlers for sub ioctl */
    {
        WE_MCC_CONFIG_PARAMS,
        IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
        0,
        "setMccConfig" },

    {
        WE_UNIT_TEST_CMD,
        IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
        0,
        "setUnitTestCmd" },

#ifdef MEMORY_DEBUG
    /* handlers for sub ioctl */
    {   WE_MEM_TRACE_DUMP,
        IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
        0,
        "memTraceLog" },
#endif

    /* handlers for main ioctl */
    {   QCSAP_IOCTL_MODIFY_ACL,
        IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8,
        0,
        "modify_acl" },

    /* handlers for main ioctl */
    {   QCSAP_IOCTL_GET_CHANNEL_LIST,
        0,
        IW_PRIV_TYPE_BYTE | sizeof(tChannelListInfo),
        "getChannelList" },

    /* handlers for main ioctl */
    {   QCSAP_IOCTL_SET_TX_POWER,
        IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
        0,
        "setTxPower" },

    /* handlers for main ioctl */
    {   QCSAP_IOCTL_SET_MAX_TX_POWER,
        IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1,
        0,
        "setTxMaxPower" },

    {   QCSAP_IOCTL_DATAPATH_SNAP_SHOT,
        IW_PRIV_TYPE_NONE | IW_PRIV_TYPE_NONE,
        0,
        "dataSnapshot" },

    /* Set HDD CFG Ini param */
    {   QCSAP_IOCTL_SET_INI_CFG,
        IW_PRIV_TYPE_CHAR | QCSAP_IOCTL_MAX_STR_LEN,
        0,
        "setConfig" },

    /* Get HDD CFG Ini param */
    {   QCSAP_IOCTL_GET_INI_CFG,
        0,
        IW_PRIV_TYPE_CHAR | QCSAP_IOCTL_MAX_STR_LEN,
        "getConfig" },

    /* handlers for main ioctl */
    {   QCSAP_IOCTL_SET_TWO_INT_GET_NONE,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
        0,
        "" },
    /* handlers for sub-ioctl */
#ifdef WLAN_DEBUG
    {   QCSAP_IOCTL_SET_FW_CRASH_INJECT,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
        0,
        "crash_inject" },
#endif

    /* handlers for main ioctl */
    {   QCSAP_IOCTL_WOWL_CONFIG_PTRN,
        IW_PRIV_TYPE_CHAR | 512,
        0,
        "" },

    /* handlers for sub-ioctl */
    {   WE_WOWL_ADD_PTRN,
        IW_PRIV_TYPE_CHAR | 512,
        0,
        "wowlAddPtrn" },

    {   WE_WOWL_DEL_PTRN,
        IW_PRIV_TYPE_CHAR | 512,
        0,
        "wowlDelPtrn" },

    {   QCASAP_SET_RADAR_DBG,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,  "setRadarDbg" },

    /* dump dp trace - descriptor or dp trace records */
    {   QCSAP_IOCTL_DUMP_DP_TRACE_LEVEL,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
        0, "dump_dp_trace" },
};

static const iw_handler hostapd_private[] = {
   [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam,  //set priv ioctl
   [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam,  //get priv ioctl
   [QCSAP_IOCTL_SET_NONE_GET_THREE - SIOCIWFIRSTPRIV] = iw_softap_get_three,
   [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie, //get station genIE
   [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss,       // stop bss
   [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version,       // get driver version
   [QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES - SIOCIWFIRSTPRIV] = iw_get_WPSPBCProbeReqIEs,
   [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] = iw_softap_getchannel,
   [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] = iw_softap_getassoc_stamacaddr,
   [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] = iw_softap_disassoc_sta,
   [QCSAP_IOCTL_AP_STATS - SIOCIWFIRSTPRIV] = iw_softap_ap_stats,
   [QCSAP_PRIV_GET_CHAR_SET_NONE - SIOCIWFIRSTPRIV] = iw_get_char_setnone,
   [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV]  = iw_set_three_ints_getnone,
   [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV]     = iw_set_var_ints_getnone,
   [QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] =
                                             iw_softap_set_force_acs_ch_range,
   [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV]   = iw_softap_modify_acl,
   [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV]   = iw_get_channel_list,
   [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] = iw_softap_get_sta_info,
   [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED - SIOCIWFIRSTPRIV]     = iw_get_softap_linkspeed,
   [QCSAP_IOCTL_PRIV_GET_RSSI - SIOCIWFIRSTPRIV] = iw_get_peer_rssi,
   [QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV]   = iw_softap_set_tx_power,
   [QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV]   = iw_softap_set_max_tx_power,
   [QCSAP_IOCTL_DATAPATH_SNAP_SHOT - SIOCIWFIRSTPRIV]  =   iw_display_data_path_snapshot,
   [QCSAP_IOCTL_SET_INI_CFG - SIOCIWFIRSTPRIV]  =  iw_softap_set_ini_cfg,
   [QCSAP_IOCTL_GET_INI_CFG - SIOCIWFIRSTPRIV]  =  iw_softap_get_ini_cfg,
   [QCSAP_IOCTL_SET_TWO_INT_GET_NONE - SIOCIWFIRSTPRIV] =
                                                iw_softap_set_two_ints_getnone,
   [QCSAP_IOCTL_WOWL_CONFIG_PTRN - SIOCIWFIRSTPRIV] = iw_softap_wowl_config_pattern,
};
const struct iw_handler_def hostapd_handler_def = {
   .num_standard     = sizeof(hostapd_handler) / sizeof(hostapd_handler[0]),
#ifdef CONFIG_WEXT_PRIV
   .num_private      = sizeof(hostapd_private) / sizeof(hostapd_private[0]),
   .num_private_args = sizeof(hostapd_private_args) / sizeof(hostapd_private_args[0]),
#endif
   .standard         = (iw_handler *)hostapd_handler,
#ifdef CONFIG_WEXT_PRIV
   .private          = (iw_handler *)hostapd_private,
   .private_args     = hostapd_private_args,
#endif
   .get_wireless_stats = NULL,
};

struct net_device_ops net_ops_struct  = {
    .ndo_open = hdd_hostapd_open,
    .ndo_stop = hdd_hostapd_stop,
    .ndo_uninit = hdd_hostapd_uninit,
    .ndo_start_xmit = hdd_softap_hard_start_xmit,
    .ndo_tx_timeout = hdd_softap_tx_timeout,
    .ndo_get_stats = hdd_softap_stats,
    .ndo_set_mac_address = hdd_hostapd_set_mac_address,
    .ndo_do_ioctl = hdd_hostapd_ioctl,
    .ndo_change_mtu = hdd_hostapd_change_mtu,
    .ndo_select_queue = hdd_hostapd_select_queue,
 };

static int hdd_set_hostapd(hdd_adapter_t *pAdapter)
{
    return VOS_STATUS_SUCCESS;
}

void hdd_set_ap_ops( struct net_device *pWlanHostapdDev )
{
  pWlanHostapdDev->netdev_ops = &net_ops_struct;
}

VOS_STATUS hdd_init_ap_mode(hdd_adapter_t *pAdapter, bool reinit)
{
    hdd_hostapd_state_t * phostapdBuf;
#ifdef CONFIG_WIRELESS_EXT
    struct net_device *dev = pAdapter->dev;
#endif
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    VOS_STATUS status;
#ifdef WLAN_FEATURE_MBSSID
    v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
    v_CONTEXT_t sapContext=NULL;
    enum dfs_mode mode;
    tVOS_CON_MODE device_mode;
    uint32_t session_id = CSR_SESSION_ID_INVALID;
#endif
    int ret;

    ENTER();

    hdd_set_sap_auth_offload(pAdapter, TRUE);

    ret = hdd_set_client_block_info(pAdapter);
    if (0 != ret) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
            "%s: set client block info failed %d",
            __func__, ret);
    }

    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
               FL("SSR in progress: %d"), reinit);
#ifdef WLAN_FEATURE_MBSSID
    if (reinit) {
        sapContext = pAdapter->sessionCtx.ap.sapContext;
    } else {
        sapContext = WLANSAP_Open(pVosContext);
        if (sapContext == NULL)
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                       FL("ERROR: WLANSAP_Open failed!!"));
            return VOS_STATUS_E_FAULT;
        }

        pAdapter->sessionCtx.ap.sapContext = sapContext;
        pAdapter->sessionCtx.ap.sapConfig.channel =
                                   pHddCtx->acs_policy.acs_channel;
        mode = pHddCtx->acs_policy.acs_dfs_mode;
        pAdapter->sessionCtx.ap.sapConfig.acs_dfs_mode =
                                        wlan_hdd_get_dfs_mode(mode);
    }

    if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
        device_mode = VOS_P2P_GO_MODE;
    } else if (pAdapter->device_mode == WLAN_HDD_SOFTAP) {
        device_mode = VOS_STA_SAP_MODE;
    } else {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                FL("Invalid device_mode for AP: %d"), pAdapter->device_mode);
        return VOS_STATUS_E_FAILURE;
    }

    ret = process_wma_set_command((int)pAdapter->sessionId,
                         (int)WMI_PDEV_PARAM_BURST_ENABLE,
                         (int)pHddCtx->cfg_ini->enableSifsBurst,
                         PDEV_CMD);

    if (0 != ret) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                    "%s: WMI_PDEV_PARAM_BURST_ENABLE set failed %d",
                    __func__, ret);
    }

    status = WLANSAP_Start(sapContext, device_mode,
            pAdapter->macAddressCurrent.bytes,
            &session_id);
    if ( ! VOS_IS_STATUS_SUCCESS( status ) )
    {
          VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: WLANSAP_Start failed!!"));
          WLANSAP_Close(sapContext);
          pAdapter->sessionCtx.ap.sapContext = NULL;
          return status;
    }
    pAdapter->sessionId = session_id;
#endif

    // Allocate the Wireless Extensions state structure
    phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR( pAdapter );

    sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);

    // Zero the memory.  This zeros the profile structure.
    memset(phostapdBuf, 0,sizeof(hdd_hostapd_state_t));

    // Set up the pointer to the Wireless Extensions state structure
    // NOP
    status = hdd_set_hostapd(pAdapter);
    if(!VOS_IS_STATUS_SUCCESS(status)) {
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,("ERROR: hdd_set_hostapd failed!!"));
#ifdef WLAN_FEATURE_MBSSID
         WLANSAP_Close(sapContext);
         pAdapter->sessionCtx.ap.sapContext = NULL;
#endif
         return status;
    }

    status = vos_event_init(&phostapdBuf->vosEvent);
    if (!VOS_IS_STATUS_SUCCESS(status))
    {
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: Hostapd HDD vos event init failed!!"));
#ifdef WLAN_FEATURE_MBSSID
         WLANSAP_Close(sapContext);
         pAdapter->sessionCtx.ap.sapContext = NULL;
#endif
         return status;
    }

    status = vos_event_init(&phostapdBuf->stop_bss_event);
    if (!VOS_IS_STATUS_SUCCESS(status))
    {
         VOS_TRACE(VOS_MODULE_ID_HDD,
                   VOS_TRACE_LEVEL_ERROR,
                   "ERROR: Hostapd HDD stop bss event init failed!!");
#ifdef WLAN_FEATURE_MBSSID
         WLANSAP_Close(sapContext);
         pAdapter->sessionCtx.ap.sapContext = NULL;
#endif
         return status;
    }

    status = vos_event_init(&phostapdBuf->sta_disassoc_event);
    if (!VOS_IS_STATUS_SUCCESS(status)) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
            "ERROR: Hostapd HDD sta disassoc event init failed!!");
#ifdef WLAN_FEATURE_MBSSID
        WLANSAP_Close(sapContext);
        pAdapter->sessionCtx.ap.sapContext = NULL;
#endif
        return status;
    }

    sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1);

     // Register as a wireless device
#ifdef CONFIG_WIRELESS_EXT
    dev->wireless_handlers = (struct iw_handler_def *)& hostapd_handler_def;
#endif

    //Initialize the data path module
    status = hdd_softap_init_tx_rx(pAdapter);
    if ( !VOS_IS_STATUS_SUCCESS( status ))
    {
       hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_softap_init_tx_rx failed", __func__);
    }

    set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);

    status = hdd_wmm_adapter_init( pAdapter );
    if (!VOS_IS_STATUS_SUCCESS(status))
    {
       hddLog(VOS_TRACE_LEVEL_ERROR,
             "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);

    if (!reinit) {
        pAdapter->sessionCtx.ap.sapConfig.acs_cfg.acs_mode = false;
        vos_mem_free(pAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list);
        vos_mem_zero(&pAdapter->sessionCtx.ap.sapConfig.acs_cfg,
                                           sizeof(struct sap_acs_cfg));
    }
    return status;

error_wmm_init:
    hdd_softap_deinit_tx_rx( pAdapter );
    clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
#ifdef WLAN_FEATURE_MBSSID
    WLANSAP_Close(sapContext);
    pAdapter->sessionCtx.ap.sapContext = NULL;
#endif
    EXIT();
    return status;
}

hdd_adapter_t* hdd_wlan_create_ap_dev(hdd_context_t *pHddCtx,
                                      tSirMacAddr macAddr,
                                      unsigned char name_assign_type,
                                      tANI_U8 *iface_name )
{
    struct net_device *pWlanHostapdDev = NULL;
    hdd_adapter_t *pHostapdAdapter = NULL;

   hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: iface_name = %s", __func__, iface_name);

   pWlanHostapdDev = alloc_netdev_mq(sizeof(hdd_adapter_t),
                                     iface_name,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)) || defined(WITH_BACKPORTS)
                                     name_assign_type,
#endif
                                     ether_setup,
                                     NUM_TX_QUEUES);

    if (pWlanHostapdDev != NULL)
    {
        pHostapdAdapter = netdev_priv(pWlanHostapdDev);

        //Init the net_device structure
        ether_setup(pWlanHostapdDev);

        //Initialize the adapter context to zeros.
        vos_mem_zero(pHostapdAdapter, sizeof( hdd_adapter_t ));
        pHostapdAdapter->dev = pWlanHostapdDev;
        pHostapdAdapter->pHddCtx = pHddCtx;
        pHostapdAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;

        hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: pWlanHostapdDev = %pK, "
                                      "pHostapdAdapter = %pK, "
                                      "concurrency_mode=0x%x", __func__,
                                      pWlanHostapdDev,
                                      pHostapdAdapter,
                                      (int)vos_get_concurrency_mode());

        //Init the net_device structure
        strlcpy(pWlanHostapdDev->name, (const char *)iface_name, IFNAMSIZ);

        hdd_set_ap_ops( pHostapdAdapter->dev );

        pWlanHostapdDev->watchdog_timeo = HDD_TX_TIMEOUT;
        pWlanHostapdDev->mtu = HDD_DEFAULT_MTU;
        pWlanHostapdDev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;

        vos_mem_copy(pWlanHostapdDev->dev_addr, (void *)macAddr,sizeof(tSirMacAddr));
        vos_mem_copy(pHostapdAdapter->macAddressCurrent.bytes, (void *)macAddr, sizeof(tSirMacAddr));

        pHostapdAdapter->offloads_configured = FALSE;
        pWlanHostapdDev->priv_destructor = free_netdev;
        pWlanHostapdDev->ieee80211_ptr = &pHostapdAdapter->wdev ;
        pHostapdAdapter->wdev.wiphy = pHddCtx->wiphy;
        pHostapdAdapter->wdev.netdev =  pWlanHostapdDev;
        vos_event_init(&pHostapdAdapter->scan_info.scan_finished_event);
        pHostapdAdapter->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
        /*
         * kernel will consume ethernet header length buffer for hard_header,
         * so just reserve it
         */
        hdd_set_needed_headroom(pWlanHostapdDev,
                           pWlanHostapdDev->hard_header_len);

        if (pHddCtx->cfg_ini->enableIPChecksumOffload)
            pWlanHostapdDev->features |= NETIF_F_HW_CSUM;
        else if (pHddCtx->cfg_ini->enableTCPChkSumOffld)
            pWlanHostapdDev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
        pWlanHostapdDev->features |= NETIF_F_RXCSUM;

        SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev);
        spin_lock_init(&pHostapdAdapter->pause_map_lock);
        pHostapdAdapter->last_tx_jiffies = jiffies;
        pHostapdAdapter->bug_report_count = 0;
        pHostapdAdapter->start_time =
            pHostapdAdapter->last_time = vos_system_ticks();
    }
    return pHostapdAdapter;
}

VOS_STATUS hdd_register_hostapd( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
{
   struct net_device *dev = pAdapter->dev;
   VOS_STATUS status = VOS_STATUS_SUCCESS;

   ENTER();

   if( rtnl_lock_held )
   {
     if (strnchr(dev->name, strlen(dev->name), '%')) {
         if( dev_alloc_name(dev, dev->name) < 0 )
         {
            hddLog(VOS_TRACE_LEVEL_FATAL, "%s:Failed:dev_alloc_name", __func__);
            return VOS_STATUS_E_FAILURE;
         }
      }
      if (register_netdevice(dev))
      {
         hddLog(VOS_TRACE_LEVEL_FATAL,
                "%s:Failed:register_netdevice", __func__);
         return VOS_STATUS_E_FAILURE;
      }
   }
   else
   {
      if (register_netdev(dev))
      {
         hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed:register_netdev", __func__);
         return VOS_STATUS_E_FAILURE;
      }
   }
   set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);

   EXIT();
   return status;
}

VOS_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter, bool rtnl_held)
{
#ifdef WLAN_FEATURE_MBSSID
   VOS_STATUS status;
   v_PVOID_t sapContext=WLAN_HDD_GET_SAP_CTX_PTR(pAdapter);
#endif

   ENTER();

   /* if we are being called during driver unload, then the dev has already
      been invalidated.  if we are being called at other times, then we can
      detach the wireless device handlers */
   if (pAdapter->dev)
   {
#ifdef CONFIG_WIRELESS_EXT
      if (rtnl_held)
          pAdapter->dev->wireless_handlers = NULL;
      else {
          rtnl_lock();
          pAdapter->dev->wireless_handlers = NULL;
          rtnl_unlock();
      }
#endif
   }

#ifdef WLAN_FEATURE_MBSSID
   status = WLANSAP_Stop(sapContext);
   if ( ! VOS_IS_STATUS_SUCCESS( status ) ) {
         hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed:WLANSAP_Stop", __func__);
   }

   status = WLANSAP_Close(sapContext);
   if ( ! VOS_IS_STATUS_SUCCESS( status ) ) {
         hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed:WLANSAP_close", __func__);
   }
   pAdapter->sessionCtx.ap.sapContext = NULL;
#endif

   EXIT();
   return 0;
}

/**
 * hdd_sap_indicate_disconnect_for_sta() - Indicate disconnect indication
 * to supplicant, if there any clients connected to SAP interface.
 * @adapter: sap adapter context
 *
 * Return:   nothing
 */
void hdd_sap_indicate_disconnect_for_sta(hdd_adapter_t *adapter)
{
	tSap_Event sap_event;
	int staId;
	ptSapContext sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter);

	ENTER();

	if (!sap_ctx) {
		hddLog(LOGE, FL("invalid sap context"));
		return;
	}

	for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++) {
		if (adapter->aStaInfo[staId].isUsed) {
			hddLog(LOG1, FL("staId: %d isUsed: %d %pK"),
				staId, adapter->aStaInfo[staId].isUsed,
				sap_ctx);

			if (vos_is_macaddr_broadcast(
				&adapter->aStaInfo[staId].macAddrSTA))
				continue;

			sap_event.sapHddEventCode = eSAP_STA_DISASSOC_EVENT;
			vos_mem_copy(
				&sap_event.sapevt.
					sapStationDisassocCompleteEvent.staMac,
				&adapter->aStaInfo[staId].macAddrSTA,
				sizeof(v_MACADDR_t));
			sap_event.sapevt.sapStationDisassocCompleteEvent.
			reason =
				eSAP_MAC_INITATED_DISASSOC;
			sap_event.sapevt.sapStationDisassocCompleteEvent.
			statusCode =
				eSIR_SME_RESOURCES_UNAVAILABLE;
			hdd_hostapd_SAPEventCB(&sap_event,
				sap_ctx->pUsrContext);
		}
	}

	clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);

	EXIT();
}

/**
 * hdd_sap_destroy_events() - Destroy sap evets
 * @adapter: sap adapter context
 *
 * Return:   nothing
 */
void hdd_sap_destroy_events(hdd_adapter_t *adapter)
{
	ptSapContext sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter);

	if (!sap_ctx) {
	hddLog(LOGE, FL("invalid sap context"));
	return;
	}

	if (!VOS_IS_STATUS_SUCCESS(vos_lock_destroy(&sap_ctx->SapGlobalLock)))
		VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
		FL("WLANSAP_Stop failed destroy lock"));

	if (!VOS_IS_STATUS_SUCCESS(vos_event_destroy(
		&sap_ctx->sap_session_opened_evt)))
		VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
		FL("failed to destroy session open event"));
        if (!VOS_IS_STATUS_SUCCESS(vos_event_destroy(
               &sap_ctx->sap_session_closed_evt)))
            VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
               FL("failed to destroy session close event"));

}
