diff options
Diffstat (limited to 'drivers/staging/csr/sme_wext.c')
-rw-r--r-- | drivers/staging/csr/sme_wext.c | 3327 |
1 files changed, 0 insertions, 3327 deletions
diff --git a/drivers/staging/csr/sme_wext.c b/drivers/staging/csr/sme_wext.c deleted file mode 100644 index 84f11cb..0000000 --- a/drivers/staging/csr/sme_wext.c +++ /dev/null @@ -1,3327 +0,0 @@ -/* - * --------------------------------------------------------------------------- - * 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; - - 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); - } - - 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; - - 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); - } - - 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; - - 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); - } - - 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; - - 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; - - 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; - - 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); - - 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; - - 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); - 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; - - 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); - return convert_sme_error(err); - } - } - - 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; - - 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); - } - - 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 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 - - 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; - } - - -#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); - } - - 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; - - 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); - return convert_sme_error(err); - } - - 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; - - 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); - } - - - 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; - - 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; - } - - - 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; - - 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; - - 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; - - 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; - } - - 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; - - 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: - return -EOPNOTSUPP; - } - - 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; - - 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) { - return 0; - } - - priv->connection_config.mlmeAssociateReqInformationElements = kmalloc(len, GFP_KERNEL); - if (priv->connection_config.mlmeAssociateReqInformationElements == NULL) { - return -ENOMEM; - } - - priv->connection_config.mlmeAssociateReqInformationElementsLength = len; - memcpy( priv->connection_config.mlmeAssociateReqInformationElements, extra, len); - - 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; - - 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); - - 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; - - 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); - - 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; - - 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); - } - - 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 -}; - - |