/*
 * 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_cfg80211.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
  --------    ---            --------------------------------------------------------
 21/12/09     Ashwani        Created module.

 07/06/10     Kumar Deepak   Implemented cfg80211 callbacks for ANDROID
              Ganesh K
  ==========================================================================*/


#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/wireless.h>
#include <linux/etherdevice.h>
#include <wlan_hdd_includes.h>
#include <net/arp.h>
#include <net/cfg80211.h>
#include <linux/wireless.h>
#include <wlan_hdd_wowl.h>
#include <aniGlobal.h>
#include "ccmApi.h"
#include "sirParams.h"
#include "dot11f.h"
#include "wlan_hdd_assoc.h"
#include "wlan_hdd_wext.h"
#include "sme_Api.h"
#include "wlan_hdd_p2p.h"
#include "wlan_hdd_cfg80211.h"
#include "wlan_hdd_hostapd.h"
#include "sapInternal.h"
#include "wlan_hdd_softap_tx_rx.h"
#include "wlan_hdd_main.h"
#include "wlan_hdd_assoc.h"
#include "wlan_hdd_power.h"
#include "wlan_hdd_trace.h"
#include "vos_types.h"
#include "vos_trace.h"
#ifdef WLAN_BTAMP_FEATURE
#include "bap_hdd_misc.h"
#endif
#include <qc_sap_ioctl.h>
#include "wlan_hdd_tdls.h"
#include "wlan_hdd_wmm.h"
#include "wlan_qct_wda.h"
#include "wlan_nv.h"
#include "wlan_hdd_dev_pwr.h"
#include "qwlan_version.h"
#include "wlan_logging_sock_svc.h"
#include "wlan_hdd_misc.h"


#define g_mode_rates_size (12)
#define a_mode_rates_size (8)
#define FREQ_BASE_80211G          (2407)
#define FREQ_BAND_DIFF_80211G     (5)
#define MAX_SCAN_SSID 9
#define MAX_PENDING_LOG 5
#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
        ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))

#define HDD2GHZCHAN(freq, chan, flag)   {     \
    .band =  HDD_NL80211_BAND_2GHZ, \
    .center_freq = (freq), \
    .hw_value = (chan),\
    .flags = (flag), \
    .max_antenna_gain = 0 ,\
    .max_power = 30, \
}

#define HDD5GHZCHAN(freq, chan, flag)   {     \
    .band =  HDD_NL80211_BAND_5GHZ, \
    .center_freq = (freq), \
    .hw_value = (chan),\
    .flags = (flag), \
    .max_antenna_gain = 0 ,\
    .max_power = 30, \
}

#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
{\
    .bitrate = rate, \
    .hw_value = rate_id, \
    .flags = flag, \
}

#ifdef WLAN_FEATURE_VOWIFI_11R
#define WLAN_AKM_SUITE_FT_8021X         0x000FAC03
#define WLAN_AKM_SUITE_FT_PSK           0x000FAC04
#endif

#define HDD_CHANNEL_14 14
#define WLAN_HDD_MAX_FEATURE_SET   8

#ifdef WLAN_FEATURE_LINK_LAYER_STATS
/*
 * Used to allocate the size of 4096 for the link layer stats.
 * The size of 4096 is considered assuming that all data per
 * respective event fit with in the limit.Please take a call
 * on the limit based on the data requirements on link layer
 * statistics.
 */
#define LL_STATS_EVENT_BUF_SIZE 4096
#endif
#ifdef WLAN_FEATURE_EXTSCAN
/*
 * Used to allocate the size of 4096 for the EXTScan NL data.
 * The size of 4096 is considered assuming that all data per
 * respective event fit with in the limit.Please take a call
 * on the limit based on the data requirements.
 */

#define EXTSCAN_EVENT_BUF_SIZE 4096
#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
#endif

/*EXT TDLS*/
/*
 * Used to allocate the size of 4096 for the TDLS.
 * The size of 4096 is considered assuming that all data per
 * respective event fit with in the limit.Please take a call
 * on the limit based on the data requirements on link layer
 * statistics.
 */
#define EXTTDLS_EVENT_BUF_SIZE 4096

/*
 * Values for Mac spoofing feature
 *
 */
#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE           0
#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE            1
#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE    2
#define MAC_ADDR_SPOOFING_DEFER_INTERVAL            10 //in ms

/*
 * max_sched_scan_plans defined to 10
 */
#define MAX_SCHED_SCAN_PLANS 10

static const u32 hdd_cipher_suites[] =
{
    WLAN_CIPHER_SUITE_WEP40,
    WLAN_CIPHER_SUITE_WEP104,
    WLAN_CIPHER_SUITE_TKIP,
#ifdef FEATURE_WLAN_ESE
#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
    WLAN_CIPHER_SUITE_KRK,
    WLAN_CIPHER_SUITE_CCMP,
#else
    WLAN_CIPHER_SUITE_CCMP,
#endif
#ifdef FEATURE_WLAN_WAPI
    WLAN_CIPHER_SUITE_SMS4,
#endif
#ifdef WLAN_FEATURE_11W
    WLAN_CIPHER_SUITE_AES_CMAC,
#endif
};

const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
{
    HDD2GHZCHAN(2412, 1, 0) ,
    HDD2GHZCHAN(2417, 2, 0) ,
    HDD2GHZCHAN(2422, 3, 0) ,
    HDD2GHZCHAN(2427, 4, 0) ,
    HDD2GHZCHAN(2432, 5, 0) ,
    HDD2GHZCHAN(2437, 6, 0) ,
    HDD2GHZCHAN(2442, 7, 0) ,
    HDD2GHZCHAN(2447, 8, 0) ,
    HDD2GHZCHAN(2452, 9, 0) ,
    HDD2GHZCHAN(2457, 10, 0) ,
    HDD2GHZCHAN(2462, 11, 0) ,
    HDD2GHZCHAN(2467, 12, 0) ,
    HDD2GHZCHAN(2472, 13, 0) ,
    HDD2GHZCHAN(2484, 14, 0) ,
};

const static struct ieee80211_channel hdd_channels_5_GHZ[] =
{
    HDD5GHZCHAN(4920, 240, 0) ,
    HDD5GHZCHAN(4940, 244, 0) ,
    HDD5GHZCHAN(4960, 248, 0) ,
    HDD5GHZCHAN(4980, 252, 0) ,
    HDD5GHZCHAN(5040, 208, 0) ,
    HDD5GHZCHAN(5060, 212, 0) ,
    HDD5GHZCHAN(5080, 216, 0) ,
    HDD5GHZCHAN(5180, 36, 0) ,
    HDD5GHZCHAN(5200, 40, 0) ,
    HDD5GHZCHAN(5220, 44, 0) ,
    HDD5GHZCHAN(5240, 48, 0) ,
    HDD5GHZCHAN(5260, 52, 0) ,
    HDD5GHZCHAN(5280, 56, 0) ,
    HDD5GHZCHAN(5300, 60, 0) ,
    HDD5GHZCHAN(5320, 64, 0) ,
    HDD5GHZCHAN(5500,100, 0) ,
    HDD5GHZCHAN(5520,104, 0) ,
    HDD5GHZCHAN(5540,108, 0) ,
    HDD5GHZCHAN(5560,112, 0) ,
    HDD5GHZCHAN(5580,116, 0) ,
    HDD5GHZCHAN(5600,120, 0) ,
    HDD5GHZCHAN(5620,124, 0) ,
    HDD5GHZCHAN(5640,128, 0) ,
    HDD5GHZCHAN(5660,132, 0) ,
    HDD5GHZCHAN(5680,136, 0) ,
    HDD5GHZCHAN(5700,140, 0) ,
#ifdef FEATURE_WLAN_CH144
    HDD5GHZCHAN(5720,144, 0) ,
#endif /* FEATURE_WLAN_CH144 */
    HDD5GHZCHAN(5745,149, 0) ,
    HDD5GHZCHAN(5765,153, 0) ,
    HDD5GHZCHAN(5785,157, 0) ,
    HDD5GHZCHAN(5805,161, 0) ,
    HDD5GHZCHAN(5825,165, 0) ,
};

static struct ieee80211_rate g_mode_rates[] =
{
    HDD_G_MODE_RATETAB(10, 0x1, 0),
    HDD_G_MODE_RATETAB(20, 0x2, 0),
    HDD_G_MODE_RATETAB(55, 0x4, 0),
    HDD_G_MODE_RATETAB(110, 0x8, 0),
    HDD_G_MODE_RATETAB(60, 0x10, 0),
    HDD_G_MODE_RATETAB(90, 0x20, 0),
    HDD_G_MODE_RATETAB(120, 0x40, 0),
    HDD_G_MODE_RATETAB(180, 0x80, 0),
    HDD_G_MODE_RATETAB(240, 0x100, 0),
    HDD_G_MODE_RATETAB(360, 0x200, 0),
    HDD_G_MODE_RATETAB(480, 0x400, 0),
    HDD_G_MODE_RATETAB(540, 0x800, 0),
};

static struct ieee80211_rate a_mode_rates[] =
{
    HDD_G_MODE_RATETAB(60, 0x10, 0),
    HDD_G_MODE_RATETAB(90, 0x20, 0),
    HDD_G_MODE_RATETAB(120, 0x40, 0),
    HDD_G_MODE_RATETAB(180, 0x80, 0),
    HDD_G_MODE_RATETAB(240, 0x100, 0),
    HDD_G_MODE_RATETAB(360, 0x200, 0),
    HDD_G_MODE_RATETAB(480, 0x400, 0),
    HDD_G_MODE_RATETAB(540, 0x800, 0),
};

static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
{
    .channels = NULL,
    .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
    .band       = HDD_NL80211_BAND_2GHZ,
    .bitrates = g_mode_rates,
    .n_bitrates = g_mode_rates_size,
    .ht_cap.ht_supported   = 1,
    .ht_cap.cap            =  IEEE80211_HT_CAP_SGI_20
                            | IEEE80211_HT_CAP_GRN_FLD
                            | IEEE80211_HT_CAP_DSSSCCK40
                            | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
    .ht_cap.ampdu_factor   = IEEE80211_HT_MAX_AMPDU_64K,
    .ht_cap.ampdu_density  = IEEE80211_HT_MPDU_DENSITY_16,
    .ht_cap.mcs.rx_mask    = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
    .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
    .ht_cap.mcs.tx_params  = IEEE80211_HT_MCS_TX_DEFINED,
};

static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
{
    .channels = NULL,
    .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
    .band     = HDD_NL80211_BAND_5GHZ,
    .bitrates = a_mode_rates,
    .n_bitrates = a_mode_rates_size,
    .ht_cap.ht_supported   = 1,
    .ht_cap.cap            =  IEEE80211_HT_CAP_SGI_20
                            | IEEE80211_HT_CAP_GRN_FLD
                            | IEEE80211_HT_CAP_DSSSCCK40
                            | IEEE80211_HT_CAP_LSIG_TXOP_PROT
                            | IEEE80211_HT_CAP_SGI_40
                            | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
    .ht_cap.ampdu_factor   = IEEE80211_HT_MAX_AMPDU_64K,
    .ht_cap.ampdu_density  = IEEE80211_HT_MPDU_DENSITY_16,
    .ht_cap.mcs.rx_mask    = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
    .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
    .ht_cap.mcs.tx_params  = IEEE80211_HT_MCS_TX_DEFINED,
};

/* This structure contain information what kind of frame are expected in
     TX/RX direction for each kind of interface */
static const struct ieee80211_txrx_stypes
wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
    [NL80211_IFTYPE_STATION] = {
        .tx = 0xffff,
        .rx = BIT(SIR_MAC_MGMT_ACTION) |
            BIT(SIR_MAC_MGMT_PROBE_REQ),
    },
    [NL80211_IFTYPE_AP] = {
        .tx = 0xffff,
        .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
            BIT(SIR_MAC_MGMT_REASSOC_REQ) |
            BIT(SIR_MAC_MGMT_PROBE_REQ) |
            BIT(SIR_MAC_MGMT_DISASSOC) |
            BIT(SIR_MAC_MGMT_AUTH) |
            BIT(SIR_MAC_MGMT_DEAUTH) |
            BIT(SIR_MAC_MGMT_ACTION),
    },
    [NL80211_IFTYPE_ADHOC] = {
        .tx = 0xffff,
        .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
            BIT(SIR_MAC_MGMT_REASSOC_REQ) |
            BIT(SIR_MAC_MGMT_PROBE_REQ) |
            BIT(SIR_MAC_MGMT_DISASSOC) |
            BIT(SIR_MAC_MGMT_AUTH) |
            BIT(SIR_MAC_MGMT_DEAUTH) |
            BIT(SIR_MAC_MGMT_ACTION),
    },
    [NL80211_IFTYPE_P2P_CLIENT] = {
        .tx = 0xffff,
        .rx = BIT(SIR_MAC_MGMT_ACTION) |
            BIT(SIR_MAC_MGMT_PROBE_REQ),
    },
    [NL80211_IFTYPE_P2P_GO] = {
        /* This is also same as for SoftAP */
        .tx = 0xffff,
        .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
            BIT(SIR_MAC_MGMT_REASSOC_REQ) |
            BIT(SIR_MAC_MGMT_PROBE_REQ) |
            BIT(SIR_MAC_MGMT_DISASSOC) |
            BIT(SIR_MAC_MGMT_AUTH) |
            BIT(SIR_MAC_MGMT_DEAUTH) |
            BIT(SIR_MAC_MGMT_ACTION),
    },
};

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
static const struct ieee80211_iface_limit
wlan_hdd_iface_limit[] = {
    {
        /* max = 3 ; Our driver create two interfaces during driver init
         * wlan0 and p2p0 interfaces. p2p0 is considered as station
         * interface until a group is formed. In JB architecture, once the
         * group is formed, interface type of p2p0 is changed to P2P GO or
         * Client.
         * When supplicant remove the group, it first issue a set interface
         * cmd to change the mode back to Station. In JB this works fine as
         * we advertize two station type interface during driver init.
         * Some vendors create separate interface for P2P GO/Client,
         * after group formation(Third one). But while group remove
         * supplicant first tries to change the mode(3rd interface) to STATION
         * But as we advertized only two sta type interfaces nl80211 was
         * returning error for the third one which was leading to failure in
         * delete interface. Ideally while removing the group, supplicant
         * should not try to change the 3rd interface mode to Station type.
         * Till we get a fix in wpa_supplicant, we advertize max STA
         * interface type to 3
         */
        .max = 3,
        .types = BIT(NL80211_IFTYPE_STATION),
    },
    {
        .max = 1,
        .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
    },
    {
        .max = 1,
        .types = BIT(NL80211_IFTYPE_P2P_GO) |
                 BIT(NL80211_IFTYPE_P2P_CLIENT),
    },
};

/* interface limits for sta + monitor SCC */
static const struct ieee80211_iface_limit
wlan_hdd_iface_sta_mon_limit[] = {
	{
		.max = 1,
		.types = BIT(NL80211_IFTYPE_STATION),
	},
	{
		.max = 1, /* Monitor interface */
		.types = BIT(NL80211_IFTYPE_MONITOR),
	},
};

/* By default, only single channel concurrency is allowed */
static struct ieee80211_iface_combination
wlan_hdd_iface_combination[] = {
	{
		.limits = wlan_hdd_iface_limit,
		.num_different_channels = 1,
		/*
		 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
		 * and p2p0 interfaces during driver init
		 * Some vendors create separate interface for P2P operations.
		 * wlan0: STA interface
		 * p2p0: P2P Device interface, action frames goes
		 * through this interface.
		 * p2p-xx: P2P interface, After GO negotiation this interface is
		 * created for p2p operations(GO/CLIENT interface).
		 */
		.max_interfaces = WLAN_MAX_INTERFACES,
		.n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
		.beacon_int_infra_match = false,
	},
	{
		.limits = wlan_hdd_iface_sta_mon_limit,
		.num_different_channels = 1,
		.max_interfaces = WLAN_STA_AND_MON_INTERFACES,
		.n_limits = ARRAY_SIZE(wlan_hdd_iface_sta_mon_limit),
		.beacon_int_infra_match = false,
	}
};
#endif

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
static const struct wiphy_wowlan_support wowlan_support_cfg80211_init = {
    .flags = WIPHY_WOWLAN_MAGIC_PKT,
    .n_patterns = WOWL_MAX_PTRNS_ALLOWED,
    .pattern_min_len = 1,
    .pattern_max_len = WOWL_PTRN_MAX_SIZE,
};
#endif

static struct cfg80211_ops wlan_hdd_cfg80211_ops;

/* Data rate 100KBPS based on IE Index */
struct index_data_rate_type
{
   v_U8_t   beacon_rate_index;
   v_U16_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
{
   v_U8_t   beacon_rate_index;
   v_U16_t  supported_rate[4];
} 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 */
static struct index_data_rate_type supported_mcs_rate[] =
{
/* 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}}
};

#ifdef WLAN_FEATURE_11AC

#define DATA_RATE_11AC_MCS_MASK    0x03

struct index_vht_data_rate_type
{
   v_U8_t   beacon_rate_index;
   v_U16_t  supported_VHT80_rate[2];
   v_U16_t  supported_VHT40_rate[2];
   v_U16_t  supported_VHT20_rate[2];
};

typedef enum
{
   DATA_RATE_11AC_MAX_MCS_7,
   DATA_RATE_11AC_MAX_MCS_8,
   DATA_RATE_11AC_MAX_MCS_9,
   DATA_RATE_11AC_MAX_MCS_NA
} eDataRate11ACMaxMcs;

/* SSID broadcast  type */
typedef enum eSSIDBcastType
{
  eBCAST_UNKNOWN      = 0,
  eBCAST_NORMAL       = 1,
  eBCAST_HIDDEN       = 2,
} tSSIDBcastType;

/* MCS Based VHT rate table */
static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
{
/* 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}}
};
#endif /* WLAN_FEATURE_11AC */

/*array index points to MCS and array value points respective rssi*/
static int rssiMcsTbl[][10] =
{
/*MCS 0   1     2   3    4    5    6    7    8    9*/
   {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
   {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
   {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51}  //80
};

extern struct net_device_ops net_ops_struct;
#ifdef FEATURE_WLAN_SCAN_PNO
static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
#endif

#ifdef WLAN_NL80211_TESTMODE
enum wlan_hdd_tm_attr
{
    WLAN_HDD_TM_ATTR_INVALID = 0,
    WLAN_HDD_TM_ATTR_CMD     = 1,
    WLAN_HDD_TM_ATTR_DATA    = 2,
    WLAN_HDD_TM_ATTR_TYPE    = 3,
    /* keep last */
    WLAN_HDD_TM_ATTR_AFTER_LAST,
    WLAN_HDD_TM_ATTR_MAX       = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
};

enum wlan_hdd_tm_cmd
{
    WLAN_HDD_TM_CMD_WLAN_HB    = 1,
};

#define WLAN_HDD_TM_DATA_MAX_LEN    5000

static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
{
    [WLAN_HDD_TM_ATTR_CMD]        = { .type = NLA_U32 },
    [WLAN_HDD_TM_ATTR_DATA]       = { .type = NLA_BINARY,
                                    .len = WLAN_HDD_TM_DATA_MAX_LEN },
};
#endif /* WLAN_NL80211_TESTMODE */

#ifdef FEATURE_WLAN_CH_AVOID
/*
 * FUNCTION: wlan_hdd_send_avoid_freq_event
 * This is called when wlan driver needs to send vendor specific
 * avoid frequency range event to userspace
 */
int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
                                   tHddAvoidFreqList *pAvoidFreqList)
{
    struct sk_buff *vendor_event;

    ENTER();

    if (!pHddCtx)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: HDD context is null", __func__);
        return -1;
    }

    if (!pAvoidFreqList)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: pAvoidFreqList is null", __func__);
        return -1;
    }

    vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
                       NULL,
#endif
                       sizeof(tHddAvoidFreqList),
                       QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
                       GFP_KERNEL);
    if (!vendor_event)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: cfg80211_vendor_event_alloc failed", __func__);
        return -1;
    }

    memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
                   (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));

    cfg80211_vendor_event(vendor_event, GFP_KERNEL);

    EXIT();
    return 0;
}
#endif /* FEATURE_WLAN_CH_AVOID */

/*
 * define short names for the global vendor params
 * used by QCA_NL80211_VENDOR_SUBCMD_HANG
 */
#define HANG_REASON_INDEX QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX

/**
 * hdd_convert_hang_reason() - Convert cds recovery reason to vendor specific
 * hang reason
 * @reason: cds recovery reason
 *
 * Return: Vendor specific reason code
 */
static enum qca_wlan_vendor_hang_reason
hdd_convert_hang_reason(enum vos_hang_reason reason)
{
	unsigned int ret_val;

	switch (reason) {
	case VOS_GET_MSG_BUFF_FAILURE:
		ret_val = QCA_WLAN_HANG_GET_MSG_BUFF_FAILURE;
		break;
	case VOS_ACTIVE_LIST_TIMEOUT:
		ret_val = QCA_WLAN_HANG_ACTIVE_LIST_TIMEOUT;
		break;
	case VOS_SCAN_REQ_EXPIRED:
		ret_val = QCA_WLAN_HANG_SCAN_REQ_EXPIRED;
		break;
	case VOS_TRANSMISSIONS_TIMEOUT:
		ret_val = QCA_WLAN_HANG_TRANSMISSIONS_TIMEOUT;
		break;
	case VOS_DXE_FAILURE:
		ret_val = QCA_WLAN_HANG_DXE_FAILURE;
		break;
	case VOS_WDI_FAILURE:
		ret_val = QCA_WLAN_HANG_WDI_FAILURE;
		break;
	case VOS_REASON_UNSPECIFIED:
	default:
		ret_val = QCA_WLAN_HANG_REASON_UNSPECIFIED;
	}
	return ret_val;
}

/**
 * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace
 * @hdd_ctx: Pointer to hdd context
 * @reason: cds recovery reason
 *
 * Return: 0 on success or failure reason
 */
int wlan_hdd_send_hang_reason_event(hdd_context_t *hdd_ctx,
				    enum vos_hang_reason reason)
{
	struct sk_buff *vendor_event;
	enum qca_wlan_vendor_hang_reason hang_reason;

	ENTER();

	if (!hdd_ctx) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			  "HDD context is null");
		return -EINVAL;
	}

	vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
						   NULL,
#endif
						   sizeof(unsigned int),
						   HANG_REASON_INDEX,
						   GFP_KERNEL);
	if (!vendor_event) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			  "cfg80211_vendor_event_alloc failed");
		return -ENOMEM;
	}

	hang_reason = hdd_convert_hang_reason(reason);

	if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_HANG_REASON,
			(unsigned int) hang_reason)) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			  "QCA_WLAN_VENDOR_ATTR_HANG_REASON put fail");
		kfree_skb(vendor_event);
		return -EINVAL;
	}

	cfg80211_vendor_event(vendor_event, GFP_KERNEL);

	EXIT();
	return 0;
}
#undef HANG_REASON_INDEX

/*
 * FUNCTION: __wlan_hdd_cfg80211_nan_request
 * This is called when wlan driver needs to send vendor specific
 * nan request event.
 */
static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
                                         struct wireless_dev *wdev,
                                         const void *data, int data_len)
{
    tNanRequestReq nan_req;
    VOS_STATUS status;
    int ret_val = -1;
    struct net_device *dev = wdev->netdev;
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    hdd_context_t *pHddCtx = wiphy_priv(wiphy);

    if (0 == data_len)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                FL("NAN - Invalid Request, length = 0"));
        return ret_val;
    }

    if (NULL == data)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                FL("NAN - Invalid Request, data is NULL"));
        return ret_val;
    }

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("HDD context is not valid"));
        return -EINVAL;
    }

    hddLog(LOG1, FL("Received NAN command"));
    vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
        (tANI_U8 *)data, data_len);

    /* check the NAN Capability */
    if (TRUE != sme_IsFeatureSupportedByFW(NAN))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("NAN is not supported by Firmware"));
        return -EINVAL;
    }

    nan_req.request_data_len = data_len;
    nan_req.request_data = data;

    status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
    if (VOS_STATUS_SUCCESS == status)
    {
        ret_val = 0;
    }
    return ret_val;
}

/*
 * FUNCTION: wlan_hdd_cfg80211_nan_request
 * Wrapper to protect the nan vendor command from ssr
 */
static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
                                         struct wireless_dev *wdev,
                                         const void *data, int data_len)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
    vos_ssr_unprotect(__func__);

    return ret;
}

/*
 * FUNCTION: wlan_hdd_cfg80211_nan_callback
 * This is a callback function and it gets called
 * when we need to report nan response event to
 * upper layers.
 */
static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
{
    hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
    struct sk_buff *vendor_event;
    int status;
    tSirNanEvent *data;

    ENTER();
    if (NULL == msg)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   FL(" msg received here is null"));
        return;
    }
    data = msg;

    status = wlan_hdd_validate_context(pHddCtx);

    if (0 != status)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   FL("HDD context is not valid"));
        return;
    }

    vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
                                   NULL,
#endif
                                   data->event_data_len +
                                   NLMSG_HDRLEN,
                                   QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
                                   GFP_KERNEL);

    if (!vendor_event)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   FL("cfg80211_vendor_event_alloc failed"));
        return;
    }
    if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
                data->event_data_len, data->event_data))
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
        kfree_skb(vendor_event);
        return;
    }
    cfg80211_vendor_event(vendor_event, GFP_KERNEL);
    EXIT();
}

/*
 * FUNCTION: wlan_hdd_cfg80211_nan_init
 * This function is called to register the callback to sme layer
 */
inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
{
    sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
}

/*
 * define short names for the global vendor params
 * used by __wlan_hdd_cfg80211_get_station_cmd()
 */
#define STATION_INVALID \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
#define STATION_INFO \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
#define STATION_ASSOC_FAIL_REASON \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
#define STATION_REMOTE \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE
#define STATION_MAX \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX

static const struct nla_policy
hdd_get_station_policy[STATION_MAX + 1] = {
	[STATION_INFO] = {.type = NLA_FLAG},
	[STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
};

/**
 * hdd_get_station_assoc_fail() - Handle get station assoc fail
 * @hdd_ctx: HDD context within host driver
 * @wdev: wireless device
 *
 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
 * Validate cmd attributes and send the station info to upper layers.
 *
 * Return: Success(0) or reason code for failure
 */
static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
						 hdd_adapter_t *adapter)
{
	struct sk_buff *skb = NULL;
	uint32_t nl_buf_len;
	hdd_station_ctx_t *hdd_sta_ctx;

	nl_buf_len = NLMSG_HDRLEN;
	nl_buf_len += sizeof(uint32_t);
	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);

	if (!skb) {
		VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
		return -ENOMEM;
	}

	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);

	if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
			hdd_sta_ctx->conn_info.assoc_status_code)) {
		VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
		goto fail;
	}
	return cfg80211_vendor_cmd_reply(skb);
fail:
	if (skb)
		kfree_skb(skb);
	return -EINVAL;
}

/**
 * hdd_map_auth_type() - transform auth type specific to
 * vendor command
 * @auth_type: csr auth type
 *
 * Return: Success(0) or reason code for failure
 */
static int hdd_convert_auth_type(uint32_t auth_type)
{
	uint32_t ret_val;

	switch (auth_type) {
	case eCSR_AUTH_TYPE_OPEN_SYSTEM:
		ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
		break;
	case eCSR_AUTH_TYPE_SHARED_KEY:
		ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
		break;
	case eCSR_AUTH_TYPE_WPA:
		ret_val = QCA_WLAN_AUTH_TYPE_WPA;
		break;
	case eCSR_AUTH_TYPE_WPA_PSK:
		ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
		break;
	case eCSR_AUTH_TYPE_AUTOSWITCH:
		ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
		break;
	case eCSR_AUTH_TYPE_WPA_NONE:
		ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
		break;
	case eCSR_AUTH_TYPE_RSN:
		ret_val = QCA_WLAN_AUTH_TYPE_RSN;
		break;
	case eCSR_AUTH_TYPE_RSN_PSK:
		ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
		break;
	case eCSR_AUTH_TYPE_FT_RSN:
		ret_val = QCA_WLAN_AUTH_TYPE_FT;
		break;
	case eCSR_AUTH_TYPE_FT_RSN_PSK:
		ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
		break;
	case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
		ret_val = QCA_WLAN_AUTH_TYPE_WAI;
		break;
	case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
		ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
		break;
#ifdef FEATURE_WLAN_ESE
	case eCSR_AUTH_TYPE_CCKM_WPA:
		ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
		break;
	case eCSR_AUTH_TYPE_CCKM_RSN:
		ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
		break;
#endif
	case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
		ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
		break;
	case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
		ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
		break;
	case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
	case eCSR_AUTH_TYPE_FAILED:
	case eCSR_AUTH_TYPE_NONE:
	default:
		ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
		break;
	}
	return ret_val;
}

/**
 * hdd_map_dot_11_mode() - transform dot11mode type specific to
 * vendor command
 * @dot11mode: dot11mode
 *
 * Return: Success(0) or reason code for failure
 */
static int hdd_convert_dot11mode(uint32_t dot11mode)
{
	uint32_t ret_val;

	switch (dot11mode) {
	case eCSR_CFG_DOT11_MODE_11A:
		ret_val = QCA_WLAN_802_11_MODE_11A;
		break;
	case eCSR_CFG_DOT11_MODE_11B:
		ret_val = QCA_WLAN_802_11_MODE_11B;
		break;
	case eCSR_CFG_DOT11_MODE_11G:
		ret_val = QCA_WLAN_802_11_MODE_11G;
		break;
	case eCSR_CFG_DOT11_MODE_11N:
		ret_val = QCA_WLAN_802_11_MODE_11N;
		break;
	case eCSR_CFG_DOT11_MODE_11AC:
		ret_val = QCA_WLAN_802_11_MODE_11AC;
		break;
	case eCSR_CFG_DOT11_MODE_AUTO:
	case eCSR_CFG_DOT11_MODE_ABG:
	default:
		ret_val = QCA_WLAN_802_11_MODE_INVALID;
	}
	return ret_val;
}

/**
 * hdd_add_tx_bitrate() - add tx bitrate attribute
 * @skb: pointer to sk buff
 * @hdd_sta_ctx: pointer to hdd station context
 * @idx: attribute index
 *
 * Return: Success(0) or reason code for failure
 */
static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
					  hdd_station_ctx_t *hdd_sta_ctx,
					  int idx)
{
	struct nlattr *nla_attr;
	uint32_t bitrate, bitrate_compat;

	nla_attr = nla_nest_start(skb, idx);
	if (!nla_attr)
		goto fail;
	/* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
	bitrate = cfg80211_calculate_bitrate(
					&hdd_sta_ctx->cache_conn_info.txrate);

	/* report 16-bit bitrate only if we can */
	bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
	if (bitrate > 0 &&
	    nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
		VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
		goto fail;
	}
	if (bitrate_compat > 0 &&
	    nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
		VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
		goto fail;
	}
	if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
		       hdd_sta_ctx->cache_conn_info.txrate.nss)) {
		VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
		goto fail;
	}
	nla_nest_end(skb, nla_attr);
	return 0;
fail:
	return -EINVAL;
}

/**
 * hdd_add_sta_info() - add station info attribute
 * @skb: pointer to sk buff
 * @hdd_sta_ctx: pointer to hdd station context
 * @idx: attribute index
 *
 * Return: Success(0) or reason code for failure
 */
static int32_t hdd_add_sta_info(struct sk_buff *skb,
				       hdd_station_ctx_t *hdd_sta_ctx, int idx)
{
	struct nlattr *nla_attr;

	nla_attr = nla_nest_start(skb, idx);
	if (!nla_attr)
		goto fail;
	if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
		       (hdd_sta_ctx->cache_conn_info.signal + 100))) {
		VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
		goto fail;
	}
	if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
		goto fail;
	nla_nest_end(skb, nla_attr);
	return 0;
fail:
	return -EINVAL;
}

/**
 * hdd_add_survey_info() - add survey info attribute
 * @skb: pointer to sk buff
 * @hdd_sta_ctx: pointer to hdd station context
 * @idx: attribute index
 *
 * Return: Success(0) or reason code for failure
 */
static int32_t hdd_add_survey_info(struct sk_buff *skb,
					   hdd_station_ctx_t *hdd_sta_ctx,
					   int idx)
{
	struct nlattr *nla_attr;

	nla_attr = nla_nest_start(skb, idx);
	if (!nla_attr)
		goto fail;
	if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
			hdd_sta_ctx->cache_conn_info.freq) ||
	    nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
		       (hdd_sta_ctx->cache_conn_info.noise + 100))) {
		VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
		goto fail;
	}
	nla_nest_end(skb, nla_attr);
	return 0;
fail:
	return -EINVAL;
}

/**
 * hdd_add_link_standard_info() - add link info attribute
 * @skb: pointer to sk buff
 * @hdd_sta_ctx: pointer to hdd station context
 * @idx: attribute index
 *
 * Return: Success(0) or reason code for failure
 */
static int32_t
hdd_add_link_standard_info(struct sk_buff *skb,
			   hdd_station_ctx_t *hdd_sta_ctx, int idx)
{
	struct nlattr *nla_attr;

	nla_attr = nla_nest_start(skb, idx);
	if (!nla_attr)
		goto fail;
	if (nla_put(skb,
		    NL80211_ATTR_SSID,
		    hdd_sta_ctx->cache_conn_info.SSID.SSID.length,
		    hdd_sta_ctx->cache_conn_info.SSID.SSID.ssId)) {
		VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
		goto fail;
	}
	if (nla_put(skb, NL80211_ATTR_MAC, VOS_MAC_ADDR_SIZE,
		    hdd_sta_ctx->cache_conn_info.bssId))
		goto fail;
	if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
		goto fail;
	if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
		goto fail;
	nla_nest_end(skb, nla_attr);
	return 0;
fail:
	return -EINVAL;
}

/**
 * hdd_add_ap_standard_info() - add ap info attribute
 * @skb: pointer to sk buff
 * @hdd_sta_ctx: pointer to hdd station context
 * @idx: attribute index
 *
 * Return: Success(0) or reason code for failure
 */
static int32_t
hdd_add_ap_standard_info(struct sk_buff *skb,
			 hdd_station_ctx_t *hdd_sta_ctx, int idx)
{
	struct nlattr *nla_attr;

	nla_attr = nla_nest_start(skb, idx);
	if (!nla_attr)
		goto fail;
	if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
		if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
			    sizeof(hdd_sta_ctx->cache_conn_info.vht_caps),
			    &hdd_sta_ctx->cache_conn_info.vht_caps)) {
			VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
			goto fail;
		}
	if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
		if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
			    sizeof(hdd_sta_ctx->cache_conn_info.ht_caps),
			    &hdd_sta_ctx->cache_conn_info.ht_caps)) {
			VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
			goto fail;
		}
	nla_nest_end(skb, nla_attr);
	return 0;
fail:
	return -EINVAL;
}

/**
 * hdd_get_station_info() - send BSS information to supplicant
 * @hdd_ctx: pointer to hdd context
 * @adapter: pointer to adapter
 *
 * Return: 0 if success else error status
 */
static int hdd_get_station_info(hdd_context_t *hdd_ctx,
					 hdd_adapter_t *adapter)
{
	struct sk_buff *skb = NULL;
	uint8_t *tmp_hs20 = NULL;
	uint32_t nl_buf_len;
	hdd_station_ctx_t *hdd_sta_ctx;

	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);

	nl_buf_len = NLMSG_HDRLEN;

	nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.SSID.SSID.length) +
		      VOS_MAC_ADDR_SIZE +
		      sizeof(hdd_sta_ctx->cache_conn_info.freq) +
		      sizeof(hdd_sta_ctx->cache_conn_info.noise) +
		      sizeof(hdd_sta_ctx->cache_conn_info.signal) +
		      (sizeof(uint32_t) * 2) +
		      sizeof(hdd_sta_ctx->cache_conn_info.txrate.nss) +
		      sizeof(hdd_sta_ctx->cache_conn_info.roam_count) +
		      sizeof(hdd_sta_ctx->cache_conn_info.authType) +
		      sizeof(hdd_sta_ctx->cache_conn_info.dot11Mode);
	if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
		nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.vht_caps);
	if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
		nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_caps);
	if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) {
		tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->
						cache_conn_info.hs20vendor_ie);
		nl_buf_len +=
			(sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie) -
			       1);
	}
	if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
		nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_operation);
	if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
		nl_buf_len +=
			sizeof(hdd_sta_ctx->cache_conn_info.vht_operation);


	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
	if (!skb) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
			  __func__, __LINE__);
		return -ENOMEM;
	}

	if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
				       LINK_INFO_STANDARD_NL80211_ATTR)) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
		goto fail;
	}
	if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
				     AP_INFO_STANDARD_NL80211_ATTR)) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
		goto fail;
	}
	if (nla_put_u32(skb, INFO_ROAM_COUNT,
			hdd_sta_ctx->cache_conn_info.roam_count) ||
	    nla_put_u32(skb, INFO_AKM,
			hdd_convert_auth_type(
			hdd_sta_ctx->cache_conn_info.authType)) ||
	    nla_put_u32(skb, WLAN802_11_MODE,
			hdd_convert_dot11mode(
			hdd_sta_ctx->cache_conn_info.dot11Mode))) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
		goto fail;
	}
	if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
		if (nla_put(skb, HT_OPERATION,
			    (sizeof(hdd_sta_ctx->cache_conn_info.ht_operation)),
			    &hdd_sta_ctx->cache_conn_info.ht_operation)) {
			VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
			goto fail;
		}
	if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
		if (nla_put(skb, VHT_OPERATION,
			    (sizeof(hdd_sta_ctx->
				    cache_conn_info.vht_operation)),
			    &hdd_sta_ctx->cache_conn_info.vht_operation)) {
			VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
			goto fail;
		}
	if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present)
		if (nla_put(skb, AP_INFO_HS20_INDICATION,
			    (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie)
				    - 1), tmp_hs20 + 1)) {
			VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
			goto fail;
		}

	return cfg80211_vendor_cmd_reply(skb);
fail:
	if (skb)
		kfree_skb(skb);
	return -EINVAL;
}

/**
 * hdd_add_survey_info_sap_get_len - get data length used in
 * hdd_add_survey_info_sap()
 *
 * This function calculates the data length used in hdd_add_survey_info_sap()
 *
 * Return: total data length used in hdd_add_survey_info_sap()
 */
static uint32_t hdd_add_survey_info_sap_get_len(void)
{
	return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
}

/**
 * hdd_add_survey_info - add survey info attribute
 * @skb: pointer to response skb buffer
 * @stainfo: station information
 * @idx: attribute type index for nla_next_start()
 *
 * This function adds survey info attribute to response skb buffer
 *
 * Return : 0 on success and errno on failure
 */
static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
				       struct hdd_cache_sta_info *stainfo,
				       int idx)
{
	struct nlattr *nla_attr;

	nla_attr = nla_nest_start(skb, idx);
	if (!nla_attr)
		goto fail;
	if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
			stainfo->freq)) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			  FL("put fail"));
		goto fail;
	}
	nla_nest_end(skb, nla_attr);
	return 0;
fail:
	return -EINVAL;
}

/**
 * hdd_add_tx_bitrate_sap_get_len - get data length used in
 * hdd_add_tx_bitrate_sap()
 *
 * This function calculates the data length used in hdd_add_tx_bitrate_sap()
 *
 * Return: total data length used in hdd_add_tx_bitrate_sap()
 */
static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
{
	return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
}

/**
 * hdd_add_tx_bitrate_sap - add vht nss info attribute
 * @skb: pointer to response skb buffer
 * @stainfo: station information
 * @idx: attribute type index for nla_next_start()
 *
 * This function adds vht nss attribute to response skb buffer
 *
 * Return : 0 on success and errno on failure
 */
static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
				  struct hdd_cache_sta_info *stainfo,
				  int idx)
{
	struct nlattr *nla_attr;

	nla_attr = nla_nest_start(skb, idx);
	if (!nla_attr)
		goto fail;

	if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
		       stainfo->nss)) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			  FL("put fail"));
		goto fail;
	}
	nla_nest_end(skb, nla_attr);
	return 0;
fail:
	return -EINVAL;
}

/**
 * hdd_add_sta_info_sap_get_len - get data length used in
 * hdd_add_sta_info_sap()
 *
 * This function calculates the data length used in hdd_add_sta_info_sap()
 *
 * Return: total data length used in hdd_add_sta_info_sap()
 */
static uint32_t hdd_add_sta_info_sap_get_len(void)
{
	return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
		hdd_add_tx_bitrate_sap_get_len());
}

/**
 * hdd_add_sta_info_sap - add sta signal info attribute
 * @skb: pointer to response skb buffer
 * @rssi: peer rssi value
 * @stainfo: station information
 * @idx: attribute type index for nla_next_start()
 *
 * This function adds sta signal attribute to response skb buffer
 *
 * Return : 0 on success and errno on failure
 */
static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
				    struct hdd_cache_sta_info *stainfo, int idx)
{
	struct nlattr *nla_attr;

	nla_attr = nla_nest_start(skb, idx);
	if (!nla_attr)
		goto fail;

	/* upperlayer expects positive rssi value */
	if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, (rssi + 96))) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			  FL("put fail"));
		goto fail;
	}
	if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE)) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			  FL("put fail"));
		goto fail;
	}

	nla_nest_end(skb, nla_attr);
	return 0;
fail:
	return -EINVAL;
}

/**
 * hdd_add_link_standard_info_sap_get_len - get data length used in
 * hdd_add_link_standard_info_sap()
 *
 * This function calculates the data length used in
 * hdd_add_link_standard_info_sap()
 *
 * Return: total data length used in hdd_add_link_standard_info_sap()
 */
static uint32_t hdd_add_link_standard_info_sap_get_len(void)
{
	return ((NLA_HDRLEN) +
		hdd_add_survey_info_sap_get_len() +
		hdd_add_sta_info_sap_get_len() +
		(sizeof(uint32_t) + NLA_HDRLEN));
}

/**
 * hdd_add_link_standard_info_sap - add add link info attribut
 * @skb: pointer to response skb buffer
 * @stainfo: station information
 * @idx: attribute type index for nla_next_start()
 *
 * This function adds link info attribut to response skb buffer
 *
 * Return : 0 on success and errno on failure
 */
static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
					  struct hdd_cache_sta_info *stainfo,
					  int idx)
{
	struct nlattr *nla_attr;

	nla_attr = nla_nest_start(skb, idx);
	if (!nla_attr)
		goto fail;
	if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
		goto fail;
	if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
		goto fail;

	if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			  FL("put fail"));
		goto fail;
	}

	nla_nest_end(skb, nla_attr);
	return 0;
fail:
	return -EINVAL;
}

/**
 * hdd_add_ap_standard_info_sap_get_len - get data length used in
 * hdd_add_ap_standard_info_sap()
 * @stainfo: station information
 *
 * This function calculates the data length used in
 * hdd_add_ap_standard_info_sap()
 *
 * Return: total data length used in hdd_add_ap_standard_info_sap()
 */
static uint32_t hdd_add_ap_standard_info_sap_get_len(
				struct hdd_cache_sta_info *stainfo)
{
	uint32_t len;

	len = NLA_HDRLEN;
	if (stainfo->vht_present)
		len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
	if (stainfo->ht_present)
		len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);

	return len;
}

/**
 * hdd_add_ap_standard_info_sap - add HT and VHT info attributes
 * @skb: pointer to response skb buffer
 * @stainfo: station information
 * @idx: attribute type index for nla_next_start()
 *
 * This function adds HT and VHT info attributes to response skb buffer
 *
 * Return : 0 on success and errno on failure
 */
static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
					struct hdd_cache_sta_info *stainfo,
					int idx)
{
	struct nlattr *nla_attr;

	nla_attr = nla_nest_start(skb, idx);
	if (!nla_attr)
		goto fail;

	if (stainfo->vht_present) {
		if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
			    sizeof(stainfo->vht_caps),
			    &stainfo->vht_caps)) {
			VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			  FL("put fail"));
			goto fail;
		}
	}
	if (stainfo->ht_present) {
		if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
			    sizeof(stainfo->ht_caps),
			    &stainfo->ht_caps)) {
			VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			  FL("put fail"));
			goto fail;
		}
	}
	nla_nest_end(skb, nla_attr);
	return 0;
fail:
	return -EINVAL;
}

/**
 * hdd_decode_ch_width - decode channel band width based
 * @ch_width: encoded enum value holding channel band width
 *
 * This function decodes channel band width from the given encoded enum value.
 *
 * Returns: decoded channel band width.
 */
static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
{
	switch (ch_width) {
	case 0:
		return 20;
	case 1:
		return 40;
	case 2:
		return 80;
	default:
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			  "invalid enum: %d", ch_width);
		return 20;
	}
}

/**
 * hdd_get_cached_station_remote() - get cached(deleted) peer's info
 * @hdd_ctx: hdd context
 * @adapter: hostapd interface
 * @mac_addr: mac address of requested peer
 *
 * This function collect and indicate the cached(deleted) peer's info
 *
 * Return: 0 on success, otherwise error value
 */
static int hdd_get_cached_station_remote(hdd_context_t *hdd_ctx,
					 hdd_adapter_t *adapter,
					 v_MACADDR_t mac_addr)
{
	struct hdd_cache_sta_info *stainfo;
	struct sk_buff *skb = NULL;
	uint32_t nl_buf_len;
	uint8_t cw;
        ptSapContext sap_ctx;
	v_CONTEXT_t vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;

	sap_ctx = VOS_GET_SAP_CB(vos_ctx);
	if(sap_ctx == NULL){
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			  FL("psapCtx is NULL"));
		return -ENOENT;
	}

	stainfo = hdd_get_cache_stainfo(sap_ctx->cache_sta_info,
				        mac_addr.bytes);
	if (!stainfo) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			  "peer " MAC_ADDRESS_STR " not found",
			  MAC_ADDR_ARRAY(mac_addr.bytes));
		return -EINVAL;
	}
	if (sap_ctx->aStaInfo[stainfo->ucSTAId].isUsed == TRUE) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			  "peer " MAC_ADDRESS_STR " is in connected state",
			  MAC_ADDR_ARRAY(mac_addr.bytes));
		return -EINVAL;
	}


	nl_buf_len = NLMSG_HDRLEN + hdd_add_link_standard_info_sap_get_len() +
		     hdd_add_ap_standard_info_sap_get_len(stainfo) +
		     (sizeof(stainfo->dot11_mode) + NLA_HDRLEN) +
		     (sizeof(cw) + NLA_HDRLEN) +
		     (sizeof(stainfo->rx_rate) + NLA_HDRLEN);

	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
	if (!skb) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "cfg80211_vendor_cmd_alloc_reply_skb failed");
		return -ENOMEM;
	}

	if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
					   LINK_INFO_STANDARD_NL80211_ATTR)) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "link standard put fail");
		goto fail;
	}

	if (hdd_add_ap_standard_info_sap(skb, stainfo,
					 AP_INFO_STANDARD_NL80211_ATTR)) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ap standard put fail");
		goto fail;
	}

	/* upper layer expects decoded channel BW */
	cw = hdd_decode_ch_width(stainfo->ch_width);
	if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE, stainfo->dot11_mode) ||
	    nla_put_u8(skb, REMOTE_CH_WIDTH, cw)) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "remote ch put fail");
		goto fail;
	}
	if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, (stainfo->rx_rate * 100))) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "rx rate put fail");
		goto fail;
	}

	vos_mem_zero(stainfo, sizeof(*stainfo));

	return cfg80211_vendor_cmd_reply(skb);
fail:
	if (skb)
		kfree_skb(skb);

	return -EINVAL;
}

/**
 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
 * @wiphy: corestack handler
 * @wdev: wireless device
 * @data: data
 * @data_len: data length
 *
 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
 * Validate cmd attributes and send the station info to upper layers.
 *
 * Return: Success(0) or reason code for failure
 */
static int32_t
__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
			       struct wireless_dev *wdev,
			       const void *data,
			       int data_len)
{
	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
	struct net_device *dev = wdev->netdev;
	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
	int32_t status;

	VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
	if (VOS_FTM_MODE == hdd_get_conparam()) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
		status = -EPERM;
		goto out;
	}

	status = wlan_hdd_validate_context(hdd_ctx);
	if (0 != status)
		goto out;


	status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
			data, data_len, NULL);
	if (status) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
		goto out;
	}

	/* Parse and fetch Command Type*/
	if (tb[STATION_INFO]) {
		status = hdd_get_station_info(hdd_ctx, adapter);
	} else if (tb[STATION_ASSOC_FAIL_REASON]) {
		status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
	} else if (tb[STATION_REMOTE]) {
		v_MACADDR_t mac_addr;

		if (adapter->device_mode != WLAN_HDD_SOFTAP &&
		    adapter->device_mode != WLAN_HDD_P2P_GO) {
			VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"invalid device_mode:%d",
				  adapter->device_mode);
			status = -EINVAL;
			goto out;
		}

		nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE],
			   VOS_MAC_ADDRESS_LEN);

		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "STATION_REMOTE "MAC_ADDRESS_STR"",
			  MAC_ADDR_ARRAY(mac_addr.bytes));

		status = hdd_get_cached_station_remote(hdd_ctx, adapter,
						       mac_addr);
	} else {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
		status = -EINVAL;
		goto out;
	}
	EXIT();
out:
	return status;
}

/**
 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
 * @wiphy: corestack handler
 * @wdev: wireless device
 * @data: data
 * @data_len: data length
 *
 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
 * Validate cmd attributes and send the station info to upper layers.
 *
 * Return: Success(0) or reason code for failure
 */
static int32_t
hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
			     struct wireless_dev *wdev,
			     const void *data,
			     int data_len)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
	vos_ssr_unprotect(__func__);

	return ret;
}

/*
 * undef short names defined for get station command
 * used by __wlan_hdd_cfg80211_get_station_cmd()
 */
#undef STATION_INVALID
#undef STATION_INFO
#undef STATION_ASSOC_FAIL_REASON
#undef STATION_MAX

#ifdef WLAN_FEATURE_LINK_LAYER_STATS

static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
                                struct sk_buff *vendor_event)
{
    if (nla_put_u8(vendor_event,
                QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
                stats->rate.preamble)  ||
        nla_put_u8(vendor_event,
            QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
            stats->rate.nss)       ||
        nla_put_u8(vendor_event,
            QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
            stats->rate.bw)        ||
        nla_put_u8(vendor_event,
            QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
            stats->rate.rateMcsIdx) ||
        nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
            stats->rate.bitrate )   ||
        nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
            stats->txMpdu )    ||
        nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
                stats->rxMpdu )     ||
        nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
                stats->mpduLost )  ||
        nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
                stats->retries)     ||
        nla_put_u32(vendor_event,
                QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
                stats->retriesShort )   ||
        nla_put_u32(vendor_event,
                QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
                stats->retriesLong))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                FL("QCA_WLAN_VENDOR_ATTR put fail"));
        return FALSE;
    }
    return TRUE;
}

static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
                               struct sk_buff *vendor_event)
{
    u32 i = 0;
    struct nlattr *rateInfo;
    if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
                                     stats->type) ||
        nla_put(vendor_event,
                QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
                VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
                    stats->capabilities) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
                    stats->numRate))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                FL("QCA_WLAN_VENDOR_ATTR put fail"));
        goto error;
    }

    rateInfo = nla_nest_start(vendor_event,
                            QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
    if(!rateInfo)
        return FALSE;
    for (i = 0; i < stats->numRate; i++)
    {
        struct nlattr *rates;
        tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
                                            stats->rateStats +
                                       (i * sizeof(tSirWifiRateStat)));
        rates = nla_nest_start(vendor_event, i);
        if(!rates)
            return FALSE;

        if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                FL("QCA_WLAN_VENDOR_ATTR put fail"));
            return FALSE;
        }
        nla_nest_end(vendor_event, rates);
    }
    nla_nest_end(vendor_event, rateInfo);

    return TRUE;
error:
    return FALSE;
}

static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
                                  struct sk_buff *vendor_event)
{
    if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
                    stats->ac ) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
                    stats->txMpdu ) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
                    stats->rxMpdu ) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
                    stats->txMcast ) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
                    stats->rxMcast ) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
                    stats->rxAmpdu ) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
                    stats->txAmpdu ) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
                    stats->mpduLost )||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
                    stats->retries ) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
                    stats->retriesShort ) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
                    stats->retriesLong ) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
                    stats->contentionTimeMin ) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
                    stats->contentionTimeMax ) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
                    stats->contentionTimeAvg ) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
                    stats->contentionNumSamples ))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                FL("QCA_WLAN_VENDOR_ATTR put fail") );
        return FALSE;
    }
    return TRUE;
}

static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
                                    struct sk_buff *vendor_event)
{
    if (nla_put_s32(vendor_event,
                QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
            nla_put(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
                    VOS_MAC_ADDR_SIZE, stats->macAddr) ||
            nla_put_u32(vendor_event,
                        QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
                        stats->state ) ||
            nla_put_u32(vendor_event,
                        QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
                        stats->roaming ) ||
            nla_put_u32(vendor_event,
                        QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
                        stats->capabilities ) ||
            nla_put(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
                    strlen(stats->ssid), stats->ssid) ||
            nla_put(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
                    WNI_CFG_BSSID_LEN, stats->bssid) ||
            nla_put(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
                    WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
            nla_put(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
                    WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
      )
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                FL("QCA_WLAN_VENDOR_ATTR put fail") );
        return FALSE;
    }
    return TRUE;
}

static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
                            tpSirWifiIfaceStat pWifiIfaceStat,
                                 struct sk_buff *vendor_event)
{
    int i = 0;
    struct nlattr *wmmInfo;
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
    tSirWifiWmmAcStat accessclassStats;

    if (FALSE == put_wifi_interface_info(
                                &pWifiIfaceStat->info,
                                vendor_event))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                FL("QCA_WLAN_VENDOR_ATTR put fail") );
        return FALSE;

    }
    pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
                             vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
    if (NULL == pWifiIfaceStatTL)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
        return FALSE;
    }

    accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
    pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
        pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
    pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;

    accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
    pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
        pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
    pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;

    if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
    {
        if (VOS_STATUS_SUCCESS ==
         WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
                    pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
        {
            /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
             * obtained from TL structure
             */

            pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
                pWifiIfaceStatTL->mgmtRx;
            pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;

            pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
                = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
            pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
                = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
            pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
                = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
            pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
                = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;

            pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
                = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
            pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
                = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
            pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
                = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
            pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
                = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;

            pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
                = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
            pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
                = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
            pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
                = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
            pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
                = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
        }
        else
        {
            hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
        }

        pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
            pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
        pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
            pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
        pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
            pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
        pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
            pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
    }
    else
    {
        hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
    }



    if (nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
                    pWifiIfaceStat->beaconRx) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
                    pWifiIfaceStat->mgmtRx) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
                    pWifiIfaceStat->mgmtActionRx) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
                    pWifiIfaceStat->mgmtActionTx) ||
        nla_put_s32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
                    pWifiIfaceStat->rssiMgmt) ||
        nla_put_s32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
                    pWifiIfaceStat->rssiData) ||
        nla_put_s32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
                    pWifiIfaceStat->rssiAck))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("QCA_WLAN_VENDOR_ATTR put fail"));
               vos_mem_free(pWifiIfaceStatTL);
        return FALSE;
    }

#ifdef FEATURE_EXT_LL_STAT
   /*
    * Ensure when EXT_LL_STAT is supported by both host and fwr,
    * then host should send Leaky AP stats to upper layer,
    * otherwise no need to send these stats.
    */
   if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
      sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
     )
   {
       hddLog(VOS_TRACE_LEVEL_INFO,
              FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
              pWifiIfaceStat->leakyApStat.is_leaky_ap,
              pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
              pWifiIfaceStat->leakyApStat.rx_leak_window,
              pWifiIfaceStat->leakyApStat.avg_bcn_spread);
       if (nla_put_u32(vendor_event,
               QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
               pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
           nla_put_u32(vendor_event,
               QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
               pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
           nla_put_u32(vendor_event,
               QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
               pWifiIfaceStat->leakyApStat.rx_leak_window) ||
           hdd_wlan_nla_put_u64(vendor_event,
               QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
               pWifiIfaceStat->leakyApStat.avg_bcn_spread))
       {
           hddLog(VOS_TRACE_LEVEL_ERROR,
                  FL("EXT_LL_STAT put fail"));
           vos_mem_free(pWifiIfaceStatTL);
           return FALSE;
       }
   }
#endif
    wmmInfo = nla_nest_start(vendor_event,
                            QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
    if(!wmmInfo)
    {
        vos_mem_free(pWifiIfaceStatTL);
        return FALSE;
    }
    for (i = 0; i < WIFI_AC_MAX; i++)
    {
        struct nlattr *wmmStats;
        wmmStats = nla_nest_start(vendor_event, i);
        if(!wmmStats)
        {
            vos_mem_free(pWifiIfaceStatTL);
            return FALSE;
        }
        if (FALSE == put_wifi_wmm_ac_stat(
                                &pWifiIfaceStat->AccessclassStats[i],
                                vendor_event))
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    FL("QCA_WLAN_VENDOR_ATTR put Fail"));
            vos_mem_free(pWifiIfaceStatTL);
            return FALSE;
        }

        nla_nest_end(vendor_event, wmmStats);
    }
    nla_nest_end(vendor_event, wmmInfo);
    vos_mem_free(pWifiIfaceStatTL);
    return TRUE;
}

static tSirWifiInterfaceMode
    hdd_map_device_to_ll_iface_mode ( int deviceMode )
{
    switch (deviceMode)
    {
    case  WLAN_HDD_INFRA_STATION:
        return WIFI_INTERFACE_STA;
    case  WLAN_HDD_SOFTAP:
        return WIFI_INTERFACE_SOFTAP;
    case  WLAN_HDD_P2P_CLIENT:
        return WIFI_INTERFACE_P2P_CLIENT;
    case  WLAN_HDD_P2P_GO:
        return WIFI_INTERFACE_P2P_GO;
    case  WLAN_HDD_IBSS:
        return WIFI_INTERFACE_IBSS;
    default:
        return WIFI_INTERFACE_UNKNOWN;
    }
}

static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
                           tpSirWifiInterfaceInfo pInfo)
{
    v_U8_t *staMac = NULL;
    hdd_station_ctx_t *pHddStaCtx;
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);

    vos_mem_copy(pInfo->macAddr,
        pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));

    if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
            (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
            (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
    {
        pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
        if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
        {
            pInfo->state = WIFI_DISCONNECTED;
        }
        if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    "%s: Session ID %d, Connection is in progress", __func__,
                    pAdapter->sessionId);
            pInfo->state = WIFI_ASSOCIATING;
        }
        if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
            (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
        {
            staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
            hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: client " MAC_ADDRESS_STR
                " is in the middle of WPS/EAPOL exchange.", __func__,
                MAC_ADDR_ARRAY(staMac));
            pInfo->state = WIFI_AUTHENTICATING;
        }
        if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
        {
            pInfo->state = WIFI_ASSOCIATED;
            vos_mem_copy(pInfo->bssid,
                    &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
            vos_mem_copy(pInfo->ssid,
                    pHddStaCtx->conn_info.SSID.SSID.ssId,
                    pHddStaCtx->conn_info.SSID.SSID.length);
            //NULL Terminate the string.
            pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
        }
    }
    vos_mem_copy(pInfo->countryStr,
        pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);

    vos_mem_copy(pInfo->apCountryStr,
        pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);

    return TRUE;
}

/*
 * hdd_link_layer_process_peer_stats () - This function is called after
 * receiving Link Layer Peer statistics from FW.This function converts
 * the firmware data to the NL data and sends the same to the kernel/upper
 * layers.
 */
static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
                                                   v_VOID_t *pData)
{
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    tpSirWifiPeerStat   pWifiPeerStat;
    tpSirWifiPeerInfo   pWifiPeerInfo;
    struct nlattr *peerInfo;
    struct sk_buff *vendor_event;
    int status, i;

    ENTER();

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return;
    }

    pWifiPeerStat = (tpSirWifiPeerStat) pData;

    hddLog(VOS_TRACE_LEVEL_INFO,
            "LL_STATS_PEER_ALL : numPeers %u",
            pWifiPeerStat->numPeers);
    /*
     * Allocate a size of 4096 for the peer stats comprising
     * each of size = sizeof (tSirWifiPeerInfo) + numRate *
     * sizeof (tSirWifiRateStat).Each field is put with an
     * NL attribute.The size of 4096 is considered assuming
     * that number of rates shall not exceed beyond 50 with
     * the sizeof (tSirWifiRateStat) being 32.
     */
    vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
            LL_STATS_EVENT_BUF_SIZE);
    if (!vendor_event)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
                __func__);
        return;
    }
    if (nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
        nla_put_u32(vendor_event,
            QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
            pWifiPeerStat->numPeers))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
        kfree_skb(vendor_event);
        return;
    }

    peerInfo = nla_nest_start(vendor_event,
            QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
    if(!peerInfo)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
                __func__);
        kfree_skb(vendor_event);
        return;
    }

    pWifiPeerInfo = (tpSirWifiPeerInfo)  ((uint8 *)
                pWifiPeerStat->peerInfo);

    for (i = 1; i <= pWifiPeerStat->numPeers; i++)
    {
        int numRate = pWifiPeerInfo->numRate;
        struct nlattr *peers = nla_nest_start(vendor_event, i);

        if(!peers)
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    "%s: peer stats put fail",
                    __func__);
            kfree_skb(vendor_event);
            return;
        }
        if (FALSE == put_wifi_peer_info(
                                     pWifiPeerInfo, vendor_event))
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: put_wifi_peer_info put fail", __func__);
            kfree_skb(vendor_event);
            return;
        }

        pWifiPeerInfo = (tpSirWifiPeerInfo)  ((uint8 *)
                pWifiPeerStat->peerInfo +
                (i * sizeof(tSirWifiPeerInfo)) +
                (numRate * sizeof (tSirWifiRateStat)));
        nla_nest_end(vendor_event, peers);
    }
    nla_nest_end(vendor_event, peerInfo);
    cfg80211_vendor_cmd_reply(vendor_event);
    EXIT();
}

/*
 * hdd_link_layer_process_iface_stats () - This function is called after
 * receiving Link Layer Interface statistics from FW.This function converts
 * the firmware data to the NL data and sends the same to the kernel/upper
 * layers.
 */
static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
                                                   v_VOID_t *pData)
{
    tpSirWifiIfaceStat  pWifiIfaceStat;
    struct sk_buff *vendor_event;
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    int status;

    ENTER();

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return;
    }
    /*
     * Allocate a size of 4096 for the interface stats comprising
     * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
     * assuming that all these fit with in the limit.Please take
     * a call on the limit based on the data requirements on
     * interface statistics.
     */
    vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
           LL_STATS_EVENT_BUF_SIZE);
    if (!vendor_event)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
        return;
    }

    pWifiIfaceStat = (tpSirWifiIfaceStat) pData;


    if (FALSE == hdd_get_interface_info( pAdapter,
                                        &pWifiIfaceStat->info))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("hdd_get_interface_info get fail") );
        kfree_skb(vendor_event);
        return;
    }

    if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
                                       vendor_event))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("put_wifi_iface_stats fail") );
        kfree_skb(vendor_event);
        return;
    }

    hddLog(VOS_TRACE_LEVEL_INFO,
           "WMI_LINK_STATS_IFACE Data");

    cfg80211_vendor_cmd_reply(vendor_event);

    EXIT();
}

/*
 * hdd_link_layer_process_radio_stats () - This function is called after
 * receiving Link Layer Radio statistics from FW.This function converts
 * the firmware data to the NL data and sends the same to the kernel/upper
 * layers.
 */
static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
                                                   v_VOID_t *pData)
{
    int status, i;
    tpSirWifiRadioStat  pWifiRadioStat;
    tpSirWifiChannelStats pWifiChannelStats;
    struct sk_buff *vendor_event;
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    struct nlattr *chList;

    ENTER();

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return;
    }
    pWifiRadioStat = (tpSirWifiRadioStat) pData;

    hddLog(VOS_TRACE_LEVEL_INFO,
           "LL_STATS_RADIO"
           " number of radios = %u"
           " radio is %d onTime is %u "
           " txTime is %u  rxTime is %u "
           " onTimeScan is %u  onTimeNbd is %u "
           " onTimeEXTScan is %u onTimeRoamScan is %u "
           " onTimePnoScan is %u  onTimeHs20 is %u "
           " numChannels is %u",
           NUM_RADIOS,
           pWifiRadioStat->radio, pWifiRadioStat->onTime,
           pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
           pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
           pWifiRadioStat->onTimeEXTScan,
           pWifiRadioStat->onTimeRoamScan,
           pWifiRadioStat->onTimePnoScan,
           pWifiRadioStat->onTimeHs20,
           pWifiRadioStat->numChannels);
    /*
     * Allocate a size of 4096 for the Radio stats comprising
     * sizeof (tSirWifiRadioStat) + numChannels * sizeof
     * (tSirWifiChannelStats).Each channel data is put with an
     * NL attribute.The size of 4096 is considered assuming that
     * number of channels shall not exceed beyond  60 with the
     * sizeof (tSirWifiChannelStats) being 24 bytes.
     */

    vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
           LL_STATS_EVENT_BUF_SIZE);
    if (!vendor_event)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
        return;
    }

    if (nla_put_u32(vendor_event,
             QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
             QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
        nla_put_u32(vendor_event,
             QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
             pWifiRadioStat->radio)      ||
        nla_put_u32(vendor_event,
             QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
             NUM_RADIOS)     ||
        nla_put_u32(vendor_event,
             QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
             pWifiRadioStat->onTime)     ||
        nla_put_u32(vendor_event,
             QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
             pWifiRadioStat->txTime)     ||
        nla_put_u32(vendor_event,
             QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
             pWifiRadioStat->rxTime)     ||
        nla_put_u32(vendor_event,
             QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
             pWifiRadioStat->onTimeScan) ||
        nla_put_u32(vendor_event,
             QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
             pWifiRadioStat->onTimeNbd)  ||
        nla_put_u32(vendor_event,
             QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
             pWifiRadioStat->onTimeEXTScan)||
        nla_put_u32(vendor_event,
             QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
             pWifiRadioStat->onTimeRoamScan) ||
        nla_put_u32(vendor_event,
             QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
             pWifiRadioStat->onTimePnoScan) ||
        nla_put_u32(vendor_event,
             QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
             pWifiRadioStat->onTimeHs20)    ||
        nla_put_u32(vendor_event,
             QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
             pWifiRadioStat->numChannels))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                FL("QCA_WLAN_VENDOR_ATTR put fail"));
        kfree_skb(vendor_event);
        return ;
    }

    chList = nla_nest_start(vendor_event,
             QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
    if(!chList)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
                __func__);
        kfree_skb(vendor_event);
        return;
    }
    for (i = 0; i < pWifiRadioStat->numChannels; i++)
    {
        struct nlattr *chInfo;

        pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
                pWifiRadioStat->channels +
                (i * sizeof(tSirWifiChannelStats)));

        chInfo = nla_nest_start(vendor_event, i);
        if(!chInfo)
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    "%s: failed to put chInfo",
                    __func__);
            kfree_skb(vendor_event);
            return;
        }

        if (nla_put_u32(vendor_event,
                QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
                pWifiChannelStats->channel.width) ||
            nla_put_u32(vendor_event,
                QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
                pWifiChannelStats->channel.centerFreq) ||
            nla_put_u32(vendor_event,
                QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
                pWifiChannelStats->channel.centerFreq0)  ||
            nla_put_u32(vendor_event,
                QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
                pWifiChannelStats->channel.centerFreq1)    ||
            nla_put_u32(vendor_event,
                QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
                pWifiChannelStats->onTime)  ||
            nla_put_u32(vendor_event,
                QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
                pWifiChannelStats->ccaBusyTime))
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                   FL("cfg80211_vendor_event_alloc failed") );
            kfree_skb(vendor_event);
            return ;
        }
        nla_nest_end(vendor_event, chInfo);
    }
    nla_nest_end(vendor_event, chList);

    cfg80211_vendor_cmd_reply(vendor_event);

    EXIT();
    return;
}

/*
 * hdd_link_layer_stats_ind_callback () - This function is called after
 * receiving Link Layer indications from FW.This callback converts the firmware
 * data to the NL data and send the same to the kernel/upper layers.
 */
static void hdd_link_layer_stats_ind_callback ( void *pCtx,
                                                int indType,
                                                void *pRsp, u8  *macAddr)
{
    hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
    hdd_adapter_t *pAdapter = NULL;
    struct hdd_ll_stats_context *context;
    tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
    int status;

    ENTER();

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return;
    }

    pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
    if (NULL == pAdapter)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                FL(" MAC address %pM does not exist with host"),
                macAddr);
        return;
    }

    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
            "%s: Interface: %s LLStats indType: %d", __func__,
            pAdapter->dev->name, indType);

    switch (indType)
    {
    case SIR_HAL_LL_STATS_RESULTS_RSP:
        {
            hddLog(VOS_TRACE_LEVEL_INFO,
                    "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
                    "respId = %u, moreResultToFollow = %u",
                 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
                 macAddr, linkLayerStatsResults->respId,
                 linkLayerStatsResults->moreResultToFollow);

            spin_lock(&hdd_context_lock);
            context = &pHddCtx->ll_stats_context;
            /* validate response received from target */
            if ((context->request_id != linkLayerStatsResults->respId) ||
                !(context->request_bitmap & linkLayerStatsResults->paramId))
            {
                spin_unlock(&hdd_context_lock);
                hddLog(LOGE,
                   FL("Error : Request id %d response id %d request bitmap 0x%x"
                      "response bitmap 0x%x"),
                   context->request_id, linkLayerStatsResults->respId,
                   context->request_bitmap, linkLayerStatsResults->paramId);
                return;
            }
            spin_unlock(&hdd_context_lock);

            if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
            {
                hdd_link_layer_process_radio_stats(pAdapter,
                                (v_VOID_t *)linkLayerStatsResults->result);
                spin_lock(&hdd_context_lock);
                context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
                spin_unlock(&hdd_context_lock);
            }
            else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
            {
                hdd_link_layer_process_iface_stats(pAdapter,
                                (v_VOID_t *)linkLayerStatsResults->result);
                spin_lock(&hdd_context_lock);
                context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
                spin_unlock(&hdd_context_lock);
            }
            else if ( linkLayerStatsResults->paramId &
                    WMI_LINK_STATS_ALL_PEER )
            {
                hdd_link_layer_process_peer_stats(pAdapter,
                                (v_VOID_t *)linkLayerStatsResults->result);
                spin_lock(&hdd_context_lock);
                context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
                spin_unlock(&hdd_context_lock);
            } /* WMI_LINK_STATS_ALL_PEER */
            else
            {
                hddLog(VOS_TRACE_LEVEL_ERROR,
                        FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
            }

            spin_lock(&hdd_context_lock);
            /* complete response event if all requests are completed */
            if (0 == context->request_bitmap)
                complete(&context->response_event);
            spin_unlock(&hdd_context_lock);

            break;
        }
        default:
            hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
            break;
    }

    EXIT();
    return;
}

const struct
nla_policy
qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
{
    [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
    { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
    { .type = NLA_U32 },
};

static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
                                            struct wireless_dev *wdev,
                                            const void *data,
                                            int data_len)
{
    int status;
    struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
    tSirLLStatsSetReq linkLayerStatsSetReq;
    struct net_device *dev = wdev->netdev;
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx = wiphy_priv(wiphy);

    ENTER();

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return -EINVAL;
    }

    if (NULL == pAdapter)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("HDD adapter is Null"));
        return -ENODEV;
    }
    /* check the LLStats Capability */
    if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
         (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
    {
        hddLog(VOS_TRACE_LEVEL_WARN,
               FL("Link Layer Statistics not supported by Firmware"));
        return -EINVAL;
    }

    if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
           (struct nlattr *)data,
           data_len, qca_wlan_vendor_ll_set_policy))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
        return -EINVAL;
    }
    if (!tb_vendor
            [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
        return -EINVAL;
    }
    if (!tb_vendor[
         QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
        return -EINVAL;
    }
    // Shall take the request Id if the Upper layers pass. 1 For now.
    linkLayerStatsSetReq.reqId = 1;

    linkLayerStatsSetReq.mpduSizeThreshold =
        nla_get_u32(
            tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);

    linkLayerStatsSetReq.aggressiveStatisticsGathering =
        nla_get_u32(
            tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);

    vos_mem_copy(linkLayerStatsSetReq.macAddr,
               pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));


    hddLog(VOS_TRACE_LEVEL_INFO,
           "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
           "Statistics Gathering  = %d ",
           linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
           linkLayerStatsSetReq.mpduSizeThreshold,
           linkLayerStatsSetReq.aggressiveStatisticsGathering);

    if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
                               pHddCtx->hHal,
                               hdd_link_layer_stats_ind_callback))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
           "sme_SetLinkLayerStatsIndCB Failed", __func__);
        return -EINVAL;

    }

    if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
                                            &linkLayerStatsSetReq))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
           "sme_LLStatsSetReq Failed", __func__);
        return -EINVAL;
    }

    pAdapter->isLinkLayerStatsSet = 1;

    EXIT();
    return 0;
}
static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
                                          struct wireless_dev *wdev,
                                          const void *data,
                                          int data_len)
{
    int ret = 0;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
    vos_ssr_unprotect(__func__);

    return ret;
}

const struct
nla_policy
qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
{
    /* Unsigned 32bit value provided by the caller issuing the GET stats
     * command. When reporting
     * the stats results, the driver uses the same value to indicate
     * which GET request the results
     * correspond to.
     */
    [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },

    /* Unsigned 32bit value . bit mask to identify what statistics are
         requested for retrieval */
    [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
};

static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
                                            struct wireless_dev *wdev,
                                            const void *data,
                                            int data_len)
{
    unsigned long rc;
    struct hdd_ll_stats_context *context;
    hdd_context_t *pHddCtx = wiphy_priv(wiphy);
    struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
    tSirLLStatsGetReq linkLayerStatsGetReq;
    struct net_device *dev = wdev->netdev;
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    int status;

    ENTER();

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return -EINVAL ;
    }

    if (NULL == pAdapter)
    {
        hddLog(VOS_TRACE_LEVEL_FATAL,
               "%s: HDD adapter is Null", __func__);
        return -ENODEV;
    }

    if (pHddStaCtx == NULL)
    {
        hddLog(VOS_TRACE_LEVEL_FATAL,
               "%s: HddStaCtx is Null", __func__);
        return -ENODEV;
    }

    /* check the LLStats Capability */
    if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
         (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("Link Layer Statistics not supported by Firmware"));
        return -EINVAL;
    }


    if (!pAdapter->isLinkLayerStatsSet)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               "%s: isLinkLayerStatsSet : %d",
               __func__, pAdapter->isLinkLayerStatsSet);
        return -EINVAL;
    }

    if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  "%s: Roaming in progress, so unable to proceed this request", __func__);
        return -EBUSY;
    }

    if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
            (struct nlattr *)data,
            data_len, qca_wlan_vendor_ll_get_policy))
    {
       hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
       return -EINVAL;
    }

    if (!tb_vendor
            [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
    {
       hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
       return -EINVAL;
    }

    if (!tb_vendor
            [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
    {
       hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
       return -EINVAL;
    }


    linkLayerStatsGetReq.reqId =
        nla_get_u32( tb_vendor[
            QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
    linkLayerStatsGetReq.paramIdMask =
        nla_get_u32( tb_vendor[
            QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);

    vos_mem_copy(linkLayerStatsGetReq.macAddr,
               pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));

    hddLog(VOS_TRACE_LEVEL_INFO,
           "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
           linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
           linkLayerStatsGetReq.paramIdMask);

    spin_lock(&hdd_context_lock);
    context = &pHddCtx->ll_stats_context;
    context->request_id = linkLayerStatsGetReq.reqId;
    context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
    INIT_COMPLETION(context->response_event);
    spin_unlock(&hdd_context_lock);

    if (eHAL_STATUS_SUCCESS  != sme_LLStatsGetReq( pHddCtx->hHal,
                                                &linkLayerStatsGetReq))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
               "sme_LLStatsGetReq Failed", __func__);
        return -EINVAL;
    }

    rc = wait_for_completion_timeout(&context->response_event,
            msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
    if (!rc)
    {
        hddLog(LOGE,
            FL("Target response timed out request id %d request bitmap 0x%x"),
            context->request_id, context->request_bitmap);
        return -ETIMEDOUT;
    }

    EXIT();
    return 0;
}

static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
                                          struct wireless_dev *wdev,
                                          const void *data,
                                          int data_len)
{
    int ret = 0;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
    vos_ssr_unprotect(__func__);

    return ret;
}

const struct
nla_policy
qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
{
    [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
    [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
};

static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
                                              struct wireless_dev *wdev,
                                              const void *data,
                                              int data_len)
{
    hdd_context_t *pHddCtx = wiphy_priv(wiphy);
    struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
    tSirLLStatsClearReq linkLayerStatsClearReq;
    struct net_device *dev = wdev->netdev;
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    u32 statsClearReqMask;
    u8 stopReq;
    int status;

    ENTER();

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return -EINVAL;
    }

    if (NULL == pAdapter)
    {
        hddLog(VOS_TRACE_LEVEL_FATAL,
                   "%s: HDD adapter is Null", __func__);
        return -ENODEV;
    }
    /* check the LLStats Capability */
    if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
         (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("Enable LLStats Capability"));
        return -EINVAL;
    }

    if (!pAdapter->isLinkLayerStatsSet)
    {
        hddLog(VOS_TRACE_LEVEL_FATAL,
                   "%s: isLinkLayerStatsSet : %d",
                   __func__, pAdapter->isLinkLayerStatsSet);
        return -EINVAL;
    }

    if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
            (struct nlattr *)data,
            data_len, qca_wlan_vendor_ll_clr_policy))
    {
       hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
       return -EINVAL;
    }

    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||

        !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
    {
       hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
       return -EINVAL;

    }


    statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
        nla_get_u32(
            tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);

    stopReq = linkLayerStatsClearReq.stopReq =
        nla_get_u8(
            tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);

    // Shall take the request Id if the Upper layers pass. 1 For now.
    linkLayerStatsClearReq.reqId = 1;

    vos_mem_copy(linkLayerStatsClearReq.macAddr,
               pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));

    hddLog(VOS_TRACE_LEVEL_INFO,
            "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
            "statsClearReqMask = 0x%X, stopReq  = %d",
            linkLayerStatsClearReq.reqId,
            linkLayerStatsClearReq.macAddr,
            linkLayerStatsClearReq.statsClearReqMask,
            linkLayerStatsClearReq.stopReq);

    if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
                                                     &linkLayerStatsClearReq))
    {
        struct sk_buff *temp_skbuff;
        hdd_station_ctx_t *pHddStaCtx;

        pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
        if (VOS_STATUS_SUCCESS !=
           WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
           pHddStaCtx->conn_info.staId[0], statsClearReqMask))
        {
            hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
                    "WLANTL_ClearInterfaceStats Failed", __func__);
            return -EINVAL;
        }
        if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
                (statsClearReqMask & WIFI_STATS_IFACE)) {
            pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
            pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
            pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
            pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
        }

        temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
                                2 * sizeof(u32) +
                            NLMSG_HDRLEN);

        if (temp_skbuff != NULL)
        {

            if (nla_put_u32(temp_skbuff,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
                    statsClearReqMask) ||
                 nla_put_u32(temp_skbuff,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
                    stopReq))
            {
                 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
                 kfree_skb(temp_skbuff);
                 return -EINVAL;
            }
            /* If the ask is to stop the stats collection as part of clear
             * (stopReq = 1) , ensure that no further requests of get
             * go to the firmware by having isLinkLayerStatsSet set to 0.
             * However it the stopReq as part of the clear request is 0 ,
             * the request to get the statistics are honoured as in this
             * case the firmware is just asked to clear the statistics.
             */
            if (linkLayerStatsClearReq.stopReq == 1)
                pAdapter->isLinkLayerStatsSet = 0;
            return cfg80211_vendor_cmd_reply(temp_skbuff);
        }
        return -ENOMEM;
    }

    EXIT();
    return -EINVAL;
}
static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
                                            struct wireless_dev *wdev,
                                            const void *data,
                                            int data_len)
{
   int ret = 0;

   vos_ssr_protect(__func__);
   ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
   vos_ssr_unprotect(__func__);

   return ret;


}
#endif /* WLAN_FEATURE_LINK_LAYER_STATS */

#ifdef WLAN_FEATURE_EXTSCAN
static const struct nla_policy
wlan_hdd_extscan_config_policy
            [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
{
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
                                                        { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
                                                        { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
                                                        { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
                                                            { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },

    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
                                                            { .type = NLA_U8 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
                                                            { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
                                                            { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
                                                            { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
                                                            { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
                                                            { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
                                                            { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
                                                            { .type = NLA_U8 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
                                                            { .type = NLA_U8 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
                                                            { .type = NLA_U8 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
                                                             { .type = NLA_U8 },

    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
                                                            { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
        .type = NLA_UNSPEC,
        .len = HDD_MAC_ADDR_LEN},
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
                                                            { .type = NLA_S32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
                                                            { .type = NLA_S32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
                                                            { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
                                                            { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
                                                            { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
                                                          { .type = NLA_BINARY,
                                           .len = IEEE80211_MAX_SSID_LEN + 1 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
                                                           { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
                                                           { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
                                                            { .type = NLA_U8 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
                                                           { .type = NLA_S32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
                                                           { .type = NLA_S32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
                                                           { .type = NLA_U32 },
};

/**
 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
 * @ctx: hdd global context
 * @data: capabilities data
 *
 * Return: none
 */
static void
wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
{
    struct hdd_ext_scan_context *context;
    hdd_context_t *pHddCtx  = (hdd_context_t *)ctx;
    tSirEXTScanCapabilitiesEvent *data =
                    (tSirEXTScanCapabilitiesEvent *) pMsg;

    ENTER();

    if (wlan_hdd_validate_context(pHddCtx))
    {
        return;
    }

    if (!pMsg)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
        return;
    }

    vos_spin_lock_acquire(&hdd_context_lock);

    context = &pHddCtx->ext_scan_context;
    /* validate response received from target*/
    if (context->request_id != data->requestId)
    {
        vos_spin_lock_release(&hdd_context_lock);
        hddLog(LOGE,
          FL("Target response id did not match: request_id %d resposne_id %d"),
          context->request_id, data->requestId);
        return;
    }
    else
    {
        context->capability_response = *data;
        complete(&context->response_event);
    }

    vos_spin_lock_release(&hdd_context_lock);

    return;
}

/*
 * define short names for the global vendor params
 * used by wlan_hdd_send_ext_scan_capability()
 */
#define PARAM_REQUEST_ID \
    QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
#define PARAM_STATUS \
    QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
#define MAX_SCAN_CACHE_SIZE \
    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
#define MAX_SCAN_BUCKETS \
    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
#define MAX_AP_CACHE_PER_SCAN \
    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
#define MAX_RSSI_SAMPLE_SIZE \
    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
#define MAX_SCAN_RPT_THRHOLD \
    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
#define MAX_HOTLIST_BSSIDS \
    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
#define MAX_BSSID_HISTORY_ENTRIES \
    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
#define MAX_HOTLIST_SSIDS \
    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS

static int wlan_hdd_send_ext_scan_capability(void *ctx)
{
    hdd_context_t *pHddCtx  = (hdd_context_t *)ctx;
    struct sk_buff *skb     = NULL;
    int ret;
    tSirEXTScanCapabilitiesEvent *data;
    tANI_U32 nl_buf_len;

    ret = wlan_hdd_validate_context(pHddCtx);
    if (0 != ret)
    {
        return ret;
    }

    data = &(pHddCtx->ext_scan_context.capability_response);

    nl_buf_len = NLMSG_HDRLEN;
    nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
    (sizeof(data->status) + NLA_HDRLEN) +
    (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
    (sizeof(data->scanBuckets) + NLA_HDRLEN) +
    (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
    (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
    (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
    (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
    (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
    (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);

    skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);

    if (!skb)
    {
        hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
        return -ENOMEM;
    }

    hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
    hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
           data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
    hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
           data->maxRssiSampleSize, data->maxScanReportingThreshold);
    hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
           "max_hotlist_ssids (%u)", data->maxHotlistAPs,
           data->maxBsidHistoryEntries, data->maxHotlistSSIDs);

    if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
        nla_put_u32(skb, PARAM_STATUS, data->status) ||
        nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
        nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
        nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
            data->maxApPerScan) ||
        nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
            data->maxRssiSampleSize) ||
        nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
            data->maxScanReportingThreshold) ||
        nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
        nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
            data->maxBsidHistoryEntries) ||
        nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
        nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
    {
        hddLog(LOGE, FL("nla put fail"));
        goto nla_put_failure;
    }

    cfg80211_vendor_cmd_reply(skb);
    return 0;

nla_put_failure:
    kfree_skb(skb);
    return -EINVAL;;
}

/*
 * done with short names for the global vendor params
 * used by wlan_hdd_send_ext_scan_capability()
 */
#undef PARAM_REQUEST_ID
#undef PARAM_STATUS
#undef MAX_SCAN_CACHE_SIZE
#undef MAX_SCAN_BUCKETS
#undef MAX_AP_CACHE_PER_SCAN
#undef MAX_RSSI_SAMPLE_SIZE
#undef MAX_SCAN_RPT_THRHOLD
#undef MAX_HOTLIST_BSSIDS
#undef MAX_BSSID_HISTORY_ENTRIES
#undef MAX_HOTLIST_SSIDS

static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
{
    tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
    hdd_context_t *pHddCtx         = (hdd_context_t *)ctx;
    tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
    struct hdd_ext_scan_context *context;

    ENTER();

    if (wlan_hdd_validate_context(pHddCtx))
        return;

    if (!pMsg)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
        return;
    }

    hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
    hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);

    context = &pHddCtx->ext_scan_context;
    spin_lock(&hdd_context_lock);
    if (context->request_id == pData->requestId) {
        context->response_status = pData->status ? -EINVAL : 0;
        complete(&context->response_event);
    }
    spin_unlock(&hdd_context_lock);

    /*
     * Store the Request ID for comparing with the requestID obtained
     * in other requests.HDD shall return a failure is the extscan_stop
     * request is issued with a different requestId as that of the
     * extscan_start request. Also, This requestId shall be used while
     * indicating the full scan results to the upper layers.
     * The requestId is stored with the assumption that the firmware
     * shall return the ext scan start request's requestId in ext scan
     * start response.
     */
    if (pData->status == 0)
        pMac->sme.extScanStartReqId = pData->requestId;

    EXIT();
    return;
}


static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
{
    tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
    hdd_context_t *pHddCtx        = (hdd_context_t *)ctx;
    struct hdd_ext_scan_context *context;

    ENTER();

    if (wlan_hdd_validate_context(pHddCtx)){
        return;
    }

    if (!pMsg)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
        return;
    }

    hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
                                                        pData->status);

    context = &pHddCtx->ext_scan_context;
    spin_lock(&hdd_context_lock);
    if (context->request_id == pData->requestId) {
        context->response_status = pData->status ? -EINVAL : 0;
        complete(&context->response_event);
    }
    spin_unlock(&hdd_context_lock);

    EXIT();
    return;
}

static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
                                                        void *pMsg)
{
    hdd_context_t *pHddCtx    = (hdd_context_t *)ctx;
    tpSirEXTScanSetBssidHotListRspParams pData =
                    (tpSirEXTScanSetBssidHotListRspParams) pMsg;
    struct hdd_ext_scan_context *context;

    ENTER();

    if (wlan_hdd_validate_context(pHddCtx)){
        return;
    }

    if (!pMsg)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
        return;
    }

    hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
                                                        pData->status);

    context = &pHddCtx->ext_scan_context;
    spin_lock(&hdd_context_lock);
    if (context->request_id == pData->requestId) {
        context->response_status = pData->status ? -EINVAL : 0;
        complete(&context->response_event);
    }
    spin_unlock(&hdd_context_lock);

    EXIT();
    return;
}

static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
                                                          void *pMsg)
{
    hdd_context_t *pHddCtx  = (hdd_context_t *)ctx;
    tpSirEXTScanResetBssidHotlistRspParams pData =
                    (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
    struct hdd_ext_scan_context *context;

    ENTER();

    if (wlan_hdd_validate_context(pHddCtx)) {
        return;
    }
    if (!pMsg)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
        return;
    }

    hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
                                                        pData->status);

    context = &pHddCtx->ext_scan_context;
    spin_lock(&hdd_context_lock);
    if (context->request_id == pData->requestId) {
        context->response_status = pData->status ? -EINVAL : 0;
        complete(&context->response_event);
    }
    spin_unlock(&hdd_context_lock);

    EXIT();
    return;
}

static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
                                                       void *pMsg)
{
    hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
    struct sk_buff *skb    = NULL;
    tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
    tANI_S32 totalResults;
    tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
    tpSirWifiScanResult pSirWifiScanResult, head_ptr;
    struct hdd_ext_scan_context *context;
    bool ignore_cached_results = false;
    tExtscanCachedScanResult *result;
    struct nlattr *nla_results;
    tANI_U16 ieLength= 0;
    tANI_U8  *ie = NULL;

    ENTER();

    if (wlan_hdd_validate_context(pHddCtx))
        return;

    if (!pMsg)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
        return;
    }

    spin_lock(&hdd_context_lock);
    context = &pHddCtx->ext_scan_context;
    ignore_cached_results = context->ignore_cached_results;
    spin_unlock(&hdd_context_lock);

    if (ignore_cached_results) {
        hddLog(LOGE,
               FL("Ignore the cached results received after timeout"));
        return;
    }

    hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
           pData->requestId, pData->moreData, pData->scanResultSize);

    result = (tExtscanCachedScanResult *)&(pData->result);

    for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
                                                   scan_id_index++) {
         result+= scan_id_index;

         totalResults = result->num_results;
         hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
                result->scan_id, result->flags, totalResults);
         i = 0;

        do{
            resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
                    EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
            totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;

            skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
                                     EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);

            if (!skb) {
                hddLog(VOS_TRACE_LEVEL_ERROR,
                        FL("cfg80211_vendor_event_alloc failed"));
                return;
            }

            hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);

            if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
                        pData->requestId) ||
                    nla_put_u32(skb,
                        QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
                        resultsPerEvent)) {
                hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
                goto fail;
            }
            if (nla_put_u8(skb,
                        QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
                        pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
            {
                hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
                goto fail;
            }

            if (nla_put_u32(skb,
                QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
                result->scan_id)) {
                hddLog(LOGE, FL("put fail"));
                goto fail;
            }

            nla_results = nla_nest_start(skb,
                          QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
            if (!nla_results)
                goto fail;

            if (resultsPerEvent) {
                struct nlattr *aps;
                struct nlattr *nla_result;

                nla_result = nla_nest_start(skb, scan_id_index);
                if(!nla_result)
                   goto fail;

                if (nla_put_u32(skb,
                    QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
                    result->scan_id) ||
                    nla_put_u32(skb,
                    QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
                    result->flags) ||
                    nla_put_u32(skb,
                    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
                    totalResults)) {
                    hddLog(LOGE, FL("put fail"));
                    goto fail;
                }

                aps = nla_nest_start(skb,
                                QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
                if (!aps)
                {
                    hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
                    goto fail;
                }

                head_ptr = (tpSirWifiScanResult) &(result->ap);

                for (j = 0; j < resultsPerEvent; j++, i++) {
                    struct nlattr *ap;
                    pSirWifiScanResult = head_ptr + i;

                    /*
                     * Firmware returns timestamp from extscan_start till
                     * BSSID was cached (in micro seconds). Add this with
                     * time gap between system boot up to extscan_start
                     * to derive the time since boot when the
                     * BSSID was cached.
                     */
                    pSirWifiScanResult->ts +=
                                     pHddCtx->extscan_start_time_since_boot;
                    hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
                            "Ssid (%s)"
                            "Bssid: %pM "
                            "Channel (%u)"
                            "Rssi (%d)"
                            "RTT (%u)"
                            "RTT_SD (%u)"
                            "Beacon Period %u"
                            "Capability 0x%x "
                            "Ie length %d",
                            i,
                            pSirWifiScanResult->ts,
                            pSirWifiScanResult->ssid,
                            pSirWifiScanResult->bssid,
                            pSirWifiScanResult->channel,
                            pSirWifiScanResult->rssi,
                            pSirWifiScanResult->rtt,
                            pSirWifiScanResult->rtt_sd,
                            pSirWifiScanResult->beaconPeriod,
                            pSirWifiScanResult->capability,
                            ieLength);

                    ap = nla_nest_start(skb, j + 1);
                    if (!ap)
                    {
                        hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
                        goto fail;
                    }

                    if (hdd_wlan_nla_put_u64(skb,
                        QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
                        pSirWifiScanResult->ts) )
                    {
                        hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
                        goto fail;
                    }
                    if (nla_put(skb,
                             QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
                             sizeof(pSirWifiScanResult->ssid),
                            pSirWifiScanResult->ssid) )
                    {
                        hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
                        goto fail;
                    }
                    if (nla_put(skb,
                            QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
                            sizeof(pSirWifiScanResult->bssid),
                            pSirWifiScanResult->bssid) )
                    {
                        hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
                        goto fail;
                    }
                    if (nla_put_u32(skb,
                           QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
                            pSirWifiScanResult->channel) )
                    {
                        hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
                        goto fail;
                    }
                    if (nla_put_s32(skb,
                            QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
                            pSirWifiScanResult->rssi) )
                    {
                        hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
                        goto fail;
                    }
                    if (nla_put_u32(skb,
                              QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
                              pSirWifiScanResult->rtt) )
                    {
                        hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
                        goto fail;
                    }
                    if (nla_put_u32(skb,
                            QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
                            pSirWifiScanResult->rtt_sd))
                    {
                        hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
                        goto fail;
                    }
                    if (nla_put_u32(skb,
                            QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
                            pSirWifiScanResult->beaconPeriod))
                    {
                        hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
                        goto fail;
                    }
                    if (nla_put_u32(skb,
                            QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
                            pSirWifiScanResult->capability))
                    {
                        hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
                        goto fail;
                    }
                    if (nla_put_u32(skb,
                            QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
                            ieLength))
                    {
                        hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
                        goto fail;
                    }

                    if (ieLength)
                        if (nla_put(skb,
                            QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
                            ieLength, ie)) {
                            hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
                            goto fail;
                        }

                    nla_nest_end(skb, ap);
                }
                nla_nest_end(skb, aps);
                nla_nest_end(skb, nla_result);
            }

         nla_nest_end(skb, nla_results);

         cfg80211_vendor_cmd_reply(skb);

        } while (totalResults > 0);
    }

    if (!pData->moreData) {
        spin_lock(&hdd_context_lock);
        context->response_status = 0;
        complete(&context->response_event);
        spin_unlock(&hdd_context_lock);
    }

    EXIT();
    return;
fail:
    kfree_skb(skb);
    return;
}

static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
                                                      void *pMsg)
{
    tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
    hdd_context_t *pHddCtx         = (hdd_context_t *)ctx;
    struct sk_buff *skb            = NULL;
    tANI_U32 i, index;

    ENTER();

    if (wlan_hdd_validate_context(pHddCtx)) {
        hddLog(LOGE,
               FL("HDD context is not valid or response"));
        return;
    }
    if (!pMsg)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
        return;
    }

    if (pData->bss_found)
        index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
    else
        index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;

    skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
                      NULL,
#endif
                      EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
                      index, GFP_KERNEL);

    if (!skb) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                  FL("cfg80211_vendor_event_alloc failed"));
        return;
    }

    hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
    hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
    hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
    hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);

    for (i = 0; i < pData->numHotlistBss; i++) {
        hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
                              "Ssid (%s) "
                              "Bssid (" MAC_ADDRESS_STR ") "
                              "Channel (%u) "
                              "Rssi (%d) "
                              "RTT (%u) "
                              "RTT_SD (%u) ",
                              i,
                              pData->bssHotlist[i].ts,
                              pData->bssHotlist[i].ssid,
                              MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
                              pData->bssHotlist[i].channel,
                              pData->bssHotlist[i].rssi,
                              pData->bssHotlist[i].rtt,
                              pData->bssHotlist[i].rtt_sd);
    }

    if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
                      pData->requestId) ||
        nla_put_u32(skb,
                    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
                      pData->numHotlistBss)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
        goto fail;
    }
    if (pData->numHotlistBss) {
        struct nlattr *aps;

        aps = nla_nest_start(skb,
                   QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
        if (!aps)
            goto fail;

        for (i = 0; i < pData->numHotlistBss; i++) {
            struct nlattr *ap;

            ap = nla_nest_start(skb, i + 1);
            if (!ap)
                goto fail;

            if (hdd_wlan_nla_put_u64(skb,
                   QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
                    pData->bssHotlist[i].ts) ||
                nla_put(skb,
                     QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
                     sizeof(pData->bssHotlist[i].ssid),
                     pData->bssHotlist[i].ssid) ||
                nla_put(skb,
                     QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
                     sizeof(pData->bssHotlist[i].bssid),
                     pData->bssHotlist[i].bssid) ||
                nla_put_u32(skb,
                     QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
                     pData->bssHotlist[i].channel) ||
                nla_put_s32(skb,
                     QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
                     pData->bssHotlist[i].rssi) ||
                nla_put_u32(skb,
                     QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
                     pData->bssHotlist[i].rtt) ||
                nla_put_u32(skb,
                     QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
                     pData->bssHotlist[i].rtt_sd))
                goto fail;

              nla_nest_end(skb, ap);
        }
        nla_nest_end(skb, aps);

        if (nla_put_u8(skb,
                    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
                      pData->moreData))
            goto fail;
    }

    cfg80211_vendor_event(skb, GFP_KERNEL);
    EXIT();
    return;

fail:
    kfree_skb(skb);
    return;

}

static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
                                                           void *pMsg)
{
    struct sk_buff *skb;
    hdd_context_t *pHddCtx  = (hdd_context_t *)ctx;
    tpSirWifiFullScanResultEvent pData =
        (tpSirWifiFullScanResultEvent) (pMsg);

    ENTER();

    if (wlan_hdd_validate_context(pHddCtx)) {
        hddLog(LOGE,
               FL("HDD context is not valid or response"));
        return;
    }
    if (!pMsg)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
        return;
    }

    /*
         * If the full scan result including IE data exceeds NL 4K size
         * limitation, drop that beacon/probe rsp frame.
         */
    if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
        hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
        return;
    }

    skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
            NULL,
#endif
            EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
            QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
            GFP_KERNEL);

    if (!skb) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                FL("cfg80211_vendor_event_alloc failed"));
        return;
    }

    hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
    hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
    hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
                "Ssid (%s)"
                "Bssid (" MAC_ADDRESS_STR ")"
                "Channel (%u)"
                "Rssi (%d)"
                "RTT (%u)"
                "RTT_SD (%u)"
                "Bcn Period %d"
                "Capability 0x%X "),
            pData->ap.ts,
            pData->ap.ssid,
            MAC_ADDR_ARRAY(pData->ap.bssid),
            pData->ap.channel,
            pData->ap.rssi,
            pData->ap.rtt,
            pData->ap.rtt_sd,
            pData->ap.beaconPeriod,
            pData->ap.capability);

    hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
    if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
                pData->requestId) ||
        hdd_wlan_nla_put_u64(skb,
            QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
            pData->ap.ts) ||
        nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
            sizeof(pData->ap.ssid),
            pData->ap.ssid) ||
        nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
            WNI_CFG_BSSID_LEN,
            pData->ap.bssid) ||
        nla_put_u32(skb,
            QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
            pData->ap.channel) ||
        nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
            pData->ap.rssi) ||
        nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
            pData->ap.rtt) ||
        nla_put_u32(skb,
            QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
            pData->ap.rtt_sd) ||
        nla_put_u16(skb,
                QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
            pData->ap.beaconPeriod) ||
        nla_put_u16(skb,
                QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
            pData->ap.capability) ||
        nla_put_u32(skb,
                QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
            pData->ieLength) ||
        nla_put_u8(skb,
                QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
            pData->moreData))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
        goto nla_put_failure;
    }

    if (pData->ieLength) {
        if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
                    pData->ieLength,
                    pData->ie))
        {
            hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
            goto nla_put_failure;
        }
    }

    cfg80211_vendor_event(skb, GFP_KERNEL);
    EXIT();
    return;

nla_put_failure:
    kfree_skb(skb);
    return;
}

static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
                                                             void *pMsg)
{
    hdd_context_t *pHddCtx  = (hdd_context_t *)ctx;
    struct sk_buff *skb     = NULL;
    tpSirEXTScanResultsAvailableIndParams pData =
                    (tpSirEXTScanResultsAvailableIndParams) pMsg;

    ENTER();

    if (wlan_hdd_validate_context(pHddCtx)){
        hddLog(LOGE,
               FL("HDD context is not valid or response"));
        return;
    }
    if (!pMsg)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
        return;
    }

    skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
                NULL,
#endif
                EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
                QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
                GFP_KERNEL);

    if (!skb) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                  FL("cfg80211_vendor_event_alloc failed"));
        return;
    }

    hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
    hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
                                  pData->numResultsAvailable);
    if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
                    pData->requestId) ||
        nla_put_u32(skb,
                    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
                    pData->numResultsAvailable)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
        goto nla_put_failure;
    }

    cfg80211_vendor_event(skb, GFP_KERNEL);
    EXIT();
    return;

nla_put_failure:
    kfree_skb(skb);
    return;
}

static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
{
    hdd_context_t *pHddCtx  = (hdd_context_t *)ctx;
    struct sk_buff *skb     = NULL;
    tpSirEXTScanProgressIndParams pData =
                                   (tpSirEXTScanProgressIndParams) pMsg;

    ENTER();

    if (wlan_hdd_validate_context(pHddCtx)){
        hddLog(LOGE,
               FL("HDD context is not valid or response"));
        return;
    }
    if (!pMsg)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
        return;
    }

    skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
                            NULL,
#endif
                            EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
                            QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
                            GFP_KERNEL);

    if (!skb) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                  FL("cfg80211_vendor_event_alloc failed"));
        return;
    }
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
    hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
            pData->extScanEventType);
    hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
            pData->status);

    if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
                   pData->extScanEventType) ||
        nla_put_u32(skb,
                    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
                    pData->requestId) ||
        nla_put_u32(skb,
                    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
                    pData->status)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
        goto nla_put_failure;
    }

    cfg80211_vendor_event(skb, GFP_KERNEL);
    EXIT();
    return;

nla_put_failure:
    kfree_skb(skb);
    return;
}

void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
                                      void *pMsg)
{
    hdd_context_t *pHddCtx = (hdd_context_t *)ctx;

    ENTER();

    if (wlan_hdd_validate_context(pHddCtx)) {
        return;
    }

    hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);


    switch(evType) {
    case SIR_HAL_EXTSCAN_START_RSP:
            wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
        break;

    case SIR_HAL_EXTSCAN_STOP_RSP:
            wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
        break;
    case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
        /* There is no need to send this response to upper layer
           Just log the message */
        hddLog(VOS_TRACE_LEVEL_INFO,
                FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
        break;
    case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
        wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
        break;

    case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
        wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
        break;

    case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
        wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
        break;
    case SIR_HAL_EXTSCAN_PROGRESS_IND:
        wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
        break;
    case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
        wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
        break;
    case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
        wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
        break;
    case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
        wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
        break;
    case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
        wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
        break;
    default:
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
        break;
    }
    EXIT();
}

static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
                                                        struct wireless_dev *wdev,
                                                        const void *data, int dataLen)
{
    tSirGetEXTScanCapabilitiesReqParams reqMsg;
    struct net_device *dev                     = wdev->netdev;
    hdd_adapter_t *pAdapter                    = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx                     = wiphy_priv(wiphy);
    struct nlattr
        *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
    eHalStatus status;
    struct hdd_ext_scan_context *context;
    unsigned long rc;
    int ret;

    ENTER();

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return -EINVAL;
    }
    /* check the EXTScan Capability */
    if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
         (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
         (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("EXTScan not enabled/supported by Firmware"));
        return -EINVAL;
    }

    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
                    data, dataLen,
                    wlan_hdd_extscan_config_policy)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
        return -EINVAL;
    }

    /* Parse and fetch request Id */
    if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
        return -EINVAL;
    }

    reqMsg.requestId = nla_get_u32(
              tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);

    reqMsg.sessionId = pAdapter->sessionId;
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);

    vos_spin_lock_acquire(&hdd_context_lock);
    context = &pHddCtx->ext_scan_context;
    context->request_id = reqMsg.requestId;
    INIT_COMPLETION(context->response_event);
    vos_spin_lock_release(&hdd_context_lock);

    status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
    if (!HAL_STATUS_SUCCESS(status)) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
        return -EINVAL;
    }

    rc = wait_for_completion_timeout(&context->response_event,
             msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
    if (!rc) {
        hddLog(LOGE, FL("Target response timed out"));
        return -ETIMEDOUT;
    }

    ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
    if (ret)
        hddLog(LOGE, FL("Failed to send ext scan capability to user space"));

    return ret;

    EXIT();
    return 0;
}

static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
                                                      struct wireless_dev *wdev,
                                                  const void *data, int dataLen)
{
   int ret = 0;

   vos_ssr_protect(__func__);
   ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
   vos_ssr_unprotect(__func__);

   return ret;
}

static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
                                                struct wireless_dev *wdev,
                                                const void *data, int dataLen)
{
    tSirEXTScanGetCachedResultsReqParams reqMsg;
    struct net_device *dev                      = wdev->netdev;
    hdd_adapter_t *pAdapter                     = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx                      = wiphy_priv(wiphy);
    struct nlattr
            *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
    eHalStatus status;
    struct hdd_ext_scan_context *context;
    unsigned long rc;
    int retval;

    ENTER();

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

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return -EINVAL;
    }
    /* check the EXTScan Capability */
    if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
         (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
         (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("EXTScan not enabled/supported by Firmware"));
        return -EINVAL;
    }

    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
                    data, dataLen,
                    wlan_hdd_extscan_config_policy)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
        return -EINVAL;
    }
    /* Parse and fetch request Id */
    if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
        return -EINVAL;
    }

    reqMsg.requestId = nla_get_u32(
              tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);

    hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);

    reqMsg.sessionId = pAdapter->sessionId;
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);

    /* Parse and fetch flush parameter */
    if (!tb
      [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
        goto failed;
    }
    reqMsg.flush = nla_get_u8(
    tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);

    hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);

    spin_lock(&hdd_context_lock);
    context = &pHddCtx->ext_scan_context;
    context->request_id = reqMsg.requestId;
    context->ignore_cached_results = false;
    INIT_COMPLETION(context->response_event);
    spin_unlock(&hdd_context_lock);

    status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
    if (!HAL_STATUS_SUCCESS(status)) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("sme_getCachedResults failed(err=%d)"), status);
        return -EINVAL;
    }

    rc = wait_for_completion_timeout(&context->response_event,
            msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
    if (!rc) {
        hddLog(LOGE, FL("Target response timed out"));
        retval = -ETIMEDOUT;
        spin_lock(&hdd_context_lock);
        context->ignore_cached_results = true;
        spin_unlock(&hdd_context_lock);
    } else {
        spin_lock(&hdd_context_lock);
        retval = context->response_status;
        spin_unlock(&hdd_context_lock);
    }

    EXIT();
    return retval;

failed:
    return -EINVAL;
}
static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
                                                struct wireless_dev *wdev,
                                                const void *data, int dataLen)
{
   int ret = 0;

   vos_ssr_protect(__func__);
   ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
   vos_ssr_unprotect(__func__);

   return ret;
}

static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
                                        struct wireless_dev *wdev,
                                        const void *data, int dataLen)
{
    tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
    struct net_device *dev                     = wdev->netdev;
    hdd_adapter_t *pAdapter                    = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx                     = wiphy_priv(wiphy);
    struct nlattr
            *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
    struct nlattr
            *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
    struct nlattr *apTh;
    eHalStatus status;
    tANI_U8 i = 0;
    int rem;
    struct hdd_ext_scan_context *context;
    tANI_U32 request_id;
    unsigned long rc;
    int retval;

    ENTER();

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

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return -EINVAL;
    }
    /* check the EXTScan Capability */
    if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
         (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
         (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("EXTScan not enabled/supported by Firmware"));
        return -EINVAL;
    }

    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
                    data, dataLen,
                    wlan_hdd_extscan_config_policy)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
        return -EINVAL;
    }

    /* Parse and fetch request Id */
    if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
        return -EINVAL;
    }
    pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
                                     vos_mem_malloc(sizeof(*pReqMsg));
    if (!pReqMsg) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
        return -ENOMEM;
    }


    pReqMsg->requestId = nla_get_u32(
              tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);

    /* Parse and fetch number of APs */
    if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
        goto fail;
    }

    /* Parse and fetch lost ap sample size */
    if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
        hddLog(LOGE, FL("attr lost ap sample size failed"));
        goto fail;
    }

    pReqMsg->lostBssidSampleSize = nla_get_u32(
              tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
    hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);

    pReqMsg->sessionId = pAdapter->sessionId;
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);

    pReqMsg->numBssid = nla_get_u32(
              tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
    if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
        hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
               pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
        goto fail;
    }
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);

    nla_for_each_nested(apTh,
                tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
        if (i == pReqMsg->numBssid) {
            hddLog(LOGW, FL("Ignoring excess AP"));
            break;
        }

        if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
                nla_data(apTh), nla_len(apTh),
                NULL)) {
            hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
            goto fail;
        }

        /* Parse and fetch MAC address */
        if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
            hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
            goto fail;
        }
        memcpy(pReqMsg->ap[i].bssid, nla_data(
                tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
                sizeof(tSirMacAddr));
        hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);

        /* Parse and fetch low RSSI */
        if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
            hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
            goto fail;
        }
        pReqMsg->ap[i].low = nla_get_s32(
             tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
        hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);

        /* Parse and fetch high RSSI */
        if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
            hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
            goto fail;
        }
        pReqMsg->ap[i].high = nla_get_s32(
            tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
        hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
                                         pReqMsg->ap[i].high);
        i++;
    }

    if (i < pReqMsg->numBssid) {
        hddLog(LOGW, FL("Number of AP %u less than expected %u"),
               i, pReqMsg->numBssid);
        pReqMsg->numBssid = i;
    }

    context = &pHddCtx->ext_scan_context;
    spin_lock(&hdd_context_lock);
    INIT_COMPLETION(context->response_event);
    context->request_id = request_id = pReqMsg->requestId;
    spin_unlock(&hdd_context_lock);

    status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
    if (!HAL_STATUS_SUCCESS(status)) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                  FL("sme_SetBssHotlist failed(err=%d)"), status);
        vos_mem_free(pReqMsg);
        return -EINVAL;
    }

    /* request was sent -- wait for the response */
    rc = wait_for_completion_timeout(&context->response_event,
                                     msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));

    if (!rc) {
       hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
       retval = -ETIMEDOUT;
    } else {
       spin_lock(&hdd_context_lock);
       if (context->request_id == request_id)
          retval = context->response_status;
       else
          retval = -EINVAL;
       spin_unlock(&hdd_context_lock);
    }

    vos_mem_free(pReqMsg);
    EXIT();
    return retval;

fail:
    vos_mem_free(pReqMsg);
    return -EINVAL;
}

static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
                                        struct wireless_dev *wdev,
                                        const void *data, int dataLen)
{
   int ret = 0;

   vos_ssr_protect(__func__);
   ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
                                                       dataLen);
   vos_ssr_unprotect(__func__);

   return ret;
}

static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
                                        struct wireless_dev *wdev,
                                        const void *data, int dataLen)
{
    hdd_context_t *pHddCtx = wiphy_priv(wiphy);
    struct net_device *dev = wdev->netdev;
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
    uint8_t num_channels  = 0;
    uint8_t num_chan_new  = 0;
    uint8_t buf[256] = {0};
    struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
    tANI_U32 requestId, maxChannels;
    tWifiBand wifiBand;
    eHalStatus status;
    struct sk_buff *replySkb;
    tANI_U8 i,j,k;
    int ret,len = 0;;

    ENTER();

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return -EINVAL;
    }

    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
                  data, dataLen,
                  wlan_hdd_extscan_config_policy)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
        return -EINVAL;
    }

    /* Parse and fetch request Id */
    if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
        return -EINVAL;
    }
    requestId = nla_get_u32(
              tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);

    /* Parse and fetch wifi band */
    if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
        return -EINVAL;
    }
    wifiBand = nla_get_u32(
     tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);

    /* Parse and fetch max channels */
    if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
    {
        hddLog(LOGE, FL("attr max channels failed"));
        return -EINVAL;
    }
    maxChannels = nla_get_u32(
     tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);

    status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
                                        wifiBand, chan_list,
                                         &num_channels);
    if (eHAL_STATUS_SUCCESS != status) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
           FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
        return -EINVAL;
    }

    num_channels = VOS_MIN(num_channels, maxChannels);
    num_chan_new = num_channels;
    /* remove the indoor only channels if iface is SAP */
    if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
    {
        num_chan_new = 0;
        for (i = 0; i < num_channels; i++)
            for (j = 0; j < HDD_NUM_NL80211_BANDS; j++) {
                if (wiphy->bands[j] == NULL)
                    continue;
                for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
                    if ((chan_list[i] ==
                                wiphy->bands[j]->channels[k].center_freq) &&
                            (!(wiphy->bands[j]->channels[k].flags &
                               IEEE80211_CHAN_INDOOR_ONLY))) {
                        chan_list[num_chan_new] = chan_list[i];
                        num_chan_new++;
                    }
                }
            }
    }

    hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
    for (i = 0; i < num_chan_new; i++)
        len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
    hddLog(LOG1, "Channels: %s", buf);

    replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
                                                    sizeof(u32) * num_chan_new +
                                                    NLMSG_HDRLEN);

    if (!replySkb) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                FL("valid channels: buffer alloc fail"));
        return -EINVAL;
    }
    if (nla_put_u32(replySkb,
                QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
                num_chan_new) ||
            nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
                sizeof(u32) * num_chan_new, chan_list)) {

        hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
        kfree_skb(replySkb);
        return -EINVAL;
    }

    ret = cfg80211_vendor_cmd_reply(replySkb);

    EXIT();
    return ret;
}

static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
                                        struct wireless_dev *wdev,
                                        const void *data, int dataLen)
{
    int ret = 0;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
                                                         dataLen);
    vos_ssr_unprotect(__func__);

    return ret;
}

static int hdd_extscan_start_fill_bucket_channel_spec(
            hdd_context_t *pHddCtx,
            tpSirEXTScanStartReqParams pReqMsg,
            struct nlattr **tb)
{
    struct nlattr *bucket[
        QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
    struct nlattr *channel[
        QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
    struct nlattr *buckets;
    struct nlattr *channels;
    int rem1, rem2;
    eHalStatus status;
    tANI_U8 bktIndex, j, numChannels;
    uint32_t expected_buckets;
    tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
    tANI_U32 passive_max_chn_time, active_max_chn_time;

    expected_buckets = pReqMsg->numBuckets;
    bktIndex = 0;

    nla_for_each_nested(buckets,
            tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
        if (bktIndex >= expected_buckets) {
            hddLog(LOGW, FL("ignoring excess buckets"));
            break;
        }

        if (nla_parse(bucket,
                      QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
                      nla_data(buckets), nla_len(buckets),
                      wlan_hdd_extscan_config_policy)) {
            hddLog(LOGE, FL("nla_parse failed"));
            return -EINVAL;
        }

        /* Parse and fetch bucket spec */
        if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
            hddLog(LOGE, FL("attr bucket index failed"));
            return -EINVAL;
        }
        pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
            bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
        hddLog(LOG1, FL("Bucket spec Index %d"),
               pReqMsg->buckets[bktIndex].bucket);

        /* Parse and fetch wifi band */
        if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
            hddLog(LOGE, FL("attr wifi band failed"));
            return -EINVAL;
        }
        pReqMsg->buckets[bktIndex].band = nla_get_u8(
            bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
        hddLog(LOG1, FL("Wifi band %d"),
               pReqMsg->buckets[bktIndex].band);

        /* Parse and fetch period */
        if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
            hddLog(LOGE, FL("attr period failed"));
            return -EINVAL;
        }
        pReqMsg->buckets[bktIndex].period = nla_get_u32(
        bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
        hddLog(LOG1, FL("period %d"),
           pReqMsg->buckets[bktIndex].period);

        /* Parse and fetch report events */
        if (!bucket[
            QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
            hddLog(LOGE, FL("attr report events failed"));
            return -EINVAL;
        }
        pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
            bucket[
            QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
        hddLog(LOG1, FL("report events %d"),
            pReqMsg->buckets[bktIndex].reportEvents);

        /* Parse and fetch max period */
        if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
            hddLog(LOGE, FL("attr max period failed"));
            return -EINVAL;
        }
        pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
            bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
        hddLog(LOG1, FL("max period %u"),
            pReqMsg->buckets[bktIndex].max_period);

        /* Parse and fetch exponent */
        if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
            hddLog(LOGE, FL("attr exponent failed"));
            return -EINVAL;
        }
        pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
            bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
        hddLog(LOG1, FL("exponent %u"),
            pReqMsg->buckets[bktIndex].exponent);

        /* Parse and fetch step count */
        if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
            hddLog(LOGE, FL("attr step count failed"));
            return -EINVAL;
        }
        pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
            bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
        hddLog(LOG1, FL("Step count %u"),
            pReqMsg->buckets[bktIndex].step_count);

        ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
        ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);

        /* Framework shall pass the channel list if the input WiFi band is
               * WIFI_BAND_UNSPECIFIED.
               * If the input WiFi band is specified (any value other than
               * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
               */
        if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
            numChannels = 0;
            hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
            status = sme_GetValidChannelsByBand(pHddCtx->hHal,
                        pReqMsg->buckets[bktIndex].band,
                        chanList, &numChannels);
            if (!HAL_STATUS_SUCCESS(status)) {
                hddLog(LOGE,
                       FL("sme_GetValidChannelsByBand failed (err=%d)"),
                       status);
                return -EINVAL;
            }

            pReqMsg->buckets[bktIndex].numChannels =
               VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
            hddLog(LOG1, FL("Num channels %d"),
                   pReqMsg->buckets[bktIndex].numChannels);

            for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
                 j++) {
                pReqMsg->buckets[bktIndex].channels[j].channel =
                            chanList[j];
                pReqMsg->buckets[bktIndex].channels[j].
                            chnlClass = 0;
                if (CSR_IS_CHANNEL_DFS(
                    vos_freq_to_chan(chanList[j]))) {
                    pReqMsg->buckets[bktIndex].channels[j].
                                passive = 1;
                    pReqMsg->buckets[bktIndex].channels[j].
                                dwellTimeMs = passive_max_chn_time;
                } else {
                    pReqMsg->buckets[bktIndex].channels[j].
                        passive = 0;
                    pReqMsg->buckets[bktIndex].channels[j].
                        dwellTimeMs = active_max_chn_time;
                }

                hddLog(LOG1,
                    "Channel %u Passive %u Dwell time %u ms",
                    pReqMsg->buckets[bktIndex].channels[j].channel,
                    pReqMsg->buckets[bktIndex].channels[j].passive,
                    pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
            }

            bktIndex++;
            continue;
        }

        /* Parse and fetch number of channels */
        if (!bucket[
            QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
            hddLog(LOGE, FL("attr num channels failed"));
            return -EINVAL;
        }

        pReqMsg->buckets[bktIndex].numChannels =
        nla_get_u32(bucket[
        QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
        hddLog(LOG1, FL("num channels %d"),
               pReqMsg->buckets[bktIndex].numChannels);

        if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
            hddLog(LOGE, FL("attr channel spec failed"));
            return -EINVAL;
        }

        j = 0;
        nla_for_each_nested(channels,
            bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
            if (nla_parse(channel,
                QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
                nla_data(channels), nla_len(channels),
                wlan_hdd_extscan_config_policy)) {
                hddLog(LOGE, FL("nla_parse failed"));
                return -EINVAL;
           }

            /* Parse and fetch channel */
            if (!channel[
                QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
                hddLog(LOGE, FL("attr channel failed"));
                return -EINVAL;
            }
            pReqMsg->buckets[bktIndex].channels[j].channel =
                nla_get_u32(channel[
                QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
            hddLog(LOG1, FL("channel %u"),
                   pReqMsg->buckets[bktIndex].channels[j].channel);

            /* Parse and fetch dwell time */
            if (!channel[
                QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
                hddLog(LOGE, FL("attr dwelltime failed"));
                return -EINVAL;
            }
            pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
                nla_get_u32(channel[
                QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);

            hddLog(LOG1, FL("Dwell time (%u ms)"),
                pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);


            /* Parse and fetch channel spec passive */
            if (!channel[
                QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
                hddLog(LOGE,
                       FL("attr channel spec passive failed"));
                return -EINVAL;
            }
            pReqMsg->buckets[bktIndex].channels[j].passive =
                nla_get_u8(channel[
                QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
            hddLog(LOG1, FL("Chnl spec passive %u"),
                pReqMsg->buckets[bktIndex].channels[j].passive);

            j++;
       }

       bktIndex++;
    }

    return 0;
}


/*
 * define short names for the global vendor params
 * used by wlan_hdd_cfg80211_extscan_start()
 */
#define PARAM_MAX \
QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
#define PARAM_REQUEST_ID \
QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
#define PARAM_BASE_PERIOD \
QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
#define PARAM_MAX_AP_PER_SCAN \
QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
#define PARAM_RPT_THRHLD_PERCENT \
QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
#define PARAM_RPT_THRHLD_NUM_SCANS \
QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
#define PARAM_NUM_BUCKETS \
QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS

static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
                                        struct wireless_dev *wdev,
                                        const void *data, int dataLen)
{
    tpSirEXTScanStartReqParams pReqMsg = NULL;
    struct net_device *dev             = wdev->netdev;
    hdd_adapter_t *pAdapter            = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx             = wiphy_priv(wiphy);
    struct nlattr *tb[PARAM_MAX + 1];
    int retval;
    eHalStatus status;
    tANI_U32 request_id;
    struct hdd_ext_scan_context *context;
    unsigned long rc;

    ENTER();

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

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return -EINVAL;
    }
    /* check the EXTScan Capability */
    if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
         (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
         (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("EXTScan not enabled/supported by Firmware"));
        return -EINVAL;
    }

    if (nla_parse(tb, PARAM_MAX,
                    data, dataLen,
                    wlan_hdd_extscan_config_policy)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
        return -EINVAL;
    }

    /* Parse and fetch request Id */
    if (!tb[PARAM_REQUEST_ID]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
        return -EINVAL;
    }

    pReqMsg = (tpSirEXTScanStartReqParams)
                                     vos_mem_malloc(sizeof(*pReqMsg));
    if (!pReqMsg) {
       hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
       return -ENOMEM;
    }

    pReqMsg->requestId = nla_get_u32(
              tb[PARAM_REQUEST_ID]);
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);

    pReqMsg->sessionId = pAdapter->sessionId;
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);

    /* Parse and fetch base period */
    if (!tb[PARAM_BASE_PERIOD]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
        goto fail;
    }
    pReqMsg->basePeriod = nla_get_u32(
              tb[PARAM_BASE_PERIOD]);
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
                                         pReqMsg->basePeriod);

    /* Parse and fetch max AP per scan */
    if (!tb[PARAM_MAX_AP_PER_SCAN]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
        goto fail;
    }
    pReqMsg->maxAPperScan = nla_get_u32(
             tb[PARAM_MAX_AP_PER_SCAN]);
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
                                         pReqMsg->maxAPperScan);

    /* Parse and fetch report threshold */
    if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
        goto fail;
    }
    pReqMsg->reportThresholdPercent = nla_get_u8(
            tb[PARAM_RPT_THRHLD_PERCENT]);
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
                                     pReqMsg->reportThresholdPercent);

    /* Parse and fetch report threshold num scans */
    if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
        hddLog(LOGE, FL("attr report_threshold num scans failed"));
        goto fail;
    }
    pReqMsg->reportThresholdNumScans = nla_get_u8(
        tb[PARAM_RPT_THRHLD_NUM_SCANS]);
    hddLog(LOG1, FL("Report Threshold num scans %d"),
                     pReqMsg->reportThresholdNumScans);

    /* Parse and fetch number of buckets */
    if (!tb[PARAM_NUM_BUCKETS]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
        goto fail;
    }
    pReqMsg->numBuckets = nla_get_u8(
                 tb[PARAM_NUM_BUCKETS]);
    if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
        hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
          "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
        pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
    }
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
                                         pReqMsg->numBuckets);

    if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
        goto fail;
    }

    pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;

    if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
        goto fail;

    context = &pHddCtx->ext_scan_context;
    spin_lock(&hdd_context_lock);
    INIT_COMPLETION(context->response_event);
    context->request_id = request_id = pReqMsg->requestId;
    spin_unlock(&hdd_context_lock);

    status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
    if (!HAL_STATUS_SUCCESS(status)) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                     FL("sme_EXTScanStart failed(err=%d)"), status);
        goto fail;
    }

    pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();

    /* request was sent -- wait for the response */
    rc = wait_for_completion_timeout(&context->response_event,
                msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));

    if (!rc) {
        hddLog(LOGE, FL("sme_ExtScanStart timed out"));
        retval = -ETIMEDOUT;
    } else {
        spin_lock(&hdd_context_lock);
        if (context->request_id == request_id)
            retval = context->response_status;
        else
            retval = -EINVAL;
        spin_unlock(&hdd_context_lock);
    }

    vos_mem_free(pReqMsg);
    EXIT();
    return retval;

fail:
    vos_mem_free(pReqMsg);
    return -EINVAL;
}

/*
 * done with short names for the global vendor params
 * used by wlan_hdd_cfg80211_extscan_start()
 */
#undef PARAM_MAX
#undef PARAM_REQUEST_ID
#undef PARAM_BASE_PERIOD
#undef PARAMS_MAX_AP_PER_SCAN
#undef PARAMS_RPT_THRHLD_PERCENT
#undef PARAMS_RPT_THRHLD_NUM_SCANS
#undef PARAMS_NUM_BUCKETS

static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
                                        struct wireless_dev *wdev,
                                        const void *data, int dataLen)
{
   int ret = 0;

   vos_ssr_protect(__func__);
   ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
   vos_ssr_unprotect(__func__);

   return ret;
}

static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
                                        struct wireless_dev *wdev,
                                        const void *data, int dataLen)
{
    tSirEXTScanStopReqParams reqMsg;
    struct net_device *dev                  = wdev->netdev;
    hdd_adapter_t *pAdapter                 = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx                  = wiphy_priv(wiphy);
    struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
    eHalStatus status;
    int retval;
    unsigned long rc;
    struct hdd_ext_scan_context *context;
    tANI_U32 request_id;

    ENTER();

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

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return -EINVAL;
    }
    /* check the EXTScan Capability */
    if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
         (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
         (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("EXTScan not enabled/supported by Firmware"));
        return -EINVAL;
    }

    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
                    data, dataLen,
                    wlan_hdd_extscan_config_policy)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
        return -EINVAL;
    }

    /* Parse and fetch request Id */
    if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
        return -EINVAL;
    }

    reqMsg.requestId = nla_get_u32(
              tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);

    reqMsg.sessionId = pAdapter->sessionId;
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);

    context = &pHddCtx->ext_scan_context;
    spin_lock(&hdd_context_lock);
    INIT_COMPLETION(context->response_event);
    context->request_id = request_id = reqMsg.requestId;
    spin_unlock(&hdd_context_lock);

    status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
    if (!HAL_STATUS_SUCCESS(status)) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                    FL("sme_EXTScanStop failed(err=%d)"), status);
        return -EINVAL;
    }

    /* request was sent -- wait for the response */
    rc = wait_for_completion_timeout(&context->response_event,
                 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));

    if (!rc) {
        hddLog(LOGE, FL("sme_ExtScanStop timed out"));
        retval = -ETIMEDOUT;
    } else {
        spin_lock(&hdd_context_lock);
        if (context->request_id == request_id)
            retval = context->response_status;
        else
            retval = -EINVAL;
        spin_unlock(&hdd_context_lock);
    }

    return retval;

    EXIT();
    return 0;
}

static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
                                        struct wireless_dev *wdev,
                                        const void *data, int dataLen)
{
   int ret = 0;

   vos_ssr_protect(__func__);
   ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
   vos_ssr_unprotect(__func__);

   return ret;
}

static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
                                        struct wireless_dev *wdev,
                                        const void *data, int dataLen)
{
    tSirEXTScanResetBssidHotlistReqParams reqMsg;
    struct net_device *dev                       = wdev->netdev;
    hdd_adapter_t *pAdapter                      = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx                       = wiphy_priv(wiphy);
    struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
    eHalStatus status;
    struct hdd_ext_scan_context *context;
    tANI_U32 request_id;
    unsigned long rc;
    int retval;

    ENTER();

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

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        hddLog(LOGE, FL("HDD context is not valid"));
        return -EINVAL;
    }
    /* check the EXTScan Capability */
    if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
         (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
         (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("EXTScan not enabled/supported by Firmware"));
        return -EINVAL;
    }

    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
                    data, dataLen,
                    wlan_hdd_extscan_config_policy)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
        return -EINVAL;
    }

    /* Parse and fetch request Id */
    if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
        return -EINVAL;
    }

    reqMsg.requestId = nla_get_u32(
              tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);

    reqMsg.sessionId = pAdapter->sessionId;
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);

    context = &pHddCtx->ext_scan_context;
    spin_lock(&hdd_context_lock);
    INIT_COMPLETION(context->response_event);
    context->request_id = request_id = reqMsg.requestId;
    spin_unlock(&hdd_context_lock);

    status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
    if (!HAL_STATUS_SUCCESS(status)) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                          FL("sme_ResetBssHotlist failed(err=%d)"), status);
        return -EINVAL;
    }

    /* request was sent -- wait for the response */
    rc = wait_for_completion_timeout(&context->response_event,
                                     msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
    if (!rc) {
       hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
       retval = -ETIMEDOUT;
    } else {
       spin_lock(&hdd_context_lock);
       if (context->request_id == request_id)
          retval = context->response_status;
       else
          retval = -EINVAL;
       spin_unlock(&hdd_context_lock);
    }

    EXIT();
    return retval;
}

static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
                                        struct wireless_dev *wdev,
                                        const void *data, int dataLen)
{
   int ret = 0;

   vos_ssr_protect(__func__);
   ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
   vos_ssr_unprotect(__func__);

   return ret;
}
#endif /* WLAN_FEATURE_EXTSCAN */

/*EXT TDLS*/
static const struct nla_policy
wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
{
    [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
        .type = NLA_UNSPEC,
        .len = HDD_MAC_ADDR_LEN},
    [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
    [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
                                                       {.type = NLA_S32 },
    [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
    [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },

};

static const struct nla_policy
wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
{
    [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
        .type = NLA_UNSPEC,
        .len = HDD_MAC_ADDR_LEN},

};

static const struct nla_policy
wlan_hdd_tdls_config_state_change_policy[
                    QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
{
    [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
        .type = NLA_UNSPEC,
        .len = HDD_MAC_ADDR_LEN},
    [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
    [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
    [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
    [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
                                                {.type = NLA_S32 },

};

static const struct nla_policy
wlan_hdd_tdls_config_get_status_policy[
                     QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
{
    [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
        .type = NLA_UNSPEC,
        .len = HDD_MAC_ADDR_LEN},
    [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
    [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
    [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
    [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
                                                   = {.type = NLA_S32 },

};

static const struct nla_policy
wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
{
    [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
        .type = NLA_UNSPEC,
        .len = VOS_MAC_ADDR_FIRST_3_BYTES},
};

static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
        struct wireless_dev *wdev,
        const void *data,
        int data_len)
{

    hdd_context_t *pHddCtx      = wiphy_priv(wiphy);
    struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];

    ENTER();

    if (0 != wlan_hdd_validate_context(pHddCtx)){
        return -EINVAL;
    }
    if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
        hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
        return -ENOTSUPP;
    }
    if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
        hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
        return -ENOTSUPP;
    }

    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
                data, data_len, wlan_hdd_mac_config)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
        return -EINVAL;
    }

    /* Parse and fetch mac address */
    if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
        return -EINVAL;
    }

    memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
                tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
            VOS_MAC_ADDR_LAST_3_BYTES);

    pHddCtx->spoofMacAddr.isEnabled = TRUE;

    vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
            tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
            VOS_MAC_ADDR_FIRST_3_BYTES);
    if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
        (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
        (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
    {
            hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
            vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
                                                        VOS_MAC_ADDRESS_LEN);
            pHddCtx->spoofMacAddr.isEnabled = FALSE;
    }

    schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
                          msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));

    EXIT();
    return 0;
}

static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
        struct wireless_dev *wdev,
        const void *data,
        int data_len)
{
    int ret = 0;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
    vos_ssr_unprotect(__func__);

    return ret;
}

static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
                                                struct wireless_dev *wdev,
                                                const void *data,
                                                int data_len)
{
    u8 peer[6]                                 = {0};
    struct net_device *dev                     = wdev->netdev;
    hdd_adapter_t *pAdapter                    = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx                     = wiphy_priv(wiphy);
    struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
    eHalStatus ret;
    tANI_S32 state;
    tANI_S32 reason;
    tANI_S32 global_operating_class = 0;
    tANI_S32 channel = 0;
    struct sk_buff *skb         = NULL;
    int retVal;

    ENTER();

    if (!pAdapter) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
        return -EINVAL;
    }

    ret = wlan_hdd_validate_context(pHddCtx);
    if (0 != ret) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
        return -EINVAL;
    }
    if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
        return -ENOTSUPP;
    }
    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
                    data, data_len,
                    wlan_hdd_tdls_config_get_status_policy)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
        return -EINVAL;
    }

    /* Parse and fetch mac address */
    if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
        return -EINVAL;
    }

    memcpy(peer, nla_data(
           tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
           sizeof(peer));
    hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));

    wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);

    skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
                                              4 * sizeof(s32) +
                                              NLMSG_HDRLEN);

    if (!skb) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                  FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
        return -EINVAL;
    }
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
                                 reason,
                                 state,
                                 global_operating_class,
                                 channel,
                                 MAC_ADDR_ARRAY(peer));
    if (nla_put_s32(skb,
                    QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
                    state) ||
        nla_put_s32(skb,
                    QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
                    reason) ||
        nla_put_s32(skb,
                    QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
                    global_operating_class) ||
        nla_put_s32(skb,
                    QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
                    channel)) {

        hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
        goto nla_put_failure;
    }

    retVal = cfg80211_vendor_cmd_reply(skb);
    EXIT();
    return retVal;

nla_put_failure:
    kfree_skb(skb);
    return -EINVAL;
}

static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
                                                struct wireless_dev *wdev,
                                                const void *data,
                                                int data_len)
{
    int ret = 0;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
    vos_ssr_unprotect(__func__);

    return ret;
}

static int wlan_hdd_cfg80211_exttdls_callback(
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
                                              const tANI_U8* mac,
#else
                                              tANI_U8* mac,
#endif
                                              tANI_S32 state,
                                              tANI_S32 reason,
                                              void *ctx)
{
    hdd_adapter_t* pAdapter       = (hdd_adapter_t*)ctx;
    struct sk_buff *skb           = NULL;
    tANI_S32 global_operating_class = 0;
    tANI_S32 channel = 0;
    hdd_context_t *pHddCtx;

    ENTER();

    if (!pAdapter) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
        return -EINVAL;
    }

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    if (wlan_hdd_validate_context(pHddCtx)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
        return -EINVAL;
    }

    if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
        return -ENOTSUPP;
    }
    skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
                            NULL,
#endif
                            EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
                            QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
                            GFP_KERNEL);

    if (!skb) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                  FL("cfg80211_vendor_event_alloc failed"));
        return -EINVAL;
    }
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
    hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
           reason,
           state,
           global_operating_class,
           channel);
    hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
                                          MAC_ADDR_ARRAY(mac));

    if (nla_put(skb,
                QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
                VOS_MAC_ADDR_SIZE, mac) ||
        nla_put_s32(skb,
                    QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
                    state) ||
        nla_put_s32(skb,
                    QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
                    reason) ||
        nla_put_s32(skb,
                    QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
                    channel) ||
        nla_put_s32(skb,
                    QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
                    global_operating_class)
        ) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
        goto nla_put_failure;
    }

    cfg80211_vendor_event(skb, GFP_KERNEL);
    EXIT();
    return (0);

nla_put_failure:
    kfree_skb(skb);
    return -EINVAL;
}

static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
                                            struct wireless_dev *wdev,
                                            const void *data,
                                            int data_len)
{
    u8 peer[6]                                 = {0};
    struct net_device *dev                     = wdev->netdev;
    hdd_context_t *pHddCtx                     = wiphy_priv(wiphy);
    struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
    eHalStatus status;
    tdls_req_params_t   pReqMsg = {0};
    int ret;
    hdd_adapter_t *pAdapter;

    ENTER();

    if (!dev) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
        return -EINVAL;
    }

    pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    if (!pAdapter) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
        return -EINVAL;
    }

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
        return -EINVAL;
    }
    if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
        return -ENOTSUPP;
    }
    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
                    data, data_len,
                    wlan_hdd_tdls_config_enable_policy)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
        return -EINVAL;
    }

    /* Parse and fetch mac address */
    if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
        return -EINVAL;
    }

    memcpy(peer, nla_data(
                tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
                sizeof(peer));
    hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));

    /* Parse and fetch channel */
    if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
        return -EINVAL;
    }
    pReqMsg.channel = nla_get_s32(
         tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);

    /* Parse and fetch global operating class */
    if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
        return -EINVAL;
    }
    pReqMsg.global_operating_class = nla_get_s32(
        tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
                                     pReqMsg.global_operating_class);

    /* Parse and fetch latency ms */
    if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
        return -EINVAL;
    }
    pReqMsg.max_latency_ms = nla_get_s32(
        tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
                                     pReqMsg.max_latency_ms);

    /* Parse and fetch required bandwidth kbps */
    if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
        return -EINVAL;
    }

    pReqMsg.min_bandwidth_kbps = nla_get_s32(
        tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
                                     pReqMsg.min_bandwidth_kbps);

    ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
                                 peer,
                                 &pReqMsg,
                                 wlan_hdd_cfg80211_exttdls_callback);

    EXIT();
    return ret;
}

static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
                                            struct wireless_dev *wdev,
                                            const void *data,
                                            int data_len)
{
   int ret = 0;

   vos_ssr_protect(__func__);
   ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
   vos_ssr_unprotect(__func__);

   return ret;
}

static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
                                             struct wireless_dev *wdev,
                                             const void *data,
                                             int data_len)
{
    u8 peer[6]                                 = {0};
    struct net_device *dev                     = wdev->netdev;
    hdd_context_t *pHddCtx                     = wiphy_priv(wiphy);
    struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
    eHalStatus status;
    int ret;
    hdd_adapter_t *pAdapter;

    ENTER();

    if (!dev) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
        return -EINVAL;
    }

    pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    if (!pAdapter) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
        return -EINVAL;
    }

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
        return -EINVAL;
    }
    if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
        return -ENOTSUPP;
    }
    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
                    data, data_len,
                    wlan_hdd_tdls_config_disable_policy)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
        return -EINVAL;
    }
    /* Parse and fetch mac address */
    if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
        return -EINVAL;
    }

    memcpy(peer, nla_data(
                tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
                sizeof(peer));
    hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));

    ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);

    EXIT();
    return ret;
}

static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
                                             struct wireless_dev *wdev,
                                             const void *data,
                                             int data_len)
{
   int ret = 0;

   vos_ssr_protect(__func__);
   ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
   vos_ssr_unprotect(__func__);

   return ret;
}

static int
__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
                                         struct wireless_dev *wdev,
                                         const void *data, int data_len)
{
    struct net_device *dev                     = wdev->netdev;
    hdd_adapter_t *pAdapter                    = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx      = wiphy_priv(wiphy);
    struct sk_buff *skb         = NULL;
    tANI_U32       fset         = 0;
    int ret = 0;

    ENTER();

    ret = wlan_hdd_validate_context(pHddCtx);
    if (0 != ret)
    {
        return ret;
    }
    if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
        hddLog(LOG1, FL("Infra Station mode is supported by driver"));
        fset |= WIFI_FEATURE_INFRA;
    }

    if (TRUE == hdd_is_5g_supported(pHddCtx)) {
        hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
        fset |= WIFI_FEATURE_INFRA_5G;
    }

#ifdef WLAN_FEATURE_P2P
    if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
        (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
        hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
        fset |= WIFI_FEATURE_P2P;
    }
#endif

    /* Soft-AP is supported currently by default */
    fset |= WIFI_FEATURE_SOFT_AP;

    /* HOTSPOT is a supplicant feature, enable it by default */
    fset |= WIFI_FEATURE_HOTSPOT;

#ifdef WLAN_FEATURE_EXTSCAN
    if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
            sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
            sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
        hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
        fset |= WIFI_FEATURE_EXTSCAN;
    }
#endif

    if (sme_IsFeatureSupportedByFW(NAN)) {
        hddLog(LOG1, FL("NAN is supported by firmware"));
        fset |= WIFI_FEATURE_NAN;
    }

    /* D2D RTT is not supported currently by default */
    if (sme_IsFeatureSupportedByFW(RTT) &&
              pHddCtx->cfg_ini->enable_rtt_support) {
        hddLog(LOG1, FL("RTT is supported by firmware and framework"));
        fset |= WIFI_FEATURE_D2AP_RTT;
    }

   if (sme_IsFeatureSupportedByFW(RTT3)) {
        hddLog(LOG1, FL("RTT3 is supported by firmware"));
        fset |= WIFI_FEATURE_RTT3;
    }

#ifdef FEATURE_WLAN_BATCH_SCAN
    if (fset & WIFI_FEATURE_EXTSCAN) {
        hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
        fset &= ~WIFI_FEATURE_BATCH_SCAN;
    } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
        hddLog(LOG1, FL("Batch scan is supported by firmware"));
        fset |= WIFI_FEATURE_BATCH_SCAN;
    }
#endif

#ifdef FEATURE_WLAN_SCAN_PNO
    if (pHddCtx->cfg_ini->configPNOScanSupport &&
        (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
        hddLog(LOG1, FL("PNO is supported by firmware"));
        fset |= WIFI_FEATURE_PNO;
    }
#endif

    /* STA+STA is supported currently by default */
    fset |= WIFI_FEATURE_ADDITIONAL_STA;

#ifdef FEATURE_WLAN_TDLS
    if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
        sme_IsFeatureSupportedByFW(TDLS)) {
        hddLog(LOG1, FL("TDLS is supported by firmware"));
        fset |= WIFI_FEATURE_TDLS;
    }

    /* TDLS_OFFCHANNEL is not supported currently by default */
#endif

#ifdef WLAN_AP_STA_CONCURRENCY
    /* AP+STA concurrency is supported currently by default */
    fset |= WIFI_FEATURE_AP_STA;
#endif

#ifdef WLAN_FEATURE_LINK_LAYER_STATS
   if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
       (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
        fset |= WIFI_FEATURE_LINK_LAYER_STATS;
        hddLog(LOG1, FL("Link layer stats is supported by driver"));
   }
#endif

    skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
                                              NLMSG_HDRLEN);

    if (!skb) {
        hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
        return -EINVAL;
    }
    hddLog(LOG1, FL("Supported Features : 0x%x"), fset);

    if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
        hddLog(LOGE, FL("nla put fail"));
        goto nla_put_failure;
    }

    ret = cfg80211_vendor_cmd_reply(skb);
    EXIT();
    return ret;

nla_put_failure:
    kfree_skb(skb);
    return -EINVAL;
}

static int
wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
                                         struct wireless_dev *wdev,
                                         const void *data, int data_len)
{
    int ret = 0;
    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
    vos_ssr_unprotect(__func__);

    return ret;
}


static const struct
nla_policy
qca_wlan_vendor_wifi_logger_get_ring_data_policy
[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
    [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
        = {.type = NLA_U32 },
};

static int
    __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
                                                      struct wireless_dev *wdev,
                                                      const void *data,
                                                      int data_len)
{
    int ret;
    VOS_STATUS status;
    uint32_t ring_id;
    hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
    struct nlattr *tb
        [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];

    ENTER();

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

    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
            data, data_len,
            qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
        hddLog(LOGE, FL("Invalid attribute"));
        return -EINVAL;
    }

    /* Parse and fetch ring id */
    if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
        hddLog(LOGE, FL("attr ATTR failed"));
        return -EINVAL;
    }

    ring_id = nla_get_u32(
            tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);

    hddLog(LOG1, FL("Bug report triggered by framework"));

    status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
                WLAN_LOG_INDICATOR_FRAMEWORK,
                WLAN_LOG_REASON_CODE_FRAMEWORK,
                TRUE, TRUE
                );
    if (VOS_STATUS_SUCCESS != status) {
        hddLog(LOGE, FL("Failed to trigger bug report"));

        return -EINVAL;
    }

    return 0;


}


static int
    wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
                                                      struct wireless_dev *wdev,
                                                      const void *data,
                                                      int data_len)
{
    int ret = 0;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
            wdev, data, data_len);
    vos_ssr_unprotect(__func__);

    return ret;

}

#define MAX_CONCURRENT_MATRIX \
    QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
    QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
static const struct nla_policy
wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
    [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
};

static int
__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
                                         struct wireless_dev *wdev,
                                         const void *data, int data_len)
{
    uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
    uint8_t i, feature_sets, max_feature_sets;
    struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
    struct sk_buff *reply_skb;
    hdd_context_t *pHddCtx = wiphy_priv(wiphy);
    int ret;

    ENTER();

    ret = wlan_hdd_validate_context(pHddCtx);
    if (0 != ret)
    {
        return ret;
    }

    if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
                  wlan_hdd_get_concurrency_matrix_policy)) {
        hddLog(LOGE, FL("Invalid ATTR"));
        return -EINVAL;
    }

    /* Parse and fetch max feature set */
    if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
        hddLog(LOGE, FL("Attr max feature set size failed"));
        return -EINVAL;
    }
    max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
    hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);

    /* Fill feature combination matrix */
    feature_sets = 0;
    feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
                                         WIFI_FEATURE_P2P;

    feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
                                         WIFI_FEATURE_SOFT_AP;

    feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
                                         WIFI_FEATURE_SOFT_AP;

    feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
                                         WIFI_FEATURE_SOFT_AP |
                                         WIFI_FEATURE_P2P;

    /* Add more feature combinations here */

    feature_sets = VOS_MIN(feature_sets, max_feature_sets);
    hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
    hddLog(LOG1, "Feature set matrix");
    for (i = 0; i < feature_sets; i++)
        hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);

    reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
                                                    sizeof(u32) * feature_sets +
                                                    NLMSG_HDRLEN);

    if (reply_skb) {
        if (nla_put_u32(reply_skb,
                        QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
                        feature_sets) ||
            nla_put(reply_skb,
                    QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
                    sizeof(u32) * feature_sets, feature_set_matrix)) {
            hddLog(LOGE, FL("nla put fail"));
            kfree_skb(reply_skb);
            return -EINVAL;
        }

        ret = cfg80211_vendor_cmd_reply(reply_skb);
        EXIT();
        return ret;
    }
    hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
    return -ENOMEM;

}

#undef MAX_CONCURRENT_MATRIX
#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX

static int
wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
                                         struct wireless_dev *wdev,
                                         const void *data, int data_len)
{
    int ret = 0;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
                                                     data_len);
    vos_ssr_unprotect(__func__);

    return ret;
}


static int
__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
                                    struct wireless_dev *wdev,
                                    const void *data, int data_len)
{
    hdd_context_t *pHddCtx = wiphy_priv(wiphy);
    int ret;
    ENTER();

    ret = wlan_hdd_validate_context(pHddCtx);
    if (0 != ret)
    {
        return ret;
    }

    if( !pHddCtx->cfg_ini->enableFwrMemDump ||
       (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
    {
       hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
       return -EOPNOTSUPP;
    }
    /*call common API for FW mem dump req*/
    ret = wlan_hdd_fw_mem_dump_req(pHddCtx);

    if (!ret)
    {
        /*indicate to userspace the status of fw mem dump */
        wlan_indicate_mem_dump_complete(true);
    }
    else
    {
        /*else send failure to userspace */
        wlan_indicate_mem_dump_complete(false);
    }
    EXIT();
    return ret;
}

/**
 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
 * @wiphy:   pointer to wireless wiphy structure.
 * @wdev:    pointer to wireless_dev structure.
 * @data:    Pointer to the NL data.
 * @data_len:Length of @data
 *
 * This is called when wlan driver needs to get the firmware memory dump
 * via vendor specific command.
 *
 * Return:   0 on success, error number otherwise.
 */

static int
wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
                                              struct wireless_dev *wdev,
                                         const void *data, int data_len)
{
    int ret = 0;
    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
                                        data_len);
    vos_ssr_unprotect(__func__);
    return ret;
}

static const struct
nla_policy
qca_wlan_vendor_wifi_logger_start_policy
[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
   [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
     = {.type = NLA_U32 },
     [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
        = {.type = NLA_U32 },
     [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
          = {.type = NLA_U32 },
};

/**
 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
 * or disable the collection of packet statistics from the firmware
 * @wiphy:    WIPHY structure pointer
 * @wdev:     Wireless device structure pointer
 * @data:     Pointer to the data received
 * @data_len: Length of the data received
 *
 * This function is used to enable or disable the collection of packet
 * statistics from the firmware
 *
 * Return: 0 on success and errno on failure
 */
static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
                       struct wireless_dev *wdev,
                        const void *data,
                                int data_len)
{
    eHalStatus status;
    hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
    struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
    tAniWifiStartLog start_log;

    status = wlan_hdd_validate_context(hdd_ctx);
    if (0 != status) {
        return -EINVAL;
    }

     if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
             data, data_len,
            qca_wlan_vendor_wifi_logger_start_policy)) {
        hddLog(LOGE, FL("Invalid attribute"));
        return -EINVAL;
    }

    /* Parse and fetch ring id */
    if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
        hddLog(LOGE, FL("attr ATTR failed"));
        return -EINVAL;
    }
    start_log.ringId = nla_get_u32(
           tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
    hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);

    /* Parse and fetch verbose level */
    if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
        hddLog(LOGE, FL("attr verbose_level failed"));
        return -EINVAL;
    }
    start_log.verboseLevel = nla_get_u32(
         tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
    hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);

    /* Parse and fetch flag */
    if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
        hddLog(LOGE, FL("attr flag failed"));
        return -EINVAL;
    }
    start_log.flag = nla_get_u32(
        tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
    hddLog(LOG1, FL("flag=%d"), start_log.flag);

    if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
                 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
        !vos_isPktStatsEnabled()))

    {
       hddLog(LOGE, FL("per pkt stats not enabled"));
       return -EINVAL;
    }

    vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
    return 0;
}

/**
 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
 * or disable the collection of packet statistics from the firmware
 * @wiphy:    WIPHY structure pointer
 * @wdev:     Wireless device structure pointer
 * @data:     Pointer to the data received
 * @data_len: Length of the data received
 *
 * This function is used to enable or disable the collection of packet
 * statistics from the firmware
 *
 * Return: 0 on success and errno on failure
 */
static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
                        struct wireless_dev *wdev,
                        const void *data,
                        int data_len)
{
    int ret = 0;

    vos_ssr_protect(__func__);

    ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
          wdev, data, data_len);
    vos_ssr_unprotect(__func__);

    return ret;
}


static const struct nla_policy
wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
 +1] =
{
    [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
};

static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
                                            struct wireless_dev *wdev,
                                            const void *data,
                                            int data_len)
{
    struct net_device *dev                     = wdev->netdev;
    hdd_adapter_t *pAdapter                    = WLAN_HDD_GET_PRIV_PTR(dev);
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    hdd_context_t *pHddCtx                     = wiphy_priv(wiphy);
    struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
    eHalStatus status;
    u32 dfsFlag = 0;

    ENTER();

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status) {
        return -EINVAL;
    }
    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
                    data, data_len,
                    wlan_hdd_set_no_dfs_flag_config_policy)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
        return -EINVAL;
    }

    /* Parse and fetch required bandwidth kbps */
    if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
        return -EINVAL;
    }

    dfsFlag = nla_get_u32(
        tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
    hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
                                     dfsFlag);

    pHddCtx->disable_dfs_flag = dfsFlag;

    sme_disable_dfs_channel(hHal, dfsFlag);
    sme_FilterScanResults(hHal, pAdapter->sessionId);

    EXIT();
    return 0;
}

static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
                                            struct wireless_dev *wdev,
                                            const void *data,
                                            int data_len)
{
   int ret = 0;

   vos_ssr_protect(__func__);
   ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
   vos_ssr_unprotect(__func__);

   return ret;

}

const struct
nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
{
    [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_MAC_ADDR]       = {
        .type = NLA_UNSPEC,
        .len = HDD_MAC_ADDR_LEN},
};

static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
            struct wireless_dev *wdev, const void *data, int data_len)
{

    u8 bssid[6]                                 = {0};
    hdd_context_t *pHddCtx                      = wiphy_priv(wiphy);
    struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
    eHalStatus status = eHAL_STATUS_SUCCESS;
    v_U32_t isFwrRoamEnabled = FALSE;
    int ret;

    ENTER();

    ret = wlan_hdd_validate_context(pHddCtx);
    if (0 != ret) {
        return ret;
    }

    ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
                    data, data_len,
                    qca_wlan_vendor_attr);
    if (ret){
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
        return -EINVAL;
    }

    /* Parse and fetch Enable flag */
    if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
        return -EINVAL;
    }

    isFwrRoamEnabled = nla_get_u32(
         tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);

    hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);

    /* Parse and fetch bssid */
    if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
        return -EINVAL;
    }

    memcpy(bssid, nla_data(
                tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
                sizeof(bssid));
    hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));

    //Update roaming
    status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
    if (!HAL_STATUS_SUCCESS(status)) {
        hddLog(LOGE,
           FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
        return -EINVAL;
    }
    EXIT();
    return 0;
}

static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
            struct wireless_dev *wdev, const void *data, int data_len)
{
    int ret = 0;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
    vos_ssr_unprotect(__func__);

    return ret;
}

static const struct
nla_policy
qca_wlan_vendor_get_wifi_info_policy[
         QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
    [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
    [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
};


/**
 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
 * @wiphy:   pointer to wireless wiphy structure.
 * @wdev:    pointer to wireless_dev structure.
 * @data:    Pointer to the data to be passed via vendor interface
 * @data_len:Length of the data to be passed
 *
 * This is called when wlan driver needs to send wifi driver related info
 * (driver/fw version) to the user space application upon request.
 *
 * Return:   Return the Success or Failure code.
 */
static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
                                  struct wireless_dev *wdev,
                              const void *data, int data_len)
{
    hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
    struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
    tSirVersionString version;
    uint32 version_len;
    uint8 attr;
    int status;
    struct sk_buff *reply_skb = NULL;

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

    status = wlan_hdd_validate_context(hdd_ctx);
    if (0 != status) {
        hddLog(LOGE, FL("HDD context is not valid"));
        return -EINVAL;
    }

    if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
        data_len, qca_wlan_vendor_get_wifi_info_policy)) {
        hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
        return -EINVAL;
    }

    if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
        hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
                                                          QWLAN_VERSIONSTR);
        strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
        attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
    } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
        hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
                                               hdd_ctx->fw_Version);
        strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
        attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
    } else {
        hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
        return -EINVAL;
    }

    version_len = strlen(version);
    reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
    version_len + NLA_HDRLEN + NLMSG_HDRLEN);
    if (!reply_skb) {
        hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
        return -ENOMEM;
    }

    if (nla_put(reply_skb, attr, version_len, version)) {
        hddLog(LOGE, FL("nla put fail"));
        kfree_skb(reply_skb);
        return -EINVAL;
    }

    return cfg80211_vendor_cmd_reply(reply_skb);
}

/**
 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
 * @wiphy:   pointer to wireless wiphy structure.
 * @wdev:    pointer to wireless_dev structure.
 * @data:    Pointer to the data to be passed via vendor interface
 * @data_len:Length of the data to be passed
 * @data_len: Length of the data received
 *
 * This function is used to enable or disable the collection of packet
 * statistics from the firmware
 *
 * Return: 0 on success and errno on failure
 */

static int
wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
                                  struct wireless_dev *wdev,
                              const void *data, int data_len)


{
    int ret = 0;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
          wdev, data, data_len);
    vos_ssr_unprotect(__func__);

    return ret;
}


/*
 * define short names for the global vendor params
 * used by __wlan_hdd_cfg80211_monitor_rssi()
 */
#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI

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

  \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
                                       monitor start is completed successfully.

  \return -  None

  --------------------------------------------------------------------------*/
void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
{
   hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;

   if (NULL == pHddCtx)
   {
      hddLog(VOS_TRACE_LEVEL_ERROR,
                 "%s: HDD context is NULL",__func__);
      return;
   }

   if (VOS_STATUS_SUCCESS == status)
   {
      hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
   }
   else
   {
      hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
   }

   return;
}

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

  \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
                                      stop is completed successfully.

  \return -  None

  --------------------------------------------------------------------------*/
void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
{
   hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;

   if (NULL == pHddCtx)
   {
      hddLog(VOS_TRACE_LEVEL_ERROR,
                 "%s: HDD context is NULL",__func__);
      return;
   }

   if (VOS_STATUS_SUCCESS == status)
   {
      hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
   }
   else
   {
      hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
   }

   return;
}

/**
 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
 * @wiphy: Pointer to wireless phy
 * @wdev: Pointer to wireless device
 * @data: Pointer to data
 * @data_len: Data length
 *
 * Return: 0 on success, negative errno on failure
 */

static int
__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
                                 struct wireless_dev *wdev,
                                 const void *data,
                                 int data_len)
{
        struct net_device *dev = wdev->netdev;
        hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
        hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
        hdd_station_ctx_t *pHddStaCtx;
        struct nlattr *tb[PARAM_MAX + 1];
        tpSirRssiMonitorReq pReq;
        eHalStatus status;
        int ret;
        uint32_t control;
        static const struct nla_policy policy[PARAM_MAX + 1] = {
                        [PARAM_REQUEST_ID] = { .type = NLA_U32 },
                        [PARAM_CONTROL] = { .type = NLA_U32 },
                        [PARAM_MIN_RSSI] = { .type = NLA_S8 },
                        [PARAM_MAX_RSSI] = { .type = NLA_S8 },
        };

        ENTER();

        ret = wlan_hdd_validate_context(hdd_ctx);
        if (0 != ret) {
                return -EINVAL;
        }

        if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
                hddLog(LOGE, FL("Not in Connected state!"));
                return -ENOTSUPP;
        }

        if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
                hddLog(LOGE, FL("Invalid ATTR"));
                return -EINVAL;
        }

        if (!tb[PARAM_REQUEST_ID]) {
                hddLog(LOGE, FL("attr request id failed"));
                return -EINVAL;
        }

        if (!tb[PARAM_CONTROL]) {
                hddLog(LOGE, FL("attr control failed"));
                return -EINVAL;
        }

        pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

        pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
        if(NULL == pReq)
        {
            hddLog(LOGE,
                 FL("vos_mem_alloc failed "));
            return eHAL_STATUS_FAILED_ALLOC;
        }
        vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);

        pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
        pReq->sessionId = pAdapter->sessionId;
        pReq->rssiMonitorCbContext = hdd_ctx;
        control = nla_get_u32(tb[PARAM_CONTROL]);
        vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);

        hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
                        pReq->requestId, pReq->sessionId, control);

        if (control == QCA_WLAN_RSSI_MONITORING_START) {
                if (!tb[PARAM_MIN_RSSI]) {
                        hddLog(LOGE, FL("attr min rssi failed"));
                        goto fail;
                }

                if (!tb[PARAM_MAX_RSSI]) {
                        hddLog(LOGE, FL("attr max rssi failed"));
                        goto fail;
                }

                pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
                pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
                pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;

                if (!(pReq->minRssi < pReq->maxRssi)) {
                        hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
                                        pReq->minRssi, pReq->maxRssi);
                        goto fail;
                }
                hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
                       pReq->minRssi, pReq->maxRssi);
                status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);

        }
        else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
                pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
                status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
        }
        else {
                hddLog(LOGE, FL("Invalid control cmd: %d"), control);
                goto fail;
        }

        if (!HAL_STATUS_SUCCESS(status)) {
                hddLog(LOGE,
                        FL("sme_set_rssi_monitoring failed(err=%d)"), status);
                goto fail;
        }

        return 0;
fail:
        vos_mem_free(pReq);
        return -EINVAL;
}

/*
 * done with short names for the global vendor params
 * used by __wlan_hdd_cfg80211_monitor_rssi()
 */
#undef PARAM_MAX
#undef PARAM_CONTROL
#undef PARAM_REQUEST_ID
#undef PARAM_MAX_RSSI
#undef PARAM_MIN_RSSI

/**
 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
 * @wiphy:    wiphy structure pointer
 * @wdev:     Wireless device structure pointer
 * @data:     Pointer to the data received
 * @data_len: Length of @data
 *
 * Return: 0 on success; errno on failure
 */
static int
wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
                               const void *data, int data_len)
{
        int ret;

        vos_ssr_protect(__func__);
        ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
        vos_ssr_unprotect(__func__);

        return ret;
}

/**
 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
 * @hddctx: HDD context
 * @data: rssi breached event data
 *
 * This function reads the rssi breached event %data and fill in the skb with
 * NL attributes and send up the NL event.
 * This callback execute in atomic context and must not invoke any
 * blocking calls.
 *
 * Return: none
 */
void hdd_rssi_threshold_breached_cb(void *hddctx,
                                 struct rssi_breach_event *data)
{
        hdd_context_t *pHddCtx  = (hdd_context_t *)hddctx;
        int status;
        struct sk_buff *skb;

        ENTER();
        status = wlan_hdd_validate_context(pHddCtx);

        if (0 != status) {
                return;
        }

        if (!data) {
                hddLog(LOGE, FL("data is null"));
                return;
        }

        skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
                                  NULL,
#endif
                                  EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
                                  QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
                                  GFP_KERNEL);

        if (!skb) {
                hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
                return;
        }

        hddLog(LOG1, "Req Id: %u Current rssi: %d",
                        data->request_id, data->curr_rssi);
        hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
                        MAC_ADDR_ARRAY(data->curr_bssid.bytes));

        if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
                data->request_id) ||
            nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
                sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
            nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
                data->curr_rssi)) {
                hddLog(LOGE, FL("nla put fail"));
                goto fail;
        }

        cfg80211_vendor_event(skb, GFP_KERNEL);
        return;

fail:
        kfree_skb(skb);
        return;
}



/**
 * __wlan_hdd_cfg80211_setband() - set band
 * @wiphy: Pointer to wireless phy
 * @wdev: Pointer to wireless device
 * @data: Pointer to data
 * @data_len: Data length
 *
 * Return: 0 on success, negative errno on failure
 */
static int
__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
                            struct wireless_dev *wdev,
                            const void *data,
                            int data_len)
{
    struct net_device *dev = wdev->netdev;
    hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
    struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
    int ret;
    static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
                = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};

    ENTER();

    ret = wlan_hdd_validate_context(hdd_ctx);
    if (0 != ret) {
        hddLog(LOGE, FL("HDD context is not valid"));
        return ret;
    }

    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
                  policy)) {
        hddLog(LOGE, FL("Invalid ATTR"));
        return -EINVAL;
    }

    if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
        hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
        return -EINVAL;
    }

    hdd_ctx->isSetBandByNL = TRUE;
    ret = hdd_setBand(dev,
                       nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
    hdd_ctx->isSetBandByNL = FALSE;

    EXIT();
    return ret;
}

/**
 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
 * @wiphy:    wiphy structure pointer
 * @wdev:     Wireless device structure pointer
 * @data:     Pointer to the data received
 * @data_len: Length of @data
 *
 * Return: 0 on success; errno on failure
 */
static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
                                     struct wireless_dev *wdev,
                                     const void *data,
                                     int data_len)
{
    int ret = 0;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_setband(wiphy,
                    wdev, data, data_len);
    vos_ssr_unprotect(__func__);

    return ret;
}

#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
/**
 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
 * @hdd_ctx: HDD context
 * @request_id: [input] request id
 * @pattern_id: [output] pattern id
 *
 * This function loops through request id to pattern id array
 * if the slot is available, store the request id and return pattern id
 * if entry exists, return the pattern id
 *
 * Return: 0 on success and errno on failure
 */
static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
        uint32_t request_id,
        uint8_t *pattern_id)
{
    uint32_t i;

    mutex_lock(&hdd_ctx->op_ctx.op_lock);
    for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
    {
        if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
        {
            hdd_ctx->op_ctx.op_table[i].request_id = request_id;
            *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
            mutex_unlock(&hdd_ctx->op_ctx.op_lock);
            return 0;
        } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
                request_id) {
            *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
            mutex_unlock(&hdd_ctx->op_ctx.op_lock);
            return 0;
        }
    }
    mutex_unlock(&hdd_ctx->op_ctx.op_lock);
    return -EINVAL;
}

/**
 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
 * @hdd_ctx: HDD context
 * @request_id: [input] request id
 * @pattern_id: [output] pattern id
 *
 * This function loops through request id to pattern id array
 * reset request id to 0 (slot available again) and
 * return pattern id
 *
 * Return: 0 on success and errno on failure
 */
static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
        uint32_t request_id,
        uint8_t *pattern_id)
{
    uint32_t i;

    mutex_lock(&hdd_ctx->op_ctx.op_lock);
    for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
    {
        if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
        {
            hdd_ctx->op_ctx.op_table[i].request_id = 0;
            *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
            mutex_unlock(&hdd_ctx->op_ctx.op_lock);
            return 0;
        }
    }
    mutex_unlock(&hdd_ctx->op_ctx.op_lock);
    return -EINVAL;
}


/*
 * define short names for the global vendor params
 * used by __wlan_hdd_cfg80211_offloaded_packets()
 */
#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
#define PARAM_REQUEST_ID \
    QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
#define PARAM_CONTROL \
    QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
#define PARAM_IP_PACKET \
    QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
#define PARAM_SRC_MAC_ADDR \
    QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
#define PARAM_DST_MAC_ADDR \
    QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD

/**
 * wlan_hdd_add_tx_ptrn() - add tx pattern
 * @adapter: adapter pointer
 * @hdd_ctx: hdd context
 * @tb: nl attributes
 *
 * This function reads the NL attributes and forms a AddTxPtrn message
 * posts it to SME.
 *
 */
static int
wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
        struct nlattr **tb)
{
    struct sSirAddPeriodicTxPtrn *add_req;
    eHalStatus status;
    uint32_t request_id, ret, len;
    uint8_t pattern_id = 0;
    v_MACADDR_t dst_addr;
    uint16_t eth_type = htons(ETH_P_IP);

    if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
    {
        hddLog(LOGE, FL("Not in Connected state!"));
        return -ENOTSUPP;
    }

    add_req = vos_mem_malloc(sizeof(*add_req));
    if (!add_req)
    {
        hddLog(LOGE, FL("memory allocation failed"));
        return -ENOMEM;
    }

    /* Parse and fetch request Id */
    if (!tb[PARAM_REQUEST_ID])
    {
        hddLog(LOGE, FL("attr request id failed"));
        goto fail;
    }

    request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
    hddLog(LOG1, FL("Request Id: %u"), request_id);
    if (request_id == 0)
    {
        hddLog(LOGE, FL("request_id cannot be zero"));
        goto fail;
    }

    if (!tb[PARAM_PERIOD])
    {
        hddLog(LOGE, FL("attr period failed"));
        goto fail;
    }
    add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
    hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
    if (add_req->usPtrnIntervalMs == 0)
    {
        hddLog(LOGE, FL("Invalid interval zero, return failure"));
        goto fail;
    }

    if (!tb[PARAM_SRC_MAC_ADDR])
    {
        hddLog(LOGE, FL("attr source mac address failed"));
        goto fail;
    }
    nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
            VOS_MAC_ADDR_SIZE);
    hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
            MAC_ADDR_ARRAY(add_req->macAddress));

    if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
                VOS_MAC_ADDR_SIZE))
    {
        hddLog(LOGE,
            FL("input src mac address and connected ap bssid are different"));
        goto fail;
    }

    if (!tb[PARAM_DST_MAC_ADDR])
    {
        hddLog(LOGE, FL("attr dst mac address failed"));
        goto fail;
    }
    nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
    hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
            MAC_ADDR_ARRAY(dst_addr.bytes));

    if (!tb[PARAM_IP_PACKET])
    {
        hddLog(LOGE, FL("attr ip packet failed"));
        goto fail;
    }
    add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
    hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);

    if (add_req->ucPtrnSize < 0 ||
            add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
                HDD_ETH_HEADER_LEN))
    {
        hddLog(LOGE, FL("Invalid IP packet len: %d"),
                add_req->ucPtrnSize);
        goto fail;
    }

    len = 0;
    vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
    len += VOS_MAC_ADDR_SIZE;
    vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
            VOS_MAC_ADDR_SIZE);
    len += VOS_MAC_ADDR_SIZE;
    vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
    len += 2;

    /*
     * This is the IP packet, add 14 bytes Ethernet (802.3) header
     * ------------------------------------------------------------
     * | 14 bytes Ethernet (802.3) header | IP header and payload |
     * ------------------------------------------------------------
     */
    vos_mem_copy(&add_req->ucPattern[len],
            nla_data(tb[PARAM_IP_PACKET]),
            add_req->ucPtrnSize);
    add_req->ucPtrnSize += len;

    VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
            add_req->ucPattern, add_req->ucPtrnSize);

    ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
    if (ret)
    {
        hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
        goto fail;
    }
    add_req->ucPtrnId = pattern_id;
    hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);

    status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
    if (!HAL_STATUS_SUCCESS(status))
    {
        hddLog(LOGE,
                FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
        goto fail;
    }

    EXIT();
    vos_mem_free(add_req);
    return 0;

fail:
    vos_mem_free(add_req);
    return -EINVAL;
}

/**
 * wlan_hdd_del_tx_ptrn() - delete tx pattern
 * @adapter: adapter pointer
 * @hdd_ctx: hdd context
 * @tb: nl attributes
 *
 * This function reads the NL attributes and forms a DelTxPtrn message
 * posts it to SME.
 *
 */
static int
wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
        struct nlattr **tb)
{
    struct sSirDelPeriodicTxPtrn *del_req;
    eHalStatus status;
    uint32_t request_id, ret;
    uint8_t pattern_id = 0;

    /* Parse and fetch request Id */
    if (!tb[PARAM_REQUEST_ID])
    {
        hddLog(LOGE, FL("attr request id failed"));
        return -EINVAL;
    }
    request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
    if (request_id == 0)
    {
        hddLog(LOGE, FL("request_id cannot be zero"));
        return -EINVAL;
    }

    ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
    if (ret)
    {
        hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
        return -EINVAL;
    }

    del_req = vos_mem_malloc(sizeof(*del_req));
    if (!del_req)
    {
        hddLog(LOGE, FL("memory allocation failed"));
        return -ENOMEM;
    }

    vos_mem_set(del_req, sizeof(*del_req), 0);
    vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
            VOS_MAC_ADDR_SIZE);
    hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
    del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
    hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
         request_id, pattern_id, del_req->ucPatternIdBitmap);

    status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
    if (!HAL_STATUS_SUCCESS(status))
    {
        hddLog(LOGE,
                FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
        goto fail;
    }

    EXIT();
    vos_mem_free(del_req);
    return 0;

fail:
    vos_mem_free(del_req);
    return -EINVAL;
}


/**
 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
 * @wiphy: Pointer to wireless phy
 * @wdev: Pointer to wireless device
 * @data: Pointer to data
 * @data_len: Data length
 *
 * Return: 0 on success, negative errno on failure
 */
static int
__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
        struct wireless_dev *wdev,
        const void *data,
        int data_len)
{
    struct net_device *dev = wdev->netdev;
    hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
    struct nlattr *tb[PARAM_MAX + 1];
    uint8_t control;
    int ret;
    static const struct nla_policy policy[PARAM_MAX + 1] =
    {
        [PARAM_REQUEST_ID] = { .type = NLA_U32 },
        [PARAM_CONTROL] = { .type = NLA_U32 },
        [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
            .len = VOS_MAC_ADDR_SIZE },
        [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
            .len = VOS_MAC_ADDR_SIZE },
        [PARAM_PERIOD] = { .type = NLA_U32 },
    };

    ENTER();

    ret = wlan_hdd_validate_context(hdd_ctx);
    if (0 != ret)
    {
        hddLog(LOGE, FL("HDD context is not valid"));
        return ret;
    }

    if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
    {
        hddLog(LOGE,
            FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
        return -ENOTSUPP;
    }

    if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
    {
        hddLog(LOGE, FL("Invalid ATTR"));
        return -EINVAL;
    }

    if (!tb[PARAM_CONTROL])
    {
        hddLog(LOGE, FL("attr control failed"));
        return -EINVAL;
    }
    control = nla_get_u32(tb[PARAM_CONTROL]);
    hddLog(LOG1, FL("Control: %d"), control);

    if (control == WLAN_START_OFFLOADED_PACKETS)
        return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
    else if (control == WLAN_STOP_OFFLOADED_PACKETS)
        return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
    else
    {
        hddLog(LOGE, FL("Invalid control: %d"), control);
        return -EINVAL;
    }
}

/*
 * done with short names for the global vendor params
 * used by __wlan_hdd_cfg80211_offloaded_packets()
 */
#undef PARAM_MAX
#undef PARAM_REQUEST_ID
#undef PARAM_CONTROL
#undef PARAM_IP_PACKET
#undef PARAM_SRC_MAC_ADDR
#undef PARAM_DST_MAC_ADDR
#undef PARAM_PERIOD

/**
 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
 * @wiphy:    wiphy structure pointer
 * @wdev:     Wireless device structure pointer
 * @data:     Pointer to the data received
 * @data_len: Length of @data
 *
 * Return: 0 on success; errno on failure
 */
static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
        struct wireless_dev *wdev,
        const void *data,
        int data_len)
{
    int ret = 0;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
            wdev, data, data_len);
    vos_ssr_unprotect(__func__);

    return ret;
}
#endif

static const struct
nla_policy
qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
    [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
        .type = NLA_BINARY,
        .len = HDD_MAC_ADDR_LEN},
};

/**
 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
 * get link properties like nss, rate flags and operating frequency for
 * the connection with the given peer.
 * @wiphy:    WIPHY structure pointer
 * @wdev:     Wireless device structure pointer
 * @data:     Pointer to the data received
 * @data_len: Length of the data received
 *
 * This function return the above link properties on success.
 *
 * Return: 0 on success and errno on failure
 */
static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
        struct wireless_dev *wdev,
        const void *data,
        int data_len)
{
    hdd_context_t       *hdd_ctx = wiphy_priv(wiphy);
    struct net_device   *dev = wdev->netdev;
    hdd_adapter_t       *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_station_ctx_t   *hdd_sta_ctx;
    struct nlattr       *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
    uint8_t             peer_mac[VOS_MAC_ADDR_SIZE];
    uint32_t            sta_id;
    struct sk_buff      *reply_skb;
    uint32_t            rate_flags = 0;
    uint8_t             nss;
    uint8_t             final_rate_flags = 0;
    uint32_t            freq;
    v_CONTEXT_t pVosContext = NULL;
    ptSapContext pSapCtx = NULL;

    if (0 != wlan_hdd_validate_context(hdd_ctx)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
        return -EINVAL;
    }

    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
                qca_wlan_vendor_attr_policy)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
        return -EINVAL;
    }

    if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                FL("Attribute peerMac not provided for mode=%d"),
                adapter->device_mode);
        return -EINVAL;
    }

    if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    FL("Attribute peerMac is invalid=%d"),
                    adapter->device_mode);
            return -EINVAL;
    }

    memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
            sizeof(peer_mac));
    hddLog(VOS_TRACE_LEVEL_INFO,
            FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
            MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);

    if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
            adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
        hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
        if ((hdd_sta_ctx->conn_info.connState !=
                    eConnectionState_Associated) ||
                !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
                    VOS_MAC_ADDRESS_LEN)) {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    FL("Not Associated to mac "MAC_ADDRESS_STR),
                    MAC_ADDR_ARRAY(peer_mac));
            return -EINVAL;
        }

        nss  = 1; //pronto supports only one spatial stream
        freq = vos_chan_to_freq(
                hdd_sta_ctx->conn_info.operationChannel);
        rate_flags = hdd_sta_ctx->conn_info.rate_flags;

    } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
            adapter->device_mode == WLAN_HDD_SOFTAP) {

          pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
          pSapCtx = VOS_GET_SAP_CB(pVosContext);
          if(pSapCtx == NULL){
                 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   FL("psapCtx is NULL"));
                     return -ENOENT;
          }


        for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
            if (pSapCtx->aStaInfo[sta_id].isUsed &&
                    !vos_is_macaddr_broadcast(
                        &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
                    vos_mem_compare(
                        &pSapCtx->aStaInfo[sta_id].macAddrSTA,
                        peer_mac, VOS_MAC_ADDRESS_LEN))
                break;
        }

        if (WLAN_MAX_STA_COUNT == sta_id) {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    FL("No active peer with mac="MAC_ADDRESS_STR),
                    MAC_ADDR_ARRAY(peer_mac));
            return -EINVAL;
        }

        nss  = 1; //pronto supports only one spatial stream
        freq = vos_chan_to_freq(
                (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
        rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
    } else {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                FL("Not Associated! with mac"MAC_ADDRESS_STR),
                MAC_ADDR_ARRAY(peer_mac));
        return -EINVAL;
    }

    if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
        if (rate_flags & eHAL_TX_RATE_VHT80) {
            final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
	!defined(WITH_BACKPORTS)
            final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
#endif
        } else if (rate_flags & eHAL_TX_RATE_VHT40) {
            final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
	!defined(WITH_BACKPORTS)
            final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
#endif
        } else if (rate_flags & eHAL_TX_RATE_VHT20) {
            final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
        } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
            final_rate_flags |= RATE_INFO_FLAGS_MCS;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
	!defined(WITH_BACKPORTS)
            if (rate_flags & eHAL_TX_RATE_HT40)
                final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
#endif
        }

        if (rate_flags & eHAL_TX_RATE_SGI) {
            if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
                final_rate_flags |= RATE_INFO_FLAGS_MCS;
            final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
        }
    }

    reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
            sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);

    if (NULL == reply_skb) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                FL("getLinkProperties: skb alloc failed"));
        return -EINVAL;
    }

    if (nla_put_u8(reply_skb,
                QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
                nss) ||
            nla_put_u8(reply_skb,
                QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
                final_rate_flags) ||
            nla_put_u32(reply_skb,
                QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
                freq)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
        kfree_skb(reply_skb);
        return -EINVAL;
    }

    return cfg80211_vendor_cmd_reply(reply_skb);
}

#define BEACON_MISS_THRESH_2_4 \
        QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
#define BEACON_MISS_THRESH_5_0 \
        QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
        QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS

/*
 * hdd_set_qpower() - Process the qpower command and invoke the SME api
 * @hdd_ctx: hdd context
 * @enable: Value received in the command, 1 for disable and 2 for enable
 *
 * Return: void
 */
static void hdd_set_qpower(hdd_context_t *hdd_ctx, uint8_t enable)
{
    if (!hdd_ctx) {
        hddLog(LOGE, "hdd_ctx NULL");
        return;
    }

    sme_set_qpower(hdd_ctx->hHal, enable);
}

/**
 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
 * vendor command
 *
 * @wiphy: wiphy device pointer
 * @wdev: wireless device pointer
 * @data: Vendor command data buffer
 * @data_len: Buffer length
 *
 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
 *
 * Return: EOK or other error codes.
 */

static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
                            struct wireless_dev *wdev,
                            const void *data,
                            int data_len)
{
    struct net_device *dev = wdev->netdev;
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx  = wiphy_priv(wiphy);
    hdd_station_ctx_t *pHddStaCtx;
    struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
    tpSetWifiConfigParams pReq;
    tModifyRoamParamsReqParams modifyRoamParamsReq;
    eHalStatus status;
    int ret_val;
    uint8_t hb_thresh_val;
    uint8_t qpower;

    static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
                        [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
                        [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
                        [PARAM_GUARD_TIME] = { .type = NLA_U32},
                        [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
                                             { .type = NLA_U32},
                        [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
                        [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
    };

    ENTER();

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

    ret_val = wlan_hdd_validate_context(pHddCtx);
    if (ret_val) {
        return ret_val;
    }

    pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

    if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
               hddLog(LOGE, FL("Invalid ATTR"));
               return -EINVAL;
    }

    /* check the Wifi Capability */
    if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
         (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("WIFICONFIG not supported by Firmware"));
        return -EINVAL;
    }

    if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
        modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
        modifyRoamParamsReq.value =
        nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);

        if (eHAL_STATUS_SUCCESS !=
                sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
        {
            hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
            ret_val = -EINVAL;
        }
        return ret_val;
    }

    /* Moved this down in order to provide provision to set beacon
     * miss penalty count irrespective of connection state.
     */
    if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
                hddLog(LOGE, FL("Not in Connected state!"));
                return -ENOTSUPP;
    }

    pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));

    if (!pReq) {
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
             "%s: Not able to allocate memory for tSetWifiConfigParams",
             __func__);
       return eHAL_STATUS_E_MALLOC_FAILED;
   }

   vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);

   pReq->sessionId = pAdapter->sessionId;
   vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);

    if (tb[PARAM_MODULATED_DTIM]) {
       pReq->paramValue = nla_get_u32(
            tb[PARAM_MODULATED_DTIM]);
       hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
                                        pReq->paramValue);
       pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
       hdd_set_pwrparams(pHddCtx);
    if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
       hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));

       sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
                            iw_full_power_cbfn, pAdapter,
                            eSME_FULL_PWR_NEEDED_BY_HDD);
       }
       else
       {
            hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
       }
    }

    if (tb[PARAM_STATS_AVG_FACTOR]) {
        pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
        pReq->paramValue = nla_get_u16(
            tb[PARAM_STATS_AVG_FACTOR]);
        hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
                                        pReq->paramType, pReq->paramValue);
        status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);

        if (eHAL_STATUS_SUCCESS != status)
        {
            vos_mem_free(pReq);
            pReq = NULL;
            ret_val = -EPERM;
            return ret_val;
        }
    }


    if (tb[PARAM_GUARD_TIME]) {
        pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
        pReq->paramValue = nla_get_u32(
            tb[PARAM_GUARD_TIME]);
       hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
                                        pReq->paramType, pReq->paramValue);
        status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);

        if (eHAL_STATUS_SUCCESS != status)
        {
            vos_mem_free(pReq);
            pReq = NULL;
            ret_val = -EPERM;
            return ret_val;
        }

    }

    if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
       hb_thresh_val = nla_get_u8(
                      tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);

       hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
                                              hb_thresh_val);
       ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
                     WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
                     NULL, eANI_BOOLEAN_FALSE);

       status = sme_update_hb_threshold(
                        (WLAN_HDD_GET_CTX(pAdapter))->hHal,
                         WNI_CFG_HEART_BEAT_THRESHOLD,
                         hb_thresh_val, eCSR_BAND_24);
       if (eHAL_STATUS_SUCCESS != status) {
           hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
           vos_mem_free(pReq);
           pReq = NULL;
           return -EPERM;
       }
    }

    if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
       hb_thresh_val = nla_get_u8(
                     tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);

       hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
                                            hb_thresh_val);
       ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
                     WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
                     NULL, eANI_BOOLEAN_FALSE);

       status = sme_update_hb_threshold(
                        (WLAN_HDD_GET_CTX(pAdapter))->hHal,
                         WNI_CFG_HEART_BEAT_THRESHOLD,
                         hb_thresh_val, eCSR_BAND_5G);
       if (eHAL_STATUS_SUCCESS != status) {
           hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
           vos_mem_free(pReq);
           pReq = NULL;
           return -EPERM;
       }
    }

    if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]) {
       qpower = nla_get_u8(
              tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]);

       if(qpower > 1) {
           hddLog(LOGE, "Invalid QPOWER value %d", qpower);
           vos_mem_free(pReq);
           pReq = NULL;
           return -EINVAL;
       }
       /* FW is expacting qpower as 1 for Disable and 2 for enable */
       qpower++;
       hdd_set_qpower(pHddCtx, qpower);
    }

    EXIT();
    return ret_val;
}

/**
 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
 * vendor command
 *
 * @wiphy: wiphy device pointer
 * @wdev: wireless device pointer
 * @data: Vendor command data buffer
 * @data_len: Buffer length
 *
 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
 *
 * Return: EOK or other error codes.
 */
static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
                            struct wireless_dev *wdev,
                            const void *data,
                            int data_len)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
                             data, data_len);
    vos_ssr_unprotect(__func__);

    return ret;
}

/*
 * define short names for the global vendor params
 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
 */
#define STATS_SET_INVALID \
    QCA_ATTR_NUD_STATS_SET_INVALID
#define STATS_SET_START \
    QCA_ATTR_NUD_STATS_SET_START
#define STATS_GW_IPV4 \
    QCA_ATTR_NUD_STATS_GW_IPV4
#define STATS_SET_MAX \
    QCA_ATTR_NUD_STATS_SET_MAX

const struct nla_policy
qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
{
    [STATS_SET_START] = {.type = NLA_FLAG },
    [STATS_GW_IPV4] = {.type = NLA_U32 },
};

/**
 * hdd_set_nud_stats_cb() - hdd callback api to get status
 * @data: pointer to adapter
 * @rsp: status
 *
 * Return: None
 */
static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
{

   hdd_adapter_t *adapter = (hdd_adapter_t *)data;

   if (NULL == adapter)
      return;

   if (VOS_STATUS_SUCCESS == rsp) {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                "%s success received STATS_SET_START", __func__);
   } else {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "%s STATS_SET_START Failed!!", __func__);
   }
   return;
}

/**
 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
 * @wiphy: pointer to wireless wiphy structure.
 * @wdev: pointer to wireless_dev structure.
 * @data: pointer to apfind configuration data.
 * @data_len: the length in byte of apfind data.
 *
 * This is called when wlan driver needs to send arp stats to
 * firmware.
 *
 * Return: An error code or 0 on success.
 */
static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
        struct wireless_dev *wdev,
        const void *data, int data_len)
{
    struct nlattr *tb[STATS_SET_MAX + 1];
    struct net_device   *dev = wdev->netdev;
    hdd_adapter_t       *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
    v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
    setArpStatsParams arp_stats_params;
    int err = 0;

    ENTER();

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

    if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s NUD_DEBUG feature not supported by firmware!!", __func__);
        return -EINVAL;
    }

    err = nla_parse(tb, STATS_SET_MAX, data, data_len,
                    qca_wlan_vendor_set_nud_stats);
    if (err)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s STATS_SET_START ATTR", __func__);
        return err;
    }

    if (tb[STATS_SET_START])
    {
        if (!tb[STATS_GW_IPV4]) {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s STATS_SET_START CMD", __func__);
            return -EINVAL;
        }
        arp_stats_params.flag = true;
        arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
    } else {
        arp_stats_params.flag = false;
    }
    if (arp_stats_params.flag)
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  "%s STATS_SET_START Cleared!!", __func__);
    vos_mem_zero(&adapter->hdd_stats.hddArpStats,
                 sizeof(adapter->hdd_stats.hddArpStats));

    arp_stats_params.pkt_type = 1; // ARP packet type

    if (arp_stats_params.flag) {
       hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
       WLANTL_SetARPFWDatapath(pVosContext, true);
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                 "%s Set FW in data path for ARP with tgt IP :%d",
                 __func__,  hdd_ctx->track_arp_ip);
    }
    else {
       WLANTL_SetARPFWDatapath(pVosContext, false);
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                 "%s Remove FW from data path", __func__);
    }

    arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
    arp_stats_params.data_ctx = adapter;

    if (eHAL_STATUS_SUCCESS !=
        sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s STATS_SET_START CMD Failed!!", __func__);
        return -EINVAL;
    }

    EXIT();

    return err;
}

/**
 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
 * @wiphy: pointer to wireless wiphy structure.
 * @wdev: pointer to wireless_dev structure.
 * @data: pointer to apfind configuration data.
 * @data_len: the length in byte of apfind data.
 *
 * This is called when wlan driver needs to send arp stats to
 * firmware.
 *
 * Return: An error code or 0 on success.
 */
static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
        struct wireless_dev *wdev,
        const void *data, int data_len)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
    vos_ssr_unprotect(__func__);

    return ret;
}
#undef STATS_SET_INVALID
#undef STATS_SET_START
#undef STATS_GW_IPV4
#undef STATS_SET_MAX

/*
 * define short names for the global vendor params
 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
 */
#define STATS_GET_INVALID \
    QCA_ATTR_NUD_STATS_SET_INVALID
#define COUNT_FROM_NETDEV \
    QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
#define COUNT_TO_LOWER_MAC \
    QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
#define RX_COUNT_BY_LOWER_MAC \
    QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
#define COUNT_TX_SUCCESS \
    QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
#define RSP_RX_COUNT_BY_LOWER_MAC \
    QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
#define RSP_RX_COUNT_BY_UPPER_MAC \
    QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
#define RSP_COUNT_TO_NETDEV \
    QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
#define RSP_COUNT_OUT_OF_ORDER_DROP \
    QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
#define AP_LINK_ACTIVE \
    QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
#define AP_LINK_DAD \
    QCA_ATTR_NUD_STATS_AP_LINK_DAD
#define STATS_GET_MAX \
    QCA_ATTR_NUD_STATS_GET_MAX

const struct nla_policy
qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
{
    [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
    [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
    [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
    [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
    [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
    [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
    [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
    [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
    [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
    [AP_LINK_DAD] = {.type = NLA_FLAG },
};

static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
{

    hdd_adapter_t *adapter = (hdd_adapter_t *)data;
    hdd_context_t *hdd_ctx;
    struct hdd_nud_stats_context *context;
    int status;

    ENTER();

    if (NULL == adapter)
        return;

    if (!rsp) {
        hddLog(LOGE, FL("data is null"));
        return;
    }

    hdd_ctx = WLAN_HDD_GET_CTX(adapter);
    status = wlan_hdd_validate_context(hdd_ctx);
    if (0 != status) {
        return;
    }

    adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
    adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
    adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
    adapter->dad |= rsp->dad;

    spin_lock(&hdd_context_lock);
    context = &hdd_ctx->nud_stats_context;
    complete(&context->response_event);
    spin_unlock(&hdd_context_lock);

    return;
}
static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
        struct wireless_dev *wdev,
        const void *data, int data_len)
{
    int err = 0;
    unsigned long rc;
    struct hdd_nud_stats_context *context;
    struct net_device   *dev = wdev->netdev;
    hdd_adapter_t       *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
    getArpStatsParams arp_stats_params;
    struct sk_buff *skb;

    ENTER();

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

    arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
    arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
    arp_stats_params.data_ctx = adapter;

    spin_lock(&hdd_context_lock);
    context = &hdd_ctx->nud_stats_context;
    INIT_COMPLETION(context->response_event);
    spin_unlock(&hdd_context_lock);

    if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s NUD_DEBUG feature not supported by firmware!!", __func__);
        return -EINVAL;
    }

    if (eHAL_STATUS_SUCCESS !=
        sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s STATS_SET_START CMD Failed!!", __func__);
        return -EINVAL;
    }

    rc = wait_for_completion_timeout(&context->response_event,
            msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
    if (!rc)
    {
        hddLog(LOGE,
            FL("Target response timed out request "));
        return -ETIMEDOUT;
    }

    skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
            WLAN_NUD_STATS_LEN);
    if (!skb)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
                __func__);
        return -ENOMEM;
    }

    if (nla_put_u16(skb, COUNT_FROM_NETDEV,
            adapter->hdd_stats.hddArpStats.txCount) ||
            nla_put_u16(skb, COUNT_TO_LOWER_MAC,
            adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
            nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
            adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
            nla_put_u16(skb, COUNT_TX_SUCCESS,
            adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
            nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
            adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
            nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
            adapter->hdd_stats.hddArpStats.rxCount) ||
            nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
            adapter->hdd_stats.hddArpStats.rxDelivered) ||
            nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
            adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
            hddLog(LOGE, FL("nla put fail"));
            kfree_skb(skb);
            return -EINVAL;
    }
    if (adapter->con_status)
        nla_put_flag(skb, AP_LINK_ACTIVE);
    if (adapter->dad)
        nla_put_flag(skb, AP_LINK_DAD);

    cfg80211_vendor_cmd_reply(skb);
    return err;
}

static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
        struct wireless_dev *wdev,
        const void *data, int data_len)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
    vos_ssr_unprotect(__func__);

    return ret;
}

#undef QCA_ATTR_NUD_STATS_SET_INVALID
#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
#undef QCA_ATTR_NUD_STATS_GET_MAX



#ifdef WLAN_FEATURE_APFIND
/**
 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
 * @wiphy: pointer to wireless wiphy structure.
 * @wdev: pointer to wireless_dev structure.
 * @data: pointer to apfind configuration data.
 * @data_len: the length in byte of apfind data.
 *
 * This is called when wlan driver needs to send APFIND configurations to
 * firmware.
 *
 * Return: An error code or 0 on success.
 */
static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
        struct wireless_dev *wdev,
        const void *data, int data_len)
{
    struct sme_ap_find_request_req  apfind_req;
    VOS_STATUS      status;
    int ret_val;
    hdd_context_t *hdd_ctx = wiphy_priv(wiphy);

    ENTER();

    ret_val = wlan_hdd_validate_context(hdd_ctx);
    if (ret_val)
        return ret_val;

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

    apfind_req.request_data_len = data_len;
    apfind_req.request_data = data;

    status = sme_apfind_set_cmd(&apfind_req);
    if (VOS_STATUS_SUCCESS != status) {
        ret_val = -EIO;
    }
    return ret_val;
}

/**
 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
 * @wiphy: pointer to wireless wiphy structure.
 * @wdev: pointer to wireless_dev structure.
 * @data: pointer to apfind configuration data.
 * @data_len: the length in byte of apfind data.
 *
 * This is called when wlan driver needs to send APFIND configurations to
 * firmware.
 *
 * Return: An error code or 0 on success.
 */
static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
        struct wireless_dev *wdev,
        const void *data, int data_len)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
    vos_ssr_unprotect(__func__);

    return ret;
}
#endif /* WLAN_FEATURE_APFIND */
const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
{
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV |
                 WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_firmware_roaming
    },

    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV |
                 WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_nan_request
    },

#ifdef WLAN_FEATURE_LINK_LAYER_STATS
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
            WIPHY_VENDOR_CMD_NEED_NETDEV |
            WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_ll_stats_clear
    },

    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
            WIPHY_VENDOR_CMD_NEED_NETDEV |
            WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_ll_stats_set
    },

    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
            WIPHY_VENDOR_CMD_NEED_NETDEV |
            WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_ll_stats_get
    },
#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
#ifdef WLAN_FEATURE_EXTSCAN
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV |
                 WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_extscan_start
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV |
                 WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_extscan_stop
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV,
        .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV |
                 WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_extscan_get_capabilities
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV |
                 WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_extscan_get_cached_results
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV |
                 WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV |
                 WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
    },
#endif /* WLAN_FEATURE_EXTSCAN */
/*EXT TDLS*/
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV |
                 WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_exttdls_enable
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV |
                 WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_exttdls_disable
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV,
        .doit = wlan_hdd_cfg80211_exttdls_get_status
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV,
        .doit = wlan_hdd_cfg80211_get_supported_features
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV,
        .doit = wlan_hdd_cfg80211_disable_dfs_channels
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV,
        .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV,
        .doit = wlan_hdd_cfg80211_get_concurrency_matrix
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV |
                 WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_get_fw_mem_dump
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
            WIPHY_VENDOR_CMD_NEED_NETDEV |
            WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_setband
    },
    {
         .info.vendor_id = QCA_NL80211_VENDOR_ID,
         .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
         .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                  WIPHY_VENDOR_CMD_NEED_NETDEV,
         .doit = wlan_hdd_cfg80211_wifi_logger_start
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV|
                  WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_get_wifi_info
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV |
                 WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV |
                 WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_monitor_rssi
    },
#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
            WIPHY_VENDOR_CMD_NEED_NETDEV |
            WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_offloaded_packets
    },
#endif
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
            WIPHY_VENDOR_CMD_NEED_NETDEV |
            WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_get_link_properties
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV |
                 WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_wifi_configuration_set
    },
#ifdef WLAN_FEATURE_APFIND
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
            WIPHY_VENDOR_CMD_NEED_NETDEV,
        .doit = wlan_hdd_cfg80211_apfind_cmd
    },
#endif /* WLAN_FEATURE_APFIND */
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
            WIPHY_VENDOR_CMD_NEED_NETDEV |
            WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_set_nud_stats
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
            WIPHY_VENDOR_CMD_NEED_NETDEV |
            WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_get_nud_stats
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
            WIPHY_VENDOR_CMD_NEED_NETDEV |
            WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = hdd_cfg80211_get_station_cmd
    },
};

/* vendor specific events */
static const
struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
{
#ifdef FEATURE_WLAN_CH_AVOID
    {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
    },
#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
#ifdef WLAN_FEATURE_LINK_LAYER_STATS
    {
        /* Index = 1*/
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
    },
    {
        /* Index = 2*/
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
    },
    {
        /* Index = 3*/
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
    },
    {
        /* Index = 4*/
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
    },
    {
        /* Index = 5*/
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
    },
    {
        /* Index = 6*/
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
    },
#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
#ifdef WLAN_FEATURE_EXTSCAN
    {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
    },
    {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
    },
    {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
    },
    {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
    },
    {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
    },
    {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
    },
    {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
    },
    {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
    },
    {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
    },
    {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
    },
#endif /* WLAN_FEATURE_EXTSCAN */
/*EXT TDLS*/
    {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
    },
    [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
    },


    [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
    },

    {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
    },
    [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
    },
    [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
    },
    [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
    },
    [QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_HANG,
    },
    [QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX] = {
         .vendor_id = QCA_NL80211_VENDOR_ID,
         .subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
    },
};

/*
 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
 * This function is called by hdd_wlan_startup()
 * during initialization.
 * This function is used to allocate wiphy structure.
 */
struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
{
    struct wiphy *wiphy;
    ENTER();
    /*
     *   Create wiphy device
     */
    wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);

    if (!wiphy)
    {
        /* Print error and jump into err label and free the memory */
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
        return NULL;
    }


    return wiphy;
}

#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
    defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
/**
 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
 * @wiphy: pointer to wiphy
 * @config: pointer to config
 *
 * Return: None
 */
static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
                                                 hdd_config_t *config)
{
    wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
    if (config->max_sched_scan_plan_interval)
        wiphy->max_sched_scan_plan_interval =
            config->max_sched_scan_plan_interval;
    if (config->max_sched_scan_plan_iterations)
        wiphy->max_sched_scan_plan_iterations =
               config->max_sched_scan_plan_iterations;
}
#else
static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
                                                 hdd_config_t *config)
{
}
#endif

/*
 * FUNCTION: wlan_hdd_cfg80211_update_band
 * This function is called from the supplicant through a
 * private ioctl to change the band value
 */
int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
{
    int i, j;
    eNVChannelEnabledType channelEnabledState;

    ENTER();

    for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
    {

        if (NULL == wiphy->bands[i])
        {
           hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
                  __func__, i);
           continue;
        }

        for (j = 0; j < wiphy->bands[i]->n_channels; j++)
        {
            struct ieee80211_supported_band *band = wiphy->bands[i];

            channelEnabledState = vos_nv_getChannelEnabledState(
                                  band->channels[j].hw_value);

            if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
            {
                band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
                continue;
            }
            else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
            {
                band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
                continue;
            }

            if (NV_CHANNEL_DISABLE == channelEnabledState ||
                NV_CHANNEL_INVALID == channelEnabledState)
            {
                band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
            }
            else if (NV_CHANNEL_DFS == channelEnabledState)
            {
                band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
                band->channels[j].flags |= IEEE80211_CHAN_RADAR;
            }
            else
            {
                band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
                                             |IEEE80211_CHAN_RADAR);
            }
        }
    }
    return 0;
}

/**
 * hdd_add_channel_switch_support()- Adds Channel Switch flag if supported
 * @wiphy: Pointer to the wiphy.
 *
 * This Function adds Channel Switch support flag, if channel switch is
 * supported by kernel.
 * Return: void.
 */
#ifdef CHANNEL_SWITCH_SUPPORTED
static inline
void hdd_add_channel_switch_support(struct wiphy *wiphy)
{
   wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
   wiphy->max_num_csa_counters = WLAN_HDD_MAX_NUM_CSA_COUNTERS;
}
#else
static inline
void hdd_add_channel_switch_support(struct wiphy *wiphy)
{
}
#endif

/*
 * FUNCTION: wlan_hdd_cfg80211_init
 * This function is called by hdd_wlan_startup()
 * during initialization.
 * This function is used to initialize and register wiphy structure.
 */
int wlan_hdd_cfg80211_init(struct device *dev,
                               struct wiphy *wiphy,
                               hdd_config_t *pCfg
                               )
{
    int i, j;
    hdd_context_t *pHddCtx = wiphy_priv(wiphy);

    ENTER();

    /* Now bind the underlying wlan device with wiphy */
    set_wiphy_dev(wiphy, dev);

    wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;

#ifndef CONFIG_ENABLE_LINUX_REG
    /* the flag for the other case would be initialzed in
       vos_init_wiphy_from_nv_bin */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
    wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
#else
    wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
#endif
#endif

    /* This will disable updating of NL channels from passive to
     * active if a beacon is received on passive channel. */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
    wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
#else
    wiphy->flags |=   WIPHY_FLAG_DISABLE_BEACON_HINTS;
#endif

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
    wiphy->wowlan = &wowlan_support_cfg80211_init;
#else
    wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT;
    wiphy->wowlan.n_patterns = WOWL_MAX_PTRNS_ALLOWED;
    wiphy->wowlan.pattern_min_len = 1;
    wiphy->wowlan.pattern_max_len = WOWL_PTRN_MAX_SIZE;
#endif

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
    wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
                 |  WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
                 |  WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
                    | WIPHY_FLAG_OFFCHAN_TX;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
    wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
#else
     wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
#endif
#endif

#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
    if (pCfg->isFastTransitionEnabled
#ifdef FEATURE_WLAN_LFR
       || pCfg->isFastRoamIniFeatureEnabled
#endif
#ifdef FEATURE_WLAN_ESE
       || pCfg->isEseIniFeatureEnabled
#endif
    )
    {
        wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
    }
#endif
#ifdef FEATURE_WLAN_TDLS
    wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
                 |  WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
#endif
#ifdef FEATURE_WLAN_SCAN_PNO
    if (pCfg->configPNOScanSupport)
    {
        wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
        wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
        wiphy->max_match_sets       = SIR_PNO_MAX_SUPP_NETWORKS;
        wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
    }
#endif/*FEATURE_WLAN_SCAN_PNO*/

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
    wiphy->features |= NL80211_FEATURE_HT_IBSS;
#endif

#ifdef CONFIG_ENABLE_LINUX_REG
    /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
       driver can still register regulatory callback and
       it will get regulatory settings in wiphy->band[], but
       driver need to determine what to do with both
       regulatory settings */

    wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
#else
    wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
#endif

    wiphy->max_scan_ssids = MAX_SCAN_SSID;

    wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;

    wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;

    /* Supports STATION & AD-HOC modes right now */
    wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
                            | BIT(NL80211_IFTYPE_ADHOC)
                            | BIT(NL80211_IFTYPE_P2P_CLIENT)
                            | BIT(NL80211_IFTYPE_P2P_GO)
                            | BIT(NL80211_IFTYPE_AP)
                            | BIT(NL80211_IFTYPE_MONITOR);

    if( pCfg->advertiseConcurrentOperation )
    {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
        if( pCfg->enableMCC )
        {
            /* Currently, supports up to two channels */
            wlan_hdd_iface_combination[0].num_different_channels = 2;

            if( !pCfg->allowMCCGODiffBI )
                wlan_hdd_iface_combination[0].beacon_int_infra_match = true;

        }
        wiphy->iface_combinations = wlan_hdd_iface_combination;
        wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
#endif
    }

    /* Before registering we need to update the ht capabilitied based
     * on ini values*/
    if( !pCfg->ShortGI20MhzEnable )
    {
        wlan_hdd_band_2_4_GHZ.ht_cap.cap     &= ~IEEE80211_HT_CAP_SGI_20;
        wlan_hdd_band_5_GHZ.ht_cap.cap       &= ~IEEE80211_HT_CAP_SGI_20;
    }

    if( !pCfg->ShortGI40MhzEnable )
    {
        wlan_hdd_band_5_GHZ.ht_cap.cap       &= ~IEEE80211_HT_CAP_SGI_40;
    }

    if( !pCfg->nChannelBondingMode5GHz )
    {
        wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
    }
    /*
     * In case of static linked driver at the time of driver unload,
     * module exit doesn't happens. Module cleanup helps in cleaning
     * of static memory.
     * If driver load happens statically, at the time of driver unload,
     * wiphy flags don't get reset because of static memory.
     * It's better not to store channel in static memory.
     */
    wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
    wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
        (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
    if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                FL("Not enough memory to allocate channels"));
        return -ENOMEM;
    }
    vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
            &hdd_channels_2_4_GHZ[0],
            sizeof(hdd_channels_2_4_GHZ));

    if (true == hdd_is_5g_supported(pHddCtx))
    {
        wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
        wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
            (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
        if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL)
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    FL("Not enough memory to allocate channels"));
            vos_mem_free(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels);
            wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
            return -ENOMEM;
        }
        vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
                &hdd_channels_5_GHZ[0],
                sizeof(hdd_channels_5_GHZ));
    }

   for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
   {

       if (NULL == wiphy->bands[i])
       {
          hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
                 __func__, i);
          continue;
       }

       for (j = 0; j < wiphy->bands[i]->n_channels; j++)
       {
           struct ieee80211_supported_band *band = wiphy->bands[i];

           if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
           {
               // Enable social channels for P2P
               if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
                   band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
               else
                   band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
               continue;
           }
           else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
           {
               band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
               continue;
           }
       }
    }
    /*Initialise the supported cipher suite details*/
    wiphy->cipher_suites = hdd_cipher_suites;
    wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);

    /*signal strength in mBm (100*dBm) */
    wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
    wiphy->max_remain_on_channel_duration = 5000;
#endif

    hdd_add_channel_switch_support(wiphy);
    wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
    wiphy->vendor_commands = hdd_wiphy_vendor_commands;
    wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
    wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);

    hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);

    EXIT();
    return 0;
}

/* In this function we are registering wiphy. */
int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
{
    ENTER();
 /* Register our wiphy dev with cfg80211 */
    if (0 > wiphy_register(wiphy))
    {
        /* print error */
        hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
        return -EIO;
    }

    EXIT();
    return 0;
}

/* In this function we are updating channel list when,
   regulatory domain is FCC and country code is US.
   Here In FCC standard 5GHz UNII-1 Bands are indoor only.
   As per FCC smart phone is not a indoor device.
   GO should not opeate on indoor channels */
void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
{
    int j;
    hdd_context_t *pHddCtx = wiphy_priv(wiphy);
    tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
    //Default counrtycode from NV at the time of wiphy initialization.
    if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
                                  &defaultCountryCode[0]))
    {
       hddLog(LOGE, FL("Failed to get default country code from NV"));
    }
    if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
    {
       if (NULL == wiphy->bands[HDD_NL80211_BAND_5GHZ])
       {
          hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[HDD_NL80211_BAND_5GHZ] is NULL",__func__ );
          return;
       }
       for (j = 0; j < wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels; j++)
       {
          struct ieee80211_supported_band *band = wiphy->bands[HDD_NL80211_BAND_5GHZ];
          // Mark UNII -1 band channel as passive
          if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
             band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
       }
    }
}
/* This function registers for all frame which supplicant is interested in */
void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
{
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    /* Register for all P2P action, public action etc frames */
    v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
    ENTER();
    /* Register frame indication call back */
    sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
   /* Right now we are registering these frame when driver is getting
      initialized. Once we will move to 2.6.37 kernel, in which we have
      frame register ops, we will move this code as a part of that */
    /* GAS Initial Request */
    sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
                         (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );

    /* GAS Initial Response */
    sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
                         (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );

    /* GAS Comeback Request */
    sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
                         (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );

    /* GAS Comeback Response */
    sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
                         (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );

    /* P2P Public Action */
    sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
                         (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
                                  P2P_PUBLIC_ACTION_FRAME_SIZE );

    /* P2P Action */
    sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
                         (v_U8_t*)P2P_ACTION_FRAME,
                                  P2P_ACTION_FRAME_SIZE );

    /* WNM BSS Transition Request frame */
    sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
                         (v_U8_t*)WNM_BSS_ACTION_FRAME,
                                  WNM_BSS_ACTION_FRAME_SIZE );

    /* WNM-Notification */
    sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
                         (v_U8_t*)WNM_NOTIFICATION_FRAME,
                                  WNM_NOTIFICATION_FRAME_SIZE );
}

void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
{
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    /* Register for all P2P action, public action etc frames */
    v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);

    ENTER();

   /* Right now we are registering these frame when driver is getting
      initialized. Once we will move to 2.6.37 kernel, in which we have
      frame register ops, we will move this code as a part of that */
    /* GAS Initial Request */

    sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
                          (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );

    /* GAS Initial Response */
    sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
                         (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );

    /* GAS Comeback Request */
    sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
                         (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );

    /* GAS Comeback Response */
    sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
                         (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );

    /* P2P Public Action */
    sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
                         (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
                                  P2P_PUBLIC_ACTION_FRAME_SIZE );

    /* P2P Action */
    sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
                         (v_U8_t*)P2P_ACTION_FRAME,
                                  P2P_ACTION_FRAME_SIZE );
    /* WNM-Notification */
    sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
                         (v_U8_t*)WNM_NOTIFICATION_FRAME,
                                  WNM_NOTIFICATION_FRAME_SIZE );
}

#ifdef FEATURE_WLAN_WAPI
void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
                                     const u8 *mac_addr, const u8 *key , int key_Len)
{
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    tCsrRoamSetKey  setKey;
    v_BOOL_t isConnected = TRUE;
    int status = 0;
    v_U32_t roamId= 0xFF;
    tANI_U8 *pKeyPtr = NULL;
    int n = 0;

    hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
           __func__, hdd_device_modetoString(pAdapter->device_mode),
                                             pAdapter->device_mode);

    vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
    setKey.keyId = key_index; // Store Key ID
    setKey.encType  = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
    setKey.keyDirection = eSIR_TX_RX;  // Key Directionn both TX and RX
    setKey.paeRole = 0 ; // the PAE role
    if (!mac_addr || is_broadcast_ether_addr(mac_addr))
    {
        vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
    }
    else
    {
        isConnected = hdd_connIsConnected(pHddStaCtx);
        vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
    }
    setKey.keyLength = key_Len;
    pKeyPtr = setKey.Key;
    memcpy( pKeyPtr, key, key_Len);

    hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
                                            __func__, key_Len);
    for (n = 0 ; n < key_Len; n++)
        hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
                                           __func__,n,setKey.Key[n]);

    pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
    if ( isConnected )
    {
        status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
                             pAdapter->sessionId, &setKey, &roamId );
    }
    if ( status != 0 )
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "[%4d] sme_RoamSetKey returned ERROR status= %d",
                                                __LINE__, status );
        pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
    }
    /* Need to clear any trace of key value in the memory.
     * Thus zero out the memory even though it is local
     * variable.
     */
    vos_mem_zero(&setKey, sizeof(setKey));
}
#endif /* FEATURE_WLAN_WAPI*/

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
                                       beacon_data_t **ppBeacon,
                                       struct beacon_parameters *params)
#else
int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
                                       beacon_data_t **ppBeacon,
                                       struct cfg80211_beacon_data *params,
                                       int dtim_period)
#endif
{
    int size;
    beacon_data_t *beacon = NULL;
    beacon_data_t *old = NULL;
    int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
    const u8 *head, *tail, *proberesp_ies, *assocresp_ies;

    ENTER();
    if (params->head && !params->head_len)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  FL("head_len is  NULL"));
        return -EINVAL;
    }

    old = pAdapter->sessionCtx.ap.beacon;

    if (!params->head && !old)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 FL("session(%d) old and new heads points to NULL"),
                     pAdapter->sessionId);
        return -EINVAL;
    }

    if (params->tail && !params->tail_len)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
            FL("tail_len is zero but tail is not NULL"));
        return -EINVAL;
    }

#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
    /* Kernel 3.0 is not updating dtim_period for set beacon */
    if (!params->dtim_period)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  FL("dtim period is 0"));
        return -EINVAL;
    }
#endif

    if (params->head)
    {
        head_len = params->head_len;
        head = params->head;
    } else
    {
        head_len = old->head_len;
        head = old->head;
    }

    if (params->tail || !old)
    {
        tail_len = params->tail_len;
        tail = params->tail;
    } else
    {
        tail_len = old->tail_len;
        tail = old->tail;
    }

    if (params->proberesp_ies || !old)
    {
        proberesp_ies_len = params->proberesp_ies_len;
        proberesp_ies = params->proberesp_ies;
    } else
    {
        proberesp_ies_len = old->proberesp_ies_len;
        proberesp_ies = old->proberesp_ies;
    }

    if (params->assocresp_ies || !old)
    {
        assocresp_ies_len = params->assocresp_ies_len;
        assocresp_ies = params->assocresp_ies;
    } else
    {
        assocresp_ies_len = old->assocresp_ies_len;
        assocresp_ies = old->assocresp_ies;
    }

    size = sizeof(beacon_data_t) + head_len + tail_len +
        proberesp_ies_len + assocresp_ies_len;

    beacon = kzalloc(size, GFP_KERNEL);
    if( beacon == NULL )
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  FL("Mem allocation for beacon failed"));
        return -ENOMEM;
    }

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
    if (params->dtim_period)
        beacon->dtim_period = params->dtim_period;
    else
        beacon->dtim_period = old->dtim_period;
#else
    if (dtim_period)
        beacon->dtim_period = dtim_period;
    else
        beacon->dtim_period = old->dtim_period;
#endif

    beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
    beacon->tail = beacon->head + head_len;
    beacon->proberesp_ies = beacon->tail + tail_len;
    beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;

    beacon->head_len = head_len;
    beacon->tail_len = tail_len;
    beacon->proberesp_ies_len = proberesp_ies_len;
    beacon->assocresp_ies_len= assocresp_ies_len;

    if (head && head_len)
        memcpy(beacon->head, head, head_len);
    if (tail && tail_len)
        memcpy(beacon->tail, tail, tail_len);
    if (proberesp_ies && proberesp_ies_len)
        memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
    if (assocresp_ies && assocresp_ies_len)
        memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);

    *ppBeacon = beacon;

    kfree(old);

    return 0;
}

v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
                                     const v_U8_t *pIes,
#else
                                     v_U8_t *pIes,
#endif
                                     int length, v_U8_t eid)
{
    int left = length;
    v_U8_t *ptr =  (v_U8_t *)pIes;
    v_U8_t elem_id,elem_len;

    while(left >= 2)
    {
        elem_id  =  ptr[0];
        elem_len =  ptr[1];
        left -= 2;
        if(elem_len > left)
        {
            hddLog(VOS_TRACE_LEVEL_FATAL,
                    FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
                                                    eid,elem_len,left);
            return NULL;
        }
        if (elem_id == eid)
        {
            return ptr;
        }

        left -= elem_len;
        ptr += (elem_len + 2);
    }
    return NULL;
}

/* Check if rate is 11g rate or not */
static int wlan_hdd_rate_is_11g(u8 rate)
{
    static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
    u8 i;
    for (i = 0; i < 8; i++)
    {
        if(rate == gRateArray[i])
            return TRUE;
    }
    return FALSE;
}

/* Check for 11g rate and set proper 11g only mode */
static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
                     u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
{
    u8 i, num_rates = pIe[0];

    pIe += 1;
    for ( i = 0; i < num_rates; i++)
    {
        if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
        {
            /* If rate set have 11g rate than change the mode to 11G */
            *pSapHw_mode = eSAP_DOT11_MODE_11g;
            if (pIe[i] & BASIC_RATE_MASK)
            {
                /* If we have 11g rate as  basic rate, it means mode
                   is 11g only mode.
                 */
               *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
               *pCheckRatesfor11g = FALSE;
            }
        }
        else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
        {
            *require_ht = TRUE;
        }
    }
    return;
}

static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
{
    tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
    beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
    struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
    u8 checkRatesfor11g = TRUE;
    u8 require_ht = FALSE;
    u8 *pIe=NULL;

    pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;

    pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
                                       pBeacon->head_len, WLAN_EID_SUPP_RATES);
    if (pIe != NULL)
    {
        pIe += 1;
        wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
                               &pConfig->SapHw_mode);
    }

    pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
                                WLAN_EID_EXT_SUPP_RATES);
    if (pIe != NULL)
    {

        pIe += 1;
        wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
                               &pConfig->SapHw_mode);
    }

    if( pConfig->channel > 14 )
    {
        pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
    }

    pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
                                       WLAN_EID_HT_CAPABILITY);

    if(pIe)
    {
        pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
        if(require_ht)
            pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
    }
}

static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
                              v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
{
    v_U16_t ielen = 0;
    v_U8_t *pIe = NULL;
    beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;

    pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
                                          pBeacon->tail, pBeacon->tail_len);

    if (pIe)
    {
        ielen = pIe[1] + 2;
        if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
        {
            vos_mem_copy(&genie[*total_ielen], pIe, ielen);
        }
        else
        {
            hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
            return -EINVAL;
        }
        *total_ielen += ielen;
    }
    return 0;
}

static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
                                           v_U8_t *genie, v_U8_t *total_ielen)
{
    beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
    int left = pBeacon->tail_len;
    v_U8_t *ptr = pBeacon->tail;
    v_U8_t elem_id, elem_len;
    v_U16_t ielen = 0;

    if ( NULL == ptr || 0 == left )
        return;

    while (left >= 2)
    {
        elem_id  = ptr[0];
        elem_len = ptr[1];
        left -= 2;
        if (elem_len > left)
        {
            hddLog( VOS_TRACE_LEVEL_ERROR,
                    "****Invalid IEs eid = %d elem_len=%d left=%d*****",
                    elem_id, elem_len, left);
            return;
        }
        if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
        {
            /* skipping the VSIE's which we don't want to include or
             * it will be included by existing code
             */
            if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
#ifdef WLAN_FEATURE_WFD
               (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
#endif
               (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
               (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
               (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
               (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
               (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
            {
               ielen = ptr[1] + 2;
               if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
               {
                   vos_mem_copy(&genie[*total_ielen], ptr, ielen);
                   *total_ielen += ielen;
               }
               else
               {
                   hddLog( VOS_TRACE_LEVEL_ERROR,
                           "IE Length is too big "
                           "IEs eid=%d elem_len=%d total_ie_lent=%d",
                           elem_id, elem_len, *total_ielen);
               }
            }
        }

        left -= elem_len;
        ptr += (elem_len + 2);
    }
    return;
}

int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
{
    v_U8_t *genie;
    v_U8_t total_ielen = 0;
    v_U8_t addIE[1] = {0};
    int ret = 0;
    beacon_data_t *pBeacon = NULL;

    genie = vos_mem_malloc(MAX_GENIE_LEN);

    if(genie == NULL) {

        return -ENOMEM;
    }

    pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
    if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
                              &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
    {
         hddLog(LOGE,
               FL("Adding WPS IE failed"));
         ret = -EINVAL;
         goto done;
    }

#ifdef WLAN_FEATURE_WFD
    if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
                              &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
    {
         hddLog(LOGE,
               FL("Adding WFD IE failed"));
         ret = -EINVAL;
         goto done;
    }
#endif

    if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
                              &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
    {
         hddLog(LOGE,
               FL("Adding P2P IE failed"));
         ret = -EINVAL;
         goto done;
    }

    if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
    {
        wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
    }

    if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
       WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
               eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
    {
        hddLog(LOGE,
               "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
        ret = -EINVAL;
        goto done;
    }

    if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
          WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
          test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
                   eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
          ==eHAL_STATUS_FAILURE)
    {
        hddLog(LOGE,
            "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
        ret = -EINVAL;
        goto done;
    }

    // Added for ProResp IE
    if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
    {
        u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
        u8 probe_rsp_ie_len[3] = {0};
        u8 counter = 0;
        /* Check Probe Resp Length if it is greater then 255 then Store
           Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
           WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
           Store More then 255 bytes into One Variable.
        */
        while ((rem_probe_resp_ie_len > 0) && (counter < 3))
        {
            if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
            {
                probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
                rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
            }
            else
            {
                probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
                rem_probe_resp_ie_len = 0;
            }
        }

        rem_probe_resp_ie_len = 0;

        if (probe_rsp_ie_len[0] > 0)
        {
            if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
                            WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
                            (tANI_U8*)&pBeacon->
                            proberesp_ies[rem_probe_resp_ie_len],
                            probe_rsp_ie_len[0], NULL,
                            eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
            {
                 hddLog(LOGE,
                       "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
                 ret = -EINVAL;
                 goto done;
            }
            rem_probe_resp_ie_len += probe_rsp_ie_len[0];
        }

        if (probe_rsp_ie_len[1] > 0)
        {
            if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
                            WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
                            (tANI_U8*)&pBeacon->
                            proberesp_ies[rem_probe_resp_ie_len],
                            probe_rsp_ie_len[1], NULL,
                            eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
            {
                 hddLog(LOGE,
                       "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
                 ret = -EINVAL;
                 goto done;
            }
            rem_probe_resp_ie_len += probe_rsp_ie_len[1];
        }

        if (probe_rsp_ie_len[2] > 0)
        {
            if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
                            WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
                            (tANI_U8*)&pBeacon->
                            proberesp_ies[rem_probe_resp_ie_len],
                            probe_rsp_ie_len[2], NULL,
                            eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
            {
                 hddLog(LOGE,
                       "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
                 ret = -EINVAL;
                 goto done;
            }
            rem_probe_resp_ie_len += probe_rsp_ie_len[2];
        }

        if (probe_rsp_ie_len[1] == 0 )
        {
            if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
                            WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
                            eANI_BOOLEAN_FALSE) )
            {
                hddLog(LOGE,
                   "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
            }
        }

        if (probe_rsp_ie_len[2] == 0 )
        {
            if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
                            WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
                            eANI_BOOLEAN_FALSE) )
            {
                hddLog(LOGE,
                   "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
            }
        }

        if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
             WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
             test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
                      eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
             == eHAL_STATUS_FAILURE)
        {
           hddLog(LOGE,
             "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
           ret = -EINVAL;
           goto done;
        }
    }
    else
    {
        // Reset WNI_CFG_PROBE_RSP Flags
        wlan_hdd_reset_prob_rspies(pHostapdAdapter);

        hddLog(VOS_TRACE_LEVEL_INFO,
               "%s: No Probe Response IE received in set beacon",
               __func__);
    }

    // Added for AssocResp IE
    if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
    {
       if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
               WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
               pBeacon->assocresp_ies_len, NULL,
               eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
       {
            hddLog(LOGE,
                  "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
            ret = -EINVAL;
            goto done;
       }

       if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
          WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
          test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
                   eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
          == eHAL_STATUS_FAILURE)
       {
          hddLog(LOGE,
            "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
          ret = -EINVAL;
          goto done;
       }
    }
    else
    {
        hddLog(VOS_TRACE_LEVEL_INFO,
               "%s: No Assoc Response IE received in set beacon",
               __func__);

        if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
                            WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
                            eANI_BOOLEAN_FALSE) )
        {
            hddLog(LOGE,
               "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
        }
    }

done:
    vos_mem_free(genie);
    return ret;
}

/*
 * FUNCTION: wlan_hdd_validate_operation_channel
 * called by wlan_hdd_cfg80211_start_bss() and
 * wlan_hdd_cfg80211_set_channel()
 * This function validates whether given channel is part of valid
 * channel list.
 */
VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
{

    v_U32_t num_ch = 0;
    u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
    u32 indx = 0;
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    v_U8_t fValidChannel = FALSE, count = 0;
    hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;

    num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;

    if ( hdd_pConfig_ini->sapAllowAllChannel)
    {
         /* Validate the channel */
        for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
        {
            if ( channel == rfChannels[count].channelNum )
            {
                fValidChannel = TRUE;
                break;
            }
        }
        if (fValidChannel != TRUE)
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: Invalid Channel [%d]", __func__, channel);
            return VOS_STATUS_E_FAILURE;
        }
    }
    else
    {
        if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
            valid_ch, &num_ch))
            {
                hddLog(VOS_TRACE_LEVEL_ERROR,
                    "%s: failed to get valid channel list", __func__);
                return VOS_STATUS_E_FAILURE;
            }
        for (indx = 0; indx < num_ch; indx++)
        {
            if (channel == valid_ch[indx])
            {
                break;
            }
         }

         if (indx >= num_ch)
         {
             if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
             {
                 eCsrBand band;
                 unsigned int freq;

                 sme_GetFreqBand(hHal, &band);

                 if (eCSR_BAND_5G == band)
                 {
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
                     if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
                     {
                         freq = ieee80211_channel_to_frequency(channel,
                                                          HDD_NL80211_BAND_2GHZ);
                     }
                     else
                     {
                         freq = ieee80211_channel_to_frequency(channel,
                                                          HDD_NL80211_BAND_5GHZ);
                     }
#else
                     freq = ieee80211_channel_to_frequency(channel);
#endif
                     if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
                         return VOS_STATUS_SUCCESS;
                 }
             }

             hddLog(VOS_TRACE_LEVEL_ERROR,
                    "%s: Invalid Channel [%d]", __func__, channel);
             return VOS_STATUS_E_FAILURE;
         }
    }

    return VOS_STATUS_SUCCESS;

}

/**
 * FUNCTION: __wlan_hdd_cfg80211_set_channel
 * This function is used to set the channel number
 */
static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
                                   struct ieee80211_channel *chan,
                                   enum nl80211_channel_type channel_type
                                 )
{
    hdd_adapter_t *pAdapter = NULL;
    v_U32_t num_ch = 0;
    int channel = 0;
    int freq = chan->center_freq; /* freq is in MHZ */
    hdd_context_t *pHddCtx;
    int status;

    ENTER();

    if( NULL == dev )
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: Called with dev = NULL.", __func__);
        return -ENODEV;
    }
    pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
                     channel_type ));
    hddLog(VOS_TRACE_LEVEL_INFO,
                "%s: device_mode = %s (%d)  freq = %d", __func__,
                hdd_device_modetoString(pAdapter->device_mode),
                pAdapter->device_mode, chan->center_freq);

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    /*
     * Do freq to chan conversion
     * TODO: for 11a
     */

    channel = ieee80211_frequency_to_channel(freq);

    /* Check freq range */
    if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
            (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: Channel [%d] is outside valid range from %d to %d",
                __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
                WNI_CFG_CURRENT_CHANNEL_STAMAX);
        return -EINVAL;
    }

    num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;

    if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
       (WLAN_HDD_P2P_GO != pAdapter->device_mode))
    {
        if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    "%s: Invalid Channel [%d]", __func__, channel);
            return -EINVAL;
        }
        hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
                "%s: set channel to [%d] for device mode =%d",
                          __func__, channel,pAdapter->device_mode);
    }
    if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
     || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
      )
    {
        hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
        tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
        hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

        if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
        {
           /* Link is up then return cant set channel*/
            hddLog( VOS_TRACE_LEVEL_ERROR,
                   "%s: IBSS Associated, can't set the channel", __func__);
            return -EINVAL;
        }

        num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
        pHddStaCtx->conn_info.operationChannel = channel;
        pRoamProfile->ChannelInfo.ChannelList =
            &pHddStaCtx->conn_info.operationChannel;
    }
    else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
        ||   (pAdapter->device_mode == WLAN_HDD_P2P_GO)
            )
    {
        if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
        {
            if(VOS_STATUS_SUCCESS !=
                       wlan_hdd_validate_operation_channel(pAdapter,channel))
            {
               hddLog(VOS_TRACE_LEVEL_ERROR,
                      "%s: Invalid Channel [%d]", __func__, channel);
               return -EINVAL;
            }
            (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
        }
        else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
        {
            hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;

            /* If auto channel selection is configured as enable/ 1 then ignore
            channel set by supplicant
            */
            if ( cfg_param->apAutoChannelSelection )
            {
                (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
                                                          AUTO_CHANNEL_SELECT;
                hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
                     "%s: set channel to auto channel (0) for device mode =%s (%d)",
                     __func__, hdd_device_modetoString(pAdapter->device_mode),
                                                     pAdapter->device_mode);
            }
            else
            {
                if(VOS_STATUS_SUCCESS !=
                         wlan_hdd_validate_operation_channel(pAdapter,channel))
                {
                   hddLog(VOS_TRACE_LEVEL_ERROR,
                          "%s: Invalid Channel [%d]", __func__, channel);
                   return -EINVAL;
                }
                (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
            }
        }
    }
    else
    {
        hddLog(VOS_TRACE_LEVEL_FATAL,
               "%s: Invalid device mode failed to set valid channel", __func__);
        return -EINVAL;
    }
    EXIT();
    return status;
}

static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
                                          struct net_device *dev,
                                          struct ieee80211_channel *chan,
                                          enum nl80211_channel_type channel_type
                                        )
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
    vos_ssr_unprotect(__func__);

    return ret;
}

#ifdef DHCP_SERVER_OFFLOAD
void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
				  VOS_STATUS status)
{
	hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;

	ENTER();

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

	adapter->dhcp_status.dhcp_offload_status = status;
	vos_event_set(&adapter->dhcp_status.vos_event);
	return;
}

/**
 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
 * @hostapd_adapter: pointer to hostapd adapter.
 * @re_init: flag set if api called post ssr
 *
 * Return: None
 */
VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
					    bool re_init)
{
	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
	sir_dhcp_srv_offload_info dhcp_srv_info;
	tANI_U8 num_entries = 0;
	tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
	tANI_U8 num;
	tANI_U32 temp;
	VOS_STATUS ret;

	ENTER();

	if (!re_init) {
		ret = wlan_hdd_validate_context(hdd_ctx);
		if (0 != ret)
			return VOS_STATUS_E_INVAL;
	}

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

	vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));

	dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
	dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
	dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
	dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
	dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
	dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;

	hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
			       srv_ip,
			       &num_entries,
			       IPADDR_NUM_ENTRIES, ".", false);
	if (num_entries != IPADDR_NUM_ENTRIES) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       "%s: incorrect IP address (%s) assigned for DHCP server!",
		       __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
		vos_mem_free(dhcp_srv_info);
		return VOS_STATUS_E_FAILURE;
	}

	if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
		       __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
		vos_mem_free(dhcp_srv_info);
		return VOS_STATUS_E_FAILURE;
	}

	if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       "%s: invalid IP address (%s)! The last field must be less than 100!",
		       __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
		vos_mem_free(dhcp_srv_info);
		return VOS_STATUS_E_FAILURE;
	}

	for (num = 0; num < num_entries; num++) {
		temp = srv_ip[num];
		dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
	}

	if (eHAL_STATUS_SUCCESS !=
	    sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       "%s: sme_set_dhcp_srv_offload fail!", __func__);
		vos_mem_free(dhcp_srv_info);
		return VOS_STATUS_E_FAILURE;
	}

	hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
	       "%s: enable DHCP Server offload successfully!", __func__);

	vos_mem_free(dhcp_srv_info);
	return 0;
}
#endif /* DHCP_SERVER_OFFLOAD */

/*
 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
 * @wiphy_chan: wiphy channel number
 * @rfChannel: channel hw value
 * @disable: Disable/enable the flags
 *
 * Modify wiphy flags and cds state if channel is indoor.
 *
 * Return: void
 */
void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
    v_U32_t rfChannel, bool disable)
{
    v_U32_t channelLoop;
    eRfChannels channelEnum = INVALID_RF_CHANNEL;

    for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {

        if (rfChannels[channelLoop].channelNum == rfChannel) {
            channelEnum = (eRfChannels)channelLoop;
            break;
        }
    }

    if (INVALID_RF_CHANNEL == channelEnum)
        return;

    if (disable) {
        if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
            wiphy_chan->flags |=
                IEEE80211_CHAN_DISABLED;
            regChannels[channelEnum].enabled =
                NV_CHANNEL_DISABLE;
        }
    } else {
        if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
            wiphy_chan->flags &=
                    ~IEEE80211_CHAN_DISABLED;
            /*
             * Indoor channels are marked as DFS
             * during regulatory processing
             */

            regChannels[channelEnum].enabled =
                    NV_CHANNEL_DFS;
        }
    }

}

void hdd_update_indoor_channel(hdd_context_t *hdd_ctx,
                    bool disable)
{
    int band_num;
    int chan_num;
    v_U32_t rfChannel;
    struct ieee80211_channel *wiphy_chan;
    struct wiphy *wiphy;

    ENTER();
    hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);

    wiphy = hdd_ctx->wiphy;
    for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {

        if (wiphy->bands[band_num] == NULL)
            continue;

        for (chan_num = 0;
             chan_num < wiphy->bands[band_num]->n_channels;
             chan_num++) {

            wiphy_chan =
                &(wiphy->bands[band_num]->channels[chan_num]);
            rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;

            hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
                                        disable);
        }
    }
    EXIT();
}

/*
 * FUNCTION: wlan_hdd_disconnect
 * This function is used to issue a disconnect request to SME
 */
int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
{
    int status, result = 0;
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    long ret;
    eConnectionState prev_conn_state;
    uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;

    ENTER();

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }
    /* Indicate sme of disconnect so that in progress connection or preauth
     * can be aborted
     */
    sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
                            pAdapter->sessionId);
    pHddCtx->isAmpAllowed = VOS_TRUE;

    /* Need to apply spin lock before decreasing active sessions
     * as there can be chance for double decrement if context switch
     * Calls  hdd_DisConnectHandler.
     */

    prev_conn_state = pHddStaCtx->conn_info.connState;

    spin_lock_bh(&pAdapter->lock_for_active_session);
    if (eConnectionState_Associated ==  pHddStaCtx->conn_info.connState)
    {
        wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
    }
    hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
    spin_unlock_bh(&pAdapter->lock_for_active_session);
    vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);

    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  FL( "Set HDD connState to eConnectionState_Disconnecting" ));

    INIT_COMPLETION(pAdapter->disconnect_comp_var);

    /*
     * stop tx queues before deleting STA/BSS context from the firmware.
     * tx has to be disabled because the firmware can get busy dropping
     * the tx frames after BSS/STA has been deleted and will not send
     * back a response resulting in WDI timeout
     */
    hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
    netif_tx_disable(pAdapter->dev);
    netif_carrier_off(pAdapter->dev);

    wlan_hdd_check_and_stop_mon(pAdapter, true);

    /*issue disconnect*/
    status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
                                 pAdapter->sessionId, reason);
    if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
             prev_conn_state != eConnectionState_Connecting)
    {
        hddLog(LOG1,
            FL("status = %d, already disconnected"), status);
        result = 0;
        /*
         * Wait here instead of returning directly. This will block the
         * next connect command and allow processing of the disconnect
         * in SME else we might hit some race conditions leading to SME
         * and HDD out of sync. As disconnect is already in progress,
         * wait here for 1 sec instead of 5 sec.
         */
        wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
        goto wait_for_disconnect;
    }
    /*
     * Wait here instead of returning directly, this will block the next
     * connect command and allow processing of the scan for ssid and
     * the previous connect command in CSR. Else we might hit some
     * race conditions leading to SME and HDD out of sync.
     */
    else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
    {
        hddLog(LOG1,
            FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
    }
    else if ( 0 != status )
    {
        hddLog(LOGE,
               FL("csrRoamDisconnect failure, returned %d"),
               (int)status);
        result = -EINVAL;
        goto disconnected;
    }
wait_for_disconnect:
    ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
                                      msecs_to_jiffies(wait_time));
    if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
    {
        hddLog(LOGE,
              "%s: Failed to disconnect, timed out", __func__);
        result = -ETIMEDOUT;
    }
disconnected:
     hddLog(LOG1,
              FL("Set HDD connState to eConnectionState_NotConnected"));
    pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
    /* Sending disconnect event to userspace for kernel version < 3.11
     * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
     */
    hddLog(LOG1, FL("Send disconnected event to userspace"));

    wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
                                          WLAN_REASON_UNSPECIFIED);
#endif

    EXIT();
    return result;
}

/*
 * hdd_check_and_disconnect_sta_on_invalid_channel() - Disconnect STA if it is
 * on indoor channel
 * @hdd_ctx: pointer to hdd context
 *
 * STA should be disconnected before starting the SAP if it is on indoor
 * channel.
 *
 * Return: void
 */
void hdd_check_and_disconnect_sta_on_invalid_channel(hdd_context_t *hdd_ctx)
{

    hdd_adapter_t *sta_adapter;
    tANI_U8 sta_chan;

    sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);

    if (!sta_chan) {
        hddLog(LOG1, FL("STA not connected"));
        return;
    }

    hddLog(LOG1, FL("STA connected on chan %hu"), sta_chan);

    if (sme_IsChannelValid(hdd_ctx->hHal, sta_chan)) {
        hddLog(LOG1, FL("STA connected on chan %hu and it is valid"),
                sta_chan);
        return;
    }

    sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);

    if (!sta_adapter) {
        hddLog(LOG1, FL("STA adapter doesn't exist"));
        return;
    }

    hddLog(LOG1, FL("chan %hu not valid, issue disconnect"), sta_chan);
    /* Issue Disconnect request */
    wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
}

int wlan_hdd_restore_channels(hdd_context_t *hdd_ctx)
{
	struct hdd_cache_channels *cache_chann;
	struct wiphy *wiphy;
	int freq, status, rfChannel;
	int i, band_num, channel_num;
	struct ieee80211_channel *wiphy_channel;

	ENTER();

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

	wiphy = hdd_ctx->wiphy;

	mutex_lock(&hdd_ctx->cache_channel_lock);

	cache_chann = hdd_ctx->orginal_channels;

	if (!cache_chann || !cache_chann->num_channels) {
		hddLog(VOS_TRACE_LEVEL_INFO,
		       "%s channel list is NULL or num channels are zero",
		       __func__);
		mutex_unlock(&hdd_ctx->cache_channel_lock);
		return -EINVAL;
	}

	for (i = 0; i < cache_chann->num_channels; i++) {
		status = hdd_wlan_get_freq(
				cache_chann->channel_info[i].channel_num,
				&freq);

		for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
		     band_num++) {
			for (channel_num = 0; channel_num <
				wiphy->bands[band_num]->n_channels;
				channel_num++) {
				wiphy_channel = &(wiphy->bands[band_num]->
							channels[channel_num]);
				if (wiphy_channel->center_freq == freq) {
					rfChannel = wiphy_channel->hw_value;
					/*
					 *Restore the orginal states
					 *of the channels
					 */
					vos_nv_set_channel_state(
						rfChannel,
						cache_chann->
						channel_info[i].reg_status);
					wiphy_channel->flags =
						cache_chann->
						channel_info[i].wiphy_status;
					break;
				}
			}
			if (channel_num < wiphy->bands[band_num]->n_channels)
				break;
		}
	}

	mutex_unlock(&hdd_ctx->cache_channel_lock);

	status = sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
	if (status)
		hddLog(VOS_TRACE_LEVEL_ERROR, "Can't Restore channel list");
	EXIT();

	return 0;
}

/*
 * wlan_hdd_disable_channels() - Cache the the channels
 * and current state of the channels from the channel list
 * received in the command and disable the channels on the
 * wiphy and NV table.
 * @hdd_ctx: Pointer to hdd context
 *
 * @return: 0 on success, Error code on failure
 */

static int wlan_hdd_disable_channels(hdd_context_t *hdd_ctx)
{
	struct hdd_cache_channels *cache_chann;
	struct wiphy *wiphy;
	int freq, status, rfChannel;
	int i, band_num, band_ch_num;
	struct ieee80211_channel *wiphy_channel;

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

	wiphy = hdd_ctx->wiphy;

	mutex_lock(&hdd_ctx->cache_channel_lock);
	cache_chann = hdd_ctx->orginal_channels;

	if (!cache_chann || !cache_chann->num_channels) {
		hddLog(VOS_TRACE_LEVEL_INFO,
		       "%s channel list is NULL or num channels are zero",
		       __func__);
		mutex_unlock(&hdd_ctx->cache_channel_lock);
		return -EINVAL;
	}

	for (i = 0; i < cache_chann->num_channels; i++) {
		status = hdd_wlan_get_freq(
				cache_chann->channel_info[i].channel_num,
				&freq);

		for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
							band_num++) {
			for (band_ch_num = 0; band_ch_num <
					wiphy->bands[band_num]->n_channels;
					band_ch_num++) {
				wiphy_channel = &(wiphy->bands[band_num]->
							channels[band_ch_num]);
				if (wiphy_channel->center_freq == freq) {
					rfChannel = wiphy_channel->hw_value;
					/*
					 * Cache the current states of
					 * the channels
					 */
					cache_chann->
					channel_info[i].reg_status =
						vos_nv_getChannelEnabledState(
							rfChannel);

					cache_chann->
						channel_info[i].wiphy_status =
							wiphy_channel->flags;
					hddLog(VOS_TRACE_LEVEL_INFO,
					"Disable channel %d reg_stat %d wiphy_stat 0x%x",
					cache_chann->
						channel_info[i].channel_num,
					cache_chann->
						channel_info[i].reg_status,
					wiphy_channel->flags);

					vos_nv_set_channel_state(
							rfChannel,
							NV_CHANNEL_DISABLE);
					wiphy_channel->flags |=
						IEEE80211_CHAN_DISABLED;
					break;
				}
			}
			if (band_ch_num < wiphy->bands[band_num]->n_channels)
				break;
		}
	}

	mutex_unlock(&hdd_ctx->cache_channel_lock);
	sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
	return 0;
}

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
                            struct beacon_parameters *params)
#else
static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
                                       struct cfg80211_beacon_data *params,
                                       const u8 *ssid, size_t ssid_len,
                                       enum nl80211_hidden_ssid hidden_ssid,
                                       v_U8_t auth_type)
#endif
{
    tsap_Config_t *pConfig;
    beacon_data_t *pBeacon = NULL;
    struct ieee80211_mgmt *pMgmt_frame;
    v_U8_t *pIe=NULL;
    v_U16_t capab_info;
    eCsrAuthType RSNAuthType;
    eCsrEncryptionType RSNEncryptType;
    eCsrEncryptionType mcRSNEncryptType;
    int status = VOS_STATUS_SUCCESS, ret = 0;
    tpWLAN_SAPEventCB pSapEventCallback;
    hdd_hostapd_state_t *pHostapdState;
    v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
    struct qc_mac_acl_entry *acl_entry = NULL;
    hdd_config_t *iniConfig;
    v_SINT_t i;
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
    tSmeConfigParams *psmeConfig;
    v_BOOL_t MFPCapable = VOS_FALSE;
    v_BOOL_t MFPRequired = VOS_FALSE;
    v_BOOL_t sapEnable11AC =
             (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
    u_int16_t prev_rsn_length = 0;

    ENTER();

    wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
    iniConfig = pHddCtx->cfg_ini;

    /* Mark the indoor channel (passive) to disable */
    if (iniConfig->disable_indoor_channel &&
                pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
        hdd_update_indoor_channel(pHddCtx, true);

        if (!VOS_IS_STATUS_SUCCESS(
                sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
            hdd_update_indoor_channel(pHddCtx, false);
            VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
                 FL("Can't start BSS: update channel list failed"));
            return eHAL_STATUS_FAILURE;
        }

        /* check if STA is on indoor channel */
        if (hdd_is_sta_sap_scc_allowed_on_dfs_chan(pHddCtx))
            hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
    }

    if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
        /* Disable the channels received in command SET_DISABLE_CHANNEL_LIST*/
        wlan_hdd_disable_channels(pHddCtx);
        hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
    }

    pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);

    pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;

    pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;

    pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;

    pConfig->beacon_int =  pMgmt_frame->u.beacon.beacon_int;

    //channel is already set in the set_channel Call back
    //pConfig->channel = pCommitConfig->channel;

    /*Protection parameter to enable or disable*/
    pConfig->protEnabled =
           (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;

    pConfig->dtim_period = pBeacon->dtim_period;

    hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
                                      pConfig->dtim_period);

    if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
    {
        pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
                                       WLAN_EID_COUNTRY);
        if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
        {
           tANI_BOOLEAN restartNeeded;
           pConfig->ieee80211d = 1;
           vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
           sme_setRegInfo(hHal, pConfig->countryCode);
           sme_ResetCountryCodeInformation(hHal, &restartNeeded);
        }
        else if(pIe)
        {
            tANI_BOOLEAN restartNeeded;
            pConfig->ieee80211d = 1;
            vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
            sme_setRegInfo(hHal, pConfig->countryCode);
            sme_ResetCountryCodeInformation(hHal, &restartNeeded);
        }
        else
        {
            pConfig->ieee80211d = 0;
        }
        /*
        * If auto channel is configured i.e. channel is 0,
        * so skip channel validation.
        */
        if( AUTO_CHANNEL_SELECT != pConfig->channel )
        {
            if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
            {
                 hddLog(VOS_TRACE_LEVEL_ERROR,
                         "%s: Invalid Channel [%d]", __func__, pConfig->channel);
                 ret = -EINVAL;
                 goto error;
            }
            pConfig->user_config_channel = pConfig->channel;
        }
        else
        {
             if(1 != pHddCtx->is_dynamic_channel_range_set)
             {
                  hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
                  WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
                       hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
             }
             pHddCtx->is_dynamic_channel_range_set = 0;
             pConfig->user_config_channel = SAP_DEFAULT_24GHZ_CHANNEL;
        }
    }
    else
    {
        pConfig->ieee80211d = 0;
    }

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
    if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
        pConfig->authType = eSAP_OPEN_SYSTEM;
    else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
        pConfig->authType = eSAP_SHARED_KEY;
    else
        pConfig->authType = eSAP_AUTO_SWITCH;
#else
    if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
        pConfig->authType = eSAP_OPEN_SYSTEM;
    else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
        pConfig->authType = eSAP_SHARED_KEY;
    else
        pConfig->authType = eSAP_AUTO_SWITCH;
#endif

    capab_info = pMgmt_frame->u.beacon.capab_info;

    pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
                        WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
#ifdef SAP_AUTH_OFFLOAD
    /* In case of sap offload, hostapd.conf is configuted with open mode and
     * security is configured from ini file. Due to open mode in hostapd.conf
     * privacy bit is set to false which will result in not sending,
     * data packets as encrypted.
     * If enable_sap_auth_offload is enabled in ini and
     * sap_auth_offload_sec_type is type of WPA2-PSK,
     * driver will set privacy bit to 1.
     */
    if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
            pHddCtx->cfg_ini->sap_auth_offload_sec_type)
        pConfig->privacy = VOS_TRUE;
#endif

    (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;

    /*Set wps station to configured*/
    pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);

    if(pIe)
    {
        if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
        {
            hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
            ret = -EINVAL;
            goto error;
        }
        else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
        {
             hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
             /* Check 15 bit of WPS IE as it contain information for wps state
              * WPS state
              */
              if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
              {
                  pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
              } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
              {
                  pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
              }
        }
    }
    else
    {
        pConfig->wps_state = SAP_WPS_DISABLED;
    }
    pConfig->fwdWPSPBCProbeReq  = 1; // Forward WPS PBC probe request frame up

    pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
    pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
    (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
        eCSR_ENCRYPT_TYPE_NONE;

    pConfig->RSNWPAReqIELength = 0;
    memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
    pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
                                       WLAN_EID_RSN);
    if(pIe && pIe[1])
    {
        pConfig->RSNWPAReqIELength = pIe[1] + 2;
        if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
            memcpy(&pConfig->RSNWPAReqIE[0], pIe,
                                   pConfig->RSNWPAReqIELength);
        else
            hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
                                         pConfig->RSNWPAReqIELength);
        /* The actual processing may eventually be more extensive than
         * this. Right now, just consume any PMKIDs that are  sent in
         * by the app.
         * */
        status = hdd_softap_unpackIE(
                        vos_get_context( VOS_MODULE_ID_SME, pVosContext),
                        &RSNEncryptType,
                        &mcRSNEncryptType,
                        &RSNAuthType,
                        &MFPCapable,
                        &MFPRequired,
                        pConfig->RSNWPAReqIE[1]+2,
                        pConfig->RSNWPAReqIE);

        if( VOS_STATUS_SUCCESS == status )
        {
            /* Now copy over all the security attributes you have
             * parsed out
             * */
            pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
            pConfig->mcRSNEncryptType = mcRSNEncryptType;
            (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
                                                              = RSNEncryptType;
            hddLog( LOG1, FL("CSR AuthType = %d, "
                        "EncryptionType = %d mcEncryptionType = %d"),
                        RSNAuthType, RSNEncryptType, mcRSNEncryptType);
        }
    }

    pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
                                         pBeacon->tail, pBeacon->tail_len);

    if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
    {
        if (pConfig->RSNWPAReqIE[0])
        {
            /*Mixed mode WPA/WPA2*/
            prev_rsn_length = pConfig->RSNWPAReqIELength;
            pConfig->RSNWPAReqIELength += pIe[1] + 2;
            if (pConfig->RSNWPAReqIELength <=
               (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
                memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
                                                            pIe[1] + 2);
            else
                hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
                                             pConfig->RSNWPAReqIELength);

        }
        else
        {
            pConfig->RSNWPAReqIELength = pIe[1] + 2;
            if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
                memcpy(&pConfig->RSNWPAReqIE[0], pIe,
                                       pConfig->RSNWPAReqIELength);
            else
               hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
                                            pConfig->RSNWPAReqIELength);
            status = hdd_softap_unpackIE(
                          vos_get_context( VOS_MODULE_ID_SME, pVosContext),
                          &RSNEncryptType,
                          &mcRSNEncryptType,
                          &RSNAuthType,
                          &MFPCapable,
                          &MFPRequired,
                          pConfig->RSNWPAReqIE[1]+2,
                          pConfig->RSNWPAReqIE);

            if( VOS_STATUS_SUCCESS == status )
            {
                /* Now copy over all the security attributes you have
                 * parsed out
                 * */
                pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
                pConfig->mcRSNEncryptType = mcRSNEncryptType;
                (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
                                                              = RSNEncryptType;
                hddLog( LOG1, FL("CSR AuthType = %d, "
                                "EncryptionType = %d mcEncryptionType = %d"),
                                RSNAuthType, RSNEncryptType, mcRSNEncryptType);
            }
        }
    }

    if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
        hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
        ret = -EINVAL;
        goto error;
    }

    pConfig->SSIDinfo.ssidHidden = VOS_FALSE;

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
    if (params->ssid != NULL)
    {
        memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
        pConfig->SSIDinfo.ssid.length = params->ssid_len;
        if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
            pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
    }
#else
    if (ssid != NULL)
    {
        memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
        pConfig->SSIDinfo.ssid.length = ssid_len;
        if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
            pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
    }
#endif

    vos_mem_copy(pConfig->self_macaddr.bytes,
               pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));

    /* default value */
    pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
    pConfig->num_accept_mac = 0;
    pConfig->num_deny_mac = 0;

    pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
                                         pBeacon->tail, pBeacon->tail_len);

    /* pIe for black list is following form:
            type    : 1 byte
            length  : 1 byte
            OUI     : 4 bytes
            acl type : 1 byte
            no of mac addr in black list: 1 byte
            list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
    */
    if ((pIe != NULL) && (pIe[1] != 0))
    {
        pConfig->SapMacaddr_acl = pIe[6];
        pConfig->num_deny_mac   = pIe[7];
        hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
                                     pIe[6], pIe[7]);
        if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
            pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
        acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
        for (i = 0; i < pConfig->num_deny_mac; i++)
        {
            vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
            acl_entry++;
        }
    }
    pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
                                         pBeacon->tail, pBeacon->tail_len);

    /* pIe for white list is following form:
            type    : 1 byte
            length  : 1 byte
            OUI     : 4 bytes
            acl type : 1 byte
            no of mac addr in white list: 1 byte
            list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
    */
    if ((pIe != NULL) && (pIe[1] != 0))
    {
        pConfig->SapMacaddr_acl = pIe[6];
        pConfig->num_accept_mac   = pIe[7];
        hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
                                      pIe[6], pIe[7]);
        if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
            pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
        acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
        for (i = 0; i < pConfig->num_accept_mac; i++)
        {
            vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
            acl_entry++;
        }
    }

    wlan_hdd_set_sapHwmode(pHostapdAdapter);

#ifdef WLAN_FEATURE_11AC
    /* Overwrite the hostapd setting for HW mode only for 11ac.
     * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
     * is set in .ini and 11ac is supported by both host and firmware.
     * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
     */
    if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
         (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
         (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
         (sme_IsFeatureSupportedByFW(DOT11AC)) )
    {
        v_U32_t operatingBand = 0;
        pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
        ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);

        /* If ACS disable and selected channel <= 14
         *  OR
         *  ACS enabled and ACS operating band is choosen as 2.4
         *  AND
         *  VHT in 2.4G Disabled
         *  THEN
         *  Fallback to 11N mode
         */
        if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
                    || (AUTO_CHANNEL_SELECT == pConfig->channel &&
            operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
                iniConfig->enableVhtFor24GHzBand == FALSE)
        {
            hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
                    operatingBand, pConfig->channel);
            pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
        }
    }
#endif

    // ht_capab is not what the name conveys,this is used for protection bitmap
    pConfig->ht_capab =
                 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;

    if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
    {
        hddLog(LOGE, FL("SAP Not able to set AP IEs"));
        ret = -EINVAL;
        goto error;
    }

    //Uapsd Enabled Bit
    pConfig->UapsdEnable =
          (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
    //Enable OBSS protection
    pConfig->obssProtEnabled =
           (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;

#ifdef WLAN_FEATURE_11W
    pConfig->mfpCapable = MFPCapable;
    pConfig->mfpRequired = MFPRequired;
    hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
           pConfig->mfpCapable, pConfig->mfpRequired);
#endif

    hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
                 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
    hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
                   pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
                    (int)pConfig->channel);
    hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
                   pConfig->SapHw_mode, pConfig->privacy,
                   pConfig->authType);
    hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
                   (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
    hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
                    pConfig->protEnabled, pConfig->obssProtEnabled);

    if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
    {
        //Bss already started. just return.
        //TODO Probably it should update some beacon params.
        hddLog( LOGE, "Bss Already started...Ignore the request");
        EXIT();
        return 0;
    }

    if (vos_max_concurrent_connections_reached()) {
        hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
        ret = -EINVAL;
        goto error;
    }

    pConfig->persona = pHostapdAdapter->device_mode;

    psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
    if ( NULL != psmeConfig)
    {
        vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
        sme_GetConfigParam(hHal, psmeConfig);
        pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
#ifdef WLAN_FEATURE_AP_HT40_24G
        if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
          || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
          && pHddCtx->cfg_ini->apHT40_24GEnabled)
        {
            psmeConfig->csrConfig.apHT40_24GEnabled = 1;
            sme_UpdateConfig (hHal, psmeConfig);
        }
#endif
        vos_mem_free(psmeConfig);
    }
    pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;

    set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);

    pSapEventCallback = hdd_hostapd_SAPEventCB;
    if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
                 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
    {
        hddLog(LOGE,FL("SAP Start Bss fail"));
        ret = -EINVAL;
        goto error;
    }

    hddLog(LOG1,
           FL("Waiting for Scan to complete(auto mode) and BSS to start"));

    status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);

    if (!VOS_IS_STATUS_SUCCESS(status))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 ("ERROR: HDD vos wait for single_event failed!!"));
        smeGetCommandQStatus(hHal);
        VOS_ASSERT(0);
    }

    set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
    if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
                         VOS_STATUS_SUCCESS)
    {
        hddLog(LOGE,FL("Fail to get Softap sessionID"));
        VOS_ASSERT(0);
    }
    /* Initialize WMM configuation */
    hdd_wmm_init(pHostapdAdapter);
    wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);

#ifdef DHCP_SERVER_OFFLOAD
    /* set dhcp server offload */
    if (iniConfig->enable_dhcp_srv_offload &&
        sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
        vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
        status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
        if (!VOS_IS_STATUS_SUCCESS(status))
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      ("HDD DHCP Server Offload Failed!!"));
            vos_event_reset(&pHostapdState->vosEvent);
            if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
                status = vos_wait_single_event(&pHostapdState->vosEvent,
                                               10000);
                if (!VOS_IS_STATUS_SUCCESS(status)) {
                    hddLog(LOGE, FL("SAP Stop Failed"));
                    ret = -EINVAL;
                    goto error;
                }
            }
        }
        status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
        if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                     ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
                     pHostapdAdapter->dhcp_status.dhcp_offload_status);
            vos_event_reset(&pHostapdState->vosEvent);
            if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
                status = vos_wait_single_event(&pHostapdState->vosEvent,
                                               10000);
                if (!VOS_IS_STATUS_SUCCESS(status)) {
                    hddLog(LOGE, FL("SAP Stop Failed"));
                    ret = -EINVAL;
                    goto error;
                }
            }
        }
#ifdef MDNS_OFFLOAD
        if (iniConfig->enable_mdns_offload) {
            vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
            status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
            if (VOS_IS_STATUS_SUCCESS(status))
            {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                          ("HDD MDNS Server Offload Failed!!"));
                vos_event_reset(&pHostapdState->vosEvent);
                if (VOS_STATUS_SUCCESS ==
                    WLANSAP_StopBss(pHddCtx->pvosContext)) {
                    status = vos_wait_single_event(&pHostapdState->vosEvent,
                                                   10000);
                    if (!VOS_IS_STATUS_SUCCESS(status)) {
                        hddLog(LOGE, FL("SAP Stop Failed"));
                        ret = -EINVAL;
                        goto error;
                    }
                }
            }
            status = vos_wait_single_event(&pHostapdAdapter->
                                           mdns_status.vos_event, 2000);
            if (!VOS_IS_STATUS_SUCCESS(status) ||
                pHostapdAdapter->mdns_status.mdns_enable_status ||
                pHostapdAdapter->mdns_status.mdns_fqdn_status ||
                pHostapdAdapter->mdns_status.mdns_resp_status)
            {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                          ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
                          pHostapdAdapter->mdns_status.mdns_enable_status,
                          pHostapdAdapter->mdns_status.mdns_fqdn_status,
                          pHostapdAdapter->mdns_status.mdns_resp_status);
                vos_event_reset(&pHostapdState->vosEvent);
                if (VOS_STATUS_SUCCESS ==
                    WLANSAP_StopBss(pHddCtx->pvosContext)) {
                    status = vos_wait_single_event(&pHostapdState->vosEvent,
                                                   10000);
                    if (!VOS_IS_STATUS_SUCCESS(status)) {
                        hddLog(LOGE, FL("SAP Stop Failed"));
                        ret = -EINVAL;
                        goto error;
                    }
                }
            }
        }
#endif /* MDNS_OFFLOAD */
    } else {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  ("DHCP Disabled ini %d, FW %d"),
                  iniConfig->enable_dhcp_srv_offload,
                  sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
    }
#endif /* DHCP_SERVER_OFFLOAD */

#ifdef WLAN_FEATURE_P2P_DEBUG
    if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
    {
         if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
         {
             globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
             hddLog(LOGE,"[P2P State] From Go nego completed to "
                         "Non-autonomous Group started");
         }
         else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
         {
             globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
             hddLog(LOGE,"[P2P State] From Inactive to "
                         "Autonomous Group started");
         }
    }
#endif
    /* Check and restart SAP if it is on Unsafe channel */
    hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);

    pHostapdState->bCommit = TRUE;
    EXIT();

   return 0;
error:
    if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
        wlan_hdd_restore_channels(pHddCtx);
   /* Revert the indoor to passive marking if START BSS fails */
    if (iniConfig->disable_indoor_channel &&
                   pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
        hdd_update_indoor_channel(pHddCtx, false);
        sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
    }

   clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
   return ret;
}

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
                                        struct net_device *dev,
                                        struct beacon_parameters *params)
{
    hdd_adapter_t *pAdapter =  WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t  *pHddCtx;
    int status;

    ENTER();

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_ADD_BEACON,
                     pAdapter->sessionId, params->interval));
    hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
           hdd_device_modetoString(pAdapter->device_mode),
           pAdapter->device_mode);

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    if (vos_max_concurrent_connections_reached()) {
        hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
        return -EINVAL;
    }

    if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
      || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
       )
    {
        beacon_data_t *old,*new;

        old = pAdapter->sessionCtx.ap.beacon;

        if (old)
        {
            hddLog(VOS_TRACE_LEVEL_WARN,
                   FL("already beacon info added to session(%d)"),
                       pAdapter->sessionId);
            return -EALREADY;
        }

        status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);

        if(status != VOS_STATUS_SUCCESS)
        {
             hddLog(VOS_TRACE_LEVEL_FATAL,
                   "%s:Error!!! Allocating the new beacon",__func__);
             return -EINVAL;
        }

        pAdapter->sessionCtx.ap.beacon = new;

        status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
    }

    EXIT();
    return status;
}

static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
                                        struct net_device *dev,
                                        struct beacon_parameters *params)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
    vos_ssr_unprotect(__func__);

    return ret;
}

static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
                                        struct net_device *dev,
                                        struct beacon_parameters *params)
{
    hdd_adapter_t *pAdapter =  WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    hdd_context_t  *pHddCtx;
    int status;

    ENTER();

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_SET_BEACON,
                     pAdapter->sessionId, pHddStaCtx->conn_info.authType));
    hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
           __func__, hdd_device_modetoString(pAdapter->device_mode),
                                             pAdapter->device_mode);

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
     || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
       )
    {
        beacon_data_t *old,*new;

        old = pAdapter->sessionCtx.ap.beacon;

        if (!old)
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   FL("session(%d) old and new heads points to NULL"),
                       pAdapter->sessionId);
            return -ENOENT;
        }

        status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);

        if(status != VOS_STATUS_SUCCESS) {
            hddLog(VOS_TRACE_LEVEL_FATAL,
                   "%s: Error!!! Allocating the new beacon",__func__);
            return -EINVAL;
       }

       pAdapter->sessionCtx.ap.beacon = new;

       status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
    }

    EXIT();
    return status;
}

static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
                                        struct net_device *dev,
                                        struct beacon_parameters *params)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
    vos_ssr_unprotect(__func__);

    return ret;
}

#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
                                        struct net_device *dev)
#else
static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
                                      struct net_device *dev)
#endif
{
    hdd_adapter_t *pAdapter =  WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t  *pHddCtx    = NULL;
    hdd_scaninfo_t *pScanInfo  = NULL;
    VOS_STATUS status;
    long ret;

    ENTER();

    if (NULL == pAdapter)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                   "%s: HDD adapter context is Null", __func__);
        return -ENODEV;
    }

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_STOP_AP,
                     pAdapter->sessionId, pAdapter->device_mode));
    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    pScanInfo =  &pHddCtx->scan_info;

    hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
           __func__, hdd_device_modetoString(pAdapter->device_mode),
                                             pAdapter->device_mode);

    ret = wlan_hdd_scan_abort(pAdapter);

    if (ret < 0)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   FL("Timeout occurred while waiting for abortscan %ld"), ret);

        if (pHddCtx->isLogpInProgress)
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: LOGP in Progress. Ignore!!!", __func__);

            VOS_ASSERT(pScanInfo->mScanPending);
            return -EAGAIN;
        }
        VOS_ASSERT(pScanInfo->mScanPending);
    }

    /* Delete all associated STAs before stopping AP/P2P GO */
    hdd_del_all_sta(pAdapter);
    hdd_hostapd_stop(dev);

    if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
     || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
       )
    {
        beacon_data_t *old;

        old = pAdapter->sessionCtx.ap.beacon;

        if (!old)
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   FL("session(%d) beacon data points to NULL"),
                      pAdapter->sessionId);
            return -ENOENT;
        }

        hdd_cleanup_actionframe(pHddCtx, pAdapter);

        mutex_lock(&pHddCtx->sap_lock);
        if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
        {
            vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
            hdd_wait_for_ecsa_complete(pHddCtx);
            if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
            {
                hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);

                status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);

                if (!VOS_IS_STATUS_SUCCESS(status))
                {
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                             ("ERROR: HDD vos wait for single_event failed!!"));
                    VOS_ASSERT(0);
                 }
             }
            clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
            /* BSS stopped, clear the active sessions for this device mode */
            wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
        }
        mutex_unlock(&pHddCtx->sap_lock);

        if(status != VOS_STATUS_SUCCESS)
        {
            hddLog(VOS_TRACE_LEVEL_FATAL,
                    "%s:Error!!! Stopping the BSS",__func__);
            return -EINVAL;
        }

        if (ccmCfgSetInt(pHddCtx->hHal,
            WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
                                                    ==eHAL_STATUS_FAILURE)
        {
            hddLog(LOGE,
               "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
        }

        if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
                            WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
                            eANI_BOOLEAN_FALSE) )
        {
            hddLog(LOGE,
               "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
        }

        // Reset WNI_CFG_PROBE_RSP Flags
        wlan_hdd_reset_prob_rspies(pAdapter);

        clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);

        pAdapter->sessionCtx.ap.beacon = NULL;
        kfree(old);
#ifdef WLAN_FEATURE_P2P_DEBUG
        if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
           (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
        {
            hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
                        "GO got removed");
            globalP2PConnectionStatus = P2P_NOT_ACTIVE;
        }
#endif
    }
    EXIT();
    return status;
}

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
                                        struct net_device *dev)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
    vos_ssr_unprotect(__func__);

    return ret;
}
#else
static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
                                      struct net_device *dev)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
    vos_ssr_unprotect(__func__);

    return ret;
}
#endif

#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))

static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
                                      struct net_device *dev,
                                      struct cfg80211_ap_settings *params)
{
    hdd_adapter_t *pAdapter;
    hdd_context_t *pHddCtx;
    int            status;

    ENTER();

    if (NULL == dev || NULL == params)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: Device or params is Null", __func__);
        return -ENODEV;
    }

    pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    if (NULL == pAdapter)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: HDD adapter is Null", __func__);
        return -ENODEV;
    }

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
                     params-> beacon_interval));
    if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: HDD adapter magic is invalid", __func__);
        return -ENODEV;
    }

    clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
           __func__, hdd_device_modetoString(pAdapter->device_mode),
                                             pAdapter->device_mode);

    if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
      || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
       )
    {
        beacon_data_t  *old, *new;

        old = pAdapter->sessionCtx.ap.beacon;

        if (old)
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                   FL("already beacon info added to session(%d)"),
                       pAdapter->sessionId);
            return -EALREADY;
        }

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
        status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
                                                    &new,
                                                    &params->beacon);
#else
        status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
                                                    &new,
                                                    &params->beacon,
                                                    params->dtim_period);
#endif

        if (status != 0)
        {
             hddLog(VOS_TRACE_LEVEL_FATAL,
                   "%s:Error!!! Allocating the new beacon", __func__);
             return -EINVAL;
        }
        pAdapter->sessionCtx.ap.beacon = new;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
        wlan_hdd_cfg80211_set_channel(wiphy, dev,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
        params->channel, params->channel_type);
#else
        params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
#endif
#endif
        status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
                                             params->ssid_len, params->hidden_ssid,
                                             params->auth_type);
    }

    EXIT();
    return status;
}

static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
                                      struct net_device *dev,
                                      struct cfg80211_ap_settings *params)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
    vos_ssr_unprotect(__func__);

    return ret;
}

static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
                                        struct net_device *dev,
                                        struct cfg80211_beacon_data *params)
{
    hdd_adapter_t *pAdapter =  WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx;
    int status;

    ENTER();

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
                     pAdapter->sessionId, pAdapter->device_mode));
    hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
                                __func__, pAdapter->device_mode);

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
     || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
       )
    {
        beacon_data_t *old,*new;

        old = pAdapter->sessionCtx.ap.beacon;

        if (!old)
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   FL("session(%d) beacon data points to NULL"),
                      pAdapter->sessionId);
            return -ENOENT;
        }

        status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);

        if(status != VOS_STATUS_SUCCESS) {
            hddLog(VOS_TRACE_LEVEL_FATAL,
                   "%s: Error!!! Allocating the new beacon",__func__);
            return -EINVAL;
       }

       pAdapter->sessionCtx.ap.beacon = new;

       status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
                                   pAdapter->sessionCtx.ap.sapConfig.authType);
    }

    EXIT();
    return status;
}

static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
                                        struct net_device *dev,
                                        struct cfg80211_beacon_data *params)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
    vos_ssr_unprotect(__func__);

    return ret;
}

#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))

static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
                                      struct net_device *dev,
                                      struct bss_parameters *params)
{
    hdd_adapter_t *pAdapter =  WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx;
    int ret = 0;

    ENTER();

    if (NULL == pAdapter)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: HDD adapter is Null", __func__);
        return -ENODEV;
    }
    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    ret = wlan_hdd_validate_context(pHddCtx);
    if (0 != ret)
    {
        return ret;
    }
    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
                     pAdapter->sessionId, params->ap_isolate));
    hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
           __func__, hdd_device_modetoString(pAdapter->device_mode),
                                             pAdapter->device_mode);

    if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
     ||  (pAdapter->device_mode == WLAN_HDD_P2P_GO)
      )
    {
        /* ap_isolate == -1 means that in change bss, upper layer doesn't
         * want to update this parameter */
        if (-1 != params->ap_isolate)
        {
            pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
        }
    }

    EXIT();
    return 0;
}

static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
                                      struct net_device *dev,
                                      struct bss_parameters *params)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
    vos_ssr_unprotect(__func__);

    return ret;
}
/* FUNCTION: wlan_hdd_change_country_code_cd
*  to wait for contry code completion
*/
void* wlan_hdd_change_country_code_cb(void *pAdapter)
{
    hdd_adapter_t *call_back_pAdapter = pAdapter;
    complete(&call_back_pAdapter->change_country_code);
    return NULL;
}

/*
 * FUNCTION: __wlan_hdd_cfg80211_change_iface
 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
 */
int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
                                    struct net_device *ndev,
                                    enum nl80211_iftype type,
                                    u32 *flags,
                                    struct vif_params *params
                                  )
{
    struct wireless_dev *wdev;
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
    hdd_context_t *pHddCtx;
    hdd_adapter_t  *pP2pAdapter = NULL;
    tCsrRoamProfile *pRoamProfile = NULL;
    eCsrRoamBssType LastBSSType;
    hdd_config_t *pConfig = NULL;
    eMib_dot11DesiredBssType connectedBssType;
    VOS_STATUS status;
    long ret;

    ENTER();

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

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    if (!pHddCtx)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: HDD context is null", __func__);
        return VOS_STATUS_E_FAILURE;
    }

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
                     pAdapter->sessionId, type));
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
            __func__, hdd_device_modetoString(pAdapter->device_mode),
                                              pAdapter->device_mode);

    if (pHddCtx->concurrency_mode == VOS_STA_MON) {
        hddLog(VOS_TRACE_LEVEL_FATAL,
               "%s: STA + MON is in progress, cannot change interface",
               __func__);
    }

    if (vos_max_concurrent_connections_reached()) {
        hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
        return -EINVAL;
    }
    pConfig = pHddCtx->cfg_ini;
    wdev = ndev->ieee80211_ptr;

#ifdef WLAN_BTAMP_FEATURE
    if((NL80211_IFTYPE_P2P_CLIENT == type)||
       (NL80211_IFTYPE_ADHOC == type)||
       (NL80211_IFTYPE_AP == type)||
       (NL80211_IFTYPE_P2P_GO == type))
    {
        pHddCtx->isAmpAllowed = VOS_FALSE;
        // stop AMP traffic
        status = WLANBAP_StopAmp();
        if(VOS_STATUS_SUCCESS != status )
        {
            pHddCtx->isAmpAllowed = VOS_TRUE;
            hddLog(VOS_TRACE_LEVEL_FATAL,
                   "%s: Failed to stop AMP", __func__);
            return -EINVAL;
        }
    }
#endif //WLAN_BTAMP_FEATURE
    /* Reset the current device mode bit mask*/
    wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);

    if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
        ((type == NL80211_IFTYPE_P2P_CLIENT) ||
         (type == NL80211_IFTYPE_P2P_GO)))
    {
        /* Notify Mode change in case of concurrency.
         * Below function invokes TDLS teardown Functionality Since TDLS is
         * not Supported in case of concurrency i.e Once P2P session
         * is detected disable offchannel and teardown TDLS links
         */
        hddLog(LOG1,
               FL("Device mode = %d Interface type = %d"),
               pAdapter->device_mode, type);
        hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
    }

    if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
      || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
      || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
      )
    {
        hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
        if (!pWextState)
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: pWextState is null", __func__);
            return VOS_STATUS_E_FAILURE;
        }
        pRoamProfile = &pWextState->roamProfile;
        LastBSSType = pRoamProfile->BSSType;

        switch (type)
        {
            case NL80211_IFTYPE_STATION:
            case NL80211_IFTYPE_P2P_CLIENT:
                hddLog(VOS_TRACE_LEVEL_INFO,
                   "%s: setting interface Type to INFRASTRUCTURE", __func__);
                pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
#ifdef WLAN_FEATURE_11AC
                if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
                {
                    pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
                }
#endif
                pRoamProfile->phyMode =
                hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
                wdev->iftype = type;
                //Check for sub-string p2p to confirm its a p2p interface
                if (NULL != strstr(ndev->name,"p2p"))
                {
#ifdef FEATURE_WLAN_TDLS
                   mutex_lock(&pHddCtx->tdls_lock);
                   wlan_hdd_tdls_exit(pAdapter, TRUE);
                   mutex_unlock(&pHddCtx->tdls_lock);
#endif
                    pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
                                WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
                }
                else
                {
                    pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
                                WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
                }
                break;

            case NL80211_IFTYPE_ADHOC:
                hddLog(VOS_TRACE_LEVEL_INFO,
                  "%s: setting interface Type to ADHOC", __func__);
                pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
                pRoamProfile->phyMode =
                    hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
                pAdapter->device_mode = WLAN_HDD_IBSS;
                wdev->iftype = type;
                hdd_set_ibss_ops( pAdapter );
                hdd_ibss_init_tx_rx( pAdapter );

                status = hdd_sta_id_hash_attach(pAdapter);
                if (VOS_STATUS_SUCCESS != status) {
                     hddLog(VOS_TRACE_LEVEL_ERROR,
                            FL("Failed to initialize hash for IBSS"));
                }
                break;

            case NL80211_IFTYPE_AP:
            case NL80211_IFTYPE_P2P_GO:
            {
                hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
                      "%s: setting interface Type to %s", __func__,
                      (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");

                //Cancel any remain on channel for GO mode
                if (NL80211_IFTYPE_P2P_GO == type)
                {
                    wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
                }
                if (NL80211_IFTYPE_AP == type)
                {
                     /* As Loading WLAN Driver one interface being created for p2p device
                      * address. This will take one HW STA and the max number of clients
                      * that can connect to softAP will be reduced by one. so while changing
                      * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
                      * interface as it is not required in SoftAP mode.
                      */

                    // Get P2P Adapter
                    pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);

                    if (pP2pAdapter)
                    {
                        hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
                        hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
                        hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
                    }
                }
                //Disable IMPS & BMPS for SAP/GO
                if(VOS_STATUS_E_FAILURE ==
                       hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
                {
                    //Fail to Exit BMPS
                    VOS_ASSERT(0);
                }

                hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );

#ifdef FEATURE_WLAN_TDLS

                /* A Mutex Lock is introduced while changing the mode to
                 * protect the concurrent access for the Adapters by TDLS
                 * module.
                 */
                mutex_lock(&pHddCtx->tdls_lock);
#endif
                //De-init the adapter.
                hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
                memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
                pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
                                   WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
#ifdef FEATURE_WLAN_TDLS
                mutex_unlock(&pHddCtx->tdls_lock);
#endif
                if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
                    (pConfig->apRandomBssidEnabled))
                {
                    /* To meet Android requirements create a randomized
                       MAC address of the form 02:1A:11:Fx:xx:xx */
                    get_random_bytes(&ndev->dev_addr[3], 3);
                    ndev->dev_addr[0] = 0x02;
                    ndev->dev_addr[1] = 0x1A;
                    ndev->dev_addr[2] = 0x11;
                    ndev->dev_addr[3] |= 0xF0;
                    memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
                           VOS_MAC_ADDR_SIZE);
                    pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
                            MAC_ADDR_ARRAY(ndev->dev_addr));
                }

                hdd_set_ap_ops( pAdapter->dev );

                /* This is for only SAP mode where users can
                 * control country through ini.
                 * P2P GO follows station country code
                 * acquired during the STA scanning. */
                if((NL80211_IFTYPE_AP == type) &&
                   (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
                {
                    int status = 0;
                    VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
                         "%s: setting country code from INI ", __func__);
                    init_completion(&pAdapter->change_country_code);
                    status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
                                     (void *)(tSmeChangeCountryCallback)
                                      wlan_hdd_change_country_code_cb,
                                      pConfig->apCntryCode, pAdapter,
                                      pHddCtx->pvosContext,
                                      eSIR_FALSE,
                                      eSIR_TRUE);
                    if (eHAL_STATUS_SUCCESS == status)
                    {
                        /* Wait for completion */
                        ret = wait_for_completion_interruptible_timeout(
                                       &pAdapter->change_country_code,
                                       msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
                        if (ret <= 0)
                        {
                            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                             FL("SME Timed out while setting country code %ld"),
                                 ret);

                            if (pHddCtx->isLogpInProgress)
                            {
                                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                                          "%s: LOGP in Progress. Ignore!!!", __func__);
                                return -EAGAIN;
                            }
                        }
                    }
                    else
                    {
                         VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                          "%s: SME Change Country code failed",__func__);
                         return -EINVAL;
                    }
                }
                status = hdd_init_ap_mode(pAdapter, false);
                if(status != VOS_STATUS_SUCCESS)
                {
                    hddLog(VOS_TRACE_LEVEL_FATAL,
                           "%s: Error initializing the ap mode", __func__);
                    return -EINVAL;
                }
                hdd_set_conparam(1);

                status = hdd_sta_id_hash_attach(pAdapter);
                if (VOS_STATUS_SUCCESS != status)
                {
                    hddLog(VOS_TRACE_LEVEL_ERROR,
                           FL("Failed to initialize hash for AP"));
                    return -EINVAL;
                }

                /*interface type changed update in wiphy structure*/
                if(wdev)
                {
                    wdev->iftype = type;
                    pHddCtx->change_iface = type;
                }
                else
                {
                    hddLog(VOS_TRACE_LEVEL_ERROR,
                            "%s: ERROR !!!! Wireless dev is NULL", __func__);
                    return -EINVAL;
                }
                goto done;
            }

            default:
                hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
                        __func__);
                return -EOPNOTSUPP;
        }
    }
    else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
           || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
            )
    {
       switch(type)
       {
           case NL80211_IFTYPE_STATION:
           case NL80211_IFTYPE_P2P_CLIENT:
           case NL80211_IFTYPE_ADHOC:

                hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
#ifdef FEATURE_WLAN_TDLS

                /* A Mutex Lock is introduced while changing the mode to
                 * protect the concurrent access for the Adapters by TDLS
                 * module.
                 */
                mutex_lock(&pHddCtx->tdls_lock);
#endif
                hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
                wdev->iftype = type;
                //Check for sub-string p2p to confirm its a p2p interface
                if (NULL != strstr(ndev->name,"p2p"))
                {
                    pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
                                  WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
                }
                else
                {
                    pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
                                  WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
                }

                /* set con_mode to STA only when no SAP concurrency mode */
                if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
                    hdd_set_conparam(0);
                pHddCtx->change_iface = type;
                memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
                hdd_set_station_ops( pAdapter->dev );
#ifdef FEATURE_WLAN_TDLS
                mutex_unlock(&pHddCtx->tdls_lock);
#endif
                status = hdd_init_station_mode( pAdapter );
                if( VOS_STATUS_SUCCESS != status )
                    return -EOPNOTSUPP;
                /* In case of JB, for P2P-GO, only change interface will be called,
                 * This is the right place to enable back bmps_imps()
                 */
                if (pHddCtx->hdd_wlan_suspended)
                {
                    hdd_set_pwrparams(pHddCtx);
                }
                hdd_enable_bmps_imps(pHddCtx);
                goto done;
            case NL80211_IFTYPE_AP:
            case NL80211_IFTYPE_P2P_GO:
                wdev->iftype = type;
                pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
                                        WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
               goto done;
           default:
                hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
                        __func__);
                return -EOPNOTSUPP;

       }

    }
    else
    {
      hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
           __func__, hdd_device_modetoString(pAdapter->device_mode),
                                             pAdapter->device_mode);
      return -EOPNOTSUPP;
    }


    if(pRoamProfile)
    {
        if ( LastBSSType != pRoamProfile->BSSType )
        {
            /*interface type changed update in wiphy structure*/
            wdev->iftype = type;

            /*the BSS mode changed, We need to issue disconnect
              if connected or in IBSS disconnect state*/
            if ( hdd_connGetConnectedBssType(
                 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
                ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
            {
                /*need to issue a disconnect to CSR.*/
                INIT_COMPLETION(pAdapter->disconnect_comp_var);
                if( eHAL_STATUS_SUCCESS ==
                        sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
                                pAdapter->sessionId,
                                eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
                {
                    ret = wait_for_completion_interruptible_timeout(
                                   &pAdapter->disconnect_comp_var,
                                   msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
                    if (ret <= 0)
                    {
                        hddLog(VOS_TRACE_LEVEL_ERROR,
                          FL("wait on disconnect_comp_var failed %ld"), ret);
                    }
                }
            }
        }
    }

done:
    /*set bitmask based on updated value*/
    wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);

   /* Only STA mode support TM now
    * all other mode, TM feature should be disabled */
    if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
         (~VOS_STA & pHddCtx->concurrency_mode) )
    {
        hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
    }

#ifdef WLAN_BTAMP_FEATURE
    if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
       (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
    {
        //we are ok to do AMP
        pHddCtx->isAmpAllowed = VOS_TRUE;
    }
#endif //WLAN_BTAMP_FEATURE
    EXIT();
    return 0;
}

/*
 * FUNCTION: wlan_hdd_cfg80211_change_iface
 * wrapper function to protect the actual implementation from SSR.
 */
int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
                                    struct net_device *ndev,
                                    enum nl80211_iftype type,
                                    u32 *flags,
                                    struct vif_params *params
                                  )
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
    vos_ssr_unprotect(__func__);

    return ret;
}

#ifdef FEATURE_WLAN_TDLS
static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
          struct net_device *dev,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
          const u8 *mac,
#else
          u8 *mac,
#endif
          bool update, tCsrStaParams *StaParams)
{
    hdd_context_t *pHddCtx = wiphy_priv(wiphy);
    hddTdlsPeer_t *pTdlsPeer;
    long ret;
    tANI_U16 numCurrTdlsPeers;
    hdd_adapter_t *pAdapter;
    VOS_STATUS status;

    ENTER();

    if (!dev) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
        return -EINVAL;
    }

    pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    if (!pAdapter) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
        return -EINVAL;
    }

    if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "Invalid arguments");
        return -EINVAL;
    }

    if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
        (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
    {
         VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                    "%s: TDLS mode is disabled OR not enabled in FW."
                    MAC_ADDRESS_STR " Request declined.",
                    __func__, MAC_ADDR_ARRAY(mac));
        return -ENOTSUPP;
    }

    if (pHddCtx->isLogpInProgress)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "%s:LOGP in Progress. Ignore!!!", __func__);
        wlan_hdd_tdls_set_link_status(pAdapter,
                                      mac,
                                      eTDLS_LINK_IDLE,
                                      eTDLS_LINK_UNSPECIFIED);
        return -EBUSY;
    }

    mutex_lock(&pHddCtx->tdls_lock);
    pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);

    if ( NULL == pTdlsPeer ) {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
               "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
               __func__, MAC_ADDR_ARRAY(mac), update);
        mutex_unlock(&pHddCtx->tdls_lock);
        return -EINVAL;
    }

    /* in add station, we accept existing valid staId if there is */
    if ((0 == update) &&
        ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
         (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                   "%s: " MAC_ADDRESS_STR
                   " link_status %d. staId %d. add station ignored.",
                   __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
        mutex_unlock(&pHddCtx->tdls_lock);
        return 0;
    }
    /* in change station, we accept only when staId is valid */
    if ((1 == update) &&
        ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
         (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
    {
        tANI_U16 staId = pTdlsPeer->staId;
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: " MAC_ADDRESS_STR
                   " link status %d. staId %d. change station %s.",
                   __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
                   (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
        mutex_unlock(&pHddCtx->tdls_lock);
        return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
    }
    mutex_unlock(&pHddCtx->tdls_lock);

    /* when others are on-going, we want to change link_status to idle */
    if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: " MAC_ADDRESS_STR
                   " TDLS setup is ongoing. Request declined.",
                   __func__, MAC_ADDR_ARRAY(mac));
        goto error;
    }

    /* first to check if we reached to maximum supported TDLS peer.
       TODO: for now, return -EPERM looks working fine,
       but need to check if any other errno fit into this category.*/
    numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
    if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: " MAC_ADDRESS_STR
                   " TDLS Max peer already connected. Request declined."
                   " Num of peers (%d), Max allowed (%d).",
                   __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
                   HDD_MAX_NUM_TDLS_STA);
        goto error;
    }
    else
    {
        hddTdlsPeer_t *pTdlsPeer;
        mutex_lock(&pHddCtx->tdls_lock);
        pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
        if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
        {
            mutex_unlock(&pHddCtx->tdls_lock);
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                       "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
                       __func__, MAC_ADDR_ARRAY(mac));
            return -EPERM;
        }
        mutex_unlock(&pHddCtx->tdls_lock);
    }
    if (0 == update)
        wlan_hdd_tdls_set_link_status(pAdapter,
                                      mac,
                                      eTDLS_LINK_CONNECTING,
                                      eTDLS_LINK_SUCCESS);

    /* debug code */
    if (NULL != StaParams)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  "%s: TDLS Peer Parameters.", __func__);
        if(StaParams->htcap_present)
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "ht_capa->extended_capabilities: %0x",
                      StaParams->HTCap.extendedHtCapInfo);
        }
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  "params->capability: %0x",StaParams->capability);
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
        if(StaParams->vhtcap_present)
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
                      StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
                      StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
        }
        {
            int i = 0;
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
            for (i = 0; i < sizeof(StaParams->supported_rates); i++)
               VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                          "[%d]: %x ", i, StaParams->supported_rates[i]);
        }
    }  /* end debug code */
    else if ((1 == update) && (NULL == StaParams))
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s : update is true, but staParams is NULL. Error!", __func__);
        return -EPERM;
    }

    INIT_COMPLETION(pAdapter->tdls_add_station_comp);

    if (!update)
    {
        /*Before adding sta make sure that device exited from BMPS*/
        if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                       "%s: Adding tdls peer sta. Disable BMPS", __func__);
            status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
            if (status != VOS_STATUS_SUCCESS) {
                hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
            }
        }

        ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
                pAdapter->sessionId, mac);
        if (ret != eHAL_STATUS_SUCCESS) {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    FL("Failed to add TDLS peer STA. Enable Bmps"));
            wlan_hdd_tdls_check_bmps(pAdapter);
            return -EPERM;
        }
    }
    else
    {
        ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                       pAdapter->sessionId, mac, StaParams);
        if (ret != eHAL_STATUS_SUCCESS) {
            hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
            return -EPERM;
        }
    }

    ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
           msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));

    mutex_lock(&pHddCtx->tdls_lock);
    pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);

    if ((pTdlsPeer != NULL) &&
         (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
    {
         hddLog(VOS_TRACE_LEVEL_ERROR,
                FL("peer link status %u"), pTdlsPeer->link_status);
         mutex_unlock(&pHddCtx->tdls_lock);
         goto error;
    }
    mutex_unlock(&pHddCtx->tdls_lock);

    if (ret <= 0)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "%s: timeout waiting for tdls add station indication %ld",
                __func__, ret);
        goto error;
    }

    if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "%s: Add Station is unsucessful", __func__);
        return -EPERM;
    }

    return 0;

error:
    wlan_hdd_tdls_set_link_status(pAdapter,
                                  mac,
                                  eTDLS_LINK_IDLE,
                                  eTDLS_LINK_UNSPECIFIED);
    return -EPERM;

}
#endif

VOS_STATUS wlan_hdd_send_sta_authorized_event(
					hdd_adapter_t *adapter,
					hdd_context_t *hdd_ctx,
					const v_MACADDR_t *mac_addr)
{
	struct sk_buff *vendor_event;
	uint32_t sta_flags = 0;
	VOS_STATUS status;

	ENTER();

	if (!hdd_ctx) {
		hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is null"));
		return -EINVAL;
	}

	vendor_event =
		cfg80211_vendor_event_alloc(
			hdd_ctx->wiphy,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
			&adapter->wdev,
#endif
			sizeof(sta_flags) +
			VOS_MAC_ADDR_SIZE + NLMSG_HDRLEN,
			QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX,
			GFP_KERNEL);
	if (!vendor_event) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       FL("cfg80211_vendor_event_alloc failed"));
		return -EINVAL;
	}

	sta_flags |= BIT(NL80211_STA_FLAG_AUTHORIZED);

	status = nla_put_u32(vendor_event,
			     QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS,
			     sta_flags);
	if (status) {
		hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA flag put fails"));
		kfree_skb(vendor_event);
		return VOS_STATUS_E_FAILURE;
	}
	status = nla_put(vendor_event,
			 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_MAC,
			 VOS_MAC_ADDR_SIZE, mac_addr->bytes);
	if (status) {
		hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA MAC put fails"));
		kfree_skb(vendor_event);
		return VOS_STATUS_E_FAILURE;
	}

	cfg80211_vendor_event(vendor_event, GFP_KERNEL);

	EXIT();
	return 0;
}

static int __wlan_hdd_change_station(struct wiphy *wiphy,
                                         struct net_device *dev,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
                                         const u8 *mac,
#else
                                         u8 *mac,
#endif
                                         struct station_parameters *params)
{
    VOS_STATUS status = VOS_STATUS_SUCCESS;
    hdd_adapter_t *pAdapter;
    hdd_context_t *pHddCtx;
    hdd_station_ctx_t *pHddStaCtx;
    v_MACADDR_t STAMacAddress;
    int ret = 0;
#ifdef FEATURE_WLAN_TDLS
    tCsrStaParams StaParams = {0};
    tANI_U8 isBufSta = 0;
    tANI_U8 isOffChannelSupported = 0;
    tANI_U8 isQosWmmSta = FALSE;
#endif

    ENTER();

    pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    if ((NULL == pAdapter))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                  "invalid adapter ");
        return -EINVAL;
    }

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CHANGE_STATION,
                      pAdapter->sessionId, params->listen_interval));
    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);

    ret = wlan_hdd_validate_context(pHddCtx);
    if (0 != ret)
    {
        return ret;
    }

    pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

    if (NULL == pHddStaCtx)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                  "invalid HDD station context");
        return -EINVAL;
    }
    vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));

    if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
      || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
    {
        if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
        {
            status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
                                                  WLANTL_STA_AUTHENTICATED);

            if (status != VOS_STATUS_SUCCESS)
            {
                VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                         "%s: Not able to change TL state to AUTHENTICATED", __func__);
                return -EINVAL;
            }
            status = wlan_hdd_send_sta_authorized_event(pAdapter, pHddCtx,
                                                        &STAMacAddress);
            if (status != VOS_STATUS_SUCCESS)
                return -EINVAL;
        }
    }
    else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
          || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
#ifdef FEATURE_WLAN_TDLS
        if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
            StaParams.capability = params->capability;
            StaParams.uapsd_queues = params->uapsd_queues;
            StaParams.max_sp = params->max_sp;

            /* Convert (first channel , number of channels) tuple to
             * the total list of channels. This goes with the assumption
             * that if the first channel is < 14, then the next channels
             * are an incremental of 1 else an incremental of 4 till the number
             * of channels.
             */
            if (0 != params->supported_channels_len) {
                int i = 0,j = 0,k = 0, no_of_channels = 0 ;
                for ( i = 0 ; i < params->supported_channels_len ; i+=2)
                {
                    int wifi_chan_index;
                    StaParams.supported_channels[j] = params->supported_channels[i];
                    wifi_chan_index =
                        ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
                    no_of_channels = params->supported_channels[i+1];
                    for(k=1; k <= no_of_channels; k++)
                    {
                        StaParams.supported_channels[j+1] =
                              StaParams.supported_channels[j] + wifi_chan_index;
                        j+=1;
                    }
                }
                StaParams.supported_channels_len = j;
            }
            if (params->supported_oper_classes_len >
                SIR_MAC_MAX_SUPP_OPER_CLASSES) {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                          "received oper classes:%d, resetting it to max supported %d",
                          params->supported_oper_classes_len,
                          SIR_MAC_MAX_SUPP_OPER_CLASSES);
                params->supported_oper_classes_len =
                    SIR_MAC_MAX_SUPP_OPER_CLASSES;
            }
            vos_mem_copy(StaParams.supported_oper_classes,
                         params->supported_oper_classes,
                         params->supported_oper_classes_len);
            StaParams.supported_oper_classes_len  =
                                             params->supported_oper_classes_len;

            if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                          "received extn capabilities:%d, resetting it to max supported",
                          params->ext_capab_len);
                params->ext_capab_len = sizeof(StaParams.extn_capability);
            }
            if (0 != params->ext_capab_len)
                vos_mem_copy(StaParams.extn_capability, params->ext_capab,
                             params->ext_capab_len);

            if (NULL != params->ht_capa)
            {
                StaParams.htcap_present = 1;
                vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
            }

            StaParams.supported_rates_len = params->supported_rates_len;

            /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
             * The supported_rates array , for all the structures propogating till Add Sta
             * to the firmware has to be modified , if the supplicant (ieee80211) is
             * modified to send more rates.
             */

            /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
             */
            if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
                StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;

            if (0 != StaParams.supported_rates_len) {
                int i = 0;
                vos_mem_copy(StaParams.supported_rates, params->supported_rates,
                             StaParams.supported_rates_len);
                VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                           "Supported Rates with Length %d", StaParams.supported_rates_len);
                for (i=0; i < StaParams.supported_rates_len; i++)
                    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                               "[%d]: %0x", i, StaParams.supported_rates[i]);
            }

            if (NULL != params->vht_capa)
            {
                StaParams.vhtcap_present = 1;
                vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
            }

            if (0 != params->ext_capab_len ) {
                /*Define A Macro : TODO Sunil*/
                if ((1<<4) & StaParams.extn_capability[3]) {
                    isBufSta = 1;
                }
                /* TDLS Channel Switching Support */
                if ((1<<6) & StaParams.extn_capability[3]) {
                    isOffChannelSupported = 1;
                }
            }

            if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
                (params->ht_capa || params->vht_capa ||
                (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
                /* TDLS Peer is WME/QoS capable */
                isQosWmmSta = TRUE;

            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
                      __func__, isQosWmmSta, StaParams.htcap_present);

            status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
                                                  &StaParams, isBufSta,
                                                  isOffChannelSupported,
                                                  isQosWmmSta);

            if (VOS_STATUS_SUCCESS != status) {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                          "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
                return -EINVAL;
            }
            status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);

            if (VOS_STATUS_SUCCESS != status) {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                          "%s: sme_ChangeTdlsPeerSta failed!", __func__);
                return -EINVAL;
            }
        }
#endif
    }
    EXIT();
    return status;
}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
static int wlan_hdd_change_station(struct wiphy *wiphy,
                                         struct net_device *dev,
                                         const u8 *mac,
                                         struct station_parameters *params)
#else
static int wlan_hdd_change_station(struct wiphy *wiphy,
                                         struct net_device *dev,
                                         u8 *mac,
                                         struct station_parameters *params)
#endif
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
    vos_ssr_unprotect(__func__);

    return ret;
}

/*
 * FUNCTION: __wlan_hdd_cfg80211_add_key
 * This function is used to initialize the key information
 */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
                                      struct net_device *ndev,
                                      u8 key_index, bool pairwise,
                                      const u8 *mac_addr,
                                      struct key_params *params
                                      )
#else
static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
                                      struct net_device *ndev,
                                      u8 key_index, const u8 *mac_addr,
                                      struct key_params *params
                                      )
#endif
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
    tCsrRoamSetKey  setKey;
    u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
    int status;
    v_U32_t roamId= 0xFF;
    v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
    hdd_hostapd_state_t *pHostapdState;
    VOS_STATUS vos_status;
    eHalStatus halStatus;
    hdd_context_t *pHddCtx;
    uint8_t i;
    v_MACADDR_t *peerMacAddr;
    u64 rsc_counter = 0;
    uint8_t staid = HDD_MAX_STA_COUNT;
    bool pairwise_set_key = false;

    ENTER();

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_ADD_KEY,
                      pAdapter->sessionId, params->key_len));
    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
            __func__, hdd_device_modetoString(pAdapter->device_mode),
                                              pAdapter->device_mode);

    if (CSR_MAX_NUM_KEY <= key_index)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
                key_index);

        return -EINVAL;
    }

    if (CSR_MAX_KEY_LEN < params->key_len)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
                params->key_len);

        return -EINVAL;
    }

    if (CSR_MAX_RSC_LEN < params->seq_len)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
                params->seq_len);

        return -EINVAL;
    }

    hddLog(VOS_TRACE_LEVEL_INFO,
           "%s: called with key index = %d & key length %d & seq length %d",
           __func__, key_index, params->key_len, params->seq_len);

    peerMacAddr = (v_MACADDR_t *)mac_addr;

    /*extract key idx, key len and key*/
    vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
    setKey.keyId = key_index;
    setKey.keyLength = params->key_len;
    vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
    vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);

    switch (params->cipher)
    {
        case WLAN_CIPHER_SUITE_WEP40:
            setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
            break;

        case WLAN_CIPHER_SUITE_WEP104:
            setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
            break;

        case WLAN_CIPHER_SUITE_TKIP:
            {
                u8 *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, params->key, 16);

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

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


                break;
            }

        case WLAN_CIPHER_SUITE_CCMP:
            setKey.encType = eCSR_ENCRYPT_TYPE_AES;
            break;

#ifdef FEATURE_WLAN_WAPI
        case WLAN_CIPHER_SUITE_SMS4:
            {
                vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
                wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
                        params->key, params->key_len);
                return 0;
            }
#endif

#ifdef FEATURE_WLAN_ESE
        case WLAN_CIPHER_SUITE_KRK:
            setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
            break;
#endif

#ifdef WLAN_FEATURE_11W
        case WLAN_CIPHER_SUITE_AES_CMAC:
            setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
            break;
#endif

        default:
            hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
                    __func__, params->cipher);
            status = -EOPNOTSUPP;
            goto end;
    }

    hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
            __func__, setKey.encType);

    if (
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
                (!pairwise)
#else
                (!mac_addr || is_broadcast_ether_addr(mac_addr))
#endif
       )
    {
        /* set group key*/
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                "%s- %d: setting Broadcast key",
                __func__, __LINE__);
        setKey.keyDirection = eSIR_RX_ONLY;
        vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
    }
    else
    {
        /* set pairwise key*/
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                "%s- %d: setting pairwise key",
                __func__, __LINE__);
        setKey.keyDirection = eSIR_TX_RX;
        vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
        pairwise_set_key = true;
    }
    if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
    {
        setKey.keyDirection = eSIR_TX_RX;
        /*Set the group key*/
        status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
            pAdapter->sessionId, &setKey, &roamId );

        if ( 0 != status )
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    "%s: sme_RoamSetKey failed, returned %d", __func__, status);
            status = -EINVAL;
            goto end;
        }
        /*Save the keys here and call sme_RoamSetKey for setting
          the PTK after peer joins the IBSS network*/
        vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
                                    &setKey, sizeof(tCsrRoamSetKey));
        goto end;
    }
    if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
           (pAdapter->device_mode == WLAN_HDD_P2P_GO))
    {
        pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
        if( pHostapdState->bssState == BSS_START )
        {
            hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
            vos_status = wlan_hdd_check_ula_done(pAdapter);

            if (peerMacAddr && (pairwise_set_key == true))
                staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);

            if ( vos_status != VOS_STATUS_SUCCESS )
            {
                VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                        "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
                        __LINE__, vos_status );

                pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;

                status = -EINVAL;
                goto end;
            }

            status = WLANSAP_SetKeySta( pVosContext, &setKey);

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

        /* Saving WEP keys */
        else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY  == setKey.encType ||
                eCSR_ENCRYPT_TYPE_WEP104_STATICKEY  == setKey.encType  )
        {
            //Save the wep key in ap context. Issue setkey after the BSS is started.
            hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
            vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
        }
        else
        {
            //Save the key in ap context. Issue setkey after the BSS is started.
            hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
            vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
        }
    }
    else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
              (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
    {
        hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
        hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
        if (!pairwise)
#else
        if (!mac_addr || is_broadcast_ether_addr(mac_addr))
#endif
        {
            /* set group key*/
            if (pHddStaCtx->roam_info.deferKeyComplete)
            {
                VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                           "%s- %d: Perform Set key Complete",
                           __func__, __LINE__);
                hdd_PerformRoamSetKeyComplete(pAdapter);
            }
        }

        if (pairwise_set_key == true)
           staid = pHddStaCtx->conn_info.staId[0];

        pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;

        pWextState->roamProfile.Keys.defaultIndex = key_index;


        vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
                params->key, params->key_len);


        pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;

        hddLog(VOS_TRACE_LEVEL_INFO_MED,
                "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
                __func__, setKey.peerMac[0], setKey.peerMac[1],
                setKey.peerMac[2], setKey.peerMac[3],
                setKey.peerMac[4], setKey.peerMac[5],
                setKey.keyDirection);

        vos_status = wlan_hdd_check_ula_done(pAdapter);

        if ( vos_status != VOS_STATUS_SUCCESS )
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                    "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
                    __LINE__, vos_status );

            pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;

            status = -EINVAL;
            goto end;

        }

#ifdef WLAN_FEATURE_VOWIFI_11R
        /* The supplicant may attempt to set the PTK once pre-authentication
           is done. Save the key in the UMAC and include it in the ADD BSS
           request */
        halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
        if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
        {
           hddLog(VOS_TRACE_LEVEL_INFO_MED,
                  "%s: Update PreAuth Key success", __func__);
           status = 0;
           goto end;
        }
        else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
        {
           hddLog(VOS_TRACE_LEVEL_ERROR,
                  "%s: Update PreAuth Key failed", __func__);
           status = -EINVAL;
           goto end;
        }
#endif /* WLAN_FEATURE_VOWIFI_11R */

        /* issue set key request to SME*/
        status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
                pAdapter->sessionId, &setKey, &roamId );

        if ( 0 != status )
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    "%s: sme_RoamSetKey failed, returned %d", __func__, status);
            pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
            status = -EINVAL;
            goto end;
        }


        /* in case of IBSS as there was no information available about WEP keys during
         * IBSS join, group key intialized with NULL key, so re-initialize group key
         * with correct value*/
        if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
            !(  ( IW_AUTH_KEY_MGMT_802_1X
                    == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
                    && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
                 )
                &&
                (  (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
                   || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
                )
           )
        {
            setKey.keyDirection = eSIR_RX_ONLY;
            vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);

            hddLog(VOS_TRACE_LEVEL_INFO_MED,
                    "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
                    __func__, setKey.peerMac[0], setKey.peerMac[1],
                    setKey.peerMac[2], setKey.peerMac[3],
                    setKey.peerMac[4], setKey.peerMac[5],
                    setKey.keyDirection);

            status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
                    pAdapter->sessionId, &setKey, &roamId );

            if ( 0 != status )
            {
                hddLog(VOS_TRACE_LEVEL_ERROR,
                        "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
                        __func__, status);
                pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
                status = -EINVAL;
                goto end;
            }
        }
    }

    if (pairwise_set_key == true) {
       for (i = 0; i < params->seq_len; i++) {
          rsc_counter |= (params->seq[i] << i*8);
       }
       WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
    }

end:
    /* Need to clear any trace of key value in the memory.
     * Thus zero out the memory even though it is local
     * variable.
     */
    vos_mem_zero(&setKey, sizeof(setKey));
    EXIT();
    return status;
}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
                                      struct net_device *ndev,
                                      u8 key_index, bool pairwise,
                                      const u8 *mac_addr,
                                      struct key_params *params
                                      )
#else
static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
                                      struct net_device *ndev,
                                      u8 key_index, const u8 *mac_addr,
                                      struct key_params *params
                                      )
#endif
{
    int ret;
    vos_ssr_protect(__func__);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
    ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
                                      mac_addr, params);
#else
    ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
                                       params);
#endif
    vos_ssr_unprotect(__func__);

    return ret;
}

/*
 * FUNCTION: __wlan_hdd_cfg80211_get_key
 * This function is used to get the key information
 */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
static int __wlan_hdd_cfg80211_get_key(
                        struct wiphy *wiphy,
                        struct net_device *ndev,
                        u8 key_index, bool pairwise,
                        const u8 *mac_addr, void *cookie,
                        void (*callback)(void *cookie, struct key_params*)
                        )
#else
static int __wlan_hdd_cfg80211_get_key(
                        struct wiphy *wiphy,
                        struct net_device *ndev,
                        u8 key_index, const u8 *mac_addr, void *cookie,
                        void (*callback)(void *cookie, struct key_params*)
                        )
#endif
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
    hdd_wext_state_t *pWextState = NULL;
    tCsrRoamProfile *pRoamProfile = NULL;
    struct key_params params;
    hdd_context_t *pHddCtx;
    int ret = 0;

    ENTER();

    if (NULL == pAdapter)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: HDD adapter is Null", __func__);
        return -ENODEV;
    }

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

    pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    pRoamProfile = &(pWextState->roamProfile);

    hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
            __func__, hdd_device_modetoString(pAdapter->device_mode),
                                              pAdapter->device_mode);

    memset(&params, 0, sizeof(params));

    if (CSR_MAX_NUM_KEY <= key_index)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
        return -EINVAL;
    }

    switch(pRoamProfile->EncryptionType.encryptionType[0])
    {
        case eCSR_ENCRYPT_TYPE_NONE:
            params.cipher = IW_AUTH_CIPHER_NONE;
            break;

        case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
        case eCSR_ENCRYPT_TYPE_WEP40:
            params.cipher = WLAN_CIPHER_SUITE_WEP40;
            break;

        case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
        case eCSR_ENCRYPT_TYPE_WEP104:
            params.cipher = WLAN_CIPHER_SUITE_WEP104;
            break;

        case eCSR_ENCRYPT_TYPE_TKIP:
            params.cipher = WLAN_CIPHER_SUITE_TKIP;
            break;

        case eCSR_ENCRYPT_TYPE_AES:
            params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
            break;

        default:
            params.cipher = IW_AUTH_CIPHER_NONE;
            break;
    }

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_GET_KEY,
                     pAdapter->sessionId, params.cipher));

    params.key_len = pRoamProfile->Keys.KeyLength[key_index];
    params.seq_len = 0;
    params.seq = NULL;
    params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
    callback(cookie, &params);
    EXIT();
    return 0;
}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
static int wlan_hdd_cfg80211_get_key(
                        struct wiphy *wiphy,
                        struct net_device *ndev,
                        u8 key_index, bool pairwise,
                        const u8 *mac_addr, void *cookie,
                        void (*callback)(void *cookie, struct key_params*)
                        )
#else
static int wlan_hdd_cfg80211_get_key(
                        struct wiphy *wiphy,
                        struct net_device *ndev,
                        u8 key_index, const u8 *mac_addr, void *cookie,
                        void (*callback)(void *cookie, struct key_params*)
                        )
#endif
{
    int ret;

    vos_ssr_protect(__func__);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
    ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
                                    mac_addr, cookie, callback);
#else
    ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
                                    callback);
#endif
    vos_ssr_unprotect(__func__);

    return ret;
}

/*
 * FUNCTION: __wlan_hdd_cfg80211_del_key
 * This function is used to delete the key information
 */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
                                      struct net_device *ndev,
                                      u8 key_index,
                                      bool pairwise,
                                      const u8 *mac_addr
                                    )
#else
static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
                                      struct net_device *ndev,
                                      u8 key_index,
                                      const u8 *mac_addr
                                    )
#endif
{
    int status = 0;

    //This code needs to be revisited. There is sme_removeKey API, we should
    //plan to use that. After the change to use correct index in setkey,
    //it is observed that this is invalidating peer
    //key index whenever re-key is done. This is affecting data link.
    //It should be ok to ignore del_key.
#if 0
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
    v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
    u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
    tCsrRoamSetKey  setKey;
    v_U32_t roamId= 0xFF;

    ENTER();

    hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
                                     __func__,pAdapter->device_mode);

    if (CSR_MAX_NUM_KEY <= key_index)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
                key_index);

        return -EINVAL;
    }

    vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
    setKey.keyId = key_index;

    if (mac_addr)
        vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
    else
        vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);

    setKey.encType = eCSR_ENCRYPT_TYPE_NONE;

    if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
      || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
       )
    {

        hdd_hostapd_state_t *pHostapdState =
                                  WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
        if( pHostapdState->bssState == BSS_START)
        {
            status = WLANSAP_SetKeySta( pVosContext, &setKey);

            if ( status != eHAL_STATUS_SUCCESS )
            {
                VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                     "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
                     __LINE__, status );
            }
        }
    }
    else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
           || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
            )
    {
        hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

        pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;

        hddLog(VOS_TRACE_LEVEL_INFO_MED,
                "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
                __func__, setKey.peerMac[0], setKey.peerMac[1],
                setKey.peerMac[2], setKey.peerMac[3],
                setKey.peerMac[4], setKey.peerMac[5]);
        if(pAdapter->sessionCtx.station.conn_info.connState ==
                                       eConnectionState_Associated)
        {
            status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
                                   pAdapter->sessionId, &setKey, &roamId );

            if ( 0 != status )
            {
                hddLog(VOS_TRACE_LEVEL_ERROR,
                        "%s: sme_RoamSetKey failure, returned %d",
                                                     __func__, status);
                pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
                return -EINVAL;
            }
        }
    }
#endif
    EXIT();
    return status;
}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
                                      struct net_device *ndev,
                                      u8 key_index,
                                      bool pairwise,
                                      const u8 *mac_addr
                                    )
#else
static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
                                      struct net_device *ndev,
                                      u8 key_index,
                                      const u8 *mac_addr
                                    )
#endif
{
    int ret;

    vos_ssr_protect(__func__);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
    ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
                                    mac_addr);
#else
    ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
#endif
    vos_ssr_unprotect(__func__);

    return ret;
}

/*
 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
 * This function is used to set the default tx key index
 */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
                                              struct net_device *ndev,
                                              u8 key_index,
                                              bool unicast, bool multicast)
#else
static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
                                              struct net_device *ndev,
                                              u8 key_index)
#endif
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
    int status;
    hdd_wext_state_t *pWextState;
    hdd_station_ctx_t *pHddStaCtx;
    hdd_context_t *pHddCtx;

    ENTER();

    if ((NULL == pAdapter))
    {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
          "invalid adapter");
       return -EINVAL;
    }

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
                     pAdapter->sessionId, key_index));

    pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

    if ((NULL == pWextState) || (NULL == pHddStaCtx))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                  "invalid Wext state or HDD context");
        return -EINVAL;
    }

    hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
                                         __func__,pAdapter->device_mode, key_index);

    if (CSR_MAX_NUM_KEY <= key_index)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
                key_index);

        return -EINVAL;
    }

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
     || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
       )
    {
        if ( (eCSR_ENCRYPT_TYPE_TKIP !=
                pHddStaCtx->conn_info.ucEncryptionType) &&
#ifdef FEATURE_WLAN_WAPI
             (eCSR_ENCRYPT_TYPE_WPI !=
                pHddStaCtx->conn_info.ucEncryptionType) &&
#endif
             (eCSR_ENCRYPT_TYPE_AES !=
                pHddStaCtx->conn_info.ucEncryptionType)
           )
        {
            /* if default key index is not same as previous one,
             * then update the default key index */

            tCsrRoamSetKey  setKey;
            v_U32_t roamId= 0xFF;
            tCsrKeys *Keys = &pWextState->roamProfile.Keys;

            hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
                    __func__, key_index);

            Keys->defaultIndex = (u8)key_index;
            vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
            setKey.keyId = key_index;
            setKey.keyLength = Keys->KeyLength[key_index];

            vos_mem_copy(&setKey.Key[0],
                    &Keys->KeyMaterial[key_index][0],
                    Keys->KeyLength[key_index]);

            setKey.keyDirection = eSIR_TX_RX;

            vos_mem_copy(setKey.peerMac,
                    &pHddStaCtx->conn_info.bssId[0],
                    WNI_CFG_BSSID_LEN);

            if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
               pWextState->roamProfile.EncryptionType.encryptionType[0] ==
               eCSR_ENCRYPT_TYPE_WEP104)
            {
                /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
                 even though ap is configured for WEP-40 encryption. In this canse the key length
                 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
                 type(104) and switching encryption type to 40*/
                pWextState->roamProfile.EncryptionType.encryptionType[0] =
                   eCSR_ENCRYPT_TYPE_WEP40;
                pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
                   eCSR_ENCRYPT_TYPE_WEP40;
            }

            setKey.encType =
                pWextState->roamProfile.EncryptionType.encryptionType[0];

            /* issue set key request */
            status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
                                   pAdapter->sessionId, &setKey, &roamId );

            if ( 0 != status )
            {
                hddLog(VOS_TRACE_LEVEL_ERROR,
                        "%s: sme_RoamSetKey failed, returned %d", __func__,
                        status);
                return -EINVAL;
            }
        }
    }

    /* In SoftAp mode setting key direction for default mode */
    else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
    {
        if ( (eCSR_ENCRYPT_TYPE_TKIP !=
                pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
             (eCSR_ENCRYPT_TYPE_AES !=
                pWextState->roamProfile.EncryptionType.encryptionType[0])
           )
        {
            /*  Saving key direction for default key index to TX default */
            hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
            pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
        }
    }
    EXIT();
    return status;
}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
                                              struct net_device *ndev,
                                              u8 key_index,
                                              bool unicast, bool multicast)
#else
static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
                                              struct net_device *ndev,
                                              u8 key_index)
#endif
{
    int ret;
    vos_ssr_protect(__func__);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
    ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
                                              multicast);
#else
    ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
#endif
    vos_ssr_unprotect(__func__);

    return ret;
}

/*
 * FUNCTION: wlan_hdd_cfg80211_inform_bss
 * This function is used to inform the BSS details to nl80211 interface.
 */
static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
                    hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
{
    struct net_device *dev = pAdapter->dev;
    struct wireless_dev *wdev = dev->ieee80211_ptr;
    struct wiphy *wiphy = wdev->wiphy;
    tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
    int chan_no;
    int ie_length;
    const char *ie;
    unsigned int freq;
    struct ieee80211_channel *chan;
    int rssi = 0;
    struct cfg80211_bss *bss = NULL;

    if( NULL == pBssDesc )
    {
        hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
        return bss;
    }

    chan_no = pBssDesc->channelId;
    ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
    ie =  ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);

    if( NULL == ie )
    {
       hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
       return bss;
    }

#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
    if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
    {
        freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
    }
    else
    {
        freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
    }
#else
    freq = ieee80211_channel_to_frequency(chan_no);
#endif

    chan = __ieee80211_get_channel(wiphy, freq);

    if (!chan) {
       hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
       return NULL;
    }

    rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;

    return cfg80211_inform_bss(wiphy, chan,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
                CFG80211_BSS_FTYPE_UNKNOWN,
#endif
                pBssDesc->bssId,
                le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
                pBssDesc->capabilityInfo,
                pBssDesc->beaconInterval, ie, ie_length,
                rssi, GFP_KERNEL );
}

/*
 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
 * interface that BSS might have been lost.
 * @pAdapter: adaptor
 * @bssid: bssid which might have been lost
 *
 * Return: bss which is unlinked from kernel cache
 */
struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
   hdd_adapter_t *pAdapter, tSirMacAddr bssid)
{
    struct net_device *dev = pAdapter->dev;
    struct wireless_dev *wdev = dev->ieee80211_ptr;
    struct wiphy *wiphy = wdev->wiphy;
    struct cfg80211_bss *bss = NULL;

    bss = hdd_get_bss_entry(wiphy,
          NULL, bssid,
          NULL, 0);
    if (bss == NULL) {
        hddLog(LOGE, FL("BSS not present"));
    } else {
        hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
               MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
        cfg80211_unlink_bss(wiphy, bss);
    }
    return bss;
}


/*
 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
 * This function is used to inform the BSS details to nl80211 interface.
 */
struct cfg80211_bss*
wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
                                    tSirBssDescription *bss_desc
                                    )
{
    /*
      cfg80211_inform_bss() is not updating ie field of bss entry, if entry
      already exists in bss data base of cfg80211 for that particular BSS ID.
      Using cfg80211_inform_bss_frame to update the bss entry instead of
      cfg80211_inform_bss, But this call expects mgmt packet as input. As of
      now there is no possibility to get the mgmt(probe response) frame from PE,
      converting bss_desc to ieee80211_mgmt(probe response) and passing to
      cfg80211_inform_bss_frame.
     */
    struct net_device *dev = pAdapter->dev;
    struct wireless_dev *wdev = dev->ieee80211_ptr;
    struct wiphy *wiphy = wdev->wiphy;
    int chan_no = bss_desc->channelId;
#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
    qcom_ie_age *qie_age = NULL;
    int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
#else
    int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
#endif
    const char *ie =
        ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
    unsigned int freq;
    struct ieee80211_channel *chan;
    struct ieee80211_mgmt *mgmt = NULL;
    struct cfg80211_bss *bss_status = NULL;
    size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
    int rssi = 0;
    hdd_context_t *pHddCtx;
    int status;
#ifdef WLAN_OPEN_SOURCE
    struct timespec ts;
#endif


    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return NULL;
    }

    mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
    if (!mgmt)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: memory allocation failed ", __func__);
        return NULL;
    }

    memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);

#ifdef WLAN_OPEN_SOURCE
    /* Android does not want the timestamp from the frame.
       Instead it wants a monotonic increasing value */
    get_monotonic_boottime(&ts);
    mgmt->u.probe_resp.timestamp =
         ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
#else
    /* keep old behavior for non-open source (for now) */
    memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
            sizeof (bss_desc->timeStamp));

#endif

    mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
    mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;

#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
    /* GPS Requirement: need age ie per entry. Using vendor specific. */
    /* Assuming this is the last IE, copy at the end */
    ie_length           -=sizeof(qcom_ie_age);
    qie_age =  (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
    qie_age->element_id = QCOM_VENDOR_IE_ID;
    qie_age->len        = QCOM_VENDOR_IE_AGE_LEN;
    qie_age->oui_1      = QCOM_OUI1;
    qie_age->oui_2      = QCOM_OUI2;
    qie_age->oui_3      = QCOM_OUI3;
    qie_age->type       = QCOM_VENDOR_IE_AGE_TYPE;
    /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
     * bss related timestamp is in units of ms. Due to this when scan results
     * are sent to lowi the scan age is high.To address this, send age in units
     * of 1/10 ms.
     */
    qie_age->age        = (vos_timer_get_system_time() -
                                   bss_desc->nReceivedTime)/10;
#endif

    memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
    if (bss_desc->fProbeRsp)
    {
         mgmt->frame_control |=
                   (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
    }
    else
    {
         mgmt->frame_control |=
                   (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
    }

#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
    if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
        (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL))
    {
        freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
    }
    else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
        (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL))

    {
        freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
    }
    else
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
                                                 __func__, chan_no);
        kfree(mgmt);
        return NULL;
    }
#else
    freq = ieee80211_channel_to_frequency(chan_no);
#endif
    chan = __ieee80211_get_channel(wiphy, freq);
    /*when the band is changed on the fly using the GUI, three things are done
     * 1. scan abort 2.flush scan results from cache 3.update the band with the new band user specified(refer to the hdd_setBand_helper function)
     * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
     * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
     * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
     * and discards the channels correponding to previous band and calls back with zero bss results.
     * but if the time between band update and scan done callback is very small then band change will not reflect in SME and SME reports to HDD
     * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
     * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
     * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
     * So drop the bss and continue to next bss.
     */
    if(chan == NULL)
    {
       hddLog(VOS_TRACE_LEVEL_ERROR,
           FL("chan pointer is NULL, chan_no: %d freq: %d"),
           chan_no, freq);
       kfree(mgmt);
       return NULL;
    }
    /*To keep the rssi icon of the connected AP in the scan window
    *and the rssi icon of the wireless networks in sync
    * */
    if (( eConnectionState_Associated ==
             pAdapter->sessionCtx.station.conn_info.connState ) &&
             ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
                             pAdapter->sessionCtx.station.conn_info.bssId,
                             WNI_CFG_BSSID_LEN)) &&
                             (pHddCtx->hdd_wlan_suspended == FALSE))
    {
       /* supplicant takes the signal strength in terms of mBm(100*dBm) */
       rssi = (pAdapter->rssi * 100);
    }
    else
    {
       rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
    }

    hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
          " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
                      vos_freq_to_chan(chan->center_freq), (int)(rssi/100));

    bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
            frame_len, rssi, GFP_KERNEL);
    kfree(mgmt);
    return bss_status;
}

/*
 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
 * This function is used to update the BSS data base of CFG8011
 */
struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
                                      tCsrRoamInfo *pRoamInfo
                                      )
{
    tCsrRoamConnectedProfile roamProfile;
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    struct cfg80211_bss *bss = NULL;

    ENTER();

    memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
    sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);

    if (NULL != roamProfile.pBssDesc)
    {
        bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
                roamProfile.pBssDesc);

        if (NULL == bss)
        {
            hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
                    __func__);
        }

        sme_RoamFreeConnectProfile(hHal, &roamProfile);
    }
    else
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s:  roamProfile.pBssDesc is NULL",
                __func__);
    }
    return bss;
}

/*
 * FUNCTION: wlan_hdd_cfg80211_update_bss
 */
static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
                                         hdd_adapter_t *pAdapter
                                        )
{
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    tCsrScanResultInfo *pScanResult;
    eHalStatus status = 0;
    int ret;
    tScanResultHandle pResult;
    struct cfg80211_bss *bss_status = NULL;
    hdd_context_t *pHddCtx;
    bool is_p2p_scan = false;
    ENTER();

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
                       NO_SESSION, pAdapter->sessionId));

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

    if (pAdapter->request != NULL)
    {
        if ((pAdapter->request->n_ssids == 1)
                && (pAdapter->request->ssids != NULL)
                && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
            is_p2p_scan = true;
    }
    /*
     * start getting scan results and populate cgf80211 BSS database
     */
    status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);

    /* no scan results */
    if (NULL == pResult)
    {
        hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
                                                      __func__, status);
        wlan_hdd_get_frame_logs(pAdapter,
                                WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
        return status;
    }

    pScanResult = sme_ScanResultGetFirst(hHal, pResult);

    while (pScanResult)
    {
        /*
         * cfg80211_inform_bss() is not updating ie field of bss entry, if
         * entry already exists in bss data base of cfg80211 for that
         * particular BSS ID.  Using cfg80211_inform_bss_frame to update the
         * bss entry instead of cfg80211_inform_bss, But this call expects
         * mgmt packet as input. As of now there is no possibility to get
         * the mgmt(probe response) frame from PE, converting bss_desc to
         * ieee80211_mgmt(probe response) and passing to c
         * fg80211_inform_bss_frame.
         * */
        if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
                !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
        {
            pScanResult = sme_ScanResultGetNext(hHal, pResult);
            continue; //Skip the non p2p bss entries
        }
        bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
                &pScanResult->BssDescriptor);


        if (NULL == bss_status)
        {
            hddLog(VOS_TRACE_LEVEL_INFO,
                    "%s: NULL returned by cfg80211_inform_bss", __func__);
        }
        else
        {
            cfg80211_put_bss(
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
                             wiphy,
#endif
                             bss_status);
        }

        pScanResult = sme_ScanResultGetNext(hHal, pResult);
    }

    sme_ScanResultPurge(hHal, pResult);
    is_p2p_scan = false;
    return 0;
}

void
hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
{
    VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
              MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
} /****** end hddPrintMacAddr() ******/

void
hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
{
    VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
              "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
              pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
              pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
              pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
} /****** end hddPrintPmkId() ******/

//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);

//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);

#define dump_bssid(bssid) \
    { \
        hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
        hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
    }

#define dump_pmkid(pMac, pmkid) \
    { \
        hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
        hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
    }

#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
/*
 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
 * This function is used to notify the supplicant of a new PMKSA candidate.
 */
int wlan_hdd_cfg80211_pmksa_candidate_notify(
                    hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
                    int index, bool preauth )
{
#ifdef FEATURE_WLAN_OKC
    struct net_device *dev = pAdapter->dev;
    hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;

    ENTER();
    hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);

    if( NULL == pRoamInfo )
    {
        hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
        return -EINVAL;
    }

    if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
    {
        dump_bssid(pRoamInfo->bssid);
        cfg80211_pmksa_candidate_notify(dev, index,
                                    pRoamInfo->bssid, preauth, GFP_KERNEL);
    }
#endif  /* FEATURE_WLAN_OKC */
    return 0;
}
#endif //FEATURE_WLAN_LFR

#ifdef FEATURE_WLAN_LFR_METRICS
/*
 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
 * 802.11r/LFR metrics reporting function to report preauth initiation
 *
 */
#define MAX_LFR_METRICS_EVENT_LENGTH 100
VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
                                                  tCsrRoamInfo *pRoamInfo)
{
    unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
    union iwreq_data wrqu;

    ENTER();

    if (NULL == pAdapter)
    {
        hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
        return VOS_STATUS_E_FAILURE;
    }

    /* create the event */
    memset(&wrqu, 0, sizeof(wrqu));
    memset(metrics_notification, 0, sizeof(metrics_notification));

    wrqu.data.pointer = metrics_notification;
    wrqu.data.length = scnprintf(metrics_notification,
        sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
        MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));

    wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);

    EXIT();

    return VOS_STATUS_SUCCESS;
}

/*
 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
 * 802.11r/LFR metrics reporting function to report preauth completion
 * or failure
 */
VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
    hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
{
    unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
    union iwreq_data wrqu;

    ENTER();

    if (NULL == pAdapter)
    {
        hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
        return VOS_STATUS_E_FAILURE;
    }

    /* create the event */
    memset(&wrqu, 0, sizeof(wrqu));
    memset(metrics_notification, 0, sizeof(metrics_notification));

    scnprintf(metrics_notification, sizeof(metrics_notification),
        "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
        MAC_ADDR_ARRAY(pRoamInfo->bssid));

    if (1 == preauth_status)
        strncat(metrics_notification, " TRUE", 5);
    else
        strncat(metrics_notification, " FALSE", 6);

    wrqu.data.pointer = metrics_notification;
    wrqu.data.length = strlen(metrics_notification);

    wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);

    EXIT();

    return VOS_STATUS_SUCCESS;
}

/*
 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
 * 802.11r/LFR metrics reporting function to report handover initiation
 *
 */
VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
                                                   tCsrRoamInfo *pRoamInfo)
{
    unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
    union iwreq_data wrqu;

    ENTER();

    if (NULL == pAdapter)
    {
        hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
        return VOS_STATUS_E_FAILURE;
    }

    /* create the event */
    memset(&wrqu, 0, sizeof(wrqu));
    memset(metrics_notification, 0, sizeof(metrics_notification));

    wrqu.data.pointer = metrics_notification;
    wrqu.data.length = scnprintf(metrics_notification,
        sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
        MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));

    wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);

    EXIT();

    return VOS_STATUS_SUCCESS;
}
#endif


/**
 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
 * @scan_req: scan request to be checked
 *
 * Return: true or false
 */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
                                                       cfg80211_scan_request
                                                       *scan_req, hdd_context_t
                                                       *hdd_ctx)
{
        if (!scan_req || !scan_req->wiphy ||
            scan_req->wiphy != hdd_ctx->wiphy) {
                hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
                return false;
        }
        if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
                hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
                return false;
        }
        return true;
}
#else
static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
                                                       cfg80211_scan_request
                                                       *scan_req, hdd_context_t
                                                       *hdd_ctx)
{
        if (!scan_req || !scan_req->wiphy ||
            scan_req->wiphy != hdd_ctx->wiphy) {
                hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
                return false;
        }
        return true;
}
#endif

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
/**
 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
 * @adapter: Pointer to the adapter
 * @req : Scan request
 * @aborted : true scan aborted false scan success
 *
 * This function notifies scan done to cfg80211
 *
 * Return: none
 */
static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
				   struct cfg80211_scan_request *req,
				   bool aborted)
{
	struct cfg80211_scan_info info = {
		.aborted = aborted
	};

	if (adapter->dev->flags & IFF_UP)
		cfg80211_scan_done(req, &info);
	else
		hddLog(LOGW,
		       FL("IFF_UP flag reset for %s"), adapter->dev->name);
}
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
/**
 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
 * @adapter: Pointer to the adapter
 * @req : Scan request
 * @aborted : true scan aborted false scan success
 *
 * This function notifies scan done to cfg80211
 *
 * Return: none
 */
static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
				   struct cfg80211_scan_request *req,
				   bool aborted)
{
	if (adapter->dev->flags & IFF_UP)
		cfg80211_scan_done(req, aborted);
	else
		hddLog(LOGW,
		       FL("IFF_UP flag reset for %s"), adapter->dev->name);
}
#else
/**
 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
 * @adapter: Pointer to the adapter
 * @req : Scan request
 * @aborted : true scan aborted false scan success
 *
 * This function notifies scan done to cfg80211
 *
 * Return: none
 */
static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
				   struct cfg80211_scan_request *req,
				   bool aborted)
{
	cfg80211_scan_done(req, aborted);
}
#endif

#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
/*
 * FUNCTION: hdd_cfg80211_scan_done_callback
 * scanning callback function, called after finishing scan
 *
 */
static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
        void *pContext, tANI_U32 scanId, eCsrScanStatus status)
{
    struct net_device *dev = (struct net_device *) pContext;
    //struct wireless_dev *wdev = dev->ieee80211_ptr;
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
    hdd_scaninfo_t *pScanInfo;
    struct cfg80211_scan_request *req = NULL;
    int ret = 0;
    bool aborted = false;
    long waitRet = 0;
    hdd_context_t *pHddCtx;

    ENTER();

    if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
        !pAdapter->dev) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
        return 0;
    }
    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    if (NULL == pHddCtx) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
        return 0;
    }

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
    if (!NET_DEV_IS_IFF_UP(pAdapter))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
    }
#endif
    pScanInfo = &pHddCtx->scan_info;

    hddLog(VOS_TRACE_LEVEL_INFO,
            "%s called with halHandle = %pK, pContext = %pK,"
            "scanID = %d, returned status = %d",
            __func__, halHandle, pContext, (int) scanId, (int) status);

    pScanInfo->mScanPendingCounter = 0;

    //Block on scan req completion variable. Can't wait forever though.
    waitRet = wait_for_completion_interruptible_timeout(
                         &pScanInfo->scan_req_completion_event,
                         msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
    if (waitRet <= 0)
    {
       hddLog(VOS_TRACE_LEVEL_ERROR,
               "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
       VOS_ASSERT(pScanInfo->mScanPending);
       goto allow_suspend;
    }

    if (pScanInfo->mScanPending != VOS_TRUE)
    {
        VOS_ASSERT(pScanInfo->mScanPending);
        goto allow_suspend;
    }

    /* Check the scanId */
    if (pScanInfo->scanId != scanId)
    {
        hddLog(VOS_TRACE_LEVEL_INFO,
                "%s called with mismatched scanId pScanInfo->scanId = %d "
                "scanId = %d", __func__, (int) pScanInfo->scanId,
                (int) scanId);
    }

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
    if (NET_DEV_IS_IFF_UP(pAdapter))
#endif
    {
        ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
                                        pAdapter);
        if (0 > ret)
            hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
    }

    /* If any client wait scan result through WEXT
     * send scan done event to client */
    if (pHddCtx->scan_info.waitScanResult)
    {
        /* The other scan request waiting for current scan finish
         * Send event to notify current scan finished */
        if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
        {
            vos_event_set(&pHddCtx->scan_info.scan_finished_event);
        }
        /* Send notify to WEXT client */
        else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
        {
            struct net_device *dev = pAdapter->dev;
            union iwreq_data wrqu;
            int we_event;
            char *msg;

            memset(&wrqu, '\0', sizeof(wrqu));
            we_event = SIOCGIWSCAN;
            msg = NULL;
            wireless_send_event(dev, we_event, &wrqu, msg);
        }
    }
    pHddCtx->scan_info.waitScanResult = FALSE;

    /* Get the Scan Req */
    req = pAdapter->request;
    pAdapter->request = NULL;

    /* Scan is no longer pending */
    pScanInfo->mScanPending = VOS_FALSE;

    if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
    {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
            hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
                   NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
#endif

        if (pAdapter->dev) {
               hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
                      pAdapter->dev->name);
        }
        complete(&pScanInfo->abortscan_event_var);
        goto allow_suspend;
    }

    /* last_scan_timestamp is used to decide if new scan
     * is needed or not on station interface. If last station
     *  scan time and new station scan time is less then
     * last_scan_timestamp ; driver will return cached scan.
     * Also only last_scan_timestamp is updated here last_scan_channellist
     * is updated on receiving scan request itself to make sure kernel
     * allocated scan request(scan_req) object is not dereferenced here,
     * because interface down, where kernel frees scan_req, may happen any
     * time while driver is processing scan_done_callback. So it's better
     * not to access scan_req in this routine.
     */
    if (pScanInfo->no_cck == FALSE) { // no_cck will be set during p2p find
        if (status == eCSR_SCAN_SUCCESS)
            pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
        else {
                vos_mem_zero(pHddCtx->scan_info.last_scan_channelList,
                             sizeof(pHddCtx->scan_info.last_scan_channelList));
                pHddCtx->scan_info.last_scan_numChannels = 0;
                pScanInfo->last_scan_timestamp = 0;
        }
    }

    /*
     * cfg80211_scan_done informing NL80211 about completion
     * of scanning
     */
    if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
    {
         aborted = true;
    }

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
    if (NET_DEV_IS_IFF_UP(pAdapter) &&
        wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
#endif
        hdd_cfg80211_scan_done(pAdapter, req, aborted);

    complete(&pScanInfo->abortscan_event_var);

allow_suspend:
    if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
       ) && (pHddCtx->spoofMacAddr.isEnabled
         ||  pHddCtx->spoofMacAddr.isReqDeferred)) {
        /* Generate new random mac addr for next scan */
        hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");

        schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
                           msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
    }

    /* release the wake lock at the end of the scan*/
    hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);

    /* Acquire wakelock to handle the case where APP's tries to suspend
     * immediatly after the driver gets connect request(i.e after scan)
     * from supplicant, this result in app's is suspending and not able
     * to process the connect request to AP */
    hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
    if (NET_DEV_IS_IFF_UP(pAdapter))
#endif
#ifdef FEATURE_WLAN_TDLS
        wlan_hdd_tdls_scan_done_callback(pAdapter);
#endif

    EXIT();
    return 0;
}

/*
 * FUNCTION: hdd_isConnectionInProgress
 * Go through each adapter and check if Connection is in progress
 *
 */
v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
                                    scan_reject_states *reason)
{
    hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
    hdd_station_ctx_t *pHddStaCtx = NULL;
    hdd_adapter_t *pAdapter = NULL;
    VOS_STATUS status = 0;
    v_U8_t staId = 0;
    v_U8_t *staMac = NULL;

    status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );

    while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
    {
        pAdapter = pAdapterNode->pAdapter;

        if( pAdapter )
        {
            hddLog(VOS_TRACE_LEVEL_INFO,
                    "%s: Adapter with device mode %s (%d) exists",
                    __func__, hdd_device_modetoString(pAdapter->device_mode),
                                                       pAdapter->device_mode);
            if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
                 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
                 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
                 (eConnectionState_Connecting ==
                (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
            {
                hddLog(LOG1,
                       "%s: %pK(%d) Connection is in progress", __func__,
                       WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
                if (session_id && reason)
                {
                    *session_id = pAdapter->sessionId;
                    *reason = eHDD_CONNECTION_IN_PROGRESS;
                }
                return VOS_TRUE;
            }
            if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
                 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
            {
                hddLog(LOG1,
                       "%s: %pK(%d) Reassociation is in progress", __func__,
                       WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
                if (session_id && reason)
                {
                    *session_id = pAdapter->sessionId;
                    *reason = eHDD_REASSOC_IN_PROGRESS;
                }
                return VOS_TRUE;
            }
            if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
                     (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
                     (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
            {
                pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
                if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
                    (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
                {
                    staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
                    hddLog(LOG1,
                           "%s: client " MAC_ADDRESS_STR
                           " is in the middle of WPS/EAPOL exchange.", __func__,
                            MAC_ADDR_ARRAY(staMac));
                    if (session_id && reason)
                    {
                        *session_id = pAdapter->sessionId;
                        *reason = eHDD_EAPOL_IN_PROGRESS;
                    }
                    return VOS_TRUE;
                }
            }
            else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
                    (WLAN_HDD_P2P_GO == pAdapter->device_mode))
            {
                v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
                ptSapContext pSapCtx = NULL;
                pSapCtx = VOS_GET_SAP_CB(pVosContext);
                if(pSapCtx == NULL){
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                            FL("psapCtx is NULL"));
                    return VOS_FALSE;
                }
                for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
                {
                    if ((pSapCtx->aStaInfo[staId].isUsed) &&
                            (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
                    {
                        staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);

                        hddLog(LOG1,
                               "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
                               "middle of WPS/EAPOL exchange.", __func__,
                                MAC_ADDR_ARRAY(staMac));
                        if (session_id && reason)
                        {
                            *session_id = pAdapter->sessionId;
                            *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
                        }
                        return VOS_TRUE;
                    }
                }
            }
        }
        status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
        pAdapterNode = pNext;
    }
    return VOS_FALSE;
}

/**
 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
 *                                   to the Scan request
 * @scanRequest: Pointer to the csr scan request
 * @request: Pointer to the scan request from supplicant
 *
 * Return: None
 */
#ifdef CFG80211_SCAN_BSSID
static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
					struct cfg80211_scan_request *request)
{
	vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
}
#else
static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
					struct cfg80211_scan_request *request)
{
}
#endif

/*
 * FUNCTION: __wlan_hdd_cfg80211_scan
 * this scan respond to scan trigger and update cfg80211 scan database
 * later, scan dump command can be used to recieve scan results
 */
int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
                            struct net_device *dev,
#endif
                            struct cfg80211_scan_request *request)
{
    hdd_adapter_t *pAdapter = NULL;
    hdd_context_t *pHddCtx = NULL;
    hdd_wext_state_t *pwextBuf = NULL;
    hdd_config_t *cfg_param = NULL;
    tCsrScanRequest scanRequest;
    tANI_U8 *channelList = NULL, i;
    v_U32_t scanId = 0;
    int status;
    hdd_scaninfo_t *pScanInfo = NULL;
    v_U8_t* pP2pIe = NULL;
    int ret = 0;
    v_U8_t *pWpsIe=NULL;
    bool is_p2p_scan = false;
    v_U8_t curr_session_id;
    scan_reject_states curr_reason;

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
    struct net_device *dev = NULL;
    if (NULL == request)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: scan req param null", __func__);
        return -EINVAL;
    }
    dev = request->wdev->netdev;
#endif

    pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
    pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
    pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);

    ENTER();

    hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
           __func__, hdd_device_modetoString(pAdapter->device_mode),
                                             pAdapter->device_mode);

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    if (NULL == pwextBuf)
    {
        hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
                __func__);
        return -EIO;
    }
    cfg_param = pHddCtx->cfg_ini;
    pScanInfo = &pHddCtx->scan_info;

#ifdef WLAN_BTAMP_FEATURE
    //Scan not supported when AMP traffic is on.
    if (VOS_TRUE == WLANBAP_AmpSessionOn())
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: No scanning when AMP is on", __func__);
        return -EOPNOTSUPP;
    }
#endif
    //Scan on any other interface is not supported.
    if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
              "%s: Not scanning on device_mode = %s (%d)",
              __func__, hdd_device_modetoString(pAdapter->device_mode),
                                                pAdapter->device_mode);
        return -EOPNOTSUPP;
    }

    if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
        hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
        return -EOPNOTSUPP;
    }

    if (TRUE == pScanInfo->mScanPending)
    {
        if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
        {
            hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
        }
        return -EBUSY;
    }

    // Don't allow scan if PNO scan is going on.
    if (pHddCtx->isPnoEnable)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                   FL("pno scan in progress"));
        return -EBUSY;
    }

    //Don't Allow Scan and return busy if Remain On
    //Channel and action frame is pending
    //Otherwise Cancel Remain On Channel and allow Scan
    //If no action frame pending
    if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
        return -EBUSY;
    }

    if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
                  "%s: Acquire lock fail", __func__);
        return -EAGAIN;
    }
    if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               "%s: MAX TM Level Scan not allowed", __func__);
        mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
        return -EBUSY;
    }
    mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);

    /* Check if scan is allowed at this point of time.
     */
    if (TRUE == pHddCtx->btCoexModeSet)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
           FL("BTCoex Mode operation in progress"));
        return -EBUSY;
    }
    if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
    {

        if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
            hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
                curr_session_id, curr_reason);
        if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
            pHddCtx->last_scan_reject_reason != curr_reason ||
            !pHddCtx->last_scan_reject_timestamp)
        {
            pHddCtx->last_scan_reject_session_id = curr_session_id;
            pHddCtx->last_scan_reject_reason = curr_reason;
            pHddCtx->last_scan_reject_timestamp =
              jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
            pHddCtx->scan_reject_cnt = 0;
        }
        else
        {
            pHddCtx->scan_reject_cnt++;

            if ((pHddCtx->scan_reject_cnt >=
               SCAN_REJECT_THRESHOLD) &&
               vos_system_time_after(jiffies_to_msecs(jiffies),
               pHddCtx->last_scan_reject_timestamp))
            {
                hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
                    curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
                    vos_system_time_after(jiffies_to_msecs(jiffies),
                    pHddCtx->last_scan_reject_timestamp));
                pHddCtx->last_scan_reject_timestamp = 0;
                pHddCtx->scan_reject_cnt = 0;
                if (pHddCtx->cfg_ini->enableFatalEvent)
                    vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
                          WLAN_LOG_INDICATOR_HOST_DRIVER,
                          WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
                          FALSE, FALSE);
                else
                {
                    hddLog(LOGE, FL("Triggering SSR"));
                    vos_wlanRestart(VOS_SCAN_REQ_EXPIRED);
                }
            }
        }
        return -EBUSY;
    }
    pHddCtx->last_scan_reject_timestamp = 0;
    pHddCtx->last_scan_reject_session_id = 0xFF;
    pHddCtx->last_scan_reject_reason = 0;
    pHddCtx->scan_reject_cnt = 0;

    vos_mem_zero( &scanRequest, sizeof(scanRequest));

    /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
     * Becasue of this, driver is assuming that this is not wildcard scan and so
     * is not aging out the scan results.
     */
    if ((request->ssids) && (request->n_ssids == 1) &&
        ('\0' == request->ssids->ssid[0])) {
        request->n_ssids = 0;
    }

    if ((request->ssids) && (0 < request->n_ssids))
    {
        tCsrSSIDInfo *SsidInfo;
        int j;
        scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
        /* Allocate num_ssid tCsrSSIDInfo structure */
        SsidInfo = scanRequest.SSIDs.SSIDList =
                  ( tCsrSSIDInfo *)vos_mem_malloc(
                          request->n_ssids*sizeof(tCsrSSIDInfo));

        if(NULL == scanRequest.SSIDs.SSIDList)
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                      "%s: memory alloc failed SSIDInfo buffer", __func__);
            return -ENOMEM;
        }

        /* copy all the ssid's and their length */
        for(j = 0; j < request->n_ssids; j++, SsidInfo++)
        {
            /* get the ssid length */
            SsidInfo->SSID.length = request->ssids[j].ssid_len;
            vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
                         SsidInfo->SSID.length);
            SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
            hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d:  %s",
                                                   j, SsidInfo->SSID.ssId);
        }
        /* set the scan type to active */
        scanRequest.scanType = eSIR_ACTIVE_SCAN;
    }
    else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
    {
        MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                    TRACE_CODE_HDD_CFG80211_SCAN,
                    pAdapter->sessionId, 0));
        /* set the scan type to active */
        scanRequest.scanType = eSIR_ACTIVE_SCAN;
    }
    else
    {
        /*Set the scan type to default type, in this case it is ACTIVE*/
        scanRequest.scanType = pScanInfo->scan_mode;
    }
    scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
    scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;

    csr_scan_request_assign_bssid(&scanRequest, request);

    /* set BSSType to default type */
    scanRequest.BSSType = eCSR_BSS_TYPE_ANY;

    /*TODO: scan the requested channels only*/

    /*Right now scanning all the channels */
    if (MAX_CHANNEL < request->n_channels)
    {
        hddLog(VOS_TRACE_LEVEL_WARN,
           "No of Scan Channels exceeded limit: %d", request->n_channels);
        request->n_channels = MAX_CHANNEL;
    }

    hddLog(VOS_TRACE_LEVEL_INFO,
                           "No of Scan Channels: %d", request->n_channels);


    if( request->n_channels )
    {
        char chList [(request->n_channels*5)+1];
        int len;
        channelList = vos_mem_malloc( request->n_channels );
        if( NULL == channelList )
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                           "%s: memory alloc failed channelList", __func__);
            status = -ENOMEM;
            goto free_mem;
        }

        for( i = 0, len = 0; i < request->n_channels ; i++ )
        {
            channelList[i] = request->channels[i]->hw_value;
            len += snprintf(chList+len, 5, "%d ", channelList[i]);
        }

        hddLog(VOS_TRACE_LEVEL_INFO,
                           "Channel-List:  %s ", chList);
    }

    scanRequest.ChannelInfo.numOfChannels = request->n_channels;
    scanRequest.ChannelInfo.ChannelList = channelList;

    /* set requestType to full scan */
    scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;

    /* if there is back to back scan happening in driver with in
     * nDeferScanTimeInterval interval driver should defer new scan request
     * and should provide last cached scan results instead of new channel list.
     * This rule is not applicable if scan is p2p scan.
     * This condition will work only in case when last request no of channels
     * and channels are exactly same as new request.
     * This should be done only in connected state
     * Scan shouldn't be defered for WPS scan case.
     */

    pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
    /* if wps ie is NULL , then only defer scan */
    if ( pWpsIe == NULL &&
        (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
    {
        if ( pScanInfo->last_scan_timestamp !=0 &&
             ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
        {
            if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
               (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
                vos_mem_compare(pScanInfo->last_scan_channelList,
                           channelList, pScanInfo->last_scan_numChannels))
            {
                hddLog(VOS_TRACE_LEVEL_WARN,
                     " New and old station scan time differ is less then %u",
                pHddCtx->cfg_ini->nDeferScanTimeInterval);

                ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
                                        pAdapter);

                hddLog(VOS_TRACE_LEVEL_WARN,
                    "Return old cached scan as all channels and no of channels are same");

                if (0 > ret)
                    hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);

                hdd_cfg80211_scan_done(pAdapter, request, eCSR_SCAN_SUCCESS);

                status = eHAL_STATUS_SUCCESS;
                goto free_mem;
            }
        }
    }

    /* Flush the scan results(only p2p beacons) for STA scan and P2P
     * search (Flush on both full  scan and social scan but not on single
     * channel scan).P2P  search happens on 3 social channels (1, 6, 11)
     */

    /* Supplicant does single channel scan after 8-way handshake
     * and in that case driver shoudnt flush scan results. If
     * driver flushes the scan results here and unfortunately if
     * the AP doesnt respond to our probe req then association
     * fails which is not desired
     */
    if ((request->n_ssids == 1)
            && (request->ssids != NULL)
            && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
        is_p2p_scan = true;

    if( is_p2p_scan ||
            (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
    {
        hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
        sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
                                            pAdapter->sessionId );
    }

    if( request->ie_len )
    {
        /* save this for future association (join requires this) */
        /*TODO: Array needs to be converted to dynamic allocation,
         * as multiple ie.s can be sent in cfg80211_scan_request structure
         * CR 597966
         */
        memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
        memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
        pScanInfo->scanAddIE.length = request->ie_len;

        if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
            (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
            (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
        {
            if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
            {
                pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
                memcpy( pwextBuf->roamProfile.addIEScan,
                                 request->ie, request->ie_len);
            }
            else
            {
                hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
                         "%zu", request->ie_len);
            }

        }
        scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
        scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;

        pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
                                                   request->ie_len);
        if (pP2pIe != NULL)
        {
#ifdef WLAN_FEATURE_P2P_DEBUG
            if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
                (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
                (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
            {
                globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
                hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
                                "Go nego completed to Connection is started");
                hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
                               "for 8way Handshake");
            }
            else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
                    (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
            {
                globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
                hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
                                "Disconnected state to Connection is started");
                hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
                                                    "for 4way Handshake");
            }
#endif

            /* no_cck will be set during p2p find to disable 11b rates */
            if(TRUE == request->no_cck)
            {
                hddLog(VOS_TRACE_LEVEL_INFO,
                       "%s: This is a P2P Search", __func__);
                scanRequest.p2pSearch = 1;

                if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
                {
                     /* set requestType to P2P Discovery */
                     scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
                }

                /*
                   Skip Dfs Channel in case of P2P Search
                   if it is set in ini file
                */
                if(cfg_param->skipDfsChnlInP2pSearch)
                {
                   scanRequest.skipDfsChnlInP2pSearch = 1;
                }
                else
                {
                   scanRequest.skipDfsChnlInP2pSearch = 0;
                }

            }
        }
    }

    INIT_COMPLETION(pScanInfo->scan_req_completion_event);

#ifdef FEATURE_WLAN_TDLS
    /* if tdls disagree scan right now, return immediately.
       tdls will schedule the scan when scan is allowed. (return SUCCESS)
       or will reject the scan if any TDLS is in progress. (return -EBUSY)
     */
    status = wlan_hdd_tdls_scan_callback (pAdapter,
                                          wiphy,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
                                          dev,
#endif
                                          request);
    if (status <= 0)
    {
       if (!status)
           hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
                  "scan rejected  %d", __func__, status);
       else
           hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
                                          __func__, status);
       hdd_wlan_block_scan_by_tdls();
       goto free_mem;
    }
#endif

    /* acquire the wakelock to avoid the apps suspend during the scan. To
     * address the following issues.
     * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
     * BMPS/IMPS this result in android trying to suspend aggressively and backing off
     * for long time, this result in apps running at full power for long time.
     * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
     * be stuck in full power because of resume BMPS
     */
    hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);

    hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
           "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
           "p2pSearch %d, skipDfsChnlInP2pSearch %d",
           scanRequest.requestType, scanRequest.scanType,
           scanRequest.minChnTime, scanRequest.maxChnTime,
           scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);

    if (pHddCtx->spoofMacAddr.isEnabled &&
        pHddCtx->cfg_ini->enableMacSpoofing == 1)
    {
        hddLog(VOS_TRACE_LEVEL_INFO,
                        "%s: MAC Spoofing enabled for current scan", __func__);
        /* Updating SelfSta Mac Addr in TL which will be used to get staidx
         * to fill TxBds for probe request during current scan
         */
        status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
            &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);

        if(status != VOS_STATUS_SUCCESS)
        {
            hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
            status = -EFAULT;
#ifdef FEATURE_WLAN_TDLS
        wlan_hdd_tdls_scan_done_callback(pAdapter);
#endif
            goto free_mem;
        }
    }
    wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
    status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
                              pAdapter->sessionId, &scanRequest, &scanId,
                              &hdd_cfg80211_scan_done_callback, dev );

    if (eHAL_STATUS_SUCCESS != status)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: sme_ScanRequest returned error %d", __func__, status);
        complete(&pScanInfo->scan_req_completion_event);
        if(eHAL_STATUS_RESOURCES == status)
        {
                hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
                                 "So defer the scan by informing busy",__func__);
                status = -EBUSY;
        } else {
                status = -EIO;
        }
        hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);

#ifdef FEATURE_WLAN_TDLS
        wlan_hdd_tdls_scan_done_callback(pAdapter);
#endif
        goto free_mem;
    }

    pScanInfo->mScanPending = TRUE;
    pScanInfo->sessionId = pAdapter->sessionId;
    pAdapter->request = request;
    pScanInfo->scanId = scanId;
    pScanInfo->no_cck = request->no_cck;
    pHddCtx->scan_info.last_scan_numChannels = request->n_channels;
    for (i = 0; i < pHddCtx->scan_info.last_scan_numChannels; i++) {
         pHddCtx->scan_info.last_scan_channelList[i] =
             request->channels[i]->hw_value;
    }

    complete(&pScanInfo->scan_req_completion_event);

free_mem:
    if( scanRequest.SSIDs.SSIDList )
    {
        vos_mem_free(scanRequest.SSIDs.SSIDList);
    }

    if( channelList )
      vos_mem_free( channelList );

    EXIT();
    return status;
}

int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
                            struct net_device *dev,
#endif
                            struct cfg80211_scan_request *request)
{
    int ret;

    vos_ssr_protect(__func__);
    ret =  __wlan_hdd_cfg80211_scan(wiphy,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
                                   dev,
#endif
                                   request);
    vos_ssr_unprotect(__func__);

    return ret;
}

void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
{
    v_U8_t iniDot11Mode =
               (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
    eHddDot11Mode   hddDot11Mode = iniDot11Mode;

    hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
           iniDot11Mode);
    switch ( iniDot11Mode )
    {
       case eHDD_DOT11_MODE_AUTO:
       case eHDD_DOT11_MODE_11ac:
       case eHDD_DOT11_MODE_11ac_ONLY:
#ifdef WLAN_FEATURE_11AC
          if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
               sme_IsFeatureSupportedByFW(DOT11AC) )
              hddDot11Mode = eHDD_DOT11_MODE_11ac;
          else
              hddDot11Mode = eHDD_DOT11_MODE_11n;
#else
          hddDot11Mode = eHDD_DOT11_MODE_11n;
#endif
          break;
       case eHDD_DOT11_MODE_11n:
       case eHDD_DOT11_MODE_11n_ONLY:
          hddDot11Mode = eHDD_DOT11_MODE_11n;
          break;
       default:
          hddDot11Mode = iniDot11Mode;
          break;
    }
#ifdef WLAN_FEATURE_AP_HT40_24G
    if (operationChannel > SIR_11B_CHANNEL_END)
#endif
    {
        /* This call decides required channel bonding mode */
        sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
                     hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
                     operationChannel, eHT_MAX_CHANNEL_WIDTH);
    }
}

/*
 * FUNCTION: wlan_hdd_cfg80211_connect_start
 * This function is used to start the association process
 */
int wlan_hdd_cfg80211_connect_start( hdd_adapter_t  *pAdapter,
        const u8 *ssid, size_t ssid_len, const u8 *bssid,
        const u8 *bssid_hint, u8 operatingChannel)
{
    int status = 0;
    hdd_wext_state_t *pWextState;
    hdd_context_t *pHddCtx;
    hdd_station_ctx_t *hdd_sta_ctx;
    v_U32_t roamId;
    tCsrRoamProfile *pRoamProfile;
    eCsrAuthType RSNAuthType;

    ENTER();

    pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

    status = wlan_hdd_validate_context(pHddCtx);
    if (status)
    {
        return status;
    }

    if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
        return -EINVAL;
    }

    wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);

    pRoamProfile = &pWextState->roamProfile;

    if (pRoamProfile)
    {
        hdd_station_ctx_t *pHddStaCtx;
        pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
        pHddStaCtx->get_mgmt_log_sent = FALSE;

        wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);

        if (HDD_WMM_USER_MODE_NO_QOS ==
                        (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
        {
            /*QoS not enabled in cfg file*/
            pRoamProfile->uapsd_mask = 0;
        }
        else
        {
            /*QoS enabled, update uapsd mask from cfg file*/
            pRoamProfile->uapsd_mask =
                     (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
        }

        pRoamProfile->SSIDs.numOfSSIDs = 1;
        pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
        vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
                sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
        vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
                ssid, ssid_len);

        vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
        vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);

        if (bssid)
        {
            pRoamProfile->BSSIDs.numOfBSSIDs = 1;
            vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
                    WNI_CFG_BSSID_LEN);
            /* Save BSSID in seperate variable as well, as RoamProfile
               BSSID is getting zeroed out in the association process. And in
               case of join failure we should send valid BSSID to supplicant
             */
            vos_mem_copy(pWextState->req_bssId, bssid,
                    WNI_CFG_BSSID_LEN);

        }
        else if (bssid_hint)
        {
            /* Store bssid_hint to use in the scan filter. */
            vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
                    WNI_CFG_BSSID_LEN);
            /*
             * Save BSSID in seperate variable as well, as RoamProfile
             * BSSID is getting zeroed out in the association process. And in
             * case of join failure we should send valid BSSID to supplicant
             */
            vos_mem_copy(pWextState->req_bssId, bssid_hint,
                    WNI_CFG_BSSID_LEN);
            hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
                   MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
        }


        hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
               pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
        if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
                (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
        {
            /*set gen ie*/
            hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
            /*set auth*/
            hdd_set_csr_auth_type(pAdapter, RSNAuthType);
        }
#ifdef FEATURE_WLAN_WAPI
        if (pAdapter->wapi_info.nWapiMode)
        {
            hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
            switch (pAdapter->wapi_info.wapiAuthMode)
            {
                case WAPI_AUTH_MODE_PSK:
                {
                    hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
                                                   pAdapter->wapi_info.wapiAuthMode);
                    pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
                    break;
                }
                case WAPI_AUTH_MODE_CERT:
                {
                    hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
                                                    pAdapter->wapi_info.wapiAuthMode);
                    pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
                    break;
                }
            } // End of switch
            if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
                pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
            {
                hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
                pRoamProfile->AuthType.numEntries = 1;
                pRoamProfile->EncryptionType.numEntries = 1;
                pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
                pRoamProfile->mcEncryptionType.numEntries = 1;
                pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
            }
        }
#endif /* FEATURE_WLAN_WAPI */
#ifdef WLAN_FEATURE_GTK_OFFLOAD
        /* Initializing gtkOffloadReqParams */
        if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
            (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
        {
            memset(&pHddStaCtx->gtkOffloadReqParams, 0,
                  sizeof (tSirGtkOffloadParams));
            pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
        }
#endif
        pRoamProfile->csrPersona = pAdapter->device_mode;

        if( operatingChannel )
        {
           pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
           pRoamProfile->ChannelInfo.numOfChannels = 1;
        }
        else
        {
            pRoamProfile->ChannelInfo.ChannelList = NULL;
            pRoamProfile->ChannelInfo.numOfChannels = 0;
        }
        if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
        {
            hdd_select_cbmode(pAdapter,operatingChannel);
        }

       /*
        * Change conn_state to connecting before sme_RoamConnect(),
        * because sme_RoamConnect() has a direct path to call
        * hdd_smeRoamCallback(), which will change the conn_state
        * If direct path, conn_state will be accordingly changed
        * to NotConnected or Associated by either
        * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
        * in sme_RoamCallback()
        * if sme_RomConnect is to be queued,
        * Connecting state will remain until it is completed.
        * If connection state is not changed,
        * connection state will remain in eConnectionState_NotConnected state.
        * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
        * if conn state is eConnectionState_NotConnected.
        * If "hddDisconInProgress" is set to true then cfg80211 layer is not
        * informed of connect result indication which is an issue.
        */

        if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
            WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                   FL("Set HDD connState to eConnectionState_Connecting"));
            hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
                                                 eConnectionState_Connecting);
            vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
            hdd_wait_for_ecsa_complete(pHddCtx);
        }

        status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
                            pAdapter->sessionId, pRoamProfile, &roamId);

        if ((eHAL_STATUS_SUCCESS != status) &&
            (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
             WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))

        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                        FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
                        pAdapter->sessionId, status);
            /* change back to NotAssociated */
            hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
                                             eConnectionState_NotConnected);
        }

        pRoamProfile->ChannelInfo.ChannelList = NULL;
        pRoamProfile->ChannelInfo.numOfChannels = 0;

    }
    else
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
        return -EINVAL;
    }
    EXIT();
    return status;
}

/*
 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
 * This function is used to set the authentication type (OPEN/SHARED).
 *
 */
static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
        enum nl80211_auth_type auth_type)
{
    hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

    ENTER();

    /*set authentication type*/
    switch (auth_type)
    {
        case NL80211_AUTHTYPE_AUTOMATIC:
            hddLog(VOS_TRACE_LEVEL_INFO,
                    "%s: set authentication type to AUTOSWITCH", __func__);
            pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
            break;

        case NL80211_AUTHTYPE_OPEN_SYSTEM:
#ifdef WLAN_FEATURE_VOWIFI_11R
        case NL80211_AUTHTYPE_FT:
#endif /* WLAN_FEATURE_VOWIFI_11R */
            hddLog(VOS_TRACE_LEVEL_INFO,
                    "%s: set authentication type to OPEN", __func__);
            pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
            break;

        case NL80211_AUTHTYPE_SHARED_KEY:
            hddLog(VOS_TRACE_LEVEL_INFO,
                    "%s: set authentication type to SHARED", __func__);
            pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
            break;
#ifdef FEATURE_WLAN_ESE
        case NL80211_AUTHTYPE_NETWORK_EAP:
            hddLog(VOS_TRACE_LEVEL_INFO,
                            "%s: set authentication type to CCKM WPA", __func__);
            pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
            break;
#endif


        default:
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    "%s: Unsupported authentication type %d", __func__,
                    auth_type);
            pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
            return -EINVAL;
    }

    pWextState->roamProfile.AuthType.authType[0] =
                                        pHddStaCtx->conn_info.authType;
    return 0;
}

/*
 * FUNCTION: wlan_hdd_set_akm_suite
 * This function is used to set the key mgmt type(PSK/8021x).
 *
 */
static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
                                   u32 key_mgmt
                                   )
{
    hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    ENTER();
    /* Should be in ieee802_11_defs.h */
#ifndef WLAN_AKM_SUITE_8021X_SHA256
#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
#endif
#ifndef WLAN_AKM_SUITE_PSK_SHA256
#define WLAN_AKM_SUITE_PSK_SHA256   0x000FAC06
#endif
    /*set key mgmt type*/
    switch(key_mgmt)
    {
        case WLAN_AKM_SUITE_PSK:
        case WLAN_AKM_SUITE_PSK_SHA256:
#ifdef WLAN_FEATURE_VOWIFI_11R
        case WLAN_AKM_SUITE_FT_PSK:
#endif
            hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
                    __func__);
            pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
            break;

        case WLAN_AKM_SUITE_8021X:
        case WLAN_AKM_SUITE_8021X_SHA256:
#ifdef WLAN_FEATURE_VOWIFI_11R
        case WLAN_AKM_SUITE_FT_8021X:
#endif
            hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
                    __func__);
            pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
            break;
#ifdef FEATURE_WLAN_ESE
#define WLAN_AKM_SUITE_CCKM         0x00409600 /* Should be in ieee802_11_defs.h */
#define IW_AUTH_KEY_MGMT_CCKM       8  /* Should be in linux/wireless.h */
        case WLAN_AKM_SUITE_CCKM:
            hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
                            __func__);
            pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
            break;
#endif
#ifndef WLAN_AKM_SUITE_OSEN
#define WLAN_AKM_SUITE_OSEN         0x506f9a01 /* Should be in ieee802_11_defs.h */
        case WLAN_AKM_SUITE_OSEN:
            hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
                            __func__);
            pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
            break;
#endif

        default:
            hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
                    __func__, key_mgmt);
            return -EINVAL;

    }
    return 0;
}

/*
 * FUNCTION: wlan_hdd_cfg80211_set_cipher
 * This function is used to set the encryption type
 * (NONE/WEP40/WEP104/TKIP/CCMP).
 */
static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
                                u32 cipher,
                                bool ucast
                                )
{
    eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
    hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

    ENTER();

    if (!cipher)
    {
        hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
                __func__, cipher);
        encryptionType = eCSR_ENCRYPT_TYPE_NONE;
    }
    else
    {

        /*set encryption method*/
        switch (cipher)
        {
            case IW_AUTH_CIPHER_NONE:
                encryptionType = eCSR_ENCRYPT_TYPE_NONE;
                break;

            case WLAN_CIPHER_SUITE_WEP40:
                encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
                break;

            case WLAN_CIPHER_SUITE_WEP104:
                encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
                break;

            case WLAN_CIPHER_SUITE_TKIP:
                encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
                break;

            case WLAN_CIPHER_SUITE_CCMP:
                encryptionType = eCSR_ENCRYPT_TYPE_AES;
                break;
#ifdef FEATURE_WLAN_WAPI
        case WLAN_CIPHER_SUITE_SMS4:
            encryptionType = eCSR_ENCRYPT_TYPE_WPI;
            break;
#endif

#ifdef FEATURE_WLAN_ESE
        case WLAN_CIPHER_SUITE_KRK:
            encryptionType = eCSR_ENCRYPT_TYPE_KRK;
            break;
#endif
            default:
                hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
                        __func__, cipher);
                return -EOPNOTSUPP;
        }
    }

    if (ucast)
    {
        hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
                __func__, encryptionType);
        pHddStaCtx->conn_info.ucEncryptionType            = encryptionType;
        pWextState->roamProfile.EncryptionType.numEntries = 1;
        pWextState->roamProfile.EncryptionType.encryptionType[0] =
                                          encryptionType;
    }
    else
    {
        hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
                __func__, encryptionType);
        pHddStaCtx->conn_info.mcEncryptionType                       = encryptionType;
        pWextState->roamProfile.mcEncryptionType.numEntries        = 1;
        pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
    }

    return 0;
}


/*
 * FUNCTION: wlan_hdd_cfg80211_set_ie
 * This function is used to parse WPA/RSN IE's.
 */
int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
                              const u8 *ie,
#else
                              u8 *ie,
#endif
                              size_t ie_len
                              )
{
    hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
    const u8 *genie = ie;
#else
    u8 *genie = ie;
#endif
    v_U16_t remLen = ie_len;
#ifdef FEATURE_WLAN_WAPI
    v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
    u16 *tmp;
    v_U16_t akmsuiteCount;
    int *akmlist;
#endif
    ENTER();

    /* clear previous assocAddIE */
    pWextState->assocAddIE.length = 0;
    pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
    pWextState->roamProfile.bOSENAssociation = VOS_FALSE;

    while (remLen >= 2)
    {
        v_U16_t eLen = 0;
        v_U8_t elementId;
        elementId = *genie++;
        eLen  = *genie++;
        remLen -= 2;

        /* Sanity check on eLen */
        if (eLen > remLen) {
            hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
                    __func__, eLen, elementId);
            VOS_ASSERT(0);
            return -EINVAL;
        }

        hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
            __func__, elementId, eLen);

        switch ( elementId )
        {
            case DOT11F_EID_WPA:
                if (4 > eLen) /* should have at least OUI which is 4 bytes so extra 2 bytes not needed */
                {
                    hddLog(VOS_TRACE_LEVEL_ERROR,
                              "%s: Invalid WPA IE", __func__);
                    return -EINVAL;
                }
                else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
                {
                    v_U16_t curAddIELen = pWextState->assocAddIE.length;
                    hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
                            __func__, eLen + 2);

                    if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
                    {
                       hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
                                                      "Need bigger buffer space");
                       VOS_ASSERT(0);
                       return -ENOMEM;
                    }
                    // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
                    memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
                    pWextState->assocAddIE.length += eLen + 2;

                    pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
                    pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
                    pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
                }
                else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
                {
                    if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
                        hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
                            __func__, eLen);
                        VOS_ASSERT(0);
                        return -EINVAL;
                    }

                    hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
                    memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
                    memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
                    pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
                    pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
                }
                else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
                                                         P2P_OUI_TYPE_SIZE)))
                {
                    v_U16_t curAddIELen = pWextState->assocAddIE.length;
                    hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
                            __func__, eLen + 2);

                    if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
                    {
                       hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
                                                      "Need bigger buffer space");
                       VOS_ASSERT(0);
                       return -ENOMEM;
                    }
                    // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
                    memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
                    pWextState->assocAddIE.length += eLen + 2;

                    pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
                    pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
                }
#ifdef WLAN_FEATURE_WFD
                else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
                                                         WFD_OUI_TYPE_SIZE))
                        /*Consider WFD IE, only for P2P Client */
                         && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
                {
                    v_U16_t curAddIELen = pWextState->assocAddIE.length;
                    hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
                            __func__, eLen + 2);

                    if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
                    {
                       hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
                                                      "Need bigger buffer space");
                       VOS_ASSERT(0);
                       return -ENOMEM;
                    }
                    // WFD IE is saved to Additional IE ; it should be accumulated to handle
                    // WPS IE + P2P IE + WFD IE
                    memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
                    pWextState->assocAddIE.length += eLen + 2;

                    pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
                    pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
                }
#endif
                /* Appending HS 2.0 Indication Element in Assiciation Request */
                else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
                                       HS20_OUI_TYPE_SIZE)) )
                {
                    v_U16_t curAddIELen = pWextState->assocAddIE.length;
                    hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
                            __func__, eLen + 2);

                    if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
                    {
                        hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
                               "Need bigger buffer space");
                        VOS_ASSERT(0);
                        return -ENOMEM;
                    }
                    memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
                    pWextState->assocAddIE.length += eLen + 2;

                    pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
                    pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
                }
                 /* Appending OSEN Information  Element in Assiciation Request */
                else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
                                       OSEN_OUI_TYPE_SIZE)) )
                {
                    v_U16_t curAddIELen = pWextState->assocAddIE.length;
                    hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
                            __func__, eLen + 2);

                    if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
                    {
                        hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
                               "Need bigger buffer space");
                        VOS_ASSERT(0);
                        return -ENOMEM;
                    }
                    memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
                    pWextState->assocAddIE.length += eLen + 2;

                    pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
                    pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
                    pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
                }

                 /* Update only for WPA IE */
                if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
                       (WLAN_HDD_IBSS == pAdapter->device_mode)) {

                   /* populating as ADDIE in beacon frames */
                   if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
                       WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
                       NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
                   {
                       if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
                           WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
                           eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
                       {
                           hddLog(LOGE,
                                  "Coldn't pass "
                                  "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
                       }
                   }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
                   else
                       hddLog(LOGE,
                              "Could not pass on "
                              "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");

                   /* IBSS mode doesn't contain params->proberesp_ies still
                    beaconIE's need to be populated in probe response frames */
                   if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
                   {
                      u16 rem_probe_resp_ie_len = eLen + 2;
                      u8 probe_rsp_ie_len[3] = {0};
                      u8 counter = 0;

                      /* Check Probe Resp Length if it is greater then 255 then
                         Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
                         & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
                         not able Store More then 255 bytes into One Variable */

                      while ((rem_probe_resp_ie_len > 0) && (counter < 3))
                      {
                         if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
                         {
                            probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
                            rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
                         }
                         else
                         {
                            probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
                            rem_probe_resp_ie_len = 0;
                         }
                      }

                      rem_probe_resp_ie_len = 0;

                      if (probe_rsp_ie_len[0] > 0)
                      {
                         if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                          WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
                                          (tANI_U8*)(genie - 2),
                                          probe_rsp_ie_len[0], NULL,
                                          eANI_BOOLEAN_FALSE)
                                          == eHAL_STATUS_FAILURE)
                         {
                            hddLog(LOGE,
                                   "Could not pass"
                                   "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
                         }
                         rem_probe_resp_ie_len += probe_rsp_ie_len[0];
                      }

                      if (probe_rsp_ie_len[1] > 0)
                      {
                         if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                          WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
                                          (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
                                          probe_rsp_ie_len[1], NULL,
                                          eANI_BOOLEAN_FALSE)
                                          == eHAL_STATUS_FAILURE)
                         {
                             hddLog(LOGE,
                                    "Could not pass"
                                    "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
                         }
                         rem_probe_resp_ie_len += probe_rsp_ie_len[1];
                      }

                      if (probe_rsp_ie_len[2] > 0)
                      {
                         if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                          WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
                                          (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
                                          probe_rsp_ie_len[2], NULL,
                                          eANI_BOOLEAN_FALSE)
                                          == eHAL_STATUS_FAILURE)
                          {
                            hddLog(LOGE,
                                   "Could not pass"
                                   "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
                          }
                          rem_probe_resp_ie_len += probe_rsp_ie_len[2];
                       }

                       if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
                           WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
                           eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
                       {
                          hddLog(LOGE,
                                "Could not pass"
                                "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
                       }
                   }
                } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
                break;
            case DOT11F_EID_RSN:
                if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
                    hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
                            __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
                    VOS_ASSERT(0);
                    return -EINVAL;
                }
                hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
                memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
                memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
                pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
                pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
                break;

                /* Appending extended capabilities with Interworking or
                 * bsstransition bit set in Assoc Req.
                 *
                 * In assoc req this EXT Cap will only be taken into account if
                 * interworkingService or bsstransition bit is set to 1.
                 * Driver is only interested in interworkingService and
                 * bsstransition capability from supplicant.
                 * If in future any other EXT Cap info is
                 * required from supplicat, it needs to be handled while
                 * sending Assoc Req in LIM.
                 */
            case DOT11F_EID_EXTCAP:
                {
                    v_U16_t curAddIELen = pWextState->assocAddIE.length;
                    hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
                            __func__, eLen + 2);

                    if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
                    {
                       hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
                                                      "Need bigger buffer space");
                       VOS_ASSERT(0);
                       return -ENOMEM;
                    }
                    memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
                    pWextState->assocAddIE.length += eLen + 2;

                    pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
                    pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
                    break;
                }
#ifdef FEATURE_WLAN_WAPI
            case WLAN_EID_WAPI:
                pAdapter->wapi_info.nWapiMode = 1;   //Setting WAPI Mode to ON=1
                hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
                                          pAdapter->wapi_info.nWapiMode);
                tmp = (u16 *)ie;
                tmp = tmp + 2; // Skip element Id and Len, Version
                akmsuiteCount = WPA_GET_LE16(tmp);
                tmp = tmp + 1;
                akmlist = (int *)(tmp);
                if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
                {
                    memcpy(akmsuite, akmlist, (4*akmsuiteCount));
                }
                else
                {
                    hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
                    VOS_ASSERT(0);
                    return -EINVAL;
                }

                if (WAPI_PSK_AKM_SUITE == akmsuite[0])
                {
                    hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
                                                            __func__);
                    pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
                }
                if (WAPI_CERT_AKM_SUITE == akmsuite[0])
                {
                    hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
                                                             __func__);
                    pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
                }
                break;
#endif
            default:
                hddLog (VOS_TRACE_LEVEL_ERROR,
                        "%s Set UNKNOWN IE %X", __func__, elementId);
                /* when Unknown IE is received we should break and continue
                 * to the next IE in the buffer instead we were returning
                 * so changing this to break */
                break;
        }
        genie += eLen;
        remLen -= eLen;
    }
    EXIT();
    return 0;
}

/*
 * FUNCTION: hdd_isWPAIEPresent
 * Parse the received IE to find the WPA IE
 *
 */
static bool hdd_isWPAIEPresent(
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
                               const u8 *ie,
#else
                               u8 *ie,
#endif
                               u8 ie_len)
{
    v_U8_t eLen = 0;
    v_U16_t remLen = ie_len;
    v_U8_t elementId = 0;

    while (remLen >= 2)
    {
        elementId = *ie++;
        eLen  = *ie++;
        remLen -= 2;
        if (eLen > remLen)
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: IE length is wrong %d", __func__, eLen);
            return FALSE;
        }
        if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
        {
          /* OUI - 0x00 0X50 0XF2
             WPA Information Element - 0x01
             WPA version - 0x01*/
            if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
               return TRUE;
        }
        ie += eLen;
        remLen -= eLen;
    }
    return FALSE;
}

/*
 * FUNCTION: wlan_hdd_cfg80211_set_privacy
 * This function is used to initialize the security
 * parameters during connect operation.
 */
int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
                                   struct cfg80211_connect_params *req
                                  )
{
    int status = 0;
    hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    ENTER();

    /*set wpa version*/
    pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;

    if (req->crypto.wpa_versions)
    {
        if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
        {
            pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
        }
        else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
        {
            pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
        }
    }

    hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
            pWextState->wpaVersion);

    /*set authentication type*/
    status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);

    if (0 > status)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: failed to set authentication type ", __func__);
        return status;
    }

    /*set key mgmt type*/
    if (req->crypto.n_akm_suites)
    {
        status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
        if (0 > status)
        {
            hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
                    __func__);
            return status;
        }
    }

    /*set pairwise cipher type*/
    if (req->crypto.n_ciphers_pairwise)
    {
        status = wlan_hdd_cfg80211_set_cipher(pAdapter,
                                      req->crypto.ciphers_pairwise[0], true);
        if (0 > status)
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    "%s: failed to set unicast cipher type", __func__);
            return status;
        }
    }
    else
    {
        /*Reset previous cipher suite to none*/
        status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
        if (0 > status)
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    "%s: failed to set unicast cipher type", __func__);
            return status;
        }
    }

    /*set group cipher type*/
    status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
                                                                       false);

    if (0 > status)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
                __func__);
        return status;
    }

#ifdef WLAN_FEATURE_11W
    pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
#endif

    /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
    if (req->ie_len)
    {
        status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
        if ( 0 > status)
        {
            hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
                    __func__);
            return status;
        }
    }

    /*incase of WEP set default key information*/
    if (req->key && req->key_len)
    {
        if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
                || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
          )
        {
            if ( IW_AUTH_KEY_MGMT_802_1X
                    == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X  ))
            {
                hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
                        __func__);
                return -EOPNOTSUPP;
            }
            else
            {
                u8 key_len = req->key_len;
                u8 key_idx = req->key_idx;

                if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
                        && (CSR_MAX_NUM_KEY > key_idx)
                  )
                {
                    hddLog(VOS_TRACE_LEVEL_INFO,
                     "%s: setting default wep key, key_idx = %hu key_len %hu",
                            __func__, key_idx, key_len);
                    vos_mem_copy(
                       &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
                                  req->key, key_len);
                    pWextState->roamProfile.Keys.KeyLength[key_idx] =
                                                               (u8)key_len;
                    pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
                }
            }
        }
    }

    return status;
}

/*
 * FUNCTION: wlan_hdd_try_disconnect
 * This function is used to disconnect from previous
 * connection
 */
int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
{
    long ret = 0;
    int status, result = 0;
    hdd_station_ctx_t *pHddStaCtx;
    eMib_dot11DesiredBssType connectedBssType;
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);

    ret = wlan_hdd_validate_context(pHddCtx);
    if (0 != ret)
    {
        return ret;
    }
    pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

    hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );

    if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
      (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
      (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
      (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
    {
        /* Indicate disconnect to SME so that in-progress connection or preauth
         * can be aborted
         */
        sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
                            pAdapter->sessionId);
        spin_lock_bh(&pAdapter->lock_for_active_session);
        if (eConnectionState_Associated ==  pHddStaCtx->conn_info.connState)
        {
            wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
        }
        spin_unlock_bh(&pAdapter->lock_for_active_session);
        hdd_connSetConnectionState(pHddStaCtx,
                     eConnectionState_Disconnecting);
        /* Issue disconnect to CSR */
        INIT_COMPLETION(pAdapter->disconnect_comp_var);
        status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
                        pAdapter->sessionId,
                        eCSR_DISCONNECT_REASON_UNSPECIFIED);
        if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
            hddLog(LOG1,
             FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
        } else if ( 0 != status ) {
            hddLog(LOGE,
               FL("csrRoamDisconnect failure, returned %d"),
               (int)status );
            result = -EINVAL;
            goto disconnected;
        }
        ret = wait_for_completion_timeout(
                         &pAdapter->disconnect_comp_var,
                         msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
        if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
            hddLog(LOGE,
              "%s: Failed to disconnect, timed out", __func__);
            result = -ETIMEDOUT;
        }
    }
    else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
    {
        ret = wait_for_completion_timeout(
                     &pAdapter->disconnect_comp_var,
                     msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
        if (!ret)
        {
            hddLog(LOGE, FL("Failed to receive disconnect event"));
            result = -ETIMEDOUT;
        }
    }
disconnected:
    hddLog(LOG1,
          FL("Set HDD connState to eConnectionState_NotConnected"));
    pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
    return result;
}

/**
 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
 * @adapter: Pointer to the HDD adapter
 * @req: Pointer to the structure cfg_connect_params receieved from user space
 *
 * This function will start reassociation if bssid hint, channel hint and
 * previous bssid parameters are present in the connect request
 *
 * Return: success if reassociation is happening
 *         Error code if reassociation is not permitted or not happening
 */
#ifdef CFG80211_CONNECT_PREV_BSSID
static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
				struct cfg80211_connect_params *req)
{
	int status = -EPERM;
	if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
		hddLog(VOS_TRACE_LEVEL_INFO,
			FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
			req->channel_hint->hw_value,
			MAC_ADDR_ARRAY(req->bssid_hint));
		status  = hdd_reassoc(adapter, req->bssid_hint,
					req->channel_hint->hw_value,
					CONNECT_CMD_USERSPACE);
	}
	return status;
}
#else
static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
				struct cfg80211_connect_params *req)
{
	return -EPERM;
}
#endif

/**
 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
 * connect in HT20 mode
 * @hdd_ctx: hdd context
 * @adapter: Pointer to the HDD adapter
 * @req: Pointer to the structure cfg_connect_params receieved from user space
 *
 * This function will check if supplicant has indicated to to connect in HT20
 * mode. this is currently applicable only for 2.4Ghz mode only.
 * if feature is enabled and supplicant indicate HT20 set
 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
 *
 * Return: void
 */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
    hdd_adapter_t *adapter,
    struct cfg80211_connect_params *req)
{
    hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
    tCsrRoamProfile *roam_profile;

    roam_profile = &wext_state->roamProfile;
    roam_profile->force_24ghz_in_ht20 = false;
    if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
        !(req->ht_capa.cap_info &
          IEEE80211_HT_CAP_SUP_WIDTH_20_40))
        roam_profile->force_24ghz_in_ht20 = true;

    hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
         req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
}
#else
static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
    hdd_adapter_t *adapter,
    struct cfg80211_connect_params *req)
{
    hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
    tCsrRoamProfile *roam_profile;

    roam_profile = &wext_state->roamProfile;
    roam_profile->force_24ghz_in_ht20 = false;
}
#endif

/*
 * FUNCTION: __wlan_hdd_cfg80211_connect
 * This function is used to start the association process
 */
static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
                                      struct net_device *ndev,
                                      struct cfg80211_connect_params *req
                                      )
{
    int status;
    u16 channel;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
             defined(CFG80211_BSSID_HINT_BACKPORT)
    const u8 *bssid_hint = req->bssid_hint;
#else
    const u8 *bssid_hint = NULL;
#endif
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
    VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
    hdd_context_t *pHddCtx = NULL;

    ENTER();

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_CONNECT,
                      pAdapter->sessionId, pAdapter->device_mode));
    hddLog(VOS_TRACE_LEVEL_INFO,
           "%s: device_mode = %s (%d)", __func__,
           hdd_device_modetoString(pAdapter->device_mode),
                                   pAdapter->device_mode);

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    if (!pHddCtx)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: HDD context is null", __func__);
        return -EINVAL;
    }

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    if (wlan_hdd_check_and_stop_mon(pAdapter, true))
        return -EINVAL;

    status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
    if (0 == status)
        return status;


#ifdef WLAN_BTAMP_FEATURE
    //Infra connect not supported when AMP traffic is on.
    if( VOS_TRUE == WLANBAP_AmpSessionOn() )
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: No connection when AMP is on", __func__);
        return -ECONNREFUSED;
    }
#endif

    //If Device Mode is Station Concurrent Sessions Exit BMps
    //P2P Mode will be taken care in Open/close adapter
    if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
        (vos_concurrent_open_sessions_running())) {
        exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
                                               WLAN_HDD_INFRA_STATION);
    }

    /*Try disconnecting if already in connected state*/
    status = wlan_hdd_try_disconnect(pAdapter);
    if ( 0 > status)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
                " connection"));
        return -EALREADY;
    }
    /* Check for max concurrent connections after doing disconnect if any*/
    if (vos_max_concurrent_connections_reached()) {
        hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
        return -ECONNREFUSED;
    }

    /*initialise security parameters*/
    status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);

    if ( 0 > status)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
                __func__);
        return status;
    }

    if (pHddCtx->spoofMacAddr.isEnabled)
    {
        hddLog(VOS_TRACE_LEVEL_INFO,
                        "%s: MAC Spoofing enabled ", __func__);
        /* Updating SelfSta Mac Addr in TL which will be used to get staidx
         * to fill TxBds for probe request during SSID scan which may happen
         * as part of connect command
         */
        status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
            &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
        if (status != VOS_STATUS_SUCCESS)
            return -ECONNREFUSED;
    }

    if (req->channel)
        channel = req->channel->hw_value;
    else
        channel = 0;

    /* Abort if any scan is going on */
    status = wlan_hdd_scan_abort(pAdapter);
    if (0 != status)
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));

    wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);

    status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
                                             req->ssid_len, req->bssid,
                                             bssid_hint, channel);

    if (0 != status)
    {
        //ReEnable BMPS if disabled
        if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
            (NULL != pHddCtx))
        {
            if (pHddCtx->hdd_wlan_suspended)
            {
                hdd_set_pwrparams(pHddCtx);
            }
           //ReEnable Bmps and Imps back
           hdd_enable_bmps_imps(pHddCtx);
        }
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
        return status;
    }
    pHddCtx->isAmpAllowed = VOS_FALSE;
    EXIT();
    return status;
}

static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
                                      struct net_device *ndev,
                                      struct cfg80211_connect_params *req)
{
    int ret;
    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
    vos_ssr_unprotect(__func__);

    return ret;
}

/*
 * FUNCTION: __wlan_hdd_cfg80211_disconnect
 * This function is used to issue a disconnect request to SME
 */
static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
                                         struct net_device *dev,
                                         u16 reason
                                         )
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
    int status;
    tCsrRoamProfile  *pRoamProfile;
    hdd_station_ctx_t *pHddStaCtx;
    hdd_context_t *pHddCtx;
#ifdef FEATURE_WLAN_TDLS
    tANI_U8 staIdx;
#endif

    ENTER();

    if (!pAdapter) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
        return -EINVAL;
    }

    pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    if (!pHddStaCtx) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
        return -EINVAL;
    }

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_DISCONNECT,
                     pAdapter->sessionId, reason));
    hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
           __func__, hdd_device_modetoString(pAdapter->device_mode),
                                             pAdapter->device_mode);

    hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
            __func__, reason);

    if (NULL != pRoamProfile)
    {
        /*issue disconnect request to SME, if station is in connected state*/
        if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
            (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
        {
            eCsrRoamDisconnectReason reasonCode =
                                       eCSR_DISCONNECT_REASON_UNSPECIFIED;
            hdd_scaninfo_t *pScanInfo;
            switch(reason)
            {
                case WLAN_REASON_MIC_FAILURE:
                    reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
                    break;

                case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
                case WLAN_REASON_DISASSOC_AP_BUSY:
                case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
                    reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
                    break;

                case WLAN_REASON_PREV_AUTH_NOT_VALID:
                case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
                case WLAN_REASON_DEAUTH_LEAVING:
                    reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
                    break;

                default:
                    reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
                    break;
            }
            pScanInfo =  &pHddCtx->scan_info;
            if (pScanInfo->mScanPending)
            {
                hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
                              "Aborting Scan");
                hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
                                   eCSR_SCAN_ABORT_DEFAULT);
            }
            wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
#ifdef FEATURE_WLAN_TDLS
            /* First clean up the tdls peers if any */
            for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
            {
                if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
                    (pHddCtx->tdlsConnInfo[staIdx].staId))
                {
                    uint8 *mac;
                    mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                            "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
                            __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
                            MAC_ADDR_ARRAY(mac));
                    status = sme_DeleteTdlsPeerSta(
                                              WLAN_HDD_GET_HAL_CTX(pAdapter),
                                              pAdapter->sessionId,
                                              mac);
                    if (status != eHAL_STATUS_SUCCESS) {
                        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
                        return -EPERM;
                    }
                }
            }
#endif

            hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
                   reasonCode,
                   pHddStaCtx->conn_info.connState);
            status = wlan_hdd_disconnect(pAdapter, reasonCode);
            if ( 0 != status )
            {
                hddLog(VOS_TRACE_LEVEL_ERROR,
                        "%s wlan_hdd_disconnect failure, returned %d",
                        __func__, (int)status );
                return -EINVAL;
            }
        }
        else
        {
            hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
                   "called while in %d state", __func__,
                    pHddStaCtx->conn_info.connState);
        }
    }
    else
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
    }

    EXIT();
    return status;
}

static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
                                         struct net_device *dev,
                                         u16 reason
                                         )
{
    int ret;
    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
    vos_ssr_unprotect(__func__);

    return ret;
}

/*
 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
 * This function is used to initialize the security
 * settings in IBSS mode.
 */
static int wlan_hdd_cfg80211_set_privacy_ibss(
                                         hdd_adapter_t *pAdapter,
                                         struct cfg80211_ibss_params *params
                                         )
{
    int status = 0;
    tANI_U32 ret;
    hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

    ENTER();

    pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
    vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));

    if (params->ie_len && ( NULL != params->ie) )
    {
        if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
                            params->ie_len, WLAN_EID_RSN ))
        {
            pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
            encryptionType = eCSR_ENCRYPT_TYPE_AES;
        }
        else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
        {
            tDot11fIEWPA dot11WPAIE;
            tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
            u8 *ie;

            memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
            ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
                                     params->ie_len, DOT11F_EID_WPA);
            if ( NULL != ie )
            {
                pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
                // Unpack the WPA IE
                //Skip past the EID byte and length byte - and four byte WiFi OUI
                ret = dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
                                &ie[2+4],
                                ie[1] - 4,
                                &dot11WPAIE);
                if (DOT11F_FAILED(ret))
                {
                    hddLog(LOGE,
                           FL("unpack failed status:(0x%08x)"),
                           ret);
                    return -EINVAL;
                }

                /*Extract the multicast cipher, the encType for unicast
                               cipher for wpa-none is none*/
                encryptionType =
                  hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
            }
        }

        status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);

        if (0 > status)
        {
            hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
                    __func__);
            return status;
        }
    }

    pWextState->roamProfile.AuthType.authType[0] =
                                pHddStaCtx->conn_info.authType =
                                eCSR_AUTH_TYPE_OPEN_SYSTEM;
    if (params->privacy)
    {
        /* Security enabled IBSS, At this time there is no information available
         * about the security paramters, so initialise the encryption type to
         * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
         * The correct security parameters will be updated later in
         * wlan_hdd_cfg80211_add_key */
        /* Hal expects encryption type to be set inorder
         *enable privacy bit in beacons */

        encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
    }
    VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
                          "encryptionType=%d", encryptionType);
    pHddStaCtx->conn_info.ucEncryptionType                   = encryptionType;
    pWextState->roamProfile.EncryptionType.numEntries        = 1;
    pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
    return status;
}

/*
 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
 * This function is used to create/join an IBSS
 */
static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
                                        struct net_device *dev,
                                        struct cfg80211_ibss_params *params
                                       )
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
    hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    tCsrRoamProfile          *pRoamProfile;
    int status;
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    tSirMacAddr bssid;

    ENTER();

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
                     pAdapter->sessionId, pAdapter->device_mode));
    hddLog(VOS_TRACE_LEVEL_INFO,
           "%s: device_mode = %s (%d)", __func__,
           hdd_device_modetoString(pAdapter->device_mode),
                                   pAdapter->device_mode);

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    if (NULL == pWextState)
    {
        hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
                __func__);
        return -EIO;
    }

    if (vos_max_concurrent_connections_reached()) {
        hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
        return -ECONNREFUSED;
    }

    /*Try disconnecting if already in connected state*/
    status = wlan_hdd_try_disconnect(pAdapter);
    if ( 0 > status)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
                " IBSS connection"));
        return -EALREADY;
    }

    pRoamProfile = &pWextState->roamProfile;

    if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
    {
        hddLog (VOS_TRACE_LEVEL_ERROR,
                "%s Interface type is not set to IBSS", __func__);
        return -EINVAL;
    }

    /* BSSID is provided by upper layers hence no need to AUTO generate */
    if (NULL != params->bssid) {
       if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
                        NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
           hddLog (VOS_TRACE_LEVEL_ERROR,
                  "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
           return -EIO;
       }
       vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
    }
    else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
    {
        if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
                         NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
        {
            hddLog (VOS_TRACE_LEVEL_ERROR,
                    "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
            return -EIO;
        }

        vos_mem_copy((v_U8_t *)bssid,
                     (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
                      sizeof(bssid));
    }

    /* Set Channel */
    if (NULL !=
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
                params->chandef.chan)
#else
                params->channel)
#endif
    {
        u8 channelNum;
        v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
        v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
        tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
        int indx;

        /* Get channel number */
        channelNum =
               ieee80211_frequency_to_channel(
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
                                            params->chandef.chan->center_freq);
#else
                                            params->channel->center_freq);
#endif

        if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
                    validChan, &numChans))
        {
            hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
                    __func__);
            return -EOPNOTSUPP;
        }

        for (indx = 0; indx < numChans; indx++)
        {
            if (channelNum == validChan[indx])
            {
                break;
            }
        }
        if (indx >= numChans)
        {
            hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
                    __func__, channelNum);
            return -EINVAL;
        }
        /* Set the Operational Channel */
        hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
                channelNum);
        pRoamProfile->ChannelInfo.numOfChannels = 1;
        pHddStaCtx->conn_info.operationChannel = channelNum;
        pRoamProfile->ChannelInfo.ChannelList =
            &pHddStaCtx->conn_info.operationChannel;
    }

    /* Initialize security parameters */
    status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
    if (status < 0)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
                __func__);
        return status;
    }

    /* Issue connect start */
    status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
            params->ssid_len, (const u8 *)&bssid, NULL,
            pHddStaCtx->conn_info.operationChannel);

    if (0 > status)
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);

    EXIT();
    return status;
}

static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
                                        struct net_device *dev,
                                        struct cfg80211_ibss_params *params
                                       )
{
    int ret = 0;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
    vos_ssr_unprotect(__func__);

    return ret;
}

/*
 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
 * This function is used to leave an IBSS
 */
static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
                                         struct net_device *dev
                                         )
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
    hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    tCsrRoamProfile *pRoamProfile;
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    int status;
    eHalStatus hal_status;
#ifdef WLAN_FEATURE_RMC
    tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
#endif

    ENTER();

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
                      pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
                       hdd_device_modetoString(pAdapter->device_mode),
                                               pAdapter->device_mode);
    if (NULL == pWextState)
    {
        hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
                __func__);
        return -EIO;
    }

    pRoamProfile = &pWextState->roamProfile;

    /* Issue disconnect only if interface type is set to IBSS */
    if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
    {
        hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
                __func__);
        return -EINVAL;
    }

#ifdef WLAN_FEATURE_RMC
    /* Clearing add IE of beacon */
    if (ccmCfgSetStr(pHddCtx->hHal,
        WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
        WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
        NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
    {
        hddLog (VOS_TRACE_LEVEL_ERROR,
                "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
        return -EINVAL;
    }
    if (ccmCfgSetInt(pHddCtx->hHal,
        WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
        eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
    {
        hddLog (VOS_TRACE_LEVEL_ERROR,
                "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
                __func__);
        return -EINVAL;
    }

    // Reset WNI_CFG_PROBE_RSP Flags
    wlan_hdd_reset_prob_rspies(pAdapter);

    if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
                     WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
                     eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
    {
        hddLog (VOS_TRACE_LEVEL_ERROR,
                "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
                __func__);
        return -EINVAL;
    }
#endif

    /* Issue Disconnect request */
    INIT_COMPLETION(pAdapter->disconnect_comp_var);
    hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
                 pAdapter->sessionId,
                 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
    if (!HAL_STATUS_SUCCESS(hal_status)) {
        hddLog(LOGE,
               FL("sme_RoamDisconnect failed hal_status(%d)"),
               hal_status);
        return -EAGAIN;
    }
    status = wait_for_completion_timeout(
                     &pAdapter->disconnect_comp_var,
                     msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
    if (!status) {
        hddLog(LOGE,
              FL("wait on disconnect_comp_var failed"));
        return -ETIMEDOUT;
    }

    EXIT();
    return 0;
}

static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
                                         struct net_device *dev
                                         )
{
    int ret = 0;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
    vos_ssr_unprotect(__func__);

    return ret;
}

/*
 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
 * This function is used to set the phy parameters
 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
 */
static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
        u32 changed)
{
    hdd_context_t *pHddCtx = wiphy_priv(wiphy);
    tHalHandle hHal = pHddCtx->hHal;
    int status;

    ENTER();

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                      TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
                       NO_SESSION, wiphy->rts_threshold));

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    if (changed & WIPHY_PARAM_RTS_THRESHOLD)
    {
        u16 rts_threshold = (wiphy->rts_threshold == -1) ?
                               WNI_CFG_RTS_THRESHOLD_STAMAX :
                               wiphy->rts_threshold;

        if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
                (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    "%s: Invalid RTS Threshold value %hu",
                    __func__, rts_threshold);
            return -EINVAL;
        }

        if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
                    rts_threshold, ccmCfgSetCallback,
                    eANI_BOOLEAN_TRUE))
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    "%s: ccmCfgSetInt failed for rts_threshold value %hu",
                    __func__, rts_threshold);
            return -EIO;
        }

        hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
                rts_threshold);
    }

    if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
    {
        u16 frag_threshold = (wiphy->frag_threshold == -1) ?
                                WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
                                wiphy->frag_threshold;

        if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
                (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    "%s: Invalid frag_threshold value %hu", __func__,
                    frag_threshold);
            return -EINVAL;
        }

        if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
                    frag_threshold, ccmCfgSetCallback,
                    eANI_BOOLEAN_TRUE))
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    "%s: ccmCfgSetInt failed for frag_threshold value %hu",
                    __func__, frag_threshold);
            return -EIO;
        }

        hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
                frag_threshold);
    }

    if ((changed & WIPHY_PARAM_RETRY_SHORT)
            || (changed & WIPHY_PARAM_RETRY_LONG))
    {
        u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
                         wiphy->retry_short :
                         wiphy->retry_long;

        if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
                (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
        {
            hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
                    __func__, retry_value);
            return -EINVAL;
        }

        if (changed & WIPHY_PARAM_RETRY_SHORT)
        {
            if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
                        retry_value, ccmCfgSetCallback,
                        eANI_BOOLEAN_TRUE))
            {
                hddLog(VOS_TRACE_LEVEL_ERROR,
                        "%s: ccmCfgSetInt failed for long retry count %hu",
                        __func__, retry_value);
                return -EIO;
            }
            hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
                    __func__, retry_value);
        }
        else if (changed & WIPHY_PARAM_RETRY_SHORT)
        {
            if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
                        retry_value, ccmCfgSetCallback,
                        eANI_BOOLEAN_TRUE))
            {
                hddLog(VOS_TRACE_LEVEL_ERROR,
                        "%s: ccmCfgSetInt failed for short retry count %hu",
                        __func__, retry_value);
                return -EIO;
            }
            hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
                    __func__, retry_value);
        }
    }

    EXIT();
    return 0;
}

static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
                                                                u32 changed)
{
     int ret;

     vos_ssr_protect(__func__);
     ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
     vos_ssr_unprotect(__func__);

     return ret;
}

/*
 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
 * This function is used to set the txpower
 */
static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
        struct wireless_dev *wdev,
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
        enum tx_power_setting type,
#else
        enum nl80211_tx_power_setting type,
#endif
        int dbm)
{
    hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
    tHalHandle hHal = NULL;
    tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
    tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
    int status;

    ENTER();

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                      TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
                      NO_SESSION, type ));
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    hHal = pHddCtx->hHal;

    if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
                dbm, ccmCfgSetCallback,
                eANI_BOOLEAN_TRUE))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
        return -EIO;
    }

    hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
            dbm);

    switch(type)
    {
    case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
       /* Fall through */
    case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
       if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
       {
          hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
                 __func__);
          return -EIO;
       }
       break;
    case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
       hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
              __func__);
       return -EOPNOTSUPP;
       break;
    default:
       hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
              __func__, type);
       return -EIO;
    }

    EXIT();
    return 0;
}

static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
        struct wireless_dev *wdev,
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
        enum tx_power_setting type,
#else
        enum nl80211_tx_power_setting type,
#endif
        int dbm)
{
    int ret;
    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
                                        wdev,
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
                                        type,
#else
                                        type,
#endif
                                        dbm);
   vos_ssr_unprotect(__func__);

   return ret;
}

/*
 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
 * This function is used to read the txpower
 */
static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
                                         struct wireless_dev *wdev,
#endif
                                         int *dbm)
{

    hdd_adapter_t *pAdapter;
    hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
    int status;

    ENTER();

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        *dbm = 0;
        return status;
    }

    pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
    if (NULL == pAdapter)
    {
        hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
        return -ENOENT;
    }

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
                     pAdapter->sessionId, pAdapter->device_mode));
    wlan_hdd_get_classAstats(pAdapter);
    *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;

    EXIT();
    return 0;
}

static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
                                         struct wireless_dev *wdev,
#endif
                                         int *dbm)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
                                          wdev,
#endif
                                          dbm);
    vos_ssr_unprotect(__func__);

    return ret;
}

/*
 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
 * @stats: summary stats to use as a source
 * @info: kernel station_info struct to use as a destination
 *
 * Return: None
 */
static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
					struct station_info *info)
{
	int i;

	info->rx_packets = stats->rx_frm_cnt;
	info->tx_packets = 0;
	info->tx_retries = 0;
	info->tx_failed = 0;

	for (i = 0; i < 4; ++i) {
		info->tx_packets += stats->tx_frm_cnt[i];
		info->tx_retries += stats->multiple_retry_cnt[i];
		info->tx_failed += stats->fail_cnt[i];
	}

#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
	!defined(WITH_BACKPORTS)
	info->filled |= STATION_INFO_TX_PACKETS |
			STATION_INFO_TX_RETRIES |
			STATION_INFO_TX_FAILED |
			STATION_INFO_RX_PACKETS;
#else
	info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
			BIT(NL80211_STA_INFO_TX_RETRIES) |
			BIT(NL80211_STA_INFO_TX_FAILED) |
			BIT(NL80211_STA_INFO_RX_PACKETS);
#endif
}

/**
 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
 * @adapter: sap adapter pointer
 * @staid: station id of the client
 * @rssi: rssi value to fill
 *
 * Return: None
 */
void
wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
{
	v_CONTEXT_t pVosContext =  (WLAN_HDD_GET_CTX(adapter))->pvosContext;

	WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
}

#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
	!defined(WITH_BACKPORTS)
static inline void wlan_hdd_fill_station_info_signal(struct station_info
						     *sinfo)
{
	sinfo->filled |= STATION_INFO_SIGNAL;
}
#else
static inline void wlan_hdd_fill_station_info_signal(struct station_info
						     *sinfo)
{
	sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
}
#endif

/**
 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
 * @adapter: sap adapter to get stats for
 * @mac: mac address of the station
 * @info: kernel station_info struct to populate
 *
 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
 * support "station dump" and "station get" for SAP vdevs, even though they
 * aren't technically stations.
 *
 * Return: errno
 */
static int
wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
		       const u8* mac,
#else
		       u8* mac,
#endif
		       struct station_info *info)
{
	v_MACADDR_t *peerMacAddr;
	uint8_t staid;
	VOS_STATUS status;
	bool bc_mac_addr;

	status = wlan_hdd_get_station_stats(adapter);
	if (!VOS_IS_STATUS_SUCCESS(status)) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
			"Failed to get SAP stats; status:%d", status);
		return 0;
	}

	peerMacAddr = (v_MACADDR_t *)mac;
	bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
	staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
	hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);

	if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
		wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
		wlan_hdd_fill_station_info_signal(info);
	}

	wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);

	return 0;
}

static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
                                          const u8* mac,
#else
                                          u8* mac,
#endif
                                          struct station_info *sinfo)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
    tANI_U32 rate_flags;

    hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
    hdd_config_t  *pCfg    = pHddCtx->cfg_ini;

    tANI_U8  OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
    tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
    tANI_U8  ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
    tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
    tANI_U8  MCSRates[SIZE_OF_BASIC_MCS_SET];
    tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
    tANI_U16 maxRate = 0;
    int8_t snr = 0;
    tANI_U16 myRate;
    tANI_U16 currentRate = 0;
    tANI_U8  maxSpeedMCS = 0;
    tANI_U8  maxMCSIdx = 0;
    tANI_U8  rateFlag = 1;
    tANI_U8  i, j, rssidx, mode=0;
    tANI_U16 temp;
    int status;

#ifdef WLAN_FEATURE_11AC
    tANI_U32 vht_mcs_map;
    eDataRate11ACMaxMcs vhtMaxMcs;
#endif /* WLAN_FEATURE_11AC */

    ENTER();

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
        return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);

    if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
            (0 == ssidlen))
    {
        hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
                    " Invalid ssidlen, %d", __func__, ssidlen);
        /*To keep GUI happy*/
        return 0;
    }

    if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  "%s: Roaming in progress, so unable to proceed this request", __func__);
        /* return a cached value */
        sinfo->signal = pAdapter->rssi;
        return 0;
    }

    wlan_hdd_get_station_stats(pAdapter);
    rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;

    wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
    wlan_hdd_get_snr(pAdapter, &snr);
    pHddStaCtx->conn_info.signal = sinfo->signal;
    pHddStaCtx->cache_conn_info.signal = sinfo->signal;
    pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
    pHddStaCtx->cache_conn_info.noise = pHddStaCtx->conn_info.noise;
    wlan_hdd_fill_station_info_signal(sinfo);

    /*overwrite rate_flags if MAX link-speed need to be reported*/
    if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
        (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
         sinfo->signal >= pCfg->linkSpeedRssiLow))
    {
        rate_flags = pAdapter->maxRateFlags;
    }

    //convert to the UI units of 100kbps
    myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;

#ifdef LINKSPEED_DEBUG_ENABLED
    pr_info("RSSI %d, RLMS %u, rate %d, rssi high %d, rssi mid %d, rssi low %d, rate_flags 0x%x, MCS %d\n",
            sinfo->signal,
            pCfg->reportMaxLinkSpeed,
            myRate,
            (int) pCfg->linkSpeedRssiHigh,
            (int) pCfg->linkSpeedRssiMid,
            (int) pCfg->linkSpeedRssiLow,
            (int) rate_flags,
            (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
#endif //LINKSPEED_DEBUG_ENABLED

    if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
    {
        // we do not want to necessarily report the current speed
        if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
        {
            // report the max possible speed
            rssidx = 0;
        }
        else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
        {
            // report the max possible speed with RSSI scaling
            if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
            {
                // report the max possible speed
                rssidx = 0;
            }
            else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
            {
                // report middle speed
                rssidx = 1;
            }
            else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
            {
                // report middle speed
                rssidx = 2;
            }
            else
            {
                // report actual speed
                rssidx = 3;
            }
        }
        else
        {
            // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
            hddLog(VOS_TRACE_LEVEL_ERROR,
                   "%s: Invalid value for reportMaxLinkSpeed: %u",
                    __func__, pCfg->reportMaxLinkSpeed);
            rssidx = 0;
        }

        maxRate = 0;

        /* Get Basic Rate Set */
        if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
                             OperationalRates, &ORLeng))
        {
            hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
            /*To keep GUI happy*/
            return 0;
        }

        for (i = 0; i < ORLeng; i++)
        {
            for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
            {
                /* Validate Rate Set */
                if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
                {
                    currentRate = supported_data_rate[j].supported_rate[rssidx];
                    break;
                }
            }
            /* Update MAX rate */
            maxRate = (currentRate > maxRate)?currentRate:maxRate;
        }

        /* Get Extended Rate Set */
        if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
                             ExtendedRates, &ERLeng))
        {
            hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
            /*To keep GUI happy*/
            return 0;
        }

        for (i = 0; i < ERLeng; i++)
        {
            for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
            {
                if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
                {
                    currentRate = supported_data_rate[j].supported_rate[rssidx];
                    break;
                }
            }
            /* Update MAX rate */
            maxRate = (currentRate > maxRate)?currentRate:maxRate;
        }

        /* Get MCS Rate Set --
           Only if we are always reporting max speed  (or)
           if we have good rssi */
        if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
        {
            if (rate_flags & eHAL_TX_RATE_VHT80)
                mode = 2;
            else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
                mode = 1;
            else
                mode = 0;

            if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
                                 MCSRates, &MCSLeng))
            {
                hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
                /*To keep GUI happy*/
                return 0;
            }
            rateFlag = 0;
#ifdef WLAN_FEATURE_11AC
            /* VHT80 rate has seperate rate table */
            if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
            {
                ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
                vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
                if (rate_flags & eHAL_TX_RATE_SGI)
                {
                    rateFlag |= 1;
                }
                if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
                {
                    maxMCSIdx = 7;
                }
                else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
                {
                    maxMCSIdx = 8;
                }
                else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
                {
                    //VHT20 is supporting 0~8
                    if (rate_flags & eHAL_TX_RATE_VHT20)
                        maxMCSIdx = 8;
                    else
                        maxMCSIdx = 9;
                }

                if (0 != rssidx)/*check for scaled */
                {
                    //get middle rate MCS index if rssi=1/2
                    for (i=0; i <= maxMCSIdx; i++)
                    {
                        if (sinfo->signal <= rssiMcsTbl[mode][i])
                        {
                            maxMCSIdx = i;
                            break;
                        }
                    }
                }

                if (rate_flags & eHAL_TX_RATE_VHT80)
                {
                    currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
                    maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
                }
                else if (rate_flags & eHAL_TX_RATE_VHT40)
                {
                    currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
                    maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
                }
                else if (rate_flags & eHAL_TX_RATE_VHT20)
                {
                    currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
                    maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
                }

                maxSpeedMCS = 1;
                if (currentRate > maxRate)
                {
                    maxRate = currentRate;
                }

            }
            else
#endif /* WLAN_FEATURE_11AC */
            {
                if (rate_flags & eHAL_TX_RATE_HT40)
                {
                    rateFlag |= 1;
                }
                if (rate_flags & eHAL_TX_RATE_SGI)
                {
                    rateFlag |= 2;
                }

                temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
                if (rssidx == 1 || rssidx == 2)
                {
                    //get middle rate MCS index if rssi=1/2
                    for (i=0; i <= 7; i++)
                    {
                        if (sinfo->signal <= rssiMcsTbl[mode][i])
                        {
                            temp = i+1;
                            break;
                         }
                     }
                }

                for (i = 0; i < MCSLeng; i++)
                {
                    for (j = 0; j < temp; j++)
                    {
                        if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
                        {
                            currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
                            maxMCSIdx   = supported_mcs_rate[j].beacon_rate_index;
                            break;
                        }
                    }
                    if ((j < temp) && (currentRate > maxRate))
                    {
                        maxRate     = currentRate;
                    }
                }
                maxSpeedMCS = 1;
            }
        }

        else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
        {
            maxRate = myRate;
            maxSpeedMCS = 1;
            maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
        }
        // make sure we report a value at least as big as our current rate
        if ((maxRate < myRate) || (0 == maxRate))
        {
           maxRate = myRate;
           if (rate_flags & eHAL_TX_RATE_LEGACY)
           {
              maxSpeedMCS = 0;
           }
           else
           {
              maxSpeedMCS = 1;
              maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
           }
        }

        if (rate_flags & eHAL_TX_RATE_LEGACY)
        {
            sinfo->txrate.legacy  = maxRate;
#ifdef LINKSPEED_DEBUG_ENABLED
            pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
#endif //LINKSPEED_DEBUG_ENABLED
        }
        else
        {
            sinfo->txrate.mcs    = maxMCSIdx;
#ifdef WLAN_FEATURE_11AC
            sinfo->txrate.nss = 1;
            if (rate_flags & eHAL_TX_RATE_VHT80)
            {
                sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
	defined(WITH_BACKPORTS)
                sinfo->txrate.bw = RATE_INFO_BW_80;
#else
                sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
#endif
            }
            else if (rate_flags & eHAL_TX_RATE_VHT40)
            {
                sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
	defined(WITH_BACKPORTS)
                sinfo->txrate.bw = RATE_INFO_BW_40;
#else
                sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
#endif
            }
            else if (rate_flags & eHAL_TX_RATE_VHT20)
            {
                sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
            }
#endif /* WLAN_FEATURE_11AC */
            if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
            {
                sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
                if (rate_flags & eHAL_TX_RATE_HT40)
                {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
	defined(WITH_BACKPORTS)
                    sinfo->txrate.bw = RATE_INFO_BW_40;
#else
                    sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
#endif
                }
            }
            if (rate_flags & eHAL_TX_RATE_SGI)
            {
                sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
            }

#ifdef LINKSPEED_DEBUG_ENABLED
            pr_info("Reporting MCS rate %d flags %x\n",
                    sinfo->txrate.mcs,
                    sinfo->txrate.flags );
#endif //LINKSPEED_DEBUG_ENABLED
        }
    }
    else
    {
        // report current rate instead of max rate

        if (rate_flags & eHAL_TX_RATE_LEGACY)
        {
            //provide to the UI in units of 100kbps
            sinfo->txrate.legacy = myRate;
#ifdef LINKSPEED_DEBUG_ENABLED
            pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
#endif //LINKSPEED_DEBUG_ENABLED
        }
        else
        {
            //must be MCS
            sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
#ifdef WLAN_FEATURE_11AC
            sinfo->txrate.nss = 1;
            if (rate_flags & eHAL_TX_RATE_VHT80)
            {
                sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
            }
            else
#endif /* WLAN_FEATURE_11AC */
            {
                sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
            }
            if (rate_flags & eHAL_TX_RATE_SGI)
            {
                sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
            }
            if (rate_flags & eHAL_TX_RATE_HT40)
            {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
	defined(WITH_BACKPORTS)
                sinfo->txrate.bw = RATE_INFO_BW_40;
#else
                sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
#endif
            }
#ifdef WLAN_FEATURE_11AC
            else if (rate_flags & eHAL_TX_RATE_VHT80)
            {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
	defined(WITH_BACKPORTS)
                sinfo->txrate.bw = RATE_INFO_BW_80;
#else
                sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
#endif
            }
#endif /* WLAN_FEATURE_11AC */
#ifdef LINKSPEED_DEBUG_ENABLED
            pr_info("Reporting actual MCS rate %d flags %x\n",
                    sinfo->txrate.mcs,
                    sinfo->txrate.flags );
#endif //LINKSPEED_DEBUG_ENABLED
        }
    }

#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
	!defined(WITH_BACKPORTS)
    sinfo->filled |= STATION_INFO_TX_BITRATE;
#else
    sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
#endif

    sinfo->tx_packets =
       pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
       pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
       pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
       pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];

    sinfo->tx_retries =
       pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
       pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
       pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
       pAdapter->hdd_stats.summary_stat.retry_cnt[3];

    sinfo->tx_failed =
       pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
       pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
       pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
       pAdapter->hdd_stats.summary_stat.fail_cnt[3];

#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
	!defined(WITH_BACKPORTS)
    sinfo->filled |=
       STATION_INFO_RX_PACKETS |
       STATION_INFO_TX_PACKETS |
       STATION_INFO_TX_RETRIES |
       STATION_INFO_TX_FAILED;
#else
    sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
                     BIT(NL80211_STA_INFO_TX_PACKETS) |
                     BIT(NL80211_STA_INFO_TX_RETRIES) |
                     BIT(NL80211_STA_INFO_TX_FAILED);
#endif

    sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;

    vos_mem_copy(&pHddStaCtx->conn_info.txrate,
                 &sinfo->txrate, sizeof(sinfo->txrate));
    vos_mem_copy(&pHddStaCtx->cache_conn_info.txrate,
                 &sinfo->txrate, sizeof(sinfo->txrate));

    if (rate_flags & eHAL_TX_RATE_LEGACY)
        hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
               sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
               sinfo->rx_packets);
    else
        hddLog(LOG1,
               FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
               sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
               sinfo->tx_packets, sinfo->rx_packets);

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_GET_STA,
                      pAdapter->sessionId, maxRate));
       EXIT();
       return 0;
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
                                   const u8* mac, struct station_info *sinfo)
#else
static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
                                   u8* mac, struct station_info *sinfo)
#endif
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
    vos_ssr_unprotect(__func__);

    return ret;
}

static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
                     struct net_device *dev, bool mode, int timeout)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx;
    VOS_STATUS vos_status;
    int status;

    ENTER();

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

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
                     pAdapter->sessionId, timeout));

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    if ((DRIVER_POWER_MODE_AUTO == !mode) &&
        (TRUE == pHddCtx->hdd_wlan_suspended) &&
        (pHddCtx->cfg_ini->fhostArpOffload) &&
        (eConnectionState_Associated ==
             (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
    {

        hddLog(VOS_TRACE_LEVEL_INFO,
               "offload: in cfg80211_set_power_mgmt, calling arp offload");
        vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
        if (!VOS_IS_STATUS_SUCCESS(vos_status))
        {
            hddLog(VOS_TRACE_LEVEL_INFO,
                   "%s:Failed to enable ARPOFFLOAD Feature %d",
                   __func__, vos_status);
        }
    }

    /**The get power cmd from the supplicant gets updated by the nl only
     *on successful execution of the function call
     *we are oppositely mapped w.r.t mode in the driver
     **/
    vos_status =  wlan_hdd_enter_bmps(pAdapter, !mode);

    if (VOS_STATUS_E_FAILURE == vos_status)
    {
         VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: failed to enter bmps mode", __func__);
        return -EINVAL;
    }
    EXIT();
    return 0;
}

static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
                     struct net_device *dev, bool mode, int timeout)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
    vos_ssr_unprotect(__func__);

    return ret;
}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
                                           struct net_device *netdev,
                                           u8 key_index)
{
    ENTER();
    return 0;
}

static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
                                         struct net_device *netdev,
                                         u8 key_index)
{
    int ret;
    vos_ssr_protect(__func__);
    ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
    vos_ssr_unprotect(__func__);
    return ret;
}
#endif //LINUX_VERSION_CODE

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
                   struct net_device *dev,
                   struct ieee80211_txq_params *params)
{
    ENTER();
    return 0;
}
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
                   struct ieee80211_txq_params *params)
{
    ENTER();
    return 0;
}
#endif //LINUX_VERSION_CODE

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
                                   struct net_device *dev,
                                   struct ieee80211_txq_params *params)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
    vos_ssr_unprotect(__func__);
    return ret;
}
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
                   struct ieee80211_txq_params *params)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_set_txq_params(wiphy, params);
    vos_ssr_unprotect(__func__);
    return ret;
}
#endif

static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
                                       struct net_device *dev,
                                       struct tagCsrDelStaParams *pDelStaParams)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx;
    VOS_STATUS vos_status;
    int status;
    v_U8_t staId;
    v_CONTEXT_t pVosContext = NULL;
    ptSapContext pSapCtx = NULL;

    ENTER();

    if ( NULL == pAdapter )
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
        return -EINVAL;
    }

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_DEL_STA,
                     pAdapter->sessionId, pAdapter->device_mode));

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
       || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
       )
    {
        pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
        pSapCtx = VOS_GET_SAP_CB(pVosContext);
        if(pSapCtx == NULL){
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 FL("psapCtx is NULL"));
            return -ENOENT;
        }
        if (pHddCtx->cfg_ini->enable_sap_auth_offload)
        {
            VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
              "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
            pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
        }
        if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
        {
            v_U16_t i;
            for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
            {
                if ((pSapCtx->aStaInfo[i].isUsed) &&
                    (!pSapCtx->aStaInfo[i].isDeauthInProgress))
                {
                    vos_mem_copy(pDelStaParams->peerMacAddr,
                                 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
                                 ETHER_ADDR_LEN);

                    hddLog(VOS_TRACE_LEVEL_INFO,
                           "%s: Delete STA with MAC::"
                            MAC_ADDRESS_STR,
                            __func__,
                            MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
                    vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
                    if (VOS_IS_STATUS_SUCCESS(vos_status))
                        pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
                }
            }
        }
        else
        {

            vos_status = hdd_softap_GetStaId(pAdapter,
                            (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
            if (!VOS_IS_STATUS_SUCCESS(vos_status))
            {
                hddLog(VOS_TRACE_LEVEL_INFO,
                       "%s: Skip this DEL STA as this is not used::"
                       MAC_ADDRESS_STR,
                       __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
                return -ENOENT;
            }

            if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
            {
                hddLog(VOS_TRACE_LEVEL_INFO,
                       "%s: Skip this DEL STA as deauth is in progress::"
                       MAC_ADDRESS_STR,
                       __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
                return -ENOENT;
            }

            pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;

            hddLog(VOS_TRACE_LEVEL_INFO,
                                "%s: Delete STA with MAC::"
                                MAC_ADDRESS_STR,
                                __func__,
                                MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));

            vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
            if (!VOS_IS_STATUS_SUCCESS(vos_status))
            {
                pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
                hddLog(VOS_TRACE_LEVEL_INFO,
                                "%s: STA removal failed for ::"
                                MAC_ADDRESS_STR,
                                __func__,
                                MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
                return -ENOENT;
            }

        }
    }

    EXIT();

    return 0;
}

#ifdef USE_CFG80211_DEL_STA_V2
int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
                                         struct net_device *dev,
                                         struct station_del_parameters *param)
#else
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
                                         struct net_device *dev, const u8 *mac)
#else
int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
                                         struct net_device *dev, u8 *mac)
#endif
#endif
{
    int ret;
    struct tagCsrDelStaParams delStaParams;

    vos_ssr_protect(__func__);

#ifdef USE_CFG80211_DEL_STA_V2
    if (NULL == param) {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
        vos_ssr_unprotect(__func__);
        return -EINVAL;
    }

    WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
                                 param->subtype, &delStaParams);

#else
    WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
                                 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
#endif
    ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);

    vos_ssr_unprotect(__func__);

    return ret;
}

static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
                                           struct net_device *dev,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
                                           const u8 *mac,
#else
                                           u8 *mac,
#endif
                                           struct station_parameters *params)
{
    hdd_adapter_t *pAdapter;
    hdd_context_t *pHddCtx;
    int status = -EPERM;
#ifdef FEATURE_WLAN_TDLS
    u32 mask, set;

    ENTER();

    pAdapter =  WLAN_HDD_GET_PRIV_PTR(dev);
    if (NULL == pAdapter)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Adapter is NULL",__func__);
        return -EINVAL;
    }
    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_ADD_STA,
                     pAdapter->sessionId, params->listen_interval));
    mask = params->sta_flags_mask;

    set = params->sta_flags_set;

    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
               "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
               __func__, mask, set, MAC_ADDR_ARRAY(mac));

    if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
        if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
            status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
        }
    }
#endif
    EXIT();
    return status;
}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
          struct net_device *dev, const u8 *mac,
          struct station_parameters *params)
#else
static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
          struct net_device *dev, u8 *mac, struct station_parameters *params)
#endif
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
    vos_ssr_unprotect(__func__);

    return ret;
}
#ifdef FEATURE_WLAN_LFR

static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
            struct cfg80211_pmksa *pmksa)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    tHalHandle halHandle;
    eHalStatus result;
    int status;
    hdd_context_t *pHddCtx;
    tPmkidCacheInfo pmk_id;

    ENTER();

    // Validate pAdapter
    if ( NULL == pAdapter )
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
        return -EINVAL;
    }

    if (!pmksa) {
        hddLog(LOGE, FL("pmksa is NULL"));
        return -EINVAL;
    }

    if (!pmksa->bssid || !pmksa->pmkid) {
       hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
              pmksa->bssid, pmksa->pmkid);
       return -EINVAL;
    }

    hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
           __func__, MAC_ADDR_ARRAY(pmksa->bssid));

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    // Retrieve halHandle
    halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);

    vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
    vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);

    /* Add to the PMKSA ID Cache in CSR */
    result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
                                   &pmk_id, 1, FALSE);

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_SET_PMKSA,
                     pAdapter->sessionId, result));

    EXIT();
    return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
}

static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
            struct cfg80211_pmksa *pmksa)
{
   int ret;

   vos_ssr_protect(__func__);
   ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
   vos_ssr_unprotect(__func__);

   return ret;
}


static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
             struct cfg80211_pmksa *pmksa)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    tHalHandle halHandle;
    hdd_context_t *pHddCtx;
    int status = 0;

    ENTER();

    /* Validate pAdapter */
    if (NULL == pAdapter)
    {
       hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
       return -EINVAL;
    }

    if (!pmksa) {
        hddLog(LOGE, FL("pmksa is NULL"));
        return -EINVAL;
    }

    if (!pmksa->bssid) {
       hddLog(LOGE, FL("pmksa->bssid is NULL"));
       return -EINVAL;
    }

    hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
           __func__, MAC_ADDR_ARRAY(pmksa->bssid));

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    /*Retrieve halHandle*/
    halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
                     pAdapter->sessionId, 0));
    /* Delete the PMKID CSR cache */
    if (eHAL_STATUS_SUCCESS !=
        sme_RoamDelPMKIDfromCache(halHandle,
                                  pAdapter->sessionId, pmksa->bssid, FALSE)) {
        hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
                     MAC_ADDR_ARRAY(pmksa->bssid));
        status = -EINVAL;
    }

    EXIT();
    return status;
}


static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
             struct cfg80211_pmksa *pmksa)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
    vos_ssr_unprotect(__func__);

    return ret;

}

static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    tHalHandle halHandle;
    hdd_context_t *pHddCtx;
    int status = 0;

    ENTER();

    /* Validate pAdapter */
    if (NULL == pAdapter)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               "%s: Invalid Adapter" ,__func__);
       return -EINVAL;
    }

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
       return status;
    }

    /*Retrieve halHandle*/
    halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);

    /* Flush the PMKID cache in CSR */
    if (eHAL_STATUS_SUCCESS !=
        sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
        status = -EINVAL;
    }
    EXIT();
    return status;
}

static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
    vos_ssr_unprotect(__func__);

    return ret;
}
#endif

#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
                                             struct net_device *dev,
                                             struct cfg80211_update_ft_ies_params *ftie)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_station_ctx_t *pHddStaCtx;
    hdd_context_t *pHddCtx;
    int ret = 0;

    ENTER();

    if (NULL == pAdapter)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
        return -ENODEV;
    }
    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    ret = wlan_hdd_validate_context(pHddCtx);
    if (0 != ret)
    {
        return ret;
    }
    pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    if (NULL == pHddStaCtx)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
        return -EINVAL;
    }

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
                     pAdapter->sessionId, pHddStaCtx->conn_info.connState));
    // Added for debug on reception of Re-assoc Req.
    if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
    {
        hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
               ftie->ie_len);
        hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
    }

#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
    hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
           ftie->ie_len);
#endif

    // Pass the received FT IEs to SME
    sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
                  (const u8 *)ftie->ie,
                  ftie->ie_len);

    EXIT();
    return 0;
}

static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
                                           struct net_device *dev,
                                           struct cfg80211_update_ft_ies_params *ftie)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
    vos_ssr_unprotect(__func__);

    return ret;
}
#endif

#ifdef FEATURE_WLAN_SCAN_PNO

void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
                              tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
{
    int ret;
    hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
    hdd_context_t *pHddCtx;

    ENTER();

    if (NULL == pAdapter)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: HDD adapter is Null", __func__);
        return ;
    }

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    if (NULL == pHddCtx)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "%s: HDD context is Null!!!", __func__);
        return ;
    }

    spin_lock(&pHddCtx->schedScan_lock);
    if (TRUE == pHddCtx->isWiphySuspended)
    {
        pHddCtx->isSchedScanUpdatePending = TRUE;
        spin_unlock(&pHddCtx->schedScan_lock);
        hddLog(VOS_TRACE_LEVEL_INFO,
               "%s: Update cfg80211 scan database after it resume", __func__);
        return ;
    }
    spin_unlock(&pHddCtx->schedScan_lock);

    ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);

    if (0 > ret)
        hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
    else
    {
       /* Acquire wakelock to handle the case where APP's tries to suspend
        * immediatly after the driver gets connect request(i.e after pno)
        * from supplicant, this result in app's is suspending and not able
        * to process the connect request to AP */
        hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
    }
    cfg80211_sched_scan_results(pHddCtx->wiphy);
    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
            "%s: cfg80211 scan result database updated", __func__);
}

/*
 * FUNCTION: wlan_hdd_is_pno_allowed
 * Disallow pno if any session is active
 */
static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
{
   hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
   hdd_adapter_t *pTempAdapter = NULL;
   hdd_station_ctx_t *pStaCtx;
   hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
   int status = 0;

   if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
   {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
            "%s: PNO is allowed only in STA interface", __func__);
       return eHAL_STATUS_FAILURE;
   }

   status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);

   /* The current firmware design does not allow PNO during any
    * active sessions. PNO is allowed only in case when sap session
    * is present and sapo auth offload feature enabled in firmare.
    */
   while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
   {
        pTempAdapter = pAdapterNode->pAdapter;
        pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);

        if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
          && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
          || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
          || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
          || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
                 !pHddCtx->cfg_ini->enable_sap_auth_offload)
          || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
          )
        {
            return eHAL_STATUS_FAILURE;
        }
        status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
        pAdapterNode = pNext;
   }
   return eHAL_STATUS_SUCCESS;
}

void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
{
    hdd_adapter_t *pAdapter = callbackContext;
    hdd_context_t *pHddCtx;

    ENTER();

    if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  FL("Invalid adapter or adapter has invalid magic"));
        return;
    }

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

    if (VOS_STATUS_SUCCESS != status)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
              FL("PNO enable response status = %d"), status);
        pHddCtx->isPnoEnable = FALSE;
    }

    pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
    complete(&pAdapter->pno_comp_var);
    EXIT();
}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
   defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
/**
 * hdd_config_sched_scan_plan() - configures the sched scan plans
 *    from the framework.
 * @pno_req: pointer to PNO scan request
 * @request: pointer to scan request from framework
 *
 * Return: None
 */
static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
                                  struct cfg80211_sched_scan_request *request,
                                  hdd_context_t *hdd_ctx)
{
    v_U32_t i = 0;

    pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
    for (i = 0; i < request->n_scan_plans; i++)
    {
        pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
            request->scan_plans[i].iterations;
        pno_req->scanTimers.aTimerValues[i].uTimerValue =
            request->scan_plans[i].interval;
    }
}
#else
static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
                                  struct cfg80211_sched_scan_request *request,
                                  hdd_context_t *hdd_ctx)
{
    v_U32_t i, temp_int;
    /* Driver gets only one time interval which is hardcoded in
     * supplicant for 10000ms. Taking power consumption into account 6
     * timers will be used, Timervalue is increased exponentially
     * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
     * timer is configurable through INI param gPNOScanTimerRepeatValue.
     * If it is set to 0 only one timer will be used and PNO scan cycle
     * will be repeated after each interval specified by supplicant
     * till PNO is disabled.
     */
    if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
        pno_req->scanTimers.ucScanTimersCount =
            HDD_PNO_SCAN_TIMERS_SET_ONE;
    else
        pno_req->scanTimers.ucScanTimersCount =
            HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;

    temp_int = (request->interval)/1000;
    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
              "Base scan interval = %d PNOScanTimerRepeatValue = %d",
              temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
    for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
    {
        pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
            hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
        pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
        temp_int *= 2;
    }
    //Repeat last timer until pno disabled.
    pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
}
#endif

/*
 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
 * Function to enable PNO
 */
static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
          struct net_device *dev, struct cfg80211_sched_scan_request *request)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    tSirPNOScanReq pnoRequest = {0};
    hdd_context_t *pHddCtx;
    tHalHandle hHal;
    v_U32_t i, indx, num_ch, j;
    u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
    u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
    v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
    eHalStatus status = eHAL_STATUS_FAILURE;
    int ret = 0;
    hdd_config_t *pConfig = NULL;
    v_U32_t num_ignore_dfs_ch = 0;

    ENTER();

    if (NULL == pAdapter)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                  "%s: HDD adapter is Null", __func__);
        return -ENODEV;
    }

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    ret = wlan_hdd_validate_context(pHddCtx);

    if (0 != ret)
    {
        return -EINVAL;
    }

    pConfig = pHddCtx->cfg_ini;
    hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    if (NULL == hHal)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: HAL context  is Null!!!", __func__);
        return -EINVAL;
    }
    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
                     pAdapter->sessionId, pAdapter->device_mode));
    ret = wlan_hdd_scan_abort(pAdapter);
    if (ret < 0)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: aborting the existing scan is unsuccessfull", __func__);
        return -EBUSY;
    }

    if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                  FL("Cannot handle sched_scan"));
        return -EBUSY;
    }

    if (TRUE == pHddCtx->isPnoEnable)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                  FL("already PNO is enabled"));
       return -EBUSY;
    }

    if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: abort ROC failed ", __func__);
        return -EBUSY;
    }

    pHddCtx->isPnoEnable = TRUE;

    pnoRequest.enable = 1; /*Enable PNO */
    pnoRequest.ucNetworksCount = request->n_match_sets;

    if (( !pnoRequest.ucNetworksCount ) ||
        ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Network input is not correct %d Max Network supported is %d",
                   __func__, pnoRequest.ucNetworksCount,
                   SIR_PNO_MAX_SUPP_NETWORKS);
        ret = -EINVAL;
        goto error;
    }

    if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Incorrect number of channels %d",
                            __func__, request->n_channels);
        ret = -EINVAL;
        goto error;
    }

    /* Framework provides one set of channels(all)
     * common for all saved profile */
    if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
            channels_allowed, &num_channels_allowed))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "%s: failed to get valid channel list", __func__);
        ret = -EINVAL;
        goto error;
    }
    /* Checking each channel against allowed channel list */
    num_ch = 0;
    if (request->n_channels)
    {
        char chList [(request->n_channels*5)+1];
        int len;
        for (i = 0, len = 0; i < request->n_channels; i++)
        {
            for (indx = 0; indx < num_channels_allowed; indx++)
            {
                if (request->channels[i]->hw_value == channels_allowed[indx])
                {
                    if ((!pConfig->enableDFSPnoChnlScan) &&
                      (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
                    {
                        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                        "%s : Dropping DFS channel : %d",
                        __func__,channels_allowed[indx]);
                        num_ignore_dfs_ch++;
                        break;
                    }

                    valid_ch[num_ch++] = request->channels[i]->hw_value;
                    len += snprintf(chList+len, 5, "%d ",
                                         request->channels[i]->hw_value);
                    break ;
                 }
            }
        }
        hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List:  %s ", chList);

        /*If all channels are DFS and dropped, then ignore the PNO request*/
        if (num_ignore_dfs_ch == request->n_channels)
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
             "%s : All requested channels are DFS channels", __func__);
            ret = -EINVAL;
            goto error;
        }
     }

    pnoRequest.aNetworks =
             vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
    if (pnoRequest.aNetworks == NULL)
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
            FL("failed to allocate memory aNetworks %u"),
                (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
        goto error;
    }
    vos_mem_zero(pnoRequest.aNetworks,
                 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);

    /* Filling per profile  params */
    for (i = 0; i < pnoRequest.ucNetworksCount; i++)
    {
        pnoRequest.aNetworks[i].ssId.length =
               request->match_sets[i].ssid.ssid_len;

        if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
            ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: SSID Len %d is not correct for network %d",
                      __func__, pnoRequest.aNetworks[i].ssId.length, i);
            ret = -EINVAL;
            goto error;
        }

        memcpy(pnoRequest.aNetworks[i].ssId.ssId,
               request->match_sets[i].ssid.ssid,
               request->match_sets[i].ssid.ssid_len);
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  "%s: SSID of network %d is %s ",  __func__,
                   i, pnoRequest.aNetworks[i].ssId.ssId);
        pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
        pnoRequest.aNetworks[i].encryption     = 0; /*eED_ANY*/
        pnoRequest.aNetworks[i].bcastNetwType  = 0; /*eBCAST_UNKNOWN*/

        /*Copying list of valid channel into request */
        memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
        pnoRequest.aNetworks[i].ucChannelCount = num_ch;

        pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
    }

    for (i = 0; i < request->n_ssids; i++)
    {
        j = 0;
        while (j < pnoRequest.ucNetworksCount)
        {
            if ((pnoRequest.aNetworks[j].ssId.length ==
                 request->ssids[i].ssid_len) &&
                 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
                            request->ssids[i].ssid,
                            pnoRequest.aNetworks[j].ssId.length)))
            {
                pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
                break;
            }
            j++;
        }
    }
    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
              "Number of hidden networks being Configured = %d",
              request->n_ssids);
    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
              "request->ie_len = %zu", request->ie_len);

    pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
    if (pnoRequest.p24GProbeTemplate == NULL)
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
            FL("failed to allocate memory p24GProbeTemplate %u"),
                SIR_PNO_MAX_PB_REQ_SIZE);
        goto error;
    }

    pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
    if (pnoRequest.p5GProbeTemplate == NULL)
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
            FL("failed to allocate memory p5GProbeTemplate %u"),
                SIR_PNO_MAX_PB_REQ_SIZE);
        goto error;
    }

    vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
    vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);

    if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
        (NULL != request->ie))
    {
        pnoRequest.us24GProbeTemplateLen = request->ie_len;
        memcpy(pnoRequest.p24GProbeTemplate, request->ie,
                pnoRequest.us24GProbeTemplateLen);

        pnoRequest.us5GProbeTemplateLen = request->ie_len;
        memcpy(pnoRequest.p5GProbeTemplate, request->ie,
                pnoRequest.us5GProbeTemplateLen);
    }

    hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);

    pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;

    INIT_COMPLETION(pAdapter->pno_comp_var);
    pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
    pnoRequest.callbackContext = pAdapter;
    pAdapter->pno_req_status = 0;

    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
              "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
              pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
                                pnoRequest.scanTimers.ucScanTimersCount);

    status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
                              &pnoRequest, pAdapter->sessionId,
                              hdd_cfg80211_sched_scan_done_callback, pAdapter);
    if (eHAL_STATUS_SUCCESS != status)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Failed to enable PNO", __func__);
        ret = -EINVAL;
        goto error;
    }

    ret = wait_for_completion_timeout(
                 &pAdapter->pno_comp_var,
                  msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
    if (0 >= ret)
    {
        // Did not receive the response for PNO enable in time.
        // Assuming the PNO enable was success.
        // Returning error from here, because we timeout, results
        // in side effect of Wifi (Wifi Setting) not to work.
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  FL("Timed out waiting for PNO to be Enabled"));
        ret = 0;
    }

    ret = pAdapter->pno_req_status;
    return ret;

error:
    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
              FL("PNO scanRequest offloaded ret = %d"), ret);
    pHddCtx->isPnoEnable = FALSE;
    if (pnoRequest.aNetworks)
        vos_mem_free(pnoRequest.aNetworks);
    if (pnoRequest.p24GProbeTemplate)
        vos_mem_free(pnoRequest.p24GProbeTemplate);
    if (pnoRequest.p5GProbeTemplate)
        vos_mem_free(pnoRequest.p5GProbeTemplate);

    EXIT();
    return ret;
}

/*
 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
 * NL interface to enable PNO
 */
static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
          struct net_device *dev, struct cfg80211_sched_scan_request *request)
{
     int ret;

     vos_ssr_protect(__func__);
     ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
     vos_ssr_unprotect(__func__);

     return ret;
}

/*
 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
 * Function to disable PNO
 */
static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
          struct net_device *dev)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx;
    tHalHandle hHal;
    tSirPNOScanReq pnoRequest = {0};
    int ret = 0;

    ENTER();

    if (NULL == pAdapter)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                  "%s: HDD adapter is Null", __func__);
        return -ENODEV;
    }

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);

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

    /* The return 0 is intentional when isLogpInProgress and
     * isLoadUnloadInProgress. We did observe a crash due to a return of
     * failure in sched_scan_stop , especially for a case where the unload
     * of the happens at the same time. The function __cfg80211_stop_sched_scan
     * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
     * success. If it returns a failure , then its next invocation due to the
     * clean up of the second interface will have the dev pointer corresponding
     * to the first one leading to a crash.
     */
    if (pHddCtx->isLogpInProgress)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: LOGP in Progress. Ignore!!!", __func__);
        pHddCtx->isPnoEnable = FALSE;
        return ret;
    }

    if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
        return ret;
    }

    hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    if (NULL == hHal)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "%s: HAL context  is Null!!!", __func__);
        return -EINVAL;
    }

    pnoRequest.enable = 0; /* Disable PNO */
    pnoRequest.ucNetworksCount = 0;

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
                     pAdapter->sessionId, pAdapter->device_mode));

    INIT_COMPLETION(pAdapter->pno_comp_var);
    pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
    pnoRequest.callbackContext = pAdapter;
    pAdapter->pno_req_status = 0;
    status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
                                pAdapter->sessionId,
                                NULL, pAdapter);
    if (eHAL_STATUS_SUCCESS != status)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "Failed to disabled PNO");
        ret = -EINVAL;
        goto error;
    }
    ret = wait_for_completion_timeout(
                 &pAdapter->pno_comp_var,
                  msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
    if (0 >= ret)
    {
        // Did not receive the response for PNO disable in time.
        // Assuming the PNO disable was success.
        // Returning error from here, because we timeout, results
        // in side effect of Wifi (Wifi Setting) not to work.
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  FL("Timed out waiting for PNO to be disabled"));
        ret = 0;
    }

    ret = pAdapter->pno_req_status;
    pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;

error:
    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                   FL("PNO scan disabled ret = %d"), ret);

    EXIT();
    return ret;
}

/*
 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
 * NL interface to disable PNO
 */
static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
          struct net_device *dev)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
    vos_ssr_unprotect(__func__);

    return ret;
}
#endif /*FEATURE_WLAN_SCAN_PNO*/


#ifdef FEATURE_WLAN_TDLS
#if TDLS_MGMT_VERSION2
static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
                                         struct net_device *dev,
                                         u8 *peer, u8 action_code,
                                         u8 dialog_token,
                                         u16 status_code, u32 peer_capability,
                                         const u8 *buf, size_t len)
#else /* TDLS_MGMT_VERSION2 */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
	defined(WITH_BACKPORTS)
static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
                                         struct net_device *dev,
                                         const u8 *peer, u8 action_code,
                                         u8 dialog_token, u16 status_code,
                                         u32 peer_capability, bool initiator,
                                         const u8 *buf, size_t len)
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
                                         struct net_device *dev,
                                         const u8 *peer, u8 action_code,
                                         u8 dialog_token, u16 status_code,
                                         u32 peer_capability, const u8 *buf,
                                         size_t len)
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
                                         struct net_device *dev,
                                         u8 *peer, u8 action_code,
                                         u8 dialog_token,
                                         u16 status_code, u32 peer_capability,
                                         const u8 *buf, size_t len)
#else
static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
                                         struct net_device *dev,
                                         u8 *peer, u8 action_code,
                                         u8 dialog_token,
                                         u16 status_code, const u8 *buf,
                                         size_t len)
#endif
#endif
{
    hdd_adapter_t *pAdapter;
    hdd_context_t *pHddCtx;
    VOS_STATUS status;
    int max_sta_failed = 0;
    int responder;
    long rc;
    int ret;
    hddTdlsPeer_t *pTdlsPeer;
#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
    u32 peer_capability = 0;
#endif
    tANI_U16 numCurrTdlsPeers;
    hdd_station_ctx_t *pHddStaCtx = NULL;
    tdlsCtx_t *pHddTdlsCtx;

    pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    if (NULL == pAdapter)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Adapter is NULL",__func__);
        return -EINVAL;
    }
    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
                     pAdapter->sessionId, action_code));

    pHddCtx = wiphy_priv(wiphy);
    if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "Invalid arguments");
        return -EINVAL;
    }

    if (pHddCtx->isLogpInProgress)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "%s:LOGP in Progress. Ignore!!!", __func__);
        wlan_hdd_tdls_set_link_status(pAdapter,
                                      peer,
                                      eTDLS_LINK_IDLE,
                                      eTDLS_LINK_UNSPECIFIED);
        return -EBUSY;
    }

    if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
        return -EAGAIN;
    }

    pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
    if (!pHddTdlsCtx) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: pHddTdlsCtx not valid.", __func__);
        return -EINVAL;
    }

    if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
    {
         VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                    "%s: TDLS mode is disabled OR not enabled in FW."
                    MAC_ADDRESS_STR " action %d declined.",
                    __func__, MAC_ADDR_ARRAY(peer), action_code);
        return -ENOTSUPP;
    }

    pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

    if( NULL == pHddStaCtx )
    {
       VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
               "%s: HDD station context NULL ",__func__);
       return -EINVAL;
    }

    /* STA should be connected and authenticated
     * before sending any TDLS frames
     */
    if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
        (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "STA is not connected or unauthenticated. "
                "connState %u, uIsAuthenticated %u",
                pHddStaCtx->conn_info.connState,
                pHddStaCtx->conn_info.uIsAuthenticated);
        return -EAGAIN;
    }

    /* other than teardown frame, other mgmt frames are not sent if disabled */
    if (SIR_MAC_TDLS_TEARDOWN != action_code)
    {
       /* if tdls_mode is disabled to respond to peer's request */
        if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
        {
             VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                        "%s: " MAC_ADDRESS_STR
                        " TDLS mode is disabled. action %d declined.",
                        __func__, MAC_ADDR_ARRAY(peer), action_code);

             return -ENOTSUPP;
        }

        if (vos_max_concurrent_connections_reached())
        {
            hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
            return -EINVAL;
        }
    }

    if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
    {
        if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                       "%s: " MAC_ADDRESS_STR
                       " TDLS setup is ongoing. action %d declined.",
                       __func__, MAC_ADDR_ARRAY(peer), action_code);
            return -EPERM;
        }
    }

    if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
        SIR_MAC_TDLS_SETUP_RSP == action_code )
    {
        numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
        if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
        {
            /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
               we return error code at 'add_station()'. Hence we have this
               check again in addtion to add_station().
               Anyway, there is no hard to double-check. */
            if (SIR_MAC_TDLS_SETUP_REQ == action_code)
            {
                VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                           "%s: " MAC_ADDRESS_STR
                           " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
                           __func__, MAC_ADDR_ARRAY(peer), action_code,
                           numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
                return -EINVAL;
            }
            else
            {
                /* maximum reached. tweak to send error code to peer and return
                   error code to supplicant */
                status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
                VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                           "%s: " MAC_ADDRESS_STR
                           " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
                           __func__, MAC_ADDR_ARRAY(peer), status_code,
                           numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
                max_sta_failed = -EPERM;
                /* fall through to send setup resp with failure status
                code */
            }
        }
        else
        {
            mutex_lock(&pHddCtx->tdls_lock);
            pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
            if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
            {
                mutex_unlock(&pHddCtx->tdls_lock);
                VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                        "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
                        __func__, MAC_ADDR_ARRAY(peer), action_code);
                return -EPERM;
            }
            mutex_unlock(&pHddCtx->tdls_lock);
        }
    }

    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
               "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
               "tdls_mgmt", MAC_ADDR_ARRAY(peer),
               action_code, dialog_token, status_code, len);

    /*Except teardown responder will not be used so just make 0*/
    responder = 0;
    if (SIR_MAC_TDLS_TEARDOWN == action_code)
    {

       mutex_lock(&pHddCtx->tdls_lock);
       pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);

       if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
            responder = pTdlsPeer->is_responder;
       else
       {
           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                    "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %zu",
                    __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
                     dialog_token, status_code, len);
           mutex_unlock(&pHddCtx->tdls_lock);
           return -EPERM;
       }
       mutex_unlock(&pHddCtx->tdls_lock);
    }

    /* Discard TDLS setup if peer is removed by user app */
    if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
        ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
        (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
        (SIR_MAC_TDLS_DIS_REQ == action_code))) {

        mutex_lock(&pHddCtx->tdls_lock);
        pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
        if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
            mutex_unlock(&pHddCtx->tdls_lock);
            hddLog(LOGE, FL("TDLS External Control enabled, but peer "
                   MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
                   MAC_ADDR_ARRAY(peer), action_code);
            return -EINVAL;
        }
        mutex_unlock(&pHddCtx->tdls_lock);
    }

    /* For explicit trigger of DIS_REQ come out of BMPS for
       successfully receiving DIS_RSP from peer. */
    if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
        (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
        (SIR_MAC_TDLS_DIS_RSP == action_code) ||
        (SIR_MAC_TDLS_DIS_REQ == action_code))
    {
        if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                    "%s: Sending frame action_code %u.Disable BMPS", __func__,
                    action_code);
            status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
            if (status != VOS_STATUS_SUCCESS) {
                hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
            } else {
                pHddTdlsCtx->is_tdls_disabled_bmps = true;
            }
        }
        if (SIR_MAC_TDLS_DIS_REQ != action_code) {
            if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
                hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
            }
        }
    }

    /* make sure doesn't call send_mgmt() while it is pending */
    if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
            "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
            __func__, MAC_ADDR_ARRAY(peer), action_code);
        ret = -EBUSY;
        goto tx_failed;
    }

    pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
    INIT_COMPLETION(pAdapter->tdls_mgmt_comp);

    status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
            pAdapter->sessionId, peer, action_code, dialog_token,
            status_code, peer_capability, (tANI_U8 *)buf, len,
            responder);

    if (VOS_STATUS_SUCCESS != status)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "%s: sme_SendTdlsMgmtFrame failed!", __func__);
        pAdapter->mgmtTxCompletionStatus = FALSE;
        ret = -EINVAL;
        goto tx_failed;
    }

    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
            "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
            WAIT_TIME_TDLS_MGMT);

    rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
                                                        msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));

    if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
                  __func__, rc, pAdapter->mgmtTxCompletionStatus);
        pAdapter->mgmtTxCompletionStatus = FALSE;

        if (pHddCtx->isLogpInProgress)
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: LOGP in Progress. Ignore!!!", __func__);
            return -EAGAIN;
        }
        if (rc <= 0)
            vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
                 WLAN_LOG_INDICATOR_HOST_DRIVER,
                 WLAN_LOG_REASON_HDD_TIME_OUT,
                 TRUE, TRUE);

        ret = -EINVAL;
        goto tx_failed;
    }
    else
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                "%s: Mgmt Tx Completion status %ld TxCompletion %u",
                __func__, rc, pAdapter->mgmtTxCompletionStatus);
    }

    if (max_sta_failed)
    {
        ret = max_sta_failed;
        goto tx_failed;
    }

    if (SIR_MAC_TDLS_SETUP_RSP == action_code)
    {
        if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
            hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
        }
    }
    else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
    {
        if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
            hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
        }
    }

    return 0;

tx_failed:
    /* add_station will be called before sending TDLS_SETUP_REQ and
     * TDLS_SETUP_RSP and as part of add_station driver will enable
     * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
     * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
     * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
     * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
     */

    if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
            (SIR_MAC_TDLS_SETUP_RSP == action_code))
        wlan_hdd_tdls_check_bmps(pAdapter);
    return ret;
}

#if TDLS_MGMT_VERSION2
static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
                                       u8 *peer, u8 action_code,  u8 dialog_token,
                                       u16 status_code, u32 peer_capability,
                                       const u8 *buf, size_t len)
#else  /* TDLS_MGMT_VERSION2 */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
                                       struct net_device *dev,
                                       const u8 *peer, u8 action_code,
                                       u8 dialog_token, u16 status_code,
                                       u32 peer_capability, bool initiator,
                                       const u8 *buf, size_t len)
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
                                       struct net_device *dev,
                                       const u8 *peer, u8 action_code,
                                       u8 dialog_token, u16 status_code,
                                       u32 peer_capability, const u8 *buf,
                                       size_t len)
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
                                       struct net_device *dev,
                                       u8 *peer, u8 action_code,
                                       u8 dialog_token,
                                       u16 status_code, u32 peer_capability,
                                       const u8 *buf, size_t len)
#else
static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
                                       u8 *peer, u8 action_code,  u8 dialog_token,
                                       u16 status_code, const u8 *buf, size_t len)
#endif
#endif
{
    int ret;

    vos_ssr_protect(__func__);
#if TDLS_MGMT_VERSION2
    ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
                                        dialog_token, status_code,
                                        peer_capability, buf, len);
#else /* TDLS_MGMT_VERSION2 */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
	defined(WITH_BACKPORTS)
    ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
                                        dialog_token, status_code,
                                        peer_capability, initiator,
                                        buf, len);
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
    ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
                                        dialog_token, status_code,
                                        peer_capability, buf, len);
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
    ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
                                        dialog_token, status_code,
                                        peer_capability, buf, len);
#else
    ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
                                        dialog_token, status_code, buf, len);
#endif
#endif
    vos_ssr_unprotect(__func__);

    return ret;
}

int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
                                      const u8 *peer,
#else
                                      u8 *peer,
#endif
                                      tdls_req_params_t *tdls_peer_params,
                                      cfg80211_exttdls_callback callback)
{

    hddTdlsPeer_t *pTdlsPeer = NULL;
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
              " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
              __func__, MAC_ADDR_ARRAY(peer));

    if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
         (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {

        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
              " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
              __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
              pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
        return -ENOTSUPP;
    }

    /* To cater the requirement of establishing the TDLS link
     * irrespective of the data traffic , get an entry of TDLS peer.
     */
    mutex_lock(&pHddCtx->tdls_lock);
    pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
    if (pTdlsPeer == NULL) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: peer " MAC_ADDRESS_STR " not existing",
                  __func__, MAC_ADDR_ARRAY(peer));
        mutex_unlock(&pHddCtx->tdls_lock);
        return -EINVAL;
    }

    /* check FW TDLS Off Channel capability */
    if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
        (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
        (NULL != tdls_peer_params))
    {
        pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
        pTdlsPeer->peerParams.global_operating_class =
                         tdls_peer_params->global_operating_class;
        pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
        pTdlsPeer->peerParams.min_bandwidth_kbps =
                                          tdls_peer_params->min_bandwidth_kbps;
        /* check configured channel is valid, non dfs and
         * not current operating channel */
        if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                      tdls_peer_params->channel)) &&
            (pHddStaCtx) &&
            (tdls_peer_params->channel !=
                              pHddStaCtx->conn_info.operationChannel))
        {
            pTdlsPeer->isOffChannelConfigured = TRUE;
        }
        else
        {
            pTdlsPeer->isOffChannelConfigured = FALSE;
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: Configured Tdls Off Channel is not valid", __func__);

        }
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  "%s: tdls_off_channel %d isOffChannelConfigured %d "
                  "current operating channel %d",
                  __func__, pTdlsPeer->peerParams.channel,
                  pTdlsPeer->isOffChannelConfigured,
                  (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
    }
    else
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: TDLS off channel FW capability %d, "
                  "host capab %d or Invalid TDLS Peer Params", __func__,
                  sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
                  pHddCtx->cfg_ini->fEnableTDLSOffChannel);
    }

    if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {

        mutex_unlock(&pHddCtx->tdls_lock);

        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
              " %s TDLS Add Force Peer Failed",
              __func__);
        return -EINVAL;
    }
    /*EXT TDLS*/

    if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
        mutex_unlock(&pHddCtx->tdls_lock);
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
              " %s TDLS set callback Failed",
              __func__);
        return -EINVAL;
    }

    mutex_unlock(&pHddCtx->tdls_lock);

    return(0);

}

int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
                                        const u8 *peer
#else
                                        u8 *peer
#endif
)
{

    hddTdlsPeer_t *pTdlsPeer;
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);

    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
              " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
              __func__, MAC_ADDR_ARRAY(peer));

    if (0 != wlan_hdd_validate_context(pHddCtx)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
        return -EINVAL;
    }

    if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
         (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {

        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
              " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
              __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
              pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
        return -ENOTSUPP;
    }

    mutex_lock(&pHddCtx->tdls_lock);
    pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);

    if ( NULL == pTdlsPeer ) {
        mutex_unlock(&pHddCtx->tdls_lock);
        hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
               " peer not existing",
               __func__, MAC_ADDR_ARRAY(peer));
        return -EINVAL;
    }
    else {
        wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
                           eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
        hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
                                                 pTdlsPeer->peerMac);
        /* if channel switch is configured, reset
           the channel for this peer */
        if (TRUE == pTdlsPeer->isOffChannelConfigured)
        {
            pTdlsPeer->peerParams.channel = 0;
            pTdlsPeer->isOffChannelConfigured = FALSE;
        }
    }

    if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
        mutex_unlock(&pHddCtx->tdls_lock);
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
        return -EINVAL;
    }

    /*EXT TDLS*/

    if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
        mutex_unlock(&pHddCtx->tdls_lock);
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
              " %s TDLS set callback Failed",
              __func__);
        return -EINVAL;
    }

    mutex_unlock(&pHddCtx->tdls_lock);

    return(0);
}
static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
                                         const u8 *peer,
#else
                                         u8 *peer,
#endif
                                         enum nl80211_tdls_operation oper)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx = wiphy_priv(wiphy);
    int status;
    hddTdlsPeer_t *pTdlsPeer;

    ENTER();

    if (!pAdapter) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
        return -EINVAL;
    }

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_TDLS_OPER,
                     pAdapter->sessionId, oper));
    if ( NULL == peer )
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: Invalid arguments", __func__);
        return -EINVAL;
    }

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }


    if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
        FALSE == sme_IsFeatureSupportedByFW(TDLS))
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
                "Cannot process TDLS commands",
                pHddCtx->cfg_ini->fEnableTDLSSupport,
                sme_IsFeatureSupportedByFW(TDLS));
        return -ENOTSUPP;
    }

    switch (oper) {
        case NL80211_TDLS_ENABLE_LINK:
            {
                VOS_STATUS status;
                long ret;
                tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
                                                0, 0, 0, 0, 0, 0, {0}, 0, {0} };
                WLAN_STADescType         staDesc;
                tANI_U16 numCurrTdlsPeers = 0;
                hddTdlsPeer_t *connPeer = NULL;
                tANI_U8 suppChannelLen = 0;
                tSirMacAddr peerMac;
                int channel;
                tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;

                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                        " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
                                __func__, MAC_ADDR_ARRAY(peer));

                mutex_lock(&pHddCtx->tdls_lock);
                pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
                memset(&staDesc, 0, sizeof(staDesc));
                if ( NULL == pTdlsPeer ) {
                    mutex_unlock(&pHddCtx->tdls_lock);
                    hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
                           " (oper %d) not exsting. ignored",
                           __func__, MAC_ADDR_ARRAY(peer), (int)oper);
                    return -EINVAL;
                }

                VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                           "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
                           MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
                           "NL80211_TDLS_ENABLE_LINK");

                if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
                {
                    hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
                           MAC_ADDRESS_STR " failed",
                           __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
                    mutex_unlock(&pHddCtx->tdls_lock);
                    return -EINVAL;
                }

                /* before starting tdls connection, set tdls
                 * off channel established status to default value */
                pTdlsPeer->isOffChannelEstablished = FALSE;

                mutex_unlock(&pHddCtx->tdls_lock);

                wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
                /* TDLS Off Channel, Disable tdls channel switch,
                   when there are more than one tdls link */
                numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
                if (numCurrTdlsPeers == 2)
                {
                    mutex_lock(&pHddCtx->tdls_lock);
                    /* get connected peer and send disable tdls off chan */
                    connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
                    if ((connPeer) &&
                        (connPeer->isOffChannelSupported == TRUE) &&
                        (connPeer->isOffChannelConfigured == TRUE))
                    {
                        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                                  "%s: More then one peer connected, Disable "
                                  "TDLS channel switch", __func__);

                        connPeer->isOffChannelEstablished = FALSE;
                        vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
                        channel = connPeer->peerParams.channel;

                        mutex_unlock(&pHddCtx->tdls_lock);

                        ret = sme_SendTdlsChanSwitchReq(
                                           WLAN_HDD_GET_HAL_CTX(pAdapter),
                                           pAdapter->sessionId,
                                           peerMac,
                                           channel,
                                           TDLS_OFF_CHANNEL_BW_OFFSET,
                                           TDLS_CHANNEL_SWITCH_DISABLE);
                        if (ret != VOS_STATUS_SUCCESS) {
                             hddLog(VOS_TRACE_LEVEL_ERROR,
                                   FL("Failed to send TDLS switch channel request"));
                        }
                    }
                    else
                    {
                        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                                  "%s: No TDLS Connected Peer or "
                                  "isOffChannelSupported %d "
                                  "isOffChannelConfigured %d",
                                  __func__,
                                  (connPeer ? (connPeer->isOffChannelSupported)
                                    : -1),
                                  (connPeer ? (connPeer->isOffChannelConfigured)
                                    : -1));
                        mutex_unlock(&pHddCtx->tdls_lock);
                    }
                }

                mutex_lock(&pHddCtx->tdls_lock);
                pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
                if ( NULL == pTdlsPeer ) {
                    mutex_unlock(&pHddCtx->tdls_lock);
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                              "%s: " MAC_ADDRESS_STR
                              " (oper %d) peer got freed in other context. ignored",
                              __func__, MAC_ADDR_ARRAY(peer), (int)oper);
                    return -EINVAL;
                }
                peer_status = pTdlsPeer->link_status;
                mutex_unlock(&pHddCtx->tdls_lock);

                if (eTDLS_LINK_CONNECTED != peer_status)
                {
                    if (IS_ADVANCE_TDLS_ENABLE) {

                        if (0 != wlan_hdd_tdls_get_link_establish_params(
                                   pAdapter, peer,&tdlsLinkEstablishParams)) {
                            hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
                            return -EINVAL;
                        }
                        INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);

                        ret = sme_SendTdlsLinkEstablishParams(
                                         WLAN_HDD_GET_HAL_CTX(pAdapter),
                                         pAdapter->sessionId, peer,
                                         &tdlsLinkEstablishParams);
                        if (ret != VOS_STATUS_SUCCESS) {
                            hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
                        }
                        /* Send TDLS peer UAPSD capabilities to the firmware and
                         * register with the TL on after the response for this operation
                         * is received .
                         */
                        ret = wait_for_completion_interruptible_timeout(
                                &pAdapter->tdls_link_establish_req_comp,
                                msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));

                        mutex_lock(&pHddCtx->tdls_lock);
                        pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
                        if ( NULL == pTdlsPeer ) {
                            mutex_unlock(&pHddCtx->tdls_lock);
                            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                                      "%s %d: " MAC_ADDRESS_STR
                                      " (oper %d) peer got freed in other context. ignored",
                                      __func__, __LINE__, MAC_ADDR_ARRAY(peer),
                                      (int)oper);
                            return -EINVAL;
                        }
                        peer_status = pTdlsPeer->link_status;
                        mutex_unlock(&pHddCtx->tdls_lock);

                        if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
                        {
                            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                                      FL("Link Establish Request Failed Status %ld"),
                                           ret);
                            return -EINVAL;
                        }
                    }

                    mutex_lock(&pHddCtx->tdls_lock);
                    pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
                    if ( NULL == pTdlsPeer ) {
                        mutex_unlock(&pHddCtx->tdls_lock);
                        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                                  "%s: " MAC_ADDRESS_STR
                                  " (oper %d) peer got freed in other context. ignored",
                                  __func__, MAC_ADDR_ARRAY(peer), (int)oper);
                        return -EINVAL;
                    }

                    wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
                                                       eTDLS_LINK_CONNECTED,
                                                       eTDLS_LINK_SUCCESS);
                    staDesc.ucSTAId = pTdlsPeer->staId;
                    staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;

                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                              "%s: tdlsLinkEstablishParams of peer "
                              MAC_ADDRESS_STR "uapsdQueues: %d"
                              "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
                              "isResponder: %d  peerstaId: %d",
                              __func__,
                              MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
                              tdlsLinkEstablishParams.uapsdQueues,
                              tdlsLinkEstablishParams.qos,
                              tdlsLinkEstablishParams.maxSp,
                              tdlsLinkEstablishParams.isBufSta,
                              tdlsLinkEstablishParams.isOffChannelSupported,
                              tdlsLinkEstablishParams.isResponder,
                              pTdlsPeer->staId);

                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                              "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
                              __func__,
                              staDesc.ucSTAId,
                              staDesc.ucQosEnabled);

                    ret = WLANTL_UpdateTdlsSTAClient(
                                                pHddCtx->pvosContext,
                                                &staDesc);
                    if (ret != VOS_STATUS_SUCCESS) {
                        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
                    }

                    /* Mark TDLS client Authenticated .*/
                    status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
                                                    pTdlsPeer->staId,
                                                    WLANTL_STA_AUTHENTICATED);
                    if (VOS_STATUS_SUCCESS == status)
                    {
                        if (pTdlsPeer->is_responder == 0)
                        {
                            v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
                            tdlsConnInfo_t *tdlsInfo;

                            tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);

                            if (!vos_timer_is_initialized(
                                 &pTdlsPeer->initiatorWaitTimeoutTimer))
                            {
                                /* Initialize initiator wait callback */
                                vos_timer_init(
                                    &pTdlsPeer->initiatorWaitTimeoutTimer,
                                    VOS_TIMER_TYPE_SW,
                                    wlan_hdd_tdls_initiator_wait_cb,
                                    tdlsInfo);
                            }
                            wlan_hdd_tdls_timer_restart(pAdapter,
                                                        &pTdlsPeer->initiatorWaitTimeoutTimer,
                                                       WAIT_TIME_TDLS_INITIATOR);
                            /* suspend initiator TX until it receives direct packet from the
                            reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
                            ret = WLANTL_SuspendDataTx(
                                      (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
                                      &staId, NULL);
                            if (ret != VOS_STATUS_SUCCESS) {
                                 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
                            }
                        }

                        if  ((TRUE == pTdlsPeer->isOffChannelSupported) &&
                             (TRUE == pTdlsPeer->isOffChannelConfigured))
                        {
                             suppChannelLen =
                                 tdlsLinkEstablishParams.supportedChannelsLen;

                             if ((suppChannelLen > 0) &&
                                 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
                             {
                                 tANI_U8 suppPeerChannel = 0;
                                 int i = 0;
                                 for (i = 0U; i < suppChannelLen; i++)
                                 {
                                    suppPeerChannel =
                                   tdlsLinkEstablishParams.supportedChannels[i];

                                    pTdlsPeer->isOffChannelSupported = FALSE;
                                    if (suppPeerChannel ==
                                        pTdlsPeer->peerParams.channel)
                                    {
                                        pTdlsPeer->isOffChannelSupported = TRUE;
                                        break;
                                    }
                                 }
                             }
                             else
                             {
                                pTdlsPeer->isOffChannelSupported = FALSE;
                             }
                        }
                        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                                  "%s: TDLS channel switch request for channel "
                                  "%d isOffChannelConfigured %d suppChannelLen "
                                  "%d isOffChannelSupported %d", __func__,
                                  pTdlsPeer->peerParams.channel,
                                  pTdlsPeer->isOffChannelConfigured,
                                  suppChannelLen,
                                  pTdlsPeer->isOffChannelSupported);

                        /* TDLS Off Channel, Enable tdls channel switch,
                           when their is only one tdls link and it supports */
                        numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
                        if ((numCurrTdlsPeers == 1) &&
                            (TRUE == pTdlsPeer->isOffChannelSupported) &&
                            (TRUE == pTdlsPeer->isOffChannelConfigured))
                        {
                            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                                  "%s: Send TDLS channel switch request for channel %d",
                                  __func__, pTdlsPeer->peerParams.channel);

                            pTdlsPeer->isOffChannelEstablished = TRUE;
                            vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
                            channel = pTdlsPeer->peerParams.channel;

                            mutex_unlock(&pHddCtx->tdls_lock);

                            ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                                           pAdapter->sessionId,
                                                           peerMac,
                                                           channel,
                                                           TDLS_OFF_CHANNEL_BW_OFFSET,
                                                           TDLS_CHANNEL_SWITCH_ENABLE);
                            if (ret != VOS_STATUS_SUCCESS) {
                                 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
                            }
                        }
                        else
                        {
                            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                                      "%s: TDLS channel switch request not sent"
                                      " numCurrTdlsPeers %d "
                                      "isOffChannelSupported %d "
                                      "isOffChannelConfigured %d",
                                      __func__, numCurrTdlsPeers,
                                      pTdlsPeer->isOffChannelSupported,
                                      pTdlsPeer->isOffChannelConfigured);
                            mutex_unlock(&pHddCtx->tdls_lock);
                        }

                    }
                    else
                        mutex_unlock(&pHddCtx->tdls_lock);

                    wlan_hdd_tdls_check_bmps(pAdapter);

                    /* Update TL about the UAPSD masks , to route the packets to firmware */
                    if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
                        || pHddCtx->cfg_ini->fTDLSUapsdMask )
                    {
                        int ac;
                        uint8 ucAc[4] = { WLANTL_AC_VO,
                                          WLANTL_AC_VI,
                                          WLANTL_AC_BK,
                                          WLANTL_AC_BE };
                        uint8 tlTid[4] = { 7, 5, 2, 3 } ;
                        for(ac=0; ac < 4; ac++)
                        {
                            status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
                                                               pTdlsPeer->staId, ucAc[ac],
                                                               tlTid[ac], tlTid[ac], 0, 0,
                                                               WLANTL_BI_DIR );
                            if (status != VOS_STATUS_SUCCESS) {
                                hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
                            }
                        }
                    }
                }

                /* stop TCP delack timer if TDLS is enable  */
                set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
                hdd_manage_delack_timer(pHddCtx);
                hdd_wlan_tdls_enable_link_event(peer,
                           pTdlsPeer->isOffChannelSupported,
                           pTdlsPeer->isOffChannelConfigured,
                           pTdlsPeer->isOffChannelEstablished);
            }
            break;
        case NL80211_TDLS_DISABLE_LINK:
            {
                tANI_U16 numCurrTdlsPeers = 0;
                hddTdlsPeer_t *connPeer = NULL;

                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                        " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
                                __func__, MAC_ADDR_ARRAY(peer));

                mutex_lock(&pHddCtx->tdls_lock);
                pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);


                if ( NULL == pTdlsPeer ) {
                    mutex_unlock(&pHddCtx->tdls_lock);
                    hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
                           " (oper %d) not exsting. ignored",
                           __func__, MAC_ADDR_ARRAY(peer), (int)oper);
                    return -EINVAL;
                }

                VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                           "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
                           MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
                           "NL80211_TDLS_DISABLE_LINK");

                if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
                {
                    long status;

                    /* set tdls off channel status to false for this peer */
                    pTdlsPeer->isOffChannelEstablished = FALSE;
                    wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
                              eTDLS_LINK_TEARING,
                              (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
                              eTDLS_LINK_UNSPECIFIED:
                              eTDLS_LINK_DROPPED_BY_REMOTE);
                    mutex_unlock(&pHddCtx->tdls_lock);

                    INIT_COMPLETION(pAdapter->tdls_del_station_comp);

                    status = sme_DeleteTdlsPeerSta(
                                WLAN_HDD_GET_HAL_CTX(pAdapter),
                                pAdapter->sessionId, peer );
                    if (status != VOS_STATUS_SUCCESS) {
                        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
                    }

                    status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
                              msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));

                    mutex_lock(&pHddCtx->tdls_lock);
                    pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
                    if ( NULL == pTdlsPeer ) {
                        mutex_unlock(&pHddCtx->tdls_lock);
                        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
                                " peer was freed in other context",
                                __func__, MAC_ADDR_ARRAY(peer));
                        return -EINVAL;
                    }

                    wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
                                                       eTDLS_LINK_IDLE,
                                                       eTDLS_LINK_UNSPECIFIED);
                    mutex_unlock(&pHddCtx->tdls_lock);

                    if (status <= 0)
                    {
                        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                                  "%s: Del station failed status %ld",
                                  __func__, status);
                        return -EPERM;
                    }

                    /* TDLS Off Channel, Enable tdls channel switch,
                       when their is only one tdls link and it supports */
                    numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
                    if (numCurrTdlsPeers == 1)
                    {
                        tSirMacAddr peerMac;
                        int channel;

                        mutex_lock(&pHddCtx->tdls_lock);
                        connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);

                        if (connPeer == NULL) {
                            mutex_unlock(&pHddCtx->tdls_lock);
                            hddLog(VOS_TRACE_LEVEL_ERROR,
                                    "%s connPeer is NULL", __func__);
                            return -EINVAL;
                        }

                        vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
                        channel = connPeer->peerParams.channel;

                        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                                "%s: TDLS channel switch "
                                "isOffChannelSupported %d "
                                "isOffChannelConfigured %d "
                                "isOffChannelEstablished %d",
                                __func__,
                                (connPeer ? connPeer->isOffChannelSupported : -1),
                                (connPeer ? connPeer->isOffChannelConfigured : -1),
                                (connPeer ? connPeer->isOffChannelEstablished : -1));

                        if ((connPeer) &&
                            (connPeer->isOffChannelSupported == TRUE) &&
                            (connPeer->isOffChannelConfigured == TRUE))
                        {
                            connPeer->isOffChannelEstablished = TRUE;
                            mutex_unlock(&pHddCtx->tdls_lock);
                            status = sme_SendTdlsChanSwitchReq(
                                         WLAN_HDD_GET_HAL_CTX(pAdapter),
                                         pAdapter->sessionId,
                                         peerMac,
                                         channel,
                                         TDLS_OFF_CHANNEL_BW_OFFSET,
                                         TDLS_CHANNEL_SWITCH_ENABLE);
                            if (status != VOS_STATUS_SUCCESS) {
                                hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
                            }
                        }
                        else
                            mutex_unlock(&pHddCtx->tdls_lock);
                   }
                    else
                    {
                        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                                  "%s: TDLS channel switch request not sent "
                                  "numCurrTdlsPeers %d ",
                                  __func__, numCurrTdlsPeers);
                    }
                }
                else
                {
                    mutex_unlock(&pHddCtx->tdls_lock);
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                              "%s: TDLS Peer Station doesn't exist.", __func__);
                }
                if (numCurrTdlsPeers == 0) {
                   /* start TCP delack timer if TDLS is disable  */
                    clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
                    hdd_manage_delack_timer(pHddCtx);
                }
            }
            break;
        case NL80211_TDLS_TEARDOWN:
            {
                status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);

                if (0 != status)
                {
                    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                               FL("Error in TDLS Teardown"));
                    return status;
                }
                break;
            }
        case NL80211_TDLS_SETUP:
            {
                status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
                                                           peer,
                                                           NULL,
                                                           NULL);

                if (0 != status)
                {
                    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                               FL("Error in TDLS Setup"));
                    return status;
                }
                break;
            }
        case NL80211_TDLS_DISCOVERY_REQ:
            /* We don't support in-driver setup/teardown/discovery */
             VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                 "%s: Driver doesn't support in-driver setup/teardown/discovery "
                 ,__func__);
            return -ENOTSUPP;
        default:
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "%s: unsupported event",__func__);
            return -ENOTSUPP;
    }

    EXIT();
    return 0;
}

static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
                                       const u8 *peer,
#else
                                       u8 *peer,
#endif
                                       enum nl80211_tdls_operation oper)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
    vos_ssr_unprotect(__func__);

    return ret;
}

int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
                            struct net_device *dev, u8 *peer)
{
    hddLog(VOS_TRACE_LEVEL_INFO,
           "tdls send discover req: "MAC_ADDRESS_STR,
           MAC_ADDR_ARRAY(peer));
#if TDLS_MGMT_VERSION2
    return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
                            WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
#else
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
    return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
                            WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
    return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
                            WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
    return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
                            WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
#else
    return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
                            WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
#endif
#endif /* KERNEL_VERSION */
}
#endif

#ifdef WLAN_FEATURE_GTK_OFFLOAD
/*
 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
 * Callback rountine called upon receiving response for
 * get offload info
 */
void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
                            tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
{

    hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
    tANI_U8 tempReplayCounter[8];
    hdd_station_ctx_t *pHddStaCtx;

    ENTER();

    if (NULL == pAdapter)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: HDD adapter is Null", __func__);
        return ;
    }

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

    if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "%s: wlan Failed to get replay counter value",
                __func__);
        return ;
    }

    pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    /* Update replay counter */
    pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
                                   pGtkOffloadGetInfoRsp->ullKeyReplayCounter;

    {
        /* changing from little to big endian since supplicant
         * works on big endian format
         */
        int i;
        tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;

        for (i = 0; i < 8; i++)
        {
            tempReplayCounter[7-i] = (tANI_U8)p[i];
        }
    }

    /* Update replay counter to NL */
    cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
          tempReplayCounter, GFP_KERNEL);
}

/*
 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
 * This function is used to offload GTK rekeying job to the firmware.
 */
int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
                                     struct cfg80211_gtk_rekey_data *data)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx = wiphy_priv(wiphy);
    hdd_station_ctx_t *pHddStaCtx;
    tHalHandle hHal;
    int result;
    tSirGtkOffloadParams hddGtkOffloadReqParams;
    eHalStatus status = eHAL_STATUS_FAILURE;

    ENTER();

    if (NULL == pAdapter)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                   "%s: HDD adapter is Null", __func__);
        return -ENODEV;
    }

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
                     pAdapter->sessionId, pAdapter->device_mode));

    result = wlan_hdd_validate_context(pHddCtx);
    if (0 != result)
    {
        return result;
    }

    pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    if (NULL == hHal)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "%s: HAL context  is Null!!!", __func__);
        return -EAGAIN;
    }

    pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
    memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
    memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
    memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
          WNI_CFG_BSSID_LEN);
    {
        /* changing from big to little endian since driver
         * works on little endian format
         */
        tANI_U8 *p =
              (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
        int i;

        for (i = 0; i < 8; i++)
        {
            p[7-i] = data->replay_ctr[i];
        }
    }

    if (TRUE == pHddCtx->hdd_wlan_suspended)
    {
        /* if wlan is suspended, enable GTK offload directly from here */
        memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
              sizeof (tSirGtkOffloadParams));
        status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
                       pAdapter->sessionId);

        if (eHAL_STATUS_SUCCESS != status)
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                    "%s: sme_SetGTKOffload failed, returned %d",
                    __func__, status);

           /* Need to clear any trace of key value in the memory.
            * Thus zero out the memory even though it is local
            * variable.
            */
            vos_mem_zero(&hddGtkOffloadReqParams,
                          sizeof(hddGtkOffloadReqParams));
            return status;
        }
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                "%s: sme_SetGTKOffload successfull", __func__);
    }
    else
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                "%s: wlan not suspended GTKOffload request is stored",
                __func__);
    }

    /* Need to clear any trace of key value in the memory.
     * Thus zero out the memory even though it is local
     * variable.
     */
    vos_mem_zero(&hddGtkOffloadReqParams,
                  sizeof(hddGtkOffloadReqParams));

    EXIT();
    return eHAL_STATUS_SUCCESS;
}

int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
                                     struct cfg80211_gtk_rekey_data *data)
{
    int ret;

    vos_ssr_protect(__func__);
    ret =  __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
    vos_ssr_unprotect(__func__);

    return ret;
}
#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
/*
 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
 * This function is used to set access control policy
 */
static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
                                         struct net_device *dev,
                                         const struct cfg80211_acl_data *params)
{
    int i;
    hdd_adapter_t *pAdapter =  WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_hostapd_state_t *pHostapdState;
    tsap_Config_t *pConfig;
    v_CONTEXT_t pVosContext = NULL;
    hdd_context_t *pHddCtx;
    int status;

    ENTER();

    if (NULL == pAdapter)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                   "%s: HDD adapter is Null", __func__);
        return -ENODEV;
    }

    if (NULL == params)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                   "%s: params is Null", __func__);
        return -EINVAL;
    }

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    pVosContext = pHddCtx->pvosContext;
    pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);

    if (NULL == pHostapdState)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                   "%s: pHostapdState is Null", __func__);
        return -EINVAL;
    }

    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
             "no acl entries = %d", params->acl_policy, params->n_acl_entries);
    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
                     pAdapter->sessionId, pAdapter->device_mode));

    if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
    {
        pConfig = &pAdapter->sessionCtx.ap.sapConfig;

        /* default value */
        pConfig->num_accept_mac = 0;
        pConfig->num_deny_mac = 0;

        /**
         * access control policy
         * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
         *   listed in hostapd.deny file.
         * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
         *   listed in hostapd.accept file.
         */
        if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
        {
            pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
        }
        else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
        {
            pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
        }
        else
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                    "%s:Acl Policy : %d is not supported",
                                            __func__, params->acl_policy);
            return -ENOTSUPP;
        }

        if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
        {
            pConfig->num_accept_mac = params->n_acl_entries;
            for (i = 0; i < params->n_acl_entries; i++)
            {
                VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                    "** Add ACL MAC entry %i in WhiletList :"
                                MAC_ADDRESS_STR, i,
                                MAC_ADDR_ARRAY(params->mac_addrs[i].addr));

                vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
                                                             sizeof(qcmacaddr));
            }
        }
        else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
        {
            pConfig->num_deny_mac = params->n_acl_entries;
            for (i = 0; i < params->n_acl_entries; i++)
            {
                VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                    "** Add ACL MAC entry %i in BlackList :"
                                MAC_ADDRESS_STR, i,
                                MAC_ADDR_ARRAY(params->mac_addrs[i].addr));

                vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
                                                           sizeof(qcmacaddr));
            }
        }

        if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                       "%s: SAP Set Mac Acl fail", __func__);
            return -EINVAL;
        }
    }
    else
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: Invalid device_mode = %s (%d)",
                    __func__, hdd_device_modetoString(pAdapter->device_mode),
                                                      pAdapter->device_mode);
        return -EINVAL;
    }

    EXIT();
    return 0;
}

static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
                                         struct net_device *dev,
                                         const struct cfg80211_acl_data *params)
{
    int ret;
    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
    vos_ssr_unprotect(__func__);

    return ret;
}

#ifdef WLAN_NL80211_TESTMODE
#ifdef FEATURE_WLAN_LPHB
void wlan_hdd_cfg80211_lphb_ind_handler
(
   void *pAdapter,
   void *indCont
)
{
   tSirLPHBInd     *lphbInd;
   struct sk_buff  *skb;
   hdd_context_t  *pHddCtxt;

   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
             "LPHB indication arrived");

   if (pAdapter == NULL)
   {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 "%s: pAdapter is NULL\n",__func__);
       return;
   }

   if (NULL == indCont)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "LPHB IND, invalid argument");
      return;
   }

   pHddCtxt  = (hdd_context_t *)pAdapter;
   lphbInd = (tSirLPHBInd *)indCont;
   skb = cfg80211_testmode_alloc_event_skb(
                  pHddCtxt->wiphy,
                  sizeof(tSirLPHBInd),
                  GFP_ATOMIC);
   if (!skb)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
             "LPHB timeout, NL buffer alloc fail");
      return;
   }

   if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "WLAN_HDD_TM_ATTR_CMD put fail");
      goto nla_put_failure;
   }
   if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "WLAN_HDD_TM_ATTR_TYPE put fail");
      goto nla_put_failure;
   }
   if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
           sizeof(tSirLPHBInd), lphbInd))
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "WLAN_HDD_TM_ATTR_DATA put fail");
      goto nla_put_failure;
   }
   cfg80211_testmode_event(skb, GFP_ATOMIC);
   return;

nla_put_failure:
   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
             "NLA Put fail");
   kfree_skb(skb);

   return;
}
#endif /* FEATURE_WLAN_LPHB */

static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
{
    struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
    int err = 0;
#ifdef FEATURE_WLAN_LPHB
    hdd_context_t *pHddCtx = wiphy_priv(wiphy);
    eHalStatus smeStatus;

    ENTER();

    err = wlan_hdd_validate_context(pHddCtx);
    if (0 != err)
    {
        return err;
    }
#endif /* FEATURE_WLAN_LPHB */

    err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
    if (err)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s Testmode INV ATTR", __func__);
        return err;
    }

    if (!tb[WLAN_HDD_TM_ATTR_CMD])
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s Testmode INV CMD", __func__);
        return -EINVAL;
    }

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_TESTMODE,
                     NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
    switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
    {
#ifdef FEATURE_WLAN_LPHB
        /* Low Power Heartbeat configuration request */
        case WLAN_HDD_TM_CMD_WLAN_HB:
        {
            int   buf_len;
            void *buf;
            tSirLPHBReq *hb_params = NULL;
            tSirLPHBReq *hb_params_temp = NULL;

            if (!tb[WLAN_HDD_TM_ATTR_DATA])
            {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                          "%s Testmode INV DATA", __func__);
                return -EINVAL;
            }

            buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
            buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);

            if (buf_len > sizeof(*hb_params)) {
                hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
                       buf_len);
                return -ERANGE;
            }

            hb_params_temp =(tSirLPHBReq *)buf;
            if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
                (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
                return -EINVAL;

            hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
            if (NULL == hb_params)
            {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                          "%s Request Buffer Alloc Fail", __func__);
                return -EINVAL;
            }

            vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
            vos_mem_copy(hb_params, buf, buf_len);
            smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
                               hb_params,
                               wlan_hdd_cfg80211_lphb_ind_handler);
            if (eHAL_STATUS_SUCCESS != smeStatus)
            {
               VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                         "LPHB Config Fail, disable");
               vos_mem_free(hb_params);
            }
            return 0;
         }
#endif /* FEATURE_WLAN_LPHB */
        default:
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: unsupported event",__func__);
            return -EOPNOTSUPP;
    }

    EXIT();
    return err;
}

static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
                                      struct wireless_dev *wdev,
#endif
                                      void *data, int len)
{
   int ret;

   vos_ssr_protect(__func__);
   ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
   vos_ssr_unprotect(__func__);

   return ret;
}
#endif /* CONFIG_NL80211_TESTMODE */

extern void hdd_set_wlan_suspend_mode(bool suspend);
static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
                                         struct net_device *dev,
                                         int idx, struct survey_info *survey)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx;
    hdd_station_ctx_t *pHddStaCtx;
    tHalHandle halHandle;
    v_U32_t channel = 0, freq = 0; /* Initialization Required */
    v_S7_t snr,rssi;
    int status, i, j, filled = 0;

    ENTER();

    if (NULL == pAdapter)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                   "%s: HDD adapter is Null", __func__);
        return -ENODEV;
    }

    if (NULL == wiphy)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                   "%s: wiphy is Null", __func__);
        return -ENODEV;
    }

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
    {
        return status;
    }

    pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

    if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
        0 != pAdapter->survey_idx ||
        eConnectionState_Associated != pHddStaCtx->conn_info.connState)
    {
        /* The survey dump ops when implemented completely is expected to
         * return a survey of all channels and the ops is called by the
         * kernel with incremental values of the argument 'idx' till it
         * returns -ENONET. But we can only support the survey for the
         * operating channel for now. survey_idx is used to track
         * that the ops is called only once and then return -ENONET for
         * the next iteration
         */
        pAdapter->survey_idx = 0;
        return -ENONET;
    }

    if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                 "%s: Roaming in progress, hence return ", __func__);
        return -ENONET;
    }

    halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);

    wlan_hdd_get_snr(pAdapter, &snr);
    wlan_hdd_get_rssi(pAdapter, &rssi);

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
                     pAdapter->sessionId, pAdapter->device_mode));
    sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
    hdd_wlan_get_freq(channel, &freq);


    for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
    {
        if (NULL == wiphy->bands[i])
        {
           VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
                     "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
           continue;
        }

        for (j = 0; j < wiphy->bands[i]->n_channels; j++)
        {
            struct ieee80211_supported_band *band = wiphy->bands[i];

            if (band->channels[j].center_freq == (v_U16_t)freq)
            {
                survey->channel = &band->channels[j];
                /* The Rx BDs contain SNR values in dB for the received frames
                 * while the supplicant expects noise. So we calculate and
                 * return the value of noise (dBm)
                 *  SNR (dB) = RSSI (dBm) - NOISE (dBm)
                 */
                survey->noise = rssi - snr;
                survey->filled = SURVEY_INFO_NOISE_DBM;
                filled = 1;
            }
        }
     }

     if (filled)
        pAdapter->survey_idx = 1;
     else
     {
        pAdapter->survey_idx = 0;
        return -ENONET;
     }

     EXIT();
     return 0;
}

static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
                                         struct net_device *dev,
                                         int idx, struct survey_info *survey)
{
     int ret;

     vos_ssr_protect(__func__);
     ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
     vos_ssr_unprotect(__func__);

     return ret;
}

/*
 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
 * this is called when cfg80211 driver resume
 * driver updates  latest sched_scan scan result(if any) to cfg80211 database
 */
int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
{
    hdd_context_t *pHddCtx = wiphy_priv(wiphy);
    hdd_adapter_t *pAdapter;
    hdd_adapter_list_node_t *pAdapterNode, *pNext;
    VOS_STATUS status = VOS_STATUS_SUCCESS;

    ENTER();

    if (0 != wlan_hdd_validate_context(pHddCtx))
    {
        return 0;
    }

    MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
                     NO_SESSION, pHddCtx->isWiphySuspended));

    if (pHddCtx->is_ap_mode_wow_supported)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  "%s: Resume SoftAP", __func__);
           hdd_set_wlan_suspend_mode(false);
    }

    spin_lock(&pHddCtx->schedScan_lock);
    pHddCtx->isWiphySuspended = FALSE;
    if (TRUE != pHddCtx->isSchedScanUpdatePending)
    {
        spin_unlock(&pHddCtx->schedScan_lock);
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
              "%s: Return resume is not due to PNO indication", __func__);
        return 0;
    }
    // Reset flag to avoid updatating cfg80211 data old results again
    pHddCtx->isSchedScanUpdatePending = FALSE;
    spin_unlock(&pHddCtx->schedScan_lock);

    status =  hdd_get_front_adapter ( pHddCtx, &pAdapterNode );

    while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
    {
        pAdapter = pAdapterNode->pAdapter;
        if ( (NULL != pAdapter) &&
             (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
        {
            if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
            {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                      "%s: NO SCAN result", __func__);
            }
            else
            {
                /* Acquire wakelock to handle the case where APP's tries to
                 * suspend immediately after updating the scan results. Whis
                 * results in app's is in suspended state and not able to
                 * process the connect request to AP
                 */
                hdd_prevent_suspend_timeout(2000,
                                    WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
                cfg80211_sched_scan_results(pHddCtx->wiphy);
            }

            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                    "%s : cfg80211 scan result database updated", __func__);

            EXIT();
            return 0;

        }
        status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
        pAdapterNode = pNext;
    }

    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
          "%s: Failed to find Adapter", __func__);
    EXIT();
    return 0;
}

int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
    vos_ssr_unprotect(__func__);

    return ret;
}

/*
 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
 * this is called when cfg80211 driver suspends
 */
int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
                                   struct cfg80211_wowlan *wow)
{
    hdd_context_t *pHddCtx = wiphy_priv(wiphy);
    int ret = 0;

    ENTER();

    ret = wlan_hdd_validate_context(pHddCtx);
    if (0 != ret)
    {
        return ret;
    }

    if (pHddCtx->is_ap_mode_wow_supported) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  "%s: Suspend SoftAP", __func__);
         hdd_set_wlan_suspend_mode(true);
    }


    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
                     NO_SESSION, pHddCtx->isWiphySuspended));
    pHddCtx->isWiphySuspended = TRUE;

    EXIT();

    return 0;
}

int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
                                   struct cfg80211_wowlan *wow)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
    vos_ssr_unprotect(__func__);

    return ret;
}

#ifdef FEATURE_OEM_DATA_SUPPORT
static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
                                   void *pMsg, tANI_U32 evLen)
{
    hdd_context_t *pHddCtx         = (hdd_context_t *)ctx;

    ENTER();

    if (wlan_hdd_validate_context(pHddCtx)) {
        return;
    }
    if (!pMsg)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
        return;
    }

    send_oem_data_rsp_msg(evLen, pMsg);

    EXIT();
    return;

}

void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
                                      void *pMsg,  tANI_U32 evLen)
{
    hdd_context_t *pHddCtx = (hdd_context_t *)ctx;

    ENTER();

    if (wlan_hdd_validate_context(pHddCtx)) {
        return;
    }

    hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);

    switch(evType) {
    case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
        wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
        break;
    default:
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
        break;
    }
    EXIT();
}
#endif

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
    defined(CFG80211_ABORT_SCAN)
/**
 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
 * @wiphy: Pointer to wiphy
 * @wdev: Pointer to wireless device structure
 *
 * This function is used to abort an ongoing scan
 *
 * Return: None
 */
static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
                                           struct wireless_dev *wdev)
{
    struct net_device *dev = wdev->netdev;
    hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
    int ret;

    ENTER();

    if (NULL == adapter) {
        hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
        return;
    }

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

    wlan_hdd_scan_abort(adapter);

    return;
}

/**
 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
 * @wiphy: Pointer to wiphy
 * @wdev: Pointer to wireless device structure
 *
 * Return: None
 */
void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
                                  struct wireless_dev *wdev)
{
    vos_ssr_protect(__func__);
    __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
    vos_ssr_unprotect(__func__);

    return;
}
#endif

#ifdef CHANNEL_SWITCH_SUPPORTED
/**
 * __wlan_hdd_cfg80211_channel_switch()- function to switch
 * channel in SAP/GO
 * @wiphy:  wiphy pointer
 * @dev: dev pointer.
 * @csa_params: Change channel params
 *
 * This function is called to switch channel in SAP/GO
 *
 * Return: 0 if success else return non zero
 */
static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
   struct net_device *dev, struct cfg80211_csa_settings *csa_params)
{
   hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
   hdd_context_t *hdd_ctx;
   uint8_t channel;
   int ret;
   ptSapContext sap_ctx;
   v_CONTEXT_t vos_ctx;

   hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);

   hdd_ctx = WLAN_HDD_GET_CTX(adapter);
   ret = wlan_hdd_validate_context(hdd_ctx);
   if (ret)
       return ret;

   vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
   if (!vos_ctx) {
       hddLog(LOGE, FL("Vos ctx is null"));
       return -EINVAL;
   }

   if (WLAN_HDD_SOFTAP != adapter->device_mode)
        return -ENOTSUPP;

   sap_ctx = VOS_GET_SAP_CB(vos_ctx);
   if (!sap_ctx) {
       hddLog(LOGE, FL("sap_ctx is NULL"));
       return -EINVAL;
   }

   ret = wlansap_chk_n_set_chan_change_in_progress(sap_ctx);
   if (ret)
       return ret;

   INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);

   channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
   ret = wlansap_set_channel_change(vos_ctx, channel, false);

   if (ret) {
       wlansap_reset_chan_change_in_progress(sap_ctx);
       complete(&sap_ctx->ecsa_info.chan_switch_comp);
   }

   return ret;
}

/**
 * wlan_hdd_cfg80211_channel_switch()- function to switch
 * channel in SAP/GO
 * @wiphy:  wiphy pointer
 * @dev: dev pointer.
 * @csa_params: Change channel params
 *
 * This function is called to switch channel in SAP/GO
 *
 * Return: 0 if success else return non zero
 */
static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
   struct net_device *dev, struct cfg80211_csa_settings *csa_params)
{
   int ret;

   vos_ssr_protect(__func__);
   ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
   vos_ssr_unprotect(__func__);

   return ret;
}
#endif

/* cfg80211_ops */
static struct cfg80211_ops wlan_hdd_cfg80211_ops =
{
    .add_virtual_intf = wlan_hdd_add_virtual_intf,
    .del_virtual_intf = wlan_hdd_del_virtual_intf,
    .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
    .change_station = wlan_hdd_change_station,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
    .add_beacon = wlan_hdd_cfg80211_add_beacon,
    .del_beacon = wlan_hdd_cfg80211_del_beacon,
    .set_beacon = wlan_hdd_cfg80211_set_beacon,
#else
    .start_ap = wlan_hdd_cfg80211_start_ap,
    .change_beacon = wlan_hdd_cfg80211_change_beacon,
    .stop_ap = wlan_hdd_cfg80211_stop_ap,
#endif
    .change_bss = wlan_hdd_cfg80211_change_bss,
    .add_key = wlan_hdd_cfg80211_add_key,
    .get_key = wlan_hdd_cfg80211_get_key,
    .del_key = wlan_hdd_cfg80211_del_key,
    .set_default_key = wlan_hdd_cfg80211_set_default_key,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
    .set_channel = wlan_hdd_cfg80211_set_channel,
#endif
    .scan = wlan_hdd_cfg80211_scan,
    .connect = wlan_hdd_cfg80211_connect,
    .disconnect = wlan_hdd_cfg80211_disconnect,
    .join_ibss  = wlan_hdd_cfg80211_join_ibss,
    .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
    .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
    .set_tx_power = wlan_hdd_cfg80211_set_txpower,
    .get_tx_power = wlan_hdd_cfg80211_get_txpower,
    .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
    .cancel_remain_on_channel =  wlan_hdd_cfg80211_cancel_remain_on_channel,
    .mgmt_tx =  wlan_hdd_mgmt_tx,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
     .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
     .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
     .set_txq_params = wlan_hdd_set_txq_params,
#endif
     .get_station = wlan_hdd_cfg80211_get_station,
     .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
     .del_station  = wlan_hdd_cfg80211_del_station,
     .add_station  = wlan_hdd_cfg80211_add_station,
#ifdef FEATURE_WLAN_LFR
     .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
     .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
     .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
#endif
#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
     .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
#endif
#ifdef FEATURE_WLAN_TDLS
     .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
     .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
#endif
#ifdef WLAN_FEATURE_GTK_OFFLOAD
     .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
#endif /* WLAN_FEATURE_GTK_OFFLOAD */
#ifdef FEATURE_WLAN_SCAN_PNO
     .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
     .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
#endif /*FEATURE_WLAN_SCAN_PNO */
     .resume = wlan_hdd_cfg80211_resume_wlan,
     .suspend = wlan_hdd_cfg80211_suspend_wlan,
     .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
#ifdef WLAN_NL80211_TESTMODE
     .testmode_cmd = wlan_hdd_cfg80211_testmode,
#endif
     .dump_survey = wlan_hdd_cfg80211_dump_survey,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
    defined(CFG80211_ABORT_SCAN)
     .abort_scan = wlan_hdd_cfg80211_abort_scan,
#endif
#ifdef CHANNEL_SWITCH_SUPPORTED
	.channel_switch = wlan_hdd_cfg80211_channel_switch,
#endif

};

