/*
 * 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/etherdevice.h>
#include <linux/wireless.h>
#include <wlan_hdd_includes.h>
#include <net/arp.h>
#include <net/cfg80211.h>
#include <vos_trace.h>
#include "vos_cnss.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 "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"
#include "vos_utils.h"
#include "vos_sched.h"
#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 "hif.h"
#include "wma.h"
#include "wlan_hdd_misc.h"
#ifdef WLAN_FEATURE_NAN
#include "nan_Api.h"
#include "wlan_hdd_nan.h"
#endif
#ifdef IPA_OFFLOAD
#include <wlan_hdd_ipa.h>
#endif
#include "wlan_hdd_mdns_offload.h"
#include "wlan_hdd_ocb.h"
#include "qwlan_version.h"

#include "wlan_logging_sock_svc.h"
#include "sapApi.h"
#include "csrApi.h"

#include "wmi_unified_priv.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 10
#define MAX_PENDING_LOG 5
#define MAX_HT_MCS_IDX 8
#define MAX_VHT_MCS_IDX 10
#define INVALID_MCS_IDX 255
#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
        ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
/*
 * Android CTS verifier needs atleast this much wait time (in msec)
 */
#define MAX_REMAIN_ON_CHANNEL_DURATION    (5000)
#define HDD_WAKE_LOCK_SCAN_DURATION       (5 * 1000) /* in msec */

#define WLAN_HDD_TGT_NOISE_FLOOR_DBM      (-96)

/*
 * max_sched_scan_plans defined to 2 for
 * (1)fast scan
 * (2)slow scan
 */
#define MAX_SCHED_SCAN_PLANS 2

/* For IBSS, enable obss, fromllb, overlapOBSS & overlapFromllb protection
   check. The bit map is defined in:

    typedef struct sCfgProtection
    {
        tANI_U32 overlapFromlla:1;
        tANI_U32 overlapFromllb:1;
        tANI_U32 overlapFromllg:1;
        tANI_U32 overlapHt20:1;
        tANI_U32 overlapNonGf:1;
        tANI_U32 overlapLsigTxop:1;
        tANI_U32 overlapRifs:1;
        tANI_U32 overlapOBSS:1;
        tANI_U32 fromlla:1;
        tANI_U32 fromllb:1;
        tANI_U32 fromllg:1;
        tANI_U32 ht20:1;
        tANI_U32 nonGf:1;
        tANI_U32 lsigTxop:1;
        tANI_U32 rifs:1;
        tANI_U32 obss:1;
    }tCfgProtection, *tpCfgProtection;

*/
#define IBSS_CFG_PROTECTION_ENABLE_MASK 0x8282

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

#define HDD5GHZCHAN(freq, chan, flag)   {     \
    .band =  IEEE80211_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 MAX_TXPOWER_SCALE 4

#define HDD_CHANNEL_14 14
#define WLAN_HDD_MAX_FEATURE_SET   8

#define IS_DFS_MODE_VALID(mode) ((mode >= DFS_MODE_NONE && mode <= DFS_MODE_DEPRIORITIZE))

#ifdef FEATURE_WLAN_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
#endif

#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

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

/* (30 Mins) */
#define MIN_TIME_REQUIRED_FOR_NEXT_BUG_REPORT (30 * 60 * 1000)

/*
 * Count to ratelimit the HDD logs during Scan and connect
 */
#define HDD_SCAN_REJECT_RATE_LIMIT 5

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_BTK 0x004096fe /* use for BTK */
#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
    WLAN_CIPHER_SUITE_BTK,
    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(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) ,
#ifndef FEATURE_STATICALLY_ADD_11P_CHANNELS
    HDD5GHZCHAN(5852,170, 0) ,
    HDD5GHZCHAN(5855,171, 0) ,
    HDD5GHZCHAN(5860,172, 0) ,
    HDD5GHZCHAN(5865,173, 0) ,
    HDD5GHZCHAN(5870,174, 0) ,
    HDD5GHZCHAN(5875,175, 0) ,
    HDD5GHZCHAN(5880,176, 0) ,
    HDD5GHZCHAN(5885,177, 0) ,
    HDD5GHZCHAN(5890,178, 0) ,
    HDD5GHZCHAN(5895,179, 0) ,
    HDD5GHZCHAN(5900,180, 0) ,
    HDD5GHZCHAN(5905,181, 0) ,
    HDD5GHZCHAN(5910,182, 0) ,
    HDD5GHZCHAN(5915,183, 0) ,
    HDD5GHZCHAN(5920,184, 0) ,
#endif
};

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       = IEEE80211_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
                            | 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,
    .vht_cap.cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454
                            | IEEE80211_VHT_CAP_SHORT_GI_80
                            | IEEE80211_VHT_CAP_TXSTBC
#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,4,0)) || defined(WITH_BACKPORTS)
                            | (IEEE80211_VHT_CAP_RXSTBC_MASK &
                              ( IEEE80211_VHT_CAP_RXSTBC_1
                              | IEEE80211_VHT_CAP_RXSTBC_2))
#endif
                            | IEEE80211_VHT_CAP_RXLDPC,
};

static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
{
    .channels = NULL,
    .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
    .band     = IEEE80211_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,
    .vht_cap.vht_supported = 1,
    .vht_cap.cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454
                 | IEEE80211_VHT_CAP_SHORT_GI_80
                 | IEEE80211_VHT_CAP_TXSTBC
#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,4,0))
                 | (IEEE80211_VHT_CAP_RXSTBC_MASK &
                   ( IEEE80211_VHT_CAP_RXSTBC_1
                   | IEEE80211_VHT_CAP_RXSTBC_2))
#endif
                 | IEEE80211_VHT_CAP_RXLDPC
};

/* 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_TIME_ADVERT) |
            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)) || defined(WITH_BACKPORTS)
/* Interface limits and combinations registered by the driver */

/* STA ( + STA ) combination */
static const struct ieee80211_iface_limit
wlan_hdd_sta_iface_limit[] = {
   {
      .max = 3, /* p2p0 is a STA as well */
      .types = BIT(NL80211_IFTYPE_STATION),
   },
};

/* ADHOC (IBSS) limit */
static const struct ieee80211_iface_limit
wlan_hdd_adhoc_iface_limit[] = {
   {
      .max = 1,
      .types = BIT(NL80211_IFTYPE_STATION),
   },
   {
      .max = 1,
      .types = BIT(NL80211_IFTYPE_ADHOC),
   },
};

/*
 * AP ( + AP) combination or
 * AP ( + AP + AP + AP) combination if 4-SAP is supported
 *  (WLAN_4SAP_CONCURRENCY)
 */
static const struct ieee80211_iface_limit
wlan_hdd_ap_iface_limit[] = {
   {
      .max = (VOS_MAX_NO_OF_SAP_MODE +
              SAP_MAX_OBSS_STA_CNT),
      .types = BIT(NL80211_IFTYPE_AP),
   },
};

/* P2P limit */
static const struct ieee80211_iface_limit
wlan_hdd_p2p_iface_limit[] = {
   {
      .max = 1,
      .types = BIT(NL80211_IFTYPE_P2P_CLIENT),
   },
   {
      .max = 1,
      .types = BIT(NL80211_IFTYPE_P2P_GO),
   },
};

static const struct ieee80211_iface_limit
wlan_hdd_sta_ap_iface_limit[] = {
    {
        /* We need 1 extra STA interface for OBSS scan when SAP starts
         * with HT40 in STA+SAP concurrency mode
         */
        .max = (1 + SAP_MAX_OBSS_STA_CNT),
        .types = BIT(NL80211_IFTYPE_STATION),
    },
    {
        .max = VOS_MAX_NO_OF_SAP_MODE,
        .types = BIT(NL80211_IFTYPE_AP),
    },
};

/* STA + P2P combination */
static const struct ieee80211_iface_limit
wlan_hdd_sta_p2p_iface_limit[] = {
   {
      /* One reserved for dedicated P2PDEV usage */
      .max = 2,
      .types = BIT(NL80211_IFTYPE_STATION)
   },
   {
      /* Support for two identical (GO + GO or CLI + CLI)
       * or dissimilar (GO + CLI) P2P interfaces
       */
      .max = 2,
      .types = BIT(NL80211_IFTYPE_P2P_GO) |
               BIT(NL80211_IFTYPE_P2P_CLIENT),
   },
};

/* STA + AP + P2PGO combination */
static const struct ieee80211_iface_limit
wlan_hdd_sta_ap_p2pgo_iface_limit[] = {
   /* Support for AP+P2PGO interfaces */
   {
      .max = 2,
      .types = BIT(NL80211_IFTYPE_STATION)
   },
   {
      .max = 1,
      .types = BIT(NL80211_IFTYPE_P2P_GO)
   },
   {
      .max = 1,
      .types = BIT(NL80211_IFTYPE_AP)
   }
};

static const struct ieee80211_iface_limit
   wlan_hdd_mon_iface_limit[] = {
   {
       .max = 3, /* Monitor interface */
       .types = BIT(NL80211_IFTYPE_MONITOR),
   },
};

static struct ieee80211_iface_combination
wlan_hdd_iface_combination[] = {
   /* STA */
   {
      .limits = wlan_hdd_sta_iface_limit,
      .num_different_channels = 2,
      .max_interfaces = 3,
      .n_limits = ARRAY_SIZE(wlan_hdd_sta_iface_limit),
   },
   /* ADHOC */
   {
      .limits = wlan_hdd_adhoc_iface_limit,
      .num_different_channels = 1,
      .max_interfaces = 2,
      .n_limits = ARRAY_SIZE(wlan_hdd_adhoc_iface_limit),
   },
   /* AP */
   {
      .limits = wlan_hdd_ap_iface_limit,
      .num_different_channels = 2,
      .max_interfaces = (SAP_MAX_OBSS_STA_CNT +
                         VOS_MAX_NO_OF_SAP_MODE),
      .n_limits = ARRAY_SIZE(wlan_hdd_ap_iface_limit),
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)) || defined(BEACON_INTV_BACKPORTS)
      .beacon_int_min_gcd = 1,
#endif
   },
   /* P2P */
   {
      .limits = wlan_hdd_p2p_iface_limit,
      .num_different_channels = 2,
      .max_interfaces = 2,
      .n_limits = ARRAY_SIZE(wlan_hdd_p2p_iface_limit),
   },
   /* STA + AP */
   {
      .limits = wlan_hdd_sta_ap_iface_limit,
      .num_different_channels = 2,
      .max_interfaces = (1 + SAP_MAX_OBSS_STA_CNT +
                         VOS_MAX_NO_OF_SAP_MODE),
      .n_limits = ARRAY_SIZE(wlan_hdd_sta_ap_iface_limit),
      .beacon_int_infra_match = true,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)) || defined(BEACON_INTV_BACKPORTS)
      .beacon_int_min_gcd = 1,
#endif
   },
   /* STA + P2P */
   {
      .limits = wlan_hdd_sta_p2p_iface_limit,
      .num_different_channels = 2,
      /* one interface reserved for P2PDEV dedicated usage */
      .max_interfaces = 4,
      .n_limits = ARRAY_SIZE(wlan_hdd_sta_p2p_iface_limit),
      .beacon_int_infra_match = true,
   },
   /* STA + P2P GO + SAP */
   {
      .limits = wlan_hdd_sta_ap_p2pgo_iface_limit,
      /* we can allow 3 channels for three different persona
       * but due to firmware limitation, allow max 2 concurrent channels.
       */
      .num_different_channels = 2,
      /* one interface reserved for P2PDEV dedicated usage */
      .max_interfaces = 4,
      .n_limits = ARRAY_SIZE(wlan_hdd_sta_ap_p2pgo_iface_limit),
      .beacon_int_infra_match = true,
   },
   /* Monitor */
   {
      .limits = wlan_hdd_mon_iface_limit,
      .max_interfaces = 3,
      .num_different_channels = 2,
      .n_limits = ARRAY_SIZE(wlan_hdd_mon_iface_limit),
   },
};
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) ||
         defined(WITH_BACKPORTS) */


static struct cfg80211_ops wlan_hdd_cfg80211_ops;
struct hdd_bpf_context bpf_context;

/* 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 */
/* HT MCS parameters with Nss = 1 */
static struct index_data_rate_type supported_mcs_rate_nss1[] =
{
/* MCS  L20   L40   S20  S40 */
   {0,  {65,  135,  72,  150}},
   {1,  {130, 270,  144, 300}},
   {2,  {195, 405,  217, 450}},
   {3,  {260, 540,  289, 600}},
   {4,  {390, 810,  433, 900}},
   {5,  {520, 1080, 578, 1200}},
   {6,  {585, 1215, 650, 1350}},
   {7,  {650, 1350, 722, 1500}}
};
/* HT MCS parameters with Nss = 2 */
static struct index_data_rate_type supported_mcs_rate_nss2[] =
{
/* MCS  L20    L40   S20   S40 */
   {0,  {130,  270,  144,  300}},
   {1,  {260,  540,  289,  600}},
   {2,  {390,  810,  433,  900}},
   {3,  {520,  1080, 578,  1200}},
   {4,  {780,  1620, 867,  1800}},
   {5,  {1040, 2160, 1156, 2400}},
   {6,  {1170, 2430, 1300, 2700}},
   {7,  {1300, 2700, 1444, 3000}}
};

#ifdef WLAN_FEATURE_11AC

#define DATA_RATE_11AC_MCS_MASK    0x03

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

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

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

/**
 * struct cfg_hostapd_edca - Store hostapd EDCA params
 *                           and fill them in gLimEdcaParams
 *                           structure
 * @acm: EDCA param
 * @aifs: EDCA param
 * @cwmin: EDCA param
 * @cwmax: EDCA param
 * @txop: EDCA param
 * @paramb: EDCA param for 11b
 * @paramg: EDCA param for 11g
 * @enable: enable hostapd EDCA params
 */
struct cfg_hostapd_edca {
	uint8_t acm;
	uint8_t aifs;
	uint16_t cwmin;
	uint16_t cwmax;
	uint8_t txop;
	uint8_t paramsb[5];
	uint8_t paramsg[5];
	uint8_t enable;
};

#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_STREAM_ID = 3,
    WLAN_HDD_TM_ATTR_TYPE    = 4,
    /* 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_FTM   = 0,
    WLAN_HDD_TM_CMD_WLAN_HB    = 1,
};

#define WLAN_HDD_TM_DATA_MAX_LEN    5000

enum wlan_hdd_vendor_ie_access_policy {
	WLAN_HDD_VENDOR_IE_ACCESS_NONE = 0,
	WLAN_HDD_VENDOR_IE_ACCESS_ALLOW_IF_LISTED,
};

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_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_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_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] = { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE] = { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] = { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] = { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BASE] = { .type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] = { .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 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] = { .type = NLA_U32 },
};

static const struct nla_policy
wlan_hdd_pno_config_policy[QCA_WLAN_VENDOR_ATTR_PNO_MAX + 1] = {
    [QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NUM] = {
        .type = NLA_U32
    },
    [QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ID] = {
        .type = NLA_U32
    },
    [QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_NUM_NETWORKS] = {
        .type = NLA_U32
    },
    [QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_SSID] = {
        .type = NLA_BINARY,
        .len = IEEE80211_MAX_SSID_LEN + 1
    },
    [QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_FLAGS] = {
        .type = NLA_U8
    },
    [QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_AUTH_BIT] = {
        .type = NLA_U8
    },
    [QCA_WLAN_VENDOR_ATTR_EPNO_MIN5GHZ_RSSI] = {
        .type = NLA_U32
    },
    [QCA_WLAN_VENDOR_ATTR_EPNO_MIN24GHZ_RSSI] = {
        .type = NLA_U32
    },
    [QCA_WLAN_VENDOR_ATTR_EPNO_INITIAL_SCORE_MAX] = {
        .type = NLA_U32
    },
    [QCA_WLAN_VENDOR_ATTR_EPNO_CURRENT_CONNECTION_BONUS] = {
        .type = NLA_U32
    },
    [QCA_WLAN_VENDOR_ATTR_EPNO_SAME_NETWORK_BONUS] = {
        .type = NLA_U32
    },
    [QCA_WLAN_VENDOR_ATTR_EPNO_SECURE_BONUS] = {
        .type = NLA_U32
    },
    [QCA_WLAN_VENDOR_ATTR_EPNO_BAND5GHZ_BONUS] = {
        .type = NLA_U32
    },
    [QCA_WLAN_VENDOR_ATTR_PNO_CONFIG_REQUEST_ID] = {
         .type = NLA_U32
    },
};

static const struct nla_policy
wlan_hdd_extscan_results_policy[QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_MAX + 1] =
{
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD] = { .type = NLA_U16 },
    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY] = { .type = NLA_U16 },
};


#endif /* FEATURE_WLAN_EXTSCAN */

#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

#if defined(FEATURE_WLAN_CH_AVOID) || defined(FEATURE_WLAN_FORCE_SAP_SCC)
/*
 * FUNCTION: wlan_hdd_send_avoid_freq_event
 * This is called when wlan driver needs to send vendor specific
 * avoid frequency range event to user space
 */
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,
                              NULL,
                              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 || FEATURE_WLAN_FORCE_SAP_SCC */

#ifdef WLAN_FEATURE_NAN
/**
 * __wlan_hdd_cfg80211_nan_request() - handle NAN request
 * @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 function is called by userspace to send a NAN request to
 * firmware.
 *
 * Return: 0 on success, negative errno on failure
 */
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 = -EINVAL;
    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;
    }

    if (!hdd_ctx->cfg_ini->enable_nan_support) {
        hddLog(LOGE, FL("NaN is not suported"));
        return -EPERM;
    }

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

    status = sme_NanRequest(&nan_req);
    if (VOS_STATUS_SUCCESS != status) {
        ret_val = -EINVAL;
    }
    return ret_val;
}

/**
 * wlan_hdd_cfg80211_nan_request() - handle NAN request
 * @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 function is called by userspace to send a NAN request to
 * firmware.  This is an SSR-protected wrapper function.
 *
 * Return: 0 on success, negative errno on failure
 */
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;

    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)
        return;

    vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
                                   NULL,
                                   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);
}

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

#endif

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

/* vendor specific events */
static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
{
#ifdef FEATURE_WLAN_CH_AVOID
    [QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
    },
#endif /* FEATURE_WLAN_CH_AVOID */

#ifdef WLAN_FEATURE_NAN
    [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
    },
#endif

#ifdef WLAN_FEATURE_STATS_EXT
    [QCA_NL80211_VENDOR_SUBCMD_STATS_EXT_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_STATS_EXT
    },
#endif /* WLAN_FEATURE_STATS_EXT */
#ifdef FEATURE_WLAN_EXTSCAN
    [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
    },
    [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
    },
    [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
    },
    [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
    },
    [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
    },
    [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
    },
    [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
    },
    [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
    },
    [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
    },
    [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
    },
    [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
    },
    [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
    },
    [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
    },
#endif /* FEATURE_WLAN_EXTSCAN */

#ifdef WLAN_FEATURE_LINK_LAYER_STATS
    [QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET_INDEX] =  {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
    },
    [QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET_INDEX] =  {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
    },
    [QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR_INDEX] =  {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
    },
    [QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX] =  {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
    },
    [QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX] =  {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
    },
    [QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX] =  {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
    },
    [QCA_NL80211_VENDOR_SUBCMD_LL_STATS_EXT_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_EXT
    },
#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
/* EXT TDLS */
    [QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX] =  {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
    },
    [QCA_NL80211_VENDOR_SUBCMD_DO_ACS_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_DO_ACS
    },
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
    [QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH_INDEX] =  {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH
    },
#endif
    [QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED_INDEX] =  {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED
    },
    [QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED_INDEX] =  {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED
    },
    [QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_ABORTED_INDEX] =  {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_ABORTED
    },
    [QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_NOP_FINISHED_INDEX] =  {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_NOP_FINISHED
    },
    [QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED_INDEX] =  {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED
    },
#ifdef FEATURE_WLAN_EXTSCAN
    [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_NETWORK_FOUND_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_NETWORK_FOUND
    },
    [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_PASSPOINT_NETWORK_FOUND_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_PASSPOINT_NETWORK_FOUND
    },
    [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
    },
#endif /* FEATURE_WLAN_EXTSCAN */
    /* OCB events */
    [QCA_NL80211_VENDOR_SUBCMD_DCC_STATS_EVENT_INDEX] =  {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_DCC_STATS_EVENT
    },
    [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
    },
#ifdef WLAN_FEATURE_NAN_DATAPATH
    [QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_NDP
    },
#endif /* WLAN_FEATURE_NAN_DATAPATH */
    [QCA_NL80211_VENDOR_SUBCMD_PWR_SAVE_FAIL_DETECTED_INDEX] = {
        .vendor_id = QCA_NL80211_VENDOR_ID,
        .subcmd = QCA_NL80211_VENDOR_SUBCMD_CHIP_PWRSAVE_FAILURE
    }
};

/**
 * __is_driver_dfs_capable() - get driver DFS capability
 * @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 function is called by userspace to indicate whether or not
 * the driver supports DFS offload.
 *
 * Return: 0 on success, negative errno on failure
 */
static int __is_driver_dfs_capable(struct wiphy *wiphy,
				   struct wireless_dev *wdev,
				   const void *data,
				   int data_len)
{
    u32 dfs_capability = 0;
    struct sk_buff *temp_skbuff;
    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;
    }

#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,4,0)) || \
    defined (DFS_MASTER_OFFLOAD_IND_SUPPORT) || defined(WITH_BACKPORTS)
    dfs_capability = !!(wiphy->flags & WIPHY_FLAG_DFS_OFFLOAD);
#endif

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

    if (temp_skbuff != NULL)
    {

        ret_val = nla_put_u32(temp_skbuff, QCA_WLAN_VENDOR_ATTR_DFS,
                              dfs_capability);
        if (ret_val)
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: QCA_WLAN_VENDOR_ATTR_DFS put fail", __func__);
            kfree_skb(temp_skbuff);

            return ret_val;
        }

        return cfg80211_vendor_cmd_reply(temp_skbuff);
    }

    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
              "%s: dfs capability: buffer alloc fail", __func__);
    return -ENOMEM;
}

/**
 * is_driver_dfs_capable() - get driver DFS capability
 * @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 function is called by userspace to indicate whether or not
 * the driver supports DFS offload.  This is an SSR-protected
 * wrapper function.
 *
 * Return: 0 on success, negative errno on failure
 */
static int is_driver_dfs_capable(struct wiphy *wiphy,
				 struct wireless_dev *wdev,
				 const void *data,
				 int data_len)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __is_driver_dfs_capable(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)
{
    hdd_context_t *pHddCtx      = wiphy_priv(wiphy);
    struct sk_buff *skb         = NULL;
    tANI_U32       fset         = 0;
    int ret;

    /* ENTER() intentionally not used in a frequently invoked API */

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

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

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

    if (TRUE == hdd_is_5g_supported(pHddCtx)) {
        hddLog(LOG1, "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, "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 FEATURE_WLAN_EXTSCAN
    if (pHddCtx->cfg_ini->extscan_enabled &&
        sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
        hddLog(LOG1, "EXTScan is supported by firmware");
        fset |= WIFI_FEATURE_EXTSCAN | WIFI_FEATURE_HAL_EPNO;
    }
#endif

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

    if (sme_IsFeatureSupportedByFW(RTT)) {
        hddLog(LOG1, "RTT is supported by firmware");
        fset |= WIFI_FEATURE_D2D_RTT;
        fset |= WIFI_FEATURE_D2AP_RTT;
    }

#ifdef FEATURE_WLAN_SCAN_PNO
    if (pHddCtx->cfg_ini->configPNOScanSupport &&
        sme_IsFeatureSupportedByFW(PNO)) {
        hddLog(LOG1, "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, "TDLS is supported by firmware");
        fset |= WIFI_FEATURE_TDLS;
    }

    if (sme_IsFeatureSupportedByFW(TDLS) &&
       (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
       sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) {
        hddLog(LOG1, "TDLS off-channel is supported by firmware");
        fset |= WIFI_FEATURE_TDLS_OFFCHANNEL;
    }
#endif

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

    if (hdd_link_layer_stats_supported())
        fset |= WIFI_FEATURE_LINK_LAYER_STATS;

    if (hdd_roaming_supported(pHddCtx))
        fset |= WIFI_FEATURE_CONTROL_ROAMING;

    if (pHddCtx->cfg_ini->probe_req_ie_whitelist)
        fset |= WIFI_FEATURE_IE_WHITELIST;

    if (hdd_scan_random_mac_addr_supported())
        fset |= WIFI_FEATURE_SCAN_RAND;

    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);
    return ret;

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

/**
 * wlan_hdd_cfg80211_get_supported_features() - get supported features
 * @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
 *
 * Return:   Return the Success or Failure code.
 */
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;
}

/**
 * wlan_hdd_fill_whitelist_ie_attrs - fill the white list members
 * @ie_whitelist: enables whitelist
 * @probe_req_ie_bitmap: bitmap to be filled
 * @num_vendor_oui: pointer to no of ouis
 * @voui: pointer to ouis to be filled
 * @pHddCtx: pointer to hdd ctx
 *
 * This function fills the ie bitmap and vendor oui fields with the
 * corresponding values present in cfg_ini and PHddCtx
 *
 * Return:   Return none
 */
static void wlan_hdd_fill_whitelist_ie_attrs(bool *ie_whitelist,
					     uint32_t *probe_req_ie_bitmap,
					     uint32_t *num_vendor_oui,
					     struct vendor_oui *voui,
					     hdd_context_t *pHddCtx)
{
	uint32_t i = 0;

	*ie_whitelist = true;
	probe_req_ie_bitmap[0] = pHddCtx->cfg_ini->probe_req_ie_bitmap_0;
	probe_req_ie_bitmap[1] = pHddCtx->cfg_ini->probe_req_ie_bitmap_1;
	probe_req_ie_bitmap[2] = pHddCtx->cfg_ini->probe_req_ie_bitmap_2;
	probe_req_ie_bitmap[3] = pHddCtx->cfg_ini->probe_req_ie_bitmap_3;
	probe_req_ie_bitmap[4] = pHddCtx->cfg_ini->probe_req_ie_bitmap_4;
	probe_req_ie_bitmap[5] = pHddCtx->cfg_ini->probe_req_ie_bitmap_5;
	probe_req_ie_bitmap[6] = pHddCtx->cfg_ini->probe_req_ie_bitmap_6;
	probe_req_ie_bitmap[7] = pHddCtx->cfg_ini->probe_req_ie_bitmap_7;

	*num_vendor_oui = 0;

	if ((pHddCtx->no_of_probe_req_ouis != 0) && (voui != NULL)) {
		*num_vendor_oui = pHddCtx->no_of_probe_req_ouis;
		for (i = 0; i < pHddCtx->no_of_probe_req_ouis; i++) {
			voui[i].oui_type = pHddCtx->probe_req_voui[i].oui_type;
			voui[i].oui_subtype =
					pHddCtx->probe_req_voui[i].oui_subtype;
		}
	}
}

/**
 * __wlan_hdd_cfg80211_set_scanning_mac_oui() - set scan MAC
 * @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
 *
 * Set the MAC address that is to be used for scanning.
 *
 * Return:   Return the Success or Failure code.
 */
static int
__wlan_hdd_cfg80211_set_scanning_mac_oui(struct wiphy *wiphy,
					 struct wireless_dev *wdev,
					 const void *data,
					 int data_len)
{
    tpSirScanMacOui pReqMsg   = NULL;
    hdd_context_t *pHddCtx    = wiphy_priv(wiphy);
    struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
    eHalStatus status;
    int ret;
    struct net_device *ndev = wdev->netdev;
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(ndev);

    ENTER();

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

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

    if (FALSE == pHddCtx->cfg_ini->enable_mac_spoofing) {
        hddLog(LOGW, FL("MAC address spoofing is not enabled"));
        return -ENOTSUPP;
    }

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

    pReqMsg = vos_mem_malloc(sizeof(*pReqMsg) +
                    (pHddCtx->no_of_probe_req_ouis) *
                    (sizeof(struct vendor_oui)));
    if (!pReqMsg) {
        hddLog(LOGE, FL("vos_mem_malloc failed"));
        return -ENOMEM;
    }
    vos_mem_zero(pReqMsg, sizeof(*pReqMsg) +
                    (pHddCtx->no_of_probe_req_ouis) *
                    (sizeof(struct vendor_oui)));

    /* Parse and fetch oui */
    if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
        hddLog(LOGE, FL("attr mac oui failed"));
        goto fail;
    }

    nla_memcpy(&pReqMsg->oui[0],
            tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI],
            sizeof(pReqMsg->oui));

    /* populate pReqMsg for mac addr randomization */
    pReqMsg->vdev_id = pAdapter->sessionId;
    pReqMsg->enb_probe_req_sno_randomization = 1;

    hddLog(LOG1, FL("Oui (%02x:%02x:%02x), vdev_id = %d"), pReqMsg->oui[0],
                     pReqMsg->oui[1], pReqMsg->oui[2], pReqMsg->vdev_id);

    if (pHddCtx->cfg_ini->probe_req_ie_whitelist)
         wlan_hdd_fill_whitelist_ie_attrs(&pReqMsg->ie_whitelist,
                                      pReqMsg->probe_req_ie_bitmap,
                                      &pReqMsg->num_vendor_oui,
                                      (struct vendor_oui *)((uint8_t *)pReqMsg +
                                      sizeof(*pReqMsg)),
                                      pHddCtx);

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

    return 0;

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

/**
 * wlan_hdd_cfg80211_set_scanning_mac_oui() - set scan MAC
 * @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
 *
 * Set the MAC address that is to be used for scanning.  This is an
 * SSR-protecting wrapper function.
 *
 * Return:   Return the Success or Failure code.
 */
static int
wlan_hdd_cfg80211_set_scanning_mac_oui(struct wiphy *wiphy,
				       struct wireless_dev *wdev,
				       const void *data,
				       int data_len)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_set_scanning_mac_oui(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 *hdd_ctx = wiphy_priv(wiphy);
    int ret;

    ENTER();

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

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

    if (nla_parse(tb, MAX_CONCURRENT_MATRIX,
                  data, data_len, wlan_hdd_get_concurrency_matrix_policy, NULL)) {
        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_NAN;

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

/**
 * wlan_hdd_cfg80211_get_concurrency_matrix() - get concurrency matrix
 * @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
 *
 * Return:   Return the Success or Failure code.
 */
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;
}

#define MAX_ROAMING_PARAM \
       QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX

static const struct nla_policy
wlan_hdd_set_roam_param_policy[MAX_ROAMING_PARAM + 1] = {
	[QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD] = {.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID] = {.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_NUM_NETWORKS] = {
					.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_LIST] = {
					.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID] = {
					.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_THRESHOLD] = {
					.type = NLA_S32},
	[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_PENALTY_THRESHOLD] = {
					.type = NLA_S32},
	[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_FACTOR] = {
					.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_PENALTY_FACTOR] = {
					.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_MAX_BOOST] = {
					.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_LAZY_ROAM_HISTERESYS] = {
					.type = NLA_S32},
	[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALERT_ROAM_RSSI_TRIGGER] = {
					.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_ENABLE] = {
					.type = NLA_S32},
	[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_NUM_BSSID] = {
					.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_BSSID] = {
					.type = NLA_BINARY,
					.len = MAC_ADDRESS_STR_LEN},
	[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_RSSI_MODIFIER] = {
					.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID] = {
					.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_BSSID] = {
					.type = NLA_BINARY,
					.len = MAC_ADDRESS_STR_LEN},
};

static int
__wlan_hdd_cfg80211_set_ext_roam_params(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);
	uint8_t session_id;
	struct roam_ext_params roam_params;
	uint32_t cmd_type, req_id;
	struct nlattr *curr_attr = NULL;
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX + 1];
	struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX + 1];
	int rem, i;
	uint32_t buf_len = 0;
	uint32_t count;
	int ret;

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

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

	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX,
		data, data_len,
		wlan_hdd_set_roam_param_policy, NULL)) {
		hddLog(LOGE, FL("Invalid ATTR"));
		return -EINVAL;
	}
	/* Parse and fetch Command Type*/
	if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD]) {
		hddLog(LOGE, FL("roam cmd type failed"));
		goto fail;
	}
	session_id = pAdapter->sessionId;
	vos_mem_set(&roam_params, sizeof(roam_params),0);
	cmd_type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD]);
	if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID]) {
		hddLog(LOGE, FL("attr request id failed"));
		goto fail;
	}
	req_id = nla_get_u32(
		tb[QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID]);
	hddLog(VOS_TRACE_LEVEL_DEBUG, FL("Req Id (%d)"), req_id);
	hddLog(VOS_TRACE_LEVEL_DEBUG, FL("Cmd Type (%d)"), cmd_type);
	switch(cmd_type) {
	case QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SSID_WHITE_LIST:
		i = 0;
		if (tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_NUM_NETWORKS]) {
			count = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_NUM_NETWORKS]);
		} else {
			hddLog(LOGE, FL("Number of networks is not provided"));
			goto fail;
		}

		if (count &&
		    tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_LIST]) {
			nla_for_each_nested(curr_attr,
				tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_LIST],
				rem) {
				if (nla_parse(tb2,
					QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_MAX,
					nla_data(curr_attr), nla_len(curr_attr),
					wlan_hdd_set_roam_param_policy, NULL)) {
					hddLog(LOGE, FL("nla_parse failed"));
					goto fail;
				}
				/* Parse and Fetch allowed SSID list*/
				if (!tb2[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID]) {
					hddLog(LOGE, FL("attr allowed ssid failed"));
					goto fail;
				}
				buf_len = nla_len(tb2[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID]);
				/*
				 * Upper Layers include a null termination character.
				 * Check for the actual permissible length of SSID and
				 * also ensure not to copy the NULL termination
				 * character to the driver buffer.
				 */
				if (buf_len && (i < MAX_SSID_ALLOWED_LIST) &&
					((buf_len - 1) <= SIR_MAC_MAX_SSID_LENGTH)) {
					nla_memcpy(roam_params.ssid_allowed_list[i].ssId,
						tb2[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID],
						buf_len - 1);
					roam_params.ssid_allowed_list[i].length =
						buf_len - 1;
					hddLog(VOS_TRACE_LEVEL_DEBUG,
						FL("SSID[%d]: %.*s,length = %d"), i,
						roam_params.ssid_allowed_list[i].length,
						roam_params.ssid_allowed_list[i].ssId,
						roam_params.ssid_allowed_list[i].length);
					i++;
				} else {
					hddLog(LOGE, FL("Invalid SSID len %d,idx %d"),
						buf_len, i);
				}
			}
		}
		if (i != count) {
			hddLog(LOGE, FL("Invalid number of SSIDs i = %d, count = %d"),
						i, count);
			goto fail;
		}
		roam_params.num_ssid_allowed_list = i;
		hddLog(VOS_TRACE_LEVEL_DEBUG, FL("Num of Allowed SSID %d"),
			roam_params.num_ssid_allowed_list);
		sme_update_roam_params(pHddCtx->hHal, session_id,
				roam_params, REASON_ROAM_SET_SSID_ALLOWED);
		break;
	case QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SET_EXTSCAN_ROAM_PARAMS:
		/* Parse and fetch 5G Boost Threshold */
		if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_THRESHOLD]) {
			hddLog(LOGE, FL("5G boost threshold failed"));
			goto fail;
		}
		roam_params.raise_rssi_thresh_5g = nla_get_s32(
			tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_THRESHOLD]);
		hddLog(VOS_TRACE_LEVEL_DEBUG,
			FL("5G Boost Threshold (%d)"),
			roam_params.raise_rssi_thresh_5g);
		/* Parse and fetch 5G Penalty Threshold */
		if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_PENALTY_THRESHOLD]) {
			hddLog(LOGE, FL("5G penalty threshold failed"));
			goto fail;
		}
		roam_params.drop_rssi_thresh_5g = nla_get_s32(
			tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_PENALTY_THRESHOLD]);
		hddLog(VOS_TRACE_LEVEL_DEBUG,
			FL("5G Penalty Threshold (%d)"),
			roam_params.drop_rssi_thresh_5g);
		/* Parse and fetch 5G Boost Factor */
		if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_FACTOR]) {
			hddLog(LOGE, FL("5G boost Factor failed"));
			goto fail;
		}
		roam_params.raise_factor_5g = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_FACTOR]);
		hddLog(VOS_TRACE_LEVEL_DEBUG, FL("5G Boost Factor (%d)"),
			roam_params.raise_factor_5g);
		/* Parse and fetch 5G Penalty factor */
		if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_PENALTY_FACTOR]) {
			hddLog(LOGE, FL("5G Penalty Factor failed"));
			goto fail;
		}
		roam_params.drop_factor_5g = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_PENALTY_FACTOR]);
		hddLog(VOS_TRACE_LEVEL_DEBUG,
			FL("5G Penalty factor (%d)"),
			roam_params.drop_factor_5g);
		/* Parse and fetch 5G Max Boost */
		if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_MAX_BOOST]) {
			hddLog(LOGE, FL("5G Max Boost failed"));
			goto fail;
		}
		roam_params.max_raise_rssi_5g = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_MAX_BOOST]);
		hddLog(VOS_TRACE_LEVEL_DEBUG, FL("5G Max Boost (%d)"),
			roam_params.max_raise_rssi_5g);
		/* Parse and fetch Rssi Diff */
		if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_LAZY_ROAM_HISTERESYS]) {
			hddLog(LOGE, FL("Rssi Diff failed"));
			goto fail;
		}
		roam_params.rssi_diff = nla_get_s32(
			tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_LAZY_ROAM_HISTERESYS]);
		hddLog(VOS_TRACE_LEVEL_DEBUG, FL("RSSI Diff (%d)"),
			roam_params.rssi_diff);
		/* Parse and fetch Good Rssi Threshold */
		if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALERT_ROAM_RSSI_TRIGGER]) {
			hddLog(LOGE, FL("Alert Rssi Threshold failed"));
			goto fail;
		}
		roam_params.alert_rssi_threshold = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALERT_ROAM_RSSI_TRIGGER]);
		hddLog(VOS_TRACE_LEVEL_DEBUG,
			FL("Alert RSSI Threshold (%d)"),
			roam_params.alert_rssi_threshold);
		sme_update_roam_params(pHddCtx->hHal, session_id,
			roam_params,
			REASON_ROAM_EXT_SCAN_PARAMS_CHANGED);
		break;
	case QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SET_LAZY_ROAM:
		/* Parse and fetch Activate Good Rssi Roam */
		if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_ENABLE]) {
			hddLog(LOGE, FL("Activate Good Rssi Roam failed"));
			goto fail;
		}
		roam_params.good_rssi_roam = nla_get_s32(
			tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_ENABLE]);
		hddLog(VOS_TRACE_LEVEL_DEBUG,
			FL("Activate Good Rssi Roam (%d)"),
			roam_params.good_rssi_roam);
		sme_update_roam_params(pHddCtx->hHal, session_id,
			roam_params, REASON_ROAM_GOOD_RSSI_CHANGED);
		break;
	case QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SET_BSSID_PREFS:
		/* Parse and fetch number of preferred BSSID */
		if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_NUM_BSSID]) {
			hddLog(LOGE, FL("attr num of preferred bssid failed"));
			goto fail;
		}
		count = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_NUM_BSSID]);
		if (count > MAX_BSSID_FAVORED) {
			hddLog(LOGE, FL("Preferred BSSID count %u exceeds max %u"),
			       count, MAX_BSSID_FAVORED);
			goto fail;
		}
		hddLog(VOS_TRACE_LEVEL_DEBUG,
			FL("Num of Preferred BSSID: %d"), count);
		if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PREFS]) {
			hddLog(LOGE, FL("attr Preferred BSSID failed"));
			goto fail;
		}
		i = 0;
		nla_for_each_nested(curr_attr,
			tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PREFS],
			rem) {

			if (i == count) {
				hddLog(LOGW, FL("Ignoring excess Preferred BSSID"));
				break;
			}

			if (nla_parse(tb2,
				QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX,
				nla_data(curr_attr), nla_len(curr_attr),
				wlan_hdd_set_roam_param_policy, NULL)) {
				hddLog(LOGE, FL("nla_parse failed"));
				goto fail;
			}
			/* Parse and fetch MAC address */
			if (!tb2[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_BSSID]) {
				hddLog(LOGE, FL("attr mac address failed"));
				goto fail;
			}
			nla_memcpy(roam_params.bssid_favored[i],
				tb2[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_BSSID],
				sizeof(tSirMacAddr));
			hddLog(VOS_TRACE_LEVEL_DEBUG, MAC_ADDRESS_STR,
				MAC_ADDR_ARRAY(roam_params.bssid_favored[i]));
			/* Parse and fetch preference factor*/
			if (!tb2[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_RSSI_MODIFIER]) {
				hddLog(LOGE, FL("BSSID Preference score failed"));
				goto fail;
			}
			roam_params.bssid_favored_factor[i] = nla_get_u32(
				tb2[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_RSSI_MODIFIER]);
			hddLog(VOS_TRACE_LEVEL_DEBUG,
				FL("BSSID Preference score (%d)"),
				roam_params.bssid_favored_factor[i]);
			i++;
		}
		if (i < count)
			hddLog(LOGW,
			       FL("Num Preferred BSSID %u less than expected %u"),
			       i, count);
		roam_params.num_bssid_favored = i;
		sme_update_roam_params(pHddCtx->hHal, session_id,
			roam_params, REASON_ROAM_SET_FAVORED_BSSID);
		break;
	case QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SET_BLACKLIST_BSSID:
		/* Parse and fetch number of blacklist BSSID */
		if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID]) {
			hddLog(LOGE, FL("attr num of blacklist bssid failed"));
			goto fail;
		}
		count = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID]);
		if (count > MAX_BSSID_AVOID_LIST) {
			hddLog(LOGE, FL("Blacklist BSSID count %u exceeds max %u"),
			       count, MAX_BSSID_AVOID_LIST);
			goto fail;
		}
		hddLog(VOS_TRACE_LEVEL_DEBUG,
			FL("Num of blacklist BSSID: %d"), count);
		i = 0;
		if (count &&
		    tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS]) {
			nla_for_each_nested(curr_attr,
				tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS],
				rem) {
				if (i == count) {
					hddLog(LOGW, FL("Ignoring excess Blacklist BSSID"));
					break;
				}
				if (nla_parse(tb2,
					QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX,
					nla_data(curr_attr), nla_len(curr_attr),
					wlan_hdd_set_roam_param_policy, NULL)) {
					hddLog(LOGE, FL("nla_parse failed"));
					goto fail;
				}
				/* Parse and fetch MAC address */
				if (!tb2[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_BSSID]) {
					hddLog(LOGE, FL("attr blacklist addr failed"));
					goto fail;
				}
				nla_memcpy(roam_params.bssid_avoid_list[i],
					tb2[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_BSSID],
					sizeof(tSirMacAddr));
				hddLog(VOS_TRACE_LEVEL_DEBUG, MAC_ADDRESS_STR,
					MAC_ADDR_ARRAY(
					roam_params.bssid_avoid_list[i]));
				i++;
			}
		}
		if (i < count)
			hddLog(LOGW,
			       FL("Num Blacklist BSSID %u less than expected %u"),
			       i, count);
		roam_params.num_bssid_avoid_list = i;
		sme_update_roam_params(pHddCtx->hHal, session_id,
			roam_params, REASON_ROAM_SET_BLACKLIST_BSSID);
		break;
	}
	return 0;
fail:
	return -EINVAL;
}

/**
 * wlan_hdd_cfg80211_set_ext_roam_params() - set ext scan roam params
 * @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
 *
 * Return:   Return the Success or Failure code.
 */
static int
wlan_hdd_cfg80211_set_ext_roam_params(struct wiphy *wiphy,
				struct wireless_dev *wdev,
				const void *data,
				int data_len)
{
	int ret;

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

	return ret;
}

#ifdef WLAN_FEATURE_STATS_EXT
/**
 * __wlan_hdd_cfg80211_stats_ext_request() - ext stats request
 * @wiphy: Pointer to wiphy
 * @wdev: Pointer to wdev
 * @data: Pointer to data
 * @data_len: Data length
 *
 * Return: int
 */
static int __wlan_hdd_cfg80211_stats_ext_request(struct wiphy *wiphy,
						 struct wireless_dev *wdev,
						 const void *data,
						 int data_len)
{
    tStatsExtRequestReq stats_ext_req;
    struct net_device *dev = wdev->netdev;
    hdd_adapter_t *pAdapter =  WLAN_HDD_GET_PRIV_PTR(dev);
    int ret_val;
    eHalStatus status;
    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 -EINVAL;
    }

    stats_ext_req.request_data_len = data_len;
    stats_ext_req.request_data = (void *)data;

    status = sme_StatsExtRequest(pAdapter->sessionId, &stats_ext_req);

    if (eHAL_STATUS_SUCCESS != status)
        ret_val = -EINVAL;

    return ret_val;
}

/**
 * wlan_hdd_cfg80211_stats_ext_request() - ext stats request
 * @wiphy: Pointer to wiphy
 * @wdev: Pointer to wdev
 * @data: Pointer to data
 * @data_len: Data length
 *
 * Return: int
 */
static int wlan_hdd_cfg80211_stats_ext_request(struct wiphy *wiphy,
					       struct wireless_dev *wdev,
					       const void *data,
					       int data_len)
{
	int ret;

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

	return ret;
}

static void wlan_hdd_cfg80211_stats_ext_callback(void* ctx, tStatsExtEvent* msg)
{

    hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
    struct sk_buff *vendor_event;
    int status;
    int ret_val;
    tStatsExtEvent *data = msg;
    hdd_adapter_t *pAdapter = NULL;

    status = wlan_hdd_validate_context(pHddCtx);

    if (0 != status)
        return;

    pAdapter = hdd_get_adapter_by_vdev( pHddCtx, data->vdev_id);

    if (NULL == pAdapter)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: vdev_id %d does not exist with host",
                  __func__, data->vdev_id);
        return;
    }


    vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
                                               NULL,
                                               data->event_data_len +
                                               sizeof(tANI_U32) +
                                               NLMSG_HDRLEN + NLMSG_HDRLEN,
                                               QCA_NL80211_VENDOR_SUBCMD_STATS_EXT_INDEX,
                                               GFP_KERNEL);

    if (!vendor_event)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: cfg80211_vendor_event_alloc failed", __func__);
        return;
    }

    ret_val = nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_IFINDEX,
                          pAdapter->dev->ifindex);
    if (ret_val)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: QCA_WLAN_VENDOR_ATTR_IFINDEX put fail", __func__);
        kfree_skb(vendor_event);

        return;
    }


    ret_val = nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_STATS_EXT,
                      data->event_data_len, data->event_data);

    if (ret_val)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: QCA_WLAN_VENDOR_ATTR_STATS_EXT put fail", __func__);
        kfree_skb(vendor_event);

        return;
    }

    cfg80211_vendor_event(vendor_event, GFP_KERNEL);

}

/**
 * wlan_hdd_cfg80211_stats_ext2_callback - stats_ext2_callback
 * @ctx: hdd context
 * @pmsg: stats_ext2_event
 *
 * Return: void
 */
static void wlan_hdd_cfg80211_stats_ext2_callback(void *ctx,
	struct stats_ext2_event *pmsg)
{
	hdd_context_t *hdd_ctx = (hdd_context_t *)ctx;
	int status, data_size;
	struct sk_buff *vendor_event;

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

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

	data_size = sizeof(struct stats_ext2_event) +
		(pmsg->hole_cnt)*sizeof(pmsg->hole_info_array[0]);

	vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
			NULL,
			data_size + NLMSG_HDRLEN + NLMSG_HDRLEN,
			QCA_NL80211_VENDOR_SUBCMD_STATS_EXT_INDEX,
			GFP_KERNEL);

	if (!vendor_event) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			"vendor_event_alloc failed for STATS_EXT2");
		return;
	}

	if (nla_put_u32(vendor_event,
			QCA_WLAN_VENDOR_ATTR_RX_AGGREGATION_STATS_HOLES_NUM,
			pmsg->hole_cnt)) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			"%s put fail",
			"QCA_WLAN_VENDOR_ATTR_RX_AGGREGATION_STATS_HOLES_NUM");
		kfree_skb(vendor_event);
		return;
	}

        if (nla_put(vendor_event,
			QCA_WLAN_VENDOR_ATTR_RX_AGGREGATION_STATS_HOLES_INFO,
			(pmsg->hole_cnt)*sizeof(pmsg->hole_info_array[0]),
			(void *)(pmsg->hole_info_array))) {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			"%s put fail",
			"QCA_WLAN_VENDOR_ATTR_RX_AGGREGATION_STATS_HOLES_INFO");
		kfree_skb(vendor_event);
		return;
	}

	cfg80211_vendor_event(vendor_event, GFP_KERNEL);
}

void wlan_hdd_cfg80211_stats_ext_init(hdd_context_t *pHddCtx)
{
    sme_StatsExtRegisterCallback(pHddCtx->hHal,
                                 wlan_hdd_cfg80211_stats_ext_callback);
    sme_register_stats_ext2_callback(pHddCtx->hHal,
				wlan_hdd_cfg80211_stats_ext2_callback);
}

#endif

#ifdef FEATURE_WLAN_EXTSCAN

/*
 * 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_SIGNIFICANT_WIFI_CHANGE_APS \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
#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_NUM_EPNO_NETS \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS
#define MAX_NUM_EPNO_NETS_BY_SSID \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS_BY_SSID
#define MAX_NUM_WHITELISTED_SSID \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_NUM_WHITELISTED_SSID
#define MAX_NUM_BLACKLISTED_BSSID \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_MAX_NUM_BLACKLISTED_BSSID

/**
 * wlan_hdd_send_ext_scan_capability - send ext scan capability to user space
 * @hdd_ctx: Pointer to hdd context
 *
 * Return: 0 for success, non-zero for failure
 */
static int wlan_hdd_send_ext_scan_capability(hdd_context_t *hdd_ctx)
{
	int ret;
	struct sk_buff *skb;
	struct ext_scan_capabilities_response *data;
	uint32_t nl_buf_len;

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

	data = &(hdd_ctx->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->max_scan_cache_size) + NLA_HDRLEN) +
	(sizeof(data->max_scan_buckets) + NLA_HDRLEN) +
	(sizeof(data->max_ap_cache_per_scan) + NLA_HDRLEN) +
	(sizeof(data->max_rssi_sample_size) + NLA_HDRLEN) +
	(sizeof(data->max_scan_reporting_threshold) + NLA_HDRLEN) +
	(sizeof(data->max_hotlist_bssids) + NLA_HDRLEN) +
	(sizeof(data->max_significant_wifi_change_aps) + NLA_HDRLEN) +
	(sizeof(data->max_bssid_history_entries) + NLA_HDRLEN) +
	(sizeof(data->max_hotlist_ssids) + NLA_HDRLEN) +
	(sizeof(data->max_number_epno_networks) + NLA_HDRLEN) +
	(sizeof(data->max_number_epno_networks_by_ssid) + NLA_HDRLEN) +
	(sizeof(data->max_number_of_white_listed_ssid) + NLA_HDRLEN) +
	(sizeof(data->max_number_of_black_listed_bssid) + NLA_HDRLEN);

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

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

	hddLog(LOG1, "Req Id (%u)", data->requestId);
	hddLog(LOG1, "Status (%u)", data->status);
	hddLog(LOG1, "Scan cache size (%u)", data->max_scan_cache_size);
	hddLog(LOG1, "Scan buckets (%u)", data->max_scan_buckets);
	hddLog(LOG1, "Max AP per scan (%u)", data->max_ap_cache_per_scan);
	hddLog(LOG1, "max_rssi_sample_size (%u)",
					data->max_rssi_sample_size);
	hddLog(LOG1, "max_scan_reporting_threshold (%u)",
					data->max_scan_reporting_threshold);
	hddLog(LOG1, "max_hotlist_bssids (%u)", data->max_hotlist_bssids);
	hddLog(LOG1, "max_significant_wifi_change_aps (%u)",
					data->max_significant_wifi_change_aps);
	hddLog(LOG1, "max_bssid_history_entries (%u)",
					data->max_bssid_history_entries);
	hddLog(LOG1, "max_hotlist_ssids (%u)", data->max_hotlist_ssids);
	hddLog(LOG1, "max_number_epno_networks (%u)",
					data->max_number_epno_networks);
	hddLog(LOG1, "max_number_epno_networks_by_ssid (%u)",
					data->max_number_epno_networks_by_ssid);
	hddLog(LOG1, "max_number_of_white_listed_ssid (%u)",
					data->max_number_of_white_listed_ssid);
	hddLog(LOG1, "max_number_of_black_listed_bssid (%u)",
					data->max_number_of_black_listed_bssid);

	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->max_scan_cache_size) ||
	    nla_put_u32(skb, MAX_SCAN_BUCKETS, data->max_scan_buckets) ||
	    nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
			data->max_ap_cache_per_scan) ||
	    nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
			data->max_rssi_sample_size) ||
	    nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
			data->max_scan_reporting_threshold) ||
	    nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->max_hotlist_bssids) ||
	    nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS,
			data->max_significant_wifi_change_aps) ||
	    nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
			data->max_bssid_history_entries) ||
	    nla_put_u32(skb, MAX_HOTLIST_SSIDS,	data->max_hotlist_ssids) ||
	    nla_put_u32(skb, MAX_NUM_EPNO_NETS,
			data->max_number_epno_networks) ||
	    nla_put_u32(skb, MAX_NUM_EPNO_NETS_BY_SSID,
			data->max_number_epno_networks_by_ssid) ||
	    nla_put_u32(skb, MAX_NUM_WHITELISTED_SSID,
			data->max_number_of_white_listed_ssid) ||
	    nla_put_u32(skb, MAX_NUM_BLACKLISTED_BSSID,
			data->max_number_of_black_listed_bssid)) {
		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_SIGNIFICANT_WIFI_CHANGE_APS
#undef MAX_BSSID_HISTORY_ENTRIES
#undef MAX_HOTLIST_SSIDS
#undef MAX_NUM_EPNO_NETS
#undef MAX_NUM_EPNO_NETS_BY_SSID
#undef MAX_NUM_WHITELISTED_SSID
#undef MAX_NUM_BLACKLISTED_BSSID

static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
                                                struct wireless_dev *wdev,
                                                const void *data,
                                                int data_len)
{
    int ret;
    unsigned long rc;
    struct hdd_ext_scan_context *context;
    tpSirGetExtScanCapabilitiesReqParams 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];
    eHalStatus status;

    ENTER();

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

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

    if (!pHddCtx->cfg_ini->extscan_enabled) {
        hddLog(LOGE, FL("extscan not supported"));
        return -ENOTSUPP;
    }
    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
                    data, data_len,
                    wlan_hdd_extscan_config_policy, NULL)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
        return -EINVAL;
    }

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

    /* 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"));
        goto fail;
    }

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

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

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


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

    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"));

    EXIT();
    return ret;

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

/**
 * wlan_hdd_cfg80211_extscan_get_capabilities() - get ext scan capabilities
 * @wiphy: Pointer to wiphy
 * @wdev: Pointer to wdev
 * @data: Pointer to data
 * @data_len: Data length
 *
 * Return: 0 for success, non-zero for failure
 */
static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
						struct wireless_dev *wdev,
						const void *data, int data_len)
{
	int ret = 0;

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

	return ret;
}



/*
 * define short names for the global vendor params
 * used by wlan_hdd_cfg80211_extscan_get_cached_results()
 */
#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_FLUSH \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH
/**
 * __wlan_hdd_cfg80211_extscan_get_cached_results() - extscan get cached results
 * @wiphy: wiphy pointer
 * @wdev: pointer to struct wireless_dev
 * @data: pointer to incoming NL vendor data
 * @data_len: length of @data
 *
 * This function parses the incoming NL vendor command data attributes and
 * invokes the SME Api and blocks on a completion variable.
 * Each WMI event with cached scan results data chunk results in
 * function call wlan_hdd_cfg80211_extscan_cached_results_ind and each
 * data chunk is sent up the layer in cfg80211_vendor_cmd_alloc_reply_skb.
 *
 * If timeout happens before receiving all of the data, this function sets
 * a context variable @ignore_cached_results to %true, all of the next data
 * chunks are checked against this variable and dropped.
 *
 * Return: 0 on success; error number otherwise.
 */
static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
                                                  struct wireless_dev *wdev,
                                                  const void *data,
                                                  int data_len)
{
	tpSirExtScanGetCachedResultsReqParams 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 hdd_ext_scan_context *context;
	struct nlattr *tb[PARAM_MAX + 1];
	eHalStatus status;
	int retval = 0;
	unsigned long rc;

	/* ENTER() intentionally not used in a frequently invoked API */

	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;

	if (!pHddCtx->cfg_ini->extscan_enabled) {
		hddLog(LOGE, FL("extscan not supported"));
		return -ENOTSUPP;
	}
	if (nla_parse(tb, PARAM_MAX, data, data_len,
			wlan_hdd_extscan_config_policy, NULL)) {
		hddLog(LOGE, FL("Invalid ATTR"));
		return -EINVAL;
	}

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

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

	pReqMsg->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
	pReqMsg->sessionId = pAdapter->sessionId;

	/* Parse and fetch flush parameter */
	if (!tb[PARAM_FLUSH]) {
		hddLog(LOGE, FL("attr flush failed"));
		goto fail;
	}
	pReqMsg->flush = nla_get_u8(tb[PARAM_FLUSH]);
	hddLog(LOG1, FL("Req Id: %u Session Id: %d Flush: %d"),
		pReqMsg->requestId, pReqMsg->sessionId, pReqMsg->flush);

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

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

	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);
	}
	return retval;

fail:
	vos_mem_free(pReqMsg);
	return -EINVAL;
}
/*
 * done with short names for the global vendor params
 * used by wlan_hdd_cfg80211_extscan_get_cached_results()
 */
#undef PARAM_MAX
#undef PARAM_REQUEST_ID
#undef PARAM_FLUSH

/**
 * wlan_hdd_cfg80211_extscan_get_cached_results() - extscan get cached results
 * @wiphy: wiphy pointer
 * @wdev: pointer to struct wireless_dev
 * @data: pointer to incoming NL vendor data
 * @data_len: length of @data
 *
 * This function parses the incoming NL vendor command data attributes and
 * invokes the SME Api and blocks on a completion variable.
 * Each WMI event with cached scan results data chunk results in
 * function call wlan_hdd_cfg80211_extscan_cached_results_ind and each
 * data chunk is sent up the layer in cfg80211_vendor_cmd_alloc_reply_skb.
 *
 * If timeout happens before receiving all of the data, this function sets
 * a context variable @ignore_cached_results to %true, all of the next data
 * chunks are checked against this variable and dropped.
 *
 * Return: 0 on success; error number otherwise.
 */
static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
						struct wireless_dev *wdev,
						const void *data, int data_len)
{
	int ret = 0;

	vos_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data,
								data_len);
	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 data_len)
{
    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;
    struct hdd_ext_scan_context *context;
    uint32_t request_id;
    eHalStatus status;
    tANI_U8 i;
    int rem, retval;
    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;

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

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

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

    pReqMsg->requestId = nla_get_u32(
              tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
    hddLog(LOG1, 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(LOGE, FL("attr number of AP failed"));
        goto fail;
    }
    pReqMsg->numAp = nla_get_u32(
              tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
    if (pReqMsg->numAp > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
        hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
               pReqMsg->numAp, WLAN_EXTSCAN_MAX_HOTLIST_APS);
        goto fail;
    }
    hddLog(LOG1, FL("Number of AP %d"), pReqMsg->numAp);

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

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

    if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM]) {
        hddLog(LOGE, FL("attr ap threshold failed"));
        goto fail;
    }
    i = 0;
    nla_for_each_nested(apTh,
                tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
        if (i == pReqMsg->numAp) {
            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),
                wlan_hdd_extscan_config_policy, NULL)) {
            hddLog(LOGE, FL("nla_parse failed"));
            goto fail;
        }

        /* Parse and fetch MAC address */
        if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
            hddLog(LOGE, FL("attr mac address failed"));
            goto fail;
        }
        nla_memcpy(pReqMsg->ap[i].bssid,
                tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID],
                sizeof(tSirMacAddr));
        hddLog(LOG1, MAC_ADDRESS_STR,
               MAC_ADDR_ARRAY(pReqMsg->ap[i].bssid));

        /* Parse and fetch low RSSI */
        if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
            hddLog(LOGE, 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(LOG1, 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(LOGE, 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(LOG1, FL("RSSI High %d"), pReqMsg->ap[i].high);
        i++;
    }

    if (i < pReqMsg->numAp) {
        hddLog(LOGW, FL("Number of AP %u less than expected %u"),
               i, pReqMsg->numAp);
        pReqMsg->numAp = 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(LOGE, FL("sme_SetBssHotlist failed(err=%d)"), status);
        goto fail;
    }

    /* 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);
    }
    EXIT();
    return retval;

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

/**
 * wlan_hdd_cfg80211_extscan_set_bssid_hotlist() - set ext scan bssid hotlist
 * @wiphy: Pointer to wiphy
 * @wdev: Pointer to wdev
 * @data: Pointer to data
 * @data_len: Data length
 *
 * Return: 0 for success, non-zero for failure
 */
static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
					struct wireless_dev *wdev,
					const void *data, int data_len)
{
	int ret = 0;

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

	return ret;
}


static int __wlan_hdd_cfg80211_extscan_set_significant_change(
                                        struct wiphy *wiphy,
                                        struct wireless_dev *wdev,
                                        const void *data,
                                        int data_len)
{
    tpSirExtScanSetSigChangeReqParams 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;
    struct hdd_ext_scan_context *context;
    uint32_t request_id;
    eHalStatus status;
    tANI_U8 i;
    int rem;
    int retval;
    unsigned long rc;

    ENTER();

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

    retval = wlan_hdd_validate_context(pHddCtx);
    if (0 != retval)
       return -EINVAL;

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

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

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

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

    /* Parse and fetch RSSI sample size */
    if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
    {
        hddLog(LOGE, FL("attr RSSI sample size failed"));
        goto fail;
    }
    pReqMsg->rssiSampleSize = nla_get_u32(
              tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
    hddLog(LOG1, FL("RSSI sample size %u"), pReqMsg->rssiSampleSize);

    /* Parse and fetch lost AP sample size */
    if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
    {
        hddLog(LOGE, FL("attr lost AP sample size failed"));
        goto fail;
    }
    pReqMsg->lostApSampleSize = nla_get_u32(
       tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
    hddLog(LOG1, FL("Lost AP sample size %u"), pReqMsg->lostApSampleSize);

    /* Parse and fetch AP min breaching */
    if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING])
    {
        hddLog(LOGE, FL("attr AP min breaching"));
        goto fail;
    }
    pReqMsg->minBreaching = nla_get_u32(
     tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
    hddLog(LOG1, FL("AP min breaching %u"), pReqMsg->minBreaching);

    /* Parse and fetch number of APs */
    if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
        hddLog(LOGE, FL("attr number of AP failed"));
        goto fail;
    }
    pReqMsg->numAp = nla_get_u32(
            tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
    if (pReqMsg->numAp > WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS) {
        hddLog(LOGE, FL("Number of AP %u exceeds max %u"),
               pReqMsg->numAp, WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS);
        goto fail;
    }

    pReqMsg->sessionId = pAdapter->sessionId;
    hddLog(LOG1, FL("Number of AP %d Session Id %d"), pReqMsg->numAp,
           pReqMsg->sessionId);
    if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM]) {
        hddLog(LOGE, FL("attr ap threshold failed"));
        goto fail;
    }
    i = 0;
    nla_for_each_nested(apTh,
                tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {

        if (i == pReqMsg->numAp) {
            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),
                wlan_hdd_extscan_config_policy, NULL)) {
            hddLog(LOGE, FL("nla_parse failed"));
            goto fail;
        }

        /* Parse and fetch MAC address */
        if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
            hddLog(LOGE, FL("attr mac address failed"));
            goto fail;
        }
        nla_memcpy(pReqMsg->ap[i].bssid,
                tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID],
                sizeof(tSirMacAddr));
        hddLog(LOG1, MAC_ADDRESS_STR,
               MAC_ADDR_ARRAY(pReqMsg->ap[i].bssid));

        /* Parse and fetch low RSSI */
        if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
            hddLog(LOGE, 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(LOG1, 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(LOGE, 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(LOG1, FL("RSSI High %d"), pReqMsg->ap[i].high);

        i++;
    }
    if (i < pReqMsg->numAp) {
        hddLog(LOGW, FL("Number of AP %u less than expected %u"),
               i, pReqMsg->numAp);
        pReqMsg->numAp = 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_SetSignificantChange(pHddCtx->hHal, pReqMsg);
    if (!HAL_STATUS_SUCCESS(status)) {
        hddLog(LOGE, FL("sme_SetSignificantChange failed(err=%d)"), status);
        goto fail;
    }

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

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

/**
 * wlan_hdd_cfg80211_extscan_set_significant_change() - set significant change
 * @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_extscan_set_significant_change(struct wiphy *wiphy,
				struct wireless_dev *wdev,
				const void *data, int data_len)
{
	int ret = 0;

	vos_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_extscan_set_significant_change(wiphy, wdev,
					data, data_len);
	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 data_len)
{
    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, num_chan_new = 0, 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 *reply_skb;
    int i, j, k, retval, len = 0;

    /* ENTER() intentionally not used in a frequently invoked API */

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

    retval = wlan_hdd_validate_context(pHddCtx);
    if (0 != retval)
       return -EINVAL;

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

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

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

    /* 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(LOG1, FL("Req Id: %d Wifi band: %d Max channels: %d"),
           requestId, wifiBand, maxChannels);

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

    num_channels = VOS_MIN(num_channels, maxChannels);

    /* remove the DSRC channels from the list */
    num_chan_new = 0;
    for (i = 0; i < num_channels; i++) {
        if (!vos_is_dsrc_channel(chan_list[i])) {
            chan_list[num_chan_new] = chan_list[i];
            num_chan_new++;
        }
    }

    num_channels = num_chan_new;

    /* remove the indoor only channels if iface is SAP */
    if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
        !strncmp(hdd_get_fwpath(), "ap", 2)) {
        num_chan_new = 0;
        for (i = 0; i < num_channels; i++)
            for (j = 0; j < IEEE80211_NUM_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);

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

    if (reply_skb) {
        if (nla_put_u32(reply_skb,
                        QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
                        num_chan_new) ||
            nla_put(reply_skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
                    sizeof(u32) * num_chan_new, chan_list)) {
            hddLog(LOGE, FL("nla put fail"));
            kfree_skb(reply_skb);
            return -EINVAL;
        }

        retval = cfg80211_vendor_cmd_reply(reply_skb);
        return retval;
    }
    hddLog(LOGE, FL("valid channels: buffer alloc fail"));
    return -EINVAL;
}

/**
 * wlan_hdd_cfg80211_extscan_get_valid_channels() - get ext scan valid channels
 * @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_extscan_get_valid_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_extscan_get_valid_channels(wiphy, wdev, data,
			data_len);
	vos_ssr_unprotect(__func__);

	return ret;
}

/**
 * hdd_extscan_update_dwell_time_limits() - update dwell times
 * @req_msg: Pointer to request message
 * @bkt_idx: Index of current bucket being processed
 * @active_min: minimum active dwell time
 * @active_max: maximum active dwell time
 * @passive_min: minimum passive dwell time
 * @passive_max: maximum passive dwell time
 *
 * Return: none
 */
static void hdd_extscan_update_dwell_time_limits(
			tpSirWifiScanCmdReqParams req_msg, uint32_t bkt_idx,
			uint32_t active_min, uint32_t active_max,
			uint32_t passive_min, uint32_t passive_max)
{
	/* update per-bucket dwell times */
	if (req_msg->buckets[bkt_idx].min_dwell_time_active >
			active_min) {
		req_msg->buckets[bkt_idx].min_dwell_time_active =
			active_min;
	}
	if (req_msg->buckets[bkt_idx].max_dwell_time_active <
			active_max) {
		req_msg->buckets[bkt_idx].max_dwell_time_active =
			active_max;
	}
	if (req_msg->buckets[bkt_idx].min_dwell_time_passive >
			passive_min) {
		req_msg->buckets[bkt_idx].min_dwell_time_passive =
			passive_min;
	}
	if (req_msg->buckets[bkt_idx].max_dwell_time_passive <
			passive_max) {
		req_msg->buckets[bkt_idx].max_dwell_time_passive =
			passive_max;
	}
	/* update dwell-time across all buckets */
	if (req_msg->min_dwell_time_active >
			req_msg->buckets[bkt_idx].min_dwell_time_active) {
		req_msg->min_dwell_time_active =
			req_msg->buckets[bkt_idx].min_dwell_time_active;
	}
	if (req_msg->max_dwell_time_active <
			req_msg->buckets[bkt_idx].max_dwell_time_active) {
		req_msg->max_dwell_time_active =
			req_msg->buckets[bkt_idx].max_dwell_time_active;
	}
	if (req_msg->min_dwell_time_passive >
			req_msg->buckets[bkt_idx].min_dwell_time_passive) {
		req_msg->min_dwell_time_passive =
			req_msg->buckets[bkt_idx].min_dwell_time_passive;
	}
	if (req_msg->max_dwell_time_passive >
			req_msg->buckets[bkt_idx].max_dwell_time_passive) {
		req_msg->max_dwell_time_passive =
			req_msg->buckets[bkt_idx].max_dwell_time_passive;
	}
}

/**
 * hdd_extscan_channel_max_reached() - channel max reached
 * @req: extscan request structure
 * @total_channels: total number of channels
 *
 * Return: true if total channels reached max, false otherwise
 */
static bool hdd_extscan_channel_max_reached(tSirWifiScanCmdReqParams *req,
					    uint8_t total_channels)
{
	if (total_channels == WLAN_EXTSCAN_MAX_CHANNELS) {
		hddLog(LOGW,
			FL("max #of channels %d reached, taking only first %d bucket(s)"),
			total_channels, req->numBuckets);
		return true;
	}
	return false;
}

static int hdd_extscan_start_fill_bucket_channel_spec(
			hdd_context_t *pHddCtx,
			tpSirWifiScanCmdReqParams 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;
	uint8_t bktIndex, j, numChannels, total_channels = 0;
	uint32_t expected_buckets;
	uint32_t chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};

	uint32_t min_dwell_time_active_bucket =
		pHddCtx->cfg_ini->extscan_active_max_chn_time;
	uint32_t max_dwell_time_active_bucket =
		pHddCtx->cfg_ini->extscan_active_max_chn_time;
	uint32_t min_dwell_time_passive_bucket =
		pHddCtx->cfg_ini->extscan_passive_max_chn_time;
	uint32_t max_dwell_time_passive_bucket =
		pHddCtx->cfg_ini->extscan_passive_max_chn_time;

	pReqMsg->min_dwell_time_active =
		pReqMsg->max_dwell_time_active =
			pHddCtx->cfg_ini->extscan_active_max_chn_time;

	pReqMsg->min_dwell_time_passive =
		pReqMsg->max_dwell_time_passive =
			pHddCtx->cfg_ini->extscan_passive_max_chn_time;

	expected_buckets = pReqMsg->numBuckets;
	pReqMsg->numBuckets = 0;
	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, NULL)) {
			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]);

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

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

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

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

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

		/* 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("Bucket spec Index: %d Wifi band: %d period: %d report events: %d max period: %u base: %u Step count: %u"),
				pReqMsg->buckets[bktIndex].bucket,
				pReqMsg->buckets[bktIndex].band,
				pReqMsg->buckets[bktIndex].period,
				pReqMsg->buckets[bktIndex].reportEvents,
				pReqMsg->buckets[bktIndex].max_period,
				pReqMsg->buckets[bktIndex].exponent,
				pReqMsg->buckets[bktIndex].step_count);

		/* start with known good values for bucket dwell times */
		pReqMsg->buckets[bktIndex].min_dwell_time_active =
		pReqMsg->buckets[bktIndex].max_dwell_time_active =
			pHddCtx->cfg_ini->extscan_active_max_chn_time;

		pReqMsg->buckets[bktIndex].min_dwell_time_passive =
		pReqMsg->buckets[bktIndex].max_dwell_time_passive =
			pHddCtx->cfg_ini->extscan_passive_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) {
			if (hdd_extscan_channel_max_reached(pReqMsg,
							    total_channels))
				return 0;

			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;
			}
			hddLog(LOG1, FL("before trimming, num_channels: %d"),
				numChannels);

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

			total_channels += 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 =
						pHddCtx->cfg_ini->
						extscan_passive_max_chn_time;
					/* reconfigure per-bucket dwell time */
					if (min_dwell_time_passive_bucket >
							pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs) {
						min_dwell_time_passive_bucket =
							pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs;
					}
					if (max_dwell_time_passive_bucket <
							pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs) {
						max_dwell_time_passive_bucket =
							pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs;
					}
				} else {
					pReqMsg->buckets[bktIndex].channels[j].
						passive = 0;
					pReqMsg->buckets[bktIndex].channels[j].
						dwellTimeMs =
						pHddCtx->cfg_ini->extscan_active_max_chn_time;
					/* reconfigure per-bucket dwell times */
					if (min_dwell_time_active_bucket >
							pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs) {
						min_dwell_time_active_bucket =
							pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs;
					}
					if (max_dwell_time_active_bucket <
							pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs) {
						max_dwell_time_active_bucket =
							pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs;
					}
				}

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

			hdd_extscan_update_dwell_time_limits(
					pReqMsg, bktIndex,
					min_dwell_time_active_bucket,
					max_dwell_time_active_bucket,
					min_dwell_time_passive_bucket,
					max_dwell_time_passive_bucket);

			hddLog(LOG1, FL("bktIndex:%d actv_min:%d actv_max:%d pass_min:%d pass_max:%d"),
					bktIndex,
					pReqMsg->buckets[bktIndex].min_dwell_time_active,
					pReqMsg->buckets[bktIndex].max_dwell_time_active,
					pReqMsg->buckets[bktIndex].min_dwell_time_passive,
					pReqMsg->buckets[bktIndex].max_dwell_time_passive);

			bktIndex++;
			pReqMsg->numBuckets++;
			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("before trimming: num channels %d"),
				pReqMsg->buckets[bktIndex].numChannels);
		pReqMsg->buckets[bktIndex].numChannels =
			VOS_MIN(pReqMsg->buckets[bktIndex].numChannels,
				(WLAN_EXTSCAN_MAX_CHANNELS - total_channels));
		hddLog(LOG1,
			FL("Num channels/bucket: %d total_channels: %d"),
			pReqMsg->buckets[bktIndex].numChannels,
			total_channels);
		if (hdd_extscan_channel_max_reached(pReqMsg, total_channels))
			return 0;

		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 ((j >= pReqMsg->buckets[bktIndex].numChannels) ||
			    hdd_extscan_channel_max_reached(pReqMsg,
							    total_channels))
				break;

			if (nla_parse(channel,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
				nla_data(channels), nla_len(channels),
				wlan_hdd_extscan_config_policy, NULL)) {
				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]);

			/* Override dwell time if required */
			if (pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs <
				pHddCtx->cfg_ini->extscan_active_min_chn_time ||
				pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs >
				pHddCtx->cfg_ini->extscan_active_max_chn_time) {
				hddLog(LOG1,
					FL("WiFi band is unspecified, dwellTime:%d"),
					pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);

				if (CSR_IS_CHANNEL_DFS(
					vos_freq_to_chan(
						pReqMsg->buckets[bktIndex].channels[j].channel))) {
					pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
						pHddCtx->cfg_ini->extscan_passive_max_chn_time;
				} else {
					pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
						pHddCtx->cfg_ini->extscan_active_max_chn_time;
				}
			}

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

			if (CSR_IS_CHANNEL_DFS(
						vos_freq_to_chan(
						pReqMsg->buckets[bktIndex].channels[j].channel))) {
				if(min_dwell_time_passive_bucket >
						pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs) {
					min_dwell_time_passive_bucket =
						pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs;
				}
				if(max_dwell_time_passive_bucket <
						pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs) {
					max_dwell_time_passive_bucket =
						pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs;
				}
			} else {
				if(min_dwell_time_active_bucket >
						pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs) {
					min_dwell_time_active_bucket =
						pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs;
				}
				if(max_dwell_time_active_bucket <
						pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs) {
					max_dwell_time_active_bucket =
						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);

			/* Override scan type if required */
			if (CSR_IS_CHANNEL_DFS(
				vos_freq_to_chan(
					pReqMsg->buckets[bktIndex].channels[j].channel))) {
				pReqMsg->buckets[bktIndex].channels[j].passive = TRUE;
			} else {
				pReqMsg->buckets[bktIndex].channels[j].passive = FALSE;
			}

			j++;
			total_channels++;
		}

		hdd_extscan_update_dwell_time_limits(
					pReqMsg, bktIndex,
					min_dwell_time_active_bucket,
					max_dwell_time_active_bucket,
					min_dwell_time_passive_bucket,
					max_dwell_time_passive_bucket);

		hddLog(LOG1, FL("bktIndex:%d actv_min:%d actv_max:%d pass_min:%d pass_max:%d"),
				bktIndex,
				pReqMsg->buckets[bktIndex].min_dwell_time_active,
				pReqMsg->buckets[bktIndex].max_dwell_time_active,
				pReqMsg->buckets[bktIndex].min_dwell_time_passive,
				pReqMsg->buckets[bktIndex].max_dwell_time_passive);

		bktIndex++;
		pReqMsg->numBuckets++;
	}

	hddLog(LOG1, FL("Global: actv_min:%d actv_max:%d pass_min:%d pass_max:%d"),
				pReqMsg->min_dwell_time_active,
				pReqMsg->max_dwell_time_active,
				pReqMsg->min_dwell_time_passive,
				pReqMsg->max_dwell_time_passive);

	return 0;
}

/*
 * hdd_extscan_map_usr_drv_config_flags() - map userspace to driver config flags
 * @config_flags - [input] configuration flags.
 *
 * This function maps user space received configuration flags to
 * driver representation.
 *
 * Return: configuration flags
 */
static uint32_t hdd_extscan_map_usr_drv_config_flags(uint32_t config_flags)
{
	uint32_t configuration_flags = 0;

	if (config_flags & EXTSCAN_LP_EXTENDED_BATCHING)
		configuration_flags |= EXTSCAN_LP_EXTENDED_BATCHING;

	return configuration_flags;
}

/*
 * 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
#define PARAM_CONFIG_FLAGS \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS

/**
 * __wlan_hdd_cfg80211_extscan_start() - start extscan
 * @wiphy: Pointer to wireless phy.
 * @wdev: Pointer to wireless device.
 * @data: Pointer to input data.
 * @data_len: Length of @data.
 *
 * Return: 0 on success, negative errno on failure
 */
static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
					   struct wireless_dev *wdev,
					   const void *data,
					   int data_len)
{
	tpSirWifiScanCmdReqParams 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];
	struct hdd_ext_scan_context *context;
	uint32_t request_id, num_buckets;
	eHalStatus status;
	int retval;
	unsigned long rc;

	ENTER();

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

	retval = wlan_hdd_validate_context(pHddCtx);
	if (0 != retval)
		return -EINVAL;

	if (!pHddCtx->cfg_ini->extscan_enabled) {
		hddLog(LOGE, FL("extscan not supported"));
		return -ENOTSUPP;
	}

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

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

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

	pReqMsg->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
	pReqMsg->sessionId = pAdapter->sessionId;

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

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

	/* Parse and fetch report threshold percent */
	if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
		hddLog(LOGE, FL("attr report_threshold percent failed"));
		goto fail;
	}
	pReqMsg->report_threshold_percent = nla_get_u8(
		tb[PARAM_RPT_THRHLD_PERCENT]);

	/* 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->report_threshold_num_scans = nla_get_u8(
		tb[PARAM_RPT_THRHLD_NUM_SCANS]);
	hddLog(LOG1, FL("Req Id: %d Session Id: %d Base Period: %d Max AP per Scan: %d Rpt Thld percent: %d Rpt Thld num scans: %d"),
		pReqMsg->requestId, pReqMsg->sessionId,
		pReqMsg->basePeriod, pReqMsg->maxAPperScan,
		pReqMsg->report_threshold_percent,
		pReqMsg->report_threshold_num_scans);

	/* Parse and fetch number of buckets */
	if (!tb[PARAM_NUM_BUCKETS]) {
		hddLog(LOGE, FL("attr number of buckets failed"));
		goto fail;
	}
	num_buckets = nla_get_u8(tb[PARAM_NUM_BUCKETS]);
	if (num_buckets > WLAN_EXTSCAN_MAX_BUCKETS) {
		hddLog(LOGW,
			FL("Exceeded MAX number of buckets: %d"),
			WLAN_EXTSCAN_MAX_BUCKETS);
		num_buckets = WLAN_EXTSCAN_MAX_BUCKETS;
	}
	hddLog(LOG1, FL("Input: Number of Buckets %d"), num_buckets);
	pReqMsg->numBuckets = num_buckets;

	/* This is optional attribute, if not present set it to 0 */
	if (!tb[PARAM_CONFIG_FLAGS])
		pReqMsg->configuration_flags = 0;
	else
		pReqMsg->configuration_flags =
			hdd_extscan_map_usr_drv_config_flags(
				nla_get_u32(tb[PARAM_CONFIG_FLAGS]));

	hddLog(LOG1, FL("Configuration flags: %u"),
				pReqMsg->configuration_flags);

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

	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;
	context->buckets_scanned = 0;
	spin_unlock(&hdd_context_lock);

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

	pHddCtx->ext_scan_start_since_boot = vos_get_monotonic_boottime();
	hddLog(LOG1, FL("Timestamp since boot: %llu"),
			pHddCtx->ext_scan_start_since_boot);

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

/**
 * wlan_hdd_cfg80211_extscan_start() - start extscan
 * @wiphy: Pointer to wireless phy.
 * @wdev: Pointer to wireless device.
 * @data: Pointer to input data.
 * @data_len: Length of @data.
 *
 * Return: 0 on success, negative errno on failure
 */
static int wlan_hdd_cfg80211_extscan_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_extscan_start(wiphy, wdev, data, data_len);
	vos_ssr_unprotect(__func__);

	return ret;
}

/*
 * define short names for the global vendor params
 * used by wlan_hdd_cfg80211_extscan_stop()
 */
#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

/**
 * wlan_hdd_cfg80211_extscan_stop() - stop extscan
 * @wiphy: Pointer to wireless phy.
 * @wdev: Pointer to wireless device.
 * @data: Pointer to input data.
 * @data_len: Length of @data.
 *
 * Return: 0 on success, negative errno on failure
 */
static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
					  struct wireless_dev *wdev,
					  const void *data,
					  int data_len)
{
	tpSirExtScanStopReqParams 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 hdd_ext_scan_context *context;
	struct nlattr *tb[PARAM_MAX + 1];
	uint32_t request_id;
	eHalStatus status;
	int retval;
	unsigned long rc;

	ENTER();

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

	retval = wlan_hdd_validate_context(pHddCtx);
	if (0 != retval)
		return -EINVAL;

	if (!pHddCtx->cfg_ini->extscan_enabled) {
		hddLog(LOGE, FL("extscan not supported"));
		return -ENOTSUPP;
	}
	if (nla_parse(tb, PARAM_MAX, data, data_len,
			wlan_hdd_extscan_config_policy, NULL)) {
		hddLog(LOGE, FL("Invalid ATTR"));
		return -EINVAL;
	}

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

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

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

	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_ExtScanStop(pHddCtx->hHal, pReqMsg);
	if (!HAL_STATUS_SUCCESS(status)) {
		hddLog(LOGE,
			FL("sme_ExtScanStop failed(err=%d)"), status);
		goto fail;
	}

	/* 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);
	}
	EXIT();
	return retval;

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

/**
 * wlan_hdd_cfg80211_extscan_stop() - stop extscan
 * @wiphy: Pointer to wireless phy.
 * @wdev: Pointer to wireless device.
 * @data: Pointer to input data.
 * @data_len: Length of @data.
 *
 * Return: 0 on success, negative errno on failure
 */
static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
                                        struct wireless_dev *wdev,
                                        const void *data, int data_len)
{
	int ret = 0;

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

	return ret;
}

/*
 * done with short names for the global vendor params
 * used by wlan_hdd_cfg80211_extscan_stop()
 */
#undef PARAM_MAX
#undef PARAM_REQUEST_ID

static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
                                        struct wireless_dev *wdev,
                                        const void *data,
                                        int data_len)
{
    tpSirExtScanResetBssidHotlistReqParams 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 hdd_ext_scan_context *context;
    uint32_t request_id;
    eHalStatus status;
    int retval;
    unsigned long rc;

    ENTER();

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

    retval = wlan_hdd_validate_context(pHddCtx);
    if (0 != retval)
        return -EINVAL;

    if (!pHddCtx->cfg_ini->extscan_enabled) {
        hddLog(LOGE, FL("extscan not supported"));
        return -ENOTSUPP;
    }
    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
                    data, data_len,
                    wlan_hdd_extscan_config_policy, NULL)) {
        hddLog(LOGE, FL("Invalid ATTR"));
        return -EINVAL;
    }

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

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

    pReqMsg->requestId = nla_get_u32(
              tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);

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

    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_ResetBssHotlist(pHddCtx->hHal, pReqMsg);
    if (!HAL_STATUS_SUCCESS(status)) {
        hddLog(LOGE, FL("sme_ResetBssHotlist failed(err=%d)"), status);
        goto fail;
    }

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

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

/**
 * wlan_hdd_cfg80211_extscan_reset_bssid_hotlist() - reset bssid hot list
 * @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_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
                                        struct wireless_dev *wdev,
                                        const void *data, int data_len)
{
	int ret = 0;

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

	return ret;
}

static int __wlan_hdd_cfg80211_extscan_reset_significant_change(
                                        struct wiphy *wiphy,
                                        struct wireless_dev *wdev,
                                        const void *data,
                                        int data_len)
{
    tpSirExtScanResetSignificantChangeReqParams 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 hdd_ext_scan_context *context;
    uint32_t request_id;
    eHalStatus status;
    int retval;
    unsigned long rc;

    ENTER();

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

    retval = wlan_hdd_validate_context(pHddCtx);
    if (0 != retval)
         return -EINVAL;

    if (!pHddCtx->cfg_ini->extscan_enabled) {
        hddLog(LOGE, FL("extscan not supported"));
        return -ENOTSUPP;
    }
    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
                    data, data_len,
                    wlan_hdd_extscan_config_policy, NULL)) {
        hddLog(LOGE, FL("Invalid ATTR"));
        return -EINVAL;
    }

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

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

    pReqMsg->requestId = nla_get_u32(
              tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);

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

    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_ResetSignificantChange(pHddCtx->hHal, pReqMsg);
    if (!HAL_STATUS_SUCCESS(status)) {
        hddLog(LOGE, FL("sme_ResetSignificantChange failed(err=%d)"), status);
        goto fail;
    }

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

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

/**
 * wlan_hdd_cfg80211_extscan_reset_significant_change() - reset significant
 *							change
 * @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_extscan_reset_significant_change(struct wiphy *wiphy,
						struct wireless_dev *wdev,
						const void *data, int data_len)
{
	int ret = 0;

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

	return ret;
}


/**
 * hdd_extscan_epno_fill_network_list() - epno fill network list
 * @hddctx: HDD context
 * @req_msg: request message
 * @tb: vendor attribute table
 *
 * This function reads the network block NL vendor attributes from %tb and
 * fill in the epno request message.
 *
 * Return: 0 on success, error number otherwise
 */
static int hdd_extscan_epno_fill_network_list(
			hdd_context_t *hddctx,
			struct wifi_epno_params *req_msg,
			struct nlattr **tb)
{
	struct nlattr *network[QCA_WLAN_VENDOR_ATTR_PNO_MAX + 1];
	struct nlattr *networks;
	int rem1, ssid_len;
	uint8_t index, *ssid;
	uint32_t expected_networks;

	expected_networks = req_msg->num_networks;
	index = 0;
	if (!tb[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORKS_LIST]) {
		hddLog(LOGE, FL("attr networks list failed"));
		return -EINVAL;
	}
	nla_for_each_nested(networks,
			    tb[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORKS_LIST],
			    rem1) {

		if (index == expected_networks) {
			hddLog(LOGW, FL("ignoring excess networks"));
			break;
		}

		if (nla_parse(network, QCA_WLAN_VENDOR_ATTR_PNO_MAX,
			      nla_data(networks), nla_len(networks),
			      wlan_hdd_pno_config_policy, NULL)) {
			hddLog(LOGE, FL("nla_parse failed"));
			return -EINVAL;
		}

		/* Parse and fetch ssid */
		if (!network[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_SSID]) {
			hddLog(LOGE, FL("attr network ssid failed"));
			return -EINVAL;
		}
		ssid_len = nla_len(
			network[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_SSID]);

		/* nla_parse will detect overflow but not underflow */
		if (0 == ssid_len) {
			hddLog(LOGE, FL("zero ssid length"));
			return -EINVAL;
		}

		/* Decrement by 1, don't count null character */
		ssid_len--;

		req_msg->networks[index].ssid.length = ssid_len;
		hddLog(LOG1, FL("network ssid length %d"), ssid_len);
		ssid = nla_data(network[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_SSID]);
		vos_mem_copy(req_msg->networks[index].ssid.ssId, ssid, ssid_len);
		hddLog(LOG1, FL("Ssid: %.*s"),
			req_msg->networks[index].ssid.length,
			req_msg->networks[index].ssid.ssId);

		/* Parse and fetch epno flags */
		if (!network[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_FLAGS]) {
			hddLog(LOGE, FL("attr epno flags failed"));
			return -EINVAL;
		}
		req_msg->networks[index].flags = nla_get_u8(
			network[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_FLAGS]);
		hddLog(LOG1, FL("flags %u"), req_msg->networks[index].flags);

		/* Parse and fetch auth bit */
		if (!network[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_AUTH_BIT]) {
			hddLog(LOGE, FL("attr auth bit failed"));
			return -EINVAL;
		}
		req_msg->networks[index].auth_bit_field = nla_get_u8(
			network[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_AUTH_BIT]);
		hddLog(LOG1, FL("auth bit %u"),
			req_msg->networks[index].auth_bit_field);

		index++;
	}
	req_msg->num_networks = index;
	return 0;
}

/**
 * __wlan_hdd_cfg80211_set_epno_list() - epno set network list
 * @wiphy: wiphy
 * @wdev: pointer to wireless dev
 * @data: data pointer
 * @data_len: data length
 *
 * This function reads the NL vendor attributes from %tb and
 * fill in the epno request message.
 *
 * Return: 0 on success, error number otherwise
 */
static int __wlan_hdd_cfg80211_set_epno_list(struct wiphy *wiphy,
					     struct wireless_dev *wdev,
					     const void *data,
					     int data_len)
{
	struct wifi_epno_params *req_msg = NULL;
	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[
		QCA_WLAN_VENDOR_ATTR_PNO_MAX + 1];
	eHalStatus status;
	uint32_t num_networks, len;
	int ret_val;

	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 -EINVAL;
	}

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

	/* Parse and fetch number of networks */
	if (!tb[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_NUM_NETWORKS]) {
		hddLog(LOGE, FL("attr num networks failed"));
		return -EINVAL;
	}
	/*
	 * num_networks is also used as EPNO SET/RESET request.
	 * if num_networks is zero then it is treated as RESET.
	 */
	num_networks = nla_get_u32(
		tb[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_NUM_NETWORKS]);

	if (num_networks > MAX_EPNO_NETWORKS) {
		hddLog(LOG1,
		       FL("input num_networks: %d exceeded max: %d, hence reset to: %d"),
		       num_networks, MAX_EPNO_NETWORKS, MAX_EPNO_NETWORKS);
		num_networks = MAX_EPNO_NETWORKS;
	}

	hddLog(LOG1, FL("num networks %u"), num_networks);
	len = sizeof(*req_msg) +
			(num_networks * sizeof(struct wifi_epno_network));

	req_msg = vos_mem_malloc(len);
	if (!req_msg) {
		hddLog(LOGE, FL("vos_mem_malloc failed"));
		return -ENOMEM;
	}
	vos_mem_zero(req_msg, len);
	req_msg->num_networks = num_networks;

	/* Parse and fetch request Id */
	if (!tb[QCA_WLAN_VENDOR_ATTR_PNO_CONFIG_REQUEST_ID]) {
		hddLog(LOGE, FL("attr request id failed"));
		goto fail;
	}
	req_msg->request_id = nla_get_u32(
	    tb[QCA_WLAN_VENDOR_ATTR_PNO_CONFIG_REQUEST_ID]);

	req_msg->session_id = adapter->sessionId;
	hddLog(LOG1, FL("Req Id %u Session Id %d"),
		req_msg->request_id, req_msg->session_id);

	if (num_networks) {

		/* Parse and fetch min_5ghz_rssi */
		if (!tb[QCA_WLAN_VENDOR_ATTR_EPNO_MIN5GHZ_RSSI]) {
			hddLog(LOGE, FL("min_5ghz_rssi id failed"));
			goto fail;
		}
		req_msg->min_5ghz_rssi = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_EPNO_MIN5GHZ_RSSI]);

		/* Parse and fetch min_24ghz_rssi */
		if (!tb[QCA_WLAN_VENDOR_ATTR_EPNO_MIN24GHZ_RSSI]) {
			hddLog(LOGE, FL("min_24ghz_rssi id failed"));
			goto fail;
		}
		req_msg->min_24ghz_rssi = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_EPNO_MIN24GHZ_RSSI]);

		/* Parse and fetch initial_score_max */
		if (!tb[QCA_WLAN_VENDOR_ATTR_EPNO_INITIAL_SCORE_MAX]) {
			hddLog(LOGE, FL("initial_score_max id failed"));
			goto fail;
		}
		req_msg->initial_score_max = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_EPNO_INITIAL_SCORE_MAX]);

		/* Parse and fetch current_connection_bonus */
		if (!tb[QCA_WLAN_VENDOR_ATTR_EPNO_CURRENT_CONNECTION_BONUS]) {
			hddLog(LOGE, FL("current_connection_bonus id failed"));
			goto fail;
		}
		req_msg->current_connection_bonus = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_EPNO_CURRENT_CONNECTION_BONUS]
			);

		/* Parse and fetch same_network_bonus */
		if (!tb[QCA_WLAN_VENDOR_ATTR_EPNO_SAME_NETWORK_BONUS]) {
			hddLog(LOGE, FL("same_network_bonus id failed"));
			goto fail;
		}
		req_msg->same_network_bonus = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_EPNO_SAME_NETWORK_BONUS]);

		/* Parse and fetch secure_bonus */
		if (!tb[QCA_WLAN_VENDOR_ATTR_EPNO_SECURE_BONUS]) {
			hddLog(LOGE, FL("secure_bonus id failed"));
			goto fail;
		}
		req_msg->secure_bonus = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_EPNO_SECURE_BONUS]);

		/* Parse and fetch band_5ghz_bonus */
		if (!tb[QCA_WLAN_VENDOR_ATTR_EPNO_BAND5GHZ_BONUS]) {
			hddLog(LOGE, FL("band_5ghz_bonus id failed"));
			goto fail;
		}
		req_msg->band_5ghz_bonus = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_EPNO_BAND5GHZ_BONUS]);

		hddLog(LOG1,
		       FL("min_5ghz_rssi: %d min_24ghz_rssi: %d initial_score_max: %d current_connection_bonus: %d"),
		       req_msg->min_5ghz_rssi,
		       req_msg->min_24ghz_rssi,
		       req_msg->initial_score_max,
		       req_msg->current_connection_bonus);
		hddLog(LOG1,
		       FL("same_network_bonus: %d secure_bonus: %d band_5ghz_bonus: %d"),
		       req_msg->same_network_bonus,
		       req_msg->secure_bonus,
		       req_msg->band_5ghz_bonus);

		if (hdd_extscan_epno_fill_network_list(hdd_ctx, req_msg, tb))
			goto fail;

	}

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

	EXIT();
	vos_mem_free(req_msg);
	return 0;

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

/**
 * wlan_hdd_cfg80211_set_epno_list() - epno set network list
 * @wiphy: wiphy
 * @wdev: pointer to wireless dev
 * @data: data pointer
 * @data_len: data length
 *
 * This function reads the NL vendor attributes from %tb and
 * fill in the epno request message.
 *
 * Return: 0 on success, error number otherwise
 */
static int wlan_hdd_cfg80211_set_epno_list(struct wiphy *wiphy,
					   struct wireless_dev *wdev,
					   const void *data,
					   int data_len)
{
	int ret;

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

	return ret;
}

/**
 * hdd_extscan_passpoint_fill_network_list() - passpoint fill network list
 * @hddctx: HDD context
 * @req_msg: request message
 * @tb: vendor attribute table
 *
 * This function reads the network block NL vendor attributes from %tb and
 * fill in the passpoint request message.
 *
 * Return: 0 on success, error number otherwise
 */
static int hdd_extscan_passpoint_fill_network_list(
			hdd_context_t *hddctx,
			struct wifi_passpoint_req *req_msg,
			struct nlattr **tb)
{
	struct nlattr *network[QCA_WLAN_VENDOR_ATTR_PNO_MAX + 1];
	struct nlattr *networks;
	int rem1, len;
	uint8_t index;
	uint32_t expected_networks;

	expected_networks = req_msg->num_networks;
	index = 0;

	if (!tb[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NETWORK_ARRAY]) {
		hddLog(LOGE, FL("attr network array failed"));
		return -EINVAL;
	}
	nla_for_each_nested(networks,
		tb[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NETWORK_ARRAY],
		rem1) {

		if (index == expected_networks) {
			hddLog(LOGW, FL("ignoring excess networks"));
			break;
		}

		if (nla_parse(network,
			QCA_WLAN_VENDOR_ATTR_PNO_MAX,
			nla_data(networks), nla_len(networks),
			wlan_hdd_pno_config_policy, NULL)) {
			hddLog(LOGE, FL("nla_parse failed"));
			return -EINVAL;
		}

		/* Parse and fetch identifier */
		if (!network[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ID]) {
			hddLog(LOGE, FL("attr passpoint id failed"));
			return -EINVAL;
		}
		req_msg->networks[index].id = nla_get_u32(
			network[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ID]);
		hddLog(LOG1, FL("Id %u"), req_msg->networks[index].id);

		/* Parse and fetch realm */
		if (!network[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_REALM]) {
			hddLog(LOGE, FL("attr realm failed"));
			return -EINVAL;
		}
		len = nla_len(
			network[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_REALM]);
		if (len < 0 || len > SIR_PASSPOINT_REALM_LEN) {
			hddLog(LOGE, FL("Invalid realm size %d"), len);
			return -EINVAL;
		}
		vos_mem_copy(req_msg->networks[index].realm,
				nla_data(network[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_REALM]),
				len);
		hddLog(LOG1, FL("realm len %d"), len);
		hddLog(LOG1, FL("realm: %s"), req_msg->networks[index].realm);

		/* Parse and fetch roaming consortium ids */
		if (!network[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ROAM_CNSRTM_ID]) {
			hddLog(LOGE, FL("attr roaming consortium ids failed"));
			return -EINVAL;
		}
		nla_memcpy(&req_msg->networks[index].roaming_consortium_ids,
			network[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ROAM_CNSRTM_ID],
			sizeof(req_msg->networks[0].roaming_consortium_ids));
		hddLog(LOG1, FL("roaming consortium ids"));
		VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
				req_msg->networks[index].roaming_consortium_ids,
				sizeof(req_msg->networks[0].roaming_consortium_ids));

		/* Parse and fetch plmn */
		if (!network[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ROAM_PLMN]) {
			hddLog(LOGE, FL("attr plmn failed"));
			return -EINVAL;
		}
		nla_memcpy(&req_msg->networks[index].plmn,
			network[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ROAM_PLMN],
			SIR_PASSPOINT_PLMN_LEN);
		hddLog(LOG1, FL("plmn %02x:%02x:%02x"),
			req_msg->networks[index].plmn[0],
			req_msg->networks[index].plmn[1],
			req_msg->networks[index].plmn[2]);

		index++;
	}
	req_msg->num_networks = index;
	return 0;
}

/**
 * __wlan_hdd_cfg80211_set_passpoint_list() - set passpoint network list
 * @wiphy: wiphy
 * @wdev: pointer to wireless dev
 * @data: data pointer
 * @data_len: data length
 *
 * This function reads the NL vendor attributes from %tb and
 * fill in the passpoint request message.
 *
 * Return: 0 on success, error number otherwise
 */
static int __wlan_hdd_cfg80211_set_passpoint_list(struct wiphy *wiphy,
						  struct wireless_dev *wdev,
						  const void *data,
						  int data_len)
{
	struct wifi_passpoint_req *req_msg = NULL;
	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[QCA_WLAN_VENDOR_ATTR_PNO_MAX + 1];
	eHalStatus status;
	uint32_t num_networks = 0;
	int ret;

	ENTER();

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

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

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

	/* Parse and fetch number of networks */
	if (!tb[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NUM]) {
		hddLog(LOGE, FL("attr num networks failed"));
		return -EINVAL;
	}
	num_networks = nla_get_u32(
		tb[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NUM]);
	if (num_networks > SIR_PASSPOINT_LIST_MAX_NETWORKS) {
		hddLog(LOGE, FL("num networks %u exceeds max %u"),
		       num_networks, SIR_PASSPOINT_LIST_MAX_NETWORKS);
		return -EINVAL;
	}

	hddLog(LOG1, FL("num networks %u"), num_networks);
	req_msg = vos_mem_malloc(sizeof(*req_msg) +
			(num_networks * sizeof(req_msg->networks[0])));
	if (!req_msg) {
		hddLog(LOGE, FL("vos_mem_malloc failed"));
		return -ENOMEM;
	}
	req_msg->num_networks = num_networks;

	/* Parse and fetch request Id */
	if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
		hddLog(LOGE, FL("attr request id failed"));
		goto fail;
	}
	req_msg->request_id = nla_get_u32(
	    tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);

	req_msg->session_id = adapter->sessionId;
	hddLog(LOG1, FL("Req Id %u Session Id %d"), req_msg->request_id,
			req_msg->session_id);

	if (hdd_extscan_passpoint_fill_network_list(hdd_ctx, req_msg, tb))
		goto fail;

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

	EXIT();
	vos_mem_free(req_msg);
	return 0;

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

/**
 * wlan_hdd_cfg80211_set_passpoint_list() - set passpoint network list
 * @wiphy: wiphy
 * @wdev: pointer to wireless dev
 * @data: data pointer
 * @data_len: data length
 *
 * This function reads the NL vendor attributes from %tb and
 * fill in the passpoint request message.
 *
 * Return: 0 on success, error number otherwise
 */
static int wlan_hdd_cfg80211_set_passpoint_list(struct wiphy *wiphy,
						struct wireless_dev *wdev,
						const void *data,
						int data_len)
{
	int ret;

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

	return ret;
}

/**
 * __wlan_hdd_cfg80211_reset_passpoint_list() - reset passpoint network list
 * @wiphy: wiphy
 * @wdev: pointer to wireless dev
 * @data: data pointer
 * @data_len: data length
 *
 * This function resets passpoint networks list
 *
 * Return: 0 on success, error number otherwise
 */
static int __wlan_hdd_cfg80211_reset_passpoint_list(struct wiphy *wiphy,
						    struct wireless_dev *wdev,
						    const void *data,
						    int data_len)
{
	struct wifi_passpoint_req *req_msg = NULL;
	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[QCA_WLAN_VENDOR_ATTR_PNO_MAX + 1];
	eHalStatus status;
	int ret;

	ENTER();

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

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

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

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

	/* Parse and fetch request Id */
	if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
		hddLog(LOGE, FL("attr request id failed"));
		goto fail;
	}
	req_msg->request_id = nla_get_u32(
	    tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);

	req_msg->session_id = adapter->sessionId;
	hddLog(LOG1, FL("Req Id %u Session Id %d"),
			req_msg->request_id, req_msg->session_id);

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

	EXIT();
	vos_mem_free(req_msg);
	return 0;

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

/**
 * wlan_hdd_cfg80211_reset_passpoint_list() - reset passpoint network list
 * @wiphy: wiphy
 * @wdev: pointer to wireless dev
 * @data: data pointer
 * @data_len: data length
 *
 * This function resets passpoint networks list
 *
 * Return: 0 on success, error number otherwise
 */
static int wlan_hdd_cfg80211_reset_passpoint_list(struct wiphy *wiphy,
						struct wireless_dev *wdev,
						const void *data,
						int data_len)
{
	int ret;

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

	return ret;
}
#endif /* FEATURE_WLAN_EXTSCAN */

/**
 * wlan_hdd_cfg80211_set_feature() - Set the bitmask for supported features
 * @feature_flags:   pointer to the byte array of features.
 * @feature:         Feature to be turned ON in the byte array.
 *
 * Return:  None
 *
 * This is called to turn ON or SET the feature flag for the requested feature.
 */
#define NUM_BITS_IN_BYTE	8
void wlan_hdd_cfg80211_set_feature(uint8_t *feature_flags, uint8_t feature)
{
	uint32_t index;
	uint8_t bit_mask;

	index = feature / NUM_BITS_IN_BYTE;
	bit_mask = 1 << (feature % NUM_BITS_IN_BYTE);
	feature_flags[index] |= bit_mask;
}

/**
 * __wlan_hdd_cfg80211_get_features() - Get the Driver Supported features
 * @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 supported feature set to
 * supplicant upon a request/query from the supplicant.
 *
 * Return:   Return the Success or Failure code.
 */
static int
__wlan_hdd_cfg80211_get_features(struct wiphy *wiphy,
		struct wireless_dev *wdev,
		const void *data, int data_len)
{
	struct sk_buff *skb = NULL;
	uint8_t feature_flags[(NUM_QCA_WLAN_VENDOR_FEATURES + 7) / 8] = {0};
	int ret_val;
	hdd_context_t *pHddCtx = wiphy_priv(wiphy);

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

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

#ifdef WLAN_FEATURE_ROAM_OFFLOAD
	if (pHddCtx->cfg_ini->isRoamOffloadEnabled) {
		hddLog(LOG1, FL("Key Mgmt Offload is supported"));
		wlan_hdd_cfg80211_set_feature (feature_flags,
				QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD);
	}
#endif

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

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

	if (nla_put(skb,
		QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS,
		sizeof(feature_flags), feature_flags))
		goto nla_put_failure;

	return cfg80211_vendor_cmd_reply(skb);

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

/**
 * wlan_hdd_cfg80211_get_features() - Get the Driver Supported features
 * @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 supported feature set to
 * supplicant upon a request/query from the supplicant.
 *
 * Return:   Return the Success or Failure code.
 */
static int
wlan_hdd_cfg80211_get_features(struct wiphy *wiphy,
		struct wireless_dev *wdev,
		const void *data, int data_len)
{
	int ret;

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

	return ret;
}

#ifdef WLAN_FEATURE_LINK_LAYER_STATS

static bool 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 bool put_wifi_peer_info( tpSirWifiPeerInfo stats,
                               struct sk_buff *vendor_event)
{
    u32 i = 0;
    tpSirWifiRateStat pRateStats;

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

    if (stats->numRate)
    {
        struct nlattr *rateInfo;
        struct nlattr *rates;

        rateInfo = nla_nest_start(vendor_event,
                            QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
        if (rateInfo == NULL)
            goto error;

        for (i = 0; i < stats->numRate; i++)
        {
            pRateStats = (tpSirWifiRateStat )((uint8 *)
                                          stats->rateStats +
                                          (i * sizeof(tSirWifiRateStat)));
            rates = nla_nest_start(vendor_event, i);
            if (rates == NULL)
                goto error;

            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 bool 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_PENDING_MSDU,
                    stats->pending_msdu ) ||
        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 bool put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
                                    struct sk_buff *vendor_event)
{
    if (nla_put_u32(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,
                VOS_MAC_ADDR_SIZE, 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 bool put_wifi_iface_stats(tpSirWifiIfaceStat pWifiIfaceStat,
                                 u32 num_peers,
                                 struct sk_buff *vendor_event)
{
    int i = 0;
    struct nlattr *wmmInfo;
    struct nlattr *wmmStats;
    u64 average_tsf_offset;

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

    }

    average_tsf_offset =  pWifiIfaceStat->avg_bcn_spread_offset_high;
    average_tsf_offset =  (average_tsf_offset << 32) |
        pWifiIfaceStat->avg_bcn_spread_offset_low ;

    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_NUM_PEERS,
                    num_peers) ||
        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_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
                    pWifiIfaceStat->rssiMgmt) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
                    pWifiIfaceStat->rssiData) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
                    pWifiIfaceStat->rssiAck) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
                    pWifiIfaceStat->is_leaky_ap) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
                    pWifiIfaceStat->avg_rx_frms_leaked) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
                    pWifiIfaceStat->rx_leak_window) ||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
        nla_put_u64_64bit(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
                    average_tsf_offset,
                   QCA_WLAN_VENDOR_ATTR_LL_STATS_PAD) ||
#else
        nla_put_u64(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
                    average_tsf_offset) ||
#endif
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RTS_SUCC_CNT,
                    pWifiIfaceStat->rts_succ_cnt) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RTS_FAIL_CNT,
                    pWifiIfaceStat->rts_fail_cnt) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_PPDU_SUCC_CNT,
                    pWifiIfaceStat->ppdu_succ_cnt) ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_PPDU_FAIL_CNT,
                    pWifiIfaceStat->ppdu_fail_cnt))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("QCA_WLAN_VENDOR_ATTR put fail"));
        return FALSE;
    }

    wmmInfo = nla_nest_start(vendor_event,
                            QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
    if (wmmInfo == NULL)
        return FALSE;

    for (i = 0; i < WIFI_AC_MAX; i++)
    {
        wmmStats = nla_nest_start(vendor_event, i);
        if (wmmStats == NULL)
            return FALSE;

        if (FALSE == put_wifi_wmm_ac_stat(
                &pWifiIfaceStat->AccessclassStats[i],
                vendor_event))
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                   FL("put_wifi_wmm_ac_stat Fail"));
            return FALSE;
        }

        nla_nest_end(vendor_event, wmmStats);
    }
    nla_nest_end(vendor_event, wmmInfo);
    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 Interface Mode as STA for all the unsupported modes */
        return WIFI_INTERFACE_STA;
    }
}

static bool 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, VOS_MAC_ADDR_SIZE);
            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 void hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
                                              u32 more_data,
                                              tpSirWifiPeerStat pData)
{
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    tpSirWifiPeerStat   pWifiPeerStat;
    tpSirWifiPeerInfo   pWifiPeerInfo;
    struct sk_buff *vendor_event;
    int status, i;
    struct nlattr *peers;
    int numRate;

    ENTER();

    pWifiPeerStat = pData;
    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
        return;

    hddLog(VOS_TRACE_LEVEL_INFO,
           "LL_STATS_PEER_ALL : numPeers %u, more data = %u",
           pWifiPeerStat->numPeers,
           more_data);

    /*
     * 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_RESULTS_MORE_DATA,
                    more_data) ||
        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;
    }


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

    if (pWifiPeerStat->numPeers)
    {
        struct nlattr *peerInfo;
        peerInfo = nla_nest_start(vendor_event,
                              QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
        if (peerInfo == NULL) {
            hddLog(LOGE, FL("nla_nest_start failed"));
            kfree_skb(vendor_event);
            return;
        }

        for (i = 1; i <= pWifiPeerStat->numPeers; i++)
        {
            peers = nla_nest_start(vendor_event, i);
            if (peers == NULL) {
                hddLog(LOGE, FL("nla_nest_start failed"));
                kfree_skb(vendor_event);
                return;
            }

            numRate = pWifiPeerInfo->numRate;

            if (FALSE == put_wifi_peer_info(
                    pWifiPeerInfo, vendor_event))
            {
                hddLog(VOS_TRACE_LEVEL_ERROR, FL("put_wifi_peer_info fail"));
                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 void hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
                                               tpSirWifiIfaceStat pData,
                                               u32 num_peers)
{
    tpSirWifiIfaceStat  pWifiIfaceStat;
    struct sk_buff *vendor_event;
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    int status;

    ENTER();

    pWifiIfaceStat = pData;
    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;
    }

    hddLog(VOS_TRACE_LEVEL_INFO, "WMI_LINK_STATS_IFACE Data");

    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(pWifiIfaceStat, num_peers, vendor_event)) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("put_wifi_iface_stats fail"));
        kfree_skb(vendor_event);
        return;
    }

    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 void hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
                                               u32 more_data,
                                               tpSirWifiRadioStat pData,
                                               u32 num_radio)
{
    int status, i;
    tpSirWifiRadioStat  pWifiRadioStat;
    tpSirWifiChannelStats pWifiChannelStats;
    struct sk_buff *vendor_event;
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);

    ENTER();

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

    hddLog(LOG1,
           "LL_STATS_RADIO"
           " number of radios: %u radio: %d onTime: %u"
           " txTime: %u rxTime: %u onTimeScan: %u onTimeNbd: %u"
           " onTimeGscan: %u onTimeRoamScan: %u"
           " onTimePnoScan: %u onTimeHs20: %u"
           " numChannels: %u total_num_tx_power_levels: %u",
           num_radio, pWifiRadioStat->radio, pWifiRadioStat->onTime,
           pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
           pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
           pWifiRadioStat->onTimeGscan, pWifiRadioStat->onTimeRoamScan,
           pWifiRadioStat->onTimePnoScan, pWifiRadioStat->onTimeHs20,
           pWifiRadioStat->numChannels,
           pWifiRadioStat->total_num_tx_power_levels);

    /*
     * 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_RESULTS_MORE_DATA,
                    more_data)                  ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
                    num_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_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_GSCAN,
                    pWifiRadioStat->onTimeGscan)||
        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_TX_LEVELS,
                    pWifiRadioStat->total_num_tx_power_levels)    ||
        nla_put_u32(vendor_event,
                    QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
                    pWifiRadioStat->numChannels)) {
        hddLog(LOGE, FL("QCA_WLAN_VENDOR_ATTR put fail"));

        kfree_skb(vendor_event);
        return ;
    }

    if (pWifiRadioStat->total_num_tx_power_levels) {
        if (nla_put(vendor_event,
                QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME_PER_LEVEL,
                sizeof(u32) * pWifiRadioStat->total_num_tx_power_levels,
                pWifiRadioStat->tx_time_per_power_level)) {
            hddLog(LOGE, FL("ATTR_LL_STATS_RADIO_TX_TIME_PER_LEVEL put fail"));
            kfree_skb(vendor_event);
            return;
        }
    }

    if (pWifiRadioStat->numChannels)
    {
        struct nlattr *chList;
        struct nlattr *chInfo;

        chList = nla_nest_start(vendor_event,
                            QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
        if (chList == NULL) {
            hddLog(LOGE, FL("nla_nest_start failed"));
            kfree_skb(vendor_event);
            return;
        }

        for (i = 0; i < pWifiRadioStat->numChannels; i++)
        {
            pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
                                             pWifiRadioStat->channels +
                                            (i * sizeof(tSirWifiChannelStats)));

            chInfo = nla_nest_start(vendor_event, i);
            if (chInfo == NULL) {
                hddLog(LOGE, FL("nla_nest_start failed"));
                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("nla_put 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();
}

/*
 * wlan_hdd_cfg80211_link_layer_stats_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 wlan_hdd_cfg80211_link_layer_stats_callback(void *ctx, int indType,
                                                        void *pRsp)
{
    hdd_adapter_t *pAdapter = NULL;
    struct hdd_ll_stats_context *context;
    hdd_context_t *pHddCtx = ctx;
    tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
    int status;

    status = wlan_hdd_validate_context(pHddCtx);

    if (0 != status)
        return;

    pAdapter = hdd_get_adapter_by_vdev(pHddCtx,
                                       linkLayerStatsResults->ifaceId);

    if (NULL == pAdapter)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: vdev_id %d does not exist with host",
                  __func__, linkLayerStatsResults->ifaceId);
        return;
    }

    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
            "%s: Link Layer Indication indType: %d", __func__, indType);

    switch (indType)
    {
    case SIR_HAL_LL_STATS_RESULTS_RSP:
        {
            hddLog(VOS_TRACE_LEVEL_INFO,
                 "LL_STATS RESP paramID = 0x%x, ifaceId = %u respId = %u, moreResultToFollow = %u, num radio = %u result = %pK",
                 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
                 linkLayerStatsResults->rspId,
                 linkLayerStatsResults->moreResultToFollow,
                 linkLayerStatsResults->num_radio,
                 linkLayerStatsResults->results);

            spin_lock(&hdd_context_lock);
            context = &pHddCtx->ll_stats_context;
            /* validate response received from target */
            if ((context->request_id != linkLayerStatsResults->rspId) ||
                !(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->rspId,
                     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,
                                   linkLayerStatsResults->moreResultToFollow,
                                   (tpSirWifiRadioStat)
                                   linkLayerStatsResults->results,
                                   linkLayerStatsResults->num_radio);

                spin_lock(&hdd_context_lock);
                if (!linkLayerStatsResults->moreResultToFollow)
                     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,
                                   (tpSirWifiIfaceStat)
                                   linkLayerStatsResults->results,
                                   linkLayerStatsResults->num_peers);

                spin_lock(&hdd_context_lock);
                /* Firmware doesn't send peerstats event if no peers are
                 * connected. HDD should not wait for any peerstats in this case
                 * and return the status to middlewre after receiving iface
                 * stats
                 */
                if (!linkLayerStatsResults->num_peers)
                     context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
                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,
                                   linkLayerStatsResults->moreResultToFollow,
                                   (tpSirWifiPeerStat)
                                   linkLayerStatsResults->results);

                spin_lock(&hdd_context_lock);
                if (!linkLayerStatsResults->moreResultToFollow)
                     context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
                spin_unlock(&hdd_context_lock);

            }
            else
            {
                hddLog(VOS_TRACE_LEVEL_ERROR,
                        FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
            }

            spin_lock(&hdd_context_lock);
            /* complete response event if all requests bitmaps are cleared */
            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;
    }

    return;
}

static const struct nla_policy
qca_wlan_vendor_ll_ext_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_MAX + 1] = {
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_PERIOD] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_GLOBAL] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_THRESHOLD] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BITMAP] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BITMAP] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CCA_BSS_BITMAP] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_SIGNAL_BITMAP] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MSDU] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MPDU] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_PPDU] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BYTES] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP_BYTES] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_RETRY] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_NO_ACK] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_NO_BACK] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_AGGR] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_SUCC_MCS] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_FAIL_MCS] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DELAY] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_BYTES] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU_BYTES] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_LOST] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_RETRY] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DUP] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DISCARD] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MCS] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_AGGR] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_TIMES] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_DURATION] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PROBE_REQ] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MGMT] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IDLE_TIME] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_TIME] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BUSY] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BAD] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BAD] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_NO_AVAIL] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IN_BSS_TIME] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_OUT_BSS_TIME] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_SNR] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_NF] = {
		.type = NLA_U32
	},
};

/**
 * __wlan_hdd_cfg80211_ll_stats_ext_set_param - config monitor parameters
 * @wiphy: wiphy handle
 * @wdev: wdev handle
 * @data: user layer input
 * @data_len: length of user layer input
 *
 * This function is called in SSR protected environment.
 *
 * Return: 0 Success, EINVAL failure
 */
static int __wlan_hdd_cfg80211_ll_stats_ext_set_param(struct wiphy *wiphy,
						      struct wireless_dev *wdev,
						      const void *data,
						      int data_len)
{
	int status;
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_MAX + 1];
	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
	struct sir_ll_ext_stats_threshold thresh = {0,};

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

	ENTER();

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

	hddLog(VOS_TRACE_LEVEL_INFO_LOW,
	       FL("Get user layer settings for LL stat. Length is %d bytes"),
	       data_len);
	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_MAX,
		      (struct nlattr *)data, data_len,
		      qca_wlan_vendor_ll_ext_policy, NULL)) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       FL("maximum attribute not present"));
		return -EINVAL;
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_PERIOD]) {
		thresh.period = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_PERIOD]);

		if (thresh.period != 0 && thresh.period < LL_STATS_MIN_PERIOD)
			thresh.period = LL_STATS_MIN_PERIOD;

		if (thresh.period > LL_STATS_MAX_PERIOD)
			thresh.period = LL_STATS_MAX_PERIOD;
	} else {
		thresh.period = LL_STATS_INVALID_PERIOD;
		hddLog(VOS_TRACE_LEVEL_INFO,
		       FL("No MAC counter period parameter"));
	}

	/* period==0. Just disable mac counter */
	if (thresh.period == 0) {
		hddLog(VOS_TRACE_LEVEL_INFO,
		       FL("Mac counter will be disaabled"));
		goto set_param;
	}

	/* global thresh is not enabled */
	if (!tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_THRESHOLD]) {
		thresh.global = false;
		hddLog(VOS_TRACE_LEVEL_WARN, FL("Global thresh is not set"));
	} else {
		thresh.global_threshold = nla_get_u32(tb[
				QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_THRESHOLD]);
		thresh.global = true;
		hddLog(VOS_TRACE_LEVEL_INFO_LOW, FL("thresh is %d"),
		       thresh.global_threshold);
	}

	if (!tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_GLOBAL]) {
		thresh.global = false;
		hddLog(VOS_TRACE_LEVEL_WARN, FL("Global thresh is not set"));
	} else {
		thresh.global = nla_get_u32(tb[
				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_GLOBAL]);
		hddLog(VOS_TRACE_LEVEL_INFO_LOW, FL("Global is %d"),
		       thresh.global);
	}

	thresh.enable_bitmap = false;
	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BITMAP]) {
		thresh.tx_bitmap = nla_get_u32(tb[
				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BITMAP]);
		thresh.enable_bitmap = true;
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BITMAP]) {
		thresh.rx_bitmap = nla_get_u32(tb[
				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BITMAP]);
		thresh.enable_bitmap = true;
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CCA_BSS_BITMAP]) {
		thresh.cca_bitmap = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CCA_BSS_BITMAP]);
		thresh.enable_bitmap = true;
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_SIGNAL_BITMAP]) {
		thresh.signal_bitmap = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_SIGNAL_BITMAP]);
		thresh.enable_bitmap = true;
	}

	if (!thresh.global && !thresh.enable_bitmap) {
		hddLog(VOS_TRACE_LEVEL_WARN, FL("No thresh exits."));
		thresh.enable = false;
	} else {
		thresh.enable = true;
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MSDU]) {
		thresh.tx.msdu = nla_get_u32(tb[
				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MSDU]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MPDU]) {
		thresh.tx.mpdu = nla_get_u32(tb[
				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MPDU]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_PPDU]) {
		thresh.tx.ppdu = nla_get_u32(tb[
				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_PPDU]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BYTES]) {
		thresh.tx.bytes = nla_get_u32(tb[
				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BYTES]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP]) {
		thresh.tx.msdu_drop = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP_BYTES]) {
		thresh.tx.byte_drop = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP_BYTES]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_RETRY]) {
		thresh.tx.mpdu_retry = nla_get_u32(tb[
				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_RETRY]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_NO_ACK]) {
		thresh.tx.mpdu_fail = nla_get_u32(tb[
				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_NO_ACK]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_NO_BACK]) {
		thresh.tx.ppdu_fail = nla_get_u32(tb[
				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_NO_BACK]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_AGGR]) {
		thresh.tx.aggregation = nla_get_u32(tb[
				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_AGGR]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_SUCC_MCS]) {
		thresh.tx.succ_mcs = nla_get_u32(tb[
				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_SUCC_MCS]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_FAIL_MCS]) {
		thresh.tx.fail_mcs = nla_get_u32(tb[
				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_FAIL_MCS]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DELAY]) {
		thresh.tx.delay = nla_get_u32(tb[
				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DELAY]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU]) {
		thresh.rx.mpdu = nla_get_u32(tb[
				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_BYTES]) {
		thresh.rx.bytes = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_BYTES]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU]) {
		thresh.rx.ppdu = nla_get_u32(tb[
				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU_BYTES]) {
		thresh.rx.ppdu_bytes = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU_BYTES]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_LOST]) {
		thresh.rx.mpdu_lost = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_LOST]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_RETRY]) {
		thresh.rx.mpdu_retry = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_RETRY]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DUP]) {
		thresh.rx.mpdu_dup = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DUP]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DISCARD]) {
		thresh.rx.mpdu_discard = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DISCARD]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_AGGR]) {
		thresh.rx.aggregation = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_AGGR]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MCS]) {
		thresh.rx.mcs = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MCS]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_TIMES]) {
		thresh.rx.ps_inds = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_TIMES]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_DURATION]) {
		thresh.rx.ps_durs = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_DURATION]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PROBE_REQ]) {
		thresh.rx.probe_reqs = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PROBE_REQ]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MGMT]) {
		thresh.rx.other_mgmt = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MGMT]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IDLE_TIME]) {
		thresh.cca.idle_time = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IDLE_TIME]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_TIME]) {
		thresh.cca.tx_time = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_TIME]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IN_BSS_TIME]) {
		thresh.cca.rx_in_bss_time = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IN_BSS_TIME]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_OUT_BSS_TIME]) {
		thresh.cca.rx_out_bss_time = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_OUT_BSS_TIME]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BUSY]) {
		thresh.cca.rx_busy_time = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BUSY]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BAD]) {
		thresh.cca.rx_in_bad_cond_time = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BAD]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BAD]) {
		thresh.cca.tx_in_bad_cond_time = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BAD]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_NO_AVAIL]) {
		thresh.cca.wlan_not_avail_time = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_NO_AVAIL]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_SNR]) {
		thresh.signal.snr = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_SNR]);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_NF]) {
		thresh.signal.nf = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_NF]);
	}

set_param:
	hddLog(VOS_TRACE_LEVEL_INFO_LOW, FL("Send thresh settings to target"));
	if (eHAL_STATUS_SUCCESS != sme_ll_stats_set_thresh(hdd_ctx->hHal,
							   &thresh)) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       FL("sme_ll_stats_set_thresh failed."));
		return -EINVAL;
	}
	EXIT();
	return 0;
}

/**
 * __wlan_hdd_cfg80211_ll_stats_ext_set_param - config monitor parameters
 * @wiphy: wiphy handle
 * @wdev: wdev handle
 * @data: user layer input
 * @data_len: length of user layer input
 *
 * Return: 0 Success, EINVAL failure
 */
int wlan_hdd_cfg80211_ll_stats_ext_set_param(struct wiphy *wiphy,
					     struct wireless_dev *wdev,
					     const void *data,
					     int data_len)
{
	int ret;

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

	return ret;
}

/**
 * put_per_peer_ps_info() - put per peer sta's PS info into nl80211 msg
 * @wifi_peer_info: peer information
 * @vendor_event: buffer for vendor event
 *
 * Return: 0 success
 */
static int put_per_peer_ps_info(tSirWifiPeerInfo *wifi_peer_info,
				struct sk_buff *vendor_event)
{
	if (!wifi_peer_info) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       FL("Invalid pointer to peer info."));
		return -EINVAL;
	}

	if (nla_put_u32(vendor_event,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_STATE,
			wifi_peer_info->power_saving) ||
	    nla_put(vendor_event,
		    QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_MAC_ADDRESS,
		    VOS_MAC_ADDR_SIZE, wifi_peer_info->peerMacAddress)) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       FL("QCA_WLAN_VENDOR_ATTR put fail"));
		return -EINVAL;
	}
	return 0;
}

/**
 * put_wifi_peer_ps_info() - Put peer sta's power state into nl80211 msg
 * @data - stats for peer STA
 * @vendor_event - buffer for vendor event
 *
 * Return: 0 success
 */
static int put_wifi_peer_ps_info(tSirWifiPeerStat *data,
				 struct sk_buff *vendor_event)
{
	uint32_t peer_num, i;
	tSirWifiPeerInfo *wifi_peer_info;
	struct nlattr *peer_info, *peers;

	if (!data) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       FL("Invalid pointer to Wifi peer stat."));
		return -EINVAL;
	}

	peer_num = data->numPeers;

	if (peer_num == 0) {
		hddLog(VOS_TRACE_LEVEL_ERROR, FL("Peer number is zero."));
		return -EINVAL;
	}

	if (nla_put_u32(vendor_event,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_NUM,
			peer_num)) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       FL("QCA_WLAN_VENDOR_ATTR put fail"));
		return -EINVAL;
	}

	peers = nla_nest_start(vendor_event,
			       QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_CHG);
	if (peers == NULL) {
		hddLog(LOGE, FL("nla_nest_start failed"));
		return -EINVAL;
	}

	for (i = 0; i < peer_num; i++) {
		wifi_peer_info = &data->peerInfo[i];
		peer_info = nla_nest_start(vendor_event, i);

		if (peer_info == NULL) {
			hddLog(LOGE, FL("nla_nest_start failed"));
			return -EINVAL;
		}

		if (put_per_peer_ps_info(wifi_peer_info, vendor_event))
			return -EINVAL;

		nla_nest_end(vendor_event, peer_info);
	}
	nla_nest_end(vendor_event, peers);

	return 0;
}

/**
 * put_tx_failure_info() - Put TX failure info
 * @tx_fail - TX failure info
 * @skb - buffer for vendor event
 *
 * Return: 0 Success
 */
static inline int put_tx_failure_info(struct sir_wifi_iface_tx_fail *tx_fail,
				      struct sk_buff *skb)
{
	int status = 0;

	if (!tx_fail || !skb)
		return -EINVAL;

	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TID,
			tx_fail->tid) ||
	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_NUM_MSDU,
			tx_fail->msdu_num) ||
	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_STATUS,
			tx_fail->status)) {
		hddLog(LOGE, FL("QCA_WLAN_VENDOR_ATTR put fail"));
		status = -EINVAL;
	}
	return status;
}

/**
 * put_wifi_channel_cca_info() - put channel cca info to vendor event
 * @info: cca info array for all channels
 * @vendor_event: vendor event buffer
 *
 * Return: 0 Success, EINVAL failure
 */
static int put_wifi_channel_cca_info(struct sir_wifi_chan_cca_stats *cca,
				     struct sk_buff *vendor_event)
{
	/* There might be no CCA info for a channel */
	if (cca == NULL)
		return 0;

	if (nla_put_u32(vendor_event,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IDLE_TIME,
			cca->idle_time) ||
	    nla_put_u32(vendor_event,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_TIME,
			cca->tx_time) ||
	    nla_put_u32(vendor_event,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IN_BSS_TIME,
			cca->rx_in_bss_time) ||
	    nla_put_u32(vendor_event,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_OUT_BSS_TIME,
			cca->rx_out_bss_time) ||
	    nla_put_u32(vendor_event,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BUSY,
			cca->rx_busy_time) ||
	    nla_put_u32(vendor_event,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BAD,
			cca->rx_in_bad_cond_time) ||
	    nla_put_u32(vendor_event,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BAD,
			cca->tx_in_bad_cond_time) ||
	    nla_put_u32(vendor_event,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_NO_AVAIL,
			cca->wlan_not_avail_time) ||
	    nla_put_u32(vendor_event,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IFACE_ID,
			cca->vdev_id)) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       FL("QCA_WLAN_VENDOR_ATTR put fail"));
		return -EINVAL;
	}
	return 0;
}

/**
 * put_wifi_signal_info - put chain signal info
 * @info: RF chain signal info
 * @skb: vendor event buffer
 *
 * Return: 0 Success, EINVAL failure
 */
static int put_wifi_signal_info(struct sir_wifi_peer_signal_stats *peer_signal,
				struct sk_buff *skb)
{
	uint32_t i, chain_count;
	struct nlattr *chains, *att;

	/* There might be no signal info for a peer */
	if (peer_signal == NULL)
		return 0;

	chain_count = peer_signal->num_chain < WIFI_MAX_CHAINS ?
		      peer_signal->num_chain : WIFI_MAX_CHAINS;
	if (nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_ANT_NUM,
			chain_count)) {
		hddLog(LOGE, FL("QCA_WLAN_VENDOR_ATTR put fail"));
		return -EINVAL;
	}

	att = nla_nest_start(skb,
			     QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_SIGNAL);
	if (att == NULL) {
		hddLog(LOGE, FL("nla_nest_start failed"));
		return -EINVAL;
	}

	for (i = 0; i < chain_count; i++) {
		chains = nla_nest_start(skb, i);

		if (chains == NULL) {
			hddLog(LOGE, FL("nla_nest_start failed"));
			return -EINVAL;
		}

		hddLog(LOG2,
		       FL("SNR=%d, NF=%d, RX=%d, TX=%d"),
		       peer_signal->per_ant_snr[i],
		       peer_signal->nf[i],
		       peer_signal->per_ant_rx_mpdus[i],
		       peer_signal->per_ant_tx_mpdus[i]);
		if (nla_put_u32(skb,
				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_SNR,
				peer_signal->per_ant_snr[i]) ||
		    nla_put_u32(skb,
				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_NF,
				peer_signal->nf[i]) ||
		    nla_put_u32(skb,
				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU,
				peer_signal->per_ant_rx_mpdus[i]) ||
		    nla_put_u32(skb,
				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MPDU,
				peer_signal->per_ant_tx_mpdus[i])) {
			hddLog(VOS_TRACE_LEVEL_ERROR,
			       FL("QCA_WLAN_VENDOR_ATTR put fail"));
			return -EINVAL;
		}
		nla_nest_end(skb, chains);
	}
	nla_nest_end(skb, att);

	return 0;
}

/**
 * put_wifi_wmm_ac_tx_info() - put AC TX info
 * @info: tx info
 * @skb: vendor event buffer
 *
 * Return: 0 Success, EINVAL failure
 */
static int put_wifi_wmm_ac_tx_info(struct sir_wifi_tx *tx_stats,
				   struct sk_buff *skb)
{
	uint32_t *agg_size, *succ_mcs, *fail_mcs, *delay;

	/* There might be no TX info for a peer */
	if (tx_stats == NULL)
		return 0;

	agg_size = tx_stats->mpdu_aggr_size;
	succ_mcs = tx_stats->success_mcs;
	fail_mcs = tx_stats->fail_mcs;
	delay = tx_stats->delay;

	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MSDU,
			tx_stats->msdus) ||
	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MPDU,
			tx_stats->mpdus) ||
	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_PPDU,
			tx_stats->ppdus) ||
	    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BYTES,
			tx_stats->bytes) ||
	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP,
			tx_stats->drops) ||
	    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP_BYTES,
			tx_stats->drop_bytes) ||
	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_RETRY,
			tx_stats->retries) ||
	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_NO_ACK,
			tx_stats->failed) ||
	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_AGGR_NUM,
			tx_stats->aggr_len) ||
	    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_SUCC_MCS_NUM,
			tx_stats->success_mcs_len) ||
	    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_FAIL_MCS_NUM,
			tx_stats->fail_mcs_len) ||
	    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_DELAY_ARRAY_SIZE,
			tx_stats->delay_len))
		goto put_attr_fail;

	if (agg_size) {
		if (nla_put(skb,
			    QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_AGGR,
			    tx_stats->aggr_len, agg_size))
			goto put_attr_fail;
	}

	if (succ_mcs) {
		if (nla_put(skb,
			    QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_SUCC_MCS,
			    tx_stats->success_mcs_len, succ_mcs))
			goto put_attr_fail;
	}

	if (fail_mcs) {
		if (nla_put(skb,
			    QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_FAIL_MCS,
			    tx_stats->fail_mcs_len, fail_mcs))
			goto put_attr_fail;
	}

	if (delay) {
		if (nla_put(skb,
			    QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DELAY,
			    tx_stats->delay_len, delay))
			goto put_attr_fail;
	}
	return 0;

put_attr_fail:
	hddLog(VOS_TRACE_LEVEL_ERROR,
	       FL("QCA_WLAN_VENDOR_ATTR put fail"));
	return -EINVAL;
}

/**
 * put_wifi_wmm_ac_rx_info() - put AC RX info
 * @info: rx info
 * @skb: vendor event buffer
 *
 * Return: 0 Success, EINVAL failure
 */
static int put_wifi_wmm_ac_rx_info(struct sir_wifi_rx *rx_stats,
				   struct sk_buff *skb)
{
	uint32_t *mcs, *aggr;

	/* There might be no RX info for a peer */
	if (rx_stats == NULL)
		return 0;

	aggr = rx_stats->mpdu_aggr;
	mcs = rx_stats->mcs;

	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU,
			rx_stats->mpdus) ||
	    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_BYTES,
			rx_stats->bytes) ||
	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU,
			rx_stats->ppdus) ||
	    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU_BYTES,
			rx_stats->ppdu_bytes) ||
	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_LOST,
			rx_stats->mpdu_lost) ||
	    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_RETRY,
			rx_stats->mpdu_retry) ||
	    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DUP,
			rx_stats->mpdu_dup) ||
	    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DISCARD,
			rx_stats->mpdu_discard) ||
	    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_AGGR_NUM,
			rx_stats->aggr_len) ||
	    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MCS_NUM,
			rx_stats->mcs_len))
		goto put_attr_fail;

	if (aggr) {
		if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_AGGR,
			    rx_stats->aggr_len, aggr))
			goto put_attr_fail;
	}

	if (mcs) {
		if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MCS,
			    rx_stats->mcs_len, mcs))
			goto put_attr_fail;
	}

	return 0;

put_attr_fail:
	hddLog(VOS_TRACE_LEVEL_ERROR, FL("QCA_WLAN_VENDOR_ATTR put fail"));
	return -EINVAL;
}

/**
 * put_wifi_wmm_ac_info() - put WMM AC info
 * @info: per AC stats
 * @skb: vendor event buffer
 *
 * Return: 0 Success, EINVAL failure
 */
static int put_wifi_wmm_ac_info(struct sir_wifi_ll_ext_wmm_ac_stats *ac_stats,
				struct sk_buff *skb)
{
	struct nlattr *wmm;

	wmm = nla_nest_start(skb, ac_stats->type);
	if (wmm == NULL)
		goto nest_start_fail;

	if (put_wifi_wmm_ac_tx_info(ac_stats->tx_stats, skb) ||
	    put_wifi_wmm_ac_rx_info(ac_stats->rx_stats, skb))
		goto put_attr_fail;

	nla_nest_end(skb, wmm);
	return 0;

nest_start_fail:
	hddLog(LOGE, FL("nla_nest_start failed"));
	return -EINVAL;

put_attr_fail:
	hddLog(VOS_TRACE_LEVEL_ERROR, FL("QCA_WLAN_VENDOR_ATTR put fail"));
	return -EINVAL;
}

/**
 * put_wifi_ll_ext_peer_info() - put per peer info
 * @info: peer stats
 * @skb: vendor event buffer
 *
 * Return: 0 Success, EINVAL failure
 */
static int put_wifi_ll_ext_peer_info(struct sir_wifi_ll_ext_peer_stats *peers,
				     struct sk_buff *skb)
{
	uint32_t i;
	struct nlattr *wmm_ac;

	if (nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_ID,
			peers->peer_id) ||
	    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IFACE_ID,
			peers->vdev_id) ||
	    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_TIMES,
			peers->sta_ps_inds) ||
	    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_DURATION,
			peers->sta_ps_durs) ||
	    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PROBE_REQ,
			peers->rx_probe_reqs) ||
	    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MGMT,
			peers->rx_oth_mgmts) ||
	    nla_put(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_MAC_ADDRESS,
		    VOS_MAC_ADDR_SIZE, peers->mac_address) ||
	    put_wifi_signal_info(&peers->peer_signal_stats, skb)) {
		hddLog(LOGE, FL("put peer signal attr failed"));
		return -EINVAL;
	}

	wmm_ac = nla_nest_start(skb,
				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_STATUS);
	if (wmm_ac == NULL) {
		hddLog(LOGE, FL("nla_nest_start failed"));
		return -EINVAL;
	}

	for (i = 0; i < WLAN_MAX_AC; i++) {
		if (put_wifi_wmm_ac_info(&peers->ac_stats[i], skb)) {
			hddLog(LOGE, FL("put WMM AC attr failed"));
			return -EINVAL;
		}
	}

	nla_nest_end(skb, wmm_ac);
	return 0;
}

/**
 * put_wifi_ll_ext_stats() - put link layer extension stats
 * @info: link layer stats
 * @skb: vendor event buffer
 *
 * Return: 0 Success, EINVAL failure
 */
static int put_wifi_ll_ext_stats(struct sir_wifi_ll_ext_stats *stats,
				 struct sk_buff *skb)
{
	uint32_t i;
	struct nlattr *peer, *peer_info, *channels, *channel_info;
	struct sir_wifi_ll_ext_period *period;

	period = &stats->time_stamp;
	if (hdd_wlan_nla_put_u64(skb,
				 QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_REPORT_TIME,
				 period->end_time) ||
	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_MEASUREMENT_TIME,
			period->duration) ||
	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_EVENT_MODE,
			stats->trigger_cond_id) ||
	    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CCA_BSS_BITMAP,
			stats->cca_chgd_bitmap) ||
	    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_SIGNAL_BITMAP,
			stats->sig_chgd_bitmap) ||
	    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BITMAP,
			stats->tx_chgd_bitmap) ||
	    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BITMAP,
			stats->rx_chgd_bitmap) ||
	    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CHANNEL_NUM,
			stats->channel_num) ||
	    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_NUM,
			stats->peer_num)) {
		goto put_attr_fail;
	}

	channels = nla_nest_start(skb,
				  QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CCA_BSS);
	if (channels == NULL) {
		hddLog(LOGE, FL("nla_nest_start failed"));
		return -EINVAL;
	}

	for (i = 0; i < stats->channel_num; i++) {
		channel_info = nla_nest_start(skb, i);
		if (channel_info == NULL) {
			hddLog(LOGE, FL("nla_nest_start failed"));
			return -EINVAL;
		}

		if (put_wifi_channel_cca_info(&stats->cca[i], skb))
			goto put_attr_fail;
		nla_nest_end(skb, channel_info);
	}
	nla_nest_end(skb, channels);

	peer_info = nla_nest_start(skb,
				   QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER);
	if (peer_info == NULL) {
		hddLog(LOGE, FL("nla_nest_start failed"));
		return -EINVAL;
	}

	for (i = 0; i < stats->peer_num; i++) {
		peer = nla_nest_start(skb, i);
		if (peer == NULL) {
			hddLog(LOGE, FL("nla_nest_start failed"));
			return -EINVAL;
		}

		if (put_wifi_ll_ext_peer_info(&stats->peer_stats[i], skb))
			goto put_attr_fail;
		nla_nest_end(skb, peer);
	}

	nla_nest_end(skb, peer_info);
	return 0;

put_attr_fail:
	hddLog(VOS_TRACE_LEVEL_ERROR, FL("QCA_WLAN_VENDOR_ATTR put fail"));
	return -EINVAL;
}

/**
 * wlan_hdd_cfg80211_ll_stats_ext_callback() - LL stats callback
 * @rsp - msg from FW
 *
 * An extension of wlan_hdd_cfg80211_link_layer_stats_callback.
 * It converts monitoring parameters offloaded to NL data and send the same
 * to the kerbel/upper layer.
 */
static void wlan_hdd_cfg80211_ll_stats_ext_callback(tSirLLStatsResults *rsp)
{
	hdd_context_t *hdd_ctx;
	struct sk_buff *skb;
	int flags = vos_get_gfp_flags();
	uint32_t param_id, index;
	hdd_adapter_t *adapter;
	tSirWifiPeerStat *peer_stats;
	uint8_t *results;
	int status, len;
	v_CONTEXT_t vos_context = vos_get_global_context(0, NULL);

	ENTER();

	if (!rsp) {
		hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid result."));
		return;
	}

	hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_context);
	status = wlan_hdd_validate_context(hdd_ctx);
	if (0 != status)
		return;

	adapter = hdd_get_adapter_by_vdev(hdd_ctx, rsp->ifaceId);
	if (NULL == adapter) {
		hddLog(LOGE, FL("vdev_id %d does not exist with host"),
		       rsp->ifaceId);
		return;
	}

	index = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_EXT_INDEX;
	len = LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN;
	skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL, len,
					  index, flags);
	if (!skb) {
		hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
		return;
	}

	results = rsp->results;
	param_id = rsp->paramId;
	hddLog(LOG1,
	       FL("LL_STATS RESP paramID = 0x%x, ifaceId = %u, result = %pK"),
	       rsp->paramId, rsp->ifaceId, rsp->results);
	if (param_id & WMI_LL_STATS_EXT_PS_CHG) {
		peer_stats = (tSirWifiPeerStat *)results;
		status = put_wifi_peer_ps_info(peer_stats, skb);
	} else if (param_id & WMI_LL_STATS_EXT_TX_FAIL) {
		struct sir_wifi_iface_tx_fail *tx_fail;

		tx_fail = (struct sir_wifi_iface_tx_fail *)results;
		status = put_tx_failure_info(tx_fail, skb);
	} else if (param_id & WMI_LL_STATS_EXT_MAC_COUNTER) {
		hddLog(LOGE, FL("MAC counters stats"));
		status = put_wifi_ll_ext_stats((struct sir_wifi_ll_ext_stats *)
					       rsp->results, skb);
	} else {
		hddLog(LOGE, FL("Unknown link layer stats"));
		status = -1;
	}

	if (status == 0)
		cfg80211_vendor_event(skb, flags);
	else
		kfree_skb(skb);
	EXIT();
}

void wlan_hdd_cfg80211_link_layer_stats_init(hdd_context_t *pHddCtx)
{
        sme_SetLinkLayerStatsIndCB(pHddCtx->hHal,
                                   wlan_hdd_cfg80211_link_layer_stats_callback);
        sme_set_ll_ext_cb(pHddCtx->hHal,
                          wlan_hdd_cfg80211_ll_stats_ext_callback);
}

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

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

    ENTER();

    status = wlan_hdd_validate_context(pHddCtx);
    if (0 != status)
        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, NULL))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("maximum attribute not present"));
        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]);

    LinkLayerStatsSetReq.staId = pAdapter->sessionId;

    hddLog(VOS_TRACE_LEVEL_INFO,
           "LL_STATS_SET reqId = %d, staId = %d, mpduSizeThreshold = %d Statistics Gathering  = %d ",
           LinkLayerStatsSetReq.reqId, LinkLayerStatsSetReq.staId,
           LinkLayerStatsSetReq.mpduSizeThreshold,
           LinkLayerStatsSetReq.aggressiveStatisticsGathering);



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

/**
 * wlan_hdd_cfg80211_ll_stats_set() - set ll stats
 * @wiphy: Pointer to wiphy
 * @wdev: Pointer to wdev
 * @data: Pointer to data
 * @data_len: Data length
 *
 * Return: 0 if success, non-zero for failure
 */
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 *hddstactx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    int status;

    printk("WAR: return ll_stats, because fw didn't enable\n");
    return 0;
    if (VOS_FTM_MODE == hdd_get_conparam()) {
        hddLog(LOGE, FL("Command not allowed in FTM mode"));
        return -EINVAL;
    }

    /* ENTER() intentionally not used in a frequently invoked API */

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

    if (!pAdapter->isLinkLayerStatsSet) {
        hddLog(LOGW, FL("isLinkLayerStatsSet : %d"),
               pAdapter->isLinkLayerStatsSet);
        return -EINVAL;
    }

    if (hddstactx->hdd_ReassocScenario) {
        hddLog(VOS_TRACE_LEVEL_INFO,
               FL("Roaming in progress, so unable to proceed this request"));
        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, NULL))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("max attribute not present"));
        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]);

    LinkLayerStatsGetReq.staId = pAdapter->sessionId;

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

/**
 * wlan_hdd_cfg80211_ll_stats_get() - get ll stats
 * @wiphy: Pointer to wiphy
 * @wdev: Pointer to wdev
 * @data: Pointer to data
 * @data_len: Data length
 *
 * Return: 0 if success, non-zero for failure
 */
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;
    struct sk_buff *temp_skbuff;

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

    ENTER();

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

    if (!pAdapter->isLinkLayerStatsSet)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               "%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, NULL))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("STATS_CLR_MAX is not present"));
        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;

    LinkLayerStatsClearReq.staId = pAdapter->sessionId;

    hddLog(VOS_TRACE_LEVEL_INFO,
            "LL_STATS_CLEAR reqId = %d, staId = %d, statsClearReqMask = 0x%X, stopReq  = %d",
            LinkLayerStatsClearReq.reqId,
            LinkLayerStatsClearReq.staId,
            LinkLayerStatsClearReq.statsClearReqMask,
            LinkLayerStatsClearReq.stopReq);


    if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
                                                   &LinkLayerStatsClearReq))
    {
        temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
                                                          2 * sizeof(u32) +
                                                          2 * 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 (stopReq == 1)
                pAdapter->isLinkLayerStatsSet = 0;

            return cfg80211_vendor_cmd_reply(temp_skbuff);
        }
        EXIT();
        return -ENOMEM;
    }
    return -EINVAL;
}

/**
 * wlan_hdd_cfg80211_ll_stats_clear() - clear ll stats
 * @wiphy: Pointer to wiphy
 * @wdev: Pointer to wdev
 * @data: Pointer to data
 * @data_len: Data length
 *
 * Return: 0 if success, non-zero for failure
 */
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;
}

/**
 * wlan_hdd_clear_link_layer_stats() - clear link layer stats
 * @adapter: pointer to adapter
 *
 * Wrapper function to clear link layer stats.
 * return - void
 */
void wlan_hdd_clear_link_layer_stats(hdd_adapter_t *adapter)
{
	tSirLLStatsClearReq link_layer_stats_clear_req;
	tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter);

	link_layer_stats_clear_req.statsClearReqMask = WIFI_STATS_IFACE_AC |
		WIFI_STATS_IFACE_ALL_PEER;
	link_layer_stats_clear_req.stopReq = 0;
	link_layer_stats_clear_req.reqId = 1;
	link_layer_stats_clear_req.staId = adapter->sessionId;
	sme_LLStatsClearReq(hal, &link_layer_stats_clear_req);

	return;
}

#endif /* WLAN_FEATURE_LINK_LAYER_STATS */

#ifdef WLAN_FEATURE_ROAM_OFFLOAD
/**
 * __wlan_hdd_cfg80211_keymgmt_set_key() - Store the Keys in the driver session
 * @wiphy:   pointer to wireless wiphy structure.
 * @wdev:    pointer to wireless_dev structure.
 * @data:    Pointer to the Key data
 * @data_len:Length of the data passed
 *
 * This is called when wlan driver needs to save the keys received via
 * vendor specific command.
 *
 * Return:   Return the Success or Failure code.
 */
static int __wlan_hdd_cfg80211_keymgmt_set_key(struct wiphy *wiphy,
					struct wireless_dev *wdev,
					const void *data, int data_len)
{
	uint8_t local_pmk[SIR_ROAM_SCAN_PSK_SIZE];
	struct net_device *dev = wdev->netdev;
	hdd_adapter_t *hdd_adapter_ptr = WLAN_HDD_GET_PRIV_PTR(dev);
	hdd_context_t *hdd_ctx_ptr;
	int status;

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

	if ((data == NULL) || (data_len == 0) ||
		(data_len > SIR_ROAM_SCAN_PSK_SIZE)) {
		hddLog(LOGE, FL("Invalid data"));
		return -EINVAL;
	}

	hdd_ctx_ptr = WLAN_HDD_GET_CTX(hdd_adapter_ptr);
	if (!hdd_ctx_ptr) {
		hddLog(LOGE, FL("HDD context is null"));
		return -EINVAL;
	}

	status = wlan_hdd_validate_context(hdd_ctx_ptr);
	if (0 != status)
		return status;

	sme_UpdateRoamKeyMgmtOffloadEnabled(hdd_ctx_ptr->hHal,
			hdd_adapter_ptr->sessionId,
			TRUE);
	vos_mem_zero(&local_pmk, SIR_ROAM_SCAN_PSK_SIZE);
	vos_mem_copy(local_pmk, data, data_len);
	sme_RoamSetPSK_PMK(WLAN_HDD_GET_HAL_CTX(hdd_adapter_ptr),
			hdd_adapter_ptr->sessionId, local_pmk, data_len);
	return 0;
}

/**
 * wlan_hdd_cfg80211_keymgmt_set_key() - Store the Keys in the driver session
 * @wiphy:   pointer to wireless wiphy structure.
 * @wdev:    pointer to wireless_dev structure.
 * @data:    Pointer to the Key data
 * @data_len:Length of the data passed
 *
 * This is called when wlan driver needs to save the keys received via
 * vendor specific command.
 *
 * Return:   Return the Success or Failure code.
 */
static int wlan_hdd_cfg80211_keymgmt_set_key(struct wiphy *wiphy,
					struct wireless_dev *wdev,
					const void *data, int data_len)
{
	int ret;

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

	return ret;
}

/**
 * wlan_hdd_send_roam_auth_event() - Send the roamed and authorized event
 * @hdd_ctx_ptr:   pointer to HDD Context.
 * @bssid:    pointer to bssid of roamed AP.
 * @req_rsn_ie:    Pointer to request RSN IE
 * @req_rsn_len:   Length of the request RSN IE
 * @rsp_rsn_ie:    Pointer to response RSN IE
 * @rsp_rsn_len:   Length of the response RSN IE
 * @roam_info_ptr: Pointer to the roaming related information
 *
 * This is called when wlan driver needs to send the roaming and
 * authorization information after roaming.
 *
 * The information that would be sent is the request RSN IE, response
 * RSN IE and BSSID of the newly roamed AP.
 *
 * If the Authorized status is authenticated, then additional parameters
 * like PTK's KCK and KEK and Replay Counter would also be passed to the
 * supplicant.
 *
 * The supplicant upon receiving this event would ignore the legacy
 * cfg80211_roamed call and use the entire information from this event.
 * The cfg80211_roamed should still co-exist since the kernel will
 * make use of the parameters even if the supplicant ignores it.
 *
 * Return:   Return the Success or Failure code.
 */
int wlan_hdd_send_roam_auth_event(hdd_context_t *hdd_ctx_ptr, uint8_t *bssid,
		uint8_t *req_rsn_ie, uint32_t req_rsn_len,
		uint8_t *rsp_rsn_ie, uint32_t rsp_rsn_len,
		tCsrRoamInfo *roam_info_ptr)
{
	struct sk_buff *skb     = NULL;
	ENTER();

	if (wlan_hdd_validate_context(hdd_ctx_ptr))
		return -EINVAL;

	skb = cfg80211_vendor_event_alloc(hdd_ctx_ptr->wiphy,
			NULL,
			ETH_ALEN + req_rsn_len + rsp_rsn_len +
			sizeof(uint8) + SIR_REPLAY_CTR_LEN +
			SIR_KCK_KEY_LEN + SIR_KCK_KEY_LEN +
			(7 * NLMSG_HDRLEN),
			QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH_INDEX,
			GFP_KERNEL);

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

	if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID,
				ETH_ALEN, bssid) ||
		nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE,
			req_rsn_len, req_rsn_ie) ||
		nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE,
			rsp_rsn_len, rsp_rsn_ie)) {
		hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
		goto nla_put_failure;
	}
	hddLog(VOS_TRACE_LEVEL_DEBUG, FL("Auth Status = %d"),
			roam_info_ptr->synchAuthStatus);
	if (roam_info_ptr->synchAuthStatus ==
			CSR_ROAM_AUTH_STATUS_AUTHENTICATED) {
		hddLog(VOS_TRACE_LEVEL_DEBUG, FL("Include Auth Params TLV's"));
		if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED,
					TRUE) ||
			nla_put(skb,
				QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR,
				SIR_REPLAY_CTR_LEN, roam_info_ptr->replay_ctr)
			|| nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK,
				SIR_KCK_KEY_LEN, roam_info_ptr->kck)
			|| nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK,
				SIR_KEK_KEY_LEN, roam_info_ptr->kek)) {
			hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
			goto nla_put_failure;
		}
	} else {
		hddLog(VOS_TRACE_LEVEL_DEBUG, FL("No Auth Params TLV's"));
		if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED,
					FALSE)) {
			hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
			goto nla_put_failure;
		}
	}

	cfg80211_vendor_event(skb, GFP_KERNEL);
	return 0;

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

#endif

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 },
	[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_RADIO_INDEX] = {.type = NLA_U32 },
};

/**
 * __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 driver_version;
	tSirVersionString firmware_version;
	uint32_t major_spid = 0, minor_spid = 0, siid = 0, crmid = 0;
	int status;
	struct sk_buff *reply_skb;
	uint32_t skb_len = 0, count = 0;

	ENTER();

	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)
		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, NULL)) {
		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"));
		strlcpy(driver_version, QWLAN_VERSIONSTR,
			sizeof(driver_version));
		skb_len += strlen(driver_version) + 1;
		count++;
	}

	if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
		hddLog(LOG1, FL("Rcvd req for FW version"));
		hdd_get_fw_version(hdd_ctx, &major_spid, &minor_spid, &siid,
				   &crmid);
		snprintf(firmware_version, sizeof(firmware_version),
			 "%d:%d:%d:%d", major_spid, minor_spid, siid, crmid);
		skb_len += strlen(firmware_version) + 1;
		count++;
	}

	if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_RADIO_INDEX]) {
		hddLog(LOG1, FL("Rcvd req for Radio Index"));
		skb_len += sizeof(hdd_ctx->radio_index);
		count++;
	}

	if (count == 0) {
		hddLog(LOGE, FL("unknown attribute in get_wifi_info request"));
		return -EINVAL;
	}

	skb_len += (NLA_HDRLEN * count) + NLMSG_HDRLEN;
	reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, skb_len);

	if (!reply_skb)
		goto error_skb_fail;

	if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
		if (nla_put_string(reply_skb,
			    QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION,
			    driver_version))
			goto error_nla_fail;
	}

	if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
		if (nla_put_string(reply_skb,
			    QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION,
			    firmware_version))
			goto error_nla_fail;
	}

	if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_RADIO_INDEX]) {
		if (nla_put_u32(reply_skb,
				QCA_WLAN_VENDOR_ATTR_WIFI_INFO_RADIO_INDEX,
				hdd_ctx->radio_index))
			goto error_nla_fail;
	}

	return cfg80211_vendor_cmd_reply(reply_skb);

error_skb_fail:
	hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
	return -ENOMEM;

error_nla_fail:
	hddLog(LOGE, FL("nla put fail"));
	kfree_skb(reply_skb);
	return -EINVAL;
}

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

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

	return ret;
}

/**
 * __wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
 * @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 by userspace to know the supported logger features
 *
 * Return:   Return the Success or Failure code.
 */
static int
__wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
		struct wireless_dev *wdev,
		const void *data, int data_len)
{
	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
	int status;
	uint32_t features;
	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)
		return -EINVAL;

	features = 0;

	features |= WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED;
	features |= WIFI_LOGGER_CONNECT_EVENT_SUPPORTED;
	features |= WIFI_LOGGER_WAKE_LOCK_SUPPORTED;

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

	hddLog(LOG1, FL("Supported logger features: 0x%0x"), features);
	if (nla_put_u32(reply_skb, QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED,
				   features)) {
		hddLog(LOGE, FL("nla put fail"));
		kfree_skb(reply_skb);
		return -EINVAL;
	}

	return cfg80211_vendor_cmd_reply(reply_skb);
}

/**
 * wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
 * @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 by userspace to know the supported logger features
 *
 * Return:   Return the Success or Failure code.
 */
static int
wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
		struct wireless_dev *wdev,
		const void *data, int data_len)
{
	int ret;

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

	return ret;
}

#ifdef FEATURE_WLAN_TDLS
/* 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_U32 },
    [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
    [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
                                                {.type = NLA_U32 },

};

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_U32 },
    [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
    [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_U32 },
    [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
                                                   = {.type = NLA_U32 },

};
static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
                                                struct wireless_dev *wdev,
                                                const void *data,
                                                int data_len)
{
    uint8_t 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_U32 state;
    tANI_S32 reason;
    uint32_t global_operating_class = 0;
    uint32_t channel = 0;
    struct sk_buff *skb = NULL;

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

    ENTER();

    ret = wlan_hdd_validate_context(pHddCtx);
    if (0 != ret)
        return -EINVAL;
    if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
        return -ENOTSUPP;
    }
    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
                    data, data_len,
                    wlan_hdd_tdls_config_get_status_policy, NULL)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
        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));

    ret = wlan_hdd_tdls_get_status(pAdapter, peer, &global_operating_class,
                                   &channel, &state, &reason);

    if (0 != ret) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("get status Failed"));
        return -EINVAL;
    }
    skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
                                              4 * sizeof(int32_t) +
                                              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_u32(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_u32(skb,
                    QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
                    global_operating_class) ||
        nla_put_u32(skb,
                    QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
                    channel)) {

        hddLog(VOS_TRACE_LEVEL_ERROR, 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;
}

/**
 * wlan_hdd_cfg80211_exttdls_get_status() - get ext tdls status
 * @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
 *
 * Return:   Return the Success or Failure code.
 */
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(const tANI_U8* mac,
                                              uint32_t global_operating_class,
                                              uint32_t channel,
                                              tANI_U32 state,
                                              tANI_S32 reason,
                                              void *ctx)
{
    hdd_adapter_t* pAdapter       = (hdd_adapter_t*)ctx;
    hdd_context_t *pHddCtx        = WLAN_HDD_GET_CTX(pAdapter);
    struct sk_buff *skb           = NULL;

    ENTER();

    if (wlan_hdd_validate_context(pHddCtx))
        return -EINVAL;

    if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
        return -ENOTSUPP;
    }
    skb = cfg80211_vendor_event_alloc(
                            pHddCtx->wiphy,
                            NULL,
                            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("Reason %d Status %d class %d channel %d peer " MAC_ADDRESS_STR),
           reason, state, global_operating_class,
           channel, MAC_ADDR_ARRAY(mac));

    if (nla_put(skb,
                QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
                VOS_MAC_ADDR_SIZE, mac) ||
        nla_put_u32(skb,
                    QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
                    state) ||
        nla_put_s32(skb,
                    QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
                    reason) ||
        nla_put_u32(skb,
                    QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
                    channel) ||
        nla_put_u32(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)
{
    uint8_t 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_ENABLE_MAX + 1];
    eHalStatus status;
    tdls_req_params_t   pReqMsg = {0};
    int ret;

    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;
    if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("TDLS External Control is not enabled"));
        return -ENOTSUPP;
    }
    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
                    data, data_len,
                    wlan_hdd_tdls_config_enable_policy, NULL)) {
        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,
                                 wlan_hdd_cfg80211_exttdls_callback,
                                 pReqMsg.channel,
                                 pReqMsg.max_latency_ms,
                                 pReqMsg.global_operating_class,
                                 pReqMsg.min_bandwidth_kbps);
    EXIT();
    return ret;
}

/**
 * wlan_hdd_cfg80211_exttdls_enable() - enable ext tdls
 * @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
 *
 * Return:   Return the Success or Failure code.
 */
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_adapter_t *pAdapter                    = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx                     = wiphy_priv(wiphy);
    struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
    eHalStatus status;

    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;
    if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {

        return -ENOTSUPP;
    }
    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
                    data, data_len,
                    wlan_hdd_tdls_config_disable_policy, NULL)) {
        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));

    status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
    EXIT();
    return status;
}

/**
 * wlan_hdd_cfg80211_exttdls_disable() - disable ext tdls
 * @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
 *
 * Return:   Return the Success or Failure code.
 */
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;
}

#endif


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 },
};

/**
 * wlan_hdd_disable_dfs_chan_scan () - disable/enable DFS channels
 *
 * @pHddCtx: HDD context within host driver
 * @pAdapter: Adapter pointer
 * @no_dfs_flag: If TRUE, DFS channels cannot be used for scanning
 *
 * Loops through devices to see who is operating on DFS channels
 * and then disables/enables DFS channels by calling SME API.
 * Fails the disable request if any device is active on a DFS channel.
 *
 * Return: EOK or other error codes.
 */

int wlan_hdd_disable_dfs_chan_scan(hdd_context_t *pHddCtx,
                                   hdd_adapter_t *pAdapter,
                                   u32 no_dfs_flag)
{
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    hdd_adapter_list_node_t *p_adapter_node = NULL, *p_next = NULL;
    hdd_adapter_t *p_adapter;
    VOS_STATUS vos_status;
    hdd_ap_ctx_t *p_ap_ctx;
    hdd_station_ctx_t *p_sta_ctx;
    eHalStatus status;
    int ret_val = -EPERM;

    if (no_dfs_flag == pHddCtx->cfg_ini->enableDFSChnlScan) {
        if (no_dfs_flag) {
            vos_status = hdd_get_front_adapter( pHddCtx, &p_adapter_node);
            while ((NULL != p_adapter_node) &&
                   (VOS_STATUS_SUCCESS == vos_status))
            {
                p_adapter = p_adapter_node->pAdapter;

                if (WLAN_HDD_SOFTAP == p_adapter->device_mode) {
                    p_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(p_adapter);

                    /* if there is SAP already running on DFS channel,
                       do not disable scan on dfs channels. Note that with
                       SAP on DFS, there cannot be conurrency on single
                       radio. But then we can have multiple radios !!!!! */
                    if (NV_CHANNEL_DFS ==
                        vos_nv_getChannelEnabledState(
                            p_ap_ctx->operatingChannel)) {
                        hddLog(LOGE, FL("SAP running on DFS channel"));
                        return -EOPNOTSUPP;
                    }
                }

                if (WLAN_HDD_INFRA_STATION == p_adapter->device_mode) {
                    p_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(p_adapter);

                    /* if STA is already connected on DFS channel,
                       do not disable scan on dfs channels */
                    if (hdd_connIsConnected(p_sta_ctx) &&
                        (NV_CHANNEL_DFS ==
                         vos_nv_getChannelEnabledState(
                             p_sta_ctx->conn_info.operationChannel))) {
                        hddLog(LOGE, FL("client connected on DFS channel"));
                        return -EOPNOTSUPP;
                    }
                }

                vos_status = hdd_get_next_adapter(pHddCtx, p_adapter_node,
                                                  &p_next);
                p_adapter_node = p_next;
            }
        }

        pHddCtx->cfg_ini->enableDFSChnlScan = !no_dfs_flag;

        hdd_abort_mac_scan_all_adapters(pHddCtx);

        /* call the SME API to tunnel down the new channel list
           to the firmware  */
        status = sme_handle_dfs_chan_scan(hHal,
                                      pHddCtx->cfg_ini->enableDFSChnlScan);

        if (eHAL_STATUS_SUCCESS == status) {
            ret_val = 0;

            /* Clear the SME scan cache also. Note that the clearing of scan
             * results is independent of session; so no need to iterate over
             * all sessions
             */
            status = sme_ScanFlushResult(hHal, pAdapter->sessionId);
            if (eHAL_STATUS_SUCCESS != status)
                ret_val = -EPERM;
        }
    } else {
        hddLog(LOG1, FL(" the DFS flag has not changed"));
        ret_val = 0;
    }
    return ret_val;
}

/**
 * __wlan_hdd_cfg80211_disable_dfs_chan_scan () - DFS scan vendor command
 *
 * @wiphy: wiphy device pointer
 * @wdev: wireless device pointer
 * @data: Vendof command data buffer
 * @data_len: Buffer length
 *
 * Handles QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX. Validate it and
 * call wlan_hdd_disable_dfs_chan_scan to send it to firmware.
 *
 * Return: EOK or other error codes.
 */

static int __wlan_hdd_cfg80211_disable_dfs_chan_scan(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 nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
    int ret_val = -EPERM;
    u32 no_dfs_flag = 0;

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

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

    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
                    data, data_len,
                    wlan_hdd_set_no_dfs_flag_config_policy, NULL)) {
        hddLog(LOGE, FL("invalid attr"));
        return -EINVAL;
    }

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

    no_dfs_flag = nla_get_u32(
        tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);

    hddLog(LOG1, FL(" DFS flag = %d"),
           no_dfs_flag);

    if (no_dfs_flag > 1) {
        hddLog(LOGE, FL("invalid value of dfs flag"));
        return -EINVAL;
    }

    ret_val = wlan_hdd_disable_dfs_chan_scan(pHddCtx, pAdapter, no_dfs_flag);
    return ret_val;
}

/**
 * wlan_hdd_cfg80211_disable_dfs_chan_scan () - DFS scan vendor command
 *
 * @wiphy: wiphy device pointer
 * @wdev: wireless device pointer
 * @data: Vendof command data buffer
 * @data_len: Buffer length
 *
 * Handles QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX. Validate it and
 * call wlan_hdd_disable_dfs_chan_scan to send it to firmware.
 *
 * Return: EOK or other error codes.
 */

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

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

	return ret;
}

/**
 * wlan_hdd_sap_cfg_dfs_override() - DFS MCC restriction check
 *
 * @adapter: SAP adapter pointer
 *
 * DFS in MCC is not supported for Multi bssid SAP mode due to single physical
 * radio. So in case of DFS MCC scenario override current SAP given config
 * to follow concurrent SAP DFS config
 *
 * Return: 0 - No DFS issue, 1 - Override done and negative error codes
 */

#ifdef WLAN_FEATURE_MBSSID
static int wlan_hdd_sap_cfg_dfs_override(hdd_adapter_t *adapter)
{
	hdd_adapter_t *con_sap_adapter;
	tsap_Config_t *sap_config, *con_sap_config;
	int con_ch;
	tHalHandle hHal;

	/*
	 * Check if STA is running in a concurrent channel
	 */
	hHal = WLAN_HDD_GET_HAL_CTX(adapter);
	con_ch = sme_GetConcurrentOperationChannel(hHal);
	sap_config = &adapter->sessionCtx.ap.sapConfig;

	if (con_ch && vos_get_concurrency_mode() == VOS_STA_SAP) {

		hddLog(LOG1, FL("concurrent STA role running on channel %d"),
			con_ch);

		/*
		 * There is a STA role running on the same card, in that case
		 * DFS channel cannot be used by concurrent SAP.
		 * Try to use the same channel as the STA to achieve SCC
		 */
		if (VOS_IS_DFS_CH(sap_config->channel)) {
			hddLog(LOG1,
				FL("SAP channel config overridden due to DFS channel not allowed in STA+SAP mode %d -> %d"),
				sap_config->channel, con_ch);
			sap_config->channel = con_ch;
		}
	}

	/*
	 * Check if AP+AP case, once primary AP chooses a DFS
	 * channel secondary AP should always follow primary APs channel
	 */
	if (!vos_concurrent_beaconing_sessions_running())
		return 0;

	con_sap_adapter = hdd_get_con_sap_adapter(adapter, true);
	if (!con_sap_adapter)
		return 0;

	con_sap_config = &con_sap_adapter->sessionCtx.ap.sapConfig;
	con_ch = con_sap_adapter->sessionCtx.ap.operatingChannel;

	if (!VOS_IS_DFS_CH(con_ch))
		return 0;

	hddLog(LOGE, FL("Only SCC AP-AP DFS Permitted (ch=%d, con_ch=%d)"),
						sap_config->channel, con_ch);
	hddLog(LOG1, FL("Overriding guest AP's channel"));
	sap_config->channel = con_ch;

	if (con_sap_config->acs_cfg.acs_mode == true) {
		if (con_ch != con_sap_config->acs_cfg.pri_ch &&
				con_ch != con_sap_config->acs_cfg.ht_sec_ch) {
			hddLog(LOGE, FL("Primary AP channel config error"));
			hddLog(LOGE, FL("Operating ch: %d ACS ch: %d %d"),
				con_ch, con_sap_config->acs_cfg.pri_ch,
				con_sap_config->acs_cfg.ht_sec_ch);
			return -EINVAL;
		}
		/* Sec AP ACS info is overwritten with Pri AP due to DFS
		 * MCC restriction. So free ch list allocated in do_acs
		 * func for Sec AP and realloc for Pri AP ch list size
		 */
		if (sap_config->acs_cfg.ch_list)
		        vos_mem_free(sap_config->acs_cfg.ch_list);

		vos_mem_copy(&sap_config->acs_cfg,
					&con_sap_config->acs_cfg,
					sizeof(struct sap_acs_cfg));
		sap_config->acs_cfg.ch_list = vos_mem_malloc(
					sizeof(uint8_t) *
					con_sap_config->acs_cfg.ch_list_count);
		if (!sap_config->acs_cfg.ch_list) {
			hddLog(LOGE, FL("ACS config alloc fail"));
			return -ENOMEM;
		}

		vos_mem_copy(sap_config->acs_cfg.ch_list,
					con_sap_config->acs_cfg.ch_list,
					con_sap_config->acs_cfg.ch_list_count);

	} else {
		sap_config->acs_cfg.pri_ch = con_ch;
		if (sap_config->acs_cfg.ch_width > eHT_CHANNEL_WIDTH_20MHZ)
			sap_config->acs_cfg.ht_sec_ch = con_sap_config->sec_ch;
	}

	return con_ch;
}
#else
static int wlan_hdd_sap_cfg_dfs_override(hdd_adapter_t *adapter)
{
	return 0;
}
#endif



static int wlan_hdd_config_acs(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter)
{
    tsap_Config_t *sap_config;
    hdd_config_t *ini_config;
    tHalHandle hal;

    hal = WLAN_HDD_GET_HAL_CTX(adapter);
    sap_config = &adapter->sessionCtx.ap.sapConfig;
    ini_config = hdd_ctx->cfg_ini;

    sap_config->enOverLapCh = !!hdd_ctx->cfg_ini->gEnableOverLapCh;
#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
    hddLog(LOG1, FL("HDD_ACS_SKIP_STATUS = %d"), hdd_ctx->skip_acs_scan_status);

    if (hdd_ctx->skip_acs_scan_status == eSAP_SKIP_ACS_SCAN) {
        hdd_adapter_t *con_sap_adapter;
        tsap_Config_t *con_sap_config = NULL;

        con_sap_adapter = hdd_get_con_sap_adapter(adapter, false);

        if (con_sap_adapter)
            con_sap_config = &con_sap_adapter->sessionCtx.ap.sapConfig;

        sap_config->acs_cfg.skip_scan_status = eSAP_DO_NEW_ACS_SCAN;

        if (con_sap_config && con_sap_config->acs_cfg.acs_mode == true &&
            hdd_ctx->skip_acs_scan_status == eSAP_SKIP_ACS_SCAN) {

            if (con_sap_config->acs_cfg.hw_mode == sap_config->acs_cfg.hw_mode) {
                v_U8_t con_sap_st_ch, con_sap_end_ch;
                v_U8_t cur_sap_st_ch, cur_sap_end_ch;
                v_U8_t bandStartChannel, bandEndChannel;

                con_sap_st_ch = con_sap_config->acs_cfg.start_ch;
                con_sap_end_ch = con_sap_config->acs_cfg.end_ch;
                cur_sap_st_ch = sap_config->acs_cfg.start_ch;
                cur_sap_end_ch = sap_config->acs_cfg.end_ch;

                WLANSAP_extend_to_acs_range(&cur_sap_st_ch, &cur_sap_end_ch,
                                &bandStartChannel, &bandEndChannel);

                WLANSAP_extend_to_acs_range(&con_sap_st_ch, &con_sap_end_ch,
                                &bandStartChannel, &bandEndChannel);

                if (con_sap_st_ch <= cur_sap_st_ch &&
                    con_sap_end_ch >= cur_sap_end_ch) {

                    sap_config->acs_cfg.skip_scan_status = eSAP_SKIP_ACS_SCAN;

                } else if (con_sap_st_ch >= cur_sap_st_ch &&
                    con_sap_end_ch >= cur_sap_end_ch) {

                    sap_config->acs_cfg.skip_scan_status = eSAP_DO_PAR_ACS_SCAN;

                    sap_config->acs_cfg.skip_scan_range1_stch = cur_sap_st_ch;
                    sap_config->acs_cfg.skip_scan_range1_endch =
                                                            con_sap_st_ch - 1;
                    sap_config->acs_cfg.skip_scan_range2_stch = 0;
                    sap_config->acs_cfg.skip_scan_range2_endch = 0;

                } else if (con_sap_st_ch <= cur_sap_st_ch &&
                    con_sap_end_ch <= cur_sap_end_ch) {

                    sap_config->acs_cfg.skip_scan_status = eSAP_DO_PAR_ACS_SCAN;

                    sap_config->acs_cfg.skip_scan_range1_stch =
                                                            con_sap_end_ch + 1;
                    sap_config->acs_cfg.skip_scan_range1_endch = cur_sap_end_ch;
                    sap_config->acs_cfg.skip_scan_range2_stch = 0;
                    sap_config->acs_cfg.skip_scan_range2_endch = 0;

                } else if (con_sap_st_ch >= cur_sap_st_ch &&
                    con_sap_end_ch <= cur_sap_end_ch) {

                    sap_config->acs_cfg.skip_scan_status = eSAP_DO_PAR_ACS_SCAN;

                    sap_config->acs_cfg.skip_scan_range1_stch = cur_sap_st_ch;
                    sap_config->acs_cfg.skip_scan_range1_endch =
                                                             con_sap_st_ch - 1;
                    sap_config->acs_cfg.skip_scan_range2_stch = con_sap_end_ch;
                    sap_config->acs_cfg.skip_scan_range2_endch =
                                                             cur_sap_end_ch + 1;

                } else
                    sap_config->acs_cfg.skip_scan_status = eSAP_DO_NEW_ACS_SCAN;
            }
            hddLog(LOG1,
                   FL("SecAP ACS Skip = %d, ACS CH RANGE = %d-%d, %d-%d"),
                   sap_config->acs_cfg.skip_scan_status,
                   sap_config->acs_cfg.skip_scan_range1_stch,
                   sap_config->acs_cfg.skip_scan_range1_endch,
                   sap_config->acs_cfg.skip_scan_range2_stch,
                   sap_config->acs_cfg.skip_scan_range2_endch);
        }
    }
#endif

    return 0;
}

/**
 * wlan_hdd_set_acs_ch_range : Start ACS channel range values
 * @sap_cfg: pointer to SAP config struct
 *
 * This function sets the default ACS start and end channel for the given band
 * and also parses the given ACS channel list.
 *
 * Return: None
 */

static void wlan_hdd_set_acs_ch_range(tsap_Config_t *sap_cfg, bool ht_enabled,
							bool vht_enabled)
{
	int i;
	if (sap_cfg->acs_cfg.hw_mode == QCA_ACS_MODE_IEEE80211B) {
		sap_cfg->acs_cfg.hw_mode = eCSR_DOT11_MODE_11b;
		sap_cfg->acs_cfg.start_ch = rfChannels[RF_CHAN_1].channelNum;
		sap_cfg->acs_cfg.end_ch = rfChannels[RF_CHAN_14].channelNum;
		sap_cfg->target_band = eCSR_BAND_24;
	} else if (sap_cfg->acs_cfg.hw_mode == QCA_ACS_MODE_IEEE80211G) {
		sap_cfg->acs_cfg.hw_mode = eCSR_DOT11_MODE_11g;
		sap_cfg->acs_cfg.start_ch = rfChannels[RF_CHAN_1].channelNum;
		sap_cfg->acs_cfg.end_ch = rfChannels[RF_CHAN_13].channelNum;
		sap_cfg->target_band = eCSR_BAND_24;
	} else if (sap_cfg->acs_cfg.hw_mode == QCA_ACS_MODE_IEEE80211A) {
		sap_cfg->acs_cfg.hw_mode = eCSR_DOT11_MODE_11a;
		sap_cfg->acs_cfg.start_ch = rfChannels[RF_CHAN_36].channelNum;
		sap_cfg->acs_cfg.end_ch = rfChannels[RF_CHAN_165].channelNum;
		sap_cfg->target_band = eCSR_BAND_5G;
	} else {
		hddLog(LOG1, FL("hw_mode %d"), sap_cfg->acs_cfg.hw_mode);
		sap_cfg->target_band = eCSR_BAND_5G;
	}
	if (ht_enabled)
		sap_cfg->acs_cfg.hw_mode = eCSR_DOT11_MODE_11n;

	if (vht_enabled)
		sap_cfg->acs_cfg.hw_mode = eCSR_DOT11_MODE_11ac;


	/* Parse ACS Chan list from hostapd */
	if (!sap_cfg->acs_cfg.ch_list)
		return;

	sap_cfg->acs_cfg.start_ch = sap_cfg->acs_cfg.ch_list[0];
	sap_cfg->acs_cfg.end_ch =
		sap_cfg->acs_cfg.ch_list[sap_cfg->acs_cfg.ch_list_count - 1];
	for (i = 0; i < sap_cfg->acs_cfg.ch_list_count; i++) {
		/* avoid channel 0 as start channel */
		if (sap_cfg->acs_cfg.start_ch > sap_cfg->acs_cfg.ch_list[i] &&
		   sap_cfg->acs_cfg.ch_list[i] != 0 )
			sap_cfg->acs_cfg.start_ch = sap_cfg->acs_cfg.ch_list[i];
		if (sap_cfg->acs_cfg.end_ch < sap_cfg->acs_cfg.ch_list[i])
			sap_cfg->acs_cfg.end_ch = sap_cfg->acs_cfg.ch_list[i];
	}

}


static void wlan_hdd_cfg80211_start_pending_acs(struct work_struct *work);

/**
 * wlan_hdd_cfg80211_start_acs : Start ACS Procedure for SAP
 * @adapter: pointer to SAP adapter struct
 *
 * This function starts the ACS procedure if there are no
 * constraints like MBSSID DFS restrictions.
 *
 * Return: Status of ACS Start procedure
 */

static int wlan_hdd_cfg80211_start_acs(hdd_adapter_t *adapter)
{

	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	tsap_Config_t *sap_config;
	tpWLAN_SAPEventCB acs_event_callback;
	int status;

	sap_config = &adapter->sessionCtx.ap.sapConfig;

	if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))
		sap_config->backup_channel = sap_config->channel;

	if (hdd_ctx->acs_policy.acs_channel)
		sap_config->channel = hdd_ctx->acs_policy.acs_channel;
	else
		sap_config->channel = AUTO_CHANNEL_SELECT;
	status = wlan_hdd_sap_cfg_dfs_override(adapter);
	if (status < 0) {
		return status;
	} else {
		if (status > 0) {
			/* notify hostapd about channel override */
			wlan_hdd_cfg80211_acs_ch_select_evt(adapter);
			clear_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags);
			return 0;
		}
	}

	status = wlan_hdd_config_acs(hdd_ctx, adapter);
	if (status) {
		hddLog(LOGE, FL("ACS config failed"));
		return -EINVAL;
	}

	acs_event_callback = hdd_hostapd_SAPEventCB;

	vos_mem_copy(sap_config->self_macaddr.bytes,
		adapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
	hddLog(LOG1, FL("ACS Started for wlan%d"), adapter->dev->ifindex);
	status = WLANSAP_ACS_CHSelect(
#ifdef WLAN_FEATURE_MBSSID
		WLAN_HDD_GET_SAP_CTX_PTR(adapter),
#else
		hdd_ctx->pvosContext,
#endif
		acs_event_callback, sap_config, (v_PVOID_t)adapter->dev);


	if (status) {
		hddLog(LOGE, FL("ACS channel select failed"));
		return -EINVAL;
	}
	sap_config->acs_cfg.acs_mode = true;
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
	if (is_auto_channel_select(WLAN_HDD_GET_SAP_CTX_PTR(adapter)))
#endif
	set_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags);

	return 0;
}

/**
 * wlan_hdd_cfg80211_relaunch_acs() - Relaunch ACS for SAP
 * @adapter: pointer to SAP adapter structure
 *
 * This function relaunches ACS.
 *
 * Return: Result status of ACS relaunch
 */

static int wlan_hdd_cfg80211_relaunch_acs(hdd_adapter_t *adapter)
{
	uint8_t channel_list[MAX_CHANNEL] = {0};
	uint8_t number_of_channels = 0;
	hdd_context_t *hdd_ctx = (hdd_context_t *)adapter->pHddCtx;
	tsap_Config_t *sap_config;
	int status;
	uint8_t cur_band, i;
	uint8_t band_start_channel;
	uint8_t band_end_channel;
	bool ht_enabled = false, vht_enabled = false;

	if (!test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
		hddLog(LOGE, FL("Softap is not started"));
		return -EINVAL;
	}

	cur_band = vos_chan_to_band((WLAN_HDD_GET_AP_CTX_PTR(
				   adapter))->operatingChannel);
	sap_config = &adapter->sessionCtx.ap.sapConfig;
	vos_mem_zero(&sap_config->acs_cfg, sizeof(struct sap_acs_cfg));

	if (VOS_BAND_2GHZ == cur_band) {
		band_start_channel = RF_CHAN_1;
		band_end_channel = RF_CHAN_14;
	} else {
		band_start_channel = RF_CHAN_36;
		band_end_channel = RF_CHAN_165;
	}

	for (i = band_start_channel; i <= band_end_channel; i++) {
		if (NV_CHANNEL_ENABLE ==
			vos_nv_getChannelEnabledState(
			    rfChannels[i].channelNum)) {
			channel_list[number_of_channels++] =
			    rfChannels[i].channelNum;
			hddLog(LOG1,
			       FL("Config acs channel[%d]"),
			       rfChannels[i].channelNum);
		}
	}

	if (sap_config->SapHw_mode &
		(eCSR_DOT11_MODE_11n |
		 eCSR_DOT11_MODE_11n_ONLY |
		 eCSR_DOT11_MODE_11ac))
		ht_enabled = true;

	if (sap_config->SapHw_mode &
		(eCSR_DOT11_MODE_11ac |
		 eCSR_DOT11_MODE_11ac_ONLY))
		vht_enabled = true;

	sap_config->acs_cfg.ch_width = sap_config->ch_width_orig;

	hddLog(LOG1,
	       FL("ht_enabled=%d vht_enabled=%d ch_width=%d"),
	       ht_enabled,
	       vht_enabled,
	       sap_config->acs_cfg.ch_width);

	wlan_hdd_set_acs_ch_range(sap_config, ht_enabled, vht_enabled);

	sap_config->acsBandSwitchThreshold =
	    hdd_ctx->cfg_ini->acsBandSwitchThreshold;

	if (hdd_ctx->cfg_ini->auto_channel_select_weight)
		sap_config->auto_channel_select_weight =
		    hdd_ctx->cfg_ini->auto_channel_select_weight;

	sap_config->acs_cfg.acs_mode = true;
	if (test_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags)) {
		hddLog(LOG1, FL("ACS Pending for wlan"));
		status = -EINVAL;
	} else {
		hddLog(LOG1, FL("Relaunch ACS"));
		wlan_hdd_cfg80211_start_acs(adapter);
		status = 0;
	}

	return status;
}

#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
/**
 * wlan_hdd_set_mcc_to_scc_switch() - set mcc to scc switch mode from ini
 * @adapter:  hdd_adapter_t ptr of the interface
 *
 * This function updates ini WlanMccToSccSwitchMode value to adapter
 * context. The value controls the MCC to SCC switch behavior.
 *
 * Return: void
 */
static void
wlan_hdd_set_mcc_to_scc_switch(hdd_adapter_t *adapter)
{
	hdd_context_t * hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	hdd_config_t *cfg_ini = hdd_ctx->cfg_ini;
	tsap_Config_t *sap_config;

	sap_config = &adapter->sessionCtx.ap.sapConfig;
	sap_config->cc_switch_mode = cfg_ini->WlanMccToSccSwitchMode;
	sap_config->band_switch_enable = cfg_ini->wlan_band_switch_enable;
	sap_config->ap_p2pclient_concur_enable =
		cfg_ini->wlan_ap_p2pgo_conc_enable;
	sap_config->ch_width_24g_orig = cfg_ini->nChannelBondingMode24GHz ?
		eHT_CHANNEL_WIDTH_40MHZ : eHT_CHANNEL_WIDTH_20MHZ;
	sap_config->ch_width_5g_orig = cfg_ini->vhtChannelWidth;
}
#else
static void
wlan_hdd_set_mcc_to_scc_switch(hdd_adapter_t *adapter)
{}
#endif
static const struct nla_policy
wlan_hdd_cfg80211_do_acs_policy[QCA_WLAN_VENDOR_ATTR_ACS_MAX+1] = {
	[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE] = { .type = NLA_U8 },
	[QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED] = { .type = NLA_FLAG },
	[QCA_WLAN_VENDOR_ATTR_ACS_HT40_ENABLED] = { .type = NLA_FLAG },
	[QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED] = { .type = NLA_FLAG },
	[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH] = { .type = NLA_U16 },
	[QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST] = { .type = NLA_UNSPEC },
};


/**
 * __wlan_hdd_cfg80211_do_acs() : CFG80211 handler fucntion for DO_ACS
 * Vendor CMD
 * @wiphy:  Linux wiphy struct pointer
 * @wdev:   Linux wireless device struct pointer
 * @data:   ACS information from hostapd
 * @data_len: ACS information len
 *
 * This function handle DO_ACS Vendor command from hostapd, parses ACS config
 * and starts ACS procedure.
 *
 * Return: ACS procedure start status
 */

static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
					struct wireless_dev *wdev,
					const void *data, int data_len)
{
	struct net_device *ndev = wdev->netdev;
	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
	tsap_Config_t *sap_config;
	struct sk_buff *temp_skbuff;
	int status = -EINVAL, i = 0;
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACS_MAX + 1];
	bool ht_enabled, ht40_enabled, vht_enabled;
	uint8_t ch_width;

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

	if (hdd_ctx->cfg_ini->force_sap_acs) {
		hddLog(LOGE, FL("Hostapd ACS rejected as driver INI force ACS is enabled"));
		return -EPERM;
	}

	/* ***Note*** Donot set SME config related to ACS operation here because
	 * ACS operation is not synchronouse and ACS for Second AP may come when
	 * ACS operation for first AP is going on. So only do_acs is split to
	 * seperate start_acs routine. Also SME-PMAC struct that is used to
	 * pass paremeters from HDD to SAP is global. Thus All ACS related SME
	 * config shall be set only from start_acs.
	 */

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

	if (hdd_cfg_is_static_sub20_channel_width_enabled(hdd_ctx)) {
		hddLog(LOGE, FL("ACS not support if static sub20 enable"));
		status = -EINVAL;
		goto out;
	}

	if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
		uint32_t sap_sub20_channelwidth;
		WLANSAP_get_sub20_channelwidth(WLAN_HDD_GET_SAP_CTX_PTR(
						adapter),
					       &sap_sub20_channelwidth);
		if (sap_sub20_channelwidth == SUB20_MODE_NONE) {
			hddLog(LOGE, FL("Bss started, relaunch ACS"));
			status = wlan_hdd_cfg80211_relaunch_acs(adapter);
		} else {
			hddLog(LOGE, FL("ACS not support in sub20 enable"));
			status = -EINVAL;
		}
		return status;
	}

	sap_config = &adapter->sessionCtx.ap.sapConfig;
	vos_mem_zero(&sap_config->acs_cfg, sizeof(struct sap_acs_cfg));

	status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ACS_MAX, data, data_len,
						wlan_hdd_cfg80211_do_acs_policy, NULL);
	if (status) {
		hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
		goto out;
	}

	if (!tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]) {
		hddLog(VOS_TRACE_LEVEL_ERROR, FL("Attr hw_mode failed"));
		goto out;
	}
	sap_config->acs_cfg.hw_mode = nla_get_u8(
					tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]);

	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED])
		ht_enabled =
			nla_get_flag(tb[QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED]);
	else
		ht_enabled = 0;

	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_HT40_ENABLED])
		ht40_enabled =
			nla_get_flag(tb[QCA_WLAN_VENDOR_ATTR_ACS_HT40_ENABLED]);
	else
		ht40_enabled = 0;

	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED])
		vht_enabled =
			nla_get_flag(tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED]);
	else
		vht_enabled = 0;

	if (hdd_ctx->cfg_ini->sap_force_11n_for_11ac) {
		vht_enabled = 0;
		hddLog(LOG1, FL("VHT is Disabled in ACS"));
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH]) {
		ch_width = nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH]);
	} else {
		if (ht_enabled && ht40_enabled)
			ch_width = 40;
		else
			ch_width = 20;
	}

	/* this may be possible, when sap_force_11n_for_11ac is set */
	if ((ch_width == 80 || ch_width == 160) && !vht_enabled) {
		if (ht_enabled && ht40_enabled)
			ch_width = 40;
		else
			ch_width = 20;
	}

	if (ch_width == 80)
		sap_config->acs_cfg.ch_width = eHT_CHANNEL_WIDTH_80MHZ;
	else if (ch_width == 40)
		sap_config->acs_cfg.ch_width = eHT_CHANNEL_WIDTH_40MHZ;
	else
		sap_config->acs_cfg.ch_width = eHT_CHANNEL_WIDTH_20MHZ;

	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST]) {
		char *tmp = nla_data(tb[QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST]);
		sap_config->acs_cfg.ch_list_count = nla_len(
					tb[QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST]);
		if (sap_config->acs_cfg.ch_list_count) {
			sap_config->acs_cfg.ch_list = vos_mem_malloc(
					sizeof(uint8_t) *
					sap_config->acs_cfg.ch_list_count);
			if (sap_config->acs_cfg.ch_list == NULL) {
				hddLog(LOGE, FL("ACS config alloc fail"));
				status = -ENOMEM;
				goto out;
			}
			vos_mem_copy(sap_config->acs_cfg.ch_list, tmp,
					sap_config->acs_cfg.ch_list_count);
		}
	}
	wlan_hdd_set_mcc_to_scc_switch(adapter);
	wlan_hdd_set_acs_ch_range(sap_config, ht_enabled, vht_enabled);

	/* ACS override for android */
	if (hdd_ctx->cfg_ini->sap_p2p_11ac_override && ht_enabled &&
	    !hdd_ctx->cfg_ini->sap_force_11n_for_11ac) {
		hddLog(LOG1, FL("ACS Config override for 11AC"));
		vht_enabled = 1;
		sap_config->acs_cfg.hw_mode = eCSR_DOT11_MODE_11ac;
		sap_config->acs_cfg.ch_width =
					 hdd_ctx->cfg_ini->vhtChannelWidth;
		/* No VHT80 in 2.4G so perform ACS accordingly */
		if (sap_config->acs_cfg.end_ch <= 14 &&
			sap_config->acs_cfg.ch_width == eHT_CHANNEL_WIDTH_80MHZ)
			sap_config->acs_cfg.ch_width = eHT_CHANNEL_WIDTH_40MHZ;
	}

	sap_config->acsBandSwitchThreshold =
		hdd_ctx->cfg_ini->acsBandSwitchThreshold;

	if (hdd_ctx->cfg_ini->auto_channel_select_weight)
		sap_config->auto_channel_select_weight =
		    hdd_ctx->cfg_ini->auto_channel_select_weight;

	hddLog(LOG1, FL("ACS Config for wlan%d: HW_MODE: %d ACS_BW: %d HT: %d VHT: %d START_CH: %d END_CH: %d"),
		adapter->dev->ifindex, sap_config->acs_cfg.hw_mode,
		ch_width, ht_enabled, vht_enabled,
		sap_config->acs_cfg.start_ch, sap_config->acs_cfg.end_ch);

	if (sap_config->acs_cfg.ch_list_count) {
		hddLog(LOG1, FL("ACS channel list: len: %d"),
					sap_config->acs_cfg.ch_list_count);
		for (i = 0; i < sap_config->acs_cfg.ch_list_count; i++)
			hddLog(LOG1, "%d ", sap_config->acs_cfg.ch_list[i]);
	}
	sap_config->acs_cfg.acs_mode = true;
	if (test_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags)) {
		/* ***Note*** Completion variable usage is not allowed here since
		 * ACS scan operation may take max 2.2 sec for 5G band.
		 * 9 Active channel X 40 ms active scan time +
		 * 16 Passive channel X 110ms passive scan time
		 * Since this CFG80211 call lock rtnl mutex, we cannot hold on
		 * for this long. So we split up the scanning part.
		 */
		set_bit(ACS_PENDING, &adapter->event_flags);
		hddLog(LOG1, FL("ACS Pending for wlan%d"),
							adapter->dev->ifindex);
		status = 0;
	} else {
		status = wlan_hdd_cfg80211_start_acs(adapter);
	}

out:
	if (0 == status) {
		temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
							      NLMSG_HDRLEN);
		if (temp_skbuff != NULL)
			return cfg80211_vendor_cmd_reply(temp_skbuff);
	}
	wlan_hdd_undo_acs(adapter);
	clear_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags);

	return status;
}

/**
 * wlan_hdd_cfg80211_do_acs : CFG80211 handler fucntion for DO_ACS Vendor CMD
 * @wiphy:  Linux wiphy struct pointer
 * @wdev:   Linux wireless device struct pointer
 * @data:   ACS information from hostapd
 * @data_len: ACS information len
 *
 * This function handle DO_ACS Vendor command from hostapd, parses ACS config
 * and starts ACS procedure.
 *
 * Return: ACS procedure start status
 */

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

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

	return ret;
}

/**
 * wlan_hdd_undo_acs : Do cleanup of DO_ACS
 * @adapter:  Pointer to adapter struct
 *
 * This function handle cleanup of what was done in DO_ACS, including free
 * memory.
 *
 * Return: void
 */

void wlan_hdd_undo_acs(hdd_adapter_t *adapter)
{
	if (adapter == NULL)
		return;
	if (adapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list) {
		vos_mem_free(adapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list);
		adapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list = NULL;
	}
}

/**
 * wlan_hdd_cfg80211_start_pending_acs : Start pending ACS procedure for SAP
 * @work:  Linux workqueue struct pointer for ACS work
 *
 * This function starts the ACS procedure which was marked pending when an ACS
 * procedure was in progress for a concurrent SAP interface.
 *
 * Return: None
 */

static void wlan_hdd_cfg80211_start_pending_acs(struct work_struct *work)
{
	hdd_adapter_t *adapter = container_of(work, hdd_adapter_t,
							acs_pending_work.work);
	wlan_hdd_cfg80211_start_acs(adapter);
}

/**
 * wlan_hdd_cfg80211_acs_ch_select_evt: Callback function for ACS evt
 * @adapter: Pointer to SAP adapter struct
 * @pri_channel: SAP ACS procedure selected Primary channel
 * @sec_channel: SAP ACS procedure selected secondary channel
 *
 * This is a callback function from SAP module on ACS procedure is completed.
 * This function send the ACS selected channel information to hostapd
 *
 * Return: None
 */

void wlan_hdd_cfg80211_acs_ch_select_evt(hdd_adapter_t *adapter)
{
	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	tsap_Config_t *sap_cfg = &(WLAN_HDD_GET_AP_CTX_PTR(adapter))->sapConfig;
	struct sk_buff *vendor_event;
	int ret_val;
	struct nlattr *nla;
	hdd_adapter_t *con_sap_adapter;
	uint16_t ch_width;

	vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
			NULL,
			4 * sizeof(u8) + 1 * sizeof(u16) + 4 + NLMSG_HDRLEN,
			QCA_NL80211_VENDOR_SUBCMD_DO_ACS_INDEX,
			GFP_KERNEL);

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

	/* Send the IF INDEX to differentiate the ACS event for each interface
	 * TODO: To be update once cfg80211 APIs are updated to accept if_index
	 */
	nla_nest_cancel(vendor_event, ((void **)vendor_event->cb)[2]);

	ret_val = nla_put_u32(vendor_event, NL80211_ATTR_IFINDEX,
							adapter->dev->ifindex);
	if (ret_val) {
		hddLog(LOGE, FL("NL80211_ATTR_IFINDEX put fail"));
		kfree_skb(vendor_event);
		return;
	}

	nla = nla_nest_start(vendor_event, NL80211_ATTR_VENDOR_DATA);
	((void **)vendor_event->cb)[2] = nla;

	ret_val = nla_put_u8(vendor_event,
				QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL,
				sap_cfg->acs_cfg.pri_ch);
	if (ret_val) {
		hddLog(LOGE,
			FL("QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL put fail"));
		kfree_skb(vendor_event);
		return;
	}

	ret_val = nla_put_u8(vendor_event,
				QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL,
				sap_cfg->acs_cfg.ht_sec_ch);
	if (ret_val) {
		hddLog(LOGE,
			FL(
			"QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL put fail"));
		kfree_skb(vendor_event);
		return;
	}

	ret_val = nla_put_u8(vendor_event,
				QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL,
				sap_cfg->acs_cfg.vht_seg0_center_ch);
	if (ret_val) {
		hddLog(LOGE,
			FL(
			"QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL put fail"));
		kfree_skb(vendor_event);
		return;
	}

	ret_val = nla_put_u8(vendor_event,
				QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL,
				sap_cfg->acs_cfg.vht_seg1_center_ch);
	if (ret_val) {
		hddLog(LOGE,
			FL(
			"QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL put fail"));
		kfree_skb(vendor_event);
		return;
	}

	if (sap_cfg->acs_cfg.ch_width == eHT_CHANNEL_WIDTH_80MHZ)
		ch_width = 80;
	else if (sap_cfg->acs_cfg.ch_width == eHT_CHANNEL_WIDTH_40MHZ)
		ch_width = 40;
	else
		ch_width = 20;

	ret_val = nla_put_u16(vendor_event,
				QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH,
				ch_width);
	if (ret_val) {
		hddLog(LOGE,
			FL(
			"QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH put fail"));
		kfree_skb(vendor_event);
		return;
	}

	hddLog(LOG1,
		FL("ACS result for wlan%d: PRI_CH: %d SEC_CH: %d VHT_SEG0: %d VHT_SEG1: %d ACS_BW: %d"),
		adapter->dev->ifindex, sap_cfg->acs_cfg.pri_ch,
		sap_cfg->acs_cfg.ht_sec_ch,sap_cfg->acs_cfg.vht_seg0_center_ch,
		sap_cfg->acs_cfg.vht_seg1_center_ch, ch_width);

	cfg80211_vendor_event(vendor_event, GFP_KERNEL);
	/* ***Note*** As already mentioned Completion variable usage is not
	 * allowed here since ACS scan operation may take max 2.2 sec.
	 * Further in AP-AP mode pending ACS is resumed here to serailize ACS
	 * operation.
	 * TODO: Delayed operation is used since SME-PMAC strut is global. Thus
	 * when Primary AP ACS is complete and secondary AP ACS is started here
	 * immediately, Primary AP start_bss may come inbetween ACS operation
	 * and overwrite Sec AP ACS paramters. Thus Sec AP ACS is executed with
	 * delay. This path and below constraint will be removed on sessionizing
	 * SAP acs parameters and decoupling SAP from PMAC (WIP).
	 * As per design constraint user space control application must take
	 * care of serailizing hostapd start for each VIF in AP-AP mode to avoid
	 * this code path. Sec AP hostapd should be started after Primary AP
	 * start beaconing which can be confirmed by getchannel iwpriv command
	 */

	con_sap_adapter = hdd_get_con_sap_adapter(adapter, false);
	if (con_sap_adapter &&
		test_bit(ACS_PENDING, &con_sap_adapter->event_flags)) {
#ifdef CONFIG_CNSS
		cnss_init_delayed_work(&con_sap_adapter->acs_pending_work,
				      wlan_hdd_cfg80211_start_pending_acs);
#else
		INIT_DELAYED_WORK(&con_sap_adapter->acs_pending_work,
				      wlan_hdd_cfg80211_start_pending_acs);
#endif
		/* Lets give 500ms for OBSS + START_BSS to complete */
		schedule_delayed_work(&con_sap_adapter->acs_pending_work,
							msecs_to_jiffies(500));
		clear_bit(ACS_PENDING, &con_sap_adapter->event_flags);
	}

	return;
}

static const struct nla_policy
wlan_hdd_wifi_config_policy[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
                            +1] =
{
	[QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM] = {.type = NLA_U32 },
	[QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR] = {.type = NLA_U16 },
	[QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME] = {.type = NLA_U32 },
	[QCA_WLAN_VENDOR_ATTR_CONFIG_FINE_TIME_MEASUREMENT] = {.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_RATE] = {.type = NLA_U16 },
	[QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_AVOIDANCE_IND] = {.type = NLA_U8 },
	[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MPDU_AGGREGATION] = {.type = NLA_U8 },
	[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MPDU_AGGREGATION] = {.type = NLA_U8 },
	[QCA_WLAN_VENDOR_ATTR_CONFIG_NON_AGG_RETRY] = {.type = NLA_U8},
	[QCA_WLAN_VENDOR_ATTR_CONFIG_AGG_RETRY] = {.type = NLA_U8},
	[QCA_WLAN_VENDOR_ATTR_CONFIG_MGMT_RETRY] = {.type = NLA_U8},
	[QCA_WLAN_VENDOR_ATTR_CONFIG_CTRL_RETRY] = {.type = NLA_U8},
	[QCA_WLAN_VENDOR_ATTR_CONFIG_PROPAGATION_DELAY] = {.type = NLA_U8},
	[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_FAIL_COUNT] = {.type = NLA_U32 },
	[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ENA] = {.type = NLA_U32 },
	[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_CHAIN] = {.type = NLA_U32 },
	[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST] = {.type = NLA_U32 },
	[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST_INTVL] = {.type = NLA_U32 },
	[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VOICE] = {
							.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VIDEO] = {
							.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BESTEFFORT] = {
							.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BACKGROUND] = {
							.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_PEER_MAC] = {
							.type = NLA_UNSPEC},
	[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_WINLIMIT] = {
							.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_CONFIG_SUB20_CHAN_WIDTH] = {.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_CONFIG_PROPAGATION_ABS_DELAY] = {.type = NLA_U32},
};

/**
 * wlan_hdd_update_tx_rate() - update tx rate to firmware
 * @hdd_ctx: HDD context
 * @tx_rate: User-specified tx-rate to be operated for the specific
 * HW mode.
 * Return: 0 on success; Errno on failure
 */
int wlan_hdd_update_tx_rate(hdd_context_t *hddctx, uint16_t tx_rate)
{

	hdd_adapter_t *adapter;
	hdd_station_ctx_t *hddstactx;
	eHalStatus hstatus;
	struct sir_txrate_update *buf_txrate_update;

	ENTER();
	adapter = hdd_get_adapter(hddctx, WLAN_HDD_INFRA_STATION);
	if (!adapter) {
		hddLog(LOGE, FL("hdd adapter is null"));
		return -EINVAL;
	}
	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
		hddLog(LOGE, FL("hdd adapter cookie is invalid"));
		return -EINVAL;
	}

	if (WLAN_HDD_INFRA_STATION != adapter->device_mode) {
		hddLog(LOGE, FL("Only Sta Mode supported!"));
		return -ENOTSUPP;
	}

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

	buf_txrate_update = vos_mem_malloc(sizeof(*buf_txrate_update));
	if (!buf_txrate_update) {
		hddLog(LOGE, FL("Failed to allocate memory for buf_txrate_update"));
		return -ENOMEM;
	}


	buf_txrate_update->session_id = adapter->sessionId;

	buf_txrate_update->txrate = tx_rate;
	vos_mem_copy(buf_txrate_update->bssid, hddstactx->conn_info.bssId,
				VOS_MAC_ADDR_SIZE);

	hstatus = sme_update_txrate(hddctx->hHal, buf_txrate_update);
	if (!HAL_STATUS_SUCCESS(hstatus)) {
		hddLog(LOGE,
			FL("sme_update_txrate failed(err=%d)"), hstatus);
		vos_mem_free(buf_txrate_update);
		return -EINVAL;
	}
	EXIT();
	vos_mem_free(buf_txrate_update);
	return 0;
}

/**
 * hdd_set_qpower_config() - set qpower config to firmware
 * @adapter: HDD adapter
 * @qpower: new qpower config value
 *
 * Return: 0 on success; Errno on failure
 */
static int hdd_set_qpower_config(hdd_context_t *hddctx, hdd_adapter_t *adapter,
				 uint8_t qpower)
{
	VOS_STATUS vos_status;

	if(!adapter) {
		hddLog(LOGE,"invalid adapter");
		return -EINVAL;
	}
	if (adapter->device_mode != WLAN_HDD_INFRA_STATION &&
	    adapter->device_mode != WLAN_HDD_P2P_CLIENT) {
		hddLog(VOS_TRACE_LEVEL_INFO,
		       FL("QPOWER is only supported for STA/P2P-CLIENT"));
		return -EINVAL;
	}
	if (!hddctx->cfg_ini->enablePowersaveOffload) {
		hddLog(LOGE,
		       FL("qpower is disabled in configuration"));
		return -EINVAL;
	}
	if (qpower > PS_DUTY_CYCLING_QPOWER ||
	    qpower < PS_LEGACY_NODEEPSLEEP) {
		hddLog(LOGE,
		       FL("invalid qpower value=%d"), qpower);
		return -EINVAL;
	}
	vos_status = wma_set_powersave_config(adapter->sessionId, qpower);
	if (vos_status != VOS_STATUS_SUCCESS) {
		hddLog(LOGE,
		       FL("failed to update qpower %d"),
		       vos_status);
		return -EINVAL;
	}
	return 0;
}

/**
 * hdd_sta_set_sub20_channelwidth() -
 * This api function does a sub20 channel width change
 * for STA while STA in disconnect state
 * @adapter: HDD adapter
 * @chan_width:  New channel width change to
 *
 * Return: The VOS_STATUS code associated with performing
 * the operation
 */
static VOS_STATUS
hdd_sta_set_sub20_channelwidth(hdd_adapter_t *adapter, uint32_t chan_width)
{
	tHalHandle hal_ptr;

	hddLog(LOGE, FL("chanwidth: %d"), chan_width);

	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
		hddLog(LOGE, FL("hdd adapter cookie is invalid"));
		return -EINVAL;
	}

	if (WLAN_HDD_INFRA_STATION != adapter->device_mode) {
		hddLog(LOGE, FL("Only Sta Mode supported!"));
		return -ENOTSUPP;
	}

	hal_ptr = WLAN_HDD_GET_HAL_CTX(adapter);
	if (hal_ptr == NULL) {
		hddLog(LOGE, FL("hdd hal is null"));
		return -EINVAL;
	}

	sme_set_sta_chanlist_with_sub20(hal_ptr, chan_width);

	return VOS_STATUS_SUCCESS;
}

/**
 * hdd_get_sub20_channelwidth() -
 * This api function get sub20 channel width
 * @adapter: HDD adapter
 * @sub20_channelwidth:  restore sub20 channel width
 *
 * Return: The VOS_STATUS code associated with performing
 * the operation
 */
static VOS_STATUS
hdd_get_sub20_channelwidth(hdd_adapter_t *adapter, uint32_t *sub20_channelwidth)
{
	tHalHandle hal_ptr = WLAN_HDD_GET_HAL_CTX(adapter);
	tpAniSirGlobal mac_ptr = PMAC_STRUCT(hal_ptr);
	v_CONTEXT_t vos_ctx_ptr = WLAN_HDD_GET_SAP_CTX_PTR(adapter);
	uint32_t sap_sub20_channelwidth;

	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
		hddLog(LOGE, FL("hdd adapter cookie is invalid"));
		return -EINVAL;
	}

	if (WLAN_HDD_INFRA_STATION == adapter->device_mode) {
		*sub20_channelwidth = mac_ptr->sta_sub20_current_channelwidth ?
			mac_ptr->sta_sub20_current_channelwidth :
			mac_ptr->sub20_channelwidth;
	} else if (WLAN_HDD_SOFTAP == adapter->device_mode) {
		WLANSAP_get_sub20_channelwidth(vos_ctx_ptr,
					       &sap_sub20_channelwidth);
		*sub20_channelwidth = sap_sub20_channelwidth;
	} else {
		hddLog(LOGE, FL("error dev mode!"));
		return -EINVAL;
	}

	return VOS_STATUS_SUCCESS;
}

/**
 * __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);
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX + 1];
	int ret_val = 0;
	u32 modulated_dtim;
	uint16_t stats_avg_factor, tx_rate;
	uint8_t set_value, retry, qpower, delay;
	uint32_t abs_delay;
	u32 guard_time;
	u32 ftm_capab;
	eHalStatus status;
	struct sir_set_tx_rx_aggregation_size request;
	struct sir_set_rx_reorder_timeout_val reorder_timeout;
	struct sir_peer_set_rx_blocksize rx_blocksize;
	VOS_STATUS vos_status;
	uint32_t tx_fail_count;
	uint32_t antdiv_ena, antdiv_chain;
	uint32_t antdiv_selftest, antdiv_selftest_intvl;
	int attr_len;
	int access_policy = 0;
	char vendor_ie[SIR_MAC_MAX_IE_LENGTH + 2];
	bool vendor_ie_present = false, access_policy_present = false;
	uint32_t ant_div_usrcfg;

	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;

	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_CONFIG_MAX,
		      data, data_len,
		      wlan_hdd_wifi_config_policy, NULL)) {
		hddLog(LOGE, FL("invalid attr"));
		return -EINVAL;
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_FINE_TIME_MEASUREMENT]) {
		ftm_capab = nla_get_u32(tb[
			QCA_WLAN_VENDOR_ATTR_CONFIG_FINE_TIME_MEASUREMENT]);
		pHddCtx->cfg_ini->fine_time_meas_cap =
			pHddCtx->fine_time_meas_cap_target & ftm_capab;
		sme_update_fine_time_measurement_capab(pHddCtx->hHal,
				     pHddCtx->cfg_ini->fine_time_meas_cap);
		hddLog(LOG1,
		       "FTM capability: user value: 0x%x, target value: 0x%x, final value: 0x%x",
		       ftm_capab, pHddCtx->fine_time_meas_cap_target,
		       pHddCtx->cfg_ini->fine_time_meas_cap);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM]) {
		modulated_dtim = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM]);

		status = sme_configure_modulated_dtim(pHddCtx->hHal,
							pAdapter->sessionId,
							modulated_dtim);

		if (eHAL_STATUS_SUCCESS != status)
			ret_val = -EPERM;
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR]) {
		stats_avg_factor = nla_get_u16(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR]);
		status = sme_configure_stats_avg_factor(pHddCtx->hHal,
							pAdapter->sessionId,
							stats_avg_factor);

		if (eHAL_STATUS_SUCCESS != status)
			ret_val = -EPERM;
	}


	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME]) {
		guard_time = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME]);
		status = sme_configure_guard_time(pHddCtx->hHal,
						  pAdapter->sessionId,
						  guard_time);

		if (eHAL_STATUS_SUCCESS != status)
			ret_val = -EPERM;
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_RATE]) {
		tx_rate = nla_get_u16(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_RATE]);
		hddLog(LOG1, "Config Txrate: tx_rate received :%d", tx_rate);
		status = wlan_hdd_update_tx_rate(pHddCtx, tx_rate);

		if (eHAL_STATUS_SUCCESS != status)
			ret_val = -EPERM;
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_AVOIDANCE_IND]) {
		set_value = nla_get_u8(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_AVOIDANCE_IND]);
		hddLog(LOG1, "set_value: %d", set_value);
		ret_val = hdd_enable_disable_ca_event(pHddCtx, set_value);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]) {
		qpower = nla_get_u8(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]);
		if (hdd_set_qpower_config(pHddCtx, pAdapter, qpower) != 0)
			ret_val = -EINVAL;
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MPDU_AGGREGATION] ||
	    tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MPDU_AGGREGATION]) {
		/* if one is specified, both must be specified */
		if (!tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MPDU_AGGREGATION] ||
		    !tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MPDU_AGGREGATION]) {
			hddLog(LOGE,
				FL("Both TX and RX MPDU Aggregation required"));
			return -EINVAL;
		}

		request.tx_aggregation_size = nla_get_u8(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MPDU_AGGREGATION]);
		request.rx_aggregation_size = nla_get_u8(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MPDU_AGGREGATION]);
		request.vdev_id = pAdapter->sessionId;

		if (request.tx_aggregation_size >=
					CFG_TX_AGGREGATION_SIZE_MIN &&
			request.tx_aggregation_size <=
					CFG_TX_AGGREGATION_SIZE_MAX &&
			request.rx_aggregation_size >=
					CFG_RX_AGGREGATION_SIZE_MIN &&
			request.rx_aggregation_size <=
					CFG_RX_AGGREGATION_SIZE_MAX) {
			vos_status = wma_set_tx_rx_aggregation_size(&request);
			if (vos_status != VOS_STATUS_SUCCESS) {
				hddLog(LOGE,
					FL("failed to set aggr sizes err %d"),
					vos_status);
				ret_val = -EPERM;
			}
		} else {
			hddLog(LOGE,
				FL("TX %d RX %d MPDU aggr size not in range"),
				request.tx_aggregation_size,
				request.rx_aggregation_size);
			ret_val = -EINVAL;
		}
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_NON_AGG_RETRY]) {
		retry = nla_get_u8(
				tb[QCA_WLAN_VENDOR_ATTR_CONFIG_NON_AGG_RETRY]);

		retry = retry > CFG_NON_AGG_RETRY_MAX ?
				CFG_NON_AGG_RETRY_MAX : retry;

		if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_IFINDEX]) {
			status = sme_update_short_retry_limit_threshold(
					pHddCtx->hHal,
					pAdapter->sessionId,
					retry);
			if (!HAL_STATUS_SUCCESS(status)) {
				hddLog(LOGE,
				FL("sme_update_short_retry_limit_threshold(err=%d)"),
				status);
				return -EINVAL;
			}
		} else {
			ret_val = process_wma_set_command(
					(int)pAdapter->sessionId,
					(int)WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH,
					retry, PDEV_CMD);
		}
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_AGG_RETRY]) {
		retry = nla_get_u8(
				tb[QCA_WLAN_VENDOR_ATTR_CONFIG_AGG_RETRY]);

		retry = retry > CFG_AGG_RETRY_MAX ?
			CFG_AGG_RETRY_MAX : retry;

		/* Value less than CFG_AGG_RETRY_MIN has side effect to t-put */
		retry = ((retry > 0) && (retry < CFG_AGG_RETRY_MIN)) ?
				CFG_AGG_RETRY_MIN : retry;

		if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_IFINDEX]) {
			status = sme_update_long_retry_limit_threshold(
					pHddCtx->hHal,
					pAdapter->sessionId,
					retry);
			if (!HAL_STATUS_SUCCESS(status)) {
				hddLog(LOGE,
				FL("sme_update_long_retry_limit_threshold(err=%d)"),
						status);
				return -EINVAL;
			}
		} else {
			ret_val = process_wma_set_command(
					(int)pAdapter->sessionId,
					(int)WMI_PDEV_PARAM_AGG_SW_RETRY_TH,
					retry, PDEV_CMD);
		}

	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_MGMT_RETRY]) {
		retry = nla_get_u8(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_MGMT_RETRY]);

		retry = retry > CFG_MGMT_RETRY_MAX ?
				CFG_MGMT_RETRY_MAX : retry;
		ret_val = process_wma_set_command((int)pAdapter->sessionId,
				(int)WMI_PDEV_PARAM_MGMT_RETRY_LIMIT,
				retry, PDEV_CMD);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_CTRL_RETRY]) {
		retry = nla_get_u8(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_CTRL_RETRY]);
		retry = retry > CFG_CTRL_RETRY_MAX ?
				CFG_CTRL_RETRY_MAX : retry;
		ret_val = process_wma_set_command((int)pAdapter->sessionId,
				(int)WMI_PDEV_PARAM_CTRL_RETRY_LIMIT,
				retry, PDEV_CMD);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_PROPAGATION_DELAY]) {
		delay = nla_get_u8(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_PROPAGATION_DELAY]);
		delay = delay > CFG_PROPAGATION_DELAY_MAX ?
				CFG_PROPAGATION_DELAY_MAX : delay;
		abs_delay = delay + CFG_PROPAGATION_DELAY_BASE;
		ret_val = process_wma_set_command((int)pAdapter->sessionId,
				(int)WMI_PDEV_PARAM_PROPAGATION_DELAY,
				abs_delay, PDEV_CMD);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_PROPAGATION_ABS_DELAY]) {
		abs_delay = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_PROPAGATION_ABS_DELAY]);
		ret_val = process_wma_set_command((int)pAdapter->sessionId,
				(int)WMI_PDEV_PARAM_PROPAGATION_DELAY,
				abs_delay, PDEV_CMD);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_FAIL_COUNT]) {
		tx_fail_count = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_FAIL_COUNT]);
		if (tx_fail_count) {
			status = sme_update_tx_fail_cnt_threshold(pHddCtx->hHal,
				pAdapter->sessionId,
				tx_fail_count);
			if (!HAL_STATUS_SUCCESS(status)) {
				hddLog(LOGE,
				FL("sme_update_tx_fail_cnt_threshold (err=%d)"),
				status);
				return -EINVAL;
			}
		}
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY_IE_LIST]) {
		vos_mem_zero(&vendor_ie[0], SIR_MAC_MAX_IE_LENGTH + 2);
		attr_len = nla_len(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY_IE_LIST]);
		if (attr_len < 0 || attr_len > SIR_MAC_MAX_IE_LENGTH + 2) {
			hddLog(LOGE, FL("Invalid value. attr_len %d"),
					attr_len);
			return -EINVAL;
		}

		nla_memcpy(&vendor_ie,
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY_IE_LIST],
			attr_len);
		vendor_ie_present = true;
		hddLog(LOG1, FL("Access policy vendor ie present.attr_len %d"),
				attr_len);
		vos_trace_hex_dump(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
				&vendor_ie[0], attr_len);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY]) {
		access_policy = (int) nla_get_u32(
				tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY]);
		if ((access_policy < QCA_ACCESS_POLICY_ACCEPT_UNLESS_LISTED) ||
			(access_policy > QCA_ACCESS_POLICY_DENY_UNLESS_LISTED)){
			hddLog(LOGE, FL("Invalid value. access_policy %d"),
					access_policy);
			return -EINVAL;
		}
		access_policy_present = true;
		hddLog(LOG1, FL("Access policy present. access_policy %d"),
				access_policy);
	}

	if (vendor_ie_present && access_policy_present) {
		if (access_policy == QCA_ACCESS_POLICY_DENY_UNLESS_LISTED) {
			access_policy =
				WLAN_HDD_VENDOR_IE_ACCESS_ALLOW_IF_LISTED;
		}
		else {
			access_policy = WLAN_HDD_VENDOR_IE_ACCESS_NONE;
		}

		hddLog(LOG1, FL("calling sme_update_access_policy_vendor_ie"));
		status = sme_update_access_policy_vendor_ie(pHddCtx->hHal,
				pAdapter->sessionId, &vendor_ie[0],
				access_policy);
		if (status == eHAL_STATUS_FAILURE) {
			hddLog(LOGE, FL(
				"Failed to set vendor ie and access policy."));
			return -EINVAL;
		}
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ENA]) {
		antdiv_ena = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ENA]);
		hddLog(LOG1, FL("antdiv_ena: %d"), antdiv_ena);
		ret_val = process_wma_set_command((int)pAdapter->sessionId,
					(int)WMI_PDEV_PARAM_ENA_ANT_DIV,
					antdiv_ena, PDEV_CMD);
		if (ret_val) {
			hddLog(LOG1, FL("Failed to set antdiv_ena"));
			return ret_val;
		}
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_CHAIN]) {
		antdiv_chain = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_CHAIN]);
		hddLog(LOG1, FL("antdiv_chain: %d"), antdiv_chain);
		ret_val = process_wma_set_command((int)pAdapter->sessionId,
					(int)WMI_PDEV_PARAM_FORCE_CHAIN_ANT,
					antdiv_chain, PDEV_CMD);
		if (ret_val) {
			hddLog(LOG1, FL("Failed to set antdiv_chain"));
			return ret_val;
		}
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST]) {
		antdiv_selftest = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST]);
		hddLog(LOG1, FL("antdiv_selftest: %d"), antdiv_selftest);
		ret_val = process_wma_set_command((int)pAdapter->sessionId,
					(int)WMI_PDEV_PARAM_ANT_DIV_SELFTEST,
					antdiv_selftest, PDEV_CMD);
		if (ret_val) {
			hddLog(LOG1, FL("Failed to set antdiv_selftest"));
			return ret_val;
		}
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST_INTVL]) {
		antdiv_selftest_intvl = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST_INTVL]);
		hddLog(LOG1, FL("antdiv_selftest_intvl: %d"),
			antdiv_selftest_intvl);
		ret_val = process_wma_set_command((int)pAdapter->sessionId,
				(int)WMI_PDEV_PARAM_ANT_DIV_SELFTEST_INTVL,
				antdiv_selftest_intvl, PDEV_CMD);
		if (ret_val) {
			hddLog(LOG1, FL("Failed to set antdiv_selftest_intvl"));
			return ret_val;
		}
	}

#define RX_TIMEOUT_VAL_MIN 10
#define RX_TIMEOUT_VAL_MAX 1000
	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VOICE] ||
	    tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VIDEO] ||
	    tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BESTEFFORT] ||
	    tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BACKGROUND]) {

		/* if one is specified, all must be specified */
		if (!tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VOICE] ||
		    !tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VIDEO] ||
		    !tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BESTEFFORT] ||
		    !tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BACKGROUND]) {
			hddLog(LOGE,
				FL("four AC timeout val are required MAC"));
			return -EINVAL;
		}

		reorder_timeout.rx_timeout_pri[0] = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VOICE]);
		reorder_timeout.rx_timeout_pri[1] = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VIDEO]);
		reorder_timeout.rx_timeout_pri[2] = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BESTEFFORT]);
		reorder_timeout.rx_timeout_pri[3] = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BACKGROUND]);
		/* timeout value is required to be in the rang 10 to 1000ms */
		if (reorder_timeout.rx_timeout_pri[0] >= RX_TIMEOUT_VAL_MIN &&
		    reorder_timeout.rx_timeout_pri[0] <= RX_TIMEOUT_VAL_MAX &&
		    reorder_timeout.rx_timeout_pri[1] >= RX_TIMEOUT_VAL_MIN &&
		    reorder_timeout.rx_timeout_pri[1] <= RX_TIMEOUT_VAL_MAX &&
		    reorder_timeout.rx_timeout_pri[2] >= RX_TIMEOUT_VAL_MIN &&
		    reorder_timeout.rx_timeout_pri[2] <= RX_TIMEOUT_VAL_MAX &&
		    reorder_timeout.rx_timeout_pri[3] >= RX_TIMEOUT_VAL_MIN &&
		    reorder_timeout.rx_timeout_pri[3] <= RX_TIMEOUT_VAL_MAX) {
			vos_status = sme_set_reorder_timeout(pHddCtx->hHal,
				&reorder_timeout);
			if (vos_status != VOS_STATUS_SUCCESS) {
				hddLog(LOGE,
					FL("failed to set reorder timeout err %d"),
					vos_status);
				ret_val = -EPERM;
			}
		} else {
			hddLog(LOGE,
				FL("one of the timeout value is not in range"));
			ret_val = -EINVAL;
		}
	}

#define WINDOW_SIZE_VAL_MIN 1
#define WINDOW_SIZE_VAL_MAX 64
	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_PEER_MAC] ||
	    tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_WINLIMIT]) {

		/* if one is specified, both must be specified */
		if (!tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_PEER_MAC] ||
		    !tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_WINLIMIT]) {
			hddLog(LOGE,
				FL("Both Peer MAC and windows limit required"));
			return -EINVAL;
		}

		memcpy(&rx_blocksize.peer_macaddr,
			nla_data(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_PEER_MAC]),
			sizeof(rx_blocksize.peer_macaddr)),

		rx_blocksize.vdev_id = pAdapter->sessionId;
		set_value = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_WINLIMIT]);
		/* maximum window size is 64 */
		if (set_value >= WINDOW_SIZE_VAL_MIN &&
		    set_value <= WINDOW_SIZE_VAL_MAX) {
			rx_blocksize.rx_block_ack_win_limit = set_value;
			vos_status = sme_set_rx_set_blocksize(pHddCtx->hHal,
							&rx_blocksize);
			if (vos_status != VOS_STATUS_SUCCESS) {
				hddLog(LOGE,
					FL("failed to set aggr sizes err %d"),
					vos_status);
				ret_val = -EPERM;
			}
		} else {
			hddLog(LOGE, FL("window size val is not in range"));
			ret_val = -EINVAL;
		}
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_SUB20_CHAN_WIDTH]) {
		bool manual_set_sub20;
		uint32_t sub20_chan_width;

		sub20_chan_width = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_SUB20_CHAN_WIDTH]);
		hddLog(LOGE, FL("SUB20 %d"), sub20_chan_width);

		switch (sub20_chan_width) {
		case NL80211_CHAN_WIDTH_5:
			sub20_chan_width = SUB20_MODE_5MHZ;
			break;
		case NL80211_CHAN_WIDTH_10:
			sub20_chan_width = SUB20_MODE_10MHZ;
			break;
		case NL80211_CHAN_WIDTH_20_NOHT:
			sub20_chan_width = SUB20_MODE_NONE;
			break;
		default:
			hddLog(LOGE, FL("invalid param %d"), sub20_chan_width);
			return -EINVAL;
		}
		manual_set_sub20 =
			hdd_sub20_channelwidth_can_set(pAdapter,
						       sub20_chan_width);
		if (!manual_set_sub20) {
			hddLog(LOGE, FL("STA can't set sub20 chanwidth"));
			return -EINVAL;
		}
		hdd_sta_set_sub20_channelwidth(pAdapter, sub20_chan_width);
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_PROBE_PERIOD] ||
	    tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_STAY_PERIOD]) {

		if (!tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_PROBE_PERIOD] ||
		    !tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_STAY_PERIOD]) {
			hddLog(LOGE, FL("Both probe and stay period required"));
			return -EINVAL;
		}

		ant_div_usrcfg = ANT_DIV_SET_PERIOD(
			nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_PROBE_PERIOD]),
			nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_STAY_PERIOD]));
		hddLog(LOG1, FL("ant div set period: %x"), ant_div_usrcfg);
		ret_val = process_wma_set_command((int)pAdapter->sessionId,
					(int)WMI_PDEV_PARAM_ANT_DIV_USRCFG,
					ant_div_usrcfg, PDEV_CMD);
		if (ret_val) {
			hddLog(LOG1, FL("Failed to set ant div period"));
			return ret_val;
		}
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SNR_DIFF]) {
		ant_div_usrcfg = ANT_DIV_SET_SNR_DIFF(
			nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SNR_DIFF]));
		hddLog(LOG1, FL("ant div set snr diff: %x"), ant_div_usrcfg);
		ret_val = process_wma_set_command((int)pAdapter->sessionId,
					(int)WMI_PDEV_PARAM_ANT_DIV_USRCFG,
					ant_div_usrcfg, PDEV_CMD);
		if (ret_val) {
			hddLog(LOG1, FL("Failed to set ant snr diff"));
			return ret_val;
		}
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_PROBE_DWELL_TIME]) {
		ant_div_usrcfg = ANT_DIV_SET_PROBE_DWELL_TIME(
			nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_PROBE_DWELL_TIME]));
		hddLog(LOG1, FL("ant div set probe dewll time: %x"), ant_div_usrcfg);
		ret_val = process_wma_set_command((int)pAdapter->sessionId,
					(int)WMI_PDEV_PARAM_ANT_DIV_USRCFG,
					ant_div_usrcfg, PDEV_CMD);
		if (ret_val) {
			hddLog(LOG1, FL("Failed to set ant div probe dewll time"));
			return ret_val;
		}
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_MGMT_SNR_WEIGHT] ||
	    tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_DATA_SNR_WEIGHT] ||
	    tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ACK_SNR_WEIGHT]) {

		if (!tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_MGMT_SNR_WEIGHT] ||
		    !tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_DATA_SNR_WEIGHT] ||
		    !tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ACK_SNR_WEIGHT]) {
			hddLog(LOGE, FL("Mgmt snr, data snr and ack snr weight are required"));
			return -EINVAL;
		}

		ant_div_usrcfg = ANT_DIV_SET_WEIGHT(
			nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_MGMT_SNR_WEIGHT]),
			nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_DATA_SNR_WEIGHT]),
			nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ACK_SNR_WEIGHT]));
		hddLog(LOG1, FL("ant div set weight: %x"), ant_div_usrcfg);
		ret_val = process_wma_set_command((int)pAdapter->sessionId,
					(int)WMI_PDEV_PARAM_ANT_DIV_USRCFG,
					ant_div_usrcfg, PDEV_CMD);
		if (ret_val) {
			hddLog(LOG1, FL("Failed to set ant div weight"));
			return ret_val;
		}
	}

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

/**
 * __wlan_hdd_cfg80211_wifi_configuration_get() -
 * Get the wifi configuration 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
 *
 * Return:   Return the Success or Failure code.
 */
static int
__wlan_hdd_cfg80211_wifi_configuration_get(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_CONFIG_MAX + 1];
	uint32_t sub20_chan_width = 0;
	int status;
	struct sk_buff *reply_skb;
	uint32_t skb_len = 0, count = 0;
	struct net_device *dev = wdev->netdev;
	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);

	ENTER();

	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)
		return -EINVAL;

	if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_CONFIG_MAX, data,
		      data_len, wlan_hdd_wifi_config_policy, NULL)) {
		hddLog(LOGE, FL("WIFI_CFG_GET NL CMD parsing failed"));
		return -EINVAL;
	}

	if (tb_vendor[QCA_WLAN_VENDOR_ATTR_CONFIG_SUB20_CHAN_WIDTH]) {
		hdd_get_sub20_channelwidth(adapter, &sub20_chan_width);

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

		skb_len += sizeof(sub20_chan_width);
		count++;
	}

	if (count == 0) {
		hddLog(LOGE, FL("unknown attribute in get_wifi_cfg request"));
		return -EINVAL;
	}

	skb_len += NLMSG_HDRLEN;
	reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, skb_len);

	if (!reply_skb)
		goto error_skb_fail;

	if (tb_vendor[QCA_WLAN_VENDOR_ATTR_CONFIG_SUB20_CHAN_WIDTH]) {
		if (nla_put_u32(reply_skb,
				QCA_WLAN_VENDOR_ATTR_CONFIG_SUB20_CHAN_WIDTH,
				sub20_chan_width))
		goto error_nla_fail;
	}

	return cfg80211_vendor_cmd_reply(reply_skb);

error_skb_fail:
	hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
	return -ENOMEM;

error_nla_fail:
	hddLog(LOGE, FL("nla put fail"));
	kfree_skb(reply_skb);
	return -EINVAL;
}

/**
 * wlan_hdd_cfg80211_wifi_configuration_get() - Get the wifi configuration 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
 *
 * Return:   Return the Success or Failure code.
 */
static int
wlan_hdd_cfg80211_wifi_configuration_get(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_get(wiphy, wdev,
							 data, data_len);
	vos_ssr_unprotect(__func__);

	return ret;
}

#ifdef FEATURE_WLAN_TDLS

/* TDLS capabilities params */
#define PARAM_MAX_TDLS_SESSION \
		QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX_CONC_SESSIONS
#define PARAM_TDLS_FEATURE_SUPPORT \
		QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_FEATURES_SUPPORTED

/**
 * __wlan_hdd_cfg80211_get_tdls_capabilities() - Provide TDLS Capabilites.
 * @wiphy:    WIPHY structure pointer
 * @wdev:     Wireless device structure pointer
 * @data:     Pointer to the data received
 * @data_len: Length of the data received
 *
 * This function provides TDLS capabilities
 *
 * Return: 0 on success and errno on failure
 */
static int
__wlan_hdd_cfg80211_get_tdls_capabilities(struct wiphy *wiphy,
					  struct wireless_dev *wdev,
					  const void *data,
					  int data_len)
{
	int status;
	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
	struct sk_buff *skb;
	uint32_t set = 0;

	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 (status)
		return status;

	skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, (2 * sizeof(u32)) +
						   NLMSG_HDRLEN);
	if (!skb) {
		hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
		goto fail;
	}

	if (FALSE == hdd_ctx->cfg_ini->fEnableTDLSSupport) {
		hddLog(LOGE,
			FL("TDLS feature not Enabled or Not supported in FW"));
		if (nla_put_u32(skb, PARAM_MAX_TDLS_SESSION, 0) ||
			nla_put_u32(skb, PARAM_TDLS_FEATURE_SUPPORT, 0)) {
			hddLog(LOGE, FL("nla put fail"));
			goto fail;
		}
	} else {
		set = set | WIFI_TDLS_SUPPORT;
		set = set | (hdd_ctx->cfg_ini->fTDLSExternalControl ?
					WIFI_TDLS_EXTERNAL_CONTROL_SUPPORT : 0);
		set = set | (hdd_ctx->cfg_ini->fEnableTDLSOffChannel ?
					WIIF_TDLS_OFFCHANNEL_SUPPORT : 0);
		hddLog(LOG1, FL("TDLS Feature supported value %x"), set);
		if (nla_put_u32(skb, PARAM_MAX_TDLS_SESSION,
				 hdd_ctx->max_num_tdls_sta) ||
			nla_put_u32(skb, PARAM_TDLS_FEATURE_SUPPORT,
				 set)) {
			hddLog(LOGE, FL("nla put fail"));
			goto fail;
		}
	}
	return cfg80211_vendor_cmd_reply(skb);
fail:
	if (skb)
		kfree_skb(skb);
	return -EINVAL;
}

/**
 * wlan_hdd_cfg80211_get_tdls_capabilities() - Provide TDLS Capabilites.
 * @wiphy:    WIPHY structure pointer
 * @wdev:     Wireless device structure pointer
 * @data:     Pointer to the data received
 * @data_len: Length of the data received
 *
 * This function provides TDLS capabilities
 *
 * Return: 0 on success and errno on failure
 */
static int
wlan_hdd_cfg80211_get_tdls_capabilities(struct wiphy *wiphy,
					struct wireless_dev *wdev,
					const void *data,
					int data_len)
{
	int ret;

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

	return ret;
}
#endif

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];
	struct sir_wifi_start_log start_log;

	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)
		return -EINVAL;

	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
		      data, data_len,
		      qca_wlan_vendor_wifi_logger_start_policy, NULL)) {
		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.ring_id = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
	hddLog(LOG1, FL("Ring ID=%d"), start_log.ring_id);

	/* 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.verbose_level = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
	hddLog(LOG1, FL("verbose_level=%d"), start_log.verbose_level);

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

	vos_set_ring_log_level(start_log.ring_id, start_log.verbose_level);

	if (start_log.ring_id == RING_ID_WAKELOCK) {
		/* Start/stop wakelock events */
		if (start_log.verbose_level > WLAN_LOG_LEVEL_OFF)
			vos_set_wakelock_logging(true);
		else
			vos_set_wakelock_logging(false);
		return 0;
	}

	status = sme_wifi_start_logger(hdd_ctx->hHal, start_log);
	if (!HAL_STATUS_SUCCESS(status)) {
		hddLog(LOGE, FL("sme_wifi_start_logger failed(err=%d)"),
			status);
		return -EINVAL;
	}
	return 0;
}

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;

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

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

	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
		      qca_wlan_vendor_attr_policy, NULL)) {
		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  = hdd_sta_ctx->conn_info.nss;
		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) {

		for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
			if (adapter->aStaInfo[sta_id].isUsed &&
			    !vos_is_macaddr_broadcast(
				&adapter->aStaInfo[sta_id].macAddrSTA) &&
			    vos_mem_compare(
				&adapter->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  = adapter->aStaInfo[sta_id].nss;
		freq = vos_chan_to_freq(
			(WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
		rate_flags = adapter->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))
			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))
			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))
			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);
}

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

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

	return ret;
}

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

/**
 * __wlan_hdd_cfg80211_wifi_logger_get_ring_data() - Flush per packet stats
 * @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 flush or retrieve the per packet statistics from
 * the driver
 *
 * Return: 0 on success and errno on failure
 */
static int __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
						struct wireless_dev *wdev,
						const void *data,
						int data_len)
{
	eHalStatus status;
	VOS_STATUS ret;
	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];

	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)
		return -EINVAL;

	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, NULL)) {
		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]);

	if (ring_id == RING_ID_PER_PACKET_STATS) {
		wlan_logging_set_per_pkt_stats();
		hddLog(LOG1, FL("Flushing/Retrieving packet stats"));
	} else if (ring_id == RING_ID_DRIVER_DEBUG) {
		/*
		 * As part of DRIVER ring ID, flush both driver and fw logs.
		 * For other Ring ID's driver doesn't have any rings to flush
		 */
		hddLog(LOG1, FL("Bug report triggered by framework"));

		ret = vos_flush_logs(WLAN_LOG_TYPE_NON_FATAL,
				     WLAN_LOG_INDICATOR_FRAMEWORK,
				     WLAN_LOG_REASON_CODE_UNUSED,
				     DUMP_VOS_TRACE | DUMP_PACKET_TRACE);
		if (VOS_STATUS_SUCCESS != ret) {
			hddLog(LOGE, FL("Failed to trigger bug report"));
			return -EINVAL;
		}
	} else
		wlan_report_log_completion(FALSE, WLAN_LOG_INDICATOR_FRAMEWORK,
					   WLAN_LOG_REASON_CODE_UNUSED);
	return 0;
}

/**
 * wlan_hdd_cfg80211_wifi_logger_get_ring_data() - Wrapper to flush packet stats
 * @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 flush or retrieve the per packet statistics from
 * the driver
 *
 * Return: 0 on success and errno on failure
 */
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;
}

#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 == MAX_REQUEST_ID) {
			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 = MAX_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;
}


/*
 * 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]);
	if (request_id == MAX_REQUEST_ID) {
		hddLog(LOGE, FL("request_id cannot be MAX"));
		goto fail;
	}

	hddLog(LOG1, FL("Request Id: %u"), request_id);

	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;

	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 == MAX_REQUEST_ID) {
		hddLog(LOGE, FL("request_id cannot be MAX"));
		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_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
			VOS_MAC_ADDR_SIZE);
	hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
	del_req->ucPtrnId = pattern_id;
	hddLog(LOG1, FL("Request Id: %u Pattern id: %d"),
			 request_id, del_req->ucPtrnId);

	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();

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

	ret = wlan_hdd_validate_context(hdd_ctx);
	if (0 != ret)
		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, NULL)) {
		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

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

/**
 * __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 *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
	struct nlattr *tb[PARAM_MAX + 1];
	struct rssi_monitor_req req;
	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(adapter))) {
		hddLog(LOGE, FL("Not in Connected state!"));
		return -ENOTSUPP;
	}

	if (nla_parse(tb, PARAM_MAX, data, data_len, policy, NULL)) {
		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;
	}

	req.request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
	req.session_id = adapter->sessionId;
	control = nla_get_u32(tb[PARAM_CONTROL]);

	if (control == QCA_WLAN_RSSI_MONITORING_START) {
		req.control = true;
		if (!tb[PARAM_MIN_RSSI]) {
			hddLog(LOGE, FL("attr min rssi failed"));
			return -EINVAL;
		}

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

		req.min_rssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
		req.max_rssi = nla_get_s8(tb[PARAM_MAX_RSSI]);

		if (!(req.min_rssi < req.max_rssi)) {
			hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
					req.min_rssi, req.max_rssi);
			return -EINVAL;
		}
		hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
			req.min_rssi, req.max_rssi);

	} else if (control == QCA_WLAN_RSSI_MONITORING_STOP)
		req.control = false;
	else {
		hddLog(LOGE, FL("Invalid control cmd: %d"), control);
		return -EINVAL;
	}
	hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
			req.request_id, req.session_id, req.control);

	status = sme_set_rssi_monitoring(hdd_ctx->hHal, &req);
	if (!HAL_STATUS_SUCCESS(status)) {
		hddLog(LOGE,
			FL("sme_set_rssi_monitoring failed(err=%d)"), status);
		return -EINVAL;
	}

	return 0;
}

/*
 * 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() - 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(void *hddctx,
				 struct rssi_breach_event *data)
{
	hdd_context_t *hdd_ctx  = hddctx;
	struct sk_buff *skb;
	int flags = vos_get_gfp_flags();

	ENTER();

	if (wlan_hdd_validate_context(hdd_ctx))
		return;

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

	skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
				  NULL,
				  EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
				  QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
				  flags);

	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, flags);
	return;

fail:
	kfree_skb(skb);
	return;
}
#define PWR_SAVE_FAIL_CMD_INDEX \
        QCA_NL80211_VENDOR_SUBCMD_PWR_SAVE_FAIL_DETECTED_INDEX
/**
 * hdd_chip_pwr_save_fail_detected() - chip power save failure detected
 * NL event
 * @hddctx: HDD context
 * @data: chip power save failure detected data
 *
 * This function reads the chip power save failure detected 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_chip_pwr_save_fail_detected_cb(void *hddctx,
				struct chip_pwr_save_fail_detected_params
				*data)
{
	hdd_context_t *hdd_ctx  = hddctx;
	struct sk_buff *skb;
	int flags = vos_get_gfp_flags();

	ENTER();

	if (wlan_hdd_validate_context(hdd_ctx))
		return;

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

	skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
				  NULL, NLMSG_HDRLEN +
				  sizeof(data-> failure_reason_code) +
				  NLMSG_HDRLEN, PWR_SAVE_FAIL_CMD_INDEX,
				  flags);

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

	hddLog(LOG1, "failure reason code: %u, wake lock bitmap : %u %u %u %u",
			data->failure_reason_code,
			data->wake_lock_bitmap[0],
			data->wake_lock_bitmap[1],
			data->wake_lock_bitmap[2],
			data->wake_lock_bitmap[3]);

	if (nla_put_u32(skb,
		QCA_ATTR_CHIP_POWER_SAVE_FAILURE_REASON,
		data->failure_reason_code))
		goto fail;

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

fail:
	kfree_skb(skb);
	EXIT();
	return;
}
#undef PWR_SAVE_FAIL_CMD_INDEX

static const struct nla_policy
ns_offload_set_policy[QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_MAX + 1] = {
	[QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_FLAG] = {.type = NLA_U8},
};

/**
 * __wlan_hdd_cfg80211_set_ns_offload() - enable/disable NS offload
 * @wiphy: Pointer to wireless phy
 * @wdev: Pointer to wireless device
 * @data: Pointer to data
 * @data_len: Length of @data
 *
 * Return: 0 on success, negative errno on failure
 */
static int
__wlan_hdd_cfg80211_set_ns_offload(struct wiphy *wiphy,
			struct wireless_dev *wdev,
			const void *data, int data_len)
{
	int status;
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_MAX + 1];
	hdd_context_t *pHddCtx = wiphy_priv(wiphy);
	struct net_device *dev = wdev->netdev;
	hdd_adapter_t *pAdapter =  WLAN_HDD_GET_PRIV_PTR(dev);

	ENTER();

	status = wlan_hdd_validate_context(pHddCtx);
	if (0 != status)
		return status;
	if (TRUE != pHddCtx->cfg_ini->fhostNSOffload) {
		hddLog(LOGE, FL("ND Offload not supported"));
		return -EINVAL;
	}

	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_MAX,
			(struct nlattr *)data,
			data_len, ns_offload_set_policy, NULL)) {
		hddLog(LOGE, FL("nla_parse failed"));
		return -EINVAL;
	}

	if (!tb[QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_FLAG]) {
		hddLog(LOGE, FL("ND Offload flag attribute not present"));
		return -EINVAL;
	}

	pHddCtx->ns_offload_enable =
		nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_FLAG]);

	/*
         * If active mode offload is enabled configure the nsoffload
         * enable/disable request from the upper layer.
         */
	if (pHddCtx->cfg_ini->active_mode_offload) {
		hddLog(LOG1,
			FL("Configure NS offload with command: %d"),
			pHddCtx->ns_offload_enable);
		hdd_conf_ns_offload(pAdapter, pHddCtx->ns_offload_enable);
	}

	return 0;
}

/**
 * wlan_hdd_cfg80211_set_ns_offload() - enable/disable NS offload
 * @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
 *
 * Return:   Return the Success or Failure code.
 */
static int wlan_hdd_cfg80211_set_ns_offload(struct wiphy *wiphy,
					struct wireless_dev *wdev,
					const void *data, int data_len)
{
	int ret;

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

	return ret;
}

/**
 * __wlan_hdd_cfg80211_setband() - set band
 * @wiphy: Pointer to wireless phy
 * @wdev: Pointer to wireless device
 * @data: Pointer to data
 * @data_len: Length of @data
 *
 * 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 (ret)
		return ret;

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

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

	return hdd_setBand(dev,
			nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
}

/**
 * wlan_hdd_cfg80211_setband() - Wrapper to setband
 * @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;
}

/*
 * define short names for the global vendor params
 * used by __wlan_hdd_cfg80211_bpf_offload()
 */
#define BPF_INVALID \
	QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_INVALID
#define BPF_SET_RESET \
	QCA_WLAN_VENDOR_ATTR_SET_RESET_PACKET_FILTER
#define BPF_VERSION \
	QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION
#define BPF_FILTER_ID \
	QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_ID
#define BPF_PACKET_SIZE \
	QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE
#define BPF_CURRENT_OFFSET \
	QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_CURRENT_OFFSET
#define BPF_PROGRAM \
	QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM
#define BPF_MAX \
	QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_MAX

static const struct nla_policy
wlan_hdd_bpf_offload_policy[BPF_MAX + 1] = {
	[BPF_SET_RESET] = {.type = NLA_U32},
	[BPF_VERSION] = {.type = NLA_U32},
	[BPF_FILTER_ID] = {.type = NLA_U32},
	[BPF_PACKET_SIZE] = {.type = NLA_U32},
	[BPF_CURRENT_OFFSET] = {.type = NLA_U32},
	[BPF_PROGRAM] = {.type = NLA_U8},
};

/**
 * hdd_get_bpf_offload_cb() - Callback function to BPF Offload
 * @hdd_context: hdd_context
 * @bpf_get_offload: struct for get offload
 *
 * This function receives the response/data from the lower layer and
 * checks to see if the thread is still waiting then post the results to
 * upper layer, if the request has timed out then ignore.
 *
 * Return: None
 */
void hdd_get_bpf_offload_cb(void *hdd_context,
			    struct sir_bpf_get_offload *data)
{
	hdd_context_t *hdd_ctx = hdd_context;
	struct hdd_bpf_context *context;

	ENTER();

	if (wlan_hdd_validate_context(hdd_ctx))
		return;

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

	context = &bpf_context;
	/* The caller presumably timed out so there is nothing we can do */
	if (context->magic != BPF_CONTEXT_MAGIC) {
		spin_unlock(&hdd_context_lock);
		return;
	}

	/* context is valid so caller is still waiting */
	/* paranoia: invalidate the magic */
	context->magic = 0;

	context->capability_response = *data;
	complete(&context->completion);

	spin_unlock(&hdd_context_lock);

	return;
}

/**
 * hdd_post_get_bpf_capabilities_rsp() - Callback function to BPF Offload
 * @hdd_context: hdd_context
 * @bpf_get_offload: struct for get offload
 *
 * Return: 0 on success, error number otherwise.
 */
static int hdd_post_get_bpf_capabilities_rsp(hdd_context_t *hdd_ctx,
			    struct sir_bpf_get_offload *bpf_get_offload)
{
	struct sk_buff *skb;
	uint32_t nl_buf_len;

	ENTER();

	nl_buf_len = NLMSG_HDRLEN;
	nl_buf_len +=
		(sizeof(bpf_get_offload->max_bytes_for_bpf_inst) + NLA_HDRLEN) +
		(sizeof(bpf_get_offload->bpf_version) + NLA_HDRLEN);

	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
	if (!skb) {
		hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
		return -ENOMEM;
	}

	hddLog(LOG1, "BPF Version: %u BPF max bytes: %u",
			bpf_get_offload->bpf_version,
			bpf_get_offload->max_bytes_for_bpf_inst);

	if (nla_put_u32(skb, BPF_PACKET_SIZE,
			bpf_get_offload->max_bytes_for_bpf_inst) ||
	    nla_put_u32(skb, BPF_VERSION, bpf_get_offload->bpf_version)) {
		hddLog(LOGE, FL("nla put failure"));
		goto nla_put_failure;
	}

	cfg80211_vendor_cmd_reply(skb);
	EXIT();
	return 0;

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

/**
 * hdd_get_bpf_offload - Get BPF offload Capabilities
 * @hdd_ctx: Hdd context
 *
 * Return: 0 on success, errno on failure
 */
static int hdd_get_bpf_offload(hdd_context_t *hdd_ctx)
{
	unsigned long rc;
	struct hdd_bpf_context *context;
	eHalStatus hstatus;
	int ret;

	ENTER();

	spin_lock(&hdd_context_lock);
	context = &bpf_context;
	context->magic = BPF_CONTEXT_MAGIC;
	INIT_COMPLETION(context->completion);
	spin_unlock(&hdd_context_lock);

	hstatus = sme_get_bpf_offload_capabilities(hdd_ctx->hHal);
	if (!HAL_STATUS_SUCCESS(hstatus)) {
		hddLog(LOGE, FL("Unable to retrieve BPF caps"));
		return -EINVAL;
	}
	/* request was sent -- wait for the response */
	rc = wait_for_completion_timeout(&context->completion,
			msecs_to_jiffies(WLAN_WAIT_TIME_BPF));
	if (!rc) {
		hddLog(LOGE, FL("Target response timed out"));
		spin_lock(&hdd_context_lock);
		context->magic = 0;
		spin_unlock(&hdd_context_lock);

		return -ETIMEDOUT;
	}
	ret = hdd_post_get_bpf_capabilities_rsp(hdd_ctx,
					&bpf_context.capability_response);
	if (ret)
		hddLog(LOGE, FL("Failed to post get bpf capabilities"));

	EXIT();
	return ret;
}

/**
 * hdd_set_reset_bpf_offload - Post set/reset bpf to SME
 * @hdd_ctx: Hdd context
 * @tb: Length of @data
 * @adapter: pointer to adapter struct
 *
 * Return: 0 on success; errno on failure
 */
static int hdd_set_reset_bpf_offload(hdd_context_t *hdd_ctx,
				     struct nlattr **tb,
				     hdd_adapter_t *adapter)
{
	struct sir_bpf_set_offload *bpf_set_offload;
	eHalStatus hstatus;
	int prog_len;
	int ret_val = -EINVAL;

	ENTER();

	if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
			adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
		if (!hdd_connIsConnected(
				WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
			hddLog(LOGE, FL("Not in Connected state!"));
			return -ENOTSUPP;
		}
	}

	bpf_set_offload = vos_mem_malloc(sizeof(*bpf_set_offload));
	if (bpf_set_offload == NULL) {
		hddLog(LOGE, FL("vos_mem_malloc failed for bpf_set_offload"));
		return -ENOMEM;
	}
	vos_mem_zero(bpf_set_offload, sizeof(*bpf_set_offload));

	/* Parse and fetch bpf packet size */
	if (!tb[BPF_PACKET_SIZE]) {
		hddLog(LOGE, FL("attr bpf packet size failed"));
		goto fail;
	}
	bpf_set_offload->total_length = nla_get_u32(tb[BPF_PACKET_SIZE]);

	if (!bpf_set_offload->total_length) {
		hddLog(LOG1, FL("BPF reset packet filter received"));
		goto post_sme;
	}

	/* Parse and fetch bpf program */
	if (!tb[BPF_PROGRAM]) {
		hddLog(LOGE, FL("attr bpf program failed"));
		goto fail;
	}

	prog_len = nla_len(tb[BPF_PROGRAM]);
	bpf_set_offload->program = vos_mem_malloc(sizeof(uint8_t) * prog_len);
	if (!bpf_set_offload->program) {
		hddLog(LOGE, FL("failed to allocate memory for bpf filter"));
		ret_val = -ENOMEM;
		goto fail;
	}
	bpf_set_offload->current_length = prog_len;
	nla_memcpy(bpf_set_offload->program, tb[BPF_PROGRAM], prog_len);
	bpf_set_offload->session_id = adapter->sessionId;

	hddLog(LOG1, FL("BPF set instructions"));
	VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
			   bpf_set_offload->program, prog_len);

	/* Parse and fetch filter Id */
	if (!tb[BPF_FILTER_ID]) {
		hddLog(LOGE, FL("attr filter id failed"));
		goto fail;
	}
	bpf_set_offload->filter_id = nla_get_u32(tb[BPF_FILTER_ID]);

	/* Parse and fetch current offset */
	if (!tb[BPF_CURRENT_OFFSET]) {
		hddLog(LOGE, FL("attr current offset failed"));
		goto fail;
	}
	bpf_set_offload->current_offset = nla_get_u32(tb[BPF_CURRENT_OFFSET]);

post_sme:
	hddLog(LOG1, FL("Posting BPF SET/RESET to SME, session_id: %d Bpf Version: %d filter ID: %d total_length: %d current_length: %d current offset: %d"),
			bpf_set_offload->session_id,
			bpf_set_offload->version,
			bpf_set_offload->filter_id,
			bpf_set_offload->total_length,
			bpf_set_offload->current_length,
			bpf_set_offload->current_offset);

	hstatus = sme_set_bpf_instructions(hdd_ctx->hHal, bpf_set_offload);
	if (!HAL_STATUS_SUCCESS(hstatus)) {
		hddLog(LOGE,
			FL("sme_set_bpf_instructions failed(err=%d)"), hstatus);
		goto fail;
	}
	EXIT();
	if (bpf_set_offload->current_length)
		vos_mem_free(bpf_set_offload->program);
	vos_mem_free(bpf_set_offload);
	return 0;

fail:
	if (bpf_set_offload->current_length)
		vos_mem_free(bpf_set_offload->program);
	vos_mem_free(bpf_set_offload);
	return ret_val;
}

/**
 * wlan_hdd_cfg80211_bpf_offload() - Set/Reset to BPF Offload
 * @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_bpf_offload(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 *pAdapter =  WLAN_HDD_GET_PRIV_PTR(dev);
	struct nlattr *tb[BPF_MAX + 1];
	int ret_val, packet_filter_subcmd;

	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 -EINVAL;
	}

	if (!hdd_ctx->bpf_enabled) {
		hddLog(LOGE, FL("BPF offload is not supported/enabled"));
		return -ENOTSUPP;
	}

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

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

	packet_filter_subcmd = nla_get_u32(tb[BPF_SET_RESET]);

	if (packet_filter_subcmd == QCA_WLAN_GET_PACKET_FILTER)
		return hdd_get_bpf_offload(hdd_ctx);
	else
		return hdd_set_reset_bpf_offload(hdd_ctx, tb,
						 pAdapter);
}

/**
 * wlan_hdd_cfg80211_bpf_offload() - SSR Wrapper to BPF Offload
 * @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_bpf_offload(struct wiphy *wiphy,
		struct wireless_dev *wdev,
		const void *data, int data_len)
{
	int ret;

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

	return ret;
}

/**
 * hdd_init_bpf_completion() - Initialize the completion event for bpf
 *
 * Return: None
 */
void hdd_init_bpf_completion(void)
{
	init_completion(&bpf_context.completion);
}

#undef BPF_INVALID
#undef BPF_SET_RESET
#undef BPF_VERSION
#undef BPF_ID
#undef BPF_PACKET_SIZE
#undef BPF_CURRENT_OFFSET
#undef BPF_PROGRAM
#undef BPF_MAX

/**
 * __wlan_hdd_cfg80211_get_bus_size() - Get WMI Bus size
 * @wiphy:    wiphy structure pointer
 * @wdev:     Wireless device structure pointer
 * @data:     Pointer to the data received
 * @data_len: Length of @data
 *
 * This function reads wmi max bus size and fill in the skb with
 * NL attributes and send up the NL event.
 * Return: 0 on success; errno on failure
 */

static int
__wlan_hdd_cfg80211_get_bus_size(struct wiphy *wiphy,
				struct wireless_dev *wdev,
				const void *data, int data_len)
{
	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
	int ret_val;
	struct sk_buff *skb;
	uint32_t nl_buf_len;

	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 -EINVAL;
	}

	hddLog(LOG1, "WMI Max Bus size: %d", hdd_ctx->wmi_max_len);

	nl_buf_len = NLMSG_HDRLEN;
	nl_buf_len +=  (sizeof(hdd_ctx->wmi_max_len) + NLA_HDRLEN);

	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
	if (!skb) {
		hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
		return -ENOMEM;
	}

	if (nla_put_u16(skb, QCA_WLAN_VENDOR_ATTR_DRV_INFO_BUS_SIZE,
			hdd_ctx->wmi_max_len)) {
		hddLog(LOGE, FL("nla put failure"));
		goto nla_put_failure;
	}
	cfg80211_vendor_cmd_reply(skb);
	EXIT();
	return 0;

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

/**
 * wlan_hdd_cfg80211_get_bus_size() - SSR Wrapper to Get Bus size
 * @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_get_bus_size(struct wiphy *wiphy,
					struct wireless_dev *wdev,
					const void *data, int data_len)
{
	int ret;

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

	return ret;
}

/**
 * define short names for the global vendor params
 * used by wlan_hdd_cfg80211_wakelock_stats_rsp_callback()
 */
#define PARAM_TOTAL_CMD_EVENT_WAKE \
		QCA_WLAN_VENDOR_ATTR_TOTAL_CMD_EVENT_WAKE
#define PARAM_CMD_EVENT_WAKE_CNT_PTR \
		QCA_WLAN_VENDOR_ATTR_CMD_EVENT_WAKE_CNT_PTR
#define PARAM_CMD_EVENT_WAKE_CNT_SZ \
		QCA_WLAN_VENDOR_ATTR_CMD_EVENT_WAKE_CNT_SZ
#define PARAM_TOTAL_DRIVER_FW_LOCAL_WAKE \
		QCA_WLAN_VENDOR_ATTR_TOTAL_DRIVER_FW_LOCAL_WAKE
#define PARAM_DRIVER_FW_LOCAL_WAKE_CNT_PTR \
		QCA_WLAN_VENDOR_ATTR_DRIVER_FW_LOCAL_WAKE_CNT_PTR
#define PARAM_DRIVER_FW_LOCAL_WAKE_CNT_SZ \
		QCA_WLAN_VENDOR_ATTR_DRIVER_FW_LOCAL_WAKE_CNT_SZ
#define PARAM_TOTAL_RX_DATA_WAKE \
		QCA_WLAN_VENDOR_ATTR_TOTAL_RX_DATA_WAKE
#define PARAM_RX_UNICAST_CNT \
		QCA_WLAN_VENDOR_ATTR_RX_UNICAST_CNT
#define PARAM_RX_MULTICAST_CNT \
		QCA_WLAN_VENDOR_ATTR_RX_MULTICAST_CNT
#define PARAM_RX_BROADCAST_CNT \
		QCA_WLAN_VENDOR_ATTR_RX_BROADCAST_CNT
#define PARAM_ICMP_PKT \
		QCA_WLAN_VENDOR_ATTR_ICMP_PKT
#define PARAM_ICMP6_PKT \
		QCA_WLAN_VENDOR_ATTR_ICMP6_PKT
#define PARAM_ICMP6_RA \
		QCA_WLAN_VENDOR_ATTR_ICMP6_RA
#define PARAM_ICMP6_NA \
		QCA_WLAN_VENDOR_ATTR_ICMP6_NA
#define PARAM_ICMP6_NS \
		QCA_WLAN_VENDOR_ATTR_ICMP6_NS
#define PARAM_ICMP4_RX_MULTICAST_CNT \
		QCA_WLAN_VENDOR_ATTR_ICMP4_RX_MULTICAST_CNT
#define PARAM_ICMP6_RX_MULTICAST_CNT \
		QCA_WLAN_VENDOR_ATTR_ICMP6_RX_MULTICAST_CNT
#define PARAM_OTHER_RX_MULTICAST_CNT \
		QCA_WLAN_VENDOR_ATTR_OTHER_RX_MULTICAST_CNT
#define PARAM_RSSI_BREACH_CNT \
		QCA_WLAN_VENDOR_ATTR_RSSI_BREACH_CNT
#define PARAM_LOW_RSSI_CNT \
		QCA_WLAN_VENDOR_ATTR_LOW_RSSI_CNT
#define PARAM_GSCAN_CNT \
		QCA_WLAN_VENDOR_ATTR_GSCAN_CNT
#define PARAM_PNO_COMPLETE_CNT \
		QCA_WLAN_VENDOR_ATTR_PNO_COMPLETE_CNT
#define PARAM_PNO_MATCH_CNT \
		QCA_WLAN_VENDOR_ATTR_PNO_MATCH_CNT


/**
 * hdd_send_wakelock_stats() - API to send wakelock stats
 * @ctx: context to be passed to callback
 * @data: data passed to callback
 *
 * This function is used to send wake lock stats to HAL layer
 *
 * Return: 0 on success, error number otherwise.
 */
static uint32_t hdd_send_wakelock_stats(hdd_context_t *hdd_ctx,
					const struct sir_wake_lock_stats *data)
{
	struct sk_buff *skb;
	uint32_t nl_buf_len;
	uint32_t total_rx_data_wake, rx_multicast_cnt;
	uint32_t ipv6_rx_multicast_addr_cnt;
	uint32_t icmpv6_cnt;

	ENTER();

	nl_buf_len = NLMSG_HDRLEN;
	nl_buf_len +=
		QCA_WLAN_VENDOR_GET_WAKE_STATS_MAX *
				(NLMSG_HDRLEN + sizeof(uint32_t));

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

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

	hddLog(LOG1, "wow_ucast_wake_up_count %d",
			data->wow_ucast_wake_up_count);
	hddLog(LOG1, "wow_bcast_wake_up_count %d",
			data->wow_bcast_wake_up_count);
	hddLog(LOG1, "wow_ipv4_mcast_wake_up_count %d",
			data->wow_ipv4_mcast_wake_up_count);
	hddLog(LOG1, "wow_ipv6_mcast_wake_up_count %d",
			data->wow_ipv6_mcast_wake_up_count);
	hddLog(LOG1, "wow_ipv6_mcast_ra_stats %d",
			data->wow_ipv6_mcast_ra_stats);
	hddLog(LOG1, "wow_ipv6_mcast_ns_stats %d",
			data->wow_ipv6_mcast_ns_stats);
	hddLog(LOG1, "wow_ipv6_mcast_na_stats %d",
			data->wow_ipv6_mcast_na_stats);
	hddLog(LOG1, "wow_icmpv4_count %d", data->wow_icmpv4_count);
	hddLog(LOG1, "wow_icmpv6_count %d", data->wow_icmpv6_count);
	hddLog(LOG1, "wow_rssi_breach_wake_up_count %d",
			data->wow_rssi_breach_wake_up_count);
	hddLog(LOG1, "wow_low_rssi_wake_up_count %d",
			data->wow_low_rssi_wake_up_count);
	hddLog(LOG1, "wow_gscan_wake_up_count %d",
			data->wow_gscan_wake_up_count);
	hddLog(LOG1, "wow_pno_complete_wake_up_count %d",
			data->wow_pno_complete_wake_up_count);
	hddLog(LOG1, "wow_pno_match_wake_up_count %d",
			data->wow_pno_match_wake_up_count);

	ipv6_rx_multicast_addr_cnt =
		data->wow_ipv6_mcast_wake_up_count;

	icmpv6_cnt =
		data->wow_icmpv6_count;

	rx_multicast_cnt =
		data->wow_ipv4_mcast_wake_up_count +
		ipv6_rx_multicast_addr_cnt;

	total_rx_data_wake =
		data->wow_ucast_wake_up_count +
		data->wow_bcast_wake_up_count +
		rx_multicast_cnt;

	if (nla_put_u32(skb, PARAM_TOTAL_CMD_EVENT_WAKE, 0) ||
	    nla_put_u32(skb, PARAM_CMD_EVENT_WAKE_CNT_PTR, 0) ||
	    nla_put_u32(skb, PARAM_CMD_EVENT_WAKE_CNT_SZ, 0) ||
	    nla_put_u32(skb, PARAM_TOTAL_DRIVER_FW_LOCAL_WAKE, 0) ||
	    nla_put_u32(skb, PARAM_DRIVER_FW_LOCAL_WAKE_CNT_PTR, 0) ||
	    nla_put_u32(skb, PARAM_DRIVER_FW_LOCAL_WAKE_CNT_SZ, 0) ||
	    nla_put_u32(skb, PARAM_TOTAL_RX_DATA_WAKE,
				total_rx_data_wake) ||
	    nla_put_u32(skb, PARAM_RX_UNICAST_CNT,
				data->wow_ucast_wake_up_count) ||
	    nla_put_u32(skb, PARAM_RX_MULTICAST_CNT,
				rx_multicast_cnt) ||
	    nla_put_u32(skb, PARAM_RX_BROADCAST_CNT,
				data->wow_bcast_wake_up_count) ||
	    nla_put_u32(skb, PARAM_ICMP_PKT,
				data->wow_icmpv4_count) ||
	    nla_put_u32(skb, PARAM_ICMP6_PKT,
				icmpv6_cnt) ||
	    nla_put_u32(skb, PARAM_ICMP6_RA,
				data->wow_ipv6_mcast_ra_stats) ||
	    nla_put_u32(skb, PARAM_ICMP6_NA,
				data->wow_ipv6_mcast_na_stats) ||
	    nla_put_u32(skb, PARAM_ICMP6_NS,
				data->wow_ipv6_mcast_ns_stats) ||
	    nla_put_u32(skb, PARAM_ICMP4_RX_MULTICAST_CNT,
				data->wow_ipv4_mcast_wake_up_count) ||
	    nla_put_u32(skb, PARAM_ICMP6_RX_MULTICAST_CNT,
				ipv6_rx_multicast_addr_cnt) ||
	    nla_put_u32(skb, PARAM_OTHER_RX_MULTICAST_CNT, 0) ||
	    nla_put_u32(skb, PARAM_RSSI_BREACH_CNT,
				data->wow_rssi_breach_wake_up_count) ||
		nla_put_u32(skb, PARAM_LOW_RSSI_CNT,
				data->wow_low_rssi_wake_up_count) ||
		nla_put_u32(skb, PARAM_GSCAN_CNT,
				data->wow_gscan_wake_up_count) ||
		nla_put_u32(skb, PARAM_PNO_COMPLETE_CNT,
				data->wow_pno_complete_wake_up_count) ||
		nla_put_u32(skb, PARAM_PNO_MATCH_CNT,
				data->wow_pno_match_wake_up_count)) {
		hddLog(LOGE, FL("nla put fail"));
		goto nla_put_failure;
	}

	cfg80211_vendor_cmd_reply(skb);

	EXIT();
	return 0;

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

/**
 * __wlan_hdd_cfg80211_get_wakelock_stats() - gets wake lock stats
 * @wiphy: wiphy pointer
 * @wdev: pointer to struct wireless_dev
 * @data: pointer to incoming NL vendor data
 * @data_len: length of @data
 *
 * This function parses the incoming NL vendor command data attributes and
 * invokes the SME Api and blocks on a completion variable.
 * WMA copies required data and invokes callback
 * wlan_hdd_cfg80211_wakelock_stats_rsp_callback to send wake lock stats.
 *
 * Return: 0 on success; error number otherwise.
 */
static int __wlan_hdd_cfg80211_get_wakelock_stats(struct wiphy *wiphy,
					struct wireless_dev *wdev,
					const void *data,
					int data_len)
{
	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
	eHalStatus status;
	int ret;
	struct sir_wake_lock_stats wake_lock_stats;
	VOS_STATUS vos_status;

	ENTER();

	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)
		return -EINVAL;

	vos_status = wma_get_wakelock_stats(&wake_lock_stats);
	if (vos_status != VOS_STATUS_SUCCESS) {
		hddLog(LOGE,
			FL("failed to get wakelock stats(err=%d)"), vos_status);
		return -EINVAL;
	}

	ret = hdd_send_wakelock_stats(hdd_ctx,
					&wake_lock_stats);
	if (ret)
		hddLog(LOGE, FL("Failed to post wake lock stats"));

	EXIT();
	return ret;
}

/**
 * wlan_hdd_cfg80211_get_wakelock_stats() - gets wake lock stats
 * @wiphy: wiphy pointer
 * @wdev: pointer to struct wireless_dev
 * @data: pointer to incoming NL vendor data
 * @data_len: length of @data
 *
 * This function parses the incoming NL vendor command data attributes and
 * invokes the SME Api and blocks on a completion variable.
 * WMA copies required data and invokes callback
 * wlan_hdd_cfg80211_wakelock_stats_rsp_callback to send wake lock stats.
 *
 * Return: 0 on success; error number otherwise.
 */
static int wlan_hdd_cfg80211_get_wakelock_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_wakelock_stats(wiphy, wdev, data,
								data_len);
	vos_ssr_unprotect(__func__);

	return ret;
}

static const struct nla_policy
wlan_hdd_set_acs_dfs_config_policy[QCA_WLAN_VENDOR_ATTR_ACS_DFS_MAX + 1] =
{
	[QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE] = {.type = NLA_U8 },
	[QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT] = {.type = NLA_U8 },
};

/**
 * __wlan_hdd_cfg80211_acs_dfs_mode() - set ACS DFS mode and channel
 * @wiphy: Pointer to wireless phy
 * @wdev: Pointer to wireless device
 * @data: Pointer to data
 * @data_len: Length of @data
 *
 * This function parses the incoming NL vendor command data attributes and
 * updates the SAP context about channel_hint and DFS mode.
 * If channel_hint is set, SAP will choose that channel
 * as operating channel.
 *
 * If DFS mode is enabled, driver will include DFS channels
 * in ACS else driver will skip DFS channels.
 *
 * Return: 0 on success, negative errno on failure
 */
static int
__wlan_hdd_cfg80211_acs_dfs_mode(struct wiphy *wiphy,
		struct wireless_dev *wdev,
		const void *data, int data_len)
{
	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACS_DFS_MAX + 1];
	int ret;
	struct acs_dfs_policy *acs_policy;
	int mode = DFS_MODE_NONE;
	int channel_hint = 0;

	ENTER();

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

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

	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ACS_DFS_MAX,
				data, data_len,
				wlan_hdd_set_acs_dfs_config_policy, NULL)) {
		hddLog(LOGE, FL("invalid attr"));
		return -EINVAL;
	}

	acs_policy = &hdd_ctx->acs_policy;
	/*
	 * SCM sends this attribute to restrict SAP from choosing
	 * DFS channels from ACS.
	 */
	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE])
		mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE]);

	if (!IS_DFS_MODE_VALID(mode)) {
		hddLog(LOGE, FL("attr acs dfs mode is not valid"));
		return -EINVAL;
	}
	acs_policy->acs_dfs_mode = mode;

	/*
	 * SCM sends this attribute to provide an active channel,
	 * to skip redundant ACS between drivers, and save driver start up time
	 */
	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT])
		channel_hint = nla_get_u8(
				tb[QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT]);

	if (!IS_CHANNEL_VALID(channel_hint)) {
		hddLog(LOGE, FL("acs channel is not valid"));
		return -EINVAL;
	}
	acs_policy->acs_channel = channel_hint;

	return 0;
}
/**
 * wlan_hdd_cfg80211_acs_dfs_mode() - Wrapper to set ACS DFS mode
 * @wiphy:    wiphy structure pointer
 * @wdev:     Wireless device structure pointer
 * @data:     Pointer to the data received
 * @data_len: Length of @data
 *
 * This function parses the incoming NL vendor command data attributes and
 * updates the SAP context about channel_hint and DFS mode.
 *
 * Return: 0 on success; errno on failure
 */
static int wlan_hdd_cfg80211_acs_dfs_mode(struct wiphy *wiphy,
		struct wireless_dev *wdev,
		const void *data, int data_len)
{
	int ret;

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

	return ret;
}
/**
 * wlan_hdd_get_sta_roam_dfs_mode() - get sta roam dfs mode policy
 * @mode : cfg80211 dfs mode
 *
 * Return: return csr sta roam dfs mode else return NONE
 */
static enum sta_roam_policy_dfs_mode wlan_hdd_get_sta_roam_dfs_mode(
		enum dfs_mode mode)
{
	switch (mode) {
	case DFS_MODE_ENABLE:
		return CSR_STA_ROAM_POLICY_DFS_ENABLED;
		break;
	case DFS_MODE_DISABLE:
		return CSR_STA_ROAM_POLICY_DFS_DISABLED;
		break;
	case DFS_MODE_DEPRIORITIZE:
		return CSR_STA_ROAM_POLICY_DFS_DEPRIORITIZE;
		break;
	default:
		hddLog(VOS_TRACE_LEVEL_ERROR,
			FL("STA Roam policy dfs mode is NONE"));
		return  CSR_STA_ROAM_POLICY_NONE;
	}
}
/*
 * hdd_get_sap_operating_channel:  Get current operating channel
 * for sap.
 * @hdd_ctx: hdd context
 *
 * Return : Corresponding band for SAP operating channel
 */
uint8_t hdd_get_sap_operating_channel(hdd_context_t *hdd_ctx) {
	hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
	VOS_STATUS status;
	hdd_adapter_t *adapter;
	uint8_t  operating_channel = 0;
	uint8_t sap_operating_band = 0;
	status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
	while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
		adapter = adapter_node->pAdapter;

		if (!(adapter && (WLAN_HDD_SOFTAP == adapter->device_mode))) {
			status = hdd_get_next_adapter(hdd_ctx, adapter_node,
					&next);
			adapter_node = next;
			continue;
		}
		operating_channel = adapter->sessionCtx.ap.operatingChannel;
		if (IS_24G_CH(operating_channel))
			sap_operating_band = eCSR_BAND_24;
		else if(IS_5G_CH(operating_channel))
			sap_operating_band = eCSR_BAND_5G;
		else sap_operating_band = eCSR_BAND_ALL;
		status = hdd_get_next_adapter(hdd_ctx, adapter_node,
				&next);
		adapter_node = next;
	}
	return sap_operating_band;
}

static const struct nla_policy
wlan_hdd_set_sta_roam_config_policy[
QCA_WLAN_VENDOR_ATTR_STA_CONNECT_ROAM_POLICY_MAX + 1] =
{
	[QCA_WLAN_VENDOR_ATTR_STA_DFS_MODE] = {.type = NLA_U8 },
	[QCA_WLAN_VENDOR_ATTR_STA_SKIP_UNSAFE_CHANNEL] = {.type = NLA_U8 },
};

/**
 * __wlan_hdd_cfg80211_sta_roam_policy() - Set params to restrict scan channels
 * for station connection or roaming.
 * @wiphy: Pointer to wireless phy
 * @wdev: Pointer to wireless device
 * @data: Pointer to data
 * @data_len: Length of @data
 *
 * __wlan_hdd_cfg80211_sta_roam_policy will decide if DFS channels or unsafe
 * channels needs to be skipped in scanning or not.
 * If dfs_mode is disabled, driver will not scan DFS channels.
 * If skip_unsafe_channels is set, driver will skip unsafe channels
 * in Scanning.
 *
 * Return: 0 on success, negative errno on failure
 */
static int
__wlan_hdd_cfg80211_sta_roam_policy(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[
		QCA_WLAN_VENDOR_ATTR_STA_CONNECT_ROAM_POLICY_MAX + 1];
	int ret;
	enum sta_roam_policy_dfs_mode sta_roam_dfs_mode;
	enum dfs_mode mode = DFS_MODE_NONE;
	bool skip_unsafe_channels = false;
	eHalStatus status;
	uint8_t sap_operating_band = 0;

	ENTER();

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

	ret = wlan_hdd_validate_context(hdd_ctx);
	if (0 != ret)
		return -EINVAL;
	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_STA_CONNECT_ROAM_POLICY_MAX,
				data, data_len,
				wlan_hdd_set_sta_roam_config_policy, NULL)) {
		hddLog(LOGE, FL("invalid attr"));
		return -EINVAL;
        }
        if (tb[QCA_WLAN_VENDOR_ATTR_STA_DFS_MODE])
		mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_STA_DFS_MODE]);

	if (!IS_DFS_MODE_VALID(mode)) {
		hddLog(LOGE, FL("attr sta roam dfs mode policy is not valid"));
		return -EINVAL;
	}

	sta_roam_dfs_mode = wlan_hdd_get_sta_roam_dfs_mode(mode);

	if (tb[QCA_WLAN_VENDOR_ATTR_STA_SKIP_UNSAFE_CHANNEL])
		skip_unsafe_channels = nla_get_u8(
			tb[QCA_WLAN_VENDOR_ATTR_STA_SKIP_UNSAFE_CHANNEL]);
	sap_operating_band = hdd_get_sap_operating_channel(hdd_ctx);
	status = sme_update_sta_roam_policy(hdd_ctx->hHal, sta_roam_dfs_mode,
			skip_unsafe_channels, adapter->sessionId,
			sap_operating_band);

	if (!HAL_STATUS_SUCCESS(status)) {
		hddLog(LOGE,
			FL("sme_update_sta_roam_policy (err=%d)"), status);
		return -EINVAL;
	}
	return 0;
}

/**
 * wlan_hdd_cfg80211_sta_roam_policy() - Wrapper to restrict scan channels,
 * connection and roaming for station.
 * @wiphy:    wiphy structure pointer
 * @wdev:     Wireless device structure pointer
 * @data:     Pointer to the data received
 * @data_len: Length of @data
 *
 * __wlan_hdd_cfg80211_sta_roam_policy will decide if DFS channels or unsafe
 * channels needs to be skipped in scanning or not.
 * If dfs_mode is disabled, driver will not scan DFS channels.
 * If skip_unsafe_channels is set, driver will skip unsafe channels
 * in Scanning.
 * Return: 0 on success; errno on failure
 */
static int wlan_hdd_cfg80211_sta_roam_policy(struct wiphy *wiphy,
		struct wireless_dev *wdev,
		const void *data, int data_len)
{
	int ret;

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

	return ret;
}

#ifdef FEATURE_WLAN_CH_AVOID

static int hdd_validate_avoid_freq_chanlist(hdd_context_t *hdd_ctx,
					    tHddAvoidFreqList *channel_list)
{
	unsigned int range_idx, ch_idx;
	unsigned int unsafe_channel_index, unsafe_channel_count = 0;
	bool ch_found = false;

	unsafe_channel_count = VOS_MIN((uint16_t)hdd_ctx->unsafe_channel_count,
			(uint16_t)NUM_20MHZ_RF_CHANNELS);

	for (range_idx = 0; range_idx < channel_list->avoidFreqRangeCount;
					range_idx++) {
		if ((channel_list->avoidFreqRange[range_idx].startFreq <
		     VOS_24_GHZ_CHANNEL_1) ||
		    (channel_list->avoidFreqRange[range_idx].endFreq >
		     VOS_5_GHZ_CHANNEL_165) ||
		    (channel_list->avoidFreqRange[range_idx].startFreq >
		     channel_list->avoidFreqRange[range_idx].endFreq))
				continue;

		for (ch_idx = channel_list->avoidFreqRange[range_idx].startFreq;
		     ch_idx <= channel_list->avoidFreqRange[range_idx].endFreq;
		     ch_idx++) {
			for (unsafe_channel_index = 0;
			     unsafe_channel_index < unsafe_channel_count;
			     unsafe_channel_index++) {
				if (ch_idx ==
					hdd_ctx->unsafe_channel_list[
					unsafe_channel_index]) {
					hddLog(VOS_TRACE_LEVEL_INFO,
					       FL("Duplicate channel %d"),
					       ch_idx);
					ch_found = true;
					break;
				}
			}
			if (!ch_found) {
				hdd_ctx->unsafe_channel_list[
				unsafe_channel_count++] = ch_idx;
			}
			ch_found = false;
		}
	}
	return unsafe_channel_count;
}

/**
 * __wlan_hdd_cfg80211_avoid_freq() - ask driver to restart SAP if SAP
 * is on unsafe channel.
 * @wiphy:    wiphy structure pointer
 * @wdev:     Wireless device structure pointer
 * @data:     Pointer to the data received
 * @data_len: Length of @data
 *
 * wlan_hdd_cfg80211_avoid_freq do restart the sap if sap is already
 * on any of unsafe channels.
 * If sap is on any of unsafe channel, hdd_unsafe_channel_restart_sap
 * will send WLAN_SVC_LTE_COEX_IND indication to userspace to restart.
 *
 * Return: 0 on success; errno on failure
 */
static int
__wlan_hdd_cfg80211_avoid_freq(struct wiphy *wiphy,
		struct wireless_dev *wdev,
		const void *data, int data_len)
{
	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
	int ret;
	int unsafe_channel_index;
	tHddAvoidFreqList *channel_list;
	tVOS_CON_MODE curr_mode;

	ENTER();

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

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

	channel_list = (tHddAvoidFreqList *)data;
	if (!channel_list) {
		hddLog(LOGE, FL("Avoid frequency channel list empty"));
		return -EINVAL;
	}

	vos_get_wlan_unsafe_channel(hdd_ctx->unsafe_channel_list,
			&(hdd_ctx->unsafe_channel_count),
			sizeof(hdd_ctx->unsafe_channel_list));

	hdd_ctx->unsafe_channel_count =
		hdd_validate_avoid_freq_chanlist(hdd_ctx,
						 channel_list);

	vos_set_wlan_unsafe_channel(hdd_ctx->unsafe_channel_list,
			hdd_ctx->unsafe_channel_count);

	for (unsafe_channel_index = 0;
		unsafe_channel_index < hdd_ctx->unsafe_channel_count;
		unsafe_channel_index++) {
		hddLog(LOGE, FL("Channel %d is not safe. "),
			hdd_ctx->unsafe_channel_list[unsafe_channel_index]);
	}
	hdd_unsafe_channel_restart_sap(hdd_ctx);
	return 0;
}

/**
 * wlan_hdd_cfg80211_avoid_freq() - ask driver to restart SAP if SAP
 * is on unsafe channel.
 * @wiphy:    wiphy structure pointer
 * @wdev:     Wireless device structure pointer
 * @data:     Pointer to the data received
 * @data_len: Length of @data
 *
 * wlan_hdd_cfg80211_avoid_freq do restart the sap if sap is already
 * on any of unsafe channels.
 * If sap is on any of unsafe channel, hdd_unsafe_channel_restart_sap
 * will send WLAN_SVC_LTE_COEX_IND indication to userspace to restart.
 *
 * Return: 0 on success; errno on failure
 */
static int wlan_hdd_cfg80211_avoid_freq(struct wiphy *wiphy,
		struct wireless_dev *wdev,
		const void *data, int data_len)
{
	int ret;

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

	return ret;
}
#endif

static const struct nla_policy
wlan_hdd_sap_config_policy[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_MAX + 1] =
{
	[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL] = {.type = NLA_U8 },
};

/*
 * __wlan_hdd_cfg80211_sap_configuration_set() - ask driver to restart SAP if
   SAP
 * is on unsafe channel.
 * @wiphy:    wiphy structure pointer
 * @wdev:     Wireless device structure pointer
 * @data:     Pointer to the data received
 * @data_len: Length of @data
 *
 * __wlan_hdd_cfg80211_sap_configuration_set function set SAP params to
 * driver.
 * QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHAN will set sap config channel and
 * will initiate restart of sap.
 *
 * Return: 0 on success; errno on failure
 */
static int
__wlan_hdd_cfg80211_sap_configuration_set(struct wiphy *wiphy,
		struct wireless_dev *wdev,
		const void *data, int data_len)
{
	struct net_device *ndev = wdev->netdev;
	hdd_adapter_t *hostapd_adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_MAX + 1];
	uint8_t config_channel = 0;
	hdd_ap_ctx_t *ap_ctx;
	int ret;

	ENTER();

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

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

	if (!test_bit(SOFTAP_BSS_STARTED, &hostapd_adapter->event_flags)) {
		hddLog(LOGE, FL("SAP is not started yet. Restart sap will be invalid"));
		return -EINVAL;
	}

	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_MAX,
				data, data_len,
				wlan_hdd_sap_config_policy, NULL)) {
		hddLog(LOGE, FL("invalid attr"));
		return -EINVAL;
	}

	if (tb[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL])
		config_channel =
			nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL]);

	if (!IS_CHANNEL_VALID(config_channel)) {
		hddLog(LOGE, FL("Channel  %d is not valid to restart SAP"),
				config_channel);
		return -ENOTSUPP;
	}
	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(hostapd_adapter);
	ap_ctx->sapConfig.channel = config_channel;
	sme_SelectCBMode(hdd_ctx->hHal,
			ap_ctx->sapConfig.SapHw_mode,
			ap_ctx->sapConfig.channel,
			ap_ctx->sapConfig.sec_ch,
			&ap_ctx->sapConfig.vht_channel_width,
			ap_ctx->sapConfig.ch_width_orig);

	wlan_hdd_restart_sap(hostapd_adapter);

	return 0;
}

/**
 * wlan_hdd_cfg80211_sap_configuration_set() - sap configuration vendor command
 * @wiphy:    wiphy structure pointer
 * @wdev:     Wireless device structure pointer
 * @data:     Pointer to the data received
 * @data_len: Length of @data
 *
 * __wlan_hdd_cfg80211_sap_configuration_set function set SAP params to
 * driver.
 * QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHAN will set sap config channel and
 * will initiate restart of sap.
 *
 * Return: 0 on success; errno on failure
 */
static int wlan_hdd_cfg80211_sap_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_sap_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_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},
};

/* define short names for get station info attributes */
#define LINK_INFO_STANDARD_NL80211_ATTR \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_LINK_STANDARD_NL80211_ATTR
#define AP_INFO_STANDARD_NL80211_ATTR \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_STANDARD_NL80211_ATTR
#define INFO_ROAM_COUNT \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ROAM_COUNT
#define INFO_AKM \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AKM
#define WLAN802_11_MODE \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_802_11_MODE
#define AP_INFO_HS20_INDICATION \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_HS20_INDICATION
#define HT_OPERATION \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HT_OPERATION
#define VHT_OPERATION \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_VHT_OPERATION
#define INFO_ASSOC_FAIL_REASON \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ASSOC_FAIL_REASON
#define REMOTE_MAX_PHY_RATE \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_MAX_PHY_RATE
#define REMOTE_TX_PACKETS \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_PACKETS
#define REMOTE_TX_BYTES \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_BYTES
#define REMOTE_RX_PACKETS \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_PACKETS
#define REMOTE_RX_BYTES \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_BYTES
#define REMOTE_LAST_TX_RATE \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_LAST_TX_RATE
#define REMOTE_LAST_RX_RATE \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_LAST_RX_RATE
#define REMOTE_WMM \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_WMM
#define REMOTE_SUPPORTED_MODE \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_SUPPORTED_MODE
#define REMOTE_AMPDU \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_AMPDU
#define REMOTE_TX_STBC \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_STBC
#define REMOTE_RX_STBC \
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_STBC
#define REMOTE_CH_WIDTH\
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_CH_WIDTH
#define REMOTE_SGI_ENABLE\
	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_SGI_ENABLE
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
#define REMOTE_PAD\
       QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_PAD
#endif

/**
 * 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) {
		hddLog(LOGE, FL("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)) {
		hddLog(LOGE, FL("put fail assoc status code"));
		goto fail;
	}

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

#ifdef FEATURE_WLAN_ESE
/**
 * hdd_check_cckm_auth_type() - check cckm auth type
 * @auth_type: csr auth type
 *
 * Return: auth type
 */
static int hdd_check_cckm_auth_type(uint32_t auth_type)
{
	uint32_t ret_val = QCA_WLAN_AUTH_TYPE_INVALID;

	if (auth_type == eCSR_AUTH_TYPE_CCKM_WPA)
		ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
	else if (auth_type == eCSR_AUTH_TYPE_CCKM_RSN)
		ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
	return ret_val;
}
#else
static int hdd_check_cckm_auth_type(uint32_t auth_type)
{
	return QCA_WLAN_AUTH_TYPE_INVALID;
}
#endif

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

	ret_val = hdd_check_cckm_auth_type(auth_type);
	if (ret_val != QCA_WLAN_AUTH_TYPE_INVALID)
		return 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 WLAN_FEATURE_11W
	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;
#endif
	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;
	struct rate_info txrate;

	nla_attr = nla_nest_start(skb, idx);
	if (!nla_attr)
		goto fail;
	/* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
	txrate.flags = hdd_sta_ctx->conn_info.txrate.flags;
	txrate.mcs = hdd_sta_ctx->conn_info.txrate.mcs;
	txrate.legacy = hdd_sta_ctx->conn_info.txrate.legacy;
	txrate.nss = hdd_sta_ctx->conn_info.txrate.nss;

	bitrate = cfg80211_calculate_bitrate(&txrate);

	hdd_sta_ctx->conn_info.txrate.flags = txrate.flags;
	hdd_sta_ctx->conn_info.txrate.mcs = txrate.mcs;
	hdd_sta_ctx->conn_info.txrate.legacy = txrate.legacy;
	hdd_sta_ctx->conn_info.txrate.nss = txrate.nss;

	/* 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)) {
		hddLog(LOGE, FL("put fail bitrate32"));
		goto fail;
	}
	if (bitrate_compat > 0 &&
	    nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
		hddLog(LOGE, FL("put fail bitrate"));
		goto fail;
	}
	if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
		       hdd_sta_ctx->conn_info.txrate.nss)) {
		hddLog(LOGE, FL("put fail nss"));
		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->conn_info.signal + 100))) {
		hddLog(LOGE, FL("put fail signal"));
		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->conn_info.freq) ||
	    nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
		       (hdd_sta_ctx->conn_info.noise + 100))) {
		hddLog(LOGE, FL("put fail noise"));
		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->conn_info.last_ssid.SSID.length,
		    hdd_sta_ctx->conn_info.last_ssid.SSID.ssId)) {
		hddLog(LOGE, FL("put fail ssid"));
		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->conn_info.conn_flag.vht_present)
		if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
			    sizeof(hdd_sta_ctx->conn_info.vht_caps),
			    &hdd_sta_ctx->conn_info.vht_caps)) {
			hddLog(LOGE, FL("put fail vht cap"));
			goto fail;
		}
	if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
		if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
			    sizeof(hdd_sta_ctx->conn_info.ht_caps),
			    &hdd_sta_ctx->conn_info.ht_caps)) {
			hddLog(LOGE, FL("put fail ht cap"));
			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->conn_info.last_ssid.SSID.length) +
		      sizeof(hdd_sta_ctx->conn_info.freq) +
		      sizeof(hdd_sta_ctx->conn_info.noise) +
		      sizeof(hdd_sta_ctx->conn_info.signal) +
		      (sizeof(uint32_t) * 2) +
		      sizeof(hdd_sta_ctx->conn_info.txrate.nss) +
		      sizeof(hdd_sta_ctx->conn_info.roam_count) +
		      sizeof(hdd_sta_ctx->conn_info.last_auth_type) +
		      sizeof(hdd_sta_ctx->conn_info.dot11Mode);
	if (hdd_sta_ctx->conn_info.conn_flag.vht_present)
		nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_caps);
	if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
		nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_caps);
	if (hdd_sta_ctx->conn_info.conn_flag.hs20_present) {
		tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->conn_info.hs20vendor_ie);
		nl_buf_len += (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) -
			       1);
	}
	if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
		nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_operation);
	if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
		nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_operation);


	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
	if (!skb) {
		hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
		return -ENOMEM;
	}

	if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
				       LINK_INFO_STANDARD_NL80211_ATTR)) {
		hddLog(LOGE, FL("put fail link standard info"));
		goto fail;
	}
	if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
				     AP_INFO_STANDARD_NL80211_ATTR)) {
		hddLog(LOGE, FL("put fail ap standard info"));
		goto fail;
	}
	if (nla_put_u32(skb, INFO_ROAM_COUNT,
			hdd_sta_ctx->conn_info.roam_count) ||
	    nla_put_u32(skb, INFO_AKM,
			hdd_convert_auth_type(
			hdd_sta_ctx->conn_info.last_auth_type)) ||
	    nla_put_u32(skb, WLAN802_11_MODE,
			hdd_convert_dot11mode(
			hdd_sta_ctx->conn_info.dot11Mode))) {
		hddLog(LOGE, FL("put fail roam_count, etc."));
		goto fail;
	}
	if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
		if (nla_put(skb, HT_OPERATION,
			    (sizeof(hdd_sta_ctx->conn_info.ht_operation)),
			    &hdd_sta_ctx->conn_info.ht_operation)) {
			hddLog(LOGE, FL("put fail HT oper"));
			goto fail;
		}
	if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
		if (nla_put(skb, VHT_OPERATION,
			    (sizeof(hdd_sta_ctx->conn_info.vht_operation)),
			    &hdd_sta_ctx->conn_info.vht_operation)) {
			hddLog(LOGE, FL("put fail VHT oper"));
			goto fail;
		}
	if (hdd_sta_ctx->conn_info.conn_flag.hs20_present)
		if (nla_put(skb, AP_INFO_HS20_INDICATION,
			    (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) - 1),
			    tmp_hs20 + 1)) {
			hddLog(LOGE, FL("put fail HS20 IND"));
			goto fail;
		}

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

/**
 * hdd_get_peer_txrx_rate_cb() - get station's txrx rate callback
 * @peer_info: pointer of peer information
 * @context: get peer info callback context
 *
 * This function fill txrx rate information to aStaInfo[staid] of hostapd
 * adapter
 */
static void hdd_get_peer_txrx_rate_cb(struct sir_peer_info_ext_resp *peer_info,
		void *context)
{
	struct statsContext *get_txrx_rate_context;
	struct sir_peer_info_ext *txrx_rate = NULL;
	hdd_adapter_t *adapter;
	uint8_t staid;

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

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

	spin_lock(&hdd_context_lock);
	/*
	 * there is a race condition that exists between this callback
	 * function and the caller since the caller could time out either
	 * before or while this code is executing.  we use a spinlock to
	 * serialize these actions
	 */
	get_txrx_rate_context = context;
	if (PEER_INFO_CONTEXT_MAGIC !=
			get_txrx_rate_context->magic) {

		/*
		 * the caller presumably timed out so there is nothing
		 * we can do
		 */
		spin_unlock(&hdd_context_lock);
		hddLog(VOS_TRACE_LEVEL_WARN,
			"%s: Invalid context, magic [%08x]",
			__func__,
			get_txrx_rate_context->magic);
		return;
	}

	if (!peer_info->count) {
		spin_unlock(&hdd_context_lock);
		hddLog(VOS_TRACE_LEVEL_ERROR,
				FL("Fail to get remote peer info"));
		return;
	}

	adapter = get_txrx_rate_context->pAdapter;
	txrx_rate = peer_info->info;
	if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(adapter,
				(v_MACADDR_t *)txrx_rate->peer_macaddr,
				&staid)) {
		spin_unlock(&hdd_context_lock);
		hddLog(VOS_TRACE_LEVEL_ERROR,
				"%s: Station MAC address does not matching",
				__func__);
		return;
	}

	adapter->aStaInfo[staid].tx_rate = txrx_rate->tx_rate;
	adapter->aStaInfo[staid].rx_rate = txrx_rate->rx_rate;
	hddLog(VOS_TRACE_LEVEL_INFO, "%s txrate %x rxrate %x\n",
			__func__,
			adapter->aStaInfo[staid].tx_rate,
			adapter->aStaInfo[staid].rx_rate);

	get_txrx_rate_context->magic = 0;

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

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

	if (txrx_rate)
		hddLog(VOS_TRACE_LEVEL_INFO, "%s %pM tx rate %u rx rate %u",
				__func__,
				txrx_rate->peer_macaddr,
				txrx_rate->tx_rate,
				txrx_rate->rx_rate);
}

/**
 * wlan_hdd_get_peer_txrx_rate() - get station's txrx rate
 * @adapter: hostapd interface
 * @macaddress: mac address of requested peer
 *
 * This function call sme_get_peer_info_ext to get txrx rate
 *
 * Return: 0 on success, otherwise error value
 */
static int wlan_hdd_get_txrx_rate(hdd_adapter_t *adapter,
		v_MACADDR_t macaddress)
{
	eHalStatus hstatus;
	int ret;
	struct statsContext context;
	struct sir_peer_info_ext_req txrx_rate_req;

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

	init_completion(&context.completion);
	context.magic = PEER_INFO_CONTEXT_MAGIC;
	context.pAdapter = adapter;

	vos_mem_copy(&(txrx_rate_req.peer_macaddr), &macaddress,
				VOS_MAC_ADDR_SIZE);
	txrx_rate_req.sessionid = adapter->sessionId;
	txrx_rate_req.reset_after_request = 0;
	hstatus = sme_get_peer_info_ext(WLAN_HDD_GET_HAL_CTX(adapter),
				&txrx_rate_req,
				&context,
				hdd_get_peer_txrx_rate_cb);
	if (eHAL_STATUS_SUCCESS != hstatus) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
			"%s: Unable to retrieve statistics for txrx_rate",
			__func__);
		ret = -EFAULT;
	} else {
		if (!wait_for_completion_timeout(&context.completion,
				msecs_to_jiffies(WLAN_WAIT_TIME_STATS))) {
			hddLog(VOS_TRACE_LEVEL_ERROR,
				"%s: SME timed out while retrieving txrx_rate",
				__func__);
			ret = -EFAULT;
		} else {
			ret = 0;
		}
	}
	/*
	 * either we never sent a request, we sent a request and received a
	 * response or we sent a request and timed out.  if we never sent a
	 * request or if we sent a request and got a response, we want to
	 * clear the magic out of paranoia.  if we timed out there is a
	 * race condition such that the callback function could be
	 * executing at the same time we are. of primary concern is if the
	 * callback function had already verified the "magic" but had not
	 * yet set the completion variable when a timeout occurred. we
	 * serialize these activities by invalidating the magic while
	 * holding a shared spinlock which will cause us to block if the
	 * callback is currently executing
	 */
	spin_lock(&hdd_context_lock);
	context.magic = 0;
	spin_unlock(&hdd_context_lock);
	return ret;
}

/**
 * hdd_get_stainfo() - get stainfo for the specified peer
 * @adapter: hostapd interface
 * @mac_addr: mac address of requested peer
 *
 * This function find the stainfo for the peer with mac_addr
 *
 * Return: stainfo if found, NULL if not found
 */
static hdd_station_info_t *hdd_get_stainfo(hdd_adapter_t *adapter,
		v_MACADDR_t mac_addr)
{
	hdd_station_info_t *stainfo = NULL;
	int i;

	for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
		if (vos_mem_compare(&adapter->aStaInfo[i].macAddrSTA,
					&mac_addr,
					VOS_MAC_ADDR_SIZE))
			stainfo = &adapter->aStaInfo[i];
	}

	return stainfo;
}

/**
 * hdd_get_station_remote() - get remote peer's info
 * @hdd_ctx: hdd context
 * @adapter: hostapd interface
 * @mac_addr: mac address of requested peer
 *
 * This function collect and indicate the remote peer's info
 *
 * Return: 0 on success, otherwise error value
 */
static int hdd_get_station_remote(hdd_context_t *hdd_ctx,
		hdd_adapter_t *adapter,
		v_MACADDR_t mac_addr)
{
	hdd_station_info_t *stainfo = hdd_get_stainfo(adapter, mac_addr);
	struct sk_buff *skb = NULL;
	uint32_t nl_buf_len;
	bool txrx_rate = true;

	if (!stainfo) {
		hddLog(LOGE, FL("peer" MAC_ADDRESS_STR "not found"),
				MAC_ADDR_ARRAY(mac_addr.bytes));
		goto fail;
	}

	nl_buf_len = NLMSG_HDRLEN;
	nl_buf_len += (sizeof(stainfo->max_phy_rate) + NLA_HDRLEN) +
		(sizeof(stainfo->tx_packets) + NLA_HDRLEN) +
		(sizeof(stainfo->tx_bytes) + NLA_HDRLEN) +
		(sizeof(stainfo->rx_packets) + NLA_HDRLEN) +
		(sizeof(stainfo->rx_bytes) + NLA_HDRLEN) +
		(sizeof(stainfo->isQosEnabled) + NLA_HDRLEN) +
		(sizeof(stainfo->mode) + NLA_HDRLEN);

	if (!hdd_ctx->cfg_ini->sap_get_peer_info ||
			wlan_hdd_get_txrx_rate(adapter, mac_addr)) {
		hddLog(LOGE, FL("fail to get tx/rx rate"));
		txrx_rate = false;
	} else {
		nl_buf_len += (sizeof(stainfo->tx_rate) + NLA_HDRLEN) +
			(sizeof(stainfo->rx_rate) + NLA_HDRLEN);
	}

	/* below info is only valid for HT/VHT mode */
	if (stainfo->mode > SIR_SME_PHY_MODE_LEGACY)
		nl_buf_len += (sizeof(stainfo->ampdu) + NLA_HDRLEN) +
			(sizeof(stainfo->tx_stbc) + NLA_HDRLEN) +
			(sizeof(stainfo->rx_stbc) + NLA_HDRLEN) +
			(sizeof(stainfo->ch_width) + NLA_HDRLEN) +
			(sizeof(stainfo->sgi_enable) + NLA_HDRLEN);

	hddLog(VOS_TRACE_LEVEL_INFO, FL("buflen %d hdrlen %d"),
			nl_buf_len, NLMSG_HDRLEN);

	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
			nl_buf_len);
	if (!skb) {
		hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
		goto fail;
	}

	hddLog(VOS_TRACE_LEVEL_INFO,
			FL("stainfo"));
	hddLog(VOS_TRACE_LEVEL_INFO,
			FL("maxrate %x tx_pkts %x tx_bytes %llx"),
			stainfo->max_phy_rate, stainfo->tx_packets,
			stainfo->tx_bytes);
	hddLog(VOS_TRACE_LEVEL_INFO,
			FL("rx_pkts %x rx_bytes %llx mode %x"),
			stainfo->rx_packets, stainfo->rx_bytes,
			stainfo->mode);
	if (stainfo->mode > SIR_SME_PHY_MODE_LEGACY) {
		hddLog(VOS_TRACE_LEVEL_INFO,
				FL("ampdu %d tx_stbc %d rx_stbc %d"),
				stainfo->ampdu, stainfo->tx_stbc,
				stainfo->rx_stbc);
		hddLog(VOS_TRACE_LEVEL_INFO,
				FL("wmm %d chwidth %d sgi %d"),
				stainfo->isQosEnabled,
				stainfo->ch_width,
				stainfo->sgi_enable);
	}

	if (nla_put_u32(skb, REMOTE_MAX_PHY_RATE, stainfo->max_phy_rate) ||
	    nla_put_u32(skb, REMOTE_TX_PACKETS, stainfo->tx_packets) ||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
           nla_put_u64_64bit(skb, REMOTE_TX_BYTES, stainfo->tx_bytes,
                                                       REMOTE_PAD) ||
#else
	    nla_put_u64(skb, REMOTE_TX_BYTES, stainfo->tx_bytes) ||
#endif
	    nla_put_u32(skb, REMOTE_RX_PACKETS, stainfo->rx_packets) ||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
           nla_put_u64_64bit(skb, REMOTE_RX_BYTES, stainfo->rx_bytes,
                                                       REMOTE_PAD) ||
#else
	    nla_put_u64(skb, REMOTE_RX_BYTES, stainfo->rx_bytes) ||
#endif
	    nla_put_u8(skb, REMOTE_WMM, stainfo->isQosEnabled) ||
	    nla_put_u8(skb, REMOTE_SUPPORTED_MODE, stainfo->mode)) {
		hddLog(LOGE, FL("put fail"));
		goto fail;
	}

	if (txrx_rate) {
		if (nla_put_u32(skb, REMOTE_LAST_TX_RATE, stainfo->tx_rate) ||
		    nla_put_u32(skb, REMOTE_LAST_RX_RATE, stainfo->rx_rate)) {
			hddLog(LOGE, FL("put fail"));
			goto fail;
		} else {
			hddLog(VOS_TRACE_LEVEL_INFO,
					FL("tx_rate %x rx_rate %x"),
					stainfo->tx_rate, stainfo->rx_rate);
		}
	}

	if (stainfo->mode > SIR_SME_PHY_MODE_LEGACY) {
		if (nla_put_u8(skb, REMOTE_AMPDU, stainfo->ampdu) ||
		    nla_put_u8(skb, REMOTE_TX_STBC, stainfo->tx_stbc) ||
		    nla_put_u8(skb, REMOTE_RX_STBC, stainfo->rx_stbc) ||
		    nla_put_u8(skb, REMOTE_CH_WIDTH, stainfo->ch_width) ||
		    nla_put_u8(skb, REMOTE_SGI_ENABLE, stainfo->sgi_enable)) {
			hddLog(LOGE, FL("put fail"));
			goto fail;
		}
	}

	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 int
__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;

	ENTER();
	if (VOS_FTM_MODE == hdd_get_conparam()) {
		hddLog(LOGE, FL("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, STATION_MAX, data, data_len,
			   hdd_get_station_policy, NULL);
	if (status) {
		hddLog(LOGE, FL("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) {
			hddLog(VOS_TRACE_LEVEL_INFO,
					FL("invalid device_mode:%d"),
					adapter->device_mode);
			status = -EINVAL;
			goto out;
		}

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

		hddLog(VOS_TRACE_LEVEL_INFO,
				FL("STATION_REMOTE "MAC_ADDRESS_STR""),
				MAC_ADDR_ARRAY(mac_addr.bytes));

		status = hdd_get_station_remote(hdd_ctx, adapter, mac_addr);
	} else {
		hddLog(LOGE, FL("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_REMOTE
#undef STATION_MAX
#undef LINK_INFO_STANDARD_NL80211_ATTR
#undef AP_INFO_STANDARD_NL80211_ATTR
#undef INFO_ROAM_COUNT
#undef INFO_AKM
#undef WLAN802_11_MODE
#undef AP_INFO_HS20_INDICATION
#undef HT_OPERATION
#undef VHT_OPERATION
#undef INFO_ASSOC_FAIL_REASON
#undef REMOTE_MAX_PHY_RATE
#undef REMOTE_TX_PACKETS
#undef REMOTE_TX_BYTES
#undef REMOTE_RX_PACKETS
#undef REMOTE_RX_BYTES
#undef REMOTE_LAST_TX_RATE
#undef REMOTE_LAST_RX_RATE
#undef REMOTE_WMM
#undef REMOTE_SUPPORTED_MODE
#undef REMOTE_AMPDU
#undef REMOTE_TX_STBC
#undef REMOTE_RX_STBC
#undef REMOTE_CH_WIDTH
#undef REMOTE_SGI_ENABLE
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
#undef REMOTE_PAD
#endif
static 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_BINARY,
					.len = VOS_MAC_ADDR_SIZE},
};

/**
 * __wlan_hdd_cfg80211_fast_roaming() - enable/disable roaming
 * @wiphy: Pointer to wireless phy
 * @wdev: Pointer to wireless device
 * @data: Pointer to data
 * @data_len: Length of @data
 *
 * This function is used to enable/disable roaming using vendor commands
 *
 * Return: 0 on success, negative errno on failure
 */
static int __wlan_hdd_cfg80211_fast_roaming(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_MAX + 1];
	uint32_t is_fast_roam_enabled;
	eHalStatus status;
	int ret;
	hdd_station_ctx_t *hddstactx;

	ENTER();

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

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

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

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

	is_fast_roam_enabled = nla_get_u32(
				tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
	hddLog(LOG1, FL("isFastRoamEnabled %d"), is_fast_roam_enabled);

	/*
	 * If framework sends pause_roam, host to send WAIT indication to
	 * framework if roaming is in progress. This can help framework to
	 * defer out-network roaming. EBUSY is used to convey wait indication.
	 */
	if (!is_fast_roam_enabled) {
		if (sme_staInMiddleOfRoaming(hdd_ctx->hHal,
					adapter->sessionId)) {
			hddLog(LOG1, FL("Roaming in progress, do not allow disable"));
			return -EBUSY;
		}

		hddstactx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
		if (hddstactx->hdd_ReassocScenario) {
			hddLog(LOG1,
				FL("Roaming in progress, so unable to disable roaming"));
			return -EBUSY;
		}
	}

	/* Update roaming */
	status = sme_config_fast_roaming(hdd_ctx->hHal, adapter->sessionId,
					 is_fast_roam_enabled);
	if (!HAL_STATUS_SUCCESS(status)) {
		hddLog(LOGE,
			FL("sme_config_fast_roaming (err=%d)"), status);
		return -EINVAL;
	}

	EXIT();
	return 0;
}

/**
 * wlan_hdd_cfg80211_fast_roaming() - enable/disable roaming
 * @wiphy: Pointer to wireless phy
 * @wdev: Pointer to wireless device
 * @data: Pointer to data
 * @data_len: Length of @data
 *
 * Wrapper function of __wlan_hdd_cfg80211_fast_roaming()
 *
 * Return: 0 on success, negative errno on failure
 */
static int wlan_hdd_cfg80211_fast_roaming(struct wiphy *wiphy,
					  struct wireless_dev *wdev,
					  const void *data, int data_len)
{
	int ret;

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

	return ret;
}

static const struct nla_policy
txpower_scale_policy[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_MAX + 1] = {
	[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE] = { .type = NLA_U8 },
};

/**
 * __wlan_hdd_cfg80211_txpower_scale () - txpower scaling
 * @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_txpower_scale(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;
	int ret;
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_MAX + 1];
	uint8_t scale_value;
	VOS_STATUS status;

	ENTER();

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

	adapter = WLAN_HDD_GET_PRIV_PTR(dev);

	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_MAX,
		      data, data_len, txpower_scale_policy, NULL)) {
		hddLog(LOGE, "Invalid ATTR");
		return -EINVAL;
	}

	if (!tb[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE]) {
		hddLog(LOGE, "attr tx power scale failed");
		return -EINVAL;
	}

	scale_value = nla_get_u8(tb
		    [QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE]);

	if (scale_value > MAX_TXPOWER_SCALE) {
		hddLog(LOGE, "Invalid tx power scale level");
		return -EINVAL;
	}

	status = wma_set_tx_power_scale(adapter->sessionId, scale_value);

	if (VOS_STATUS_SUCCESS != status) {
		hddLog(LOGE, "Set tx power scale failed");
		return -EINVAL;
	}

	return 0;
}

/**
 * wlan_hdd_cfg80211_txpower_scale () - txpower scaling
 * @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_txpower_scale(struct wiphy *wiphy,
						struct wireless_dev *wdev,
						const void *data,
						int data_len)
{
	int ret;

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

	return ret;
}

static const struct nla_policy txpower_scale_decr_db_policy
[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB_MAX + 1] = {
	[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB] = { .type = NLA_U8 },
};

/**
 * __wlan_hdd_cfg80211_txpower_scale_decr_db () - txpower scaling
 * @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_txpower_scale_decr_db(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;
	int ret;
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB_MAX + 1];
	uint8_t scale_value;
	VOS_STATUS status;

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

	adapter = WLAN_HDD_GET_PRIV_PTR(dev);

	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB_MAX,
		      data, data_len, txpower_scale_decr_db_policy, NULL)) {
		hddLog(LOGE, "Invalid ATTR");
		return -EINVAL;
	}

	if (!tb[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB]) {
		hddLog(LOGE, "attr tx power decrease db value failed");
		return -EINVAL;
	}

	scale_value = nla_get_u8(tb
		    [QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB]);

	status = wma_set_tx_power_scale_decr_db(adapter->sessionId,
							scale_value);

	if (VOS_STATUS_SUCCESS != status) {
		hddLog(LOGE,"Set tx power decrease db failed");
		return -EINVAL;
	}

	return 0;
}

/**
 * wlan_hdd_cfg80211_txpower_scale_decr_db () - txpower scaling
 * @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_txpower_scale_decr_db(struct wiphy *wiphy,
						struct wireless_dev *wdev,
						const void *data,
						int data_len)
{
	int ret;

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

	return ret;
}

/**
 * hdd_post_get_chain_rssi_rsp - send rsp to user space
 * @hdd_ctx: Pointer to hdd context
 *
 * Return: 0 for success, non-zero for failure
 */
static int hdd_post_get_chain_rssi_rsp(hdd_context_t *hdd_ctx)
{
	struct sk_buff *skb = NULL;
	struct chain_rssi_result *result =
			&hdd_ctx->chain_rssi_context.result;

	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
			(sizeof(result->chain_rssi) + NLA_HDRLEN) +
			(sizeof(result->ant_id) + NLA_HDRLEN) +
			NLMSG_HDRLEN);

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

	if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_CHAIN_RSSI,
			sizeof(result->chain_rssi),
			result->chain_rssi)) {
		hddLog(LOGE, FL("put fail"));
		goto nla_put_failure;
	}

	if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_ANTENNA_INFO,
			sizeof(result->ant_id),
			result->ant_id)) {
		hddLog(LOGE, FL("put fail"));
		goto nla_put_failure;
	}

	cfg80211_vendor_cmd_reply(skb);
	return 0;

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

/**
 * __wlan_hdd_cfg80211_get_chain_rssi() - get chain rssi
 * @wiphy: wiphy pointer
 * @wdev: pointer to struct wireless_dev
 * @data: pointer to incoming NL vendor data
 * @data_len: length of @data
 *
 * Return: 0 on success; error number otherwise.
 */
static int __wlan_hdd_cfg80211_get_chain_rssi(struct wiphy *wiphy,
						struct wireless_dev *wdev,
						const void *data,
						int data_len)
{
	struct get_chain_rssi_req_params req_msg;
	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
	struct hdd_chain_rssi_context *context;
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
	eHalStatus status;
	int retval;
	unsigned long rc;
	const int mac_len = sizeof(req_msg.peer_macaddr);
	int msg_len;

	ENTER();

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

	/* nla validation doesn't do exact lengths, do the validation later */
	retval = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len, NULL, NULL);
	if (retval) {
		hddLog(LOGE, FL("Invalid ATTR"));
		return retval;
	}

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

	msg_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]);
	if (msg_len != mac_len) {
		hddLog(LOGE, FL("Invalid mac address length: %d, expected %d"),
			msg_len, mac_len);
		return -ERANGE;
	}

	memcpy(&req_msg.peer_macaddr,
		nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]), mac_len);

	spin_lock(&hdd_context_lock);
	context = &hdd_ctx->chain_rssi_context;
	INIT_COMPLETION(context->response_event);
	context->ignore_result = false;
	spin_unlock(&hdd_context_lock);

	status = sme_get_chain_rssi(hdd_ctx->hHal, &req_msg);
	if (!HAL_STATUS_SUCCESS(status)) {
		hddLog(LOGE,
			FL("sme_get_chain_rssi failed(err=%d)"), status);
		return -EINVAL;
	}

	rc = wait_for_completion_timeout(&context->response_event,
			msecs_to_jiffies(WLAN_WAIT_TIME_CHAIN_RSSI));
	if (!rc) {
		hddLog(LOGE, FL("Target response timed out"));
		spin_lock(&hdd_context_lock);
		context->ignore_result = true;
		spin_unlock(&hdd_context_lock);
		return -ETIMEDOUT;
	}

	retval = hdd_post_get_chain_rssi_rsp(hdd_ctx);
	if (retval)
		hddLog(LOGE,
			FL("Failed to send chain rssi to user space"));

	EXIT();
	return retval;
}

/**
 * wlan_hdd_cfg80211_get_chain_rssi() - get chain rssi
 * @wiphy: wiphy pointer
 * @wdev: pointer to struct wireless_dev
 * @data: pointer to incoming NL vendor data
 * @data_len: length of @data
 *
 * Return: 0 on success; error number otherwise.
 */
static int wlan_hdd_cfg80211_get_chain_rssi(struct wiphy *wiphy,
			struct wireless_dev *wdev,
			const void *data, int data_len)
{
	int ret;

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

	return ret;
}

static const struct
nla_policy
qca_wlan_vendor_peer_flush_pending_policy
	[QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_MAX + 1] = {
	[QCA_WLAN_VENDOR_ATTR_PEER_ADDR] = {.type = NLA_BINARY,
					.len = VOS_MAC_ADDR_SIZE},
	[QCA_WLAN_VENDOR_ATTR_AC] = { .type = NLA_U8 },
};

/**
 * __wlan_hdd_cfg80211_peer_flush_tids() - flush peer pending packets
 * @wiphy: Pointer to wireless phy
 * @wdev: Pointer to wireless device
 * @data: Pointer to data
 * @data_len: Length of @data
 *
 * This function is used to flush peer pending packets using vendor commands
 *
 * Return: 0 on success, negative errno on failure
 */
static int
__wlan_hdd_cfg80211_peer_flush_pending(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_FLUSH_PENDING_MAX + 1];
	struct sme_flush_pending flush_pending;
	eHalStatus status;
	int ret;

	ENTER();

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

	if (VOS_FTM_MODE == hdd_get_conparam()) {
		hddLog(LOGE, FL("Command not allowed in FTM mode"));
		return -EINVAL;
	}
	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_MAX, data,
		      data_len, qca_wlan_vendor_peer_flush_pending_policy, NULL)) {
		hddLog(LOGE, FL("Invalid attribute"));
		return -EINVAL;
	}

	if (!tb[QCA_WLAN_VENDOR_ATTR_PEER_ADDR]) {
		hddLog(LOGE,
		       FL("Attribute peerMac not provided"));
		return -EINVAL;
	}
	memcpy(flush_pending.peer_addr.bytes,
	       nla_data(tb[QCA_WLAN_VENDOR_ATTR_PEER_ADDR]),
	       VOS_MAC_ADDR_SIZE);

	if (!tb[QCA_WLAN_VENDOR_ATTR_AC]) {
		hddLog(LOGE, FL("Attribute AC not provided"));
		return -EINVAL;
	}
	flush_pending.flush_ac = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_AC]);
	hddLog(LOG1, FL("flush ac = %02x"), flush_pending.flush_ac & 0x0f);

	flush_pending.session_id = adapter->sessionId;
	hddLog(LOG1, FL("session_id = %d"), flush_pending.session_id);

	status = sme_peer_flush_pending(hdd_ctx->hHal, &flush_pending);
	if (!HAL_STATUS_SUCCESS(status)) {
		hddLog(LOGE, FL("sme_config_peer_flush_pending (err=%d)"),
		       status);
		return -EINVAL;
	}
	EXIT();
	return 0;
}

/**
 * wlan_hdd_cfg80211_peer_flush_tids() - flush peer pending packets
 * @wiphy: Pointer to wireless phy
 * @wdev: Pointer to wireless device
 * @data: Pointer to data
 * @data_len: Length of @data
 *
 * Wrapper function of __wlan_hdd_cfg80211_peer_flush_ac()
 *
 * Return: 0 on success, negative errno on failure
 */
static int wlan_hdd_cfg80211_peer_flush_pending(struct wiphy *wiphy,
						struct wireless_dev *wdev,
						const void *data, int data_len)
{
	int ret;

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

	return ret;
}

const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
{
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV,
        .doit = is_driver_dfs_capable
    },

#ifdef WLAN_FEATURE_NAN
    {
        .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
    },
#endif

#ifdef WLAN_FEATURE_STATS_EXT
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_STATS_EXT,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV |
                 WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_stats_ext_request
    },
#endif
#ifdef FEATURE_WLAN_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,
        .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
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV |
                 WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_extscan_set_significant_change
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV |
                 WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_SET_LIST,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV |
                 WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_set_epno_list
    },
#endif /* FEATURE_WLAN_EXTSCAN */

#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 FEATURE_WLAN_TDLS
/* 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
    },
#endif
    {
        .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_SCANNING_MAC_OUI,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV,
        .doit = wlan_hdd_cfg80211_set_scanning_mac_oui
    },
    {
        .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_chan_scan
     },
    {
        .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
    },
#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_DO_ACS,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV |
                 WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_do_acs
    },

    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV,
        .doit = wlan_hdd_cfg80211_get_features
    },
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_SET_KEY,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV |
                 WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_keymgmt_set_key
    },
#endif
    {
        .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
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_CONFIGURATION,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV |
                 WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_wifi_configuration_get
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAM,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV,
        .doit = wlan_hdd_cfg80211_set_ext_roam_params
    },
#ifdef FEATURE_WLAN_EXTSCAN
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_SET_PASSPOINT_LIST,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV |
                 WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_set_passpoint_list
    },
    {
        .info.vendor_id = QCA_NL80211_VENDOR_ID,
        .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_RESET_PASSPOINT_LIST,
        .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
                 WIPHY_VENDOR_CMD_NEED_NETDEV |
                 WIPHY_VENDOR_CMD_NEED_RUNNING,
        .doit = wlan_hdd_cfg80211_reset_passpoint_list
    },
#endif /* FEATURE_WLAN_EXTSCAN */
    {
        .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,
        .doit = wlan_hdd_cfg80211_get_wifi_info
    },
	/* OCB commands */
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OCB_SET_CONFIG,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
				 WIPHY_VENDOR_CMD_NEED_NETDEV |
				 WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_ocb_set_config
	},
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OCB_SET_UTC_TIME,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
				 WIPHY_VENDOR_CMD_NEED_NETDEV |
				 WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_ocb_set_utc_time
	},
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd =
			QCA_NL80211_VENDOR_SUBCMD_OCB_START_TIMING_ADVERT,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
				 WIPHY_VENDOR_CMD_NEED_NETDEV |
				 WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_ocb_start_timing_advert
	},
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OCB_STOP_TIMING_ADVERT,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
				 WIPHY_VENDOR_CMD_NEED_NETDEV |
				 WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_ocb_stop_timing_advert
	},
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OCB_GET_TSF_TIMER,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
				 WIPHY_VENDOR_CMD_NEED_NETDEV |
				 WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_ocb_get_tsf_timer
	},
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_DCC_GET_STATS,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
				 WIPHY_VENDOR_CMD_NEED_NETDEV |
				 WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_dcc_get_stats
	},
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_DCC_CLEAR_STATS,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
				 WIPHY_VENDOR_CMD_NEED_NETDEV |
				 WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_dcc_clear_stats
	},
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_DCC_UPDATE_NDL,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
				 WIPHY_VENDOR_CMD_NEED_NETDEV |
				 WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_dcc_update_ndl
	},
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
			WIPHY_VENDOR_CMD_NEED_NETDEV |
			WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_get_logger_supp_feature
	},
	{
		.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
	},
#ifdef FEATURE_WLAN_TDLS
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_CAPABILITIES,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
			WIPHY_VENDOR_CMD_NEED_NETDEV |
			WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_get_tdls_capabilities
	},
#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_GET_RING_DATA,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
			WIPHY_VENDOR_CMD_NEED_NETDEV,
		.doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
	},
#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_MONITOR_RSSI,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
			WIPHY_VENDOR_CMD_NEED_NETDEV |
			WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_monitor_rssi
	},
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ND_OFFLOAD,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
			 WIPHY_VENDOR_CMD_NEED_NETDEV |
			 WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_set_ns_offload
	},
	{
		.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_PACKET_FILTER,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
			WIPHY_VENDOR_CMD_NEED_NETDEV |
			WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_bpf_offload
	},
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_BUS_SIZE,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
			WIPHY_VENDOR_CMD_NEED_NETDEV,
		.doit = wlan_hdd_cfg80211_get_bus_size
	},
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WAKE_REASON_STATS,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
			 WIPHY_VENDOR_CMD_NEED_NETDEV |
			 WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_get_wakelock_stats
	},
#ifdef WLAN_FEATURE_NAN_DATAPATH
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NDP,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
			WIPHY_VENDOR_CMD_NEED_NETDEV |
			WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_process_ndp_cmd
	},
#endif
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ACS_POLICY,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
			WIPHY_VENDOR_CMD_NEED_NETDEV |
			WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_acs_dfs_mode
	},
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_STA_CONNECT_ROAM_POLICY,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
			WIPHY_VENDOR_CMD_NEED_NETDEV |
			WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_sta_roam_policy
	},
#ifdef FEATURE_WLAN_CH_AVOID
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
			WIPHY_VENDOR_CMD_NEED_NETDEV |
			WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_avoid_freq
	},
#endif
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_SAP_CONFIG,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
			WIPHY_VENDOR_CMD_NEED_NETDEV |
			WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_sap_configuration_set
	},
	{
		.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
	},
	{
		.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_fast_roaming
	},
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_SCALE,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
				 WIPHY_VENDOR_CMD_NEED_NETDEV |
				 WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_txpower_scale
	},
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd =
			QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_SCALE_DECR_DB,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
				 WIPHY_VENDOR_CMD_NEED_NETDEV |
				 WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_txpower_scale_decr_db
	},
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CHAIN_RSSI,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
				 WIPHY_VENDOR_CMD_NEED_NETDEV |
				 WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_get_chain_rssi
	},
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd =
			QCA_NL80211_VENDOR_SUBCMD_LL_STATS_EXT,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
				 WIPHY_VENDOR_CMD_NEED_NETDEV |
				 WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_ll_stats_ext_set_param
	},
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_PEER_FLUSH_PENDING,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
				 WIPHY_VENDOR_CMD_NEED_NETDEV |
				 WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_peer_flush_pending
	},
};

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

#ifdef CFG80211_SCAN_RANDOM_MAC_ADDR
static void wlan_hdd_cfg80211_scan_randomization_init(struct wiphy *wiphy)
{
	wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
	wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
}
#else
static void wlan_hdd_cfg80211_scan_randomization_init(struct wiphy *wiphy)
{
	return;
}
#endif

/**
 * wlan_hdd_cfg80211_add_connected_pno_support() - Set connected PNO support
 * @wiphy: Pointer to wireless phy
 *
 * This function is used to set connected PNO support to kernel
 *
 * Return: None
 */
#if defined(CFG80211_REPORT_BETTER_BSS_IN_SCHED_SCAN)
static void wlan_hdd_cfg80211_add_connected_pno_support(struct wiphy *wiphy)
{
	wiphy_ext_feature_set(wiphy,
		NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI);
}
#else
static void wlan_hdd_cfg80211_add_connected_pno_support(struct wiphy *wiphy)
{
	return;
}
#endif

#ifdef CFG80211_RAND_TA_FOR_PUBLIC_ACTION_FRAME
/**
 * wlan_hdd_cfg80211_action_frame_randomization_init() - Randomize SA of MA frms
 * @wiphy: Pointer to wiphy
 *
 * This function is used to indicate the support of source mac address
 * randomization of management action frames
 *
 * Return: None
 */
static void
wlan_hdd_cfg80211_action_frame_randomization_init(struct wiphy *wiphy)
{
       wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA);
}
#else
static void
wlan_hdd_cfg80211_action_frame_randomization_init(struct wiphy *wiphy)
{
       return;
}
#endif

#if defined(WLAN_FEATURE_FILS_SK) && defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT)
static void wlan_hdd_cfg80211_set_wiphy_fils_feature(struct wiphy *wiphy)
{
    wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_SK_OFFLOAD);
}
#else
static void wlan_hdd_cfg80211_set_wiphy_fils_feature(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;


    /* 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)) || defined(WITH_BACKPORTS)
    wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
#else
    wiphy->flags |=   WIPHY_FLAG_DISABLE_BEACON_HINTS;
#endif

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) || defined(WITH_BACKPORTS)
    wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
                 |  WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
                 |  WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
#ifdef FEATURE_WLAN_STA_4ADDR_SCHEME
                 |  WIPHY_FLAG_4ADDR_STATION
#endif
                    | WIPHY_FLAG_OFFCHAN_TX;

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) || defined(WITH_BACKPORTS)
    wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
#else
    wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
#endif
#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  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

    wiphy->features |= NL80211_FEATURE_HT_IBSS;

#ifdef FEATURE_WLAN_SCAN_PNO
    if (pCfg->configPNOScanSupport)
    {
	wiphy->max_sched_scan_reqs = 1;
        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;
    }
    wlan_hdd_cfg80211_add_connected_pno_support(wiphy);
#endif/*FEATURE_WLAN_SCAN_PNO*/

#if  defined QCA_WIFI_FTM
    if (vos_get_conparam() != VOS_FTM_MODE) {
#endif

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

#if  defined QCA_WIFI_FTM
    }
#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)) || defined(WITH_BACKPORTS)
       if( pCfg->enableMCC ) {
          int i;
          for (i = 0; i < ARRAY_SIZE(wlan_hdd_iface_combination); i++) {
             if( !pCfg->allowMCCGODiffBI )
                wlan_hdd_iface_combination[i].beacon_int_infra_match = true;
          }
       }
       wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
       wiphy->iface_combinations = wlan_hdd_iface_combination;
#endif
    }

    /* Before registering we need to update the HT capability 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[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
    wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
        vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
    if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                FL("Not enough memory to allocate channels"));
        return -ENOMEM;
    }
    vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
            &hdd_channels_2_4_GHZ[0],
            sizeof(hdd_channels_2_4_GHZ));
   if (hdd_is_5g_supported(pHddCtx) &&
       ((eHDD_DOT11_MODE_11b != pCfg->dot11Mode) &&
       (eHDD_DOT11_MODE_11g != pCfg->dot11Mode) &&
       (eHDD_DOT11_MODE_11b_ONLY != pCfg->dot11Mode) &&
       (eHDD_DOT11_MODE_11g_ONLY != pCfg->dot11Mode)))
   {
        wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
        wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
            vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
        if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL) {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    FL("Not enough memory to allocate channels"));
            vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
            wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
            return -ENOMEM;
        }
        vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
                &hdd_channels_5_GHZ[0],
                sizeof(hdd_channels_5_GHZ));
   }

   for (i = 0; i < IEEE80211_NUM_BANDS; i++)
   {

       if (NULL == wiphy->bands[i])
          continue;

       for (j = 0; j < wiphy->bands[i]->n_channels; j++)
       {
           struct ieee80211_supported_band *band = wiphy->bands[i];

           if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
           {
#ifdef WLAN_ENABLE_SOCIAL_CHANNELS_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
#endif
                   band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
               continue;
           }
           else if (IEEE80211_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;
    wiphy->max_remain_on_channel_duration = MAX_REMAIN_ON_CHANNEL_DURATION;
    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);

#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,4,0)) || \
    defined (DFS_MASTER_OFFLOAD_IND_SUPPORT) || defined(WITH_BACKPORTS)
    if (pCfg->enableDFSMasterCap) {
        wiphy->flags |= WIPHY_FLAG_DFS_OFFLOAD;
    }
#endif

    wiphy->max_ap_assoc_sta = pHddCtx->max_peers;
#ifdef QCA_HT_2040_COEX
    wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE;
#endif

#ifdef CHANNEL_SWITCH_SUPPORTED
    wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
#endif

    if (pCfg->sub_20_channel_width)
        wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ;

    wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER;

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,8,0)) || \
    defined(CFG80211_BEACON_TX_RATE_CUSTOM_BACKPORT)
    wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_LEGACY);
    wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HT);
    wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_VHT);
#endif
    wlan_hdd_cfg80211_set_wiphy_fils_feature(wiphy);
    hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
    wlan_hdd_cfg80211_scan_randomization_init(wiphy);
    wlan_hdd_cfg80211_action_frame_randomization_init(wiphy);

    EXIT();
    return 0;
}

/**
 * wlan_hdd_cfg80211_deinit - Deinit cfg80211
 * @ wiphy: the wiphy to validate against
 *
 * this function deinit cfg80211 and cleanup the
 * memory allocated in wlan_hdd_cfg80211_init
 *
 * Return: void
 */
void wlan_hdd_cfg80211_deinit(struct wiphy *wiphy)
{
	int i;

	for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
		if (NULL != wiphy->bands[i] &&
		   (NULL != wiphy->bands[i]->channels)) {
			vos_mem_free(wiphy->bands[i]->channels);
			wiphy->bands[i]->channels = NULL;
		}
	}
	vos_reset_global_reg_params();
}

/*
 * In this function, wiphy structure is updated after VOSS
 * initialization. In wlan_hdd_cfg80211_init, only the
 * default values will be initialized. The final initialization
 * of all required members can be done here.
 */
void wlan_hdd_update_wiphy(struct wiphy *wiphy,
                           hdd_context_t *ctx)
{
    uint32_t val32;
    uint16_t val16;
    tSirMacHTCapabilityInfo *ht_cap_info;
    eHalStatus status;

    wiphy->max_ap_assoc_sta = ctx->max_peers;
    if (!sme_IsFeatureSupportedByFW(DOT11AC)) {
       wiphy->bands[IEEE80211_BAND_2GHZ]->vht_cap.vht_supported = 0;
       wiphy->bands[IEEE80211_BAND_2GHZ]->vht_cap.cap = 0;
       wiphy->bands[IEEE80211_BAND_5GHZ]->vht_cap.vht_supported = 0;
       wiphy->bands[IEEE80211_BAND_5GHZ]->vht_cap.cap = 0;
    }

    status = ccmCfgGetInt(ctx->hHal, WNI_CFG_HT_CAP_INFO, &val32);
    if (eHAL_STATUS_SUCCESS != status) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                  "%s: could not get HT capability info",
                  __func__);
        val32 = 0;
    }
    val16 = (uint16_t)val32;
    ht_cap_info = (tSirMacHTCapabilityInfo *)&val16;

    if (ht_cap_info->txSTBC == TRUE) {
        if (NULL != wiphy->bands[IEEE80211_BAND_2GHZ])
            wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap |=
                                                    IEEE80211_HT_CAP_TX_STBC;
        if (NULL != wiphy->bands[IEEE80211_BAND_5GHZ])
            wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap.cap |=
                                                    IEEE80211_HT_CAP_TX_STBC;
    }
}

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

/*
  HDD function to update wiphy capability based on target offload status.

  wlan_hdd_cfg80211_init() does initialization of all wiphy related
  capability even before downloading firmware to the target. In discrete
  case, host will get know certain offload capability (say sched_scan
  caps) only after downloading firmware to the target and target boots up.
  This function is used to override setting done in wlan_hdd_cfg80211_init()
  based on target capability.
*/
void wlan_hdd_cfg80211_update_wiphy_caps(struct wiphy *wiphy)
{
#ifdef FEATURE_WLAN_SCAN_PNO
   hdd_context_t *pHddCtx = wiphy_priv(wiphy);
   hdd_config_t *pCfg = pHddCtx->cfg_ini;

   /* wlan_hdd_cfg80211_init() sets sched_scan caps already in wiphy before
    * control comes here. Here just we need to clear it if firmware doesn't
    * have PNO support. */
   if (!pCfg->PnoOffload) {
       wiphy->max_sched_scan_reqs = 0;
       wiphy->max_sched_scan_ssids = 0;
       wiphy->max_match_sets = 0;
       wiphy->max_sched_scan_ie_len = 0;
   }
#endif
}

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

    /* Register for p2p ack indication */
    sme_register_p2p_ack_ind_callback(hHal, hdd_send_action_cnf_cb);

   /* 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, HDD_SESSION_ID_ANY, type,
                         (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );

    /* GAS Initial Response */
    sme_RegisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, type,
                         (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );

    /* GAS Comeback Request */
    sme_RegisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, type,
                         (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );

    /* GAS Comeback Response */
    sme_RegisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, type,
                         (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );

    /* P2P Public Action */
    sme_RegisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, type,
                         (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
                                  P2P_PUBLIC_ACTION_FRAME_SIZE );

    /* P2P Action */
    sme_RegisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, type,
                         (v_U8_t*)P2P_ACTION_FRAME,
                                  P2P_ACTION_FRAME_SIZE );

    /* WNM BSS Transition Request frame */
    sme_RegisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, 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, HDD_SESSION_ID_ANY, type,
                          (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );

    /* GAS Initial Response */
    sme_DeregisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, type,
                         (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );

    /* GAS Comeback Request */
    sme_DeregisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, type,
                         (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );

    /* GAS Comeback Response */
    sme_DeregisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, type,
                         (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );

    /* P2P Public Action */
    sme_DeregisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, type,
                         (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
                                  P2P_PUBLIC_ACTION_FRAME_SIZE );

    /* P2P Action */
    sme_DeregisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, 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(LOG1, FL("Device_mode %s(%d)"),
           hdd_device_mode_to_string(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 Direction 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
    {
        vos_mem_copy(setKey.peerMac, mac_addr, VOS_MAC_ADDR_SIZE);
    }
    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;
    }
}
#endif /* FEATURE_WLAN_WAPI*/

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) && !defined(WITH_BACKPORTS)
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 point to NULL"),
                     pAdapter->sessionId);
        return -EINVAL;
    }

    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)) && !defined(WITH_BACKPORTS)
    if (params->dtim_period)
        beacon->dtim_period = params->dtim_period;
    else if (old)
        beacon->dtim_period = old->dtim_period;
#else
    if (dtim_period)
        beacon->dtim_period = dtim_period;
    else if (old)
        beacon->dtim_period = old->dtim_period;
#endif

    /* -----------------------------------------------
     * | head | tail | proberesp_ies | assocresp_ies |
     * -----------------------------------------------
     */
    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(const v_U8_t *pIes, 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* require_vht,
                     u8* pCheckRatesfor11g, eCsrPhyMode* 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 = eCSR_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 = eCSR_DOT11_MODE_11g_ONLY;
               *pCheckRatesfor11g = FALSE;
            }
        }
        else if ((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) ==
                                                                      pIe[i]) {
            *require_ht = TRUE;
        }
        else if ((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_VHT_PHY) ==
                                                                      pIe[i]) {
            *require_vht = TRUE;
        }
    }
    return;
}

#ifdef QCA_HT_2040_COEX
static bool wlan_hdd_get_sap_obss(hdd_adapter_t *pHostapdAdapter)
{
    uint8_t ht_cap_ie[DOT11F_IE_HTCAPS_MAX_LEN];
    tDot11fIEHTCaps dot11_ht_cap_ie = {0};
    hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
    beacon_data_t *beacon = pHostapdAdapter->sessionCtx.ap.beacon;
    uint8_t *ie = NULL;

    ie = wlan_hdd_cfg80211_get_ie_ptr(beacon->tail, beacon->tail_len,
                                                        WLAN_EID_HT_CAPABILITY);
    if (ie && ie[1]) {
        vos_mem_copy(ht_cap_ie, &ie[2], DOT11F_IE_HTCAPS_MAX_LEN);
        dot11fUnpackIeHTCaps((tpAniSirGlobal)hdd_ctx->hHal, ht_cap_ie, ie[1],
                                                           &dot11_ht_cap_ie);
        return dot11_ht_cap_ie.supportedChannelWidthSet;
    }

    return false;
}
#else
static bool wlan_hdd_get_sap_obss(hdd_adapter_t *pHostapdAdapter)
{
    return false;
}
#endif

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, require_vht = false;
    u8 *pIe=NULL;

    pConfig->SapHw_mode= eCSR_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, &require_vht, &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, &require_vht, &checkRatesfor11g,
                               &pConfig->SapHw_mode);
    }

    if (pConfig->channel > 14)
        pConfig->SapHw_mode= eCSR_DOT11_MODE_11a;

    pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
                                                        WLAN_EID_HT_CAPABILITY);
    if (pIe) {
        pConfig->SapHw_mode= eCSR_DOT11_MODE_11n;
        if (require_ht)
            pConfig->SapHw_mode= eCSR_DOT11_MODE_11n_ONLY;
    }

    pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
                                                       WLAN_EID_VHT_CAPABILITY);
    if (pIe) {
        pConfig->SapHw_mode= eCSR_DOT11_MODE_11ac;
        if (require_vht)
            pConfig->SapHw_mode= eCSR_DOT11_MODE_11ac_ONLY;
    }
}

static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
                              v_U16_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_U16_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;
}

static void wlan_hdd_add_extra_ie(hdd_adapter_t* pHostapdAdapter,
                                           v_U8_t *genie, v_U16_t *total_ielen,
                                           v_U8_t temp_ie_id)
{
    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 (temp_ie_id == elem_id)
        {
            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;
}

#ifdef QCA_HT_2040_COEX
static void wlan_hdd_add_sap_obss_scan_ie(
	hdd_adapter_t *pHostapdAdapter, v_U8_t *ie_buf, v_U16_t *ie_len)
{
	if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode) {
		if (wlan_hdd_get_sap_obss(pHostapdAdapter))
			wlan_hdd_add_extra_ie(pHostapdAdapter, ie_buf, ie_len,
					WLAN_EID_OVERLAP_BSS_SCAN_PARAM);
	}
}
#else
static void wlan_hdd_add_sap_obss_scan_ie(
	hdd_adapter_t* pHostapdAdapter, v_U8_t *ie_buf, v_U16_t *ie_len)
{
}
#endif

int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter)
{
    v_U8_t *genie;
    v_U16_t total_ielen = 0;
    int ret = 0;
    tsap_Config_t *pConfig;
    tSirUpdateIE   updateIE;
    beacon_data_t *pBeacon = NULL;

    pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
    pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;

    genie = vos_mem_malloc(MAX_GENIE_LEN);

    if(genie == NULL) {

        return -ENOMEM;
    }

    /* Extract and add the extended capabilities and interworking IE */
    wlan_hdd_add_extra_ie(pHostapdAdapter, genie, &total_ielen,
                          WLAN_EID_EXT_CAPABILITY);

    wlan_hdd_add_extra_ie(pHostapdAdapter, genie, &total_ielen,
                          WLAN_EID_INTERWORKING);

    wlan_hdd_add_extra_ie(pHostapdAdapter, genie, &total_ielen,
                          WLAN_EID_VHT_TX_POWER_ENVELOPE);

    if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
        wlan_hdd_add_extra_ie(pHostapdAdapter, genie, &total_ielen,
                              WLAN_EID_RSN);

    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

#ifdef FEATURE_WLAN_WAPI
    if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
    {
        wlan_hdd_add_extra_ie(pHostapdAdapter, genie, &total_ielen,
                WLAN_EID_WAPI);
    }
#endif

    if ((WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode) ||
        (WLAN_HDD_P2P_GO == pHostapdAdapter->device_mode))
    {
        wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
    }

    wlan_hdd_add_sap_obss_scan_ie(pHostapdAdapter, genie, &total_ielen);

    vos_mem_copy(updateIE.bssid, pHostapdAdapter->macAddressCurrent.bytes,
                   sizeof(tSirMacAddr));
    updateIE.smeSessionId =  pHostapdAdapter->sessionId;

    if (wlan_hdd_add_ie(pHostapdAdapter, genie,
                       &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0) {
         hddLog(LOGE, FL("Adding P2P IE failed"));
         ret = -EINVAL;
         goto done;
    }


    if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) {
        updateIE.ieBufferlength = total_ielen;
        updateIE.pAdditionIEBuffer = genie;
        updateIE.append = VOS_FALSE;
        updateIE.notify = VOS_TRUE;
        if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pHostapdAdapter),
                &updateIE, eUPDATE_IE_PROBE_BCN) == eHAL_STATUS_FAILURE) {
            hddLog(LOGE, FL("Could not pass on Add Ie probe beacon data"));
            ret = -EINVAL;
            goto done;
        }
        WLANSAP_ResetSapConfigAddIE(pConfig , eUPDATE_IE_PROBE_BCN);
    } else {
        WLANSAP_UpdateSapConfigAddIE(pConfig,
                                     genie,
                                     total_ielen,
                                     eUPDATE_IE_PROBE_BCN);
    }

    /* Added for Probe Response IE */
    total_ielen = 0;
    if (pBeacon->proberesp_ies_len > 0 &&
        pBeacon->proberesp_ies_len <= MAX_GENIE_LEN) {
        vos_mem_copy(genie, pBeacon->proberesp_ies, pBeacon->proberesp_ies_len);
        total_ielen = pBeacon->proberesp_ies_len;
    }
    wlan_hdd_add_sap_obss_scan_ie(pHostapdAdapter, genie, &total_ielen);

    if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) {
        updateIE.ieBufferlength = total_ielen;
        updateIE.pAdditionIEBuffer = genie;
        updateIE.append = VOS_FALSE;
        updateIE.notify = VOS_FALSE;
        if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pHostapdAdapter),
                  &updateIE, eUPDATE_IE_PROBE_RESP) == eHAL_STATUS_FAILURE) {
            hddLog(LOGE, FL("Could not pass on PROBE_RESP add Ie data"));
            ret = -EINVAL;
            goto done;
        }
        WLANSAP_ResetSapConfigAddIE(pConfig, eUPDATE_IE_PROBE_RESP);
    } else {
        WLANSAP_UpdateSapConfigAddIE(pConfig, genie, total_ielen,
                             eUPDATE_IE_PROBE_RESP);
    }

    /* Assoc resp Add ie Data */
    if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) {
        updateIE.ieBufferlength = pBeacon->assocresp_ies_len;
        updateIE.pAdditionIEBuffer = (tANI_U8*)pBeacon->assocresp_ies;
        updateIE.append = VOS_FALSE;
        updateIE.notify = VOS_FALSE;
        if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pHostapdAdapter),
                &updateIE, eUPDATE_IE_ASSOC_RESP) == eHAL_STATUS_FAILURE) {
            hddLog(LOGE, FL("Could not pass on Add Ie Assoc Response data"));
            ret = -EINVAL;
            goto done;
        }
        WLANSAP_ResetSapConfigAddIE(pConfig, eUPDATE_IE_ASSOC_RESP);
    } else {
        WLANSAP_UpdateSapConfigAddIE(pConfig,
                         pBeacon->assocresp_ies,
                         pBeacon->assocresp_ies_len,
                         eUPDATE_IE_ASSOC_RESP);
    }

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)
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: Invalid Channel [%d]", __func__, channel);
            return VOS_STATUS_E_FAILURE;
        }
    }
    return VOS_STATUS_SUCCESS;

}

/**
 * __wlan_hdd_cfg80211_set_channel() - cfg80211 set channel
 * @wiphy: pointer to wiphy structure
 * @dev: pointer to net_device structure
 * @chan: pointer to ieee80211_channel structure
 * @channel_type: channel type
 *
 * This function is used to set the channel number
 *
 * Return; 0 on success, error number otherwise
 */
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;
    tSmeConfigParams smeConfig;
    tsap_Config_t *sap_config;

    ENTER();

    if( NULL == dev )
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: Called with dev = NULL.", __func__);
        return -ENODEV;
    }

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

    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(LOG1, FL("Device_mode %s(%d) freq = %d"),
                 hdd_device_mode_to_string(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(LOG2, FL("set channel to [%d] for device mode %s(%d)"),
               channel, hdd_device_mode_to_string(pAdapter->device_mode),
               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)
            )
    {
        sap_config = &((WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig);
        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;
            }
            sap_config->channel = channel;
        }
        else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
        {

            /* set channel to what hostapd configured */
            if (VOS_STATUS_SUCCESS !=
                       wlan_hdd_validate_operation_channel(pAdapter,channel)) {
                   hddLog(VOS_TRACE_LEVEL_ERROR,
                          "%s: Invalid Channel [%d]", __func__, channel);
                   return -EINVAL;
            }
            sap_config->channel = channel;

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) && !defined(WITH_BACKPORTS)
            sap_config->ch_width_orig = eHT_CHANNEL_WIDTH_40MHZ;
#endif
            vos_mem_zero(&smeConfig, sizeof(smeConfig));
            sme_GetConfigParam(pHddCtx->hHal, &smeConfig);

            switch (channel_type) {
            case NL80211_CHAN_HT20:
            case NL80211_CHAN_NO_HT:
                if (channel <= 14)
                    smeConfig.csrConfig.channelBondingMode24GHz =
                                           eCSR_INI_SINGLE_CHANNEL_CENTERED;
                else
                    smeConfig.csrConfig.channelBondingMode5GHz =
                                           eCSR_INI_SINGLE_CHANNEL_CENTERED;
                sap_config->sec_ch = 0;

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) && !defined(WITH_BACKPORTS)
                sap_config->ch_width_orig = eHT_CHANNEL_WIDTH_20MHZ;
#endif
                sap_config->sec_ch = 0;
                break;

            case NL80211_CHAN_HT40MINUS:
                if (channel <= 14)
                    smeConfig.csrConfig.channelBondingMode24GHz =
                            eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
                else
                    smeConfig.csrConfig.channelBondingMode5GHz =
                            eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;

                sap_config->sec_ch = sap_config->channel - 4;
                break;
            case NL80211_CHAN_HT40PLUS:
                if (channel <= 14)
                    smeConfig.csrConfig.channelBondingMode24GHz =
                            eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
                else
                    smeConfig.csrConfig.channelBondingMode5GHz =
                            eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;

                sap_config->sec_ch = sap_config->channel + 4;
                break;
            default:
                hddLog(VOS_TRACE_LEVEL_ERROR,
                          "%s:Error!!! Invalid HT20/40 mode !",
                          __func__);
                return -EINVAL;
            }
            smeConfig.csrConfig.obssEnabled = wlan_hdd_get_sap_obss(pAdapter);
            sme_UpdateConfig (pHddCtx->hHal, &smeConfig);
        }
    }
    else
    {
        hddLog(VOS_TRACE_LEVEL_FATAL,
               "%s: Invalid device mode failed to set valid channel", __func__);
        return -EINVAL;
    }
    EXIT();
    return status;
}

/**
 * wlan_hdd_cfg80211_set_channel() - cfg80211 set channel
 * @wiphy: pointer to wiphy structure
 * @dev: pointer to net_device structure
 * @chan: pointer to ieee80211_channel structure
 * @channel_type: channel type
 *
 * This is the cfg80211 set channel handler function which invokes
 * the internal function @__wlan_hdd_cfg80211_set_channel with
 * SSR protection.
 *
 * Return; 0 on success, error number otherwise
 */
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
static void wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *pHostapdAdapter)
{
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
    tpSirDhcpSrvOffloadInfo pDhcpSrvInfo;
    tANI_U8 numEntries = 0;
    tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
    tANI_U8 num;
    tANI_U32 temp;

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

    vos_mem_zero(pDhcpSrvInfo, sizeof(*pDhcpSrvInfo));

    pDhcpSrvInfo->vdev_id = pHostapdAdapter->sessionId;
    pDhcpSrvInfo->dhcpSrvOffloadEnabled = TRUE;
    pDhcpSrvInfo->dhcpClientNum = pHddCtx->cfg_ini->dhcpMaxNumClients;
    pDhcpSrvInfo->dhcp_client_start_ip =
                           pHddCtx->cfg_ini->dhcp_client_start_ip;

    hdd_string_to_u8_array(pHddCtx->cfg_ini->dhcpServerIP,
                           srv_ip,
                           &numEntries,
                           IPADDR_NUM_ENTRIES);
    if (numEntries != IPADDR_NUM_ENTRIES) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               "%s: incorrect IP address (%s) assigned for DHCP server!",
               __func__, pHddCtx->cfg_ini->dhcpServerIP);
        goto end;
    }

    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__, pHddCtx->cfg_ini->dhcpServerIP);
        goto end;
    }

    if (srv_ip[IPADDR_NUM_ENTRIES-1] >= 100) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
          "%s: invalid IP address (%s)! The last field must be less than 100!",
          __func__, pHddCtx->cfg_ini->dhcpServerIP);
        goto end;
    }

    for (num = 0; num < numEntries; num++) {
        temp = srv_ip[num];
        pDhcpSrvInfo->dhcpSrvIP |= (temp << (8 * num));
    }

    if (eHAL_STATUS_SUCCESS !=
                        sme_setDhcpSrvOffload(pHddCtx->hHal, pDhcpSrvInfo)) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               "%s: sme_setDHCPSrvOffload fail!", __func__);
        goto end;
    }

    hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
           "%s: enable DHCP Server offload successfully!", __func__);

end:
    vos_mem_free(pDhcpSrvInfo);
    return;
}
#endif /* DHCP_SERVER_OFFLOAD */


/**
 * wlan_hdd_setup_driver_overrides : Overrides SAP / P2P GO Params
 * @adapter: pointer to adapter struct
 *
 * This function overrides SAP / P2P Go configuration based on driver INI
 * parameters for 11AC override and ACS. This overrides are done to support
 * android legacy configuration method.
 *
 * NOTE: Non android platform supports concurrency and these overrides shall
 * not be used. Also future driver based overrides shall be consolidated in this
 * function only. Avoid random overrides in other location based on ini.
 *
 * Return: 0 for Success or Negative error codes.
 */
int wlan_hdd_setup_driver_overrides(hdd_adapter_t *ap_adapter)
{
	tsap_Config_t *sap_cfg = &ap_adapter->sessionCtx.ap.sapConfig;
	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
	tHalHandle h_hal = WLAN_HDD_GET_HAL_CTX(ap_adapter);

	if (ap_adapter->device_mode == WLAN_HDD_SOFTAP &&
				hdd_ctx->cfg_ini->force_sap_acs)
		goto setup_acs_overrides;

	/* Fixed channel 11AC override:
	 * 11AC override in qcacld is introduced for following reasons:
	 * 1. P2P GO also follows start_bss and since p2p GO could not be
	 *    configured to setup VHT channel width in wpa_supplicant
	 * 2. Android UI does not provide advanced configuration options for SAP
	 *
	 * Default override enabled (for android). MDM shall disable this in ini
	 */
	if (hdd_ctx->cfg_ini->sap_p2p_11ac_override &&
			(sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n ||
			sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac ||
			sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY) &&
			!hdd_ctx->cfg_ini->sap_force_11n_for_11ac) {
		hddLog(LOG1, FL("** Driver force 11AC override for SAP/Go **"));

		/* 11n only shall not be overridden since it may be on purpose*/
		if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n)
			sap_cfg->SapHw_mode = eCSR_DOT11_MODE_11ac;

		if (sap_cfg->channel >= 36)
			sap_cfg->ch_width_orig =
					hdd_ctx->cfg_ini->vhtChannelWidth;
		else
			sap_cfg->ch_width_orig =
				hdd_ctx->cfg_ini->nChannelBondingMode24GHz ?
				eHT_CHANNEL_WIDTH_40MHZ :
				eHT_CHANNEL_WIDTH_20MHZ;

	}

	sap_cfg->vht_channel_width = sap_cfg->ch_width_orig;

	sme_SelectCBMode(h_hal, sap_cfg->SapHw_mode, sap_cfg->channel,
			sap_cfg->sec_ch, &sap_cfg->vht_channel_width,
						sap_cfg->ch_width_orig);
	return 0;

setup_acs_overrides:
	hddLog(LOGE, FL("** Driver force ACS override **"));

	sap_cfg->channel = AUTO_CHANNEL_SELECT;
	sap_cfg->acs_cfg.acs_mode = true;
	sap_cfg->acs_cfg.start_ch = hdd_ctx->cfg_ini->force_sap_acs_st_ch;
	sap_cfg->acs_cfg.end_ch = hdd_ctx->cfg_ini->force_sap_acs_end_ch;

	if (sap_cfg->acs_cfg.start_ch > sap_cfg->acs_cfg.end_ch) {
		hddLog(LOGE, FL("Driver force ACS start ch (%d) > end ch (%d)"),
			sap_cfg->acs_cfg.start_ch,  sap_cfg->acs_cfg.end_ch);
		return -EINVAL;
	}

	/* Derive ACS HW mode */
	sap_cfg->SapHw_mode = hdd_cfg_xlate_to_csr_phy_mode(
						hdd_ctx->cfg_ini->dot11Mode);
	if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_AUTO)
		sap_cfg->SapHw_mode = eCSR_DOT11_MODE_11ac;

	if (hdd_ctx->cfg_ini->sap_force_11n_for_11ac) {
		if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac ||
		    sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY)
			sap_cfg->SapHw_mode = eCSR_DOT11_MODE_11n;
	}

	if ((sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11b ||
			sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11g ||
			sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11g_ONLY) &&
			sap_cfg->acs_cfg.start_ch > 14) {
		hddLog(LOGE, FL("Invalid ACS Dot11Mode %d & CH range <%d - %d> Combination"),
			sap_cfg->SapHw_mode, sap_cfg->acs_cfg.start_ch,
			sap_cfg->acs_cfg.end_ch);
		return -EINVAL;
	}
	sap_cfg->acs_cfg.hw_mode = sap_cfg->SapHw_mode;

	/* Derive ACS BW */
	sap_cfg->ch_width_orig = eHT_CHANNEL_WIDTH_20MHZ;
	if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac ||
			sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY) {

		sap_cfg->ch_width_orig = hdd_ctx->cfg_ini->vhtChannelWidth;
		/* VHT in 2.4G depends on gChannelBondingMode24GHz INI param */
		if (sap_cfg->acs_cfg.end_ch <= 14)
			sap_cfg->ch_width_orig =
				hdd_ctx->cfg_ini->nChannelBondingMode24GHz ?
				eHT_CHANNEL_WIDTH_40MHZ :
				eHT_CHANNEL_WIDTH_20MHZ;
	}

	if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n ||
			sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n_ONLY) {
		if (sap_cfg->acs_cfg.end_ch <= 14)
			sap_cfg->ch_width_orig =
				hdd_ctx->cfg_ini->nChannelBondingMode24GHz ?
				eHT_CHANNEL_WIDTH_40MHZ :
				eHT_CHANNEL_WIDTH_20MHZ;
		else
			sap_cfg->ch_width_orig =
				hdd_ctx->cfg_ini->nChannelBondingMode5GHz ?
				eHT_CHANNEL_WIDTH_40MHZ :
				eHT_CHANNEL_WIDTH_20MHZ;
	}
	sap_cfg->acs_cfg.ch_width = sap_cfg->ch_width_orig;

	hddLog(LOGE, FL("Force ACS Config: HW_MODE: %d ACS_BW: %d ST_CH: %d END_CH: %d"),
		sap_cfg->acs_cfg.hw_mode, sap_cfg->acs_cfg.ch_width,
		sap_cfg->acs_cfg.start_ch, sap_cfg->acs_cfg.end_ch);

	return 0;
}


#ifdef WLAN_FEATURE_UDP_RESPONSE_OFFLOAD
/**
 * wlan_hdd_set_udp_resp_offload() - get specific udp and response udp info from
 * ini file
 * @padapter: hdd adapter pointer
 * @enable: enable or disable the specific udp and response behaviour
 *
 * This function reads specific udp and response udp related info from ini file,
 * these configurations will be sent to fw through wmi.
 *
 * Return: 0 on success, otherwise error value
 */
static int wlan_hdd_set_udp_resp_offload(hdd_adapter_t *padapter, bool enable)
{
	hdd_context_t *phddctx = WLAN_HDD_GET_CTX(padapter);
	hdd_config_t *pcfg_ini = phddctx->cfg_ini;
	struct udp_resp_offload udp_resp_cmd_info;
	VOS_STATUS status;
	uint8 udp_payload_filter_len;
	uint8 udp_response_payload_len;

	hddLog(LOG1, FL("udp_resp_offload enable flag is %d"), enable);

	/* prepare the request to send to SME */
	if ((enable == TRUE) &&
	    (pcfg_ini->udp_resp_offload_support)) {
		if (pcfg_ini->response_payload[0] != '\0') {
			udp_resp_cmd_info.vdev_id = padapter->sessionId;
			udp_resp_cmd_info.enable = 1;
			udp_resp_cmd_info.dest_port =
					pcfg_ini->dest_port;

			udp_payload_filter_len =
				strlen(pcfg_ini->payload_filter);
			hddLog(LOG2, "payload_filter[%s]",
				pcfg_ini->payload_filter);
			udp_response_payload_len =
				strlen(pcfg_ini->response_payload);
			hddLog(LOG2, "response_payload[%s]",
				pcfg_ini->response_payload);

			vos_mem_copy(udp_resp_cmd_info.udp_payload_filter,
					pcfg_ini->payload_filter,
					udp_payload_filter_len + 1);

			vos_mem_copy(udp_resp_cmd_info.udp_response_payload,
					pcfg_ini->response_payload,
					udp_response_payload_len + 1);

			status = sme_set_udp_resp_offload(&udp_resp_cmd_info);
			if (VOS_STATUS_E_FAILURE == status) {
				hddLog(VOS_TRACE_LEVEL_ERROR,
					"%s: sme_set_udp_resp_offload failure!",
					__func__);
				return -EIO;
			}
			hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
				"%s: sme_set_udp_resp_offload success!",
				__func__);
		}
	} else {
		udp_resp_cmd_info.vdev_id = padapter->sessionId;
		udp_resp_cmd_info.enable = 0;
		udp_resp_cmd_info.dest_port = 0;
		udp_resp_cmd_info.udp_payload_filter[0] = '\0';
		udp_resp_cmd_info.udp_response_payload[0] = '\0';
		status = sme_set_udp_resp_offload(&udp_resp_cmd_info);
		if (VOS_STATUS_E_FAILURE == status) {
			hddLog(VOS_TRACE_LEVEL_ERROR,
			"%s: sme_set_udp_resp_offload fialure!", __func__);
			return -EIO;
		}
		hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
			"%s: sme_set_udp_resp_offload success!", __func__);
	}
	return 0;
}
#else
static inline int wlan_hdd_set_udp_resp_offload(hdd_adapter_t *padapter,
				bool enable)
{
	return 0;
}
#endif

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) && !defined(WITH_BACKPORTS)
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)
#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;
    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;
    v_SINT_t i;
    hdd_config_t *iniConfig;
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
    tSmeConfigParams *sme_config_ptr = NULL;
    v_BOOL_t MFPCapable =  VOS_FALSE;
    v_BOOL_t MFPRequired =  VOS_FALSE;
    u_int16_t prev_rsn_length = 0;
    enum dfs_mode mode;
    int ret;
    ENTER();

    wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
    iniConfig = pHddCtx->cfg_ini;
    pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);

    clear_bit(ACS_PENDING, &pHostapdAdapter->event_flags);
    clear_bit(ACS_IN_PROGRESS, &pHddCtx->g_event_flags);

    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;

    pConfig->disableDFSChSwitch = iniConfig->disableDFSChSwitch;
    pConfig->enable_radar_war = iniConfig->enable_radar_war;

    pConfig->sap_chanswitch_beacon_cnt =
        iniConfig->sap_chanswitch_beacon_cnt;
    pConfig->sap_chanswitch_mode =
        iniConfig->sap_chanswitch_mode;

    pConfig->dfs_beacon_tx_enhanced =
        iniConfig->dfs_beacon_tx_enhanced;

    pConfig->reduced_beacon_interval =
        iniConfig->reduced_beacon_interval;
    switch (iniConfig->sub_20_channel_width) {
    case CFG_SUB_20_CHANNEL_WIDTH_DISABLE:
        pConfig->sub20_switch_mode = SUB20_NONE;
        break;
    case CFG_SUB_20_CHANNEL_WIDTH_5MHZ:
    case CFG_SUB_20_CHANNEL_WIDTH_10MHZ:
        pConfig->sub20_switch_mode = SUB20_STATIC;
        break;
    case CFG_SUB_20_CHANNEL_WIDTH_DYN_5MHZ:
    case CFG_SUB_20_CHANNEL_WIDTH_DYN_10MHZ:
    case CFG_SUB_20_CHANNEL_WIDTH_DYN_ALL:
        pConfig->sub20_switch_mode = SUB20_DYN;
        break;
    case CFG_SUB_20_CHANNEL_WIDTH_MANUAL:
        pConfig->sub20_switch_mode = SUB20_MANUAL;
        break;
    }

    pConfig->auto_channel_select_weight = iniConfig->auto_channel_select_weight;
    //channel is already set in the set_channel Call back
    //pConfig->channel = pCommitConfig->channel;

    /*Protection parameter to enable or disable*/
    pConfig->protEnabled = iniConfig->apProtEnabled;

    pConfig->dtim_period = pBeacon->dtim_period;

    hddLog(VOS_TRACE_LEVEL_INFO_HIGH, FL("acs_mode %d"),
            pConfig->acs_cfg.acs_mode);

    if (pConfig->acs_cfg.acs_mode == true) {
        hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
                FL("acs_channel %d, acs_dfs_mode %d"),
                pHddCtx->acs_policy.acs_channel,
                pHddCtx->acs_policy.acs_dfs_mode);

        if (pHddCtx->acs_policy.acs_channel)
            pConfig->channel = pHddCtx->acs_policy.acs_channel;

        mode = pHddCtx->acs_policy.acs_dfs_mode;
        pConfig->acs_dfs_mode = wlan_hdd_get_dfs_mode(mode);
    }

    hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
            FL("pConfig->channel %d, pConfig->acs_dfs_mode %d"),
            pConfig->channel, pConfig->acs_dfs_mode);

    hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
                                      pConfig->dtim_period);

    if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
    {
#ifndef QCA_HT_2040_COEX
        /*
         * Restore the channel bonding parameter to avoid
         * falling to previous SAP configuration in concurrency
         * scenarios.
         */
        tSmeConfigParams *sme_config;

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

        vos_mem_zero(sme_config, sizeof(*sme_config));
        sme_GetConfigParam(hHal, sme_config);
        sme_config->csrConfig.channelBondingMode5GHz =
                           pHddCtx->cfg_ini->nChannelBondingMode5GHz;
        sme_UpdateConfig(hHal, sme_config);
        vos_mem_free(sme_config);
#endif
        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->countryCode[0] = pHddCtx->reg.alpha2[0];
            pConfig->countryCode[1] = pHddCtx->reg.alpha2[1];
            pConfig->ieee80211d = 0;
        }

        ret = wlan_hdd_sap_cfg_dfs_override(pHostapdAdapter);
        if (ret < 0) {
            goto error;
        } else {
            if (ret == 0) {
                if (VOS_IS_DFS_CH(pConfig->channel))
                    pHddCtx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
            }
        }

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

           /* reject SAP if DFS channel scan is not allowed */
           if ((pHddCtx->cfg_ini->enableDFSChnlScan == false) &&
             (NV_CHANNEL_DFS ==
              vos_nv_getChannelEnabledState(pConfig->channel))) {
             hddLog(LOGE, FL("not allowed to start SAP on DFS channel"));
             ret = -EOPNOTSUPP;
             goto error;
          }
       }
        /*
         * Set the JAPAN W53 disabled INI param
         * in to SAP DFS for restricting these
         * channel from being picked during DFS
         * random channel selection.
         */
        WLANSAP_set_Dfs_Restrict_JapanW53(hHal,
                         iniConfig->gDisableDfsJapanW53);

        /*
         * Set the SAP Indoor/Outdoor preferred
         * operating channel location. This
         * prameter will restrict SAP picking
         * channel from only Indoor/outdoor
         * channels list only based up on the
         * this parameter.
         */
        WLANSAP_set_Dfs_Preferred_Channel_location(hHal,
                                     iniConfig->gSapPreferredChanLocation);

#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
        wlan_sap_set_channel_avoidance(hHal, iniConfig->sap_channel_avoidance);
#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
    }
    else if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
    {
       pConfig->countryCode[0] = pHddCtx->reg.alpha2[0];
       pConfig->countryCode[1] = pHddCtx->reg.alpha2[1];
       pConfig->ieee80211d = 0;
    }
    else
    {
        pConfig->ieee80211d = 0;
    }

    WLANSAP_Set_Dfs_Ignore_CAC(hHal, iniConfig->ignoreCAC);

    wlansap_set_tx_leakage_threshold(hHal,
                                     iniConfig->sap_tx_leakage_threshold);

    capab_info = pMgmt_frame->u.beacon.capab_info;

    pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
                        WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;

    (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
    {
        hddLog(LOG1, "WPS disabled");
        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))
                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)) && !defined(WITH_BACKPORTS)
    if (params->ssid != NULL)
    {
        vos_mem_copy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
        pConfig->SSIDinfo.ssid.length = params->ssid_len;

        switch (params->hidden_ssid) {
        case NL80211_HIDDEN_SSID_NOT_IN_USE:
                hddLog(LOG1, "HIDDEN_SSID_NOT_IN_USE");
                pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_NOT_IN_USE;
                break;
        case NL80211_HIDDEN_SSID_ZERO_LEN:
                hddLog(LOG1, "HIDDEN_SSID_ZERO_LEN");
                pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_ZERO_LEN;
                break;
        case NL80211_HIDDEN_SSID_ZERO_CONTENTS:
                hddLog(LOG1, "HIDDEN_SSID_ZERO_CONTENTS");
                pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_ZERO_CONTENTS;
                break;
        default:
                hddLog(LOGE, "Wrong hidden_ssid param %d", params->hidden_ssid);
                break;
        }
    }
#else
    if (ssid != NULL)
    {
        vos_mem_copy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
        pConfig->SSIDinfo.ssid.length = ssid_len;

        switch (hidden_ssid) {
        case NL80211_HIDDEN_SSID_NOT_IN_USE:
                hddLog(LOG1, "HIDDEN_SSID_NOT_IN_USE");
                pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_NOT_IN_USE;
                break;
        case NL80211_HIDDEN_SSID_ZERO_LEN:
                hddLog(LOG1, "HIDDEN_SSID_ZERO_LEN");
                pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_ZERO_LEN;
                break;
        case NL80211_HIDDEN_SSID_ZERO_CONTENTS:
                hddLog(LOG1, "HIDDEN_SSID_ZERO_CONTENTS");
                pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_ZERO_CONTENTS;
                break;
        default:
                hddLog(LOGE, "Wrong hidden_ssid param %d", hidden_ssid);
                break;
        }
    }
#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;
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
    /*
     * We don't want P2PGO to follow STA's channel
     * so lets limit the logic for SAP only.
     * Later if we decide to make p2pgo follow STA's
     * channel then remove this check.
     */
    if ((0 == pHddCtx->cfg_ini->conc_custom_rule1) ||
        (pHddCtx->cfg_ini->conc_custom_rule1 &&
         WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)) {
        pConfig->cc_switch_mode = iniConfig->WlanMccToSccSwitchMode;
        pConfig->band_switch_enable = iniConfig->wlan_band_switch_enable;
        pConfig->ap_p2pclient_concur_enable =
                iniConfig->wlan_ap_p2pclient_conc_enable;
    }
#endif

    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++;
        }
    }
    if (!pHddCtx->cfg_ini->force_sap_acs) {
        pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
                pBeacon->head_len, WLAN_EID_SUPP_RATES);
        if (pIe != NULL) {
            pIe++;
            pConfig->supported_rates.numRates = pIe[0];
            pIe++;
            for (i = 0; i < pConfig->supported_rates.numRates; i++)
                if (pIe[i]) {
                    pConfig->supported_rates.rate[i]= pIe[i];
                    hddLog(LOG1, FL("Configured Supported rate is %2x"),
                            pConfig->supported_rates.rate[i]);
                }
        }
        pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
                WLAN_EID_EXT_SUPP_RATES);
        if (pIe != NULL) {
            pIe++;
            pConfig->extended_rates.numRates = pIe[0];
            pIe++;
            for (i = 0; i < pConfig->extended_rates.numRates; i++)
                if (pIe[i]) {
                    pConfig->extended_rates.rate[i]= pIe[i];
                    hddLog(LOG1,
                            FL("Configured extended Supported rate is %2x"),
                            pConfig->extended_rates.rate[i]);
                }
        }
    }

    wlan_hdd_set_sapHwmode(pHostapdAdapter);

    if (pHddCtx->cfg_ini->sap_force_11n_for_11ac) {
        if (pConfig->SapHw_mode == eCSR_DOT11_MODE_11ac ||
            pConfig->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY)
            pConfig->SapHw_mode = eCSR_DOT11_MODE_11n;
        }

    /* Override hostapd.conf wmm_enabled only for 11n and 11AC configs (IOT)
     * As per spec 11n/11AC STA are QOS STA and may not connect to nonQOS 11n AP
     * Default enable QOS for SAP
     */
    sme_config_ptr = vos_mem_malloc(sizeof(*sme_config_ptr));
    if (!sme_config_ptr) {
        hddLog(LOGE, FL("memory allocation failed for sme_config"));
        return -ENOMEM;
    }
    vos_mem_zero(sme_config_ptr, sizeof(tSmeConfigParams));
    sme_GetConfigParam(pHddCtx->hHal, sme_config_ptr);
    sme_config_ptr->csrConfig.WMMSupportMode = eCsrRoamWmmAuto;

    pIe = wlan_hdd_get_vendor_oui_ie_ptr(WMM_OUI_TYPE, WMM_OUI_TYPE_SIZE,
                                         pBeacon->tail, pBeacon->tail_len);
    if (!pIe && (pConfig->SapHw_mode == eCSR_DOT11_MODE_11a ||
                 pConfig->SapHw_mode == eCSR_DOT11_MODE_11g ||
                 pConfig->SapHw_mode == eCSR_DOT11_MODE_11b))
        sme_config_ptr->csrConfig.WMMSupportMode = eCsrRoamWmmNoQos;
    sme_UpdateConfig(pHddCtx->hHal, sme_config_ptr);

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) && !defined(WITH_BACKPORTS)
    /* Linux kernel < 3.8 does not support ch width param. So for
     * 11AC get from ch width from ini file only if ht40 is enabled.
     * VHT80 depends on HT40 config.
     */
    if (pConfig->SapHw_mode == eCSR_DOT11_MODE_11ac)
        if (pConfig->ch_width_orig == NL80211_CHAN_WIDTH_40)
            pConfig->ch_width_orig = iniConfig->vhtChannelWidth;
#endif

    if (pConfig->ch_width_orig == NL80211_CHAN_WIDTH_80 &&
        !pHddCtx->cfg_ini->sap_force_11n_for_11ac) {
        if (pHddCtx->isVHT80Allowed == false)
            pConfig->ch_width_orig = eHT_CHANNEL_WIDTH_40MHZ;
        else
            pConfig->ch_width_orig = eHT_CHANNEL_WIDTH_80MHZ;
    } else if (pConfig->ch_width_orig == NL80211_CHAN_WIDTH_40)
        pConfig->ch_width_orig = eHT_CHANNEL_WIDTH_40MHZ;
    else
        pConfig->ch_width_orig = eHT_CHANNEL_WIDTH_20MHZ;

    if (wlan_hdd_setup_driver_overrides(pHostapdAdapter)) {
        ret = -EINVAL;
        goto error;
    }

#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
    pConfig->ch_width_24g_orig = iniConfig->nChannelBondingMode24GHz ?
        eHT_CHANNEL_WIDTH_40MHZ : eHT_CHANNEL_WIDTH_20MHZ;
    pConfig->ch_width_5g_orig = iniConfig->vhtChannelWidth;
#endif

    // ht_capab is not what the name conveys,this is used for protection bitmap
    pConfig->ht_capab = iniConfig->apProtection;

    if (0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
    {
        hddLog(LOGE, FL("SAP Not able to set AP IEs"));
        WLANSAP_ResetSapConfigAddIE(pConfig, eUPDATE_IE_ALL);
        ret = -EINVAL;
        goto error;
    }

    //Uapsd Enabled Bit
    pConfig->UapsdEnable = iniConfig->apUapsdEnabled;
    //Enable OBSS protection
    pConfig->obssProtEnabled = iniConfig->apOBSSProtEnabled;

    if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
        pConfig->sap_dot11mc = iniConfig->sap_dot11mc;
    } else { /* for P2P-Go case */
        pConfig->sap_dot11mc = 1;
    }
    hddLog(LOG1, FL("11MC Support Enabled : %d\n"),
           pConfig->sap_dot11mc);

#ifdef WLAN_FEATURE_11W
    pConfig->mfpCapable = MFPCapable;
    pConfig->mfpRequired = MFPRequired;
    hddLog(LOG1, 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))
    {
        WLANSAP_ResetSapConfigAddIE(pConfig, eUPDATE_IE_ALL);
        //Bss already started. just return.
        //TODO Probably it should update some beacon params.
        vos_mem_free(sme_config_ptr);
        hddLog( LOGE, "Bss Already started...Ignore the request");
        EXIT();
        return 0;
    }

    if (vos_max_concurrent_connections_reached()) {
        hddLog(VOS_TRACE_LEVEL_DEBUG, FL("Reached max concurrent connections"));
        ret = -EINVAL;
        goto error;
    }

    pConfig->persona = pHostapdAdapter->device_mode;

    pSapEventCallback = hdd_hostapd_SAPEventCB;

    (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->dfs_cac_block_tx = VOS_TRUE;

    /* Set ANTENNA_MODE_2X2 before starting SAP/GO */
    if (pHddCtx->cfg_ini->enable_dynamic_sta_chainmask)
       hdd_decide_dynamic_chain_mask(pHddCtx, HDD_ANTENNA_MODE_2X2);

    set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);

    vos_event_reset(&pHostapdState->vosEvent);
    status = WLANSAP_StartBss(
#ifdef WLAN_FEATURE_MBSSID
                 WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
#else
                 pVosContext,
#endif
                 pSapEventCallback, pConfig, (v_PVOID_t)pHostapdAdapter->dev);
    if (!VOS_IS_STATUS_SUCCESS(status))
    {
        WLANSAP_ResetSapConfigAddIE(pConfig, eUPDATE_IE_ALL);
        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);

    WLANSAP_ResetSapConfigAddIE(pConfig, eUPDATE_IE_ALL);

    if (!VOS_IS_STATUS_SUCCESS(status) ||
        pHostapdState->vosStatus != VOS_STATUS_SUCCESS)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 ("%s: ERROR: HDD vos wait for single_event failed!!"),
                 __func__);
        smeGetCommandQStatus(hHal);
#ifdef WLAN_FEATURE_MBSSID
        WLANSAP_StopBss(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter));
#else
        WLANSAP_StopBss(pHddCtx->pvosContext);
#endif
        VOS_ASSERT(0);
        ret = -EINVAL;
        goto error;
    }

    /* Successfully started Bss update the state bit. */
    set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
    /* Disable runtime PM if obss protection is enabled */
    if (pConfig->obssProtEnabled)
        vos_runtime_pm_prevent_suspend(pHddCtx->runtime_context.obss);

    /* 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->enableDHCPServerOffload) {
        wlan_hdd_set_dhcp_server_offload(pHostapdAdapter);
        wlan_hdd_set_mdns_offload(pHostapdAdapter);
    }
#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_unsafe_channel_restart_sap(pHddCtx);

    pHostapdState->bCommit = TRUE;
    vos_mem_free(sme_config_ptr);
    EXIT();

   return 0;

error:
    vos_mem_free(sme_config_ptr);
    clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
    if (pHostapdAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list) {
        vos_mem_free(pHostapdAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list);
        pHostapdAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list = NULL;
    }
    /* Decide antenna_mode on SAP start failure */
    if (pHddCtx->cfg_ini->enable_dynamic_sta_chainmask)
       hdd_decide_dynamic_chain_mask(pHddCtx, HDD_ANTENNA_MODE_INVALID);

    return ret;
}

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) && !defined(WITH_BACKPORTS)
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(LOG2, FL("Device mode %s(%d)"),
           hdd_device_mode_to_string(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_FTM_MODE == hdd_get_conparam()) {
        hddLog(LOGE, FL("Command not allowed in FTM mode"));
        return -EINVAL;
    }

    if (vos_max_concurrent_connections_reached()) {
        hddLog(VOS_TRACE_LEVEL_DEBUG, FL("Reached max concurrent connections"));
        return -EINVAL;
    }
    if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
        hdd_adapter_t  *pP2pAdapter = NULL;
        pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
        if (pP2pAdapter) {
            hddLog(VOS_TRACE_LEVEL_DEBUG,
                FL("cancel active p2p device ROC before GO starting"));
            wlan_hdd_cancel_existing_remain_on_channel(pP2pAdapter);
        }
    }

    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,
                    FL("Error!!! Allocating the new beacon"));
             return -EINVAL;
        }

        pAdapter->sessionCtx.ap.beacon = new;

        status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
        if (0 != status) {
           pAdapter->sessionCtx.ap.beacon = NULL;
           kfree(new);
        }
    }

    EXIT();
    return status;
}

/**
 * wlan_hdd_cfg80211_add_beacon() - add beacon in sap mode
 * @wiphy: Pointer to wiphy
 * @dev: Pointer to netdev
 * @param: Pointer to beacon parameters
 *
 * Return: zero for success non-zero for failure
 */
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(LOG1, FL("Device_mode %s(%d)"),
           hdd_device_mode_to_string(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_FTM_MODE == hdd_get_conparam()) {
        hddLog(LOGE, FL("Command not allowed in FTM mode"));
        return -EINVAL;
    }
    if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
        hdd_adapter_t  *pP2pAdapter = NULL;
        pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
        if (pP2pAdapter) {
            hddLog(VOS_TRACE_LEVEL_DEBUG,
                FL("cancel active p2p device ROC before GO starting"));
            wlan_hdd_cancel_existing_remain_on_channel(pP2pAdapter);
        }
    }

    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(LOGE,
                   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,
                   FL("Error!!! Allocating the new beacon"));
            return -EINVAL;
        }

        pAdapter->sessionCtx.ap.beacon = new;
        status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
    }

    EXIT();
    return status;
}
/**
 * wlan_hdd_cfg80211_set_beacon() - set beacon in sap mode
 * @wiphy: Pointer to wiphy
 * @dev: Pointer to netdev
 * @param: Pointer to beacon parameters
 *
 * Return: zero for success non-zero for failure
 */
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)) &&
          !defined(WITH_BACKPORTS) */

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(WITH_BACKPORTS)
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);
    tHalHandle hal_ptr = WLAN_HDD_GET_HAL_CTX(pAdapter);
    tpAniSirGlobal mac_ptr = PMAC_STRUCT(hal_ptr);
    hdd_context_t  *pHddCtx    = NULL;
    hdd_scaninfo_t *pScanInfo  = NULL;
    hdd_adapter_t  *staAdapter = NULL;
    VOS_STATUS      status     = VOS_STATUS_E_FAILURE;
    tSirUpdateIE    updateIE;
    beacon_data_t  *old;
    int             ret = 0;
    unsigned long   rc;
    hdd_adapter_list_node_t *pAdapterNode = NULL;
    hdd_adapter_list_node_t *pNext        = NULL;
    uint8_t i, zeros[18] = {0};
    uint32_t hostapd_edca_local[] = {WNI_CFG_EDCA_HOSTAPD_ACVO_LOCAL,
                                     WNI_CFG_EDCA_HOSTAPD_ACVI_LOCAL,
                                     WNI_CFG_EDCA_HOSTAPD_ACBE_LOCAL,
                                     WNI_CFG_EDCA_HOSTAPD_ACBK_LOCAL};

    ENTER();

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

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

    if (!(pAdapter->device_mode == WLAN_HDD_SOFTAP ||
          pAdapter->device_mode == WLAN_HDD_P2P_GO)) {
        return -EOPNOTSUPP;
    }

    hddLog(LOG1, FL("Device_mode %s(%d)"),
           hdd_device_mode_to_string(pAdapter->device_mode),
           pAdapter->device_mode);

    if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
        hdd_wlan_green_ap_stop_bss(pHddCtx);

    if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
        (pHddCtx->cfg_ini->enable_hostapd_edca_local)) {
        for (i = 0; i < 4; ++i)
            cfgSetStr(mac_ptr, hostapd_edca_local[i], zeros, 18);
    }

    status = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
    while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
        staAdapter = pAdapterNode->pAdapter;

        if (WLAN_HDD_INFRA_STATION == staAdapter->device_mode ||
           (WLAN_HDD_P2P_CLIENT == staAdapter->device_mode) ||
           (WLAN_HDD_P2P_GO == staAdapter->device_mode)) {
            pScanInfo = &staAdapter->scan_info;

            if (pScanInfo && pScanInfo->mScanPending) {
               hddLog(LOG1, FL("Aborting pending scan for device mode:%d"),
                      staAdapter->device_mode);
               INIT_COMPLETION(pScanInfo->abortscan_event_var);
               hdd_abort_mac_scan(staAdapter->pHddCtx, staAdapter->sessionId,
                                  eCSR_SCAN_ABORT_DEFAULT);
               rc = wait_for_completion_timeout(
                     &pScanInfo->abortscan_event_var,
                     msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
               if (!rc) {
                   hddLog(LOGE,
                          FL("Timeout occurred while waiting for abortscan"));
                   VOS_ASSERT(pScanInfo->mScanPending);
               }
            }
        }

        status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
        pAdapterNode = pNext;
    }
    /*
     * When ever stop ap adapter gets called, we need to check
     * whether any restart AP work is pending. If any restart is pending
     * then lets finish it and go ahead from there.
     */
    if (pHddCtx->cfg_ini->conc_custom_rule1 &&
        (WLAN_HDD_SOFTAP == pAdapter->device_mode)) {
        vos_flush_work(&pHddCtx->sap_start_work);
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                  FL("Canceled the pending restart work"));
        hdd_change_ch_avoidance_status(pHddCtx, false);
        hdd_change_sap_restart_required_status(pHddCtx, false);
    }

    pAdapter->sessionCtx.ap.sapConfig.acs_cfg.acs_mode = false;
    wlan_hdd_undo_acs(pAdapter);

    vos_mem_zero(&pAdapter->sessionCtx.ap.sapConfig.acs_cfg,
                                                    sizeof(struct sap_acs_cfg));

    hdd_hostapd_stop(dev);

    old = pAdapter->sessionCtx.ap.beacon;
    if (!old) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("Session(%d) beacon data points to NULL"),
               pAdapter->sessionId);
        return -EINVAL;
    }

    hdd_cleanup_actionframe(pHddCtx, pAdapter);
    wlan_hdd_cleanup_remain_on_channel_ctx(pAdapter);

    mutex_lock(&pHddCtx->sap_lock);
    if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags)) {
        hdd_hostapd_state_t *pHostapdState =
                    WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);

        vos_event_reset(&pHostapdState->stop_bss_event);
#ifdef WLAN_FEATURE_MBSSID
        status = WLANSAP_StopBss(WLAN_HDD_GET_SAP_CTX_PTR(pAdapter));
#else
        status = WLANSAP_StopBss(pHddCtx->pvosContext);
#endif
        if (VOS_IS_STATUS_SUCCESS(status)) {
            status = vos_wait_single_event(&pHostapdState->stop_bss_event,
                                           10000);
            if (!VOS_IS_STATUS_SUCCESS(status)) {
                hddLog(VOS_TRACE_LEVEL_ERROR,
                       FL("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);

        pAdapter->sessionCtx.ap.beacon = NULL;
        kfree(old);
    }
    mutex_unlock(&pHddCtx->sap_lock);

    if (pHddCtx->cfg_ini->enable_dynamic_sta_chainmask)
       hdd_decide_dynamic_chain_mask(pHddCtx, HDD_ANTENNA_MODE_INVALID);
    if (pHddCtx->cfg_ini->apOBSSProtEnabled)
        vos_runtime_pm_allow_suspend(pHddCtx->runtime_context.obss);

    if (status != VOS_STATUS_SUCCESS) {
        hddLog(VOS_TRACE_LEVEL_FATAL, FL("Stopping the BSS"));
        return -EINVAL;
    }

    vos_mem_copy(updateIE.bssid, pAdapter->macAddressCurrent.bytes,
          sizeof(tSirMacAddr));
    updateIE.smeSessionId = pAdapter->sessionId;
    updateIE.ieBufferlength = 0;
    updateIE.pAdditionIEBuffer = NULL;
    updateIE.append = VOS_TRUE;
    updateIE.notify = VOS_TRUE;
    if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pAdapter),
              &updateIE, eUPDATE_IE_PROBE_BCN) == eHAL_STATUS_FAILURE) {
        hddLog(LOGE, FL("Could not pass on PROBE_RSP_BCN data to PE"));
    }

    if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pAdapter),
              &updateIE, eUPDATE_IE_ASSOC_RESP) == eHAL_STATUS_FAILURE) {
        hddLog(LOGE, FL("Could not pass on ASSOC_RSP data to PE"));
    }

    // Reset WNI_CFG_PROBE_RSP Flags
    wlan_hdd_reset_prob_rspies(pAdapter);
    clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);

#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 ret;
}

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(WITH_BACKPORTS)
/**
 * wlan_hdd_cfg80211_del_beacon() - delete beacon in sap mode
 * @wiphy: Pointer to wiphy
 * @dev: Pointer to netdev
 *
 * Return: zero for success non-zero for failure
 */
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
/**
 * wlan_hdd_cfg80211_stop_ap() - stop sap
 * @wiphy: Pointer to wiphy
 * @dev: Pointer to netdev
 *
 * Return: zero for success non-zero for failure
 */
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(4, 8, 0)) || \
	defined(CFG80211_BEACON_TX_RATE_CUSTOM_BACKPORT)
/**
 * hdd_get_data_rate_from_rate_mask() - convert mask to rate
 * @wiphy: Pointer to wiphy
 * @band: band
 * @bit_rate_mask: pointer to bit_rake_mask
 *
 * This function takes band and bit_rate_mask as input and
 * derives the beacon_tx_rate based on the supported rates
 * published as part of wiphy register.
 *
 * Return: zero for data rate on success or 0 on failure
 */
uint16_t hdd_get_data_rate_from_rate_mask(struct wiphy *wiphy,
		enum ieee80211_band band,
		struct cfg80211_bitrate_mask *bit_rate_mask)
{
	struct ieee80211_supported_band *sband = wiphy->bands[band];
	int sband_n_bitrates;
	struct ieee80211_rate *sband_bitrates;
	int i;

	if (sband) {
		sband_bitrates = sband->bitrates;
		sband_n_bitrates = sband->n_bitrates;
		for (i = 0; i < sband_n_bitrates; i++) {
			if (bit_rate_mask->control[band].legacy ==
				sband_bitrates[i].hw_value) {
				return sband_bitrates[i].bitrate;
			}
		}
	}
	return 0;
}

/**
 * hdd_update_beacon_rate() - Update beacon tx rate
 * @pAdapter: Pointer to hdd_adapter_t
 * @wiphy: Pointer to wiphy
 * @params: Pointet to cfg80211_ap_settings
 *
 * This function updates the beacon tx rate which is provided
 * as part of cfg80211_ap_settions in to the sapConfig
 * structure
 *
 * Return: zero for data rate on success or 0 on failure
 */
void hdd_update_beacon_rate(hdd_adapter_t *pAdapter, struct wiphy *wiphy,
		struct cfg80211_ap_settings *params)
{
	struct cfg80211_bitrate_mask *beacon_rate_mask;
	enum ieee80211_band band;

	band = params->chandef.chan->band;
	beacon_rate_mask = &params->beacon_rate;
	if (beacon_rate_mask->control[band].legacy) {
		pAdapter->sessionCtx.ap.sapConfig.beacon_tx_rate =
			hdd_get_data_rate_from_rate_mask(wiphy, band,
					beacon_rate_mask);
		hddLog(VOS_TRACE_LEVEL_INFO,
				FL("beacon mask value %u, rate %hu"),
				params->beacon_rate.control[0].legacy,
				pAdapter->sessionCtx.ap.sapConfig.beacon_tx_rate);
	}
}
#else
void hdd_update_beacon_rate(hdd_adapter_t *pAdapter, struct wiphy *wiphy,
		struct cfg80211_ap_settings *params)
{
}
#endif

#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0)) || defined(WITH_BACKPORTS)

static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
                                      struct net_device *dev,
                                      struct cfg80211_ap_settings *params)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    uint8_t channel;
    uint32_t channel_width;
    hdd_context_t *pHddCtx;
    int            status;
    ENTER();

    clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
    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;
    }

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

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

    hddLog(LOG2, FL("pAdapter = %pK, device mode %s(%d)"),
           pAdapter, hdd_device_mode_to_string(pAdapter->device_mode),
           pAdapter->device_mode);

    if (vos_max_concurrent_connections_reached()) {
        hddLog(VOS_TRACE_LEVEL_DEBUG, FL("Reached max concurrent connections"));
        return -EINVAL;
    }

    if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
        hdd_wlan_green_ap_start_bss(pHddCtx);

    channel_width = params->chandef.width;
    channel = ieee80211_frequency_to_channel(
                  params->chandef.chan->center_freq);

    /* Avoid ACS/DFS, and overwrite channel width to 20 */
    if (hdd_cfg_is_sub20_channel_width_enabled(pHddCtx)) {
            bool channel_support_sub20 = true;
            tSmeConfigParams sme_config;
            uint8_t sub20_config;
            uint8_t sub20_dyn_channelwidth = 0;
            uint8_t sub20_static_channelwidth = 0;
            uint8_t sub20_channelwidth = 0;
            enum phy_ch_width phy_sub20_channel_width = CH_WIDTH_INVALID;

            vos_mem_zero(&sme_config, sizeof(sme_config));
            sme_GetConfigParam(pHddCtx->hHal, &sme_config);
            sub20_config = sme_config.sub20_config_info;

            switch (sub20_config) {
            case CFG_SUB_20_CHANNEL_WIDTH_5MHZ:
                sub20_static_channelwidth = SUB20_MODE_5MHZ;
                break;
            case CFG_SUB_20_CHANNEL_WIDTH_10MHZ:
                sub20_static_channelwidth = SUB20_MODE_10MHZ;
                break;
            case CFG_SUB_20_CHANNEL_WIDTH_DYN_5MHZ:
                sub20_dyn_channelwidth = SUB20_MODE_5MHZ;
                break;
            case CFG_SUB_20_CHANNEL_WIDTH_DYN_10MHZ:
                sub20_dyn_channelwidth = SUB20_MODE_10MHZ;
                break;
            case CFG_SUB_20_CHANNEL_WIDTH_DYN_ALL:
                sub20_dyn_channelwidth = SUB20_MODE_5MHZ | SUB20_MODE_10MHZ;
                break;
            default:
                break;
            }

            if (channel == 0) {
                    hddLog(VOS_TRACE_LEVEL_WARN,
                           FL("Can't start SAP-ACS with sub20 channel width"));
                    return -EINVAL;
            }

            if (CSR_IS_CHANNEL_DFS(channel)) {
                    hddLog(VOS_TRACE_LEVEL_WARN,
                           FL("Can't start SAP-DFS with sub20 channel width"));
                    return -EINVAL;
            }

            if (channel_width != NL80211_CHAN_WIDTH_20 &&
                channel_width != NL80211_CHAN_WIDTH_20_NOHT) {
                    hddLog(VOS_TRACE_LEVEL_WARN,
                           FL("Hostapd (20+MHz) conflicts config.ini(sub20)"));
                    return -EINVAL;
            }

            switch (sub20_config) {
            case CFG_SUB_20_CHANNEL_WIDTH_5MHZ:
            case CFG_SUB_20_CHANNEL_WIDTH_10MHZ:
            case CFG_SUB_20_CHANNEL_WIDTH_DYN_5MHZ:
            case CFG_SUB_20_CHANNEL_WIDTH_DYN_10MHZ:
                sub20_channelwidth = (sub20_static_channelwidth != 0) ?
                        sub20_static_channelwidth : sub20_dyn_channelwidth;
                phy_sub20_channel_width =
                        (sub20_channelwidth == SUB20_MODE_5MHZ) ?
                            CH_WIDTH_5MHZ : CH_WIDTH_10MHZ;
                channel_support_sub20 =
                        vos_is_channel_support_sub20(channel,
                                                     phy_sub20_channel_width,
                                                     0);
                if (!channel_support_sub20) {
                        hddLog(VOS_TRACE_LEVEL_ERROR,
                               FL("ch%dwidth%d unsupport by reg domain"),
                               channel, phy_sub20_channel_width);
                        return -EINVAL;
                }
                break;
            case CFG_SUB_20_CHANNEL_WIDTH_DYN_ALL:
                channel_support_sub20 =
                    vos_is_channel_support_sub20(channel, CH_WIDTH_5MHZ, 0);
                if (!channel_support_sub20) {
                        hddLog(VOS_TRACE_LEVEL_ERROR,
                               FL("ch%dwidth5M unsupport by reg domain"),
                               channel);
                        sub20_dyn_channelwidth &= ~SUB20_MODE_5MHZ;
                }

                channel_support_sub20 =
                    vos_is_channel_support_sub20(channel, CH_WIDTH_10MHZ, 0);
                if (!channel_support_sub20) {
                        hddLog(VOS_TRACE_LEVEL_ERROR,
                               FL("ch%dwidth10M unsupport by reg domain"),
                               channel);
                        sub20_dyn_channelwidth &= ~SUB20_MODE_10MHZ;
                }

                if (sub20_dyn_channelwidth == 0) {
                        return -EINVAL;
                } else {
                        sme_config.sub20_dynamic_channelwidth =
                                 sub20_dyn_channelwidth;
                        sme_UpdateConfig(pHddCtx->hHal, &sme_config);
                }
                break;
            default:
                break;
            }
    }

    if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
        hdd_adapter_t  *pP2pAdapter = NULL;
        pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
        if (pP2pAdapter) {
            hddLog(VOS_TRACE_LEVEL_DEBUG,
                FL("cancel active p2p device ROC before GO starting"));
            wlan_hdd_cancel_existing_remain_on_channel(pP2pAdapter);
        }
    }

    if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
      || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
       )
    {
        beacon_data_t  *old, *new;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)) || defined(WITH_BACKPORTS)
        enum nl80211_channel_type channel_type;
#endif
        old = pAdapter->sessionCtx.ap.beacon;

        if (old)
            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,8,0)) || defined(WITH_BACKPORTS)
        if (params->chandef.width < NL80211_CHAN_WIDTH_80)
            channel_type = cfg80211_get_chandef_type(&(params->chandef));
        else
            channel_type = NL80211_CHAN_HT40PLUS;
#endif

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) || defined(WITH_BACKPORTS)
        wlan_hdd_cfg80211_set_channel(wiphy, dev,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) && !defined(WITH_BACKPORTS)
        params->channel, params->channel_type);
#else
        params->chandef.chan, channel_type);
#endif
#endif

        hdd_update_beacon_rate(pAdapter, wiphy, params);

        /* set authentication type */
        switch ( params->auth_type )
        {
        case  NL80211_AUTHTYPE_OPEN_SYSTEM:
            pAdapter->sessionCtx.ap.sapConfig.authType = eSAP_OPEN_SYSTEM;
            break;
        case NL80211_AUTHTYPE_SHARED_KEY:
            pAdapter->sessionCtx.ap.sapConfig.authType = eSAP_SHARED_KEY;
            break;
        default:
            pAdapter->sessionCtx.ap.sapConfig.authType = eSAP_AUTO_SWITCH;
        }

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)) || defined(WITH_BACKPORTS)
        pAdapter->sessionCtx.ap.sapConfig.ch_width_orig =
                                             params->chandef.width;
#endif

        status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
                                             params->ssid_len, params->hidden_ssid);
        if (status == 0) {
            if (0 != wlan_hdd_set_udp_resp_offload(pAdapter, TRUE)) {
                hddLog(VOS_TRACE_LEVEL_ERROR, "%s: set udp resp cmd failed %d",
                        __func__, status);
            }
        }
        hdd_change_ch_avoidance_status(pHddCtx, false);
        if (pHddCtx->cfg_ini->sap_max_inactivity_override)
            sme_update_sta_inactivity_timeout(WLAN_HDD_GET_HAL_CTX(pAdapter),
                    pAdapter->sessionId, params->inactivity_timeout);
    }

    EXIT();
    return status;
}

/**
 * wlan_hdd_cfg80211_start_ap() - start sap
 * @wiphy: Pointer to wiphy
 * @dev: Pointer to netdev
 * @params: Pointer to start ap configuration parameters
 *
 * Return: zero for success non-zero for failure
 */
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;
}
#endif


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;
    beacon_data_t *old,*new;
    int status;

    ENTER();

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
                     pAdapter->sessionId, pAdapter->device_mode));
    hddLog(LOG1, FL("Device_mode %s(%d)"),
           hdd_device_mode_to_string(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_FTM_MODE == hdd_get_conparam()) {
        hddLog(LOGE, FL("Command not allowed in FTM mode"));
        return -EINVAL;
    }

    if (!(pAdapter->device_mode == WLAN_HDD_SOFTAP ||
          pAdapter->device_mode == WLAN_HDD_P2P_GO)) {
        return -EOPNOTSUPP;
    }
    if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
        hdd_adapter_t  *pP2pAdapter = NULL;
        pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
        if (pP2pAdapter) {
            hddLog(VOS_TRACE_LEVEL_DEBUG,
                FL("cancel active p2p device ROC before GO starting"));
            wlan_hdd_cancel_existing_remain_on_channel(pP2pAdapter);
        }
    }

    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 -EINVAL;
    }

    status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);

    if (status != VOS_STATUS_SUCCESS) {
        hddLog(VOS_TRACE_LEVEL_FATAL, FL("new beacon alloc failed"));
        return -EINVAL;
    }

    pAdapter->sessionCtx.ap.beacon = new;
    status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);

    EXIT();
    return status;
}
/**
 * wlan_hdd_cfg80211_change_beacon() - change beacon content in sap mode
 * @wiphy: Pointer to wiphy
 * @dev: Pointer to netdev
 * @params: Pointer to change beacon parameters
 *
 * Return: zero for success non-zero for failure
 */
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;
}

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 = WLAN_HDD_GET_CTX(pAdapter);
    int ret = 0;
    eHalStatus halStatus;

    ENTER();

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
                     pAdapter->sessionId, params->ap_isolate));
    hddLog(LOG1, FL("Device_mode %s(%d), ap_isolate = %d"),
           hdd_device_mode_to_string(pAdapter->device_mode),
           pAdapter->device_mode, params->ap_isolate);

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

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

    if (!(pAdapter->device_mode == WLAN_HDD_SOFTAP ||
          pAdapter->device_mode == WLAN_HDD_P2P_GO)) {
        return -EOPNOTSUPP;
    }

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

        halStatus = sme_ApDisableIntraBssFwd(pHddCtx->hHal,
                    pAdapter->sessionId,
                    pAdapter->sessionCtx.ap.apDisableIntraBssFwd);
        if (!HAL_STATUS_SUCCESS(halStatus)) {
            ret = -EINVAL;
        }
    }

    EXIT();
    return ret;
}

/**
 * wlan_hdd_change_client_iface_to_new_mode() - to change iface to provided mode
 * @ndev: pointer to net device provided by supplicant
 * @type: type of the interface, upper layer wanted to change
 *
 * Upper layer provides the new interface mode that needs to be changed
 * for given net device
 *
 * Return: success or failure in terms of integer value
 */
static int wlan_hdd_change_client_iface_to_new_mode(struct net_device *ndev,
                                                    enum nl80211_iftype type)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(ndev);
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    hdd_config_t *config = pHddCtx->cfg_ini;
    hdd_wext_state_t *wext;
    struct wireless_dev *wdev;
    VOS_STATUS status;

    ENTER();

    if (test_bit(ACS_IN_PROGRESS, &pHddCtx->g_event_flags))
    {
        hddLog(LOG1, FL("ACS is in progress, don't change iface!"));
        return 0;
    }

    wdev = ndev->ieee80211_ptr;
    hdd_stop_adapter(pHddCtx, pAdapter, VOS_TRUE);
    hdd_deinit_adapter(pHddCtx, pAdapter, true);
    wdev->iftype = type;
    /*Check for sub-string p2p to confirm its a p2p interface*/
    if (NULL != strnstr(ndev->name, "p2p", 3)) {
        pAdapter->device_mode =
                        (type == NL80211_IFTYPE_STATION)?
                                     WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
    } else if (type == NL80211_IFTYPE_ADHOC) {
        pAdapter->device_mode = WLAN_HDD_IBSS;
    } 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);
    status = hdd_init_station_mode(pAdapter);
    wext = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    wext->roamProfile.pAddIEScan = pAdapter->scan_info.scanAddIE.addIEdata;
    wext->roamProfile.nAddIEScanLength = pAdapter->scan_info.scanAddIE.length;
    if (type == NL80211_IFTYPE_ADHOC) {
        wext->roamProfile.BSSType = eCSR_BSS_TYPE_START_IBSS;
        wext->roamProfile.phyMode =
            hdd_cfg_xlate_to_csr_phy_mode(config->dot11Mode);
    }
    EXIT();

    return vos_status_to_os_return(status);
}

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 country 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)
 */
static 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;
    tCsrRoamProfile *pRoamProfile = NULL;
    eCsrRoamBssType LastBSSType;
    hdd_config_t *pConfig = NULL;
    unsigned long rc;
    VOS_STATUS vstatus;
    eHalStatus hstatus;
    int status;

    ENTER();

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

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

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
                     pAdapter->sessionId, type));

    hddLog(LOG1, FL("Device_mode %s(%d), IFTYPE = 0x%x"),
           hdd_device_mode_to_string(pAdapter->device_mode),
           pAdapter->device_mode, type);

    if (vos_max_concurrent_connections_reached()) {
        hddLog(VOS_TRACE_LEVEL_DEBUG, FL("Reached max concurrent connections"));
        return -EINVAL;
    }

    pConfig = pHddCtx->cfg_ini;
    wdev = ndev->ieee80211_ptr;

    /* Reset the current device mode bit mask */
    wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);

    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) ||
        (pAdapter->device_mode == WLAN_HDD_IBSS)) {
        hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);

        pRoamProfile = &pWextState->roamProfile;
        LastBSSType = pRoamProfile->BSSType;

        switch (type) {
        case NL80211_IFTYPE_STATION:
        case NL80211_IFTYPE_P2P_CLIENT:
        case NL80211_IFTYPE_ADHOC:
           if (type == NL80211_IFTYPE_ADHOC) {
               wlan_hdd_tdls_exit(pAdapter);
               wlan_hdd_clean_tx_flow_control_timer(pHddCtx, pAdapter);
               hddLog(LOG1, FL("Setting interface Type to ADHOC"));
           }
           status = wlan_hdd_change_client_iface_to_new_mode(ndev, type);
           if (status != 0)
               return status;

#ifdef QCA_LL_TX_FLOW_CT
           if (pAdapter->tx_flow_timer_initialized == VOS_FALSE) {
              vos_timer_init(&pAdapter->tx_flow_control_timer,
                             VOS_TIMER_TYPE_SW,
                             hdd_tx_resume_timer_expired_handler,
                             pAdapter);
              pAdapter->tx_flow_timer_initialized = VOS_TRUE;
           }

           /*
            * for ibss interface type flow control is not required
            * so don't register tx flow control
            */
           if (type != NL80211_IFTYPE_ADHOC)
                WLANTL_RegisterTXFlowControl(pHddCtx->pvosContext,
                            hdd_tx_resume_cb,
                            pAdapter->sessionId,
                           (void *)pAdapter);
#endif /* QCA_LL_TX_FLOW_CT */

           goto done;

        case NL80211_IFTYPE_AP:
        case NL80211_IFTYPE_P2P_GO:
        {
            hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
                   FL("Setting interface Type to %s"),
                   (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);
            }

            hdd_stop_adapter(pHddCtx, pAdapter, VOS_TRUE);

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

            /*
             * If Powersave Offload is enabled
             * Fw will take care incase of concurrency
             */
            if (!pHddCtx->cfg_ini->enablePowersaveOffload) {
                /* Disable BMPS and IMPS if enabled before starting Go */
                if (WLAN_HDD_P2P_GO == pAdapter->device_mode) {
                    if(VOS_STATUS_E_FAILURE ==
                           hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO)) {
                           /* Fail to Exit BMPS */
                           VOS_ASSERT(0);
                    }
                }
            }

            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)) {
                hddLog(LOG1, FL("Setting country code from INI"));
                init_completion(&pAdapter->change_country_code);
                hstatus = 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 == hstatus) {
                    /* Wait for completion */
                    rc = wait_for_completion_timeout(
                                      &pAdapter->change_country_code,
                                      msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
                    if (!rc) {
                        hddLog(LOGE,
                               FL("SME Timed out while setting country code"));
                    }
                } else {
                    hddLog(LOGE, FL("SME Change Country code failed"));
                    return -EINVAL;
                }
            }

            vstatus = hdd_init_ap_mode(pAdapter, false);
            if (vstatus != VOS_STATUS_SUCCESS) {
                hddLog(LOGP, FL("Error initializing the ap mode"));
                return -EINVAL;
            }
            hdd_set_conparam(1);

#ifdef QCA_LL_TX_FLOW_CT
            if (pAdapter->tx_flow_timer_initialized == VOS_FALSE) {
               vos_timer_init(&pAdapter->tx_flow_control_timer,
                            VOS_TIMER_TYPE_SW,
                            hdd_softap_tx_resume_timer_expired_handler,
                            pAdapter);
               pAdapter->tx_flow_timer_initialized = VOS_TRUE;
            }
            WLANTL_RegisterTXFlowControl(pHddCtx->pvosContext,
                         hdd_softap_tx_resume_cb,
                         pAdapter->sessionId,
                         (void *)pAdapter);
#endif /* QCA_LL_TX_FLOW_CT */

            /* Interface type changed update in wiphy structure */
            if (wdev) {
                wdev->iftype = type;
                pHddCtx->change_iface = type;
            } else {
                hddLog(LOGE, FL("Wireless dev is NULL"));
                return -EINVAL;
            }
            goto done;
        }

        default:
            hddLog(LOGE, FL("Unsupported interface type (%d)"), type);
            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:

          if (WLAN_HDD_VDEV_STA_MAX ==
              hdd_get_current_vdev_sta_count(pHddCtx)) {
              hddLog(VOS_TRACE_LEVEL_DEBUG,
                  FL("Unable to change as sta interface: max sta cnt is %d"),
                  WLAN_HDD_VDEV_STA_MAX);
              return -EINVAL;
          }

          status = wlan_hdd_change_client_iface_to_new_mode(ndev, type);
          if (status != 0)
              return status;

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

          /* FW will take care if PS offload is enabled. */
          if (pHddCtx->cfg_ini->enablePowersaveOffload)
              goto done;

          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;
#ifdef QCA_LL_TX_FLOW_CT
           if (pAdapter->tx_flow_timer_initialized == VOS_FALSE) {
              vos_timer_init(&pAdapter->tx_flow_control_timer,
                             VOS_TIMER_TYPE_SW,
                             hdd_softap_tx_resume_timer_expired_handler,
                             pAdapter);
              pAdapter->tx_flow_timer_initialized = VOS_TRUE;
           }
           WLANTL_RegisterTXFlowControl(pHddCtx->pvosContext,
                         hdd_softap_tx_resume_cb,
                         pAdapter->sessionId,
                         (void *)pAdapter);
#endif /* QCA_LL_TX_FLOW_CT */
           goto done;

           default:
                hddLog(LOGE, FL("Unsupported interface type(%d)"), type);
                return -EOPNOTSUPP;
       }
    } else {
      hddLog(LOGE, FL("Unsupported device mode(%d)"), pAdapter->device_mode);
      return -EOPNOTSUPP;
    }

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_FEATURE_LPSS
    wlan_hdd_send_all_scan_intf_info(pHddCtx);
#endif

    EXIT();
    return 0;
}

/*
 * FUNCTION: wlan_hdd_cfg80211_change_iface
 * wrapper function to protect the actual implementation from SSR.
 */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
static int wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy,
                                          struct net_device *ndev,
                                          enum nl80211_iftype type,
                                          struct vif_params *params)
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, &params->flags, params);
    vos_ssr_unprotect(__func__);

    return ret;
}
#else
static 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;
}
#endif

#ifdef FEATURE_WLAN_TDLS
static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
                                     struct net_device *dev,
                                     const u8 *mac,
                                     bool update,
                                     tCsrStaParams *StaParams)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx = wiphy_priv(wiphy);
    VOS_STATUS status;
    hddTdlsPeer_t *pTdlsPeer;
    tANI_U16 numCurrTdlsPeers;
    unsigned long rc;
    long ret;

    ENTER();

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

    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 (!test_bit(TDLS_INIT_DONE, &pAdapter->event_flags)) {
        hddLog(LOG1, FL("TDLS init was not done!"));
        if (0 != wlan_hdd_tdls_init(pAdapter)) {
            hddLog(LOGE, FL("wlan_hdd_tdls_init failed, exit"));
            return -EINVAL;
        }
        set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
    }

    pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac, TRUE);

    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);
        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);
        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))))
    {
        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, pTdlsPeer->staId,
                   (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
        return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
    }

    /* 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 (pHddCtx->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,
                   pHddCtx->max_num_tdls_sta);
        goto error;
    }
    else
    {
        hddTdlsPeer_t *pTdlsPeer;
        pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
        if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
        {
            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;
        }
    }
    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);

    /* Update the number of stream for each peer */
    if ((NULL != StaParams) && (StaParams->htcap_present)) {
        hddTdlsPeer_t *tdls_peer;
        tdls_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
        if (NULL != tdls_peer)
            tdls_peer->spatial_streams = StaParams->HTCap.suppMcsSet[1];
    }

    if (!update)
    {
        status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
                pAdapter->sessionId, mac);
    }
    else
    {
        status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                       pAdapter->sessionId, mac, StaParams);
    }

    rc = wait_for_completion_timeout(&pAdapter->tdls_add_station_comp,
           msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
    if (rc <= 0) {
        hddLog(LOGE, FL("timeout waiting for tdls add station indication %ld"), ret);
        goto error;
    }

    mutex_lock(&pHddCtx->tdls_lock);
    pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);

    if (pTdlsPeer && (pTdlsPeer->link_status == eTDLS_LINK_TEARING)) {
        hddLog(LOGE, FL("peer link status %u"), pTdlsPeer->link_status);
        mutex_unlock(&pHddCtx->tdls_lock);
        goto error;
    }

    mutex_unlock(&pHddCtx->tdls_lock);
    if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "%s: Add Station is unsuccessful", __func__);
        return -EPERM;
    }

    return 0;

error:
    wlan_hdd_tdls_set_link_status(pAdapter,
                                  mac,
                                  eTDLS_LINK_IDLE,
                                  eTDLS_LINK_UNSPECIFIED);
    return -EPERM;

}

static bool wlan_hdd_is_duplicate_channel(tANI_U8 *arr,
                                          int index,
                                          tANI_U8 match)
{
    int i;
    for (i = 0; i < index; i++) {
        if (arr[i] == match)
            return TRUE;
    }
    return FALSE;
}
#endif /* FEATURE_WLAN_TDLS */

/**
 * __wlan_hdd_change_station() - change station
 * @wiphy: Pointer to the wiphy structure
 * @dev: Pointer to the net device.
 * @mac: bssid
 * @params: Pointer to station parameters
 *
 * Return: 0 for success, error number on failure.
 */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0)) || defined(WITH_BACKPORTS)
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
{
    VOS_STATUS status = VOS_STATUS_SUCCESS;
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx;
    hdd_station_ctx_t *pHddStaCtx;
    v_MACADDR_t STAMacAddress;
#ifdef FEATURE_WLAN_TDLS
    tCsrStaParams StaParams = {0};
    tANI_U8 isBufSta = 0;
    tANI_U8 isOffChannelSupported = 0;
    bool is_qos_wmm_sta = false;
#endif
    uint32_t  sub20_chanwidth;
    int ret;

    ENTER();

    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;

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

    pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

    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) {
                hddLog(VOS_TRACE_LEVEL_INFO,
                       FL("Not able to change TL state to AUTHENTICATED"));
                return -EINVAL;
            }

            if (hdd_hostapd_sub20_channelwidth_can_switch(pAdapter,
                                                          &sub20_chanwidth)) {
                    WLANSAP_set_sub20_channelwidth_with_csa(
                        WLAN_HDD_GET_SAP_CTX_PTR(pAdapter), sub20_chanwidth);
            }
        }
    } 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)) {
                if (hdd_cfg_is_sub20_channel_width_enabled(pHddCtx)) {
                        hddLog(LOGE, FL("TDLS not allowed with sub 20 MHz"));
                        return -EINVAL;
                }

            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.
             */
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "%s: params->supported_channels_len: %d",
                      __func__, params->supported_channels_len);
            if (0 != params->supported_channels_len) {
                int i = 0, j = 0, k = 0, no_of_channels = 0;
                int num_unique_channels;
                int next;
                for (i = 0 ; i < params->supported_channels_len &&
                             j < SIR_MAC_MAX_SUPP_CHANNELS; i += 2) {
                    int wifi_chan_index;
                    if (!wlan_hdd_is_duplicate_channel(
                                            StaParams.supported_channels,
                                            j,
                                            params->supported_channels[i])){
                        StaParams.supported_channels[j] =
                                  params->supported_channels[i];
                    } else {
                        continue;
                    }
                    wifi_chan_index =
                        ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
                    no_of_channels = params->supported_channels[i + 1];

                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                              "%s: i: %d, j: %d, k: %d, StaParams.supported_channels[%d]: %d, wifi_chan_index: %d, no_of_channels: %d",
                              __func__, i, j, k, j,
                             StaParams.supported_channels[j],
                             wifi_chan_index,
                             no_of_channels);

                    for (k = 1; k <= no_of_channels &&
                                j <  SIR_MAC_MAX_SUPP_CHANNELS - 1; k++) {
                        next = StaParams.supported_channels[j] + wifi_chan_index;
                        if (!wlan_hdd_is_duplicate_channel(
                                             StaParams.supported_channels,
                                             j+1,
                                             next)){
                            StaParams.supported_channels[j + 1] = next;
                        } else {
                            continue;
                        }
                        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                                  "%s: i: %d, j: %d, k: %d, StaParams.supported_channels[%d]: %d",
                                  __func__, i, j, k, j+1,
                                  StaParams.supported_channels[j+1]);
                        j += 1;
                    }
                }
                num_unique_channels = j+1;

                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                              "%s: Unique Channel List", __func__);
                for (i = 0; i < num_unique_channels; i++) {
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                             "%s: StaParams.supported_channels[%d]: %d,",
                             __func__, i, StaParams.supported_channels[i]);
                }
                /* num of channels should not be more than max
                 * number of channels in 2.4GHz and 5GHz
                 */
                if (MAX_CHANNEL < num_unique_channels)
                    num_unique_channels = MAX_CHANNEL;

                StaParams.supported_channels_len = num_unique_channels;
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                          "%s: After removing duplcates StaParams.supported_channels_len: %d",
                          __func__, StaParams.supported_channels_len);
            }
            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
             * propagating till Add Sta to the firmware has to be modified,
             * if the supplicant (ieee80211) is modified to send more rates.
             */

            /* To avoid Data Corruption, 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))))
                is_qos_wmm_sta = true;

            hddLog(VOS_TRACE_LEVEL_INFO,
                   FL("%s: TDLS Peer is QOS capable is_qos_wmm_sta= %d HTcapPresent = %d"),
                   __func__, is_qos_wmm_sta, StaParams.htcap_present);

            status = wlan_hdd_tdls_set_peer_caps(pAdapter, mac,
                                                  &StaParams, isBufSta,
                                                  isOffChannelSupported,
                                                  is_qos_wmm_sta);
            if (VOS_STATUS_SUCCESS != status) {
                hddLog(VOS_TRACE_LEVEL_ERROR,
                       FL("wlan_hdd_tdls_set_peer_caps failed!"));
                return -EINVAL;
            }

            status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
            if (VOS_STATUS_SUCCESS != status) {
                hddLog(VOS_TRACE_LEVEL_ERROR,
                       FL("wlan_hdd_tdls_add_station failed!"));
                return -EINVAL;
            }
        }
#endif
    }
    EXIT();
    return ret;
}

/**
 * wlan_hdd_change_station() - cfg80211 change station handler function
 * @wiphy: Pointer to the wiphy structure
 * @dev: Pointer to the net device.
 * @mac: bssid
 * @params: Pointer to station parameters
 *
 * This is the cfg80211 change station handler function which invokes
 * the internal function @__wlan_hdd_change_station with
 * SSR protection.
 *
 * Return: 0 for success, error number on failure.
 */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)) || defined(WITH_BACKPORTS)
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
 */
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
                                      )
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
    tCsrRoamSetKey  setKey;
    u8 groupmacaddr[VOS_MAC_ADDR_SIZE] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
    int status;
    v_U32_t roamId= 0xFF;
#ifndef WLAN_FEATURE_MBSSID
    v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
#endif
    hdd_hostapd_state_t *pHostapdState;
    eHalStatus halStatus;
    hdd_context_t *pHddCtx;
    hdd_ap_ctx_t *ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);

    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;

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

    hddLog(LOG1, FL("Device_mode %s(%d)"),
           hdd_device_mode_to_string(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);

    /*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;
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
        case WLAN_CIPHER_SUITE_BTK:
            setKey.encType = eCSR_ENCRYPT_TYPE_BTK;
            break;
#endif
#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);
            return -EOPNOTSUPP;
    }

    hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
            __func__, setKey.encType);

    if (!pairwise)
    {
        /* 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, VOS_MAC_ADDR_SIZE);
    }
    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, VOS_MAC_ADDR_SIZE);
    }
    if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
    {
        /* if a key is already installed, block all subsequent ones */
        if (pAdapter->sessionCtx.station.ibss_enc_key_installed) {
            hddLog(VOS_TRACE_LEVEL_INFO_MED,
                   "%s: IBSS key installed already", __func__);
            return 0;
        }

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

        pAdapter->sessionCtx.station.ibss_enc_key_installed = 1;
        return status;
    }
    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 )
        {
#ifdef WLAN_FEATURE_MBSSID
            status = WLANSAP_SetKeySta( WLAN_HDD_GET_SAP_CTX_PTR(pAdapter),
                                        &setKey);
#else
            status = WLANSAP_SetKeySta( pVosContext, &setKey);
#endif
            if ( status != eHAL_STATUS_SUCCESS )
            {
                VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                        "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
                        __LINE__, status );
            }
        }

        if (pairwise ||
                eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
                eCSR_ENCRYPT_TYPE_WEP104_STATICKEY  == setKey.encType)
            vos_mem_copy(&ap_ctx->wepKey[key_index], &setKey,
                                               sizeof(tCsrRoamSetKey));
        else
            vos_mem_copy(&ap_ctx->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 (!pairwise)
        {
            /* 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);
            }
        }

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


#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),
                                     pAdapter->sessionId, &setKey);
        if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
        {
           hddLog(VOS_TRACE_LEVEL_INFO_MED,
                  "%s: Update PreAuth Key success", __func__);
           return 0;
        }
        else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
        {
           hddLog(VOS_TRACE_LEVEL_ERROR,
                  "%s: Update PreAuth Key failed", __func__);
           return -EINVAL;
        }
#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;
            return -EINVAL;
        }


        /* in case of IBSS as there was no information available about WEP keys during
         * IBSS join, group key initialized 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, VOS_MAC_ADDR_SIZE);

            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;
                return -EINVAL;
            }
        }
    }
    EXIT();
    return 0;
}

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
                                      )
{
    int ret;
    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
                                      mac_addr, params);
    vos_ssr_unprotect(__func__);

    return ret;
}

/*
 * FUNCTION: __wlan_hdd_cfg80211_get_key
 * This function is used to get the key information
 */
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*)
                        )
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
    hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
    struct key_params params;

    ENTER();

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

    hddLog(LOG1, FL("Device_mode %s(%d)"),
           hdd_device_mode_to_string(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;
}

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*)
                        )
{
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
                                    mac_addr, cookie, callback);
    vos_ssr_unprotect(__func__);

    return ret;
}

/**
 * __wlan_hdd_cfg80211_del_key() - cfg80211 delete key
 * @wiphy: Pointer to wiphy structure.
 * @ndev: Pointer to net_device structure.
 * @key_index: key index
 * @pairwise: pairwise
 * @mac_addr: mac address
 *
 * This function is used to delete the key information
 *
 * Return: 0 for success, error number on failure.
 */
static int __wlan_hdd_cfg80211_del_key(struct wiphy *wiphy,
					struct net_device *ndev,
					u8 key_index,
					bool pairwise, const u8 *mac_addr)
{
    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[VOS_MAC_ADDR_SIZE] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
    tCsrRoamSetKey  setKey;
    v_U32_t roamId= 0xFF;

    ENTER();

    hddLog(LOG2, FL("Device_mode %s(%d)"),
           hdd_device_mode_to_string(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;
    }

    vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
    setKey.keyId = key_index;

    if (mac_addr)
        vos_mem_copy(setKey.peerMac, mac_addr, VOS_MAC_ADDR_SIZE);
    else
        vos_mem_copy(setKey.peerMac, groupmacaddr, VOS_MAC_ADDR_SIZE);

    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)
        {
#ifdef WLAN_FEATURE_MBSSID
            status = WLANSAP_SetKeySta( WLAN_HDD_GET_SAP_CTX_PTR(pAdapter),
                                        &setKey);
#else
            status = WLANSAP_SetKeySta( pVosContext, &setKey);
#endif

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

/**
 * wlan_hdd_cfg80211_del_key() - cfg80211 delete key handler function
 * @wiphy: Pointer to wiphy structure.
 * @dev: Pointer to net_device structure.
 * @key_index: key index
 * @pairwise: pairwise
 * @mac_addr: mac address
 *
 * This is the cfg80211 delete key handler function which invokes
 * the internal function @__wlan_hdd_cfg80211_del_key with
 * SSR protection.
 *
 * Return: 0 for success, error number on failure.
 */
static int wlan_hdd_cfg80211_del_key(struct wiphy *wiphy,
					struct net_device *dev,
					u8 key_index,
					bool pairwise, const u8 *mac_addr)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_del_key(wiphy, dev, key_index,
					  pairwise, mac_addr);
	vos_ssr_unprotect(__func__);

	return ret;
}

/*
 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
 * This function is used to set the default tx key index
 */
static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
                                              struct net_device *ndev,
                                              u8 key_index,
                                              bool unicast, bool multicast)
{
    hdd_adapter_t     *pAdapter   = WLAN_HDD_GET_PRIV_PTR(ndev);
    hdd_wext_state_t  *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    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_DEFAULT_KEY,
                     pAdapter->sessionId, key_index));

    hddLog(LOG1, FL("Device_mode %s(%d) key_index = %d"),
                 hdd_device_mode_to_string(pAdapter->device_mode),
                 pAdapter->device_mode, key_index);

    if (CSR_MAX_NUM_KEY <= key_index) {
        hddLog(LOGE, FL("Invalid key index %d"), key_index);
        return -EINVAL;
    }

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

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

    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(LOG2, FL("Default tx key index %d"), 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], VOS_MAC_ADDR_SIZE);

            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 case the key length is 5 but the
                 * encryption type is 104 hence checking the key length(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(LOGE, FL("sme_RoamSetKey failed, returned %d"), status);
                return -EINVAL;
            }
        }
    } else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode ) {
        /* In SoftAp mode setting key direction for default 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;
            hddLog(LOG1, FL("WEP default key index set to SAP context %d"),
                   key_index);
            pAPCtx->wep_def_key_idx = key_index;
        }
    }

    EXIT();
    return status;
}

static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
                                              struct net_device *ndev,
                                              u8 key_index,
                                              bool unicast, bool multicast)
{
    int ret;
    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
                                              multicast);
    vos_ssr_unprotect(__func__);

    return ret;
}

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

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4 , 3, 0)) || \
    defined (CFG80211_INFORM_BSS_FRAME_DATA)
static struct cfg80211_bss *
wlan_hdd_cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
		struct ieee80211_channel *chan,
		struct ieee80211_mgmt *mgmt,
		size_t frame_len,
		int rssi, gfp_t gfp,
		uint64_t boottime_ns)
{
	struct cfg80211_bss *bss_status  = NULL;
	struct cfg80211_inform_bss data  = {0};

	data.chan = chan;
	data.boottime_ns = boottime_ns;
	data.signal = rssi;
	bss_status = cfg80211_inform_bss_frame_data(wiphy, &data, mgmt,
						    frame_len, gfp);
	return bss_status;
}
#else
static struct cfg80211_bss *
wlan_hdd_cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
		struct ieee80211_channel *chan,
		struct ieee80211_mgmt *mgmt,
		size_t frame_len,
		int rssi, gfp_t gfp,
		uint64_t boottime_ns)
{
	struct cfg80211_bss *bss_status = NULL;

	bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt, frame_len,
					       rssi, gfp);
	return bss_status;
}
#endif

/*
 * 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 = ie_length + offsetof(struct ieee80211_mgmt,
                                               u.probe_resp.variable);
    int rssi = 0;
    hdd_context_t *pHddCtx;
    int status;
#ifdef CONFIG_CNSS
    struct timespec ts;
#endif
    hdd_config_t *cfg_param = NULL;

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

    cfg_param = pHddCtx->cfg_ini;
    mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
    if (!mgmt) {
        hddLog(LOGE, FL("memory allocation failed"));
        return NULL;
    }

    memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);

#ifdef CONFIG_CNSS
    /* Android does not want the time stamp from the frame.
       Instead it wants a monotonic increasing value */
    vos_get_monotonic_boottime_ts(&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;
    qie_age->tsf_delta  = bss_desc->tsf_delta;
#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 (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
        (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL)) {
        freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
    } else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
               (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL)) {
        freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
    } else {
        hddLog(LOGE, FL("Invalid chan_no %d"), chan_no);
        kfree(mgmt);
        return NULL;
    }

    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 will be
     * queued to PE and we proceed with flushing and changing 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 sufficient
     * enough the band change reflects in SME, SME validates the channels
     * and discards the channels corresponding 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 corresponding 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 continuously 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(LOGE,
                FL("chan pointer is NULL, chan_no: %d freq: %d"),
                chan_no, freq);
       kfree(mgmt);
       return NULL;
    }

    /* Based on .ini configuration, raw rssi can be reported for bss.
     * Raw rssi is typically used for estimating power.
     */

    rssi = (cfg_param->inform_bss_rssi_raw) ? bss_desc->rssi_raw :
                                              bss_desc->rssi;

    /* Supplicant takes the signal strength in terms of mBm(100*dBm) */
    rssi = (VOS_MIN(rssi, 0)) * 100;

    hddLog(LOG1, "BSSID: "MAC_ADDRESS_STR" Channel:%d RSSI:%d",
           MAC_ADDR_ARRAY(mgmt->bssid),
           vos_freq_to_chan(chan->center_freq),(int)(rssi/100));

    bss_status = wlan_hdd_cfg80211_inform_bss_frame_data(wiphy, chan, mgmt,
                                                         frame_len, rssi,
                                                         GFP_KERNEL,
                                                   bss_desc->scansystimensec);
    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(LOG1, FL("wlan_hdd_cfg80211_inform_bss_frame return NULL"));
        }

        sme_RoamFreeConnectProfile(hHal, &roamProfile);
    } else {
        hddLog(LOGE, FL("roamProfile.pBssDesc is NULL"));
    }
    EXIT();
    return bss;
}

/**
 * wlan_hdd_cfg80211_update_bss() - update scan result to cfg80211
 * @wiphy: wiphy context
 * @pAdapter: hdd_adapter_t context
 *
 * This function will update the cached scan result to cfg80211 module
 *
 * Return: 0 for updating successfully
 *            other value for error
 */
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;
    tScanResultHandle pResult;
    struct cfg80211_bss *bss_status = NULL;
    hdd_context_t *pHddCtx;
    int ret;
    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(LOG1, FL("No scan result Status %d"), status);
        return -EAGAIN;
    }

    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.length >= 7) &&
                !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(LOG1, FL("NULL returned by cfg80211_inform_bss_frame"));
        } else {
            cfg80211_put_bss(
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) || defined(WITH_BACKPORTS)
                             wiphy,
#endif
                             bss_status);
        }

        pScanResult = sme_ScanResultGetNext(hHal, pResult);
    }

    sme_ScanResultPurge(hHal, pResult);

    /*
     *  For SAP mode, scan is invoked by hostapd during SAP start, if hostapd is
     *  restarted, we need to flush previous scan result so that it will reflect
     *  environment change
     */
    if (pAdapter->device_mode == WLAN_HDD_SOFTAP
#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
                        && pHddCtx->skip_acs_scan_status != eSAP_SKIP_ACS_SCAN
#endif
       )
        sme_ScanFlushResult(hHal, pAdapter->sessionId);

    EXIT();
    is_p2p_scan = false;
    return 0;
}

#define dump_pmkid(pMac, pmkid) \
{ \
    hddLog(LOG1, "PMKSA-ID: %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]); \
}

#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))\
	    || defined(WITH_BACKPORTS)
/*
 * 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(LOG1, FL("is going to notify supplicant of:"));

    if (NULL == pRoamInfo) {
        hddLog(LOGP, FL("pRoamInfo is NULL"));
        return -EINVAL;
    }

    if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx)) {
        hddLog(VOS_TRACE_LEVEL_INFO, MAC_ADDRESS_STR,
               MAC_ADDR_ARRAY(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)) {
                /* As per CR1059683, not invoking cfg80211_scan_done when module
                   load/unload is in progress, but this is causing assertion in
                   cfg80211 in kernel. Hence setting scan_req->notified to avoid
                   assertion. Kernel will take care of memory cleanup.
                */
                scan_req->notified = true;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,8,0))
                scan_req->info.aborted = true;
#endif
                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


/*
 * 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_U8 sessionId,
                                                  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 = &pAdapter->scan_info;
    struct cfg80211_scan_request *req = NULL;
    hdd_context_t *pHddCtx = NULL;
    bool aborted = false;
    unsigned long rc;
    unsigned int current_timestamp, time_elapsed;
    int ret = 0;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
    bool iface_down = false;
#endif

    ENTER();

    if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
        hddLog(LOGE, FL("pAdapter is not valid!"));
        return eHAL_STATUS_FAILURE;
    }

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    if (!pHddCtx) {
        hddLog(LOGE, FL("HDD context is not valid!"));
        return eHAL_STATUS_FAILURE;
    }

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
    if (pAdapter->dev && !(pAdapter->dev->flags & IFF_UP)) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
        iface_down = true;
    }
#endif

    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.
    rc = wait_for_completion_timeout(
                         &pScanInfo->scan_req_completion_event,
                         msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
    if (!rc) {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               "%s wait on scan_req_completion_event timed out", __func__);
       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 (!iface_down)
#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 (pHddCtx->cfg_ini->bug_report_for_scan_results) {
                current_timestamp = jiffies_to_msecs(jiffies);
                time_elapsed = current_timestamp -
                               pHddCtx->last_scan_bug_report_timestamp;

                /* check if we have generated bug report in
                 * MIN_TIME_REQUIRED_FOR_NEXT_BUG_REPORT time.
                 *
                 */
                if (time_elapsed > MIN_TIME_REQUIRED_FOR_NEXT_BUG_REPORT) {
                    vos_flush_logs(WLAN_LOG_TYPE_NON_FATAL,
                                   WLAN_LOG_INDICATOR_HOST_DRIVER,
                                   WLAN_LOG_REASON_NO_SCAN_RESULTS,
                                   DUMP_VOS_TRACE);
                    pHddCtx->last_scan_bug_report_timestamp = current_timestamp;
                }
                pHddCtx->last_scan_bug_report_timestamp = current_timestamp;
            }
        }
    }

    /* If any client wait scan result through WEXT
     * send scan done event to client */
    if (pAdapter->scan_info.waitScanResult)
    {
        /* The other scan request waiting for current scan finish
         * Send event to notify current scan finished */
        if(WEXT_SCAN_PENDING_DELAY == pAdapter->scan_info.scan_pending_option)
        {
            vos_event_set(&pAdapter->scan_info.scan_finished_event);
        }
        /* Send notify to WEXT client */
        else if(WEXT_SCAN_PENDING_PIGGYBACK == pAdapter->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);
        }
    }
    pAdapter->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"),
                   iface_down ? "down" : "up");
#endif
        if (pAdapter->dev)
        {
            hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
                   pAdapter->dev->name);
        }
        complete(&pScanInfo->abortscan_event_var);
        goto allow_suspend;
    }


    /*
     * 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 (!iface_down)
#endif
    {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,8,0))
        struct cfg80211_scan_info info = {
                        .aborted = aborted,
        };

        cfg80211_scan_done(req, &info);
#else
        cfg80211_scan_done(req, aborted);
#endif
    }

    complete(&pScanInfo->abortscan_event_var);

allow_suspend:

    vos_runtime_pm_allow_suspend(pHddCtx->runtime_context.scan);
    /* 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
     * immediately 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 (!iface_down)
#endif
     {
#ifdef FEATURE_WLAN_TDLS
         if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
             wlan_hdd_tdls_scan_done_callback(pAdapter);
#endif
     }

    EXIT();
    return 0;
}

/**
 * hdd_is_sta_in_middle_of_eapol() - to check STA connection Status
 * @adapter: Pointer to Global MAC Structure
 * @session_id: session id
 * @reason: scan reject reason
 *
 * This function is used to check the connection status of STA/P2P Client
 *
 * Return: true or false
 */
static bool hdd_is_sta_in_middle_of_eapol(hdd_adapter_t *adapter,
			v_U8_t *session_id, scan_reject_states *reason)
{
	hdd_station_ctx_t *hdd_sta_ctx = NULL;
	v_U8_t *sta_mac = NULL;

	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
	if ((eConnectionState_Associated == hdd_sta_ctx->conn_info.connState) &&
	    (VOS_FALSE == hdd_sta_ctx->conn_info.uIsAuthenticated)) {
		sta_mac = (v_U8_t *) &(adapter->macAddressCurrent.bytes[0]);
		hddLog(LOG1, FL("client " MAC_ADDRESS_STR " is in the middle of WPS/EAPOL exchange."),
			MAC_ADDR_ARRAY(sta_mac));
		if (session_id && reason) {
			*session_id = adapter->sessionId;
			*reason = eHDD_EAPOL_IN_PROGRESS;
		}
		return true;
	}
	return false;
}

/**
 * hdd_is_sap_in_middle_of_eapol() - to check SAP connection Status
 * @adapter: Pointer to Global MAC Structure
 * @session_id: session id
 * @reason: scan reject reason
 *
 * This function is used to check the connection status of SAP/P2P GO
 *
 * Return: true or false
 */
static bool hdd_is_sap_in_middle_of_eapol(hdd_adapter_t *adapter,
			v_U8_t *session_id, scan_reject_states *reason)
{
	v_U8_t sta_id = 0;
	v_U8_t *sta_mac = NULL;

	for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
		if ((adapter->aStaInfo[sta_id].isUsed) &&
		    (WLANTL_STA_CONNECTED ==
		     adapter->aStaInfo[sta_id].tlSTAState)) {
			sta_mac = (v_U8_t *) &(adapter->aStaInfo[sta_id].
				macAddrSTA.bytes[0]);

			hddLog(LOG1, FL("client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the middle of WPS/EAPOL exchange."),
				MAC_ADDR_ARRAY(sta_mac));
			if (session_id && reason) {
				*session_id = adapter->sessionId;
				*reason = eHDD_SAP_EAPOL_IN_PROGRESS;
			}
			return true;
		}
	}
	return false;
}

/**
 * hdd_check_connection_status() - to check connection Status
 * @adapter: Pointer to Global MAC Structure
 * @session_id: session id
 * @reason: scan reject reason
 *
 * This function is used to check the connection status
 *
 * Return: true or false
 */
static bool hdd_check_connection_status(hdd_adapter_t *adapter,
			v_U8_t *session_id, scan_reject_states *reason)
{
	hddLog(LOG1, FL("Adapter with device mode %s(%d) exists"),
		hdd_device_mode_to_string(adapter->device_mode),
		adapter->device_mode);
	if (((WLAN_HDD_INFRA_STATION == adapter->device_mode) ||
	     (WLAN_HDD_P2P_CLIENT == adapter->device_mode) ||
	     (WLAN_HDD_P2P_DEVICE == adapter->device_mode)) &&
	    (eConnectionState_Connecting ==
	     (WLAN_HDD_GET_STATION_CTX_PTR(adapter))->conn_info.connState)) {
		hddLog(LOG1, FL("%pK(%d) Connection is in progress"),
			WLAN_HDD_GET_STATION_CTX_PTR(adapter),
			adapter->sessionId);
		if (session_id && reason) {
			*session_id = adapter->sessionId;
			*reason = eHDD_CONNECTION_IN_PROGRESS;
		}
		return true;
	}
	if ((WLAN_HDD_INFRA_STATION == adapter->device_mode) &&
	    smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(adapter),
					adapter->sessionId)) {
		hddLog(LOG1, FL("%pK(%d) Reassociation is in progress"),
			WLAN_HDD_GET_STATION_CTX_PTR(adapter),
			adapter->sessionId);
		if (session_id && reason) {
			*session_id = adapter->sessionId;
			*reason = eHDD_REASSOC_IN_PROGRESS;
		}
		return true;
	}
	if ((WLAN_HDD_INFRA_STATION == adapter->device_mode) ||
	    (WLAN_HDD_P2P_CLIENT == adapter->device_mode) ||
	    (WLAN_HDD_P2P_DEVICE == adapter->device_mode)) {
		if(hdd_is_sta_in_middle_of_eapol(adapter, session_id, reason))
			return true;
	} else if ((WLAN_HDD_SOFTAP == adapter->device_mode) ||
		   (WLAN_HDD_P2P_GO == adapter->device_mode)) {
		if(hdd_is_sap_in_middle_of_eapol(adapter, session_id, reason))
			return true;
	}
	return false;
}


/*
 * hdd_isConnectionInProgress() - HDD function to check connection in progress
 * @pHddCtx - HDD context
 * @session_id: session id
 * @reason: scan reject reason
 *
 * Go through each adapter and check if Connection is in progress
 *
 * Return: true if connection in progress; false otherwise.
 */
bool 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_adapter_t *pAdapter = NULL;
	VOS_STATUS status = 0;

	if (TRUE == pHddCtx->btCoexModeSet) {
		hddLog(LOG1, FL("BTCoex Mode operation in progress"));
		return true;
	}

	status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);

	while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
		pAdapter = pAdapterNode->pAdapter;

		if (pAdapter)
			hdd_check_connection_status(pAdapter, session_id,
						    reason);
		status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
		pAdapterNode = pNext;
	}
	return false;
}

#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
/**
 * wlan_hdd_sap_skip_scan_check() - The function will check OBSS
 *         scan skip or not for SAP.
 * @hdd_ctx: pointer to hdd context.
 * @request: pointer to scan request.
 *
 * This function will check the scan request's chan list against the
 * previous ACS scan chan list. If all the chan are covered by
 * previous ACS scan, we can skip the scan and return scan complete
 * to save the SAP starting time.
 *
 * Return: true to skip the scan,
 *            false to continue the scan
 */
static bool wlan_hdd_sap_skip_scan_check(hdd_context_t *hdd_ctx,
	struct cfg80211_scan_request *request)
{
	int i, j;
	bool skip;

	hddLog(LOG1, FL("HDD_ACS_SKIP_STATUS = %d"),
		hdd_ctx->skip_acs_scan_status);
	if (hdd_ctx->skip_acs_scan_status != eSAP_SKIP_ACS_SCAN)
		return false;
	spin_lock(&hdd_ctx->acs_skip_lock);
	if (hdd_ctx->last_acs_channel_list == NULL ||
	   hdd_ctx->num_of_channels == 0 ||
	   request->n_channels == 0) {
		spin_unlock(&hdd_ctx->acs_skip_lock);
		return false;
	}
	skip = true;
	for (i = 0; i < request->n_channels ; i++ ) {
		bool find = false;
		for (j = 0; j < hdd_ctx->num_of_channels; j++) {
			if (hdd_ctx->last_acs_channel_list[j] ==
			   request->channels[i]->hw_value) {
				find = true;
				break;
			}
		}
		if (!find) {
			skip = false;
			hddLog(LOG1, FL("Chan %d isn't in ACS chan list"),
				request->channels[i]->hw_value);
			break;
		}
	}
	spin_unlock(&hdd_ctx->acs_skip_lock);
	return skip;
}
#else
static bool wlan_hdd_sap_skip_scan_check(hdd_context_t *hdd_ctx,
	struct cfg80211_scan_request *request)
{
	return false;
}
#endif

void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work)
{
    hdd_adapter_t *adapter = container_of(work,
                                   hdd_adapter_t, scan_block_work);
    struct cfg80211_scan_request *request = NULL;
    if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
       VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
                  "%s: HDD adapter context is invalid", __func__);
       return;
    }

    request = adapter->request;
    if (request) {
        request->n_ssids = 0;
        request->n_channels = 0;

        hddLog(LOGE,
                "%s:##In DFS Master mode. Scan aborted. Null result sent",
                 __func__);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,8,0))
       {
            struct cfg80211_scan_info info = {
                            .aborted = true,
            };

            cfg80211_scan_done(request, &info);
       }
#else
        cfg80211_scan_done(request, true);
#endif
        adapter->request = NULL;
    }
}

#ifdef CFG80211_SCAN_RANDOM_MAC_ADDR
/**
 * wlan_hdd_update_scan_rand_attrs - fill the host/pno scan rand attrs
 * @scan_req: pointer for destination mac addr and mac mask
 * @cfg_scan_req: pointer for source mac addr and mac mask
 * @scan_type: type of scan from enum wlan_hdd_scan_type_for_randomization
 *
 * If scan randomize flag is set in cfg scan request flags, this function
 * copies mac addr and mac mask in cfg80211 scan/sched scan request to
 * randomization attributes in tCsrScanRequest (normal scan) or
 * tpSirPNOScanReq (sched scan). Based on the type of scan, scan_req and
 * cfg_scan_req are type casted accordingly.
 *
 * Return:   Return none
 */
static void wlan_hdd_update_scan_rand_attrs(void *scan_req,
					    void *cfg_scan_req,
					    uint32_t scan_type)
{
	uint32_t flags = 0;
	uint8_t *cfg_mac_addr = NULL;
	uint8_t *cfg_mac_addr_mask = NULL;
	uint32_t *scan_randomization = NULL;
	uint8_t *scan_mac_addr = NULL;
	uint8_t *scan_mac_addr_mask = NULL;

	if (scan_type == WLAN_HDD_HOST_SCAN) {
		tCsrScanRequest *csr_scan_req = NULL;
		struct cfg80211_scan_request *request = NULL;

		csr_scan_req = (tCsrScanRequest *)scan_req;
		request = (struct cfg80211_scan_request *)cfg_scan_req;

		flags = request->flags;
		if (!(flags & NL80211_SCAN_FLAG_RANDOM_ADDR))
			return;

		cfg_mac_addr = request->mac_addr;
		cfg_mac_addr_mask = request->mac_addr_mask;
		scan_randomization = &csr_scan_req->enable_scan_randomization;
		scan_mac_addr = csr_scan_req->mac_addr;
		scan_mac_addr_mask = csr_scan_req->mac_addr_mask;
	} else if (scan_type == WLAN_HDD_PNO_SCAN) {
		tpSirPNOScanReq pno_scan_req = NULL;
		struct cfg80211_sched_scan_request *request = NULL;

		pno_scan_req = (tpSirPNOScanReq)scan_req;
		request = (struct cfg80211_sched_scan_request *)cfg_scan_req;

		flags = request->flags;
		if (!(flags & NL80211_SCAN_FLAG_RANDOM_ADDR))
			return;

		cfg_mac_addr = request->mac_addr;
		cfg_mac_addr_mask = request->mac_addr_mask;
		scan_randomization =
				&pno_scan_req->enable_pno_scan_randomization;
		scan_mac_addr = pno_scan_req->mac_addr;
		scan_mac_addr_mask = pno_scan_req->mac_addr_mask;
	} else {
		hddLog(LOGE, FL("invalid scan type for randomization"));
		return;
	}

	/* enable mac randomization */
	*scan_randomization = 1;
	memcpy(scan_mac_addr, cfg_mac_addr, VOS_MAC_ADDR_SIZE);
	memcpy(scan_mac_addr_mask, cfg_mac_addr_mask, VOS_MAC_ADDR_SIZE);

	hddLog(LOG1, FL("Mac Addr: "MAC_ADDRESS_STR
			" and Mac Mask: " MAC_ADDRESS_STR),
			MAC_ADDR_ARRAY(scan_mac_addr),
			MAC_ADDR_ARRAY(scan_mac_addr_mask));
}
#else
static void wlan_hdd_update_scan_rand_attrs(void *scan_req,
					    void *cfg_scan_req,
					    uint32_t scan_type)
{
	return;
}
#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 receive scan results
 */
int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) && !defined(WITH_BACKPORTS)
                            struct net_device *dev,
#endif
                            struct cfg80211_scan_request *request)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) || defined(WITH_BACKPORTS)
   struct net_device *dev = request->wdev->netdev;
#endif
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
    hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    hdd_station_ctx_t *station_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    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;
    hdd_adapter_t *con_sap_adapter;
    uint16_t con_dfs_ch;
    bool is_p2p_scan = false;
    uint8_t num_chan = 0;
    v_U8_t curr_session_id;
    scan_reject_states curr_reason;
    static uint32_t scan_ebusy_cnt;

    ENTER();

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_SCAN,
                     pAdapter->sessionId, request->n_channels));

    hddLog(LOG1, FL("Device_mode %s(%d)"),
           hdd_device_mode_to_string(pAdapter->device_mode),
           pAdapter->device_mode);

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

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

    cfg_param = pHddCtx->cfg_ini;
    pScanInfo = &pAdapter->scan_info;

    /* Block All Scan during DFS operation and send null scan result */
    con_sap_adapter = hdd_get_con_sap_adapter(pAdapter, true);
    if (con_sap_adapter) {
        con_dfs_ch = con_sap_adapter->sessionCtx.ap.operatingChannel;

        if (VOS_IS_DFS_CH(con_dfs_ch)) {
            /* Provide empty scan result during DFS operation since scanning
             * not supported during DFS. Reason is following case:
             * DFS is supported only in SCC for MBSSID Mode.
             * We shall not return EBUSY or ENOTSUPP as when Primary AP is
             * operating in DFS channel and secondary AP is started. Though we
             * force SCC in driver, the hostapd issues obss scan before
             * starting secAP. This results in MCC in DFS mode.
             * Thus we return null scan result. If we return scan failure
             * hostapd fails secondary AP startup.
             */
            hddLog(LOGE,
                   FL("##In DFS Master mode. Scan aborted"));

            pAdapter->request = request;

            schedule_work(&pAdapter->scan_block_work);
            return 0;
        }
    }

    if (TRUE == pScanInfo->mScanPending) {
        scan_ebusy_cnt++;

        if (MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++) {
            hddLog(LOGE, "%s: mScanPending is TRUE scan_ebusy_cnt: %u",
                   __func__, scan_ebusy_cnt);
        }
        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)) {
        scan_ebusy_cnt++;
        hddLog(LOGE, "%s: Remain On Channel Pending. scan_ebusy_cnt: %u",
               __func__, scan_ebusy_cnt);

        return -EBUSY;
    }
#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)) && !defined(WITH_BACKPORTS)
                                          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_event();
      return status;
    }
#endif

    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)
    {
        mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
        scan_ebusy_cnt++;
        hddLog(LOGE, "%s: MAX TM Level Scan not allowed. scan_ebusy_cnt: %u",
               __func__, scan_ebusy_cnt);

        return -EBUSY;
    }
    mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);

    /* Check if scan is allowed at this point of time.
     */
    if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason)) {
        scan_ebusy_cnt++;
	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("scan reject threshold reached Session %d reason %d reject cnt %d"),
			curr_session_id, curr_reason, pHddCtx->scan_reject_cnt);
                pHddCtx->last_scan_reject_timestamp = 0;
                pHddCtx->scan_reject_cnt = 0;
                if (pHddCtx->cfg_ini->enable_fatal_event) {
                    vos_flush_logs(WLAN_LOG_TYPE_FATAL,
                          WLAN_LOG_INDICATOR_HOST_DRIVER,
                          WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
                          DUMP_NO_TRACE);
                } else {
                    hddLog(LOGE, FL("Triggering SSR due to scan stuck"));
                    vos_wlanRestart();
                }
            }
         }
        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;

    /* Check whether SAP scan can be skipped or not */
    if (pAdapter->device_mode == WLAN_HDD_SOFTAP &&
       wlan_hdd_sap_skip_scan_check(pHddCtx, request)) {
        hddLog(LOGE, FL("sap scan skipped"));
        pAdapter->request = request;
        schedule_work(&pAdapter->scan_block_work);
        return 0;
    }

    vos_mem_zero( &scanRequest, sizeof(scanRequest));

    /* Even though supplicant doesn't provide any SSIDs, n_ssids is
     * set to 1.  Because 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 =
            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)
    {
        /* set the scan type to active */
        scanRequest.scanType = eSIR_ACTIVE_SCAN;
    }
    else
    {
        /*
         *Set the scan type to passive if there is no ssid list provided else
         *set default type configured in the driver.
         */
        if (!request->ssids) {
            /* In case of AP+AP there is a reason to fix scanType to
             * ACTIVE, historically this is to increase probablity of
             * successfull OBSS scan
             */
            if((WLAN_HDD_SOFTAP == pAdapter->device_mode) && \
               (pHddCtx->no_of_active_sessions[VOS_STA_SAP_MODE] > 1)) {
                scanRequest.scanType = eSIR_ACTIVE_SCAN;
            }
            else {
                scanRequest.scanType = eSIR_PASSIVE_SCAN;
            }
        }
        else
            scanRequest.scanType = pHddCtx->ioctl_scan_mode;
    }
    if (scanRequest.scanType == eSIR_PASSIVE_SCAN) {
        scanRequest.minChnTime = cfg_param->nPassiveMinChnTime;
        scanRequest.maxChnTime = cfg_param->nPassiveMaxChnTime;
    } else {
        scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
        scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
    }

#ifdef CFG80211_SCAN_BSSID
    vos_mem_copy(scanRequest.bssid, request->bssid, VOS_MAC_ADDR_SIZE);
#endif
    /* set BSSType to default type */
    scanRequest.BSSType = eCSR_BSS_TYPE_ANY;

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

    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,
                 "channelList memory alloc failed channelList");
          status = -ENOMEM;
          goto free_mem;
       }
       for (i = 0, len = 0; i < request->n_channels ; i++ )
       {
          if (!vos_is_dsrc_channel(vos_chan_to_freq(
                   request->channels[i]->hw_value))) {
              channelList[num_chan] = request->channels[i]->hw_value;
              len += snprintf(chList+len, 5, "%d ", channelList[i]);
              num_chan++;
          }
       }

       hddLog(LOG1, "No of Scan Channels: %d", num_chan);
       hddLog(VOS_TRACE_LEVEL_INFO, "Channel-List: %s", chList);
    }

    if (!num_chan) {
       hddLog(LOGE, FL("Received zero non-dsrc channels"));
       status = -EINVAL;
       goto free_mem;
    }

    scanRequest.ChannelInfo.numOfChannels = num_chan;
    scanRequest.ChannelInfo.ChannelList = channelList;

    /* set requestType to full scan */
    scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;

    /* 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 shouldn't flush scan results. If
     * driver flushes the scan results here and unfortunately if
     * the AP doesn't 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) */
       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)
           )
       {
          pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
          pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
       }

       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 (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);

    /* 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_timeout(HDD_WAKE_LOCK_SCAN_DURATION,
                                WIFI_POWER_EVENT_WAKELOCK_SCAN);
    hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
           "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,p2pSearch %d, skipDfsChnlIn P2pSearch %d",
           scanRequest.requestType, scanRequest.scanType,
           scanRequest.minChnTime, scanRequest.maxChnTime,
           scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,7,0))
    if (request->flags & NL80211_SCAN_FLAG_FLUSH)
        sme_ScanFlushResult(WLAN_HDD_GET_HAL_CTX(pAdapter),
                pAdapter->sessionId);
#endif

    wlan_hdd_update_scan_rand_attrs((void *)&scanRequest, (void *)request,
                                    WLAN_HDD_HOST_SCAN);

    if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION &&
        !is_p2p_scan &&
        !hdd_connIsConnected(station_ctx) &&
        (pHddCtx->cfg_ini->probe_req_ie_whitelist)) {
        if (pHddCtx->no_of_probe_req_ouis != 0) {
            scanRequest.voui = (struct vendor_oui *)vos_mem_malloc(
                                              pHddCtx->no_of_probe_req_ouis *
                                              sizeof(struct vendor_oui));
            if (!scanRequest.voui) {
                hddLog(LOGE, FL("Not enough memory for voui"));
                scanRequest.num_vendor_oui = 0;
                status = -ENOMEM;
                goto free_mem;
            }
        }

        wlan_hdd_fill_whitelist_ie_attrs(&scanRequest.ie_whitelist,
                                         scanRequest.probe_req_ie_bitmap,
                                         &scanRequest.num_vendor_oui,
                                         scanRequest.voui,
                                         pHddCtx);
    }

    vos_runtime_pm_prevent_suspend(pHddCtx->runtime_context.scan);
    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) {
           scan_ebusy_cnt++;
           hddLog(LOGE, FL("HO is in progress. Defer scan by informing busy scan_ebusy_cnt: %u"),
                  scan_ebusy_cnt);

           status = -EBUSY;
        } else {
           status = -EIO;
        }

        vos_runtime_pm_allow_suspend(pHddCtx->runtime_context.scan);
        hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
        goto free_mem;
    }

    pScanInfo->mScanPending = TRUE;
    pAdapter->request = request;
    pScanInfo->scanId = scanId;

    complete(&pScanInfo->scan_req_completion_event);

free_mem:
    if( scanRequest.SSIDs.SSIDList )
    {
        vos_mem_free(scanRequest.SSIDs.SSIDList);
    }

    if( channelList )
      vos_mem_free( channelList );

    if(scanRequest.voui)
        vos_mem_free(scanRequest.voui);

    if (status == 0)
        scan_ebusy_cnt = 0;

    EXIT();
    return status;
}

int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) && !defined(WITH_BACKPORTS)
                            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)) && !defined(WITH_BACKPORTS)
                                   dev,
#endif
                                   request);
    vos_ssr_unprotect(__func__);

    return ret;
}

void hdd_select_cbmode(hdd_adapter_t *pAdapter, v_U8_t operationChannel,
                       uint16_t *vht_channel_width)
{
    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);
    *vht_channel_width =
               (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->vhtChannelWidth;

    /*
     * In IBSS mode while operating in 2.4 GHz,
     * the device will be configured to CBW 20
     */
    if ((WLAN_HDD_IBSS == pAdapter->device_mode) &&
            (SIR_11B_CHANNEL_END >= operationChannel))
        *vht_channel_width = eHT_CHANNEL_WIDTH_20MHZ;

    switch ( iniDot11Mode )
    {
       case eHDD_DOT11_MODE_AUTO:
       case eHDD_DOT11_MODE_11ac:
       case eHDD_DOT11_MODE_11ac_ONLY:
#ifdef WLAN_FEATURE_11AC
          if (sme_IsFeatureSupportedByFW(DOT11AC))
              hddDot11Mode = eHDD_DOT11_MODE_11ac;
          else
              hddDot11Mode = eHDD_DOT11_MODE_11n;
#if defined(FEATURE_WLAN_WAPI) && defined(FEATURE_WLAN_WAPI_MODE_11AC_DISABLE)
          if (pAdapter->wapi_info.nWapiMode)
              hddDot11Mode = eHDD_DOT11_MODE_11n;
#endif
#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;
    }
     /* This call decides required channel bonding mode */
    sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
                     hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
                     operationChannel, 0,
                     vht_channel_width,
                     *vht_channel_width);
}

/**
 * hdd_select_mon_cbmode() - This function will handle channel bonding mode
                             for monitor mode.
 * @adapter: pointer to hdd adapter.
 * @operation_channel: operating channel.
 * @vht_channel_width: pointer to channel width.
 *
 *
 * Return: None.
 */
void hdd_select_mon_cbmode(hdd_adapter_t *adapter, v_U8_t operation_channel,
                uint16_t *vht_channel_width)
{
    v_U8_t ini_dot11_mode = (WLAN_HDD_GET_CTX(adapter))->cfg_ini->dot11Mode;
    eHddDot11Mode   hdd_dot11_mode = ini_dot11_mode;
    hdd_station_ctx_t *station_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
    uint32_t cb_mode;
    struct hdd_mon_set_ch_info *ch_info = &station_ctx->ch_info;

    hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"), ini_dot11_mode);

    switch ( ini_dot11_mode )
    {
       case eHDD_DOT11_MODE_AUTO:
       case eHDD_DOT11_MODE_11ac:
       case eHDD_DOT11_MODE_11ac_ONLY:
#ifdef WLAN_FEATURE_11AC
          if (sme_IsFeatureSupportedByFW(DOT11AC))
              hdd_dot11_mode = eHDD_DOT11_MODE_11ac;
          else
              hdd_dot11_mode = eHDD_DOT11_MODE_11n;
#else
          hdd_dot11_mode = eHDD_DOT11_MODE_11n;
#endif
          break;
       case eHDD_DOT11_MODE_11n:
       case eHDD_DOT11_MODE_11n_ONLY:
          hdd_dot11_mode = eHDD_DOT11_MODE_11n;
          break;
       default:
          hdd_dot11_mode = ini_dot11_mode;
          break;
    }
    /* This call decides required channel bonding mode */
    cb_mode = sme_SelectCBMode((WLAN_HDD_GET_CTX(adapter)->hHal),
                     hdd_cfg_xlate_to_csr_phy_mode(hdd_dot11_mode),
                     operation_channel, 0,
                     vht_channel_width,
                     *vht_channel_width);

    ch_info->channel_width = *vht_channel_width;
    ch_info->phy_mode = hdd_cfg_xlate_to_csr_phy_mode(hdd_dot11_mode);
    ch_info->channel = operation_channel;
    ch_info->cb_mode = cb_mode;
    hddLog(LOG1, FL("ch_info width %d, phymode %d channel %d"),
           ch_info->channel_width, ch_info->phy_mode, ch_info->channel);
}


/**
 * wlan_hdd_sta_sap_concur_handle() - This function will handle Station and sap
 *                                    concurrency.
 * @hdd_ctx: pointer to hdd context.
 * @sta_adapter: pointer to station adapter.
 * @roam_profile: pointer to station's roam profile.
 *
 * This function will find the AP to which station is likely to make the
 * the connection, if that AP's channel happens to be different than
 * SAP's channel then this function will stop the SAP.
 *
 * Return: true or false based on function's overall success.
 */
static bool wlan_hdd_sta_sap_concur_handle(hdd_context_t *hdd_ctx,
                                           hdd_adapter_t *sta_adapter,
                                           tCsrRoamProfile *roam_profile)
{
    hdd_adapter_t *ap_adapter = hdd_get_adapter(hdd_ctx,
                                               WLAN_HDD_SOFTAP);
    bool are_cc_channels_same = false;
    tScanResultHandle scan_cache = NULL;
    VOS_STATUS status;

    if ((ap_adapter != NULL) &&
        test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
        status =
         wlan_hdd_check_custom_con_channel_rules(sta_adapter, ap_adapter,
                                                 roam_profile, &scan_cache,
                                                 &are_cc_channels_same);
        sme_ScanResultPurge(WLAN_HDD_GET_HAL_CTX(sta_adapter),
                            scan_cache);
        /*
         * are_cc_channels_same will be false incase if SAP and STA
         * channel is different or STA channel is zero.
         * incase if STA channel is zero then lets stop the AP and
         * restart flag set, so later whenever STA channel is defined
         * we can restart our SAP in that channel.
         */
        if (false == are_cc_channels_same) {
            hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
                   FL("Stop AP due to mismatch with STA channel"));
            wlan_hdd_stop_sap(ap_adapter);
            hdd_change_sap_restart_required_status(hdd_ctx, true);
            return false;
        } else {
            hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
                   FL("sap channels are same"));
        }
    }
    return true;
}

#ifdef FEATURE_WLAN_CH_AVOID
/**
 * wlan_hdd_sta_p2pgo_concur_handle() - This function will handle Station and GO
 *                                      concurrency.
 * @hdd_ctx: pointer to hdd context.
 * @sta_adapter: pointer to station adapter.
 * @roam_profile: pointer to station's roam profile.
 * @roam_id: reference to roam_id variable being passed.
 *
 * This function will find the AP to which station is likely to make the
 * the connection, if that AP's channel happens to be different than our
 * P2PGO's channel then this function will send avoid frequency event to
 * framework to make P2PGO stop and also caches station's connect request.
 *
 * Return: true or false based on function's overall success.
 */
static bool wlan_hdd_sta_p2pgo_concur_handle(hdd_context_t *hdd_ctx,
                                             hdd_adapter_t *sta_adapter,
                                             tCsrRoamProfile *roam_profile,
                                             uint32_t *roam_id)
{
    hdd_adapter_t *p2pgo_adapter = hdd_get_adapter(hdd_ctx,
                                               WLAN_HDD_P2P_GO);
    bool are_cc_channels_same = false;
    tScanResultHandle scan_cache = NULL;
    uint32_t p2pgo_channel_num, freq;
    tHddAvoidFreqList   hdd_avoid_freq_list;
    VOS_STATUS status;

    if ((p2pgo_adapter != NULL) &&
        test_bit(SOFTAP_BSS_STARTED, &p2pgo_adapter->event_flags)) {
        status =
         wlan_hdd_check_custom_con_channel_rules(sta_adapter, p2pgo_adapter,
                                                 roam_profile, &scan_cache,
                                                 &are_cc_channels_same);
        /*
         * are_cc_channels_same will be false incase if P2PGO and STA
         * channel is different or STA channel is zero.
         */
        if (false == are_cc_channels_same) {
            if (true == hdd_is_sta_connection_pending(hdd_ctx)) {
                MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                       TRACE_CODE_HDD_CLEAR_JOIN_REQ,
                       sta_adapter->sessionId, *roam_id));
                sme_clear_joinreq_param(WLAN_HDD_GET_HAL_CTX(sta_adapter),
                                        sta_adapter->sessionId);
                hdd_change_sta_conn_pending_status(hdd_ctx, false);
                hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
                       FL("===>Clear pending join req"));
            }
            MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                   TRACE_CODE_HDD_STORE_JOIN_REQ,
                   sta_adapter->sessionId, *roam_id));
            /* store the scan cache here */
            sme_store_joinreq_param(WLAN_HDD_GET_HAL_CTX(sta_adapter),
                                    roam_profile,
                                    scan_cache,
                                    roam_id,
                                    sta_adapter->sessionId);
            hdd_change_sta_conn_pending_status(hdd_ctx, true);
            /*
             * fill frequency avoidance event and send it up
             * so, p2pgo stop event should get trigger from upper layer
             */
            p2pgo_channel_num =
              WLAN_HDD_GET_AP_CTX_PTR(p2pgo_adapter)->operatingChannel;
            if (p2pgo_channel_num <= ARRAY_SIZE(hdd_channels_2_4_GHZ)) {
                freq = ieee80211_channel_to_frequency(p2pgo_channel_num,
                                                   IEEE80211_BAND_2GHZ);
            } else {
                freq = ieee80211_channel_to_frequency(p2pgo_channel_num,
                                                   IEEE80211_BAND_5GHZ);
            }
            vos_mem_zero(&hdd_avoid_freq_list,
                         sizeof(hdd_avoid_freq_list));
            hdd_avoid_freq_list.avoidFreqRangeCount = 1;
            hdd_avoid_freq_list.avoidFreqRange[0].startFreq = freq;
            hdd_avoid_freq_list.avoidFreqRange[0].endFreq = freq;
            wlan_hdd_send_avoid_freq_event(hdd_ctx,
                                           &hdd_avoid_freq_list);
            hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
                   FL("===>Sending chnl_avoid ch[%d] freq[%d]"),
                   p2pgo_channel_num, freq);
            hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
                   FL("===>Stop GO due to mismatch with STA channel"));
            return false;
        } else {
            hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
                   FL("===>p2pgo channels are same"));
            sme_ScanResultPurge(WLAN_HDD_GET_HAL_CTX(sta_adapter),
                                scan_cache);
        }
    }
    return true;
}
#endif

/*
 * Time in msec
 * Time for complete association including DHCP
 */
#define WLAN_HDD_CONNECTION_TIME (30 * 1000)

#ifdef WLAN_FEATURE_11W
/**
 * wlan_hdd_cfg80211_check_pmf_valid() - check if pmf status is ok
 * @ wext_state: pointer to wireless extension
 *
 * This routine is called when connecting, according to check result,
 * host will decide drop the connect request or not.
 *
 * Return: 0 if check result is valid, otherwise return error code
 */
static int wlan_hdd_cfg80211_check_pmf_valid(hdd_wext_state_t *wext_state)
{
	if (wext_state->roamProfile.MFPEnabled &&
	    !(wext_state->roamProfile.MFPRequired ||
	    wext_state->roamProfile.MFPCapable)) {
		hddLog(LOGE, FL("Drop connect req as supplicant has indicated PMF required for the non-PMF peer. MFPEnabled %d MFPRequired %d MFPCapable %d"),
				wext_state->roamProfile.MFPEnabled,
				wext_state->roamProfile.MFPRequired,
				wext_state->roamProfile.MFPCapable);
		return -EINVAL;
	}
	return 0;
}
#else
static inline
int wlan_hdd_cfg80211_check_pmf_valid(hdd_wext_state_t *wext_state)
{
	return 0;
}
#endif

/*
 * 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;
    uint16_t ch_width;

    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 (VOS_FTM_MODE == hdd_get_conparam()) {
        hddLog(LOGE, FL("Command not allowed in FTM mode"));
        return -EINVAL;
    }

    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;

    adf_os_mem_zero(&hdd_sta_ctx->conn_info.conn_flag,
                    sizeof(hdd_sta_ctx->conn_info.conn_flag));

    if (pRoamProfile)
    {
        hdd_station_ctx_t *pHddStaCtx;
        pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

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

        if (NULL == pRoamProfile->SSIDs.SSIDList)
        {
             hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SSIDList NULL ", __func__);
             return -EINVAL;
        }

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

        /* cleanup bssid hint and bssid */
        vos_mem_zero(pRoamProfile->bssid_hint, VOS_MAC_ADDR_SIZE);
        vos_mem_zero(pRoamProfile->BSSIDs.bssid, VOS_MAC_ADDR_SIZE);

        if (bssid) {
            pRoamProfile->BSSIDs.numOfBSSIDs = 1;
            pRoamProfile->do_not_roam = true;
            vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
                    VOS_MAC_ADDR_SIZE);
            /* Save BSSID in separate 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((void *)(pWextState->req_bssId), bssid,
                    VOS_MAC_ADDR_SIZE);
        } else if (bssid_hint) {
            vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
                    VOS_MAC_ADDR_SIZE);
            /* Save BSSID in separate 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((void *)(pWextState->req_bssId), bssid_hint,
                    VOS_MAC_ADDR_SIZE);
            hddLog(LOGW, FL(" bssid_hint "MAC_ADDRESS_STR),
                   MAC_ADDR_ARRAY(bssid_hint));
        }

        hddLog(LOG1, FL("Connect to SSID: %.*s operating Channel: %u"),
               pRoamProfile->SSIDs.SSIDList->SSID.length,
               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)
        {
            /*
             * Need to post the IBSS power save parameters
             * to WMA. WMA will configure this parameters
             * to firmware if power save is enabled by the
             * firmware.
             */
            status = hdd_setIbssPowerSaveParams(pAdapter);

            if (VOS_STATUS_SUCCESS != status)
            {
                hddLog(VOS_TRACE_LEVEL_ERROR,
                       "%s: Set IBSS Power Save Params Failed", __func__);
                return -EINVAL;
            }
            hdd_select_cbmode(pAdapter,operatingChannel, &ch_width);
            pRoamProfile->vht_channel_width = ch_width;
        }
        /*
         * if MFPEnabled is set but the peer AP is non-PMF i.e ieee80211w=2
         * or pmf=2 is an explicit configuration in the supplicant
         * configuration, drop the connection request.
         */
        if (wlan_hdd_cfg80211_check_pmf_valid(pWextState) != 0) {
             return -EINVAL;
        }
        /*
         * 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) {
            hdd_connSetConnectionState(pAdapter,
                    eConnectionState_Connecting);
        }

        /* After 8-way handshake supplicant should give the scan command
         * in that it update the additional IEs, But because of scan
         * enhancements, the supplicant is not issuing the scan command now.
         * So the unicast frames which are sent from the host are not having
         * the additional IEs. If it is P2P CLIENT and there is no additional
         * IE present in roamProfile, then use the additional IE form scan_info
         */

        if ((pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) &&
                (!pRoamProfile->pAddIEScan))
        {
            pRoamProfile->pAddIEScan = &pAdapter->scan_info.scanAddIE.addIEdata[0];
            pRoamProfile->nAddIEScanLength = pAdapter->scan_info.scanAddIE.length;
        }
        /*
         * Custom concurrency rule1: As per this rule if station is trying to
         * connect to some AP in 2.4Ghz and SAP is already in started state then
         * SAP should restart in station's channel.
         */
        if (pHddCtx->cfg_ini->conc_custom_rule1 &&
            (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) {

            wlan_hdd_sta_sap_concur_handle (pHddCtx, pAdapter, pRoamProfile);
        }
#ifdef FEATURE_WLAN_CH_AVOID
        /*
         * Custom concurrency rule2: As per this rule if station is trying to
         * connect to some AP in 5Ghz and P2PGO is already in started state then
         * P2PGO should restart in station's channel.
         */
        if (pHddCtx->cfg_ini->conc_custom_rule2 &&
            (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) {
            if (false ==
                wlan_hdd_sta_p2pgo_concur_handle(pHddCtx, pAdapter,
                                                 pRoamProfile, &roamId)) {
                hddLog(VOS_TRACE_LEVEL_ERROR,
                       FL("P2PGO - STA chnl diff, cached join req"));
                return 0;
            }
        }
#endif

        vos_runtime_pm_prevent_suspend(pAdapter->runtime_context.connect);

        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(LOGE,
                    FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
                    pAdapter->sessionId, status);
            /* change back to NotAssociated */
            hdd_connSetConnectionState(pAdapter,
                                       eConnectionState_NotConnected);
            vos_runtime_pm_allow_suspend(pAdapter->runtime_context.connect);
        }

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

    /*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
#if defined(WLAN_FEATURE_FILS_SK) && defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT)
        case NL80211_AUTHTYPE_FILS_SK:
            hddLog(LOG1, "set authentication type to FILS SHARED KEY");
            pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
            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;
}

#if defined(WLAN_FEATURE_FILS_SK) && defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT)
static bool hdd_validate_fils_info_ptr(hdd_wext_state_t *wext_state)
{
    struct cds_fils_connection_info *fils_con_info;

    fils_con_info = wext_state->roamProfile.fils_con_info;
    if (!fils_con_info) {
        hddLog(LOGE, "No valid Roam profile");
        return false;
    }

    return true;
}
#else
static bool hdd_validate_fils_info_ptr(hdd_wext_state_t *wext_state)
{
    return TRUE;
}
#endif

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

    roam_profile = &pWextState->roamProfile;
    if (!hdd_validate_fils_info_ptr(pWextState))
        return -EINVAL;

    /* 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_SHA256:
        case WLAN_AKM_SUITE_8021X:
#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 */
#endif
        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;
#if defined(WLAN_FEATURE_FILS_SK) && defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT)
        case WLAN_AKM_SUITE_FILS_SHA256:
            hddLog(LOG1, "setting key mgmt type to FILS SHA256");
            pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
            roam_profile->fils_con_info->akm_type =
                eCSR_AUTH_TYPE_FILS_SHA256;
            break;

        case WLAN_AKM_SUITE_FILS_SHA384:
            hddLog(LOG1, "setting key mgmt type to FILS SH384");
            pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
            roam_profile->fils_con_info->akm_type =
                eCSR_AUTH_TYPE_FILS_SHA384;
            break;

        case WLAN_AKM_SUITE_FT_FILS_SHA256:
            hddLog(LOG1, "setting key mgmt type to FILS FT SH256");
            pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
            roam_profile->fils_con_info->akm_type =
                eCSR_AUTH_TYPE_FT_FILS_SHA256;
            break;

        case WLAN_AKM_SUITE_FT_FILS_SHA384:
            pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
            roam_profile->fils_con_info->akm_type =
                eCSR_AUTH_TYPE_FT_FILS_SHA384;
            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);

    if (!cipher) {
        hddLog(LOG1, FL("received cipher %d - considering none"), 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;
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
        case WLAN_CIPHER_SUITE_BTK:
            encryptionType = eCSR_ENCRYPT_TYPE_BTK;
            break;
#endif
#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,
                             const u8 *ie,
                             size_t ie_len)
{
    hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    const u8 *genie = ie;
    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

    /* 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], exceeds %d bytes",
                                __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
                        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 Association 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 Association 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;
                }
                else
                {
                    uint16_t curAddIELen = pWextState->assocAddIE.length;
                    if ((pWextState->assocAddIE.length + eLen) >
                                SIR_MAC_MAX_IE_LENGTH) {
                           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;
            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.
                 * Currently driver is only interested in interworkingService
                 * and bsstransition capability from supplicant.
                 * If in future any other EXT Cap info is
                 * required from supplicant, 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;
    }
    return 0;
}

/*
 * FUNCTION: hdd_isWPAIEPresent
 * Parse the received IE to find the WPA IE
 *
 */
static bool hdd_isWPAIEPresent(const u8 *ie, 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;
}

#if defined(WLAN_FEATURE_FILS_SK) && defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT)
static int wlan_hdd_get_fils_auth_type(enum nl80211_auth_type auth)
{
    switch (auth) {
        case NL80211_AUTHTYPE_FILS_SK:
            return eSIR_FILS_SK_WITHOUT_PFS;
        case NL80211_AUTHTYPE_FILS_SK_PFS:
            return eSIR_FILS_SK_WITH_PFS;
        case NL80211_AUTHTYPE_FILS_PK:
            return eSIR_FILS_PK_AUTH;
        default:
            return -EINVAL;
    }
}

/**
 * wlan_hdd_cfg80211_set_fils_config() - set fils config params during connect
 * @adapter: Pointer to adapter
 * @req: Pointer to fils parameters
 *
 * Return: 0 for success, non-zero for failure
 */
static int wlan_hdd_cfg80211_set_fils_config(hdd_adapter_t *adapter,
                                             struct cfg80211_connect_params *req)
{
    hdd_wext_state_t *wext_state;
    tCsrRoamProfile *roam_profile;
    int auth_type;
    uint8_t *buf;

    wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
    roam_profile = &wext_state->roamProfile;

    if (!roam_profile) {
        hddLog(LOGE, "No valid Roam profile");
        return -EINVAL;
    }

    roam_profile->fils_con_info =
        vos_mem_malloc(sizeof(struct cds_fils_connection_info));

    if (!roam_profile->fils_con_info) {
        hddLog(VOS_TRACE_LEVEL_INFO,"failed to allocate memory");
        return -EINVAL;
    }
    if (req->auth_type != NL80211_AUTHTYPE_FILS_SK) {
        roam_profile->fils_con_info->is_fils_connection = false;
        return 0;
    }

    roam_profile->fils_con_info->is_fils_connection = true;
    roam_profile->fils_con_info->sequence_number = req->fils_erp_next_seq_num;
    auth_type = wlan_hdd_get_fils_auth_type(req->auth_type);
    if (auth_type < 0) {
        hddLog(VOS_TRACE_LEVEL_INFO,"invalid auth type for fils %d", req->auth_type);
        return -EINVAL;
    }
    roam_profile->fils_con_info->auth_type = auth_type;

    roam_profile->fils_con_info->r_rk_length = req->fils_erp_rrk_len;
    if (req->fils_erp_rrk_len)
        vos_mem_copy(roam_profile->fils_con_info->r_rk,
            req->fils_erp_rrk,
            roam_profile->fils_con_info->r_rk_length);

    roam_profile->fils_con_info->realm_len = req->fils_erp_realm_len;
    if (req->fils_erp_realm_len)
        vos_mem_copy(roam_profile->fils_con_info->realm,
            req->fils_erp_realm,
            roam_profile->fils_con_info->realm_len);

    roam_profile->fils_con_info->key_nai_length =
            req->fils_erp_username_len + sizeof(char) +
    req->fils_erp_realm_len;
    if (req->fils_erp_username_len) {
        buf = roam_profile->fils_con_info->keyname_nai;
        vos_mem_copy(buf,
            req->fils_erp_username,
            req->fils_erp_username_len);
            buf += req->fils_erp_username_len;
            vos_mem_copy(buf, "@", sizeof(char));
            buf += sizeof(char);
            vos_mem_copy(buf, req->fils_erp_realm,
            req->fils_erp_realm_len);
    }
    hddLog(VOS_TRACE_LEVEL_INFO,"fils connection seq=%d auth=%d user_len=%zu rrk_len=%zu realm_len=%zu keyname nai len %d\n",
        req->fils_erp_next_seq_num, req->auth_type,
        req->fils_erp_username_len, req->fils_erp_rrk_len,
        req->fils_erp_realm_len,
        roam_profile->fils_con_info->key_nai_length);

    return 0;
}
#else
static int wlan_hdd_cfg80211_set_fils_config(hdd_adapter_t *adapter,
                                             struct cfg80211_connect_params *req)
{
    return 0;
}
#endif

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

    /*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;
    }
    /* Parase extra info from connect request */
    status = wlan_hdd_cfg80211_set_fils_config(pAdapter, req);
    if (0 > status)
    {
        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 corresponding fields 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,
                   FL("failed to parse the WPA/RSN IE"));
            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 )
{
    unsigned long rc;
    hdd_station_ctx_t *pHddStaCtx;
    eMib_dot11DesiredBssType connectedBssType;
    int status, result = 0;

    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))
    {
        hdd_connSetConnectionState(pAdapter, 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);
        /*
         * 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.
         */
        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 );
             pHddStaCtx->staDebugState = status;
             result = -EINVAL;
             goto disconnected;
        }

        rc = wait_for_completion_timeout(
                     &pAdapter->disconnect_comp_var,
                     msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
        if (!rc && (eHAL_STATUS_CMD_NOT_QUEUED != status)) {
             hddLog(LOGE, FL("Sme disconnect event timed out session Id %d"
                 " staDebugState %d"), pAdapter->sessionId,
                 pHddStaCtx->staDebugState);
             result = -ETIMEDOUT;
        }
    }
    else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
    {
        rc = wait_for_completion_timeout(
                     &pAdapter->disconnect_comp_var,
                     msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
        if (!rc) {
            hddLog(LOGE, FL("Disconnect event timed out session Id %d"
               " staDebugState %d"), pAdapter->sessionId,
               pHddStaCtx->staDebugState);
            result = -ETIMEDOUT;
        }
    }
disconnected:
    hdd_connSetConnectionState(pAdapter,
                                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
 * @status: out variable for status of reassoc request
 *
 * This function will start reassociation if prev_bssid is set and bssid/
 * bssid_hint, channel/channel_hint  parameters are present in connect request.
 *
 * Return: true if connect was for ReAssociation, false otherwise
 */
#ifdef CFG80211_CONNECT_PREV_BSSID
static bool wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
				struct cfg80211_connect_params *req,
				int *status)
{
	bool reassoc = false;
	const uint8_t *bssid = NULL;
	uint16_t channel = 0;

	if (req->bssid)
		bssid = req->bssid;
	else if (req->bssid_hint)
		bssid = req->bssid_hint;

	if (req->channel)
		channel = req->channel->hw_value;
	else if (req->channel_hint)
		channel = req->channel_hint->hw_value;

	if (bssid && channel && req->prev_bssid) {
		reassoc = true;
		hddLog(VOS_TRACE_LEVEL_INFO,
			FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
			channel, MAC_ADDR_ARRAY(bssid));
		*status  = hdd_reassoc(adapter, bssid, channel,
					CONNECT_CMD_USERSPACE);
		hddLog(VOS_TRACE_LEVEL_DEBUG,
			"hdd_reassoc: status: %d", *status);
	}
	return reassoc;
}
#else
static bool wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
				struct cfg80211_connect_params *req,
				int *status)
{
	return false;
}
#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;
    ENTER();

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_CONNECT,
                     pAdapter->sessionId, pAdapter->device_mode));
    hddLog(LOG1, FL("Device_mode %s(%d)"),
           hdd_device_mode_to_string(pAdapter->device_mode),
           pAdapter->device_mode);

    if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION &&
        pAdapter->device_mode != WLAN_HDD_P2P_CLIENT) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: device_mode is not supported", __func__);
        return -EINVAL;
    }

    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 (true == wlan_hdd_reassoc_bssid_hint(pAdapter, req, &status))
        return status;

#if defined(FEATURE_WLAN_LFR) && defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD)
    wlan_hdd_disable_roaming(pAdapter);
#endif


    //If Device Mode is Station Concurrent Sessions Exit BMps
    //P2P Mode will be taken care in Open/close adapter
    if (!pHddCtx->cfg_ini->enablePowersaveOffload &&
        (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_ERROR, 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 (req->channel)
        channel = req->channel->hw_value;
    else
        channel = 0;
    if (pHddCtx->cfg_ini->enable_dynamic_sta_chainmask)
       hdd_decide_dynamic_chain_mask(pHddCtx, HDD_ANTENNA_MODE_2X2);

    /* 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 PS offload is enabled, fw will take care of
// ps in cae of concurrency.
        if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
            (NULL != pHddCtx) && !pHddCtx->cfg_ini->enablePowersaveOffload) {
            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"));
       /* Decide the antenna mode if connect fails */
       if (pHddCtx->cfg_ini->enable_dynamic_sta_chainmask)
          hdd_decide_dynamic_chain_mask(pHddCtx, HDD_ANTENNA_MODE_INVALID);
        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_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;
    unsigned long rc;
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    eConnectionState prev_conn_state;
    uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;

    ENTER();

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

    prev_conn_state = pHddStaCtx->conn_info.connState;

    /*stop tx queues*/
    hddLog(LOG1, FL("Disabling queues"));
    wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
          WLAN_CONTROL_PATH);
    pHddCtx->isAmpAllowed = VOS_TRUE;
    hdd_connSetConnectionState(pAdapter,
                                eConnectionState_Disconnecting);
    INIT_COMPLETION(pAdapter->disconnect_comp_var);

    /*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(VOS_TRACE_LEVEL_ERROR,
               "%s csrRoamDisconnect failure, returned %d",
               __func__, (int)status );
        pHddStaCtx->staDebugState = status;
        result = -EINVAL;
        goto disconnected;
    }
wait_for_disconnect:
    rc = wait_for_completion_timeout(
                &pAdapter->disconnect_comp_var,
                msecs_to_jiffies(wait_time));

    if (!rc && (eHAL_STATUS_CMD_NOT_QUEUED != status)) {
       hddLog(VOS_TRACE_LEVEL_ERROR,
              "%s: Failed to disconnect, timed out", __func__);
       result = -ETIMEDOUT;
    }

disconnected:
    hdd_connSetConnectionState(pAdapter,
                                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_ieee80211_reason_code_to_str() - return string conversion of reason code
 * @reason: ieee80211 reason code.
 *
 * This utility function helps log string conversion of reason code.
 *
 * Return: string conversion of reason code, if match found;
 *         "Unknown" otherwise.
 */
static const char *hdd_ieee80211_reason_code_to_str(uint16_t reason)
{
	switch (reason) {
	CASE_RETURN_STRING(WLAN_REASON_UNSPECIFIED);
	CASE_RETURN_STRING(WLAN_REASON_PREV_AUTH_NOT_VALID);
	CASE_RETURN_STRING(WLAN_REASON_DEAUTH_LEAVING);
	CASE_RETURN_STRING(WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
	CASE_RETURN_STRING(WLAN_REASON_DISASSOC_AP_BUSY);
	CASE_RETURN_STRING(WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA);
	CASE_RETURN_STRING(WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
	CASE_RETURN_STRING(WLAN_REASON_DISASSOC_STA_HAS_LEFT);
	CASE_RETURN_STRING(WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH);
	CASE_RETURN_STRING(WLAN_REASON_DISASSOC_BAD_POWER);
	CASE_RETURN_STRING(WLAN_REASON_DISASSOC_BAD_SUPP_CHAN);
	CASE_RETURN_STRING(WLAN_REASON_INVALID_IE);
	CASE_RETURN_STRING(WLAN_REASON_MIC_FAILURE);
	CASE_RETURN_STRING(WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT);
	CASE_RETURN_STRING(WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT);
	CASE_RETURN_STRING(WLAN_REASON_IE_DIFFERENT);
	CASE_RETURN_STRING(WLAN_REASON_INVALID_GROUP_CIPHER);
	CASE_RETURN_STRING(WLAN_REASON_INVALID_PAIRWISE_CIPHER);
	CASE_RETURN_STRING(WLAN_REASON_INVALID_AKMP);
	CASE_RETURN_STRING(WLAN_REASON_UNSUPP_RSN_VERSION);
	CASE_RETURN_STRING(WLAN_REASON_INVALID_RSN_IE_CAP);
	CASE_RETURN_STRING(WLAN_REASON_IEEE8021X_FAILED);
	CASE_RETURN_STRING(WLAN_REASON_CIPHER_SUITE_REJECTED);
	CASE_RETURN_STRING(WLAN_REASON_DISASSOC_UNSPECIFIED_QOS);
	CASE_RETURN_STRING(WLAN_REASON_DISASSOC_QAP_NO_BANDWIDTH);
	CASE_RETURN_STRING(WLAN_REASON_DISASSOC_LOW_ACK);
	CASE_RETURN_STRING(WLAN_REASON_DISASSOC_QAP_EXCEED_TXOP);
	CASE_RETURN_STRING(WLAN_REASON_QSTA_LEAVE_QBSS);
	CASE_RETURN_STRING(WLAN_REASON_QSTA_NOT_USE);
	CASE_RETURN_STRING(WLAN_REASON_QSTA_REQUIRE_SETUP);
	CASE_RETURN_STRING(WLAN_REASON_QSTA_TIMEOUT);
	CASE_RETURN_STRING(WLAN_REASON_QSTA_CIPHER_NOT_SUPP);
	CASE_RETURN_STRING(WLAN_REASON_MESH_PEER_CANCELED);
	CASE_RETURN_STRING(WLAN_REASON_MESH_MAX_PEERS);
	CASE_RETURN_STRING(WLAN_REASON_MESH_CONFIG);
	CASE_RETURN_STRING(WLAN_REASON_MESH_CLOSE);
	CASE_RETURN_STRING(WLAN_REASON_MESH_MAX_RETRIES);
	CASE_RETURN_STRING(WLAN_REASON_MESH_CONFIRM_TIMEOUT);
	CASE_RETURN_STRING(WLAN_REASON_MESH_INVALID_GTK);
	CASE_RETURN_STRING(WLAN_REASON_MESH_INCONSISTENT_PARAM);
	CASE_RETURN_STRING(WLAN_REASON_MESH_INVALID_SECURITY);
	CASE_RETURN_STRING(WLAN_REASON_MESH_PATH_ERROR);
	CASE_RETURN_STRING(WLAN_REASON_MESH_PATH_NOFORWARD);
	CASE_RETURN_STRING(WLAN_REASON_MESH_PATH_DEST_UNREACHABLE);
	CASE_RETURN_STRING(WLAN_REASON_MAC_EXISTS_IN_MBSS);
	CASE_RETURN_STRING(WLAN_REASON_MESH_CHAN_REGULATORY);
	CASE_RETURN_STRING(WLAN_REASON_MESH_CHAN);
	default:
		return "Unknown";
	}
}
/*
 * 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;
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);

    ENTER();

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_DISCONNECT,
                     pAdapter->sessionId, reason));
    hddLog(LOG1, FL("Device_mode %s(%d) reason code(%d)"),
           hdd_device_mode_to_string(pAdapter->device_mode),
           pAdapter->device_mode, reason);

    status = wlan_hdd_validate_context(pHddCtx);

    if (0 != status)
        return status;

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

    /* 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:
             reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
             break;

        case WLAN_REASON_DEAUTH_LEAVING:
             reasonCode = pHddCtx->cfg_ini->gEnableDeauthToDisassocMap ?
                 eCSR_DISCONNECT_REASON_STA_HAS_LEFT :
                 eCSR_DISCONNECT_REASON_DEAUTH;
             break;
        case WLAN_REASON_DISASSOC_STA_HAS_LEFT:
             reasonCode = eCSR_DISCONNECT_REASON_STA_HAS_LEFT;
             break;
        default:
             reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
            break;
        }
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  FL("convert to internal reason %d to reasonCode %d"),
                  reason, reasonCode);
#ifdef QCA_PKT_PROTO_TRACE
        vos_pkt_trace_buf_dump();
#endif
        pScanInfo =  &pAdapter->scan_info;
        if (pScanInfo->mScanPending) {
            hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
                          "Aborting Scan");
            hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
                               eCSR_SCAN_ABORT_DEFAULT);
        }

        wlan_hdd_cleanup_remain_on_channel_ctx(pAdapter);
#ifdef FEATURE_WLAN_TDLS
        /* Delete all connected TDLS peers by sending deauth */
        hddLog(LOG1, FL("Delete all connected TDLS peers"));
        sme_delete_all_tdls_peers(WLAN_HDD_GET_HAL_CTX(pAdapter),
                        pAdapter->sessionId);
#endif
        hddLog(LOGE,
               FL("Disconnect request from user space with reason: %s"),
               hdd_ieee80211_reason_code_to_str(reason));
        status = wlan_hdd_disconnect(pAdapter, reasonCode);
        if (0 != status) {
            hddLog(VOS_TRACE_LEVEL_ERROR, FL("failure, returned %d"), status);
            return -EINVAL;
        }
    } else {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               FL("unexpected cfg disconnect called while in state (%d)"),
               pHddStaCtx->conn_info.connState);
    }

    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;
    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));
    pHddStaCtx->ibss_enc_key_installed = 0;

    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
                dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
                                &ie[2+4],
                                ie[1] - 4,
                                &dot11WPAIE);
                /*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, FL("failed to parse WPA/RSN IE"));
            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 parameters, 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(LOG1, FL("Device_mode %s(%d)"),
           hdd_device_mode_to_string(pAdapter->device_mode),
           pAdapter->device_mode);

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

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

    if (vos_max_concurrent_connections_reached()) {
        hddLog(VOS_TRACE_LEVEL_DEBUG, 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;
    }

    /* enable selected protection checks in IBSS mode */
    pRoamProfile->cfg_protection = IBSS_CFG_PROTECTION_ENABLE_MASK;

    if (eHAL_STATUS_FAILURE == ccmCfgSetInt( pHddCtx->hHal,
                                             WNI_CFG_IBSS_ATIM_WIN_SIZE,
                                             pHddCtx->cfg_ini->ibssATIMWinSize,
                                             NULL,
                                             eANI_BOOLEAN_FALSE))
    {
        hddLog(LOGE,
               "%s: Could not pass on WNI_CFG_IBSS_ATIM_WIN_SIZE to CCM",
               __func__);
    }

    /* 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));
    }
    if ((params->beacon_interval > CFG_BEACON_INTERVAL_MIN)
        && (params->beacon_interval <= CFG_BEACON_INTERVAL_MAX))
        pRoamProfile->beaconInterval = params->beacon_interval;
    else {
        pRoamProfile->beaconInterval = CFG_BEACON_INTERVAL_DEFAULT;
        hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
                "%s: input beacon interval %d TU is invalid, use default %d TU",
                __func__, params->beacon_interval,
                pRoamProfile->beaconInterval);
    }

    /* Set Channel */
    if (NULL !=
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)) || defined(WITH_BACKPORTS)
                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)) || defined(WITH_BACKPORTS)
                                            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,
               FL("failed to set security parameters status: %d"), status);
        return status;
    }

    /* Issue connect start */
    status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
            params->ssid_len, bssid, NULL,
            pHddStaCtx->conn_info.operationChannel);

    if (0 > status)
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed status: %d"), status);

    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);
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    int status;
    eHalStatus hal_status;
    tSirUpdateIE updateIE;

    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;

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

    hddLog(LOG1, FL("Device_mode %s(%d)"),
           hdd_device_mode_to_string(pAdapter->device_mode),
           pAdapter->device_mode);
    if (NULL == pWextState) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Data Storage Corruption"));
        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, FL("BSS Type is not set to IBSS"));
        return -EINVAL;
    }

    /* Clearing add IE of beacon */
    vos_mem_copy(updateIE.bssid, pAdapter->macAddressCurrent.bytes,
            sizeof(tSirMacAddr));
    updateIE.smeSessionId = pAdapter->sessionId;
    updateIE.ieBufferlength = 0;
    updateIE.pAdditionIEBuffer = NULL;
    updateIE.append = VOS_TRUE;
    updateIE.notify = VOS_TRUE;
    if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pAdapter),
            &updateIE, eUPDATE_IE_PROBE_BCN) == eHAL_STATUS_FAILURE) {
         hddLog(LOGE, FL("Could not pass on PROBE_RSP_BCN data to PE"));
    }

    /* Delete scan cache in cfg80211 and remove BSSID from SME
     * scan list
     */
    hddLog(LOG1, FL("clear scan cache in kernel cfg80211"));
    wlan_hdd_cfg80211_update_bss_list(pAdapter, pWextState->req_bssId);
    sme_remove_bssid_from_scan_list(hHal, pWextState->req_bssId );

    /* Reset WNI_CFG_PROBE_RSP Flags */
    wlan_hdd_reset_prob_rspies(pAdapter);

    /* 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 (VOS_FTM_MODE == hdd_get_conparam()) {
        hddLog(LOGE, FL("Command not allowed in FTM mode"));
        return -EINVAL;
    }

    if (changed & WIPHY_PARAM_RTS_THRESHOLD)
    {
        u32 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 %u",
                    __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 %u",
                    __func__, rts_threshold);
            return -EIO;
        }

        hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %u", __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) || defined(WITH_BACKPORTS)
        struct wireless_dev *wdev,
#endif
        enum nl80211_tx_power_setting type,
        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;

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

    hHal = pHddCtx->hHal;

    if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
                dbm, ccmCfgSetCallback,
                eANI_BOOLEAN_TRUE)) {
        hddLog(LOGE, FL("ccmCfgSetInt failed for tx power %hu"), dbm);
        return -EIO;
    }

    hddLog(VOS_TRACE_LEVEL_INFO_MED, FL("Set tx power level %d dbm"), dbm);

    switch (type) {
    /* Automatically determine transmit power */
    case NL80211_TX_POWER_AUTOMATIC:
    /* 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(LOGE, FL("Setting maximum tx power failed"));
          return -EIO;
      }
      break;

    case NL80211_TX_POWER_FIXED: /* Fix TX power to the mBm parameter */
       hddLog(LOGE, FL("NL80211_TX_POWER_FIXED not supported"));
       return -EOPNOTSUPP;
       break;

    default:
       hddLog(LOGE, FL("Invalid power setting type %d"), 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) || defined(WITH_BACKPORTS)
        struct wireless_dev *wdev,
#endif
        enum nl80211_tx_power_setting type,
        int dbm)
{
    int ret;
    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0) || defined(WITH_BACKPORTS)
                                        wdev,
#endif
                                        type,
                                        dbm);
   vos_ssr_unprotect(__func__);

   return ret;
}

/**
 * __wlan_hdd_cfg80211_get_txpower() - cfg80211 get txpower
 * @wiphy: Pointer to wiphy structure.
 * @wdev: Pointer to wireless_dev structure.
 * @dbm: dbm
 *
 * This function is used to read the txpower
 *
 * Return: 0 for success, error number on failure.
 */
static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) || defined(WITH_BACKPORTS)
                                         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;
    }

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

    pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
    if (NULL == pAdapter) {
        hddLog(VOS_TRACE_LEVEL_FATAL, FL("pAdapter is NULL"));
        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;
}

/**
 * wlan_hdd_cfg80211_get_txpower() - cfg80211 get power handler function
 * @wiphy: Pointer to wiphy structure.
 * @wdev: Pointer to wireless_dev structure.
 * @dbm: dbm
 *
 * This is the cfg80211 get txpower handler function which invokes
 * the internal function @__wlan_hdd_cfg80211_get_txpower with
 * SSR protection.
 *
 * Return: 0 for success, error number on failure.
 */
static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) || defined(WITH_BACKPORTS)
					 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) || defined(WITH_BACKPORTS)
						wdev,
#endif
						dbm);
	vos_ssr_unprotect(__func__);

	return ret;
}

/**
 * hdd_get_rate_flags_ht() - get HT rate flags based on rate, nss and mcs
 * @rate: Data rate (100 kbps)
 * @nss: Number of streams
 * @mcs: HT mcs index
 *
 * This function is used to construct HT rate flag with rate, nss and mcs
 *
 * Return: rate flags for success, 0 on failure.
 */
static uint8_t hdd_get_rate_flags_ht(uint32_t rate,
		uint8_t nss,
		uint8_t mcs)
{
	struct index_data_rate_type *mcs_rate;
	uint8_t flags = 0;

	mcs_rate = (struct index_data_rate_type *)
		((nss == 1) ? &supported_mcs_rate_nss1 :
		 &supported_mcs_rate_nss2);

	if (rate == mcs_rate[mcs].supported_rate[0]) {
		flags |= eHAL_TX_RATE_HT20;
	} else if (rate == mcs_rate[mcs].supported_rate[1]) {
		flags |= eHAL_TX_RATE_HT40;
	} else if (rate == mcs_rate[mcs].supported_rate[2]) {
		flags |= eHAL_TX_RATE_HT20;
		flags |= eHAL_TX_RATE_SGI;
	} else if (rate == mcs_rate[mcs].supported_rate[3]) {
		flags |= eHAL_TX_RATE_HT40;
		flags |= eHAL_TX_RATE_SGI;
	} else {
		hddLog(VOS_TRACE_LEVEL_ERROR,
				FL("invalid params rate %d nss %d mcs %d"),
				rate, nss, mcs);
	}

	return flags;
}

#ifdef WLAN_FEATURE_11AC
/**
 * hdd_get_rate_flags_vht() - get VHT rate flags based on rate, nss and mcs
 * @rate: Data rate (100 kbps)
 * @nss: Number of streams
 * @mcs: VHT mcs index
 *
 * This function is used to construct VHT rate flag with rate, nss and mcs
 *
 * Return: rate flags for success, 0 on failure.
 */
static uint8_t hdd_get_rate_flags_vht(uint32_t rate,
		uint8_t nss,
		uint8_t mcs)
{
	struct index_vht_data_rate_type *mcs_rate;
	uint8_t flags = 0;

	mcs_rate = (struct index_vht_data_rate_type *)
		((nss == 1) ?
		 &supported_vht_mcs_rate_nss1 :
		 &supported_vht_mcs_rate_nss2);

	if (rate == mcs_rate[mcs].supported_VHT80_rate[0]) {
		flags |= eHAL_TX_RATE_VHT80;
	} else if (rate == mcs_rate[mcs].supported_VHT80_rate[1]) {
		flags |= eHAL_TX_RATE_VHT80;
		flags |= eHAL_TX_RATE_SGI;
	} else if (rate == mcs_rate[mcs].supported_VHT40_rate[0]) {
		flags |= eHAL_TX_RATE_VHT40;
	} else if (rate == mcs_rate[mcs].supported_VHT40_rate[1]) {
		flags |= eHAL_TX_RATE_VHT40;
		flags |= eHAL_TX_RATE_SGI;
	} else if (rate == mcs_rate[mcs].supported_VHT20_rate[0]) {
		flags |= eHAL_TX_RATE_VHT20;
	} else if (rate == mcs_rate[mcs].supported_VHT20_rate[1]) {
		flags |= eHAL_TX_RATE_VHT20;
		flags |= eHAL_TX_RATE_SGI;
	} else {
		hddLog(VOS_TRACE_LEVEL_ERROR,
				FL("invalid params rate %d nss %d mcs %d"),
				rate, nss, mcs);
	}

	return flags;
}
#else
static uint8_t hdd_get_rate_flags_vht(uint32_t rate,
		uint8_t nss,
		uint8_t mcs)
{
	return 0;
}
#endif

/**
 * hdd_get_rate_flags() - get HT/VHT rate flags based on rate, nss and mcs
 * @rate: Data rate (100 kbps)
 * @mode: Tx/Rx mode
 * @nss: Number of streams
 * @mcs: Mcs index
 *
 * This function is used to construct rate flag with rate, nss and mcs
 *
 * Return: rate flags for success, 0 on failure.
 */
static uint8_t hdd_get_rate_flags(uint32_t rate,
		uint8_t mode,
		uint8_t nss,
		uint8_t mcs)
{
	uint8_t flags = 0;

	if (mode == SIR_SME_PHY_MODE_HT)
		flags = hdd_get_rate_flags_ht(rate, nss, mcs);
	else if (mode == SIR_SME_PHY_MODE_VHT)
		flags = hdd_get_rate_flags_vht(rate, nss, mcs);
	else
		hddLog(VOS_TRACE_LEVEL_ERROR,
				FL("invalid mode param %d"),
				mode);

	return flags;
}

/**
 * wlan_hdd_fill_rate_info() - fill HDD rate info from SIR peer info
 * @ap_ctx: AP Context
 * @peer_info: SIR peer info pointer
 *
 * This function is used to fill HDD rate info rom SIR peer info
 *
 * Return: None
 */
static void wlan_hdd_fill_rate_info(hdd_ap_ctx_t *ap_ctx,
		struct sir_peer_info_ext *peer_info)
{
	uint8_t flags;
	uint32_t rate_code;

	/* tx rate info */
	ap_ctx->txrx_stats.tx_rate.rate = peer_info->tx_rate;
	rate_code = peer_info->tx_rate_code;

	ap_ctx->txrx_stats.tx_rate.mode = SIR_SME_PHY_MODE_LEGACY;
	if ((WMI_GET_HW_RATECODE_PREAM_V1(rate_code)) ==
			WMI_RATE_PREAMBLE_HT)
		ap_ctx->txrx_stats.tx_rate.mode = SIR_SME_PHY_MODE_HT;
	else if ((WMI_GET_HW_RATECODE_PREAM_V1(rate_code)) ==
			WMI_RATE_PREAMBLE_VHT)
		ap_ctx->txrx_stats.tx_rate.mode = SIR_SME_PHY_MODE_VHT;

	ap_ctx->txrx_stats.tx_rate.nss =
		WMI_GET_HW_RATECODE_NSS_V1(rate_code) + 1;
	ap_ctx->txrx_stats.tx_rate.mcs =
		WMI_GET_HW_RATECODE_RATE_V1(rate_code);

	flags = hdd_get_rate_flags(ap_ctx->txrx_stats.tx_rate.rate/100,
			ap_ctx->txrx_stats.tx_rate.mode,
			ap_ctx->txrx_stats.tx_rate.nss,
			ap_ctx->txrx_stats.tx_rate.mcs);
	if (flags != 0)
		ap_ctx->txrx_stats.tx_rate.rate_flags = flags;

	hddLog(VOS_TRACE_LEVEL_INFO,
			FL("tx: mode %d nss %d mcs %d rate_flags %x flags %x"),
			ap_ctx->txrx_stats.tx_rate.mode,
			ap_ctx->txrx_stats.tx_rate.nss,
			ap_ctx->txrx_stats.tx_rate.mcs,
			ap_ctx->txrx_stats.tx_rate.rate_flags,
			flags);

	/* rx rate info */
	ap_ctx->txrx_stats.rx_rate.rate = peer_info->rx_rate;
	rate_code = peer_info->rx_rate_code;

	ap_ctx->txrx_stats.rx_rate.mode = SIR_SME_PHY_MODE_LEGACY;
	if ((WMI_GET_HW_RATECODE_PREAM_V1(rate_code)) ==
			WMI_RATE_PREAMBLE_HT)
		ap_ctx->txrx_stats.rx_rate.mode = SIR_SME_PHY_MODE_HT;
	else if ((WMI_GET_HW_RATECODE_PREAM_V1(rate_code)) ==
			WMI_RATE_PREAMBLE_VHT)
		ap_ctx->txrx_stats.rx_rate.mode = SIR_SME_PHY_MODE_VHT;

	ap_ctx->txrx_stats.rx_rate.nss =
		WMI_GET_HW_RATECODE_NSS_V1(rate_code) + 1;
	ap_ctx->txrx_stats.rx_rate.mcs =
		WMI_GET_HW_RATECODE_RATE_V1(rate_code);

	flags = hdd_get_rate_flags(ap_ctx->txrx_stats.rx_rate.rate/100,
			ap_ctx->txrx_stats.rx_rate.mode,
			ap_ctx->txrx_stats.rx_rate.nss,
			ap_ctx->txrx_stats.rx_rate.mcs);
	if (flags != 0)
		ap_ctx->txrx_stats.rx_rate.rate_flags = flags;

	hddLog(VOS_TRACE_LEVEL_INFO,
			FL("rx: mode %d nss %d mcs %d rate_flags %x flags %x"),
			ap_ctx->txrx_stats.rx_rate.mode,
			ap_ctx->txrx_stats.rx_rate.nss,
			ap_ctx->txrx_stats.rx_rate.mcs,
			ap_ctx->txrx_stats.rx_rate.rate_flags,
			flags);
}

/**
 * wlan_hdd_get_peer_info_cb() - get peer info callback
 * @sta_info: pointer of peer information
 * @context: get peer info callback context
 *
 * This function will fill stats info of AP Context
 *
 */
void wlan_hdd_get_peer_info_cb(struct sir_peer_info_ext_resp *sta_info,
		void *context)
{
	struct statsContext *get_peer_info_context;
	struct sir_peer_info_ext *peer_info;
	hdd_adapter_t *adapter;
	hdd_ap_ctx_t *ap_ctx;

	if ((NULL == sta_info) || (NULL == context)) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
			"%s: Bad param, sta_info [%pK] context [%pK]",
			__func__, sta_info, context);
		return;
	}

	spin_lock(&hdd_context_lock);
	/*
	 * there is a race condition that exists between this callback
	 * function and the caller since the caller could time out either
	 * before or while this code is executing.  we use a spinlock to
	 * serialize these actions
	 */
	get_peer_info_context = context;
	if (PEER_INFO_CONTEXT_MAGIC !=
			get_peer_info_context->magic) {
		/*
		 * the caller presumably timed out so there is nothing
		 * we can do
		 */
		spin_unlock(&hdd_context_lock);
		hddLog(VOS_TRACE_LEVEL_WARN,
			"%s: Invalid context, magic [%08x]",
			__func__,
			get_peer_info_context->magic);
		return;
	}

	if (!sta_info->count) {
		spin_unlock(&hdd_context_lock);
		hddLog(VOS_TRACE_LEVEL_ERROR,
				FL("Fail to get remote peer info"));
		return;
	}

	adapter = get_peer_info_context->pAdapter;
	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
	vos_mem_zero(&ap_ctx->txrx_stats,
			sizeof(struct hdd_fw_txrx_stats));

	peer_info = sta_info->info;
	ap_ctx->txrx_stats.tx_packets = peer_info->tx_packets;
	ap_ctx->txrx_stats.tx_bytes = peer_info->tx_bytes;
	ap_ctx->txrx_stats.rx_packets = peer_info->rx_packets;
	ap_ctx->txrx_stats.rx_bytes = peer_info->rx_bytes;
	ap_ctx->txrx_stats.tx_retries = peer_info->tx_retries;
	ap_ctx->txrx_stats.tx_failed = peer_info->tx_failed;
	ap_ctx->txrx_stats.rssi =
		peer_info->rssi + WLAN_HDD_TGT_NOISE_FLOOR_DBM;
	wlan_hdd_fill_rate_info(ap_ctx, peer_info);

	get_peer_info_context->magic = 0;

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

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

/**
 * wlan_hdd_get_peer_info() - get peer info
 * @adapter: hostapd interface
 * @macaddress: request peer mac address
 *
 * This function will call sme_get_peer_info_ext to get peer info
 *
 * Return: 0 on success, otherwise error value
 */
static int wlan_hdd_get_peer_info(hdd_adapter_t *adapter,
					v_MACADDR_t macaddress)
{
	eHalStatus hstatus;
	int ret;
	struct statsContext context;
	struct sir_peer_info_ext_req peer_info_req;

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

	init_completion(&context.completion);
	context.magic = PEER_INFO_CONTEXT_MAGIC;
	context.pAdapter = adapter;

	vos_mem_copy(&(peer_info_req.peer_macaddr), &macaddress,
			VOS_MAC_ADDR_SIZE);
	peer_info_req.sessionid = adapter->sessionId;
	peer_info_req.reset_after_request = 0;
	hstatus = sme_get_peer_info_ext(WLAN_HDD_GET_HAL_CTX(adapter),
			&peer_info_req,
			&context,
			wlan_hdd_get_peer_info_cb);
	if (eHAL_STATUS_SUCCESS != hstatus) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
			"%s: Unable to retrieve statistics for peer info",
			__func__);
		ret = -EFAULT;
	} else {
		if (!wait_for_completion_timeout(&context.completion,
				msecs_to_jiffies(WLAN_WAIT_TIME_STATS))) {
			hddLog(VOS_TRACE_LEVEL_ERROR,
				"%s: SME timed out while retrieving peer info",
				__func__);
			ret = -EFAULT;
		} else
			ret = 0;
	}
	/*
	 * either we never sent a request, we sent a request and received a
	 * response or we sent a request and timed out.  if we never sent a
	 * request or if we sent a request and got a response, we want to
	 * clear the magic out of paranoia.  if we timed out there is a
	 * race condition such that the callback function could be
	 * executing at the same time we are. of primary concern is if the
	 * callback function had already verified the "magic" but had not
	 * yet set the completion variable when a timeout occurred. we
	 * serialize these activities by invalidating the magic while
	 * holding a shared spinlock which will cause us to block if the
	 * callback is currently executing
	 */
	spin_lock(&hdd_context_lock);
	context.magic = 0;
	spin_unlock(&hdd_context_lock);
	return ret;
}

/**
 * hdd_get_max_rate_legacy() - get max rate for legacy mode
 * @stainfo: stainfo pointer
 * @rssidx: rssi index
 *
 * This function will get max rate for legacy mode
 *
 * Return: max rate on success, otherwise 0
 */
static uint32_t hdd_get_max_rate_legacy(hdd_station_info_t *stainfo,
		uint8_t rssidx)
{
	uint32_t maxrate = 0;
	int maxidx = 12;
	int i;

	/* check supported rates */
	if (stainfo->max_supp_idx != 0xff &&
			maxidx < stainfo->max_supp_idx)
		maxidx = stainfo->max_supp_idx;

	/* check extended rates */
	if (stainfo->max_ext_idx != 0xff &&
			maxidx < stainfo->max_ext_idx)
		maxidx = stainfo->max_ext_idx;

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

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

	return maxrate;
}

/**
 * hdd_get_max_rate_ht() - get max rate for ht mode
 * @stainfo: stainfo pointer
 * @stats: fw txrx status pointer
 * @nss: number of streams
 * @maxrate: returned max rate buffer pointer
 * @max_mcs_idx: max mcs idx
 * @report_max: report max rate or max rate
 *
 * This function will get max rate for ht mode
 *
 * Return: None
 */
static void hdd_get_max_rate_ht(hdd_station_info_t *stainfo,
		struct hdd_fw_txrx_stats *stats,
		uint32_t rate_flags,
		uint8_t nss,
		uint32_t *maxrate,
		uint8_t *max_mcs_idx,
		bool report_max)
{
	struct index_data_rate_type *supported_mcs_rate;
	uint32_t tmprate, mcsidx;
	uint8_t flag = 0;
	int8_t rssi = stats->rssi;
	int mode = 0;
	int i;

	if (rate_flags & eHAL_TX_RATE_HT40)
		mode = 1;
	else
		mode = 0;

	if (rate_flags & eHAL_TX_RATE_HT40)
		flag |= 1;
	if (rate_flags & eHAL_TX_RATE_SGI)
		flag |= 2;

	supported_mcs_rate = (struct index_data_rate_type *)
		((nss == 1) ? &supported_mcs_rate_nss1 :
		 &supported_mcs_rate_nss2);

	if (stainfo->max_mcs_idx == 0xff) {
		hddLog(LOGE, FL("invalid max_mcs_idx"));
		/* report real mcs idx */
		mcsidx = stats->tx_rate.mcs;
	} else {
		mcsidx = stainfo->max_mcs_idx;
	}

	if (!report_max) {
		for (i = 0; i < mcsidx; i++) {
			if (rssi <= rssiMcsTbl[mode][i]) {
				mcsidx = i;
				break;
			}
		}
		if (mcsidx < stats->tx_rate.mcs)
			mcsidx = stats->tx_rate.mcs;
	}

	tmprate = supported_mcs_rate[mcsidx].supported_rate[flag];

	hddLog(VOS_TRACE_LEVEL_INFO,
			FL("tmprate %d mcsidx %d"),
			tmprate, mcsidx);

	*maxrate = tmprate;
	*max_mcs_idx = mcsidx;
}

#ifdef WLAN_FEATURE_11AC
/**
 * hdd_get_max_rate_vht() - get max rate for vht mode
 * @stainfo: stainfo pointer
 * @stats: fw txrx status pointer
 * @nss: number of streams
 * @maxrate: returned max rate buffer pointer
 * @max_mcs_idx: max mcs idx
 * @report_max: report max rate or max rate
 *
 * This function will get max rate for vht mode
 *
 * Return: None
 */
static void hdd_get_max_rate_vht(hdd_station_info_t *stainfo,
		struct hdd_fw_txrx_stats *stats,
		uint32_t rate_flags,
		uint8_t nss,
		uint32_t *maxrate,
		uint8_t *max_mcs_idx,
		bool report_max)
{
	struct index_vht_data_rate_type *supported_vht_mcs_rate;
	uint32_t tmprate = 0, mcsidx = INVALID_MCS_IDX;
	uint32_t vht_max_mcs;
	uint8_t flag = 0;
	int8_t rssi = stats->rssi;
	int mode = 0;
	int i;

	supported_vht_mcs_rate = (struct index_vht_data_rate_type *)
		((nss == 1) ?
		 &supported_vht_mcs_rate_nss1 :
		 &supported_vht_mcs_rate_nss2);

	if (rate_flags & eHAL_TX_RATE_VHT80)
		mode = 2;
	else if (rate_flags & eHAL_TX_RATE_VHT40)
		mode = 1;
	else
		mode = 0;

	if (rate_flags &
	    (eHAL_TX_RATE_VHT20 | eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_VHT80)) {
		vht_max_mcs =
			(eDataRate11ACMaxMcs)
			(stainfo->tx_mcs_map & DATA_RATE_11AC_MCS_MASK);
		if (rate_flags & eHAL_TX_RATE_SGI)
			flag |= 1;

		if (DATA_RATE_11AC_MAX_MCS_7 == vht_max_mcs) {
			mcsidx = 7;
		} else if (DATA_RATE_11AC_MAX_MCS_8 == vht_max_mcs) {
			mcsidx = 8;
		} else if (DATA_RATE_11AC_MAX_MCS_9 == vht_max_mcs) {
			/*
			 * 'IEEE_P802.11ac_2013.pdf' page 325, 326
			 * - MCS9 is valid for VHT20 when Nss = 3 or Nss = 6
			 * - MCS9 is not valid for VHT20 when Nss = 1,2,4,5,7,8
			 */
			if ((rate_flags & eHAL_TX_RATE_VHT20) &&
			    (nss != 3 && nss != 6))
				mcsidx = 8;
			else
				mcsidx = 9;
		} else {
			hddLog(LOGE, FL("invalid vht_max_mcs"));
			/* report real mcs idx */
			mcsidx = stats->tx_rate.mcs;
		}

		if (!report_max) {
			for (i = 0; i <= mcsidx; i++) {
				if (rssi <= rssiMcsTbl[mode][i]) {
					mcsidx = i;
					break;
				}
			}
			if (mcsidx < stats->tx_rate.mcs)
				mcsidx = stats->tx_rate.mcs;
		}

		if (rate_flags & eHAL_TX_RATE_VHT80)
			tmprate =
		    supported_vht_mcs_rate[mcsidx].supported_VHT80_rate[flag];
		else if (rate_flags & eHAL_TX_RATE_VHT40)
			tmprate =
		    supported_vht_mcs_rate[mcsidx].supported_VHT40_rate[flag];
		else if (rate_flags & eHAL_TX_RATE_VHT20)
			tmprate =
		    supported_vht_mcs_rate[mcsidx].supported_VHT20_rate[flag];
	}

	hddLog(VOS_TRACE_LEVEL_INFO,
			FL("tmprate %d mcsidx %d"),
			tmprate, mcsidx);

	*maxrate = tmprate;
	*max_mcs_idx = mcsidx;
}
#else
static void hdd_get_max_rate_vht(hdd_station_info_t *stainfo,
		struct hdd_fw_txrx_stats *stats,
		uint32_t rate_flags,
		uint8_t nss,
		uint32_t *maxrate,
		uint8_t *max_mcs_idx,
		bool report_max) { }
#endif

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
/**
 * hdd_fill_bw_mcs() - fill ch width and mcs flags
 * @stainfo: stainfo pointer
 * @rate_flags: HDD rate flags
 * @mcsidx: mcs index
 * @nss: number of streams
 * @vht: vht mode or not
 *
 * This function will fill ch width and mcs flags
 *
 * Return: None
 */
static void hdd_fill_bw_mcs(struct station_info *sinfo,
		uint8_t rate_flags,
		uint8_t mcsidx,
		uint8_t nss,
		bool vht)
{
	if (vht) {
		sinfo->txrate.nss = nss;
		sinfo->txrate.mcs = mcsidx;
		sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
		if (rate_flags & eHAL_TX_RATE_VHT80)
			sinfo->txrate.bw = RATE_INFO_BW_80;
		else if (rate_flags & eHAL_TX_RATE_VHT40)
			sinfo->txrate.bw = RATE_INFO_BW_40;
		else if (rate_flags & eHAL_TX_RATE_VHT20)
			sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
	} else {
		sinfo->txrate.mcs = (nss-1) << 3;
		sinfo->txrate.mcs |= mcsidx;
		sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
		if (rate_flags & eHAL_TX_RATE_HT40)
			sinfo->txrate.bw = RATE_INFO_BW_40;
	}
}
#else
/**
 * hdd_fill_bw_mcs() - fill ch width and mcs flags
 * @stainfo: stainfo pointer
 * @rate_flags: HDD rate flags
 * @mcsidx: mcs index
 * @nss: number of streams
 * @vht: vht mode or not
 *
 * This function will fill ch width and mcs flags
 *
 * Return: None
 */
static void hdd_fill_bw_mcs(struct station_info *sinfo,
		uint8_t rate_flags,
		uint8_t mcsidx,
		uint8_t nss,
		bool vht)
{
	if (vht) {
		sinfo->txrate.nss = nss;
		sinfo->txrate.mcs = mcsidx;
		sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
		if (rate_flags & eHAL_TX_RATE_VHT80)
			sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
		else if (rate_flags & eHAL_TX_RATE_VHT40)
			sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
		else if (rate_flags & eHAL_TX_RATE_VHT20)
			sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
	} else {
		sinfo->txrate.mcs = (nss-1) << 3;
		sinfo->txrate.mcs |= mcsidx;
		sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
		if (rate_flags & eHAL_TX_RATE_HT40)
			sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
	}
}
#endif

#ifdef WLAN_FEATURE_11AC
/**
 * hdd_fill_bw_mcs_vht() - fill ch width and mcs flags for VHT mode
 * @stainfo: stainfo pointer
 * @rate_flags: HDD rate flags
 * @mcsidx: mcs index
 * @nss: number of streams
 *
 * This function will fill ch width and mcs flags for VHT mode
 *
 * Return: None
 */
static void hdd_fill_bw_mcs_vht(struct station_info *sinfo,
		uint8_t rate_flags,
		uint8_t mcsidx,
		uint8_t nss)
{
	hdd_fill_bw_mcs(sinfo, rate_flags, mcsidx, nss, TRUE);
}
#else
static void hdd_fill_bw_mcs_vht(struct station_info *sinfo,
		uint8_t rate_flags,
		uint8_t mcsidx,
		uint8_t nss) { }
#endif

/**
 * hdd_fill_sinfo_rate_info() - fill rate info of sinfo struct
 * @sinfo: station_info struct pointer
 * @rate_flags: HDD rate flags
 * @mcsidx: mcs index
 * @nss: number of streams
 * @maxrate: data rate (kbps)
 *
 * This function will fill rate info of sinfo struct
 *
 * Return: None
 */
static void hdd_fill_sinfo_rate_info(struct station_info *sinfo,
		uint32_t rate_flags,
		uint8_t mcsidx,
		uint8_t nss,
		uint32_t maxrate)
{
	if (rate_flags & eHAL_TX_RATE_LEGACY) {
		/* provide to the UI in units of 100kbps */
		sinfo->txrate.legacy = maxrate;
	} else {
		/* must be MCS */
		if (rate_flags &
				(eHAL_TX_RATE_VHT80 |
				 eHAL_TX_RATE_VHT40 |
				 eHAL_TX_RATE_VHT20))
			hdd_fill_bw_mcs_vht(sinfo, rate_flags, mcsidx, nss);

		if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
			hdd_fill_bw_mcs(sinfo, rate_flags, mcsidx, nss, FALSE);

		if (rate_flags & eHAL_TX_RATE_SGI) {
			if (!(sinfo->txrate.flags & RATE_INFO_FLAGS_VHT_MCS))
				sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
			sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
		}
	}

	hddLog(VOS_TRACE_LEVEL_INFO, FL("flag %x mcs %d legacy %d nss %d"),
			sinfo->txrate.flags,
			sinfo->txrate.mcs,
			sinfo->txrate.legacy,
			sinfo->txrate.nss);
}

#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0))
/**
 * hdd_fill_sinfo_rate_info() - fill flags of sinfo struct
 * @sinfo: station_info struct pointer
 *
 * This function will fill flags of sinfo struct
 *
 * Return: None
 */
static void hdd_fill_station_info_flags(struct station_info *sinfo)
{
	sinfo->filled |= STATION_INFO_SIGNAL |
		STATION_INFO_TX_BITRATE |
		STATION_INFO_TX_BYTES   |
		STATION_INFO_TX_BYTES64   |
		STATION_INFO_TX_PACKETS |
		STATION_INFO_TX_RETRIES |
		STATION_INFO_TX_FAILED  |
		STATION_INFO_RX_BYTES   |
		STATION_INFO_RX_BYTES64   |
		STATION_INFO_RX_PACKETS |
		STATION_INFO_INACTIVE_TIME |
		STATION_INFO_CONNECTED_TIME;
}
#else
/**
 * hdd_fill_sinfo_rate_info() - fill flags of sinfo struct
 * @sinfo: station_info struct pointer
 *
 * This function will fill flags of sinfo struct
 *
 * Return: None
 */
static void hdd_fill_station_info_flags(struct station_info *sinfo)
{
	sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
		BIT(NL80211_STA_INFO_TX_BYTES)   |
		BIT(NL80211_STA_INFO_TX_BYTES64)   |
		BIT(NL80211_STA_INFO_TX_BITRATE) |
		BIT(NL80211_STA_INFO_TX_PACKETS) |
		BIT(NL80211_STA_INFO_TX_RETRIES) |
		BIT(NL80211_STA_INFO_TX_FAILED)  |
		BIT(NL80211_STA_INFO_RX_BYTES)   |
		BIT(NL80211_STA_INFO_RX_BYTES64)   |
		BIT(NL80211_STA_INFO_RX_PACKETS) |
		BIT(NL80211_STA_INFO_INACTIVE_TIME) |
		BIT(NL80211_STA_INFO_CONNECTED_TIME);
}
#endif

/**
 * hdd_fill_rate_info() - fill rate info of sinfo
 * @sinfo: station_info struct pointer
 * @stainfo: stainfo pointer
 * @stats: fw txrx status pointer
 * @cfg: hdd config pointer
 *
 * This function will fill rate info of sinfo
 *
 * Return: None
 */
static void hdd_fill_rate_info(struct station_info *sinfo,
		hdd_station_info_t *stainfo,
		struct hdd_fw_txrx_stats *stats,
		hdd_config_t *cfg)
{
	uint8_t rate_flags;
	uint8_t mcsidx = 0xff;
	uint32_t myrate, maxrate, tmprate;
	int rssidx;
	int nss = 1;

	hddLog(VOS_TRACE_LEVEL_INFO, FL("reportMaxLinkSpeed %d"),
			cfg->reportMaxLinkSpeed);

	/* convert to 100kbps expected in rate table */
	myrate = stats->tx_rate.rate/100;
	rate_flags = stainfo->rate_flags;
	if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
		nss = stainfo->nss;
		if (eHDD_LINK_SPEED_REPORT_ACTUAL == cfg->reportMaxLinkSpeed) {
			/* Get current rate flags if report actual */
			if (stats->tx_rate.rate_flags)
				rate_flags =
					stats->tx_rate.rate_flags;
			nss = stats->tx_rate.nss;
		}

		if (stats->tx_rate.mcs == INVALID_MCS_IDX)
			rate_flags = eHAL_TX_RATE_LEGACY;
	}

	if (eHDD_LINK_SPEED_REPORT_ACTUAL != cfg->reportMaxLinkSpeed) {
		/* we do not want to necessarily report the current speed */
		if (eHDD_LINK_SPEED_REPORT_MAX == cfg->reportMaxLinkSpeed) {
			/* report the max possible speed */
			rssidx = 0;
		} else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED ==
				cfg->reportMaxLinkSpeed) {
			/* report the max possible speed with RSSI scaling */
			if (stats->rssi >= cfg->linkSpeedRssiHigh) {
				/* report the max possible speed */
				rssidx = 0;
			} else if (stats->rssi >=
					cfg->linkSpeedRssiMid) {
				/* report middle speed */
				rssidx = 1;
			} else if (stats->rssi >=
					cfg->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__, cfg->reportMaxLinkSpeed);
			rssidx = 0;
		}

		maxrate = hdd_get_max_rate_legacy(stainfo, rssidx);

		/*
		 * Get MCS Rate Set --
		 * Only if we are connected in non legacy mode and not
		 * reporting actual speed
		 */
		if ((3 != rssidx) &&
				!(rate_flags & eHAL_TX_RATE_LEGACY)) {
			hdd_get_max_rate_vht(stainfo,
					stats,
					rate_flags,
					nss,
					&tmprate,
					&mcsidx,
					rssidx == 0);

			if (maxrate < tmprate &&
					mcsidx != INVALID_MCS_IDX)
				maxrate = tmprate;

			if (mcsidx == INVALID_MCS_IDX)
				hdd_get_max_rate_ht(stainfo,
						stats,
						rate_flags,
						nss,
						&tmprate,
						&mcsidx,
						rssidx == 0);

			if (maxrate < tmprate &&
					mcsidx != INVALID_MCS_IDX)
				maxrate = tmprate;
		} else if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
			maxrate = myrate;
			mcsidx = stats->tx_rate.mcs;
		}

		/*
		 * 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)) {
				mcsidx = stats->tx_rate.mcs;
				/*
				 * 'IEEE_P802.11ac_2013.pdf' page 325, 326
				 * - MCS9 is valid for VHT20 when Nss = 3 or
				 *   Nss = 6
				 * - MCS9 is not valid for VHT20 when
				 *   Nss = 1,2,4,5,7,8
				 */
				if ((rate_flags & eHAL_TX_RATE_VHT20) &&
						(mcsidx > 8) &&
						(nss != 3 && nss != 6))
					mcsidx = 8;
			}
		}
	} else {
		/* report current rate instead of max rate */
		maxrate = myrate;
		if (!(rate_flags & eHAL_TX_RATE_LEGACY))
			mcsidx = stats->tx_rate.mcs;
	}

	hdd_fill_sinfo_rate_info(sinfo,
			rate_flags,
			mcsidx,
			nss,
			maxrate);
}

/**
 * wlan_hdd_fill_station_info() - fill station_info struct
 * @sinfo: station_info struct pointer
 * @stainfo: stainfo pointer
 * @stats: fw txrx status pointer
 * @cfg: hdd config pointer
 *
 * This function will fill station_info struct
 *
 * Return: None
 */
static void wlan_hdd_fill_station_info(struct station_info *sinfo,
		hdd_station_info_t *stainfo,
		struct hdd_fw_txrx_stats *stats,
		hdd_config_t *cfg)
{
	adf_os_time_t curr_time, dur;

	curr_time = vos_system_ticks();
	dur = curr_time - stainfo->assoc_ts;
	sinfo->connected_time = vos_system_ticks_to_msecs(dur)/1000;
	dur = curr_time - stainfo->last_tx_rx_ts;
	sinfo->inactive_time = vos_system_ticks_to_msecs(dur);
	sinfo->signal = stats->rssi;
	sinfo->tx_bytes = stats->tx_bytes;
	sinfo->tx_packets = stats->tx_packets;
	sinfo->rx_bytes = stats->rx_bytes;
	sinfo->rx_packets = stats->rx_packets;
	sinfo->tx_failed = stats->tx_failed;
	sinfo->tx_retries = stats->tx_retries;

	/* tx rate info */
	hdd_fill_rate_info(sinfo, stainfo, stats, cfg);

	hdd_fill_station_info_flags(sinfo);

	/* dump sta info*/
	hddLog(VOS_TRACE_LEVEL_INFO, FL("dump stainfo"));
	hddLog(VOS_TRACE_LEVEL_INFO,
			FL("con_time %d inact_time %d tx_pkts %d rx_pkts %d"),
			sinfo->connected_time, sinfo->inactive_time,
			sinfo->tx_packets, sinfo->rx_packets);
	hddLog(VOS_TRACE_LEVEL_INFO,
			FL("failed %d retries %d tx_bytes %lld rx_bytes %lld"),
			sinfo->tx_failed, sinfo->tx_retries,
			sinfo->tx_bytes, sinfo->rx_bytes);
	hddLog(VOS_TRACE_LEVEL_INFO,
			FL("rssi %d mcs %d legacy %d nss %d flags %x"),
			sinfo->signal, sinfo->txrate.mcs,
			sinfo->txrate.legacy, sinfo->txrate.nss,
			sinfo->txrate.flags);

}

/**
 * wlan_hdd_get_station_remote() - NL80211_CMD_GET_STATION handler for SoftAP
 * @wiphy: pointer to wiphy
 * @dev: pointer to net_device structure
 * @mac: request peer mac address
 * @sinfo: pointer to station_info struct
 *
 * This function will get remote peer info from fw and fill sinfo struct
 *
 * Return: 0 on success, otherwise error value
 */
static int wlan_hdd_get_station_remote(struct wiphy *wiphy,
		struct net_device *dev,
		const u8 *mac,
		struct station_info *sinfo)
{
	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	hdd_context_t *hddctx = (hdd_context_t *)wiphy_priv(wiphy);
	hdd_ap_ctx_t *ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
	hdd_station_info_t *stainfo = NULL;
	hdd_config_t *cfg = hddctx->cfg_ini;
	v_MACADDR_t macaddr;
	int status;
	int i;

	status = wlan_hdd_validate_context(hddctx);
	if (0 != status)
		return status;

	hddLog(VOS_TRACE_LEVEL_INFO, FL("get peer %pM info"), mac);

	for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
		if (vos_mem_compare(adapter->aStaInfo[i].macAddrSTA.bytes,
					mac,
					VOS_MAC_ADDR_SIZE)) {
			stainfo = &adapter->aStaInfo[i];
			break;
		}
	}

	if (!stainfo) {
		hddLog(LOGE, FL("peer %pM not found"), mac);
		return -EINVAL;
	}

	vos_mem_copy(macaddr.bytes, mac, VOS_MAC_ADDR_SIZE);
	status = wlan_hdd_get_peer_info(adapter, macaddr);
	if (status) {
		hddLog(LOGE, FL("fail to get peer info from fw"));
		return -EPERM;
	}

	wlan_hdd_fill_station_info(sinfo, stainfo, &ap_ctx->txrx_stats, cfg);

	return status;
}

static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy,
                                           struct net_device *dev,
                                           const u8* mac,
                                           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_U8 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;
    tANI_U16 myRate;
    int8_t   snr = 0;
    tANI_U16 currentRate = 0;
    tANI_U8  maxSpeedMCS = 0;
    tANI_U8  maxMCSIdx = 0;
    tANI_U8  rateFlag = 1;
    tANI_U8  i, j, rssidx;
    tANI_U8  nss = 1;
    int status, mode = 0, maxHtIdx;
    struct index_vht_data_rate_type *supported_vht_mcs_rate;
    struct index_data_rate_type *supported_mcs_rate;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
    bool rssi_stats_valid = FALSE;
#endif

#ifdef WLAN_FEATURE_11AC
    tANI_U32 vht_mcs_map;
    eDataRate11ACMaxMcs vhtMaxMcs;
#endif /* WLAN_FEATURE_11AC */

    ENTER();

    if (VOS_FTM_MODE == hdd_get_conparam()) {
        hddLog(LOGE, FL("Command not allowed in FTM mode"));
        return -EINVAL;
    }
    if (pAdapter->device_mode == WLAN_HDD_SOFTAP &&
		    pCfg->sap_get_peer_info)
        return wlan_hdd_get_station_remote(wiphy, dev, 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 (true == pHddStaCtx->hdd_ReassocScenario) {
        hddLog(LOG1,
               FL("Roaming is in progress, cannot continue with this request"));
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0))
    sinfo->filled |= STATION_INFO_SIGNAL;
#else
    sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
#endif
        sinfo->signal = pAdapter->rssi;
        return 0;
    }

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

    wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
    wlan_hdd_get_snr(pAdapter, &snr);
    pHddStaCtx->conn_info.signal = sinfo->signal;
    pHddStaCtx->conn_info.noise =
        pHddStaCtx->conn_info.signal - snr;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0))
    sinfo->filled |= STATION_INFO_SIGNAL;
#else
    sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
#endif

#ifdef WLAN_FEATURE_LPSS
    if (!pAdapter->rssi_send) {
        pAdapter->rssi_send = VOS_TRUE;
        wlan_hdd_send_status_pkg(pAdapter, pHddStaCtx, 1, 1);
    }
#endif

    wlan_hdd_get_station_stats(pAdapter);
    rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;

    //convert to the UI units of 100kbps
    myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
    if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
        nss = pAdapter->hdd_stats.ClassA_stat.rx_frag_cnt;

        if (eHDD_LINK_SPEED_REPORT_ACTUAL == pCfg->reportMaxLinkSpeed) {
            /* Get current rate flags if report actual */
            rate_flags = pAdapter->hdd_stats.ClassA_stat.promiscuous_rx_frag_cnt;
        }

        if (pAdapter->hdd_stats.ClassA_stat.mcs_index == INVALID_MCS_IDX) {
            rate_flags = eHAL_TX_RATE_LEGACY;
            pAdapter->hdd_stats.ClassA_stat.mcs_index = 0;
        }
    }

    hddLog(LOG1,
           FL("RSSI %d, RLMS %u, rate %d, rssi high %d, rssi mid %d, rssi low %d, rate_flags 0x%x, MCS %d"),
            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);

    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 connected in non legacy mode and not reporting
           actual speed */
         if ((3 != rssidx) &&
              !(rate_flags & eHAL_TX_RATE_LEGACY))
        {
            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
            supported_vht_mcs_rate = (struct index_vht_data_rate_type *)
                                      ((nss == 1)?
                                       &supported_vht_mcs_rate_nss1 :
                                       &supported_vht_mcs_rate_nss2);

            if (rate_flags & eHAL_TX_RATE_VHT80)
                mode = 2;
            else if ((rate_flags & eHAL_TX_RATE_VHT40) ||
                     (rate_flags & eHAL_TX_RATE_HT40))
                mode = 1;
            else
                mode = 0;

            /* VHT80 rate has separate 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)
                {
                    /*
                     * 'IEEE_P802.11ac_2013.pdf' page 325, 326
                     * - MCS9 is valid for VHT20 when Nss = 3 or Nss = 6
                     * - MCS9 is not valid for VHT20 when Nss = 1,2,4,5,7,8
                     */
                    if ((rate_flags & eHAL_TX_RATE_VHT20) &&
                        (nss != 3 && nss != 6)) {
                        maxMCSIdx = 8;
                    } else {
                        maxMCSIdx = 9;
                    }
                }

                if (rssidx != 0)
                {
                    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;
                }

                supported_mcs_rate = (struct index_data_rate_type *)
                                      ((nss == 1)? &supported_mcs_rate_nss1 :
                                                   &supported_mcs_rate_nss2);

                maxHtIdx = MAX_HT_MCS_IDX;
                if (rssidx != 0)
                {
                    for (i=0; i < MAX_HT_MCS_IDX; i++)
                    {
                         if (sinfo->signal <= rssiMcsTbl[mode][i])
                         {
                             maxHtIdx = i + 1;
                             break;
                         }
                    }
                }

                for (i = 0; i < MCSLeng; i++)
                {
                    for (j = 0; j < maxHtIdx; 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 < MAX_HT_MCS_IDX) && (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;
              /*
               * 'IEEE_P802.11ac_2013.pdf' page 325, 326
               * - MCS9 is valid for VHT20 when Nss = 3 or Nss = 6
               * - MCS9 is not valid for VHT20 when Nss = 1,2,4,5,7,8
               */
              if ((rate_flags & eHAL_TX_RATE_VHT20) &&
                  (maxMCSIdx > 8) &&
                  (nss != 3 && nss != 6)) {
#ifdef LINKSPEED_DEBUG_ENABLED
                  pr_info("MCS%d is not valid for VHT20 when nss=%d, hence report MCS8.",
                          maxMCSIdx, nss);
#endif
                  maxMCSIdx = 8;
              }
           }
        }

        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 = nss;
            if (rate_flags & eHAL_TX_RATE_VHT80)
            {
                sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
                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))
                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;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
                sinfo->txrate.bw = RATE_INFO_BW_20;
#endif
            }
            else
                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))
                    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_HT20)
                {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
                    sinfo->txrate.bw = RATE_INFO_BW_20;
#endif
                }
            }
            if (rate_flags & eHAL_TX_RATE_SGI)
            {
                if (!(sinfo->txrate.flags & RATE_INFO_FLAGS_VHT_MCS))
                    sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
                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 = nss;
            sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
            if (rate_flags & eHAL_TX_RATE_VHT80)
            {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
                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)
            {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
                sinfo->txrate.bw = RATE_INFO_BW_40;
#else
                sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
#endif
            }
#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))
                    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_MCS;
                sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
            }
#ifdef LINKSPEED_DEBUG_ENABLED
            pr_info("Reporting actual MCS rate %d flags %x\n",
                    sinfo->txrate.mcs,
                    sinfo->txrate.flags );
#endif //LINKSPEED_DEBUG_ENABLED
        }
    }


    sinfo->tx_bytes = pAdapter->stats.tx_bytes;

    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.multiple_retry_cnt[0] +
       pAdapter->hdd_stats.summary_stat.multiple_retry_cnt[1] +
       pAdapter->hdd_stats.summary_stat.multiple_retry_cnt[2] +
       pAdapter->hdd_stats.summary_stat.multiple_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];

    sinfo->rx_bytes = pAdapter->stats.rx_bytes;

    sinfo->rx_packets = pAdapter->stats.rx_packets;

    pHddStaCtx->conn_info.txrate.flags = sinfo->txrate.flags;
    pHddStaCtx->conn_info.txrate.mcs = sinfo->txrate.mcs;
    pHddStaCtx->conn_info.txrate.legacy = sinfo->txrate.legacy;
    pHddStaCtx->conn_info.txrate.nss = sinfo->txrate.nss;

#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0))
    sinfo->filled |= STATION_INFO_TX_BITRATE |
                     STATION_INFO_TX_BYTES   |
                     STATION_INFO_TX_PACKETS |
                     STATION_INFO_TX_RETRIES |
                     STATION_INFO_TX_FAILED  |
                     STATION_INFO_RX_BYTES   |
                     STATION_INFO_RX_PACKETS;
#else
    sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES)   |
                     BIT(NL80211_STA_INFO_TX_BITRATE) |
                     BIT(NL80211_STA_INFO_TX_PACKETS) |
                     BIT(NL80211_STA_INFO_TX_RETRIES) |
                     BIT(NL80211_STA_INFO_TX_FAILED)  |
                     BIT(NL80211_STA_INFO_RX_BYTES)   |
                     BIT(NL80211_STA_INFO_RX_PACKETS);
#endif

    if (rate_flags & eHAL_TX_RATE_LEGACY)
        hddLog(LOG1, FL("Reporting legacy rate %d pkt cnt tx %d rx %d"),
               sinfo->txrate.legacy, sinfo->tx_packets, sinfo->rx_packets);
    else
        hddLog(LOG1, FL("Reporting MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
               sinfo->txrate.mcs, sinfo->txrate.flags, sinfo->tx_packets,
               sinfo->rx_packets);

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
    sinfo->signal_avg = WLAN_HDD_TGT_NOISE_FLOOR_DBM;
    for (i = 0; i < NUM_CHAINS_MAX; i++) {
        sinfo->chain_signal_avg[i] =
               pAdapter->hdd_stats.per_chain_rssi_stats.rssi[i];
        sinfo->chains |= 1 << i;
        if (sinfo->chain_signal_avg[i] > sinfo->signal_avg &&
                   sinfo->chain_signal_avg[i] != 0)
            sinfo->signal_avg = sinfo->chain_signal_avg[i];

        hddLog(LOG1, FL("RSSI for chain %d, vdev_id %d is %d"),
            i, pAdapter->sessionId, sinfo->chain_signal_avg[i]);

        if (sinfo->chain_signal_avg[i] && !rssi_stats_valid)
            rssi_stats_valid = TRUE;
    }

    if (rssi_stats_valid) {
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0))
        sinfo->filled |= STATION_INFO_CHAIN_SIGNAL_AVG;
        sinfo->filled |= STATION_INFO_SIGNAL_AVG;
#else
        sinfo->filled |= BIT(NL80211_STA_INFO_CHAIN_SIGNAL_AVG);
        sinfo->filled |= BIT(NL80211_STA_INFO_CHAIN_SIGNAL);
#endif
    }
#endif

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_GET_STA,
                     pAdapter->sessionId, maxRate));
       EXIT();
       return 0;
}

static int __wlan_hdd_cfg80211_dump_station(struct wiphy *wiphy,
					struct net_device *dev,
					int idx, u8 *mac,
					struct station_info *sinfo)
{
	hdd_context_t *hdd_ctx = (hdd_context_t *) wiphy_priv(wiphy);

	hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: idx %d", __func__, idx);
	if (idx != 0)
		return -ENOENT;
	vos_mem_copy(mac, hdd_ctx->cfg_ini->intfMacAddr[0].bytes,
				VOS_MAC_ADDR_SIZE);
	return __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
}

static int wlan_hdd_cfg80211_dump_station(struct wiphy *wiphy,
					struct net_device *dev,
					int idx, u8 *mac,
					struct station_info *sinfo)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_dump_station(wiphy, dev, idx, mac, sinfo);
	vos_ssr_unprotect(__func__);
	return ret;
}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0)) || defined(WITH_BACKPORTS)
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();

    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 (VOS_FTM_MODE == hdd_get_conparam()) {
        hddLog(LOGE, FL("Command not allowed in FTM mode"));
        return -EINVAL;
    }

    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
     **/
    if(!pHddCtx->cfg_ini->enablePowersaveOffload)
        vos_status =  wlan_hdd_enter_bmps(pAdapter, !mode);
    else
        vos_status =  wlan_hdd_set_powersave(pAdapter, !mode);

    if (!mode)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
                  "%s: DHCP start indicated through power save", __func__);
        vos_runtime_pm_prevent_suspend(pAdapter->runtime_context.connect);
        sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
                         pAdapter->macAddressCurrent.bytes, pAdapter->sessionId);
    }
    else
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
                  "%s: DHCP stop indicated through power save", __func__);
        vos_runtime_pm_allow_suspend(pAdapter->runtime_context.connect);
        sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
                        pAdapter->macAddressCurrent.bytes, pAdapter->sessionId);
    }

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

/**
 * __wlan_hdd_set_default_mgmt_key() - set default mgmt key
 * @wiphy: pointer to wiphy
 * @netdev: pointer to net_device structure
 * @key_index: key index
 *
 * Return: 0 on success
 */
static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
                         struct net_device *netdev,
                         u8 key_index)
{
    ENTER();
    return 0;
}

/**
 * wlan_hdd_set_default_mgmt_key() - SSR wrapper for
 *				wlan_hdd_set_default_mgmt_key
 * @wiphy: pointer to wiphy
 * @netdev: pointer to net_device structure
 * @key_index: key index
 *
 * Return: 0 on success, error number on failure
 */
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;
}

/**
 * __wlan_hdd_set_txq_params() - set tx queue parameters
 * @wiphy: pointer to wiphy
 * @netdev: pointer to net_device structure
 * @params: pointer to ieee80211_txq_params
 *
 * Return: 0 on success
 */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) || defined(WITH_BACKPORTS)
static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
				     struct net_device *dev,
				     struct ieee80211_txq_params *params)
{
	hdd_adapter_t *padapter = WLAN_HDD_GET_PRIV_PTR(dev);
	tHalHandle hal_ptr = WLAN_HDD_GET_HAL_CTX(padapter);
	tpAniSirGlobal pmac = PMAC_STRUCT(hal_ptr);
	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
	uint32_t hostapd_edca_local[] = {WNI_CFG_EDCA_HOSTAPD_ACVO_LOCAL,
					 WNI_CFG_EDCA_HOSTAPD_ACVI_LOCAL,
					 WNI_CFG_EDCA_HOSTAPD_ACBE_LOCAL,
					 WNI_CFG_EDCA_HOSTAPD_ACBK_LOCAL};
	int rc;
	struct cfg_hostapd_edca tmp;

	ENTER();

	memset(&tmp, 0 , sizeof(struct cfg_hostapd_edca));

	if (hdd_ctx->cfg_ini->enable_hostapd_edca_local) {
		rc = wlan_hdd_validate_context(hdd_ctx);
		if (0 != rc)
			return rc;

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

		if (params->ac >= MAX_NUM_AC) {
			hddLog(LOGE, "Wrong Params ac %d\r\n", params->ac);
			return -EINVAL;
		}

		tmp.aifs = params->aifs;
		tmp.cwmin = sirSwapU16(params->cwmin);
		tmp.cwmax = sirSwapU16(params->cwmax);
		tmp.txop = (uint8_t)params->txop;
		memcpy(&tmp.paramsb, (uint8_t *)(&tmp.cwmin), 5);
		memcpy(&tmp.paramsg, (uint8_t *)(&tmp.cwmin), 5);
		tmp.enable = 1;
		/* Store Hostapd EDCA params in cfg */
		cfgSetStr(pmac, hostapd_edca_local[params->ac], (uint8_t *)(&tmp),
			  sizeof(struct cfg_hostapd_edca));
	}
	return 0;
}
#else
static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
				     struct ieee80211_txq_params *params)
{
	ENTER();
	return 0;
}
#endif

/**
 * wlan_hdd_set_txq_params() - SSR wrapper for wlan_hdd_set_txq_params
 * @wiphy: pointer to wiphy
 * @netdev: pointer to net_device structure
 * @params: pointer to ieee80211_txq_params
 *
 * Return: 0 on success, error number on failure
 */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) || defined(WITH_BACKPORTS)
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;
}
#else
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 //LINUX_VERSION_CODE

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 = VOS_STATUS_E_FAILURE;
    hdd_hostapd_state_t *pHostapdState;
    int status;
    v_U8_t staId;

    ENTER();

    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 (VOS_FTM_MODE == hdd_get_conparam()) {
        hddLog(LOGE, FL("Command not allowed in FTM mode"));
        return -EINVAL;
    }

    if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
        (WLAN_HDD_P2P_GO == pAdapter->device_mode)) {

        pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
        if (!pHostapdState) {
            hddLog(VOS_TRACE_LEVEL_FATAL,
                  "%s: pHostapdState is Null", __func__);
            return 0;
        }

        if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
        {
            v_U16_t i;
            for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
                if ((pAdapter->aStaInfo[i].isUsed) &&
                    (!pAdapter->aStaInfo[i].isDeauthInProgress)) {
                    vos_mem_copy(pDelStaParams->peerMacAddr,
                                 pAdapter->aStaInfo[i].macAddrSTA.bytes,
                                 ETHER_ADDR_LEN);

#ifdef IPA_UC_OFFLOAD
                    if (pHddCtx->cfg_ini->IpaUcOffloadEnabled) {
                       hdd_ipa_wlan_evt(pAdapter, pAdapter->aStaInfo[i].ucSTAId,
                          WLAN_CLIENT_DISCONNECT, pDelStaParams->peerMacAddr);
                    }
#endif /* IPA_UC_OFFLOAD */
                    hddLog(VOS_TRACE_LEVEL_INFO,
                           FL("Delete STA with MAC::"MAC_ADDRESS_STR),
                           MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));

                    /* Case: SAP in ACS selected DFS ch and station connected.
                     * Now Radar detected. Then if random channel is another DFS
                     * ch then new CAC is initiated and no TX allowed. Thus
                     * do not send any mgmt frames as it will timeout during CAC
                     */
                    if (pHddCtx->dev_dfs_cac_status == DFS_CAC_IN_PROGRESS)
                        goto fn_end;

                    /* Send disassoc and deauth both to avoid some IOT issues */
                    vos_event_reset(&pHostapdState->sta_disassoc_event);

                    vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
                    if (VOS_IS_STATUS_SUCCESS(vos_status)) {
                        pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
                        vos_status = vos_wait_single_event(
                                            &pHostapdState->sta_disassoc_event, 1000);
                        if (!VOS_IS_STATUS_SUCCESS(vos_status))
                            hddLog(VOS_TRACE_LEVEL_ERROR,
                                "!!%s: ERROR: Deauth wait expired!!", __func__);
                    }
                    hdd_softap_sta_disassoc(pAdapter, pDelStaParams);
                }
            }
        } 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,
                       FL("Skip DEL STA as this is not used::"MAC_ADDRESS_STR),
                       MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
                return -ENOENT;
            }

#ifdef IPA_UC_OFFLOAD
            if (pHddCtx->cfg_ini->IpaUcOffloadEnabled) {
               hdd_ipa_wlan_evt(pAdapter, staId,
                  WLAN_CLIENT_DISCONNECT, pDelStaParams->peerMacAddr);
            }
#endif /* IPA_UC_OFFLOAD */

            if (pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE) {
                hddLog(VOS_TRACE_LEVEL_INFO,
                       FL("Skip DEL STA as deauth is in progress::"
                          MAC_ADDRESS_STR),
                          MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
                return -ENOENT;
            }

            pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;

            hddLog(VOS_TRACE_LEVEL_INFO,
                   FL("Delete STA with MAC::"MAC_ADDRESS_STR),
                   MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));

            if (pHddCtx->dev_dfs_cac_status == DFS_CAC_IN_PROGRESS)
                goto fn_end;

            /* Send disassoc and deauth both to avoid some IOT issues */
            vos_event_reset(&pHostapdState->sta_disassoc_event);
            sme_send_disassoc_req_frame(WLAN_HDD_GET_HAL_CTX(pAdapter),
                             pAdapter->sessionId,
                             (uint8_t *)pDelStaParams->peerMacAddr,
                             pDelStaParams->reason_code, 0);

            vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
            if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
                pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
                hddLog(VOS_TRACE_LEVEL_INFO,
                       FL("STA removal failed for ::"MAC_ADDRESS_STR),
                       MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
                return -ENOENT;
            } else {
                vos_status = vos_wait_single_event(
                    &pHostapdState->sta_disassoc_event, 1000);
                if (!VOS_IS_STATUS_SUCCESS(vos_status))
                    hddLog(VOS_TRACE_LEVEL_ERROR,
                        "!!%s: ERROR: Deauth wait expired!!", __func__);
            }
        }
    }

fn_end:
    EXIT();
    return 0;
}

#ifdef 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)) || defined(WITH_BACKPORTS)
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 CFG80211_DEL_STA_V2
    if (NULL == param) {
        hddLog(LOGE, FL("Invalid argument passed"));
        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,
                                           const u8 *mac,
                                           struct station_parameters *params)
{
    int status = -EPERM;
#ifdef FEATURE_WLAN_TDLS
#ifdef TRACE_RECORD
    hdd_adapter_t *pAdapter =  WLAN_HDD_GET_PRIV_PTR(dev);
#endif
    hdd_context_t *pHddCtx = wiphy_priv(wiphy);
    u32 mask, set;

    ENTER();

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

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_ADD_STA,
                     pAdapter->sessionId, params->listen_interval));

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

    mask = params->sta_flags_mask;
    set = params->sta_flags_set;

    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
              FL("mask 0x%x set 0x%x " MAC_ADDRESS_STR),
              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)) || defined(WITH_BACKPORTS)
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 CFG80211_FILS_SK_OFFLOAD_SUPPORT
/*
 * wlan_hdd_is_pmksa_valid: API to validate pmksa
 * @pmksa: pointer to cfg80211_pmksa structure
 *
 * Return: True if valid else false
 */
static inline bool wlan_hdd_is_pmksa_valid(struct cfg80211_pmksa *pmksa)
{
    if (pmksa->bssid || (pmksa->ssid && pmksa->cache_id) ){
        return true;
    }
    else
    {
        hddLog(LOGE, FL(" Either of  bssid (%pK) ssid (%pK) or cache_id (%pK) are NULL"),
                pmksa->bssid, pmksa->ssid, pmksa->cache_id);
        return false;
    }
}

/*
 * hdd_update_pmksa_info: API to update tPmkidCacheInfo from cfg80211_pmksa
 * @pmk_cache: pmksa from supplicant
 * @pmk_cache: pmk needs to be updated
 *
 * Return: None
 */
static void hdd_update_pmksa_info(tPmkidCacheInfo *pmk_cache,
        struct cfg80211_pmksa *pmksa, bool is_delete)
{
    if (pmksa->bssid) {
        hddLog(VOS_TRACE_LEVEL_DEBUG,"set PMKSA for " MAC_ADDRESS_STR,
                MAC_ADDR_ARRAY(pmksa->bssid));
        vos_mem_copy(pmk_cache->BSSID,
                pmksa->bssid, VOS_MAC_ADDR_SIZE);
    } else {
        vos_mem_copy(pmk_cache->ssid, pmksa->ssid,
                SIR_MAC_MAX_SSID_LENGTH);
        vos_mem_copy(pmk_cache->cache_id, pmksa->cache_id, CACHE_ID_LEN);
        pmk_cache->ssid_len = pmksa->ssid_len;
        hddLog(VOS_TRACE_LEVEL_INFO, "set PMKSA for ssid %*.*s cache_id %x %x",
                pmk_cache->ssid_len, pmk_cache->ssid_len,
                pmksa->ssid, pmksa->cache_id[0], pmksa->cache_id[1]);
   }

    if (is_delete)
        return;

    vos_mem_copy(pmk_cache->PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
    if (pmksa->pmk_len && (pmksa->pmk_len <= CSR_RSN_MAX_PMK_LEN)) {
        vos_mem_copy(pmk_cache->pmk, pmksa->pmk, pmksa->pmk_len);
        pmk_cache->pmk_len = pmksa->pmk_len;
    } else
        hddLog(VOS_TRACE_LEVEL_INFO, "pmk len is %zu", pmksa->pmk_len);
}
#else
/*
 * wlan_hdd_is_pmksa_valid: API to validate pmksa
 * @pmksa: pointer to cfg80211_pmksa structure
 *
 * Return: True if valid else false
 */
static inline bool wlan_hdd_is_pmksa_valid(struct cfg80211_pmksa *pmksa)
{
    if (!pmksa->bssid) {
        hddLog(LOGE,FL("both bssid is NULL %pK"), pmksa->bssid);
        return false;
    }
    return true;
}

/*
 * hdd_update_pmksa_info: API to update tPmkidCacheInfo from cfg80211_pmksa
 * @pmk_cache: pmksa from supplicant
 * @pmk_cache: pmk needs to be updated
 *
 * Return: None
 */
static void hdd_update_pmksa_info(tPmkidCacheInfo *pmk_cache,
        struct cfg80211_pmksa *pmksa, bool is_delete)
{
    hddLog(VOS_TRACE_LEVEL_INFO,"set PMKSA for " MAC_ADDRESS_STR,
            MAC_ADDR_ARRAY(pmksa->bssid));
    vos_mem_copy(pmk_cache->BSSID,
            pmksa->bssid, VOS_MAC_ADDR_SIZE);

    if (is_delete)
        return;

    vos_mem_copy(pmk_cache->PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
}
#endif

#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);
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    tHalHandle halHandle;
    eHalStatus result = eHAL_STATUS_SUCCESS;
    int status;
    tPmkidCacheInfo pmk_cache;

    ENTER();

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

    if (!pmksa) {
        hddLog(LOGE, FL("pmksa is NULL"));
        return -EINVAL;
    }

    if (!pmksa->pmkid) {
        hddLog(LOGE, FL("pmksa->pmkid(%pK) is NULL"),
               pmksa->pmkid);
        return -EINVAL;
    }

    if (!wlan_hdd_is_pmksa_valid(pmksa))
        return -EINVAL;

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

    halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);

    vos_mem_zero(&pmk_cache, sizeof(pmk_cache));

    hdd_update_pmksa_info(&pmk_cache, pmksa, false);

    /* Add to the PMKSA ID Cache in CSR
     * PMKSA cache will be having following
     * 1. pmkid id
     * 2. pmk 15733
     * 3. bssid or cache identifier
    */
   result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
                                   &pmk_cache, 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);
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    tHalHandle halHandle;
    int status = 0;
    tPmkidCacheInfo pmk_cache;

    ENTER();

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

    if (!pmksa) {
        hddLog(LOGE, FL("pmksa is NULL"));
        return -EINVAL;
    }

    if (!wlan_hdd_is_pmksa_valid(pmksa))
        return -EINVAL;

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

    halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);

    MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
                                      pAdapter->sessionId, 0));

    vos_mem_zero(&pmk_cache, sizeof(pmk_cache));

    hdd_update_pmksa_info(&pmk_cache, pmksa, true);

    /* Delete the PMKID CSR cache */
    if (eHAL_STATUS_SUCCESS !=
        sme_RoamDelPMKIDfromCache(halHandle,
                                  pAdapter->sessionId, &pmk_cache, 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);
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    tHalHandle halHandle;
    int status = 0;

    ENTER();

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

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

    /* 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_context_t *hdd_ctx = wiphy_priv(wiphy);
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    int status;

    status = wlan_hdd_validate_context(hdd_ctx);
    if (status)
        return status;

    ENTER();

    if (VOS_FTM_MODE == hdd_get_conparam()) {
        hddLog(LOGE, FL("Command not allowed in FTM mode"));
        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(LOG1, 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

int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
{
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    hdd_scaninfo_t *pScanInfo = NULL;
    unsigned long rc;

    pScanInfo = &pAdapter->scan_info;

    if (pScanInfo->mScanPending && pAdapter->request)
    {
        INIT_COMPLETION(pScanInfo->abortscan_event_var);
        hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
                           eCSR_SCAN_ABORT_DEFAULT);

        rc = wait_for_completion_timeout(
                           &pScanInfo->abortscan_event_var,
                           msecs_to_jiffies(5000));
        if (!rc) {
           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Timeout occurred while waiting for abort scan" ,
                  __func__);
            return -ETIME;
        }
    }
    return 0;
}

#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
         * immediately 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, 0);
    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
            "%s: cfg80211 scan result database updated", __func__);
}

#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)
{
	if (request->n_scan_plans == 2) {
		pno_req->fast_scan_period =
			request->scan_plans[0].interval * MSEC_PER_SEC;
		pno_req->fast_scan_max_cycles =
			request->scan_plans[0].iterations;
		pno_req->slow_scan_period =
			request->scan_plans[1].interval * MSEC_PER_SEC;
		hddLog(LOGE, "Base scan interval: %d sec, scan cycles: %d, slow scan interval %d",
		       request->scan_plans[0].interval,
		       request->scan_plans[0].iterations,
		       request->scan_plans[1].interval);
	} else if (request->n_scan_plans == 1) {
		pno_req->fast_scan_period = request->scan_plans[0].interval *
			MSEC_PER_SEC;
		pno_req->fast_scan_max_cycles = 1;
		pno_req->slow_scan_period = request->scan_plans[0].interval *
			MSEC_PER_SEC;
	} else {
		hddLog(LOGE, "Invalid number of scan plans %d !!",
		       request->n_scan_plans);
	}
}
#else
static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
				struct cfg80211_sched_scan_request *request,
				hdd_context_t *hdd_ctx)
{
	pno_req->fast_scan_period = request->interval;
	pno_req->fast_scan_max_cycles =
		hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
	pno_req->slow_scan_period =
		hdd_ctx->cfg_ini->pno_slow_scan_multiplier *
		pno_req->fast_scan_period;
	hddLog(LOGE, "Base scan interval: %d sec PNOScanTimerRepeatValue: %d",
		    (request->interval / 1000),
		    hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
}
#endif

/**
 * wlan_hdd_sched_scan_update_relative_rssi() - update CPNO params
 * @pno_request: pointer to PNO scan request
 * @request: Pointer to cfg80211 scheduled scan start request
 *
 * This function is used to update Connected PNO params sent by kernel
 *
 * Return: None
 */
#if defined(CFG80211_REPORT_BETTER_BSS_IN_SCHED_SCAN)
static inline void wlan_hdd_sched_scan_update_relative_rssi(
			tpSirPNOScanReq pno_request,
			struct cfg80211_sched_scan_request *request)
{
	pno_request->relative_rssi_set = request->relative_rssi_set;
	pno_request->relative_rssi = request->relative_rssi;
	if (NL80211_BAND_2GHZ == request->rssi_adjust.band)
		pno_request->band_rssi_pref.band = SIR_BAND_2_4_GHZ;
	else if (NL80211_BAND_5GHZ == request->rssi_adjust.band)
		pno_request->band_rssi_pref.band = SIR_BAND_5_GHZ;
	pno_request->band_rssi_pref.rssi = request->rssi_adjust.delta;
}
#else
static inline void wlan_hdd_sched_scan_update_relative_rssi(
			tpSirPNOScanReq pno_request,
			struct cfg80211_sched_scan_request *request)
{
}
#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);
    tpSirPNOScanReq pPnoRequest = NULL;
    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_scaninfo_t *pScanInfo = &pAdapter->scan_info;
    hdd_config_t *config = NULL;
    v_U32_t num_ignore_dfs_ch = 0;
    hdd_station_ctx_t *station_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

    ENTER();

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

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

    config = 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;
    }

    if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
        (eConnectionState_Connecting ==
           (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: %pK(%d) Connection in progress: sched_scan_start denied (EBUSY)",
               __func__,
                WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
        return -EBUSY;
    }

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
                     pAdapter->sessionId, pAdapter->device_mode));
    /*
     * The current umac is unable to handle the SCAN_PREEMPT and SCAN_DEQUEUED
     * so its necessary to terminate the existing scan which is already issued
     * otherwise the host won't enter into the suspend state due to the reason
     * that the wlan wakelock which was held in the wlan_hdd_cfg80211_scan
     * function.
     */
    if (TRUE == pScanInfo->mScanPending)
    {
        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 unsuccessful", __func__);
            return -EBUSY;
        }
    }

    if (!hdd_connIsConnected(station_ctx) &&
        pHddCtx->cfg_ini->probe_req_ie_whitelist)
        pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof(tSirPNOScanReq) +
                                    (pHddCtx->no_of_probe_req_ouis) *
                                    (sizeof(struct vendor_oui)));
    else
        pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof(tSirPNOScanReq));

    if (NULL == pPnoRequest)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                  "%s: vos_mem_malloc failed", __func__);
        return -ENOMEM;
    }

    if (!hdd_connIsConnected(station_ctx) &&
        pHddCtx->cfg_ini->probe_req_ie_whitelist)
        memset(pPnoRequest, 0, sizeof (tSirPNOScanReq) +
               (pHddCtx->no_of_probe_req_ouis) *
               (sizeof(struct vendor_oui)));
    else
        memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));

    pPnoRequest->enable = 1; /*Enable PNO */
    pPnoRequest->ucNetworksCount = request->n_match_sets;
    if ((!pPnoRequest->ucNetworksCount ) ||
        (pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 "%s: Network input is not correct %d",
                 __func__, pPnoRequest->ucNetworksCount);
        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 ((!config->enable_dfs_pno_chnl_scan) &&
                      (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;
                    }

                    if (!vos_is_dsrc_channel(vos_chan_to_freq(
                        request->channels[i]->hw_value))) {
                       valid_ch[num_ch++] = request->channels[i]->hw_value;
                       len += snprintf(chList+len, 5, "%d ",
                                       request->channels[i]->hw_value);
                    }
                    break ;
                }
             }
         }

         if (!num_ch) {
             VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                 "%s : Channel list empty due to filtering of DSRC,DFS channels",
                 __func__);
             ret = -EINVAL;
             goto error;
         }

         hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
    }

    /* Filling per profile  params */
    for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
    {
        pPnoRequest->aNetworks[i].ssId.length =
               request->match_sets[i].ssid.ssid_len;

        if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
            ( pPnoRequest->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__, pPnoRequest->aNetworks[i].ssId.length, i);
            ret = -EINVAL;
            goto error;
        }

        memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
               request->match_sets[i].ssid.ssid,
               request->match_sets[i].ssid.ssid_len);
        pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
        pPnoRequest->aNetworks[i].encryption     = 0; /*eED_ANY*/
        pPnoRequest->aNetworks[i].bcastNetwType  = 0; /*eBCAST_UNKNOWN*/

        /*Copying list of valid channel into request */
        memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
        pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) || defined(WITH_BACKPORTS)
        pPnoRequest->aNetworks[i].rssiThreshold =
                                    request->match_sets[i].rssi_thold;
#else
        pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
#endif
    }
    /* set scan to passive if no SSIDs are specified in the request */
    if (0 == request->n_ssids)
       pPnoRequest->do_passive_scan = true;
    else
       pPnoRequest->do_passive_scan = false;

    for (i = 0; i < request->n_ssids; i++) {
        j = 0;
        while (j < pPnoRequest->ucNetworksCount) {
            if ((pPnoRequest->aNetworks[j].ssId.length ==
                 request->ssids[i].ssid_len) &&
                (0 == memcmp(pPnoRequest->aNetworks[j].ssId.ssId,
                            request->ssids[i].ssid,
                            pPnoRequest->aNetworks[j].ssId.length))) {
                pPnoRequest->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);
    if ((request->ie_len > 0 && request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
        (NULL != request->ie)) {
        pPnoRequest->us24GProbeTemplateLen = request->ie_len;
        memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
                pPnoRequest->us24GProbeTemplateLen);

        pPnoRequest->us5GProbeTemplateLen = request->ie_len;
        memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
                pPnoRequest->us5GProbeTemplateLen);
    }

    hdd_config_sched_scan_plan(pPnoRequest, request, pHddCtx);
    wlan_hdd_sched_scan_update_relative_rssi(pPnoRequest, request);

    pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;

    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
             "SessionId %d, enable %d, modePNO %d",
             pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO);

    wlan_hdd_update_scan_rand_attrs((void *)pPnoRequest, (void *)request,
                                    WLAN_HDD_PNO_SCAN);

    if (pHddCtx->cfg_ini->probe_req_ie_whitelist &&
        !hdd_connIsConnected(station_ctx))
        wlan_hdd_fill_whitelist_ie_attrs(&pPnoRequest->ie_whitelist,
                                         pPnoRequest->probe_req_ie_bitmap,
                                         &pPnoRequest->num_vendor_oui,
                                         (struct vendor_oui *)(
                                         (uint8_t *)pPnoRequest +
                                         sizeof(*pPnoRequest)),
                                         pHddCtx);

    status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
                              pPnoRequest, 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;
    }

    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  "PNO scanRequest offloaded");

error:
    vos_mem_free(pPnoRequest);
    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
 */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
          struct net_device *dev, u64 reqid)
#else
static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
          struct net_device *dev)
#endif
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx;
    tHalHandle hHal;
    tpSirPNOScanReq pPnoRequest = NULL;
    int ret = 0;

    ENTER();

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

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

    /* 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__);
        return ret;
    }

    if ((pHddCtx->isLoadInProgress) ||
        (pHddCtx->isUnloadInProgress))
    {
        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;
    }

    pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
    if (NULL == pPnoRequest)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                   "%s: vos_mem_malloc failed", __func__);
        return -ENOMEM;
    }

    memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
    pPnoRequest->enable = 0; /* Disable PNO */
    pPnoRequest->ucNetworksCount = 0;


    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
                     pAdapter->sessionId, pAdapter->device_mode));
    status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
                                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;
    }

    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                   "%s: PNO scan disabled", __func__);

    vos_mem_free(pPnoRequest);

    EXIT();
    return ret;
}

/*
 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
 * NL interface to disable PNO
 */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
          struct net_device *dev, u64 reqid)
#else
static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
          struct net_device *dev)
#endif
{
    int ret;

    vos_ssr_protect(__func__);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
    ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev, reqid);
#else
    ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
#endif
    vos_ssr_unprotect(__func__);

    return ret;
}
#endif /*FEATURE_WLAN_SCAN_PNO*/

#ifdef FEATURE_WLAN_TDLS

/**
 * __wlan_hdd_cfg80211_tdls_mgmt() - cfg80211 tdls mgmt handler function
 * @wiphy: Pointer to wiphy structure.
 * @dev: Pointer to net_device structure.
 * @peer: peer address
 * @action_code: action code
 * @dialog_token: dialog token
 * @status_code: status code
 * @peer_capability: peer capability
 * @buf: buffer
 * @len: Length of @buf
 *
 * Return: 0 for success, error number on failure.
 */
#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 = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx = wiphy_priv(wiphy);
    hdd_station_ctx_t *pHddStaCtx = NULL;
    VOS_STATUS status;
    int max_sta_failed = 0;
    int responder;
    unsigned long rc;
    tANI_U16 numCurrTdlsPeers;
#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
    u32 peer_capability;
    peer_capability = 0;
#endif
    tdlsCtx_t *pHddTdlsCtx;

    MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                     TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
                     pAdapter->sessionId, action_code));

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

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

    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__);
    }

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

    /* If any concurrency is detected */
    if (((1 << VOS_STA_MODE) != pHddCtx->concurrency_mode) ||
        (pHddCtx->no_of_active_sessions[VOS_STA_MODE] > 1)) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
                  FL("Multiple STA OR Concurrency detected. Ignore TDLS MGMT frame. action_code=%d, concurrency_mode: 0x%x, active_sessions: %d"),
                  action_code,
                  pHddCtx->concurrency_mode,
                  pHddCtx->no_of_active_sessions[VOS_STA_MODE]);
        return -EPERM;
    }
    /* other than teardown frame, 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_ERROR,
                        "%s: " MAC_ADDRESS_STR
                        " TDLS mode is disabled. action %d declined.",
                        __func__, MAC_ADDR_ARRAY(peer), action_code);

             return -ENOTSUPP;
        } else if (pHddCtx->tdls_nss_switch_in_progress) {
             hddLog(LOGE,
                    FL("TDLS antenna switch in progress, action %d declined for "
                    MAC_ADDRESS_STR), action_code, MAC_ADDR_ARRAY(peer));
             return -EAGAIN;
        }
    }
    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;
        }
    }
    /* Discard TDLS Discovery request and setup confirm if violates ACM rules */
    if ((SIR_MAC_TDLS_DIS_REQ == action_code || SIR_MAC_TDLS_SETUP_CNF == action_code) &&
        (hdd_wmm_is_active(pAdapter)) &&
        !(pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VI].wmmAcAccessAllowed))
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Admission control is set to VI, action %d is not allowed.",
                  __func__, 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 (pHddCtx->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 addition 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, pHddCtx->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, pHddCtx->max_num_tdls_sta);
                max_sta_failed = -EPERM;
                /* fall through to send setup resp with failure status
                code */
            }
        }
        else
        {
            hddTdlsPeer_t *pTdlsPeer;
            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)
    {

       hddTdlsPeer_t *pTdlsPeer;
       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);
    }

    /* 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))
    {
        /* Fw will take care if PS offload is enabled. */
        if (!pHddCtx->cfg_ini->enablePowersaveOffload)
        {
            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) && (pHddTdlsCtx != NULL))
                    pHddTdlsCtx->is_tdls_disabled_bmps = true;
            }
        }
        if (SIR_MAC_TDLS_DIS_REQ != action_code)
            wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
    }

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

    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;

        wlan_hdd_tdls_check_bmps(pAdapter);
        return -EINVAL;
    }

    if (SIR_MAC_TDLS_TEARDOWN == action_code &&
        pHddCtx->tdls_nss_switch_in_progress) {
        mutex_lock(&pHddCtx->tdls_lock);
        if (pHddCtx->tdls_teardown_peers_cnt != 0)
            pHddCtx->tdls_teardown_peers_cnt--;
        if (pHddCtx->tdls_teardown_peers_cnt == 0) {
            if (pHddCtx->tdls_nss_transition_mode ==
                TDLS_NSS_TRANSITION_1x1_to_2x2) {
                /* TDLS NSS switch is fully completed, so reset the flags */
                hddLog(LOG1, FL("TDLS NSS switch is fully completed"));
                pHddCtx->tdls_nss_switch_in_progress = false;
                pHddCtx->tdls_nss_teardown_complete = false;
            } else {
               /* TDLS NSS switch is not yet completed, but tdls teardown
                * is completed for all the peers.
                */
                hddLog(LOG1,
                       FL("TDLS NSS switch is not completed, but teardown completed for all peers"
                       ));
                pHddCtx->tdls_nss_teardown_complete = true;
            }
        }
        mutex_unlock(&pHddCtx->tdls_lock);
    }

    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_timeout(&pAdapter->tdls_mgmt_comp,
                                       msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));

    if ((0 == rc) || (TRUE != pAdapter->mgmtTxCompletionStatus)) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: %s rc %ld mgmtTxCompletionStatus %u",
                  __func__,
                  !rc ? "Mgmt Tx Completion timed out" :"Mgmt Tx Completion failed",
                  rc, pAdapter->mgmtTxCompletionStatus);

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

        if (pHddCtx->isUnloadInProgress)
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
            return -EAGAIN;
        }
        if (rc <= 0)
            vos_flush_logs(WLAN_LOG_TYPE_FATAL,
                           WLAN_LOG_INDICATOR_HOST_DRIVER,
                           WLAN_LOG_REASON_HDD_TIME_OUT,
                           DUMP_VOS_TRACE);
        pAdapter->mgmtTxCompletionStatus = FALSE;
        wlan_hdd_tdls_check_bmps(pAdapter);
        return -EINVAL;
    } 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)
    {
      wlan_hdd_tdls_check_bmps(pAdapter);
      return max_sta_failed;
    }

    if (SIR_MAC_TDLS_SETUP_RSP == action_code)
    {
        return wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE);
    }
    else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
    {
        return wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE);
    }

    return 0;
}

/**
 * wlan_hdd_cfg80211_tdls_mgmt() - cfg80211 tdls mgmt handler function
 * @wiphy: Pointer to wiphy structure.
 * @dev: Pointer to net_device structure.
 * @peer: peer address
 * @action_code: action code
 * @dialog_token: dialog token
 * @status_code: status code
 * @peer_capability: peer capability
 * @buf: buffer
 * @len: Length of @buf
 *
 * This is the cfg80211 tdls mgmt handler function which invokes
 * the internal function @__wlan_hdd_cfg80211_tdls_mgmt with
 * SSR protection.
 *
 * Return: 0 for success, error number on failure.
 */
#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
{
	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,
                                      const u8 *peer,
                                      cfg80211_exttdls_callback callback,
                                      u32 chan,
                                      u32 max_latency,
                                      u32 op_class,
                                      u32 min_bandwidth)
{
    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_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 or Implicit Trigger not enabled ",
              __func__);
        return -ENOTSUPP;
    }

    /* To cater the requirement of establishing the TDLS link
     * irrespective of the data traffic , get an entry of TDLS peer.
     */
    pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer, TRUE);
    if (pTdlsPeer == NULL) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: peer " MAC_ADDRESS_STR " does not exist",
                  __func__, MAC_ADDR_ARRAY(peer));
        return -EINVAL;
    }

    if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {

        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
              "%s TDLS Add Force Peer Failed",
              __func__);
        return -EINVAL;
    }

    /* Update the peer mac to firmware, so firmware
     * could update the connection table
     */
    if (0 != wlan_hdd_tdls_update_peer_mac(pAdapter, peer,
        eSME_TDLS_PEER_ADD_MAC_ADDR)) {
        hddLog(LOGE, FL("TDLS Peer mac update Failed "
               MAC_ADDRESS_STR), MAC_ADDR_ARRAY(peer));
        return -EINVAL;
    }

    /* validate if off channel is DFS channel */
    if (VOS_IS_DFS_CH(chan)) {
        hddLog(LOGE,
               FL("Resetting TDLS off-channel from %d to %d"),
               chan, CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEFAULT);
        chan = CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEFAULT;
    }

    if ( 0 != wlan_hdd_tdls_set_extctrl_param(pAdapter, peer,
                                              chan, max_latency,
                                              op_class, min_bandwidth) ) {

        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
              "%s TDLS Set Peer's External Ctrl Parameter Failed",
              __func__);
        return -EINVAL;
    }

    if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
              "%s TDLS set callback Failed",
              __func__);
        return -EINVAL;
    }

    return(0);
}

int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, const u8 *peer)
{
    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 ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
         (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {

        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
              "%s TDLS External control or Implicit Trigger not enabled ",
              __func__);
        return -ENOTSUPP;
    }


    pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);

    if ( NULL == pTdlsPeer ) {
        hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
               "peer matching MAC_ADDRESS_STR not found",
               __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 (0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE)) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
              "%s Failed",
              __func__);
        return -EINVAL;
    }

    /* Update the peer mac to firmware, so firmware
     * could update the connection table
     */
    if (0 != wlan_hdd_tdls_update_peer_mac(pAdapter, peer,
        eSME_TDLS_PEER_REMOVE_MAC_ADDR)) {
        hddLog(LOGE, FL("TDLS Peer mac update Failed "
               MAC_ADDRESS_STR), MAC_ADDR_ARRAY(peer));
        return -EINVAL;
    }

    /* EXT TDLS */
    if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {

        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
              "%s TDLS set callback Failed",
              __func__);
        return -EINVAL;
    }
    return(0);
}

static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy,
                                         struct net_device *dev,
                                         const u8 *peer,
                                         enum nl80211_tdls_operation oper)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx = wiphy_priv(wiphy);
    int status;
    tSmeTdlsPeerStateParams smeTdlsPeerStateParams;
    eHalStatus halStatus = eHAL_STATUS_FAILURE;
    hddTdlsPeer_t *pTdlsPeer;

    ENTER();

    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 (VOS_FTM_MODE == hdd_get_conparam()) {
        hddLog(LOGE, FL("Command not allowed in FTM mode"));
        return -EINVAL;
    }

    /* QCA 2.0 Discrete ANDs feature capability in cfg_ini with that
     * received from target, so cfg_ini gives combined intersected result
     */
    if (FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "TDLS Disabled in INI OR not enabled in FW. "
                "Cannot process TDLS commands");
        return -ENOTSUPP;
    }

    switch (oper) {
        case NL80211_TDLS_ENABLE_LINK:
            {
                VOS_STATUS status;
                unsigned long rc;
                tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
                                                0, 0, 0, 0, 0, 0, {0}, 0, {0} };
                pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);

                if (NULL == pTdlsPeer)
                {
                    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                               "%s: peer matching "MAC_ADDRESS_STR
                               " not found, ignore NL80211_TDLS_ENABLE_LINK",
                                __func__, MAC_ADDR_ARRAY(peer));
                    return -EINVAL;
                }

                VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                           "%s: NL80211_TDLS_ENABLE_LINK for peer "
                           MAC_ADDRESS_STR" link_status: %d",
                           __func__, MAC_ADDR_ARRAY(peer),
                           pTdlsPeer->link_status);

                if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
                {
                    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                               "%s: invalid sta index %u for "
                                MAC_ADDRESS_STR" TDLS_ENABLE_LINK failed",
                                __func__, pTdlsPeer->staId,
                                MAC_ADDR_ARRAY(peer));
                    return -EINVAL;
                }
                wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
                vos_mem_set(&tdlsLinkEstablishParams,
                            sizeof(tCsrTdlsLinkEstablishParams), 0);

                if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
                {
                    if (IS_ADVANCE_TDLS_ENABLE) {

                        if (0 != wlan_hdd_tdls_get_link_establish_params(
                                   pAdapter, peer, &tdlsLinkEstablishParams))
                            return -EINVAL;

                        INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);

                        sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                                        pAdapter->sessionId,
                                                        peer,
                                                        &tdlsLinkEstablishParams);
                        /* Send TDLS peer UAPSD capabilities to the firmware and
                         * register with the TL on after the response for this operation
                         * is received .
                         */
                        rc = wait_for_completion_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 (!pTdlsPeer) {
                            mutex_unlock(&pHddCtx->tdls_lock);
                            hddLog(LOGE, FL(MAC_ADDRESS_STR" (oper %d) peer got freed in other context. ignored"),
                                         MAC_ADDR_ARRAY(peer), (int)oper);
                            return -EINVAL;
                        }
                        mutex_unlock(&pHddCtx->tdls_lock);

                        if ((rc <= 0) || (pTdlsPeer->link_status ==
                                                eTDLS_LINK_TEARING)) {
                            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                              "%s: Link Establish Request timed out", __func__);
                            return -EINVAL;
                        }
                    }
                    wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
                                                       eTDLS_LINK_CONNECTED,
                                                       eTDLS_LINK_SUCCESS,
                                                       TRUE);

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

                    /* start TDLS client registration with TL */
                    status = hdd_roamRegisterTDLSSTA(pAdapter, peer,
                                                     pTdlsPeer->staId,
                                                     pTdlsPeer->signature,
                                                     pTdlsPeer->qos);
                    if (VOS_STATUS_SUCCESS == status)
                    {
                        tANI_U8 i;

                        vos_mem_zero(&smeTdlsPeerStateParams,
                                     sizeof(tSmeTdlsPeerStateParams));

                        smeTdlsPeerStateParams.vdevId = pAdapter->sessionId;
                        vos_mem_copy(&smeTdlsPeerStateParams.peerMacAddr,
                                     &pTdlsPeer->peerMac,
                                     sizeof(tSirMacAddr));
                        smeTdlsPeerStateParams.peerState =
                            eSME_TDLS_PEER_STATE_CONNECTED;
                        smeTdlsPeerStateParams.peerCap.isPeerResponder =
                            pTdlsPeer->is_responder;
                        smeTdlsPeerStateParams.peerCap.peerUapsdQueue =
                            pTdlsPeer->uapsdQueues;
                        smeTdlsPeerStateParams.peerCap.peerMaxSp =
                            pTdlsPeer->maxSp;
                        smeTdlsPeerStateParams.peerCap.peerBuffStaSupport =
                            pTdlsPeer->isBufSta;
                        smeTdlsPeerStateParams.peerCap.peerOffChanSupport =
                            pTdlsPeer->isOffChannelSupported;
                        smeTdlsPeerStateParams.peerCap.peerCurrOperClass = 0;
                        smeTdlsPeerStateParams.peerCap.selfCurrOperClass = 0;
                        smeTdlsPeerStateParams.peerCap.peerChanLen =
                            pTdlsPeer->supported_channels_len;
                        smeTdlsPeerStateParams.peerCap.prefOffChanNum =
                            pTdlsPeer->pref_off_chan_num;
                        smeTdlsPeerStateParams.peerCap.prefOffChanBandwidth =
                            pHddCtx->cfg_ini->fTDLSPrefOffChanBandwidth;
                        smeTdlsPeerStateParams.peerCap.opClassForPrefOffChan =
                            pTdlsPeer->op_class_for_pref_off_chan;

                        if (VOS_IS_DFS_CH(
                              smeTdlsPeerStateParams.peerCap.prefOffChanNum)) {
                            hddLog(LOGE,
                                 FL("Resetting TDLS off-channel from %d to %d"),
                                 smeTdlsPeerStateParams.peerCap.prefOffChanNum,
                                 CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEFAULT);
                            smeTdlsPeerStateParams.peerCap.prefOffChanNum =
                                CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEFAULT;
                        }

                        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                           "%s: Peer " MAC_ADDRESS_STR " vdevId: %d, peerState: %d, isPeerResponder: %d, uapsdQueues: 0x%x, maxSp: 0x%x, peerBuffStaSupport: %d, peerOffChanSupport: %d, peerCurrOperClass: %d, selfCurrOperClass: %d, peerChanLen: %d, peerOperClassLen: %d, prefOffChanNum: %d, prefOffChanBandwidth: %d, op_class_for_pref_off_chan: %d",
                              __func__, MAC_ADDR_ARRAY(peer),
                           smeTdlsPeerStateParams.vdevId,
                           smeTdlsPeerStateParams.peerState,
                           smeTdlsPeerStateParams.peerCap.isPeerResponder,
                           smeTdlsPeerStateParams.peerCap.peerUapsdQueue,
                           smeTdlsPeerStateParams.peerCap.peerMaxSp,
                           smeTdlsPeerStateParams.peerCap.peerBuffStaSupport,
                           smeTdlsPeerStateParams.peerCap.peerOffChanSupport,
                           smeTdlsPeerStateParams.peerCap.peerCurrOperClass,
                           smeTdlsPeerStateParams.peerCap.selfCurrOperClass,
                           smeTdlsPeerStateParams.peerCap.peerChanLen,
                           smeTdlsPeerStateParams.peerCap.peerOperClassLen,
                           smeTdlsPeerStateParams.peerCap.prefOffChanNum,
                           smeTdlsPeerStateParams.peerCap.prefOffChanBandwidth,
                           pTdlsPeer->op_class_for_pref_off_chan);

                        for (i = 0; i < pTdlsPeer->supported_channels_len; i++)
                        {
                            smeTdlsPeerStateParams.peerCap.peerChan[i] =
                                pTdlsPeer->supported_channels[i];
                        }
                        smeTdlsPeerStateParams.peerCap.peerOperClassLen =
                            pTdlsPeer->supported_oper_classes_len;
                        for (i = 0; i < pTdlsPeer->supported_oper_classes_len; i++)
                        {
                            smeTdlsPeerStateParams.peerCap.peerOperClass[i] =
                                pTdlsPeer->supported_oper_classes[i];
                        }

                        halStatus = sme_UpdateTdlsPeerState(pHddCtx->hHal,
                                                      &smeTdlsPeerStateParams);
                        if (eHAL_STATUS_SUCCESS != halStatus)
                        {
                           VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                                     "%s: sme_UpdateTdlsPeerState failed for "
                                     MAC_ADDRESS_STR,
                                     __func__, MAC_ADDR_ARRAY(peer));
                           return -EPERM;
                        }
                        wlan_hdd_tdls_increment_peer_count(pAdapter);
                    }
                    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,
                                                               1,
                                                               pAdapter->sessionId );
                        }
                    }
                }
                hdd_wlan_tdls_enable_link_event(peer,
                           pTdlsPeer->isOffChannelSupported,
                           0, 0);
            }
            break;
        case NL80211_TDLS_DISABLE_LINK:
            {
                pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);

                if ( NULL == pTdlsPeer ) {
                    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                               "%s: peer matching "MAC_ADDRESS_STR
                               " not found, ignore NL80211_TDLS_DISABLE_LINK",
                                __func__, MAC_ADDR_ARRAY(peer));
                    return -EINVAL;
                }

                VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                           "%s: NL80211_TDLS_DISABLE_LINK for peer "
                            MAC_ADDRESS_STR " link_status: %d",
                            __func__, MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status);

                if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
                {
                    unsigned long rc;

                    INIT_COMPLETION(pAdapter->tdls_del_station_comp);

                    sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
                            pAdapter->sessionId, peer);

                    rc = wait_for_completion_timeout(&pAdapter->tdls_del_station_comp,
                              msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
                    if (!rc) {
                        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                                  "%s: Del station timed out", __func__);
                        return -EPERM;
                    }
                    wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
                                eTDLS_LINK_IDLE,
                                (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
                                eTDLS_LINK_UNSPECIFIED:
                                eTDLS_LINK_DROPPED_BY_REMOTE,
                                TRUE);
                }
                else
                {
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                              "%s: TDLS Peer Station doesn't exist.", __func__);
                }
            }
            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, pHddCtx->cfg_ini->fTDLSPrefOffChanNum,
                             0, 0, 0);
                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;
}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0)) || defined(WITH_BACKPORTS)
static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy,
                                       struct net_device *dev,
                                       const u8 *peer,
                                       enum nl80211_tdls_operation oper)
#else
static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy,
                                       struct net_device *dev,
                                       u8 *peer,
                                       enum nl80211_tdls_operation oper)
#endif
{
    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)) || defined(WITH_BACKPORTS)
    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 /* KERNEL_VERSION */

#endif
}
#endif

#ifdef WLAN_FEATURE_GTK_OFFLOAD
/*
 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
 * Callback routine 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();

    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;

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

    pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    if (NULL == hHal){
        hddLog(LOGE, FL("HAL context is Null!!!"));
        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,
          VOS_MAC_ADDR_SIZE);
    {
        /* 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) {
            hddLog(LOGE, FL("sme_SetGTKOffload failed, status(%d)"), status);
            return -EINVAL;
        }
        hddLog(LOG1, FL("sme_SetGTKOffload successful"));
    } else {
        hddLog(LOG1, FL("wlan not suspended GTKOffload request is stored"));
    }
    EXIT();
    return result;
}

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

/**
 * __wlan_hdd_cfg80211_set_mac_acl() - Set access control policy
 * @wiphy: pointer to wiphy structure
 * @dev: pointer to net_device
 * @params: pointer to cfg80211_acl_data
 *
 * Return; 0 on success, error number otherwise
 */
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;
    VOS_STATUS vos_status = VOS_STATUS_SUCCESS;

    ENTER();

    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;

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

    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));
            }
        }

#ifdef WLAN_FEATURE_MBSSID
        vos_status = WLANSAP_SetMacACL(WLAN_HDD_GET_SAP_CTX_PTR(pAdapter), pConfig);
#else
        vos_status = WLANSAP_SetMacACL(pVosContext, pConfig);
#endif
        if (!VOS_IS_STATUS_SUCCESS(vos_status))
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                       "%s: SAP Set Mac Acl fail", __func__);
            return -EINVAL;
        }
    } else {
        hddLog(LOGE, FL("Invalid device_mode %s(%d)"),
               hdd_device_mode_to_string(pAdapter->device_mode),
               pAdapter->device_mode);
        return -EINVAL;
    }
    EXIT();
    return 0;
}

/**
 * wlan_hdd_cfg80211_set_mac_acl() - SSR wrapper for
 *				__wlan_hdd_cfg80211_set_mac_acl
 * @wiphy: pointer to wiphy structure
 * @dev: pointer to net_device
 * @params: pointer to cfg80211_acl_data
 *
 * Return; 0 on success, error number otherwise
 */
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 CONFIG_NL80211_TESTMODE
#ifdef WLAN_NL80211_TESTMODE
#ifdef FEATURE_WLAN_LPHB
void wlan_hdd_cfg80211_lphb_ind_handler
(
   void *pHddCtx,
   tSirLPHBInd *lphbInd
)
{
   struct sk_buff  *skb;

   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
             "LPHB indication arrived");

   if (0 != wlan_hdd_validate_context((hdd_context_t *)pHddCtx))
      return;

   if (NULL == lphbInd) {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "%s: invalid argument lphbInd", __func__);
      return;
   }

   skb = cfg80211_testmode_alloc_event_skb(
                  ((hdd_context_t *)pHddCtx)->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;
    hdd_context_t *pHddCtx = wiphy_priv(wiphy);
#ifdef FEATURE_WLAN_LPHB
    eHalStatus smeStatus;
#endif /* FEATURE_WLAN_LPHB */

    err = wlan_hdd_validate_context(pHddCtx);
    if (err)
       return err;

    ENTER();

    err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy, NULL);
    if (err) {
        hddLog(LOGE, FL("Testmode INV ATTR"));
        return err;
    }

    if (!tb[WLAN_HDD_TM_ATTR_CMD]) {
        hddLog(LOGE, FL("Testmode INV CMD"));
        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]) {
                hddLog(LOGE, FL("Testmode INV DATA"));
                return -EINVAL;
            }

            buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
            buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);

            hb_params_temp =(tSirLPHBReq *)buf;
            if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
                (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
                return -EINVAL;

            if (buf_len > sizeof(*hb_params)) {
                hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
                       buf_len);
                return -ERANGE;
            }

            hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
            if (NULL == hb_params) {
                hddLog(LOGE, FL("Request Buffer Alloc Fail"));
                return -ENOMEM;
            }

            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) {
               hddLog(LOGE, "LPHB Config Fail, disable");
               vos_mem_free(hb_params);
            }
            return 0;
         }
#endif /* FEATURE_WLAN_LPHB */

#if  defined(QCA_WIFI_FTM)
        case WLAN_HDD_TM_CMD_WLAN_FTM:
        {
            int   buf_len;
            void *buf;
            VOS_STATUS status;
            if (!tb[WLAN_HDD_TM_ATTR_DATA]) {
                    hddLog(LOGE,
                           FL("WLAN_HDD_TM_ATTR_DATA attribute is invalid"));
                    return -EINVAL;
            }

            buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
            buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);

            hddLog(LOGE, FL("****FTM Tx cmd len = %d*****"), buf_len);

            status = wlan_hdd_ftm_testmode_cmd(buf, buf_len, FALSE);

            if (status != VOS_STATUS_SUCCESS)
                err = -EBUSY;
            break;
        }
#endif

        default:
            hddLog(LOGE, FL("command %d not supported"),
                         nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]));
            return -EOPNOTSUPP;
    }
    EXIT();
    return err;
}

static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0)) || defined(WITH_BACKPORTS)
                                      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;
}

#if  defined(QCA_WIFI_FTM)
void wlan_hdd_testmode_rx_event(void *buf, size_t buf_len)
{
    struct sk_buff *skb;
    hdd_context_t *hdd_ctx;
    void *vos_global_ctx;

    if (!buf || !buf_len) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: buf or buf_len invalid, buf = %pK buf_len = %zu",
                  __func__, buf, buf_len);
        return;
    }

    vos_global_ctx = vos_get_global_context(VOS_MODULE_ID_HDD, NULL);

    if (!vos_global_ctx) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: voss global context invalid",
                  __func__);
        return;
    }

    hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_global_ctx);

    if (!hdd_ctx) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: hdd context invalid",
                  __func__);
        return;
    }

    skb = cfg80211_testmode_alloc_event_skb(hdd_ctx->wiphy,
                                            buf_len, GFP_KERNEL);
    if (!skb) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to allocate testmode rx skb!",
                  __func__);
        return;
    }

    if (nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_FTM) ||
        nla_put(skb, WLAN_HDD_TM_ATTR_DATA, buf_len, buf))
        goto nla_put_failure;

    hddLog(LOGE, FL("****FTM Rx cmd len = %zu*****"), buf_len);

    cfg80211_testmode_event(skb, GFP_KERNEL);
    return;

nla_put_failure:
    kfree_skb(skb);
    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
              "%s: nla_put failed on testmode rx skb!",
              __func__);
}
#endif
#endif /* CONFIG_NL80211_TESTMODE */
#endif

/**
 * wlan_hdd_chan_info_cb() - channel info callback
 * @chan_info: struct scan_chan_info
 *
 * Store channel info into HDD context
 *
 * Return: None.
 */
static void wlan_hdd_chan_info_cb(struct scan_chan_info *info)
{
	v_CONTEXT_t vos_context = vos_get_global_context(0, NULL);
	hdd_context_t *hdd_ctx;
	struct hdd_scan_chan_info *chan;
	uint8_t idx = 0;

	ENTER();

	hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_context);
	if (NULL == hdd_ctx) {
		hddLog(LOGE, FL("hdd_ctx is invalid"));
		EXIT();
		return;
	}

	if (NULL == hdd_ctx->chan_info) {
		hddLog(LOGE, FL("chan_info is NULL"));
		EXIT();
		return;
	}

	mutex_lock(&hdd_ctx->chan_info_lock);
	chan = hdd_ctx->chan_info;
	for (; idx < SIR_MAX_NUM_CHANNELS; idx++) {
		if (chan[idx].freq == info->freq) {
			if (info->cmd_flag == WMI_CHAN_INFO_START_RESP) {
				chan[idx].freq = info->freq;
				chan[idx].cmd_flag = info->cmd_flag;
				chan[idx].noise_floor = info->noise_floor;
				chan[idx].cycle_count = info->cycle_count;
				chan[idx].rx_clear_count = info->rx_clear_count;
				chan[idx].tx_frame_count = info->tx_frame_count;
				chan[idx].clock_freq = info->clock_freq;
				break;
			} else if (info->cmd_flag == WMI_CHAN_INFO_END_RESP) {
				chan[idx].delta_cycle_count =
						info->cycle_count -
						chan[idx].cycle_count;

				chan[idx].delta_rx_clear_count =
						info->rx_clear_count -
						chan[idx].rx_clear_count;

				chan[idx].delta_tx_frame_count =
						info->tx_frame_count -
						chan[idx].tx_frame_count;

				chan[idx].noise_floor = info->noise_floor;
				chan[idx].cmd_flag = info->cmd_flag;
				break;
			} else {
				hddLog(LOGE, FL("cmd flag is invalid: %d"),
							info->cmd_flag);
				break;
			}
		}
	}
	mutex_unlock(&hdd_ctx->chan_info_lock);

	EXIT();
}

/**
 * wlan_hdd_init_chan_info() - init chan info in hdd context
 * @hdd_ctx: HDD context pointer
 *
 * Return: none
 */
void wlan_hdd_init_chan_info(hdd_context_t *hdd_ctx)
{
	uint8_t num_2g, num_5g, index = 0;

	if (!hdd_ctx->cfg_ini->fEnableSNRMonitoring)
		return;

	hdd_ctx->chan_info =
		vos_mem_malloc(sizeof(struct scan_chan_info)
					* NUM_RF_CHANNELS);
	if (NULL == hdd_ctx->chan_info) {
		hddLog(LOGE, FL("Failed to malloc for chan info"));
	} else {
		mutex_init(&hdd_ctx->chan_info_lock);
		vos_mem_zero(hdd_ctx->chan_info,
			sizeof(struct scan_chan_info) * NUM_RF_CHANNELS);

		num_2g = ARRAY_SIZE(hdd_channels_2_4_GHZ);
		for (; index < num_2g; index++) {
			hdd_ctx->chan_info[index].freq =
				hdd_channels_2_4_GHZ[index].center_freq;
		}

		num_5g = ARRAY_SIZE(hdd_channels_5_GHZ);
		for (; (index - num_2g) < num_5g; index++) {
			if (vos_is_dsrc_channel(
				hdd_channels_5_GHZ[index - num_2g].center_freq))
				continue;
			hdd_ctx->chan_info[index].freq =
				hdd_channels_5_GHZ[index - num_2g].center_freq;
		}
		sme_set_chan_info_callback(
			hdd_ctx->hHal,
			&wlan_hdd_chan_info_cb
			);
	}
}

/**
 * wlan_hdd_deinit_chan_info() - deinit chan info in hdd context
 * @chan_info: channel information
 *
 * Return: none
 */
void wlan_hdd_deinit_chan_info(hdd_context_t *hdd_ctx)
{
	if (hdd_ctx->chan_info) {
		vos_mem_free(hdd_ctx->chan_info);
		hdd_ctx->chan_info = NULL;
	}
}

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, opfreq; /* Initialization Required */
    int status, i, j = 0;
    bool filled = false;

    ENTER();

    hddLog(LOG1, FL("dump survey index:%d"), idx);
    if (idx > NUM_RF_CHANNELS - 1) {
        return -EINVAL;
    }

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

    if ((NULL == pHddCtx->chan_info) &&
        (pHddCtx->cfg_ini->fEnableSNRMonitoring)) {
        hddLog(LOGE, FL("chan_info is NULL"));
        return -EINVAL;
    }

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

    pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

    if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
        eConnectionState_Associated != pHddStaCtx->conn_info.connState)
    {
        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);

    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, &opfreq);

    mutex_lock(&pHddCtx->chan_info_lock);
    freq = pHddCtx->chan_info[idx].freq;

    for (i = 0; i < IEEE80211_NUM_BANDS && !filled; i++)
    {
        if (NULL == wiphy->bands[i])
           continue;

        for (j = 0; j < wiphy->bands[i]->n_channels && !filled; j++)
        {
            struct ieee80211_supported_band *band = wiphy->bands[i];

            if (band->channels[j].center_freq == (v_U16_t)freq)
            {
                survey->channel = &band->channels[j];
                survey->noise = pHddCtx->chan_info[idx].noise_floor;
                survey->filled = SURVEY_INFO_NOISE_DBM;
                if (pHddCtx->chan_info[idx].clock_freq > 0) {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0))
                    /**
                     * time = cycle_count * cycle
                     * cycle = 1 / clock_freq
                     * Since the unit of clock_freq reported from FW is MHZ,
                     * and we want to calculate time in ms level, the result is
                     * time = cycle / (clock_freq * 1000)
                     */

                    survey->time =
                              pHddCtx->chan_info[idx].delta_cycle_count /
                                  (pHddCtx->chan_info[idx].clock_freq * 1000);
                    survey->time_busy =
                              pHddCtx->chan_info[idx].delta_rx_clear_count /
                                  (pHddCtx->chan_info[idx].clock_freq * 1000);
                    survey->time_tx =
                              pHddCtx->chan_info[idx].delta_tx_frame_count /
                                  (pHddCtx->chan_info[idx].clock_freq * 1000);

                    survey->filled |= SURVEY_INFO_TIME |
                                      SURVEY_INFO_TIME_BUSY |
                                      SURVEY_INFO_TIME_TX;
#else
                    survey->channel_time =
                              pHddCtx->chan_info[idx].delta_cycle_count /
                                  (pHddCtx->chan_info[idx].clock_freq * 1000);
                    survey->channel_time_busy =
                              pHddCtx->chan_info[idx].delta_rx_clear_count /
                                  (pHddCtx->chan_info[idx].clock_freq * 1000);
                    survey->channel_time_tx =
                              pHddCtx->chan_info[idx].delta_tx_frame_count /
                                  (pHddCtx->chan_info[idx].clock_freq * 1000);

                    survey->filled |= SURVEY_INFO_CHANNEL_TIME |
                                      SURVEY_INFO_CHANNEL_TIME_BUSY |
                                      SURVEY_INFO_CHANNEL_TIME_TX;
#endif
                }
                if (opfreq == freq)
                    survey->filled |= SURVEY_INFO_IN_USE;

                filled = true;
            }
        }
     }
     mutex_unlock(&pHddCtx->chan_info_lock);

     if (!filled)
        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;
}

#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;
	v_U8_t channel;
	uint8_t current_channel;
	v_U16_t freq;
	int ret;
	tsap_Config_t *sap_config;

	hddLog(LOG1, FL("Set Freq %d sub20 chanwidth %d"),
	       csa_params->chandef.chan->center_freq,
	       csa_params->chandef.width);

	current_channel =
		(WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel;
	sap_config = &((WLAN_HDD_GET_AP_CTX_PTR(adapter))->sapConfig);
	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	ret = wlan_hdd_validate_context(hdd_ctx);

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

	if ((WLAN_HDD_P2P_GO != adapter->device_mode) &&
		(WLAN_HDD_SOFTAP != adapter->device_mode))
		return -ENOTSUPP;

	freq = csa_params->chandef.chan->center_freq;
	channel = vos_freq_to_chan(freq);

	if (channel != current_channel) {
		ret = hdd_softap_set_channel_change(dev, channel);
	} else if (sap_config->sub20_switch_mode == SUB20_MANUAL) {
		ret = hdd_softap_set_channel_sub20_chanwidth_change(
					dev, csa_params->chandef.width);
	} else {
		hddLog(LOGE, FL("nothing to do"));
		return -EINVAL;
	}
	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

#ifdef FEATURE_WLAN_THERMAL_SHUTDOWN
static void wlan_hdd_thermal_suspend(hdd_context_t *pHddCtx)
{
	/* send auto shutdown timer val 0 to fw as suspend */
	sme_set_auto_shutdown_timer(pHddCtx->hHal, 0);
}

static int wlan_hdd_thermal_resume(hdd_context_t *pHddCtx, bool thermal)
{
	hddLog(LOG1, "state=%d, thermal=%d\n",
			   hdd_thermal_suspend_state(pHddCtx), thermal);

	/* If system suspend after thermal suspend, assure system resume first. */
	if (hdd_thermal_suspend_state(pHddCtx) == HDD_WLAN_THERMAL_SUSPENDED &&
		!thermal) {
		hddLog(LOG1, FL("System resume when thermal suspended"));
		return -EINVAL;
	}

	/* send auto shutdown timer val 1 to fw as resume */
	sme_set_auto_shutdown_timer(pHddCtx->hHal, 1);

	return 0;
}
#else
static int wlan_hdd_thermal_resume(hdd_context_t *pHddCtx, bool thermal)
{
	return 0;
}

static void wlan_hdd_thermal_suspend(hdd_context_t *pHddCtx)
{
	return;
}

#endif

/*
 * 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, bool thermal)
{
    hdd_context_t *pHddCtx = wiphy_priv(wiphy);
    hdd_adapter_t *pAdapter;
    hdd_adapter_list_node_t *pAdapterNode, *pNext;
    VOS_STATUS status = VOS_STATUS_SUCCESS;
    int result;
    struct device *dev;
    pVosSchedContext vosSchedContext = get_vos_sched_ctxt();

    ENTER();

    result = wlan_hdd_validate_context(pHddCtx);
    if (0 != result)
       return result;

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

    /* Driver has been reset by another API(SSR), return success */
    if (!pHddCtx->isWiphySuspended) {
        hddLog(LOGE, FL("Driver not suspended"));
        return 0;
    }

    result = wlan_hdd_thermal_resume(pHddCtx, thermal);
    if (0 != result)
        return result;

    if (!thermal && hif_is_80211_fw_wow_required()) {
        result = wma_resume_fw();
        if (result) {
          /* SSR happened while we were waiting for this */
          if (result == VOS_STATUS_E_ALREADY)
              return 0;

          hddLog(LOGE, FL("Failed to resume FW err:%d"), result);
          /* Do not panic (VOS_BUG(0)) if FW dump is in progress.
           * Otherwise, the FW dump will be incomplete.
           */
          if (!vos_is_logp_in_progress(VOS_MODULE_ID_HDD, NULL))
              VOS_BUG(0);
          return -EBUSY;
        }
    }
    dev = pHddCtx->parent_dev;
    vos_request_bus_bandwidth(dev, CNSS_BUS_WIDTH_MEDIUM);

    /* Resume MC thread */
    if (pHddCtx->isMcThreadSuspended) {
        complete(&vosSchedContext->ResumeMcEvent);
        pHddCtx->isMcThreadSuspended = FALSE;
    }

#ifdef QCA_CONFIG_SMP
    /* Resume tlshim Rx thread */
    if (pHddCtx->isTlshimRxThreadSuspended) {
        complete(&vosSchedContext->ResumeTlshimRxEvent);
        pHddCtx->isTlshimRxThreadSuspended = FALSE;
    }

#endif

    hdd_resume_wlan(thermal);

    MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
                          NO_SESSION, pHddCtx->isWiphySuspended));
    spin_lock(&pHddCtx->schedScan_lock);
    pHddCtx->isWiphySuspended = FALSE;
    if (TRUE != pHddCtx->isSchedScanUpdatePending) {
        spin_unlock(&pHddCtx->schedScan_lock);
        hddLog(LOG1, FL("Return resume is not due to PNO indication"));
        return 0;
    }
    /* Reset flag to avoid updating 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)) {
                hddLog(LOGW, FL("NO SCAN result"));
            } else {
                /* Acquire wakelock to handle the case where APP's tries to
                 * suspend immediately after updating the scan results. This
                 * results in app's is in suspended state and not able to
                 * process the connect request to AP
                 */
                hdd_prevent_suspend_timeout(1000,
                                         WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
                cfg80211_sched_scan_results(pHddCtx->wiphy, 0);
            }

            hddLog(LOG1, FL("cfg80211 scan result database updated"));
            EXIT();
            return result;
        }
        status = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
        pAdapterNode = pNext;
    }

    hddLog(LOG1, FL("Failed to find Adapter"));
    EXIT();
    return result;
}

void wlan_hdd_cfg80211_ready_to_suspend(void *callbackContext, boolean suspended)
{
    hdd_context_t *pHddCtx = (hdd_context_t *)callbackContext;
    pHddCtx->suspended = suspended;
    complete(&pHddCtx->ready_to_suspend);
}

int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
{
    hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_resume_wlan(wiphy, false);
    hdd_system_suspend_state_set(hdd_ctx, false);
    vos_ssr_unprotect(__func__);

    return ret;
}

#ifdef FEATURE_WLAN_THERMAL_SHUTDOWN
static bool wlan_hdd_is_thermal_suspended(hdd_context_t *pHddCtx)
{
	if (hdd_thermal_suspend_state(pHddCtx) == HDD_WLAN_THERMAL_SUSPENDED) {
		hddLog(LOG1, FL("System suspend when thermal suspended"));
		return true;
	}
	return false;
}

static VOS_STATUS wlan_hdd_suspend_mc_thread(pVosSchedContext vosSchedCtx,
					hdd_context_t *pHddCtx)
{
	return VOS_STATUS_SUCCESS;
}
#else
static bool wlan_hdd_is_thermal_suspended(hdd_context_t *pHddCtx)
{
	return false;
}

static VOS_STATUS wlan_hdd_suspend_mc_thread(pVosSchedContext vosSchedCtx,
					hdd_context_t *pHddCtx)
{
	int rc;

	/* Suspend MC thread */
	set_bit(MC_SUSPEND_EVENT, &vosSchedCtx->mcEventFlag);
	wake_up_interruptible(&vosSchedCtx->mcWaitQueue);

	/* Wait for suspend confirmation from MC thread */
	rc = wait_for_completion_timeout(&pHddCtx->mc_sus_event_var,
			msecs_to_jiffies(WLAN_WAIT_TIME_MCTHREAD_SUSPEND));
	if (!rc)
	{
		clear_bit(MC_SUSPEND_EVENT, &vosSchedCtx->mcEventFlag);
		VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
				   "%s: Failed to stop mc thread", __func__);
		return VOS_STATUS_E_FAILURE;
	}

	pHddCtx->isMcThreadSuspended = TRUE;
	return VOS_STATUS_SUCCESS;
}

#endif
/*
 * 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, bool thermal)
{
#ifdef QCA_CONFIG_SMP
#define RX_TLSHIM_SUSPEND_TIMEOUT 200 /* msecs */
#endif
    hdd_context_t *pHddCtx = wiphy_priv(wiphy);
    pVosSchedContext vosSchedContext = get_vos_sched_ctxt();
    hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
    hdd_adapter_t *pAdapter;
    hdd_scaninfo_t *pScanInfo;
    VOS_STATUS status;
    struct device *dev;
    int rc;

    ENTER();

    rc = wlan_hdd_validate_context(pHddCtx);
    if (0 != rc)
       return rc;

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

    if (true == vos_is_mon_enable()) {
        hddLog(LOGE, FL("command not allowed in FTM mode"));
        return -EINVAL;
    }

    if (wlan_hdd_is_thermal_suspended(pHddCtx)) {
        return 0;
    }

    /* If RADAR detection is in progress (HDD), prevent suspend. The flag
     * "dfs_cac_block_tx" is set to TRUE when RADAR is found and stay TRUE until
     * CAC is done for a SoftAP which is in started state.
     */
    status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
    while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
        pAdapter = pAdapterNode->pAdapter;
        if (WLAN_HDD_SOFTAP == pAdapter->device_mode) {
            if (BSS_START ==
                    WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter)->bssState &&
                VOS_TRUE ==
                    WLAN_HDD_GET_AP_CTX_PTR(pAdapter)->dfs_cac_block_tx) {
                hddLog(VOS_TRACE_LEVEL_DEBUG,
                    FL("RADAR detection in progress, do not allow suspend"));
                return -EAGAIN;
            } else if (!pHddCtx->cfg_ini->enableSapSuspend) {
                /* return -EOPNOTSUPP if SAP does not support suspend
                 */
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                    "%s:SAP does not support suspend!!", __func__);
                return -EOPNOTSUPP;
            }
        } else if (WLAN_HDD_P2P_GO == pAdapter->device_mode) {
            if (!pHddCtx->cfg_ini->enableSapSuspend) {
                /* return -EOPNOTSUPP if GO does not support suspend
                 */
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                    "%s:GO does not support suspend!!", __func__);
                return -EOPNOTSUPP;
            }
        }
        status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
        pAdapterNode = pNext;
    }

    /* Stop ongoing scan on each interface */
    status =  hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
    while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
    {
        pAdapter = pAdapterNode->pAdapter;
        pScanInfo = &pAdapter->scan_info;

        if (pScanInfo->mScanPending && pAdapter->request)
        {
           INIT_COMPLETION(pScanInfo->abortscan_event_var);
           hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
                              eCSR_SCAN_ABORT_DEFAULT);

           status = wait_for_completion_timeout(
                           &pScanInfo->abortscan_event_var,
                           msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
           if (!status)
           {
              VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                         "%s: Timeout occurred while waiting for abort scan" ,
                         __func__);
              return -ETIME;
           }
        }

        if (sme_staInMiddleOfRoaming(pHddCtx->hHal, pAdapter->sessionId)) {
            hddLog(LOG1, FL("Roaming in progress, don't allow suspend"));
            return -EAGAIN;
        }

        if (pAdapter->is_roc_inprogress)
            wlan_hdd_cleanup_remain_on_channel_ctx(pAdapter);

        status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
        pAdapterNode = pNext;
    }

#ifdef IPA_OFFLOAD
    /*
     * Suspend IPA early before proceeding to suspend other entities like
     * firmware to avoid any race conditions.
     */
    if (hdd_ipa_suspend(pHddCtx)) {
        hddLog(VOS_TRACE_LEVEL_DEBUG, FL("IPA not ready to suspend!"));
        return -EAGAIN;
    }
#endif

    /* Wait for the target to be ready for suspend */
    INIT_COMPLETION(pHddCtx->ready_to_suspend);

    hdd_suspend_wlan(&wlan_hdd_cfg80211_ready_to_suspend, pHddCtx, thermal);

    rc = wait_for_completion_timeout(&pHddCtx->ready_to_suspend,
                             msecs_to_jiffies(WLAN_WAIT_TIME_READY_TO_SUSPEND));
    if (!rc)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: Failed to get ready to suspend", __func__);
        goto resume_tx;
    }

    if (!pHddCtx->suspended) {
       VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: Faied as suspend_status is wrong:%d",
                           __func__, pHddCtx->suspended);
       goto resume_tx;
    }

    /* Suspend MC thread */
    status = wlan_hdd_suspend_mc_thread(vosSchedContext, pHddCtx);
    if (VOS_STATUS_SUCCESS != status)
        goto resume_tx;

#ifdef QCA_CONFIG_SMP
    /* Suspend tlshim rx thread */
    set_bit(RX_SUSPEND_EVENT, &vosSchedContext->tlshimRxEvtFlg);
    wake_up_interruptible(&vosSchedContext->tlshimRxWaitQueue);
    rc = wait_for_completion_timeout(
                     &vosSchedContext->SuspndTlshimRxEvent,
                     msecs_to_jiffies(RX_TLSHIM_SUSPEND_TIMEOUT));
    if (!rc) {
        clear_bit(RX_SUSPEND_EVENT, &vosSchedContext->tlshimRxEvtFlg);
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: Failed to stop tl_shim rx thread", __func__);
        goto resume_all;
    }
    pHddCtx->isTlshimRxThreadSuspended = TRUE;
#endif

    MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
                           NO_SESSION, pHddCtx->isWiphySuspended));
    pHddCtx->isWiphySuspended = TRUE;

    vos_request_bus_bandwidth(dev, CNSS_BUS_WIDTH_NONE);

    if (thermal) {
        wlan_hdd_thermal_suspend(pHddCtx);
    } else {
        if (hif_is_80211_fw_wow_required()) {
           rc = wma_suspend_fw();
           if (rc) {
              hddLog(LOGE, FL("Failed to suspend FW err:%d"), rc);
              goto fail_suspend;
           }
        }
    }

    EXIT();
    return 0;
fail_suspend:
    vos_request_bus_bandwidth(dev, CNSS_BUS_WIDTH_MEDIUM);
    pHddCtx->isWiphySuspended = FALSE;
#ifdef QCA_CONFIG_SMP
    complete(&vosSchedContext->ResumeTlshimRxEvent);
    pHddCtx->isTlshimRxThreadSuspended = FALSE;
#endif

#ifdef QCA_CONFIG_SMP
resume_all:
#endif
    if (pHddCtx->isMcThreadSuspended) {
        complete(&vosSchedContext->ResumeMcEvent);
        pHddCtx->isMcThreadSuspended = FALSE;
    }

resume_tx:

    hdd_resume_wlan(thermal);

    return -ETIME;
}

int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
                                   struct cfg80211_wowlan *wow)
{
    hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
    int ret;

    vos_ssr_protect(__func__);
    ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow, false);
    hdd_system_suspend_state_set(hdd_ctx, true);
    vos_ssr_unprotect(__func__);

    return ret;
}


#ifdef QCA_HT_2040_COEX
/**
 * __wlan_hdd_cfg80211_set_ap_channel_width() - set ap channel bandwidth
 * @wiphy: Pointer to wiphy
 * @dev: Pointer to network device
 * @chandef: Pointer to channel definition parameter
 *
 * Return: 0 for success, non-zero for failure
 */
static int
__wlan_hdd_cfg80211_set_ap_channel_width(struct wiphy *wiphy,
					 struct net_device *dev,
					 struct cfg80211_chan_def *chandef)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx;
    VOS_STATUS status;
    tSmeConfigParams smeConfig;
    bool cbModeChange = false;

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    status = wlan_hdd_validate_context(pHddCtx);

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

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

    vos_mem_zero(&smeConfig, sizeof (tSmeConfigParams));
    sme_GetConfigParam(pHddCtx->hHal, &smeConfig);
    switch (chandef->width) {
    case NL80211_CHAN_WIDTH_20:
        if (smeConfig.csrConfig.channelBondingMode24GHz !=
                      eCSR_INI_SINGLE_CHANNEL_CENTERED) {
            smeConfig.csrConfig.channelBondingMode24GHz =
                      eCSR_INI_SINGLE_CHANNEL_CENTERED;
            sme_UpdateConfig(pHddCtx->hHal, &smeConfig);
            cbModeChange = TRUE;
        }
        break;

    case NL80211_CHAN_WIDTH_40:
        if (smeConfig.csrConfig.channelBondingMode24GHz ==
                      eCSR_INI_SINGLE_CHANNEL_CENTERED) {
            if ( NL80211_CHAN_HT40MINUS == cfg80211_get_chandef_type(chandef))
                smeConfig.csrConfig.channelBondingMode24GHz =
                      eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
            else
                smeConfig.csrConfig.channelBondingMode24GHz =
                      eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
            sme_UpdateConfig(pHddCtx->hHal, &smeConfig);
            cbModeChange = TRUE;
        }
        break;

    default:
        hddLog(LOGE, FL("Error!!! Invalid HT20/40 mode !"));
        return -EINVAL;
    }

    if (!cbModeChange)
       return 0;

    if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
        return 0;

    hddLog(LOG1, FL("Channel bonding changed to %d"),
                 smeConfig.csrConfig.channelBondingMode24GHz);

    /* Change SAP ht2040 mode */
    status = hdd_set_sap_ht2040_mode(pAdapter,
                                     cfg80211_get_chandef_type(chandef));
    if (status != VOS_STATUS_SUCCESS) {
        hddLog(LOGE,
               FL("Error!!! Cannot set SAP HT20/40 mode!"));
        return -EINVAL;
    }

    return 0;
}

/**
 * wlan_hdd_cfg80211_set_ap_channel_width() - set ap channel bandwidth
 * @wiphy: Pointer to wiphy
 * @dev: Pointer to network device
 * @chandef: Pointer to channel definition parameter
 *
 * Return: 0 for success, non-zero for failure
 */
static int
wlan_hdd_cfg80211_set_ap_channel_width(struct wiphy *wiphy,
				       struct net_device *dev,
				       struct cfg80211_chan_def *chandef)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_set_ap_channel_width(wiphy, dev, chandef);
	vos_ssr_unprotect(__func__);

	return ret;
}
#endif

#ifdef FEATURE_WLAN_EXTSCAN
/**
 * 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,
	struct ext_scan_capabilities_response *data)
{
	struct hdd_ext_scan_context *context;
	hdd_context_t *hdd_ctx  = (hdd_context_t *)ctx;

	ENTER();

	if (wlan_hdd_validate_context(hdd_ctx))
		return;

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

	context = &hdd_ctx->ext_scan_context;
	/* validate response received from target*/
	if (context->request_id != data->requestId) {
		spin_unlock(&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);
	}

	spin_unlock(&hdd_context_lock);

	return;
}

/*
 * define short names for the global vendor params
 * used by hdd_extscan_nl_fill_bss()
 */
#define PARAM_TIME_STAMP \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
#define PARAM_SSID \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID
#define PARAM_BSSID \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID
#define PARAM_CHANNEL \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL
#define PARAM_RSSI \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI
#define PARAM_RTT \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT
#define PARAM_RTT_SD \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD
#define PARAM_BEACON_PERIOD \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD
#define PARAM_CAPABILITY \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY
#define PARAM_IE_LENGTH \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH
#define PARAM_IE_DATA \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
#define PARAM_PAD \
       QCA_WLAN_VENDOR_ATTR_EXTSCAN_PAD
#endif

/** hdd_extscan_nl_fill_bss() - extscan nl fill bss
 * @skb: socket buffer
 * @ap: bss information
 * @idx: nesting index
 *
 * Return: 0 on success; error number otherwise
 */
static int hdd_extscan_nl_fill_bss(struct sk_buff *skb, tSirWifiScanResult *ap,
					int idx)
{
	struct nlattr *nla_ap;

	nla_ap = nla_nest_start(skb, idx);
	if (!nla_ap)
		return -EINVAL;

	if (
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
        nla_put_u64_64bit(skb, PARAM_TIME_STAMP, ap->ts, PARAM_PAD) ||
#else
	nla_put_u64(skb, PARAM_TIME_STAMP, ap->ts) ||
#endif
	    nla_put(skb, PARAM_SSID, sizeof(ap->ssid), ap->ssid) ||
	    nla_put(skb, PARAM_BSSID, sizeof(ap->bssid), ap->bssid) ||
	    nla_put_u32(skb, PARAM_CHANNEL, ap->channel) ||
	    nla_put_s32(skb, PARAM_RSSI, ap->rssi) ||
	    nla_put_u32(skb, PARAM_RTT, ap->rtt) ||
	    nla_put_u32(skb, PARAM_RTT_SD, ap->rtt_sd) ||
	    nla_put_u16(skb, PARAM_BEACON_PERIOD, ap->beaconPeriod) ||
	    nla_put_u16(skb, PARAM_CAPABILITY, ap->capability) ||
	    nla_put_u16(skb, PARAM_IE_LENGTH, ap->ieLength)) {
		hddLog(LOGE, FL("put fail"));
		return -EINVAL;
	}

	if (ap->ieLength)
		if (nla_put(skb, PARAM_IE_DATA, ap->ieLength, ap->ieData)) {
			hddLog(LOGE, FL("put fail"));
			return -EINVAL;
		}

	nla_nest_end(skb, nla_ap);

	return 0;
}
/*
 * done with short names for the global vendor params
 * used by hdd_extscan_nl_fill_bss()
 */
#undef PARAM_TIME_STAMP
#undef PARAM_SSID
#undef PARAM_BSSID
#undef PARAM_CHANNEL
#undef PARAM_RSSI
#undef PARAM_RTT
#undef PARAM_RTT_SD
#undef PARAM_BEACON_PERIOD
#undef PARAM_CAPABILITY
#undef PARAM_IE_LENGTH
#undef PARAM_IE_DATA
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
#undef PARAM_PAD
#endif

/** wlan_hdd_cfg80211_extscan_cached_results_ind() - get cached results
 * @ctx: hdd global context
 * @data: cached results
 *
 * This function reads the cached results %data, populates the NL
 * attributes and sends the NL event to the upper layer.
 *
 * Return: none
 */
static void
wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
				struct extscan_cached_scan_results *data)
{
	hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
	struct extscan_cached_scan_result *result;
	struct hdd_ext_scan_context *context;
	struct sk_buff *skb    = NULL;
	tSirWifiScanResult *ap;
	uint32_t i, j, nl_buf_len;
	bool ignore_cached_results = false;

	/* ENTER() intentionally not used in a frequently invoked API */

	if (wlan_hdd_validate_context(pHddCtx))
		return;
	if (!data) {
		hddLog(VOS_TRACE_LEVEL_ERROR, FL("data 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;
	}

#define EXTSCAN_CACHED_NEST_HDRLEN NLA_HDRLEN
#define EXTSCAN_CACHED_NL_FIXED_TLV \
		(sizeof(data->request_id) + NLA_HDRLEN) + \
		(sizeof(data->num_scan_ids) + NLA_HDRLEN) + \
		(sizeof(data->more_data) + NLA_HDRLEN)
#define EXTSCAN_CACHED_NL_SCAN_ID_TLV \
		(sizeof(result->scan_id) + NLA_HDRLEN) + \
		(sizeof(result->flags) + NLA_HDRLEN) + \
		(sizeof(result->num_results) + NLA_HDRLEN)+ \
		(sizeof(result->buckets_scanned) + NLA_HDRLEN)
#define EXTSCAN_CACHED_NL_SCAN_RESULTS_TLV \
		(sizeof(ap->ts) + NLA_HDRLEN) + \
		(sizeof(ap->ssid) + NLA_HDRLEN) + \
		(sizeof(ap->bssid) + NLA_HDRLEN) + \
		(sizeof(ap->channel) + NLA_HDRLEN) + \
		(sizeof(ap->rssi) + NLA_HDRLEN) + \
		(sizeof(ap->rtt) + NLA_HDRLEN) + \
		(sizeof(ap->rtt_sd) + NLA_HDRLEN) + \
		(sizeof(ap->beaconPeriod) + NLA_HDRLEN) + \
		(sizeof(ap->capability) + NLA_HDRLEN) + \
		(sizeof(ap->ieLength) + NLA_HDRLEN)
#define EXTSCAN_CACHED_NL_SCAN_RESULTS_IE_DATA_TLV \
		(ap->ieLength + NLA_HDRLEN)

	nl_buf_len = NLMSG_HDRLEN;
	nl_buf_len += EXTSCAN_CACHED_NL_FIXED_TLV;
	if (data->num_scan_ids) {
		nl_buf_len += sizeof(result->scan_id) + NLA_HDRLEN;
		nl_buf_len += EXTSCAN_CACHED_NEST_HDRLEN;
		result = &data->result[0];
		for (i = 0; i < data->num_scan_ids; i++) {
			nl_buf_len += EXTSCAN_CACHED_NEST_HDRLEN;
			nl_buf_len += EXTSCAN_CACHED_NL_SCAN_ID_TLV;
			nl_buf_len += EXTSCAN_CACHED_NEST_HDRLEN;

			ap = &result->ap[0];
			for (j = 0; j < result->num_results; j++) {
				nl_buf_len += EXTSCAN_CACHED_NEST_HDRLEN;
				nl_buf_len +=
					EXTSCAN_CACHED_NL_SCAN_RESULTS_TLV;
				if (ap->ieLength)
					nl_buf_len +=
					EXTSCAN_CACHED_NL_SCAN_RESULTS_IE_DATA_TLV;
				ap++;
			}
			result++;
		}
	}

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

	if (!skb) {
		hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
		goto fail;
	}
	hddLog(LOG1,
		FL("ReqId: %u Num_scan_ids: %u  MoreData: %u"),
		data->request_id, data->num_scan_ids,
		data->more_data);

	result = &data->result[0];
	for (i = 0; i < data->num_scan_ids; i++) {
		hddLog(LOG1, "[i=%d] scan_id %u flags %u num_results %u buckets_scanned: %u",
			i, result->scan_id, result->flags, result->num_results,
			result->buckets_scanned);

		ap = &result->ap[0];
		for (j = 0; j < result->num_results; j++) {
			/*
			 * Firmware returns timestamp from ext scan start till
			 * BSSID was cached (in micro seconds). Add this with
			 * time gap between system boot up to ext scan start
			 * to derive the time since boot when the
			 * BSSID was cached.
			 */
			ap->ts += pHddCtx->ext_scan_start_since_boot;
			hddLog(LOG1, "Timestamp %llu "
				"Ssid: %s "
				"Bssid (" MAC_ADDRESS_STR ") "
				"Channel %u "
				"Rssi %d "
				"RTT %u "
				"RTT_SD %u "
				"Beacon Period %u "
				"Capability 0x%x "
				"Ie length %d",
				ap->ts,
				ap->ssid,
				MAC_ADDR_ARRAY(ap->bssid),
				ap->channel,
				ap->rssi,
				ap->rtt,
				ap->rtt_sd,
				ap->beaconPeriod,
				ap->capability,
				ap->ieLength);
			ap++;
		}
		result++;
	}

	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
		data->request_id) ||
	    nla_put_u32(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_NUM_RESULTS_AVAILABLE,
		data->num_scan_ids) ||
	    nla_put_u8(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
		data->more_data)) {
		hddLog(LOGE, FL("put fail"));
		goto fail;
	}

	if (data->num_scan_ids) {
		struct nlattr *nla_results;
		result = &data->result[0];

		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;

		for (i = 0; i < data->num_scan_ids; i++) {
			struct nlattr *nla_result;
			struct nlattr *nla_aps;

			nla_result = nla_nest_start(skb, i);
			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_BUCKETS_SCANNED,
				result->buckets_scanned) ||
			    nla_put_u32(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_NUM_RESULTS_AVAILABLE,
				result->num_results)) {
				hddLog(LOGE, FL("put fail"));
				goto fail;
			}

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

			ap = &result->ap[0];
			for (j = 0; j < result->num_results; j++) {
				if (hdd_extscan_nl_fill_bss(skb, ap, j))
					goto fail;
				ap++;
			}
			nla_nest_end(skb, nla_aps);
			nla_nest_end(skb, nla_result);
			result++;
		}
		nla_nest_end(skb, nla_results);
	}

	cfg80211_vendor_cmd_reply(skb);

	if (!data->more_data) {
		spin_lock(&hdd_context_lock);
		context->response_status = 0;
		complete(&context->response_event);
		spin_unlock(&hdd_context_lock);
	}
	return;

fail:
	if (skb)
		kfree_skb(skb);

	spin_lock(&hdd_context_lock);
	context->response_status = -EINVAL;
	spin_unlock(&hdd_context_lock);
	return;
}

/**
 * wlan_hdd_cfg80211_extscan_hotlist_match_ind() - hotlist match callback
 * @hddctx: HDD context
 * @data: event data
 *
 * This function reads the hotlist matched 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
 */
static void
wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
                                            struct extscan_hotlist_match *data)
{
	hdd_context_t *pHddCtx = ctx;
	struct sk_buff *skb    = NULL;
	uint32_t i, index;
	int flags = vos_get_gfp_flags();

	ENTER();

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

	if (data->ap_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,
					NULL,
					EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
					index, flags);

	if (!skb) {
		hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
		return;
	}
	hddLog(LOG1, "Req Id: %u Num_APs: %u MoreData: %u ap_found: %u",
			data->requestId, data->numOfAps, data->moreData,
			data->ap_found);

	for (i = 0; i < data->numOfAps; i++) {
		data->ap[i].ts = vos_get_monotonic_boottime();

		hddLog(LOG1, "[i=%d] Timestamp %llu "
				"Ssid: %s "
				"Bssid (" MAC_ADDRESS_STR ") "
				"Channel %u "
				"Rssi %d "
				"RTT %u "
				"RTT_SD %u",
				i,
				data->ap[i].ts,
				data->ap[i].ssid,
				MAC_ADDR_ARRAY(data->ap[i].bssid),
				data->ap[i].channel,
				data->ap[i].rssi,
				data->ap[i].rtt,
				data->ap[i].rtt_sd);
	}

	if (nla_put_u32(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
		data->requestId) ||
	    nla_put_u32(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_NUM_RESULTS_AVAILABLE,
		data->numOfAps)) {
		hddLog(LOGE, FL("put fail"));
		goto fail;
	}

	if (data->numOfAps) {
		struct nlattr *aps;

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

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

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

			if (
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
                           nla_put_u64_64bit(skb,
                               QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
                               data->ap[i].ts,
                               QCA_WLAN_VENDOR_ATTR_EXTSCAN_PAD) ||
#else
				nla_put_u64(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
				data->ap[i].ts) ||
#endif
			    nla_put(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
				sizeof(data->ap[i].ssid),
				data->ap[i].ssid) ||
			    nla_put(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
				sizeof(data->ap[i].bssid),
				data->ap[i].bssid) ||
			    nla_put_u32(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
			        data->ap[i].channel) ||
			    nla_put_s32(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
				data->ap[i].rssi) ||
			    nla_put_u32(skb,
			        QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
				data->ap[i].rtt) ||
			    nla_put_u32(skb,
			        QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
				data->ap[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,
			data->moreData))
			goto fail;
	}

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

fail:
	kfree_skb(skb);
	return;
}

/**
 * wlan_hdd_cfg80211_extscan_generic_rsp() -
 *	Handle a generic ExtScan Response message
 * @ctx: HDD context registered with SME
 * @response: The ExtScan response from firmware
 *
 * This function will handle a generic ExtScan response message from
 * firmware and will communicate the result to the userspace thread
 * that is waiting for the response.
 *
 * Return: none
 */
static void
wlan_hdd_cfg80211_extscan_generic_rsp
	(void *ctx,
	 struct sir_extscan_generic_response *response)
{
	hdd_context_t *hdd_ctx = ctx;
	struct hdd_ext_scan_context *context;

	ENTER();

	if (wlan_hdd_validate_context(hdd_ctx))
		return;

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

	hddLog(LOG1, FL("request %u status %d"),
	       response->request_id, response->status);

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

	return;
}

/**
 * wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind() - results callback
 * @hddctx: HDD context
 * @data: event data
 *
 * This function reads the 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
 */
static void
wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(
                                          void *ctx,
                                          tpSirWifiSignificantChangeEvent pData)
{
    hdd_context_t  *pHddCtx = (hdd_context_t *)ctx;
    struct sk_buff *skb     = NULL;
    tSirWifiSignificantChange *ap_info;
    tANI_S32                  *rssi;
    tANI_U32 i, j;
    int flags = vos_get_gfp_flags();

    ENTER();

    if (wlan_hdd_validate_context(pHddCtx))
        return;

    if (!pData) {
        hddLog(LOGE, FL("pData is null"));
        return;
    }
    skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
                    NULL,
                    EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
                    QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
                    flags);

    if (!skb) {
        hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
        return;
    }
    hddLog(LOG1, "Req Id %u Num results %u More Data %u", pData->requestId,
           pData->numResults, pData->moreData);

    ap_info = &pData->ap[0];
    for (i = 0; i < pData->numResults; i++) {
        hddLog(LOG1, "[i=%d] "
                     "Bssid (" MAC_ADDRESS_STR ") "
                     "Channel %u "
                     "numOfRssi %d",
                     i,
                     MAC_ADDR_ARRAY(ap_info->bssid),
                     ap_info->channel,
                     ap_info->numOfRssi);
        rssi = &(ap_info)->rssi[0];
        for (j = 0; j < ap_info->numOfRssi; j++)
            hddLog(LOG1, "Rssi %d", *rssi++);

        ap_info += ap_info->numOfRssi * sizeof(*rssi);
    }

    if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
                         pData->requestId) ||
        nla_put_u32(skb,
                    QCA_WLAN_VENDOR_ATTR_EXTSCAN_NUM_RESULTS_AVAILABLE,
                    pData->numResults)) {
        hddLog(LOGE, FL("put fail"));
        goto fail;
    }

    if (pData->numResults) {
        struct nlattr *aps;

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

        ap_info = &pData->ap[0];
        for (i = 0; i < pData->numResults; i++) {
            struct nlattr *ap;

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

            if (nla_put(skb,
                  QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
                sizeof(tSirMacAddr), ap_info->bssid) ||
                nla_put_u32(skb,
                  QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
                ap_info->channel) ||
                nla_put_u32(skb,
                  QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
                ap_info->numOfRssi) ||
                nla_put(skb,
                  QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
                  sizeof(s32) * ap_info->numOfRssi, &(ap_info)->rssi[0]))
                goto fail;

              nla_nest_end(skb, ap);

            ap_info += ap_info->numOfRssi * sizeof(*rssi);
        }
        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, flags);
    return;

fail:
    kfree_skb(skb);
    return;

}

/**
 * wlan_hdd_cfg80211_extscan_full_scan_result_event() - full scan results event
 * @hddctx: HDD context
 * @data: event data
 *
 * This function reads the 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
 */
static void
wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
					tpSirWifiFullScanResultEvent pData)
{
	hdd_context_t *pHddCtx  = (hdd_context_t *)ctx;
	struct sk_buff *skb;
	struct timespec ts;
	int flags = vos_get_gfp_flags();
	struct hdd_ext_scan_context *context;

	/* ENTER() intentionally not used in a frequently invoked API */

	if (wlan_hdd_validate_context(pHddCtx))
		return;

	if (!pData) {
		hddLog(LOGE, FL("pData 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->ap.ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
		hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
		return;
	}

	skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
		  NULL,
		  EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
		  QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
		  flags);

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

	pData->ap.channel = vos_chan_to_freq(pData->ap.channel);
	/* Android does not want the time stamp from the frame.
	   Instead it wants a monotonic increasing value since boot */
	vos_get_monotonic_boottime_ts(&ts);
	pData->ap.ts = ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
	hddLog(LOG1, "AP Info: Timestamp %llu Ssid: %s "
				"Bssid (" MAC_ADDRESS_STR ") "
				"Channel %u "
				"Rssi %d "
				"RTT %u "
				"RTT_SD %u "
				"Bcn Period %d "
				"Capability 0x%X "
				"IE Length %d",
				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,
				pData->ap.ieLength);

	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
		pData->requestId) ||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
           nla_put_u64_64bit(skb,
               QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
               pData->ap.ts,
               QCA_WLAN_VENDOR_ATTR_EXTSCAN_PAD) ||
#else
	    nla_put_u64(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
		pData->ap.ts) ||
#endif
	    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,
		sizeof(pData->ap.bssid),
		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->ap.ieLength) ||
	    nla_put_u8(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
		pData->moreData)) {
		hddLog(LOGE, FL("nla put fail"));
		goto nla_put_failure;
	}

	if (pData->ap.ieLength) {
		if (nla_put(skb,
			QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
			pData->ap.ieLength, pData->ap.ieData))
		goto nla_put_failure;
	}

	spin_lock(&hdd_context_lock);
	context = &pHddCtx->ext_scan_context;
	if (nla_put_u32(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_BUCKETS_SCANNED,
		context->buckets_scanned)) {
		spin_unlock(&hdd_context_lock);
		hddLog(LOGE, FL("Failed to include buckets_scanned"));
		goto nla_put_failure;
	}
	spin_unlock(&hdd_context_lock);

	cfg80211_vendor_event(skb, flags);
	return;

nla_put_failure:
	kfree_skb(skb);
	return;
}

/**
 * wlan_hdd_cfg80211_extscan_epno_match_found() - pno match found
 * @hddctx: HDD context
 * @data: matched network data
 *
 * This function reads the matched network data and fills NL vendor attributes
 * and send it to upper layer.
 * This callback execute in atomic context and must not invoke any
 * blocking calls.
 *
 * Return: 0 on success, error number otherwise
 */
static void
wlan_hdd_cfg80211_extscan_epno_match_found(void *ctx,
					struct pno_match_found *data)
{
	hdd_context_t *pHddCtx  = (hdd_context_t *)ctx;
	struct sk_buff *skb     = NULL;
	uint32_t len, i;
	int flags = vos_get_gfp_flags();

	ENTER();

	if (wlan_hdd_validate_context(pHddCtx))
		return;

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

	/*
	 * If the number of match found APs including IE data exceeds NL 4K size
	 * limitation, drop that beacon/probe rsp frame.
	 */
	len = sizeof(*data) +
			(data->num_results + sizeof(tSirWifiScanResult));
	for (i = 0; i < data->num_results; i++) {
		len += data->ap[i].ieLength;
	}
	if (len >= EXTSCAN_EVENT_BUF_SIZE) {
		hddLog(LOGE, FL("Frame exceeded NL size limitation, drop it!"));
		return;
}

	skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
		  NULL,
		  EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
		  QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_NETWORK_FOUND_INDEX,
		  flags);

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

	hddLog(LOG1, "Req Id %u More Data %u num_results %d",
		data->request_id, data->more_data, data->num_results);
	for (i = 0; i < data->num_results; i++) {
		data->ap[i].channel = vos_chan_to_freq(data->ap[i].channel);
		hddLog(LOG1, "AP Info: Timestamp %llu Ssid: %s "
					"Bssid (" MAC_ADDRESS_STR ") "
					"Channel %u "
					"Rssi %d "
					"RTT %u "
					"RTT_SD %u "
					"Bcn Period %d "
					"Capability 0x%X "
					"IE Length %d",
					data->ap[i].ts,
					data->ap[i].ssid,
					MAC_ADDR_ARRAY(data->ap[i].bssid),
					data->ap[i].channel,
					data->ap[i].rssi,
					data->ap[i].rtt,
					data->ap[i].rtt_sd,
					data->ap[i].beaconPeriod,
					data->ap[i].capability,
					data->ap[i].ieLength);
	}

	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
		data->request_id) ||
	    nla_put_u32(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_NUM_RESULTS_AVAILABLE,
		data->num_results) ||
	    nla_put_u8(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
		data->more_data)) {
		hddLog(LOGE, FL("nla put fail"));
		goto fail;
	}

	if (data->num_results) {
		struct nlattr *nla_aps;
		nla_aps = nla_nest_start(skb,
			QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
		if (!nla_aps)
			goto fail;

		for (i = 0; i < data->num_results; i++) {
			if (hdd_extscan_nl_fill_bss(skb, &data->ap[i], i))
				goto fail;
		}
		nla_nest_end(skb, nla_aps);
	}

	cfg80211_vendor_event(skb, flags);
	return;

fail:
	kfree_skb(skb);
	return;
}

/**
 * wlan_hdd_cfg80211_extscan_scan_res_available_event() - scan available event
 * @hddctx: HDD context
 * @data: event data
 *
 * This function reads the 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
 */
static void
wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
                                    tpSirExtScanResultsAvailableIndParams pData)
{
    hdd_context_t *pHddCtx  = (hdd_context_t *)ctx;
    struct sk_buff *skb     = NULL;
    int flags = vos_get_gfp_flags();

    ENTER();

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

    skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
                NULL,
                EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
                QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
                flags);

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

    hddLog(LOG1, "Req Id %u Num results %u", pData->requestId,
           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_NUM_RESULTS_AVAILABLE,
                    pData->numResultsAvailable)) {
        hddLog(LOGE, FL("nla put fail"));
        goto nla_put_failure;
    }

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

nla_put_failure:
    kfree_skb(skb);
    return;
}

/**
 * wlan_hdd_cfg80211_extscan_scan_progress_event() - scan progress event
 * @hddctx: HDD context
 * @data: event data
 *
 * This function reads the 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
 */
static void
wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx,
					tpSirExtScanOnScanEventIndParams data)
{
	hdd_context_t *pHddCtx  = ctx;
	struct sk_buff *skb;
	int flags = vos_get_gfp_flags();
	struct hdd_ext_scan_context *context;

	/* ENTER() intentionally not used in a frequently invoked API */

	if (wlan_hdd_validate_context(pHddCtx))
		return;

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

	hddLog(LOG1, "Request Id: %u ScanEventType: %u ScanEventStatus: %u buckets_scanned: %u",
		data->requestId, data->scanEventType, data->status,
		data->buckets_scanned);

	spin_lock(&hdd_context_lock);
	context = &pHddCtx->ext_scan_context;
	if (data->scanEventType == WIFI_EXTSCAN_CYCLE_COMPLETED_EVENT) {
		context->buckets_scanned = 0;
		data->scanEventType = WIFI_EXTSCAN_RESULTS_AVAILABLE;
		spin_unlock(&hdd_context_lock);
	} else if (data->scanEventType == WIFI_EXTSCAN_CYCLE_STARTED_EVENT) {
		context->buckets_scanned = data->buckets_scanned;
		/* No need to report to user space */
		spin_unlock(&hdd_context_lock);
		return;
	} else {
		spin_unlock(&hdd_context_lock);
	}

	skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
			NULL,
			EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
			QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
			flags);

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

	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
		data->requestId) ||
	    nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
		data->scanEventType)) {
		hddLog(LOGE, FL("nla put fail"));
		goto nla_put_failure;
	}

	cfg80211_vendor_event(skb, flags);
	return;

nla_put_failure:
	kfree_skb(skb);
	return;
}

/**
 * wlan_hdd_cfg80211_passpoint_match_found() - passpoint match found
 * @hddctx: HDD context
 * @data: matched network data
 *
 * This function reads the match network %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
 */
static void
wlan_hdd_cfg80211_passpoint_match_found(void *ctx,
					struct wifi_passpoint_match *data)
{
	hdd_context_t *pHddCtx  = ctx;
	struct sk_buff *skb     = NULL;
	uint32_t len, i, num_matches = 1, more_data = 0;
	struct nlattr *nla_aps;
	struct nlattr *nla_bss;
	int flags = vos_get_gfp_flags();

	ENTER();

	if (wlan_hdd_validate_context(pHddCtx))
		return;

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

	len = sizeof(*data) + data->ap.ieLength + data->anqp_len;
	if (len >= EXTSCAN_EVENT_BUF_SIZE) {
		hddLog(LOGE, FL("Result exceeded NL size limitation, drop it"));
		return;
	}

	skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
		  NULL,
		  EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
		  QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_PASSPOINT_NETWORK_FOUND_INDEX,
		  flags);

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

	hddLog(LOG1, "Req Id %u Id %u ANQP length %u num_matches %u",
		data->request_id, data->id, data->anqp_len, num_matches);
	for (i = 0; i < num_matches; i++) {
		hddLog(LOG1, "AP Info: Timestamp %llu Ssid: %s "
					"Bssid (" MAC_ADDRESS_STR ") "
					"Channel %u "
					"Rssi %d "
					"RTT %u "
					"RTT_SD %u "
					"Bcn Period %d "
					"Capability 0x%X "
					"IE Length %d",
					data->ap.ts,
					data->ap.ssid,
					MAC_ADDR_ARRAY(data->ap.bssid),
					data->ap.channel,
					data->ap.rssi,
					data->ap.rtt,
					data->ap.rtt_sd,
					data->ap.beaconPeriod,
					data->ap.capability,
					data->ap.ieLength);
	}

	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
		data->request_id) ||
	    nla_put_u32(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_PNO_RESULTS_PASSPOINT_NETWORK_FOUND_NUM_MATCHES,
		num_matches) ||
	    nla_put_u8(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
		more_data)) {
		hddLog(LOGE, FL("nla put fail"));
		goto fail;
	}

	nla_aps = nla_nest_start(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_PNO_RESULTS_PASSPOINT_MATCH_RESULT_LIST);
	if (!nla_aps)
		goto fail;

	for (i = 0; i < num_matches; i++) {
		struct nlattr *nla_ap;

		nla_ap = nla_nest_start(skb, i);
		if (!nla_ap)
			goto fail;

		if (nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_EXTSCAN_PNO_RESULTS_PASSPOINT_MATCH_ID,
			data->id) ||
		    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_EXTSCAN_PNO_RESULTS_PASSPOINT_MATCH_ANQP_LEN,
			data->anqp_len)) {
			goto fail;
		}

		if (data->anqp_len)
			if (nla_put(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_PNO_RESULTS_PASSPOINT_MATCH_ANQP,
				data->anqp_len, data->anqp))
				goto fail;

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

		if (hdd_extscan_nl_fill_bss(skb, &data->ap, 0))
				goto fail;
		nla_nest_end(skb, nla_bss);
		nla_nest_end(skb, nla_ap);
	}
	nla_nest_end(skb, nla_aps);

	cfg80211_vendor_event(skb, flags);
	return;

fail:
	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() intentionally not used in a frequently invoked API */

    if (wlan_hdd_validate_context(pHddCtx))
        return;

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

    switch (evType) {
    case eSIR_EXTSCAN_CACHED_RESULTS_RSP:
             /* There is no need to send this response to upper layer
                Just log the message */
             hddLog(LOG2, FL("Rcvd eSIR_EXTSCAN_CACHED_RESULTS_RSP"));
            break;

    case eSIR_EXTSCAN_GET_CAPABILITIES_IND:
            wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx,
                    (struct ext_scan_capabilities_response *)pMsg);
            break;

    case eSIR_EXTSCAN_HOTLIST_MATCH_IND:
            wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
            break;

    case eSIR_EXTSCAN_SIGNIFICANT_WIFI_CHANGE_RESULTS_IND:
            wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(
                                         ctx,
                                         (tpSirWifiSignificantChangeEvent)pMsg);
            break;

    case eSIR_EXTSCAN_CACHED_RESULTS_IND:
            wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
            break;

    case eSIR_EXTSCAN_SCAN_RES_AVAILABLE_IND:
            wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx,
                                   (tpSirExtScanResultsAvailableIndParams)pMsg);
            break;

    case eSIR_EXTSCAN_FULL_SCAN_RESULT_IND:
            wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx,
                                   (tpSirWifiFullScanResultEvent)pMsg);
            break;

    case eSIR_EPNO_NETWORK_FOUND_IND:
            wlan_hdd_cfg80211_extscan_epno_match_found(ctx,
                                   (struct pno_match_found *)pMsg);
            break;

    case eSIR_EXTSCAN_SCAN_PROGRESS_EVENT_IND:
            wlan_hdd_cfg80211_extscan_scan_progress_event(ctx,
                                   (tpSirExtScanOnScanEventIndParams)pMsg);
            break;

    case eSIR_PASSPOINT_NETWORK_FOUND_IND:
            wlan_hdd_cfg80211_passpoint_match_found(ctx,
                                    (struct wifi_passpoint_match *) pMsg);
            break;

    case eSIR_EXTSCAN_START_RSP:
    case eSIR_EXTSCAN_STOP_RSP:
    case eSIR_EXTSCAN_SET_BSSID_HOTLIST_RSP:
    case eSIR_EXTSCAN_RESET_BSSID_HOTLIST_RSP:
    case eSIR_EXTSCAN_SET_SIGNIFICANT_WIFI_CHANGE_RSP:
    case eSIR_EXTSCAN_RESET_SIGNIFICANT_WIFI_CHANGE_RSP:
    case eSIR_EXTSCAN_SET_SSID_HOTLIST_RSP:
    case eSIR_EXTSCAN_RESET_SSID_HOTLIST_RSP:
	    wlan_hdd_cfg80211_extscan_generic_rsp(ctx, pMsg);
	    break;

    default:
            hddLog(LOGE, FL("Unknown event type %u"), evType);
            break;
    }
}

#endif /* FEATURE_WLAN_EXTSCAN */

/**
 * wlan_hdd_cfg80211_chainrssi_callback - chainrssi callback
 * @ctx: hdd context
 * @pmsg: pmsg
 *
 * Return: void
 */
void wlan_hdd_cfg80211_chainrssi_callback(void *ctx, void *pmsg)
{
	hdd_context_t *hdd_ctx = (hdd_context_t *)ctx;
	struct chain_rssi_result *data = (struct chain_rssi_result *)pmsg;
	struct hdd_chain_rssi_context *context;
	bool ignore_result;

	ENTER();

	if (wlan_hdd_validate_context(hdd_ctx))
		return;

	spin_lock(&hdd_context_lock);
	context = &hdd_ctx->chain_rssi_context;
	ignore_result = context->ignore_result;

	if (ignore_result) {
		hddLog(LOGE, FL("Ignore the result received after timeout"));
		spin_unlock(&hdd_context_lock);
		return;
	}

	memcpy(&context->result, data, sizeof(*data));

	complete(&context->response_event);
	spin_unlock(&hdd_context_lock);

	return;
}

#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();

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

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

	wlan_hdd_scan_abort(adapter);
}

/**
 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
 * @wiphy: Pointer to wiphy
 * @wdev: Pointer to wireless device structure
 *
 * Wrapper to __wlan_hdd_cfg80211_abort_scan() -
 * function is used to abort an ongoing scan
 *
 * Return: None
 */
static 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__);
}
#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)) && !defined(WITH_BACKPORTS)
    .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)) && !defined(WITH_BACKPORTS)
    .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,
     .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,
     .dump_station = wlan_hdd_cfg80211_dump_station,
     .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 CONFIG_NL80211_TESTMODE
#ifdef WLAN_NL80211_TESTMODE
     .testmode_cmd = wlan_hdd_cfg80211_testmode,
#endif
#endif
#ifdef QCA_HT_2040_COEX
     .set_ap_chanwidth = wlan_hdd_cfg80211_set_ap_channel_width,
#endif
     .dump_survey = wlan_hdd_cfg80211_dump_survey,
#ifdef CHANNEL_SWITCH_SUPPORTED
     .channel_switch = wlan_hdd_cfg80211_channel_switch,
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
    defined(CFG80211_ABORT_SCAN)
     .abort_scan = wlan_hdd_cfg80211_abort_scan,
#endif
};
