summaryrefslogtreecommitdiffstats
path: root/drivers/staging/csr/sme_wext.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/csr/sme_wext.c')
-rw-r--r--drivers/staging/csr/sme_wext.c3327
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 84f11cb53596..000000000000
--- 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
-};
-
-