/*
 * ---------------------------------------------------------------------------
 * FILE:     sme_wext.c
 *
 * PURPOSE:
 *      Handlers for ioctls from iwconfig.
 *      These provide the control plane operations.
 *
 * Copyright (C) 2007-2009 by Cambridge Silicon Radio Ltd.
 *
 * Refer to LICENSE.txt included with this source code for details on
 * the license terms.
 *
 * ---------------------------------------------------------------------------
 */
#include <linux/types.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
#include <asm/uaccess.h>
#include <linux/ctype.h>
#include "unifi_priv.h"
#include <linux/rtnetlink.h>

#define CHECK_INITED(_priv)                             \
    do {                                                    \
        if (_priv->init_progress != UNIFI_INIT_COMPLETED) { \
            unifi_trace(_priv, UDBG2, "%s unifi not ready, failing wext call\n", __FUNCTION__); \
            return -ENODEV;                                 \
        }                                                   \
    } while (0)

/* Workaround for the wpa_supplicant hanging issue - disabled on Android */
#ifndef ANDROID_BUILD
#define CSR_WIFI_WEXT_HANG_WORKAROUND
#endif

#ifdef CSR_WIFI_WEXT_HANG_WORKAROUND
# define UF_RTNL_LOCK()    rtnl_lock()
# define UF_RTNL_UNLOCK()  rtnl_unlock()
#else
# define UF_RTNL_LOCK()
# define UF_RTNL_UNLOCK()
#endif


/*
 * ---------------------------------------------------------------------------
 *      Helper functions
 * ---------------------------------------------------------------------------
 */

/*
 * ---------------------------------------------------------------------------
 *  wext_freq_to_channel
 *  channel_to_mhz
 *
 *      These functions convert between channel number and frequency.
 *
 *  Arguments:
 *      ch      Channel number, as defined in 802.11 specs
 *      m, e    Mantissa and exponent as provided by wireless extension.
 *
 *  Returns:
 *      channel or frequency (in MHz) value
 * ---------------------------------------------------------------------------
 */
static int
wext_freq_to_channel(int m, int e)
{
    int mhz;

    mhz = m;
    while (e < 6) {
        mhz /= 10;
        e++;
    }
    while (e > 6) {
        mhz *= 10;
        e--;
    }

    if (mhz >= 5000) {
        return ((mhz - 5000) / 5);
    }

    if (mhz == 2482) {
        return 14;
    }

    if (mhz >= 2407) {
        return ((mhz - 2407) / 5);
    }

    return 0;
} /* wext_freq_to_channel() */

static int
channel_to_mhz(int ch, int dot11a)
{

    if (ch == 0) return 0;
    if (ch > 200) return 0;

    /* 5G */
    if (dot11a) {
        return (5000 + (5 * ch));
    }

    /* 2.4G */
    if (ch == 14) {
        return 2484;
    }

    if ((ch < 14) && (ch > 0)) {
        return (2407 + (5 * ch));
    }

    return 0;
}
#ifdef CSR_SUPPORT_WEXT_AP
void uf_sme_wext_ap_set_defaults(unifi_priv_t *priv)
{
    memcpy(priv->ap_config.ssid.ssid,"defaultssid",sizeof("defaultssid"));

    priv->ap_config.ssid.length = 8;
    priv->ap_config.channel = 6;
    priv->ap_config.if_index = 1;
    priv->ap_config.credentials.authType = 0;
    priv->ap_config.max_connections=8;

    priv->group_sec_config.apGroupkeyTimeout = 0;
    priv->group_sec_config.apStrictGtkRekey = 0;
    priv->group_sec_config.apGmkTimeout = 0;
    priv->group_sec_config.apResponseTimeout = 100; /* Default*/
    priv->group_sec_config.apRetransLimit = 3; /* Default*/
    /* Set default params even if they may not be used*/
    /* Until Here*/

    priv->ap_mac_config.preamble = CSR_WIFI_SME_USE_LONG_PREAMBLE;
    priv->ap_mac_config.shortSlotTimeEnabled = FALSE;
    priv->ap_mac_config.ctsProtectionType=CSR_WIFI_SME_CTS_PROTECTION_AUTOMATIC;

    priv->ap_mac_config.wmmEnabled = TRUE;
    priv->ap_mac_config.wmmApParams[0].cwMin=4;
    priv->ap_mac_config.wmmApParams[0].cwMax=10;
    priv->ap_mac_config.wmmApParams[0].aifs=3;
    priv->ap_mac_config.wmmApParams[0].txopLimit=0;
    priv->ap_mac_config.wmmApParams[0].admissionControlMandatory=FALSE;
    priv->ap_mac_config.wmmApParams[1].cwMin=4;
    priv->ap_mac_config.wmmApParams[1].cwMax=10;
    priv->ap_mac_config.wmmApParams[1].aifs=7;
    priv->ap_mac_config.wmmApParams[1].txopLimit=0;
    priv->ap_mac_config.wmmApParams[1].admissionControlMandatory=FALSE;
    priv->ap_mac_config.wmmApParams[2].cwMin=3;
    priv->ap_mac_config.wmmApParams[2].cwMax=4;
    priv->ap_mac_config.wmmApParams[2].aifs=1;
    priv->ap_mac_config.wmmApParams[2].txopLimit=94;
    priv->ap_mac_config.wmmApParams[2].admissionControlMandatory=FALSE;
    priv->ap_mac_config.wmmApParams[3].cwMin=2;
    priv->ap_mac_config.wmmApParams[3].cwMax=3;
    priv->ap_mac_config.wmmApParams[3].aifs=1;
    priv->ap_mac_config.wmmApParams[3].txopLimit=47;
    priv->ap_mac_config.wmmApParams[3].admissionControlMandatory=FALSE;

    priv->ap_mac_config.wmmApBcParams[0].cwMin=4;
    priv->ap_mac_config.wmmApBcParams[0].cwMax=10;
    priv->ap_mac_config.wmmApBcParams[0].aifs=3;
    priv->ap_mac_config.wmmApBcParams[0].txopLimit=0;
    priv->ap_mac_config.wmmApBcParams[0].admissionControlMandatory=FALSE;
    priv->ap_mac_config.wmmApBcParams[1].cwMin=4;
    priv->ap_mac_config.wmmApBcParams[1].cwMax=10;
    priv->ap_mac_config.wmmApBcParams[1].aifs=7;
    priv->ap_mac_config.wmmApBcParams[1].txopLimit=0;
    priv->ap_mac_config.wmmApBcParams[1].admissionControlMandatory=FALSE;
    priv->ap_mac_config.wmmApBcParams[2].cwMin=3;
    priv->ap_mac_config.wmmApBcParams[2].cwMax=4;
    priv->ap_mac_config.wmmApBcParams[2].aifs=2;
    priv->ap_mac_config.wmmApBcParams[2].txopLimit=94;
    priv->ap_mac_config.wmmApBcParams[2].admissionControlMandatory=FALSE;
    priv->ap_mac_config.wmmApBcParams[3].cwMin=2;
    priv->ap_mac_config.wmmApBcParams[3].cwMax=3;
    priv->ap_mac_config.wmmApBcParams[3].aifs=2;
    priv->ap_mac_config.wmmApBcParams[3].txopLimit=47;
    priv->ap_mac_config.wmmApBcParams[3].admissionControlMandatory=FALSE;

    priv->ap_mac_config.accessType=CSR_WIFI_AP_ACCESS_TYPE_NONE;
    priv->ap_mac_config.macAddressListCount=0;
    priv->ap_mac_config.macAddressList=NULL;

    priv->ap_mac_config.apHtParams.rxStbc=1;
    priv->ap_mac_config.apHtParams.rifsModeAllowed=TRUE;
    priv->ap_mac_config.apHtParams.greenfieldSupported=FALSE;
    priv->ap_mac_config.apHtParams.shortGi20MHz=TRUE;
    priv->ap_mac_config.apHtParams.htProtection=0;
    priv->ap_mac_config.apHtParams.dualCtsProtection=FALSE;

    priv->ap_mac_config.phySupportedBitmap =
            (CSR_WIFI_SME_AP_PHY_SUPPORT_B|CSR_WIFI_SME_AP_PHY_SUPPORT_G|CSR_WIFI_SME_AP_PHY_SUPPORT_N);
    priv->ap_mac_config.beaconInterval= 100;
    priv->ap_mac_config.dtimPeriod=3;
    priv->ap_mac_config.maxListenInterval=0x00ff;/* Set it to a large value
                                                    to enable different types of
                                                    devices to join us */
    priv->ap_mac_config.supportedRatesCount =
           uf_configure_supported_rates(priv->ap_mac_config.supportedRates,priv->ap_mac_config.phySupportedBitmap);
}
#endif
/*
 * ---------------------------------------------------------------------------
 *  uf_sme_wext_set_defaults
 *
 *      Set up power-on defaults for driver config.
 *
 *      Note: The SME Management API *cannot* be used in this function.
 *
 *  Arguments:
 *      priv            Pointer to device private context struct
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
void
uf_sme_wext_set_defaults(unifi_priv_t *priv)
{
    memset(&priv->connection_config, 0, sizeof(CsrWifiSmeConnectionConfig));

    priv->connection_config.bssType = CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE;
    priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_OPEN;
    priv->connection_config.encryptionModeMask = CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE;
    priv->connection_config.privacyMode = CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED;
    priv->connection_config.wmmQosInfo = 0xFF;
    priv->connection_config.ifIndex = CSR_WIFI_SME_RADIO_IF_BOTH;
    priv->connection_config.adhocJoinOnly = FALSE;
    priv->connection_config.adhocChannel = 6;

    priv->wep_tx_key_index = 0;

    priv->wext_wireless_stats.qual.qual = 0;
    priv->wext_wireless_stats.qual.level = 0;
    priv->wext_wireless_stats.qual.noise = 0;
    priv->wext_wireless_stats.qual.updated = 0x70;
#ifdef CSR_SUPPORT_WEXT_AP
    /* Initialize the default configuration for AP */
    uf_sme_wext_ap_set_defaults(priv);
#endif


} /* uf_sme_wext_set_defaults() */


/*
 * ---------------------------------------------------------------------------
 *      WEXT methods
 * ---------------------------------------------------------------------------
 */

/*
 * ---------------------------------------------------------------------------
 *  unifi_giwname   - handler for SIOCGIWNAME
 *  unifi_siwfreq   - handler for SIOCSIWFREQ
 *  unifi_giwfreq   - handler for SIOCGIWFREQ
 *  unifi_siwmode   - handler for SIOCSIWMODE
 *  unifi_giwmode   - handler for SIOCGIWMODE
 *  unifi_giwrange  - handler for SIOCGIWRANGE
 *  unifi_siwap     - handler for SIOCSIWAP
 *  unifi_giwap     - handler for SIOCGIWAP
 *  unifi_siwscan   - handler for SIOCSIWSCAN
 *  unifi_giwscan   - handler for SIOCGIWSCAN
 *  unifi_siwessid  - handler for SIOCSIWESSID
 *  unifi_giwessid  - handler for SIOCGIWESSID
 *  unifi_siwencode - handler for SIOCSIWENCODE
 *  unifi_giwencode - handler for SIOCGIWENCODE
 *
 *      Handler functions for IW extensions.
 *      These are registered via the unifi_iw_handler_def struct below
 *      and called by the generic IW driver support code.
 *      See include/net/iw_handler.h.
 *
 *  Arguments:
 *      None.
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
static int
iwprivsdefs(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    int r;
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    CsrWifiSmeMibConfig mibConfig;
    CsrWifiSmePowerConfig powerConfig;

    unifi_trace(priv, UDBG1, "iwprivs80211defaults: reload defaults\n");

    uf_sme_wext_set_defaults(priv);

    /* Get, modify and set the MIB data */
    r = sme_mgt_mib_config_get(priv, &mibConfig);
    if (r) {
        unifi_error(priv, "iwprivs80211defaults: Get CsrWifiSmeMibConfigValue failed.\n");
        return r;
    }
    mibConfig.dot11RtsThreshold = 2347;
    mibConfig.dot11FragmentationThreshold = 2346;
    r = sme_mgt_mib_config_set(priv, &mibConfig);
    if (r) {
        unifi_error(priv, "iwprivs80211defaults: Set CsrWifiSmeMibConfigValue failed.\n");
        return r;
    }

    powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW;
    powerConfig.listenIntervalTu = 100;
    powerConfig.rxDtims = 1;

    r = sme_mgt_power_config_set(priv, &powerConfig);
    if (r) {
        unifi_error(priv, "iwprivs80211defaults: Set unifi_PowerConfigValue failed.\n");
        return r;
    }

    return 0;
} /* iwprivsdefs() */

static int
iwprivs80211ps(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    int r = 0;
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;

    int ps_mode = (int)(*extra);
    CsrWifiSmePowerConfig powerConfig;

    unifi_trace(priv, UDBG1, "iwprivs80211ps: power save mode = %d\n", ps_mode);

    r = sme_mgt_power_config_get(priv, &powerConfig);
    if (r) {
        unifi_error(priv, "iwprivs80211ps: Get unifi_PowerConfigValue failed.\n");
        return r;
    }

    switch (ps_mode) {
        case CSR_PMM_ACTIVE_MODE:
            powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW;
            break;
        case CSR_PMM_POWER_SAVE:
            powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_HIGH;
            break;
        case CSR_PMM_FAST_POWER_SAVE:
            powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_MED;
            break;
        default:
            powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_AUTO;
            break;
    }

    r = sme_mgt_power_config_set(priv, &powerConfig);
    if (r) {
        unifi_error(priv, "iwprivs80211ps: Set unifi_PowerConfigValue failed.\n");
    }

    return r;
}

static int
iwprivg80211ps(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;

    CsrWifiSmePowerConfig powerConfig;
    int r;

    r = sme_mgt_power_config_get(priv, &powerConfig);
    if (r) {
        unifi_error(priv, "iwprivg80211ps: Get 802.11 power mode failed.\n");
        return r;
    }

    switch (powerConfig.powerSaveLevel) {
        case CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW:
            snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING,
                     "Power save mode: %d (Active)",
                     powerConfig.powerSaveLevel);
            break;
        case CSR_WIFI_SME_POWER_SAVE_LEVEL_MED:
            snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING,
                     "Power save mode: %d (Fast)",
                     powerConfig.powerSaveLevel);
            break;
        case CSR_WIFI_SME_POWER_SAVE_LEVEL_HIGH:
            snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING,
                     "Power save mode: %d (Full)",
                     powerConfig.powerSaveLevel);
            break;
        case CSR_WIFI_SME_POWER_SAVE_LEVEL_AUTO:
            snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING,
                     "Power save mode: %d (Auto)",
                     powerConfig.powerSaveLevel);
            break;
        default:
            snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING,
                     "Power save mode: %d (Unknown)",
                     powerConfig.powerSaveLevel);
            break;
    }

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

    return 0;
}

static int
iwprivssmedebug(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    /* No longer supported on the API */
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE)
    unifi_debug_buf_dump();
#endif

    return 0;
}

#ifdef CSR_SUPPORT_WEXT_AP
#define PARAM_TYPE_INT 0
#define PARAM_TYPE_STRING 1
#define CSR_WIFI_MAX_SSID_LEN 32
#define CSR_WIFI_MAX_SEC_LEN 16
#define CSR_WIFI_MAX_KEY_LEN 65

static int hex_look_up(char x)
{
    if(x>='0' && x<='9')
        return (x-48);
    if(x>= 'a' && x <= 'f')
        return (x-87);
    return -1;
}

static int power (int a, int b)
{
    int i;
    int num =1;
    for(i=0;i<b;i++)
       num *=a;
    return num;
}

static int decode_parameter_from_string(unifi_priv_t* priv, char **str_ptr,
                                        const char *token, int param_type,
                                        void  *dst, int param_max_len)
{
    u8 int_str[7] = "0";
    u32 param_str_len;
    u8  *param_str_begin,*param_str_end;
    u8  *orig_str = *str_ptr;

    if (!strncmp(*str_ptr, token, strlen(token))) {
        strsep(str_ptr, "=,");
        param_str_begin = *str_ptr;
        strsep(str_ptr, "=,");
        if (*str_ptr == NULL) {
            param_str_len = strlen(param_str_begin);
        } else {
            param_str_end = *str_ptr-1;
            param_str_len = param_str_end - param_str_begin;
        }
        unifi_trace(priv,UDBG2,"'token:%s', len:%d, ", token, param_str_len);
        if (param_str_len > param_max_len) {
            unifi_notice(priv,"extracted param len:%d is > MAX:%d\n",param_str_len, param_max_len);
            param_str_len = param_max_len;
        }
        switch (param_type) {
            case PARAM_TYPE_INT:
            {
                u32 *pdst_int = dst,num =0;
                int i,j=0;
                if (param_str_len > sizeof(int_str)) {
                    param_str_len = sizeof(int_str);
                }
                memcpy(int_str, param_str_begin, param_str_len);
                for(i = param_str_len; i>0;i--) {
                    if(int_str[i-1] >= '0' && int_str[i-1] <='9') {
                        num += ((int_str[i-1]-'0')*power(10,j));
                        j++;
                    } else {
                        unifi_error(priv,"decode_parameter_from_string:not a number %c\n",(int_str[i-1]));
                        return -1;
                    }
                }
                *pdst_int = num;
                unifi_trace(priv,UDBG2,"decode_parameter_from_string:decoded int = %d\n",*pdst_int);
            }
            break;
            default:
                memcpy(dst, param_str_begin, param_str_len);
                *((char *)dst + param_str_len) = 0;
                unifi_trace(priv,UDBG2,"decode_parameter_from_string:decoded string = %s\n",(char *)dst);
            break;
        }
    } else {
        unifi_error(priv,"decode_parameter_from_string: Token:%s not found in %s \n",token,orig_str);
        return -1;
    }
    return 0;
}
static int store_ap_advanced_config_from_string(unifi_priv_t *priv, char *param_str)
{
    char * str_ptr=param_str;
    int ret = 0,tmp_var;
    char phy_mode[6];
    CsrWifiSmeApMacConfig * ap_mac_config = &priv->ap_mac_config;

    /* Check for BI */
    ret = decode_parameter_from_string(priv, &str_ptr, "BI=",
                                       PARAM_TYPE_INT, &tmp_var, 5);
    if(ret) {
        unifi_error(priv,"store_ap_advanced_config_from_string: BI not found\n");
        return -1;
    }
    ap_mac_config->beaconInterval = tmp_var;
    ret = decode_parameter_from_string(priv, &str_ptr, "DTIM_PER=",
                                        PARAM_TYPE_INT, &tmp_var, 5);
    if(ret) {
        unifi_error(priv,"store_ap_advanced_config_from_string: DTIM_PER not found\n");
        return -1;
    }
    ap_mac_config->dtimPeriod = tmp_var;
    ret = decode_parameter_from_string(priv, &str_ptr, "WMM=",
                                        PARAM_TYPE_INT, &tmp_var, 5);
    if(ret) {
        unifi_error(priv,"store_ap_advanced_config_from_string: WMM not found\n");
        return -1;
    }
    ap_mac_config->wmmEnabled = tmp_var;
    ret = decode_parameter_from_string(priv, &str_ptr, "PHY=",
                                        PARAM_TYPE_STRING, phy_mode, 5);
    if(ret) {
        unifi_error(priv,"store_ap_advanced_config_from_string: PHY not found\n");
    } else {
       if(strstr(phy_mode,"b")){
           ap_mac_config->phySupportedBitmap = CSR_WIFI_SME_AP_PHY_SUPPORT_B;
       }
       if(strstr(phy_mode,"g")) {
           ap_mac_config->phySupportedBitmap |= CSR_WIFI_SME_AP_PHY_SUPPORT_G;
       }
       if(strstr(phy_mode,"n")) {
           ap_mac_config->phySupportedBitmap |= CSR_WIFI_SME_AP_PHY_SUPPORT_N;
       }
       ap_mac_config->supportedRatesCount =
       uf_configure_supported_rates(ap_mac_config->supportedRates, ap_mac_config->phySupportedBitmap);
    }
    return ret;
}

static int store_ap_config_from_string( unifi_priv_t * priv,char *param_str)

{
    char *str_ptr = param_str;
    char sub_cmd[16];
    char sec[CSR_WIFI_MAX_SEC_LEN];
    char key[CSR_WIFI_MAX_KEY_LEN];
    int ret = 0,tmp_var;
    CsrWifiSmeApConfig_t *ap_config = &priv->ap_config;
    CsrWifiSmeApMacConfig * ap_mac_config = &priv->ap_mac_config;
    memset(sub_cmd, 0, sizeof(sub_cmd));
    if(!strstr(param_str,"END")) {
        unifi_error(priv,"store_ap_config_from_string:Invalid config string:%s\n",param_str);
        return -1;
    }
    if (decode_parameter_from_string(priv,&str_ptr, "ASCII_CMD=",
        PARAM_TYPE_STRING, sub_cmd, 6) != 0) {
         return -1;
    }
    if (strncmp(sub_cmd, "AP_CFG", 6)) {

        if(!strncmp(sub_cmd ,"ADVCFG", 6)) {
           return store_ap_advanced_config_from_string(priv, str_ptr);
        }
        unifi_error(priv,"store_ap_config_from_string: sub_cmd:%s != 'AP_CFG or ADVCFG'!\n", sub_cmd);
        return -1;
    }
    memset(ap_config, 0, sizeof(CsrWifiSmeApConfig_t));
    ret = decode_parameter_from_string(priv,&str_ptr, "SSID=",
                                       PARAM_TYPE_STRING, ap_config->ssid.ssid,
                                       CSR_WIFI_MAX_SSID_LEN);
    if(ret) {
        unifi_error(priv,"store_ap_config_from_string: SSID not found\n");
        return -1;
    }
    ap_config->ssid.length = strlen(ap_config->ssid.ssid);

    ret = decode_parameter_from_string(priv, &str_ptr, "SEC=",
                                       PARAM_TYPE_STRING, sec, CSR_WIFI_MAX_SEC_LEN);
    if(ret) {
        unifi_error(priv,"store_ap_config_from_string: SEC not found\n");
        return -1;
    }
    ret = decode_parameter_from_string(priv,&str_ptr, "KEY=",
                         PARAM_TYPE_STRING,  key, CSR_WIFI_MAX_KEY_LEN);
    if(!strcasecmp(sec,"open")) {
        unifi_trace(priv,UDBG2,"store_ap_config_from_string: security open");
        ap_config->credentials.authType = CSR_WIFI_SME_AP_AUTH_TYPE_OPEN_SYSTEM;
        if(ret) {
            unifi_notice(priv,"store_ap_config_from_string: KEY not found:fine with Open\n");
        }
    }
    else if(!strcasecmp(sec,"wpa2-psk")) {
        int i,j=0;
        CsrWifiNmeApAuthPers *pers =
                            ((CsrWifiNmeApAuthPers *)&(ap_config->credentials.nmeAuthType.authTypePersonal));
        u8 *psk = pers->authPers_credentials.psk.psk;

        unifi_trace(priv,UDBG2,"store_ap_config_from_string: security WPA2");
        if(ret) {
            unifi_error(priv,"store_ap_config_from_string: KEY not found for WPA2\n");
            return -1;
        }
        ap_config->credentials.authType = CSR_WIFI_SME_AP_AUTH_TYPE_PERSONAL;
        pers->authSupport = CSR_WIFI_SME_RSN_AUTH_WPA2PSK;
        pers->rsnCapabilities =0;
        pers->wapiCapabilities =0;
        pers->pskOrPassphrase=CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PSK;
        pers->authPers_credentials.psk.encryptionMode =
                 (CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_CCMP |CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_CCMP) ;
        for(i=0;i<32;i++){
           psk[i] = (16*hex_look_up(key[j]))+hex_look_up(key[j+1]);
           j+=2;
        }

    } else {
       unifi_notice(priv,"store_ap_config_from_string: Unknown security: Assuming Open");
       ap_config->credentials.authType = CSR_WIFI_SME_AP_AUTH_TYPE_OPEN_SYSTEM;
       return -1;
    }
   /* Get the decoded value in a temp int variable to ensure that other fields within the struct
      which are of type other than int are not over written */
    ret = decode_parameter_from_string(priv,&str_ptr, "CHANNEL=", PARAM_TYPE_INT, &tmp_var, 5);
    if(ret)
        return -1;
    ap_config->channel = tmp_var;
    ret = decode_parameter_from_string(priv,&str_ptr, "PREAMBLE=", PARAM_TYPE_INT, &tmp_var, 5);
    if(ret)
        return -1;
    ap_mac_config->preamble = tmp_var;
    ret = decode_parameter_from_string(priv,&str_ptr, "MAX_SCB=", PARAM_TYPE_INT,  &tmp_var, 5);
    ap_config->max_connections = tmp_var;
    return ret;
}

static int
iwprivsapstart(struct net_device *dev, struct iw_request_info *info,
               union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    int r;

    unifi_trace(priv, UDBG1, "iwprivsapstart\n" );
    r = sme_ap_start(priv,interfacePriv->InterfaceTag,&priv->ap_config);
    if(r) {
        unifi_error(priv,"iwprivsapstart AP START failed : %d\n",-r);
    }
    return r;
}

static int
iwprivsapconfig(struct net_device *dev, struct iw_request_info *info,
                union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    char  *cfg_str = NULL;
    int r;

    unifi_trace(priv, UDBG1, "iwprivsapconfig\n" );
    if (wrqu->data.length != 0) {
        char *str;
        if (!(cfg_str = kmalloc(wrqu->data.length+1, GFP_KERNEL)))
        {
            return -ENOMEM;
        }
        if (copy_from_user(cfg_str, wrqu->data.pointer, wrqu->data.length)) {
            kfree(cfg_str);
            return -EFAULT;
        }
        cfg_str[wrqu->data.length] = 0;
        unifi_trace(priv,UDBG2,"length:%d\n",wrqu->data.length);
        unifi_trace(priv,UDBG2,"AP configuration string:%s\n",cfg_str);
        str = cfg_str;
       if ((r = store_ap_config_from_string(priv,str))) {
           unifi_error(priv, "iwprivsapconfig:Failed  to decode the string %d\n",r);
           kfree(cfg_str);
           return -EIO;

       }
    } else {
        unifi_error(priv,"iwprivsapconfig argument length = 0 \n");
        return -EIO;
    }
    r = sme_ap_config(priv, &priv->ap_mac_config, &priv->group_sec_config);
    if(r) {
        unifi_error(priv,"iwprivsapstop AP Config failed : %d\n",-r);
    } else if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
        interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
        unifi_trace(priv, UDBG1, "iwprivsapconfig: Starting the AP");
        r = sme_ap_start(priv,interfacePriv->InterfaceTag,&priv->ap_config);
        if(r) {
            unifi_error(priv,"iwprivsapstart AP START failed : %d\n",-r);
        }
    }
    kfree(cfg_str);
    return r;
}

static int
iwprivsapstop(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    int r;
    u16 interface_tag = interfacePriv->InterfaceTag;

    unifi_trace(priv, UDBG1, "iwprivsapstop\n" );
    r = sme_ap_stop(priv,interface_tag);
    if(r) {
        unifi_error(priv,"iwprivsapstop AP STOP failed : %d\n",-r);
    }
    return r;
}

#ifdef ANDROID_BUILD
static int
iwprivsapfwreload(struct net_device *dev, struct iw_request_info *info,
                  union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;

    unifi_trace(priv, UDBG1, "iwprivsapfwreload\n" );
    return 0;
}

static int
iwprivsstackstart(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    unifi_trace(priv, UDBG1, "iwprivsstackstart\n" );
    return 0;
}

static int
iwprivsstackstop(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    int r = 0;
    u16 interface_tag = interfacePriv->InterfaceTag;

    unifi_trace(priv, UDBG1, "iwprivsstackstop\n" );

    switch(interfacePriv->interfaceMode) {
        case CSR_WIFI_ROUTER_CTRL_MODE_STA:
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
        case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
            r = sme_mgt_disconnect(priv);
            break;
        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
            r = sme_ap_stop(priv,interface_tag);
            break;
        default :
            break;
    }

    if(r) {
        unifi_error(priv,"iwprivsstackstop Stack stop failed : %d\n",-r);
    }
    return 0;
}
#endif /* ANDROID_BUILD */
#endif /* CSR_SUPPORT_WEXT_AP */

#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
static int
iwprivsconfwapi(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    u8 enable;
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    func_enter();

    unifi_trace(priv, UDBG1, "iwprivsconfwapi\n" );

    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
       unifi_error(priv, "iwprivsconfwapi: not permitted in Mode %d\n",
                                      interfacePriv->interfaceMode);
       return -EPERM;
    }

    enable = *(u8*)(extra);

    if (enable) {
        priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_OPEN;
        priv->connection_config.authModeMask |= (CSR_WIFI_SME_AUTH_MODE_WAPI_WAIPSK | CSR_WIFI_SME_AUTH_MODE_WAPI_WAI);
        priv->connection_config.encryptionModeMask |=
            CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_SMS4 | CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_SMS4;
    } else {
        priv->connection_config.authModeMask &= ~(CSR_WIFI_SME_AUTH_MODE_WAPI_WAIPSK | CSR_WIFI_SME_AUTH_MODE_WAPI_WAI);
        priv->connection_config.encryptionModeMask &=
            ~(CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_SMS4 | CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_SMS4);
    }

    func_exit();
    return 0;
}

static int
iwprivswpikey(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    int r = 0, i;
    CsrWifiSmeKey key;
    unifiio_wapi_key_t inKey;
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    func_enter();

    unifi_trace(priv, UDBG1, "iwprivswpikey\n" );

    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
       unifi_error(priv, "iwprivswpikey: not permitted in Mode %d\n",
                                      interfacePriv->interfaceMode);
       return -EPERM;
    }

    inKey = *(unifiio_wapi_key_t*)(extra);

    if (inKey.unicastKey) {
        key.keyType   = CSR_WIFI_SME_KEY_TYPE_PAIRWISE;
    } else {
        key.keyType   = CSR_WIFI_SME_KEY_TYPE_GROUP;
    }

    key.keyIndex  = inKey.keyIndex;

    /* memcpy(key.keyRsc, inKey.keyRsc, 16); */
    for (i = 0; i < 16; i+= 2)
    {
        key.keyRsc[i/2] = inKey.keyRsc[i+1] << 8 | inKey.keyRsc[i];
    }

    memcpy(key.address.a, inKey.address, 6);
    key.keyLength = 32;
    memcpy(key.key, inKey.key, 32);
    key.authenticator = 0;
    key.wepTxKey = 0;

    unifi_trace(priv, UDBG1, "keyType = %d, keyIndex = %d, wepTxKey = %d, keyRsc = %x:%x, auth = %d, address = %x:%x, "
                "keylength = %d, key = %x:%x\n", key.keyType, key.keyIndex, key.wepTxKey,
                key.keyRsc[0], key.keyRsc[7], key.authenticator,
                key.address.a[0], key.address.a[5], key.keyLength, key.key[0],
                key.key[15]);

    r = sme_mgt_key(priv, &key, CSR_WIFI_SME_LIST_ACTION_ADD);
    if (r) {
        unifi_error(priv, "SETKEYS request was rejected with result %d\n", r);
        return convert_sme_error(r);
    }

    func_exit();
    return r;
}
#endif


static int
unifi_giwname(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    char *name = wrqu->name;
    unifi_trace(priv, UDBG2, "unifi_giwname\n");

    if (priv->if_index == CSR_INDEX_5G) {
        strcpy(name, "IEEE 802.11-a");
    } else {
        strcpy(name, "IEEE 802.11-bgn");
    }
    return 0;
} /* unifi_giwname() */


static int
unifi_siwfreq(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    struct iw_freq *freq = (struct iw_freq *)wrqu;

    func_enter();
    unifi_trace(priv, UDBG2, "unifi_siwfreq\n");

    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
       unifi_error(priv, "unifi_siwfreq: not permitted in Mode %d\n",
                                      interfacePriv->interfaceMode);
       return -EPERM;
    }


    /*
     * Channel is stored in the connection configuration,
     * and set later when ask for a connection.
     */
    if ((freq->e == 0) && (freq->m <= 1000)) {
        priv->connection_config.adhocChannel = freq->m;
    } else {
        priv->connection_config.adhocChannel = wext_freq_to_channel(freq->m, freq->e);
    }

    func_exit();
    return 0;
} /* unifi_siwfreq() */


static int
unifi_giwfreq(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    struct iw_freq *freq = (struct iw_freq *)wrqu;
    int err = 0;
    CsrWifiSmeConnectionInfo connectionInfo;

    func_enter();
    unifi_trace(priv, UDBG2, "unifi_giwfreq\n");
    CHECK_INITED(priv);

    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
       unifi_error(priv, "unifi_giwfreq: not permitted in Mode %d\n",
                                      interfacePriv->interfaceMode);
       return -EPERM;
    }


    UF_RTNL_UNLOCK();
    err = sme_mgt_connection_info_get(priv, &connectionInfo);
    UF_RTNL_LOCK();

    freq->m = channel_to_mhz(connectionInfo.channelNumber,
            (connectionInfo.networkType80211 == CSR_WIFI_SME_RADIO_IF_GHZ_5_0));
    freq->e = 6;

    func_exit();
    return convert_sme_error(err);
} /* unifi_giwfreq() */


static int
unifi_siwmode(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;

    func_enter();
    unifi_trace(priv, UDBG2, "unifi_siwmode\n");

    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
       unifi_error(priv, "unifi_siwmode: not permitted in Mode %d\n",
                                      interfacePriv->interfaceMode);
       return -EPERM;
    }


    switch(wrqu->mode) {
        case IW_MODE_ADHOC:
            priv->connection_config.bssType = CSR_WIFI_SME_BSS_TYPE_ADHOC;
            break;
        case IW_MODE_INFRA:
            priv->connection_config.bssType = CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE;
            break;
        case IW_MODE_AUTO:
            priv->connection_config.bssType = CSR_WIFI_SME_BSS_TYPE_ANY_BSS;
            break;
        default:
            unifi_notice(priv, "Unknown IW MODE value.\n");
    }

    /* Clear the SSID and BSSID configuration */
    priv->connection_config.ssid.length = 0;
    memset(priv->connection_config.bssid.a, 0xFF, ETH_ALEN);

    func_exit();
    return 0;
} /* unifi_siwmode() */



static int
unifi_giwmode(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    int r = 0;
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    CsrWifiSmeConnectionConfig connectionConfig;

    func_enter();
    unifi_trace(priv, UDBG2, "unifi_giwmode\n");
    CHECK_INITED(priv);

    unifi_trace(priv, UDBG2, "unifi_giwmode: Exisitng mode = 0x%x\n",
                interfacePriv->interfaceMode);
    switch(interfacePriv->interfaceMode) {
        case CSR_WIFI_ROUTER_CTRL_MODE_STA:
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
           wrqu->mode = IW_MODE_INFRA;
           break;
        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
            wrqu->mode = IW_MODE_MASTER;
            break;
        case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
            wrqu->mode = IW_MODE_ADHOC;
            break;
        case CSR_WIFI_ROUTER_CTRL_MODE_P2P:
        case CSR_WIFI_ROUTER_CTRL_MODE_NONE:
            UF_RTNL_UNLOCK();
            r = sme_mgt_connection_config_get(priv, &connectionConfig);
            UF_RTNL_LOCK();
            if (r == 0) {
                switch(connectionConfig.bssType) {
                    case CSR_WIFI_SME_BSS_TYPE_ADHOC:
                        wrqu->mode = IW_MODE_ADHOC;
                        break;
                    case CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE:
                        wrqu->mode = IW_MODE_INFRA;
                        break;
                    default:
                        wrqu->mode = IW_MODE_AUTO;
                        unifi_notice(priv, "Unknown IW MODE value.\n");
                }
            }
            break;
        default:
            wrqu->mode = IW_MODE_AUTO;
            unifi_notice(priv, "Unknown IW MODE value.\n");

    }
    unifi_trace(priv, UDBG4, "unifi_giwmode: mode = 0x%x\n", wrqu->mode);
    func_exit();
    return r;
} /* unifi_giwmode() */



static int
unifi_giwrange(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    struct iw_point *dwrq = &wrqu->data;
    struct iw_range *range = (struct iw_range *) extra;
    int i;

    unifi_trace(NULL, UDBG2, "unifi_giwrange\n");

    dwrq->length = sizeof(struct iw_range);
    memset(range, 0, sizeof(*range));
    range->min_nwid = 0x0000;
    range->max_nwid = 0x0000;

    /*
     * Don't report the frequency/channel table, then the channel
     * number returned elsewhere will be printed as a channel number.
     */

    /* Ranges of values reported in quality structs */
    range->max_qual.qual  = 40;         /* Max expected qual value */
    range->max_qual.level = -120;       /* Noise floor in dBm */
    range->max_qual.noise = -120;       /* Noise floor in dBm */


    /* space for IW_MAX_BITRATES (8 up to WE15, 32 later) */
    i = 0;
#if WIRELESS_EXT > 15
    range->bitrate[i++] =   2 * 500000;
    range->bitrate[i++] =   4 * 500000;
    range->bitrate[i++] =  11 * 500000;
    range->bitrate[i++] =  22 * 500000;
    range->bitrate[i++] =  12 * 500000;
    range->bitrate[i++] =  18 * 500000;
    range->bitrate[i++] =  24 * 500000;
    range->bitrate[i++] =  36 * 500000;
    range->bitrate[i++] =  48 * 500000;
    range->bitrate[i++] =  72 * 500000;
    range->bitrate[i++] =  96 * 500000;
    range->bitrate[i++] = 108 * 500000;
#else
    range->bitrate[i++] =   2 * 500000;
    range->bitrate[i++] =   4 * 500000;
    range->bitrate[i++] =  11 * 500000;
    range->bitrate[i++] =  22 * 500000;
    range->bitrate[i++] =  24 * 500000;
    range->bitrate[i++] =  48 * 500000;
    range->bitrate[i++] =  96 * 500000;
    range->bitrate[i++] = 108 * 500000;
#endif /* WIRELESS_EXT < 16 */
    range->num_bitrates = i;

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

    range->we_version_source = 20;
    range->we_version_compiled = WIRELESS_EXT;

    /* Number of channels available in h/w */
    range->num_channels = 14;
    /* Number of entries in freq[] array */
    range->num_frequency = 14;
    for (i = 0; (i < range->num_frequency) && (i < IW_MAX_FREQUENCIES); i++) {
        int chan = i + 1;
        range->freq[i].i = chan;
        range->freq[i].m = channel_to_mhz(chan, 0);
        range->freq[i].e = 6;
    }
    if ((i+3) < IW_MAX_FREQUENCIES) {
        range->freq[i].i = 36;
        range->freq[i].m = channel_to_mhz(36, 1);
        range->freq[i].e = 6;
        range->freq[i+1].i = 40;
        range->freq[i+1].m = channel_to_mhz(40, 1);
        range->freq[i+1].e = 6;
        range->freq[i+2].i = 44;
        range->freq[i+2].m = channel_to_mhz(44, 1);
        range->freq[i+2].e = 6;
        range->freq[i+3].i = 48;
        range->freq[i+3].m = channel_to_mhz(48, 1);
        range->freq[i+3].e = 6;
    }

#if WIRELESS_EXT > 16
    /* Event capability (kernel + driver) */
    range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
            IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
            IW_EVENT_CAPA_MASK(SIOCGIWAP) |
            IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
    range->event_capa[1] = IW_EVENT_CAPA_K_1;
    range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVTXDROP) |
            IW_EVENT_CAPA_MASK(IWEVCUSTOM) |
            IW_EVENT_CAPA_MASK(IWEVREGISTERED) |
            IW_EVENT_CAPA_MASK(IWEVEXPIRED));
#endif /* WIRELESS_EXT > 16 */

#if WIRELESS_EXT > 17
    range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
        IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
#endif /* WIRELESS_EXT > 17 */


    return 0;
} /* unifi_giwrange() */


static int
unifi_siwap(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    int err = 0;

    func_enter();

    CHECK_INITED(priv);

    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
       unifi_error(priv, "unifi_siwap: not permitted in Mode %d\n",
                                      interfacePriv->interfaceMode);
       return -EPERM;
    }


    if (wrqu->ap_addr.sa_family != ARPHRD_ETHER) {
        return -EINVAL;
    }

	unifi_trace(priv, UDBG1, "unifi_siwap: asked for %pM\n",
		wrqu->ap_addr.sa_data);

    if (is_zero_ether_addr(wrqu->ap_addr.sa_data)) {
        priv->ignore_bssid_join = FALSE;
        err = sme_mgt_disconnect(priv);
        if (err) {
            unifi_trace(priv, UDBG4, "unifi_siwap: Disconnect failed, status %d\n", err);
        }
        return 0;
    }

    if (priv->ignore_bssid_join) {
        unifi_trace(priv, UDBG4, "unifi_siwap: ignoring second join\n");
        priv->ignore_bssid_join = FALSE;
    } else {
        memcpy(priv->connection_config.bssid.a, wrqu->ap_addr.sa_data, ETH_ALEN);
        unifi_trace(priv, UDBG1, "unifi_siwap: Joining %X:%X:%X:%X:%X:%X\n",
                    priv->connection_config.bssid.a[0],
                    priv->connection_config.bssid.a[1],
                    priv->connection_config.bssid.a[2],
                    priv->connection_config.bssid.a[3],
                    priv->connection_config.bssid.a[4],
                    priv->connection_config.bssid.a[5]);
        err = sme_mgt_connect(priv);
        if (err) {
            unifi_error(priv, "unifi_siwap: Join failed, status %d\n", err);
            func_exit();
            return convert_sme_error(err);
        }
    }
    func_exit();

    return 0;
} /* unifi_siwap() */


static int
unifi_giwap(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    CsrWifiSmeConnectionInfo connectionInfo;
    int r = 0;
    u8 *bssid;

    func_enter();

    CHECK_INITED(priv);
    unifi_trace(priv, UDBG2, "unifi_giwap\n");

    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
       unifi_error(priv, "iwprivswpikey: not permitted in Mode %d\n",
                                      interfacePriv->interfaceMode);
       return -EPERM;
    }

    UF_RTNL_UNLOCK();
    r = sme_mgt_connection_info_get(priv, &connectionInfo);
    UF_RTNL_LOCK();

    if (r == 0) {
        bssid = connectionInfo.bssid.a;
        wrqu->ap_addr.sa_family = ARPHRD_ETHER;
		unifi_trace(priv, UDBG4, "unifi_giwap: BSSID = %pM\n", bssid);

        memcpy(wrqu->ap_addr.sa_data, bssid, ETH_ALEN);
    } else {
        memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
    }

    func_exit();
    return 0;
} /* unifi_giwap() */


static int
unifi_siwscan(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    int scantype;
    int r;
    CsrWifiSsid scan_ssid;
    unsigned char *channel_list = NULL;
    int chans_good = 0;
#if WIRELESS_EXT > 17
    struct iw_point *data = &wrqu->data;
    struct iw_scan_req *req = (struct iw_scan_req *) extra;
#endif

    func_enter();

    CHECK_INITED(priv);

    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
       unifi_error(priv, "unifi_siwscan: not permitted in Mode %d\n",
                                      interfacePriv->interfaceMode);
       return -EPERM;
    }


    scantype = UNIFI_SCAN_ACTIVE;

#if WIRELESS_EXT > 17
    /* Providing a valid channel list will force an active scan */
    if (req) {
        if ((req->num_channels > 0) && (req->num_channels < IW_MAX_FREQUENCIES)) {
            channel_list = kmalloc(req->num_channels, GFP_KERNEL);
            if (channel_list) {
                int i;
                for (i = 0; i < req->num_channels; i++) {
                    /* Convert frequency to channel number */
                    int ch = wext_freq_to_channel(req->channel_list[i].m,
                            req->channel_list[i].e);
                    if (ch) {
                        channel_list[chans_good++] = ch;
                    }
                }
                unifi_trace(priv, UDBG1,
                            "SIWSCAN: Scanning %d channels\n", chans_good);
            } else {
                /* Fall back to scanning all */
                unifi_error(priv, "SIWSCAN: Can't alloc channel_list (%d)\n",
                        req->num_channels);
            }
        }
    }

    if (req && (data->flags & IW_SCAN_THIS_ESSID)) {
        memcpy(scan_ssid.ssid, req->essid, req->essid_len);
        scan_ssid.length = req->essid_len;
        unifi_trace(priv, UDBG1,
                    "SIWSCAN: Scanning for %.*s\n",
                    scan_ssid.length, scan_ssid.ssid);
    } else
#endif
    {
        unifi_trace(priv, UDBG1, "SIWSCAN: Scanning for all APs\n");
        scan_ssid.length = 0;
    }

    r = sme_mgt_scan_full(priv, &scan_ssid, chans_good, channel_list);
    if (r) {
        unifi_error(priv, "SIWSCAN: Scan returned error %d\n", r);
    } else {
        unifi_trace(priv, UDBG1, "SIWSCAN: Scan done\n");
        wext_send_scan_results_event(priv);
    }

    if (channel_list) {
        kfree(channel_list);
    }

    func_exit();
    return r;

} /* unifi_siwscan() */


static const unsigned char *
unifi_find_info_element(int id, const unsigned char *info, int len)
{
    const unsigned char *ie = info;

    while (len > 1)
    {
        int e_id, e_len;
        e_id = ie[0];
        e_len = ie[1];

        /* Return if we find a match */
        if (e_id == id)
        {
            return ie;
        }

        len -= (e_len + 2);
        ie  += (e_len + 2);
    }

    return NULL;
} /* unifi_find_info_element() */


/*
 * Translate scan data returned from the card to a card independent
 * format that the Wireless Tools will understand - Jean II
 */
int
unifi_translate_scan(struct net_device *dev,
                     struct iw_request_info *info,
                     char *current_ev, char *end_buf,
                     CsrWifiSmeScanResult *scan_data,
                     int scan_index)
{
    struct iw_event iwe;                /* Temporary buffer */
    unsigned char *info_elems;
    int info_elem_len;
    const unsigned char *elem;
    u16 capabilities;
    int signal, noise, snr;
    char *start_buf = current_ev;
    char *current_val;  /* For rates */
    int i, r;

    info_elems    = scan_data->informationElements;
    info_elem_len = scan_data->informationElementsLength;

    if (!scan_data->informationElementsLength || !scan_data->informationElements) {
        unifi_error(NULL, "*** NULL SCAN IEs ***\n");
        return -EIO;
    }

    /* get capinfo bits */
    capabilities = scan_data->capabilityInformation;

    unifi_trace(NULL, UDBG5, "Capabilities: 0x%x\n", capabilities);

    /* First entry *MUST* be the AP MAC address */
    memset(&iwe, 0, sizeof(iwe));
    iwe.cmd = SIOCGIWAP;
    iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
    memcpy(iwe.u.ap_addr.sa_data, scan_data->bssid.a, ETH_ALEN);
    iwe.len = IW_EV_ADDR_LEN;
    r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_ADDR_LEN);
    if (r < 0) {
        return r;
    }
    start_buf += r;

    /* Other entries will be displayed in the order we give them */

    /* Add the ESSID */
    /* find SSID in Info Elems */
    elem = unifi_find_info_element(IE_SSID_ID, info_elems, info_elem_len);
    if (elem) {
        int e_len = elem[1];
        const unsigned char *e_ptr = elem + 2;
        unsigned char buf[33];

        memset(&iwe, 0, sizeof(iwe));
        iwe.cmd = SIOCGIWESSID;
        iwe.u.essid.length = e_len;
        if (iwe.u.essid.length > 32) {
            iwe.u.essid.length = 32;
        }
        iwe.u.essid.flags = scan_index;
        memcpy(buf, e_ptr, iwe.u.essid.length);
        buf[iwe.u.essid.length] = '\0';
        r = uf_iwe_stream_add_point(info, start_buf, end_buf, &iwe, buf);
        if (r < 0) {
            return r;
        }
        start_buf += r;

    }

    /* Add mode */
    memset(&iwe, 0, sizeof(iwe));
    iwe.cmd = SIOCGIWMODE;
    if (scan_data->bssType == CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE) {
        iwe.u.mode = IW_MODE_INFRA;
    } else {
        iwe.u.mode = IW_MODE_ADHOC;
    }
    iwe.len = IW_EV_UINT_LEN;
    r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_UINT_LEN);
    if (r < 0) {
        return r;
    }
    start_buf += r;

    /* Add frequency. iwlist will convert to channel using table given in giwrange */
    memset(&iwe, 0, sizeof(iwe));
    iwe.cmd = SIOCGIWFREQ;
    iwe.u.freq.m = scan_data->channelFrequency;
    iwe.u.freq.e = 6;
    r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_FREQ_LEN);
    if (r < 0) {
        return r;
    }
    start_buf += r;


    /* Add quality statistics */
    iwe.cmd = IWEVQUAL;
    /*
     * level and noise below are mapped into an unsigned 8 bit number,
     * ranging from [-192; 63]. The way this is achieved is simply to
     * add 0x100 onto the number if it is negative,
     * once clipped to the correct range.
     */
    signal = scan_data->rssi; /* This value is in dBm */
    /* Clip range of snr */
    snr    = (scan_data->snr > 0) ? scan_data->snr : 0; /* In dB relative, from 0 - 255 */
    snr    = (snr < 255) ? snr : 255;
    noise  = signal - snr;

    /* Clip range of signal */
    signal = (signal < 63) ? signal : 63;
    signal = (signal > -192) ? signal : -192;

    /* Clip range of noise */
    noise = (noise < 63) ? noise : 63;
    noise = (noise > -192) ? noise : -192;

    /* Make u8 */
    signal = ( signal < 0 ) ? signal + 0x100 : signal;
    noise = ( noise < 0 ) ? noise + 0x100 : noise;

    iwe.u.qual.level = (u8)signal; /* -192 : 63 */
    iwe.u.qual.noise = (u8)noise;  /* -192 : 63 */
    iwe.u.qual.qual = snr;         /* 0 : 255 */
    iwe.u.qual.updated = 0;
#if WIRELESS_EXT > 16
    iwe.u.qual.updated |= IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_UPDATED |
        IW_QUAL_QUAL_UPDATED;
#if WIRELESS_EXT > 18
    iwe.u.qual.updated |= IW_QUAL_DBM;
#endif
#endif
    r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_QUAL_LEN);
    if (r < 0) {
        return r;
    }
    start_buf += r;

    /* Add encryption capability */
    iwe.cmd = SIOCGIWENCODE;
    if (capabilities & SIG_CAP_PRIVACY) {
        iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
    } else {
        iwe.u.data.flags = IW_ENCODE_DISABLED;
    }
    iwe.u.data.length = 0;
    iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
    r = uf_iwe_stream_add_point(info, start_buf, end_buf, &iwe, "");
    if (r < 0) {
        return r;
    }
    start_buf += r;


    /*
     * Rate : stuffing multiple values in a single event require a bit
     * more of magic - Jean II
     */
    current_val = start_buf + IW_EV_LCP_LEN;

    iwe.cmd = SIOCGIWRATE;
    /* Those two flags are ignored... */
    iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;

    elem = unifi_find_info_element(IE_SUPPORTED_RATES_ID,
            info_elems, info_elem_len);
    if (elem) {
        int e_len = elem[1];
        const unsigned char *e_ptr = elem + 2;

        /*
         * Count how many rates we have.
         * Zero marks the end of the list, if the list is not truncated.
         */
        /* Max 8 values */
        for (i = 0; i < e_len; i++) {
            if (e_ptr[i] == 0) {
                break;
            }
            /* Bit rate given in 500 kb/s units (+ 0x80) */
            iwe.u.bitrate.value = ((e_ptr[i] & 0x7f) * 500000);
            /* Add new value to event */
            r = uf_iwe_stream_add_value(info, start_buf, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
            if (r < 0) {
                return r;
            }
            current_val +=r;

        }
    }
    elem = unifi_find_info_element(IE_EXTENDED_SUPPORTED_RATES_ID,
            info_elems, info_elem_len);
    if (elem) {
        int e_len = elem[1];
        const unsigned char *e_ptr = elem + 2;

        /*
         * Count how many rates we have.
         * Zero marks the end of the list, if the list is not truncated.
         */
        /* Max 8 values */
        for (i = 0; i < e_len; i++) {
            if (e_ptr[i] == 0) {
                break;
            }
            /* Bit rate given in 500 kb/s units (+ 0x80) */
            iwe.u.bitrate.value = ((e_ptr[i] & 0x7f) * 500000);
            /* Add new value to event */
            r = uf_iwe_stream_add_value(info, start_buf, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
            if (r < 0) {
                return r;
            }
            current_val +=r;
        }
    }
    /* Check if we added any rates event */
    if ((current_val - start_buf) > IW_EV_LCP_LEN) {
        start_buf = current_val;
    }


#if WIRELESS_EXT > 17
    memset(&iwe, 0, sizeof(iwe));
    iwe.cmd = IWEVGENIE;
    iwe.u.data.length = info_elem_len;

    r = uf_iwe_stream_add_point(info, start_buf, end_buf, &iwe, info_elems);
    if (r < 0) {
        return r;
    }

    start_buf += r;
#endif /* WE > 17 */

    return (start_buf - current_ev);
} /* unifi_translate_scan() */



static int
unifi_giwscan(struct net_device *dev, struct iw_request_info *info,
              union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    struct iw_point *dwrq = &wrqu->data;
    int r;

    CHECK_INITED(priv);

    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
       unifi_error(priv, "unifi_giwscan: not permitted in Mode %d\n",
                                      interfacePriv->interfaceMode);
       return -EPERM;
    }


    unifi_trace(priv, UDBG1,
            "unifi_giwscan: buffer (%d bytes) \n",
            dwrq->length);
    UF_RTNL_UNLOCK();
    r = sme_mgt_scan_results_get_async(priv, info, extra, dwrq->length);
    UF_RTNL_LOCK();
    if (r < 0) {
        unifi_trace(priv, UDBG1,
                "unifi_giwscan: buffer (%d bytes) not big enough.\n",
                dwrq->length);
        return r;
    }

    dwrq->length = r;
    dwrq->flags = 0;

    return 0;
} /* unifi_giwscan() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_siwessid
 *
 *      Request to join a network or start and AdHoc.
 *
 *  Arguments:
 *      dev             Pointer to network device struct.
 *      info            Pointer to broken-out ioctl request.
 *      data            Pointer to argument data.
 *      essid           Pointer to string giving name of network to join
 *                      or start
 *
 *  Returns:
 *      0 on success and everything complete
 *      -EINPROGRESS to have the higher level call the commit method.
 * ---------------------------------------------------------------------------
 */
static int
unifi_siwessid(struct net_device *dev, struct iw_request_info *info,
               struct iw_point *data, char *essid)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    int len;
    int err = 0;

    func_enter();
    CHECK_INITED(priv);

    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
       unifi_error(priv, "unifi_siwessid: not permitted in Mode %d\n",
                                      interfacePriv->interfaceMode);
       return -EPERM;
    }


    len = 0;
    if (data->flags & 1) {
        /* Limit length  */
        len = data->length;
        if (len > UNIFI_MAX_SSID_LEN) {
            len = UNIFI_MAX_SSID_LEN;
        }
    }

#ifdef UNIFI_DEBUG
    {
        char essid_str[UNIFI_MAX_SSID_LEN+1];
        int i;

        for (i = 0; i < len; i++) {
            essid_str[i] = (isprint(essid[i]) ? essid[i] : '?');
        }
        essid_str[i] = '\0';

        unifi_trace(priv, UDBG1, "unifi_siwessid: asked for '%*s' (%d)\n", len, essid_str, len);
        unifi_trace(priv, UDBG2, " with authModeMask = %d", priv->connection_config.authModeMask);
    }
#endif

    memset(priv->connection_config.bssid.a, 0xFF, ETH_ALEN);
    if (len) {
        if (essid[len - 1] == 0) {
            len --;
        }

        memcpy(priv->connection_config.ssid.ssid, essid, len);
        priv->connection_config.ssid.length = len;

    } else {
        priv->connection_config.ssid.length = 0;
    }

    UF_RTNL_UNLOCK();
    err = sme_mgt_connect(priv);
    UF_RTNL_LOCK();
    if (err) {
        unifi_error(priv, "unifi_siwessid: Join failed, status %d\n", err);
        func_exit();
        return convert_sme_error(err);
    }

    func_exit();
    return 0;
} /* unifi_siwessid() */


static int
unifi_giwessid(struct net_device *dev, struct iw_request_info *info,
               union iwreq_data *wrqu, char *essid)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    struct iw_point *data = &wrqu->essid;
    CsrWifiSmeConnectionInfo connectionInfo;
    int r = 0;

    func_enter();
    unifi_trace(priv, UDBG2, "unifi_giwessid\n");
    CHECK_INITED(priv);

    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
       unifi_error(priv, "unifi_giwessid: not permitted in Mode %d\n",
                                      interfacePriv->interfaceMode);
       return -EPERM;
    }

    UF_RTNL_UNLOCK();
    r = sme_mgt_connection_info_get(priv, &connectionInfo);
    UF_RTNL_LOCK();

    if (r == 0) {
        data->length = connectionInfo.ssid.length;
        strncpy(essid,
                connectionInfo.ssid.ssid,
                data->length);
        data->flags = 1;            /* active */

        unifi_trace(priv, UDBG2, "unifi_giwessid: %.*s\n",
                data->length, essid);
    }

    func_exit();

    return 0;
} /* unifi_giwessid() */


static int
unifi_siwrate(struct net_device *dev, struct iw_request_info *info,
              union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    struct iw_param *args = &wrqu->bitrate;
    CsrWifiSmeMibConfig mibConfig;
    int r;

    func_enter();

    CHECK_INITED(priv);
    unifi_trace(priv, UDBG2, "unifi_siwrate\n");

    /*
     * If args->fixed == 0, value is max rate or -1 for best
     * If args->fixed == 1, value is rate to set or -1 for best
     * args->disabled and args->flags are not used in SIOCSIWRATE
     */

    /* Get, modify and set the MIB data */
    UF_RTNL_UNLOCK();
    r = sme_mgt_mib_config_get(priv, &mibConfig);
    UF_RTNL_LOCK();
    if (r) {
        unifi_error(priv, "unifi_siwrate: Get CsrWifiSmeMibConfigValue failed.\n");
        return r;
    }

    /* Default to auto rate algorithm */
    /* in 500Kbit/s, 0 means auto */
    mibConfig.unifiFixTxDataRate = 0;

    if (args->value != -1) {
        mibConfig.unifiFixTxDataRate = args->value / 500000;
    }

    /* 1 means rate is a maximum, 2 means rate is a set value */
    if (args->fixed == 1) {
        mibConfig.unifiFixMaxTxDataRate = 0;
    } else {
        mibConfig.unifiFixMaxTxDataRate = 1;
    }
    UF_RTNL_UNLOCK();
    r = sme_mgt_mib_config_set(priv, &mibConfig);
    UF_RTNL_LOCK();
    if (r) {
        unifi_error(priv, "unifi_siwrate: Set CsrWifiSmeMibConfigValue failed.\n");
        return r;
    }

    func_exit();

    return 0;
} /* unifi_siwrate() */



static int
unifi_giwrate(struct net_device *dev, struct iw_request_info *info,
              union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    struct iw_param *args = &wrqu->bitrate;
    int r;
    int bitrate, flag;
    CsrWifiSmeMibConfig mibConfig;
    CsrWifiSmeConnectionStats connectionStats;

    func_enter();
    unifi_trace(priv, UDBG2, "unifi_giwrate\n");
    CHECK_INITED(priv);

    flag = 0;
    bitrate = 0;
    UF_RTNL_UNLOCK();
    r = sme_mgt_mib_config_get(priv, &mibConfig);
    UF_RTNL_LOCK();
    if (r) {
        unifi_error(priv, "unifi_giwrate: Get CsrWifiSmeMibConfigValue failed.\n");
        return r;
    }

    bitrate = mibConfig.unifiFixTxDataRate;
    flag = mibConfig.unifiFixMaxTxDataRate;

    /* Used the value returned by the SME if MIB returns 0 */
    if (bitrate == 0) {
        UF_RTNL_UNLOCK();
        r = sme_mgt_connection_stats_get(priv, &connectionStats);
        UF_RTNL_LOCK();
        /* Ignore errors, we may be disconnected */
        if (r == 0) {
            bitrate = connectionStats.unifiTxDataRate;
        }
    }

    args->value = bitrate * 500000;
    args->fixed = !flag;

    func_exit();

    return 0;
} /* unifi_giwrate() */


static int
unifi_siwrts(struct net_device *dev, struct iw_request_info *info,
             union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    int val = wrqu->rts.value;
    int r = 0;
    CsrWifiSmeMibConfig mibConfig;

    unifi_trace(priv, UDBG2, "unifi_siwrts\n");
    CHECK_INITED(priv);

    if (wrqu->rts.disabled) {
        val = 2347;
    }

    if ( (val < 0) || (val > 2347) )
    {
        return -EINVAL;
    }

    /* Get, modify and set the MIB data */
    UF_RTNL_UNLOCK();
    r = sme_mgt_mib_config_get(priv, &mibConfig);
    UF_RTNL_LOCK();
    if (r) {
        unifi_error(priv, "unifi_siwrts: Get CsrWifiSmeMibConfigValue failed.\n");
        return r;
    }
    mibConfig.dot11RtsThreshold = val;
    UF_RTNL_UNLOCK();
    r = sme_mgt_mib_config_set(priv, &mibConfig);
    UF_RTNL_LOCK();
    if (r) {
        unifi_error(priv, "unifi_siwrts: Set CsrWifiSmeMibConfigValue failed.\n");
        return r;
    }

    return 0;
}


static int
unifi_giwrts(struct net_device *dev, struct iw_request_info *info,
             union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    int r;
    int rts_thresh;
    CsrWifiSmeMibConfig mibConfig;

    unifi_trace(priv, UDBG2, "unifi_giwrts\n");
    CHECK_INITED(priv);

    UF_RTNL_UNLOCK();
    r = sme_mgt_mib_config_get(priv, &mibConfig);
    UF_RTNL_LOCK();
    if (r) {
        unifi_error(priv, "unifi_giwrts: Get CsrWifiSmeMibConfigValue failed.\n");
        return r;
    }

    rts_thresh = mibConfig.dot11RtsThreshold;
    if (rts_thresh > 2347) {
        rts_thresh = 2347;
    }

    wrqu->rts.value = rts_thresh;
    wrqu->rts.disabled = (rts_thresh == 2347);
    wrqu->rts.fixed = 1;

    return 0;
}


static int
unifi_siwfrag(struct net_device *dev, struct iw_request_info *info,
              union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    int val = wrqu->frag.value;
    int r = 0;
    CsrWifiSmeMibConfig mibConfig;

    unifi_trace(priv, UDBG2, "unifi_siwfrag\n");
    CHECK_INITED(priv);

    if (wrqu->frag.disabled)
        val = 2346;

    if ( (val < 256) || (val > 2347) )
        return -EINVAL;

    /* Get, modify and set the MIB data */
    UF_RTNL_UNLOCK();
    r = sme_mgt_mib_config_get(priv, &mibConfig);
    UF_RTNL_LOCK();
    if (r) {
        unifi_error(priv, "unifi_siwfrag: Get CsrWifiSmeMibConfigValue failed.\n");
        return r;
    }
    /* Fragmentation Threashold must be even */
    mibConfig.dot11FragmentationThreshold = (val & ~0x1);
    UF_RTNL_UNLOCK();
    r = sme_mgt_mib_config_set(priv, &mibConfig);
    UF_RTNL_LOCK();
    if (r) {
        unifi_error(priv, "unifi_siwfrag: Set CsrWifiSmeMibConfigValue failed.\n");
        return r;
    }

    return 0;
}


static int
unifi_giwfrag(struct net_device *dev, struct iw_request_info *info,
              union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    int r;
    int frag_thresh;
    CsrWifiSmeMibConfig mibConfig;

    unifi_trace(priv, UDBG2, "unifi_giwfrag\n");
    CHECK_INITED(priv);

    UF_RTNL_UNLOCK();
    r = sme_mgt_mib_config_get(priv, &mibConfig);
    UF_RTNL_LOCK();
    if (r) {
        unifi_error(priv, "unifi_giwfrag: Get CsrWifiSmeMibConfigValue failed.\n");
        return r;
    }

    frag_thresh = mibConfig.dot11FragmentationThreshold;

    /* Build the return structure */
    wrqu->frag.value = frag_thresh;
    wrqu->frag.disabled = (frag_thresh >= 2346);
    wrqu->frag.fixed = 1;

    return 0;
}


static int
unifi_siwencode(struct net_device *dev, struct iw_request_info *info,
                union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    struct iw_point *erq = &wrqu->encoding;
    int index;
    int rc = 0;
    int privacy = -1;
    CsrWifiSmeKey sme_key;

    func_enter();
    unifi_trace(priv, UDBG2, "unifi_siwencode\n");

    CHECK_INITED(priv);

    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
       unifi_error(priv, "unifi_siwencode: not permitted in Mode %d\n",
                                      interfacePriv->interfaceMode);
       return -EPERM;
    }


    /*
     * Key index is encoded in the flags.
     * 0 - use current default,
     * 1-4 - if a key value is given set that key
     *       if not use that key
     */
    index = (erq->flags & IW_ENCODE_INDEX);  /* key number, 1-4 */
    if ((index < 0) || (index > 4)) {
        unifi_error(priv, "unifi_siwencode: Request to set an invalid key (index:%d)", index);
        return -EINVAL;
    }

    /*
     * Basic checking: do we have a key to set ?
     * The IW_ENCODE_NOKEY flag is set when no key is present (only change flags),
     * but older versions rely on sending a key id 1-4.
     */
    if (erq->length > 0) {

        /* Check the size of the key */
        if ((erq->length > LARGE_KEY_SIZE) || (erq->length < SMALL_KEY_SIZE)) {
            unifi_error(priv, "unifi_siwencode: Request to set an invalid key (length:%d)",
                        erq->length);
            return -EINVAL;
        }

        /* Check the index (none (i.e. 0) means use current) */
        if ((index < 1) || (index > 4)) {
            /* If we do not have a previous key, use 1 as default */
            if (!priv->wep_tx_key_index) {
                priv->wep_tx_key_index = 1;
            }
            index = priv->wep_tx_key_index;
        }

        /* If we didn't have a key and a valid index is set, we want to remember it*/
        if (!priv->wep_tx_key_index) {
            priv->wep_tx_key_index = index;
        }

        unifi_trace(priv, UDBG1, "Tx key Index is %d\n", priv->wep_tx_key_index);

        privacy = 1;

        /* Check if the key is not marked as invalid */
        if ((erq->flags & IW_ENCODE_NOKEY) == 0) {

            unifi_trace(priv, UDBG1, "New %s key (len=%d, index=%d)\n",
                        (priv->wep_tx_key_index == index) ? "tx" : "",
                        erq->length, index);

            sme_key.wepTxKey = (priv->wep_tx_key_index == index);
            if (priv->wep_tx_key_index == index) {
                sme_key.keyType = CSR_WIFI_SME_KEY_TYPE_PAIRWISE;
            } else {
                sme_key.keyType = CSR_WIFI_SME_KEY_TYPE_GROUP;
            }
            /* Key index is zero based in SME but 1 based in wext */
            sme_key.keyIndex = (index - 1);
            sme_key.keyLength = erq->length;
            sme_key.authenticator = 0;
            memset(sme_key.address.a, 0xFF, ETH_ALEN);
            memcpy(sme_key.key, extra, erq->length);

            UF_RTNL_UNLOCK();
            rc = sme_mgt_key(priv, &sme_key, CSR_WIFI_SME_LIST_ACTION_ADD);
            UF_RTNL_LOCK();
            if (rc) {
                unifi_error(priv, "unifi_siwencode: Set key failed (%d)", rc);
                return convert_sme_error(rc);
            }

            /* Store the key to be reported by the SIOCGIWENCODE handler */
            priv->wep_keys[index - 1].len = erq->length;
            memcpy(priv->wep_keys[index - 1].key, extra, erq->length);
        }
    } else {
        /*
         * No additional key data, so it must be a request to change the
         * active key.
         */
        if (index != 0) {
            unifi_trace(priv, UDBG1, "Tx key Index is %d\n", index - 1);

            /* Store the index to be reported by the SIOCGIWENCODE handler */
            priv->wep_tx_key_index = index;

            sme_key.wepTxKey = 1;
            sme_key.keyType = CSR_WIFI_SME_KEY_TYPE_PAIRWISE;

            /* Key index is zero based in SME but 1 based in wext */
            sme_key.keyIndex = (index - 1);
            sme_key.keyLength = 0;
            sme_key.authenticator = 0;
            UF_RTNL_UNLOCK();
            rc = sme_mgt_key(priv, &sme_key, CSR_WIFI_SME_LIST_ACTION_ADD);
            UF_RTNL_LOCK();
            if (rc) {
                unifi_error(priv, "unifi_siwencode: Set key failed (%d)", rc);
                return convert_sme_error(rc);
            }

            /* Turn on encryption */
            privacy = 1;
        }
    }

    /* Read the flags */
    if (erq->flags & IW_ENCODE_DISABLED) {
        /* disable encryption */
        unifi_trace(priv, UDBG1, "disable WEP encryption\n");
        privacy = 0;

        priv->wep_tx_key_index = 0;

        unifi_trace(priv, UDBG1, "IW_ENCODE_DISABLED: CSR_WIFI_SME_AUTH_MODE_80211_OPEN\n");
        priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_OPEN;
    }

    if (erq->flags & IW_ENCODE_RESTRICTED) {
        /* Use shared key auth */
        unifi_trace(priv, UDBG1, "IW_ENCODE_RESTRICTED: CSR_WIFI_SME_AUTH_MODE_80211_SHARED\n");
        priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_SHARED;

        /* Turn on encryption */
        privacy = 1;
    }
    if (erq->flags & IW_ENCODE_OPEN) {
        unifi_trace(priv, UDBG1, "IW_ENCODE_OPEN: CSR_WIFI_SME_AUTH_MODE_80211_OPEN\n");
        priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_OPEN;
    }

    /* Commit the changes to flags if needed */
    if (privacy != -1) {
        priv->connection_config.privacyMode = privacy ? CSR_WIFI_SME_80211_PRIVACY_MODE_ENABLED : CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED;
        priv->connection_config.encryptionModeMask = privacy ? (CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP40 |
                CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP104 |
                CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP40 |
                CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP104) :
            CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE;
    }

    func_exit_r(rc);
    return convert_sme_error(rc);

} /* unifi_siwencode() */



static int
unifi_giwencode(struct net_device *dev, struct iw_request_info *info,
                union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    struct iw_point *erq = &wrqu->encoding;

    unifi_trace(priv, UDBG2, "unifi_giwencode\n");

    CHECK_INITED(priv);

    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
       unifi_error(priv, "unifi_giwencode: not permitted in Mode %d\n",
                                      interfacePriv->interfaceMode);
       return -EPERM;
    }


    if (priv->connection_config.authModeMask == CSR_WIFI_SME_AUTH_MODE_80211_SHARED) {
        erq->flags = IW_ENCODE_RESTRICTED;
    }
    else {
        if (priv->connection_config.privacyMode == CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED) {
            erq->flags = IW_ENCODE_DISABLED;
        } else {
            erq->flags = IW_ENCODE_OPEN;
        }
    }

    erq->length = 0;

    if (erq->flags != IW_ENCODE_DISABLED) {
        int index = priv->wep_tx_key_index;

        if ((index > 0) && (index <= NUM_WEPKEYS)) {
            erq->flags |= (index & IW_ENCODE_INDEX);
            erq->length = priv->wep_keys[index - 1].len;
            memcpy(extra, priv->wep_keys[index - 1].key, erq->length);
        } else {
            unifi_notice(priv, "unifi_giwencode: Surprise, do not have a valid key index (%d)\n",
                         index);
        }
    }

    return 0;
} /* unifi_giwencode() */


static int
unifi_siwpower(struct net_device *dev, struct iw_request_info *info,
               union iwreq_data *wrqu, char *extra)
{
    struct iw_param *args = &wrqu->power;
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    int listen_interval, wake_for_dtim;
    int r = 0;
    CsrWifiSmePowerConfig powerConfig;

    unifi_trace(priv, UDBG2, "unifi_siwpower\n");

    CHECK_INITED(priv);

    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
       unifi_error(priv, "unifi_siwpower: not permitted in Mode %d\n",
                                      interfacePriv->interfaceMode);
       return -EPERM;
    }

    UF_RTNL_UNLOCK();
    r = sme_mgt_power_config_get(priv, &powerConfig);
    UF_RTNL_LOCK();
    if (r) {
        unifi_error(priv, "unifi_siwpower: Get unifi_PowerConfigValue failed.\n");
        return r;
    }

    listen_interval = -1;
    wake_for_dtim = -1;
    if (args->disabled) {
        powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW;
    }
    else
    {
        powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_HIGH;

        switch (args->flags & IW_POWER_TYPE) {
            case 0:
                /* not specified */
                break;
            case IW_POWER_PERIOD:
                listen_interval = args->value / 1000;
                break;
            default:
                return -EINVAL;
        }

        switch (args->flags & IW_POWER_MODE) {
            case 0:
                /* not specified */
                break;
            case IW_POWER_UNICAST_R:
                /* not interested in broadcast packets */
                wake_for_dtim = 0;
                break;
            case IW_POWER_ALL_R:
                /* yes, we are interested in broadcast packets */
                wake_for_dtim = 1;
                break;
            default:
                return -EINVAL;
        }
    }

    if (listen_interval > 0) {
        powerConfig.listenIntervalTu = listen_interval;
        unifi_trace(priv, UDBG4, "unifi_siwpower: new Listen Interval = %d.\n",
                    powerConfig.listenIntervalTu);
    }

    if (wake_for_dtim >= 0) {
        powerConfig.rxDtims = wake_for_dtim;
    }
    UF_RTNL_UNLOCK();
    r = sme_mgt_power_config_set(priv, &powerConfig);
    UF_RTNL_LOCK();
    if (r) {
        unifi_error(priv, "unifi_siwpower: Set unifi_PowerConfigValue failed.\n");
        return r;
    }

    return 0;
} /* unifi_siwpower() */


static int
unifi_giwpower(struct net_device *dev, struct iw_request_info *info,
               union iwreq_data *wrqu, char *extra)
{
    struct iw_param *args = &wrqu->power;
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    CsrWifiSmePowerConfig powerConfig;
    int r;

    unifi_trace(priv, UDBG2, "unifi_giwpower\n");

    CHECK_INITED(priv);

    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
       unifi_error(priv, "unifi_giwpower: not permitted in Mode %d\n",
                                      interfacePriv->interfaceMode);
       return -EPERM;
    }


    args->flags = 0;
    UF_RTNL_UNLOCK();
    r = sme_mgt_power_config_get(priv, &powerConfig);
    UF_RTNL_LOCK();
    if (r) {
        unifi_error(priv, "unifi_giwpower: Get unifi_PowerConfigValue failed.\n");
        return r;
    }

    unifi_trace(priv, UDBG4, "unifi_giwpower: mode=%d\n",
                powerConfig.powerSaveLevel);

    args->disabled = (powerConfig.powerSaveLevel == CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW);
    if (args->disabled) {
        args->flags = 0;
        return 0;
    }

    args->value = powerConfig.listenIntervalTu * 1000;
    args->flags |= IW_POWER_PERIOD;

    if (powerConfig.rxDtims) {
        args->flags |= IW_POWER_ALL_R;
    } else {
        args->flags |= IW_POWER_UNICAST_R;
    }

    return 0;
} /* unifi_giwpower() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_siwcommit - handler for SIOCSIWCOMMIT
 *
 *      Apply all the parameters that have been set.
 *      In practice this means:
 *       - do a scan
 *       - join a network or start an AdHoc
 *       - authenticate and associate.
 *
 *  Arguments:
 *      None.
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
static int
unifi_siwcommit(struct net_device *dev, struct iw_request_info *info,
                union iwreq_data *wrqu, char *extra)
{
    return 0;
} /* unifi_siwcommit() */



static int
unifi_siwmlme(struct net_device *dev, struct iw_request_info *info,
              union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    struct iw_mlme *mlme = (struct iw_mlme *)extra;
    func_enter();

    unifi_trace(priv, UDBG2, "unifi_siwmlme\n");
    CHECK_INITED(priv);

    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
       unifi_error(priv, "unifi_siwmlme: not permitted in Mode %d\n",
                                      interfacePriv->interfaceMode);
       return -EPERM;
    }


    switch (mlme->cmd) {
        case IW_MLME_DEAUTH:
        case IW_MLME_DISASSOC:
            UF_RTNL_UNLOCK();
            sme_mgt_disconnect(priv);
            UF_RTNL_LOCK();
            break;
        default:
            func_exit_r(-EOPNOTSUPP);
            return -EOPNOTSUPP;
    }

    func_exit();
    return 0;
} /* unifi_siwmlme() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_siwgenie
 *  unifi_giwgenie
 *
 *      WPA : Generic IEEE 802.11 information element (e.g., for WPA/RSN/WMM).
 *      Handlers for SIOCSIWGENIE, SIOCGIWGENIE - set/get generic IE
 *
 *      The host program (e.g. wpa_supplicant) uses this call to set the
 *      additional IEs to accompany the next (Associate?) request.
 *
 *  Arguments:
 *      None.
 *
 *  Returns:
 *      None.
 *  Notes:
 *      From wireless.h:
 *        This ioctl uses struct iw_point and data buffer that includes IE id
 *        and len fields. More than one IE may be included in the
 *        request. Setting the generic IE to empty buffer (len=0) removes the
 *        generic IE from the driver.
 * ---------------------------------------------------------------------------
 */
static int
unifi_siwgenie(struct net_device *dev, struct iw_request_info *info,
               union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    int len;

    func_enter();
    unifi_trace(priv, UDBG2, "unifi_siwgenie\n");

    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
       unifi_error(priv, "unifi_siwgenie: not permitted in Mode %d\n",
                                      interfacePriv->interfaceMode);
       return -EPERM;
    }


    if ( priv->connection_config.mlmeAssociateReqInformationElements) {
        kfree( priv->connection_config.mlmeAssociateReqInformationElements);
    }
    priv->connection_config.mlmeAssociateReqInformationElementsLength = 0;
    priv->connection_config.mlmeAssociateReqInformationElements = NULL;

    len = wrqu->data.length;
    if (len == 0) {
        func_exit();
        return 0;
    }

    priv->connection_config.mlmeAssociateReqInformationElements = kmalloc(len, GFP_KERNEL);
    if (priv->connection_config.mlmeAssociateReqInformationElements == NULL) {
        func_exit();
        return -ENOMEM;
    }

    priv->connection_config.mlmeAssociateReqInformationElementsLength = len;
    memcpy( priv->connection_config.mlmeAssociateReqInformationElements, extra, len);

    func_exit();
    return 0;
} /* unifi_siwgenie() */


static int
unifi_giwgenie(struct net_device *dev, struct iw_request_info *info,
               union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    int len;

    func_enter();
    unifi_trace(priv, UDBG2, "unifi_giwgenie\n");

    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
       unifi_error(priv, "unifi_giwgenie: not permitted in Mode %d\n",
                                      interfacePriv->interfaceMode);
       return -EPERM;
    }


    len = priv->connection_config.mlmeAssociateReqInformationElementsLength;

    if (len == 0) {
        wrqu->data.length = 0;
        return 0;
    }

    if (wrqu->data.length < len) {
        return -E2BIG;
    }

    wrqu->data.length = len;
    memcpy(extra, priv->connection_config.mlmeAssociateReqInformationElements, len);

    func_exit();
    return 0;
} /* unifi_giwgenie() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_siwauth
 *  unifi_giwauth
 *
 *      Handlers for SIOCSIWAUTH, SIOCGIWAUTH
 *      Set/get various authentication parameters.
 *
 *  Arguments:
 *
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
static int
_unifi_siwauth(struct net_device *dev, struct iw_request_info *info,
               union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    CsrWifiSmeAuthModeMask new_auth;

    func_enter();
    unifi_trace(priv, UDBG2, "unifi_siwauth\n");

    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
       unifi_error(priv, "unifi_siwauth: not permitted in Mode %d\n",
                                      interfacePriv->interfaceMode);
       return -EPERM;
    }


    /*
     * This ioctl is safe to call even when UniFi is powered off.
     * wpa_supplicant calls it to test whether we support WPA.
     */

    switch (wrqu->param.flags & IW_AUTH_INDEX) {

        case IW_AUTH_WPA_ENABLED:
            unifi_trace(priv, UDBG1, "IW_AUTH_WPA_ENABLED: %d\n", wrqu->param.value);

            if (wrqu->param.value == 0) {
                unifi_trace(priv, UDBG5, "IW_AUTH_WPA_ENABLED: CSR_WIFI_SME_AUTH_MODE_80211_OPEN\n");
                priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_OPEN;
            }
            break;

        case IW_AUTH_PRIVACY_INVOKED:
            unifi_trace(priv, UDBG1, "IW_AUTH_PRIVACY_INVOKED: %d\n", wrqu->param.value);

            priv->connection_config.privacyMode = wrqu->param.value ? CSR_WIFI_SME_80211_PRIVACY_MODE_ENABLED : CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED;
            if (wrqu->param.value == CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED)
            {
                priv->connection_config.encryptionModeMask = CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE;
            }
            break;

        case IW_AUTH_80211_AUTH_ALG:
            /*
               IW_AUTH_ALG_OPEN_SYSTEM      0x00000001
               IW_AUTH_ALG_SHARED_KEY       0x00000002
               IW_AUTH_ALG_LEAP             0x00000004
               */
            new_auth = 0;
            if (wrqu->param.value & IW_AUTH_ALG_OPEN_SYSTEM) {
                unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: %d (IW_AUTH_ALG_OPEN_SYSTEM)\n", wrqu->param.value);
                new_auth |= CSR_WIFI_SME_AUTH_MODE_80211_OPEN;
            }
            if (wrqu->param.value & IW_AUTH_ALG_SHARED_KEY) {
                unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: %d (IW_AUTH_ALG_SHARED_KEY)\n", wrqu->param.value);
                new_auth |= CSR_WIFI_SME_AUTH_MODE_80211_SHARED;
            }
            if (wrqu->param.value & IW_AUTH_ALG_LEAP) {
                /* Initial exchanges using open-system to set EAP */
                unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: %d (IW_AUTH_ALG_LEAP)\n", wrqu->param.value);
                new_auth |= CSR_WIFI_SME_AUTH_MODE_8021X_OTHER1X;
            }
            if (new_auth == 0) {
                unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: invalid value %d\n",
                        wrqu->param.value);
                return -EINVAL;
            } else {
                priv->connection_config.authModeMask = new_auth;
            }
            break;

        case IW_AUTH_WPA_VERSION:
            unifi_trace(priv, UDBG1, "IW_AUTH_WPA_VERSION: %d\n", wrqu->param.value);
            priv->ignore_bssid_join = TRUE;
            /*
               IW_AUTH_WPA_VERSION_DISABLED 0x00000001
               IW_AUTH_WPA_VERSION_WPA      0x00000002
               IW_AUTH_WPA_VERSION_WPA2     0x00000004
               */

            if (!(wrqu->param.value & IW_AUTH_WPA_VERSION_DISABLED)) {

                priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_OPEN;

                if (wrqu->param.value & IW_AUTH_WPA_VERSION_WPA) {
                    unifi_trace(priv, UDBG4, "IW_AUTH_WPA_VERSION: WPA, WPA-PSK\n");
                    priv->connection_config.authModeMask |= (CSR_WIFI_SME_AUTH_MODE_8021X_WPA | CSR_WIFI_SME_AUTH_MODE_8021X_WPAPSK);
                }
                if (wrqu->param.value & IW_AUTH_WPA_VERSION_WPA2) {
                    unifi_trace(priv, UDBG4, "IW_AUTH_WPA_VERSION: WPA2, WPA2-PSK\n");
                    priv->connection_config.authModeMask |= (CSR_WIFI_SME_AUTH_MODE_8021X_WPA2 | CSR_WIFI_SME_AUTH_MODE_8021X_WPA2PSK);
                }
            }
            break;

        case IW_AUTH_CIPHER_PAIRWISE:
            unifi_trace(priv, UDBG1, "IW_AUTH_CIPHER_PAIRWISE: %d\n", wrqu->param.value);
            /*
             * one of:
             IW_AUTH_CIPHER_NONE	0x00000001
             IW_AUTH_CIPHER_WEP40	0x00000002
             IW_AUTH_CIPHER_TKIP	0x00000004
             IW_AUTH_CIPHER_CCMP	0x00000008
             IW_AUTH_CIPHER_WEP104	0x00000010
             */

            priv->connection_config.encryptionModeMask = CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE;

            if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
                priv->connection_config.encryptionModeMask |=
                    CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP40 | CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP40;
            }
            if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
                priv->connection_config.encryptionModeMask |=
                    CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP104 | CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP104;
            }
            if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
                priv->connection_config.encryptionModeMask |=
                    CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_TKIP | CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_TKIP;
            }
            if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
                priv->connection_config.encryptionModeMask |=
                    CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_CCMP | CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_CCMP;
            }

            break;

        case IW_AUTH_CIPHER_GROUP:
            unifi_trace(priv, UDBG1, "IW_AUTH_CIPHER_GROUP: %d\n", wrqu->param.value);
            /*
             * Use the WPA version and the group cipher suite to set the permitted
             * group key in the MIB. f/w uses this value to validate WPA and RSN IEs
             * in the probe responses from the desired BSS(ID)
             */

            priv->connection_config.encryptionModeMask &= ~(CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP40 |
                    CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP104 |
                    CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_TKIP |
                    CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_CCMP);
            if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
                priv->connection_config.encryptionModeMask |= CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP40;
            }
            if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
                priv->connection_config.encryptionModeMask |= CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP104;
            }
            if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
                priv->connection_config.encryptionModeMask |= CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_TKIP;
            }
            if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
                priv->connection_config.encryptionModeMask |= CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_CCMP;
            }

            break;

        case IW_AUTH_KEY_MGMT:
            unifi_trace(priv, UDBG1, "IW_AUTH_KEY_MGMT: %d\n", wrqu->param.value);
            /*
               IW_AUTH_KEY_MGMT_802_1X 1
               IW_AUTH_KEY_MGMT_PSK    2
               */
            if (priv->connection_config.authModeMask & (CSR_WIFI_SME_AUTH_MODE_8021X_WPA | CSR_WIFI_SME_AUTH_MODE_8021X_WPAPSK)) {
                /* Check for explicitly set mode. */
                if (wrqu->param.value == IW_AUTH_KEY_MGMT_802_1X) {
                    priv->connection_config.authModeMask &= ~CSR_WIFI_SME_AUTH_MODE_8021X_WPAPSK;
                }
                if (wrqu->param.value == IW_AUTH_KEY_MGMT_PSK) {
                    priv->connection_config.authModeMask &= ~CSR_WIFI_SME_AUTH_MODE_8021X_WPA;
                }
                unifi_trace(priv, UDBG5, "IW_AUTH_KEY_MGMT: WPA: %d\n",
                            priv->connection_config.authModeMask);
            }
            if (priv->connection_config.authModeMask & (CSR_WIFI_SME_AUTH_MODE_8021X_WPA2 | CSR_WIFI_SME_AUTH_MODE_8021X_WPA2PSK)) {
                /* Check for explicitly set mode. */
                if (wrqu->param.value == IW_AUTH_KEY_MGMT_802_1X) {
                    priv->connection_config.authModeMask &= ~CSR_WIFI_SME_AUTH_MODE_8021X_WPA2PSK;
                }
                if (wrqu->param.value == IW_AUTH_KEY_MGMT_PSK) {
                    priv->connection_config.authModeMask &= ~CSR_WIFI_SME_AUTH_MODE_8021X_WPA2;
                }
                unifi_trace(priv, UDBG5, "IW_AUTH_KEY_MGMT: WPA2: %d\n",
                            priv->connection_config.authModeMask);
            }

            break;
        case IW_AUTH_TKIP_COUNTERMEASURES:
            /*
             * Set to true at the start of the 60 second backup-off period
             * following 2 MichaelMIC failures within 60s.
             */
            unifi_trace(priv, UDBG1, "IW_AUTH_TKIP_COUNTERMEASURES: %d\n", wrqu->param.value);
            break;

        case IW_AUTH_DROP_UNENCRYPTED:
            /*
             * Set to true on init.
             * Set to false just before associate if encryption will not be
             * required.
             *
             * Note this is not the same as the 802.1X controlled port
             */
            unifi_trace(priv, UDBG1, "IW_AUTH_DROP_UNENCRYPTED: %d\n", wrqu->param.value);
            break;

        case IW_AUTH_RX_UNENCRYPTED_EAPOL:
            /*
             * This is set by wpa_supplicant to allow unencrypted EAPOL messages
             * even if pairwise keys are set when not using WPA. IEEE 802.1X
             * specifies that these frames are not encrypted, but WPA encrypts
             * them when pairwise keys are in use.
             * I think the UniFi f/w handles this decision for us.
             */
            unifi_trace(priv, UDBG1, "IW_AUTH_RX_UNENCRYPTED_EAPOL: %d\n", wrqu->param.value);
            break;

        case IW_AUTH_ROAMING_CONTROL:
            unifi_trace(priv, UDBG1, "IW_AUTH_ROAMING_CONTROL: %d\n", wrqu->param.value);
            break;

        default:
            unifi_trace(priv, UDBG1, "Unsupported auth param %d to 0x%X\n",
                        wrqu->param.flags & IW_AUTH_INDEX,
                        wrqu->param.value);
            return -EOPNOTSUPP;
    }

    unifi_trace(priv, UDBG2, "authModeMask = %d", priv->connection_config.authModeMask);
    func_exit();

    return 0;
} /* _unifi_siwauth() */


static int
unifi_siwauth(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    int err = 0;

    UF_RTNL_UNLOCK();
    err = _unifi_siwauth(dev, info, wrqu, extra);
    UF_RTNL_LOCK();

    return err;
} /* unifi_siwauth() */


static int
unifi_giwauth(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    unifi_trace(NULL, UDBG2, "unifi_giwauth\n");
    return -EOPNOTSUPP;
} /* unifi_giwauth() */

/*
 * ---------------------------------------------------------------------------
 *  unifi_siwencodeext
 *  unifi_giwencodeext
 *
 *      Handlers for SIOCSIWENCODEEXT, SIOCGIWENCODEEXT - set/get
 *      encoding token & mode
 *
 *  Arguments:
 *      None.
 *
 *  Returns:
 *      None.
 *
 *  Notes:
 *      For WPA/WPA2 we don't take note of the IW_ENCODE_EXT_SET_TX_KEY flag.
 *      This flag means "use this key to encode transmissions"; we just
 *      assume only one key will be set and that is the one to use.
 * ---------------------------------------------------------------------------
 */
static int
_unifi_siwencodeext(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
    int r = 0;
    unsigned char *keydata;
    unsigned char tkip_key[32];
    int keyid;
    unsigned char *a = (unsigned char *)ext->addr.sa_data;
    CsrWifiSmeKey sme_key;
    CsrWifiSmeKeyType key_type;

    func_enter();

    CHECK_INITED(priv);

    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
       unifi_error(priv, "unifi_siwencodeext: not permitted in Mode %d\n",
                                      interfacePriv->interfaceMode);
       return -EPERM;
    }


    unifi_trace(priv, UDBG1, "siwencodeext: flags=0x%X, alg=%d, ext_flags=0x%X, len=%d, index=%d,\n",
                wrqu->encoding.flags, ext->alg, ext->ext_flags,
                ext->key_len, (wrqu->encoding.flags & IW_ENCODE_INDEX));
	unifi_trace(priv, UDBG3, "              addr=%pM\n", a);

    if ((ext->key_len == 0) && (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)) {
        /* This means use a different key (given by key_idx) for Tx. */
        /* NYI */
        unifi_trace(priv, UDBG1, KERN_ERR "unifi_siwencodeext: NYI should change tx key id here!!\n");
        return -ENOTSUPP;
    }

    memset(&sme_key, 0, sizeof(sme_key));

    keydata = (unsigned char *)(ext + 1);
    keyid = (wrqu->encoding.flags & IW_ENCODE_INDEX);

    /*
     * Check for request to delete keys for an address.
     */
    /* Pick out request for no privacy. */
    if (ext->alg == IW_ENCODE_ALG_NONE) {

        unifi_trace(priv, UDBG1, "Deleting %s key %d\n",
                    (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) ? "GROUP" : "PAIRWISE",
                    keyid);

        if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
            sme_key.keyType = CSR_WIFI_SME_KEY_TYPE_GROUP;
        } else {
            sme_key.keyType = CSR_WIFI_SME_KEY_TYPE_PAIRWISE;
        }
        sme_key.keyIndex = (keyid - 1);
        sme_key.keyLength = 0;
        sme_key.authenticator = 0;
        memcpy(sme_key.address.a, a, ETH_ALEN);
        UF_RTNL_UNLOCK();
        r = sme_mgt_key(priv, &sme_key, CSR_WIFI_SME_LIST_ACTION_REMOVE);
        UF_RTNL_LOCK();
        if (r) {
            unifi_error(priv, "Delete key request was rejected with result %d\n", r);
            return convert_sme_error(r);
        }

        return 0;
    }

    /*
     * Request is to set a key, not delete
     */

    /* Pick out WEP and use set_wep_key(). */
    if (ext->alg == IW_ENCODE_ALG_WEP) {
        /* WEP-40, WEP-104 */

        /* Check for valid key length */
        if (!((ext->key_len == 5) || (ext->key_len == 13))) {
            unifi_trace(priv, UDBG1, KERN_ERR "Invalid length for WEP key: %d\n", ext->key_len);
            return -EINVAL;
        }

        unifi_trace(priv, UDBG1, "Setting WEP key %d tx:%d\n",
                    keyid, ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY);

        if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
            sme_key.wepTxKey = TRUE;
            sme_key.keyType = CSR_WIFI_SME_KEY_TYPE_PAIRWISE;
        } else {
            sme_key.wepTxKey = FALSE;
            sme_key.keyType = CSR_WIFI_SME_KEY_TYPE_GROUP;
        }
        sme_key.keyIndex = (keyid - 1);
        sme_key.keyLength = ext->key_len;
        sme_key.authenticator = 0;
        memset(sme_key.address.a, 0xFF, ETH_ALEN);
        memcpy(sme_key.key, keydata, ext->key_len);
        UF_RTNL_UNLOCK();
        r = sme_mgt_key(priv, &sme_key, CSR_WIFI_SME_LIST_ACTION_ADD);
        UF_RTNL_LOCK();
        if (r) {
            unifi_error(priv, "siwencodeext: Set key failed (%d)", r);
            return convert_sme_error(r);
        }

        return 0;
    }

    /*
     *
     * If we reach here, we are dealing with a WPA/WPA2 key
     *
     */
    if (ext->key_len > 32) {
        return -EINVAL;
    }

    /*
     * TKIP keys from wpa_supplicant need swapping.
     * What about other supplicants (when they come along)?
     */
    if ((ext->alg == IW_ENCODE_ALG_TKIP) && (ext->key_len == 32)) {
        memcpy(tkip_key, keydata, 16);
        memcpy(tkip_key + 16, keydata + 24, 8);
        memcpy(tkip_key + 24, keydata + 16, 8);
        keydata = tkip_key;
    }

    key_type = (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) ?
        CSR_WIFI_SME_KEY_TYPE_GROUP : /* Group Key */
        CSR_WIFI_SME_KEY_TYPE_PAIRWISE; /* Pairwise Key */

    sme_key.keyType = key_type;
    sme_key.keyIndex = (keyid - 1);
    sme_key.keyLength = ext->key_len;
    sme_key.authenticator = 0;
    memcpy(sme_key.address.a, ext->addr.sa_data, ETH_ALEN);
    if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {

		unifi_trace(priv, UDBG5, "RSC first 6 bytes = %*phC\n",
					 6, ext->rx_seq);

        /* memcpy((u8*)(&sme_key.keyRsc), ext->rx_seq, 8); */
        sme_key.keyRsc[0] = ext->rx_seq[1] << 8 | ext->rx_seq[0];
        sme_key.keyRsc[1] = ext->rx_seq[3] << 8 | ext->rx_seq[2];
        sme_key.keyRsc[2] = ext->rx_seq[5] << 8 | ext->rx_seq[4];
        sme_key.keyRsc[3] = ext->rx_seq[7] << 8 | ext->rx_seq[6];

    }

    memcpy(sme_key.key, keydata, ext->key_len);
    UF_RTNL_UNLOCK();
    r = sme_mgt_key(priv, &sme_key, CSR_WIFI_SME_LIST_ACTION_ADD);
    UF_RTNL_LOCK();
    if (r) {
        unifi_error(priv, "SETKEYS request was rejected with result %d\n", r);
        return convert_sme_error(r);
    }

    func_exit();
    return r;
} /* _unifi_siwencodeext() */


static int
unifi_siwencodeext(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    int err = 0;

    err = _unifi_siwencodeext(dev, info, wrqu, extra);

    return err;
} /* unifi_siwencodeext() */


static int
unifi_giwencodeext(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    return -EOPNOTSUPP;
} /* unifi_giwencodeext() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_siwpmksa
 *
 *      SIOCSIWPMKSA - PMKSA cache operation
 *      The caller passes a pmksa structure:
 *        - cmd         one of ADD, REMOVE, FLUSH
 *        - bssid       MAC address
 *        - pmkid       ID string (16 bytes)
 *
 *  Arguments:
 *      None.
 *
 *  Returns:
 *      None.
 *
 *  Notes:
 *      This is not needed since we provide a siwgenie method.
 * ---------------------------------------------------------------------------
 */
#define UNIFI_PMKID_KEY_SIZE 16
static int
unifi_siwpmksa(struct net_device *dev, struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    struct iw_pmksa *pmksa = (struct iw_pmksa *)extra;
    CsrResult r = 0;
    CsrWifiSmePmkidList pmkid_list;
    CsrWifiSmePmkid pmkid;
    CsrWifiSmeListAction action;

    CHECK_INITED(priv);

    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
       unifi_error(priv, "unifi_siwpmksa: not permitted in Mode %d\n",
                                      interfacePriv->interfaceMode);
       return -EPERM;
    }


	unifi_trace(priv, UDBG1, "SIWPMKSA: cmd %d, %pM\n", pmksa->cmd,
		pmksa->bssid.sa_data);

    pmkid_list.pmkids = NULL;
    switch (pmksa->cmd) {
      case IW_PMKSA_ADD:
        pmkid_list.pmkids = &pmkid;
        action = CSR_WIFI_SME_LIST_ACTION_ADD;
        pmkid_list.pmkidsCount = 1;
        memcpy(pmkid.bssid.a, pmksa->bssid.sa_data, ETH_ALEN);
        memcpy(pmkid.pmkid, pmksa->pmkid, UNIFI_PMKID_KEY_SIZE);
        break;
      case IW_PMKSA_REMOVE:
        pmkid_list.pmkids = &pmkid;
        action = CSR_WIFI_SME_LIST_ACTION_REMOVE;
        pmkid_list.pmkidsCount = 1;
        memcpy(pmkid.bssid.a, pmksa->bssid.sa_data, ETH_ALEN);
        memcpy(pmkid.pmkid, pmksa->pmkid, UNIFI_PMKID_KEY_SIZE);
        break;
      case IW_PMKSA_FLUSH:
        /* Replace current PMKID's with an empty list */
        pmkid_list.pmkidsCount = 0;
        action = CSR_WIFI_SME_LIST_ACTION_FLUSH;
        break;
      default:
        unifi_notice(priv, "SIWPMKSA: Unknown command (0x%x)\n", pmksa->cmd);
        return -EINVAL;
    }

    /* Set the Value the pmkid's will have 1 added OR 1 removed OR be cleared at this point */
    UF_RTNL_UNLOCK();
    r = sme_mgt_pmkid(priv, action, &pmkid_list);
    UF_RTNL_LOCK();
    if (r) {
        unifi_error(priv, "SIWPMKSA: Set PMKID's Failed.\n");
    }

    return r;

} /* unifi_siwpmksa() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_get_wireless_stats
 *
 *      get_wireless_stats method for Linux wireless extensions.
 *
 *  Arguments:
 *      dev             Pointer to associated netdevice.
 *
 *  Returns:
 *      Pointer to iw_statistics struct.
 * ---------------------------------------------------------------------------
 */
struct iw_statistics *
unifi_get_wireless_stats(struct net_device *dev)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;

    if (priv->init_progress != UNIFI_INIT_COMPLETED) {
        return NULL;
    }

    return &priv->wext_wireless_stats;
} /* unifi_get_wireless_stats() */


/*
 * Structures to export the Wireless Handlers
 */

static const struct iw_priv_args unifi_private_args[] = {
    /*{ cmd,         set_args,                            get_args, name } */
    { SIOCIWS80211POWERSAVEPRIV, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
        IW_PRIV_TYPE_NONE, "iwprivs80211ps" },
    { SIOCIWG80211POWERSAVEPRIV, IW_PRIV_TYPE_NONE,
        IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IWPRIV_POWER_SAVE_MAX_STRING, "iwprivg80211ps" },
    { SIOCIWS80211RELOADDEFAULTSPRIV, IW_PRIV_TYPE_NONE,
        IW_PRIV_TYPE_NONE, "iwprivsdefs" },
    { SIOCIWSSMEDEBUGPRIV, IW_PRIV_TYPE_CHAR | IWPRIV_SME_DEBUG_MAX_STRING, IW_PRIV_TYPE_NONE, "iwprivssmedebug" },
#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
    { SIOCIWSCONFWAPIPRIV, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
        IW_PRIV_TYPE_NONE, "iwprivsconfwapi" },
    { SIOCIWSWAPIKEYPRIV, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof(unifiio_wapi_key_t),
        IW_PRIV_TYPE_NONE, "iwprivswpikey" },
#endif
#ifdef CSR_SUPPORT_WEXT_AP
    { SIOCIWSAPCFGPRIV, IW_PRIV_TYPE_CHAR | 256, IW_PRIV_TYPE_NONE, "AP_SET_CFG" },
    { SIOCIWSAPSTARTPRIV, 0,IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED|IWPRIV_SME_MAX_STRING,"AP_BSS_START" },
    { SIOCIWSAPSTOPPRIV, IW_PRIV_TYPE_CHAR |IW_PRIV_SIZE_FIXED|0,
      IW_PRIV_TYPE_CHAR |IW_PRIV_SIZE_FIXED|0, "AP_BSS_STOP" },
#ifdef ANDROID_BUILD
    { SIOCIWSFWRELOADPRIV, IW_PRIV_TYPE_CHAR |256,
      IW_PRIV_TYPE_CHAR |IW_PRIV_SIZE_FIXED|0, "WL_FW_RELOAD" },
    { SIOCIWSSTACKSTART, 0,
      IW_PRIV_TYPE_CHAR |IW_PRIV_SIZE_FIXED|IWPRIV_SME_MAX_STRING, "START" },
    { SIOCIWSSTACKSTOP, 0,
      IW_PRIV_TYPE_CHAR |IW_PRIV_SIZE_FIXED|IWPRIV_SME_MAX_STRING, "STOP" },
#endif /* ANDROID_BUILD */
#endif /* CSR_SUPPORT_WEXT_AP */
};

static const iw_handler unifi_handler[] =
{
    (iw_handler) unifi_siwcommit,           /* SIOCSIWCOMMIT */
    (iw_handler) unifi_giwname,             /* SIOCGIWNAME */
    (iw_handler) NULL,                      /* SIOCSIWNWID */
    (iw_handler) NULL,                      /* SIOCGIWNWID */
    (iw_handler) unifi_siwfreq,             /* SIOCSIWFREQ */
    (iw_handler) unifi_giwfreq,             /* SIOCGIWFREQ */
    (iw_handler) unifi_siwmode,             /* SIOCSIWMODE */
    (iw_handler) unifi_giwmode,             /* SIOCGIWMODE */
    (iw_handler) NULL,                      /* SIOCSIWSENS */
    (iw_handler) NULL,                      /* SIOCGIWSENS */
    (iw_handler) NULL,                      /* SIOCSIWRANGE */
    (iw_handler) unifi_giwrange,            /* 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) unifi_siwap,               /* SIOCSIWAP */
    (iw_handler) unifi_giwap,               /* SIOCGIWAP */
#if WIRELESS_EXT > 17
    /* WPA : IEEE 802.11 MLME requests */
    unifi_siwmlme,              /* SIOCSIWMLME, request MLME operation */
#else
    (iw_handler) NULL,                      /* -- hole -- */
#endif
    (iw_handler) NULL,                      /* SIOCGIWAPLIST */
    (iw_handler) unifi_siwscan,             /* SIOCSIWSCAN */
    (iw_handler) unifi_giwscan,             /* SIOCGIWSCAN */
    (iw_handler) unifi_siwessid,            /* SIOCSIWESSID */
    (iw_handler) unifi_giwessid,            /* SIOCGIWESSID */
    (iw_handler) NULL,                      /* SIOCSIWNICKN */
    (iw_handler) NULL,                      /* SIOCGIWNICKN */
    (iw_handler) NULL,                      /* -- hole -- */
    (iw_handler) NULL,                      /* -- hole -- */
    unifi_siwrate,                          /* SIOCSIWRATE */
    unifi_giwrate,                          /* SIOCGIWRATE */
    unifi_siwrts,                           /* SIOCSIWRTS */
    unifi_giwrts,                           /* SIOCGIWRTS */
    unifi_siwfrag,                          /* SIOCSIWFRAG */
    unifi_giwfrag,                          /* SIOCGIWFRAG */
    (iw_handler) NULL,                      /* SIOCSIWTXPOW */
    (iw_handler) NULL,                      /* SIOCGIWTXPOW */
    (iw_handler) NULL,                      /* SIOCSIWRETRY */
    (iw_handler) NULL,                      /* SIOCGIWRETRY */
    unifi_siwencode,                        /* SIOCSIWENCODE */
    unifi_giwencode,                        /* SIOCGIWENCODE */
    unifi_siwpower,                         /* SIOCSIWPOWER */
    unifi_giwpower,                         /* SIOCGIWPOWER */
#if WIRELESS_EXT > 17
    (iw_handler) NULL,                      /* -- hole -- */
    (iw_handler) NULL,                      /* -- hole -- */

    /* WPA : Generic IEEE 802.11 informatiom element (e.g., for WPA/RSN/WMM). */
    unifi_siwgenie,             /* SIOCSIWGENIE */      /* set generic IE */
    unifi_giwgenie,             /* SIOCGIWGENIE */      /* get generic IE */

    /* WPA : Authentication mode parameters */
    unifi_siwauth,              /* SIOCSIWAUTH */       /* set authentication mode params */
    unifi_giwauth,              /* SIOCGIWAUTH */       /* get authentication mode params */

    /* WPA : Extended version of encoding configuration */
    unifi_siwencodeext,         /* SIOCSIWENCODEEXT */  /* set encoding token & mode */
    unifi_giwencodeext,         /* SIOCGIWENCODEEXT */  /* get encoding token & mode */

    /* WPA2 : PMKSA cache management */
    unifi_siwpmksa,             /* SIOCSIWPMKSA */      /* PMKSA cache operation */
    (iw_handler) NULL,          /* -- hole -- */
#endif /* WIRELESS_EXT > 17 */
};


static const iw_handler unifi_private_handler[] =
{
    iwprivs80211ps,                 /* SIOCIWFIRSTPRIV */
    iwprivg80211ps,                 /* SIOCIWFIRSTPRIV + 1 */
    iwprivsdefs,                    /* SIOCIWFIRSTPRIV + 2 */
    (iw_handler) NULL,
#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
    iwprivsconfwapi,                /* SIOCIWFIRSTPRIV + 4 */
    (iw_handler) NULL,              /* SIOCIWFIRSTPRIV + 5 */
    iwprivswpikey,                  /* SIOCIWFIRSTPRIV + 6 */
#else
    (iw_handler) NULL,
    (iw_handler) NULL,
    (iw_handler) NULL,
#endif
    (iw_handler) NULL,
    iwprivssmedebug,                /* SIOCIWFIRSTPRIV + 8 */
#ifdef CSR_SUPPORT_WEXT_AP
    (iw_handler) NULL,
    iwprivsapconfig,
    (iw_handler) NULL,
    iwprivsapstart,
    (iw_handler) NULL,
    iwprivsapstop,
    (iw_handler) NULL,
#ifdef ANDROID_BUILD
    iwprivsapfwreload,
    (iw_handler) NULL,
    iwprivsstackstart,
    (iw_handler) NULL,
    iwprivsstackstop,
#else
    (iw_handler) NULL,
    (iw_handler) NULL,
    (iw_handler) NULL,
    (iw_handler) NULL,
    (iw_handler) NULL,
#endif /* ANDROID_BUILD */
#else
    (iw_handler) NULL,
    (iw_handler) NULL,
    (iw_handler) NULL,
    (iw_handler) NULL,
    (iw_handler) NULL,
    (iw_handler) NULL,
    (iw_handler) NULL,
    (iw_handler) NULL,
    (iw_handler) NULL,
    (iw_handler) NULL,
    (iw_handler) NULL,
    (iw_handler) NULL,
#endif /* CSR_SUPPORT_WEXT_AP */
};

struct iw_handler_def unifi_iw_handler_def =
{
    .num_standard       = sizeof(unifi_handler) / sizeof(iw_handler),
    .num_private        = sizeof(unifi_private_handler) / sizeof(iw_handler),
    .num_private_args   = sizeof(unifi_private_args) / sizeof(struct iw_priv_args),
    .standard           = (iw_handler *) unifi_handler,
    .private            = (iw_handler *) unifi_private_handler,
    .private_args       = (struct iw_priv_args *) unifi_private_args,
#if IW_HANDLER_VERSION >= 6
    .get_wireless_stats = unifi_get_wireless_stats,
#endif
};


