/*
 * Copyright (c) 2011-2020, 2021 The Linux Foundation. All rights reserved.
 * Copyright (c) 2021 Qualcomm Innovation Center, Inc. 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_wext.c

    \brief Airgo Linux Wireless Extensions Common Control Plane Types and
    interfaces.

    $Id: wlan_hdd_wext.c,v 1.34 2007/04/14 01:49:23 jimz Exp jimz $This file defines all of the types that are utilized by the CCP module
    of the "Portable" HDD.   This file also includes the underlying Linux
    Wireless Extensions Data types referred to by CCP.

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

#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/wireless.h>
#include <macTrace.h>
#include <wlan_hdd_includes.h>
#include <wlan_nlink_common.h>
#include <vos_api.h>
#include <net/arp.h>
#include "ccmApi.h"
#include "sirParams.h"
#include "csrApi.h"
#include "csrInsideApi.h"
#if defined WLAN_FEATURE_VOWIFI
#include "smeRrmInternal.h"
#endif
#include <aniGlobal.h>
#include "dot11f.h"
#include <wlan_hdd_wowl.h>
#include <wlan_hdd_cfg.h>
#include <wlan_hdd_wmm.h>
#include "utilsApi.h"
#include "wlan_hdd_p2p.h"
#ifdef FEATURE_WLAN_TDLS
#include "wlan_hdd_tdls.h"
#endif

#include "ieee80211_common.h"
#include "ol_if_athvar.h"
#include "dbglog_host.h"
#include "wma.h"

#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include "wlan_hdd_power.h"
#include "qwlan_version.h"
#include "wlan_hdd_host_offload.h"
#include "wlan_hdd_keep_alive.h"
#ifdef WLAN_FEATURE_PACKET_FILTERING
#include "wlan_hdd_packet_filtering.h"
#endif

#include <linux/wireless.h>
#include <net/cfg80211.h>
#include "wlan_qct_tl.h"

#include "wlan_hdd_misc.h"

#include "wlan_hdd_dev_pwr.h"
#include "qc_sap_ioctl.h"
#include "sme_Api.h"
#include "wlan_qct_wda.h"
#include "vos_trace.h"
#include "wlan_hdd_assoc.h"
#include "adf_trace.h"

#ifdef QCA_PKT_PROTO_TRACE
#include "vos_packet.h"
#endif /* QCA_PKT_PROTO_TRACE */

#ifdef CONFIG_HAS_EARLYSUSPEND
#include "wlan_hdd_cfg80211.h"
#endif

#include "wlan_hdd_ocb.h"
#include "wlan_hdd_tsf.h"
#include "vos_nvitem.h"
#include "wlan_hdd_oemdata.h"
#include "wlan_hdd_request_manager.h"

#define HDD_FINISH_ULA_TIME_OUT         800
#define HDD_SET_MCBC_FILTERS_TO_FW      1
#define HDD_DELETE_MCBC_FILTERS_FROM_FW 0

static int ioctl_debug;
module_param(ioctl_debug, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

/* To Validate Channel against the Frequency and Vice-Versa */
static const hdd_freq_chan_map_t freq_chan_map[] = { {2412, 1}, {2417, 2},
        {2422, 3}, {2427, 4}, {2432, 5}, {2437, 6}, {2442, 7}, {2447, 8},
        {2452, 9}, {2457, 10}, {2462, 11}, {2467 ,12}, {2472, 13},
        {2484, 14}, {5180, 36}, {5200, 40}, {5220, 44},
        {5240, 48}, {5260, 52}, {5280, 56}, {5300, 60}, {5320, 64}, {5500, 100},
        {5520, 104}, {5540, 108}, {5560, 112}, {5580, 116}, {5600, 120},
        {5620, 124}, {5640, 128}, {5660, 132}, {5680, 136}, {5700, 140},
        {5720, 144}, {5745, 149}, {5765, 153}, {5785, 157}, {5805, 161},
        {5825, 165}, {5852, 170}, {5855, 171}, {5860, 172}, {5865, 173},
        {5870, 174}, {5875, 175}, {5880, 176}, {5885, 177}, {5890, 178},
        {5895, 179}, {5900, 180}, {5905, 181}, {5910, 182}, {5915, 183},
        {5920, 184} };

#define FREQ_CHAN_MAP_TABLE_SIZE  (sizeof(freq_chan_map)/sizeof(freq_chan_map[0]))

#define RC_2_RATE_IDX(_rc)        ((_rc) & 0x7)
#define HT_RC_2_STREAMS(_rc)      ((((_rc) & 0x78) >> 3) + 1)

#define RC_2_RATE_IDX_11AC(_rc)   ((_rc) & 0xf)
#define HT_RC_2_STREAMS_11AC(_rc) ((((_rc) & 0x30) >> 4) + 1)

/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_INT_GET_NONE                (SIOCIWFIRSTPRIV + 0)
#define WE_SET_11D_STATE                          1
#define WE_WOWL                                   2
#define WE_SET_POWER                              3
#define WE_SET_MAX_ASSOC                          4
#define WE_SET_SAP_AUTO_CHANNEL_SELECTION         5
#define WE_SET_DATA_INACTIVITY_TO                 6
#define WE_SET_MAX_TX_POWER                       7
#define WE_SET_HIGHER_DTIM_TRANSITION             8
#define WE_SET_TM_LEVEL                           9
#define WE_SET_PHYMODE                            10
#define WE_SET_NSS                                11
#define WE_SET_LDPC                               12
#define WE_SET_TX_STBC                            13
#define WE_SET_RX_STBC                            14
#define WE_SET_SHORT_GI                           15
#define WE_SET_RTSCTS                             16
#define WE_SET_CHWIDTH                            17
#define WE_SET_ANI_EN_DIS                         18
#define WE_SET_ANI_POLL_PERIOD                    19
#define WE_SET_ANI_LISTEN_PERIOD                  20
#define WE_SET_ANI_OFDM_LEVEL                     21
#define WE_SET_ANI_CCK_LEVEL                      22
#define WE_SET_DYNAMIC_BW                         23
#define WE_SET_TX_CHAINMASK                       24
#define WE_SET_RX_CHAINMASK                       25
#define WE_SET_11N_RATE                           26
#define WE_SET_AMPDU                              27
#define WE_SET_AMSDU                              28
#define WE_SET_TXPOW_2G                           29
#define WE_SET_TXPOW_5G                           30
/* Private ioctl for firmware debug log */
#define WE_DBGLOG_LOG_LEVEL                       31
#define WE_DBGLOG_VAP_ENABLE                      32
#define WE_DBGLOG_VAP_DISABLE                     33
#define WE_DBGLOG_MODULE_ENABLE                   34
#define WE_DBGLOG_MODULE_DISABLE                  35
#define WE_DBGLOG_MOD_LOG_LEVEL                   36
#define WE_DBGLOG_TYPE                            37
#define WE_SET_TXRX_FWSTATS                       38
#define WE_SET_VHT_RATE                           39
#define WE_DBGLOG_REPORT_ENABLE                   40
#define WE_TXRX_FWSTATS_RESET                     41
#define WE_SET_MAX_TX_POWER_2_4                   42
#define WE_SET_MAX_TX_POWER_5_0                   43
/* 44 is unused */
/* Private ioctl for packet power save */
#define  WE_PPS_PAID_MATCH                        45
#define  WE_PPS_GID_MATCH                         46
#define  WE_PPS_EARLY_TIM_CLEAR                   47
#define  WE_PPS_EARLY_DTIM_CLEAR                  48
#define  WE_PPS_EOF_PAD_DELIM                     49
#define  WE_PPS_MACADDR_MISMATCH                  50
#define  WE_PPS_DELIM_CRC_FAIL                    51
#define  WE_PPS_GID_NSTS_ZERO                     52
#define  WE_PPS_RSSI_CHECK                        53
/* 54 is unused */
#define WE_SET_HTSMPS                             55
/* Private ioctl for QPower */
#define WE_SET_QPOWER_MAX_PSPOLL_COUNT            56
#define WE_SET_QPOWER_MAX_TX_BEFORE_WAKE          57
#define WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL   58
#define WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL 59

#define WE_SET_BURST_ENABLE                       60
#define WE_SET_BURST_DUR                          61
/* GTX Commands */
#define WE_SET_GTX_HT_MCS                         62
#define WE_SET_GTX_VHT_MCS                        63
#define WE_SET_GTX_USRCFG                         64
#define WE_SET_GTX_THRE                           65
#define WE_SET_GTX_MARGIN                         66
#define WE_SET_GTX_STEP                           67
#define WE_SET_GTX_MINTPC                         68
#define WE_SET_GTX_BWMASK                         69
/* Private ioctl to configure MCC home channels time quota and latency */
#define WE_MCC_CONFIG_LATENCY                     70
#define WE_MCC_CONFIG_QUOTA                       71
/* Private IOCTL for debug connection issues */
#define WE_SET_DEBUG_LOG                          72
#define  WE_SET_SCAN_BAND_PREFERENCE              73
#ifdef WE_SET_TX_POWER
#undef WE_SET_TX_POWER
#endif
#define WE_SET_TX_POWER                           74
/* Private ioctl for earlyrx power save feature */
#define WE_SET_EARLY_RX_ADJUST_ENABLE             75
#define WE_SET_EARLY_RX_TGT_BMISS_NUM             76
#define WE_SET_EARLY_RX_BMISS_SAMPLE_CYCLE        77
#define WE_SET_EARLY_RX_SLOP_STEP                 78
#define WE_SET_EARLY_RX_INIT_SLOP                 79
#define WE_SET_EARLY_RX_ADJUST_PAUSE              80
#define WE_SET_MC_RATE                            81
#define WE_SET_EARLY_RX_DRIFT_SAMPLE              82
/* Private ioctl for packet power save */
#define WE_PPS_5G_EBT                             83
#define WE_SET_CTS_CBW                            84
#define WE_DUMP_STATS                             85
#define WE_CLEAR_STATS                            86
#define WE_SET_CHANNEL                            87
#define WE_SET_MODULATED_DTIM                     88
#define WE_SET_MON_FILTER                         89
typedef enum eMonFilterType{
        MON_MGMT_PKT,
        MON_CTRL_PKT,
        MON_DATA_PKT,
        MON_ALL_PKT,
} tMonFilterType;

#define WE_SET_TDLS_OFFCHANNEL_MODE               90
#define WE_SET_TDLS_OFFCHANNEL                    91
#define WE_SET_TDLS_OFFCHANNEL_SEC_OFFSET         92
#ifdef WLAN_FEATURE_MOTION_DETECTION
#define WE_MOTION_DET_START_STOP                  93
#define WE_MOTION_DET_BASE_LINE_START_STOP        94
#endif
#define WE_SET_WOW_START                          95
#define WE_SAP_TX_OFF                             96
#define WE_SET_TXRX_PRINT_LEVEL                   97
#define WE_SAP_SET_TARGET_CHANNEL                 98
#define WE_SAP_SET_CAC_TIME                       99

/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_NONE_GET_INT                (SIOCIWFIRSTPRIV + 1)
#define WE_GET_11D_STATE                          1
#define WE_IBSS_STATUS                            2
#define WE_SET_SAP_CHANNELS                       3
#define WE_GET_WLAN_DBG                           4
#define WE_GET_MAX_ASSOC                          6
/* 7 is unused */
#define WE_GET_SAP_AUTO_CHANNEL_SELECTION         8
#define WE_GET_CONCURRENCY_MODE                   9
#define WE_GET_NSS                                11
#define WE_GET_LDPC                               12
#define WE_GET_TX_STBC                            13
#define WE_GET_RX_STBC                            14
#define WE_GET_SHORT_GI                           15
#define WE_GET_RTSCTS                             16
#define WE_GET_CHWIDTH                            17
#define WE_GET_ANI_EN_DIS                         18
#define WE_GET_ANI_POLL_PERIOD                    19
#define WE_GET_ANI_LISTEN_PERIOD                  20
#define WE_GET_ANI_OFDM_LEVEL                     21
#define WE_GET_ANI_CCK_LEVEL                      22
#define WE_GET_DYNAMIC_BW                         23
#define WE_GET_TX_CHAINMASK                       24
#define WE_GET_RX_CHAINMASK                       25
#define WE_GET_11N_RATE                           26
#define WE_GET_AMPDU                              27
#define WE_GET_AMSDU                              28
#define WE_GET_TXPOW_2G                           29
#define WE_GET_TXPOW_5G                           30
/* 31 is unused */
#define WE_GET_PPS_PAID_MATCH                     32
#define WE_GET_PPS_GID_MATCH                      33
#define WE_GET_PPS_EARLY_TIM_CLEAR                34
#define WE_GET_PPS_EARLY_DTIM_CLEAR               35
#define WE_GET_PPS_EOF_PAD_DELIM                  36
#define WE_GET_PPS_MACADDR_MISMATCH               37
#define WE_GET_PPS_DELIM_CRC_FAIL                 38
#define WE_GET_PPS_GID_NSTS_ZERO                  39
#define WE_GET_PPS_RSSI_CHECK                     40
/* Private ioctl for QPower */
#define WE_GET_QPOWER_MAX_PSPOLL_COUNT            41
#define WE_GET_QPOWER_MAX_TX_BEFORE_WAKE          42
#define WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL   43
#define WE_GET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL 44
#define WE_GET_BURST_ENABLE                       45
#define WE_GET_BURST_DUR                          46
/* GTX Commands */
#define WE_GET_GTX_HT_MCS                         47
#define WE_GET_GTX_VHT_MCS                        48
#define WE_GET_GTX_USRCFG                         49
#define WE_GET_GTX_THRE                           50
#define WE_GET_GTX_MARGIN                         51
#define WE_GET_GTX_STEP                           52
#define WE_GET_GTX_MINTPC                         53
#define WE_GET_GTX_BWMASK                         54
#define WE_GET_SCAN_BAND_PREFERENCE               55
#define WE_GET_TEMPERATURE                        56
#define WE_GET_FW_STATUS                          57
#define WE_CAP_TSF                                58
#define WE_PBM_MP_GET_REASON                      59

/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_INT_GET_INT                 (SIOCIWFIRSTPRIV + 2)
/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_CHAR_GET_NONE               (SIOCIWFIRSTPRIV + 3)
#define WE_WOWL_ADD_PTRN                          1
#define WE_WOWL_DEL_PTRN                          2
#if defined WLAN_FEATURE_VOWIFI
#define WE_NEIGHBOR_REPORT_REQUEST                3
#endif
/* This is called in station mode to set probe rsp ie */
#define WE_SET_AP_WPS_IE                          4
#define WE_SET_CONFIG                             5

/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_THREE_INT_GET_NONE          (SIOCIWFIRSTPRIV + 4)
#define WE_SET_WLAN_DBG                           1
#define WE_SET_DP_TRACE                           2
#define WE_SET_SAP_CHANNELS                       3
#define WE_SET_ADD_EASY_WOW_PORT                  4
#define WE_SET_RM_EASY_WOW_PORT                   5

/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_GET_CHAR_SET_NONE               (SIOCIWFIRSTPRIV + 5)
#define WE_WLAN_VERSION                           1
#define WE_GET_STATS                              2
#define WE_GET_CFG                                3
#define WE_GET_WMM_STATUS                         4
#define WE_GET_CHANNEL_LIST                       5
#ifdef WLAN_FEATURE_11AC
#define WE_GET_RSSI                               6
#endif
#ifdef FEATURE_WLAN_TDLS
#define WE_GET_TDLS_PEERS                         8
#endif
#ifdef WLAN_FEATURE_11W
#define WE_GET_11W_INFO                           9
#endif
#define WE_GET_STATES                             10
#define WE_GET_IBSS_STA_INFO                      11
#define WE_GET_PHYMODE                            12
#ifdef FEATURE_OEM_DATA_SUPPORT
#define WE_GET_OEM_DATA_CAP                       13
#endif
#define WE_GET_SNR                                14
#define WE_GET_PS_TDCC                            15
#ifdef AUDIO_MULTICAST_AGGR_SUPPORT
#define WE_AUDIO_GET_RX_GROUP_INFO                16
#endif

/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_NONE_GET_NONE               (SIOCIWFIRSTPRIV + 6)
#define WE_ENABLE_DXE_STALL_DETECT                6
#define WE_DISPLAY_DXE_SNAP_SHOT                  7
#define WE_SET_REASSOC_TRIGGER                    8
#define WE_DISPLAY_DATAPATH_SNAP_SHOT             9
#define WE_IBSS_GET_PEER_INFO_ALL                 10
#define WE_DUMP_AGC_START                         11
#define WE_DUMP_AGC                               12
#define WE_DUMP_CHANINFO_START                    13
#define WE_DUMP_CHANINFO                          14
#define WE_DUMP_WATCHDOG                          15
#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG
#define WE_DUMP_PCIE_LOG                          16
#endif
#define WE_GET_RECOVERY_STAT                      17

/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_VAR_INT_GET_NONE            (SIOCIWFIRSTPRIV + 7)
#define WE_LOG_DUMP_CMD                           1
#define WE_P2P_NOA_CMD                            2
//IOCTL to configure MCC params
#define WE_MCC_CONFIG_CREDENTIAL                  3
#define WE_MCC_CONFIG_PARAMS                      4
#ifdef FEATURE_WLAN_TDLS
#define WE_TDLS_CONFIG_PARAMS                     5
#endif
#define WE_IBSS_GET_PEER_INFO                     6
#define WE_UNIT_TEST_CMD                          7
#define WE_MTRACE_DUMP_CMD                        8
#define WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD 9
#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
#define WE_LED_FLASHING_PARAM                     10
#endif
#ifdef MEMORY_DEBUG
#define WE_MEM_TRACE_DUMP                         11
#endif

#ifdef FEATURE_WLAN_TDLS
#undef  MAX_VAR_ARGS
#define MAX_VAR_ARGS                              11
#else
#undef  MAX_VAR_ARGS
#define MAX_VAR_ARGS                              7
#endif

#ifdef WLAN_FEATURE_MOTION_DETECTION
#undef  MAX_VAR_ARGS
#define MAX_VAR_ARGS                              15
#define WE_MOTION_DET_CONFIG_PARAM                12
#define WE_MOTION_DET_BASE_LINE_CONFIG_PARAM      13
#endif
#define WE_SET_THERMAL_THROTTLE_CONFIG            14
#define WE_SET_HPCS_PULSE_PARAMS_CONFIG           15

/* Private ioctls (with no sub-ioctls) */
/* note that they must be odd so that they have "get" semantics */
#define WLAN_PRIV_ADD_TSPEC                       (SIOCIWFIRSTPRIV +  9)
#define WLAN_PRIV_DEL_TSPEC                       (SIOCIWFIRSTPRIV + 11)
#define WLAN_PRIV_GET_TSPEC                       (SIOCIWFIRSTPRIV + 13)

/* (SIOCIWFIRSTPRIV + 8)  is currently unused */
/* (SIOCIWFIRSTPRIV + 16) is currently unused */
/* (SIOCIWFIRSTPRIV + 10) is currently unused */
/* (SIOCIWFIRSTPRIV + 12) is currently unused */
/* (SIOCIWFIRSTPRIV + 14) is currently unused */

#define WLAN_PRIV_SET_NONE_GET_THREE_INT          (SIOCIWFIRSTPRIV + 15)
#define WE_GET_TSF      1

/* (SIOCIWFIRSTPRIV + 17) is currently unused */

#define WLAN_GET_ISOLATION                        (SIOCIWFIRSTPRIV + 19)

#ifdef WLAN_FEATURE_VOWIFI_11R
#define WLAN_PRIV_SET_FTIES                       (SIOCIWFIRSTPRIV + 20)
#endif

/* Private ioctl for setting the host offload feature */
#define WLAN_PRIV_SET_HOST_OFFLOAD                (SIOCIWFIRSTPRIV + 18)
/* Private ioctl to get the statistics */
#define WLAN_GET_WLAN_STATISTICS                  (SIOCIWFIRSTPRIV + 21)
/* Private ioctl to set the Keep Alive Params */
#define WLAN_SET_KEEPALIVE_PARAMS                 (SIOCIWFIRSTPRIV + 22)

#ifdef WLAN_FEATURE_PACKET_FILTERING
/* Private ioctl to set the Packet Filtering Params */
#define WLAN_SET_PACKET_FILTER_PARAMS             (SIOCIWFIRSTPRIV + 23)
#endif

#ifdef FEATURE_WLAN_SCAN_PNO
/* Private ioctl to get the statistics */
#define WLAN_SET_PNO                              (SIOCIWFIRSTPRIV + 24)
#endif

#define WLAN_SET_BAND_CONFIG                      (SIOCIWFIRSTPRIV + 25)  /*Don't change this number*/
#define WLAN_PRIV_SET_MCBC_FILTER                 (SIOCIWFIRSTPRIV + 26)
#define WLAN_PRIV_CLEAR_MCBC_FILTER               (SIOCIWFIRSTPRIV + 27)
/* Private ioctl to trigger reassociation */
#define WLAN_SET_POWER_PARAMS                     (SIOCIWFIRSTPRIV + 29)
/* 802.11p IOCTL */
#define WLAN_SET_DOT11P_CHANNEL_SCHED             (SIOCIWFIRSTPRIV + 30)
#define WLAN_GET_LINK_SPEED                       (SIOCIWFIRSTPRIV + 31)
/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_TWO_INT_GET_NONE            (SIOCIWFIRSTPRIV + 28)
#define WE_SET_SMPS_PARAM                         1
#ifdef WLAN_DEBUG
#define WE_SET_FW_CRASH_INJECT                    2
#endif
#define WE_SET_MON_MODE_CHAN                      3
#define WE_DUMP_DP_TRACE_LEVEL                    4


#define WLAN_STATS_INVALID                        0
#define WLAN_STATS_RETRY_CNT                      1
#define WLAN_STATS_MUL_RETRY_CNT                  2
#define WLAN_STATS_TX_FRM_CNT                     3
#define WLAN_STATS_RX_FRM_CNT                     4
#define WLAN_STATS_FRM_DUP_CNT                    5
#define WLAN_STATS_FAIL_CNT                       6
#define WLAN_STATS_RTS_FAIL_CNT                   7
#define WLAN_STATS_ACK_FAIL_CNT                   8
#define WLAN_STATS_RTS_SUC_CNT                    9
#define WLAN_STATS_RX_DISCARD_CNT                 10
#define WLAN_STATS_RX_ERROR_CNT                   11
#define WLAN_STATS_TX_BYTE_CNT                    12
#define WLAN_STATS_RX_BYTE_CNT                    13
#define WLAN_STATS_RX_RATE                        14
#define WLAN_STATS_TX_RATE                        15
#define WLAN_STATS_RX_UC_BYTE_CNT                 16
#define WLAN_STATS_RX_MC_BYTE_CNT                 17
#define WLAN_STATS_RX_BC_BYTE_CNT                 18
#define WLAN_STATS_TX_UC_BYTE_CNT                 19
#define WLAN_STATS_TX_MC_BYTE_CNT                 20
#define WLAN_STATS_TX_BC_BYTE_CNT                 21
#define WE_SET_PS_TDCC                            22

#define FILL_TLV(__p, __type, __size, __val, __tlen) do {           \
        if ((__tlen + __size + 2) < WE_MAX_STR_LEN)                 \
        {                                                           \
            *__p++ = __type;                                        \
            *__p++ = __size;                                        \
            memcpy(__p, __val, __size);                             \
            __p += __size;                                          \
            __tlen += __size + 2;                                   \
        }                                                           \
        else                                                        \
        {                                                           \
            hddLog(VOS_TRACE_LEVEL_ERROR, "FILL_TLV Failed!!!");  \
        }                                                           \
    } while(0);

#define VERSION_VALUE_MAX_LEN                 32

#define TX_PER_TRACKING_DEFAULT_RATIO         5
#define TX_PER_TRACKING_MAX_RATIO             10
#define TX_PER_TRACKING_DEFAULT_WATERMARK     5

#define WLAN_ADAPTER                          0
#define P2P_ADAPTER                           1

/*MCC Configuration parameters */
enum {
    MCC_SCHEDULE_TIME_SLICE_CFG_PARAM = 1,
    MCC_MAX_NULL_SEND_TIME_CFG_PARAM,
    MCC_TX_EARLY_STOP_TIME_CFG_PARAM,
    MCC_RX_DRAIN_TIME_CFG_PARAM,
    MCC_CHANNEL_SWITCH_TIME_CFG_PARAM,
    MCC_MIN_CHANNEL_TIME_CFG_PARAM,
    MCC_PARK_BEFORE_TBTT_CFG_PARAM,
    MCC_MIN_AFTER_DTIM_CFG_PARAM,
    MCC_TOO_CLOSE_MARGIN_CFG_PARAM,
};

static const struct qwlan_hw qwlan_hw_list[] = {
    {
        .id = AR6320_REV1_VERSION,
        .subid = 0,
        .name = "QCA6174_REV1",
    },
    {
        .id = AR6320_REV1_1_VERSION,
        .subid = 0x1,
        .name = "QCA6174_REV1_1",
    },
    {
        .id = AR6320_REV1_3_VERSION,
        .subid = 0x2,
        .name = "QCA6174_REV1_3",
    },
    {
        .id = AR6320_REV2_1_VERSION,
        .subid = 0x4,
        .name = "QCA6174_REV2_1",
    },
    {
        .id = AR6320_REV2_1_VERSION,
        .subid = 0x5,
        .name = "QCA6174_REV2_2",
    },
    {
        .id = AR6320_REV3_VERSION,
        .subid = 0x6,
        .name = "QCA6174_REV2.3",
    },
    {
        .id = AR6320_REV3_VERSION,
        .subid = 0x8,
        .name = "QCA6174_REV3",
    },
    {
        .id = AR6320_REV3_VERSION,
        .subid = 0x9,
        .name = "QCA6174_REV3_1",
    },
    {
        .id = AR6320_REV3_2_VERSION,
        .subid = 0xA,
        .name = "QCA6174_REV3_2",
    },
    {
        .id = AR6320_REV3_VERSION,
        .subid = 0x0,
        .name = "QCA9377_REV1",
    },
    {
        .id = QCA9377_REV1_1_VERSION,
        .subid = 0x1,
        .name = "QCA93x7_REV1_1",
    },
    {
        .id = QCA9379_REV1_VERSION,
        .subid = 0xC,
        .name = "QCA9379_REV1",
    },
    {
        .id = QCA9379_REV1_VERSION,
        .subid = 0xD,
        .name = "QCA9379_REV1_1",
    }
};

int hdd_validate_mcc_config(hdd_adapter_t *pAdapter, v_UINT_t staId,
                                v_UINT_t arg1, v_UINT_t arg2, v_UINT_t arg3);

#ifdef WLAN_FEATURE_PACKET_FILTERING
int wlan_hdd_set_filter(hdd_context_t *pHddCtx, tpPacketFilterCfg pRequest,
                           v_U8_t sessionId);
#endif

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

  \brief mem_alloc_copy_from_user_helper -

   Helper function to allocate buffer and copy user data.

  \param  - wrqu - Pointer to IOCTL Data.
            len  - size

  \return - On Success pointer to buffer, On failure NULL

  --------------------------------------------------------------------------*/
void *mem_alloc_copy_from_user_helper(const void *wrqu_data, size_t len)
{
    u8 *ptr = NULL;

  /* in order to protect the code, an extra byte is post appended to the buffer
   * and the null termination is added.  However, when allocating (len+1) byte
   * of memory, we need to make sure that there is no uint overflow when doing
   * addition. In theory check len < UINT_MAX protects the uint overflow. For
   * wlan private ioctl, the buffer size is much less than UINT_MAX, as a good
   * guess, now, it is assumed that the private command buffer size is no
   * greater than 4K (4096 bytes). So we use 4096 as the upper boundary for now.
   */
    if (len > MAX_USER_COMMAND_SIZE)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "Invalid length");
        return NULL;
    }


    ptr = vos_mem_malloc(len + 1);
    if (NULL == ptr)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "unable to allocate memory");
        return NULL;
    }

    if (copy_from_user(ptr, wrqu_data, len))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: failed to copy data to user buffer", __func__);
        vos_mem_free(ptr);
        return NULL;
    }
    ptr[len] = '\0';
    return ptr;
}

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

  \brief hdd_priv_get_data -

   Helper function to get compatible struct iw_point passed to ioctl

  \param  - p_priv_data - pointer to iw_point struct to be filled
            wrqu - Pointer to IOCTL Data received from user space

  \return - 0 if p_priv_data successfully filled
            error otherwise

  --------------------------------------------------------------------------*/
int hdd_priv_get_data(struct iw_point *p_priv_data,
                      union iwreq_data *wrqu)
{
   if ((NULL == p_priv_data) || (NULL == wrqu)) {
      return -EINVAL;
   }

#ifdef CONFIG_COMPAT
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)) && defined(CONFIG_X86_64)
   if (in_compat_syscall()) {
#else
   if (is_compat_task()) {
#endif
      struct compat_iw_point *p_compat_priv_data;

      /* Compat task: typecast to compat structure and copy the members. */
      p_compat_priv_data = (struct compat_iw_point *) &wrqu->data;

      p_priv_data->pointer = compat_ptr(p_compat_priv_data->pointer);
      p_priv_data->length  = p_compat_priv_data->length;
      p_priv_data->flags   = p_compat_priv_data->flags;
   } else {
#endif /* #ifdef CONFIG_COMPAT */

      /* Non compat task: directly copy the structure. */
      memcpy(p_priv_data, &wrqu->data, sizeof(struct iw_point));

#ifdef CONFIG_COMPAT
   }
#endif /* #ifdef CONFIG_COMPAT */

   return 0;
}

#define WLAN_HDD_MAX_BW_VALUE	5

/**
 * wlan_hdd_validate_mon_channel() - check channel number is valid or not
 * @channel: channel number
 *
 * @return: VOS_STATUS
 */
VOS_STATUS wlan_hdd_validate_mon_channel(int channel)
{
        uint8_t fValidChannel = FALSE, count = 0;

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

/**
 * wlan_hdd_validate_mon_bw() - check bandwidth value is valid or not
 * @ch: channel value
 * @bw: bandwidth value
 *
 * @return: VOS_STATUS
 */
VOS_STATUS wlan_hdd_validate_mon_bw(int ch, int bw)
{
        if (bw >= 0 && bw <= WLAN_HDD_MAX_BW_VALUE) {
            /* Check if bandwidth from user is valid in 2.4GHz */
            if ((ch >= rfChannels[RF_CHAN_1].channelNum) &&
                (ch <= rfChannels[RF_CHAN_14].channelNum)) {
                if (bw > 1) {
                   hddLog(VOS_TRACE_LEVEL_ERROR,
                       "Invalid bw %d for 2.4GHz Chan [%d]",bw,ch);
                   return VOS_STATUS_E_INVAL;
                }
            }
            return VOS_STATUS_SUCCESS;
        }
        return VOS_STATUS_E_FAILURE;
}

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

  \brief hdd_wlan_get_stats -

   Helper function to get stats

  \param  - pAdapter Pointer to the adapter.
            wrqu - Pointer to IOCTL REQUEST Data.
            extra - Pointer to char


  \return - zero on success, non zero value on failure

  --------------------------------------------------------------------------*/
int hdd_wlan_get_stats(hdd_adapter_t *pAdapter, v_U16_t *length,
                        char *buffer, v_U16_t buf_len)
{
    hdd_tx_rx_stats_t *pStats = &pAdapter->hdd_stats.hddTxRxStats;
    v_U32_t len;
    __u32 total_rxPkt = 0, total_rxDropped = 0;
    __u32 total_rxDelv = 0, total_rxRefused = 0;
    int i = 0, ret;
    VOS_STATUS status;

    for (; i < NUM_CPUS; i++) {
        total_rxPkt += pStats->rxPackets[i];
        total_rxDropped += pStats->rxDropped[i];
        total_rxDelv += pStats->rxDelivered[i];
        total_rxRefused += pStats->rxRefused[i];
    }

    len = snprintf(buffer, buf_len,
        "\nTransmit"
        "\n  called %u, dropped %u,"
        "\n  dropped BK %u, BE %u, VI %u, VO %u"
        "\n  classified BK %u, BE %u, VI %u, VO %u"
        "\n  completed %u,"
        "\n\nReceive Total"
        "\n  packets %u, dropped %u, delivered %u, refused %u"
        "\n",
        pStats->txXmitCalled,
        pStats->txXmitDropped,

        pStats->txXmitDroppedAC[WLANTL_AC_BK],
        pStats->txXmitDroppedAC[WLANTL_AC_BE],
        pStats->txXmitDroppedAC[WLANTL_AC_VI],
        pStats->txXmitDroppedAC[WLANTL_AC_VO],

        pStats->txXmitClassifiedAC[WLANTL_AC_BK],
        pStats->txXmitClassifiedAC[WLANTL_AC_BE],
        pStats->txXmitClassifiedAC[WLANTL_AC_VI],
        pStats->txXmitClassifiedAC[WLANTL_AC_VO],

        pStats->txCompleted,
        total_rxPkt, total_rxDropped, total_rxDelv, total_rxRefused);

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

    for (i = 0; i < NUM_CPUS; i++) {
        ret = snprintf(buffer+len, buf_len-len,
            "\nReceive CPU: %d"
            "\n  packets %u, dropped %u, delivered %u, refused %u",
            i, pStats->rxPackets[i], pStats->rxDropped[i],
            pStats->rxDelivered[i], pStats->rxRefused[i]);
        if (ret >= (buf_len-len)) {
            hddLog(LOGE,FL("Insufficient buffer:%d, %d"), (buf_len-len), ret);
            return -E2BIG;
        }
        len += ret;
    }
    ret = snprintf(buffer+len, buf_len-len,
        "\n\nTX_FLOW"
        "\nCurrent status %s"
        "\ntx-flow timer start count %u"
        "\npause count %u, unpause count %u\n",
        (pStats->is_txflow_paused == TRUE ? "PAUSED" : "UNPAUSED"),
        pStats->txflow_timer_cnt,
        pStats->txflow_pause_cnt,
        pStats->txflow_unpause_cnt
        );

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

    status = WLANTL_Get_llStats(pAdapter->sessionId,
            &buffer[len], (buf_len - len));
    if (!VOS_IS_STATUS_SUCCESS(status)) {
        hddLog(LOGE,FL("Error in getting stats:%d"), ret);
        ret = (status == VOS_STATUS_E_NOMEM) ? -E2BIG: -EINVAL;
        return ret;
    }

    *length = strlen(buffer) + 1;

    return 0;
}

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

  \brief hdd_wlan_dump_stats -

   Helper function to dump stats

  \param  - pAdapter Pointer to the adapter.
            value - value given by user

  \return - none

  --------------------------------------------------------------------------*/
void hdd_wlan_dump_stats(hdd_adapter_t *pAdapter, int value)
{
    hdd_context_t* hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);

    switch(value)
    {
        case WLAN_TXRX_HIST_STATS:
            wlan_hdd_display_tx_rx_histogram(hdd_ctx);
            break;
        case WLAN_HDD_NETIF_OPER_HISTORY:
            wlan_hdd_display_netif_queue_history(hdd_ctx);
            break;
        default:
            WLANTL_display_datapath_stats(hdd_ctx->pvosContext, value);
            break;
    }
}

#ifdef CLD_REGDB
void hdd_wlan_dump_cld_regdb(hdd_adapter_t *adapter)
{
	hdd_context_t *hdd_ctx;
	struct wiphy *wiphy;
	uint32_t i;
	uint32_t j;
	struct ieee80211_supported_band *band;

	hdd_ctx = WLAN_HDD_GET_CTX(adapter);

	wiphy = hdd_ctx->wiphy;
	for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
		band = wiphy->bands[i];
		if (!band)
			continue;

		for (j = 0; j < band->n_channels; j++)
			pr_info("[CLD-REGDB-DEBUG]: freq %d flags 0x%x\n",
				band->channels[j].center_freq,
				band->channels[j].flags);
	}
}
#else
void hdd_wlan_dump_cld_regdb(hdd_adapter_t *adapter)
{

}
#endif

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

  \brief hdd_wlan_get_version() -

   This function use to get Wlan Driver, Firmware, & Hardware Version.

  \param  - pAdapter Pointer to the adapter.
            wrqu - Pointer to IOCTL REQUEST Data.
            extra - Pointer to char

  \return - none

  --------------------------------------------------------------------------*/
void hdd_wlan_get_version(hdd_adapter_t *pAdapter, union iwreq_data *wrqu,
                          char *extra)
{
    tSirVersionString wcnss_SW_version;
    const char *pSWversion;
    const char *pHWversion;
    v_U32_t MSPId = 0, mSPId = 0, SIId = 0, CRMId = 0;

    hdd_context_t *pHddContext;
    int i = 0;

    pHddContext = WLAN_HDD_GET_CTX(pAdapter);
    if (!pHddContext) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
            "%s:Invalid context, HDD context is null", __func__);
        goto error;
    }

    snprintf(wcnss_SW_version, sizeof(tSirVersionString), "%08x",
        pHddContext->target_fw_version);

    pSWversion = wcnss_SW_version;
    MSPId = (pHddContext->target_fw_version & 0xf0000000) >> 28;
    mSPId = (pHddContext->target_fw_version & 0xf000000) >> 24;
    SIId = (pHddContext->target_fw_version & 0xf00000) >> 20;
    CRMId = pHddContext->target_fw_version & 0x7fff;

    for (i = 0; i < ARRAY_SIZE(qwlan_hw_list); i++) {
        if (pHddContext->target_hw_version == qwlan_hw_list[i].id &&
            pHddContext->target_hw_revision == qwlan_hw_list[i].subid) {
            pHWversion = qwlan_hw_list[i].name;
            break;
        }
    }

    if (i == ARRAY_SIZE(qwlan_hw_list))
        pHWversion = "Unknown";
    pHddContext->target_hw_name = pHWversion;

    if (wrqu) {
        wrqu->data.length = scnprintf(extra, WE_MAX_STR_LEN,
                                     "Host SW:%s, FW:%d.%d.%d.%d, HW:%s",
                                     QWLAN_VERSIONSTR,
                                     MSPId,
                                     mSPId,
                                     SIId,
                                     CRMId,
                                     pHWversion);
    } else {
        pr_info("Host SW:%s, FW:%d.%d.%d.%d, HW:%s\n",
                QWLAN_VERSIONSTR,
                MSPId,
                mSPId,
                SIId,
                CRMId,
                pHWversion);
    }

    hdd_wlan_dump_cld_regdb(pAdapter);

error:
    return;
}

v_MACADDR_t* hdd_wlan_get_ibss_mac_addr_from_staid(hdd_adapter_t *pAdapter, v_U8_t staIdx)
{
   v_U8_t idx;
   hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

   for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
   {
      if ( 0 != pHddStaCtx->conn_info.staId[ idx ] &&
           staIdx == pHddStaCtx->conn_info.staId[ idx ])
      {
         return (&pHddStaCtx->conn_info.peerMacAddress[ idx ]);
      }
   }
   return NULL;
}

eHalStatus hdd_wlan_get_ibss_peer_info(hdd_adapter_t *pAdapter, v_U8_t staIdx)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    hdd_station_ctx_t *pStaCtx =  WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    tSirPeerInfoRspParams *pPeerInfo = &pStaCtx->ibss_peer_info;

    status = sme_RequestIBSSPeerInfo(hHal, pAdapter, hdd_get_ibss_peer_info_cb,
                                     VOS_FALSE, staIdx);

    INIT_COMPLETION(pAdapter->ibss_peer_info_comp);

    if (eHAL_STATUS_SUCCESS == status)
    {
       unsigned long rc;
       rc  = wait_for_completion_timeout
                (&pAdapter->ibss_peer_info_comp,
                msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
       if (!rc) {
          hddLog(VOS_TRACE_LEVEL_ERROR,
                  FL("failed wait on ibss_peer_info_comp"));
          return eHAL_STATUS_FAILURE;
       }

       /** Print the peer info */
       pr_info("pPeerInfo->numIBSSPeers = %d ", pPeerInfo->numPeers);
       pr_info("============================================================");
       {
          uint8_t mac_addr[VOS_MAC_ADDR_SIZE];
          uint32_t tx_rate = pPeerInfo->peerInfoParams[0].txRate;

          vos_mem_copy(mac_addr, pPeerInfo->peerInfoParams[0].mac_addr,
               sizeof(mac_addr));
          pr_info("PEER ADDR : %pM TxRate: %d Mbps  RSSI: %d",
             mac_addr, (int)tx_rate, (int)pPeerInfo->peerInfoParams[0].rssi);
       }
    }
    else
    {
       hddLog(VOS_TRACE_LEVEL_WARN,
              "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
    }

    return status;
}

eHalStatus hdd_wlan_get_ibss_peer_info_all(hdd_adapter_t *pAdapter)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    hdd_station_ctx_t *pStaCtx =  WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    tSirPeerInfoRspParams *pPeerInfo = &pStaCtx->ibss_peer_info;
    int i;

    status = sme_RequestIBSSPeerInfo(hHal, pAdapter, hdd_get_ibss_peer_info_cb,
                                     VOS_TRUE, 0xFF);
    INIT_COMPLETION(pAdapter->ibss_peer_info_comp);

    if (eHAL_STATUS_SUCCESS == status)
    {
       unsigned long rc;
       rc  = wait_for_completion_timeout
                (&pAdapter->ibss_peer_info_comp,
                 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
       if (!rc) {
          hddLog(VOS_TRACE_LEVEL_ERROR,
                  FL("failed wait on ibss_peer_info_comp"));
          return eHAL_STATUS_FAILURE;
       }

       /** Print the peer info */
       pr_info("pPeerInfo->numIBSSPeers = %d ", (int)pPeerInfo->numPeers);
       pr_info("============================================================");
       for (i = 0; i < pPeerInfo->numPeers; i++) {
          uint8_t mac_addr[VOS_MAC_ADDR_SIZE];
          uint32_t tx_rate;

          tx_rate = pPeerInfo->peerInfoParams[i].txRate;
          vos_mem_copy(mac_addr, pPeerInfo->peerInfoParams[i].mac_addr,
              sizeof(mac_addr));

          pr_info(" PEER ADDR : %pM TxRate: %d Mbps RSSI: %d",
            mac_addr, (int)tx_rate, (int)pPeerInfo->peerInfoParams[i].rssi);
       }
    }
    else
    {
       hddLog(VOS_TRACE_LEVEL_WARN,
              "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
    }

    return status;
}

int hdd_wlan_get_rts_threshold(hdd_adapter_t *pAdapter, union iwreq_data *wrqu)
{
    tHalHandle hHal;
    v_U32_t threshold = 0;
    hdd_context_t *hdd_ctx;
    int ret;

    ENTER();

    if (NULL == pAdapter) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Adapter is NULL", __func__);
        return -EINVAL;
    }

    hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);

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


    if ( eHAL_STATUS_SUCCESS !=
                     ccmCfgGetInt(hHal, WNI_CFG_RTS_THRESHOLD, &threshold) )
    {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                      FL("failed to get ini parameter, WNI_CFG_RTS_THRESHOLD"));
       return -EIO;
    }
    wrqu->rts.value = threshold;

    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                                 ("Rts-Threshold=%d!!"), wrqu->rts.value);

    EXIT();

    return 0;
}
int hdd_wlan_get_frag_threshold(hdd_adapter_t *pAdapter, union iwreq_data *wrqu)
{
    tHalHandle hHal;
    v_U32_t threshold = 0, ret;
    hdd_context_t *hdd_ctx;

    ENTER();

    if (NULL == pAdapter) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Adapter is NULL", __func__);
        return -EINVAL;
    }

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


    if ( ccmCfgGetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD, &threshold)
                                                != eHAL_STATUS_SUCCESS )
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                      FL("failed to get ini parameter, WNI_CFG_FRAGMENTATION_THRESHOLD"));
        return -EIO;
    }
    wrqu->frag.value = threshold;

    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                               ("Frag-Threshold=%d!!"), wrqu->frag.value);

    EXIT();

    return 0;
}

int hdd_wlan_get_freq(v_U32_t channel, v_U32_t *pfreq)
{
    int i;
    if (channel > 0)
    {
        for (i=0; i < FREQ_CHAN_MAP_TABLE_SIZE; i++)
        {
            if (channel == freq_chan_map[i].chan)
            {
                *pfreq = freq_chan_map[i].freq;
                return 1;
            }
        }
    }
    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                               ("Invalid channel no=%d!!"), channel);
    return -EINVAL;
}

static v_BOOL_t
hdd_IsAuthTypeRSN( tHalHandle halHandle, eCsrAuthType authType)
{
    v_BOOL_t rsnType = VOS_FALSE;
    // is the authType supported?
    switch (authType)
    {
        case eCSR_AUTH_TYPE_NONE:    //never used
            rsnType = eANI_BOOLEAN_FALSE;
            break;
        // MAC layer authentication types
        case eCSR_AUTH_TYPE_OPEN_SYSTEM:
            rsnType = eANI_BOOLEAN_FALSE;
            break;
        case eCSR_AUTH_TYPE_SHARED_KEY:
            rsnType = eANI_BOOLEAN_FALSE;
            break;
        case eCSR_AUTH_TYPE_AUTOSWITCH:
            rsnType = eANI_BOOLEAN_FALSE;
            break;

        // Upper layer authentication types
        case eCSR_AUTH_TYPE_WPA:
            rsnType = eANI_BOOLEAN_TRUE;
            break;
        case eCSR_AUTH_TYPE_WPA_PSK:
            rsnType = eANI_BOOLEAN_TRUE;
            break;
        case eCSR_AUTH_TYPE_WPA_NONE:
            rsnType = eANI_BOOLEAN_TRUE;
            break;
#ifdef WLAN_FEATURE_VOWIFI_11R
        case eCSR_AUTH_TYPE_FT_RSN:
#endif
        case eCSR_AUTH_TYPE_RSN:
            rsnType = eANI_BOOLEAN_TRUE;
            break;
#ifdef WLAN_FEATURE_VOWIFI_11R
        case eCSR_AUTH_TYPE_FT_RSN_PSK:
#endif
        case eCSR_AUTH_TYPE_RSN_PSK:
#ifdef WLAN_FEATURE_11W
        case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
        case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
#endif
            rsnType = eANI_BOOLEAN_TRUE;
            break;
        //case eCSR_AUTH_TYPE_FAILED:
        case eCSR_AUTH_TYPE_UNKNOWN:
            rsnType = eANI_BOOLEAN_FALSE;
            break;
        default:
            hddLog(LOGE, FL("%s called with unknown authType - default to Open, None"),
                   __func__);
            rsnType = eANI_BOOLEAN_FALSE;
            break;
    }
    hddLog(LOGE, FL("%s called with authType: %d, returned: %d"),
                                             __func__, authType, rsnType);
    return rsnType;
}

struct rssi_priv {
	v_S7_t rssi;
};

/**
 * hdd_get_rssi_cb() - "Get RSSI" callback function
 * @rssi: Current RSSI of the station
 * @sta_id: ID of the station
 * @context: opaque context originally passed to SME.  HDD always passes
 *	     a cookie for the request context
 *
 * Return: None
 */
static void hdd_get_rssi_cb(v_S7_t rssi, tANI_U32 sta_id, void *context)
{
	struct hdd_request *request;
	struct rssi_priv *priv;

	if (ioctl_debug) {
		pr_info("%s: rssi [%d] sta_id [%d] context [%pK]\n",
			__func__, (int)rssi, (int)sta_id, context);
	}

	request = hdd_request_get(context);
	if (!request) {
		hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Obsolete request", __func__);
		return;
	}

	priv = hdd_request_priv(request);
	priv->rssi = rssi;
	hdd_request_complete(request);
	hdd_request_put(request);
}

/**
 * wlan_hdd_get_rssi() - Get the current RSSI
 * @pAdapter: adapter upon which the measurement is requested
 * @rssi_value: pointer to where the RSSI should be returned
 *
 * Return: VOS_STATUS_SUCCESS on success, VOS_STATUS_E_** on error
 */
VOS_STATUS wlan_hdd_get_rssi(hdd_adapter_t *pAdapter, v_S7_t *rssi_value)
{
	hdd_context_t *pHddCtx;
	hdd_station_ctx_t *pHddStaCtx;
	eHalStatus hstatus;
	int ret;
	void *cookie;
	struct hdd_request *request;
	struct rssi_priv *priv;
	static const struct hdd_request_params params = {
		.priv_size = sizeof(*priv),
		.timeout_ms = WLAN_WAIT_TIME_STATS,
	};

	if (NULL == pAdapter) {
		hddLog(VOS_TRACE_LEVEL_WARN,
			"%s: Invalid context, pAdapter", __func__);
		return VOS_STATUS_E_FAULT;
	}
	if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
				"%s:LOGP in Progress. Ignore!!!",__func__);
		/* return a cached value */
		*rssi_value = pAdapter->rssi;
		return VOS_STATUS_SUCCESS;
	}

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

	if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
		hddLog(LOG1, "%s: Not associated, rssi on disconnect %d",
			__func__, pAdapter->rssi_on_disconnect);
		*rssi_value = pAdapter->rssi_on_disconnect;
		return VOS_STATUS_SUCCESS;
	}

	if (pHddStaCtx->hdd_ReassocScenario) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
				"%s: Roaming in progress, return cached RSSI",
				__func__);
		*rssi_value = pAdapter->rssi;
		return VOS_STATUS_SUCCESS;
	}

	request = hdd_request_alloc(&params);
	if (!request) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
			"%s: Request allocation failure, return cached RSSI",
			__func__);
		*rssi_value = pAdapter->rssi;
		return VOS_STATUS_SUCCESS;
	}
	cookie = hdd_request_cookie(request);

	hstatus = sme_GetRssi(pHddCtx->hHal, hdd_get_rssi_cb,
			      pHddStaCtx->conn_info.staId[0],
			      pHddStaCtx->conn_info.bssId, pAdapter->rssi,
			      cookie, pHddCtx->pvosContext);
	if (eHAL_STATUS_SUCCESS != hstatus) {
		hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve RSSI",
			__func__);
		/* we'll returned a cached value below */
	} else {
		/* request was sent -- wait for the response */
		ret = hdd_request_wait_for_response(request);
		if (ret) {
			hddLog(VOS_TRACE_LEVEL_ERROR,
				FL("SME timed out while retrieving RSSI"));
			/* we'll returned a cached value below */
		} else {
			/* update the adapter with the fresh results */
			priv = hdd_request_priv(request);
			pAdapter->rssi = priv->rssi;
			if (pAdapter->rssi > 0)
				pAdapter->rssi = 0;
		}
	}

	/*
	 * either we never sent a request, we sent a request and
	 * received a response or we sent a request and timed out.
	 * regardless we are done with the request.
	 */
	hdd_request_put(request);

	*rssi_value = pAdapter->rssi;

	return VOS_STATUS_SUCCESS;
}

struct snr_priv {
	tANI_S8 snr;
};

/**
 * hdd_get_snr_cb() - "Get SNR" callback function
 * @snr: Current SNR of the station
 * @sta_id: ID of the station
 * @context: opaque context originally passed to SME.  HDD always passes
 *	     a cookie for the request context
 *
 * Return: None
 */
static void hdd_get_snr_cb(tANI_S8 snr, tANI_U32 sta_id, void *context)
{
	struct hdd_request *request;
	struct snr_priv *priv;

	if (ioctl_debug) {
		pr_info("%s: snr [%d] sta_id [%d] context [%pK]\n",
			__func__, (int)snr, (int)sta_id, context);
	}

	request = hdd_request_get(context);
	if (!request) {
                hddLog(VOS_TRACE_LEVEL_ERROR,
                        "%s: Obsolete request", __func__);
		return;
	}

	/* propagate response back to requesting thread */
	priv = hdd_request_priv(request);
	priv->snr = snr;
	hdd_request_complete(request);
	hdd_request_put(request);
}

/**
 * wlan_hdd_get_snr() - Get the current SNR
 * @pAdapter: adapter upon which the measurement is requested
 * @snr: pointer to where the SNR should be returned
 *
 * Return: VOS_STATUS_SUCCESS on success, VOS_STATUS_E_** on error
 */
VOS_STATUS wlan_hdd_get_snr(hdd_adapter_t *pAdapter, v_S7_t *snr)
{
	hdd_context_t *pHddCtx;
	hdd_station_ctx_t *pHddStaCtx;
	eHalStatus hstatus;
	int valid;
	int ret;
	void *cookie;
	struct hdd_request *request;
	struct snr_priv *priv;
	static const struct hdd_request_params params = {
		.priv_size = sizeof(*priv),
		.timeout_ms = WLAN_WAIT_TIME_STATS,
	};

	ENTER();

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

	pHddCtx = WLAN_HDD_GET_CTX(pAdapter);

	valid = wlan_hdd_validate_context(pHddCtx);
	if (0 != valid)
		return VOS_STATUS_E_FAULT;

	pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

	request = hdd_request_alloc(&params);
	if (!request) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
			"%s: Request allocation failure", __func__);
		return VOS_STATUS_E_FAULT;
	}
	cookie = hdd_request_cookie(request);

	hstatus = sme_GetSnr(pHddCtx->hHal, hdd_get_snr_cb,
			     pHddStaCtx->conn_info.staId[0],
			     pHddStaCtx->conn_info.bssId, cookie);
	if (eHAL_STATUS_SUCCESS != hstatus) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
			"%s: Unable to retrieve SNR", __func__);
		/* we'll returned a cached value below */
	} else {
		/* request was sent -- wait for the response */
		ret = hdd_request_wait_for_response(request);
		if (ret) {
			hddLog(VOS_TRACE_LEVEL_ERROR,
				FL("SME timed out while retrieving SNR"));
			/* we'll now returned a cached value below */
		} else {
			/* update the adapter with the fresh results */
			priv = hdd_request_priv(request);
			pAdapter->snr = priv->snr;
		}
	}

	/*
	 * either we never sent a request, we sent a request and
	 * received a response or we sent a request and timed out.
	 * regardless we are done with the request.
	 */
	hdd_request_put(request);

	*snr = pAdapter->snr;
	EXIT();
	return VOS_STATUS_SUCCESS;
}

void hdd_StatisticsCB( void *pStats, void *pContext )
{
   hdd_adapter_t             *pAdapter      = (hdd_adapter_t *)pContext;
   hdd_stats_t               *pStatsCache   = NULL;
   hdd_wext_state_t *pWextState;
   VOS_STATUS vos_status = VOS_STATUS_SUCCESS;

   tCsrSummaryStatsInfo      *pSummaryStats = NULL;
   tCsrGlobalClassAStatsInfo *pClassAStats  = NULL;
   tCsrGlobalClassBStatsInfo *pClassBStats  = NULL;
   tCsrGlobalClassCStatsInfo *pClassCStats  = NULL;
   tCsrGlobalClassDStatsInfo *pClassDStats  = NULL;
   tCsrPerStaStatsInfo       *pPerStaStats  = NULL;

   if (pAdapter!= NULL)
     pStatsCache = &pAdapter->hdd_stats;


   pSummaryStats = (tCsrSummaryStatsInfo *)pStats;
   pClassAStats  = (tCsrGlobalClassAStatsInfo *)( pSummaryStats + 1 );
   pClassBStats  = (tCsrGlobalClassBStatsInfo *)( pClassAStats + 1 );
   pClassCStats  = (tCsrGlobalClassCStatsInfo *)( pClassBStats + 1 );
   pClassDStats  = (tCsrGlobalClassDStatsInfo *)( pClassCStats + 1 );
   pPerStaStats  = (tCsrPerStaStatsInfo *)( pClassDStats + 1 );

   if (pStatsCache!=NULL)
   {
      // and copy the stats into the cache we keep in the adapter instance structure
      vos_mem_copy( &pStatsCache->summary_stat, pSummaryStats, sizeof( pStatsCache->summary_stat ) );
      vos_mem_copy( &pStatsCache->ClassA_stat, pClassAStats, sizeof( pStatsCache->ClassA_stat ) );
      vos_mem_copy( &pStatsCache->ClassB_stat, pClassBStats, sizeof( pStatsCache->ClassB_stat ) );
      vos_mem_copy( &pStatsCache->ClassC_stat, pClassCStats, sizeof( pStatsCache->ClassC_stat ) );
      vos_mem_copy( &pStatsCache->ClassD_stat, pClassDStats, sizeof( pStatsCache->ClassD_stat ) );
      vos_mem_copy( &pStatsCache->perStaStats, pPerStaStats, sizeof( pStatsCache->perStaStats ) );
   }

    if (pAdapter) {
        pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
        vos_status = vos_event_set(&pWextState->vosevent);
        if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
           hddLog(LOGE, FL("vos_event_set failed"));
           return;
        }
    }
}

void ccmCfgSetCallback(tHalHandle halHandle, tANI_S32 result)
{
   v_CONTEXT_t pVosContext;
   hdd_context_t *pHddCtx;
   VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx );
#if 0
   hdd_wext_state_t *pWextState;
   v_U32_t roamId;
#endif

   ENTER();

   pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS,NULL);

   pHddCtx = (hdd_context_t*) vos_get_context(VOS_MODULE_ID_HDD,pVosContext);
   if (NULL == pHddCtx)
   {
      hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid pHddCtx", __func__);
      return;
   }
#if 0
   pWextState = pAdapter->pWextState;
#endif

   if (WNI_CFG_NEED_RESTART == result || WNI_CFG_NEED_RELOAD == result)
   {
      //TODO Verify is this is really used. If yes need to fix it.
      hdd_reconnect_all_adapters( pHddCtx );
#if 0
      pAdapter->conn_info.connState = eConnectionState_NotConnected;
      INIT_COMPLETION(pAdapter->disconnect_comp_var);
      vosStatus = sme_RoamDisconnect(halHandle, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);

      if(VOS_STATUS_SUCCESS == vosStatus)
          wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
                     msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));

      sme_RoamConnect(halHandle,
                     pAdapter->sessionId, &(pWextState->roamProfile),
                     &roamId);
#endif
   }

   EXIT();

}

/* hdd_clearRoamProfileIe() - Clear roam profile IEs
 * @pAdapter: Adapter handle
 *
 * Clears roam profile information elements
 * Returns: none
 */
void hdd_clearRoamProfileIe( hdd_adapter_t *pAdapter)
{
   int i = 0;
   hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);

   ENTER();

   if (!pWextState) {
        hddLog(LOGE, FL("ERROR: pWextState not found"));
        return;
   }
   /* clear WPA/RSN/WSC IE information in the profile */
   pWextState->roamProfile.nWPAReqIELength = 0;
   pWextState->roamProfile.pWPAReqIE = (tANI_U8 *)NULL;
   pWextState->roamProfile.nRSNReqIELength = 0;
   pWextState->roamProfile.pRSNReqIE = (tANI_U8 *)NULL;

#ifdef FEATURE_WLAN_WAPI
   pWextState->roamProfile.nWAPIReqIELength = 0;
   pWextState->roamProfile.pWAPIReqIE = (tANI_U8 *)NULL;
#endif

   pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
   pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
   pWextState->roamProfile.pAddIEScan = (tANI_U8 *)NULL;
   pWextState->roamProfile.nAddIEScanLength = 0;
   pWextState->roamProfile.pAddIEAssoc = (tANI_U8 *)NULL;
   pWextState->roamProfile.nAddIEAssocLength = 0;

   pWextState->roamProfile.EncryptionType.numEntries = 1;
   pWextState->roamProfile.EncryptionType.encryptionType[0]
                                                     = eCSR_ENCRYPT_TYPE_NONE;

   pWextState->roamProfile.mcEncryptionType.numEntries = 1;
   pWextState->roamProfile.mcEncryptionType.encryptionType[0]
                                                     = eCSR_ENCRYPT_TYPE_NONE;

   pWextState->roamProfile.AuthType.numEntries = 1;
   pWextState->roamProfile.AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;

   vos_mem_zero((pWextState->roamProfile.bssid_hint), VOS_MAC_ADDR_SIZE);

#ifdef WLAN_FEATURE_11W
   pWextState->roamProfile.MFPEnabled = eANI_BOOLEAN_FALSE;
   pWextState->roamProfile.MFPRequired = 0;
   pWextState->roamProfile.MFPCapable = 0;
#endif

   pWextState->authKeyMgmt = 0;

   for (i=0; i < CSR_MAX_NUM_KEY; i++)
       pWextState->roamProfile.Keys.KeyLength[i] = 0;

#ifdef FEATURE_WLAN_WAPI
   pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_OPEN;
   pAdapter->wapi_info.nWapiMode = 0;
#endif

   vos_mem_zero((void *)(pWextState->req_bssId), VOS_MAC_ADDR_SIZE);
   EXIT();
}

void wlan_hdd_ula_done_cb(v_VOID_t *callbackContext)
{
    hdd_adapter_t *pAdapter = (hdd_adapter_t*)callbackContext;

    if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: Invalid pAdapter magic", __func__);
    }
    else
    {
        complete(&pAdapter->ula_complete);
    }
}

VOS_STATUS wlan_hdd_check_ula_done(hdd_adapter_t *pAdapter)
{
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    VOS_STATUS vos_status;
    unsigned long rc;

    if (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated)
    {
        INIT_COMPLETION(pAdapter->ula_complete);

        /*To avoid race condition between the set key and the last EAPOL
          packet, notify TL to finish upper layer authentication incase if the
          last EAPOL packet pending in the TL queue.*/
        vos_status = WLANTL_Finish_ULA(wlan_hdd_ula_done_cb, pAdapter);

        if ( vos_status != VOS_STATUS_SUCCESS )
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "[%4d] WLANTL_Finish_ULA returned ERROR status= %d",
                   __LINE__, vos_status );
            return vos_status;

        }

        rc = wait_for_completion_timeout(&pAdapter->ula_complete,
                                    msecs_to_jiffies(HDD_FINISH_ULA_TIME_OUT));
        if (rc <= 0)
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      FL("failure wait on ULA to complete %ld"), rc);
            /* we'll still fall through and return success since the
             * connection may still get established but is just taking
             * too long for us to wait */
        }
    }
    return VOS_STATUS_SUCCESS;
}

v_U8_t* wlan_hdd_get_vendor_oui_ie_ptr(v_U8_t *oui, v_U8_t oui_size, v_U8_t *ie, int ie_len)
{

    int left = ie_len;
    v_U8_t *ptr = ie;
    v_U8_t elem_id,elem_len;
    v_U8_t eid = 0xDD;

    if ( NULL == ie || 0 == ie_len )
       return NULL;

    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) && (elem_len >= oui_size))
        {
            if(memcmp( &ptr[2], oui, oui_size)==0)
                return ptr;
        }

        left -= elem_len;
        ptr += (elem_len + 2);
    }
    return NULL;
}

/**
 * hdd_get_ldpc() - Get adapter LDPC
 * @adapter: adapter being queried
 * @value: where to store the value
 *
 * Return: 0 on success, negative errno on failure
 */
int hdd_get_ldpc(hdd_adapter_t *adapter, int *value)
{
	tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter);
	int ret;

	ENTER();
	ret = sme_GetHTConfig(hal, adapter->sessionId,
			      WNI_CFG_HT_CAP_INFO_ADVANCE_CODING);
	if (ret < 0) {
		hddLog(LOGE, FL("Failed to get LDPC value"));
	} else {
		*value = ret;
		ret = 0;
	}
	return ret;
}

/**
 * hdd_set_ldpc() - Set adapter LDPC
 * @adapter: adapter being modified
 * @value: new LDPC value
 *
 * Return: 0 on success, negative errno on failure
 */
int hdd_set_ldpc(hdd_adapter_t *adapter, int value)
{
	tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter);
	int ret;

	hddLog(LOG1, FL("%d"), value);
	if (value) {
		/* make sure HT capabilities allow this */
		eHalStatus status;
		uint32_t cfg_value;
		union {
			uint16_t cfg_value16;
			tSirMacHTCapabilityInfo ht_cap_info;
		} u;

		status = ccmCfgGetInt(hal, WNI_CFG_HT_CAP_INFO, &cfg_value);
		if (eHAL_STATUS_SUCCESS != status) {
			hddLog(LOGE, FL("Failed to get HT capability info"));
			return -EIO;
		}
		u.cfg_value16 = cfg_value & 0xFFFF;
		if (!u.ht_cap_info.advCodingCap) {
			hddLog(LOGE, FL("LDCP not supported"));
			return -EINVAL;
		}
	}

	ret = sme_UpdateHTConfig(hal, adapter->sessionId,
				 WNI_CFG_HT_CAP_INFO_ADVANCE_CODING,
				 value);
	if (ret)
		hddLog(LOGE, FL("Failed to set LDPC value"));

	return ret;
}

/**
 * hdd_get_tx_stbc() - Get adapter TX STBC
 * @adapter: adapter being queried
 * @value: where to store the value
 *
 * Return: 0 on success, negative errno on failure
 */
int hdd_get_tx_stbc(hdd_adapter_t *adapter, int *value)
{
	tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter);
	int ret;

	ENTER();
	ret = sme_GetHTConfig(hal, adapter->sessionId,
			      WNI_CFG_HT_CAP_INFO_TX_STBC);
	if (ret < 0) {
		hddLog(LOGE, FL("Failed to get TX STBC value"));
	} else {
		*value = ret;
		ret = 0;
	}

	return ret;
}

/**
 * hdd_set_tx_stbc() - Set adapter TX STBC
 * @adapter: adapter being modified
 * @value: new TX STBC value
 *
 * Return: 0 on success, negative errno on failure
 */
int hdd_set_tx_stbc(hdd_adapter_t *adapter, int value)
{
	tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter);
	int ret;

	hddLog(LOG1, FL("%d"), value);
	if (value) {
		/* make sure HT capabilities allow this */
		eHalStatus status;
		uint32_t cfg_value;
		union {
			uint16_t cfg_value16;
			tSirMacHTCapabilityInfo ht_cap_info;
		} u;

		status = ccmCfgGetInt(hal, WNI_CFG_HT_CAP_INFO, &cfg_value);
		if (eHAL_STATUS_SUCCESS != status) {
			hddLog(LOGE, FL("Failed to get HT capability info"));
			return -EIO;
		}
		u.cfg_value16 = cfg_value & 0xFFFF;
		if (!u.ht_cap_info.txSTBC) {
			hddLog(LOGE, FL("TX STBC not supported"));
			return -EINVAL;
		}
	}
	ret = sme_UpdateHTConfig(hal, adapter->sessionId,
				 WNI_CFG_HT_CAP_INFO_TX_STBC,
				 value);
	if (ret)
		hddLog(LOGE, FL("Failed to set TX STBC value"));

	return ret;
}

/**
 * hdd_get_rx_stbc() - Get adapter RX STBC
 * @adapter: adapter being queried
 * @value: where to store the value
 *
 * Return: 0 on success, negative errno on failure
 */
int hdd_get_rx_stbc(hdd_adapter_t *adapter, int *value)
{
	tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter);
	int ret;

	ENTER();
	ret = sme_GetHTConfig(hal, adapter->sessionId,
			      WNI_CFG_HT_CAP_INFO_RX_STBC);
	if (ret < 0) {
		hddLog(LOGE, FL("Failed to get RX STBC value"));
	} else {
		*value = ret;
		ret = 0;
	}

	return ret;
}

/**
 * hdd_set_rx_stbc() - Set adapter RX STBC
 * @adapter: adapter being modified
 * @value: new RX STBC value
 *
 * Return: 0 on success, negative errno on failure
 */
int hdd_set_rx_stbc(hdd_adapter_t *adapter, int value)
{
	tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter);
	int ret;

	hddLog(LOG1, FL("%d"), value);
	if (value) {
		/* make sure HT capabilities allow this */
		eHalStatus status;
		uint32_t cfg_value;
		union {
			uint16_t cfg_value16;
			tSirMacHTCapabilityInfo ht_cap_info;
		} u;

		status = ccmCfgGetInt(hal, WNI_CFG_HT_CAP_INFO, &cfg_value);
		if (eHAL_STATUS_SUCCESS != status) {
			hddLog(LOGE, FL("Failed to get HT capability info"));
			return -EIO;
		}
		u.cfg_value16 = cfg_value & 0xFFFF;
		if (!u.ht_cap_info.rxSTBC) {
			hddLog(LOGE, FL("RX STBC not supported"));
			return -EINVAL;
		}
	}
	ret = sme_UpdateHTConfig(hal, adapter->sessionId,
				 WNI_CFG_HT_CAP_INFO_RX_STBC,
				 value);
	if (ret)
		hddLog(LOGE, FL("Failed to set RX STBC value"));

	return ret;
}

/**
 * __iw_set_commit() - set commit
 * @dev: pointer to net_device
 * @info: pointer to iw_request_info
 * @wrqu: pointer to iwreq_data
 * @extra: extra
 *
 * Return: 0 on success, error number otherwise
 */
static int __iw_set_commit(struct net_device *dev, struct iw_request_info *info,
			   union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *adapter;
    hdd_context_t *hdd_ctx;
    int ret;

    ENTER();

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

    /* Do nothing for now */
    return 0;
}

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

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

	return ret;
}

/**
 * __iw_get_name() - get name
 * @dev: pointer to net_device
 * @info: pointer to iw_request_info
 * @wrqu: pointer to iwreq_data
 * @extra: extra
 *
 * Return: 0 on success, error number otherwise
 */
static int __iw_get_name(struct net_device *dev,
			 struct iw_request_info *info,
			 char *wrqu, char *extra)
{
	ENTER();
	strlcpy(wrqu, "Qcom:802.11n", IFNAMSIZ);
	EXIT();
	return 0;
}

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

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

	return ret;
}

/**
 * __iw_set_freq() - SIOCSIWFREQ ioctl handler
 * @dev: device upon which the ioctl was received
 * @info: ioctl request information
 * @wrqu: ioctl request data
 * @extra: ioctl extra data
 *
 * Return: 0 on success, non-zero on error
 */
static int __iw_set_freq(struct net_device *dev, struct iw_request_info *info,
			 union iwreq_data *wrqu, char *extra)
{
    v_U32_t numChans = 0;
    v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
    v_U32_t indx = 0;
    hdd_wext_state_t *pWextState;
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    tCsrRoamProfile * pRoamProfile;
    hdd_context_t *hdd_ctx;
    int ret;

    ENTER();

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

    pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);

    pRoamProfile = &pWextState->roamProfile;

    hddLog(LOG1,"setCHANNEL ioctl");

    /* Link is up then return cant set channel*/
    if(eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState ||
       eConnectionState_Associated == pHddStaCtx->conn_info.connState)
    {
        hddLog( LOGE, "IBSS Associated");
        return -EOPNOTSUPP;
    }

    /* Settings by Frequency as input */
    if((wrqu->freq.e == 1) && (wrqu->freq.m >= (tANI_U32)2.412e8) &&
                            (wrqu->freq.m <= (tANI_U32)5.825e8))
    {
        tANI_U32 freq = wrqu->freq.m / 100000;

        while ((indx <  FREQ_CHAN_MAP_TABLE_SIZE) && (freq != freq_chan_map[indx].freq))
            indx++;
        if (indx >= FREQ_CHAN_MAP_TABLE_SIZE)
        {
            return -EINVAL;
        }
        wrqu->freq.e = 0;
        wrqu->freq.m = freq_chan_map[indx].chan;

    }

    if (wrqu->freq.e == 0)
    {
        if((wrqu->freq.m < WNI_CFG_CURRENT_CHANNEL_STAMIN) ||
                        (wrqu->freq.m > WNI_CFG_CURRENT_CHANNEL_STAMAX))
        {
            hddLog(LOG1,"%s: Channel [%d] is outside valid range from %d to %d",
                __func__, wrqu->freq.m, WNI_CFG_CURRENT_CHANNEL_STAMIN,
                    WNI_CFG_CURRENT_CHANNEL_STAMAX);
             return -EINVAL;
        }

        numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;

        if (ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
                validChan, &numChans) != eHAL_STATUS_SUCCESS){
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
               FL("failed to get ini parameter, WNI_CFG_VALID_CHANNEL_LIST"));
            return -EIO;
        }

        for (indx = 0; indx < numChans; indx++) {
            if (wrqu->freq.m == validChan[indx]){
                break;
            }
        }
    }
    else{

        return -EINVAL;
    }

    if(indx >= numChans)
    {
        return -EINVAL;
    }

    /* Set the Operational Channel */
    numChans = pRoamProfile->ChannelInfo.numOfChannels = 1;
    pHddStaCtx->conn_info.operationChannel = wrqu->freq.m;
    pRoamProfile->ChannelInfo.ChannelList = &pHddStaCtx->conn_info.operationChannel;

    hddLog(LOG1,"pRoamProfile->operationChannel  = %d", wrqu->freq.m);

    EXIT();

    return ret;
}

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

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

	return ret;
}

/**
 * __iw_get_freq() - SIOCGIWFREQ ioctl handler
 * @dev: device upon which the ioctl was received
 * @info: ioctl request information
 * @fwrq: ioctl frequency data
 * @extra: ioctl extra data
 *
 * Return: 0 on success, non-zero on error
 */
static int __iw_get_freq(struct net_device *dev, struct iw_request_info *info,
			 struct iw_freq *fwrq, char *extra)
{
   v_U32_t status = FALSE, channel = 0, freq = 0;
   hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
   tHalHandle hHal;
   hdd_wext_state_t *pWextState;
   tCsrRoamProfile * pRoamProfile;
   hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
   hdd_context_t *hdd_ctx;
   int ret;

   ENTER();

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

   pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
   hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);

   pRoamProfile = &pWextState->roamProfile;

   if( pHddStaCtx->conn_info.connState== eConnectionState_Associated )
   {
       if (sme_GetOperationChannel(hHal, &channel, pAdapter->sessionId) != eHAL_STATUS_SUCCESS)
       {
           VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                       FL("failed to get operating channel %u"), pAdapter->sessionId);
           return -EIO;
       }
       else
       {
           status = hdd_wlan_get_freq(channel, &freq);
           if( TRUE == status )
           {
               /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
                * iwlist & iwconfig command shows frequency into proper
                * format (2.412 GHz instead of 246.2 MHz)*/
               fwrq->m = freq;
               fwrq->e = MHZ;
           }
       }
    }
    else
    {
       /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
        * iwlist & iwconfig command shows frequency into proper
        * format (2.412 GHz instead of 246.2 MHz)*/
       fwrq->m = 0;
       fwrq->e = MHZ;
    }
   return 0;
}

/**
 * iw_get_freq() - SSR wrapper for __iw_get_freq()
 * @dev: pointer to net_device
 * @info: pointer to iw_request_info
 * @fwrq: pointer to frequency data
 * @extra: pointer to extra ioctl payload
 *
 * Return: 0 on success, error number otherwise
 */
static int iw_get_freq(struct net_device *dev, struct iw_request_info *info,
		       struct iw_freq *fwrq, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_get_freq(dev, info, fwrq, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

/**
 * __iw_get_tx_power() - SIOCGIWTXPOW ioctl handler
 * @dev: device upon which the ioctl was received
 * @info: ioctl request information
 * @wrqu: ioctl request data
 * @extra: ioctl extra data
 *
 * Return: 0 on success, non-zero on error
 */
static int __iw_get_tx_power(struct net_device *dev,
			     struct iw_request_info *info,
			     union iwreq_data *wrqu, char *extra)
{

   hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
   hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
   hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
   int ret;

   ENTER();

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

   if(eConnectionState_Associated != pHddStaCtx->conn_info.connState)
   {
      wrqu->txpower.value = 0;
      return 0;
   }
   wlan_hdd_get_classAstats(pAdapter);
   wrqu->txpower.value = pAdapter->hdd_stats.ClassA_stat.max_pwr;

   return 0;
}

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

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

	return ret;
}

/**
 * __iw_set_tx_power() - SIOCSIWTXPOW ioctl handler
 * @dev: device upon which the ioctl was received
 * @info: ioctl request information
 * @wrqu: ioctl request data
 * @extra: ioctl extra data
 *
 * Return: 0 on success, non-zero on error
 */
static int __iw_set_tx_power(struct net_device *dev,
			     struct iw_request_info *info,
			     union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    hdd_context_t *hdd_ctx;
    int ret;

    ENTER();

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

    if ( ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL, wrqu->txpower.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS )
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                FL("failed to set ini parameter, WNI_CFG_CURRENT_TX_POWER_LEVEL"));
        return -EIO;
    }

    EXIT();

    return 0;
}

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

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

	return ret;
}

/**
 * __iw_get_bitrate() - SIOCGIWRATE ioctl handler
 * @dev: device upon which the ioctl was received
 * @info: ioctl request information
 * @wrqu: ioctl request data
 * @extra: ioctl extra data
 *
 * Return: 0 on success, non-zero on error
 */
static int __iw_get_bitrate(struct net_device *dev,
			    struct iw_request_info *info,
			    union iwreq_data *wrqu, char *extra)
{
   VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
   eHalStatus status = eHAL_STATUS_SUCCESS;
   hdd_wext_state_t *pWextState;
   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 *hdd_ctx;
   int ret;

   ENTER();

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

   if(eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
        wrqu->bitrate.value = 0;
   }
   else {
      status = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_HDD,
                               SME_SUMMARY_STATS       |
                               SME_GLOBAL_CLASSA_STATS |
                               SME_GLOBAL_CLASSB_STATS |
                               SME_GLOBAL_CLASSC_STATS |
                               SME_GLOBAL_CLASSD_STATS |
                               SME_PER_STA_STATS,
                               hdd_StatisticsCB, 0, FALSE,
                               pHddStaCtx->conn_info.staId[0], pAdapter,
                               pAdapter->sessionId );

      if(eHAL_STATUS_SUCCESS != status)
      {
         hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: Unable to retrieve statistics",
                __func__);
         return status;
      }

      pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);

      vos_status = vos_wait_single_event(&pWextState->vosevent, WLAN_WAIT_TIME_STATS);

      if (!VOS_IS_STATUS_SUCCESS(vos_status))
      {
         hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: SME timeout while retrieving statistics",
                __func__);
         return VOS_STATUS_E_FAILURE;
      }

      wrqu->bitrate.value = pAdapter->hdd_stats.ClassA_stat.tx_rate*500*1000;
   }

   EXIT();

   return vos_status;
}

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

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

	return ret;
}

/**
 * __iw_set_bitrate() - SIOCSIWRATE ioctl handler
 * @dev: device upon which the ioctl was received
 * @info: ioctl request information
 * @wrqu: ioctl request data
 * @extra: ioctl extra data
 *
 * Return: 0 on success, non-zero on error
 */
static int __iw_set_bitrate(struct net_device *dev,
			    struct iw_request_info *info,
			    union iwreq_data *wrqu,
			    char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_wext_state_t *pWextState;
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    uint8_t supp_rates[WNI_CFG_SUPPORTED_RATES_11A_LEN +
			WNI_CFG_SUPPORTED_RATES_11B_LEN];
    v_U32_t a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN;
    v_U32_t b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN;
    v_U32_t i, rate;
    v_U32_t valid_rate = FALSE, active_phy_mode = 0;
    hdd_context_t *hdd_ctx;
    int ret;

    ENTER();

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

    pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);

    if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
    {
        return -ENXIO ;
    }

    rate = wrqu->bitrate.value;

    if (rate == -1)
    {
        rate = WNI_CFG_FIXED_RATE_AUTO;
        valid_rate = TRUE;
    }
    else if (ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
                        WNI_CFG_DOT11_MODE, &active_phy_mode) == eHAL_STATUS_SUCCESS)
    {
        if (active_phy_mode == WNI_CFG_DOT11_MODE_11A || active_phy_mode == WNI_CFG_DOT11_MODE_11G
            || active_phy_mode == WNI_CFG_DOT11_MODE_11B)
        {
            if ((ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
                        WNI_CFG_SUPPORTED_RATES_11A,
                        supp_rates, &a_len) == eHAL_STATUS_SUCCESS) &&
                (ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
                        WNI_CFG_SUPPORTED_RATES_11B,
                        supp_rates + a_len, &b_len) == eHAL_STATUS_SUCCESS))
            {
                for (i = 0; i < (b_len + a_len); ++i)
                {
                    /* supported rates returned is double the actual rate so we divide it by 2 */
                    if ((supp_rates[i]&0x7F)/2 == rate)
                    {
                        valid_rate = TRUE;
                        rate = i + WNI_CFG_FIXED_RATE_1MBPS;
                        break;
                    }
                }
            }
        }
    }
    if (valid_rate != TRUE)
    {
        return -EINVAL;
    }
    if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
                     WNI_CFG_FIXED_RATE, rate,
                     ccmCfgSetCallback,eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                FL("failed to set ini parameter, WNI_CFG_FIXED_RATE"));
        return -EIO;
    }
    return 0;
}

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

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

	return ret;
}

/**
 * __iw_set_genie() - SIOCSIWGENIE ioctl handler
 * @dev: device upon which the ioctl was received
 * @info: ioctl request information
 * @wrqu: ioctl request data
 * @extra: ioctl extra data
 *
 * Return: 0 on success, non-zero on error
 */
static int __iw_set_genie(struct net_device *dev, struct iw_request_info *info,
			  union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    u_int8_t *genie = NULL;
    u_int8_t *base_genie = NULL;
    v_U16_t remLen;
    hdd_context_t *hdd_ctx;
    int ret;

    ENTER();

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

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

    base_genie = mem_alloc_copy_from_user_helper(wrqu->data.pointer,
                                                 wrqu->data.length);
    if (NULL == base_genie)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "mem_alloc_copy_from_user_helper fail");
        return -ENOMEM;
    }

    genie = base_genie;

    remLen = wrqu->data.length;

    hddLog(LOG1,"iw_set_genie ioctl IE[0x%X], LEN[%d]", genie[0], genie[1]);

    /* clear any previous genIE before this call */
    memset( &pWextState->genIE, 0, sizeof(pWextState->genIE) );

    while (remLen >= 2)
   {
        v_U16_t eLen = 0;
        v_U8_t elementId;
        elementId = *genie++;
        eLen  = *genie++;
        remLen -= 2;

        hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
            __func__, elementId, eLen);

        if (remLen < eLen) {
            hddLog(LOGE, "Remaining len: %u less than ie len: %u",
                   remLen, eLen);
            ret = -EINVAL;
            goto exit;
        }

        switch ( elementId )
         {
            case IE_EID_VENDOR:
                if ((IE_LEN_SIZE+IE_EID_SIZE+IE_VENDOR_OUI_SIZE) > eLen) /* should have at least OUI */
                {
                    ret = -EINVAL;
                    goto exit;
                }

                if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
                {
                    v_U16_t curGenIELen = pWextState->genIE.length;
                    hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS OUI(%02x %02x %02x %02x) IE(len %d)",
                            __func__, genie[0], genie[1], genie[2], genie[3], eLen + 2);

                    if( SIR_MAC_MAX_IE_LENGTH < (pWextState->genIE.length + eLen) )
                    {
                       hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate genIE. "
                                                      "Need bigger buffer space");
                       VOS_ASSERT(0);
                       ret = -EINVAL;
                       goto exit;
                    }
                    // save to Additional IE ; it should be accumulated to handle WPS IE + other IE
                    memcpy( pWextState->genIE.addIEdata + curGenIELen, genie - 2, eLen + 2);
                    pWextState->genIE.length += eLen + 2;
                }
                else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
                {
                    hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
                    if ((eLen + 2) > (sizeof(pWextState->WPARSNIE)))
                    {
                       hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate genIE. "
                                                      "Need bigger buffer space");
                       ret = -EINVAL;
                       VOS_ASSERT(0);
                       goto exit;
                    }
                    memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
                    memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2));
                    pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
                    pWextState->roamProfile.nWPAReqIELength = eLen + 2;
                }
                else /* any vendorId except WPA IE should be accumulated to genIE */
                {
                    v_U16_t curGenIELen = pWextState->genIE.length;
                    hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OUI(%02x %02x %02x %02x) IE(len %d)",
                            __func__, genie[0], genie[1], genie[2], genie[3], eLen + 2);

                    if( SIR_MAC_MAX_IE_LENGTH < (pWextState->genIE.length + eLen) )
                    {
                       hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate genIE. "
                                                      "Need bigger buffer space");
                       VOS_ASSERT(0);
                       ret = -ENOMEM;
                       goto exit;
                    }
                    // save to Additional IE ; it should be accumulated to handle WPS IE + other IE
                    memcpy( pWextState->genIE.addIEdata + curGenIELen, genie - 2, eLen + 2);
                    pWextState->genIE.length += eLen + 2;
                }
              break;
         case DOT11F_EID_RSN:
                hddLog (LOG1, "%s Set RSN IE (len %d)",__func__, eLen+2);
                if ((eLen + 2) > (sizeof(pWextState->WPARSNIE)))
                {
                    hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate genIE. "
                                                  "Need bigger buffer space");
                    ret = -EINVAL;
                    VOS_ASSERT(0);
                    goto exit;
                }
                memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
                memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2));
                pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
                pWextState->roamProfile.nRSNReqIELength = eLen + 2;
              break;

         default:
                hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, elementId);
                goto exit;
    }
        remLen -= eLen;

        /* Move genie only if next element is present */
        if (remLen >= 2)
            genie += eLen;
    }
exit:
    EXIT();
    vos_mem_free(base_genie);
    return ret;
}

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

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

	return ret;
}

/**
 * __iw_get_genie() - SIOCGIWGENIE ioctl handler
 * @dev: device upon which the ioctl was received
 * @info: ioctl request information
 * @wrqu: ioctl request data
 * @extra: ioctl extra data
 *
 * Return: 0 on success, non-zero on error
 */
static int __iw_get_genie(struct net_device *dev, struct iw_request_info *info,
			  union iwreq_data *wrqu, char *extra)
{
    hdd_wext_state_t *pWextState;
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    eHalStatus status;
    v_U32_t length = DOT11F_IE_RSN_MAX_LEN;
    v_U8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
    hdd_context_t *hdd_ctx;
    int ret;

    ENTER();

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

    hddLog(LOG1,"getGEN_IE ioctl");

    pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);

    if( pHddStaCtx->conn_info.connState == eConnectionState_NotConnected)
    {
        return -ENXIO;
    }

    // Return something ONLY if we are associated with an RSN or WPA network
    if ( VOS_TRUE != hdd_IsAuthTypeRSN(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                                pWextState->roamProfile.negotiatedAuthType))
    {
        return -ENXIO;
    }

    // Actually retrieve the RSN IE from CSR.  (We previously sent it down in the CSR Roam Profile.)
    status = csrRoamGetWpaRsnReqIE(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                   pAdapter->sessionId,
                                   &length,
                                   genIeBytes);
    if (eHAL_STATUS_SUCCESS != status) {
        hddLog(LOGE, FL("failed to get WPA-RSN IE data"));
        return -EFAULT;
    }

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

    vos_mem_copy( extra, (v_VOID_t*)genIeBytes, length);

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

    EXIT();

    return 0;
}

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

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

	return ret;
}

/**
 * __iw_get_encode() - SIOCGIWENCODE ioctl handler
 * @dev: device upon which the ioctl was received
 * @info: ioctl request information
 * @dwrq: ioctl request data
 * @extra: ioctl extra data
 *
 * Return: 0 on success, non-zero on error
 */
static int __iw_get_encode(struct net_device *dev, struct iw_request_info *info,
                           struct iw_point *dwrq, char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
    int keyId;
    eCsrAuthType authType = eCSR_AUTH_TYPE_NONE;
    int i;
    hdd_context_t *hdd_ctx;
    int ret;

    ENTER();

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

    keyId = pRoamProfile->Keys.defaultIndex;

    if(keyId < 0 || keyId >= MAX_WEP_KEYS)
    {
        hddLog(LOG1,"%s: Invalid keyId : %d", __func__, keyId);
        return -EINVAL;
    }

    if(pRoamProfile->Keys.KeyLength[keyId] > 0)
    {
        dwrq->flags |= IW_ENCODE_ENABLED;
        dwrq->length = pRoamProfile->Keys.KeyLength[keyId];
        vos_mem_copy(extra,&(pRoamProfile->Keys.KeyMaterial[keyId][0]),pRoamProfile->Keys.KeyLength[keyId]);

        dwrq->flags |= (keyId + 1);

    }
    else
    {
        dwrq->flags |= IW_ENCODE_DISABLED;
    }

    for(i=0; i < MAX_WEP_KEYS; i++)
    {
        if (pRoamProfile->Keys.KeyLength[i] == 0)
            continue;
        else
            break;
    }

    if(MAX_WEP_KEYS == i)
    {
        dwrq->flags |= IW_ENCODE_NOKEY;
    }

    authType = ((hdd_station_ctx_t*)WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;

    if(eCSR_AUTH_TYPE_OPEN_SYSTEM == authType)
    {
        dwrq->flags |= IW_ENCODE_OPEN;
    }
    else
    {
        dwrq->flags |= IW_ENCODE_RESTRICTED;
    }
    EXIT();
    return 0;
}

/**
 * iw_get_encode() - SSR wrapper for __iw_get_encode()
 * @dev: pointer to net_device
 * @info: pointer to iw_request_info
 * @dwrq: pointer to encoding information
 * @extra: pointer to extra ioctl payload
 *
 * Return: 0 on success, error number otherwise
 */
static int iw_get_encode(struct net_device *dev, struct iw_request_info *info,
			 struct iw_point *dwrq, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_get_encode(dev, info, dwrq, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

#define PAE_ROLE_AUTHENTICATOR 1 // =1 for authenticator,
#define PAE_ROLE_SUPPLICANT 0 // =0 for supplicant


/*
 * This function sends a single 'key' to LIM at all time.
 */

/**
 * __iw_get_rts_threshold() - SIOCGIWRTS ioctl handler
 * @dev: device upon which the ioctl was received
 * @info: ioctl request information
 * @wrqu: ioctl request data
 * @extra: ioctl extra data
 *
 * Return: 0 on success, non-zero on error
 */
static int __iw_get_rts_threshold(struct net_device *dev,
				  struct iw_request_info *info,
				  union iwreq_data *wrqu, char *extra)
{
   hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
   v_U32_t status = 0;

   status = hdd_wlan_get_rts_threshold(pAdapter,wrqu);

   return status;
}

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

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

	return ret;
}

/**
 * __iw_set_rts_threshold() - SIOCSIWRTS ioctl handler
 * @dev: device upon which the ioctl was received
 * @info: ioctl request information
 * @wrqu: ioctl request data
 * @extra: ioctl extra data
 *
 * Return: 0 on success, non-zero on error
 */
static int __iw_set_rts_threshold(struct net_device *dev,
				  struct iw_request_info *info,
				  union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    hdd_context_t *hdd_ctx;
    int ret;

    ENTER();

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

    if ( wrqu->rts.value < WNI_CFG_RTS_THRESHOLD_STAMIN || wrqu->rts.value > WNI_CFG_RTS_THRESHOLD_STAMAX )
    {
        return -EINVAL;
    }

    if ( ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD, wrqu->rts.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS )
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                FL("failed to set ini parameter, WNI_CFG_RTS_THRESHOLD"));
        return -EIO;
    }

    EXIT();

    return 0;
}

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

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

	return ret;
}

/**
 * __iw_get_frag_threshold() - SIOCGIWFRAG ioctl handler
 * @dev: device upon which the ioctl was received
 * @info: ioctl request information
 * @wrqu: ioctl request data
 * @extra: ioctl extra data
 *
 * Return: 0 on success, non-zero on error
 */
static int __iw_get_frag_threshold(struct net_device *dev,
				   struct iw_request_info *info,
				   union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    v_U32_t status = 0;

    status = hdd_wlan_get_frag_threshold(pAdapter,wrqu);

    return status;
}

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

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

	return ret;
}

/**
 * __iw_set_frag_threshold() - SIOCSIWFRAG ioctl handler
 * @dev: device upon which the ioctl was received
 * @info: ioctl request information
 * @wrqu: ioctl request data
 * @extra: ioctl extra data
 *
 * Return: 0 on success, non-zero on error
 */
static int __iw_set_frag_threshold(struct net_device *dev,
				   struct iw_request_info *info,
				   union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    hdd_context_t *hdd_ctx;
    int ret;

    ENTER();

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


    if ( wrqu->frag.value < WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN || wrqu->frag.value > WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX )
    {
        return -EINVAL;
    }

    if ( ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD, wrqu->frag.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS )
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                FL("failed to set ini parameter, WNI_CFG_FRAGMENTATION_THRESHOLD"));
        return -EIO;
    }

   EXIT();

   return 0;
}

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

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

	return ret;
}

/**
 * __iw_get_power_mode() - get power mode
 * @dev: pointer to net_device
 * @info: pointer to iw_request_info
 * @wrqu: pointer to iwreq_data
 * @extra: extra
 *
 * Return: 0 on success, error number otherwise
 */
static int __iw_get_power_mode(struct net_device *dev,
                               struct iw_request_info *info,
                               union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *adapter;
    hdd_context_t *hdd_ctx;
    int ret;

    ENTER();

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

    return -EOPNOTSUPP;
}

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

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

    return ret;
}

/**
 * __iw_set_power_mode() - set power mode
 * @dev: pointer to net_device
 * @info: pointer to iw_request_info
 * @wrqu: pointer to iwreq_data
 * @extra: extra
 *
 * Return: 0 on success, error number otherwise
 */
static int __iw_set_power_mode(struct net_device *dev,
			       struct iw_request_info *info,
			       union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *adapter;
    hdd_context_t *hdd_ctx;
    int ret;

    ENTER();

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

    return -EOPNOTSUPP;
}

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

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

	return ret;
}

/**
 * __iw_get_range() - SIOCGIWRANGE ioctl handler
 * @dev: device upon which the ioctl was received
 * @info: ioctl request information
 * @wrqu: ioctl request data
 * @extra: ioctl extra data
 *
 * Return: 0 on success, non-zero on error
 */
static int __iw_get_range(struct net_device *dev, struct iw_request_info *info,
			  union iwreq_data *wrqu, char *extra)
{
   hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
   tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
   struct iw_range *range = (struct iw_range *) extra;

   v_U8_t channels[WNI_CFG_VALID_CHANNEL_LIST_LEN];

   v_U32_t num_channels = sizeof(channels);
   v_U8_t supp_rates[WNI_CFG_SUPPORTED_RATES_11A_LEN];
   v_U32_t a_len;
   v_U32_t b_len;
   v_U32_t active_phy_mode = 0;
   v_U8_t index = 0, i;
   hdd_context_t *hdd_ctx;
   int ret;

   ENTER();

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

   wrqu->data.length = sizeof(struct iw_range);
   memset(range, 0, sizeof(struct iw_range));

   /*Get the phy mode*/
   if (ccmCfgGetInt(hHal,
                  WNI_CFG_DOT11_MODE, &active_phy_mode) == eHAL_STATUS_SUCCESS)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                "active_phy_mode = %d", active_phy_mode);

      if (active_phy_mode == WNI_CFG_DOT11_MODE_11A || active_phy_mode == WNI_CFG_DOT11_MODE_11G)
      {
         /*Get the supported rates for 11G band*/
         a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN;
         if (ccmCfgGetStr(hHal,
                          WNI_CFG_SUPPORTED_RATES_11A,
                          supp_rates, &a_len) == eHAL_STATUS_SUCCESS)
         {
            if (a_len > WNI_CFG_SUPPORTED_RATES_11A_LEN)
            {
               a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN;
            }
            for (i = 0; i < a_len; i++)
            {
               range->bitrate[i] = ((supp_rates[i] & 0x7F) / 2) * 1000000;
            }
            range->num_bitrates = a_len;
         }
         else
         {
            return -EIO;
         }
      }
      else if (active_phy_mode == WNI_CFG_DOT11_MODE_11B)
      {
         /*Get the supported rates for 11B band*/
         b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN;
         if (ccmCfgGetStr(hHal,
                          WNI_CFG_SUPPORTED_RATES_11B,
                          supp_rates, &b_len) == eHAL_STATUS_SUCCESS)
         {
            if (b_len > WNI_CFG_SUPPORTED_RATES_11B_LEN)
            {
               b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN;
            }
            for (i = 0; i < b_len; i++)
            {
               range->bitrate[i] = ((supp_rates[i] & 0x7F) / 2) * 1000000;
            }
            range->num_bitrates = b_len;
         }
         else
         {
            return -EIO;
         }
      }
   }

   range->max_rts = WNI_CFG_RTS_THRESHOLD_STAMAX;
   range->min_frag = WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN;
   range->max_frag = WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX;

   range->encoding_size[0] = 5;
   range->encoding_size[1] = 13;
   range->num_encoding_sizes = 2;
   range->max_encoding_tokens = MAX_WEP_KEYS;

   // we support through Wireless Extensions 22
   range->we_version_compiled = WIRELESS_EXT;
   range->we_version_source = 22;

   /*Supported Channels and Frequencies*/
   if (ccmCfgGetStr((hHal), WNI_CFG_VALID_CHANNEL_LIST, channels, &num_channels) != eHAL_STATUS_SUCCESS)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
               FL("failed to get ini parameter, WNI_CFG_VALID_CHANNEL_LIST"));
      return -EIO;
   }
   if (num_channels > IW_MAX_FREQUENCIES)
   {
      num_channels = IW_MAX_FREQUENCIES;
   }

   range->num_channels = num_channels;
   range->num_frequency = num_channels;

   for (index=0; index < num_channels; index++)
   {
      v_U32_t frq_indx = 0;

      range->freq[index].i = channels[index];
      while (frq_indx <  FREQ_CHAN_MAP_TABLE_SIZE)
      {
           if(channels[index] == freq_chan_map[frq_indx].chan)
           {
             range->freq[index].m = freq_chan_map[frq_indx].freq * 100000;
             range->freq[index].e = 1;
             break;
           }
           frq_indx++;
      }
   }

   /* Event capability (kernel + driver) */
   range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
                    IW_EVENT_CAPA_MASK(SIOCGIWAP) |
                    IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
   range->event_capa[1] = IW_EVENT_CAPA_K_1;

   /*Encryption capability*/
   range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
                IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;

   /* Txpower capability */
   range->txpower_capa = IW_TXPOW_MWATT;

   /*Scanning capability*/
   #if WIRELESS_EXT >= 22
   range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE | IW_SCAN_CAPA_CHANNEL;
   #endif

   EXIT();
   return 0;
}

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

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

	return ret;
}

/**
 * iw_power_callback_func() - Callback function registered with PMC
 * @context: cookie originally registered with PMC
 * @status: status code indicated by PMC state machine
 *
 * Return: None
 */
static void iw_power_callback_func(void *context, eHalStatus status)
{
	struct hdd_request *request = hdd_request_get(context);

	if (!request) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       "%s: Obsolete request", __func__);
		return;
	}

	hdd_request_complete(request);
	hdd_request_put(request);
}

/**
 * iw_power_offload_callback_fn() - Callback function registered with PMC to
 * know status of PMC request
 *
 * @context: pointer to calling context
 * @session_id: session_id
 * @status: eHAL_STATUS_SUCCESS if success else eHalStatus error code
 *
 * Return:
 */
static void iw_power_offload_callback_fn(void *context, tANI_U32 session_id,
					  eHalStatus status)
{
	struct hdd_request *request;

	request = hdd_request_get(context);
	if (!request) {
		hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Obsolete request", __func__);
		return;
	}

	hdd_request_complete(request);
	hdd_request_put(request);
}

/* Callback function for tx per hit */
void hdd_tx_per_hit_cb (void *pCallbackContext)
{
    hdd_adapter_t *pAdapter = (hdd_adapter_t *)pCallbackContext;
    unsigned char tx_fail[16];
    union iwreq_data wrqu;

    if (NULL == pAdapter || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
    {
        hddLog(LOGE, "hdd_tx_per_hit_cb: pAdapter is NULL");
        return;
    }
    memset(&wrqu, 0, sizeof(wrqu));
    wrqu.data.length = strlcpy(tx_fail, "TX_FAIL", sizeof(tx_fail));
    wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, tx_fail);
}

struct class_a_stats {
	tCsrGlobalClassAStatsInfo class_a_stats;
};

/**
 * hdd_get_class_a_statistics_cb() - Get Class A stats callback function
 * @stats: pointer to Class A stats
 * @context: user context originally registered with SME (always the
 *	     cookie from the request context)
 *
 * Return: None
 */
static void hdd_get_class_a_statistics_cb(void *stats, void *context)
{
	struct hdd_request *request;
	struct class_a_stats *priv;
	tCsrGlobalClassAStatsInfo *returned_stats;

	ENTER();
	if (ioctl_debug) {
		pr_info("%s: stats [%pK], context [%pK]\n",
			__func__, stats, context);
	}

	if (NULL == stats) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
			"%s: Bad param, stats [%pK]", __func__, stats);
		return;
	}

	request = hdd_request_get(context);
	if (!request) {
		hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Obsolete request", __func__);
		return;
	}

	returned_stats = stats;
	priv = hdd_request_priv(request);
	priv->class_a_stats = *returned_stats;
	hdd_request_complete(request);
	hdd_request_put(request);
	EXIT();
}

/**
 * wlan_hdd_get_classAstats() - Get Class A statistics
 * @pAdapter: adapter for which statistics are desired
 *
 * Return: VOS_STATUS_SUCCESS if adapter's Class A statistics were updated
 */
VOS_STATUS wlan_hdd_get_classAstats(hdd_adapter_t *pAdapter)
{
	hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
	eHalStatus hstatus;
	int ret;
	void *cookie;
	struct hdd_request *request;
	struct class_a_stats *priv;
	static const struct hdd_request_params params = {
		.priv_size = sizeof(*priv),
		.timeout_ms = WLAN_WAIT_TIME_STATS,
	};

	if (NULL == pAdapter) {
		hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
		return VOS_STATUS_E_FAULT;
	}
	if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			  "%s:LOGP in Progress. Ignore!!!",__func__);
		return VOS_STATUS_SUCCESS;
	}

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

	/* query only for Class A statistics (which include link speed) */
	hstatus = sme_GetStatistics(WLAN_HDD_GET_HAL_CTX(pAdapter),
				    eCSR_HDD, SME_GLOBAL_CLASSA_STATS,
				    hdd_get_class_a_statistics_cb,
				    0, /* not periodic */
				    FALSE, /* non-cached results */
				    pHddStaCtx->conn_info.staId[0],
				    cookie, pAdapter->sessionId);
	if (eHAL_STATUS_SUCCESS != hstatus) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
			"%s: Unable to retrieve Class A statistics",
			__func__);
		goto return_cached_results;
	}

	/* request was sent -- wait for the response */
	ret = hdd_request_wait_for_response(request);
	if (ret) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       FL("SME timed out while retrieving Class A statistics"));
		goto return_cached_results;
	}

	/* update the adapter with the fresh results */
	priv = hdd_request_priv(request);
	pAdapter->hdd_stats.ClassA_stat = priv->class_a_stats;

return_cached_results:
	/*
	 * either we never sent a request, we sent a request and
	 * received a response or we sent a request and timed out.
	 * regardless we are done with the request.
	 */
	hdd_request_put(request);

	return VOS_STATUS_SUCCESS;
}

struct station_stats {
	tCsrSummaryStatsInfo summary_stats;
	tCsrGlobalClassAStatsInfo class_a_stats;
	struct csr_per_chain_rssi_stats_info per_chain_rssi_stats;
};

/**
 * hdd_get_station_statistics_cb() - Get stats callback function
 * @stats: pointer to combined station stats
 * @context: user context originally registered with SME (always the
 *	     cookie from the request context)
 *
 * Return: None
 */
static void hdd_get_station_statistics_cb(void *stats, void *context)
{
	struct hdd_request *request;
	struct station_stats *priv;
	tCsrSummaryStatsInfo *summary_stats;
	tCsrGlobalClassAStatsInfo *class_a_stats;
	struct csr_per_chain_rssi_stats_info *per_chain_rssi_stats;

	if (ioctl_debug) {
		pr_info("%s: stats [%pK] context [%pK]\n",
			__func__, stats, context);
	}

	if (NULL == stats) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
			"%s: Bad param, stats [%pK]", __func__, stats);
		return;
	}

	request = hdd_request_get(context);
	if (!request) {
		hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Obsolete request", __func__);
		return;
	}

	summary_stats = (tCsrSummaryStatsInfo *) stats;
	class_a_stats = (tCsrGlobalClassAStatsInfo *) (summary_stats + 1);
	per_chain_rssi_stats = (struct csr_per_chain_rssi_stats_info *)
				(class_a_stats + 1);
	priv = hdd_request_priv(request);

	/* copy over the stats. do so as a struct copy */
	priv->summary_stats = *summary_stats;
	priv->class_a_stats = *class_a_stats;
	priv->per_chain_rssi_stats = *per_chain_rssi_stats;

	hdd_request_complete(request);
	hdd_request_put(request);
}

/**
 * wlan_hdd_get_station_stats() - Get station statistics
 * @pAdapter: adapter for which statistics are desired
 *
 * Return: VOS_STATUS_SUCCESS if adapter's statistics were updated
 */
VOS_STATUS wlan_hdd_get_station_stats(hdd_adapter_t *pAdapter)
{
	hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
	eHalStatus hstatus;
	int ret;
	void *cookie;
	struct hdd_request *request;
	struct station_stats *priv;
	static const struct hdd_request_params params = {
		.priv_size = sizeof(*priv),
		.timeout_ms = WLAN_WAIT_TIME_STATS,
	};

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

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

	/* query only for Summary & Class A statistics */
	hstatus = sme_GetStatistics(WLAN_HDD_GET_HAL_CTX(pAdapter),
				     eCSR_HDD,
				     SME_SUMMARY_STATS |
				     SME_GLOBAL_CLASSA_STATS |
				     SME_PER_CHAIN_RSSI_STATS,
				     hdd_get_station_statistics_cb,
				     0, /* not periodic */
				     FALSE, /* non-cached results */
				     pHddStaCtx->conn_info.staId[0],
				     cookie, pAdapter->sessionId);
	if (eHAL_STATUS_SUCCESS != hstatus) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
			"%s: Unable to retrieve statistics", __func__);
		/* we'll return with cached values */
	} else {
		/* request was sent -- wait for the response */
		ret = hdd_request_wait_for_response(request);
		if (ret) {
			hddLog(VOS_TRACE_LEVEL_WARN,
			       FL("SME timed out while retrieving statistics"));
			/* we'll returned a cached value below */
		} else {
			/* update the adapter with the fresh results */
			priv = hdd_request_priv(request);
			pAdapter->hdd_stats.summary_stat = priv->summary_stats;
			pAdapter->hdd_stats.ClassA_stat = priv->class_a_stats;
			pAdapter->hdd_stats.per_chain_rssi_stats =
				priv->per_chain_rssi_stats;
		}
	}

	/*
	 * either we never sent a request, we sent a request and
	 * received a response or we sent a request and timed out.
	 * regardless we are done with the request.
	 */
	hdd_request_put(request);

	/* either callback updated pAdapter stats or it has cached data */
	return VOS_STATUS_SUCCESS;
}

/*
 * Support for the LINKSPEED private command
 * Per the WiFi framework the response must be of the form
 *         "LinkSpeed xx"
 */
static int iw_get_linkspeed(struct net_device *dev,
                            struct iw_request_info *info,
                            union iwreq_data *wrqu, char *extra)
{
   hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
   char *pLinkSpeed = (char*)extra;
   int len = sizeof(v_U32_t) + 1;
   v_U32_t link_speed = 0;
   int rc;
   int ret_val;

   ENTER();
   ret_val = wlan_hdd_get_link_speed(pAdapter, &link_speed);
   if (0 != ret_val) {
       return ret_val;
   }

   wrqu->data.length = len;
   /* return the linkspeed in the format required by the WiFi Framework */
   rc = snprintf(pLinkSpeed, len, "%u", link_speed);
   if ((rc < 0) || (rc >= len))
   {
       /* encoding or length error? */
       hddLog(VOS_TRACE_LEVEL_ERROR,FL("Unable to encode link speed"));
       return -EIO;
   }

  /* a value is being successfully returned */
  EXIT();
  return rc;
}

/*
 * Helper function to return correct value for WLAN_GET_LINK_SPEED
 *
 */
static int __iw_get_linkspeed_priv(struct net_device *dev,
                                 struct iw_request_info *info,
                                 union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *hdd_ctx;
    int rc, valid;

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

    rc = iw_get_linkspeed(dev, info, wrqu, extra);

    if (rc < 0)
       return rc;

    /* a value is being successfully returned */
    return 0;
}

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

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

	return ret;
}

struct isolation_info {
	uint32_t isolation_chain0:8;
	uint32_t isolation_chain1:8;
	uint32_t isolation_chain2:8;
	uint32_t isolation_chain3:8;
};

static void hdd_get_isolation_cb(struct sir_isolation_resp *isolation,
				 void *cookie)
{
	struct hdd_request *request;
	struct isolation_info *priv;

	if (!isolation) {
	    hddLog(LOGE, FL("Bad param"));
	    return;
	}

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

	priv = hdd_request_priv(request);
	priv->isolation_chain0 = isolation->isolation_chain0;
	priv->isolation_chain1 = isolation->isolation_chain1;
	priv->isolation_chain2 = isolation->isolation_chain2;
	priv->isolation_chain3 = isolation->isolation_chain3;

	hdd_request_complete(request);
	hdd_request_put(request);
}

static void hdd_post_isolation(union iwreq_data *wrqu, char *extra,
			       struct isolation_info *isolation)
{
	int buf = 0;
	int length = 0;

	hddLog(LOG1, "%s: chain1 %d chain2 %d chain3 %d chain4 %d", __func__,
	       isolation->isolation_chain0, isolation->isolation_chain1,
	       isolation->isolation_chain2, isolation->isolation_chain3);

	length = scnprintf((extra), WE_MAX_STR_LEN, "\n");
	buf = scnprintf((extra + length), WE_MAX_STR_LEN - length,
			"isolation chain 0 : %d\n",
			isolation->isolation_chain0);
	length += buf;
	buf = scnprintf((extra + length), WE_MAX_STR_LEN - length,
			"isolation chain 1 : %d\n",
			isolation->isolation_chain1);
	length += buf;
	buf = scnprintf((extra + length), WE_MAX_STR_LEN - length,
			"isolation chain 2 : %d\n",
			isolation->isolation_chain2);
	length += buf;
	buf = scnprintf((extra + length), WE_MAX_STR_LEN - length,
			"isolation chain 3 : %d\n",
			isolation->isolation_chain3);
	length += buf;

	wrqu->data.length = length + 1;
}

static int wlan_hdd_get_isolation(hdd_adapter_t *adapter,
				  union iwreq_data *wrqu, char *extra)
{
	eHalStatus hstatus;
	int ret;
	void *cookie;
	struct hdd_request *request;
	struct isolation_info *priv;
	static const struct hdd_request_params params = {
		.priv_size = sizeof(*priv),
		.timeout_ms = 8000,
	};

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

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

	hstatus = sme_get_isolation(WLAN_HDD_GET_HAL_CTX(adapter),
				    cookie,
				    hdd_get_isolation_cb);
	if (eHAL_STATUS_SUCCESS != hstatus) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       "%s: Unable to retrieve isolation",
		        __func__);
		ret = -EFAULT;
	} else {
		ret = hdd_request_wait_for_response(request);
		if (ret) {
			hddLog(VOS_TRACE_LEVEL_ERROR,
			       "%s: SME timed out while retrieving isolation",
			       __func__);
			ret = -ETIMEDOUT;
		} else {
			priv = hdd_request_priv(request);
			hdd_post_isolation(wrqu, extra, priv);
			ret = 0;
		}
	}

	hdd_request_put(request);

	return ret;
}

static int __iw_get_isolation(struct net_device *dev,
        struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *hdd_ctx;
    int ret;

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

    ret = wlan_hdd_get_isolation(adapter, wrqu, extra);

    if (ret < 0)
        return ret;

    /* a value is being successfully returned */
    return 0;
}

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

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

    return ret;
}

VOS_STATUS  wlan_hdd_enter_bmps(hdd_adapter_t *pAdapter, int mode)
{
	struct hdd_request *request;
	void *cookie;
	eHalStatus status;
	hdd_context_t *pHddCtx;
	static const struct hdd_request_params params = {
		.priv_size = 0,
		.timeout_ms = WLAN_WAIT_TIME_POWER,
	};

	if (NULL == pAdapter)
	{
		hddLog(VOS_TRACE_LEVEL_FATAL, "Adapter NULL");
		return VOS_STATUS_E_FAULT;
	}

	hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "power mode=%d", mode);
	pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
	if (pHddCtx->isLogpInProgress) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			"%s:LOGP in Progress. Ignore!!!", __func__);
		return VOS_STATUS_E_FAILURE;
	}

	request = hdd_request_alloc(&params);
	if (!request) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
			"%s: Request allocation failure", __func__);
		return VOS_STATUS_E_NOMEM;
	}

	cookie = hdd_request_cookie(request);

	if (DRIVER_POWER_MODE_ACTIVE == mode)
	{
		hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering "
			"Full Power", __func__);
		status = sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
			iw_power_callback_func, cookie,
			eSME_FULL_PWR_NEEDED_BY_HDD);
		/*
		 * Enter Full power command received from GUI this means we are
		 * disconnected. Set PMC remainInPowerActiveTillDHCP flag to
		 * disable auto BMPS entry by PMC
		 */
		sme_SetDHCPTillPowerActiveFlag(pHddCtx->hHal, TRUE);
		if (eHAL_STATUS_PMC_PENDING == status)
		{
			int rc;
			/* request was sent -- wait for the response */
			rc = hdd_request_wait_for_response(request);
			if (rc)
				hddLog(VOS_TRACE_LEVEL_ERROR,
					FL("SME timed out while requesting full power"));
		}
	}
	else if (DRIVER_POWER_MODE_AUTO == mode)
	{
		if (pHddCtx->cfg_ini->fIsBmpsEnabled)
		{
			hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering Bmps ",
				__func__);
			/*
			 * Enter BMPS command received from GUI this means DHCP
			 * is completed.  Clear PMC remainInPowerActiveTillDHCP
			 * flag to enable auto BMPS entry.
			 */
			sme_SetDHCPTillPowerActiveFlag(
				WLAN_HDD_GET_HAL_CTX(pAdapter), FALSE);
			status = sme_RequestBmps(WLAN_HDD_GET_HAL_CTX(pAdapter),
				iw_power_callback_func, cookie);
			if (eHAL_STATUS_PMC_PENDING == status)
			{
				int rc;
				/* request was sent -- wait for the response */
				rc = hdd_request_wait_for_response(request);
				if (rc)
					hddLog(VOS_TRACE_LEVEL_ERROR,
						FL("SME timed out while requesting BMPS"));
			}
		} else {
			hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "BMPS is not "
				"enabled in the cfg");
		}
	}

	/*
	 * either we never sent a request, we sent a request and
	 * received a response or we sent a request and timed out.
	 * regardless we are done with the request.
	 */
	hdd_request_put(request);

	return VOS_STATUS_SUCCESS;
}

VOS_STATUS  wlan_hdd_set_powersave(hdd_adapter_t *pAdapter, int mode)
{
   hdd_context_t *pHddCtx;
   eHalStatus status;

   if (NULL == pAdapter)
   {
       hddLog(VOS_TRACE_LEVEL_FATAL, "Adapter NULL");
       return VOS_STATUS_E_FAULT;
   }

   hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "power mode=%d", mode);

   pHddCtx = WLAN_HDD_GET_CTX(pAdapter);

   if (DRIVER_POWER_MODE_ACTIVE == mode)
   {
       void *cookie;
       struct hdd_request *request;
       static const struct hdd_request_params params = {
           .priv_size = 0,
           .timeout_ms = WLAN_WAIT_TIME_POWER,
       };

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

       hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering "
               "Full Power", __func__);

       /*
        * Enter Full power command received from GUI
        * this means we are disconnected
        */
       status = sme_PsOffloadDisablePowerSave(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                     iw_power_offload_callback_fn, cookie,
                                     pAdapter->sessionId);
       if (eHAL_STATUS_PMC_PENDING == status) {
           if (hdd_request_wait_for_response(request)) {
               hddLog(VOS_TRACE_LEVEL_WARN,
                      FL("SME timed out while requesting full power"));
           }
       }
       hdd_request_put(request);

       if (pHddCtx->cfg_ini->fIsBmpsEnabled)
          sme_ConfigDisablePowerSave(pHddCtx->hHal,
                             ePMC_BEACON_MODE_POWER_SAVE);
   }
   else if (DRIVER_POWER_MODE_AUTO == mode)
   {
       if (pHddCtx->cfg_ini->fIsBmpsEnabled)
       {
           sme_ConfigEnablePowerSave(pHddCtx->hHal,
                               ePMC_BEACON_MODE_POWER_SAVE);
           hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering Bmps ",
                  __func__);

           /*
            * Enter BMPS command received from GUI
            * this means DHCP is completed
            */
           sme_PsOffloadEnablePowerSave(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                        pAdapter->sessionId);
       }
       else
       {
           hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "BMPS is not "
                   "enabled in the cfg");
       }
   }

   return VOS_STATUS_SUCCESS;
}

VOS_STATUS wlan_hdd_exit_lowpower(hdd_context_t *pHddCtx,
                                       hdd_adapter_t *pAdapter)
{
   VOS_STATUS vos_Status;

   if ((NULL == pAdapter) || (NULL == pHddCtx))
   {
       hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid pointer");
       return VOS_STATUS_E_FAULT;
   }

   /**Exit from Deep sleep or standby if we get the driver
   START cmd from android GUI
    */
   if (WLAN_MAP_DRIVER_STOP_TO_STANDBY == pHddCtx->cfg_ini->nEnableDriverStop)
   {
       hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: WLAN being exit "
              "from Stand by",__func__);
       vos_Status = hdd_exit_standby(pHddCtx);
   }
   else if (eHDD_SUSPEND_DEEP_SLEEP == pHddCtx->hdd_ps_state)
   {
       hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: WLAN being exit "
              "from deep sleep",__func__);
       vos_Status = hdd_exit_deep_sleep(pHddCtx, pAdapter);
   }
   else
   {
       hddLog(VOS_TRACE_LEVEL_WARN, "%s: Not in standby or deep sleep. "
               "Ignore start cmd %d", __func__, pHddCtx->hdd_ps_state);
       vos_Status = VOS_STATUS_SUCCESS;
   }

   return vos_Status;
}

VOS_STATUS wlan_hdd_enter_lowpower(hdd_context_t *pHddCtx)
{
   VOS_STATUS vos_Status = VOS_STATUS_E_FAILURE;

   if (NULL == pHddCtx)
   {
        hddLog(VOS_TRACE_LEVEL_ERROR, "HDD context NULL");
        return VOS_STATUS_E_FAULT;
   }

   if (WLAN_MAP_DRIVER_STOP_TO_STANDBY == pHddCtx->cfg_ini->nEnableDriverStop)
   {
      //Execute standby procedure.
      //Executing standby procedure will cause the STA to
      //disassociate first and then the chip will be put into standby.
      hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "Wlan driver entering Stand by mode");
      vos_Status  = hdd_enter_standby(pHddCtx);
   }
   else if (WLAN_MAP_DRIVER_STOP_TO_DEEP_SLEEP ==
            pHddCtx->cfg_ini->nEnableDriverStop)
   {
       //Execute deep sleep procedure
       hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "Wlan driver entering "
               "deep sleep mode");
       //Deep sleep not supported
       vos_Status  = hdd_enter_standby(pHddCtx);
   }
   else
   {
       hddLog(VOS_TRACE_LEVEL_INFO_LOW, "%s: Driver stop is not enabled %d",
           __func__, pHddCtx->cfg_ini->nEnableDriverStop);
       vos_Status = VOS_STATUS_SUCCESS;
   }

   return vos_Status;
}


void* wlan_hdd_change_country_code_callback(void *pAdapter)
{

    hdd_adapter_t *call_back_pAdapter = pAdapter;
    complete(&call_back_pAdapter->change_country_code);

    return NULL;
}

/**
 * __iw_set_nick() - set nick
 * @dev: pointer to net_device
 * @info: pointer to iw_request_info
 * @wrqu: pointer to iwreq_data
 * @extra: extra
 *
 * Return: 0 on success, error number otherwise
 */
static int __iw_set_nick(struct net_device *dev,
                         struct iw_request_info *info,
                         union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *adapter;
    hdd_context_t *hdd_ctx;
    int ret;

    ENTER();

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

    return 0;
}

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

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

	return ret;
}

/**
 * __iw_get_nick() - get nick
 * @dev: pointer to net_device
 * @info: pointer to iw_request_info
 * @wrqu: pointer to iwreq_data
 * @extra: extra
 *
 * Return: 0 on success, error number otherwise
 */
static int __iw_get_nick(struct net_device *dev,
                         struct iw_request_info *info,
                         union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *adapter;
    hdd_context_t *hdd_ctx;
    int ret;

    ENTER();

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

    return 0;
}

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

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

	return ret;
}

/**
 * __get_wireless_stats() - get wireless stats
 * @dev: pointer to net_device
 *
 * Return: %NULL
 */
static struct iw_statistics *__get_wireless_stats(struct net_device *dev)
{
	ENTER();
	return NULL;
}

/**
 * get_wireless_stats() - SSR wrapper for __get_wireless_stats
 * @dev: pointer to net_device
 *
 * Return: pointer to iw_statistics
 */
static struct iw_statistics *get_wireless_stats(struct net_device *dev)
{
	struct iw_statistics *iw_stats;

	ENTER();
	vos_ssr_protect(__func__);
	iw_stats = __get_wireless_stats(dev);
	vos_ssr_unprotect(__func__);

	return iw_stats;
}


/**
 * __iw_set_encode() - SIOCSIWENCODE ioctl handler
 * @dev: device upon which the ioctl was received
 * @info: ioctl request information
 * @wrqu: ioctl request data
 * @extra: ioctl extra data
 *
 * Return: 0 on success, non-zero on error
 */
static int __iw_set_encode(struct net_device *dev,struct iw_request_info *info,
			   union iwreq_data *wrqu,char *extra)

{
   hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
   hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
   hdd_wext_state_t  *pWextState =  WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
   struct iw_point *encoderq = &(wrqu->encoding);
   v_U32_t keyId;
   v_U8_t key_length;
   eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
   v_BOOL_t fKeyPresent = 0;
   int i;
   eHalStatus status = eHAL_STATUS_SUCCESS;
   hdd_context_t *hdd_ctx;
   int ret;

   ENTER();

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

   keyId = encoderq->flags & IW_ENCODE_INDEX;

   if(keyId)
   {
       if(keyId > MAX_WEP_KEYS)
       {
           return -EINVAL;
       }

       fKeyPresent = 1;
       keyId--;
   }
   else
   {
       fKeyPresent = 0;
   }


   if(wrqu->data.flags & IW_ENCODE_DISABLED)
   {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "****iwconfig wlan0 key off*****");
       if(!fKeyPresent) {

          for(i=0;i < CSR_MAX_NUM_KEY; i++)
                pWextState->roamProfile.Keys.KeyLength[i] = 0;
       }
       pHddStaCtx->conn_info.authType =  eCSR_AUTH_TYPE_OPEN_SYSTEM;
       pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
       pWextState->roamProfile.EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
       pWextState->roamProfile.mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;

       pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
       pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;

       if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
       {
           INIT_COMPLETION(pAdapter->disconnect_comp_var);
           status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED );
           if(eHAL_STATUS_SUCCESS == status)
           {
                 unsigned long rc;
                 rc = wait_for_completion_timeout(
                              &pAdapter->disconnect_comp_var,
                               msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
                if (!rc)
                     hddLog(VOS_TRACE_LEVEL_ERROR,
                            FL("failed wait on disconnect_comp_var"));
           }
       }

       return status;

   }

   if (wrqu->data.flags & (IW_ENCODE_OPEN | IW_ENCODE_RESTRICTED))
   {
      hddLog(VOS_TRACE_LEVEL_INFO, "iwconfig wlan0 key on");

      pHddStaCtx->conn_info.authType = (encoderq->flags & IW_ENCODE_RESTRICTED) ? eCSR_AUTH_TYPE_SHARED_KEY : eCSR_AUTH_TYPE_OPEN_SYSTEM;

   }


   if(wrqu->data.length > 0)
   {
       hddLog(VOS_TRACE_LEVEL_INFO, "%s : wrqu->data.length : %d",__func__,wrqu->data.length);

       key_length = wrqu->data.length;

       /* IW_ENCODING_TOKEN_MAX is the value that is set for wrqu->data.length by iwconfig.c when 'iwconfig wlan0 key on' is issued.*/

       if(5 == key_length)
       {
           hddLog(VOS_TRACE_LEVEL_INFO, "%s: Call with WEP40,key_len=%d",__func__,key_length);

           if((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
           {
               encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
           }
           else
           {
               encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
           }
       }
       else if(13 == key_length)
       {
           hddLog(VOS_TRACE_LEVEL_INFO, "%s:Call with WEP104,key_len:%d",__func__,key_length);

           if((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
           {
               encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
           }
           else
           {
               encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
           }
       }
       else
       {
           hddLog(VOS_TRACE_LEVEL_WARN, "%s: Invalid WEP key length :%d",
                  __func__, key_length);
           return -EINVAL;
       }

       pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
       pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
       pWextState->roamProfile.EncryptionType.numEntries = 1;
       pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
       pWextState->roamProfile.mcEncryptionType.numEntries = 1;
       pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;

       if((eConnectionState_NotConnected == pHddStaCtx->conn_info.connState) &&
            ((eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType) ||
              (eCSR_AUTH_TYPE_SHARED_KEY == pHddStaCtx->conn_info.authType)))
       {

          vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[keyId][0],extra,key_length);

          pWextState->roamProfile.Keys.KeyLength[keyId] = (v_U8_t)key_length;
          pWextState->roamProfile.Keys.defaultIndex = (v_U8_t)keyId;

          return status;
       }
   }

   return 0;
}

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

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

	return ret;
}

/**
 * __iw_get_encodeext() - SIOCGIWENCODEEXT ioctl handler
 * @dev: device upon which the ioctl was received
 * @info: ioctl request information
 * @dwrq: ioctl request data
 * @extra: ioctl extra data
 *
 * Return: 0 on success, non-zero on error
 */
static int __iw_get_encodeext(struct net_device *dev,
			      struct iw_request_info *info,
			      struct iw_point *dwrq,
			      char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_wext_state_t  *pWextState =  WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
    int keyId;
    eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
    eCsrAuthType authType = eCSR_AUTH_TYPE_NONE;
    int i, ret;
    hdd_context_t *hdd_ctx;

    ENTER();

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

    keyId = pRoamProfile->Keys.defaultIndex;

    if(keyId < 0 || keyId >= MAX_WEP_KEYS)
    {
        hddLog(LOG1,"%s: Invalid keyId : %d", __func__, keyId);
        return -EINVAL;
    }

    if(pRoamProfile->Keys.KeyLength[keyId] > 0)
    {
        dwrq->flags |= IW_ENCODE_ENABLED;
        dwrq->length = pRoamProfile->Keys.KeyLength[keyId];
        vos_mem_copy(extra, &(pRoamProfile->Keys.KeyMaterial[keyId][0]),
                     pRoamProfile->Keys.KeyLength[keyId]);
    }
    else
    {
        dwrq->flags |= IW_ENCODE_DISABLED;
    }

    for(i=0; i < MAX_WEP_KEYS; i++)
    {
        if (pRoamProfile->Keys.KeyLength[i] == 0)
        {
            continue;
        }
        else
        {
            break;
        }
    }

    if(MAX_WEP_KEYS == i)
    {
        dwrq->flags |= IW_ENCODE_NOKEY;
    }
    else
    {
        dwrq->flags |= IW_ENCODE_ENABLED;
    }

    encryptionType = pRoamProfile->EncryptionType.encryptionType[0];

    if(eCSR_ENCRYPT_TYPE_NONE == encryptionType)
    {
        dwrq->flags |= IW_ENCODE_DISABLED;
    }

    authType = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;

    if(IW_AUTH_ALG_OPEN_SYSTEM == authType)
    {
        dwrq->flags |= IW_ENCODE_OPEN;
    }
    else
    {
        dwrq->flags |= IW_ENCODE_RESTRICTED;
    }
    EXIT();
    return 0;

}

/**
 * iw_get_encodeext() - SSR wrapper for __iw_get_encodeext()
 * @dev: pointer to net_device
 * @info: pointer to iw_request_info
 * @dwrq: pointer to encoding information
 * @extra: pointer to extra ioctl payload
 *
 * Return: 0 on success, error number otherwise
 */
static int iw_get_encodeext(struct net_device *dev,
			    struct iw_request_info *info,
			    struct iw_point *dwrq, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_get_encodeext(dev, info, dwrq, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

/**
 * __iw_set_encodeext() - SIOCSIWENCODEEXT ioctl handler
 * @dev: device upon which the ioctl was received
 * @info: ioctl request information
 * @wrqu: ioctl request data
 * @extra: ioctl extra data
 *
 * Return: 0 on success, non-zero on error
 */
static int __iw_set_encodeext(struct net_device *dev,
			      struct iw_request_info *info,
			      union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    hdd_wext_state_t  *pWextState =  WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    eHalStatus halStatus= eHAL_STATUS_SUCCESS;
    tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
    struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
    v_U8_t groupmacaddr[VOS_MAC_ADDR_SIZE] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
    int key_index;
    struct iw_point *encoding = &wrqu->encoding;
    tCsrRoamSetKey  setKey;
    v_U32_t  roamId= 0xFF;
    VOS_STATUS vos_status;
    hdd_context_t *hdd_ctx;
    int ret;

    ENTER();

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

    key_index = encoding->flags & IW_ENCODE_INDEX;

    if(key_index > 0) {

         /*Convert from 1-based to 0-based keying*/
        key_index--;
    }
    if(!ext->key_len) {

      /* Set the encryption type to NONE */
       pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
       return ret;
    }

    if(eConnectionState_NotConnected == pHddStaCtx->conn_info.connState &&
                                                  (IW_ENCODE_ALG_WEP == ext->alg))
    {
       if(IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) {

          VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                     ("Invalid Configuration:%s"),__func__);
          return -EINVAL;
       }
       else {
         /*Static wep, update the roam profile with the keys */
          if ((ext->key_len <= eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES) &&
                                               (key_index < CSR_MAX_NUM_KEY)) {
             vos_mem_copy(&pRoamProfile->Keys.KeyMaterial[key_index][0],ext->key,ext->key_len);
             pRoamProfile->Keys.KeyLength[key_index] = (v_U8_t)ext->key_len;

             if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
                pRoamProfile->Keys.defaultIndex = (v_U8_t)key_index;

          }
       }
       return ret;
    }

    vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));

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

    if(ext->key_len <= CSR_MAX_KEY_LEN) {
       vos_mem_copy(&setKey.Key[0],ext->key,ext->key_len);
    }

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

       setKey.keyDirection =  eSIR_TX_RX;
       vos_mem_copy(setKey.peerMac,ext->addr.sa_data, VOS_MAC_ADDR_SIZE);
    }

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

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

       case IW_ENCODE_ALG_WEP:
         setKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
         break;

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

          setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;

          vos_mem_zero(pKey, CSR_MAX_KEY_LEN);

          /*Supplicant sends the 32bytes key in this order

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

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

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

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

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

       }
       break;

       case IW_ENCODE_ALG_CCMP:
          setKey.encType = eCSR_ENCRYPT_TYPE_AES;
          break;

#ifdef FEATURE_WLAN_ESE
#define IW_ENCODE_ALG_KRK 6
       case IW_ENCODE_ALG_KRK:
          setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
          break;
#endif  /* FEATURE_WLAN_ESE */

       default:
          setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
          break;
    }

    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
          ("%s:cipher_alg:%d key_len[%d] *pEncryptionType :%d"),__func__,(int)ext->alg,(int)ext->key_len,setKey.encType);

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

    pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;

    vos_status = wlan_hdd_check_ula_done(pAdapter);
    if ( vos_status != VOS_STATUS_SUCCESS )
    {
       VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
                   __LINE__, vos_status );

       pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
    }

    halStatus = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),pAdapter->sessionId, &setKey, &roamId );

    if ( halStatus != eHAL_STATUS_SUCCESS )
    {
       VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "[%4d] sme_RoamSetKey returned ERROR status= %d",
                   __LINE__, halStatus );

       pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
    }

   return halStatus;
}

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

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

	return ret;
}

/**
 * __iw_set_retry() - SIOCSIWRETRY ioctl handler
 * @dev: device upon which the ioctl was received
 * @info: ioctl request information
 * @wrqu: ioctl request data
 * @extra: ioctl extra data
 *
 * Return: 0 on success, non-zero on error
 */
static int __iw_set_retry(struct net_device *dev, struct iw_request_info *info,
			  union iwreq_data *wrqu, char *extra)
{
   hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
   tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
   hdd_context_t *hdd_ctx;
   int ret;

   ENTER();

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

   if(wrqu->retry.value < WNI_CFG_LONG_RETRY_LIMIT_STAMIN ||
       wrqu->retry.value > WNI_CFG_LONG_RETRY_LIMIT_STAMAX) {

      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("Invalid Retry-Limit=%d!!"),wrqu->retry.value);

      return -EINVAL;
   }

   if(wrqu->retry.flags & IW_RETRY_LIMIT) {

       if((wrqu->retry.flags & IW_RETRY_LONG))
       {
          if ( ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT, wrqu->retry.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS )
          {
             VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
               FL("failed to set ini parameter, WNI_CFG_LONG_RETRY_LIMIT"));
             return -EIO;
          }
       }
       else if((wrqu->retry.flags & IW_RETRY_SHORT))
       {
          if ( ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT, wrqu->retry.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS )
          {
             VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
               FL("failed to set ini parameter, WNI_CFG_LONG_RETRY_LIMIT"));
             return -EIO;
          }
       }
   }
   else
   {
       return -EOPNOTSUPP;
   }

   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("Set Retry-Limit=%d!!"),wrqu->retry.value);

   EXIT();

   return 0;

}

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

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

	return ret;
}

/**
 * __iw_get_retry() - SIOCGIWRETRY ioctl handler
 * @dev: device upon which the ioctl was received
 * @info: ioctl request information
 * @wrqu: ioctl request data
 * @extra: ioctl extra data
 *
 * Return: 0 on success, non-zero on error
 */
static int __iw_get_retry(struct net_device *dev, struct iw_request_info *info,
			  union iwreq_data *wrqu, char *extra)
{
   hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
   tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
   v_U32_t retry = 0;
   hdd_context_t *hdd_ctx;
   int ret;

   ENTER();

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

   if((wrqu->retry.flags & IW_RETRY_LONG))
   {
      wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG;

      if ( ccmCfgGetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT, &retry) != eHAL_STATUS_SUCCESS )
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                      FL("failed to get ini parameter, WNI_CFG_LONG_RETRY_LIMIT"));
         return -EIO;
      }

      wrqu->retry.value = retry;
   }
   else if ((wrqu->retry.flags & IW_RETRY_SHORT))
   {
      wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_SHORT;

      if ( ccmCfgGetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT, &retry) != eHAL_STATUS_SUCCESS )
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                      FL("failed to get ini parameter, WNI_CFG_LONG_RETRY_LIMIT"));
         return -EIO;
      }

      wrqu->retry.value = retry;
   }
   else {
      return -EOPNOTSUPP;
   }

   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("Retry-Limit=%d!!"),retry);

   EXIT();

   return 0;
}

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

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

	return ret;
}

/**
 * __iw_set_mlme() - SIOCSIWMLME ioctl handler
 * @dev: device upon which the ioctl was received
 * @info: ioctl request information
 * @wrqu: ioctl request data
 * @extra: ioctl extra data
 *
 * Return: 0 on success, non-zero on error
 */
static int __iw_set_mlme(struct net_device *dev, struct iw_request_info *info,
			 union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    struct iw_mlme *mlme = (struct iw_mlme *)extra;
    eHalStatus status = eHAL_STATUS_SUCCESS;
    hdd_context_t *hdd_ctx;
    int ret;

    ENTER();

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

    //reason_code is unused. By default it is set to eCSR_DISCONNECT_REASON_UNSPECIFIED
    switch (mlme->cmd) {
        case IW_MLME_DISASSOC:
        case IW_MLME_DEAUTH:

            if( pHddStaCtx->conn_info.connState == eConnectionState_Associated )
            {
                eCsrRoamDisconnectReason reason = eCSR_DISCONNECT_REASON_UNSPECIFIED;

                if( mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE )
                    reason = eCSR_DISCONNECT_REASON_MIC_ERROR;

                INIT_COMPLETION(pAdapter->disconnect_comp_var);
                status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,reason);

                if(eHAL_STATUS_SUCCESS == status)
                {
                    unsigned long rc;
                    rc = wait_for_completion_timeout(
                                   &pAdapter->disconnect_comp_var,
                                   msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
                    if (!rc)
                        hddLog(VOS_TRACE_LEVEL_ERROR,
                            FL("failed wait on disconnect_comp_var"));
                }
                else
                    hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate : csrRoamDisconnect failure returned %d",
                       __func__, (int)mlme->cmd, (int)status );

                /* Resetting authKeyMgmt */
                (WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->authKeyMgmt = 0;

                hddLog(LOG1, FL("Disabling queues"));
                wlan_hdd_netif_queue_control(pAdapter,
                    WLAN_NETIF_TX_DISABLE_N_CARRIER,
                    WLAN_CONTROL_PATH);

            }
            else
            {
                hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate called but station is not in associated state", __func__, (int)mlme->cmd );
            }
            break;
        default:
            hddLog(LOGE,"%s %d Command should be Disassociate/Deauthenticate", __func__, (int)mlme->cmd );
            return -EINVAL;
    }//end of switch

    EXIT();

    return status;

}

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

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

	return ret;
}

int process_wma_set_command(int sessid, int paramid,
                            int sval, int vpdev)
{
    int ret = 0;
    vos_msg_t msg = {0};

    v_CONTEXT_t vos_context = vos_get_global_context(0, NULL);
    hdd_context_t *hdd_ctx;
    wda_cli_set_cmd_t *iwcmd;

    /* Skip session validation in FTM mode and for PDEV commands */
    if (vpdev == PDEV_CMD || VOS_FTM_MODE == hdd_get_conparam())
       goto skip_ftm;

    hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_context);
    if (!hdd_ctx) {
       hddLog(LOGE,FL("hdd context is not valid!"));
       return -EINVAL;
    }

    if (vpdev != PDEV_CMD &&
        VOS_STATUS_SUCCESS != sme_is_session_valid(hdd_ctx->hHal,
                                                     sessid)) {
       hddLog(LOGE, FL("SME session id is not valid %d"), sessid);
       return -EINVAL;
    }

skip_ftm:
    iwcmd = (wda_cli_set_cmd_t *)vos_mem_malloc(
                                sizeof(wda_cli_set_cmd_t));
    if (NULL == iwcmd) {
       hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed", __func__);
       return -EINVAL;
    }
    vos_mem_zero((void *)iwcmd, sizeof(wda_cli_set_cmd_t));
    iwcmd->param_value = sval;
    iwcmd->param_vdev_id = sessid;
    iwcmd->param_id = paramid;
    iwcmd->param_vp_dev = vpdev;
    msg.type = WDA_CLI_SET_CMD;
    msg.reserved = 0;
    msg.bodyptr = (void *)iwcmd;
    if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA,
                                                  &msg)) {
       hddLog(VOS_TRACE_LEVEL_ERROR, "%s: "
                 "Not able to post wda_cli_set_cmd message to WDA",
                 __func__);
       vos_mem_free(iwcmd);
       ret = -EIO;
    }
    return ret;
}

int process_wma_set_command_twoargs(int sessid, int paramid,
                                    int sval, int ssecval, int vpdev)
{
    int ret = 0;
    vos_msg_t msg = {0};
    wda_cli_set_cmd_t *iwcmd;

    v_CONTEXT_t vos_context = vos_get_global_context(0, NULL);
    hdd_context_t *hdd_ctx;
    /* Skip session validation in FTM mode and for PDEV commands */
    if (vpdev == PDEV_CMD || VOS_FTM_MODE == hdd_get_conparam())
       goto skip_ftm;

    hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_context);

    if (!hdd_ctx) {
       hddLog(LOGE,FL("hdd context is not valid!"));
       return -EINVAL;
    }

    if (VOS_STATUS_SUCCESS  != sme_is_session_valid(hdd_ctx->hHal,
                                                     sessid)) {
       hddLog(LOGE, FL("SME session id is not valid %d"), sessid);
       return -EINVAL;
    }

skip_ftm:
    iwcmd = vos_mem_malloc(sizeof(*iwcmd));

    if (NULL == iwcmd) {
        hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed!", __func__);
        ret = -EINVAL;
        goto out;
    }

    vos_mem_zero(iwcmd, sizeof(*iwcmd));
    iwcmd->param_value = sval;
    iwcmd->param_sec_value = ssecval;
    iwcmd->param_vdev_id = sessid;
    iwcmd->param_id = paramid;
    iwcmd->param_vp_dev = vpdev;
    msg.type = WDA_CLI_SET_CMD;
    msg.reserved = 0;
    msg.bodyptr = iwcmd;

    if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: "
                  "Not able to post wda_cli_set_cmd message to WDA", __func__);
        vos_mem_free(iwcmd);
        ret = -EIO;
    }

out:
    return ret;
}

int wlan_hdd_update_phymode(struct net_device *net, tHalHandle hal,
                                   int new_phymode,
                                   hdd_context_t *phddctx)
{
#ifdef QCA_HT_2040_COEX
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(net);
    eHalStatus halStatus = eHAL_STATUS_FAILURE;
#endif
    v_BOOL_t band_24 = VOS_FALSE, band_5g = VOS_FALSE;
    v_BOOL_t ch_bond24 = VOS_FALSE, ch_bond5g = VOS_FALSE;
    tSmeConfigParams smeconfig = {{0}};
    tANI_U32 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
#ifdef WLAN_FEATURE_11AC
    tANI_U32 vhtchanwidth;
#endif
    eCsrPhyMode phymode = -EIO, old_phymode;
    eHddDot11Mode hdd_dot11mode = phddctx->cfg_ini->dot11Mode;
    eCsrBand curr_band = eCSR_BAND_ALL;

    old_phymode = sme_GetPhyMode(hal);

    if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
        sme_GetCBPhyStateFromCBIniValue(
                                   phddctx->cfg_ini->nChannelBondingMode24GHz))
            ch_bond24 = VOS_TRUE;

    if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
        sme_GetCBPhyStateFromCBIniValue(
                                    phddctx->cfg_ini->nChannelBondingMode5GHz))
            ch_bond5g = VOS_TRUE;

    if (phddctx->cfg_ini->nBandCapability == eCSR_BAND_ALL) {
        band_24 = band_5g = VOS_TRUE;
    } else if (phddctx->cfg_ini->nBandCapability == eCSR_BAND_24) {
        band_24 = VOS_TRUE;
    } else if (phddctx->cfg_ini->nBandCapability == eCSR_BAND_5G) {
        band_5g = VOS_TRUE;
    }

    vhtchanwidth = phddctx->cfg_ini->vhtChannelWidth;
    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, ("ch_bond24=%d "
              "ch_bond5g=%d band_24=%d band_5g=%d VHT_ch_width=%u"), ch_bond24,
              ch_bond5g, band_24, band_5g, vhtchanwidth);

    switch (new_phymode) {
    case IEEE80211_MODE_AUTO:
         sme_SetPhyMode(hal, eCSR_DOT11_MODE_AUTO);
         if ((hdd_setBand(net, WLAN_HDD_UI_BAND_AUTO) == 0)) {
             phymode = eCSR_DOT11_MODE_AUTO;
             hdd_dot11mode = eHDD_DOT11_MODE_AUTO;
             chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
             curr_band = eCSR_BAND_ALL;
             vhtchanwidth = eHT_CHANNEL_WIDTH_80MHZ;
         } else {
             sme_SetPhyMode(hal, old_phymode);
             return -EIO;
         }
         break;
    case IEEE80211_MODE_11A:
         sme_SetPhyMode(hal, eCSR_DOT11_MODE_11a);
         if ((hdd_setBand(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
             phymode = eCSR_DOT11_MODE_11a;
             hdd_dot11mode = eHDD_DOT11_MODE_11a;
             chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
             curr_band = eCSR_BAND_5G;
         } else {
             sme_SetPhyMode(hal, old_phymode);
             return -EIO;
         }
         break;
    case IEEE80211_MODE_11B:
         sme_SetPhyMode(hal, eCSR_DOT11_MODE_11b);
         if ((hdd_setBand(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
             phymode = eCSR_DOT11_MODE_11b;
             hdd_dot11mode = eHDD_DOT11_MODE_11b;
             chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
             curr_band = eCSR_BAND_24;
         } else {
             sme_SetPhyMode(hal, old_phymode);
             return -EIO;
         }
         break;
    case IEEE80211_MODE_11G:
         sme_SetPhyMode(hal, eCSR_DOT11_MODE_11g);
         if ((hdd_setBand(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
             phymode = eCSR_DOT11_MODE_11g;
             hdd_dot11mode = eHDD_DOT11_MODE_11g;
             chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
             curr_band = eCSR_BAND_24;
         } else {
              sme_SetPhyMode(hal, old_phymode);
              return -EIO;
         }
         break;
    /*
     * UMAC doesn't have option to set MODE_11NA/MODE_11NG as phymode
     * so setting phymode as eCSR_DOT11_MODE_11n and updating the band
     * and channel bonding in configuration to reflect MODE_11NA/MODE_11NG
     */
    case IEEE80211_MODE_11NA_HT20:
         sme_SetPhyMode(hal, eCSR_DOT11_MODE_11n);
         if ((hdd_setBand(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
             phymode = eCSR_DOT11_MODE_11n;
             hdd_dot11mode = eHDD_DOT11_MODE_11n;
             chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
             curr_band = eCSR_BAND_5G;
         } else {
             sme_SetPhyMode(hal, old_phymode);
             return -EIO;
         }
         break;
    case IEEE80211_MODE_11NA_HT40:
         sme_SetPhyMode(hal, eCSR_DOT11_MODE_11n);
         if ((hdd_setBand(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
             phymode = eCSR_DOT11_MODE_11n;
             hdd_dot11mode = eHDD_DOT11_MODE_11n;
             chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
             curr_band = eCSR_BAND_5G;
         } else {
             sme_SetPhyMode(hal, old_phymode);
             return -EIO;
         }
         break;
    case IEEE80211_MODE_11NG_HT20:
         sme_SetPhyMode(hal, eCSR_DOT11_MODE_11n);
         if ((hdd_setBand(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
             phymode = eCSR_DOT11_MODE_11n;
             hdd_dot11mode = eHDD_DOT11_MODE_11n;
             chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
             curr_band = eCSR_BAND_24;
         } else {
             sme_SetPhyMode(hal, old_phymode);
             return -EIO;
         }
         break;
    case IEEE80211_MODE_11NG_HT40:
         sme_SetPhyMode(hal, eCSR_DOT11_MODE_11n);
         if ((hdd_setBand(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
             phymode = eCSR_DOT11_MODE_11n;
             hdd_dot11mode = eHDD_DOT11_MODE_11n;
             chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
             curr_band = eCSR_BAND_24;
         } else {
             sme_SetPhyMode(hal, old_phymode);
             return -EIO;
         }
         break;
#ifdef WLAN_FEATURE_11AC
    case IEEE80211_MODE_11AC_VHT20:
    case IEEE80211_MODE_11AC_VHT40:
    case IEEE80211_MODE_11AC_VHT80:
         sme_SetPhyMode(hal, eCSR_DOT11_MODE_11ac);
         if ((hdd_setBand(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
             phymode = eCSR_DOT11_MODE_11ac;
             hdd_dot11mode = eHDD_DOT11_MODE_11ac;
             chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
             curr_band = eCSR_BAND_5G;
         } else {
             sme_SetPhyMode(hal, old_phymode);
             return -EIO;
         }
         break;
#endif
    case IEEE80211_MODE_2G_AUTO:
         sme_SetPhyMode(hal, eCSR_DOT11_MODE_AUTO);
         if ((hdd_setBand(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
             phymode = eCSR_DOT11_MODE_AUTO;
             hdd_dot11mode = eHDD_DOT11_MODE_AUTO;
             chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
             curr_band = eCSR_BAND_24;
         } else {
             sme_SetPhyMode(hal, old_phymode);
             return -EIO;
         }
         break;
    case IEEE80211_MODE_5G_AUTO:
         sme_SetPhyMode(hal, eCSR_DOT11_MODE_AUTO);
         if ((hdd_setBand(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
             phymode = eCSR_DOT11_MODE_AUTO;
             hdd_dot11mode = eHDD_DOT11_MODE_AUTO;
             chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
             vhtchanwidth = eHT_CHANNEL_WIDTH_80MHZ;
             curr_band = eCSR_BAND_5G;
         } else {
             sme_SetPhyMode(hal, old_phymode);
             return -EIO;
         }
         break;
    case IEEE80211_MODE_11AGN:
         sme_SetPhyMode(hal, eCSR_DOT11_MODE_11n);
         if ((hdd_setBand(net, WLAN_HDD_UI_BAND_AUTO) == 0)) {
             phymode = eCSR_DOT11_MODE_11n;
             hdd_dot11mode = eHDD_DOT11_MODE_11n;
             chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
             curr_band = eCSR_BAND_ALL;
         } else {
             sme_SetPhyMode(hal, old_phymode);
             return -EIO;
         }
         break;
     default:
         return -EIO;
    }

#ifdef WLAN_FEATURE_11AC
    switch (new_phymode) {
    case IEEE80211_MODE_11AC_VHT20:
        chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
        vhtchanwidth = eHT_CHANNEL_WIDTH_20MHZ;
        break;
    case IEEE80211_MODE_11AC_VHT40:
        vhtchanwidth = eHT_CHANNEL_WIDTH_40MHZ;
        break;
    case IEEE80211_MODE_11AC_VHT80:
        vhtchanwidth = eHT_CHANNEL_WIDTH_80MHZ;
        break;
    default:
        vhtchanwidth = phddctx->cfg_ini->vhtChannelWidth;
        break;
    }
#endif

    if (phymode != -EIO) {
        sme_GetConfigParam(hal, &smeconfig);

        smeconfig.csrConfig.phyMode = phymode;
#ifdef QCA_HT_2040_COEX
        if (phymode == eCSR_DOT11_MODE_11n &&
                             chwidth == WNI_CFG_CHANNEL_BONDING_MODE_DISABLE) {
            smeconfig.csrConfig.obssEnabled = eANI_BOOLEAN_FALSE;
            halStatus = sme_SetHT2040Mode(hal, pAdapter->sessionId,
                                      eHT_CHAN_HT20, eANI_BOOLEAN_FALSE);
            if (halStatus == eHAL_STATUS_FAILURE) {
                hddLog(LOGE, FL("Failed to disable OBSS"));
                return -EIO;
            }
        } else if (phymode == eCSR_DOT11_MODE_11n &&
                              chwidth == WNI_CFG_CHANNEL_BONDING_MODE_ENABLE) {
            smeconfig.csrConfig.obssEnabled = eANI_BOOLEAN_TRUE;
            halStatus = sme_SetHT2040Mode(hal, pAdapter->sessionId,
                                      eHT_CHAN_HT20, eANI_BOOLEAN_TRUE);
            if (halStatus == eHAL_STATUS_FAILURE) {
                hddLog(LOGE, FL("Failed to enable OBSS"));
                return -EIO;
            }
        }
#endif
        smeconfig.csrConfig.eBand = curr_band;
        smeconfig.csrConfig.bandCapability = curr_band;
        if (curr_band == eCSR_BAND_24)
            smeconfig.csrConfig.Is11hSupportEnabled = 0;
        else
            smeconfig.csrConfig.Is11hSupportEnabled =
                                    phddctx->cfg_ini->Is11hSupportEnabled;
        if (curr_band == eCSR_BAND_24)
            smeconfig.csrConfig.channelBondingMode24GHz = chwidth;
        else if (curr_band == eCSR_BAND_24)
            smeconfig.csrConfig.channelBondingMode5GHz = chwidth;
        else {
            smeconfig.csrConfig.channelBondingMode24GHz = chwidth;
            smeconfig.csrConfig.channelBondingMode5GHz = chwidth;
        }

#ifdef WLAN_FEATURE_11AC
        smeconfig.csrConfig.nVhtChannelWidth = vhtchanwidth;
#endif
        sme_UpdateConfig(hal, &smeconfig);
        phddctx->cfg_ini->dot11Mode = hdd_dot11mode;
        phddctx->cfg_ini->nBandCapability = curr_band;
        phddctx->cfg_ini->nChannelBondingMode24GHz =
                                     smeconfig.csrConfig.channelBondingMode24GHz;
        phddctx->cfg_ini->nChannelBondingMode5GHz =
                                     smeconfig.csrConfig.channelBondingMode5GHz;
        phddctx->cfg_ini->vhtChannelWidth = vhtchanwidth;
        if (hdd_update_config_dat(phddctx) == VOS_FALSE) {
            VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                       "%s: could not update config_dat", __func__ );
            return -EIO;
        }

        if (phddctx->cfg_ini->nChannelBondingMode5GHz)
            phddctx->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap.cap |=
                                              IEEE80211_HT_CAP_SUP_WIDTH_20_40;
        else
            phddctx->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap.cap &=
                                              ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;


        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, ("New_Phymode= %d "
            "ch_bonding=%d band=%d VHT_ch_width=%u"),
            phymode, chwidth, curr_band, vhtchanwidth);

    }

    return 0;
}

void hdd_GetTemperatureCB(int temperature, void *cookie)
{
	struct hdd_request *request;
	struct temperature_info *priv;

	ENTER();

	request = hdd_request_get(cookie);
	if (!request) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       "%s: Obsolete request", __func__);
		return;
	}
	priv = hdd_request_priv(request);

	priv->temperature = temperature;

	hdd_request_complete(request);
	hdd_request_put(request);

	EXIT();
}

VOS_STATUS wlan_hdd_get_temperature(hdd_adapter_t *adapter_ptr,
        union iwreq_data *wrqu, char *extra)
{
	eHalStatus hstatus;
	int ret;
	A_INT32 *data_ptr = (A_INT32 *)extra;
	void *cookie;
	struct hdd_request *request;
	struct temperature_info *priv;
	static const struct hdd_request_params params = {
		.priv_size = sizeof(*priv),
		.timeout_ms = WLAN_WAIT_TIME_STATS,
	};

	ENTER();

	if (NULL == adapter_ptr)
	{
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       FL("pAdapter is NULL"));
		return VOS_STATUS_E_FAULT;
	}

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

	/* send get temperature request to sme */
	hstatus =
		sme_GetTemperature(WLAN_HDD_GET_HAL_CTX(adapter_ptr),
				   cookie,
				   hdd_GetTemperatureCB);

	if (eHAL_STATUS_SUCCESS != hstatus) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       FL("Unable to retrieve temperature"));
	} else {
		/* request was sent -- wait for the response */
		ret = hdd_request_wait_for_response(request);
		if (ret) {
			hddLog(VOS_TRACE_LEVEL_WARN,
			       FL("timeout when get temperature"));
			/* we'll returned a cached value below */
		} else {
			/* update the adapter with the fresh results */
			priv = hdd_request_priv(request);
			/* ignore it if this was 0 */
			if (priv->temperature != 0)
				adapter_ptr->temperature =
						 priv->temperature;
		}
	}
	/*
	* either we never sent a request, we sent a request and
	* received a response or we sent a request and timed out.
	* regardless we are done with the request.
	*/
	hdd_request_put(request);

	/* update temperature */
	*data_ptr = adapter_ptr->temperature;

	EXIT();
	return VOS_STATUS_SUCCESS;
}

/**
 * wlan_hdd_mnt_filter_type_cmd() - set filter packet type
 * configuration to firmware
 * @data: pointer to filter type configuration data.
 * @data_len: the length in byte of filter type data.
 *
 * This is called when wlan driver needs to set
 * filter packet type to firmware in monitor mode.
 *
 * Return: An error code or 0 on success.
 */
static int wlan_hdd_mnt_filter_type_cmd(hdd_adapter_t *pAdapter,
                                        v_U32_t *data,
                                        int data_len)
{
    hdd_context_t *pHddCtx = NULL;
    v_CONTEXT_t pVosContext = NULL;
    struct sme_mnt_filter_type_req  filter_type;
    VOS_STATUS status;
    int ret_val = -EIO;

    /* Get the Global VOSS Context */
    pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
    if (!pVosContext) {
        hddLog(VOS_TRACE_LEVEL_FATAL,"%s: VOS context is Null", __func__);
        return ret_val;
    }

    /* Get the HDD context */
    pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
    if (!pHddCtx) {
        hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
        return ret_val;
    }

    filter_type.vdev_id = pAdapter->sessionId;
    filter_type.request_data_len = data_len;
    filter_type.request_data = data;

    status = sme_mnt_filter_type_cmd(&filter_type);
    if (VOS_STATUS_SUCCESS == status) {
        ret_val = 0;
    }
    return ret_val;
}

/* set param sub-ioctls */
static int __iw_setint_getnone(struct net_device *dev,
                               struct iw_request_info *info,
                               union iwreq_data *wrqu,
                               char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    hdd_wext_state_t  *pWextState =  WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    hdd_context_t     *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    tSmeConfigParams smeConfig;
    int *value = (int *)extra;
    int sub_cmd = value[0];
    int set_value = value[1];
    int ret;
    int enable_pbm, enable_mp;
    eHalStatus status;

#ifdef CONFIG_HAS_EARLYSUSPEND
    v_U8_t nEnableSuspendOld;
#endif

    ENTER();

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

    INIT_COMPLETION(pWextState->completion_var);
    memset(&smeConfig, 0x00, sizeof(smeConfig));


    switch(sub_cmd)
    {
        case WE_SET_11D_STATE:
        {
            if(((ENABLE_11D == set_value) || (DISABLE_11D == set_value)) &&
               (hHal)) {
                sme_GetConfigParam(hHal, &smeConfig);
                smeConfig.csrConfig.Is11dSupportEnabled = (v_BOOL_t)set_value;

                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                        ("11D state=%d!!"),
                        smeConfig.csrConfig.Is11dSupportEnabled);

                sme_UpdateConfig(hHal, &smeConfig);
            }
            else {
               return -EINVAL;
            }
            break;
        }

        case WE_WOWL:
        {
           switch (set_value)
           {
              case 0x00:
                 hdd_exit_wowl(pAdapter);
                 break;
              case 0x01:
              case 0x02:
              case 0x03:
                 enable_mp =  (set_value & 0x01) ? 1 : 0;
                 enable_pbm = (set_value & 0x02) ? 1 : 0;
                 hddLog(LOGE, "magic packet ? = %s pattern byte matching ? = %s",
                     (enable_mp ? "YES":"NO"), (enable_pbm ? "YES":"NO"));
                 hdd_enter_wowl(pAdapter, enable_mp, enable_pbm);
                 break;
              default:
                 hddLog(LOGE, "Invalid arg  %d in WE_WOWL IOCTL", set_value);
                 ret = -EINVAL;
                 break;
           }

           break;
        }
        case WE_SET_POWER:
        {
           switch (set_value)
           {
              case  0: //Full Power
              {
                 struct hdd_request *request;
                 void *cookie;
                 static const struct hdd_request_params params = {
                    .priv_size = 0,
                    .timeout_ms = WLAN_WAIT_TIME_POWER,
                 };
                 eHalStatus status = eHAL_STATUS_FAILURE;

                 if (NULL == hHal)
                    return -EINVAL;

                 request = hdd_request_alloc(&params);
                 if (!request) {
                    hddLog(VOS_TRACE_LEVEL_ERROR,
                           "%s: Request allocation failure", __func__);
                    return VOS_STATUS_E_NOMEM;
                 }

                 cookie = hdd_request_cookie(request);
                 status = sme_RequestFullPower(hHal,
                                               iw_power_callback_func, cookie,
                                               eSME_FULL_PWR_NEEDED_BY_HDD);
                 if (eHAL_STATUS_PMC_PENDING == status) {
                    if(hdd_request_wait_for_response(request))
                       hddLog(VOS_TRACE_LEVEL_ERROR,
                              FL("SME timed out while requesting full power"));
                 }
                 /*
                  * either we never sent a request, we sent a request and
                  * received a response or we sent a request and timed out.
                  * regardless we are done with the request.
                  */
                 hdd_request_put(request);
                 hddLog(LOGE, "iwpriv Full Power completed");
                 break;
              }
              case  1: //Enable BMPS
                 if (hHal)
                     sme_EnablePowerSave(hHal, ePMC_BEACON_MODE_POWER_SAVE);
                 else
                     ret = -EINVAL;
                 break;
              case  2: //Disable BMPS
                 if (hHal)
                     sme_DisablePowerSave(hHal, ePMC_BEACON_MODE_POWER_SAVE);
                 else
                     ret = -EINVAL;
                 break;
              case  3: //Request Bmps
              {
                 struct hdd_request *request;
                 void *cookie;
                 static const struct hdd_request_params params = {
                    .priv_size = 0,
                    .timeout_ms = WLAN_WAIT_TIME_POWER,
                 };
                 eHalStatus status = eHAL_STATUS_FAILURE;

                 if (NULL == hHal)
                    return -EINVAL;

                 request = hdd_request_alloc(&params);
                 if (!request) {
                    hddLog(VOS_TRACE_LEVEL_ERROR,
                           "%s: Request allocation failure", __func__);
                    return VOS_STATUS_E_NOMEM;
                 }

                 cookie = hdd_request_cookie(request);
                 status = sme_RequestBmps(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                          iw_power_callback_func, cookie);
                 if (eHAL_STATUS_PMC_PENDING == status) {
                    if (hdd_request_wait_for_response(request))
                       hddLog(VOS_TRACE_LEVEL_ERROR,
                              FL("SME timed out while requesting BMPS"));
                 }
                 /*
                  * either we never sent a request, we sent a request and
                  * received a response or we sent a request and timed out.
                  * regardless we are done with the request.
                  */
                 hdd_request_put(request);
                 hddLog(LOGE, "iwpriv Request BMPS completed");
                 break;
              }
              case  4: //Enable IMPS
                 if (hHal)
                     sme_EnablePowerSave(hHal, ePMC_IDLE_MODE_POWER_SAVE);
                 else
                     ret = -EINVAL;
                 break;
              case  5: //Disable IMPS
                 if (hHal)
                     sme_DisablePowerSave(hHal, ePMC_IDLE_MODE_POWER_SAVE);
                 else
                     ret = -EINVAL;
                 break;
              case  6: //Enable Standby
                 if (hHal)
                     sme_EnablePowerSave(hHal, ePMC_STANDBY_MODE_POWER_SAVE);
                 else
                     ret = -EINVAL;
                 break;
              case  7: //Disable Standby
                 if (hHal)
                     sme_DisablePowerSave(hHal, ePMC_STANDBY_MODE_POWER_SAVE);
                 else
                     ret = -EINVAL;
                 break;
              case  8: //Request Standby
#ifdef CONFIG_HAS_EARLYSUSPEND
#endif
                 break;
              case  9: //Start Auto Bmps Timer
                 if (hHal)
                     sme_StartAutoBmpsTimer(hHal);
                 else
                     ret = -EINVAL;
                 break;
              case  10://Stop Auto BMPS Timer
                 if (hHal)
                     sme_StopAutoBmpsTimer(hHal);
                 else
                     ret = -EINVAL;
                 break;
#ifdef CONFIG_HAS_EARLYSUSPEND
              case  11://suspend to standby
#ifdef CONFIG_HAS_EARLYSUSPEND
                 nEnableSuspendOld = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend;
                 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend = 1;
                 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend = nEnableSuspendOld;
#endif
                 break;
              case  12://suspend to deep sleep
#ifdef CONFIG_HAS_EARLYSUSPEND
                 nEnableSuspendOld = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend;
                 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend = 2;
                 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend = nEnableSuspendOld;
#endif
                 break;
              case  13://resume from suspend
#ifdef CONFIG_HAS_EARLYSUSPEND
#endif
                 break;
#endif
              case  14://reset wlan (power down/power up)
                 break;
              default:
                 hddLog(LOGE, "Invalid arg  %d in WE_SET_POWER IOCTL", set_value);
                 ret = -EINVAL;
                 break;
           }
           break;
        }

        case WE_SET_MAX_ASSOC:
        {
            if ((WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value) ||
                (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value) ||
                (NULL == hHal))
            {
                ret = -EINVAL;
            }
            else if ( ccmCfgSetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT,
                                   set_value, NULL, eANI_BOOLEAN_FALSE)
                      != eHAL_STATUS_SUCCESS )
            {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  FL("failed to set ini parameter, WNI_CFG_ASSOC_STA_LIMIT"));
                ret = -EIO;
            }
            break;
        }

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

        case  WE_SET_DATA_INACTIVITY_TO:
        {
           if (NULL == hHal)
               return -EINVAL;

           if  ((set_value < CFG_DATA_INACTIVITY_TIMEOUT_MIN) ||
                (set_value > CFG_DATA_INACTIVITY_TIMEOUT_MAX) ||
                (ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
                    WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT,
                    set_value,
                    NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE))
           {
               hddLog(LOGE,"Failure: Could not pass on "
                "WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT configuration info "
                "to CCM");
               ret = -EINVAL;
           }
           break;
        }
        case WE_SET_MC_RATE:
        {
            ret = wlan_hdd_set_mc_rate(pAdapter, set_value);
            break;
        }
        case WE_SET_TX_POWER:
        {
           tSirMacAddr bssid;

           if (NULL == hHal)
               return -EINVAL;
           vos_mem_copy(bssid, pHddStaCtx->conn_info.bssId, VOS_MAC_ADDR_SIZE);
           if ( sme_SetTxPower(hHal, pAdapter->sessionId, bssid,
                              pAdapter->device_mode, set_value) !=
                              eHAL_STATUS_SUCCESS )
           {
              hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting tx power failed",
                     __func__);
              return -EIO;
           }
           break;
        }
        case WE_SET_MAX_TX_POWER:
        {
           tSirMacAddr bssid;
           tSirMacAddr selfMac;

           if (NULL == hHal)
               return -EINVAL;
           hddLog(VOS_TRACE_LEVEL_INFO, "%s: Setting maximum tx power %d dBm",
                  __func__, set_value);
           vos_mem_copy(bssid, pHddStaCtx->conn_info.bssId,
                 VOS_MAC_ADDR_SIZE);
           vos_mem_copy(selfMac, pHddStaCtx->conn_info.bssId,
                 VOS_MAC_ADDR_SIZE);

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

           break;
        }
        case WE_SET_MAX_TX_POWER_2_4:
        {
           if (NULL == hHal)
               return -EINVAL;

           hddLog(VOS_TRACE_LEVEL_INFO,
                  "%s: Setting maximum tx power %d dBm for 2.4 GHz band",
                  __func__, set_value);
           if (sme_SetMaxTxPowerPerBand(eCSR_BAND_24, set_value, hHal) !=
                                        eHAL_STATUS_SUCCESS)
           {
              hddLog(VOS_TRACE_LEVEL_ERROR,
                     "%s: Setting maximum tx power failed for 2.4 GHz band",
                     __func__);
              return -EIO;
           }

           break;
        }
        case WE_SET_MAX_TX_POWER_5_0:
        {
           if (NULL == hHal)
               return -EINVAL;

           hddLog(VOS_TRACE_LEVEL_INFO,
                  "%s: Setting maximum tx power %d dBm for 5.0 GHz band",
                  __func__, set_value);
           if (sme_SetMaxTxPowerPerBand(eCSR_BAND_5G, set_value, hHal) !=
                                        eHAL_STATUS_SUCCESS)
           {
              hddLog(VOS_TRACE_LEVEL_ERROR,
                     "%s: Setting maximum tx power failed for 5.0 GHz band",
                     __func__);
              return -EIO;
           }

           break;
        }
        case WE_SET_HIGHER_DTIM_TRANSITION:
        {
            if(!((set_value == eANI_BOOLEAN_FALSE) ||
                          (set_value == eANI_BOOLEAN_TRUE)))
            {
                hddLog(LOGE, "Dynamic DTIM Incorrect data:%d", set_value);
                ret = -EINVAL;
            }
            else
            {
                if(pAdapter->higherDtimTransition != set_value)
                {
                    pAdapter->higherDtimTransition = set_value;
                    hddLog(LOG1, "%s: higherDtimTransition set to :%d", __func__, pAdapter->higherDtimTransition);
                }
            }

           break;
        }

        case WE_SET_TM_LEVEL:
        {
           if (NULL == hHal)
               return -EINVAL;
           hddLog(VOS_TRACE_LEVEL_INFO, "Set Thermal Mitigation Level %d",
                  set_value);
           (void)sme_SetThermalLevel(hHal, set_value);
           break;
        }

        case WE_SET_PHYMODE:
        {
           hdd_context_t *phddctx = WLAN_HDD_GET_CTX(pAdapter);

           if (NULL == hHal)
               return -EINVAL;
           ret = wlan_hdd_update_phymode(dev, hHal, set_value, phddctx);
           break;
        }

        case WE_SET_NSS:
        {
           hddLog(LOG1, "Set NSS = %d", set_value);
           if ((set_value > 2) || (set_value <= 0)) {
               hddLog(LOGE, "NSS greater than 2 not supported");
               ret = -EINVAL;
           } else {
               if (VOS_STATUS_SUCCESS !=
                     hdd_update_nss(WLAN_HDD_GET_CTX(pAdapter), set_value))
                   ret = -EINVAL;
           }
           break;
        }

        case WE_SET_GTX_HT_MCS:
        {
           hddLog(LOG1, "WMI_VDEV_PARAM_GTX_HT_MCS %d", set_value);
           ret = process_wma_set_command((int)pAdapter->sessionId,
                                         (int)WMI_VDEV_PARAM_GTX_HT_MCS,
                                         set_value, GTX_CMD);
           break;
        }

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

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

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

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

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

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

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

        case WE_SET_LDPC:
           ret = hdd_set_ldpc(pAdapter, set_value);
           break;

        case WE_SET_TX_STBC:
           ret = hdd_set_tx_stbc(pAdapter, set_value);
           break;

        case WE_SET_RX_STBC:
           ret = hdd_set_rx_stbc(pAdapter, set_value);
           break;

        case WE_SET_SHORT_GI:
        {
           if (NULL == hHal)
               return -EINVAL;
           hddLog(LOG1, "WMI_VDEV_PARAM_SGI val %d", set_value);
           ret = sme_UpdateHTConfig(hHal, pAdapter->sessionId,
                                   WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ,
                                   set_value);
           if (ret)
               VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                     "Failed to set ShortGI value");
           break;
        }

        case WE_SET_RTSCTS:
        {
           u_int32_t value;

           if (NULL == hHal)
               return -EINVAL;
           hddLog(LOG1, "WMI_VDEV_PARAM_ENABLE_RTSCTS val 0x%x", set_value);

           if ((set_value & HDD_RTSCTS_EN_MASK) == HDD_RTSCTS_ENABLE)
               value = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->RTSThreshold;
           else if (((set_value & HDD_RTSCTS_EN_MASK) == 0) ||
               ((set_value & HDD_RTSCTS_EN_MASK) == HDD_CTS_ENABLE))
               value = WNI_CFG_RTS_THRESHOLD_STAMAX;
           else
               return -EIO;

           ret = process_wma_set_command((int)pAdapter->sessionId,
                                         (int)WMI_VDEV_PARAM_ENABLE_RTSCTS,
                                         set_value, VDEV_CMD);
           if (!ret) {
               if (ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD, value,
                   ccmCfgSetCallback, eANI_BOOLEAN_TRUE) !=
                                                         eHAL_STATUS_SUCCESS) {
                   hddLog(LOGE, "FAILED TO SET RTSCTS");
                   return -EIO;
               }
           }

           break;
        }

        case WE_SET_CHWIDTH:
        {
           bool chwidth = false;
           hdd_context_t *phddctx = WLAN_HDD_GET_CTX(pAdapter);

           if (NULL == hHal)
               return -EINVAL;
           /*updating channel bonding only on 5Ghz*/
           hddLog(LOG1, "WMI_VDEV_PARAM_CHWIDTH val %d", set_value);
           if (set_value > eHT_CHANNEL_WIDTH_80MHZ) {
                hddLog(LOGE, "Invalid channel width 0->20 1->40 2->80");
                return -EINVAL;
           }

           if ((WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
               csrConvertCBIniValueToPhyCBState(
                       phddctx->cfg_ini->nChannelBondingMode5GHz)))
               chwidth = true;

           sme_GetConfigParam(hHal, &smeConfig);
           switch (set_value) {
           case eHT_CHANNEL_WIDTH_20MHZ:
                smeConfig.csrConfig.channelBondingMode5GHz =
                                          WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
                break;
           case eHT_CHANNEL_WIDTH_40MHZ:
                if (chwidth)
                    smeConfig.csrConfig.channelBondingMode5GHz =
                                     phddctx->cfg_ini->nChannelBondingMode5GHz;
                else
                    return -EINVAL;

                break;
#ifdef WLAN_FEATURE_11AC
           case eHT_CHANNEL_WIDTH_80MHZ:
                if (chwidth)
                    smeConfig.csrConfig.channelBondingMode5GHz =
                                     phddctx->cfg_ini->nChannelBondingMode5GHz;
                else
                    return -EINVAL;

                break;
#endif

           default:
                return -EINVAL;
           }

           ret = process_wma_set_command((int)pAdapter->sessionId,
                                         (int)WMI_VDEV_PARAM_CHWIDTH,
                                         set_value, VDEV_CMD);
           if (!ret)
               sme_UpdateConfig(hHal, &smeConfig);

           break;
        }

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

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

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

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

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

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

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

        case WE_SET_11N_RATE:
        {
           u_int8_t preamble = 0, nss = 0, rix = 0;
           hddLog(LOG1, "WMI_VDEV_PARAM_FIXED_RATE val %d", set_value);

           if (set_value != 0xff) {
               rix = RC_2_RATE_IDX(set_value);
               if (set_value & 0x80) {
                   preamble = WMI_RATE_PREAMBLE_HT;
                   nss = HT_RC_2_STREAMS(set_value) -1;
               } else {
                   nss = 0;
                   rix = RC_2_RATE_IDX(set_value);
                   if (set_value & 0x10) {
                       preamble = WMI_RATE_PREAMBLE_CCK;
                       /* Enable Short preamble always for CCK except 1mbps */
                       if(rix != 0x3)
                           rix |= 0x4;
                   } else
                       preamble = WMI_RATE_PREAMBLE_OFDM;
               }
               set_value = (preamble << 6) | (nss << 4) | rix;
           }
           hddLog(LOG1,
                  "WMI_VDEV_PARAM_FIXED_RATE val %d rix %d preamble %x nss %d",
                  set_value, rix, preamble, nss);

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

        case WE_SET_VHT_RATE:
        {
           u_int8_t preamble = 0, nss = 0, rix = 0;

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

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

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

         case WE_SET_AMSDU:
         {
            hddLog(LOG1, "SET AMSDU val %d", set_value);
            ret = process_wma_set_command((int)pAdapter->sessionId,
                                          (int)GEN_VDEV_PARAM_AMSDU,
                                          set_value, GEN_CMD);
            if (!ret) {
                /* Update the stored ini value */
                pHddCtx->cfg_ini->max_amsdu_num = set_value;
            }
            break;
         }

         case WE_SET_BURST_ENABLE:
         {
            hddLog(LOG1, "SET Burst enable val %d", set_value);
            if ((set_value == 0) || (set_value == 1)) {
                ret = process_wma_set_command((int)pAdapter->sessionId,
                                          (int)WMI_PDEV_PARAM_BURST_ENABLE,
                                          set_value, PDEV_CMD);
            }
            else
                ret = -EINVAL;
            break;
         }
         case WE_SET_BURST_DUR:
         {
            hddLog(LOG1, "SET Burst duration val %d", set_value);
            if ((set_value > 0) && (set_value <= 8192)) {
                ret = process_wma_set_command((int)pAdapter->sessionId,
                                          (int)WMI_PDEV_PARAM_BURST_DUR,
                                          set_value, PDEV_CMD);
            }
            else
                ret = -EINVAL;
            break;
         }

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

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

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

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

         /* Firmware debug log */
         case WE_DBGLOG_LOG_LEVEL:
         {
              hddLog(LOG1, "WE_DBGLOG_LOG_LEVEL val %d", set_value);
              pHddCtx->fw_log_settings.dl_loglevel = set_value;
              ret = process_wma_set_command((int)pAdapter->sessionId,
                                           (int)WMI_DBGLOG_LOG_LEVEL,
                                           set_value, DBG_CMD);
              break;
         }

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

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

         case WE_DBGLOG_MODULE_ENABLE:
         {
              hddLog(LOG1, "WE_DBGLOG_MODULE_ENABLE val %d", set_value);
              pHddCtx->fw_log_settings.enable = set_value;
              ret = process_wma_set_command((int)pAdapter->sessionId,
                                           (int)WMI_DBGLOG_MODULE_ENABLE,
                                           set_value, DBG_CMD);
              break;
         }

         case WE_DBGLOG_MODULE_DISABLE:
         {
              hddLog(LOG1, "WE_DBGLOG_MODULE_DISABLE val %d", set_value);
              pHddCtx->fw_log_settings.enable = set_value;
              ret = process_wma_set_command((int)pAdapter->sessionId,
                                           (int)WMI_DBGLOG_MODULE_DISABLE,
                                           set_value, DBG_CMD);
              break;
         }
         case WE_DBGLOG_MOD_LOG_LEVEL:
         {
              hddLog(LOG1, "WE_DBGLOG_MOD_LOG_LEVEL val %d", set_value);

              if (pHddCtx->fw_log_settings.index >= MAX_MOD_LOGLEVEL) {
                 pHddCtx->fw_log_settings.index = 0;
              }

              pHddCtx->fw_log_settings.dl_mod_loglevel[pHddCtx->
                                        fw_log_settings.index] = set_value;
              pHddCtx->fw_log_settings.index++;

              ret = process_wma_set_command((int)pAdapter->sessionId,
                                           (int)WMI_DBGLOG_MOD_LOG_LEVEL,
                                            set_value, DBG_CMD);
              break;
         }

         case WE_DBGLOG_TYPE:
         {
              hddLog(LOG1, "WE_DBGLOG_TYPE val %d", set_value);
              pHddCtx->fw_log_settings.dl_type = set_value;
              ret = process_wma_set_command((int)pAdapter->sessionId,
                                           (int)WMI_DBGLOG_TYPE,
                                           set_value, DBG_CMD);
              break;
         }
        case WE_DBGLOG_REPORT_ENABLE:
        {
             hddLog(LOG1, "WE_DBGLOG_REPORT_ENABLE val %d", set_value);
             pHddCtx->fw_log_settings.dl_report = set_value;
             ret = process_wma_set_command((int)pAdapter->sessionId,
                                          (int)WMI_DBGLOG_REPORT_ENABLE,
                                          set_value, DBG_CMD);
             break;
        }

    case WE_SET_TXRX_FWSTATS:
    {
           hddLog(LOG1, "WE_SET_TXRX_FWSTATS val %d", set_value);
           ret = process_wma_set_command((int)pAdapter->sessionId,
               (int)WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID,
               set_value, VDEV_CMD);
       break;
    }

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

    case WE_DUMP_STATS:
    {
         hddLog(LOG1, "WE_DUMP_STATS val %d", set_value);
         hdd_wlan_dump_stats(pAdapter, set_value);
         break;
    }

    case WE_CLEAR_STATS:
    {
         hdd_context_t* hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);

         hddLog(LOG1, "WE_CLEAR_STATS val %d", set_value);
         switch (set_value)
         {
             case WLAN_HDD_STATS:
                 memset(&pAdapter->stats, 0, sizeof(pAdapter->stats));
                 memset(&pAdapter->hdd_stats, 0, sizeof(pAdapter->hdd_stats));
                 break;
             case WLAN_TXRX_HIST_STATS:
                 wlan_hdd_clear_tx_rx_histogram(pHddCtx);
                 break;
             case WLAN_HDD_NETIF_OPER_HISTORY:
                 wlan_hdd_clear_netif_queue_history(hdd_ctx);
                 break;
             default:
                 WLANTL_clear_datapath_stats(hdd_ctx->pvosContext, set_value);
                 break;
         }
         break;
    }

    case WE_PPS_PAID_MATCH:
        {
           if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
              return EINVAL;

           hddLog(LOG1, "WMI_VDEV_PPS_PAID_MATCH val %d ", set_value);
           ret = process_wma_set_command((int)pAdapter->sessionId,
                           (int)WMI_VDEV_PPS_PAID_MATCH,
                           set_value, PPS_CMD);
           break;
        }

    case WE_PPS_GID_MATCH:
    {
       if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
        return EINVAL;
       hddLog(LOG1, "WMI_VDEV_PPS_GID_MATCH val %d ", set_value);
           ret = process_wma_set_command((int)pAdapter->sessionId,
                           (int)WMI_VDEV_PPS_GID_MATCH,
                           set_value, PPS_CMD);
           break;
        }

    case WE_PPS_EARLY_TIM_CLEAR:
    {
           if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
               return EINVAL;
           hddLog(LOG1, " WMI_VDEV_PPS_EARLY_TIM_CLEAR val %d ", set_value);
           ret = process_wma_set_command((int)pAdapter->sessionId,
                           (int)WMI_VDEV_PPS_EARLY_TIM_CLEAR,
                           set_value, PPS_CMD);
           break;
        }

    case WE_PPS_EARLY_DTIM_CLEAR:
        {
           if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
              return EINVAL;
           hddLog(LOG1, "WMI_VDEV_PPS_EARLY_DTIM_CLEAR val %d", set_value);
           ret = process_wma_set_command((int)pAdapter->sessionId,
                           (int)WMI_VDEV_PPS_EARLY_DTIM_CLEAR,
                           set_value, PPS_CMD);
           break;
        }

    case WE_PPS_EOF_PAD_DELIM:
        {
           if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
               return EINVAL;
           hddLog(LOG1, "WMI_VDEV_PPS_EOF_PAD_DELIM val %d ", set_value);
           ret = process_wma_set_command((int)pAdapter->sessionId,
                           (int)WMI_VDEV_PPS_EOF_PAD_DELIM,
                           set_value, PPS_CMD);
           break;
        }

    case WE_PPS_MACADDR_MISMATCH:
        {
           if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
              return EINVAL;
           hddLog(LOG1, "WMI_VDEV_PPS_MACADDR_MISMATCH val %d ", set_value);
           ret = process_wma_set_command((int)pAdapter->sessionId,
                           (int)WMI_VDEV_PPS_MACADDR_MISMATCH,
                           set_value, PPS_CMD);
           break;
        }

    case WE_PPS_DELIM_CRC_FAIL:
        {
           if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
              return EINVAL;
           hddLog(LOG1, "WMI_VDEV_PPS_DELIM_CRC_FAIL val %d ", set_value);
           ret = process_wma_set_command((int)pAdapter->sessionId,
                           (int)WMI_VDEV_PPS_DELIM_CRC_FAIL,
                           set_value, PPS_CMD);
           break;
        }


    case WE_PPS_GID_NSTS_ZERO:
        {
           if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
               return EINVAL;
           hddLog(LOG1, "WMI_VDEV_PPS_GID_NSTS_ZERO val %d ", set_value);
           ret = process_wma_set_command((int)pAdapter->sessionId,
                           (int)WMI_VDEV_PPS_GID_NSTS_ZERO,
                           set_value, PPS_CMD);
           break;
        }


    case WE_PPS_RSSI_CHECK:
        {
           if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
               return EINVAL;
           hddLog(LOG1, "WMI_VDEV_PPS_RSSI_CHECK val %d ", set_value);
           ret = process_wma_set_command((int)pAdapter->sessionId,
                           (int)WMI_VDEV_PPS_RSSI_CHECK,
                           set_value, PPS_CMD);
           break;
        }

        case WE_PPS_5G_EBT:
        {
           if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
              return -EINVAL;

           hddLog(LOG1, "WMI_VDEV_PPS_5G_EBT val %d", set_value);
           ret = process_wma_set_command((int)pAdapter->sessionId,
                           (int)WMI_VDEV_PPS_5G_EBT,
                           set_value, PPS_CMD);
           break;
        }

        case WE_SET_HTSMPS:
        {
            hddLog(LOG1, "WE_SET_HTSMPS val %d", set_value);
            ret = process_wma_set_command((int)pAdapter->sessionId,
                            (int)WMI_STA_SMPS_FORCE_MODE_CMDID,
                             set_value, VDEV_CMD);
            break;
        }


        case WE_SET_QPOWER_MAX_PSPOLL_COUNT:
        {
               hddLog(LOG1, "WE_SET_QPOWER_MAX_PSPOLL_COUNT val %d",
                      set_value);
           ret = process_wma_set_command((int)pAdapter->sessionId,
                                 (int)WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT,
                                 set_value, QPOWER_CMD);
               break;
        }

        case WE_SET_QPOWER_MAX_TX_BEFORE_WAKE:
        {
           hddLog(LOG1, "WE_SET_QPOWER_MAX_TX_BEFORE_WAKE val %d",
                  set_value);
           ret = process_wma_set_command((int)pAdapter->sessionId,
                         (int)WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE,
                         set_value, QPOWER_CMD);
           break;
        }

        case WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL:
        {
           hddLog(LOG1, "WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL val %d",
                  set_value);
           ret = process_wma_set_command((int)pAdapter->sessionId,
                        (int)WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
                        set_value, QPOWER_CMD);
           break;
        }

        case WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL:
        {
           hddLog(LOG1, "WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL val %d",
                  set_value);
           ret = process_wma_set_command((int)pAdapter->sessionId,
                      (int)WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
                      set_value, QPOWER_CMD);
           break;
        }
        case WE_SET_SCAN_BAND_PREFERENCE:
        {
           if((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) ||
              (NULL == hHal)) {
               ret = -EINVAL;
               break;
           }
           hddLog(LOG1, "WE_SET_BAND_PREFERRENCE val %d ", set_value);

           if (eCSR_BAND_ALL == set_value ||
                  eCSR_BAND_24 == set_value || eCSR_BAND_5G == set_value) {
               sme_GetConfigParam(hHal, &smeConfig);
               smeConfig.csrConfig.scanBandPreference = set_value;

               VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                         "set band scan preference = %d",
                         smeConfig.csrConfig.scanBandPreference);

               sme_UpdateConfig(hHal, &smeConfig);
           }
           else {
               ret = -EINVAL;
           }
           break;

        }

        case WE_MCC_CONFIG_LATENCY:
        {
            tVOS_CONCURRENCY_MODE concurrent_state = 0;
            v_U8_t first_adapter_operating_channel = 0;
            int ret = 0; /* success */

            hddLog(LOG1, "iwpriv cmd to set MCC latency with val %dms",
                    set_value);
            /**
             * Check if concurrency mode is active.
             * Need to modify this code to support MCC modes other than STA/P2P
             */
            concurrent_state = hdd_get_concurrency_mode();
            if ((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
                (concurrent_state == (VOS_STA | VOS_P2P_GO)))
            {
                hddLog(LOG1, "STA & P2P are both enabled");
                /**
                 * The channel number and latency are formatted in
                 * a bit vector then passed on to WMA layer.
                 +**********************************************+
                 |bits 31-16 |      bits 15-8    |  bits 7-0    |
                 |  Unused   | latency - Chan. 1 |  channel no. |
                 +**********************************************+
                 */
                /* Get the operating channel of the designated vdev */
                first_adapter_operating_channel =
                            hdd_get_operating_channel
                            (
                                pAdapter->pHddCtx,
                                pAdapter->device_mode
                            );
                /* Move the time latency for the adapter to bits 15-8 */
                set_value = set_value << 8;
                /* Store the channel number at bits 7-0 of the bit vector */
                set_value = set_value | first_adapter_operating_channel;
                /* Send command to WMA */
                ret = process_wma_set_command((int)pAdapter->sessionId,
                        (int)WMA_VDEV_MCC_SET_TIME_LATENCY,
                        set_value, VDEV_CMD);
            }
            else
            {
                hddLog(LOG1, "%s: MCC is not active. Exit w/o setting latency",
                       __func__);
            }
            break;
        }

        case WE_MCC_CONFIG_QUOTA:
        {

            hddLog(LOG1, "iwpriv cmd to set MCC quota with val %dms",
                set_value);
            ret = hdd_wlan_set_mcc_p2p_quota(pAdapter, set_value);
            break;
        }
       case WE_SET_DEBUG_LOG:
       {
           hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
           if (NULL == hHal)
               return -EINVAL;
#ifdef QCA_PKT_PROTO_TRACE
           /* Trace buffer dump only */
           if (VOS_PKT_TRAC_DUMP_CMD == set_value)
           {
              vos_pkt_trace_buf_dump();
              break;
           }
#endif /* QCA_PKT_PROTO_TRACE */
           pHddCtx->cfg_ini->gEnableDebugLog = set_value;
           sme_UpdateConnectDebug(pHddCtx->hHal, set_value);
           break;
       }
       case WE_SET_EARLY_RX_ADJUST_ENABLE:
       {
            hddLog(LOG1, "SET early_rx enable val %d", set_value);
            if ((set_value == 0) || (set_value == 1)) {
                 ret = process_wma_set_command((int)pAdapter->sessionId,
                                (int)WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE,
                                set_value, VDEV_CMD);
            }
            else
              ret = -EINVAL;
            break;
       }
       case WE_SET_EARLY_RX_TGT_BMISS_NUM:
       {
            hddLog(LOG1, "SET early_rx bmiss val %d", set_value);
            ret = process_wma_set_command((int)pAdapter->sessionId,
                            (int)WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM,
                            set_value, VDEV_CMD);
            break;
       }
       case WE_SET_EARLY_RX_BMISS_SAMPLE_CYCLE:
       {
            hddLog(LOG1, "SET early_rx bmiss sample cycle %d", set_value);
            ret = process_wma_set_command((int)pAdapter->sessionId,
                            (int)WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE,
                            set_value, VDEV_CMD);
            break;
       }
       case WE_SET_EARLY_RX_SLOP_STEP:
       {
            hddLog(LOG1, "SET early_rx bmiss slop step val %d", set_value);
            ret = process_wma_set_command((int)pAdapter->sessionId,
                            (int)WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP,
                            set_value, VDEV_CMD);
            break;
       }
       case WE_SET_EARLY_RX_INIT_SLOP:
       {
            hddLog(LOG1, "SET early_rx init slop step val %d", set_value);
            ret = process_wma_set_command((int)pAdapter->sessionId,
                            (int)WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP,
                            set_value, VDEV_CMD);
            break;
       }
       case WE_SET_EARLY_RX_ADJUST_PAUSE:
       {
            hddLog(LOG1, "SET early_rx adjust pause %d", set_value);
            if ((set_value == 0) || (set_value == 1)) {
                 ret = process_wma_set_command((int)pAdapter->sessionId,
                                (int)WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE,
                                set_value, VDEV_CMD);
            }
            else
              ret = -EINVAL;
            break;
       }
       case WE_SET_EARLY_RX_DRIFT_SAMPLE:
       {
            hddLog(LOG1, "SET early_rx drift sample %d", set_value);
            ret = process_wma_set_command((int)pAdapter->sessionId,
                            (int)WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE,
                            set_value, VDEV_CMD);
            break;
       }
       case WE_SET_CHANNEL:
       {
          hddLog(LOG1, "Set Channel %d Session ID %d mode = %d", set_value,
                     pAdapter->sessionId, pAdapter->device_mode);

          if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
              (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
              (NULL == hHal)) {

               status = sme_ext_change_channel(pHddCtx->hHal,
                              set_value, pAdapter->sessionId);

               if (status != eHAL_STATUS_SUCCESS)
                   ret = -EINVAL;
          } else {
               ret = -EINVAL;
          }
          break;
        }
#ifdef FEATURE_PBM_MAGIC_WOW
        case WE_SET_WOW_START:
        {
            if ((set_value != 1) && (set_value != 0)) {
                hddLog(LOGE, "Invalid value %d set wow_start", set_value);
                return -EINVAL;
            }
            if (set_value)
                hdd_start_wow_nonos(pAdapter);
	    else
                hdd_stop_wow_nonos(pAdapter);
	    break;
        }
#endif
        case WE_SET_MODULATED_DTIM:
        {
            if ((set_value < CFG_ENABLE_MODULATED_DTIM_MIN) ||
                (set_value > CFG_ENABLE_MODULATED_DTIM_MAX)) {
                hddLog(LOGE, FL("Invalid value %d in gEnableModuleDTIM"),
                             set_value);
                return -EINVAL;
            } else {
                ret = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->
                          enableModulatedDTIM = set_value;
            }
            break;
        }
        case WE_SET_MON_FILTER:
        {
            v_U32_t filter_type = (v_U32_t)set_value;

            if (VOS_MONITOR_MODE != hdd_get_conparam()) {
                hddLog(LOGE, "Unable to set Monitor Mode Filters");
                hddLog(LOGE, "WLAN Device is not in Monitor mode!!");
                return -EINVAL;
            }
            /*
             *filter type usage: 0-filter, 1-not filter;
             * Bit 0 : OFFLOAD_FRAME_TYPE_MGMT
             * Bit 1 : OFFLOAD_FRAME_TYPE_DATA
             * Bit 2 : OFFLOAD_FRAME_TYPE_CTRL
             * Bit 3 : OFFLOAD_FRAME_TYPE_MGMT_SUBTYPE_ASSOC_REQ
             * Bit 4 : OFFLOAD_FRAME_TYPE_MGMT_SUBTYPE_ASSOC_RES
             * Bit 5 : OFFLOAD_FRAME_TYPE_MGMT_SUBTYPE_REASSOC_REQ
             * Bit 6 : OFFLOAD_FRAME_TYPE_MGMT_SUBTYPE_REASSOC_RSP
             * Bit 7 : OFFLOAD_FRAME_TYPE_MGMT_SUBTYPE_PROBE_REQ
             * Bit 8 : OFFLOAD_FRAME_TYPE_MGMT_SUBTYPE_PROBE_RSP
             * Bit 9 : OFFLOAD_FRAME_TYPE_MGMT_SUBTYPE_BEACON
             * Bit 10 : OFFLOAD_FRAME_TYPE_MGMT_SUBTYPE_ATIM
             * Bit 11 : OFFLOAD_FRAME_TYPE_MGMT_SUBTYPE_DISASSOC
             * Bit 12 : OFFLOAD_FRAME_TYPE_MGMT_SUBTYPE_AUTH
             * Bit 13 : OFFLOAD_FRAME_TYPE_MGMT_SUBTYPE_DEAUTH
             * Bit 14 : OFFLOAD_FRAME_TYPE_MGMT_SUBTYPE_ACTION
             * Bit 15 : OFFLOAD_FRAME_TYPE_CTRL_SUBTYPE_BAR
             * Bit 16 : OFFLOAD_FRAME_TYPE_CTRL_SUBTYPE_BA
             * Bit 17 : OFFLOAD_FRAME_TYPE_CTRL_SUBTYPE_PSPOLL
             * Bit 18 : OFFLOAD_FRAME_TYPE_CTRL_SUBTYPE_RTS
             * Bit 19 : OFFLOAD_FRAME_TYPE_CTRL_SUBTYPE_CTS
             * Bit 20 : OFFLOAD_FRAME_TYPE_CTRL_SUBTYPE_ACK
             * Bit 21 : OFFLOAD_FRAME_TYPE_CTRL_SUBTYPE_CFEND
             * Bit 22 : OFFLOAD_FRAME_TYPE_CTRL_SUBTYPE_CFENDCFACK
             * Bit 23 : OFFLOAD_FRAME_TYPE_MGMT_SUBTYPE_TIMING_ADVERT
             * Bit 24 : OFFLOAD_FRAME_TYPE_MGMT_SUBTYPE_ACTION_NOACK
             * Bit 25 : OFFLOAD_FRAME_TYPE_CTRL_SUBTYPE_BRPOLL
             * Bit 26 : OFFLOAD_FRAME_TYPE_CTRL_SUBTYPE_NDPA
             * Bit 27 : OFFLOAD_FRAME_TYPE_DATA_SUBTYPE_DATA
             * Bit 28 : OFFLOAD_FRAME_TYPE_DATA_SUBTYPE_CF_POLL
             * Bit 29 : OFFLOAD_FRAME_TYPE_DATA_SUBTYPE_QOS
             * Bit 30 : OFFLOAD_FRAME_TYPE_DATA_SUBTYPE_NODATA
             * Bit 31 : OFFLOAD_FRAME_TYPE_DATA_SUBTYPE_QOS_NULL
             */
            hddLog(LOG1, "Monitor Mode Filter type  = %x", filter_type);
            wlan_hdd_mnt_filter_type_cmd(pAdapter,
                                         &filter_type,
                                         sizeof(v_U32_t));
            break;
        }
#ifdef FEATURE_WLAN_TDLS
        case WE_SET_TDLS_OFFCHANNEL_MODE:
        {
            hddLog(LOG1, "SET tdls_offchannel_mode  val %d", set_value);
            ret = hdd_set_tdls_offchannelmode(pAdapter, set_value);
            break;
        }
        case WE_SET_TDLS_OFFCHANNEL:
        {
            hddLog(LOG1, "SET tdls_offchannel val %d", set_value);

            if (VOS_IS_DFS_CH(set_value)) {
                hddLog(LOGE,
                      FL("DFS channel %d is passed for hdd_set_tdls_offchannel"),
                      set_value);
                ret = -EINVAL;
                break;
            }
            ret = hdd_set_tdls_offchannel(pHddCtx, set_value);
            break;
        }
	case WE_SET_TDLS_OFFCHANNEL_SEC_OFFSET:
        {
            hddLog(LOG1, "SET tdls_offchannel_mode  val %d", set_value);
            ret = hdd_set_tdls_secoffchanneloffset(pHddCtx, set_value);
	    break;
	}
#endif
#ifdef WLAN_FEATURE_MOTION_DETECTION
        case WE_MOTION_DET_START_STOP:
            {
                tSirMotionDetEnable enable;

                if ( (set_value != 1) && (set_value != 0)) {
                     hddLog(LOGE, FL("Invalid value %d in mt_start"),
                             set_value);
                    return -EINVAL;
                }

                enable.vdev_id = (int)pAdapter->sessionId;
                enable.enable = set_value;

		if (set_value == 0) {
			pAdapter->motion_detection_mode = 0;
		}
                sme_MotionDetEnable(hHal, &enable);
            }
            break;
        case WE_MOTION_DET_BASE_LINE_START_STOP:
            {
                tSirMotionDetBaseLineEnable enable;

                if ( (set_value != 1) && (set_value != 0)) {
                     hddLog(LOGE, FL("Invalid value %d in mt_bl_start"),
                             set_value);
                    return -EINVAL;
                }

                enable.vdev_id = (int)pAdapter->sessionId;
                enable.enable = set_value;
                sme_MotionDetBaseLineEnable(hHal, &enable);
            }
            break;
#endif
        case WE_SAP_TX_OFF:
        {
            ol_txrx_pdev_handle pdev =
                vos_get_context(VOS_MODULE_ID_TXRX, pHddCtx->pvosContext);

            pdev->cfg.sap_tx_off = set_value;
            PMAC_STRUCT(hHal)->sap_tx_off = set_value;
            break;
        }
#if !defined(WDI_API_AS_FUNCS)
        case WE_SET_TXRX_PRINT_LEVEL:
            {
                if ( (set_value < 0) || (set_value > 0xff)) {
                     hddLog(LOGE, FL("Invalid value %d in set_txrx_dbg"),
                             set_value);
                    return -EINVAL;
                }
                ret = process_wma_set_command((int)pAdapter->sessionId,
                        (int)GEN_PARAM_SET_TXRX_PRINT_LEVEL,
                        set_value, GEN_CMD);
            }
            break;
#endif
        case WE_SAP_SET_TARGET_CHANNEL:
        {
                if ((set_value < 0) || (set_value > 0xff)) {
                     hddLog(LOGE, FL("Invalid value %d in set_target_ch"),
                             set_value);
                    return -EINVAL;
                }
                if ((set_value != 0) &&
                    ((set_value < 36) || (vos_nv_getChannelEnabledState(set_value) != NV_CHANNEL_ENABLE))) {
                     hddLog(LOGE, FL("%d is not a valid non-DFS channel"),
                             set_value);
                    return -EINVAL;
                }
                PMAC_STRUCT(hHal)->target_channel = set_value;
                break;
        }

        case WE_SAP_SET_CAC_TIME:
        {
                if ( (set_value < 0) || (set_value > 0xff)) {
                     hddLog(LOGE, FL("Invalid value %d in set_cac_time"),
                             set_value);
                    return -EINVAL;
                }
                PMAC_STRUCT(hHal)->cac_time = set_value;
                break;
        }

        default:
        {
            hddLog(LOGE, "%s: Invalid sub command %d", __func__, sub_cmd);
            ret = -EINVAL;
            break;
        }
    }
    EXIT();
    return ret;
}

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

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

	return ret;
}

/* set param sub-ioctls */
static int __iw_setchar_getnone(struct net_device *dev,
                                struct iw_request_info *info,
                                union iwreq_data *wrqu, char *extra)
{
    VOS_STATUS vstatus;
    int sub_cmd;
    int ret;
    char *pBuffer = NULL;
    hdd_adapter_t *pAdapter = (netdev_priv(dev));
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
#ifdef WLAN_FEATURE_VOWIFI
    hdd_config_t  *pConfig = pHddCtx->cfg_ini;
#endif /* WLAN_FEATURE_VOWIFI */
    struct iw_point s_priv_data;

    ENTER();

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

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

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

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

    sub_cmd = s_priv_data.flags;

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

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

    switch(sub_cmd)
    {
       case WE_WOWL_ADD_PTRN:
          VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "ADD_PTRN");
          hdd_add_wowl_ptrn(pAdapter, pBuffer);
          break;
       case WE_WOWL_DEL_PTRN:
          VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "DEL_PTRN");
          hdd_del_wowl_ptrn(pAdapter, pBuffer);
          break;
#if defined WLAN_FEATURE_VOWIFI
       case WE_NEIGHBOR_REPORT_REQUEST:
          {
             tRrmNeighborReq neighborReq;
             tRrmNeighborRspCallbackInfo callbackInfo;

             if (pConfig->fRrmEnable)
             {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Neighbor Request");
                neighborReq.no_ssid = (s_priv_data.length - 1) ? false : true ;
                if( !neighborReq.no_ssid )
                {
                   neighborReq.ssid.length = (s_priv_data.length - 1) > 32 ?
                      32 : (s_priv_data.length - 1);
                   vos_mem_copy(neighborReq.ssid.ssId, pBuffer,
                                 neighborReq.ssid.length);
                }

                callbackInfo.neighborRspCallback = NULL;
                callbackInfo.neighborRspCallbackContext = NULL;
                callbackInfo.timeout = 5000;   //5 seconds
                sme_NeighborReportRequest(  WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, &neighborReq, &callbackInfo );
             }
             else
             {
                hddLog(LOGE, "%s: Ignoring neighbor request as RRM is not enabled", __func__);
                ret = -EINVAL;
             }
          }
          break;
#endif
       case WE_SET_AP_WPS_IE:
          hddLog( LOGE, "Received WE_SET_AP_WPS_IE" );
          sme_updateP2pIe(WLAN_HDD_GET_HAL_CTX(pAdapter), pBuffer,
                           s_priv_data.length);
          break;
       case WE_SET_CONFIG:
          vstatus = hdd_execute_global_config_command(pHddCtx, pBuffer);
#ifdef WLAN_FEATURE_MBSSID
          if (vstatus == VOS_STATUS_E_PERM) {
              vstatus = hdd_execute_sap_dyn_config_command(pAdapter, pBuffer);
              if (vstatus == VOS_STATUS_SUCCESS)
                  VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                             "%s: Stored in Dynamic SAP ini config", __func__);

          }
#endif
          if (VOS_STATUS_SUCCESS != vstatus)
          {
             ret = -EINVAL;
          }
          break;
       default:
       {
           hddLog(LOGE, "%s: Invalid sub command %d", __func__, sub_cmd);
           ret = -EINVAL;
           break;
       }
    }
    vos_mem_free(pBuffer);
    EXIT();
    return ret;
}

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

	hddLog(VOS_TRACE_LEVEL_INFO, FL("param = %d"), value[0]);

	switch (value[0]) {
	case WE_GET_TSF:
		ret = hdd_indicate_tsf(adapter, value, 3);
		break;
	default:
		hddLog(VOS_TRACE_LEVEL_ERROR,
			FL("Invalid IOCTL get_value command %d"),
			value[0]);
		break;
	}
	return ret;
}

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

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

	return ret;
}


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

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

	return ret;
}

/* get param sub-ioctls */
static int __iw_setnone_getint(struct net_device *dev,
                               struct iw_request_info *info,
                               union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    int *value = (int *)extra;
    int ret;
    hdd_context_t *wmahddCtxt = WLAN_HDD_GET_CTX(pAdapter);
    void *wmapvosContext = wmahddCtxt->pvosContext;
    tSmeConfigParams smeConfig;
    hdd_context_t *hdd_ctx;

    ENTER();

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

    if (VOS_STATUS_SUCCESS != sme_is_session_valid(hHal,
                               pAdapter->sessionId)) {
       hddLog(LOGE, FL("session id is not valid %d"), pAdapter->sessionId);
       return -EINVAL;
    }

    vos_mem_zero(&smeConfig, sizeof(smeConfig));

    switch (value[0])
    {
        case WE_GET_11D_STATE:
        {
           sme_GetConfigParam(hHal,&smeConfig);

           *value = smeConfig.csrConfig.Is11dSupportEnabled;

            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("11D state=%d!!"),*value);

           break;
        }

        case WE_IBSS_STATUS:
           VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "****Return IBSS Status*****");
           break;

        case WE_GET_WLAN_DBG:
        {
           vos_trace_display();
           *value = 0;
           break;
        }
        case WE_GET_MAX_ASSOC:
        {
            if (ccmCfgGetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, (tANI_U32 *)value) != eHAL_STATUS_SUCCESS)
            {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                      FL("failed to get ini parameter, WNI_CFG_ASSOC_STA_LIMIT"));
                ret = -EIO;
            }
            break;
        }
        case WE_GET_SAP_AUTO_CHANNEL_SELECTION:
            *value = (WLAN_HDD_GET_CTX(
                                   pAdapter))->cfg_ini->force_sap_acs;
            break;

        case WE_GET_CONCURRENCY_MODE:
        {
           *value = hdd_get_concurrency_mode ( );

           VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("concurrency mode=%d"),*value);
           break;
        }

        case WE_GET_NSS:
        {
           sme_GetConfigParam(hHal, &smeConfig);
           *value = (smeConfig.csrConfig.enable2x2 == 0) ? 1 : 2;
           hddLog(LOG1, "GET_NSS: Current NSS:%d", *value);
           break;
        }

        case WE_GET_GTX_HT_MCS:
        {
           hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_HT_MCS");
           *value = wma_cli_get_command(wmapvosContext,
                                        (int)pAdapter->sessionId,
                                        (int)WMI_VDEV_PARAM_GTX_HT_MCS,
                                        GTX_CMD);
           break;
        }

        case WE_GET_GTX_VHT_MCS:
        {
           hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_VHT_MCS");
           *value = wma_cli_get_command(wmapvosContext,
                                        (int)pAdapter->sessionId,
                                        (int)WMI_VDEV_PARAM_GTX_VHT_MCS,
                                        GTX_CMD);
           break;
        }

        case WE_GET_GTX_USRCFG:
        {
           hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_USR_CFG");
           *value = wma_cli_get_command(wmapvosContext,
                                        (int)pAdapter->sessionId,
                                        (int)WMI_VDEV_PARAM_GTX_USR_CFG,
                                        GTX_CMD);
           break;
        }

        case WE_GET_GTX_THRE:
        {
           hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_THRE");
           *value = wma_cli_get_command(wmapvosContext,
                                        (int)pAdapter->sessionId,
                                        (int)WMI_VDEV_PARAM_GTX_THRE,
                                        GTX_CMD);
           break;
        }

        case WE_GET_GTX_MARGIN:
        {
           hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_MARGIN");
           *value = wma_cli_get_command(wmapvosContext,
                                        (int)pAdapter->sessionId,
                                        (int)WMI_VDEV_PARAM_GTX_MARGIN,
                                        GTX_CMD);
           break;
        }

        case WE_GET_GTX_STEP:
        {
           hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_STEP");
           *value = wma_cli_get_command(wmapvosContext,
                                        (int)pAdapter->sessionId,
                                        (int)WMI_VDEV_PARAM_GTX_STEP,
                                        GTX_CMD);
           break;
        }

        case WE_GET_GTX_MINTPC:
        {
           hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_MINTPC");
           *value = wma_cli_get_command(wmapvosContext,
                                        (int)pAdapter->sessionId,
                                        (int)WMI_VDEV_PARAM_GTX_MINTPC,
                                        GTX_CMD);
           break;
        }

        case WE_GET_GTX_BWMASK:
        {
           hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_BW_MASK");
           *value = wma_cli_get_command(wmapvosContext,
                                        (int)pAdapter->sessionId,
                                        (int)WMI_VDEV_PARAM_GTX_BW_MASK,
                                        GTX_CMD);
           break;
        }

        case WE_GET_LDPC:
           ret = hdd_get_ldpc(pAdapter, value);
           break;

        case WE_GET_TX_STBC:
           ret = hdd_get_tx_stbc(pAdapter, value);
           break;

        case WE_GET_RX_STBC:
           ret = hdd_get_rx_stbc(pAdapter, value);
           break;

        case WE_GET_SHORT_GI:
        {
           hddLog(LOG1, "GET WMI_VDEV_PARAM_SGI");
           *value = sme_GetHTConfig(hHal, pAdapter->sessionId,
                                           WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ);
           break;
        }

        case WE_GET_RTSCTS:
        {
           hddLog(LOG1, "GET WMI_VDEV_PARAM_ENABLE_RTSCTS");
           *value = wma_cli_get_command(wmapvosContext,
                                        (int)pAdapter->sessionId,
                                        (int)WMI_VDEV_PARAM_ENABLE_RTSCTS,
                                        VDEV_CMD);
           break;
        }

        case WE_GET_CHWIDTH:
        {
           hddLog(LOG1, "GET WMI_VDEV_PARAM_CHWIDTH");
           *value = wma_cli_get_command(wmapvosContext,
                                        (int)pAdapter->sessionId,
                                        (int)WMI_VDEV_PARAM_CHWIDTH,
                                        VDEV_CMD);
           break;
        }

        case WE_GET_ANI_EN_DIS:
        {
           hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_ENABLE");
           *value = wma_cli_get_command(wmapvosContext,
                                        (int)pAdapter->sessionId,
                                        (int)WMI_PDEV_PARAM_ANI_ENABLE,
                                        PDEV_CMD);
           break;
        }

        case WE_GET_ANI_POLL_PERIOD:
        {
           hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_POLL_PERIOD");
           *value = wma_cli_get_command(wmapvosContext,
                                        (int)pAdapter->sessionId,
                                        (int)WMI_PDEV_PARAM_ANI_POLL_PERIOD,
                                        PDEV_CMD);
           break;
        }

        case WE_GET_ANI_LISTEN_PERIOD:
        {
           hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_LISTEN_PERIOD");
           *value = wma_cli_get_command(wmapvosContext,
                                        (int)pAdapter->sessionId,
                                        (int)WMI_PDEV_PARAM_ANI_LISTEN_PERIOD,
                                        PDEV_CMD);
           break;
        }

        case WE_GET_ANI_OFDM_LEVEL:
        {
           hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_OFDM_LEVEL");
           *value = wma_cli_get_command(wmapvosContext,
                                        (int)pAdapter->sessionId,
                                        (int)WMI_PDEV_PARAM_ANI_OFDM_LEVEL,
                                        PDEV_CMD);
           break;
        }

        case WE_GET_ANI_CCK_LEVEL:
        {
           hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_CCK_LEVEL");
           *value = wma_cli_get_command(wmapvosContext,
                                        (int)pAdapter->sessionId,
                                        (int)WMI_PDEV_PARAM_ANI_CCK_LEVEL,
                                        PDEV_CMD);
           break;
        }

        case WE_GET_DYNAMIC_BW:
        {
           hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_CCK_LEVEL");
           *value = wma_cli_get_command(wmapvosContext,
                                        (int)pAdapter->sessionId,
                                        (int)WMI_PDEV_PARAM_DYNAMIC_BW,
                                        PDEV_CMD);
           break;
        }

        case WE_GET_11N_RATE:
        {
            hddLog(LOG1, "GET WMI_VDEV_PARAM_FIXED_RATE");
            *value = wma_cli_get_command(wmapvosContext,
                                         (int)pAdapter->sessionId,
                                         (int)WMI_VDEV_PARAM_FIXED_RATE,
                                         VDEV_CMD);
            break;
        }

        case WE_GET_AMPDU:
        {
            hddLog(LOG1, "GET AMPDU");
            *value = wma_cli_get_command(wmapvosContext,
                                         (int)pAdapter->sessionId,
                                         (int)GEN_VDEV_PARAM_AMPDU,
                                         GEN_CMD);
            break;
        }

        case WE_GET_AMSDU:
        {
            hddLog(LOG1, "GET AMSDU");
            *value = wma_cli_get_command(wmapvosContext,
                                         (int)pAdapter->sessionId,
                                         (int)GEN_VDEV_PARAM_AMSDU,
                                         GEN_CMD);
            break;
        }

        case WE_GET_BURST_ENABLE:
        {
            hddLog(LOG1, "GET Burst enable value");
            *value = wma_cli_get_command(wmapvosContext,
                                         (int)pAdapter->sessionId,
                                         (int)WMI_PDEV_PARAM_BURST_ENABLE,
                                         PDEV_CMD);
            break;
        }
        case WE_GET_BURST_DUR:
        {
            hddLog(LOG1, "GET Burst Duration value");
            *value = wma_cli_get_command(wmapvosContext,
                                         (int)pAdapter->sessionId,
                                         (int)WMI_PDEV_PARAM_BURST_DUR,
                                         PDEV_CMD);
            break;
        }

        case WE_GET_TX_CHAINMASK:
        {
            hddLog(LOG1, "GET WMI_PDEV_PARAM_TX_CHAIN_MASK");
            *value = wma_cli_get_command(wmapvosContext,
                                         (int)pAdapter->sessionId,
                                         (int)WMI_PDEV_PARAM_TX_CHAIN_MASK,
                                         PDEV_CMD);
            break;
        }

        case WE_GET_RX_CHAINMASK:
        {
            hddLog(LOG1, "GET WMI_PDEV_PARAM_RX_CHAIN_MASK");
            *value = wma_cli_get_command(wmapvosContext,
                                         (int)pAdapter->sessionId,
                                         (int)WMI_PDEV_PARAM_RX_CHAIN_MASK,
                                         PDEV_CMD);
            break;
        }

        case WE_GET_TXPOW_2G:
        {
            tANI_U32 txpow2g = 0;
            tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
            hddLog(LOG1, "GET WMI_PDEV_PARAM_TXPOWER_LIMIT2G");
            *value = wma_cli_get_command(wmapvosContext,
                                         (int)pAdapter->sessionId,
                                         (int)WMI_PDEV_PARAM_TXPOWER_LIMIT2G,
                                         PDEV_CMD);
            if ( eHAL_STATUS_SUCCESS != ccmCfgGetInt(hHal,
                      WNI_CFG_CURRENT_TX_POWER_LEVEL, &txpow2g) )
            {
                 return -EIO;
            }
            hddLog(LOG1, "2G tx_power %d", txpow2g);
            break;
        }

        case WE_GET_TXPOW_5G:
        {
            tANI_U32 txpow5g = 0;
            tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
            hddLog(LOG1, "GET WMI_PDEV_PARAM_TXPOWER_LIMIT5G");
            *value = wma_cli_get_command(wmapvosContext,
                                         (int)pAdapter->sessionId,
                                         (int)WMI_PDEV_PARAM_TXPOWER_LIMIT5G,
                                         PDEV_CMD);
            if ( eHAL_STATUS_SUCCESS != ccmCfgGetInt(hHal,
                      WNI_CFG_CURRENT_TX_POWER_LEVEL, &txpow5g) )
            {
                 return -EIO;
            }
            hddLog(LOG1, "5G tx_power %d", txpow5g);
            break;
        }

    case WE_GET_PPS_PAID_MATCH:
        {
            hddLog(LOG1, "GET WMI_VDEV_PPS_PAID_MATCH");
            *value = wma_cli_get_command(wmapvosContext,
                                         (int)pAdapter->sessionId,
                                         (int)WMI_VDEV_PPS_PAID_MATCH,
                                         PPS_CMD);
            break;
        }

    case WE_GET_PPS_GID_MATCH:
        {
            hddLog(LOG1, "GET WMI_VDEV_PPS_GID_MATCH");
            *value = wma_cli_get_command(wmapvosContext,
                                         (int)pAdapter->sessionId,
                                         (int)WMI_VDEV_PPS_GID_MATCH,
                                         PPS_CMD);
            break;
    }

    case WE_GET_PPS_EARLY_TIM_CLEAR:
        {
            hddLog(LOG1, "GET WMI_VDEV_PPS_EARLY_TIM_CLEAR");
            *value = wma_cli_get_command(wmapvosContext,
                                         (int)pAdapter->sessionId,
                                         (int)WMI_VDEV_PPS_EARLY_TIM_CLEAR,
                                         PPS_CMD);
            break;
    }

    case WE_GET_PPS_EARLY_DTIM_CLEAR:
        {
            hddLog(LOG1, "GET WMI_VDEV_PPS_EARLY_DTIM_CLEAR");
            *value = wma_cli_get_command(wmapvosContext,
                                         (int)pAdapter->sessionId,
                                         (int)WMI_VDEV_PPS_EARLY_DTIM_CLEAR,
                                         PPS_CMD);
            break;
    }

    case WE_GET_PPS_EOF_PAD_DELIM:
        {
            hddLog(LOG1, "GET WMI_VDEV_PPS_EOF_PAD_DELIM");
            *value = wma_cli_get_command(wmapvosContext,
                                         (int)pAdapter->sessionId,
                                         (int)WMI_VDEV_PPS_EOF_PAD_DELIM,
                                         PPS_CMD);
            break;
    }

    case WE_GET_PPS_MACADDR_MISMATCH:
        {
            hddLog(LOG1, "GET WMI_VDEV_PPS_MACADDR_MISMATCH");
            *value = wma_cli_get_command(wmapvosContext,
                                         (int)pAdapter->sessionId,
                                         (int)WMI_VDEV_PPS_MACADDR_MISMATCH,
                                         PPS_CMD);
            break;
    }

    case WE_GET_PPS_DELIM_CRC_FAIL:
        {
            hddLog(LOG1, "GET WMI_VDEV_PPS_DELIM_CRC_FAIL");
            *value = wma_cli_get_command(wmapvosContext,
                                         (int)pAdapter->sessionId,
                                         (int)WMI_VDEV_PPS_DELIM_CRC_FAIL,
                                         PPS_CMD);
            break;
    }

    case WE_GET_PPS_GID_NSTS_ZERO:
        {
            hddLog(LOG1, "GET WMI_VDEV_PPS_GID_NSTS_ZERO");
            *value = wma_cli_get_command(wmapvosContext,
                                         (int)pAdapter->sessionId,
                                         (int)WMI_VDEV_PPS_GID_NSTS_ZERO,
                                         PPS_CMD);
            break;
    }

    case WE_GET_PPS_RSSI_CHECK:
    {

            hddLog(LOG1, "GET WMI_VDEV_PPS_RSSI_CHECK");
            *value = wma_cli_get_command(wmapvosContext,
                                         (int)pAdapter->sessionId,
                                         (int)WMI_VDEV_PPS_RSSI_CHECK,
                                         PPS_CMD);
            break;
    }

        case WE_GET_QPOWER_MAX_PSPOLL_COUNT:
        {
               hddLog(LOG1, "WE_GET_QPOWER_MAX_PSPOLL_COUNT");
               *value = wma_cli_get_command(wmapvosContext,
                                      (int)pAdapter->sessionId,
                                      (int)WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT,
                                      QPOWER_CMD);
               break;
        }

        case WE_GET_QPOWER_MAX_TX_BEFORE_WAKE:
        {
           hddLog(LOG1, "WE_GET_QPOWER_MAX_TX_BEFORE_WAKE");
           *value = wma_cli_get_command(wmapvosContext,
                              (int)pAdapter->sessionId,
                              (int)WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE,
                              QPOWER_CMD);
           break;
        }

        case WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL:
        {
           hddLog(LOG1, "WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL");
           *value = wma_cli_get_command(wmapvosContext,
                      (int)pAdapter->sessionId,
                      (int)WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
                      QPOWER_CMD);
           break;
        }

        case WE_GET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL:
        {
           hddLog(LOG1, "WE_GET_QPOWER_MAX_PSPOLL_COUNT");
           *value = wma_cli_get_command(wmapvosContext,
                      (int)pAdapter->sessionId,
                      (int)WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
                      QPOWER_CMD);
           break;
        }

        case WE_GET_SCAN_BAND_PREFERENCE:
        {
            sme_GetConfigParam(hHal, &smeConfig);
            *value = smeConfig.csrConfig.scanBandPreference;

            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "scanBandPreference = %d", *value);
            break;
        }

        case WE_GET_TEMPERATURE:
        {
            hddLog(VOS_TRACE_LEVEL_INFO, "WE_GET_TEMPERATURE");
            ret = wlan_hdd_get_temperature(pAdapter, wrqu, extra);
            break;
        }

        case WE_GET_FW_STATUS:
        {
            hddLog(LOG1, "WE_GET_FW_STATUS");
            *value = wlan_hdd_get_fw_state(pAdapter);
            break;
        }
        case WE_CAP_TSF:
        {
            ret = hdd_capture_tsf(pAdapter, (uint32_t *)value, 1);
            break;
        }
#ifdef FEATURE_PBM_MAGIC_WOW
        case WE_PBM_MP_GET_REASON:
        {
            *value = (uint32_t)wma_wow_get_pbm_mp_reason(wmapvosContext) & 0xFF;
            hddLog(LOGE, "PBM wow reason %d", *value);
            break;
        }
#endif
        default:
        {
           hddLog(LOGE, "Invalid IOCTL get_value command %d", value[0]);
           break;
        }
    }
    EXIT();
    return ret;
}

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

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

	return ret;
}

/* set param sub-ioctls */
static int __iw_set_three_ints_getnone(struct net_device *dev,
                                       struct iw_request_info *info,
                                       union iwreq_data *wrqu,
                                       char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
    int *value = (int *)extra;
    int sub_cmd = value[0];
    int ret;

    ENTER();

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

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

    switch(sub_cmd) {

    case WE_SET_WLAN_DBG:
       vos_trace_setValue( value[1], value[2], value[3]);
       break;
    case WE_SET_DP_TRACE:
       adf_dp_trace_set_value(value[1], value[2], value[3]);
       break;
    case WE_SET_SAP_CHANNELS:
        /* value[3] the acs band is not required as start and end channels are
         * enough but this cmd is maintained under set three ints for historic
         * reasons.
         */
        if (wlan_hdd_validate_operation_channel(pAdapter, value[1]) !=
                                        VOS_STATUS_SUCCESS ||
            wlan_hdd_validate_operation_channel(pAdapter, value[2]) !=
                                        VOS_STATUS_SUCCESS) {
            ret = -EINVAL;
        } else {
            hdd_ctx->cfg_ini->force_sap_acs_st_ch = value[1];
            hdd_ctx->cfg_ini->force_sap_acs_end_ch = value[2];
        }
        break;
#ifdef FEATURE_PBM_MAGIC_WOW
    case WE_SET_ADD_EASY_WOW_PORT:
        if (!hdd_add_easy_wow_ptrn(pAdapter, value[1], value[2], 0, 0, value[3]))
            ret = -EINVAL;
        break;
    case WE_SET_RM_EASY_WOW_PORT:
        if (!hdd_del_easy_wow_ptrn(pAdapter, value[1], value[2], 0, 0, value[3]))
            ret = -EINVAL;
        break;
#endif
    default:
       hddLog(LOGE, "%s: Invalid IOCTL command %d", __func__, sub_cmd );
       break;

    }
    EXIT();
    return ret;
}

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

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

	return ret;
}

static int __iw_get_char_setnone(struct net_device *dev,
                                 struct iw_request_info *info,
                                 union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    int sub_cmd = wrqu->data.flags;
    hdd_context_t *hdd_ctx;
    int ret;
#ifdef WLAN_FEATURE_11W
    hdd_wext_state_t *pWextState;
#endif

#ifdef WLAN_FEATURE_11W
    pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
#endif

    ENTER();

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

    switch(sub_cmd)
    {
        case WE_WLAN_VERSION:
        {
            hdd_wlan_get_version(pAdapter, wrqu, extra);
            break;
        }

        case WE_GET_STATS:
        {
            return hdd_wlan_get_stats(pAdapter, &(wrqu->data.length),
                               extra, WE_MAX_STR_LEN);
        }

/* The case prints the current state of the HDD, SME, CSR, PE, TL
   *it can be extended for WDI Global State as well.
   *And currently it only checks P2P_CLIENT adapter.
   *P2P_DEVICE and P2P_GO have not been added as of now.
*/
        case WE_GET_STATES:
        {
            int buf = 0, len = 0;
            int adapter_num = 0;
            int count = 0, check = 1;

            tANI_U16 tlState;
            tHalHandle hHal = NULL;
            tpAniSirGlobal pMac = NULL;
            hdd_station_ctx_t *pHddStaCtx = NULL;

            hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
            hdd_adapter_t *useAdapter = NULL;

            /* Print wlan0 or p2p0 states based on the adapter_num
              *by using the correct adapter
            */
            while ( adapter_num < 2 )
            {
                if ( WLAN_ADAPTER == adapter_num )
                {
                    useAdapter = pAdapter;
                    buf = scnprintf(extra + len, WE_MAX_STR_LEN - len,
                            "\n\n wlan0 States:-");
                    len += buf;
                }
                else if ( P2P_ADAPTER == adapter_num )
                {
                    buf = scnprintf(extra + len, WE_MAX_STR_LEN - len,
                            "\n\n p2p0 States:-");
                    len += buf;

                    if( !pHddCtx )
                    {
                        buf = scnprintf(extra + len, WE_MAX_STR_LEN - len,
                                "\n pHddCtx is NULL");
                        len += buf;
                        break;
                    }

                    /*Printing p2p0 states only in the case when the device is
                      configured as a p2p_client*/
                    useAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
                    if ( !useAdapter )
                    {
                        buf = scnprintf(extra + len, WE_MAX_STR_LEN - len,
                                "\n Device not configured as P2P_CLIENT.");
                        len += buf;
                        break;
                    }
                }

                hHal = WLAN_HDD_GET_HAL_CTX( useAdapter );
                if (!hHal) {
                    buf = scnprintf(extra + len,  WE_MAX_STR_LEN - len,
                            "\n pMac is NULL");
                    len += buf;
                    break;
                }
                pMac = PMAC_STRUCT( hHal );
                if (!pMac) {
                    buf = scnprintf(extra + len,  WE_MAX_STR_LEN - len,
                            "\n pMac is NULL");
                    len += buf;
                    break;
                }
                pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(useAdapter);

                tlState = smeGetTLSTAState(hHal, pHddStaCtx->conn_info.staId[0]);

                buf = scnprintf(extra + len, WE_MAX_STR_LEN - len,
                        "\n HDD Conn State - %s "
                        "\n \n SME State:"
                        "\n Neighbour Roam State - %s"
                        "\n CSR State - %s"
                        "\n CSR Substate - %s"
                        "\n \n TL STA %d State: %s",
                        macTraceGetHDDWlanConnState(
                                pHddStaCtx->conn_info.connState),
                        macTraceGetNeighbourRoamState(
                              sme_getNeighborRoamState(hHal,
                                  useAdapter->sessionId)),
                        macTraceGetcsrRoamState(
                              sme_getCurrentRoamState(hHal,
                                  useAdapter->sessionId)),
                        macTraceGetcsrRoamSubState(
                              sme_getCurrentRoamSubState(hHal,
                                  useAdapter->sessionId)),
                        pHddStaCtx->conn_info.staId[0],
                        macTraceGetTLState(tlState)
                        );
                len += buf;
                adapter_num++;
            }

            if (hHal) {
                /* Printing Lim State starting with global lim states */
                buf = scnprintf(extra + len, WE_MAX_STR_LEN - len,
                        "\n \n LIM STATES:-"
                        "\n Global Sme State - %s "\
                        "\n Global mlm State - %s "\
                        "\n",
                        macTraceGetLimSmeState(sme_getLimSmeState(hHal)),
                        macTraceGetLimMlmState(sme_getLimSmeState(hHal))
                        );
                len += buf;

                /* Printing the PE Sme and Mlm states for valid lim sessions */
                while (check < 3 && count < 255) {
                    if (sme_IsLimSessionValid(hHal, count)) {
                        buf = scnprintf(extra + len, WE_MAX_STR_LEN - len,
                            "\n Lim Valid Session %d:-"
                            "\n PE Sme State - %s "
                            "\n PE Mlm State - %s "
                            "\n",
                            check,
                            macTraceGetLimSmeState(sme_getLimSmeSessionState(
                                                                  hHal, count)),
                            macTraceGetLimMlmState(sme_getLimMlmSessionState(
                                                                  hHal, count))
                            );

                        len += buf;
                        check++;
                    }
                    count++;
                }
            }

            wrqu->data.length = strlen(extra)+1;
            break;
        }

        case WE_GET_CFG:
        {
#ifdef WLAN_FEATURE_MBSSID
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                   "%s: Printing Adapter MBSSID SAP Dyn INI Config", __func__);
            hdd_cfg_get_sap_dyn_config(pAdapter,
                                      extra, QCSAP_IOCTL_MAX_STR_LEN);
            /* Overwrite extra buffer with global ini config if need to return
             * in buf
             */
#endif
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                               "%s: Printing CLD global INI Config", __func__);
            hdd_cfg_get_global_config(WLAN_HDD_GET_CTX(pAdapter), extra,
                                      QCSAP_IOCTL_MAX_STR_LEN);
            wrqu->data.length = strlen(extra)+1;
            break;
        }
#ifdef WLAN_FEATURE_11AC
        case WE_GET_RSSI:
        {
            v_S7_t s7Rssi = 0;
            wlan_hdd_get_rssi(pAdapter, &s7Rssi);
            snprintf(extra, WE_MAX_STR_LEN, "rssi=%d",s7Rssi);
            wrqu->data.length = strlen(extra)+1;
            break;
        }
#endif

        case WE_GET_WMM_STATUS:
        {
            snprintf(extra, WE_MAX_STR_LEN,
                    "\nDir: 0=up, 1=down, 3=both\n"
                    "|------------------------|\n"
                    "|AC | ACM |Admitted| Dir |\n"
                    "|------------------------|\n"
                    "|VO |  %d  |  %3s   |  %d  |\n"
                    "|VI |  %d  |  %3s   |  %d  |\n"
                    "|BE |  %d  |  %3s   |  %d  |\n"
                    "|BK |  %d  |  %3s   |  %d  |\n"
                    "|------------------------|\n",
                    pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VO].wmmAcAccessRequired,
                    pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VO].wmmAcAccessAllowed?"YES":"NO",
                    pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VO].wmmAcTspecInfo.ts_info.direction,
                    pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VI].wmmAcAccessRequired,
                    pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VI].wmmAcAccessAllowed?"YES":"NO",
                    pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VI].wmmAcTspecInfo.ts_info.direction,
                    pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BE].wmmAcAccessRequired,
                    pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BE].wmmAcAccessAllowed?"YES":"NO",
                    pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BE].wmmAcTspecInfo.ts_info.direction,
                    pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BK].wmmAcAccessRequired,
                    pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BK].wmmAcAccessAllowed?"YES":"NO",
                    pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BK].wmmAcTspecInfo.ts_info.direction);


            wrqu->data.length = strlen(extra)+1;
            break;
        }
        case WE_GET_CHANNEL_LIST:
        {
            VOS_STATUS status;
            v_U8_t i, len;
            char* buf;
            uint8_t ubuf[WNI_CFG_COUNTRY_CODE_LEN];
            uint8_t ubuf_len = WNI_CFG_COUNTRY_CODE_LEN;
            hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);

            tChannelListInfo channel_list;

            memset(&channel_list, 0, sizeof(channel_list));
            status = iw_get_channel_list(dev, info, wrqu, (char *)&channel_list);
            if (!VOS_IS_STATUS_SUCCESS(status)) {
                hddLog(LOGE, FL("GetChannelList Failed!!!"));
                return -EINVAL;
            }
            buf = extra;
            /**
             * Maximum channels = WNI_CFG_VALID_CHANNEL_LIST_LEN. Maximum buffer
             * needed = 5 * number of channels. Check if sufficient
             * buffer is available and then proceed to fill the buffer.
             */
            if (WE_MAX_STR_LEN < (5 * WNI_CFG_VALID_CHANNEL_LIST_LEN)) {
                hddLog(LOGE,
                       FL("Insufficient Buffer to populate channel list"));
                return -EINVAL;
            }
            len = scnprintf(buf, WE_MAX_STR_LEN, "%u ",
                    channel_list.num_channels);
            if (eHAL_STATUS_SUCCESS == sme_GetCountryCode(hdd_ctx->hHal,
                                                          ubuf, &ubuf_len)) {
                /* Printing Country code in getChannelList */
                for (i = 0; i < (ubuf_len - 1); i++)
                    len += scnprintf(buf + len, WE_MAX_STR_LEN - len,
                                     "%c", ubuf[i]);
            }

            for (i = 0; i < channel_list.num_channels; i++) {
                len += scnprintf(buf + len, WE_MAX_STR_LEN - len,
                               " %u", channel_list.channels[i]);
            }
            wrqu->data.length = strlen(extra) + 1;

            break;
        }
#ifdef FEATURE_WLAN_TDLS
        case WE_GET_TDLS_PEERS:
        {
            wrqu->data.length = wlan_hdd_tdls_get_all_peers(pAdapter, extra, WE_MAX_STR_LEN)+1;
            break;
        }
#endif
#ifdef WLAN_FEATURE_11W
       case WE_GET_11W_INFO:
       {
           hddLog(LOGE, "WE_GET_11W_ENABLED = %d",  pWextState->roamProfile.MFPEnabled );

           snprintf(extra, WE_MAX_STR_LEN,
                    "\n BSSID %02X:%02X:%02X:%02X:%02X:%02X, Is PMF Assoc? %d"
                    "\n Number of Unprotected Disassocs %d"
                    "\n Number of Unprotected Deauths %d",
                    (*pWextState->roamProfile.BSSIDs.bssid)[0], (*pWextState->roamProfile.BSSIDs.bssid)[1],
                    (*pWextState->roamProfile.BSSIDs.bssid)[2], (*pWextState->roamProfile.BSSIDs.bssid)[3],
                    (*pWextState->roamProfile.BSSIDs.bssid)[4], (*pWextState->roamProfile.BSSIDs.bssid)[5],
                    pWextState->roamProfile.MFPEnabled, pAdapter->hdd_stats.hddPmfStats.numUnprotDisassocRx,
                    pAdapter->hdd_stats.hddPmfStats.numUnprotDeauthRx);

           wrqu->data.length = strlen(extra)+1;
           break;
       }
#endif
        case WE_GET_IBSS_STA_INFO:
        {
            hdd_station_ctx_t *pHddStaCtx =
                WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
            int idx = 0;
            int length = 0, buf = 0;

            for (idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++)
            {
               if (0 != pHddStaCtx->conn_info.staId[ idx ])
               {
                   buf = snprintf
                             (
                             (extra + length), WE_MAX_STR_LEN - length,
                             "\n%d .%02x:%02x:%02x:%02x:%02x:%02x\n",
                             pHddStaCtx->conn_info.staId[ idx ],
                             pHddStaCtx->conn_info.peerMacAddress[idx].bytes[0],
                             pHddStaCtx->conn_info.peerMacAddress[idx].bytes[1],
                             pHddStaCtx->conn_info.peerMacAddress[idx].bytes[2],
                             pHddStaCtx->conn_info.peerMacAddress[idx].bytes[3],
                             pHddStaCtx->conn_info.peerMacAddress[idx].bytes[4],
                             pHddStaCtx->conn_info.peerMacAddress[idx].bytes[5]
                             );
                   length += buf;
               }
            }
            wrqu->data.length = strlen(extra)+1;
            break;
        }
        case WE_GET_PHYMODE:
        {
           v_BOOL_t ch_bond24 = VOS_FALSE, ch_bond5g = VOS_FALSE;
           hdd_context_t *hddctx = WLAN_HDD_GET_CTX(pAdapter);
           tHalHandle hal = WLAN_HDD_GET_HAL_CTX(pAdapter);
           eCsrPhyMode phymode;
           eCsrBand currBand;
           tSmeConfigParams smeconfig;

           sme_GetConfigParam(hal, &smeconfig);
           if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
                                  smeconfig.csrConfig.channelBondingMode24GHz)
               ch_bond24 = VOS_TRUE;

           if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
                                  smeconfig.csrConfig.channelBondingMode5GHz)
               ch_bond5g = VOS_TRUE;

           phymode = sme_GetPhyMode(hal);
           if ((eHAL_STATUS_SUCCESS != sme_GetFreqBand(hal, &currBand))) {
               VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                         "%s: Failed to get current band config",
                         __func__);
               return -EIO;
           }


           switch (phymode) {
           case eCSR_DOT11_MODE_AUTO:
                snprintf(extra, WE_MAX_STR_LEN, "AUTO MODE");
                break;
           case eCSR_DOT11_MODE_11n:
           case eCSR_DOT11_MODE_11n_ONLY:
                if (currBand == eCSR_BAND_24) {
                    if (ch_bond24)
                        snprintf(extra, WE_MAX_STR_LEN, "11NGHT40");
                    else
                        snprintf(extra, WE_MAX_STR_LEN, "11NGHT20");
                }
                else if(currBand == eCSR_BAND_5G) {
                    if (ch_bond5g)
                        snprintf(extra, WE_MAX_STR_LEN, "11NAHT40");
                    else
                        snprintf(extra, WE_MAX_STR_LEN, "11NAHT20");
                } else {
                    snprintf(extra, WE_MAX_STR_LEN, "11N");
                }
                break;
           case eCSR_DOT11_MODE_abg:
                snprintf(extra, WE_MAX_STR_LEN, "11ABG");
                break;
           case eCSR_DOT11_MODE_11a:
                snprintf(extra, WE_MAX_STR_LEN, "11A");
                break;
           case eCSR_DOT11_MODE_11b:
           case eCSR_DOT11_MODE_11b_ONLY:
                snprintf(extra, WE_MAX_STR_LEN, "11B");
                break;
           case eCSR_DOT11_MODE_11g:
           case eCSR_DOT11_MODE_11g_ONLY:
                snprintf(extra, WE_MAX_STR_LEN, "11G");
                break;
#ifdef WLAN_FEATURE_11AC
           case eCSR_DOT11_MODE_11ac:
           case eCSR_DOT11_MODE_11ac_ONLY:
                if (hddctx->cfg_ini->vhtChannelWidth ==
                                                       eHT_CHANNEL_WIDTH_20MHZ)
                    snprintf(extra, WE_MAX_STR_LEN, "11ACVHT20");
                else if (hddctx->cfg_ini->vhtChannelWidth ==
                                                       eHT_CHANNEL_WIDTH_40MHZ)
                    snprintf(extra, WE_MAX_STR_LEN, "11ACVHT40");
                else if (hddctx->cfg_ini->vhtChannelWidth ==
                                                       eHT_CHANNEL_WIDTH_80MHZ)
                    snprintf(extra, WE_MAX_STR_LEN, "11ACVHT80");
                else if (hddctx->cfg_ini->vhtChannelWidth ==
                                                       eHT_CHANNEL_WIDTH_160MHZ)
                    snprintf(extra, WE_MAX_STR_LEN, "11ACVHT160");
                break;
#endif
           }

           wrqu->data.length = strlen(extra)+1;
           break;
        }

#ifdef FEATURE_OEM_DATA_SUPPORT
        case WE_GET_OEM_DATA_CAP:
        {
            return iw_get_oem_data_cap(dev, info, wrqu, extra);
        }
#endif /* FEATURE_OEM_DATA_SUPPORT */
        case WE_GET_SNR:
        {
            v_S7_t s7snr = 0;
            int status = 0;
            hdd_context_t *pHddCtx;
            hdd_station_ctx_t *pHddStaCtx;

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

            pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

            if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
                eConnectionState_Associated != pHddStaCtx->conn_info.connState)
            {
                hddLog(LOGE, "%s: getSNR failed: Enable SNR Monitoring-%d,"
                       " ConnectionState-%d", __func__,
                       pHddCtx->cfg_ini->fEnableSNRMonitoring,
                       pHddStaCtx->conn_info.connState);
                return -ENONET;
            }

            wlan_hdd_get_snr(pAdapter, &s7snr);
            snprintf(extra, WE_MAX_STR_LEN, "snr=%d",s7snr);
            wrqu->data.length = strlen(extra) + 1;
            break;
        }
        case WE_GET_PS_TDCC:
        {
            return hdd_wlan_get_ps_tdcc_info(pAdapter, &(wrqu->data.length),
                                             extra, WE_MAX_STR_LEN);
        }
#ifdef AUDIO_MULTICAST_AGGR_SUPPORT
        case WE_AUDIO_GET_RX_GROUP_INFO:
        {
           return wlan_hdd_get_rx_group(pAdapter, wrqu, extra);
        }
#endif
        default:
        {
            hddLog(LOGE, "%s: Invalid IOCTL command %d", __func__, sub_cmd );
            break;
        }
    }
    EXIT();
    return 0;
}

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

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

	return ret;
}

/*  action sub-ioctls */
static int __iw_setnone_getnone(struct net_device *dev,
                                struct iw_request_info *info,
                                union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *hdd_ctx;
    int ret;
    int sub_cmd;

    ENTER();

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

#ifdef CONFIG_COMPAT
    /* this ioctl is a special case where a sub-ioctl is used and both
     * the number of get and set args is 0.  in this specific case the
     * logic in iwpriv places the sub_cmd in the data.flags portion of
     * the iwreq.  unfortunately the location of this field will be
     * different between 32-bit and 64-bit user space, and the standard
     * compat support in the kernel does not handle this case.  so we
     * need to explicitly handle it here. */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)) && defined(CONFIG_X86_64)
    if (in_compat_syscall()) {
#else
    if (is_compat_task()) {
#endif
        struct compat_iw_point *compat_iw_point =
            (struct compat_iw_point *) &wrqu->data;
        sub_cmd = compat_iw_point->flags;
    } else {
        sub_cmd = wrqu->data.flags;
    }
#else
    sub_cmd = wrqu->data.flags;
#endif

    switch (sub_cmd)
    {
        case WE_GET_RECOVERY_STAT:
        {
            tHalHandle hal = WLAN_HDD_GET_HAL_CTX(pAdapter);
            sme_getRecoveryStats(hal);
            break;
        }

        case WE_IBSS_GET_PEER_INFO_ALL:
        {
            hdd_wlan_get_ibss_peer_info_all(pAdapter);
            break;
        }

        case WE_ENABLE_DXE_STALL_DETECT:
        {
            tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
            sme_transportDebug(hHal, VOS_FALSE, VOS_TRUE);
            break;
        }
        case WE_DISPLAY_DXE_SNAP_SHOT:
        {
            tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
            sme_transportDebug(hHal, VOS_TRUE, VOS_FALSE);
            break;
        }
        case WE_DISPLAY_DATAPATH_SNAP_SHOT:
        {
            hddLog(LOGE, "%s: called %d",__func__, sub_cmd);
            hdd_wmm_tx_snapshot(pAdapter);
            WLANTL_TLDebugMessage(VOS_TRUE);
            break;
        }
        case WE_SET_REASSOC_TRIGGER:
        {
            hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
            tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
            v_U32_t roamId = 0;
            tCsrRoamModifyProfileFields modProfileFields;
            sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
                                       &modProfileFields);
            sme_RoamReassoc(hHal, pAdapter->sessionId,
                            NULL, modProfileFields, &roamId, 1);
            return 0;
        }

        case WE_DUMP_AGC_START:
        {
            hddLog(LOG1, "WE_DUMP_AGC_START");
            ret = process_wma_set_command((int)pAdapter->sessionId,
                                          (int)GEN_PARAM_DUMP_AGC_START,
                                          0, GEN_CMD);
            break;
        }
        case WE_DUMP_AGC:
        {
            hddLog(LOG1, "WE_DUMP_AGC");
            ret = process_wma_set_command((int)pAdapter->sessionId,
                                          (int)GEN_PARAM_DUMP_AGC,
                                          0, GEN_CMD);
            break;
        }

        case WE_DUMP_CHANINFO_START:
        {
            hddLog(LOG1, "WE_DUMP_CHANINFO_START");
            ret = process_wma_set_command((int)pAdapter->sessionId,
                                          (int)GEN_PARAM_DUMP_CHANINFO_START,
                                          0, GEN_CMD);
            break;
        }
        case WE_DUMP_CHANINFO:
        {
            hddLog(LOG1, "WE_DUMP_CHANINFO_START");
            ret = process_wma_set_command((int)pAdapter->sessionId,
                                          (int)GEN_PARAM_DUMP_CHANINFO,
                                          0, GEN_CMD);
            break;
        }
        case WE_DUMP_WATCHDOG:
        {
            hddLog(LOG1, "WE_DUMP_WATCHDOG");
            ret = process_wma_set_command((int)pAdapter->sessionId,
                                          (int)GEN_PARAM_DUMP_WATCHDOG,
                                          0, GEN_CMD);
            break;
        }
#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG
        case WE_DUMP_PCIE_LOG:
        {
          hddLog(LOGE, "WE_DUMP_PCIE_LOG");
          ret = process_wma_set_command((int) pAdapter->sessionId,
                                        (int) GEN_PARAM_DUMP_PCIE_ACCESS_LOG,
                                        0, GEN_CMD);
          break;
        }
#endif
        default:
        {
            hddLog(LOGE, "%s: unknown ioctl %d", __func__, sub_cmd);
            break;
        }
    }
    EXIT();
    return ret;
}

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

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

	return ret;
}

void hdd_wmm_tx_snapshot(hdd_adapter_t *pAdapter)
{
    /*
     * Function to display HDD WMM information
     * for Tx Queues.
     * Prints global as well as per client depending
     * whether the clients are registered or not.
     */
    int i = 0, j = 0;
    for ( i=0; i< NUM_TX_QUEUES; i++)
    {
        adf_os_spin_lock_bh(&pAdapter->wmm_tx_queue[i].lock);
        hddLog(LOGE, "HDD WMM TxQueue Info For AC: %d Count: %d PrevAdress:%pK, NextAddress:%pK",
               i, pAdapter->wmm_tx_queue[i].count,
               pAdapter->wmm_tx_queue[i].anchor.prev, pAdapter->wmm_tx_queue[i].anchor.next);
        adf_os_spin_unlock_bh(&pAdapter->wmm_tx_queue[i].lock);
    }

    for(i =0; i<WLAN_MAX_STA_COUNT; i++)
    {
        if(pAdapter->aStaInfo[i].isUsed)
        {
             hddLog(LOGE, "******STAIndex: %d*********", i);
             for ( j=0; j< NUM_TX_QUEUES; j++)
             {
                adf_os_spin_lock_bh(&pAdapter->aStaInfo[i].wmm_tx_queue[j].lock);
                hddLog(LOGE, "HDD TxQueue Info For AC: %d Count: %d PrevAdress:%pK, NextAddress:%pK",
                       j, pAdapter->aStaInfo[i].wmm_tx_queue[j].count,
                       pAdapter->aStaInfo[i].wmm_tx_queue[j].anchor.prev,
                       pAdapter->aStaInfo[i].wmm_tx_queue[j].anchor.next);
                adf_os_spin_unlock_bh(&pAdapter->aStaInfo[i].wmm_tx_queue[j].lock);
             }
        }
    }

}

#ifdef AUDIO_MULTICAST_AGGR_SUPPORT
static int wlan_hdd_set_multicast_rate(hdd_adapter_t *pAdapter,
				int * args)
{
	struct audio_multicast_set_rate *pMultiGroup;
	int i = 0;
	int group_id,num_rate_set;
	vos_msg_t msg;

	num_rate_set = args[1];
	if (num_rate_set <= 0 || num_rate_set > MAX_NUM_RATE_SET) {
		hddLog(LOGW, FL("Invalid num_rate_set%d"), num_rate_set);
		return -EINVAL;
	}

	group_id = args[0];
	if (group_id < MIN_GROUP_ID || group_id >= MAX_GROUP_ID) {
		hddLog(LOGW, FL("Invalid group id %d"), group_id);
		return -EINVAL;
	}

	pMultiGroup = vos_mem_malloc(sizeof(struct audio_multicast_set_rate));
	if (NULL == pMultiGroup) {
		hddLog(LOGE,
		FL("vos_mem_alloc failed for pMultiRate"));
		return -ENOMEM;
	}
	adf_os_mem_zero(pMultiGroup, sizeof(struct audio_multicast_set_rate));

	pMultiGroup->param_vdev_id = pAdapter->sessionId;
	pMultiGroup->group_id = group_id;
	pMultiGroup->num_rate_set= num_rate_set;
	for (i = 0; i < num_rate_set; i++) {
		pMultiGroup->rate_set[i].mcs = args[2+2*i];
		pMultiGroup->rate_set[i].bandwidth = args[3+2*i];
	}

	msg.type = WDA_SET_MULTICAST_RATE;
	msg.reserved = 0;
	msg.bodyptr = pMultiGroup;
	if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA,
						&msg)) {
		vos_mem_free(pMultiGroup);
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			FL("Not able to post Set Multicast group Rate message to WDA"));
		return -EINVAL;
	}

	return VOS_STATUS_SUCCESS;
}

int
wlan_hdd_set_multicast_retry_limit(hdd_adapter_t *adapter,
			int group_id,int retry_limit)
{
	int ret;

	if (group_id < MIN_GROUP_ID || group_id >= MAX_GROUP_ID) {
		hddLog(LOGW, FL("Invalid group id %d"), group_id);
		return -EINVAL;
	}
	if (retry_limit < 0 || retry_limit > MAX_RETRY_LIMIT) {
		hddLog(LOGW, FL("Invalid Retry Limit %d"), retry_limit);
		return -EINVAL;
	}

	ret = process_wma_set_command_twoargs((int)adapter->sessionId,
					       (int)GEN_PARAM_MULTICAST_RETRY_LIMIT,
					       group_id, retry_limit, GEN_CMD);

	return ret;
}

int
wlan_hdd_multicast_aggr_enable(hdd_adapter_t *adapter,
						int aggr_enable, int tbd_enable)
{
	int ret;

	if (aggr_enable != 0 && aggr_enable != 1) {
		hddLog(LOGW, FL("Invalid input %d"), aggr_enable);
		return -EINVAL;
	}
	if (tbd_enable != 0 && tbd_enable != 1) {
		hddLog(LOGW, FL("Invalid input %d"), aggr_enable);
		return -EINVAL;
	}

	ret = process_wma_set_command_twoargs((int)adapter->sessionId,
						   (int)GEN_PARAM_MULTICAST_AGGR_ENABLED,
						   aggr_enable, tbd_enable, GEN_CMD);

	return ret;
}

static int wlan_hdd_set_multicast_auto_rate(hdd_adapter_t *pAdapter,
				int * args)
{
	struct audio_multicast_set_auto_rate *pMultiGroup;
	int group_id;
	vos_msg_t msg;

	group_id = args[0];
	if (group_id < MIN_GROUP_ID || group_id >= MAX_GROUP_ID) {
		hddLog(LOGW, FL("Invalid group id %d"), group_id);
		return -EINVAL;
	}

	pMultiGroup = vos_mem_malloc(sizeof(struct audio_multicast_set_auto_rate));
	if (NULL == pMultiGroup) {
		hddLog(LOGE, FL("vos_mem_alloc failed for pMultiRate"));
		return -ENOMEM;
	}
	adf_os_mem_zero(pMultiGroup, sizeof(struct audio_multicast_set_auto_rate));

	pMultiGroup->param_vdev_id = pAdapter->sessionId;
	pMultiGroup->group_id = group_id;
	pMultiGroup->bandwidth = args[1];
	pMultiGroup->nss = args[2];
	pMultiGroup->mcs_min = args[3];
	pMultiGroup->mcs_max = args[4];
	pMultiGroup->mcs_offset = args[5];

	msg.type = WDA_SET_MULTICAST_AUTO_RATE;
	msg.reserved = 0;
	msg.bodyptr = pMultiGroup;
	if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA,
						&msg)) {
		vos_mem_free(pMultiGroup);
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			FL("Not able to post Set Multicast group Rate message to WDA"));
		return -EINVAL;
	}

	return VOS_STATUS_SUCCESS;
}

int
wlan_hdd_set_multicast_probe(hdd_adapter_t *adapter,
			int group_id,int interval)
{
	int ret;

	if (interval < 0 || interval > MAX_PERIOD_LIMIT) {
		hddLog(LOGW, FL("Invalid Interval %d"), interval);
		return -EINVAL;
	}

	ret = process_wma_set_command_twoargs((int)adapter->sessionId,
					       (int)GEN_PARAM_MULTICAST_SET_PROBE,
					       group_id, interval, GEN_CMD);

	return ret;
}

static int wlan_hdd_set_multicast_sta(hdd_adapter_t *pAdapter,
				int * args, int group_num)
{
	struct audio_multicast_set_sta *pMultiGroup;
	int i;
	vos_msg_t msg;

	pMultiGroup = vos_mem_malloc(sizeof(struct audio_multicast_set_sta));
	if (NULL == pMultiGroup) {
		hddLog(LOGE, FL("vos_mem_alloc failed for pMultiGroup"));
		return -ENOMEM;
	}
	adf_os_mem_zero(pMultiGroup, sizeof(struct audio_multicast_set_sta));

	pMultiGroup->param_vdev_id = pAdapter->sessionId;
	pMultiGroup->group_num = group_num;
	pMultiGroup->bitmap = args[0];

	if (group_num > 0) {
		for (i = 0; i < group_num; i++) {
			pMultiGroup->group_addr[i].mac_addr31to0 = args[i*2+1];
			pMultiGroup->group_addr[i].mac_addr47to32 = args[i*2+2];
		}
	}

	msg.type = WDA_SET_MULTICAST_STA;
	msg.reserved = 0;
	msg.bodyptr = pMultiGroup;
	if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA,
						&msg)) {
		vos_mem_free(pMultiGroup);
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			FL("Not able to post Set Multicast group Rate message to WDA"));
		return -EINVAL;
	}

	return VOS_STATUS_SUCCESS;
}

int wlan_hdd_get_rx_group(hdd_adapter_t *pAdapter,
			union iwreq_data *wrqu, char *extra)
{
	int ret, length = 0;
	hdd_context_t *pHddCtx;
	tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);

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

	if (VOS_STATUS_SUCCESS != sme_is_session_valid(hHal,
	    pAdapter->sessionId)) {
		hddLog(LOGE, FL("session id is not valid %d"),
		pAdapter->sessionId);
		return -EINVAL;
	}

	length = wma_cli_au_get_rx_group_info(pHddCtx->pvosContext,
				(int)pAdapter->sessionId,
				extra);
	if (length < 0) {
		hddLog(LOGE, FL("get group info fail\n"));
		wrqu->data.length = 0;
		return length;
	}
	wrqu->data.length += length;
	return 0;
}

int wlan_hdd_au_set_cts(hdd_adapter_t * pAdapter, int mode, int profile)
{
	int ret;

	if (mode < 0 || mode > 2) {
		hddLog(LOGW, FL("Invalid cts mode %d"), mode);
		return -EINVAL;
	}

	ret = process_wma_set_command_twoargs((int)pAdapter->sessionId,
		(int)GEN_PARAM_MULTICAST_SET_CTS,
		mode, profile, GEN_CMD);

	if (!ret) {
		hddLog(LOGW, FL("Set CST mode fail, mode %d"), mode);
	}
	return ret;
}
#endif

static int __iw_set_var_ints_getnone(struct net_device *dev,
                                     struct iw_request_info *info,
                                     union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    int sub_cmd;
    int *apps_args = (int *) extra;
    hdd_station_ctx_t *pStaCtx = NULL ;
    hdd_ap_ctx_t  *pAPCtx = NULL;
    int cmd = 0;
    int staId = 0;
    hdd_context_t *pHddCtx;
    int ret, num_args;

    ENTER();

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

    if (extra == NULL) {
        hddLog(LOGE, FL("NULL extra buffer pointer"));
        return -EINVAL;
    }

    sub_cmd = wrqu->data.flags;
    num_args = wrqu->data.length;

    hddLog(LOG1, FL("Received length %d"), wrqu->data.length);

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

    if(( sub_cmd == WE_MCC_CONFIG_CREDENTIAL ) ||
        (sub_cmd == WE_MCC_CONFIG_PARAMS ))
    {
        if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
           (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
            pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
            staId = pStaCtx->conn_info.staId[0];
        } else if ((pAdapter->device_mode == WLAN_HDD_P2P_GO) ||
                 (pAdapter->device_mode == WLAN_HDD_SOFTAP)) {
            pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
            staId = pAPCtx->uBCStaId;
        } else {
            hddLog(LOGE, FL("Device mode %s(%d) not recognised"),
                   hdd_device_mode_to_string(pAdapter->device_mode),
                   pAdapter->device_mode);
            return 0;
        }
    }

    switch (sub_cmd)
    {
        case WE_LOG_DUMP_CMD:
            {
                hddLog(LOG1, "%s: LOG_DUMP %d arg1 %d arg2 %d arg3 %d arg4 %d",
                        __func__, apps_args[0], apps_args[1], apps_args[2],
                        apps_args[3], apps_args[4]);
                if (hHal)
                    return logPrintf(hHal, apps_args[0], apps_args[1],
                                     apps_args[2], apps_args[3], apps_args[4]);

            }
            break;
        case WE_IBSS_GET_PEER_INFO:
             {
                pr_info ( "Station ID = %d\n",apps_args[0]);
                hdd_wlan_get_ibss_peer_info(pAdapter, apps_args[0]);
             }
              break;

        case WE_P2P_NOA_CMD:
            {
                p2p_app_setP2pPs_t p2pNoA;

                if (pAdapter->device_mode != WLAN_HDD_P2P_GO) {
                    hddLog(LOGE,
                        FL("Setting NoA is not allowed in Device mode %s(%d)"),
                        hdd_device_mode_to_string(pAdapter->device_mode),
                        pAdapter->device_mode);
                    return -EINVAL;
                }

                p2pNoA.opp_ps = apps_args[0];
                p2pNoA.ctWindow = apps_args[1];
                p2pNoA.duration = apps_args[2];
                p2pNoA.interval  = apps_args[3];
                p2pNoA.count = apps_args[4];
                p2pNoA.single_noa_duration = apps_args[5];
                p2pNoA.psSelection = apps_args[6];

                hddLog(LOG1, "%s: P2P_NOA_ATTR:oppPS %d ctWindow %d duration %d "
                       "interval %d count %d single noa duration %d PsSelection %x",
                       __func__, apps_args[0], apps_args[1], apps_args[2],
                       apps_args[3], apps_args[4], apps_args[5], apps_args[6]);

                hdd_setP2pPs(dev, &p2pNoA);

            }
            break;

        case WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD:
            {
                hddLog(LOG1, "%s: SELECTIVE_MODULE_LOG %d arg1 %d arg2",
                        __func__, apps_args[0], apps_args[1]);
                vosTraceEnable(apps_args[0], apps_args[1]);
            }
            break;

        case WE_MTRACE_DUMP_CMD:
            {
                hddLog(LOG1, "%s: MTRACE_DUMP code %d session %d count %d "
                       "bitmask_of_module %d ",
                        __func__, apps_args[0], apps_args[1], apps_args[2],
                        apps_args[3]);
                if (hHal)
                    vosTraceDumpAll((void*)hHal , apps_args[0], apps_args[1],
                                    apps_args[2], apps_args[3]);

            }
            break;

        case WE_MCC_CONFIG_CREDENTIAL :
            {
                cmd = 287; //Command should be updated if there is any change
                           // in the Riva dump command
                if((apps_args[0] >= 40 ) && (apps_args[0] <= 160 ) && (hHal))
                {
                    logPrintf(hHal, cmd, staId, apps_args[0], apps_args[1], apps_args[2]);
                }
                else
                {
                     hddLog(LOGE, "%s : Enter valid MccCredential value between MIN :40 and MAX:160", __func__);
                     return 0;
                }
            }
            break;

        case WE_MCC_CONFIG_PARAMS :
            {
                cmd = 288; //command Should be updated if there is any change
                           // in the Riva dump command
                 hdd_validate_mcc_config(pAdapter, staId, apps_args[0], apps_args[1],apps_args[2]);
            }
        break;

#ifdef FEATURE_WLAN_TDLS
        case WE_TDLS_CONFIG_PARAMS :
            {
                tdls_config_params_t tdlsParams;

                tdlsParams.tdls                    = apps_args[0];
                tdlsParams.tx_period_t             = apps_args[1];
                tdlsParams.tx_packet_n             = apps_args[2];
                tdlsParams.discovery_period_t      = apps_args[3];
                tdlsParams.discovery_tries_n       = apps_args[4];
                tdlsParams.idle_timeout_t          = apps_args[5];
                tdlsParams.idle_packet_n           = apps_args[6];
                tdlsParams.rssi_hysteresis         = apps_args[7];
                tdlsParams.rssi_trigger_threshold  = apps_args[8];
                tdlsParams.rssi_teardown_threshold = apps_args[9];
                tdlsParams.rssi_delta              = apps_args[10];

                wlan_hdd_tdls_set_params(dev, &tdlsParams);
            }
        break;
#endif
        case WE_UNIT_TEST_CMD :
            {
                t_wma_unit_test_cmd *unitTestArgs;
                vos_msg_t msg = {0};
                int i, j;
                if ((apps_args[0] < WLAN_MODULE_ID_MIN) ||
                               (apps_args[0] >= WLAN_MODULE_ID_MAX)) {
                    hddLog(LOGE, FL("Invalid MODULE ID %d"), apps_args[0]);
                    return -EINVAL;
                }
                if ((apps_args[1] > (WMA_MAX_NUM_ARGS)) ||
                    (apps_args[1] < 0)) {
                    hddLog(LOGE, FL("Too Many/Few args %d"), apps_args[1]);
                    return -EINVAL;
                }
                unitTestArgs = vos_mem_malloc(sizeof(*unitTestArgs));
                if (NULL == unitTestArgs) {
                    hddLog(LOGE,
                      FL("vos_mem_alloc failed for unitTestArgs"));
                    return -ENOMEM;
                }
                unitTestArgs->vdev_id            = (int)pAdapter->sessionId;
                unitTestArgs->module_id          = apps_args[0];
                unitTestArgs->num_args           = apps_args[1];
                for (i = 0, j = 2; i < unitTestArgs->num_args; i++, j++) {
                    unitTestArgs->args[i] = apps_args[j];
                }
                msg.type = SIR_HAL_UNIT_TEST_CMD;
                msg.reserved = 0;
                msg.bodyptr = unitTestArgs;
                if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA,
                                                                    &msg)) {
                    vos_mem_free(unitTestArgs);
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                        FL("Not able to post UNIT_TEST_CMD message to WDA"));
                    return -EINVAL;
                }
            }
        break;

#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
        case WE_LED_FLASHING_PARAM:
            {
                int i;
                if (num_args != 5) {
                    hddLog(LOGE,
                          FL("gpio_control: 5 parameters are required"));
                    return -EINVAL;
                }

                for (i = 0; i < num_args; i++) {
                    if (apps_args[i] >= 0x7fffffff) {
                        hddLog(LOGE,
                               FL("gpio_control: parameter should be less than 0x7fffffff"));
                        return -EINVAL;
                    }
                }
                sme_SetLedFlashing(WLAN_HDD_GET_HAL_CTX(pAdapter),
                    0, apps_args[0], apps_args[1], apps_args[4]);
                sme_SetLedFlashing(WLAN_HDD_GET_HAL_CTX(pAdapter),
                    1, apps_args[2], apps_args[3], apps_args[4]);
            }
            break;
#endif

#ifdef MEMORY_DEBUG
        case WE_MEM_TRACE_DUMP:
            {
                int level = 0;
                if (num_args >= 1) {
                    level = apps_args[0];
                }
                vos_mem_trace_dump(level);
            }
            break;
#endif
#ifdef WLAN_FEATURE_MOTION_DETECTION
        case WE_MOTION_DET_CONFIG_PARAM:
            {
                tSirMotionDetConfig config;

                if (num_args != 15) {
                    hddLog(LOGE, FL("motion_det_config: <time_t1>"
                                                       " <time_t2>"
                                                       " <n1>"
                                                       " <n2>"
                                                       " <time_t1_gap>"
                                                       " <time_t2_gap>"
                                                       " <coarse K>"
                                                       " <fine K>"
                                                       " <coarse Q>"
                                                       " <fine Q>"
                                                       " <coarse thr high>"
                                                       " <fine thr threshold>"
                                                       " <coarse thr low>"
                                                       " <fine thr low>"
                                                       " <mode>"));
                    return -EINVAL;
                }

                config.vdev_id = (int)pAdapter->sessionId;
                config.time_t1 = apps_args[0];
                config.time_t2 = apps_args[1];
                config.n1 = apps_args[2];
                config.n2 = apps_args[3];
                config.time_t1_gap = apps_args[4];
                config.time_t2_gap = apps_args[5];
                config.coarse_K = apps_args[6];
                config.fine_K = apps_args[7];
                config.coarse_Q = apps_args[8];
                config.fine_Q = apps_args[9];
                config.md_coarse_thr_high = apps_args[10];
                config.md_fine_thr_high = apps_args[11];
                config.md_coarse_thr_low = apps_args[12];
                config.md_fine_thr_low = apps_args[13];

                pAdapter->motion_detection_mode = apps_args[14];

                sme_MotionDetConfig(hHal, &config);
            }
            break;
	case WE_MOTION_DET_BASE_LINE_CONFIG_PARAM:
            {
                tSirMotionDetBaseLineConfig config;
                if (num_args != 4) {
                    hddLog(LOGE,
                          FL("motion_det_base_line_config: <time>"
                                                          " <packet_gap>"
                                                          " <n>"
                                                          " <num_meas>"));
                    return -EINVAL;
                }

                config.vdev_id = (int)pAdapter->sessionId;
                config.bl_time_t = apps_args[0];
                config.bl_packet_gap = apps_args[1];
                config.bl_n = apps_args[2];
                config.bl_num_meas = apps_args[3];

                sme_MotionDetBaseLineConfig(hHal, &config);
            }
            break;
#endif
        case WE_SET_THERMAL_THROTTLE_CONFIG:
            {
                if (pHddCtx->cfg_ini->thermalMitigationEnable) {
                    hddLog(LOGE, "Thermal Mitigation enabled by driver "
                           "Ignoring user based thermal throttle parameters!");
                    return -EINVAL;
                }

                if (num_args != 6) {
                    hddLog(LOGE, FL("setThermalConfig: 6 args are required\n"
                           "Ex: iwpriv wlan0 setThermalConfig enable dc "
                           "dc_off_percent prio lower_thresh_deg upper_thresh_deg"));
                    return -EINVAL;
                }

                if (apps_args[0] < 0 || apps_args[1] < 0 || apps_args[2] < 0
                    || apps_args[3] < 0 || apps_args[4] < 0 || apps_args[5] < 0) {
                    hddLog(LOGE, FL("setThermalConfig: Invalid values"));
                    return -EINVAL;
                }

                if (apps_args[0] < 0 || apps_args[0] > 1) {
                    hddLog(LOGE, FL("setThermalConfig: Invalid Enable value"));
                    return -EINVAL;
                }


                if (apps_args[2] < 0 || apps_args[2] > 100) {
                    hddLog(LOGE, FL("setThermalConfig: Invalid dc_off_percent value"));
                    return -EINVAL;
                }

                if (apps_args[3] < 0 || apps_args[3] > 3) {
                    hddLog(LOGE, FL("setThermalConfig: Invalid Priority value"));
                    return -EINVAL;
                }

                if (apps_args[5] <= apps_args[4]) {
                    hddLog(LOGE, FL("setThermalConfig: Invalid Temp Threshold values"));
                    return -EINVAL;
                }

                hddLog(LOG1, "ARGS %x %x %x %x %x %x\n",apps_args[0], apps_args[1],
                       apps_args[2], apps_args[3], apps_args[4], apps_args[5]);

                ret = sme_thermal_throttle_set_conf_cmd(pAdapter, apps_args[0],
                                                     apps_args[1], apps_args[2],
                                                     apps_args[3]);
                if (ret != eHAL_STATUS_SUCCESS)
                    return -EINVAL;


                ret = sme_thermal_throttle_mgmt_cmd(pAdapter, apps_args[4],
                                                    apps_args[5]);
                if (ret != eHAL_STATUS_SUCCESS)
                    return -EINVAL;
            }
            break;

        case WE_SET_HPCS_PULSE_PARAMS_CONFIG:
            {
                tSirHpcsPulseParmasConfig config;
                if (num_args != 6) {
                    hddLog(LOGE, FL("setHpcsParams: 6 args are required\n"
                           "Ex: iwpriv wlan0 setHpcsParams start sync_time "
                           "pulse_interval active_sync_period gpio_pin pulse_width"));
                    return -EINVAL;
                }

                if ((0 == apps_args[0]) && (0 == apps_args[1])
                    && (0 == apps_args[2]) && (0 == apps_args[3])
                    && (0 == apps_args[4]) && (0 == apps_args[5])) {
                    hddLog(LOGE, FL("setHpcsParams: reset params"));
                } else if (apps_args[0] < 0 || apps_args[0] > 1
                    || apps_args[1] < 0 || apps_args[2] <= 10000
                    || apps_args[3] < 0 || apps_args[4] < 0
                    || apps_args[5] < 10000) {
                    hddLog(LOGE, FL("setHpcsParams: Invalid values"));
                    return -EINVAL;
                }

                hddLog(LOG1, "setHpcsParams vdev_id:%d args %x %x %x %x %x %x\n",
                              pAdapter->sessionId, apps_args[0], apps_args[1],
                              apps_args[2], apps_args[3], apps_args[4], apps_args[5]);

                config.vdev_id            = pAdapter->sessionId;
                config.start              = apps_args[0];
                config.sync_time          = apps_args[1];
                config.pulse_interval     = apps_args[2];
                config.active_sync_period = apps_args[3];
                config.gpio_pin           = apps_args[4];
                config.pulse_width        = apps_args[5];

                ret = sme_hpcs_pulse_params_conf_cmd(pAdapter, &config);

                if (ret != eHAL_STATUS_SUCCESS)
                    return -EINVAL;
            }
            break;
#ifdef AUDIO_MULTICAST_AGGR_SUPPORT
        case WE_AUDIO_AGGR_SET_GROUP_RATE:
            {
                if (num_args != (2 + 2*apps_args[1])) {
                    hddLog(LOGE, FL("au_set_rate: Invalid arguments"));
                    return -EINVAL;
                }
                ret = wlan_hdd_set_multicast_rate(pAdapter, apps_args);
                if (ret != eHAL_STATUS_SUCCESS)
                    return -EINVAL;
            }
            break;
        case WE_AUDIO_AGGR_SET_AUTO_RATE:
            {
                if (num_args != 6) {
                    hddLog(LOGE, FL("au_set_auto: Invalid arguments"));
                    return -EINVAL;
                }
                ret = wlan_hdd_set_multicast_auto_rate(pAdapter, apps_args);
                if (ret != eHAL_STATUS_SUCCESS)
                    return -EINVAL;
            }
            break;
        case WE_AUDIO_AGGR_SET_STA:
            {
                if ((num_args < 1) || (num_args > (MAX_GROUP_NUM*2 + 1))
                    || ((num_args & 0x1) == 0)) {
                        hddLog(LOGE, FL("au_set_sta: Invalid arguments"));
                        return -EINVAL;
                }
                ret = wlan_hdd_set_multicast_sta(pAdapter, apps_args, (num_args-1)/2);
                if (ret != eHAL_STATUS_SUCCESS)
                        return -EINVAL;
            }
            break;
#endif
        default:
            {
                hddLog(LOGE, FL("Invalid IOCTL command %d"), sub_cmd );
            }
            break;
    }
    EXIT();
    return 0;
}

/**
 * iw_hdd_set_var_ints_getnone() - set var ints getnone callback
 * @dev: pointer to net_device structure
 * @info: pointer to iw_request_info structure
 * @wrqu: pointer to iwreq_data
 * @extra; extra
 *
 * Return: 0 on success, error number otherwise
 *
 */
static int iw_hdd_set_var_ints_getnone(struct net_device *dev,
				       struct iw_request_info *info,
				       union iwreq_data *wrqu, char *extra)
{
	union iwreq_data u_priv_wrqu;
	int apps_args[MAX_VAR_ARGS] = {0};
	int ret, num_args;

	if (!capable(CAP_NET_ADMIN)) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			FL("permission check failed"));
		return -EPERM;
	}
	/* Helper function to get iwreq_data with compat handling. */
	if (hdd_priv_get_data(&u_priv_wrqu.data, wrqu))
		return -EINVAL;

	if (NULL == u_priv_wrqu.data.pointer) {
		hddLog(LOGE, FL("NULL data pointer"));
		return -EINVAL;
	}

	num_args = u_priv_wrqu.data.length;
	if (num_args > MAX_VAR_ARGS)
		num_args = MAX_VAR_ARGS;

	if (copy_from_user(apps_args, u_priv_wrqu.data.pointer,
			  (sizeof(int)) * num_args)) {
		hddLog(LOGE, FL("failed to copy data from user buffer"));
		return -EFAULT;
	}

	vos_ssr_protect(__func__);
	ret = __iw_set_var_ints_getnone(dev, info, &u_priv_wrqu,
					(char *)&apps_args);
	vos_ssr_unprotect(__func__);
	return ret;
}


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

   vos_ssr_protect(__func__);
   ret = __iw_set_var_ints_getnone(dev, info, wrqu, extra);
   vos_ssr_unprotect(__func__);
   return ret;
}


static int __iw_add_tspec(struct net_device *dev,
                          struct iw_request_info *info,
                          union iwreq_data *wrqu, char *extra)
{
   hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
   hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
   hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *)extra;
   int params[HDD_WLAN_WMM_PARAM_COUNT];
   sme_QosWmmTspecInfo tSpec;
   v_U32_t handle;
   struct iw_point s_priv_data;
   hdd_context_t *hdd_ctx;
   int ret;

   ENTER();

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

   /*
    * Make sure the application is sufficiently privileged
    * note that the kernel will do this for "set" ioctls, but since
    * this ioctl wants to return status to user space it must be
    * defined as a "get" ioctl.
    */
   if (!capable(CAP_NET_ADMIN))
   {
      return -EPERM;
   }

   // we must be associated in order to add a tspec
   if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
   {
      *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
      return 0;
   }

   // since we are defined to be a "get" ioctl, and since the number
   // of params exceeds the number of params that wireless extensions
   // will pass down in the iwreq_data, we must copy the "set" params.
   // We must handle the compat for iwreq_data in 32U/64K environment.

   // helper function to get iwreq_data with compat handling.
   if (hdd_priv_get_data(&s_priv_data, wrqu)) {
      *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
      return 0;
   }

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

   // from user space ourselves
   if (copy_from_user(&params, s_priv_data.pointer, sizeof(params))) {
      // hmmm, can't get them
      return -EIO;
   }

   // clear the tspec
   memset(&tSpec, 0, sizeof(tSpec));

   // validate the handle
   handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
   if (HDD_WMM_HANDLE_IMPLICIT == handle)
   {
      // that one is reserved
      *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
      return 0;
   }

   // validate the TID
   if (params[HDD_WLAN_WMM_PARAM_TID] > 7)
   {
      // out of range
      *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
      return 0;
   }
   tSpec.ts_info.tid = params[HDD_WLAN_WMM_PARAM_TID];

   // validate the direction
   switch (params[HDD_WLAN_WMM_PARAM_DIRECTION])
   {
   case HDD_WLAN_WMM_DIRECTION_UPSTREAM:
      tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_UPLINK;
      break;

   case HDD_WLAN_WMM_DIRECTION_DOWNSTREAM:
      tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_DOWNLINK;
      break;

   case HDD_WLAN_WMM_DIRECTION_BIDIRECTIONAL:
      tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_BOTH;
      break;

   default:
      // unknown
      *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
      return 0;
   }

   tSpec.ts_info.psb = params[HDD_WLAN_WMM_PARAM_APSD];

   // validate the user priority
   if (params[HDD_WLAN_WMM_PARAM_USER_PRIORITY] >= SME_QOS_WMM_UP_MAX)
   {
      // out of range
      *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
      return 0;
   }
   tSpec.ts_info.up = params[HDD_WLAN_WMM_PARAM_USER_PRIORITY];
   if(0 > tSpec.ts_info.up || SME_QOS_WMM_UP_MAX < tSpec.ts_info.up)
   {
   hddLog(VOS_TRACE_LEVEL_ERROR,"***ts_info.up out of bounds***");
   return 0;
   }

   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
             "%s:TS_INFO PSB %d UP %d !!!", __func__,
             tSpec.ts_info.psb, tSpec.ts_info.up);

   tSpec.nominal_msdu_size = params[HDD_WLAN_WMM_PARAM_NOMINAL_MSDU_SIZE];
   tSpec.maximum_msdu_size = params[HDD_WLAN_WMM_PARAM_MAXIMUM_MSDU_SIZE];
   tSpec.min_data_rate = params[HDD_WLAN_WMM_PARAM_MINIMUM_DATA_RATE];
   tSpec.mean_data_rate = params[HDD_WLAN_WMM_PARAM_MEAN_DATA_RATE];
   tSpec.peak_data_rate = params[HDD_WLAN_WMM_PARAM_PEAK_DATA_RATE];
   tSpec.max_burst_size = params[HDD_WLAN_WMM_PARAM_MAX_BURST_SIZE];
   tSpec.min_phy_rate = params[HDD_WLAN_WMM_PARAM_MINIMUM_PHY_RATE];
   tSpec.surplus_bw_allowance = params[HDD_WLAN_WMM_PARAM_SURPLUS_BANDWIDTH_ALLOWANCE];
   tSpec.min_service_interval = params[HDD_WLAN_WMM_PARAM_SERVICE_INTERVAL];
   tSpec.max_service_interval = params[HDD_WLAN_WMM_PARAM_MAX_SERVICE_INTERVAL];
   tSpec.suspension_interval = params[HDD_WLAN_WMM_PARAM_SUSPENSION_INTERVAL];
   tSpec.inactivity_interval = params[HDD_WLAN_WMM_PARAM_INACTIVITY_INTERVAL];

   tSpec.ts_info.burst_size_defn = params[HDD_WLAN_WMM_PARAM_BURST_SIZE_DEFN];

   // validate the ts info ack policy
   switch (params[HDD_WLAN_WMM_PARAM_ACK_POLICY])
   {
   case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK:
      tSpec.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
      break;

   case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK:
      tSpec.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
      break;

   default:
      // unknown
      *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
      return 0;
   }

   *pStatus = hdd_wmm_addts(pAdapter, handle, &tSpec);
   EXIT();
   return 0;
}

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

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

	return ret;
}

static int __iw_del_tspec(struct net_device *dev,
                          struct iw_request_info *info,
                          union iwreq_data *wrqu, char *extra)
{
   hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
   int *params = (int *)extra;
   hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *)extra;
   v_U32_t handle;
   hdd_context_t *hdd_ctx;
   int ret;

   ENTER();

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

   /*
    * Make sure the application is sufficiently privileged
    * note that the kernel will do this for "set" ioctls, but since
    * this ioctl wants to return status to user space it must be
    * defined as a "get" ioctl.
    */
   if (!capable(CAP_NET_ADMIN))
   {
      return -EPERM;
   }

   // although we are defined to be a "get" ioctl, the params we require
   // will fit in the iwreq_data, therefore unlike iw_add_tspec() there
   // is no need to copy the params from user space

   // validate the handle
   handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
   if (HDD_WMM_HANDLE_IMPLICIT == handle)
   {
      // that one is reserved
      *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
      return 0;
   }

   *pStatus = hdd_wmm_delts(pAdapter, handle);
   EXIT();
   return 0;
}

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

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

	return ret;
}

static int __iw_get_tspec(struct net_device *dev,
                          struct iw_request_info *info,
                          union iwreq_data *wrqu, char *extra)
{
   hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
   int *params = (int *)extra;
   hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *)extra;
   v_U32_t handle;
   hdd_context_t *hdd_ctx;
   int ret;

   ENTER();

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

   // although we are defined to be a "get" ioctl, the params we require
   // will fit in the iwreq_data, therefore unlike iw_add_tspec() there
   // is no need to copy the params from user space

   // validate the handle
   handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
   if (HDD_WMM_HANDLE_IMPLICIT == handle)
   {
      // that one is reserved
      *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
      return 0;
   }

   *pStatus = hdd_wmm_checkts(pAdapter, handle);
   EXIT();
   return 0;
}

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

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

	return ret;
}

#ifdef WLAN_FEATURE_VOWIFI_11R
//
//
// Each time the supplicant has the auth_request or reassoc request
// IEs ready. This is pushed to the driver. The driver will inturn use
// it to send out the auth req and reassoc req for 11r FT Assoc.
//
static int __iw_set_fties(struct net_device *dev,
                          struct iw_request_info *info,
                          union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    hdd_context_t *hdd_ctx;
    int ret;

    ENTER();

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

    if (!wrqu->data.length)
    {
        hddLog(LOGE, FL("called with 0 length IEs"));
        return -EINVAL;
    }
    if (wrqu->data.pointer == NULL)
    {
        hddLog(LOGE, FL("called with NULL IE"));
        return -EINVAL;
    }

    // Added for debug on reception of Re-assoc Req.
    if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
    {
        hddLog(LOGE, FL("Called with Ie of length = %d when not associated"),
            wrqu->data.length);
        hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
    }

#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
    hddLog(LOG1, FL("%s called with Ie of length = %d"), __func__, wrqu->data.length);
#endif

    // Pass the received FT IEs to SME
    sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, extra,
        wrqu->data.length);
    EXIT();
    return 0;
}

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

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

	return ret;
}
#endif

static int __iw_set_dynamic_mcbc_filter(struct net_device *dev,
                                        struct iw_request_info *info,
                                        union iwreq_data *wrqu,
                                        char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    tpRcvFltMcAddrList pRequest = (tpRcvFltMcAddrList)extra;
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    tpSirWlanSetRxpFilters wlanRxpFilterParam;
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    tpSirRcvFltMcAddrList mc_addr_list_ptr;
    int idx;
    eHalStatus ret_val;

    ENTER();
    if (pHddCtx->isLogpInProgress)
    {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                                  "%s:LOGP in Progress. Ignore!!!", __func__);
       return -EBUSY;
    }
    if ((HDD_MULTICAST_FILTER_LIST == pRequest->mcastBcastFilterSetting) ||
        (HDD_MULTICAST_FILTER_LIST_CLEAR == pRequest->mcastBcastFilterSetting))
    {
#ifdef WLAN_FEATURE_PACKET_FILTERING

        mc_addr_list_ptr = vos_mem_malloc(sizeof(tSirRcvFltMcAddrList));
        if (NULL == mc_addr_list_ptr)
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                   "%s: vos_mem_alloc failed", __func__);
            return -ENOMEM;
        }

        mc_addr_list_ptr->ulMulticastAddrCnt = pRequest->mcast_addr_cnt;

        if (mc_addr_list_ptr->ulMulticastAddrCnt > HDD_MAX_NUM_MULTICAST_ADDRESS)
            mc_addr_list_ptr->ulMulticastAddrCnt = HDD_MAX_NUM_MULTICAST_ADDRESS;

        hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s MC Addr List Cnt %d", __func__,
               mc_addr_list_ptr->ulMulticastAddrCnt);

        for (idx = 0; idx < mc_addr_list_ptr->ulMulticastAddrCnt; idx++)
        {
            memcpy(&mc_addr_list_ptr->multicastAddr[idx],
                   pRequest->multicastAddr[idx], HDD_WLAN_MAC_ADDR_LEN);

            hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s MC Addr for Idx %d ="MAC_ADDRESS_STR, __func__,
                   idx, MAC_ADDR_ARRAY(mc_addr_list_ptr->multicastAddr[idx]));
        }

        if (HDD_MULTICAST_FILTER_LIST_CLEAR == pRequest->mcastBcastFilterSetting)
            mc_addr_list_ptr->action = HDD_DELETE_MCBC_FILTERS_FROM_FW; //clear
        else
            mc_addr_list_ptr->action = HDD_SET_MCBC_FILTERS_TO_FW; //set

        ret_val = sme_8023MulticastList(hHal, pAdapter->sessionId, mc_addr_list_ptr);
        vos_mem_free(mc_addr_list_ptr);
        if (eHAL_STATUS_SUCCESS != ret_val)
        {
            hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to Set MC Address List",
                   __func__);
            return -EINVAL;
        }
#endif //WLAN_FEATURE_PACKET_FILTERING
    }
    else
    {

        hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
               "%s: Set MC BC Filter Config request: %d suspend %d",
               __func__, pRequest->mcastBcastFilterSetting,
               pHddCtx->hdd_wlan_suspended);

        pHddCtx->configuredMcastBcastFilter = pRequest->mcastBcastFilterSetting;

        if (pHddCtx->hdd_wlan_suspended)
        {
            wlanRxpFilterParam = vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
            if (NULL == wlanRxpFilterParam)
            {
                hddLog(VOS_TRACE_LEVEL_ERROR,
                       "%s: vos_mem_alloc failed", __func__);
                return -EINVAL;
            }

            wlanRxpFilterParam->configuredMcstBcstFilterSetting =
                pRequest->mcastBcastFilterSetting;
            wlanRxpFilterParam->setMcstBcstFilter = TRUE;

            hdd_conf_hostoffload(pAdapter, TRUE);
            wlanRxpFilterParam->configuredMcstBcstFilterSetting =
                                pHddCtx->configuredMcastBcastFilter;

            hddLog(VOS_TRACE_LEVEL_INFO, "%s:MC/BC changed Req %d Set %d En %d",
                   __func__,
                   pHddCtx->configuredMcastBcastFilter,
                   wlanRxpFilterParam->configuredMcstBcstFilterSetting,
                   wlanRxpFilterParam->setMcstBcstFilter);

            if (eHAL_STATUS_SUCCESS !=
                    sme_ConfigureRxpFilter(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                           wlanRxpFilterParam))
            {
                hddLog(VOS_TRACE_LEVEL_ERROR,
                       "%s: Failure to execute set HW MC/BC Filter request",
                       __func__);
                vos_mem_free(wlanRxpFilterParam);
                return -EINVAL;
            }

            if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)
            {
                pHddCtx->sus_res_mcastbcast_filter =
                             pRequest->mcastBcastFilterSetting;
            }
        }
    }
    EXIT();
    return 0;
}

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

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

	return ret;
}

static int __iw_clear_dynamic_mcbc_filter(struct net_device *dev,
                                          struct iw_request_info *info,
                                          union iwreq_data *wrqu,
                                          char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    tpSirWlanSetRxpFilters wlanRxpFilterParam;

    ENTER();

    if (!capable(CAP_NET_ADMIN)) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 FL("permission check failed"));
        return -EPERM;
    }
    //Reset the filter to INI value as we have to clear the dynamic filter
    pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;

    //Configure FW with new setting
    if (pHddCtx->hdd_wlan_suspended)
    {
        wlanRxpFilterParam = vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
        if (NULL == wlanRxpFilterParam)
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                   "%s: vos_mem_alloc failed", __func__);
            return -EINVAL;
        }

        wlanRxpFilterParam->configuredMcstBcstFilterSetting =
            pHddCtx->configuredMcastBcastFilter;
        wlanRxpFilterParam->setMcstBcstFilter = TRUE;

        hdd_conf_hostoffload(pAdapter, TRUE);
        wlanRxpFilterParam->configuredMcstBcstFilterSetting =
                            pHddCtx->configuredMcastBcastFilter;

        if (eHAL_STATUS_SUCCESS !=
                  sme_ConfigureRxpFilter(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                         wlanRxpFilterParam))
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                   "%s: Failure to execute set HW MC/BC Filter request",
                   __func__);
            vos_mem_free(wlanRxpFilterParam);
            return -EINVAL;
        }

        if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)
        {
            pHddCtx->sus_res_mcastbcast_filter =
                     pHddCtx->cfg_ini->mcastBcastFilterSetting;
        }
    }
    EXIT();
    return 0;
}

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

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

	return ret;
}

static int __iw_set_host_offload(struct net_device *dev,
                                 struct iw_request_info *info,
                                 union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    tpHostOffloadRequest pRequest = (tpHostOffloadRequest) extra;
    tSirHostOffloadReq offloadRequest;
    hdd_context_t *hdd_ctx;
    int ret;

    ENTER();

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

    if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
    {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                                  "%s:LOGP dev is not in CONNECTED state, ignore!!!", __func__);
       return -EINVAL;
    }

    /* Debug display of request components. */
    switch (pRequest->offloadType)
    {
        case WLAN_IPV4_ARP_REPLY_OFFLOAD:
            hddLog(VOS_TRACE_LEVEL_WARN, "%s: Host offload request: ARP reply", __func__);
            switch (pRequest->enableOrDisable)
            {
                case WLAN_OFFLOAD_DISABLE:
                    hddLog(VOS_TRACE_LEVEL_WARN, "   disable");
                    break;
                case WLAN_OFFLOAD_ARP_AND_BC_FILTER_ENABLE:
                    hddLog(VOS_TRACE_LEVEL_WARN, "   BC Filtering enable");
                case WLAN_OFFLOAD_ENABLE:
                    hddLog(VOS_TRACE_LEVEL_WARN, "   ARP offload enable");
                    hddLog(VOS_TRACE_LEVEL_WARN, "   IP address: %d.%d.%d.%d",
                            pRequest->params.hostIpv4Addr[0], pRequest->params.hostIpv4Addr[1],
                            pRequest->params.hostIpv4Addr[2], pRequest->params.hostIpv4Addr[3]);
            }
            break;

    case WLAN_IPV6_NEIGHBOR_DISCOVERY_OFFLOAD:
        hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: Host offload request: neighbor discovery",
               __func__);
        switch (pRequest->enableOrDisable)
        {
        case WLAN_OFFLOAD_DISABLE:
            hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "   disable");
            break;
        case WLAN_OFFLOAD_ENABLE:
            hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "   enable");
            hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "   IP address: %x:%x:%x:%x:%x:%x:%x:%x",
                   *(v_U16_t *)(pRequest->params.hostIpv6Addr),
                   *(v_U16_t *)(pRequest->params.hostIpv6Addr + 2),
                   *(v_U16_t *)(pRequest->params.hostIpv6Addr + 4),
                   *(v_U16_t *)(pRequest->params.hostIpv6Addr + 6),
                   *(v_U16_t *)(pRequest->params.hostIpv6Addr + 8),
                   *(v_U16_t *)(pRequest->params.hostIpv6Addr + 10),
                   *(v_U16_t *)(pRequest->params.hostIpv6Addr + 12),
                   *(v_U16_t *)(pRequest->params.hostIpv6Addr + 14));
        }
    }

    vos_mem_zero(&offloadRequest, sizeof(offloadRequest));
    offloadRequest.offloadType = pRequest->offloadType;
    offloadRequest.enableOrDisable = pRequest->enableOrDisable;
    vos_mem_copy(&offloadRequest.params, &pRequest->params,
                 sizeof(pRequest->params));
    vos_mem_copy(&offloadRequest.bssId, &pRequest->bssId.bytes,
                 VOS_MAC_ADDRESS_LEN);

    if (eHAL_STATUS_SUCCESS != sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                        pAdapter->sessionId, &offloadRequest))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to execute host offload request",
               __func__);
        return -EINVAL;
    }
    EXIT();
    return 0;
}

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

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

	return ret;
}

static int __iw_set_keepalive_params(struct net_device *dev,
                                     struct iw_request_info *info,
                                     union iwreq_data *wrqu,
                                     char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    tpSirKeepAliveReq pRequest = (tpSirKeepAliveReq) extra;
    hdd_context_t *hdd_ctx;
    int ret;

    ENTER();

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

    if (wrqu->data.length != sizeof(*pRequest)) {
        hddLog(LOGE, FL("Invalid length %d"), wrqu->data.length);
        return -EINVAL;
    }

    if (pRequest->timePeriod > WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMAX) {
        hddLog(LOGE, FL("Value of timePeriod exceed Max limit %d"),
               pRequest->timePeriod);
        return -EINVAL;
    }

    /* Debug display of request components. */
    hddLog(VOS_TRACE_LEVEL_INFO,
           "%s: Set Keep Alive Request : TimePeriod %d size %zu",
           __func__, pRequest->timePeriod, sizeof(tKeepAliveRequest));

      switch (pRequest->packetType)
      {
        case WLAN_KEEP_ALIVE_NULL_PKT:
            hddLog(VOS_TRACE_LEVEL_WARN, "%s: Keep Alive Request: Tx NULL", __func__);
            break;

        case WLAN_KEEP_ALIVE_UNSOLICIT_ARP_RSP:
            hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: Keep Alive Request: Tx UnSolicited ARP RSP",
               __func__);

            hddLog(VOS_TRACE_LEVEL_WARN, "  Host IP address: %d.%d.%d.%d",
            pRequest->hostIpv4Addr[0], pRequest->hostIpv4Addr[1],
            pRequest->hostIpv4Addr[2], pRequest->hostIpv4Addr[3]);

            hddLog(VOS_TRACE_LEVEL_WARN, "  Dest IP address: %d.%d.%d.%d",
            pRequest->destIpv4Addr[0], pRequest->destIpv4Addr[1],
            pRequest->destIpv4Addr[2], pRequest->destIpv4Addr[3]);

            hddLog(VOS_TRACE_LEVEL_WARN, "  Dest MAC address: %d:%d:%d:%d:%d:%d",
            pRequest->destMacAddr[0], pRequest->destMacAddr[1],
            pRequest->destMacAddr[2], pRequest->destMacAddr[3],
            pRequest->destMacAddr[4], pRequest->destMacAddr[5]);
            break;
      }

       hddLog(LOG1, FL("Keep alive period  %d"), pRequest->timePeriod);

    if (eHAL_STATUS_SUCCESS != sme_SetKeepAlive(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                        pAdapter->sessionId, pRequest))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to execute Keep Alive",
               __func__);
        return -EINVAL;
    }
    EXIT();
    return 0;
}

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

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

	return ret;
}

#ifdef WLAN_FEATURE_PACKET_FILTERING
int wlan_hdd_set_filter(hdd_context_t *pHddCtx, tpPacketFilterCfg pRequest,
                            tANI_U8 sessionId)
{
    tSirRcvPktFilterCfgType    packetFilterSetReq = {0};
    tSirRcvFltPktClearParam    packetFilterClrReq = {0};
    int i=0;

    if (pHddCtx->cfg_ini->disablePacketFilter)
    {
        hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Packet Filtering Disabled. Returning ",
                __func__ );
        return 0;
    }
    if (pHddCtx->isLogpInProgress)
    {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                                  "%s:LOGP in Progress. Ignore!!!", __func__);
       return -EBUSY;
    }
    /* Debug display of request components. */
    hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Packet Filter Request : FA %d params %d",
            __func__, pRequest->filterAction, pRequest->numParams);

    switch (pRequest->filterAction)
    {
        case HDD_RCV_FILTER_SET:
            hddLog(VOS_TRACE_LEVEL_INFO, "%s: Set Packet Filter Request for Id: %d",
                    __func__, pRequest->filterId);

            packetFilterSetReq.filterId = pRequest->filterId;
            if ( pRequest->numParams >= HDD_MAX_CMP_PER_PACKET_FILTER)
            {
                hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Number of Params exceed Max limit %d",
                        __func__, pRequest->numParams);
                return -EINVAL;
            }
            packetFilterSetReq.numFieldParams = pRequest->numParams;
            packetFilterSetReq.coalesceTime = 0;
            packetFilterSetReq.filterType = 1;
            for (i=0; i < pRequest->numParams; i++)
            {
                packetFilterSetReq.paramsData[i].protocolLayer = pRequest->paramsData[i].protocolLayer;
                packetFilterSetReq.paramsData[i].cmpFlag = pRequest->paramsData[i].cmpFlag;
                packetFilterSetReq.paramsData[i].dataOffset = pRequest->paramsData[i].dataOffset;
                packetFilterSetReq.paramsData[i].dataLength = pRequest->paramsData[i].dataLength;
                packetFilterSetReq.paramsData[i].reserved = 0;

                hddLog(VOS_TRACE_LEVEL_INFO, "Proto %d Comp Flag %d Filter Type %d",
                        pRequest->paramsData[i].protocolLayer, pRequest->paramsData[i].cmpFlag,
                        packetFilterSetReq.filterType);

                hddLog(VOS_TRACE_LEVEL_INFO, "Data Offset %d Data Len %d",
                        pRequest->paramsData[i].dataOffset, pRequest->paramsData[i].dataLength);
                if ((sizeof(packetFilterSetReq.paramsData[i].compareData)) <
                           (pRequest->paramsData[i].dataLength))
                    return -EINVAL;

                memcpy(&packetFilterSetReq.paramsData[i].compareData,
                        pRequest->paramsData[i].compareData, pRequest->paramsData[i].dataLength);
                memcpy(&packetFilterSetReq.paramsData[i].dataMask,
                        pRequest->paramsData[i].dataMask, pRequest->paramsData[i].dataLength);

                hddLog(VOS_TRACE_LEVEL_INFO, "CData %d CData %d CData %d CData %d CData %d CData %d",
                        pRequest->paramsData[i].compareData[0], pRequest->paramsData[i].compareData[1],
                        pRequest->paramsData[i].compareData[2], pRequest->paramsData[i].compareData[3],
                        pRequest->paramsData[i].compareData[4], pRequest->paramsData[i].compareData[5]);

                hddLog(VOS_TRACE_LEVEL_INFO, "MData %d MData %d MData %d MData %d MData %d MData %d",
                        pRequest->paramsData[i].dataMask[0], pRequest->paramsData[i].dataMask[1],
                        pRequest->paramsData[i].dataMask[2], pRequest->paramsData[i].dataMask[3],
                        pRequest->paramsData[i].dataMask[4], pRequest->paramsData[i].dataMask[5]);
            }

            if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterSetFilter(pHddCtx->hHal, &packetFilterSetReq, sessionId))
            {
                hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to execute Set Filter",
                        __func__);
                return -EINVAL;
            }

            break;

        case HDD_RCV_FILTER_CLEAR:

            hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: Clear Packet Filter Request for Id: %d",
                    __func__, pRequest->filterId);
            packetFilterClrReq.filterId = pRequest->filterId;
            if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterClearFilter(pHddCtx->hHal, &packetFilterClrReq, sessionId))
            {
                hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to execute Clear Filter",
                        __func__);
                return -EINVAL;
            }
            break;

        default :
            hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: Packet Filter Request: Invalid %d",
                    __func__, pRequest->filterAction);
            return -EINVAL;
    }
    return 0;
}

int wlan_hdd_setIPv6Filter(hdd_context_t *pHddCtx, tANI_U8 filterType,
                           tANI_U8 sessionId)
{
    tSirRcvPktFilterCfgType    packetFilterSetReq = {0};
    tSirRcvFltPktClearParam    packetFilterClrReq = {0};

    if (NULL == pHddCtx)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL(" NULL HDD Context Passed"));
        return -EINVAL;
    }

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

    if (pHddCtx->cfg_ini->disablePacketFilter)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
                "%s: Packet Filtering Disabled. Returning ",
                __func__ );
        return -EINVAL;
    }

    switch (filterType)
    {
        /* For setting IPV6 MC and UC Filter we need to configure
         * 2 filters, one for MC and one for UC.
         * The Filter ID shouldn't be swapped, which results in making
         * UC Filter ineffective.
         * We have hard coded all the values
         *
         * Reason for a separate UC filter is because, driver need to
         * specify the FW that the specific filter is for unicast
         * otherwise FW will not pass the unicast frames by default
         * through the filter. This is required to avoid any performance
         * hits when no unicast filter is set and only MC/BC are set.
         * The way driver informs host is by using the MAC protocol
         * layer, CMP flag set to MAX, CMP Data set to 1.
         */

    case HDD_FILTER_IPV6_MC_UC:
        /* Setting IPV6 MC Filter below
         */
        packetFilterSetReq.filterType = HDD_RCV_FILTER_SET;
        packetFilterSetReq.filterId = HDD_FILTER_ID_IPV6_MC;
        packetFilterSetReq.numFieldParams = 2;
        packetFilterSetReq.paramsData[0].protocolLayer =
                                         HDD_FILTER_PROTO_TYPE_MAC;
        packetFilterSetReq.paramsData[0].cmpFlag =
                                         HDD_FILTER_CMP_TYPE_NOT_EQUAL;
        packetFilterSetReq.paramsData[0].dataOffset =
                                         WLAN_HDD_80211_FRM_DA_OFFSET;
        packetFilterSetReq.paramsData[0].dataLength = 1;
        packetFilterSetReq.paramsData[0].compareData[0] =
                                         HDD_IPV6_MC_CMP_DATA;

        packetFilterSetReq.paramsData[1].protocolLayer =
                                         HDD_FILTER_PROTO_TYPE_ARP;
        packetFilterSetReq.paramsData[1].cmpFlag =
                                         HDD_FILTER_CMP_TYPE_NOT_EQUAL;
        packetFilterSetReq.paramsData[1].dataOffset = ETH_ALEN;
        packetFilterSetReq.paramsData[1].dataLength = 2;
        packetFilterSetReq.paramsData[1].compareData[0] =
                                         HDD_IPV6_CMP_DATA_0;
        packetFilterSetReq.paramsData[1].compareData[1] =
                                         HDD_IPV6_CMP_DATA_1;


        if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterSetFilter(pHddCtx->hHal,
                                    &packetFilterSetReq, sessionId))
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    "%s: Failure to execute Set IPv6 Multicast Filter",
                    __func__);
            return -EINVAL;
        }

        memset( &packetFilterSetReq, 0, sizeof(tSirRcvPktFilterCfgType));

        /*
         * Setting IPV6 UC Filter below
         */
        packetFilterSetReq.filterType = HDD_RCV_FILTER_SET;
        packetFilterSetReq.filterId = HDD_FILTER_ID_IPV6_UC;
        packetFilterSetReq.numFieldParams = 2;
        packetFilterSetReq.paramsData[0].protocolLayer =
                                         HDD_FILTER_PROTO_TYPE_MAC;
        packetFilterSetReq.paramsData[0].cmpFlag =
                                         HDD_FILTER_CMP_TYPE_MAX;
        packetFilterSetReq.paramsData[0].dataOffset = 0;
        packetFilterSetReq.paramsData[0].dataLength = 1;
        packetFilterSetReq.paramsData[0].compareData[0] =
                                         HDD_IPV6_UC_CMP_DATA;

        packetFilterSetReq.paramsData[1].protocolLayer =
                                         HDD_FILTER_PROTO_TYPE_ARP;
        packetFilterSetReq.paramsData[1].cmpFlag =
                                         HDD_FILTER_CMP_TYPE_NOT_EQUAL;
        packetFilterSetReq.paramsData[1].dataOffset = ETH_ALEN;
        packetFilterSetReq.paramsData[1].dataLength = 2;
        packetFilterSetReq.paramsData[1].compareData[0] =
                                         HDD_IPV6_CMP_DATA_0;
        packetFilterSetReq.paramsData[1].compareData[1] =
                                         HDD_IPV6_CMP_DATA_1;

        if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterSetFilter(pHddCtx->hHal,
                                    &packetFilterSetReq, sessionId))
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    "%s: Failure to execute Set IPv6 Unicast Filter",
                    __func__);
            return -EINVAL;
        }

        break;

    case HDD_FILTER_IPV6_MC:
        /*
         * IPV6 UC Filter might be already set,
         * clear the UC Filter. As the Filter
         * IDs are static, we can directly clear it.
         */
        packetFilterSetReq.filterType = HDD_RCV_FILTER_SET;
        packetFilterClrReq.filterId = HDD_FILTER_ID_IPV6_UC;
        if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterClearFilter(pHddCtx->hHal,
                                    &packetFilterClrReq, sessionId))
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    "%s: Failure to execute Clear IPv6 Unicast Filter",
                    __func__);
            return -EINVAL;
        }

        /*
         * Setting IPV6 MC Filter below
         */
        packetFilterSetReq.filterId = HDD_FILTER_ID_IPV6_MC;
        packetFilterSetReq.numFieldParams = 2;
        packetFilterSetReq.paramsData[0].protocolLayer =
                                         HDD_FILTER_PROTO_TYPE_MAC;
        packetFilterSetReq.paramsData[0].cmpFlag =
                                         HDD_FILTER_CMP_TYPE_NOT_EQUAL;
        packetFilterSetReq.paramsData[0].dataOffset =
                                         WLAN_HDD_80211_FRM_DA_OFFSET;
        packetFilterSetReq.paramsData[0].dataLength = 1;
        packetFilterSetReq.paramsData[0].compareData[0] =
                                         HDD_IPV6_MC_CMP_DATA;

        packetFilterSetReq.paramsData[1].protocolLayer =
                                         HDD_FILTER_PROTO_TYPE_ARP;
        packetFilterSetReq.paramsData[1].cmpFlag =
                                         HDD_FILTER_CMP_TYPE_NOT_EQUAL;
        packetFilterSetReq.paramsData[1].dataOffset = ETH_ALEN;
        packetFilterSetReq.paramsData[1].dataLength = 2;
        packetFilterSetReq.paramsData[1].compareData[0] =
                                         HDD_IPV6_CMP_DATA_0;
        packetFilterSetReq.paramsData[1].compareData[1] =
                                         HDD_IPV6_CMP_DATA_1;


        if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterSetFilter(pHddCtx->hHal,
                                    &packetFilterSetReq, sessionId))
        {
            hddLog(VOS_TRACE_LEVEL_ERROR,
                    "%s: Failure to execute Set IPv6 Multicast Filter",
                    __func__);
            return -EINVAL;
        }
        break;

    default :
        hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
                "%s: Packet Filter Request: Invalid",
                __func__);
        return -EINVAL;
    }
    return 0;
}

/**
 * wlan_hdd_set_mc_addr_list() - Set multicast address list
 * @pAdapter: Adapter context
 * @set: flag to notify set/clear action on the multicast addr
 *
 * Returns: 0 on success, errno on failure
 */
int wlan_hdd_set_mc_addr_list(hdd_adapter_t *pAdapter, v_U8_t set)
{
    v_U8_t i;
    int ret = 0;
    tpSirRcvFltMcAddrList pMulticastAddrs = NULL;
    tHalHandle hHal;
    hdd_context_t* pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
    hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

    ENTER();

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

    hHal = pHddCtx->hHal;

    if (NULL == hHal) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("HAL Handle is NULL"));
        return -EINVAL;
    }

    if (!sta_ctx) {
        hddLog(LOGE, "sta_ctx is NULL");
        return -EINVAL;
    }

    if (pHddCtx->cfg_ini->fEnableMCAddrList) {
        pMulticastAddrs = vos_mem_malloc(sizeof(tSirRcvFltMcAddrList));
        if (NULL == pMulticastAddrs) {
            hddLog(VOS_TRACE_LEVEL_ERROR, FL("Could not allocate Memory"));
            return -ENOMEM;
        }
        vos_mem_zero(pMulticastAddrs, sizeof(tSirRcvFltMcAddrList));
        pMulticastAddrs->action = set;

        if (set) {
            if (pAdapter->mc_addr_list.mc_cnt &&
                     (((pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
                       pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) &&
                       hdd_connIsConnected(sta_ctx)) ||
                     (WLAN_HDD_IS_NDI(pAdapter) &&
                       WLAN_HDD_IS_NDI_CONNECTED(pAdapter)))) {
                if (pAdapter->mc_addr_list.mc_cnt >
                          HDD_MAX_NUM_MULTICAST_ADDRESS) {
                    hddLog(LOGE, FL("mc_cnt: %u max: %u"),
                           pAdapter->mc_addr_list.mc_cnt,
                           HDD_MAX_NUM_MULTICAST_ADDRESS);
                    pAdapter->mc_addr_list.mc_cnt =
                        HDD_MAX_NUM_MULTICAST_ADDRESS;
                }
                pMulticastAddrs->ulMulticastAddrCnt =
                                 pAdapter->mc_addr_list.mc_cnt;
                for (i = 0; i < pAdapter->mc_addr_list.mc_cnt; i++) {
                    memcpy(pMulticastAddrs->multicastAddr[i],
                           &pAdapter->mc_addr_list.addr[i * ETH_ALEN],
                           ETH_ALEN);
                    hddLog(VOS_TRACE_LEVEL_INFO,
                            "%s: %s multicast filter: addr ="
                            MAC_ADDRESS_STR,
                            __func__, set ? "setting" : "clearing",
                            MAC_ADDR_ARRAY(pMulticastAddrs->multicastAddr[i]));
                }
                /* Set multicast filter */
                sme_8023MulticastList(hHal, pAdapter->sessionId,
                                      pMulticastAddrs);
            } else {
                hddLog(VOS_TRACE_LEVEL_INFO,
                       FL("MC address list not sent to FW, cnt: %d"),
                        pAdapter->mc_addr_list.mc_cnt);
            }
        } else {
            /* Need to clear only if it was previously configured
             */
            if (pAdapter->mc_addr_list.isFilterApplied) {
                pMulticastAddrs->ulMulticastAddrCnt =
                                 pAdapter->mc_addr_list.mc_cnt;
                i = 0;
                while (0 < pAdapter->mc_addr_list.mc_cnt) {
                    memcpy(pMulticastAddrs->multicastAddr[i],
                           &pAdapter->mc_addr_list.addr[i * ETH_ALEN],
                           ETH_ALEN);
                    pAdapter->mc_addr_list.mc_cnt--;
                    i++;
                    hddLog(VOS_TRACE_LEVEL_INFO,
                            "%s: clearing multicast filter: addr ="
                            MAC_ADDRESS_STR,
                            __func__,
                            MAC_ADDR_ARRAY(pMulticastAddrs->multicastAddr[i]));
                }
                sme_8023MulticastList(hHal, pAdapter->sessionId,
                                      pMulticastAddrs);
            }

        }
        /* MAddrCnt is MulticastAddrCnt */
        hddLog(VOS_TRACE_LEVEL_INFO, "smeSessionId:%d; set:%d; MCAdddrCnt :%d",
              pAdapter->sessionId, set, pMulticastAddrs->ulMulticastAddrCnt);

        pAdapter->mc_addr_list.isFilterApplied = set ? TRUE : FALSE;
        vos_mem_free(pMulticastAddrs);
    } else {
        hddLog(VOS_TRACE_LEVEL_INFO,
                FL("gMCAddrListEnable is not enabled in INI"));
        return -EINVAL;
    }

    EXIT();
    return ret;
}

static int __iw_set_packet_filter_params(struct net_device *dev,
                                         struct iw_request_info *info,
                                         union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    tpPacketFilterCfg pRequest = NULL;
    int ret;
    struct iw_point s_priv_data;
    hdd_context_t *hdd_ctx;

    ENTER();

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

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

    if (hdd_priv_get_data(&s_priv_data, wrqu)) {
       return -EINVAL;
    }

    if ((NULL == s_priv_data.pointer) || (0 == s_priv_data.length)) {
       return -EINVAL;
    }

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

    ret = wlan_hdd_set_filter(WLAN_HDD_GET_CTX(pAdapter), pRequest,
                              pAdapter->sessionId);
    vos_mem_free(pRequest);
    EXIT();
    return ret;
}

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

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

	return ret;
}
#endif

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

  VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
  eHalStatus status = eHAL_STATUS_SUCCESS;
  hdd_wext_state_t *pWextState;
  hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
  hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
  char *p = extra;
  int tlen = 0;
  int ret;
  tCsrSummaryStatsInfo *pStats = &(pAdapter->hdd_stats.summary_stat);
  tCsrGlobalClassAStatsInfo *aStats = &(pAdapter->hdd_stats.ClassA_stat);
  tCsrGlobalClassDStatsInfo *dStats = &(pAdapter->hdd_stats.ClassD_stat);

  ENTER();

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

  if (eConnectionState_Associated != (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) {

     wrqu->txpower.value = 0;
  }
  else {
    status = sme_GetStatistics( pHddCtx->hHal, eCSR_HDD,
                       SME_SUMMARY_STATS      |
                       SME_GLOBAL_CLASSA_STATS |
                       SME_GLOBAL_CLASSB_STATS |
                       SME_GLOBAL_CLASSC_STATS |
                       SME_GLOBAL_CLASSD_STATS |
                       SME_PER_STA_STATS,
                       hdd_StatisticsCB, 0, FALSE,
                       (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
                       pAdapter,
                       pAdapter->sessionId );

    if (eHAL_STATUS_SUCCESS != status)
    {
       hddLog(VOS_TRACE_LEVEL_ERROR,
              "%s: Unable to retrieve SME statistics",
              __func__);
        return -EINVAL;
    }

    pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);

    vos_status = vos_wait_single_event(&pWextState->vosevent, WLAN_WAIT_TIME_STATS);
    if (!VOS_IS_STATUS_SUCCESS(vos_status))
    {
       hddLog(VOS_TRACE_LEVEL_ERROR,
              "%s: SME timeout while retrieving statistics",
              __func__);
       /*Remove the SME statistics list by passing NULL in callback argument*/
       status = sme_GetStatistics( pHddCtx->hHal, eCSR_HDD,
                       SME_SUMMARY_STATS      |
                       SME_GLOBAL_CLASSA_STATS |
                       SME_GLOBAL_CLASSB_STATS |
                       SME_GLOBAL_CLASSC_STATS |
                       SME_GLOBAL_CLASSD_STATS |
                       SME_PER_STA_STATS,
                       NULL, 0, FALSE,
                       (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
                       pAdapter,
                       pAdapter->sessionId );

       return -EINVAL;
    }
    FILL_TLV(p, (tANI_U8)WLAN_STATS_RETRY_CNT,
              (tANI_U8) sizeof (pStats->retry_cnt),
              (char*) &(pStats->retry_cnt[0]),
              tlen);

    FILL_TLV(p, (tANI_U8)WLAN_STATS_MUL_RETRY_CNT,
              (tANI_U8) sizeof (pStats->multiple_retry_cnt),
              (char*) &(pStats->multiple_retry_cnt[0]),
              tlen);

    FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_FRM_CNT,
              (tANI_U8) sizeof (pStats->tx_frm_cnt),
              (char*) &(pStats->tx_frm_cnt[0]),
              tlen);

    FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_FRM_CNT,
              (tANI_U8) sizeof (pStats->rx_frm_cnt),
              (char*) &(pStats->rx_frm_cnt),
              tlen);

    FILL_TLV(p, (tANI_U8)WLAN_STATS_FRM_DUP_CNT,
              (tANI_U8) sizeof (pStats->frm_dup_cnt),
              (char*) &(pStats->frm_dup_cnt),
              tlen);

    FILL_TLV(p, (tANI_U8)WLAN_STATS_FAIL_CNT,
              (tANI_U8) sizeof (pStats->fail_cnt),
              (char*) &(pStats->fail_cnt[0]),
              tlen);

    FILL_TLV(p, (tANI_U8)WLAN_STATS_RTS_FAIL_CNT,
              (tANI_U8) sizeof (pStats->rts_fail_cnt),
              (char*) &(pStats->rts_fail_cnt),
              tlen);

    FILL_TLV(p, (tANI_U8)WLAN_STATS_ACK_FAIL_CNT,
              (tANI_U8) sizeof (pStats->ack_fail_cnt),
              (char*) &(pStats->ack_fail_cnt),
              tlen);

    FILL_TLV(p, (tANI_U8)WLAN_STATS_RTS_SUC_CNT,
              (tANI_U8) sizeof (pStats->rts_succ_cnt),
              (char*) &(pStats->rts_succ_cnt),
              tlen);

    FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_DISCARD_CNT,
              (tANI_U8) sizeof (pStats->rx_discard_cnt),
              (char*) &(pStats->rx_discard_cnt),
              tlen);

    FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_ERROR_CNT,
              (tANI_U8) sizeof (pStats->rx_error_cnt),
              (char*) &(pStats->rx_error_cnt),
              tlen);

    FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_BYTE_CNT,
              (tANI_U8) sizeof (dStats->tx_uc_byte_cnt[0]),
              (char*) &(dStats->tx_uc_byte_cnt[0]),
              tlen);

    FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_BYTE_CNT,
              (tANI_U8) sizeof (dStats->rx_byte_cnt),
              (char*) &(dStats->rx_byte_cnt),
              tlen);

    FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_RATE,
              (tANI_U8) sizeof (dStats->rx_rate),
              (char*) &(dStats->rx_rate),
              tlen);

    /* Transmit rate, in units of 500 kbit/sec */
    FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_RATE,
              (tANI_U8) sizeof (aStats->tx_rate),
              (char*) &(aStats->tx_rate),
              tlen);

    FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_UC_BYTE_CNT,
              (tANI_U8) sizeof (dStats->rx_uc_byte_cnt[0]),
              (char*) &(dStats->rx_uc_byte_cnt[0]),
              tlen);
    FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_MC_BYTE_CNT,
              (tANI_U8) sizeof (dStats->rx_mc_byte_cnt),
              (char*) &(dStats->rx_mc_byte_cnt),
              tlen);
    FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_BC_BYTE_CNT,
              (tANI_U8) sizeof (dStats->rx_bc_byte_cnt),
              (char*) &(dStats->rx_bc_byte_cnt),
              tlen);
    FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_UC_BYTE_CNT,
              (tANI_U8) sizeof (dStats->tx_uc_byte_cnt[0]),
              (char*) &(dStats->tx_uc_byte_cnt[0]),
              tlen);
    FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_MC_BYTE_CNT,
              (tANI_U8) sizeof (dStats->tx_mc_byte_cnt),
              (char*) &(dStats->tx_mc_byte_cnt),
              tlen);
    FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_BC_BYTE_CNT,
              (tANI_U8) sizeof (dStats->tx_bc_byte_cnt),
              (char*) &(dStats->tx_bc_byte_cnt),
              tlen);

    wrqu->data.length = tlen;

  }

  EXIT();

  return 0;
}

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

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

	return ret;
}

#ifdef FEATURE_WLAN_SCAN_PNO

/*Max Len for PNO notification*/
#define MAX_PNO_NOTIFY_LEN 100
void found_pref_network_cb (void *callbackContext,
                              tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
{
  hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
  union iwreq_data wrqu;
  char buf[MAX_PNO_NOTIFY_LEN+1];

  hddLog(VOS_TRACE_LEVEL_WARN, "A preferred network was found: %s with rssi: -%d",
         pPrefNetworkFoundInd->ssId.ssId, pPrefNetworkFoundInd->rssi);

  // create the event
  memset(&wrqu, 0, sizeof(wrqu));
  memset(buf, 0, sizeof(buf));

  snprintf(buf, MAX_PNO_NOTIFY_LEN, "QCOM: Found preferred network: %s with RSSI of -%u",
           pPrefNetworkFoundInd->ssId.ssId,
          (unsigned int)pPrefNetworkFoundInd->rssi);

  wrqu.data.pointer = buf;
  wrqu.data.length = strlen(buf);

  // send the event

  wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);

}


/*string based input*/
int iw_set_pno(struct net_device *dev, struct iw_request_info *info,
               union iwreq_data *wrqu, char *extra, int nOffset)
{
  hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
  /* pnoRequest is a large struct, so we make it static to avoid stack
     overflow.  This API is only invoked via ioctl, so it is
     serialized by the kernel rtnl_lock and hence does not need to be
     reentrant */
  static tSirPNOScanReq pnoRequest;
  char *ptr, *data;
  v_U8_t i,j, ucParams, ucMode;
  size_t len;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
            "PNO data len %d data %s",
            wrqu->data.length,
            extra);

  if (wrqu->data.length <= nOffset )
  {
    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "PNO input is not correct");
    return -EINVAL;
  }

  pnoRequest.enable = 0;
  pnoRequest.ucNetworksCount = 0;
  /*-----------------------------------------------------------------------
    Input is string based and expected to be like this:

    <enabled> <netw_count>
    for each network:
    <ssid_len> <ssid> <authentication> <encryption>
    <ch_num> <channel_list optional> <bcast_type> <rssi_threshold>
    <fast_scan_period> <fast_scan_cycles> <slow_scan_period> <pno_mode>

    e.g:
    1 2 4 test 0 0 3 1 6 11 2 40 5 test2 4 4 6 1 2 3 4 5 6 1 0 2 5 3 0

    this translates into:
    -----------------------------
    enable PNO
    look for 2 networks:
    test - with authentication type 0 and encryption type 0,
    that can be found on 3 channels: 1 6 and 11 ,
    SSID bcast type is unknown (directed probe will be sent if AP not found)
    and must meet -40dBm RSSI

    test2 - with auth and encryption type 4/4
    that can be found on 6 channels 1, 2, 3, 4, 5 and 6
    bcast type is non-bcast (directed probe will be sent)
    and must not meet any RSSI threshold

    scan every 5 seconds 2 times, scan every 300 seconds until stopped
  -----------------------------------------------------------------------*/

  /* making sure argument string ends with '\0' */
  len = (wrqu->data.length-nOffset) + 1;
  data = vos_mem_malloc(len);
  if (NULL == data) {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                FL("fail to allocate memory %zu"), len);
      return -EINVAL;
  }
  vos_mem_zero(data, len);
  vos_mem_copy(data, &extra[nOffset], (len-1));
  ptr = data;

  if (1 != sscanf(ptr," %hhu%n", &(pnoRequest.enable), &nOffset))
  {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "PNO enable input is not valid %s",ptr);
      vos_mem_free(data);
      return -EINVAL;
  }

  if ( 0 == pnoRequest.enable )
  {
    /*Disable PNO*/
    memset(&pnoRequest, 0, sizeof(pnoRequest));
    sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter), &pnoRequest,
                                pAdapter->sessionId,
                                found_pref_network_cb, pAdapter);
    vos_mem_free(data);
    return 0;
  }

  ptr += nOffset;

  if (1 != sscanf(ptr," %hhu %n", &(pnoRequest.ucNetworksCount), &nOffset))
  {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "PNO count input not valid %s",ptr);
      vos_mem_free(data);
      return -EINVAL;
  }

  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
            "PNO enable %d networks count %d offset %d",
            pnoRequest.enable,
            pnoRequest.ucNetworksCount,
            nOffset);

  /* Parameters checking:
      ucNetworksCount has to be larger than 0*/
  if (( 0 == pnoRequest.ucNetworksCount ) ||
      ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
  {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "Network input is not correct");
      vos_mem_free(data);
      return -EINVAL;
  }

  ptr += nOffset;

  for ( i = 0; i < pnoRequest.ucNetworksCount; i++ )
  {

    pnoRequest.aNetworks[i].ssId.length = 0;

    ucParams = sscanf(ptr," %hhu %n",
                      &(pnoRequest.aNetworks[i].ssId.length),&nOffset);

    if (1 != ucParams)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "PNO ssid length input is not valid %s",ptr);
        vos_mem_free(data);
        return -EINVAL;
    }

    if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
        ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
    {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "SSID Len %d is not correct for network %d",
                pnoRequest.aNetworks[i].ssId.length, i);
      vos_mem_free(data);
      return -EINVAL;
    }

    /*Advance to SSID*/
    ptr += nOffset;

    memcpy(pnoRequest.aNetworks[i].ssId.ssId, ptr,
           pnoRequest.aNetworks[i].ssId.length);
    ptr += pnoRequest.aNetworks[i].ssId.length;

    ucParams = sscanf(ptr," %u %u %hhu %n",
                      &(pnoRequest.aNetworks[i].authentication),
                      &(pnoRequest.aNetworks[i].encryption),
                      &(pnoRequest.aNetworks[i].ucChannelCount),
                      &nOffset);

    if ( 3 != ucParams )
    {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                "Incorrect cmd %s",ptr);
      vos_mem_free(data);
      return -EINVAL;
    }

    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
              "PNO len %d ssid 0x%08x%08x%08x%08x%08x%08x%08x%08x"
              "auth %d encry %d channel count %d offset %d",
              pnoRequest.aNetworks[i].ssId.length,
              *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[0]),
              *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[4]),
              *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[8]),
              *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[12]),
              *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[16]),
              *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[20]),
              *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[24]),
              *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[28]),
              pnoRequest.aNetworks[i].authentication,
              pnoRequest.aNetworks[i].encryption,
              pnoRequest.aNetworks[i].ucChannelCount,
              nOffset );

    /*Advance to channel list*/
    ptr += nOffset;

    if (SIR_PNO_MAX_NETW_CHANNELS < pnoRequest.aNetworks[i].ucChannelCount)
    {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                "Incorrect number of channels");
      vos_mem_free(data);
      return -EINVAL;
    }

    if ( 0 !=  pnoRequest.aNetworks[i].ucChannelCount)
    {
      for ( j = 0; j < pnoRequest.aNetworks[i].ucChannelCount; j++)
      {
           if (1 != sscanf(ptr," %hhu %n",
                           &(pnoRequest.aNetworks[i].aChannels[j]),
                           &nOffset))
            {    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                           "PNO network channel input is not valid %s",ptr);
               vos_mem_free(data);
               return -EINVAL;
            }
            if (!IS_CHANNEL_VALID(pnoRequest.aNetworks[i].aChannels[j])) {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                          FL("invalid channel: %hhu"),
                             pnoRequest.aNetworks[i].aChannels[j]);
                vos_mem_free(data);
                return -EINVAL;
            }
            /*Advance to next channel number*/
            ptr += nOffset;
      }
    }

    if (1 != sscanf(ptr," %u %n",
                    &(pnoRequest.aNetworks[i].bcastNetwType),
                    &nOffset))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "PNO broadcast network type input is not valid %s",ptr);
        vos_mem_free(data);
        return -EINVAL;
    }
    if (pnoRequest.aNetworks[i].bcastNetwType > 2) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  FL("invalid bcast nw type: %u"),
                      pnoRequest.aNetworks[i].bcastNetwType);
        vos_mem_free(data);
        return -EINVAL;
    }
    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
            "PNO bcastNetwType %d offset %d",
            pnoRequest.aNetworks[i].bcastNetwType,
            nOffset );

    /*Advance to rssi Threshold*/
    ptr += nOffset;
    if (1 != sscanf(ptr," %d %n",
                    &(pnoRequest.aNetworks[i].rssiThreshold),
                    &nOffset))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "PNO rssi threshold input is not valid %s",ptr);
        vos_mem_free(data);
        return -EINVAL;
    }
    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
            "PNO rssi %d offset %d",
            pnoRequest.aNetworks[i].rssiThreshold,
            nOffset );
    /*Advance to next network*/
    ptr += nOffset;
  }/*For ucNetworkCount*/

  if (1 != sscanf(ptr, " %u %n", &(pnoRequest.fast_scan_period), &nOffset) ) {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "failed to read fast scan period %u", *ptr);
        vos_mem_free(data);
        return -EINVAL;
  }
  if (pnoRequest.fast_scan_period == 0) {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                FL("invalid fast scan period %u"),
                 pnoRequest.fast_scan_period);
        vos_mem_free(data);
        return -EINVAL;
  }
  pnoRequest.fast_scan_period *= MSEC_PER_SEC;
  ptr += nOffset;

  if (1 != sscanf(ptr, " %hhu %n", &(pnoRequest.fast_scan_max_cycles),
             &nOffset)) {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "failed to read fast scan max cycles %hhu", *ptr);
        vos_mem_free(data);
        return -EINVAL;
  }
  if (pnoRequest.fast_scan_max_cycles < CFG_PNO_SCAN_TIMER_REPEAT_VALUE_MIN ||
      pnoRequest.fast_scan_max_cycles > CFG_PNO_SCAN_TIMER_REPEAT_VALUE_MAX) {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "invalid fast scan max cycles %hhu",
                 pnoRequest.fast_scan_max_cycles);
        vos_mem_free(data);
        return -EINVAL;
  }
  ptr += nOffset;

  if (1 != sscanf(ptr, " %u %n", &(pnoRequest.slow_scan_period), &nOffset)) {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "failed to read slow scan period %u", *ptr);
        vos_mem_free(data);
        return -EINVAL;
  }
  pnoRequest.slow_scan_period *= MSEC_PER_SEC;
  if (pnoRequest.slow_scan_period < pnoRequest.fast_scan_period) {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "invalid slow scan period %u",
                 pnoRequest.slow_scan_period);
        vos_mem_free(data);
        return -EINVAL;
  }
  ptr += nOffset;

  ucParams = sscanf(ptr," %hhu %n",&(ucMode), &nOffset);

  pnoRequest.modePNO = ucMode;
  /*for LA we just expose suspend option*/
  if (( 1 != ucParams )||(  ucMode >= SIR_PNO_MODE_MAX ))
  {
     VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                "fail to get valid pno mode %hhu %hhu", ucParams, ucMode);
     pnoRequest.modePNO = SIR_PNO_MODE_ON_SUSPEND;
  }

  sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter), &pnoRequest,
                                pAdapter->sessionId,
                                found_pref_network_cb, pAdapter);

  vos_mem_free(data);
  return 0;
}/*iw_set_pno*/

static int __iw_set_pno_priv(struct net_device *dev,
                             struct iw_request_info *info,
                             union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    VOS_STATUS status;

    ENTER();

    if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
    {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                                  "%s:LOGP in Progress. Ignore!!!", __func__);
       return -EBUSY;
    }
    status = iw_set_pno(dev,info,wrqu,extra,0);

    EXIT();
    return status;
}

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

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

	return ret;
}
#endif /*FEATURE_WLAN_SCAN_PNO*/

//Common function to SetBand
int hdd_setBand(struct net_device *dev, u8 ui_band)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    eCsrBand band;

    VOS_STATUS status;
    hdd_context_t *pHddCtx;
    hdd_adapter_list_node_t *pAdapterNode, *pNext;
    eCsrBand currBand = eCSR_BAND_MAX;
    eCsrBand connectedBand;

    ENTER();

    pAdapterNode = NULL;
    pNext = NULL;
    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);

    switch(ui_band)
    {
        case WLAN_HDD_UI_BAND_AUTO:
             band = eCSR_BAND_ALL;
        break;
        case WLAN_HDD_UI_BAND_5_GHZ:
            band = eCSR_BAND_5G;
        break;
        case WLAN_HDD_UI_BAND_2_4_GHZ:
            band = eCSR_BAND_24;
        break;
        default:
            band = eCSR_BAND_MAX;
    }

    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: change band to %u",
                __func__, band);

    if (band == eCSR_BAND_MAX)
    {
        /* Received change band request with invalid band value */
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
               "%s: Invalid band value %u", __func__, ui_band);
        return -EINVAL;
    }

    if ((band == eCSR_BAND_24 && pHddCtx->cfg_ini->nBandCapability == 2) ||
        (band == eCSR_BAND_5G && pHddCtx->cfg_ini->nBandCapability == 1)) {
        hddLog(LOGP, FL("band value %u violate INI settings %u"),
               band, pHddCtx->cfg_ini->nBandCapability);
        return -EIO;
    }

    if (band == eCSR_BAND_ALL) {
        hddLog(LOG1,
               FL("Auto band received. Setting band same as ini value %d"),
               pHddCtx->cfg_ini->nBandCapability);
        band = pHddCtx->cfg_ini->nBandCapability;
    }

    if (eHAL_STATUS_SUCCESS != sme_GetFreqBand(hHal, &currBand))
    {
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
              "%s: Failed to get current band config",
                 __func__);
         return -EIO;
    }

    if (currBand != band)
    {
        /* Change band request received.
         * Abort pending scan requests, flush the existing scan results,
         * and change the band capability
         */
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                "%s: Current band value = %u, new setting %u ",
                 __func__, currBand, band);

        status =  hdd_get_front_adapter(pHddCtx, &pAdapterNode);
        while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
        {
            pAdapter = pAdapterNode->pAdapter;
            hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
            hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
                           eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE);
            connectedBand =
                hdd_connGetConnectedBand(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter));

            /* Handling is done only for STA and P2P */
            if ( band != eCSR_BAND_ALL &&
                 ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
                 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) &&
                 (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) &&
                 (connectedBand != band))
            {
                 eHalStatus status = eHAL_STATUS_SUCCESS;
                 long lrc;

                 /* STA already connected on current band, So issue disconnect
                  * first, then change the band */

                 hddLog(LOG1,
                        FL("STA Device mode %s(%d) connected band %u, Changing band to %u, Issuing Disconnect"),
                        hdd_device_mode_to_string(pAdapter->device_mode),
                        pAdapter->device_mode, currBand, band);

                 INIT_COMPLETION(pAdapter->disconnect_comp_var);

                 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
                 pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);

                 if ( eHAL_STATUS_SUCCESS != status)
                 {
                     hddLog(VOS_TRACE_LEVEL_ERROR,
                             "%s csrRoamDisconnect failure, returned %d",
                               __func__, (int)status );
                     return -EINVAL;
                 }

                 lrc = wait_for_completion_timeout(
                         &pAdapter->disconnect_comp_var,
                         msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));

                 if (lrc == 0) {
                    hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Timeout while waiting for csrRoamDisconnect",
                                __func__);
                    return -ETIMEDOUT ;
                 }
            }

            sme_ScanFlushResult(hHal, pAdapter->sessionId);

            status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
            pAdapterNode = pNext;
        }

        if (eHAL_STATUS_SUCCESS != sme_SetFreqBand(hHal, pAdapter->sessionId,
                                                   band)) {
             VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
                     FL("Failed to set the band value to %u"), band);
             return -EINVAL;
        }
        vos_update_band((eCsrBand)band);
    }
    EXIT();
    return 0;
}

int hdd_setBand_helper(struct net_device *dev, const char *command)
{
    u8 band;
    int ret;

    /* Convert the band value from ascii to integer */
    command += WLAN_HDD_UI_SET_BAND_VALUE_OFFSET;
    ret = kstrtou8(command, 10, &band);
    if (ret < 0) {
        hddLog(LOGE, FL("kstrtou8 failed"));
        return -EINVAL;
    }

    return hdd_setBand(dev, band);
}

static int __iw_set_band_config(struct net_device *dev,
                                struct iw_request_info *info,
                                union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    int *value = (int *)extra;
    hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
    int ret;

    ENTER();

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

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

    return hdd_setBand(dev, value[0]);
}

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

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

	return ret;
}

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

  ENTER();

  if (!capable(CAP_NET_ADMIN)) {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 FL("permission check failed"));
      return -EPERM;
  }
  /* ODD number is used for set, copy data using copy_from_user */
  ptr = mem_alloc_copy_from_user_helper(wrqu->data.pointer,
                                        wrqu->data.length);
  if (NULL == ptr)
  {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "mem_alloc_copy_from_user_helper fail");
      return -ENOMEM;
  }

  ret = iw_set_power_params(dev, info, wrqu, ptr, 0);
  vos_mem_free(ptr);
  EXIT();
  return ret;
}

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

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

	return ret;
}


/*string based input*/
VOS_STATUS iw_set_power_params(struct net_device *dev, struct iw_request_info *info,
                      union iwreq_data *wrqu, char *extra, int nOffset)
{
  hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
  tSirSetPowerParamsReq powerRequest;
  char *ptr;
  v_U8_t  ucType;
  v_U32_t  uTotalSize, uValue;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
            "Power Params data len %d data %s",
            wrqu->data.length,
            extra);

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

  if (wrqu->data.length <= nOffset )
  {
    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "set power param input is not correct");
    return VOS_STATUS_E_FAILURE;
  }

  uTotalSize = wrqu->data.length - nOffset;

  /*-----------------------------------------------------------------------
    Input is string based and expected to be like this:

    <param_type> <param_value> <param_type> <param_value> ...

    e.g:
    1 2 2 3 3 0 4 1 5 1

    e.g. setting just a few:
    1 2 4 1

    parameter types:
    -----------------------------
    1 - Ignore DTIM
    2 - Listen Interval
    3 - Broadcast Multicast Filter
    4 - Beacon Early Termination
    5 - Beacon Early Termination Interval
  -----------------------------------------------------------------------*/
  powerRequest.uIgnoreDTIM       = SIR_NOCHANGE_POWER_VALUE;
  powerRequest.uListenInterval   = SIR_NOCHANGE_POWER_VALUE;
  powerRequest.uBcastMcastFilter = SIR_NOCHANGE_POWER_VALUE;
  powerRequest.uEnableBET        = SIR_NOCHANGE_POWER_VALUE;
  powerRequest.uBETInterval      = SIR_NOCHANGE_POWER_VALUE;

  ptr = extra + nOffset;

  while ( uTotalSize )
  {
    if (1 != sscanf(ptr,"%hhu %n", &(ucType), &nOffset))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "Invalid input parameter type %s",ptr);
         return VOS_STATUS_E_FAILURE;
    }

    uTotalSize -= nOffset;

    if (!uTotalSize)
    {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "Invalid input parameter type : %d with no value at offset %d",
                ucType, nOffset);
      return VOS_STATUS_E_FAILURE;
    }

    ptr += nOffset;

    if (1 != sscanf(ptr,"%u %n", &(uValue), &nOffset))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "Invalid input parameter value %s",ptr);
         return VOS_STATUS_E_FAILURE;
    }

    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
              "Power request parameter %d value %d offset %d",
              ucType, uValue, nOffset);

    switch (ucType)
    {
      case eSIR_IGNORE_DTIM:
      powerRequest.uIgnoreDTIM       = uValue;
      break;
      case eSIR_LISTEN_INTERVAL:
      powerRequest.uListenInterval   = uValue;
      break;
      case eSIR_MCAST_BCAST_FILTER:
      powerRequest.uBcastMcastFilter = uValue;
      break;
      case eSIR_ENABLE_BET:
      powerRequest.uEnableBET        = uValue;
      break;
      case eSIR_BET_INTERVAL:
      powerRequest.uBETInterval      = uValue;
      break;
      default:
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "Invalid input parameter type : %d with value: %d at offset %d",
                ucType, uValue,  nOffset);
      return VOS_STATUS_E_FAILURE;
    }

    uTotalSize -= nOffset;
    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
              "Power request parameter %d Total size",
              uTotalSize);
    ptr += nOffset;
    /* This is added for dynamic Tele LI enable (0xF1) /disable (0xF0)*/
    if(!(uTotalSize - nOffset) &&
       (powerRequest.uListenInterval != SIR_NOCHANGE_POWER_VALUE))
    {
        uTotalSize = 0;
    }

  }/*Go for as long as we have a valid string*/

  /* put the device into full power*/
  wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);

  /* Apply the power save params*/
  sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);

  /* put the device back to power save*/
  wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);

  return VOS_STATUS_SUCCESS;
}/*iw_set_power_params*/

int hdd_wlan_get_ps_tdcc_info(hdd_adapter_t *adapter,
			      uint16_t *length,
			      char *buffer,
			      uint16_t buf_len)
{
	int32_t tdcc_enable, tdcc_percent, ret;
	uint32_t len;

	ret = wlan_hdd_process_tdcc_ps(adapter, PS_TDCC_GET,
				       &tdcc_enable, &tdcc_percent);
	if (ret)
		return ret;

	len = snprintf(buffer, buf_len, "\nTDCC enable=%d percent=%d\n",
		       tdcc_enable, tdcc_percent);
	if (len >= buf_len) {
		hddLog(LOGE, "Insufficient buffer:%d, %d", buf_len, len);
		return -E2BIG;
	}

	*length = len + 1;
	return 0;
}

int wlan_hdd_process_tdcc_ps(hdd_adapter_t *adapter,
			     enum tdcc_cmd_type cmd,
			     int *enable, int *percentage)
{
	static int32_t ps_tdcc_enabled = 0;
	static int32_t ps_tdcc_percent = 0;

	if ((!enable || !percentage) && cmd != PS_TDCC_RESET) {
		hddLog(LOGE, "Input enable/percentage null pointer");
		return -EINVAL;
	}

	switch (cmd) {
	case PS_TDCC_SET:
		if (*enable != 0 && *enable != 1) {
			hddLog(LOGE, "Invalid tdcc enable/disable");
			return -EINVAL;
		}
		if (*percentage < 0 || *percentage > 100) {
			hddLog(LOGE, "Invalid tdcc duty cycle percentage");
			return -EINVAL;
		}
		break;
	case PS_TDCC_RESET:
		ps_tdcc_enabled = 0;
		ps_tdcc_percent = 0;
		return 0;
	case PS_TDCC_GET:
		*enable = ps_tdcc_enabled;
		*percentage = ps_tdcc_percent;
		return 0;
	default:
		hddLog(LOGE, "Invalid tdcc command %d", cmd);
		return -EINVAL;
	}

	if (*enable == ps_tdcc_enabled &&
	    (*percentage == ps_tdcc_percent || *enable == 0))
		return 0;

	hddLog(LOG1, "Set tdcc enable:%d percentage:%d", *enable, *percentage);
	ps_tdcc_enabled = *enable;
	ps_tdcc_percent = *percentage;
	return process_wma_set_command_twoargs((int)adapter->sessionId,
					       (int)GEN_PARAM_PS_TDCC,
					       *enable, *percentage, GEN_CMD);
}

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

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

    switch(sub_cmd) {
    case WE_SET_SMPS_PARAM:
        hddLog(LOG1, "WE_SET_SMPS_PARAM val %d %d", value[1], value[2]);
        ret = process_wma_set_command((int)pAdapter->sessionId,
                       (int)WMI_STA_SMPS_PARAM_CMDID,
                       value[1] << WMA_SMPS_PARAM_VALUE_S | value[2], VDEV_CMD);
        break;
#ifdef WLAN_DEBUG
    case WE_SET_FW_CRASH_INJECT:
        hddLog(LOGE, "WE_SET_FW_CRASH_INJECT: %d %d", value[1], value[2]);
        pr_err("SSR is triggered by iwpriv CRASH_INJECT: %d %d\n",
                                                value[1], value[2]);
        if (!hdd_ctx->cfg_ini->crash_inject_enabled) {
            hddLog(LOGE, "Crash Inject ini disabled, Ignore Crash Inject");
            return 0;
        }

        hdd_ctx->isLogpInProgress = true;
        ret = process_wma_set_command_twoargs((int) pAdapter->sessionId,
                                              (int) GEN_PARAM_CRASH_INJECT,
                                              value[1], value[2], GEN_CMD);
        if (ret)
            hdd_ctx->isLogpInProgress = false;

        break;
#endif
    case WE_SET_PS_TDCC:
        ret = wlan_hdd_process_tdcc_ps(pAdapter, PS_TDCC_SET,
                                       &value[1], &value[2]);
        break;
    case WE_SET_MON_MODE_CHAN:
        /*
         * TODO: Remove this private implementation use standard
         * interface wlan_hdd_cfg80211_ops.set_monitor_channel
         */
        if (VOS_MONITOR_MODE == hdd_get_conparam()) {
            uint16_t vht_channel_width = value[2];
            hdd_station_ctx_t *sta_ctx =
                    WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
            struct hdd_mon_set_ch_info *ch_info = &sta_ctx->ch_info;
            eHalStatus hal_status;

            tHalHandle hal_hdl = hdd_ctx->hHal;
            tCsrBssid bssid = {0};
            tCsrRoamProfile *roam_profile = NULL;
            uint8_t ini_sub_20_ch_width =
                        hdd_ctx->cfg_ini->sub_20_channel_width;

            /* Validate channel Number*/
            if (wlan_hdd_validate_mon_channel(value[1]) != VOS_STATUS_SUCCESS) {
                hddLog(LOGE, "Invalid channel for monitor mode");
                return -EINVAL;
            }

            /* Validate bandwidth Number*/
            if (wlan_hdd_validate_mon_bw(value[1], value[2]) != VOS_STATUS_SUCCESS) {
                hddLog(LOGE, "Invalid bandwidth for monitor mode");
                return -EINVAL;
            }

            roam_profile = vos_mem_malloc(sizeof(tCsrRoamProfile));
            if (roam_profile == NULL){
                hddLog(LOGE, "Failed to allocate memory");
                return -ENOMEM;
            }
            vos_mem_zero(roam_profile, sizeof(*roam_profile));

            if (vht_channel_width == 4) {
                vht_channel_width = 0;
                roam_profile->sub20_channelwidth = SUB20_MODE_5MHZ;
            } else if (vht_channel_width == 5) {
                vht_channel_width = 0;
                roam_profile->sub20_channelwidth = SUB20_MODE_10MHZ;
            } else {
                if (ini_sub_20_ch_width < CFG_SUB_20_CHANNEL_WIDTH_DYN_5MHZ)
                    roam_profile->sub20_channelwidth = ini_sub_20_ch_width;
                else
                    roam_profile->sub20_channelwidth = SUB20_MODE_NONE;
            }

            hddLog(LOGE, "Set monitor mode Channel %d bandwidth %d sub20 %d",
                   value[1], vht_channel_width,
                   roam_profile->sub20_channelwidth);

            hdd_select_mon_cbmode(pAdapter, value[1], &vht_channel_width);

            roam_profile->ChannelInfo.ChannelList = &ch_info->channel;
            roam_profile->ChannelInfo.numOfChannels = 1;
            roam_profile->vht_channel_width = ch_info->channel_width;
            roam_profile->phyMode = ch_info->phy_mode;


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

            hal_status = sme_RoamChannelChangeReq(hal_hdl,
                                 bssid,
                                 ch_info->cb_mode, roam_profile);
            if (!HAL_STATUS_SUCCESS(hal_status)) {
                hddLog(LOGE,
                       "Failed to set sme_RoamChannel for monitor mode");
                ret = -EINVAL;
            }
            vos_mem_free(roam_profile);
        } else {
            hddLog(LOGE, "Not supported, device is not in monitor mode");
            ret = -EINVAL;
        }
        break;
    case WE_DUMP_DP_TRACE_LEVEL:
        hddLog(LOG1, "WE_DUMP_DP_TRACE_LEVEL: %d %d",
                       value[1], value[2]);
        if (value[1] == DUMP_DP_TRACE)
            adf_dp_trace_dump_all(value[2]);
        else if (value[1] == ENABLE_DP_TRACE_LIVE_MODE)
            adf_dp_trace_enable_live_mode();
        else if (value[1] == CLEAR_DP_TRACE_BUFFER)
            adf_dp_trace_clear_buffer();
        else
            hddLog(LOGE, "unexpected value for dump_dp_trace");
        break;
    default:
        hddLog(LOGE, "%s: Invalid IOCTL command %d", __func__, sub_cmd);
        break;
    }

    return ret;
}

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

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

	return ret;
}

// Define the Wireless Extensions to the Linux Network Device structure
// A number of these routines are NULL (meaning they are not implemented.)

static const iw_handler      we_handler[] =
{
   (iw_handler) iw_set_commit,      /* SIOCSIWCOMMIT */
   (iw_handler) iw_get_name,      /* SIOCGIWNAME */
   (iw_handler) NULL,            /* SIOCSIWNWID */
   (iw_handler) NULL,            /* SIOCGIWNWID */
   (iw_handler) iw_set_freq,      /* SIOCSIWFREQ */
   (iw_handler) iw_get_freq,      /* SIOCGIWFREQ */
   (iw_handler) NULL,             /* SIOCSIWMODE */
   (iw_handler) NULL,             /* SIOCGIWMODE */
   (iw_handler) NULL,              /* SIOCSIWSENS */
   (iw_handler) NULL,              /* SIOCGIWSENS */
   (iw_handler) NULL,             /* SIOCSIWRANGE */
   (iw_handler) iw_get_range,      /* SIOCGIWRANGE */
   (iw_handler) NULL,             /* SIOCSIWPRIV */
   (iw_handler) NULL,             /* SIOCGIWPRIV */
   (iw_handler) NULL,             /* SIOCSIWSTATS */
   (iw_handler) NULL,             /* SIOCGIWSTATS */
   (iw_handler) NULL,             /* SIOCSIWSPY */
   (iw_handler) NULL,             /* SIOCGIWSPY */
   (iw_handler) NULL,             /* SIOCSIWTHRSPY */
   (iw_handler) NULL,             /* SIOCGIWTHRSPY */
   (iw_handler) iw_set_ap_address,   /* SIOCSIWAP */
   (iw_handler) iw_get_ap_address,   /* SIOCGIWAP */
   (iw_handler) iw_set_mlme,              /* SIOCSIWMLME */
   (iw_handler) NULL,              /* SIOCGIWAPLIST */
   (iw_handler) iw_set_scan,      /* SIOCSIWSCAN */
   (iw_handler) iw_get_scan,      /* SIOCGIWSCAN */
   (iw_handler) iw_set_essid,      /* SIOCSIWESSID */
   (iw_handler) iw_get_essid,      /* SIOCGIWESSID */
   (iw_handler) iw_set_nick,      /* SIOCSIWNICKN */
   (iw_handler) iw_get_nick,      /* SIOCGIWNICKN */
   (iw_handler) NULL,             /* -- hole -- */
   (iw_handler) NULL,             /* -- hole -- */
   (iw_handler) iw_set_bitrate,   /* SIOCSIWRATE */
   (iw_handler) iw_get_bitrate,   /* SIOCGIWRATE */
   (iw_handler) iw_set_rts_threshold,/* SIOCSIWRTS */
   (iw_handler) iw_get_rts_threshold,/* SIOCGIWRTS */
   (iw_handler) iw_set_frag_threshold,   /* SIOCSIWFRAG */
   (iw_handler) iw_get_frag_threshold,   /* SIOCGIWFRAG */
   (iw_handler) iw_set_tx_power,      /* SIOCSIWTXPOW */
   (iw_handler) iw_get_tx_power,      /* SIOCGIWTXPOW */
   (iw_handler) iw_set_retry,          /* SIOCSIWRETRY */
   (iw_handler) iw_get_retry,          /* SIOCGIWRETRY */
   (iw_handler) iw_set_encode,          /* SIOCSIWENCODE */
   (iw_handler) iw_get_encode,          /* SIOCGIWENCODE */
   (iw_handler) iw_set_power_mode,      /* SIOCSIWPOWER */
   (iw_handler) iw_get_power_mode,      /* SIOCGIWPOWER */
   (iw_handler) NULL,                 /* -- hole -- */
   (iw_handler) NULL,                /* -- hole -- */
   (iw_handler) iw_set_genie,      /* SIOCSIWGENIE */
   (iw_handler) iw_get_genie,      /* SIOCGIWGENIE */
   (iw_handler) iw_set_auth,      /* SIOCSIWAUTH */
   (iw_handler) iw_get_auth,      /* SIOCGIWAUTH */
   (iw_handler) iw_set_encodeext,   /* SIOCSIWENCODEEXT */
   (iw_handler) iw_get_encodeext,   /* SIOCGIWENCODEEXT */
   (iw_handler) NULL,         /* SIOCSIWPMKSA */
};

static const iw_handler we_private[] = {

   [WLAN_PRIV_SET_INT_GET_NONE      - SIOCIWFIRSTPRIV]   = iw_setint_getnone,  //set priv ioctl
   [WLAN_PRIV_SET_NONE_GET_INT      - SIOCIWFIRSTPRIV]   = iw_setnone_getint,  //get priv ioctl
   [WLAN_PRIV_SET_CHAR_GET_NONE     - SIOCIWFIRSTPRIV]   = iw_setchar_getnone, //get priv ioctl
   [WLAN_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV]  = iw_set_three_ints_getnone,
   [WLAN_PRIV_GET_CHAR_SET_NONE      - SIOCIWFIRSTPRIV]  = iw_get_char_setnone,
   [WLAN_PRIV_SET_NONE_GET_NONE     - SIOCIWFIRSTPRIV]   = iw_setnone_getnone, //action priv ioctl
   [WLAN_PRIV_SET_VAR_INT_GET_NONE  - SIOCIWFIRSTPRIV]   = iw_hdd_set_var_ints_getnone,
   [WLAN_PRIV_SET_NONE_GET_THREE_INT - SIOCIWFIRSTPRIV]  = iw_setnone_get_threeint,
   [WLAN_PRIV_ADD_TSPEC             - SIOCIWFIRSTPRIV]   = iw_add_tspec,
   [WLAN_PRIV_DEL_TSPEC             - SIOCIWFIRSTPRIV]   = iw_del_tspec,
   [WLAN_PRIV_GET_TSPEC             - SIOCIWFIRSTPRIV]   = iw_get_tspec,

#ifdef WLAN_FEATURE_VOWIFI_11R
   [WLAN_PRIV_SET_FTIES                 - SIOCIWFIRSTPRIV]   = iw_set_fties,
#endif
   [WLAN_PRIV_SET_HOST_OFFLOAD          - SIOCIWFIRSTPRIV]   = iw_set_host_offload,
   [WLAN_GET_WLAN_STATISTICS            - SIOCIWFIRSTPRIV]   = iw_get_statistics,
   [WLAN_SET_KEEPALIVE_PARAMS           - SIOCIWFIRSTPRIV]   = iw_set_keepalive_params
#ifdef WLAN_FEATURE_PACKET_FILTERING
   ,
   [WLAN_SET_PACKET_FILTER_PARAMS       - SIOCIWFIRSTPRIV]   = iw_set_packet_filter_params
#endif
#ifdef FEATURE_WLAN_SCAN_PNO
   ,
   [WLAN_SET_PNO                        - SIOCIWFIRSTPRIV]   = iw_set_pno_priv
#endif
   ,
   [WLAN_SET_BAND_CONFIG                - SIOCIWFIRSTPRIV]   = iw_set_band_config,
   [WLAN_PRIV_SET_MCBC_FILTER           - SIOCIWFIRSTPRIV]   = iw_set_dynamic_mcbc_filter,
   [WLAN_PRIV_CLEAR_MCBC_FILTER         - SIOCIWFIRSTPRIV]   = iw_clear_dynamic_mcbc_filter,
   [WLAN_SET_POWER_PARAMS               - SIOCIWFIRSTPRIV]   = iw_set_power_params_priv,
   [WLAN_GET_LINK_SPEED                 - SIOCIWFIRSTPRIV]   = iw_get_linkspeed_priv,
   [WLAN_PRIV_SET_TWO_INT_GET_NONE      - SIOCIWFIRSTPRIV]   = iw_set_two_ints_getnone,
   [WLAN_SET_DOT11P_CHANNEL_SCHED       - SIOCIWFIRSTPRIV]   = iw_set_dot11p_channel_sched,
   [WLAN_GET_ISOLATION                  - SIOCIWFIRSTPRIV]   = iw_get_isolation,
};

/*Maximum command length can be only 15 */
static const struct iw_priv_args we_private_args[] = {

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

    /* handlers for sub-ioctl */
    {   WE_SET_11D_STATE,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "set11Dstate" },

    {   WE_WOWL,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "wowl" },

    {   WE_SET_POWER,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "setPower" },

    {   WE_SET_MAX_ASSOC,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "setMaxAssoc" },

    {   WE_SET_SAP_AUTO_CHANNEL_SELECTION,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "setAutoChannel" },

    {   WE_SET_DATA_INACTIVITY_TO,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "inactivityTO" },

    {   WE_SET_MAX_TX_POWER,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "setMaxTxPower" },

    {   WE_SET_TX_POWER,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "setTxPower" },

    {   WE_SET_MC_RATE,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "setMcRate" },

    {   WE_SET_MAX_TX_POWER_2_4,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "setTxMaxPower2G" },

    {   WE_SET_MAX_TX_POWER_5_0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "setTxMaxPower5G" },

    /* SAP has TxMax whereas STA has MaxTx, adding TxMax for STA
     * as well to keep same syntax as in SAP. Now onwards, STA
     * will support both */
    {   WE_SET_MAX_TX_POWER,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "setTxMaxPower" },

    /* set Higher DTIM Transition (DTIM1 to DTIM3)
     * 1 = enable and 0 = disable */
    {
        WE_SET_HIGHER_DTIM_TRANSITION,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "setHDtimTransn" },

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

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

    {   WE_SET_NSS,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "nss" },

    {   WE_SET_LDPC,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "ldpc" },

    {   WE_SET_TX_STBC,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "tx_stbc" },

    {   WE_SET_RX_STBC,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "rx_stbc" },

    {   WE_SET_SHORT_GI,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "shortgi" },

    {   WE_SET_RTSCTS,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "enablertscts" },

    {   WE_SET_CHWIDTH,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "chwidth" },

    {   WE_SET_ANI_EN_DIS,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "anienable" },

    {   WE_SET_ANI_POLL_PERIOD,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "aniplen" },

    {   WE_SET_ANI_LISTEN_PERIOD,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "anilislen" },

    {   WE_SET_ANI_OFDM_LEVEL,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "aniofdmlvl" },

    {   WE_SET_ANI_CCK_LEVEL,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "aniccklvl" },

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

    {   WE_SET_CTS_CBW,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "cts_cbw" },

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

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

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

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

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

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

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

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

    {  WE_SET_TX_CHAINMASK,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "txchainmask" },

    {  WE_SET_RX_CHAINMASK,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "rxchainmask" },

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

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

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

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

    {   WE_SET_BURST_ENABLE,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "burst_enable" },

    {   WE_SET_BURST_DUR,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "burst_dur" },

    {   WE_SET_TXPOW_2G,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "txpow2g" },

    {   WE_SET_TXPOW_5G,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "txpow5g" },

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

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

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

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

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

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

    {   WE_DBGLOG_TYPE,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "dl_type" },
    {   WE_DBGLOG_REPORT_ENABLE,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "dl_report" },

    {   WE_SET_TXRX_FWSTATS,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "txrx_fw_stats" },

    {   WE_TXRX_FWSTATS_RESET,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "txrx_fw_st_rst" },

    {   WE_PPS_PAID_MATCH,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "paid_match" },


    {   WE_PPS_GID_MATCH,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "gid_match" },


    {   WE_PPS_EARLY_TIM_CLEAR,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "tim_clear" },


    {   WE_PPS_EARLY_DTIM_CLEAR,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "dtim_clear" },


    {   WE_PPS_EOF_PAD_DELIM,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "eof_delim" },


    {   WE_PPS_MACADDR_MISMATCH,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "mac_match" },


    {   WE_PPS_DELIM_CRC_FAIL,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "delim_fail" },


    {   WE_PPS_GID_NSTS_ZERO,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "nsts_zero" },


    {   WE_PPS_RSSI_CHECK,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "rssi_chk" },

    {   WE_PPS_5G_EBT,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "5g_ebt" },

    {   WE_SET_HTSMPS,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "htsmps" },


    {   WE_SET_QPOWER_MAX_PSPOLL_COUNT,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "set_qpspollcnt" },

    {   WE_SET_QPOWER_MAX_TX_BEFORE_WAKE,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "set_qtxwake" },

    {   WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "set_qwakeintv" },

    {   WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "set_qnodatapoll" },

    /* handlers for MCC time quota and latency sub ioctls */
    {   WE_MCC_CONFIG_LATENCY,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "setMccLatency" },

    {   WE_MCC_CONFIG_QUOTA,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "setMccQuota" },

    {   WE_SET_DEBUG_LOG,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "setDbgLvl" },

    {   WE_SET_SCAN_BAND_PREFERENCE,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "set_scan_pref" },
    /* handlers for early_rx power save */
    {   WE_SET_EARLY_RX_ADJUST_ENABLE,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "erx_enable" },

    {   WE_SET_EARLY_RX_TGT_BMISS_NUM,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "erx_bmiss_val" },

    {   WE_SET_EARLY_RX_BMISS_SAMPLE_CYCLE,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "erx_bmiss_smpl" },

    {   WE_SET_EARLY_RX_SLOP_STEP,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "erx_slop_step" },

    {   WE_SET_EARLY_RX_INIT_SLOP,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "erx_init_slop" },

    {   WE_SET_EARLY_RX_ADJUST_PAUSE,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "erx_adj_pause" },

    {   WE_SET_EARLY_RX_DRIFT_SAMPLE,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "erx_dri_sample" },

    {   WLAN_PRIV_SET_NONE_GET_INT,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "" },

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

    {   WE_CLEAR_STATS,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "clearStats" },

    {   WE_SET_CHANNEL,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "setChanChange" },

    {   WE_SET_MODULATED_DTIM,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "setModDTIM" },

    {
        WE_SET_MON_FILTER,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "setMonFilter" },
#ifdef FEATURE_WLAN_TDLS
    {
        WE_SET_TDLS_OFFCHANNEL_MODE,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "tdlsoffchnmode" },
    {
        WE_SET_TDLS_OFFCHANNEL,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "tdlsoffchan" },
    {
        WE_SET_TDLS_OFFCHANNEL_SEC_OFFSET,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "tdlsecchnoffst" },
#endif

    /* handlers for sub-ioctl */
    {   WE_GET_11D_STATE,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get11Dstate" },

    {   WE_IBSS_STATUS,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "getAdhocStatus" },

    {   WE_GET_WLAN_DBG,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "getwlandbg" },

    {   WE_GET_MAX_ASSOC,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "getMaxAssoc" },

    {   WE_GET_SAP_AUTO_CHANNEL_SELECTION,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "getAutoChannel" },

    {   WE_GET_CONCURRENCY_MODE,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "getconcurrency" },

    {   WE_GET_NSS,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_nss" },

    {   WE_GET_LDPC,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_ldpc" },

    {   WE_GET_TX_STBC,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_tx_stbc" },

    {   WE_GET_RX_STBC,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_rx_stbc" },

    {   WE_GET_SHORT_GI,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_shortgi" },

    {   WE_GET_RTSCTS,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_rtscts" },

    {   WE_GET_CHWIDTH,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_chwidth" },

    {   WE_GET_ANI_EN_DIS,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_anienable" },

    {   WE_GET_ANI_POLL_PERIOD,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_aniplen" },

    {   WE_GET_ANI_LISTEN_PERIOD,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_anilislen" },

    {   WE_GET_ANI_OFDM_LEVEL,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_aniofdmlvl" },

    {   WE_GET_ANI_CCK_LEVEL,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_aniccklvl" },

    {   WE_GET_DYNAMIC_BW,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_cwmenable" },

    {  WE_GET_GTX_HT_MCS,
       0,
       IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_gtxHTMcs" },

    {  WE_GET_GTX_VHT_MCS,
       0,
       IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_gtxVHTMcs" },

    {  WE_GET_GTX_USRCFG,
        0,
       IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_gtxUsrCfg" },

    {  WE_GET_GTX_THRE,
        0,
       IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_gtxThre" },

    {  WE_GET_GTX_MARGIN,
        0,
       IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_gtxMargin" },

    {  WE_GET_GTX_STEP,
        0,
       IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_gtxStep" },

    {  WE_GET_GTX_MINTPC,
        0,
       IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_gtxMinTpc" },

    {  WE_GET_GTX_BWMASK,
        0,
       IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_gtxBWMask" },

    {   WE_GET_TX_CHAINMASK,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_txchainmask" },

    {   WE_GET_RX_CHAINMASK,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_rxchainmask" },

    {   WE_GET_11N_RATE,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_11nrate" },

    {   WE_GET_AMPDU,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_ampdu" },

    {   WE_GET_AMSDU,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_amsdu" },

    {   WE_GET_BURST_ENABLE,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_burst_en" },

    {   WE_GET_BURST_DUR,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_burst_dur" },

    {   WE_GET_TXPOW_2G,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_txpow2g" },

    {   WE_GET_TXPOW_5G,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_txpow5g" },

    {   WE_GET_PPS_PAID_MATCH,
    0,
    IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
    "get_paid_match"},


    {   WE_GET_PPS_GID_MATCH,
    0,
    IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
    "get_gid_match"},


    {   WE_GET_PPS_EARLY_TIM_CLEAR,
    0,
    IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
    "get_tim_clear"},


    {   WE_GET_PPS_EARLY_DTIM_CLEAR,
    0,
    IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
    "get_dtim_clear"},


    {   WE_GET_PPS_EOF_PAD_DELIM,
    0,
    IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
    "get_eof_delim"},


    {   WE_GET_PPS_MACADDR_MISMATCH,
    0,
    IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
    "get_mac_match"},


    {   WE_GET_PPS_DELIM_CRC_FAIL,
    0,
    IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
    "get_delim_fail"},


    {   WE_GET_PPS_GID_NSTS_ZERO,
    0,
    IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
    "get_nsts_zero"},


    {   WE_GET_PPS_RSSI_CHECK,
    0,
    IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
    "get_rssi_chk"},

    {   WE_GET_QPOWER_MAX_PSPOLL_COUNT,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_qpspollcnt"},

    {   WE_GET_QPOWER_MAX_TX_BEFORE_WAKE,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_qtxwake"},

    {   WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_qwakeintv"},

    {   WE_GET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_qnodatapoll"},

    {   WE_GET_SCAN_BAND_PREFERENCE,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_scan_pref"},

    {   WE_GET_TEMPERATURE,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_temp"},

    {   WE_GET_FW_STATUS,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_fwstate"},
#ifdef WLAN_FEATURE_TSF
    {   WE_CAP_TSF,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "cap_tsf"},
#endif
    /* handlers for main ioctl */
    {   WLAN_PRIV_SET_CHAR_GET_NONE,
        IW_PRIV_TYPE_CHAR| 512,
        0,
        "" },

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

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

#if defined WLAN_FEATURE_VOWIFI
    /* handlers for sub-ioctl */
    {   WE_NEIGHBOR_REPORT_REQUEST,
        IW_PRIV_TYPE_CHAR | 512,
        0,
        "neighbor" },
#endif
    {   WE_SET_AP_WPS_IE,
        IW_PRIV_TYPE_CHAR| 512,
        0,
        "set_ap_wps_ie" },

    {   WE_SET_CONFIG,
        IW_PRIV_TYPE_CHAR| 512,
        0,
        "setConfig" },

    /* handlers for main ioctl */
    {   WLAN_PRIV_SET_THREE_INT_GET_NONE,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
        0,
        "" },

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

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

    {   WE_SET_SAP_CHANNELS,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
        0,
        "setsapchannels" },
#ifdef FEATURE_PBM_MAGIC_WOW
    {   WE_SET_ADD_EASY_WOW_PORT,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
        0,
        "add_wow_port" },

    {   WE_SET_RM_EASY_WOW_PORT,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
        0,
        "rm_wow_port" },
#endif
     /* handlers for main ioctl */
    {   WLAN_PRIV_SET_NONE_GET_THREE_INT,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
        "" },
#ifdef WLAN_FEATURE_TSF
    {   WE_GET_TSF,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
        "get_tsf" },
#endif
    /* handlers for main ioctl */
    {   WLAN_PRIV_GET_CHAR_SET_NONE,
        0,
        IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
        "" },

    /* handlers for sub-ioctl */
    {   WE_WLAN_VERSION,
        0,
        IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
        "version" },
    {   WE_GET_STATS,
        0,
        IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
        "getStats" },
    {   WE_GET_STATES,
        0,
        IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
        "getHostStates" },
    {   WE_GET_CFG,
        0,
        IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
        "getConfig" },
#ifdef WLAN_FEATURE_11AC
    {   WE_GET_RSSI,
        0,
        IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
        "getRSSI" },
#endif
    {   WE_GET_WMM_STATUS,
        0,
        IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
        "getWmmStatus" },
    {
        WE_GET_CHANNEL_LIST,
        0,
        IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
        "getChannelList" },
#ifdef FEATURE_WLAN_TDLS
    {
        WE_GET_TDLS_PEERS,
        0,
        IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
        "getTdlsPeers" },
#endif
#ifdef WLAN_FEATURE_11W
    {
        WE_GET_11W_INFO,
        0,
        IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
        "getPMFInfo" },
#endif
    {
        WE_GET_IBSS_STA_INFO,
        0,
        IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
        "getIbssSTAs" },
    {   WE_GET_PHYMODE,
        0,
        IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
        "getphymode" },
#ifdef FEATURE_OEM_DATA_SUPPORT
    {   WE_GET_OEM_DATA_CAP,
        0,
        IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
        "getOemDataCap" },
#endif /* FEATURE_OEM_DATA_SUPPORT */
    {   WE_GET_SNR,
        0,
        IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
        "getSNR" },

    /* handlers for main ioctl */
    {   WLAN_PRIV_SET_NONE_GET_NONE,
        0,
        0,
        "" },

    /* handlers for sub-ioctl */
    {
        WE_IBSS_GET_PEER_INFO_ALL,
        0,
        0,
       "ibssPeerInfoAll" },
    {   WE_GET_RECOVERY_STAT,
        0,
        0,
        "getRecoverStat" },
    {   WE_ENABLE_DXE_STALL_DETECT,
        0,
        0,
        "dxeStallDetect" },
    {   WE_DISPLAY_DXE_SNAP_SHOT,
        0,
        0,
        "dxeSnapshot" },
    {   WE_DISPLAY_DATAPATH_SNAP_SHOT,
        0,
        0,
        "dataSnapshot"},
    {
        WE_SET_REASSOC_TRIGGER,
        0,
        0,
        "reassoc" },
    {   WE_DUMP_AGC_START,
        0,
        0,
        "dump_agc_start" },

    {   WE_DUMP_AGC,
        0,
        0,
        "dump_agc" },

    {   WE_DUMP_CHANINFO_START,
        0,
        0,
        "dump_chninfo_en" },

    {   WE_DUMP_CHANINFO,
        0,
        0,
        "dump_chninfo" },

    {   WE_DUMP_WATCHDOG,
        0,
        0,
        "dump_watchdog" },
#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG
    {   WE_DUMP_PCIE_LOG,
        0,
        0,
        "dump_pcie_log" },
#endif
    /* handlers for main ioctl */
    {   WLAN_PRIV_SET_VAR_INT_GET_NONE,
        IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
        0,
        "" },

    /* handlers for sub-ioctl */
    {   WE_LOG_DUMP_CMD,
        IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
        0,
        "dump" },
    {   WE_IBSS_GET_PEER_INFO,
        IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
        0,
        "ibssPeerInfo" },

    /* handlers for sub-ioctl */
    {   WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD,
        IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
        0,
        "setdumplog" },

    {   WE_MTRACE_DUMP_CMD,
        IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
        0,
        "dumplog" },

    /* handlers for sub ioctl */
   {
       WE_MCC_CONFIG_CREDENTIAL,
       IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
       0,
       "setMccCrdnl" },

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

#ifdef FEATURE_WLAN_TDLS
    /* handlers for sub ioctl */
   {
       WE_TDLS_CONFIG_PARAMS,
       IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
       0,
       "setTdlsConfig" },
#endif
    {
        WE_UNIT_TEST_CMD,
        IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
        0,
        "setUnitTestCmd" },

#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
    {   WE_LED_FLASHING_PARAM,
        IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
        0,
        "gpio_control" },
#endif

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

    /* handlers for main ioctl */
    {   WLAN_PRIV_ADD_TSPEC,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | HDD_WLAN_WMM_PARAM_COUNT,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "addTspec" },

    /* handlers for main ioctl */
    {   WLAN_PRIV_DEL_TSPEC,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "delTspec" },

    /* handlers for main ioctl */
    {   WLAN_PRIV_GET_TSPEC,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "getTspec" },

    /* handlers for main ioctl - host offload */
    {
        WLAN_PRIV_SET_HOST_OFFLOAD,
        IW_PRIV_TYPE_BYTE | sizeof(tHostOffloadRequest),
        0,
        "setHostOffload" },

    {
        WLAN_GET_WLAN_STATISTICS,
        0,
        IW_PRIV_TYPE_BYTE | WE_MAX_STR_LEN,
        "getWlanStats" },

    {
        WLAN_SET_KEEPALIVE_PARAMS,
        IW_PRIV_TYPE_BYTE | sizeof(tSirKeepAliveReq) |
        IW_PRIV_SIZE_FIXED,
        0,
        "setKeepAlive" },
#ifdef WLAN_FEATURE_PACKET_FILTERING
    {
        WLAN_SET_PACKET_FILTER_PARAMS,
        IW_PRIV_TYPE_BYTE  | sizeof(tPacketFilterCfg),
        0,
        "setPktFilter" },
#endif
#ifdef FEATURE_WLAN_SCAN_PNO
    {
        WLAN_SET_PNO,
        IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
        0,
        "setpno" },
#endif
    {
        WLAN_SET_BAND_CONFIG,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "SETBAND" },
    /* handlers for dynamic MC BC ioctl */
    {
        WLAN_PRIV_SET_MCBC_FILTER,
        IW_PRIV_TYPE_BYTE | sizeof(tRcvFltMcAddrList),
        0,
        "setMCBCFilter" },
    {
        WLAN_PRIV_CLEAR_MCBC_FILTER,
        0,
        0,
        "clearMCBCFilter" },
    {
        WLAN_SET_POWER_PARAMS,
        IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
        0,
        "setpowerparams" },
    {
        WLAN_GET_LINK_SPEED,
        IW_PRIV_TYPE_CHAR | 18,
        IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed" },
    {
        WLAN_GET_ISOLATION,
        0,
        IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
        "get_isolation"
    },
    /* handlers for main ioctl */
    {   WLAN_PRIV_SET_TWO_INT_GET_NONE,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
        0,
        "" },
    {   WE_SET_SMPS_PARAM,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
        0, "set_smps_param" },
    {   WLAN_SET_DOT11P_CHANNEL_SCHED,
        IW_PRIV_TYPE_BYTE
      | sizeof(struct dot11p_channel_sched),
        0, "set_dot11p" },
#ifdef WLAN_DEBUG
    {   WE_SET_FW_CRASH_INJECT,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
        0, "crash_inject" },
#endif
    {   WE_SET_MON_MODE_CHAN,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
        0, "setMonChan" },
    {   WE_DUMP_DP_TRACE_LEVEL,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
        0, "dump_dp_trace"},
    {   WE_SET_PS_TDCC,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
	0, "set_ps_tdcc" },
    {   WE_GET_PS_TDCC,
        0,
        IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
        "get_ps_tdcc" },
#ifdef FEATURE_PBM_MAGIC_WOW
    {
        WE_SET_WOW_START,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "wow_start" },
    {
        WE_PBM_MP_GET_REASON,
        0,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        "get_wow_reason"},
#endif
    {
        WLAN_PRIV_SET_FTIES,
        IW_PRIV_TYPE_CHAR | MAX_FTIE_SIZE,
        0, "set_ft_ies"},
#ifdef WLAN_FEATURE_MOTION_DETECTION
    {
        WE_MOTION_DET_CONFIG_PARAM,
        IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
        0, "mt_config"},
    {
        WE_MOTION_DET_START_STOP,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "mt_start"},
    {
        WE_MOTION_DET_BASE_LINE_CONFIG_PARAM,
        IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
        0, "mt_bl_config"},
    {
        WE_MOTION_DET_BASE_LINE_START_STOP,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "mt_bl_start"},
#endif
    {   WE_SET_THERMAL_THROTTLE_CONFIG,
        IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
        0, "setThermalConfig" },
    {   WE_SET_HPCS_PULSE_PARAMS_CONFIG,
        IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
        0, "setHpcsParams" },
#ifdef AUDIO_MULTICAST_AGGR_SUPPORT
    {   WE_AUDIO_AGGR_SET_STA,
        IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
        0, "au_set_sta" },
    {   WE_AUDIO_GET_RX_GROUP_INFO,
         0,
        IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
        "au_rx_show_grp" },
#endif
    {
        WE_SAP_TX_OFF,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0, "sap_tx_off"},
#if !defined(WDI_API_AS_FUNCS)
    {   WE_SET_TXRX_PRINT_LEVEL,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "set_txrx_level" },
#endif
    {   WE_SAP_SET_TARGET_CHANNEL,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "set_target_ch" },
    {   WE_SAP_SET_CAC_TIME,
        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
        0,
        "set_cac_time" },
};



const struct iw_handler_def we_handler_def = {
   .num_standard     = sizeof(we_handler) / sizeof(we_handler[0]),
#ifdef CONFIG_WEXT_PRIV
   .num_private      = sizeof(we_private) / sizeof(we_private[0]),
   .num_private_args = sizeof(we_private_args) / sizeof(we_private_args[0]),
   .private          = (iw_handler *)we_private,
   .private_args     = we_private_args,
#endif
   .standard         = (iw_handler *)we_handler,
   .get_wireless_stats = get_wireless_stats,
};

int hdd_validate_mcc_config(hdd_adapter_t *pAdapter, v_UINT_t staId, v_UINT_t arg1, v_UINT_t arg2, v_UINT_t arg3)
{
    v_U32_t  cmd = 288; //Command to RIVA
    hdd_context_t *pHddCtx = NULL;
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    /*
     *configMccParam : specify the bit which needs to be modified
     *allowed to update based on wlan_qcom_cfg.ini
     * configuration
     * Bit 0 : SCHEDULE_TIME_SLICE   MIN : 5 MAX : 20
     * Bit 1 : MAX_NULL_SEND_TIME    MIN : 1 MAX : 10
     * Bit 2 : TX_EARLY_STOP_TIME    MIN : 1 MAX : 10
     * Bit 3 : RX_DRAIN_TIME         MIN : 1 MAX : 10
     * Bit 4 : CHANNEL_SWITCH_TIME   MIN : 1 MAX : 20
     * Bit 5 : MIN_CHANNEL_TIME      MIN : 5 MAX : 20
     * Bit 6 : PARK_BEFORE_TBTT      MIN : 1 MAX :  5
     * Bit 7 : MIN_AFTER_DTIM        MIN : 5 MAX : 15
     * Bit 8 : TOO_CLOSE_MARGIN      MIN : 1 MAX :  3
     * Bit 9 : Reserved
     */
    switch (arg1)
    {
        //Update MCC SCHEDULE_TIME_SLICE parameter
        case MCC_SCHEDULE_TIME_SLICE_CFG_PARAM :
            if( pHddCtx->cfg_ini->configMccParam & 0x0001)
            {
                if((arg2 >= 5) && (arg2 <= 20))
                {
                    logPrintf(hHal, cmd, staId, arg1, arg2, arg3);
                }
                else
                {
                    hddLog(LOGE, "%s : Enter a valid MCC configuration value", __FUNCTION__);
                    return 0;
                }
            }
            break;

        //Update MCC MAX_NULL_SEND_TIME parameter
        case MCC_MAX_NULL_SEND_TIME_CFG_PARAM :
            if( pHddCtx->cfg_ini->configMccParam & 0x0002)
            {
                if((arg2 >= 1) && (arg2 <= 10))
                {
                    logPrintf(hHal, cmd, staId, arg1, arg2, arg3);
                }
                else
                {
                    hddLog(LOGE, "%s : Enter a valid MCC configuration value", __FUNCTION__);
                    return 0;
                }
            }
            break;

        //Update MCC TX_EARLY_STOP_TIME parameter
        case MCC_TX_EARLY_STOP_TIME_CFG_PARAM :
            if( pHddCtx->cfg_ini->configMccParam & 0x0004)
            {
                if((arg2 >= 1) && (arg2 <= 10))
                {
                    logPrintf(hHal, cmd, staId, arg1, arg2, arg3);
                }
                else
                {
                    hddLog(LOGE, "%s : Enter a valid MCC configuration value", __FUNCTION__);
                    return 0;
                }
            }
            break;

        //Update MCC RX_DRAIN_TIME parameter
        case MCC_RX_DRAIN_TIME_CFG_PARAM :
            if( pHddCtx->cfg_ini->configMccParam & 0x0008)
            {
                if((arg2 >= 1) && (arg2 <= 10))
                {
                    logPrintf(hHal, cmd, staId, arg1, arg2, arg3);
                }
                else
                {
                    hddLog(LOGE, "%s : Enter a valid MCC configuration value", __FUNCTION__);
                    return 0;
                }
            }
        break;

        //Update MCC CHANNEL_SWITCH_TIME parameter
        case MCC_CHANNEL_SWITCH_TIME_CFG_PARAM :
            if( pHddCtx->cfg_ini->configMccParam & 0x0010)
            {
                if((arg2 >= 1) && (arg2 <= 20))
                {
                    logPrintf(hHal, cmd, staId, arg1, arg2, arg3);
                }
                else
                {
                    hddLog(LOGE, "%s : Enter a valid MCC configuration value", __FUNCTION__);
                    return 0;
                }
            }
            break;

        //Update MCC MIN_CHANNEL_TIME parameter
        case MCC_MIN_CHANNEL_TIME_CFG_PARAM :
            if( pHddCtx->cfg_ini->configMccParam & 0x0020)
            {
                if((arg2 >= 5) && (arg2 <= 20))
                {
                    logPrintf(hHal, cmd, staId, arg1, arg2, arg3);
                }
                else
                {
                    hddLog(LOGE, "%s : Enter a valid MCC configuration value", __FUNCTION__);
                    return 0;
                }
            }
            break;

        //Update MCC PARK_BEFORE_TBTT parameter
        case MCC_PARK_BEFORE_TBTT_CFG_PARAM :
            if( pHddCtx->cfg_ini->configMccParam & 0x0040)
            {
                if((arg2 >= 1) && (arg2 <= 5))
                {
                    logPrintf(hHal, cmd, staId, arg1, arg2, arg3);
                }
                else
                {
                    hddLog(LOGE, "%s : Enter a valid MCC configuration value", __FUNCTION__);
                    return 0;
                }
            }
            break;

        //Update MCC MIN_AFTER_DTIM parameter
        case MCC_MIN_AFTER_DTIM_CFG_PARAM :
            if( pHddCtx->cfg_ini->configMccParam & 0x0080)
            {
                if((arg2 >= 5) && (arg2 <= 15))
                {
                    logPrintf(hHal, cmd, staId, arg1, arg2, arg3);
                }
                else
                {
                    hddLog(LOGE, "%s : Enter a valid MCC configuration value", __FUNCTION__);
                    return 0;
                }
            }
            break;

        //Update MCC TOO_CLOSE_MARGIN parameter
        case MCC_TOO_CLOSE_MARGIN_CFG_PARAM :
            if( pHddCtx->cfg_ini->configMccParam & 0x0100)
            {
                if((arg2 >= 1) && (arg2 <= 3))
                {
                    logPrintf(hHal, cmd, staId, arg1, arg2, arg3);
                }
                else
                {
                    hddLog(LOGE, "%s : Enter a valid MCC configuration value", __FUNCTION__);
                    return 0;
                }
            }
            break;

        default :
            hddLog(LOGE, FL("Unknown / Not allowed to configure parameter : %d"), arg1);
            break;
    }
    return 0;
}

/* hdd_set_wext() - configures bss parameters
 * @pAdapter: handle to adapter context
 *
 * Returns: none
 */
int hdd_set_wext(hdd_adapter_t *pAdapter)
{
    hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

    ENTER();

    if (!pwextBuf) {
        hddLog(LOGE, FL("ERROR: pwextBuf is NULL"));
        return VOS_STATUS_E_FAILURE;
    }

    if (!pHddStaCtx) {
        hddLog(LOGE, FL("ERROR: pHddStaCtx is NULL"));
        return VOS_STATUS_E_FAILURE;
    }

    /* Now configure the roaming profile links. To SSID and bssid */
    pwextBuf->roamProfile.SSIDs.numOfSSIDs = 0;
    pwextBuf->roamProfile.SSIDs.SSIDList = &pHddStaCtx->conn_info.SSID;

    pwextBuf->roamProfile.BSSIDs.numOfBSSIDs = 0;
    pwextBuf->roamProfile.BSSIDs.bssid = &pHddStaCtx->conn_info.bssId;

    /*Set the numOfChannels to zero to scan all the channels*/
    pwextBuf->roamProfile.ChannelInfo.numOfChannels = 0;
    pwextBuf->roamProfile.ChannelInfo.ChannelList = NULL;

    /* Default is no encryption */
    pwextBuf->roamProfile.EncryptionType.numEntries = 1;
    pwextBuf->roamProfile.EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;

    pwextBuf->roamProfile.mcEncryptionType.numEntries = 1;
    pwextBuf->roamProfile.mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;

    pwextBuf->roamProfile.BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;

    /* Default is no authentication */
    pwextBuf->roamProfile.AuthType.numEntries = 1;
    pwextBuf->roamProfile.AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;

    pwextBuf->roamProfile.phyMode = eCSR_DOT11_MODE_AUTO;
    pwextBuf->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;

    /*Set the default scan mode*/
    pAdapter->scan_info.scan_mode = eSIR_ACTIVE_SCAN;

    hdd_clearRoamProfileIe(pAdapter);

    EXIT();
    return VOS_STATUS_SUCCESS;
}

#ifdef WLAN_FEATURE_FILS_SK
static void hdd_initialize_fils_info(hdd_wext_state_t *pwextBuf)
{
    pwextBuf->roamProfile.fils_con_info = NULL;
}
#else
static void hdd_initialize_fils_info(hdd_wext_state_t *pwextBuf)
{ }
#endif

/**
 * hdd_register_wext() - register wext context
 * @dev: net device handle
 *
 * Registers wext interface context for a given net device
 *
 * Returns: 0 on success, errno on failure
 */
int hdd_register_wext(struct net_device *dev)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    VOS_STATUS status;

    ENTER();

    if (!pwextBuf) {
        hddLog(LOGE, FL("ERROR: pwextBuf is NULL"));
        return eHAL_STATUS_FAILURE;
    }

    /* Zero the memory. This zeros the profile structure */
    memset(pwextBuf, 0, sizeof(hdd_wext_state_t));

    init_completion(&pwextBuf->completion_var);

    status = hdd_set_wext(pAdapter);
    if (!VOS_IS_STATUS_SUCCESS(status)) {
        hddLog(LOGE, FL("ERROR: hdd_set_wext failed!!"));
        return eHAL_STATUS_FAILURE;
    }

    if (!VOS_IS_STATUS_SUCCESS(vos_event_init(&pwextBuf->vosevent))) {
        hddLog(LOGE, FL("ERROR: HDD vos event init failed!!"));
        return eHAL_STATUS_FAILURE;
    }

    if (!VOS_IS_STATUS_SUCCESS(vos_event_init(&pwextBuf->scanevent))) {
        hddLog(LOGE, ("ERROR: HDD scan event init failed!!"));
        return eHAL_STATUS_FAILURE;
    }
    hdd_initialize_fils_info(pwextBuf);
#ifdef CONFIG_WIRELESS_EXT
    /* Register as a wireless device */
    dev->wireless_handlers = (struct iw_handler_def *)&we_handler_def;
#endif

    EXIT();
    return 0;
}

int hdd_UnregisterWext(struct net_device *dev)
{
	hddLog(LOG1, FL("dev(%pK)"), dev);

#ifdef CONFIG_WIRELESS_EXT
	if (dev != NULL) {
		rtnl_lock();
		dev->wireless_handlers = NULL;
		rtnl_unlock();
	}
#endif

	return 0;
}
