From: Arend van Spriel <arend@xxxxxxxxxxxx> The brcmfmac driver contained functions for wireless extensions support. However, brcmfmac is intended to be a cfg80211 driver so all the entire source file is obsolete. Signed-off-by: Arend van Spriel <arend@xxxxxxxxxxxx> Reviewed-by: Roland Vossen <rvossen@xxxxxxxxxxxx> Reviewed-by: Franky Lin <frankyl@xxxxxxxxxxxx> --- drivers/staging/brcm80211/brcmfmac/Makefile | 1 - drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 29 - drivers/staging/brcm80211/brcmfmac/wl_iw.c | 3660 ------------------------ drivers/staging/brcm80211/brcmfmac/wl_iw.h | 138 - 4 files changed, 0 insertions(+), 3828 deletions(-) delete mode 100644 drivers/staging/brcm80211/brcmfmac/wl_iw.c delete mode 100644 drivers/staging/brcm80211/brcmfmac/wl_iw.h diff --git a/drivers/staging/brcm80211/brcmfmac/Makefile b/drivers/staging/brcm80211/brcmfmac/Makefile index c5ec562..d907cae 100644 --- a/drivers/staging/brcm80211/brcmfmac/Makefile +++ b/drivers/staging/brcm80211/brcmfmac/Makefile @@ -40,7 +40,6 @@ ccflags-y += \ DHDOFILES = \ wl_cfg80211.o \ - wl_iw.o \ dhd_cdc.o \ dhd_common.o \ dhd_custom_gpio.o \ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index c556191..48859cd 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -183,12 +183,6 @@ MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver."); MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards"); MODULE_LICENSE("Dual BSD/GPL"); -/* Linux wireless extension support */ -#if defined(CONFIG_WIRELESS_EXT) -#include <wl_iw.h> -extern wl_iw_extra_params_t g_wl_iw_params; -#endif /* defined(CONFIG_WIRELESS_EXT) */ - #if defined(CONFIG_HAS_EARLYSUSPEND) #include <linux/earlysuspend.h> extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, @@ -218,10 +212,6 @@ typedef struct dhd_if { /* Local private structure (extension of pub) */ typedef struct dhd_info { -#if defined(CONFIG_WIRELESS_EXT) - wl_iw_t iw; /* wireless extensions state (must be first) */ -#endif /* defined(CONFIG_WIRELESS_EXT) */ - dhd_pub_t pub; /* OS/stack specifics */ @@ -1602,14 +1592,6 @@ static int dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) if (ifidx == DHD_BAD_IF) return -1; -#if defined(CONFIG_WIRELESS_EXT) - /* linux wireless extensions */ - if ((cmd >= SIOCIWFIRST) && (cmd <= SIOCIWLAST)) { - /* may recurse, do NOT lock */ - return wl_iw_ioctl(net, ifr, cmd); - } -#endif /* defined(CONFIG_WIRELESS_EXT) */ - if (cmd == SIOCETHTOOL) return dhd_ethtool(dhd, (void *)ifr->ifr_data); @@ -1896,13 +1878,6 @@ dhd_pub_t *dhd_attach(struct dhd_bus *bus, uint bus_hdrlen) DHD_ERROR(("dhd_prot_attach failed\n")); goto fail; } -#if defined(CONFIG_WIRELESS_EXT) - /* Attach and link in the iw */ - if (wl_iw_attach(net, (void *)&dhd->pub) != 0) { - DHD_ERROR(("wl_iw_attach failed\n")); - goto fail; - } -#endif /* defined(CONFIG_WIRELESS_EXT) */ /* Attach and link in the cfg80211 */ if (unlikely(wl_cfg80211_attach(net, &dhd->pub))) { @@ -2262,10 +2237,6 @@ void dhd_detach(dhd_pub_t *dhdp) if (dhdp->prot) dhd_prot_detach(dhdp); -#if defined(CONFIG_WIRELESS_EXT) - wl_iw_detach(); -#endif /* (CONFIG_WIRELESS_EXT) */ - wl_cfg80211_detach(); /* && defined(DHD_GPL) */ diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c deleted file mode 100644 index ef407ec..0000000 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ /dev/null @@ -1,3660 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include <linux/kthread.h> -#include <linux/semaphore.h> -#include <linux/ieee80211.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/wireless.h> -#include <linux/if_arp.h> -#include <linux/uaccess.h> - -#include <brcmu_utils.h> -#include <brcmu_wifi.h> -#include <defs.h> -#include "dngl_stats.h" -#include "dhd.h" - -#define WPA_OUI "\x00\x50\xF2" -#define DOT11_MNG_RSN_ID 48 -#define DOT11_MNG_WPA_ID 221 - -#define WL_ERROR(fmt, args...) printk(fmt, ##args) -#define WL_TRACE(fmt, args...) no_printk(fmt, ##args) -#define WL_INFORM(fmt, args...) no_printk(fmt, ##args) -#define WL_WSEC(fmt, args...) no_printk(fmt, ##args) -#define WL_SCAN(fmt, args...) no_printk(fmt, ##args) - -#include <wl_iw.h> - -#define IW_WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | \ - TKIP_ENABLED | AES_ENABLED)) - -#include <linux/rtnetlink.h> - -#define WL_IW_USE_ISCAN 1 -#define ENABLE_ACTIVE_PASSIVE_SCAN_SUPPRESS 1 - -bool g_set_essid_before_scan = true; - -#define WL_IW_IOCTL_CALL(func_call) \ - do { \ - func_call; \ - } while (0) - -static int g_onoff = G_WLAN_SET_ON; -wl_iw_extra_params_t g_wl_iw_params; - -extern bool wl_iw_conn_status_str(u32 event_type, u32 status, - u32 reason, char *stringBuf, uint buflen); - -#define MAX_WLIW_IOCTL_LEN 1024 - -#ifdef CONFIG_WIRELESS_EXT -extern int dhd_wait_pend8021x(struct net_device *dev); -#endif - -#if WIRELESS_EXT < 19 -#define IW_IOCTL_IDX(cmd) ((cmd) - SIOCIWFIRST) -#define IW_EVENT_IDX(cmd) ((cmd) - IWEVFIRST) -#endif - -static void *g_scan; -static volatile uint g_scan_specified_ssid; -static wlc_ssid_t g_specific_ssid; - -static wlc_ssid_t g_ssid; - -#if defined(WL_IW_USE_ISCAN) -#define ISCAN_STATE_IDLE 0 -#define ISCAN_STATE_SCANING 1 - -#define WLC_IW_ISCAN_MAXLEN 2048 -typedef struct iscan_buf { - struct iscan_buf *next; - char iscan_buf[WLC_IW_ISCAN_MAXLEN]; -} iscan_buf_t; - -typedef struct iscan_info { - struct net_device *dev; - struct timer_list timer; - u32 timer_ms; - u32 timer_on; - int iscan_state; - iscan_buf_t *list_hdr; - iscan_buf_t *list_cur; - - struct task_struct *sysioc_tsk; - struct semaphore sysioc_sem; - -#if defined CSCAN - char ioctlbuf[WLC_IOCTL_MEDLEN]; -#else - char ioctlbuf[WLC_IOCTL_SMLEN]; -#endif - wl_iscan_params_t *iscan_ex_params_p; - int iscan_ex_param_size; -} iscan_info_t; -iscan_info_t *g_iscan; - -typedef enum sup_auth_status { - WLC_SUP_DISCONNECTED = 0, - WLC_SUP_CONNECTING, - WLC_SUP_IDREQUIRED, - WLC_SUP_AUTHENTICATING, - WLC_SUP_AUTHENTICATED, - WLC_SUP_KEYXCHANGE, - WLC_SUP_KEYED, - WLC_SUP_TIMEOUT, - WLC_SUP_LAST_BASIC_STATE, - WLC_SUP_KEYXCHANGE_WAIT_M1 = WLC_SUP_AUTHENTICATED, - WLC_SUP_KEYXCHANGE_PREP_M2 = WLC_SUP_KEYXCHANGE, - WLC_SUP_KEYXCHANGE_WAIT_M3 = WLC_SUP_LAST_BASIC_STATE, - WLC_SUP_KEYXCHANGE_PREP_M4, - WLC_SUP_KEYXCHANGE_WAIT_G1, - WLC_SUP_KEYXCHANGE_PREP_G2 -} sup_auth_status_t; - -static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; - -static void wl_iw_timerfunc(unsigned long data); -static void wl_iw_set_event_mask(struct net_device *dev); -static int wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, u16 action); -#endif /* defined(WL_IW_USE_ISCAN) */ - -static int -wl_iw_set_scan(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -static int -wl_iw_get_scan(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, char *extra); - -static uint -wl_iw_get_scan_prep(wl_scan_results_t *list, - struct iw_request_info *info, char *extra, short max_size); - -static void swap_key_from_BE(wl_wsec_key_t *key) -{ - key->index = cpu_to_le32(key->index); - key->len = cpu_to_le32(key->len); - key->algo = cpu_to_le32(key->algo); - key->flags = cpu_to_le32(key->flags); - key->rxiv.hi = cpu_to_le32(key->rxiv.hi); - key->rxiv.lo = cpu_to_le16(key->rxiv.lo); - key->iv_initialized = cpu_to_le32(key->iv_initialized); -} - -static void swap_key_to_BE(wl_wsec_key_t *key) -{ - key->index = le32_to_cpu(key->index); - key->len = le32_to_cpu(key->len); - key->algo = le32_to_cpu(key->algo); - key->flags = le32_to_cpu(key->flags); - key->rxiv.hi = le32_to_cpu(key->rxiv.hi); - key->rxiv.lo = le16_to_cpu(key->rxiv.lo); - key->iv_initialized = le32_to_cpu(key->iv_initialized); -} - -static int dev_wlc_ioctl(struct net_device *dev, int cmd, void *arg, int len) -{ - struct ifreq ifr; - wl_ioctl_t ioc; - mm_segment_t fs; - int ret = -EINVAL; - - if (!dev) { - WL_ERROR("%s: dev is null\n", __func__); - return ret; - } - - WL_INFORM("\n%s, PID:%x: send Local IOCTL -> dhd: cmd:0x%x, buf:%p, len:%d\n", - __func__, current->pid, cmd, arg, len); - - if (g_onoff == G_WLAN_SET_ON) { - memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = cmd; - ioc.buf = arg; - ioc.len = len; - - strcpy(ifr.ifr_name, dev->name); - ifr.ifr_data = (caddr_t)&ioc; - - ret = dev_open(dev); - if (ret) { - WL_ERROR("%s: Error dev_open: %d\n", __func__, ret); - return ret; - } - - fs = get_fs(); - set_fs(get_ds()); - ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE); - set_fs(fs); - } else { - WL_TRACE("%s: call after driver stop : ignored\n", __func__); - } - return ret; -} - -static int dev_wlc_intvar_set(struct net_device *dev, char *name, int val) -{ - char buf[WLC_IOCTL_SMLEN]; - uint len; - - val = cpu_to_le32(val); - len = brcmu_mkiovar(name, (char *)(&val), sizeof(val), buf, - sizeof(buf)); - ASSERT(len); - - return dev_wlc_ioctl(dev, WLC_SET_VAR, buf, len); -} - -#if defined(WL_IW_USE_ISCAN) -static int -dev_iw_iovar_setbuf(struct net_device *dev, - char *iovar, - void *param, int paramlen, void *bufptr, int buflen) -{ - int iolen; - - iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen); - ASSERT(iolen); - - if (iolen == 0) - return 0; - - return dev_wlc_ioctl(dev, WLC_SET_VAR, bufptr, iolen); -} - -static int -dev_iw_iovar_getbuf(struct net_device *dev, - char *iovar, - void *param, int paramlen, void *bufptr, int buflen) -{ - int iolen; - - iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen); - ASSERT(iolen); - - return dev_wlc_ioctl(dev, WLC_GET_VAR, bufptr, buflen); -} -#endif /* defined(WL_IW_USE_ISCAN) */ - -#if WIRELESS_EXT > 17 -static int -dev_wlc_bufvar_set(struct net_device *dev, char *name, char *buf, int len) -{ - static char ioctlbuf[MAX_WLIW_IOCTL_LEN]; - uint buflen; - - buflen = brcmu_mkiovar(name, buf, len, ioctlbuf, sizeof(ioctlbuf)); - ASSERT(buflen); - - return dev_wlc_ioctl(dev, WLC_SET_VAR, ioctlbuf, buflen); -} -#endif /* WIRELESS_EXT > 17 */ - -static int -dev_wlc_bufvar_get(struct net_device *dev, char *name, char *buf, int buflen) -{ - static char ioctlbuf[MAX_WLIW_IOCTL_LEN]; - int error; - uint len; - - len = brcmu_mkiovar(name, NULL, 0, ioctlbuf, sizeof(ioctlbuf)); - ASSERT(len); - error = - dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)ioctlbuf, - MAX_WLIW_IOCTL_LEN); - if (!error) - memcpy(buf, ioctlbuf, buflen); - - return error; -} - -static int dev_wlc_intvar_get(struct net_device *dev, char *name, int *retval) -{ - union { - char buf[WLC_IOCTL_SMLEN]; - int val; - } var; - int error; - - uint len; - uint data_null; - - len = - brcmu_mkiovar(name, (char *)(&data_null), 0, (char *)(&var), - sizeof(var.buf)); - ASSERT(len); - error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)&var, len); - - *retval = le32_to_cpu(var.val); - - return error; -} - -#if WIRELESS_EXT < 13 -struct iw_request_info { - __u16 cmd; - __u16 flags; -}; - -typedef int (*iw_handler) (struct net_device *dev, - struct iw_request_info *info, - void *wrqu, char *extra); -#endif - -static int -wl_iw_config_commit(struct net_device *dev, - struct iw_request_info *info, void *zwrq, char *extra) -{ - wlc_ssid_t ssid; - int error; - struct sockaddr bssid; - - WL_TRACE("%s: SIOCSIWCOMMIT\n", dev->name); - - error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)); - if (error) - return error; - - ssid.SSID_len = le32_to_cpu(ssid.SSID_len); - - if (!ssid.SSID_len) - return 0; - - memset(&bssid, 0, sizeof(struct sockaddr)); - error = dev_wlc_ioctl(dev, WLC_REASSOC, &bssid, ETH_ALEN); - if (error) { - WL_ERROR("%s: WLC_REASSOC to %s failed\n", - __func__, ssid.SSID); - return error; - } - - return 0; -} - -static int -wl_iw_get_name(struct net_device *dev, - struct iw_request_info *info, char *cwrq, char *extra) -{ - WL_TRACE("%s: SIOCGIWNAME\n", dev->name); - - strcpy(cwrq, "IEEE 802.11-DS"); - - return 0; -} - -static int -wl_iw_set_freq(struct net_device *dev, - struct iw_request_info *info, struct iw_freq *fwrq, char *extra) -{ - int error, chan; - uint sf = 0; - - WL_TRACE("\n %s %s: SIOCSIWFREQ\n", __func__, dev->name); - - if (fwrq->e == 0 && fwrq->m < MAXCHANNEL) { - chan = fwrq->m; - } else { - if (fwrq->e >= 6) { - fwrq->e -= 6; - while (fwrq->e--) - fwrq->m *= 10; - } else if (fwrq->e < 6) { - while (fwrq->e++ < 6) - fwrq->m /= 10; - } - if (fwrq->m > 4000 && fwrq->m < 5000) - sf = WF_CHAN_FACTOR_4_G; - - chan = brcmu_mhz2channel(fwrq->m, sf); - } - chan = cpu_to_le32(chan); - - error = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &chan, sizeof(chan)); - if (error) - return error; - - g_wl_iw_params.target_channel = chan; - return -EINPROGRESS; -} - -static int -wl_iw_get_freq(struct net_device *dev, - struct iw_request_info *info, struct iw_freq *fwrq, char *extra) -{ - channel_info_t ci; - int error; - - WL_TRACE("%s: SIOCGIWFREQ\n", dev->name); - - error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci)); - if (error) - return error; - - fwrq->m = le32_to_cpu(ci.hw_channel); - fwrq->e = le32_to_cpu(0); - return 0; -} - -static int -wl_iw_set_mode(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, char *extra) -{ - int infra = 0, ap = 0, error = 0; - - WL_TRACE("%s: SIOCSIWMODE\n", dev->name); - - switch (*uwrq) { - case IW_MODE_MASTER: - infra = ap = 1; - break; - case IW_MODE_ADHOC: - case IW_MODE_AUTO: - break; - case IW_MODE_INFRA: - infra = 1; - break; - default: - return -EINVAL; - } - infra = cpu_to_le32(infra); - ap = cpu_to_le32(ap); - - error = dev_wlc_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(infra)); - if (error) - return error; - - error = dev_wlc_ioctl(dev, WLC_SET_AP, &ap, sizeof(ap)); - if (error) - return error; - - return -EINPROGRESS; -} - -static int -wl_iw_get_mode(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, char *extra) -{ - int error, infra = 0, ap = 0; - - WL_TRACE("%s: SIOCGIWMODE\n", dev->name); - - error = dev_wlc_ioctl(dev, WLC_GET_INFRA, &infra, sizeof(infra)); - if (error) - return error; - - error = dev_wlc_ioctl(dev, WLC_GET_AP, &ap, sizeof(ap)); - if (error) - return error; - - infra = le32_to_cpu(infra); - ap = le32_to_cpu(ap); - *uwrq = infra ? ap ? IW_MODE_MASTER : IW_MODE_INFRA : IW_MODE_ADHOC; - - return 0; -} - -static int -wl_iw_get_range(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - struct iw_range *range = (struct iw_range *)extra; - wl_u32_list_t *list; - wl_rateset_t rateset; - s8 *channels; - int error, i, k; - uint ch; - - int phytype; - int bw_cap = 0, sgi_tx = 0, nmode = 0; - channel_info_t ci; - u8 nrate_list2copy = 0; - u16 nrate_list[4][8] = { {13, 26, 39, 52, 78, 104, 117, 130}, - {14, 29, 43, 58, 87, 116, 130, 144}, - {27, 54, 81, 108, 162, 216, 243, 270}, - {30, 60, 90, 120, 180, 240, 270, 300} - }; - - WL_TRACE("%s: SIOCGIWRANGE\n", dev->name); - - if (!extra) - return -EINVAL; - - channels = kmalloc((MAXCHANNEL + 1) * 4, GFP_KERNEL); - if (!channels) { - WL_ERROR("Could not alloc channels\n"); - return -ENOMEM; - } - list = (wl_u32_list_t *) channels; - - dwrq->length = sizeof(struct iw_range); - memset(range, 0, sizeof(*range)); - - list->count = cpu_to_le32(MAXCHANNEL); - error = dev_wlc_ioctl(dev, WLC_GET_VALID_CHANNELS, channels, - (MAXCHANNEL + 1) * 4); - if (error) { - kfree(channels); - return error; - } - for (i = 0; i < le32_to_cpu(list->count) && i < IW_MAX_FREQUENCIES; - i++) { - range->freq[i].i = le32_to_cpu(list->element[i]); - - ch = le32_to_cpu(list->element[i]); - if (ch <= CH_MAX_2G_CHANNEL) { - range->freq[i].m = ieee80211_dsss_chan_to_freq(ch); - } else { - range->freq[i].m = ieee80211_ofdm_chan_to_freq( - WF_CHAN_FACTOR_5_G/2, ch); - } - range->freq[i].e = 6; - } - range->num_frequency = range->num_channels = i; - - range->max_qual.qual = 5; - range->max_qual.level = 0x100 - 200; - range->max_qual.noise = 0x100 - 200; - range->sensitivity = 65535; - -#if WIRELESS_EXT > 11 - range->avg_qual.qual = 3; - range->avg_qual.level = 0x100 + WL_IW_RSSI_GOOD; - range->avg_qual.noise = 0x100 - 75; -#endif - - error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, - sizeof(rateset)); - if (error) { - kfree(channels); - return error; - } - rateset.count = le32_to_cpu(rateset.count); - range->num_bitrates = rateset.count; - for (i = 0; i < rateset.count && i < IW_MAX_BITRATES; i++) - range->bitrate[i] = (rateset.rates[i] & 0x7f) * 500000; - dev_wlc_intvar_get(dev, "nmode", &nmode); - dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &phytype, sizeof(phytype)); - - if (nmode == 1 && phytype == WLC_PHY_TYPE_SSN) { - dev_wlc_intvar_get(dev, "mimo_bw_cap", &bw_cap); - dev_wlc_intvar_get(dev, "sgi_tx", &sgi_tx); - dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, - sizeof(channel_info_t)); - ci.hw_channel = le32_to_cpu(ci.hw_channel); - - if (bw_cap == 0 || (bw_cap == 2 && ci.hw_channel <= 14)) { - if (sgi_tx == 0) - nrate_list2copy = 0; - else - nrate_list2copy = 1; - } - if (bw_cap == 1 || (bw_cap == 2 && ci.hw_channel >= 36)) { - if (sgi_tx == 0) - nrate_list2copy = 2; - else - nrate_list2copy = 3; - } - range->num_bitrates += 8; - for (k = 0; i < range->num_bitrates; k++, i++) { - range->bitrate[i] = - (nrate_list[nrate_list2copy][k]) * 500000; - } - } - - error = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &i, sizeof(i)); - if (error) { - kfree(channels); - return error; - } - i = le32_to_cpu(i); - if (i == WLC_PHY_TYPE_A) - range->throughput = 24000000; - else - range->throughput = 1500000; - - range->min_rts = 0; - range->max_rts = 2347; - range->min_frag = 256; - range->max_frag = 2346; - - range->max_encoding_tokens = DOT11_MAX_DEFAULT_KEYS; - range->num_encoding_sizes = 4; - range->encoding_size[0] = WLAN_KEY_LEN_WEP40; - range->encoding_size[1] = WLAN_KEY_LEN_WEP104; -#if WIRELESS_EXT > 17 - range->encoding_size[2] = WLAN_KEY_LEN_TKIP; -#else - range->encoding_size[2] = 0; -#endif - range->encoding_size[3] = WLAN_KEY_LEN_AES_CMAC; - - range->min_pmp = 0; - range->max_pmp = 0; - range->min_pmt = 0; - range->max_pmt = 0; - range->pmp_flags = 0; - range->pm_capa = 0; - - range->num_txpower = 2; - range->txpower[0] = 1; - range->txpower[1] = 255; - range->txpower_capa = IW_TXPOW_MWATT; - -#if WIRELESS_EXT > 10 - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 19; - - range->retry_capa = IW_RETRY_LIMIT; - range->retry_flags = IW_RETRY_LIMIT; - range->r_time_flags = 0; - range->min_retry = 1; - range->max_retry = 255; - range->min_r_time = 0; - range->max_r_time = 0; -#endif - -#if WIRELESS_EXT > 17 - range->enc_capa = IW_ENC_CAPA_WPA; - range->enc_capa |= IW_ENC_CAPA_CIPHER_TKIP; - range->enc_capa |= IW_ENC_CAPA_CIPHER_CCMP; - range->enc_capa |= IW_ENC_CAPA_WPA2; - - IW_EVENT_CAPA_SET_KERNEL(range->event_capa); - IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP); - IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN); - IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP); - IW_EVENT_CAPA_SET(range->event_capa, IWEVMICHAELMICFAILURE); - IW_EVENT_CAPA_SET(range->event_capa, IWEVPMKIDCAND); -#endif /* WIRELESS_EXT > 17 */ - - kfree(channels); - - return 0; -} - -static int rssi_to_qual(int rssi) -{ - if (rssi <= WL_IW_RSSI_NO_SIGNAL) - return 0; - else if (rssi <= WL_IW_RSSI_VERY_LOW) - return 1; - else if (rssi <= WL_IW_RSSI_LOW) - return 2; - else if (rssi <= WL_IW_RSSI_GOOD) - return 3; - else if (rssi <= WL_IW_RSSI_VERY_GOOD) - return 4; - else - return 5; -} - -static int -wl_iw_set_spy(struct net_device *dev, - struct iw_request_info *info, struct iw_point *dwrq, char *extra) -{ - wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev); - struct sockaddr *addr = (struct sockaddr *)extra; - int i; - - WL_TRACE("%s: SIOCSIWSPY\n", dev->name); - - if (!extra) - return -EINVAL; - - iw->spy_num = min_t(int, ARRAY_SIZE(iw->spy_addr), dwrq->length); - for (i = 0; i < iw->spy_num; i++) - memcpy(iw->spy_addr[i], addr[i].sa_data, ETH_ALEN); - memset(iw->spy_qual, 0, sizeof(iw->spy_qual)); - - return 0; -} - -static int -wl_iw_get_spy(struct net_device *dev, - struct iw_request_info *info, struct iw_point *dwrq, char *extra) -{ - wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev); - struct sockaddr *addr = (struct sockaddr *)extra; - struct iw_quality *qual = (struct iw_quality *)&addr[iw->spy_num]; - int i; - - WL_TRACE("%s: SIOCGIWSPY\n", dev->name); - - if (!extra) - return -EINVAL; - - dwrq->length = iw->spy_num; - for (i = 0; i < iw->spy_num; i++) { - memcpy(addr[i].sa_data, iw->spy_addr[i], ETH_ALEN); - addr[i].sa_family = AF_UNIX; - memcpy(&qual[i], &iw->spy_qual[i], sizeof(struct iw_quality)); - iw->spy_qual[i].updated = 0; - } - - return 0; -} - -static int -wl_iw_ch_to_chanspec(int ch, wl_join_params_t *join_params, - int *join_params_size) -{ - chanspec_t chanspec = 0; - - if (ch != 0) { - join_params->params.chanspec_num = 1; - join_params->params.chanspec_list[0] = ch; - - if (join_params->params.chanspec_list[0]) - chanspec |= WL_CHANSPEC_BAND_2G; - else - chanspec |= WL_CHANSPEC_BAND_5G; - - chanspec |= WL_CHANSPEC_BW_20; - chanspec |= WL_CHANSPEC_CTL_SB_NONE; - - *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE + - join_params->params.chanspec_num * sizeof(chanspec_t); - - join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK; - join_params->params.chanspec_list[0] |= chanspec; - join_params->params.chanspec_list[0] = - cpu_to_le16(join_params->params.chanspec_list[0]); - - join_params->params.chanspec_num = - cpu_to_le32(join_params->params.chanspec_num); - - WL_TRACE("%s join_params->params.chanspec_list[0]= %X\n", - __func__, join_params->params.chanspec_list[0]); - } - return 1; -} - -static int -wl_iw_set_wap(struct net_device *dev, - struct iw_request_info *info, struct sockaddr *awrq, char *extra) -{ - int error = -EINVAL; - wl_join_params_t join_params; - int join_params_size; - - WL_TRACE("%s: SIOCSIWAP\n", dev->name); - - if (awrq->sa_family != ARPHRD_ETHER) { - WL_ERROR("Invalid Header...sa_family\n"); - return -EINVAL; - } - - if (is_broadcast_ether_addr(awrq->sa_data) || - is_zero_ether_addr(awrq->sa_data)) { - scb_val_t scbval; - memset(&scbval, 0, sizeof(scb_val_t)); - (void)dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, - sizeof(scb_val_t)); - return 0; - } - - memset(&join_params, 0, sizeof(join_params)); - join_params_size = sizeof(join_params.ssid); - - memcpy(join_params.ssid.SSID, g_ssid.SSID, g_ssid.SSID_len); - join_params.ssid.SSID_len = cpu_to_le32(g_ssid.SSID_len); - memcpy(&join_params.params.bssid, awrq->sa_data, ETH_ALEN); - - WL_TRACE("%s target_channel=%d\n", - __func__, g_wl_iw_params.target_channel); - wl_iw_ch_to_chanspec(g_wl_iw_params.target_channel, &join_params, - &join_params_size); - - error = dev_wlc_ioctl(dev, WLC_SET_SSID, &join_params, - join_params_size); - if (error) { - WL_ERROR("%s Invalid ioctl data=%d\n", __func__, error); - } - - if (g_ssid.SSID_len) { - WL_TRACE("%s: join SSID=%s BSSID=%pM ch=%d\n", - __func__, g_ssid.SSID, awrq->sa_data, - g_wl_iw_params.target_channel); - } - - memset(&g_ssid, 0, sizeof(g_ssid)); - return 0; -} - -static int -wl_iw_get_wap(struct net_device *dev, - struct iw_request_info *info, struct sockaddr *awrq, char *extra) -{ - WL_TRACE("%s: SIOCGIWAP\n", dev->name); - - awrq->sa_family = ARPHRD_ETHER; - memset(awrq->sa_data, 0, ETH_ALEN); - - (void)dev_wlc_ioctl(dev, WLC_GET_BSSID, awrq->sa_data, ETH_ALEN); - - return 0; -} - -#if WIRELESS_EXT > 17 -static int -wl_iw_mlme(struct net_device *dev, - struct iw_request_info *info, struct sockaddr *awrq, char *extra) -{ - struct iw_mlme *mlme; - scb_val_t scbval; - int error = -EINVAL; - - WL_TRACE("%s: SIOCSIWMLME DISASSOC/DEAUTH\n", dev->name); - - mlme = (struct iw_mlme *)extra; - if (mlme == NULL) { - WL_ERROR("Invalid ioctl data\n"); - return error; - } - - scbval.val = mlme->reason_code; - memcpy(&scbval.ea, &mlme->addr.sa_data, ETH_ALEN); - - if (mlme->cmd == IW_MLME_DISASSOC) { - scbval.val = cpu_to_le32(scbval.val); - error = - dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, - sizeof(scb_val_t)); - } else if (mlme->cmd == IW_MLME_DEAUTH) { - scbval.val = cpu_to_le32(scbval.val); - error = - dev_wlc_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, - &scbval, sizeof(scb_val_t)); - } else { - WL_ERROR("Invalid ioctl data\n"); - return error; - } - - return error; -} -#endif /* WIRELESS_EXT > 17 */ - -#ifndef WL_IW_USE_ISCAN -static int -wl_iw_get_aplist(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - wl_scan_results_t *list; - struct sockaddr *addr = (struct sockaddr *)extra; - struct iw_quality qual[IW_MAX_AP]; - wl_bss_info_t *bi = NULL; - int error, i; - uint buflen = dwrq->length; - - WL_TRACE("%s: SIOCGIWAPLIST\n", dev->name); - - if (!extra) - return -EINVAL; - - list = kzalloc(buflen, GFP_KERNEL); - if (!list) - return -ENOMEM; - list->buflen = cpu_to_le32(buflen); - error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, buflen); - if (error) { - WL_ERROR("%d: Scan results error %d\n", __LINE__, error); - kfree(list); - return error; - } - list->buflen = le32_to_cpu(list->buflen); - list->version = le32_to_cpu(list->version); - list->count = le32_to_cpu(list->count); - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __func__, list->version); - kfree(list); - return -EINVAL; - } - - for (i = 0, dwrq->length = 0; - i < list->count && dwrq->length < IW_MAX_AP; i++) { - bi = bi ? (wl_bss_info_t *) ((unsigned long)bi + - le32_to_cpu(bi->length)) : list-> - bss_info; - ASSERT(((unsigned long)bi + le32_to_cpu(bi->length)) <= - ((unsigned long)list + buflen)); - - if (!(le16_to_cpu(bi->capability) & WLAN_CAPABILITY_ESS)) - continue; - - memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETH_ALEN); - addr[dwrq->length].sa_family = ARPHRD_ETHER; - qual[dwrq->length].qual = rssi_to_qual(le16_to_cpu(bi->RSSI)); - qual[dwrq->length].level = 0x100 + le16_to_cpu(bi->RSSI); - qual[dwrq->length].noise = 0x100 + bi->phy_noise; - -#if WIRELESS_EXT > 18 - qual[dwrq->length].updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; -#else - qual[dwrq->length].updated = 7; -#endif - dwrq->length++; - } - - kfree(list); - - if (dwrq->length) { - memcpy(&addr[dwrq->length], qual, - sizeof(struct iw_quality) * dwrq->length); - dwrq->flags = 1; - } - - return 0; -} -#endif /* WL_IW_USE_ISCAN */ - -#ifdef WL_IW_USE_ISCAN -static int -wl_iw_iscan_get_aplist(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - wl_scan_results_t *list; - iscan_buf_t *buf; - iscan_info_t *iscan = g_iscan; - - struct sockaddr *addr = (struct sockaddr *)extra; - struct iw_quality qual[IW_MAX_AP]; - wl_bss_info_t *bi = NULL; - int i; - - WL_TRACE("%s: SIOCGIWAPLIST\n", dev->name); - - if (!extra) - return -EINVAL; - - if ((!iscan) || (!iscan->sysioc_tsk)) { - WL_ERROR("%s error\n", __func__); - return 0; - } - - buf = iscan->list_hdr; - while (buf) { - list = &((wl_iscan_results_t *) buf->iscan_buf)->results; - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __func__, list->version); - return -EINVAL; - } - - bi = NULL; - for (i = 0, dwrq->length = 0; - i < list->count && dwrq->length < IW_MAX_AP; i++) { - bi = bi ? (wl_bss_info_t *) ((unsigned long)bi + - le32_to_cpu(bi->length)) : - list->bss_info; - ASSERT(((unsigned long)bi + le32_to_cpu(bi->length)) <= - ((unsigned long)list + WLC_IW_ISCAN_MAXLEN)); - - if (!(le16_to_cpu(bi->capability) & - WLAN_CAPABILITY_ESS)) - continue; - - memcpy(addr[dwrq->length].sa_data, &bi->BSSID, - ETH_ALEN); - addr[dwrq->length].sa_family = ARPHRD_ETHER; - qual[dwrq->length].qual = - rssi_to_qual(le16_to_cpu(bi->RSSI)); - qual[dwrq->length].level = 0x100 + - le16_to_cpu(bi->RSSI); - qual[dwrq->length].noise = 0x100 + bi->phy_noise; - -#if WIRELESS_EXT > 18 - qual[dwrq->length].updated = - IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; -#else - qual[dwrq->length].updated = 7; -#endif - - dwrq->length++; - } - buf = buf->next; - } - if (dwrq->length) { - memcpy(&addr[dwrq->length], qual, - sizeof(struct iw_quality) * dwrq->length); - dwrq->flags = 1; - } - - return 0; -} - -static int wl_iw_iscan_prep(wl_scan_params_t *params, wlc_ssid_t *ssid) -{ - int err = 0; - - memcpy(params->bssid, ether_bcast, ETH_ALEN); - params->bss_type = DOT11_BSSTYPE_ANY; - params->scan_type = 0; - params->nprobes = -1; - params->active_time = -1; - params->passive_time = -1; - params->home_time = -1; - params->channel_num = 0; - - params->nprobes = cpu_to_le32(params->nprobes); - params->active_time = cpu_to_le32(params->active_time); - params->passive_time = cpu_to_le32(params->passive_time); - params->home_time = cpu_to_le32(params->home_time); - if (ssid && ssid->SSID_len) - memcpy(¶ms->ssid, ssid, sizeof(wlc_ssid_t)); - - return err; -} - -static int wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, u16 action) -{ - int err = 0; - - iscan->iscan_ex_params_p->version = cpu_to_le32(ISCAN_REQ_VERSION); - iscan->iscan_ex_params_p->action = cpu_to_le16(action); - iscan->iscan_ex_params_p->scan_duration = cpu_to_le16(0); - - WL_SCAN("%s : nprobes=%d\n", - __func__, iscan->iscan_ex_params_p->params.nprobes); - WL_SCAN("active_time=%d\n", - iscan->iscan_ex_params_p->params.active_time); - WL_SCAN("passive_time=%d\n", - iscan->iscan_ex_params_p->params.passive_time); - WL_SCAN("home_time=%d\n", iscan->iscan_ex_params_p->params.home_time); - WL_SCAN("scan_type=%d\n", iscan->iscan_ex_params_p->params.scan_type); - WL_SCAN("bss_type=%d\n", iscan->iscan_ex_params_p->params.bss_type); - - (void)dev_iw_iovar_setbuf(iscan->dev, "iscan", iscan->iscan_ex_params_p, - iscan->iscan_ex_param_size, iscan->ioctlbuf, - sizeof(iscan->ioctlbuf)); - - return err; -} - -static void wl_iw_timerfunc(unsigned long data) -{ - iscan_info_t *iscan = (iscan_info_t *) data; - if (iscan) { - iscan->timer_on = 0; - if (iscan->iscan_state != ISCAN_STATE_IDLE) { - WL_TRACE("timer trigger\n"); - up(&iscan->sysioc_sem); - } - } -} - -static void wl_iw_set_event_mask(struct net_device *dev) -{ - char eventmask[WL_EVENTING_MASK_LEN]; - char iovbuf[WL_EVENTING_MASK_LEN + 12]; - - dev_iw_iovar_getbuf(dev, "event_msgs", "", 0, iovbuf, sizeof(iovbuf)); - memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN); - setbit(eventmask, WLC_E_SCAN_COMPLETE); - dev_iw_iovar_setbuf(dev, "event_msgs", eventmask, WL_EVENTING_MASK_LEN, - iovbuf, sizeof(iovbuf)); -} - -static u32 wl_iw_iscan_get(iscan_info_t *iscan) -{ - iscan_buf_t *buf; - iscan_buf_t *ptr; - wl_iscan_results_t *list_buf; - wl_iscan_results_t list; - wl_scan_results_t *results; - u32 status; - int res = 0; - - MUTEX_LOCK_WL_SCAN_SET(); - if (iscan->list_cur) { - buf = iscan->list_cur; - iscan->list_cur = buf->next; - } else { - buf = kmalloc(sizeof(iscan_buf_t), GFP_KERNEL); - if (!buf) { - WL_ERROR("%s can't alloc iscan_buf_t : going to abort current iscan\n", - __func__); - MUTEX_UNLOCK_WL_SCAN_SET(); - return WL_SCAN_RESULTS_NO_MEM; - } - buf->next = NULL; - if (!iscan->list_hdr) - iscan->list_hdr = buf; - else { - ptr = iscan->list_hdr; - while (ptr->next) { - ptr = ptr->next; - } - ptr->next = buf; - } - } - memset(buf->iscan_buf, 0, WLC_IW_ISCAN_MAXLEN); - list_buf = (wl_iscan_results_t *) buf->iscan_buf; - results = &list_buf->results; - results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE; - results->version = 0; - results->count = 0; - - memset(&list, 0, sizeof(list)); - list.results.buflen = cpu_to_le32(WLC_IW_ISCAN_MAXLEN); - res = dev_iw_iovar_getbuf(iscan->dev, - "iscanresults", - &list, - WL_ISCAN_RESULTS_FIXED_SIZE, - buf->iscan_buf, WLC_IW_ISCAN_MAXLEN); - if (res == 0) { - results->buflen = le32_to_cpu(results->buflen); - results->version = le32_to_cpu(results->version); - results->count = le32_to_cpu(results->count); - WL_TRACE("results->count = %d\n", results->count); - WL_TRACE("results->buflen = %d\n", results->buflen); - status = le32_to_cpu(list_buf->status); - } else { - WL_ERROR("%s returns error %d\n", __func__, res); - status = WL_SCAN_RESULTS_NO_MEM; - } - MUTEX_UNLOCK_WL_SCAN_SET(); - return status; -} - -static void wl_iw_force_specific_scan(iscan_info_t *iscan) -{ - WL_TRACE("%s force Specific SCAN for %s\n", - __func__, g_specific_ssid.SSID); - rtnl_lock(); - - (void)dev_wlc_ioctl(iscan->dev, WLC_SCAN, &g_specific_ssid, - sizeof(g_specific_ssid)); - - rtnl_unlock(); -} - -static void wl_iw_send_scan_complete(iscan_info_t *iscan) -{ -#ifndef SANDGATE2G - union iwreq_data wrqu; - - memset(&wrqu, 0, sizeof(wrqu)); - - wireless_send_event(iscan->dev, SIOCGIWSCAN, &wrqu, NULL); - WL_TRACE("Send Event ISCAN complete\n"); -#endif -} - -static int _iscan_sysioc_thread(void *data) -{ - u32 status; - iscan_info_t *iscan = (iscan_info_t *) data; - static bool iscan_pass_abort; - - allow_signal(SIGTERM); - status = WL_SCAN_RESULTS_PARTIAL; - while (down_interruptible(&iscan->sysioc_sem) == 0) { - if (kthread_should_stop()) - break; - - if (iscan->timer_on) { - del_timer_sync(&iscan->timer); - iscan->timer_on = 0; - } - rtnl_lock(); - status = wl_iw_iscan_get(iscan); - rtnl_unlock(); - if (g_scan_specified_ssid && (iscan_pass_abort == true)) { - WL_TRACE("%s Get results from specific scan status = %d\n", - __func__, status); - wl_iw_send_scan_complete(iscan); - iscan_pass_abort = false; - status = -1; - } - - switch (status) { - case WL_SCAN_RESULTS_PARTIAL: - WL_TRACE("iscanresults incomplete\n"); - rtnl_lock(); - wl_iw_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE); - rtnl_unlock(); - mod_timer(&iscan->timer, - jiffies + iscan->timer_ms * HZ / 1000); - iscan->timer_on = 1; - break; - case WL_SCAN_RESULTS_SUCCESS: - WL_TRACE("iscanresults complete\n"); - iscan->iscan_state = ISCAN_STATE_IDLE; - wl_iw_send_scan_complete(iscan); - break; - case WL_SCAN_RESULTS_PENDING: - WL_TRACE("iscanresults pending\n"); - mod_timer(&iscan->timer, - jiffies + iscan->timer_ms * HZ / 1000); - iscan->timer_on = 1; - break; - case WL_SCAN_RESULTS_ABORTED: - WL_TRACE("iscanresults aborted\n"); - iscan->iscan_state = ISCAN_STATE_IDLE; - if (g_scan_specified_ssid == 0) - wl_iw_send_scan_complete(iscan); - else { - iscan_pass_abort = true; - wl_iw_force_specific_scan(iscan); - } - break; - case WL_SCAN_RESULTS_NO_MEM: - WL_TRACE("iscanresults can't alloc memory: skip\n"); - iscan->iscan_state = ISCAN_STATE_IDLE; - break; - default: - WL_TRACE("iscanresults returned unknown status %d\n", - status); - break; - } - } - - if (iscan->timer_on) { - del_timer_sync(&iscan->timer); - iscan->timer_on = 0; - } - return 0; -} -#endif /* WL_IW_USE_ISCAN */ - -static int -wl_iw_set_scan(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int error; - WL_TRACE("\n:%s dev:%s: SIOCSIWSCAN : SCAN\n", __func__, dev->name); - - g_set_essid_before_scan = false; -#if defined(CSCAN) - WL_ERROR("%s: Scan from SIOCGIWSCAN not supported\n", __func__); - return -EINVAL; -#endif - - if (g_onoff == G_WLAN_SET_OFF) - return 0; - - memset(&g_specific_ssid, 0, sizeof(g_specific_ssid)); -#ifndef WL_IW_USE_ISCAN - g_scan_specified_ssid = 0; -#endif - -#if WIRELESS_EXT > 17 - if (wrqu->data.length == sizeof(struct iw_scan_req)) { - if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { - struct iw_scan_req *req = (struct iw_scan_req *)extra; - if (g_scan_specified_ssid) { - WL_TRACE("%s Specific SCAN is not done ignore scan for = %s\n", - __func__, req->essid); - return -EBUSY; - } else { - g_specific_ssid.SSID_len = min_t(size_t, - sizeof(g_specific_ssid.SSID), - req->essid_len); - memcpy(g_specific_ssid.SSID, req->essid, - g_specific_ssid.SSID_len); - g_specific_ssid.SSID_len = - cpu_to_le32(g_specific_ssid.SSID_len); - g_scan_specified_ssid = 1; - WL_TRACE("### Specific scan ssid=%s len=%d\n", - g_specific_ssid.SSID, - g_specific_ssid.SSID_len); - } - } - } -#endif /* WIRELESS_EXT > 17 */ - error = dev_wlc_ioctl(dev, WLC_SCAN, &g_specific_ssid, - sizeof(g_specific_ssid)); - if (error) { - WL_TRACE("#### Set SCAN for %s failed with %d\n", - g_specific_ssid.SSID, error); - g_scan_specified_ssid = 0; - return -EBUSY; - } - - return 0; -} - -#ifdef WL_IW_USE_ISCAN -int wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag) -{ - wlc_ssid_t ssid; - iscan_info_t *iscan = g_iscan; - - if (flag) - rtnl_lock(); - - wl_iw_set_event_mask(dev); - - WL_TRACE("+++: Set Broadcast ISCAN\n"); - memset(&ssid, 0, sizeof(ssid)); - - iscan->list_cur = iscan->list_hdr; - iscan->iscan_state = ISCAN_STATE_SCANING; - - memset(&iscan->iscan_ex_params_p->params, 0, - iscan->iscan_ex_param_size); - wl_iw_iscan_prep(&iscan->iscan_ex_params_p->params, &ssid); - wl_iw_iscan(iscan, &ssid, WL_SCAN_ACTION_START); - - if (flag) - rtnl_unlock(); - - mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); - - iscan->timer_on = 1; - - return 0; -} - -static int -wl_iw_iscan_set_scan(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - wlc_ssid_t ssid; - iscan_info_t *iscan = g_iscan; - - WL_TRACE("%s: SIOCSIWSCAN : ISCAN\n", dev->name); - -#if defined(CSCAN) - WL_ERROR("%s: Scan from SIOCGIWSCAN not supported\n", __func__); - return -EINVAL; -#endif - - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE("%s: driver is not up yet after START\n", __func__); - return 0; - } -#ifdef PNO_SUPPORT - if (dhd_dev_get_pno_status(dev)) { - WL_ERROR("%s: Scan called when PNO is active\n", __func__); - } -#endif - - if ((!iscan) || (!iscan->sysioc_tsk)) - return wl_iw_set_scan(dev, info, wrqu, extra); - - if (g_scan_specified_ssid) { - WL_TRACE("%s Specific SCAN already running ignoring BC scan\n", - __func__); - return -EBUSY; - } - - memset(&ssid, 0, sizeof(ssid)); - -#if WIRELESS_EXT > 17 - if (wrqu->data.length == sizeof(struct iw_scan_req)) { - if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { - struct iw_scan_req *req = (struct iw_scan_req *)extra; - ssid.SSID_len = min_t(size_t, sizeof(ssid.SSID), - req->essid_len); - memcpy(ssid.SSID, req->essid, ssid.SSID_len); - ssid.SSID_len = cpu_to_le32(ssid.SSID_len); - } else { - g_scan_specified_ssid = 0; - - if (iscan->iscan_state == ISCAN_STATE_SCANING) { - WL_TRACE("%s ISCAN already in progress\n", - __func__); - return 0; - } - } - } -#endif /* WIRELESS_EXT > 17 */ - wl_iw_iscan_set_scan_broadcast_prep(dev, 0); - - return 0; -} -#endif /* WL_IW_USE_ISCAN */ - -#if WIRELESS_EXT > 17 -static bool ie_is_wpa_ie(u8 **wpaie, u8 **tlvs, int *tlvs_len) -{ - - u8 *ie = *wpaie; - - if ((ie[1] >= 6) && - !memcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x01"), 4)) { - return true; - } - - ie += ie[1] + 2; - *tlvs_len -= (int)(ie - *tlvs); - *tlvs = ie; - return false; -} - -static bool ie_is_wps_ie(u8 **wpsie, u8 **tlvs, int *tlvs_len) -{ - - u8 *ie = *wpsie; - - if ((ie[1] >= 4) && - !memcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x04"), 4)) { - return true; - } - - ie += ie[1] + 2; - *tlvs_len -= (int)(ie - *tlvs); - *tlvs = ie; - return false; -} -#endif /* WIRELESS_EXT > 17 */ - -static int -wl_iw_handle_scanresults_ies(char **event_p, char *end, - struct iw_request_info *info, wl_bss_info_t *bi) -{ -#if WIRELESS_EXT > 17 - struct iw_event iwe; - char *event; - - event = *event_p; - if (bi->ie_length) { - struct brcmu_tlv *ie; - u8 *ptr = ((u8 *) bi) + sizeof(wl_bss_info_t); - int ptr_len = bi->ie_length; - - ie = brcmu_parse_tlvs(ptr, ptr_len, DOT11_MNG_RSN_ID); - if (ie) { - iwe.cmd = IWEVGENIE; - iwe.u.data.length = ie->len + 2; - event = - IWE_STREAM_ADD_POINT(info, event, end, &iwe, - (char *)ie); - } - ptr = ((u8 *) bi) + sizeof(wl_bss_info_t); - - while ((ie = brcmu_parse_tlvs( - ptr, ptr_len, DOT11_MNG_WPA_ID))) { - if (ie_is_wps_ie(((u8 **)&ie), &ptr, &ptr_len)) { - iwe.cmd = IWEVGENIE; - iwe.u.data.length = ie->len + 2; - event = - IWE_STREAM_ADD_POINT(info, event, end, &iwe, - (char *)ie); - break; - } - } - - ptr = ((u8 *) bi) + sizeof(wl_bss_info_t); - ptr_len = bi->ie_length; - while ((ie = brcmu_parse_tlvs( - ptr, ptr_len, DOT11_MNG_WPA_ID))) { - if (ie_is_wpa_ie(((u8 **)&ie), &ptr, &ptr_len)) { - iwe.cmd = IWEVGENIE; - iwe.u.data.length = ie->len + 2; - event = - IWE_STREAM_ADD_POINT(info, event, end, &iwe, - (char *)ie); - break; - } - } - - *event_p = event; - } -#endif /* WIRELESS_EXT > 17 */ - return 0; -} - -static uint -wl_iw_get_scan_prep(wl_scan_results_t *list, - struct iw_request_info *info, char *extra, short max_size) -{ - int i, j; - struct iw_event iwe; - wl_bss_info_t *bi = NULL; - char *event = extra, *end = extra + max_size - WE_ADD_EVENT_FIX, *value; - int ret = 0; - - ASSERT(list); - - for (i = 0; i < list->count && i < IW_MAX_AP; i++) { - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __func__, list->version); - return ret; - } - - bi = bi ? (wl_bss_info_t *)((unsigned long)bi + - le32_to_cpu(bi->length)) : list-> - bss_info; - - WL_TRACE("%s : %s\n", __func__, bi->SSID); - - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETH_ALEN); - event = - IWE_STREAM_ADD_EVENT(info, event, end, &iwe, - IW_EV_ADDR_LEN); - iwe.u.data.length = le32_to_cpu(bi->SSID_len); - iwe.cmd = SIOCGIWESSID; - iwe.u.data.flags = 1; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID); - - if (le16_to_cpu(bi->capability) & (WLAN_CAPABILITY_ESS | - WLAN_CAPABILITY_IBSS)) { - iwe.cmd = SIOCGIWMODE; - if (le16_to_cpu(bi->capability) & WLAN_CAPABILITY_ESS) - iwe.u.mode = IW_MODE_INFRA; - else - iwe.u.mode = IW_MODE_ADHOC; - event = - IWE_STREAM_ADD_EVENT(info, event, end, &iwe, - IW_EV_UINT_LEN); - } - - iwe.cmd = SIOCGIWFREQ; - - if (CHSPEC_CHANNEL(bi->chanspec) <= CH_MAX_2G_CHANNEL) - iwe.u.freq.m = ieee80211_dsss_chan_to_freq( - CHSPEC_CHANNEL(bi->chanspec)); - else - iwe.u.freq.m = ieee80211_ofdm_chan_to_freq( - WF_CHAN_FACTOR_5_G/2, - CHSPEC_CHANNEL(bi->chanspec)); - - iwe.u.freq.e = 6; - event = - IWE_STREAM_ADD_EVENT(info, event, end, &iwe, - IW_EV_FREQ_LEN); - - iwe.cmd = IWEVQUAL; - iwe.u.qual.qual = rssi_to_qual(le16_to_cpu(bi->RSSI)); - iwe.u.qual.level = 0x100 + le16_to_cpu(bi->RSSI); - iwe.u.qual.noise = 0x100 + bi->phy_noise; - event = - IWE_STREAM_ADD_EVENT(info, event, end, &iwe, - IW_EV_QUAL_LEN); - - wl_iw_handle_scanresults_ies(&event, end, info, bi); - - iwe.cmd = SIOCGIWENCODE; - if (le16_to_cpu(bi->capability) & WLAN_CAPABILITY_PRIVACY) - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe.u.data.flags = IW_ENCODE_DISABLED; - iwe.u.data.length = 0; - event = - IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)event); - - if (bi->rateset.count) { - if (((event - extra) + - IW_EV_LCP_LEN) <= (unsigned long)end) { - value = event + IW_EV_LCP_LEN; - iwe.cmd = SIOCGIWRATE; - iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = - 0; - for (j = 0; - j < bi->rateset.count - && j < IW_MAX_BITRATES; j++) { - iwe.u.bitrate.value = - (bi->rateset.rates[j] & 0x7f) * - 500000; - value = - IWE_STREAM_ADD_VALUE(info, event, - value, end, &iwe, - IW_EV_PARAM_LEN); - } - event = value; - } - } - } - - ret = event - extra; - if (ret < 0) { - WL_ERROR("==> Wrong size\n"); - ret = 0; - } - WL_TRACE("%s: size=%d bytes prepared\n", - __func__, (unsigned int)(event - extra)); - return (uint)ret; -} - -static int -wl_iw_get_scan(struct net_device *dev, - struct iw_request_info *info, struct iw_point *dwrq, char *extra) -{ - channel_info_t ci; - wl_scan_results_t *list_merge; - wl_scan_results_t *list = (wl_scan_results_t *) g_scan; - int error; - uint buflen_from_user = dwrq->length; - uint len = G_SCAN_RESULTS; - __u16 len_ret = 0; -#if defined(WL_IW_USE_ISCAN) - iscan_info_t *iscan = g_iscan; - iscan_buf_t *p_buf; -#endif - - WL_TRACE("%s: buflen_from_user %d:\n", dev->name, buflen_from_user); - - if (!extra) { - WL_TRACE("%s: wl_iw_get_scan return -EINVAL\n", dev->name); - return -EINVAL; - } - - error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci)); - if (error) - return error; - ci.scan_channel = le32_to_cpu(ci.scan_channel); - if (ci.scan_channel) - return -EAGAIN; - - if (g_scan_specified_ssid) { - list = kmalloc(len, GFP_KERNEL); - if (!list) { - WL_TRACE("%s: wl_iw_get_scan return -ENOMEM\n", - dev->name); - g_scan_specified_ssid = 0; - return -ENOMEM; - } - } - - memset(list, 0, len); - list->buflen = cpu_to_le32(len); - error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, len); - if (error) { - WL_ERROR("%s: %s : Scan_results ERROR %d\n", - dev->name, __func__, error); - dwrq->length = len; - if (g_scan_specified_ssid) { - g_scan_specified_ssid = 0; - kfree(list); - } - return 0; - } - list->buflen = le32_to_cpu(list->buflen); - list->version = le32_to_cpu(list->version); - list->count = le32_to_cpu(list->count); - - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __func__, list->version); - if (g_scan_specified_ssid) { - g_scan_specified_ssid = 0; - kfree(list); - } - return -EINVAL; - } - - if (g_scan_specified_ssid) { - WL_TRACE("%s: Specified scan APs in the list =%d\n", - __func__, list->count); - len_ret = - (__u16) wl_iw_get_scan_prep(list, info, extra, - buflen_from_user); - kfree(list); - -#if defined(WL_IW_USE_ISCAN) - p_buf = iscan->list_hdr; - while (p_buf != iscan->list_cur) { - list_merge = - &((wl_iscan_results_t *) p_buf->iscan_buf)->results; - WL_TRACE("%s: Bcast APs list=%d\n", - __func__, list_merge->count); - if (list_merge->count > 0) - len_ret += - (__u16) wl_iw_get_scan_prep(list_merge, - info, extra + len_ret, - buflen_from_user - len_ret); - p_buf = p_buf->next; - } -#else - list_merge = (wl_scan_results_t *) g_scan; - WL_TRACE("%s: Bcast APs list=%d\n", - __func__, list_merge->count); - if (list_merge->count > 0) - len_ret += - (__u16) wl_iw_get_scan_prep(list_merge, info, - extra + len_ret, - buflen_from_user - - len_ret); -#endif /* defined(WL_IW_USE_ISCAN) */ - } else { - list = (wl_scan_results_t *) g_scan; - len_ret = - (__u16) wl_iw_get_scan_prep(list, info, extra, - buflen_from_user); - } - -#if defined(WL_IW_USE_ISCAN) - g_scan_specified_ssid = 0; -#endif - if ((len_ret + WE_ADD_EVENT_FIX) < buflen_from_user) - len = len_ret; - - dwrq->length = len; - dwrq->flags = 0; - - WL_TRACE("%s return to WE %d bytes APs=%d\n", - __func__, dwrq->length, list->count); - return 0; -} - -#if defined(WL_IW_USE_ISCAN) -static int -wl_iw_iscan_get_scan(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - wl_scan_results_t *list; - struct iw_event iwe; - wl_bss_info_t *bi = NULL; - int ii, j; - int apcnt; - char *event = extra, *end = extra + dwrq->length, *value; - iscan_info_t *iscan = g_iscan; - iscan_buf_t *p_buf; - u32 counter = 0; - u8 channel; - - WL_TRACE("%s %s buflen_from_user %d:\n", - dev->name, __func__, dwrq->length); - - if (!extra) { - WL_TRACE("%s: INVALID SIOCGIWSCAN GET bad parameter\n", - dev->name); - return -EINVAL; - } - - if ((!iscan) || (!iscan->sysioc_tsk)) { - WL_ERROR("%ssysioc_tsk\n", __func__); - return wl_iw_get_scan(dev, info, dwrq, extra); - } - - if (iscan->iscan_state == ISCAN_STATE_SCANING) { - WL_TRACE("%s: SIOCGIWSCAN GET still scanning\n", dev->name); - return -EAGAIN; - } - - WL_TRACE("%s: SIOCGIWSCAN GET broadcast results\n", dev->name); - apcnt = 0; - p_buf = iscan->list_hdr; - while (p_buf != iscan->list_cur) { - list = &((wl_iscan_results_t *) p_buf->iscan_buf)->results; - - counter += list->count; - - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __func__, list->version); - return -EINVAL; - } - - bi = NULL; - for (ii = 0; ii < list->count && apcnt < IW_MAX_AP; - apcnt++, ii++) { - bi = bi ? (wl_bss_info_t *)((unsigned long)bi + - le32_to_cpu(bi->length)) : - list->bss_info; - ASSERT(((unsigned long)bi + le32_to_cpu(bi->length)) <= - ((unsigned long)list + WLC_IW_ISCAN_MAXLEN)); - - if (event + ETH_ALEN + bi->SSID_len + - IW_EV_UINT_LEN + IW_EV_FREQ_LEN + IW_EV_QUAL_LEN >= - end) - return -E2BIG; - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, - ETH_ALEN); - event = - IWE_STREAM_ADD_EVENT(info, event, end, &iwe, - IW_EV_ADDR_LEN); - - iwe.u.data.length = le32_to_cpu(bi->SSID_len); - iwe.cmd = SIOCGIWESSID; - iwe.u.data.flags = 1; - event = - IWE_STREAM_ADD_POINT(info, event, end, &iwe, - bi->SSID); - - if (le16_to_cpu(bi->capability) & - (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) { - iwe.cmd = SIOCGIWMODE; - if (le16_to_cpu(bi->capability) & - WLAN_CAPABILITY_ESS) - iwe.u.mode = IW_MODE_INFRA; - else - iwe.u.mode = IW_MODE_ADHOC; - event = - IWE_STREAM_ADD_EVENT(info, event, end, &iwe, - IW_EV_UINT_LEN); - } - - iwe.cmd = SIOCGIWFREQ; - channel = - (bi->ctl_ch == - 0) ? CHSPEC_CHANNEL(bi->chanspec) : bi->ctl_ch; - - if (channel <= CH_MAX_2G_CHANNEL) - iwe.u.freq.m = - ieee80211_dsss_chan_to_freq(channel); - else - iwe.u.freq.m = ieee80211_ofdm_chan_to_freq( - WF_CHAN_FACTOR_5_G/2, - channel); - - iwe.u.freq.e = 6; - event = - IWE_STREAM_ADD_EVENT(info, event, end, &iwe, - IW_EV_FREQ_LEN); - - iwe.cmd = IWEVQUAL; - iwe.u.qual.qual = rssi_to_qual(le16_to_cpu(bi->RSSI)); - iwe.u.qual.level = 0x100 + le16_to_cpu(bi->RSSI); - iwe.u.qual.noise = 0x100 + bi->phy_noise; - event = - IWE_STREAM_ADD_EVENT(info, event, end, &iwe, - IW_EV_QUAL_LEN); - - wl_iw_handle_scanresults_ies(&event, end, info, bi); - - iwe.cmd = SIOCGIWENCODE; - if (le16_to_cpu(bi->capability) & - WLAN_CAPABILITY_PRIVACY) - iwe.u.data.flags = - IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe.u.data.flags = IW_ENCODE_DISABLED; - iwe.u.data.length = 0; - event = - IWE_STREAM_ADD_POINT(info, event, end, &iwe, - (char *)event); - - if (bi->rateset.count) { - if (event + IW_MAX_BITRATES * IW_EV_PARAM_LEN >= - end) - return -E2BIG; - - value = event + IW_EV_LCP_LEN; - iwe.cmd = SIOCGIWRATE; - iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = - 0; - for (j = 0; - j < bi->rateset.count - && j < IW_MAX_BITRATES; j++) { - iwe.u.bitrate.value = - (bi->rateset.rates[j] & 0x7f) * - 500000; - value = - IWE_STREAM_ADD_VALUE(info, event, - value, end, - &iwe, - IW_EV_PARAM_LEN); - } - event = value; - } - } - p_buf = p_buf->next; - } - - dwrq->length = event - extra; - dwrq->flags = 0; - - WL_TRACE("%s return to WE %d bytes APs=%d\n", - __func__, dwrq->length, counter); - - if (!dwrq->length) - return -EAGAIN; - - return 0; -} -#endif /* defined(WL_IW_USE_ISCAN) */ - -static int -wl_iw_set_essid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - int error; - wl_join_params_t join_params; - int join_params_size; - - WL_TRACE("%s: SIOCSIWESSID\n", dev->name); - - if (g_set_essid_before_scan) - return -EAGAIN; - - memset(&g_ssid, 0, sizeof(g_ssid)); - - CHECK_EXTRA_FOR_NULL(extra); - - if (dwrq->length && extra) { -#if WIRELESS_EXT > 20 - g_ssid.SSID_len = min_t(size_t, sizeof(g_ssid.SSID), - dwrq->length); -#else - g_ssid.SSID_len = min_t(size_t, sizeof(g_ssid.SSID), - dwrq->length - 1); -#endif - memcpy(g_ssid.SSID, extra, g_ssid.SSID_len); - } else { - g_ssid.SSID_len = 0; - } - g_ssid.SSID_len = cpu_to_le32(g_ssid.SSID_len); - - memset(&join_params, 0, sizeof(join_params)); - join_params_size = sizeof(join_params.ssid); - - memcpy(&join_params.ssid.SSID, g_ssid.SSID, g_ssid.SSID_len); - join_params.ssid.SSID_len = cpu_to_le32(g_ssid.SSID_len); - memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN); - - wl_iw_ch_to_chanspec(g_wl_iw_params.target_channel, &join_params, - &join_params_size); - - error = dev_wlc_ioctl(dev, WLC_SET_SSID, &join_params, - join_params_size); - if (error) - WL_ERROR("Invalid ioctl data=%d\n", error); - - if (g_ssid.SSID_len) { - WL_TRACE("%s: join SSID=%s ch=%d\n", - __func__, g_ssid.SSID, g_wl_iw_params.target_channel); - } - return 0; -} - -static int -wl_iw_get_essid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - wlc_ssid_t ssid; - int error; - - WL_TRACE("%s: SIOCGIWESSID\n", dev->name); - - if (!extra) - return -EINVAL; - - error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)); - if (error) { - WL_ERROR("Error getting the SSID\n"); - return error; - } - - ssid.SSID_len = le32_to_cpu(ssid.SSID_len); - - memcpy(extra, ssid.SSID, ssid.SSID_len); - - dwrq->length = ssid.SSID_len; - - dwrq->flags = 1; - - return 0; -} - -static int -wl_iw_set_nick(struct net_device *dev, - struct iw_request_info *info, struct iw_point *dwrq, char *extra) -{ - wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev); - - WL_TRACE("%s: SIOCSIWNICKN\n", dev->name); - - if (!extra) - return -EINVAL; - - if (dwrq->length > sizeof(iw->nickname)) - return -E2BIG; - - memcpy(iw->nickname, extra, dwrq->length); - iw->nickname[dwrq->length - 1] = '\0'; - - return 0; -} - -static int -wl_iw_get_nick(struct net_device *dev, - struct iw_request_info *info, struct iw_point *dwrq, char *extra) -{ - wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev); - - WL_TRACE("%s: SIOCGIWNICKN\n", dev->name); - - if (!extra) - return -EINVAL; - - strcpy(extra, iw->nickname); - dwrq->length = strlen(extra) + 1; - - return 0; -} - -static int -wl_iw_set_rate(struct net_device *dev, - struct iw_request_info *info, struct iw_param *vwrq, char *extra) -{ - wl_rateset_t rateset; - int error, rate, i, error_bg, error_a; - - WL_TRACE("%s: SIOCSIWRATE\n", dev->name); - - error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, - sizeof(rateset)); - if (error) - return error; - - rateset.count = le32_to_cpu(rateset.count); - - if (vwrq->value < 0) - rate = rateset.rates[rateset.count - 1] & 0x7f; - else if (vwrq->value < rateset.count) - rate = rateset.rates[vwrq->value] & 0x7f; - else - rate = vwrq->value / 500000; - - if (vwrq->fixed) { - error_bg = dev_wlc_intvar_set(dev, "bg_rate", rate); - error_a = dev_wlc_intvar_set(dev, "a_rate", rate); - - if (error_bg && error_a) - return error_bg | error_a; - } else { - error_bg = dev_wlc_intvar_set(dev, "bg_rate", 0); - error_a = dev_wlc_intvar_set(dev, "a_rate", 0); - - if (error_bg && error_a) - return error_bg | error_a; - - for (i = 0; i < rateset.count; i++) - if ((rateset.rates[i] & 0x7f) > rate) - break; - rateset.count = cpu_to_le32(i); - - error = dev_wlc_ioctl(dev, WLC_SET_RATESET, &rateset, - sizeof(rateset)); - if (error) - return error; - } - - return 0; -} - -static int -wl_iw_get_rate(struct net_device *dev, - struct iw_request_info *info, struct iw_param *vwrq, char *extra) -{ - int error, rate; - - WL_TRACE("%s: SIOCGIWRATE\n", dev->name); - - error = dev_wlc_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate)); - if (error) - return error; - rate = le32_to_cpu(rate); - vwrq->value = rate * 500000; - - return 0; -} - -static int -wl_iw_set_rts(struct net_device *dev, - struct iw_request_info *info, struct iw_param *vwrq, char *extra) -{ - int error, rts; - - WL_TRACE("%s: SIOCSIWRTS\n", dev->name); - - if (vwrq->disabled) - rts = DOT11_DEFAULT_RTS_LEN; - else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_RTS_LEN) - return -EINVAL; - else - rts = vwrq->value; - - error = dev_wlc_intvar_set(dev, "rtsthresh", rts); - if (error) - return error; - - return 0; -} - -static int -wl_iw_get_rts(struct net_device *dev, - struct iw_request_info *info, struct iw_param *vwrq, char *extra) -{ - int error, rts; - - WL_TRACE("%s: SIOCGIWRTS\n", dev->name); - - error = dev_wlc_intvar_get(dev, "rtsthresh", &rts); - if (error) - return error; - - vwrq->value = rts; - vwrq->disabled = (rts >= DOT11_DEFAULT_RTS_LEN); - vwrq->fixed = 1; - - return 0; -} - -static int -wl_iw_set_frag(struct net_device *dev, - struct iw_request_info *info, struct iw_param *vwrq, char *extra) -{ - int error, frag; - - WL_TRACE("%s: SIOCSIWFRAG\n", dev->name); - - if (vwrq->disabled) - frag = DOT11_DEFAULT_FRAG_LEN; - else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_FRAG_LEN) - return -EINVAL; - else - frag = vwrq->value; - - error = dev_wlc_intvar_set(dev, "fragthresh", frag); - if (error) - return error; - - return 0; -} - -static int -wl_iw_get_frag(struct net_device *dev, - struct iw_request_info *info, struct iw_param *vwrq, char *extra) -{ - int error, fragthreshold; - - WL_TRACE("%s: SIOCGIWFRAG\n", dev->name); - - error = dev_wlc_intvar_get(dev, "fragthresh", &fragthreshold); - if (error) - return error; - - vwrq->value = fragthreshold; - vwrq->disabled = (fragthreshold >= DOT11_DEFAULT_FRAG_LEN); - vwrq->fixed = 1; - - return 0; -} - -static int -wl_iw_set_txpow(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - int error, disable; - u16 txpwrmw; - WL_TRACE("%s: SIOCSIWTXPOW\n", dev->name); - - disable = vwrq->disabled ? WL_RADIO_SW_DISABLE : 0; - disable += WL_RADIO_SW_DISABLE << 16; - - disable = cpu_to_le32(disable); - error = dev_wlc_ioctl(dev, WLC_SET_RADIO, &disable, sizeof(disable)); - if (error) - return error; - - if (disable & WL_RADIO_SW_DISABLE) - return 0; - - if (!(vwrq->flags & IW_TXPOW_MWATT)) - return -EINVAL; - - if (vwrq->value < 0) - return 0; - - if (vwrq->value > 0xffff) - txpwrmw = 0xffff; - else - txpwrmw = (u16) vwrq->value; - - error = dev_wlc_intvar_set(dev, "qtxpower", - (int)(brcmu_mw_to_qdbm(txpwrmw))); - return error; -} - -static int -wl_iw_get_txpow(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - int error, disable, txpwrdbm; - u8 result; - - WL_TRACE("%s: SIOCGIWTXPOW\n", dev->name); - - error = dev_wlc_ioctl(dev, WLC_GET_RADIO, &disable, sizeof(disable)); - if (error) - return error; - - error = dev_wlc_intvar_get(dev, "qtxpower", &txpwrdbm); - if (error) - return error; - - disable = le32_to_cpu(disable); - result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE); - vwrq->value = (s32) brcmu_qdbm_to_mw(result); - vwrq->fixed = 0; - vwrq->disabled = - (disable & (WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE)) ? 1 : 0; - vwrq->flags = IW_TXPOW_MWATT; - - return 0; -} - -#if WIRELESS_EXT > 10 -static int -wl_iw_set_retry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - int error, lrl, srl; - - WL_TRACE("%s: SIOCSIWRETRY\n", dev->name); - - if (vwrq->disabled || (vwrq->flags & IW_RETRY_LIFETIME)) - return -EINVAL; - - if (vwrq->flags & IW_RETRY_LIMIT) { - -#if WIRELESS_EXT > 20 - if ((vwrq->flags & IW_RETRY_LONG) - || (vwrq->flags & IW_RETRY_MAX) - || !((vwrq->flags & IW_RETRY_SHORT) - || (vwrq->flags & IW_RETRY_MIN))) { -#else - if ((vwrq->flags & IW_RETRY_MAX) - || !(vwrq->flags & IW_RETRY_MIN)) { -#endif - lrl = cpu_to_le32(vwrq->value); - error = dev_wlc_ioctl(dev, WLC_SET_LRL, &lrl, - sizeof(lrl)); - if (error) - return error; - } -#if WIRELESS_EXT > 20 - if ((vwrq->flags & IW_RETRY_SHORT) - || (vwrq->flags & IW_RETRY_MIN) - || !((vwrq->flags & IW_RETRY_LONG) - || (vwrq->flags & IW_RETRY_MAX))) { -#else - if ((vwrq->flags & IW_RETRY_MIN) - || !(vwrq->flags & IW_RETRY_MAX)) { -#endif - srl = cpu_to_le32(vwrq->value); - error = dev_wlc_ioctl(dev, WLC_SET_SRL, &srl, - sizeof(srl)); - if (error) - return error; - } - } - return 0; -} - -static int -wl_iw_get_retry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - int error, lrl, srl; - - WL_TRACE("%s: SIOCGIWRETRY\n", dev->name); - - vwrq->disabled = 0; - - if ((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) - return -EINVAL; - - error = dev_wlc_ioctl(dev, WLC_GET_LRL, &lrl, sizeof(lrl)); - if (error) - return error; - - error = dev_wlc_ioctl(dev, WLC_GET_SRL, &srl, sizeof(srl)); - if (error) - return error; - - lrl = le32_to_cpu(lrl); - srl = le32_to_cpu(srl); - - if (vwrq->flags & IW_RETRY_MAX) { - vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; - vwrq->value = lrl; - } else { - vwrq->flags = IW_RETRY_LIMIT; - vwrq->value = srl; - if (srl != lrl) - vwrq->flags |= IW_RETRY_MIN; - } - - return 0; -} -#endif /* WIRELESS_EXT > 10 */ - -static int -wl_iw_set_encode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - wl_wsec_key_t key; - int error, val, wsec; - - WL_TRACE("%s: SIOCSIWENCODE\n", dev->name); - - memset(&key, 0, sizeof(key)); - - if ((dwrq->flags & IW_ENCODE_INDEX) == 0) { - for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; - key.index++) { - val = cpu_to_le32(key.index); - error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, - sizeof(val)); - if (error) - return error; - val = le32_to_cpu(val); - if (val) - break; - } - if (key.index == DOT11_MAX_DEFAULT_KEYS) - key.index = 0; - } else { - key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; - if (key.index >= DOT11_MAX_DEFAULT_KEYS) - return -EINVAL; - } - - if (!extra || !dwrq->length || (dwrq->flags & IW_ENCODE_NOKEY)) { - val = cpu_to_le32(key.index); - error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, &val, - sizeof(val)); - if (error) - return error; - } else { - key.len = dwrq->length; - - if (dwrq->length > sizeof(key.data)) - return -EINVAL; - - memcpy(key.data, extra, dwrq->length); - - key.flags = WL_PRIMARY_KEY; - switch (key.len) { - case WLAN_KEY_LEN_WEP40: - key.algo = CRYPTO_ALGO_WEP1; - break; - case WLAN_KEY_LEN_WEP104: - key.algo = CRYPTO_ALGO_WEP128; - break; - case WLAN_KEY_LEN_TKIP: - key.algo = CRYPTO_ALGO_TKIP; - break; - case WLAN_KEY_LEN_AES_CMAC: - key.algo = CRYPTO_ALGO_AES_CCM; - break; - default: - return -EINVAL; - } - - swap_key_from_BE(&key); - error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); - if (error) - return error; - } - - val = (dwrq->flags & IW_ENCODE_DISABLED) ? 0 : WEP_ENABLED; - - error = dev_wlc_intvar_get(dev, "wsec", &wsec); - if (error) - return error; - - wsec &= ~(WEP_ENABLED); - wsec |= val; - - error = dev_wlc_intvar_set(dev, "wsec", wsec); - if (error) - return error; - - val = (dwrq->flags & IW_ENCODE_RESTRICTED) ? 1 : 0; - val = cpu_to_le32(val); - error = dev_wlc_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val)); - if (error) - return error; - - return 0; -} - -static int -wl_iw_get_encode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - wl_wsec_key_t key; - int error, val, wsec, auth; - - WL_TRACE("%s: SIOCGIWENCODE\n", dev->name); - - memset(&key, 0, sizeof(wl_wsec_key_t)); - - if ((dwrq->flags & IW_ENCODE_INDEX) == 0) { - for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; - key.index++) { - val = key.index; - error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, - sizeof(val)); - if (error) - return error; - val = le32_to_cpu(val); - if (val) - break; - } - } else - key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; - - if (key.index >= DOT11_MAX_DEFAULT_KEYS) - key.index = 0; - - error = dev_wlc_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec)); - if (error) - return error; - - error = dev_wlc_ioctl(dev, WLC_GET_AUTH, &auth, sizeof(auth)); - if (error) - return error; - - swap_key_to_BE(&key); - - wsec = le32_to_cpu(wsec); - auth = le32_to_cpu(auth); - dwrq->length = min_t(u16, WLAN_MAX_KEY_LEN, key.len); - - dwrq->flags = key.index + 1; - if (!(wsec & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))) - dwrq->flags |= IW_ENCODE_DISABLED; - - if (auth) - dwrq->flags |= IW_ENCODE_RESTRICTED; - - if (dwrq->length && extra) - memcpy(extra, key.data, dwrq->length); - - return 0; -} - -static int -wl_iw_set_power(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - int error, pm; - - WL_TRACE("%s: SIOCSIWPOWER\n", dev->name); - - pm = vwrq->disabled ? PM_OFF : PM_MAX; - - pm = cpu_to_le32(pm); - error = dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)); - if (error) - return error; - - return 0; -} - -static int -wl_iw_get_power(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - int error, pm; - - WL_TRACE("%s: SIOCGIWPOWER\n", dev->name); - - error = dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm)); - if (error) - return error; - - pm = le32_to_cpu(pm); - vwrq->disabled = pm ? 0 : 1; - vwrq->flags = IW_POWER_ALL_R; - - return 0; -} - -#if WIRELESS_EXT > 17 -static int -wl_iw_set_wpaie(struct net_device *dev, - struct iw_request_info *info, struct iw_point *iwp, char *extra) -{ - - WL_TRACE("%s: SIOCSIWGENIE\n", dev->name); - - CHECK_EXTRA_FOR_NULL(extra); - - dev_wlc_bufvar_set(dev, "wpaie", extra, iwp->length); - - return 0; -} - -static int -wl_iw_get_wpaie(struct net_device *dev, - struct iw_request_info *info, struct iw_point *iwp, char *extra) -{ - WL_TRACE("%s: SIOCGIWGENIE\n", dev->name); - iwp->length = 64; - dev_wlc_bufvar_get(dev, "wpaie", extra, iwp->length); - return 0; -} - -static int -wl_iw_set_encodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - wl_wsec_key_t key; - int error; - struct iw_encode_ext *iwe; - - WL_TRACE("%s: SIOCSIWENCODEEXT\n", dev->name); - - CHECK_EXTRA_FOR_NULL(extra); - - memset(&key, 0, sizeof(key)); - iwe = (struct iw_encode_ext *)extra; - - if (dwrq->flags & IW_ENCODE_DISABLED) { - - } - - key.index = 0; - if (dwrq->flags & IW_ENCODE_INDEX) - key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; - - key.len = iwe->key_len; - - if (!is_multicast_ether_addr(iwe->addr.sa_data)) - memcpy(&key.ea, &iwe->addr.sa_data, ETH_ALEN); - - if (key.len == 0) { - if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - WL_WSEC("Changing the the primary Key to %d\n", - key.index); - key.index = cpu_to_le32(key.index); - error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, - &key.index, sizeof(key.index)); - if (error) - return error; - } else { - swap_key_from_BE(&key); - dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); - } - } else { - if (iwe->key_len > sizeof(key.data)) - return -EINVAL; - - WL_WSEC("Setting the key index %d\n", key.index); - if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - WL_WSEC("key is a Primary Key\n"); - key.flags = WL_PRIMARY_KEY; - } - - memcpy(key.data, iwe->key, iwe->key_len); - - if (iwe->alg == IW_ENCODE_ALG_TKIP) { - u8 keybuf[8]; - memcpy(keybuf, &key.data[24], sizeof(keybuf)); - memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); - memcpy(&key.data[16], keybuf, sizeof(keybuf)); - } - - if (iwe->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { - unsigned char *ivptr; - ivptr = (unsigned char *) iwe->rx_seq; - key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) | - (ivptr[3] << 8) | ivptr[2]; - key.rxiv.lo = (ivptr[1] << 8) | ivptr[0]; - key.iv_initialized = true; - } - - switch (iwe->alg) { - case IW_ENCODE_ALG_NONE: - key.algo = CRYPTO_ALGO_OFF; - break; - case IW_ENCODE_ALG_WEP: - if (iwe->key_len == WLAN_KEY_LEN_WEP40) - key.algo = CRYPTO_ALGO_WEP1; - else - key.algo = CRYPTO_ALGO_WEP128; - break; - case IW_ENCODE_ALG_TKIP: - key.algo = CRYPTO_ALGO_TKIP; - break; - case IW_ENCODE_ALG_CCMP: - key.algo = CRYPTO_ALGO_AES_CCM; - break; - default: - break; - } - swap_key_from_BE(&key); - - dhd_wait_pend8021x(dev); - - error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); - if (error) - return error; - } - return 0; -} - -#if WIRELESS_EXT > 17 -struct { - pmkid_list_t pmkids; - pmkid_t foo[MAXPMKID - 1]; -} pmkid_list; - -static int -wl_iw_set_pmksa(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - struct iw_pmksa *iwpmksa; - uint i; - int ret = 0; - - WL_WSEC("%s: SIOCSIWPMKSA\n", dev->name); - - CHECK_EXTRA_FOR_NULL(extra); - - iwpmksa = (struct iw_pmksa *)extra; - - if (iwpmksa->cmd == IW_PMKSA_FLUSH) { - WL_WSEC("wl_iw_set_pmksa - IW_PMKSA_FLUSH\n"); - memset((char *)&pmkid_list, 0, sizeof(pmkid_list)); - } - - else if (iwpmksa->cmd == IW_PMKSA_REMOVE) { - { - pmkid_list_t pmkid, *pmkidptr; - uint j; - pmkidptr = &pmkid; - - memcpy(&pmkidptr->pmkid[0].BSSID, - &iwpmksa->bssid.sa_data[0], - ETH_ALEN); - memcpy(&pmkidptr->pmkid[0].PMKID, - &iwpmksa->pmkid[0], - WLAN_PMKID_LEN); - - WL_WSEC("wl_iw_set_pmksa:IW_PMKSA_REMOVE:PMKID: " - "%pM = ", &pmkidptr->pmkid[0].BSSID); - for (j = 0; j < WLAN_PMKID_LEN; j++) - WL_WSEC("%02x ", pmkidptr->pmkid[0].PMKID[j]); - WL_WSEC("\n"); - } - - for (i = 0; i < pmkid_list.pmkids.npmkid; i++) - if (!memcmp - (&iwpmksa->bssid.sa_data[0], - &pmkid_list.pmkids.pmkid[i].BSSID, ETH_ALEN)) - break; - - if ((pmkid_list.pmkids.npmkid > 0) - && (i < pmkid_list.pmkids.npmkid)) { - memset(&pmkid_list.pmkids.pmkid[i], 0, sizeof(pmkid_t)); - for (; i < (pmkid_list.pmkids.npmkid - 1); i++) { - memcpy(&pmkid_list.pmkids.pmkid[i].BSSID, - &pmkid_list.pmkids.pmkid[i + 1].BSSID, - ETH_ALEN); - memcpy(&pmkid_list.pmkids.pmkid[i].PMKID, - &pmkid_list.pmkids.pmkid[i + 1].PMKID, - WLAN_PMKID_LEN); - } - pmkid_list.pmkids.npmkid--; - } else - ret = -EINVAL; - } - - else if (iwpmksa->cmd == IW_PMKSA_ADD) { - for (i = 0; i < pmkid_list.pmkids.npmkid; i++) - if (!memcmp - (&iwpmksa->bssid.sa_data[0], - &pmkid_list.pmkids.pmkid[i].BSSID, ETH_ALEN)) - break; - if (i < MAXPMKID) { - memcpy(&pmkid_list.pmkids.pmkid[i].BSSID, - &iwpmksa->bssid.sa_data[0], - ETH_ALEN); - memcpy(&pmkid_list.pmkids.pmkid[i].PMKID, - &iwpmksa->pmkid[0], - WLAN_PMKID_LEN); - if (i == pmkid_list.pmkids.npmkid) - pmkid_list.pmkids.npmkid++; - } else - ret = -EINVAL; - { - uint j; - uint k; - k = pmkid_list.pmkids.npmkid; - WL_WSEC("wl_iw_set_pmksa,IW_PMKSA_ADD - PMKID: %pM = ", - &pmkid_list.pmkids.pmkid[k].BSSID); - for (j = 0; j < WLAN_PMKID_LEN; j++) - WL_WSEC("%02x ", - pmkid_list.pmkids.pmkid[k].PMKID[j]); - WL_WSEC("\n"); - } - } - WL_WSEC("PRINTING pmkid LIST - No of elements %d\n", - pmkid_list.pmkids.npmkid); - for (i = 0; i < pmkid_list.pmkids.npmkid; i++) { - uint j; - WL_WSEC("PMKID[%d]: %pM = ", - i, &pmkid_list.pmkids.pmkid[i].BSSID); - for (j = 0; j < WLAN_PMKID_LEN; j++) - WL_WSEC("%02x ", pmkid_list.pmkids.pmkid[i].PMKID[j]); - WL_WSEC("\n"); - } - WL_WSEC("\n"); - - if (!ret) - ret = dev_wlc_bufvar_set(dev, "pmkid_info", (char *)&pmkid_list, - sizeof(pmkid_list)); - return ret; -} -#endif /* WIRELESS_EXT > 17 */ - -static int -wl_iw_get_encodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - WL_TRACE("%s: SIOCGIWENCODEEXT\n", dev->name); - return 0; -} - -static int -wl_iw_set_wpaauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - int error = 0; - int paramid; - int paramval; - int val = 0; - wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev); - - WL_TRACE("%s: SIOCSIWAUTH\n", dev->name); - - paramid = vwrq->flags & IW_AUTH_INDEX; - paramval = vwrq->value; - - WL_TRACE("%s: SIOCSIWAUTH, paramid = 0x%0x, paramval = 0x%0x\n", - dev->name, paramid, paramval); - - switch (paramid) { - case IW_AUTH_WPA_VERSION: - if (paramval & IW_AUTH_WPA_VERSION_DISABLED) - val = WPA_AUTH_DISABLED; - else if (paramval & (IW_AUTH_WPA_VERSION_WPA)) - val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED; - else if (paramval & IW_AUTH_WPA_VERSION_WPA2) - val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED; - WL_INFORM("%s: %d: setting wpa_auth to 0x%0x\n", - __func__, __LINE__, val); - error = dev_wlc_intvar_set(dev, "wpa_auth", val); - if (error) - return error; - break; - case IW_AUTH_CIPHER_PAIRWISE: - case IW_AUTH_CIPHER_GROUP: - if (paramval & (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104)) - val = WEP_ENABLED; - if (paramval & IW_AUTH_CIPHER_TKIP) - val = TKIP_ENABLED; - if (paramval & IW_AUTH_CIPHER_CCMP) - val = AES_ENABLED; - - if (paramid == IW_AUTH_CIPHER_PAIRWISE) { - iw->pwsec = val; - val |= iw->gwsec; - } else { - iw->gwsec = val; - val |= iw->pwsec; - } - - if (iw->privacy_invoked && !val) { - WL_WSEC("%s: %s: 'Privacy invoked' true but clearing wsec, assuming we're a WPS enrollee\n", - dev->name, __func__); - error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", - true); - if (error) { - WL_WSEC("Failed to set is_WPS_enrollee\n"); - return error; - } - } else if (val) { - error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", - false); - if (error) { - WL_WSEC("Failed to clear is_WPS_enrollee\n"); - return error; - } - } - - error = dev_wlc_intvar_set(dev, "wsec", val); - if (error) - return error; - - break; - - case IW_AUTH_KEY_MGMT: - error = dev_wlc_intvar_get(dev, "wpa_auth", &val); - if (error) - return error; - - if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) { - if (paramval & IW_AUTH_KEY_MGMT_PSK) - val = WPA_AUTH_PSK; - else - val = WPA_AUTH_UNSPECIFIED; - } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) { - if (paramval & IW_AUTH_KEY_MGMT_PSK) - val = WPA2_AUTH_PSK; - else - val = WPA2_AUTH_UNSPECIFIED; - } - WL_INFORM("%s: %d: setting wpa_auth to %d\n", - __func__, __LINE__, val); - error = dev_wlc_intvar_set(dev, "wpa_auth", val); - if (error) - return error; - - break; - case IW_AUTH_TKIP_COUNTERMEASURES: - dev_wlc_bufvar_set(dev, "tkip_countermeasures", - (char *)¶mval, 1); - break; - - case IW_AUTH_80211_AUTH_ALG: - WL_INFORM("Setting the D11auth %d\n", paramval); - if (paramval == IW_AUTH_ALG_OPEN_SYSTEM) - val = 0; - else if (paramval == IW_AUTH_ALG_SHARED_KEY) - val = 1; - else if (paramval == - (IW_AUTH_ALG_OPEN_SYSTEM | IW_AUTH_ALG_SHARED_KEY)) - val = 2; - else - error = 1; - if (!error) { - error = dev_wlc_intvar_set(dev, "auth", val); - if (error) - return error; - } - break; - - case IW_AUTH_WPA_ENABLED: - if (paramval == 0) { - iw->pwsec = 0; - iw->gwsec = 0; - error = dev_wlc_intvar_get(dev, "wsec", &val); - if (error) - return error; - if (val & (TKIP_ENABLED | AES_ENABLED)) { - val &= ~(TKIP_ENABLED | AES_ENABLED); - dev_wlc_intvar_set(dev, "wsec", val); - } - val = 0; - WL_INFORM("%s: %d: setting wpa_auth to %d\n", - __func__, __LINE__, val); - dev_wlc_intvar_set(dev, "wpa_auth", 0); - return error; - } - break; - - case IW_AUTH_DROP_UNENCRYPTED: - dev_wlc_bufvar_set(dev, "wsec_restrict", (char *)¶mval, 1); - break; - - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - dev_wlc_bufvar_set(dev, "rx_unencrypted_eapol", - (char *)¶mval, 1); - break; - -#if WIRELESS_EXT > 17 - case IW_AUTH_ROAMING_CONTROL: - WL_INFORM("%s: IW_AUTH_ROAMING_CONTROL\n", __func__); - break; - case IW_AUTH_PRIVACY_INVOKED: - { - int wsec; - - if (paramval == 0) { - iw->privacy_invoked = false; - error = dev_wlc_intvar_set(dev, - "is_WPS_enrollee", false); - if (error) { - WL_WSEC("Failed to clear iovar is_WPS_enrollee\n"); - return error; - } - } else { - iw->privacy_invoked = true; - error = dev_wlc_intvar_get(dev, "wsec", &wsec); - if (error) - return error; - - if (!(IW_WSEC_ENABLED(wsec))) { - error = dev_wlc_intvar_set(dev, - "is_WPS_enrollee", - true); - if (error) { - WL_WSEC("Failed to set iovar is_WPS_enrollee\n"); - return error; - } - } else { - error = dev_wlc_intvar_set(dev, - "is_WPS_enrollee", - false); - if (error) { - WL_WSEC("Failed to clear is_WPS_enrollee\n"); - return error; - } - } - } - break; - } -#endif /* WIRELESS_EXT > 17 */ - default: - break; - } - return 0; -} - -#define VAL_PSK(_val) (((_val) & WPA_AUTH_PSK) || ((_val) & WPA2_AUTH_PSK)) - -static int -wl_iw_get_wpaauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - int error; - int paramid; - int paramval = 0; - int val; - wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev); - - WL_TRACE("%s: SIOCGIWAUTH\n", dev->name); - - paramid = vwrq->flags & IW_AUTH_INDEX; - - switch (paramid) { - case IW_AUTH_WPA_VERSION: - error = dev_wlc_intvar_get(dev, "wpa_auth", &val); - if (error) - return error; - if (val & (WPA_AUTH_NONE | WPA_AUTH_DISABLED)) - paramval = IW_AUTH_WPA_VERSION_DISABLED; - else if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) - paramval = IW_AUTH_WPA_VERSION_WPA; - else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) - paramval = IW_AUTH_WPA_VERSION_WPA2; - break; - case IW_AUTH_CIPHER_PAIRWISE: - case IW_AUTH_CIPHER_GROUP: - if (paramid == IW_AUTH_CIPHER_PAIRWISE) - val = iw->pwsec; - else - val = iw->gwsec; - - paramval = 0; - if (val) { - if (val & WEP_ENABLED) - paramval |= - (IW_AUTH_CIPHER_WEP40 | - IW_AUTH_CIPHER_WEP104); - if (val & TKIP_ENABLED) - paramval |= (IW_AUTH_CIPHER_TKIP); - if (val & AES_ENABLED) - paramval |= (IW_AUTH_CIPHER_CCMP); - } else - paramval = IW_AUTH_CIPHER_NONE; - break; - case IW_AUTH_KEY_MGMT: - error = dev_wlc_intvar_get(dev, "wpa_auth", &val); - if (error) - return error; - if (VAL_PSK(val)) - paramval = IW_AUTH_KEY_MGMT_PSK; - else - paramval = IW_AUTH_KEY_MGMT_802_1X; - - break; - case IW_AUTH_TKIP_COUNTERMEASURES: - dev_wlc_bufvar_get(dev, "tkip_countermeasures", - (char *)¶mval, 1); - break; - - case IW_AUTH_DROP_UNENCRYPTED: - dev_wlc_bufvar_get(dev, "wsec_restrict", (char *)¶mval, 1); - break; - - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - dev_wlc_bufvar_get(dev, "rx_unencrypted_eapol", - (char *)¶mval, 1); - break; - - case IW_AUTH_80211_AUTH_ALG: - error = dev_wlc_intvar_get(dev, "auth", &val); - if (error) - return error; - if (!val) - paramval = IW_AUTH_ALG_OPEN_SYSTEM; - else - paramval = IW_AUTH_ALG_SHARED_KEY; - break; - case IW_AUTH_WPA_ENABLED: - error = dev_wlc_intvar_get(dev, "wpa_auth", &val); - if (error) - return error; - if (val) - paramval = true; - else - paramval = false; - break; -#if WIRELESS_EXT > 17 - case IW_AUTH_ROAMING_CONTROL: - WL_ERROR("%s: IW_AUTH_ROAMING_CONTROL\n", __func__); - break; - case IW_AUTH_PRIVACY_INVOKED: - paramval = iw->privacy_invoked; - break; - -#endif - } - vwrq->value = paramval; - return 0; -} -#endif /* WIRELESS_EXT > 17 */ - -static const iw_handler wl_iw_handler[] = { - (iw_handler) wl_iw_config_commit, - (iw_handler) wl_iw_get_name, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_freq, - (iw_handler) wl_iw_get_freq, - (iw_handler) wl_iw_set_mode, - (iw_handler) wl_iw_get_mode, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_get_range, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_spy, - (iw_handler) wl_iw_get_spy, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_wap, - (iw_handler) wl_iw_get_wap, -#if WIRELESS_EXT > 17 - (iw_handler) wl_iw_mlme, -#else - (iw_handler) NULL, -#endif -#if defined(WL_IW_USE_ISCAN) - (iw_handler) wl_iw_iscan_get_aplist, -#else - (iw_handler) wl_iw_get_aplist, -#endif -#if WIRELESS_EXT > 13 -#if defined(WL_IW_USE_ISCAN) - (iw_handler) wl_iw_iscan_set_scan, - (iw_handler) wl_iw_iscan_get_scan, -#else - (iw_handler) wl_iw_set_scan, - (iw_handler) wl_iw_get_scan, -#endif -#else - (iw_handler) NULL, - (iw_handler) NULL, -#endif /* WIRELESS_EXT > 13 */ - (iw_handler) wl_iw_set_essid, - (iw_handler) wl_iw_get_essid, - (iw_handler) wl_iw_set_nick, - (iw_handler) wl_iw_get_nick, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_rate, - (iw_handler) wl_iw_get_rate, - (iw_handler) wl_iw_set_rts, - (iw_handler) wl_iw_get_rts, - (iw_handler) wl_iw_set_frag, - (iw_handler) wl_iw_get_frag, - (iw_handler) wl_iw_set_txpow, - (iw_handler) wl_iw_get_txpow, -#if WIRELESS_EXT > 10 - (iw_handler) wl_iw_set_retry, - (iw_handler) wl_iw_get_retry, -#endif - (iw_handler) wl_iw_set_encode, - (iw_handler) wl_iw_get_encode, - (iw_handler) wl_iw_set_power, - (iw_handler) wl_iw_get_power, -#if WIRELESS_EXT > 17 - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_wpaie, - (iw_handler) wl_iw_get_wpaie, - (iw_handler) wl_iw_set_wpaauth, - (iw_handler) wl_iw_get_wpaauth, - (iw_handler) wl_iw_set_encodeext, - (iw_handler) wl_iw_get_encodeext, - (iw_handler) wl_iw_set_pmksa, -#endif /* WIRELESS_EXT > 17 */ -}; - -#if WIRELESS_EXT > 12 - -const struct iw_handler_def wl_iw_handler_def = { - .num_standard = ARRAY_SIZE(wl_iw_handler), - .standard = (iw_handler *) wl_iw_handler, - .num_private = 0, - .num_private_args = 0, - .private = 0, - .private_args = 0, - -#if WIRELESS_EXT >= 19 - .get_wireless_stats = NULL, -#endif -}; -#endif /* WIRELESS_EXT > 12 */ - -int wl_iw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - struct iwreq *wrq = (struct iwreq *)rq; - struct iw_request_info info; - iw_handler handler; - char *extra = NULL; - int token_size = 1, max_tokens = 0, ret = 0; - - WL_TRACE("\n%s, cmd:%x alled via dhd->do_ioctl()entry point\n", - __func__, cmd); - if (cmd < SIOCIWFIRST || - IW_IOCTL_IDX(cmd) >= ARRAY_SIZE(wl_iw_handler)) { - WL_ERROR("%s: error in cmd=%x : out of range\n", - __func__, cmd); - return -EOPNOTSUPP; - } - - handler = wl_iw_handler[IW_IOCTL_IDX(cmd)]; - if (!handler) { - WL_ERROR("%s: error in cmd=%x : not supported\n", - __func__, cmd); - return -EOPNOTSUPP; - } - - switch (cmd) { - - case SIOCSIWESSID: - case SIOCGIWESSID: - case SIOCSIWNICKN: - case SIOCGIWNICKN: - max_tokens = IW_ESSID_MAX_SIZE + 1; - break; - - case SIOCSIWENCODE: - case SIOCGIWENCODE: -#if WIRELESS_EXT > 17 - case SIOCSIWENCODEEXT: - case SIOCGIWENCODEEXT: -#endif - max_tokens = wrq->u.data.length; - break; - - case SIOCGIWRANGE: - max_tokens = sizeof(struct iw_range) + 500; - break; - - case SIOCGIWAPLIST: - token_size = - sizeof(struct sockaddr) + sizeof(struct iw_quality); - max_tokens = IW_MAX_AP; - break; - -#if WIRELESS_EXT > 13 - case SIOCGIWSCAN: -#if defined(WL_IW_USE_ISCAN) - if (g_iscan) - max_tokens = wrq->u.data.length; - else -#endif - max_tokens = IW_SCAN_MAX_DATA; - break; -#endif /* WIRELESS_EXT > 13 */ - - case SIOCSIWSPY: - token_size = sizeof(struct sockaddr); - max_tokens = IW_MAX_SPY; - break; - - case SIOCGIWSPY: - token_size = - sizeof(struct sockaddr) + sizeof(struct iw_quality); - max_tokens = IW_MAX_SPY; - break; - -#if WIRELESS_EXT > 17 - case SIOCSIWPMKSA: - case SIOCSIWGENIE: -#endif - case SIOCSIWPRIV: - max_tokens = wrq->u.data.length; - break; - } - - if (max_tokens && wrq->u.data.pointer) { - if (wrq->u.data.length > max_tokens) { - WL_ERROR("%s: error in cmd=%x wrq->u.data.length=%d > max_tokens=%d\n", - __func__, cmd, wrq->u.data.length, max_tokens); - return -E2BIG; - } - extra = kmalloc(max_tokens * token_size, GFP_KERNEL); - if (!extra) - return -ENOMEM; - - if (copy_from_user - (extra, wrq->u.data.pointer, - wrq->u.data.length * token_size)) { - kfree(extra); - return -EFAULT; - } - } - - info.cmd = cmd; - info.flags = 0; - - ret = handler(dev, &info, &wrq->u, extra); - - if (extra) { - if (copy_to_user - (wrq->u.data.pointer, extra, - wrq->u.data.length * token_size)) { - kfree(extra); - return -EFAULT; - } - - kfree(extra); - } - - return ret; -} - -bool -wl_iw_conn_status_str(u32 event_type, u32 status, u32 reason, - char *stringBuf, uint buflen) -{ - typedef struct conn_fail_event_map_t { - u32 inEvent; - u32 inStatus; - u32 inReason; - const char *outName; - const char *outCause; - } conn_fail_event_map_t; - -#define WL_IW_DONT_CARE 9999 - const conn_fail_event_map_t event_map[] = { - {WLC_E_SET_SSID, WLC_E_STATUS_SUCCESS, WL_IW_DONT_CARE, - "Conn", "Success"}, - {WLC_E_SET_SSID, WLC_E_STATUS_NO_NETWORKS, WL_IW_DONT_CARE, - "Conn", "NoNetworks"}, - {WLC_E_SET_SSID, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE, - "Conn", "ConfigMismatch"}, - {WLC_E_PRUNE, WL_IW_DONT_CARE, WLC_E_PRUNE_ENCR_MISMATCH, - "Conn", "EncrypMismatch"}, - {WLC_E_PRUNE, WL_IW_DONT_CARE, WLC_E_RSN_MISMATCH, - "Conn", "RsnMismatch"}, - {WLC_E_AUTH, WLC_E_STATUS_TIMEOUT, WL_IW_DONT_CARE, - "Conn", "AuthTimeout"}, - {WLC_E_AUTH, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE, - "Conn", "AuthFail"}, - {WLC_E_AUTH, WLC_E_STATUS_NO_ACK, WL_IW_DONT_CARE, - "Conn", "AuthNoAck"}, - {WLC_E_REASSOC, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE, - "Conn", "ReassocFail"}, - {WLC_E_REASSOC, WLC_E_STATUS_TIMEOUT, WL_IW_DONT_CARE, - "Conn", "ReassocTimeout"}, - {WLC_E_REASSOC, WLC_E_STATUS_ABORT, WL_IW_DONT_CARE, - "Conn", "ReassocAbort"}, - {WLC_E_PSK_SUP, WLC_SUP_KEYED, WL_IW_DONT_CARE, - "Sup", "ConnSuccess"}, - {WLC_E_PSK_SUP, WL_IW_DONT_CARE, WL_IW_DONT_CARE, - "Sup", "WpaHandshakeFail"}, - {WLC_E_DEAUTH_IND, WL_IW_DONT_CARE, WL_IW_DONT_CARE, - "Conn", "Deauth"}, - {WLC_E_DISASSOC_IND, WL_IW_DONT_CARE, WL_IW_DONT_CARE, - "Conn", "DisassocInd"}, - {WLC_E_DISASSOC, WL_IW_DONT_CARE, WL_IW_DONT_CARE, - "Conn", "Disassoc"} - }; - - const char *name = ""; - const char *cause = NULL; - int i; - - for (i = 0; i < sizeof(event_map) / sizeof(event_map[0]); i++) { - const conn_fail_event_map_t *row = &event_map[i]; - if (row->inEvent == event_type && - (row->inStatus == status - || row->inStatus == WL_IW_DONT_CARE) - && (row->inReason == reason - || row->inReason == WL_IW_DONT_CARE)) { - name = row->outName; - cause = row->outCause; - break; - } - } - - if (cause) { - memset(stringBuf, 0, buflen); - snprintf(stringBuf, buflen, "%s %s %02d %02d", - name, cause, status, reason); - WL_INFORM("Connection status: %s\n", stringBuf); - return true; - } else { - return false; - } -} - -#if WIRELESS_EXT > 14 - -static bool -wl_iw_check_conn_fail(wl_event_msg_t *e, char *stringBuf, uint buflen) -{ - u32 event = be32_to_cpu(e->event_type); - u32 status = be32_to_cpu(e->status); - u32 reason = be32_to_cpu(e->reason); - - if (wl_iw_conn_status_str(event, status, reason, stringBuf, buflen)) { - return true; - } else - return false; -} -#endif - -#ifndef IW_CUSTOM_MAX -#define IW_CUSTOM_MAX 256 -#endif - -void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data) -{ -#if WIRELESS_EXT > 13 - union iwreq_data wrqu; - char extra[IW_CUSTOM_MAX + 1]; - int cmd = 0; - u32 event_type = be32_to_cpu(e->event_type); - u16 flags = be16_to_cpu(e->flags); - u32 datalen = be32_to_cpu(e->datalen); - u32 status = be32_to_cpu(e->status); - wl_iw_t *iw; - u32 toto; - memset(&wrqu, 0, sizeof(wrqu)); - memset(extra, 0, sizeof(extra)); - iw = 0; - - if (!dev) { - WL_ERROR("%s: dev is null\n", __func__); - return; - } - - iw = *(wl_iw_t **) netdev_priv(dev); - - WL_TRACE("%s: dev=%s event=%d\n", __func__, dev->name, event_type); - - switch (event_type) { - case WLC_E_TXFAIL: - cmd = IWEVTXDROP; - memcpy(wrqu.addr.sa_data, &e->addr, ETH_ALEN); - wrqu.addr.sa_family = ARPHRD_ETHER; - break; -#if WIRELESS_EXT > 14 - case WLC_E_JOIN: - case WLC_E_ASSOC_IND: - case WLC_E_REASSOC_IND: - memcpy(wrqu.addr.sa_data, &e->addr, ETH_ALEN); - wrqu.addr.sa_family = ARPHRD_ETHER; - cmd = IWEVREGISTERED; - break; - case WLC_E_DEAUTH_IND: - case WLC_E_DISASSOC_IND: - cmd = SIOCGIWAP; - memset(wrqu.addr.sa_data, 0, ETH_ALEN); - wrqu.addr.sa_family = ARPHRD_ETHER; - memset(&extra, 0, ETH_ALEN); - break; - case WLC_E_LINK: - case WLC_E_NDIS_LINK: - cmd = SIOCGIWAP; - if (!(flags & WLC_EVENT_MSG_LINK)) { - memset(wrqu.addr.sa_data, 0, ETH_ALEN); - memset(&extra, 0, ETH_ALEN); - } else { - memcpy(wrqu.addr.sa_data, &e->addr, ETH_ALEN); - WL_TRACE("Link UP\n"); - - } - wrqu.addr.sa_family = ARPHRD_ETHER; - break; - case WLC_E_ACTION_FRAME: - cmd = IWEVCUSTOM; - if (datalen + 1 <= sizeof(extra)) { - wrqu.data.length = datalen + 1; - extra[0] = WLC_E_ACTION_FRAME; - memcpy(&extra[1], data, datalen); - WL_TRACE("WLC_E_ACTION_FRAME len %d\n", - wrqu.data.length); - } - break; - - case WLC_E_ACTION_FRAME_COMPLETE: - cmd = IWEVCUSTOM; - memcpy(&toto, data, 4); - if (sizeof(status) + 1 <= sizeof(extra)) { - wrqu.data.length = sizeof(status) + 1; - extra[0] = WLC_E_ACTION_FRAME_COMPLETE; - memcpy(&extra[1], &status, sizeof(status)); - WL_TRACE("wl_iw_event status %d PacketId %d\n", status, - toto); - WL_TRACE("WLC_E_ACTION_FRAME_COMPLETE len %d\n", - wrqu.data.length); - } - break; -#endif /* WIRELESS_EXT > 14 */ -#if WIRELESS_EXT > 17 - case WLC_E_MIC_ERROR: - { - struct iw_michaelmicfailure *micerrevt = - (struct iw_michaelmicfailure *)&extra; - cmd = IWEVMICHAELMICFAILURE; - wrqu.data.length = sizeof(struct iw_michaelmicfailure); - if (flags & WLC_EVENT_MSG_GROUP) - micerrevt->flags |= IW_MICFAILURE_GROUP; - else - micerrevt->flags |= IW_MICFAILURE_PAIRWISE; - memcpy(micerrevt->src_addr.sa_data, &e->addr, - ETH_ALEN); - micerrevt->src_addr.sa_family = ARPHRD_ETHER; - - break; - } - case WLC_E_PMKID_CACHE: - { - if (data) { - struct iw_pmkid_cand *iwpmkidcand = - (struct iw_pmkid_cand *)&extra; - pmkid_cand_list_t *pmkcandlist; - pmkid_cand_t *pmkidcand; - int count; - - cmd = IWEVPMKIDCAND; - pmkcandlist = data; - count = get_unaligned_be32(&pmkcandlist-> - npmkid_cand); - ASSERT(count >= 0); - wrqu.data.length = sizeof(struct iw_pmkid_cand); - pmkidcand = pmkcandlist->pmkid_cand; - while (count) { - memset(iwpmkidcand, 0, - sizeof(struct iw_pmkid_cand)); - if (pmkidcand->preauth) - iwpmkidcand->flags |= - IW_PMKID_CAND_PREAUTH; - memcpy(&iwpmkidcand->bssid.sa_data, - &pmkidcand->BSSID, - ETH_ALEN); -#ifndef SANDGATE2G - wireless_send_event(dev, cmd, &wrqu, - extra); -#endif - pmkidcand++; - count--; - } - } - return; - } -#endif /* WIRELESS_EXT > 17 */ - - case WLC_E_SCAN_COMPLETE: -#if defined(WL_IW_USE_ISCAN) - if ((g_iscan) && (g_iscan->sysioc_tsk) && - (g_iscan->iscan_state != ISCAN_STATE_IDLE)) { - up(&g_iscan->sysioc_sem); - } else { - cmd = SIOCGIWSCAN; - wrqu.data.length = strlen(extra); - WL_TRACE("Event WLC_E_SCAN_COMPLETE from specific scan %d\n", - g_iscan->iscan_state); - } -#else - cmd = SIOCGIWSCAN; - wrqu.data.length = strlen(extra); - WL_TRACE("Event WLC_E_SCAN_COMPLETE\n"); -#endif - break; - - case WLC_E_PFN_NET_FOUND: - { - wlc_ssid_t *ssid; - ssid = (wlc_ssid_t *) data; - WL_ERROR("%s Event WLC_E_PFN_NET_FOUND, send %s up : find %s len=%d\n", - __func__, PNO_EVENT_UP, - ssid->SSID, ssid->SSID_len); - cmd = IWEVCUSTOM; - memset(&wrqu, 0, sizeof(wrqu)); - strcpy(extra, PNO_EVENT_UP); - wrqu.data.length = strlen(extra); - } - break; - - default: - WL_TRACE("Unknown Event %d: ignoring\n", event_type); - break; - } -#ifndef SANDGATE2G - if (cmd) { - if (cmd == SIOCGIWSCAN) - wireless_send_event(dev, cmd, &wrqu, NULL); - else - wireless_send_event(dev, cmd, &wrqu, extra); - } -#endif - -#if WIRELESS_EXT > 14 - memset(extra, 0, sizeof(extra)); - if (wl_iw_check_conn_fail(e, extra, sizeof(extra))) { - cmd = IWEVCUSTOM; - wrqu.data.length = strlen(extra); -#ifndef SANDGATE2G - wireless_send_event(dev, cmd, &wrqu, extra); -#endif - } -#endif /* WIRELESS_EXT > 14 */ -#endif /* WIRELESS_EXT > 13 */ -} - -int wl_iw_attach(struct net_device *dev, void *dhdp) -{ - int params_size; - wl_iw_t *iw; -#if defined(WL_IW_USE_ISCAN) - iscan_info_t *iscan = NULL; - - if (!dev) - return 0; - - memset(&g_wl_iw_params, 0, sizeof(wl_iw_extra_params_t)); - -#ifdef CSCAN - params_size = - (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params)) + - (WL_NUMCHANNELS * sizeof(u16)) + - WL_SCAN_PARAMS_SSID_MAX * sizeof(wlc_ssid_t); -#else - params_size = - (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params)); -#endif - iscan = kzalloc(sizeof(iscan_info_t), GFP_KERNEL); - - if (!iscan) - return -ENOMEM; - - iscan->iscan_ex_params_p = kmalloc(params_size, GFP_KERNEL); - if (!iscan->iscan_ex_params_p) { - kfree(iscan); - return -ENOMEM; - } - iscan->iscan_ex_param_size = params_size; - iscan->sysioc_tsk = NULL; - - g_iscan = iscan; - iscan->dev = dev; - iscan->iscan_state = ISCAN_STATE_IDLE; - - iscan->timer_ms = 3000; - init_timer(&iscan->timer); - iscan->timer.data = (unsigned long) iscan; - iscan->timer.function = wl_iw_timerfunc; - - sema_init(&iscan->sysioc_sem, 0); - iscan->sysioc_tsk = kthread_run(_iscan_sysioc_thread, iscan, - "_iscan_sysioc"); - if (IS_ERR(iscan->sysioc_tsk)) { - iscan->sysioc_tsk = NULL; - return -ENOMEM; - } -#endif /* defined(WL_IW_USE_ISCAN) */ - - iw = *(wl_iw_t **) netdev_priv(dev); - iw->pub = (dhd_pub_t *) dhdp; - MUTEX_LOCK_INIT(iw->pub); - MUTEX_LOCK_WL_SCAN_SET_INIT(); -#ifdef SOFTAP - priv_dev = dev; - MUTEX_LOCK_SOFTAP_SET_INIT(iw->pub); -#endif - g_scan = kzalloc(G_SCAN_RESULTS, GFP_KERNEL); - if (!g_scan) - return -ENOMEM; - - g_scan_specified_ssid = 0; - - return 0; -} - -void wl_iw_detach(void) -{ -#if defined(WL_IW_USE_ISCAN) - iscan_buf_t *buf; - iscan_info_t *iscan = g_iscan; - - if (!iscan) - return; - if (iscan->sysioc_tsk) { - send_sig(SIGTERM, iscan->sysioc_tsk, 1); - kthread_stop(iscan->sysioc_tsk); - iscan->sysioc_tsk = NULL; - } - - MUTEX_LOCK_WL_SCAN_SET(); - while (iscan->list_hdr) { - buf = iscan->list_hdr->next; - kfree(iscan->list_hdr); - iscan->list_hdr = buf; - } - MUTEX_UNLOCK_WL_SCAN_SET(); - kfree(iscan->iscan_ex_params_p); - kfree(iscan); - g_iscan = NULL; -#endif /* WL_IW_USE_ISCAN */ - - kfree(g_scan); - g_scan = NULL; -} diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.h b/drivers/staging/brcm80211/brcmfmac/wl_iw.h deleted file mode 100644 index bfd8172..0000000 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wl_iw_h_ -#define _wl_iw_h_ - -#define WL_SCAN_PARAMS_SSID_MAX 10 -#define GET_SSID "SSID=" -#define GET_CHANNEL "CH=" -#define GET_NPROBE "NPROBE=" -#define GET_ACTIVE_ASSOC_DWELL "ACTIVE=" -#define GET_PASSIVE_ASSOC_DWELL "PASSIVE=" -#define GET_HOME_DWELL "HOME=" -#define GET_SCAN_TYPE "TYPE=" - -#define BAND_GET_CMD "BANDGET" -#define BAND_SET_CMD "BANDSET" -#define DTIM_SKIP_GET_CMD "DTIMSKIPGET" -#define DTIM_SKIP_SET_CMD "DTIMSKIPSET" -#define SETSUSPEND_CMD "SETSUSPENDOPT" -#define PNOSSIDCLR_SET_CMD "PNOSSIDCLR" -#define PNOSETUP_SET_CMD "PNOSETUP" -#define PNOENABLE_SET_CMD "PNOFORCE" -#define PNODEBUG_SET_CMD "PNODEBUG" - -typedef struct wl_iw_extra_params { - int target_channel; -} wl_iw_extra_params_t; - -#define WL_IW_RSSI_MINVAL -200 -#define WL_IW_RSSI_NO_SIGNAL -91 -#define WL_IW_RSSI_VERY_LOW -80 -#define WL_IW_RSSI_LOW -70 -#define WL_IW_RSSI_GOOD -68 -#define WL_IW_RSSI_VERY_GOOD -58 -#define WL_IW_RSSI_EXCELLENT -57 -#define WL_IW_RSSI_INVALID 0 -#define MAX_WX_STRING 80 -#define WL_IW_SET_ACTIVE_SCAN (SIOCIWFIRSTPRIV+1) -#define WL_IW_GET_RSSI (SIOCIWFIRSTPRIV+3) -#define WL_IW_SET_PASSIVE_SCAN (SIOCIWFIRSTPRIV+5) -#define WL_IW_GET_LINK_SPEED (SIOCIWFIRSTPRIV+7) -#define WL_IW_GET_CURR_MACADDR (SIOCIWFIRSTPRIV+9) -#define WL_IW_SET_STOP (SIOCIWFIRSTPRIV+11) -#define WL_IW_SET_START (SIOCIWFIRSTPRIV+13) - -#define WL_SET_AP_CFG (SIOCIWFIRSTPRIV+15) -#define WL_AP_STA_LIST (SIOCIWFIRSTPRIV+17) -#define WL_AP_MAC_FLTR (SIOCIWFIRSTPRIV+19) -#define WL_AP_BSS_START (SIOCIWFIRSTPRIV+21) -#define AP_LPB_CMD (SIOCIWFIRSTPRIV+23) -#define WL_AP_STOP (SIOCIWFIRSTPRIV+25) -#define WL_FW_RELOAD (SIOCIWFIRSTPRIV+27) -#define WL_COMBO_SCAN (SIOCIWFIRSTPRIV+29) -#define WL_AP_SPARE3 (SIOCIWFIRSTPRIV+31) -#define G_SCAN_RESULTS (8*1024) -#define WE_ADD_EVENT_FIX 0x80 -#define G_WLAN_SET_ON 0 -#define G_WLAN_SET_OFF 1 - -#define CHECK_EXTRA_FOR_NULL(extra) \ -if (!extra) { \ - WL_ERROR("%s: error : extra is null pointer\n", __func__); \ - return -EINVAL; \ -} - -typedef struct wl_iw { - char nickname[IW_ESSID_MAX_SIZE]; - - struct iw_statistics wstats; - - int spy_num; - u32 pwsec; - u32 gwsec; - bool privacy_invoked; - - u8 spy_addr[IW_MAX_SPY][ETH_ALEN]; - struct iw_quality spy_qual[IW_MAX_SPY]; - void *wlinfo; - dhd_pub_t *pub; -} wl_iw_t; - -#if WIRELESS_EXT > 12 -#include <net/iw_handler.h> -extern const struct iw_handler_def wl_iw_handler_def; -#endif - -extern int wl_iw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -extern void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data); -extern int wl_iw_get_wireless_stats(struct net_device *dev, - struct iw_statistics *wstats); -int wl_iw_attach(struct net_device *dev, void *dhdp); -void wl_iw_detach(void); -extern int net_os_set_suspend_disable(struct net_device *dev, int val); -extern int net_os_set_suspend(struct net_device *dev, int val); -extern int net_os_set_dtim_skip(struct net_device *dev, int val); -extern int net_os_set_packet_filter(struct net_device *dev, int val); - -#define IWE_STREAM_ADD_EVENT(info, stream, ends, iwe, extra) \ - iwe_stream_add_event(info, stream, ends, iwe, extra) -#define IWE_STREAM_ADD_VALUE(info, event, value, ends, iwe, event_len) \ - iwe_stream_add_value(info, event, value, ends, iwe, event_len) -#define IWE_STREAM_ADD_POINT(info, stream, ends, iwe, extra) \ - iwe_stream_add_point(info, stream, ends, iwe, extra) - -extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled); -extern int dhd_pno_clean(dhd_pub_t *dhd); -extern int dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t *ssids_local, int nssid, - unsigned char scan_fr); -extern int dhd_pno_get_status(dhd_pub_t *dhd); -extern int dhd_dev_pno_reset(struct net_device *dev); -extern int dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t *ssids_local, - int nssid, unsigned char scan_fr); -extern int dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled); -extern int dhd_dev_get_pno_status(struct net_device *dev); - -#define PNO_TLV_PREFIX 'S' -#define PNO_TLV_VERSION 1 -#define PNO_TLV_SUBVERSION 0 -#define PNO_TLV_RESERVED 0 -#define PNO_TLV_TYPE_SSID_IE 'S' -#define PNO_TLV_TYPE_TIME 'T' -#define PNO_EVENT_UP "PNO_EVENT" - -#endif /* _wl_iw_h_ */ -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html