aboutsummaryrefslogtreecommitdiff
path: root/net/ieee80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/ieee80211')
-rw-r--r--net/ieee80211/Kconfig74
-rw-r--r--net/ieee80211/Makefile13
-rw-r--r--net/ieee80211/ieee80211_crypt.c206
-rw-r--r--net/ieee80211/ieee80211_crypt_ccmp.c493
-rw-r--r--net/ieee80211/ieee80211_crypt_tkip.c787
-rw-r--r--net/ieee80211/ieee80211_crypt_wep.c295
-rw-r--r--net/ieee80211/ieee80211_geo.c195
-rw-r--r--net/ieee80211/ieee80211_module.c338
-rw-r--r--net/ieee80211/ieee80211_rx.c1816
-rw-r--r--net/ieee80211/ieee80211_tx.c631
-rw-r--r--net/ieee80211/ieee80211_wx.c841
-rw-r--r--net/ieee80211/softmac/Kconfig12
-rw-r--r--net/ieee80211/softmac/Makefile9
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_assoc.c489
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_auth.c413
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_event.c189
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_io.c488
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_module.c568
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_priv.h244
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_scan.c254
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_wx.c508
21 files changed, 0 insertions, 8863 deletions
diff --git a/net/ieee80211/Kconfig b/net/ieee80211/Kconfig
deleted file mode 100644
index bd501046c9c..00000000000
--- a/net/ieee80211/Kconfig
+++ /dev/null
@@ -1,74 +0,0 @@
-config IEEE80211
- tristate "Generic IEEE 802.11 Networking Stack (DEPRECATED)"
- ---help---
- This option enables the hardware independent IEEE 802.11
- networking stack. This component is deprecated in favor of the
- mac80211 component.
-
-config IEEE80211_DEBUG
- bool "Enable full debugging output"
- depends on IEEE80211
- ---help---
- This option will enable debug tracing output for the
- ieee80211 network stack.
-
- This will result in the kernel module being ~70k larger. You
- can control which debug output is sent to the kernel log by
- setting the value in
-
- /proc/net/ieee80211/debug_level
-
- For example:
-
- % echo 0x00000FFO > /proc/net/ieee80211/debug_level
-
- For a list of values you can assign to debug_level, you
- can look at the bit mask values in <net/ieee80211.h>
-
- If you are not trying to debug or develop the ieee80211
- subsystem, you most likely want to say N here.
-
-config IEEE80211_CRYPT_WEP
- tristate "IEEE 802.11 WEP encryption (802.1x)"
- depends on IEEE80211
- select CRYPTO
- select CRYPTO_ARC4
- select CRYPTO_ECB
- select CRC32
- ---help---
- Include software based cipher suites in support of IEEE
- 802.11's WEP. This is needed for WEP as well as 802.1x.
-
- This can be compiled as a module and it will be called
- "ieee80211_crypt_wep".
-
-config IEEE80211_CRYPT_CCMP
- tristate "IEEE 802.11i CCMP support"
- depends on IEEE80211
- select CRYPTO
- select CRYPTO_AES
- ---help---
- Include software based cipher suites in support of IEEE 802.11i
- (aka TGi, WPA, WPA2, WPA-PSK, etc.) for use with CCMP enabled
- networks.
-
- This can be compiled as a module and it will be called
- "ieee80211_crypt_ccmp".
-
-config IEEE80211_CRYPT_TKIP
- tristate "IEEE 802.11i TKIP encryption"
- depends on IEEE80211
- select WIRELESS_EXT
- select CRYPTO
- select CRYPTO_MICHAEL_MIC
- select CRYPTO_ECB
- select CRC32
- ---help---
- Include software based cipher suites in support of IEEE 802.11i
- (aka TGi, WPA, WPA2, WPA-PSK, etc.) for use with TKIP enabled
- networks.
-
- This can be compiled as a module and it will be called
- "ieee80211_crypt_tkip".
-
-source "net/ieee80211/softmac/Kconfig"
diff --git a/net/ieee80211/Makefile b/net/ieee80211/Makefile
deleted file mode 100644
index 796a7c76ee4..00000000000
--- a/net/ieee80211/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-obj-$(CONFIG_IEEE80211) += ieee80211.o
-obj-$(CONFIG_IEEE80211) += ieee80211_crypt.o
-obj-$(CONFIG_IEEE80211_CRYPT_WEP) += ieee80211_crypt_wep.o
-obj-$(CONFIG_IEEE80211_CRYPT_CCMP) += ieee80211_crypt_ccmp.o
-obj-$(CONFIG_IEEE80211_CRYPT_TKIP) += ieee80211_crypt_tkip.o
-ieee80211-objs := \
- ieee80211_module.o \
- ieee80211_tx.o \
- ieee80211_rx.o \
- ieee80211_wx.o \
- ieee80211_geo.o
-
-obj-$(CONFIG_IEEE80211_SOFTMAC) += softmac/
diff --git a/net/ieee80211/ieee80211_crypt.c b/net/ieee80211/ieee80211_crypt.c
deleted file mode 100644
index df5592c9339..00000000000
--- a/net/ieee80211/ieee80211_crypt.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Host AP crypto routines
- *
- * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
- * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation. See README and COPYING for
- * more details.
- *
- */
-
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <net/ieee80211.h>
-
-MODULE_AUTHOR("Jouni Malinen");
-MODULE_DESCRIPTION("HostAP crypto");
-MODULE_LICENSE("GPL");
-
-struct ieee80211_crypto_alg {
- struct list_head list;
- struct ieee80211_crypto_ops *ops;
-};
-
-static LIST_HEAD(ieee80211_crypto_algs);
-static DEFINE_SPINLOCK(ieee80211_crypto_lock);
-
-void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
-{
- struct ieee80211_crypt_data *entry, *next;
- unsigned long flags;
-
- spin_lock_irqsave(&ieee->lock, flags);
- list_for_each_entry_safe(entry, next, &ieee->crypt_deinit_list, list) {
- if (atomic_read(&entry->refcnt) != 0 && !force)
- continue;
-
- list_del(&entry->list);
-
- if (entry->ops) {
- entry->ops->deinit(entry->priv);
- module_put(entry->ops->owner);
- }
- kfree(entry);
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-/* After this, crypt_deinit_list won't accept new members */
-void ieee80211_crypt_quiescing(struct ieee80211_device *ieee)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ieee->lock, flags);
- ieee->crypt_quiesced = 1;
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-void ieee80211_crypt_deinit_handler(unsigned long data)
-{
- struct ieee80211_device *ieee = (struct ieee80211_device *)data;
- unsigned long flags;
-
- ieee80211_crypt_deinit_entries(ieee, 0);
-
- spin_lock_irqsave(&ieee->lock, flags);
- if (!list_empty(&ieee->crypt_deinit_list) && !ieee->crypt_quiesced) {
- printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
- "deletion list\n", ieee->dev->name);
- ieee->crypt_deinit_timer.expires = jiffies + HZ;
- add_timer(&ieee->crypt_deinit_timer);
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
- struct ieee80211_crypt_data **crypt)
-{
- struct ieee80211_crypt_data *tmp;
- unsigned long flags;
-
- if (*crypt == NULL)
- return;
-
- tmp = *crypt;
- *crypt = NULL;
-
- /* must not run ops->deinit() while there may be pending encrypt or
- * decrypt operations. Use a list of delayed deinits to avoid needing
- * locking. */
-
- spin_lock_irqsave(&ieee->lock, flags);
- if (!ieee->crypt_quiesced) {
- list_add(&tmp->list, &ieee->crypt_deinit_list);
- if (!timer_pending(&ieee->crypt_deinit_timer)) {
- ieee->crypt_deinit_timer.expires = jiffies + HZ;
- add_timer(&ieee->crypt_deinit_timer);
- }
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
-{
- unsigned long flags;
- struct ieee80211_crypto_alg *alg;
-
- alg = kzalloc(sizeof(*alg), GFP_KERNEL);
- if (alg == NULL)
- return -ENOMEM;
-
- alg->ops = ops;
-
- spin_lock_irqsave(&ieee80211_crypto_lock, flags);
- list_add(&alg->list, &ieee80211_crypto_algs);
- spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
-
- printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n",
- ops->name);
-
- return 0;
-}
-
-int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
-{
- struct ieee80211_crypto_alg *alg;
- unsigned long flags;
-
- spin_lock_irqsave(&ieee80211_crypto_lock, flags);
- list_for_each_entry(alg, &ieee80211_crypto_algs, list) {
- if (alg->ops == ops)
- goto found;
- }
- spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
- return -EINVAL;
-
- found:
- printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
- "'%s'\n", ops->name);
- list_del(&alg->list);
- spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
- kfree(alg);
- return 0;
-}
-
-struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name)
-{
- struct ieee80211_crypto_alg *alg;
- unsigned long flags;
-
- spin_lock_irqsave(&ieee80211_crypto_lock, flags);
- list_for_each_entry(alg, &ieee80211_crypto_algs, list) {
- if (strcmp(alg->ops->name, name) == 0)
- goto found;
- }
- spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
- return NULL;
-
- found:
- spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
- return alg->ops;
-}
-
-static void *ieee80211_crypt_null_init(int keyidx)
-{
- return (void *)1;
-}
-
-static void ieee80211_crypt_null_deinit(void *priv)
-{
-}
-
-static struct ieee80211_crypto_ops ieee80211_crypt_null = {
- .name = "NULL",
- .init = ieee80211_crypt_null_init,
- .deinit = ieee80211_crypt_null_deinit,
- .owner = THIS_MODULE,
-};
-
-static int __init ieee80211_crypto_init(void)
-{
- return ieee80211_register_crypto_ops(&ieee80211_crypt_null);
-}
-
-static void __exit ieee80211_crypto_deinit(void)
-{
- ieee80211_unregister_crypto_ops(&ieee80211_crypt_null);
- BUG_ON(!list_empty(&ieee80211_crypto_algs));
-}
-
-EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
-EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
-EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
-EXPORT_SYMBOL(ieee80211_crypt_quiescing);
-
-EXPORT_SYMBOL(ieee80211_register_crypto_ops);
-EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);
-EXPORT_SYMBOL(ieee80211_get_crypto_ops);
-
-module_init(ieee80211_crypto_init);
-module_exit(ieee80211_crypto_deinit);
diff --git a/net/ieee80211/ieee80211_crypt_ccmp.c b/net/ieee80211/ieee80211_crypt_ccmp.c
deleted file mode 100644
index 208bf35b554..00000000000
--- a/net/ieee80211/ieee80211_crypt_ccmp.c
+++ /dev/null
@@ -1,493 +0,0 @@
-/*
- * Host AP crypt: host-based CCMP encryption implementation for Host AP driver
- *
- * Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation. See README and COPYING for
- * more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/if_ether.h>
-#include <linux/if_arp.h>
-#include <asm/string.h>
-#include <linux/wireless.h>
-
-#include <net/ieee80211.h>
-
-#include <linux/crypto.h>
-
-MODULE_AUTHOR("Jouni Malinen");
-MODULE_DESCRIPTION("Host AP crypt: CCMP");
-MODULE_LICENSE("GPL");
-
-#define AES_BLOCK_LEN 16
-#define CCMP_HDR_LEN 8
-#define CCMP_MIC_LEN 8
-#define CCMP_TK_LEN 16
-#define CCMP_PN_LEN 6
-
-struct ieee80211_ccmp_data {
- u8 key[CCMP_TK_LEN];
- int key_set;
-
- u8 tx_pn[CCMP_PN_LEN];
- u8 rx_pn[CCMP_PN_LEN];
-
- u32 dot11RSNAStatsCCMPFormatErrors;
- u32 dot11RSNAStatsCCMPReplays;
- u32 dot11RSNAStatsCCMPDecryptErrors;
-
- int key_idx;
-
- struct crypto_cipher *tfm;
-
- /* scratch buffers for virt_to_page() (crypto API) */
- u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN],
- tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN];
- u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN];
-};
-
-static inline void ieee80211_ccmp_aes_encrypt(struct crypto_cipher *tfm,
- const u8 pt[16], u8 ct[16])
-{
- crypto_cipher_encrypt_one(tfm, ct, pt);
-}
-
-static void *ieee80211_ccmp_init(int key_idx)
-{
- struct ieee80211_ccmp_data *priv;
-
- priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
- if (priv == NULL)
- goto fail;
- priv->key_idx = key_idx;
-
- priv->tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->tfm)) {
- printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
- "crypto API aes\n");
- priv->tfm = NULL;
- goto fail;
- }
-
- return priv;
-
- fail:
- if (priv) {
- if (priv->tfm)
- crypto_free_cipher(priv->tfm);
- kfree(priv);
- }
-
- return NULL;
-}
-
-static void ieee80211_ccmp_deinit(void *priv)
-{
- struct ieee80211_ccmp_data *_priv = priv;
- if (_priv && _priv->tfm)
- crypto_free_cipher(_priv->tfm);
- kfree(priv);
-}
-
-static inline void xor_block(u8 * b, u8 * a, size_t len)
-{
- int i;
- for (i = 0; i < len; i++)
- b[i] ^= a[i];
-}
-
-static void ccmp_init_blocks(struct crypto_cipher *tfm,
- struct ieee80211_hdr_4addr *hdr,
- u8 * pn, size_t dlen, u8 * b0, u8 * auth, u8 * s0)
-{
- u8 *pos, qc = 0;
- size_t aad_len;
- u16 fc;
- int a4_included, qc_included;
- u8 aad[2 * AES_BLOCK_LEN];
-
- fc = le16_to_cpu(hdr->frame_ctl);
- a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
- (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS));
- qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
- (WLAN_FC_GET_STYPE(fc) & IEEE80211_STYPE_QOS_DATA));
- aad_len = 22;
- if (a4_included)
- aad_len += 6;
- if (qc_included) {
- pos = (u8 *) & hdr->addr4;
- if (a4_included)
- pos += 6;
- qc = *pos & 0x0f;
- aad_len += 2;
- }
-
- /* CCM Initial Block:
- * Flag (Include authentication header, M=3 (8-octet MIC),
- * L=1 (2-octet Dlen))
- * Nonce: 0x00 | A2 | PN
- * Dlen */
- b0[0] = 0x59;
- b0[1] = qc;
- memcpy(b0 + 2, hdr->addr2, ETH_ALEN);
- memcpy(b0 + 8, pn, CCMP_PN_LEN);
- b0[14] = (dlen >> 8) & 0xff;
- b0[15] = dlen & 0xff;
-
- /* AAD:
- * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
- * A1 | A2 | A3
- * SC with bits 4..15 (seq#) masked to zero
- * A4 (if present)
- * QC (if present)
- */
- pos = (u8 *) hdr;
- aad[0] = 0; /* aad_len >> 8 */
- aad[1] = aad_len & 0xff;
- aad[2] = pos[0] & 0x8f;
- aad[3] = pos[1] & 0xc7;
- memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
- pos = (u8 *) & hdr->seq_ctl;
- aad[22] = pos[0] & 0x0f;
- aad[23] = 0; /* all bits masked */
- memset(aad + 24, 0, 8);
- if (a4_included)
- memcpy(aad + 24, hdr->addr4, ETH_ALEN);
- if (qc_included) {
- aad[a4_included ? 30 : 24] = qc;
- /* rest of QC masked */
- }
-
- /* Start with the first block and AAD */
- ieee80211_ccmp_aes_encrypt(tfm, b0, auth);
- xor_block(auth, aad, AES_BLOCK_LEN);
- ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
- xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN);
- ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
- b0[0] &= 0x07;
- b0[14] = b0[15] = 0;
- ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
-}
-
-static int ieee80211_ccmp_hdr(struct sk_buff *skb, int hdr_len,
- u8 *aeskey, int keylen, void *priv)
-{
- struct ieee80211_ccmp_data *key = priv;
- int i;
- u8 *pos;
-
- if (skb_headroom(skb) < CCMP_HDR_LEN || skb->len < hdr_len)
- return -1;
-
- if (aeskey != NULL && keylen >= CCMP_TK_LEN)
- memcpy(aeskey, key->key, CCMP_TK_LEN);
-
- pos = skb_push(skb, CCMP_HDR_LEN);
- memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
- pos += hdr_len;
-
- i = CCMP_PN_LEN - 1;
- while (i >= 0) {
- key->tx_pn[i]++;
- if (key->tx_pn[i] != 0)
- break;
- i--;
- }
-
- *pos++ = key->tx_pn[5];
- *pos++ = key->tx_pn[4];
- *pos++ = 0;
- *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */ ;
- *pos++ = key->tx_pn[3];
- *pos++ = key->tx_pn[2];
- *pos++ = key->tx_pn[1];
- *pos++ = key->tx_pn[0];
-
- return CCMP_HDR_LEN;
-}
-
-static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct ieee80211_ccmp_data *key = priv;
- int data_len, i, blocks, last, len;
- u8 *pos, *mic;
- struct ieee80211_hdr_4addr *hdr;
- u8 *b0 = key->tx_b0;
- u8 *b = key->tx_b;
- u8 *e = key->tx_e;
- u8 *s0 = key->tx_s0;
-
- if (skb_tailroom(skb) < CCMP_MIC_LEN || skb->len < hdr_len)
- return -1;
-
- data_len = skb->len - hdr_len;
- len = ieee80211_ccmp_hdr(skb, hdr_len, NULL, 0, priv);
- if (len < 0)
- return -1;
-
- pos = skb->data + hdr_len + CCMP_HDR_LEN;
- mic = skb_put(skb, CCMP_MIC_LEN);
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
-
- blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN);
- last = data_len % AES_BLOCK_LEN;
-
- for (i = 1; i <= blocks; i++) {
- len = (i == blocks && last) ? last : AES_BLOCK_LEN;
- /* Authentication */
- xor_block(b, pos, len);
- ieee80211_ccmp_aes_encrypt(key->tfm, b, b);
- /* Encryption, with counter */
- b0[14] = (i >> 8) & 0xff;
- b0[15] = i & 0xff;
- ieee80211_ccmp_aes_encrypt(key->tfm, b0, e);
- xor_block(pos, e, len);
- pos += len;
- }
-
- for (i = 0; i < CCMP_MIC_LEN; i++)
- mic[i] = b[i] ^ s0[i];
-
- return 0;
-}
-
-/*
- * deal with seq counter wrapping correctly.
- * refer to timer_after() for jiffies wrapping handling
- */
-static inline int ccmp_replay_check(u8 *pn_n, u8 *pn_o)
-{
- u32 iv32_n, iv16_n;
- u32 iv32_o, iv16_o;
-
- iv32_n = (pn_n[0] << 24) | (pn_n[1] << 16) | (pn_n[2] << 8) | pn_n[3];
- iv16_n = (pn_n[4] << 8) | pn_n[5];
-
- iv32_o = (pn_o[0] << 24) | (pn_o[1] << 16) | (pn_o[2] << 8) | pn_o[3];
- iv16_o = (pn_o[4] << 8) | pn_o[5];
-
- if ((s32)iv32_n - (s32)iv32_o < 0 ||
- (iv32_n == iv32_o && iv16_n <= iv16_o))
- return 1;
- return 0;
-}
-
-static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct ieee80211_ccmp_data *key = priv;
- u8 keyidx, *pos;
- struct ieee80211_hdr_4addr *hdr;
- u8 *b0 = key->rx_b0;
- u8 *b = key->rx_b;
- u8 *a = key->rx_a;
- u8 pn[6];
- int i, blocks, last, len;
- size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN;
- u8 *mic = skb->data + skb->len - CCMP_MIC_LEN;
- DECLARE_MAC_BUF(mac);
-
- if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
- key->dot11RSNAStatsCCMPFormatErrors++;
- return -1;
- }
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- pos = skb->data + hdr_len;
- keyidx = pos[3];
- if (!(keyidx & (1 << 5))) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "CCMP: received packet without ExtIV"
- " flag from %s\n", print_mac(mac, hdr->addr2));
- }
- key->dot11RSNAStatsCCMPFormatErrors++;
- return -2;
- }
- keyidx >>= 6;
- if (key->key_idx != keyidx) {
- printk(KERN_DEBUG "CCMP: RX tkey->key_idx=%d frame "
- "keyidx=%d priv=%p\n", key->key_idx, keyidx, priv);
- return -6;
- }
- if (!key->key_set) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "CCMP: received packet from %s"
- " with keyid=%d that does not have a configured"
- " key\n", print_mac(mac, hdr->addr2), keyidx);
- }
- return -3;
- }
-
- pn[0] = pos[7];
- pn[1] = pos[6];
- pn[2] = pos[5];
- pn[3] = pos[4];
- pn[4] = pos[1];
- pn[5] = pos[0];
- pos += 8;
-
- if (ccmp_replay_check(pn, key->rx_pn)) {
- if (ieee80211_ratelimit_debug(IEEE80211_DL_DROP)) {
- IEEE80211_DEBUG_DROP("CCMP: replay detected: STA=%s "
- "previous PN %02x%02x%02x%02x%02x%02x "
- "received PN %02x%02x%02x%02x%02x%02x\n",
- print_mac(mac, hdr->addr2),
- key->rx_pn[0], key->rx_pn[1], key->rx_pn[2],
- key->rx_pn[3], key->rx_pn[4], key->rx_pn[5],
- pn[0], pn[1], pn[2], pn[3], pn[4], pn[5]);
- }
- key->dot11RSNAStatsCCMPReplays++;
- return -4;
- }
-
- ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b);
- xor_block(mic, b, CCMP_MIC_LEN);
-
- blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN);
- last = data_len % AES_BLOCK_LEN;
-
- for (i = 1; i <= blocks; i++) {
- len = (i == blocks && last) ? last : AES_BLOCK_LEN;
- /* Decrypt, with counter */
- b0[14] = (i >> 8) & 0xff;
- b0[15] = i & 0xff;
- ieee80211_ccmp_aes_encrypt(key->tfm, b0, b);
- xor_block(pos, b, len);
- /* Authentication */
- xor_block(a, pos, len);
- ieee80211_ccmp_aes_encrypt(key->tfm, a, a);
- pos += len;
- }
-
- if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "CCMP: decrypt failed: STA="
- "%s\n", print_mac(mac, hdr->addr2));
- }
- key->dot11RSNAStatsCCMPDecryptErrors++;
- return -5;
- }
-
- memcpy(key->rx_pn, pn, CCMP_PN_LEN);
-
- /* Remove hdr and MIC */
- memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len);
- skb_pull(skb, CCMP_HDR_LEN);
- skb_trim(skb, skb->len - CCMP_MIC_LEN);
-
- return keyidx;
-}
-
-static int ieee80211_ccmp_set_key(void *key, int len, u8 * seq, void *priv)
-{
- struct ieee80211_ccmp_data *data = priv;
- int keyidx;
- struct crypto_cipher *tfm = data->tfm;
-
- keyidx = data->key_idx;
- memset(data, 0, sizeof(*data));
- data->key_idx = keyidx;
- data->tfm = tfm;
- if (len == CCMP_TK_LEN) {
- memcpy(data->key, key, CCMP_TK_LEN);
- data->key_set = 1;
- if (seq) {
- data->rx_pn[0] = seq[5];
- data->rx_pn[1] = seq[4];
- data->rx_pn[2] = seq[3];
- data->rx_pn[3] = seq[2];
- data->rx_pn[4] = seq[1];
- data->rx_pn[5] = seq[0];
- }
- crypto_cipher_setkey(data->tfm, data->key, CCMP_TK_LEN);
- } else if (len == 0)
- data->key_set = 0;
- else
- return -1;
-
- return 0;
-}
-
-static int ieee80211_ccmp_get_key(void *key, int len, u8 * seq, void *priv)
-{
- struct ieee80211_ccmp_data *data = priv;
-
- if (len < CCMP_TK_LEN)
- return -1;
-
- if (!data->key_set)
- return 0;
- memcpy(key, data->key, CCMP_TK_LEN);
-
- if (seq) {
- seq[0] = data->tx_pn[5];
- seq[1] = data->tx_pn[4];
- seq[2] = data->tx_pn[3];
- seq[3] = data->tx_pn[2];
- seq[4] = data->tx_pn[1];
- seq[5] = data->tx_pn[0];
- }
-
- return CCMP_TK_LEN;
-}
-
-static char *ieee80211_ccmp_print_stats(char *p, void *priv)
-{
- struct ieee80211_ccmp_data *ccmp = priv;
-
- p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
- "tx_pn=%02x%02x%02x%02x%02x%02x "
- "rx_pn=%02x%02x%02x%02x%02x%02x "
- "format_errors=%d replays=%d decrypt_errors=%d\n",
- ccmp->key_idx, ccmp->key_set,
- ccmp->tx_pn[0], ccmp->tx_pn[1], ccmp->tx_pn[2],
- ccmp->tx_pn[3], ccmp->tx_pn[4], ccmp->tx_pn[5],
- ccmp->rx_pn[0], ccmp->rx_pn[1], ccmp->rx_pn[2],
- ccmp->rx_pn[3], ccmp->rx_pn[4], ccmp->rx_pn[5],
- ccmp->dot11RSNAStatsCCMPFormatErrors,
- ccmp->dot11RSNAStatsCCMPReplays,
- ccmp->dot11RSNAStatsCCMPDecryptErrors);
-
- return p;
-}
-
-static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
- .name = "CCMP",
- .init = ieee80211_ccmp_init,
- .deinit = ieee80211_ccmp_deinit,
- .build_iv = ieee80211_ccmp_hdr,
- .encrypt_mpdu = ieee80211_ccmp_encrypt,
- .decrypt_mpdu = ieee80211_ccmp_decrypt,
- .encrypt_msdu = NULL,
- .decrypt_msdu = NULL,
- .set_key = ieee80211_ccmp_set_key,
- .get_key = ieee80211_ccmp_get_key,
- .print_stats = ieee80211_ccmp_print_stats,
- .extra_mpdu_prefix_len = CCMP_HDR_LEN,
- .extra_mpdu_postfix_len = CCMP_MIC_LEN,
- .owner = THIS_MODULE,
-};
-
-static int __init ieee80211_crypto_ccmp_init(void)
-{
- return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
-}
-
-static void __exit ieee80211_crypto_ccmp_exit(void)
-{
- ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
-}
-
-module_init(ieee80211_crypto_ccmp_init);
-module_exit(ieee80211_crypto_ccmp_exit);
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
deleted file mode 100644
index bba0152e2d7..00000000000
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ /dev/null
@@ -1,787 +0,0 @@
-/*
- * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
- *
- * Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation. See README and COPYING for
- * more details.
- */
-
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/scatterlist.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/mm.h>
-#include <linux/if_ether.h>
-#include <linux/if_arp.h>
-#include <asm/string.h>
-
-#include <net/ieee80211.h>
-
-#include <linux/crypto.h>
-#include <linux/crc32.h>
-
-MODULE_AUTHOR("Jouni Malinen");
-MODULE_DESCRIPTION("Host AP crypt: TKIP");
-MODULE_LICENSE("GPL");
-
-struct ieee80211_tkip_data {
-#define TKIP_KEY_LEN 32
- u8 key[TKIP_KEY_LEN];
- int key_set;
-
- u32 tx_iv32;
- u16 tx_iv16;
- u16 tx_ttak[5];
- int tx_phase1_done;
-
- u32 rx_iv32;
- u16 rx_iv16;
- u16 rx_ttak[5];
- int rx_phase1_done;
- u32 rx_iv32_new;
- u16 rx_iv16_new;
-
- u32 dot11RSNAStatsTKIPReplays;
- u32 dot11RSNAStatsTKIPICVErrors;
- u32 dot11RSNAStatsTKIPLocalMICFailures;
-
- int key_idx;
-
- struct crypto_blkcipher *rx_tfm_arc4;
- struct crypto_hash *rx_tfm_michael;
- struct crypto_blkcipher *tx_tfm_arc4;
- struct crypto_hash *tx_tfm_michael;
-
- /* scratch buffers for virt_to_page() (crypto API) */
- u8 rx_hdr[16], tx_hdr[16];
-
- unsigned long flags;
-};
-
-static unsigned long ieee80211_tkip_set_flags(unsigned long flags, void *priv)
-{
- struct ieee80211_tkip_data *_priv = priv;
- unsigned long old_flags = _priv->flags;
- _priv->flags = flags;
- return old_flags;
-}
-
-static unsigned long ieee80211_tkip_get_flags(void *priv)
-{
- struct ieee80211_tkip_data *_priv = priv;
- return _priv->flags;
-}
-
-static void *ieee80211_tkip_init(int key_idx)
-{
- struct ieee80211_tkip_data *priv;
-
- priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
- if (priv == NULL)
- goto fail;
-
- priv->key_idx = key_idx;
-
- priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
- CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->tx_tfm_arc4)) {
- printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
- "crypto API arc4\n");
- priv->tx_tfm_arc4 = NULL;
- goto fail;
- }
-
- priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
- CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->tx_tfm_michael)) {
- printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
- "crypto API michael_mic\n");
- priv->tx_tfm_michael = NULL;
- goto fail;
- }
-
- priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
- CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->rx_tfm_arc4)) {
- printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
- "crypto API arc4\n");
- priv->rx_tfm_arc4 = NULL;
- goto fail;
- }
-
- priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
- CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->rx_tfm_michael)) {
- printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
- "crypto API michael_mic\n");
- priv->rx_tfm_michael = NULL;
- goto fail;
- }
-
- return priv;
-
- fail:
- if (priv) {
- if (priv->tx_tfm_michael)
- crypto_free_hash(priv->tx_tfm_michael);
- if (priv->tx_tfm_arc4)
- crypto_free_blkcipher(priv->tx_tfm_arc4);
- if (priv->rx_tfm_michael)
- crypto_free_hash(priv->rx_tfm_michael);
- if (priv->rx_tfm_arc4)
- crypto_free_blkcipher(priv->rx_tfm_arc4);
- kfree(priv);
- }
-
- return NULL;
-}
-
-static void ieee80211_tkip_deinit(void *priv)
-{
- struct ieee80211_tkip_data *_priv = priv;
- if (_priv) {
- if (_priv->tx_tfm_michael)
- crypto_free_hash(_priv->tx_tfm_michael);
- if (_priv->tx_tfm_arc4)
- crypto_free_blkcipher(_priv->tx_tfm_arc4);
- if (_priv->rx_tfm_michael)
- crypto_free_hash(_priv->rx_tfm_michael);
- if (_priv->rx_tfm_arc4)
- crypto_free_blkcipher(_priv->rx_tfm_arc4);
- }
- kfree(priv);
-}
-
-static inline u16 RotR1(u16 val)
-{
- return (val >> 1) | (val << 15);
-}
-
-static inline u8 Lo8(u16 val)
-{
- return val & 0xff;
-}
-
-static inline u8 Hi8(u16 val)
-{
- return val >> 8;
-}
-
-static inline u16 Lo16(u32 val)
-{
- return val & 0xffff;
-}
-
-static inline u16 Hi16(u32 val)
-{
- return val >> 16;
-}
-
-static inline u16 Mk16(u8 hi, u8 lo)
-{
- return lo | (((u16) hi) << 8);
-}
-
-static inline u16 Mk16_le(__le16 * v)
-{
- return le16_to_cpu(*v);
-}
-
-static const u16 Sbox[256] = {
- 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
- 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
- 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
- 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
- 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
- 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
- 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
- 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
- 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
- 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
- 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
- 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
- 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
- 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
- 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
- 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
- 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
- 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
- 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
- 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
- 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
- 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
- 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
- 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
- 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
- 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
- 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
- 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
- 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
- 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
- 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
- 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
-};
-
-static inline u16 _S_(u16 v)
-{
- u16 t = Sbox[Hi8(v)];
- return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
-}
-
-#define PHASE1_LOOP_COUNT 8
-
-static void tkip_mixing_phase1(u16 * TTAK, const u8 * TK, const u8 * TA,
- u32 IV32)
-{
- int i, j;
-
- /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
- TTAK[0] = Lo16(IV32);
- TTAK[1] = Hi16(IV32);
- TTAK[2] = Mk16(TA[1], TA[0]);
- TTAK[3] = Mk16(TA[3], TA[2]);
- TTAK[4] = Mk16(TA[5], TA[4]);
-
- for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
- j = 2 * (i & 1);
- TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
- TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
- TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
- TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
- TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
- }
-}
-
-static void tkip_mixing_phase2(u8 * WEPSeed, const u8 * TK, const u16 * TTAK,
- u16 IV16)
-{
- /* Make temporary area overlap WEP seed so that the final copy can be
- * avoided on little endian hosts. */
- u16 *PPK = (u16 *) & WEPSeed[4];
-
- /* Step 1 - make copy of TTAK and bring in TSC */
- PPK[0] = TTAK[0];
- PPK[1] = TTAK[1];
- PPK[2] = TTAK[2];
- PPK[3] = TTAK[3];
- PPK[4] = TTAK[4];
- PPK[5] = TTAK[4] + IV16;
-
- /* Step 2 - 96-bit bijective mixing using S-box */
- PPK[0] += _S_(PPK[5] ^ Mk16_le((__le16 *) & TK[0]));
- PPK[1] += _S_(PPK[0] ^ Mk16_le((__le16 *) & TK[2]));
- PPK[2] += _S_(PPK[1] ^ Mk16_le((__le16 *) & TK[4]));
- PPK[3] += _S_(PPK[2] ^ Mk16_le((__le16 *) & TK[6]));
- PPK[4] += _S_(PPK[3] ^ Mk16_le((__le16 *) & TK[8]));
- PPK[5] += _S_(PPK[4] ^ Mk16_le((__le16 *) & TK[10]));
-
- PPK[0] += RotR1(PPK[5] ^ Mk16_le((__le16 *) & TK[12]));
- PPK[1] += RotR1(PPK[0] ^ Mk16_le((__le16 *) & TK[14]));
- PPK[2] += RotR1(PPK[1]);
- PPK[3] += RotR1(PPK[2]);
- PPK[4] += RotR1(PPK[3]);
- PPK[5] += RotR1(PPK[4]);
-
- /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
- * WEPSeed[0..2] is transmitted as WEP IV */
- WEPSeed[0] = Hi8(IV16);
- WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
- WEPSeed[2] = Lo8(IV16);
- WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((__le16 *) & TK[0])) >> 1);
-
-#ifdef __BIG_ENDIAN
- {
- int i;
- for (i = 0; i < 6; i++)
- PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
- }
-#endif
-}
-
-static int ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len,
- u8 * rc4key, int keylen, void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
- int len;
- u8 *pos;
- struct ieee80211_hdr_4addr *hdr;
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
-
- if (skb_headroom(skb) < 8 || skb->len < hdr_len)
- return -1;
-
- if (rc4key == NULL || keylen < 16)
- return -1;
-
- if (!tkey->tx_phase1_done) {
- tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
- tkey->tx_iv32);
- tkey->tx_phase1_done = 1;
- }
- tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
-
- len = skb->len - hdr_len;
- pos = skb_push(skb, 8);
- memmove(pos, pos + 8, hdr_len);
- pos += hdr_len;
-
- *pos++ = *rc4key;
- *pos++ = *(rc4key + 1);
- *pos++ = *(rc4key + 2);
- *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */ ;
- *pos++ = tkey->tx_iv32 & 0xff;
- *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
- *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
- *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
-
- tkey->tx_iv16++;
- if (tkey->tx_iv16 == 0) {
- tkey->tx_phase1_done = 0;
- tkey->tx_iv32++;
- }
-
- return 8;
-}
-
-static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
- struct blkcipher_desc desc = { .tfm = tkey->tx_tfm_arc4 };
- int len;
- u8 rc4key[16], *pos, *icv;
- u32 crc;
- struct scatterlist sg;
- DECLARE_MAC_BUF(mac);
-
- if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
- if (net_ratelimit()) {
- struct ieee80211_hdr_4addr *hdr =
- (struct ieee80211_hdr_4addr *)skb->data;
- printk(KERN_DEBUG ": TKIP countermeasures: dropped "
- "TX packet to %s\n",
- print_mac(mac, hdr->addr1));
- }
- return -1;
- }
-
- if (skb_tailroom(skb) < 4 || skb->len < hdr_len)
- return -1;
-
- len = skb->len - hdr_len;
- pos = skb->data + hdr_len;
-
- if ((ieee80211_tkip_hdr(skb, hdr_len, rc4key, 16, priv)) < 0)
- return -1;
-
- icv = skb_put(skb, 4);
-
- crc = ~crc32_le(~0, pos, len);
- icv[0] = crc;
- icv[1] = crc >> 8;
- icv[2] = crc >> 16;
- icv[3] = crc >> 24;
-
- crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
- sg_init_one(&sg, pos, len + 4);
- return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
-}
-
-/*
- * deal with seq counter wrapping correctly.
- * refer to timer_after() for jiffies wrapping handling
- */
-static inline int tkip_replay_check(u32 iv32_n, u16 iv16_n,
- u32 iv32_o, u16 iv16_o)
-{
- if ((s32)iv32_n - (s32)iv32_o < 0 ||
- (iv32_n == iv32_o && iv16_n <= iv16_o))
- return 1;
- return 0;
-}
-
-static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
- struct blkcipher_desc desc = { .tfm = tkey->rx_tfm_arc4 };
- u8 rc4key[16];
- u8 keyidx, *pos;
- u32 iv32;
- u16 iv16;
- struct ieee80211_hdr_4addr *hdr;
- u8 icv[4];
- u32 crc;
- struct scatterlist sg;
- int plen;
- DECLARE_MAC_BUF(mac);
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
-
- if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG ": TKIP countermeasures: dropped "
- "received packet from %s\n",
- print_mac(mac, hdr->addr2));
- }
- return -1;
- }
-
- if (skb->len < hdr_len + 8 + 4)
- return -1;
-
- pos = skb->data + hdr_len;
- keyidx = pos[3];
- if (!(keyidx & (1 << 5))) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP: received packet without ExtIV"
- " flag from %s\n", print_mac(mac, hdr->addr2));
- }
- return -2;
- }
- keyidx >>= 6;
- if (tkey->key_idx != keyidx) {
- printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
- "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
- return -6;
- }
- if (!tkey->key_set) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP: received packet from %s"
- " with keyid=%d that does not have a configured"
- " key\n", print_mac(mac, hdr->addr2), keyidx);
- }
- return -3;
- }
- iv16 = (pos[0] << 8) | pos[2];
- iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
- pos += 8;
-
- if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) {
- if (ieee80211_ratelimit_debug(IEEE80211_DL_DROP)) {
- IEEE80211_DEBUG_DROP("TKIP: replay detected: STA=%s"
- " previous TSC %08x%04x received TSC "
- "%08x%04x\n", print_mac(mac, hdr->addr2),
- tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
- }
- tkey->dot11RSNAStatsTKIPReplays++;
- return -4;
- }
-
- if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
- tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
- tkey->rx_phase1_done = 1;
- }
- tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
-
- plen = skb->len - hdr_len - 12;
-
- crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
- sg_init_one(&sg, pos, plen + 4);
- if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG ": TKIP: failed to decrypt "
- "received packet from %s\n",
- print_mac(mac, hdr->addr2));
- }
- return -7;
- }
-
- crc = ~crc32_le(~0, pos, plen);
- icv[0] = crc;
- icv[1] = crc >> 8;
- icv[2] = crc >> 16;
- icv[3] = crc >> 24;
- if (memcmp(icv, pos + plen, 4) != 0) {
- if (iv32 != tkey->rx_iv32) {
- /* Previously cached Phase1 result was already lost, so
- * it needs to be recalculated for the next packet. */
- tkey->rx_phase1_done = 0;
- }
- if (ieee80211_ratelimit_debug(IEEE80211_DL_DROP)) {
- IEEE80211_DEBUG_DROP("TKIP: ICV error detected: STA="
- "%s\n", print_mac(mac, hdr->addr2));
- }
- tkey->dot11RSNAStatsTKIPICVErrors++;
- return -5;
- }
-
- /* Update real counters only after Michael MIC verification has
- * completed */
- tkey->rx_iv32_new = iv32;
- tkey->rx_iv16_new = iv16;
-
- /* Remove IV and ICV */
- memmove(skb->data + 8, skb->data, hdr_len);
- skb_pull(skb, 8);
- skb_trim(skb, skb->len - 4);
-
- return keyidx;
-}
-
-static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
- u8 * data, size_t data_len, u8 * mic)
-{
- struct hash_desc desc;
- struct scatterlist sg[2];
-
- if (tfm_michael == NULL) {
- printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
- return -1;
- }
- sg_init_table(sg, 2);
- sg_set_buf(&sg[0], hdr, 16);
- sg_set_buf(&sg[1], data, data_len);
-
- if (crypto_hash_setkey(tfm_michael, key, 8))
- return -1;
-
- desc.tfm = tfm_michael;
- desc.flags = 0;
- return crypto_hash_digest(&desc, sg, data_len + 16, mic);
-}
-
-static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
-{
- struct ieee80211_hdr_4addr *hdr11;
- u16 stype;
-
- hdr11 = (struct ieee80211_hdr_4addr *)skb->data;
- stype = WLAN_FC_GET_STYPE(le16_to_cpu(hdr11->frame_ctl));
-
- switch (le16_to_cpu(hdr11->frame_ctl) &
- (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
- case IEEE80211_FCTL_TODS:
- memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
- break;
- case IEEE80211_FCTL_FROMDS:
- memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
- break;
- case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
- memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
- break;
- case 0:
- memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
- break;
- }
-
- if (stype & IEEE80211_STYPE_QOS_DATA) {
- const struct ieee80211_hdr_3addrqos *qoshdr =
- (struct ieee80211_hdr_3addrqos *)skb->data;
- hdr[12] = le16_to_cpu(qoshdr->qos_ctl) & IEEE80211_QCTL_TID;
- } else
- hdr[12] = 0; /* priority */
-
- hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
-}
-
-static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
- void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
- u8 *pos;
-
- if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
- printk(KERN_DEBUG "Invalid packet for Michael MIC add "
- "(tailroom=%d hdr_len=%d skb->len=%d)\n",
- skb_tailroom(skb), hdr_len, skb->len);
- return -1;
- }
-
- michael_mic_hdr(skb, tkey->tx_hdr);
- pos = skb_put(skb, 8);
- if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
- skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
- return -1;
-
- return 0;
-}
-
-static void ieee80211_michael_mic_failure(struct net_device *dev,
- struct ieee80211_hdr_4addr *hdr,
- int keyidx)
-{
- union iwreq_data wrqu;
- struct iw_michaelmicfailure ev;
-
- /* TODO: needed parameters: count, keyid, key type, TSC */
- memset(&ev, 0, sizeof(ev));
- ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
- if (hdr->addr1[0] & 0x01)
- ev.flags |= IW_MICFAILURE_GROUP;
- else
- ev.flags |= IW_MICFAILURE_PAIRWISE;
- ev.src_addr.sa_family = ARPHRD_ETHER;
- memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.data.length = sizeof(ev);
- wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
-}
-
-static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
- int hdr_len, void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
- u8 mic[8];
- DECLARE_MAC_BUF(mac);
-
- if (!tkey->key_set)
- return -1;
-
- michael_mic_hdr(skb, tkey->rx_hdr);
- if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
- skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
- return -1;
- if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
- struct ieee80211_hdr_4addr *hdr;
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- printk(KERN_DEBUG "%s: Michael MIC verification failed for "
- "MSDU from %s keyidx=%d\n",
- skb->dev ? skb->dev->name : "N/A", print_mac(mac, hdr->addr2),
- keyidx);
- if (skb->dev)
- ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
- tkey->dot11RSNAStatsTKIPLocalMICFailures++;
- return -1;
- }
-
- /* Update TSC counters for RX now that the packet verification has
- * completed. */
- tkey->rx_iv32 = tkey->rx_iv32_new;
- tkey->rx_iv16 = tkey->rx_iv16_new;
-
- skb_trim(skb, skb->len - 8);
-
- return 0;
-}
-
-static int ieee80211_tkip_set_key(void *key, int len, u8 * seq, void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
- int keyidx;
- struct crypto_hash *tfm = tkey->tx_tfm_michael;
- struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
- struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
- struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
-
- keyidx = tkey->key_idx;
- memset(tkey, 0, sizeof(*tkey));
- tkey->key_idx = keyidx;
- tkey->tx_tfm_michael = tfm;
- tkey->tx_tfm_arc4 = tfm2;
- tkey->rx_tfm_michael = tfm3;
- tkey->rx_tfm_arc4 = tfm4;
- if (len == TKIP_KEY_LEN) {
- memcpy(tkey->key, key, TKIP_KEY_LEN);
- tkey->key_set = 1;
- tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
- if (seq) {
- tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
- (seq[3] << 8) | seq[2];
- tkey->rx_iv16 = (seq[1] << 8) | seq[0];
- }
- } else if (len == 0)
- tkey->key_set = 0;
- else
- return -1;
-
- return 0;
-}
-
-static int ieee80211_tkip_get_key(void *key, int len, u8 * seq, void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
-
- if (len < TKIP_KEY_LEN)
- return -1;
-
- if (!tkey->key_set)
- return 0;
- memcpy(key, tkey->key, TKIP_KEY_LEN);
-
- if (seq) {
- /* Return the sequence number of the last transmitted frame. */
- u16 iv16 = tkey->tx_iv16;
- u32 iv32 = tkey->tx_iv32;
- if (iv16 == 0)
- iv32--;
- iv16--;
- seq[0] = tkey->tx_iv16;
- seq[1] = tkey->tx_iv16 >> 8;
- seq[2] = tkey->tx_iv32;
- seq[3] = tkey->tx_iv32 >> 8;
- seq[4] = tkey->tx_iv32 >> 16;
- seq[5] = tkey->tx_iv32 >> 24;
- }
-
- return TKIP_KEY_LEN;
-}
-
-static char *ieee80211_tkip_print_stats(char *p, void *priv)
-{
- struct ieee80211_tkip_data *tkip = priv;
- p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
- "tx_pn=%02x%02x%02x%02x%02x%02x "
- "rx_pn=%02x%02x%02x%02x%02x%02x "
- "replays=%d icv_errors=%d local_mic_failures=%d\n",
- tkip->key_idx, tkip->key_set,
- (tkip->tx_iv32 >> 24) & 0xff,
- (tkip->tx_iv32 >> 16) & 0xff,
- (tkip->tx_iv32 >> 8) & 0xff,
- tkip->tx_iv32 & 0xff,
- (tkip->tx_iv16 >> 8) & 0xff,
- tkip->tx_iv16 & 0xff,
- (tkip->rx_iv32 >> 24) & 0xff,
- (tkip->rx_iv32 >> 16) & 0xff,
- (tkip->rx_iv32 >> 8) & 0xff,
- tkip->rx_iv32 & 0xff,
- (tkip->rx_iv16 >> 8) & 0xff,
- tkip->rx_iv16 & 0xff,
- tkip->dot11RSNAStatsTKIPReplays,
- tkip->dot11RSNAStatsTKIPICVErrors,
- tkip->dot11RSNAStatsTKIPLocalMICFailures);
- return p;
-}
-
-static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
- .name = "TKIP",
- .init = ieee80211_tkip_init,
- .deinit = ieee80211_tkip_deinit,
- .build_iv = ieee80211_tkip_hdr,
- .encrypt_mpdu = ieee80211_tkip_encrypt,
- .decrypt_mpdu = ieee80211_tkip_decrypt,
- .encrypt_msdu = ieee80211_michael_mic_add,
- .decrypt_msdu = ieee80211_michael_mic_verify,
- .set_key = ieee80211_tkip_set_key,
- .get_key = ieee80211_tkip_get_key,
- .print_stats = ieee80211_tkip_print_stats,
- .extra_mpdu_prefix_len = 4 + 4, /* IV + ExtIV */
- .extra_mpdu_postfix_len = 4, /* ICV */
- .extra_msdu_postfix_len = 8, /* MIC */
- .get_flags = ieee80211_tkip_get_flags,
- .set_flags = ieee80211_tkip_set_flags,
- .owner = THIS_MODULE,
-};
-
-static int __init ieee80211_crypto_tkip_init(void)
-{
- return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
-}
-
-static void __exit ieee80211_crypto_tkip_exit(void)
-{
- ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
-}
-
-module_init(ieee80211_crypto_tkip_init);
-module_exit(ieee80211_crypto_tkip_exit);
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
deleted file mode 100644
index 3fa30c40779..00000000000
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Host AP crypt: host-based WEP encryption implementation for Host AP driver
- *
- * Copyright (c) 2002-2004, Jouni Malinen <j@w1.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation. See README and COPYING for
- * more details.
- */
-
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/scatterlist.h>
-#include <linux/skbuff.h>
-#include <linux/mm.h>
-#include <asm/string.h>
-
-#include <net/ieee80211.h>
-
-#include <linux/crypto.h>
-#include <linux/crc32.h>
-
-MODULE_AUTHOR("Jouni Malinen");
-MODULE_DESCRIPTION("Host AP crypt: WEP");
-MODULE_LICENSE("GPL");
-
-struct prism2_wep_data {
- u32 iv;
-#define WEP_KEY_LEN 13
- u8 key[WEP_KEY_LEN + 1];
- u8 key_len;
- u8 key_idx;
- struct crypto_blkcipher *tx_tfm;
- struct crypto_blkcipher *rx_tfm;
-};
-
-static void *prism2_wep_init(int keyidx)
-{
- struct prism2_wep_data *priv;
-
- priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
- if (priv == NULL)
- goto fail;
- priv->key_idx = keyidx;
-
- priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->tx_tfm)) {
- printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
- "crypto API arc4\n");
- priv->tx_tfm = NULL;
- goto fail;
- }
-
- priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->rx_tfm)) {
- printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
- "crypto API arc4\n");
- priv->rx_tfm = NULL;
- goto fail;
- }
- /* start WEP IV from a random value */
- get_random_bytes(&priv->iv, 4);
-
- return priv;
-
- fail:
- if (priv) {
- if (priv->tx_tfm)
- crypto_free_blkcipher(priv->tx_tfm);
- if (priv->rx_tfm)
- crypto_free_blkcipher(priv->rx_tfm);
- kfree(priv);
- }
- return NULL;
-}
-
-static void prism2_wep_deinit(void *priv)
-{
- struct prism2_wep_data *_priv = priv;
- if (_priv) {
- if (_priv->tx_tfm)
- crypto_free_blkcipher(_priv->tx_tfm);
- if (_priv->rx_tfm)
- crypto_free_blkcipher(_priv->rx_tfm);
- }
- kfree(priv);
-}
-
-/* Add WEP IV/key info to a frame that has at least 4 bytes of headroom */
-static int prism2_wep_build_iv(struct sk_buff *skb, int hdr_len,
- u8 *key, int keylen, void *priv)
-{
- struct prism2_wep_data *wep = priv;
- u32 klen, len;
- u8 *pos;
-
- if (skb_headroom(skb) < 4 || skb->len < hdr_len)
- return -1;
-
- len = skb->len - hdr_len;
- pos = skb_push(skb, 4);
- memmove(pos, pos + 4, hdr_len);
- pos += hdr_len;
-
- klen = 3 + wep->key_len;
-
- wep->iv++;
-
- /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key
- * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N)
- * can be used to speedup attacks, so avoid using them. */
- if ((wep->iv & 0xff00) == 0xff00) {
- u8 B = (wep->iv >> 16) & 0xff;
- if (B >= 3 && B < klen)
- wep->iv += 0x0100;
- }
-
- /* Prepend 24-bit IV to RC4 key and TX frame */
- *pos++ = (wep->iv >> 16) & 0xff;
- *pos++ = (wep->iv >> 8) & 0xff;
- *pos++ = wep->iv & 0xff;
- *pos++ = wep->key_idx << 6;
-
- return 0;
-}
-
-/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
- * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
- * so the payload length increases with 8 bytes.
- *
- * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
- */
-static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct prism2_wep_data *wep = priv;
- struct blkcipher_desc desc = { .tfm = wep->tx_tfm };
- u32 crc, klen, len;
- u8 *pos, *icv;
- struct scatterlist sg;
- u8 key[WEP_KEY_LEN + 3];
-
- /* other checks are in prism2_wep_build_iv */
- if (skb_tailroom(skb) < 4)
- return -1;
-
- /* add the IV to the frame */
- if (prism2_wep_build_iv(skb, hdr_len, NULL, 0, priv))
- return -1;
-
- /* Copy the IV into the first 3 bytes of the key */
- skb_copy_from_linear_data_offset(skb, hdr_len, key, 3);
-
- /* Copy rest of the WEP key (the secret part) */
- memcpy(key + 3, wep->key, wep->key_len);
-
- len = skb->len - hdr_len - 4;
- pos = skb->data + hdr_len + 4;
- klen = 3 + wep->key_len;
-
- /* Append little-endian CRC32 over only the data and encrypt it to produce ICV */
- crc = ~crc32_le(~0, pos, len);
- icv = skb_put(skb, 4);
- icv[0] = crc;
- icv[1] = crc >> 8;
- icv[2] = crc >> 16;
- icv[3] = crc >> 24;
-
- crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
- sg_init_one(&sg, pos, len + 4);
- return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
-}
-
-/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of
- * the frame: IV (4 bytes), encrypted payload (including SNAP header),
- * ICV (4 bytes). len includes both IV and ICV.
- *
- * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
- * failure. If frame is OK, IV and ICV will be removed.
- */
-static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct prism2_wep_data *wep = priv;
- struct blkcipher_desc desc = { .tfm = wep->rx_tfm };
- u32 crc, klen, plen;
- u8 key[WEP_KEY_LEN + 3];
- u8 keyidx, *pos, icv[4];
- struct scatterlist sg;
-
- if (skb->len < hdr_len + 8)
- return -1;
-
- pos = skb->data + hdr_len;
- key[0] = *pos++;
- key[1] = *pos++;
- key[2] = *pos++;
- keyidx = *pos++ >> 6;
- if (keyidx != wep->key_idx)
- return -1;
-
- klen = 3 + wep->key_len;
-
- /* Copy rest of the WEP key (the secret part) */
- memcpy(key + 3, wep->key, wep->key_len);
-
- /* Apply RC4 to data and compute CRC32 over decrypted data */
- plen = skb->len - hdr_len - 8;
-
- crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
- sg_init_one(&sg, pos, plen + 4);
- if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
- return -7;
-
- crc = ~crc32_le(~0, pos, plen);
- icv[0] = crc;
- icv[1] = crc >> 8;
- icv[2] = crc >> 16;
- icv[3] = crc >> 24;
- if (memcmp(icv, pos + plen, 4) != 0) {
- /* ICV mismatch - drop frame */
- return -2;
- }
-
- /* Remove IV and ICV */
- memmove(skb->data + 4, skb->data, hdr_len);
- skb_pull(skb, 4);
- skb_trim(skb, skb->len - 4);
-
- return 0;
-}
-
-static int prism2_wep_set_key(void *key, int len, u8 * seq, void *priv)
-{
- struct prism2_wep_data *wep = priv;
-
- if (len < 0 || len > WEP_KEY_LEN)
- return -1;
-
- memcpy(wep->key, key, len);
- wep->key_len = len;
-
- return 0;
-}
-
-static int prism2_wep_get_key(void *key, int len, u8 * seq, void *priv)
-{
- struct prism2_wep_data *wep = priv;
-
- if (len < wep->key_len)
- return -1;
-
- memcpy(key, wep->key, wep->key_len);
-
- return wep->key_len;
-}
-
-static char *prism2_wep_print_stats(char *p, void *priv)
-{
- struct prism2_wep_data *wep = priv;
- p += sprintf(p, "key[%d] alg=WEP len=%d\n", wep->key_idx, wep->key_len);
- return p;
-}
-
-static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
- .name = "WEP",
- .init = prism2_wep_init,
- .deinit = prism2_wep_deinit,
- .build_iv = prism2_wep_build_iv,
- .encrypt_mpdu = prism2_wep_encrypt,
- .decrypt_mpdu = prism2_wep_decrypt,
- .encrypt_msdu = NULL,
- .decrypt_msdu = NULL,
- .set_key = prism2_wep_set_key,
- .get_key = prism2_wep_get_key,
- .print_stats = prism2_wep_print_stats,
- .extra_mpdu_prefix_len = 4, /* IV */
- .extra_mpdu_postfix_len = 4, /* ICV */
- .owner = THIS_MODULE,
-};
-
-static int __init ieee80211_crypto_wep_init(void)
-{
- return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
-}
-
-static void __exit ieee80211_crypto_wep_exit(void)
-{
- ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
-}
-
-module_init(ieee80211_crypto_wep_init);
-module_exit(ieee80211_crypto_wep_exit);
diff --git a/net/ieee80211/ieee80211_geo.c b/net/ieee80211/ieee80211_geo.c
deleted file mode 100644
index 960ad13f5e9..00000000000
--- a/net/ieee80211/ieee80211_geo.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/******************************************************************************
-
- Copyright(c) 2005 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
-
- You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
- Contact Information:
- James P. Ketrenos <ipw2100-admin@linux.intel.com>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-******************************************************************************/
-#include <linux/compiler.h>
-#include <linux/errno.h>
-#include <linux/if_arp.h>
-#include <linux/in6.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/proc_fs.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/tcp.h>
-#include <linux/types.h>
-#include <linux/wireless.h>
-#include <linux/etherdevice.h>
-#include <asm/uaccess.h>
-
-#include <net/ieee80211.h>
-
-int ieee80211_is_valid_channel(struct ieee80211_device *ieee, u8 channel)
-{
- int i;
-
- /* Driver needs to initialize the geography map before using
- * these helper functions */
- if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0)
- return 0;
-
- if (ieee->freq_band & IEEE80211_24GHZ_BAND)
- for (i = 0; i < ieee->geo.bg_channels; i++)
- /* NOTE: If G mode is currently supported but
- * this is a B only channel, we don't see it
- * as valid. */
- if ((ieee->geo.bg[i].channel == channel) &&
- !(ieee->geo.bg[i].flags & IEEE80211_CH_INVALID) &&
- (!(ieee->mode & IEEE_G) ||
- !(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY)))
- return IEEE80211_24GHZ_BAND;
-
- if (ieee->freq_band & IEEE80211_52GHZ_BAND)
- for (i = 0; i < ieee->geo.a_channels; i++)
- if ((ieee->geo.a[i].channel == channel) &&
- !(ieee->geo.a[i].flags & IEEE80211_CH_INVALID))
- return IEEE80211_52GHZ_BAND;
-
- return 0;
-}
-
-int ieee80211_channel_to_index(struct ieee80211_device *ieee, u8 channel)
-{
- int i;
-
- /* Driver needs to initialize the geography map before using
- * these helper functions */
- if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0)
- return -1;
-
- if (ieee->freq_band & IEEE80211_24GHZ_BAND)
- for (i = 0; i < ieee->geo.bg_channels; i++)
- if (ieee->geo.bg[i].channel == channel)
- return i;
-
- if (ieee->freq_band & IEEE80211_52GHZ_BAND)
- for (i = 0; i < ieee->geo.a_channels; i++)
- if (ieee->geo.a[i].channel == channel)
- return i;
-
- return -1;
-}
-
-u32 ieee80211_channel_to_freq(struct ieee80211_device * ieee, u8 channel)
-{
- const struct ieee80211_channel * ch;
-
- /* Driver needs to initialize the geography map before using
- * these helper functions */
- if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0)
- return 0;
-
- ch = ieee80211_get_channel(ieee, channel);
- if (!ch->channel)
- return 0;
- return ch->freq;
-}
-
-u8 ieee80211_freq_to_channel(struct ieee80211_device * ieee, u32 freq)
-{
- int i;
-
- /* Driver needs to initialize the geography map before using
- * these helper functions */
- if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0)
- return 0;
-
- freq /= 100000;
-
- if (ieee->freq_band & IEEE80211_24GHZ_BAND)
- for (i = 0; i < ieee->geo.bg_channels; i++)
- if (ieee->geo.bg[i].freq == freq)
- return ieee->geo.bg[i].channel;
-
- if (ieee->freq_band & IEEE80211_52GHZ_BAND)
- for (i = 0; i < ieee->geo.a_channels; i++)
- if (ieee->geo.a[i].freq == freq)
- return ieee->geo.a[i].channel;
-
- return 0;
-}
-
-int ieee80211_set_geo(struct ieee80211_device *ieee,
- const struct ieee80211_geo *geo)
-{
- memcpy(ieee->geo.name, geo->name, 3);
- ieee->geo.name[3] = '\0';
- ieee->geo.bg_channels = geo->bg_channels;
- ieee->geo.a_channels = geo->a_channels;
- memcpy(ieee->geo.bg, geo->bg, geo->bg_channels *
- sizeof(struct ieee80211_channel));
- memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels *
- sizeof(struct ieee80211_channel));
- return 0;
-}
-
-const struct ieee80211_geo *ieee80211_get_geo(struct ieee80211_device *ieee)
-{
- return &ieee->geo;
-}
-
-u8 ieee80211_get_channel_flags(struct ieee80211_device * ieee, u8 channel)
-{
- int index = ieee80211_channel_to_index(ieee, channel);
-
- if (index == -1)
- return IEEE80211_CH_INVALID;
-
- if (channel <= IEEE80211_24GHZ_CHANNELS)
- return ieee->geo.bg[index].flags;
-
- return ieee->geo.a[index].flags;
-}
-
-static const struct ieee80211_channel bad_channel = {
- .channel = 0,
- .flags = IEEE80211_CH_INVALID,
- .max_power = 0,
-};
-
-const struct ieee80211_channel *ieee80211_get_channel(struct ieee80211_device
- *ieee, u8 channel)
-{
- int index = ieee80211_channel_to_index(ieee, channel);
-
- if (index == -1)
- return &bad_channel;
-
- if (channel <= IEEE80211_24GHZ_CHANNELS)
- return &ieee->geo.bg[index];
-
- return &ieee->geo.a[index];
-}
-
-EXPORT_SYMBOL(ieee80211_get_channel);
-EXPORT_SYMBOL(ieee80211_get_channel_flags);
-EXPORT_SYMBOL(ieee80211_is_valid_channel);
-EXPORT_SYMBOL(ieee80211_freq_to_channel);
-EXPORT_SYMBOL(ieee80211_channel_to_freq);
-EXPORT_SYMBOL(ieee80211_channel_to_index);
-EXPORT_SYMBOL(ieee80211_set_geo);
-EXPORT_SYMBOL(ieee80211_get_geo);
diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c
deleted file mode 100644
index 3bca97f55d4..00000000000
--- a/net/ieee80211/ieee80211_module.c
+++ /dev/null
@@ -1,338 +0,0 @@
-/*******************************************************************************
-
- Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
-
- Portions of this file are based on the WEP enablement code provided by the
- Host AP project hostap-drivers v0.1.3
- Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- <j@w1.fi>
- Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
-
- You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
- Contact Information:
- James P. Ketrenos <ipw2100-admin@linux.intel.com>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include <linux/compiler.h>
-#include <linux/errno.h>
-#include <linux/if_arp.h>
-#include <linux/in6.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/proc_fs.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/tcp.h>
-#include <linux/types.h>
-#include <linux/wireless.h>
-#include <linux/etherdevice.h>
-#include <asm/uaccess.h>
-#include <net/net_namespace.h>
-#include <net/arp.h>
-
-#include <net/ieee80211.h>
-
-#define DRV_DESCRIPTION "802.11 data/management/control stack"
-#define DRV_NAME "ieee80211"
-#define DRV_VERSION IEEE80211_VERSION
-#define DRV_COPYRIGHT "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>"
-
-MODULE_VERSION(DRV_VERSION);
-MODULE_DESCRIPTION(DRV_DESCRIPTION);
-MODULE_AUTHOR(DRV_COPYRIGHT);
-MODULE_LICENSE("GPL");
-
-static int ieee80211_networks_allocate(struct ieee80211_device *ieee)
-{
- if (ieee->networks)
- return 0;
-
- ieee->networks =
- kzalloc(MAX_NETWORK_COUNT * sizeof(struct ieee80211_network),
- GFP_KERNEL);
- if (!ieee->networks) {
- printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
- ieee->dev->name);
- return -ENOMEM;
- }
-
- return 0;
-}
-
-void ieee80211_network_reset(struct ieee80211_network *network)
-{
- if (!network)
- return;
-
- if (network->ibss_dfs) {
- kfree(network->ibss_dfs);
- network->ibss_dfs = NULL;
- }
-}
-
-static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
-{
- int i;
-
- if (!ieee->networks)
- return;
-
- for (i = 0; i < MAX_NETWORK_COUNT; i++)
- if (ieee->networks[i].ibss_dfs)
- kfree(ieee->networks[i].ibss_dfs);
-
- kfree(ieee->networks);
- ieee->networks = NULL;
-}
-
-static void ieee80211_networks_initialize(struct ieee80211_device *ieee)
-{
- int i;
-
- INIT_LIST_HEAD(&ieee->network_free_list);
- INIT_LIST_HEAD(&ieee->network_list);
- for (i = 0; i < MAX_NETWORK_COUNT; i++)
- list_add_tail(&ieee->networks[i].list,
- &ieee->network_free_list);
-}
-
-static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
-{
- if ((new_mtu < 68) || (new_mtu > IEEE80211_DATA_LEN))
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-
-static struct net_device_stats *ieee80211_generic_get_stats(
- struct net_device *dev)
-{
- struct ieee80211_device *ieee = netdev_priv(dev);
- return &ieee->stats;
-}
-
-struct net_device *alloc_ieee80211(int sizeof_priv)
-{
- struct ieee80211_device *ieee;
- struct net_device *dev;
- int err;
-
- IEEE80211_DEBUG_INFO("Initializing...\n");
-
- dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
- if (!dev) {
- IEEE80211_ERROR("Unable to allocate network device.\n");
- goto failed;
- }
- ieee = netdev_priv(dev);
- dev->hard_start_xmit = ieee80211_xmit;
- dev->change_mtu = ieee80211_change_mtu;
-
- /* Drivers are free to override this if the generic implementation
- * does not meet their needs. */
- dev->get_stats = ieee80211_generic_get_stats;
-
- ieee->dev = dev;
-
- err = ieee80211_networks_allocate(ieee);
- if (err) {
- IEEE80211_ERROR("Unable to allocate beacon storage: %d\n", err);
- goto failed;
- }
- ieee80211_networks_initialize(ieee);
-
- /* Default fragmentation threshold is maximum payload size */
- ieee->fts = DEFAULT_FTS;
- ieee->rts = DEFAULT_FTS;
- ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
- ieee->open_wep = 1;
-
- /* Default to enabling full open WEP with host based encrypt/decrypt */
- ieee->host_encrypt = 1;
- ieee->host_decrypt = 1;
- ieee->host_mc_decrypt = 1;
-
- /* Host fragementation in Open mode. Default is enabled.
- * Note: host fragmentation is always enabled if host encryption
- * is enabled. For cards can do hardware encryption, they must do
- * hardware fragmentation as well. So we don't need a variable
- * like host_enc_frag. */
- ieee->host_open_frag = 1;
- ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
-
- INIT_LIST_HEAD(&ieee->crypt_deinit_list);
- setup_timer(&ieee->crypt_deinit_timer, ieee80211_crypt_deinit_handler,
- (unsigned long)ieee);
- ieee->crypt_quiesced = 0;
-
- spin_lock_init(&ieee->lock);
-
- ieee->wpa_enabled = 0;
- ieee->drop_unencrypted = 0;
- ieee->privacy_invoked = 0;
-
- return dev;
-
- failed:
- if (dev)
- free_netdev(dev);
- return NULL;
-}
-
-void free_ieee80211(struct net_device *dev)
-{
- struct ieee80211_device *ieee = netdev_priv(dev);
-
- int i;
-
- ieee80211_crypt_quiescing(ieee);
- del_timer_sync(&ieee->crypt_deinit_timer);
- ieee80211_crypt_deinit_entries(ieee, 1);
-
- for (i = 0; i < WEP_KEYS; i++) {
- struct ieee80211_crypt_data *crypt = ieee->crypt[i];
- if (crypt) {
- if (crypt->ops) {
- crypt->ops->deinit(crypt->priv);
- module_put(crypt->ops->owner);
- }
- kfree(crypt);
- ieee->crypt[i] = NULL;
- }
- }
-
- ieee80211_networks_free(ieee);
- free_netdev(dev);
-}
-
-#ifdef CONFIG_IEEE80211_DEBUG
-
-static int debug = 0;
-u32 ieee80211_debug_level = 0;
-EXPORT_SYMBOL_GPL(ieee80211_debug_level);
-static struct proc_dir_entry *ieee80211_proc = NULL;
-
-static int show_debug_level(char *page, char **start, off_t offset,
- int count, int *eof, void *data)
-{
- return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
-}
-
-static int store_debug_level(struct file *file, const char __user * buffer,
- unsigned long count, void *data)
-{
- char buf[] = "0x00000000\n";
- unsigned long len = min((unsigned long)sizeof(buf) - 1, count);
- unsigned long val;
-
- if (copy_from_user(buf, buffer, len))
- return count;
- buf[len] = 0;
- if (sscanf(buf, "%li", &val) != 1)
- printk(KERN_INFO DRV_NAME
- ": %s is not in hex or decimal form.\n", buf);
- else
- ieee80211_debug_level = val;
-
- return strnlen(buf, len);
-}
-#endif /* CONFIG_IEEE80211_DEBUG */
-
-static int __init ieee80211_init(void)
-{
-#ifdef CONFIG_IEEE80211_DEBUG
- struct proc_dir_entry *e;
-
- ieee80211_debug_level = debug;
- ieee80211_proc = proc_mkdir(DRV_NAME, init_net.proc_net);
- if (ieee80211_proc == NULL) {
- IEEE80211_ERROR("Unable to create " DRV_NAME
- " proc directory\n");
- return -EIO;
- }
- e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
- ieee80211_proc);
- if (!e) {
- remove_proc_entry(DRV_NAME, init_net.proc_net);
- ieee80211_proc = NULL;
- return -EIO;
- }
- e->read_proc = show_debug_level;
- e->write_proc = store_debug_level;
- e->data = NULL;
-#endif /* CONFIG_IEEE80211_DEBUG */
-
- printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
- printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
-
- return 0;
-}
-
-static void __exit ieee80211_exit(void)
-{
-#ifdef CONFIG_IEEE80211_DEBUG
- if (ieee80211_proc) {
- remove_proc_entry("debug_level", ieee80211_proc);
- remove_proc_entry(DRV_NAME, init_net.proc_net);
- ieee80211_proc = NULL;
- }
-#endif /* CONFIG_IEEE80211_DEBUG */
-}
-
-#ifdef CONFIG_IEEE80211_DEBUG
-#include <linux/moduleparam.h>
-module_param(debug, int, 0444);
-MODULE_PARM_DESC(debug, "debug output mask");
-#endif /* CONFIG_IEEE80211_DEBUG */
-
-module_exit(ieee80211_exit);
-module_init(ieee80211_init);
-
-const char *escape_essid(const char *essid, u8 essid_len)
-{
- static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
- const char *s = essid;
- char *d = escaped;
-
- if (ieee80211_is_empty_essid(essid, essid_len)) {
- memcpy(escaped, "<hidden>", sizeof("<hidden>"));
- return escaped;
- }
-
- essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE);
- while (essid_len--) {
- if (*s == '\0') {
- *d++ = '\\';
- *d++ = '0';
- s++;
- } else {
- *d++ = *s++;
- }
- }
- *d = '\0';
- return escaped;
-}
-
-EXPORT_SYMBOL(alloc_ieee80211);
-EXPORT_SYMBOL(free_ieee80211);
-EXPORT_SYMBOL(escape_essid);
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
deleted file mode 100644
index 1e3f87c8c01..00000000000
--- a/net/ieee80211/ieee80211_rx.c
+++ /dev/null
@@ -1,1816 +0,0 @@
-/*
- * Original code based Host AP (software wireless LAN access point) driver
- * for Intersil Prism2/2.5/3 - hostap.o module, common routines
- *
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <j@w1.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2005, Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation. See README and COPYING for
- * more details.
- */
-
-#include <linux/compiler.h>
-#include <linux/errno.h>
-#include <linux/if_arp.h>
-#include <linux/in6.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/proc_fs.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/tcp.h>
-#include <linux/types.h>
-#include <linux/wireless.h>
-#include <linux/etherdevice.h>
-#include <asm/uaccess.h>
-#include <linux/ctype.h>
-
-#include <net/ieee80211.h>
-
-static void ieee80211_monitor_rx(struct ieee80211_device *ieee,
- struct sk_buff *skb,
- struct ieee80211_rx_stats *rx_stats)
-{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- u16 fc = le16_to_cpu(hdr->frame_ctl);
-
- skb->dev = ieee->dev;
- skb_reset_mac_header(skb);
- skb_pull(skb, ieee80211_get_hdrlen(fc));
- skb->pkt_type = PACKET_OTHERHOST;
- skb->protocol = htons(ETH_P_80211_RAW);
- memset(skb->cb, 0, sizeof(skb->cb));
- netif_rx(skb);
-}
-
-/* Called only as a tasklet (software IRQ) */
-static struct ieee80211_frag_entry *ieee80211_frag_cache_find(struct
- ieee80211_device
- *ieee,
- unsigned int seq,
- unsigned int frag,
- u8 * src,
- u8 * dst)
-{
- struct ieee80211_frag_entry *entry;
- int i;
-
- for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) {
- entry = &ieee->frag_cache[i];
- if (entry->skb != NULL &&
- time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
- IEEE80211_DEBUG_FRAG("expiring fragment cache entry "
- "seq=%u last_frag=%u\n",
- entry->seq, entry->last_frag);
- dev_kfree_skb_any(entry->skb);
- entry->skb = NULL;
- }
-
- if (entry->skb != NULL && entry->seq == seq &&
- (entry->last_frag + 1 == frag || frag == -1) &&
- !compare_ether_addr(entry->src_addr, src) &&
- !compare_ether_addr(entry->dst_addr, dst))
- return entry;
- }
-
- return NULL;
-}
-
-/* Called only as a tasklet (software IRQ) */
-static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee,
- struct ieee80211_hdr_4addr *hdr)
-{
- struct sk_buff *skb = NULL;
- u16 sc;
- unsigned int frag, seq;
- struct ieee80211_frag_entry *entry;
-
- sc = le16_to_cpu(hdr->seq_ctl);
- frag = WLAN_GET_SEQ_FRAG(sc);
- seq = WLAN_GET_SEQ_SEQ(sc);
-
- if (frag == 0) {
- /* Reserve enough space to fit maximum frame length */
- skb = dev_alloc_skb(ieee->dev->mtu +
- sizeof(struct ieee80211_hdr_4addr) +
- 8 /* LLC */ +
- 2 /* alignment */ +
- 8 /* WEP */ + ETH_ALEN /* WDS */ );
- if (skb == NULL)
- return NULL;
-
- entry = &ieee->frag_cache[ieee->frag_next_idx];
- ieee->frag_next_idx++;
- if (ieee->frag_next_idx >= IEEE80211_FRAG_CACHE_LEN)
- ieee->frag_next_idx = 0;
-
- if (entry->skb != NULL)
- dev_kfree_skb_any(entry->skb);
-
- entry->first_frag_time = jiffies;
- entry->seq = seq;
- entry->last_frag = frag;
- entry->skb = skb;
- memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
- memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
- } else {
- /* received a fragment of a frame for which the head fragment
- * should have already been received */
- entry = ieee80211_frag_cache_find(ieee, seq, frag, hdr->addr2,
- hdr->addr1);
- if (entry != NULL) {
- entry->last_frag = frag;
- skb = entry->skb;
- }
- }
-
- return skb;
-}
-
-/* Called only as a tasklet (software IRQ) */
-static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
- struct ieee80211_hdr_4addr *hdr)
-{
- u16 sc;
- unsigned int seq;
- struct ieee80211_frag_entry *entry;
-
- sc = le16_to_cpu(hdr->seq_ctl);
- seq = WLAN_GET_SEQ_SEQ(sc);
-
- entry = ieee80211_frag_cache_find(ieee, seq, -1, hdr->addr2,
- hdr->addr1);
-
- if (entry == NULL) {
- IEEE80211_DEBUG_FRAG("could not invalidate fragment cache "
- "entry (seq=%u)\n", seq);
- return -1;
- }
-
- entry->skb = NULL;
- return 0;
-}
-
-#ifdef NOT_YET
-/* ieee80211_rx_frame_mgtmt
- *
- * Responsible for handling management control frames
- *
- * Called by ieee80211_rx */
-static int
-ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
- struct ieee80211_rx_stats *rx_stats, u16 type,
- u16 stype)
-{
- if (ieee->iw_mode == IW_MODE_MASTER) {
- printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",
- ieee->dev->name);
- return 0;
-/*
- hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr_4addr *)
- skb->data);*/
- }
-
- if (ieee->hostapd && type == WLAN_FC_TYPE_MGMT) {
- if (stype == WLAN_FC_STYPE_BEACON &&
- ieee->iw_mode == IW_MODE_MASTER) {
- struct sk_buff *skb2;
- /* Process beacon frames also in kernel driver to
- * update STA(AP) table statistics */
- skb2 = skb_clone(skb, GFP_ATOMIC);
- if (skb2)
- hostap_rx(skb2->dev, skb2, rx_stats);
- }
-
- /* send management frames to the user space daemon for
- * processing */
- ieee->apdevstats.rx_packets++;
- ieee->apdevstats.rx_bytes += skb->len;
- prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT);
- return 0;
- }
-
- if (ieee->iw_mode == IW_MODE_MASTER) {
- if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {
- printk(KERN_DEBUG "%s: unknown management frame "
- "(type=0x%02x, stype=0x%02x) dropped\n",
- skb->dev->name, type, stype);
- return -1;
- }
-
- hostap_rx(skb->dev, skb, rx_stats);
- return 0;
- }
-
- printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame "
- "received in non-Host AP mode\n", skb->dev->name);
- return -1;
-}
-#endif
-
-/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
-/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
-static unsigned char rfc1042_header[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
-
-/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
-static unsigned char bridge_tunnel_header[] =
- { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
-/* No encapsulation header if EtherType < 0x600 (=length) */
-
-/* Called by ieee80211_rx_frame_decrypt */
-static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
- struct sk_buff *skb)
-{
- struct net_device *dev = ieee->dev;
- u16 fc, ethertype;
- struct ieee80211_hdr_3addr *hdr;
- u8 *pos;
-
- if (skb->len < 24)
- return 0;
-
- hdr = (struct ieee80211_hdr_3addr *)skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
-
- /* check that the frame is unicast frame to us */
- if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
- IEEE80211_FCTL_TODS &&
- !compare_ether_addr(hdr->addr1, dev->dev_addr) &&
- !compare_ether_addr(hdr->addr3, dev->dev_addr)) {
- /* ToDS frame with own addr BSSID and DA */
- } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
- IEEE80211_FCTL_FROMDS &&
- !compare_ether_addr(hdr->addr1, dev->dev_addr)) {
- /* FromDS frame with own addr as DA */
- } else
- return 0;
-
- if (skb->len < 24 + 8)
- return 0;
-
- /* check for port access entity Ethernet type */
- pos = skb->data + 24;
- ethertype = (pos[6] << 8) | pos[7];
- if (ethertype == ETH_P_PAE)
- return 1;
-
- return 0;
-}
-
-/* Called only as a tasklet (software IRQ), by ieee80211_rx */
-static int
-ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
- struct ieee80211_crypt_data *crypt)
-{
- struct ieee80211_hdr_3addr *hdr;
- int res, hdrlen;
- DECLARE_MAC_BUF(mac);
-
- if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
- return 0;
-
- hdr = (struct ieee80211_hdr_3addr *)skb->data;
- hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
-
- atomic_inc(&crypt->refcnt);
- res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
- atomic_dec(&crypt->refcnt);
- if (res < 0) {
- IEEE80211_DEBUG_DROP("decryption failed (SA=%s"
- ") res=%d\n", print_mac(mac, hdr->addr2), res);
- if (res == -2)
- IEEE80211_DEBUG_DROP("Decryption failed ICV "
- "mismatch (key %d)\n",
- skb->data[hdrlen + 3] >> 6);
- ieee->ieee_stats.rx_discards_undecryptable++;
- return -1;
- }
-
- return res;
-}
-
-/* Called only as a tasklet (software IRQ), by ieee80211_rx */
-static int
-ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
- struct sk_buff *skb, int keyidx,
- struct ieee80211_crypt_data *crypt)
-{
- struct ieee80211_hdr_3addr *hdr;
- int res, hdrlen;
- DECLARE_MAC_BUF(mac);
-
- if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
- return 0;
-
- hdr = (struct ieee80211_hdr_3addr *)skb->data;
- hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
-
- atomic_inc(&crypt->refcnt);
- res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
- atomic_dec(&crypt->refcnt);
- if (res < 0) {
- printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
- " (SA=%s keyidx=%d)\n",
- ieee->dev->name, print_mac(mac, hdr->addr2), keyidx);
- return -1;
- }
-
- return 0;
-}
-
-/* All received frames are sent to this function. @skb contains the frame in
- * IEEE 802.11 format, i.e., in the format it was sent over air.
- * This function is called only as a tasklet (software IRQ). */
-int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
- struct ieee80211_rx_stats *rx_stats)
-{
- struct net_device *dev = ieee->dev;
- struct ieee80211_hdr_4addr *hdr;
- size_t hdrlen;
- u16 fc, type, stype, sc;
- struct net_device_stats *stats;
- unsigned int frag;
- u8 *payload;
- u16 ethertype;
-#ifdef NOT_YET
- struct net_device *wds = NULL;
- struct sk_buff *skb2 = NULL;
- struct net_device *wds = NULL;
- int frame_authorized = 0;
- int from_assoc_ap = 0;
- void *sta = NULL;
-#endif
- u8 dst[ETH_ALEN];
- u8 src[ETH_ALEN];
- struct ieee80211_crypt_data *crypt = NULL;
- int keyidx = 0;
- int can_be_decrypted = 0;
- DECLARE_MAC_BUF(mac);
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- stats = &ieee->stats;
-
- if (skb->len < 10) {
- printk(KERN_INFO "%s: SKB length < 10\n", dev->name);
- goto rx_dropped;
- }
-
- fc = le16_to_cpu(hdr->frame_ctl);
- type = WLAN_FC_GET_TYPE(fc);
- stype = WLAN_FC_GET_STYPE(fc);
- sc = le16_to_cpu(hdr->seq_ctl);
- frag = WLAN_GET_SEQ_FRAG(sc);
- hdrlen = ieee80211_get_hdrlen(fc);
-
- if (skb->len < hdrlen) {
- printk(KERN_INFO "%s: invalid SKB length %d\n",
- dev->name, skb->len);
- goto rx_dropped;
- }
-
- /* Put this code here so that we avoid duplicating it in all
- * Rx paths. - Jean II */
-#ifdef CONFIG_WIRELESS_EXT
-#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
- /* If spy monitoring on */
- if (ieee->spy_data.spy_number > 0) {
- struct iw_quality wstats;
-
- wstats.updated = 0;
- if (rx_stats->mask & IEEE80211_STATMASK_RSSI) {
- wstats.level = rx_stats->rssi;
- wstats.updated |= IW_QUAL_LEVEL_UPDATED;
- } else
- wstats.updated |= IW_QUAL_LEVEL_INVALID;
-
- if (rx_stats->mask & IEEE80211_STATMASK_NOISE) {
- wstats.noise = rx_stats->noise;
- wstats.updated |= IW_QUAL_NOISE_UPDATED;
- } else
- wstats.updated |= IW_QUAL_NOISE_INVALID;
-
- if (rx_stats->mask & IEEE80211_STATMASK_SIGNAL) {
- wstats.qual = rx_stats->signal;
- wstats.updated |= IW_QUAL_QUAL_UPDATED;
- } else
- wstats.updated |= IW_QUAL_QUAL_INVALID;
-
- /* Update spy records */
- wireless_spy_update(ieee->dev, hdr->addr2, &wstats);
- }
-#endif /* IW_WIRELESS_SPY */
-#endif /* CONFIG_WIRELESS_EXT */
-
-#ifdef NOT_YET
- hostap_update_rx_stats(local->ap, hdr, rx_stats);
-#endif
-
- if (ieee->iw_mode == IW_MODE_MONITOR) {
- stats->rx_packets++;
- stats->rx_bytes += skb->len;
- ieee80211_monitor_rx(ieee, skb, rx_stats);
- return 1;
- }
-
- can_be_decrypted = (is_multicast_ether_addr(hdr->addr1) ||
- is_broadcast_ether_addr(hdr->addr2)) ?
- ieee->host_mc_decrypt : ieee->host_decrypt;
-
- if (can_be_decrypted) {
- if (skb->len >= hdrlen + 3) {
- /* Top two-bits of byte 3 are the key index */
- keyidx = skb->data[hdrlen + 3] >> 6;
- }
-
- /* ieee->crypt[] is WEP_KEY (4) in length. Given that keyidx
- * is only allowed 2-bits of storage, no value of keyidx can
- * be provided via above code that would result in keyidx
- * being out of range */
- crypt = ieee->crypt[keyidx];
-
-#ifdef NOT_YET
- sta = NULL;
-
- /* Use station specific key to override default keys if the
- * receiver address is a unicast address ("individual RA"). If
- * bcrx_sta_key parameter is set, station specific key is used
- * even with broad/multicast targets (this is against IEEE
- * 802.11, but makes it easier to use different keys with
- * stations that do not support WEP key mapping). */
-
- if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key)
- (void)hostap_handle_sta_crypto(local, hdr, &crypt,
- &sta);
-#endif
-
- /* allow NULL decrypt to indicate an station specific override
- * for default encryption */
- if (crypt && (crypt->ops == NULL ||
- crypt->ops->decrypt_mpdu == NULL))
- crypt = NULL;
-
- if (!crypt && (fc & IEEE80211_FCTL_PROTECTED)) {
- /* This seems to be triggered by some (multicast?)
- * frames from other than current BSS, so just drop the
- * frames silently instead of filling system log with
- * these reports. */
- IEEE80211_DEBUG_DROP("Decryption failed (not set)"
- " (SA=%s)\n",
- print_mac(mac, hdr->addr2));
- ieee->ieee_stats.rx_discards_undecryptable++;
- goto rx_dropped;
- }
- }
-#ifdef NOT_YET
- if (type != WLAN_FC_TYPE_DATA) {
- if (type == WLAN_FC_TYPE_MGMT && stype == WLAN_FC_STYPE_AUTH &&
- fc & IEEE80211_FCTL_PROTECTED && ieee->host_decrypt &&
- (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0) {
- printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
- "from %s\n", dev->name,
- print_mac(mac, hdr->addr2));
- /* TODO: could inform hostapd about this so that it
- * could send auth failure report */
- goto rx_dropped;
- }
-
- if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
- goto rx_dropped;
- else
- goto rx_exit;
- }
-#endif
- /* drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.29) */
- if (sc == ieee->prev_seq_ctl)
- goto rx_dropped;
- else
- ieee->prev_seq_ctl = sc;
-
- /* Data frame - extract src/dst addresses */
- if (skb->len < IEEE80211_3ADDR_LEN)
- goto rx_dropped;
-
- switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
- case IEEE80211_FCTL_FROMDS:
- memcpy(dst, hdr->addr1, ETH_ALEN);
- memcpy(src, hdr->addr3, ETH_ALEN);
- break;
- case IEEE80211_FCTL_TODS:
- memcpy(dst, hdr->addr3, ETH_ALEN);
- memcpy(src, hdr->addr2, ETH_ALEN);
- break;
- case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
- if (skb->len < IEEE80211_4ADDR_LEN)
- goto rx_dropped;
- memcpy(dst, hdr->addr3, ETH_ALEN);
- memcpy(src, hdr->addr4, ETH_ALEN);
- break;
- case 0:
- memcpy(dst, hdr->addr1, ETH_ALEN);
- memcpy(src, hdr->addr2, ETH_ALEN);
- break;
- }
-
-#ifdef NOT_YET
- if (hostap_rx_frame_wds(ieee, hdr, fc, &wds))
- goto rx_dropped;
- if (wds) {
- skb->dev = dev = wds;
- stats = hostap_get_stats(dev);
- }
-
- if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
- (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
- IEEE80211_FCTL_FROMDS && ieee->stadev
- && !compare_ether_addr(hdr->addr2, ieee->assoc_ap_addr)) {
- /* Frame from BSSID of the AP for which we are a client */
- skb->dev = dev = ieee->stadev;
- stats = hostap_get_stats(dev);
- from_assoc_ap = 1;
- }
-#endif
-
- dev->last_rx = jiffies;
-
-#ifdef NOT_YET
- if ((ieee->iw_mode == IW_MODE_MASTER ||
- ieee->iw_mode == IW_MODE_REPEAT) && !from_assoc_ap) {
- switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats,
- wds != NULL)) {
- case AP_RX_CONTINUE_NOT_AUTHORIZED:
- frame_authorized = 0;
- break;
- case AP_RX_CONTINUE:
- frame_authorized = 1;
- break;
- case AP_RX_DROP:
- goto rx_dropped;
- case AP_RX_EXIT:
- goto rx_exit;
- }
- }
-#endif
-
- /* Nullfunc frames may have PS-bit set, so they must be passed to
- * hostap_handle_sta_rx() before being dropped here. */
-
- stype &= ~IEEE80211_STYPE_QOS_DATA;
-
- if (stype != IEEE80211_STYPE_DATA &&
- stype != IEEE80211_STYPE_DATA_CFACK &&
- stype != IEEE80211_STYPE_DATA_CFPOLL &&
- stype != IEEE80211_STYPE_DATA_CFACKPOLL) {
- if (stype != IEEE80211_STYPE_NULLFUNC)
- IEEE80211_DEBUG_DROP("RX: dropped data frame "
- "with no data (type=0x%02x, "
- "subtype=0x%02x, len=%d)\n",
- type, stype, skb->len);
- goto rx_dropped;
- }
-
- /* skb: hdr + (possibly fragmented, possibly encrypted) payload */
-
- if ((fc & IEEE80211_FCTL_PROTECTED) && can_be_decrypted &&
- (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
- goto rx_dropped;
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
-
- /* skb: hdr + (possibly fragmented) plaintext payload */
- // PR: FIXME: hostap has additional conditions in the "if" below:
- // ieee->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
- if ((frag != 0) || (fc & IEEE80211_FCTL_MOREFRAGS)) {
- int flen;
- struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
- IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
-
- if (!frag_skb) {
- IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG,
- "Rx cannot get skb from fragment "
- "cache (morefrag=%d seq=%u frag=%u)\n",
- (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
- WLAN_GET_SEQ_SEQ(sc), frag);
- goto rx_dropped;
- }
-
- flen = skb->len;
- if (frag != 0)
- flen -= hdrlen;
-
- if (frag_skb->tail + flen > frag_skb->end) {
- printk(KERN_WARNING "%s: host decrypted and "
- "reassembled frame did not fit skb\n",
- dev->name);
- ieee80211_frag_cache_invalidate(ieee, hdr);
- goto rx_dropped;
- }
-
- if (frag == 0) {
- /* copy first fragment (including full headers) into
- * beginning of the fragment cache skb */
- skb_copy_from_linear_data(skb, skb_put(frag_skb, flen), flen);
- } else {
- /* append frame payload to the end of the fragment
- * cache skb */
- skb_copy_from_linear_data_offset(skb, hdrlen,
- skb_put(frag_skb, flen), flen);
- }
- dev_kfree_skb_any(skb);
- skb = NULL;
-
- if (fc & IEEE80211_FCTL_MOREFRAGS) {
- /* more fragments expected - leave the skb in fragment
- * cache for now; it will be delivered to upper layers
- * after all fragments have been received */
- goto rx_exit;
- }
-
- /* this was the last fragment and the frame will be
- * delivered, so remove skb from fragment cache */
- skb = frag_skb;
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- ieee80211_frag_cache_invalidate(ieee, hdr);
- }
-
- /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
- * encrypted/authenticated */
- if ((fc & IEEE80211_FCTL_PROTECTED) && can_be_decrypted &&
- ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
- goto rx_dropped;
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep) {
- if ( /*ieee->ieee802_1x && */
- ieee80211_is_eapol_frame(ieee, skb)) {
- /* pass unencrypted EAPOL frames even if encryption is
- * configured */
- } else {
- IEEE80211_DEBUG_DROP("encryption configured, but RX "
- "frame not encrypted (SA=%s"
- ")\n", print_mac(mac, hdr->addr2));
- goto rx_dropped;
- }
- }
-
- if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep &&
- !ieee80211_is_eapol_frame(ieee, skb)) {
- IEEE80211_DEBUG_DROP("dropped unencrypted RX data "
- "frame from %s"
- " (drop_unencrypted=1)\n",
- print_mac(mac, hdr->addr2));
- goto rx_dropped;
- }
-
- /* If the frame was decrypted in hardware, we may need to strip off
- * any security data (IV, ICV, etc) that was left behind */
- if (!can_be_decrypted && (fc & IEEE80211_FCTL_PROTECTED) &&
- ieee->host_strip_iv_icv) {
- int trimlen = 0;
-
- /* Top two-bits of byte 3 are the key index */
- if (skb->len >= hdrlen + 3)
- keyidx = skb->data[hdrlen + 3] >> 6;
-
- /* To strip off any security data which appears before the
- * payload, we simply increase hdrlen (as the header gets
- * chopped off immediately below). For the security data which
- * appears after the payload, we use skb_trim. */
-
- switch (ieee->sec.encode_alg[keyidx]) {
- case SEC_ALG_WEP:
- /* 4 byte IV */
- hdrlen += 4;
- /* 4 byte ICV */
- trimlen = 4;
- break;
- case SEC_ALG_TKIP:
- /* 4 byte IV, 4 byte ExtIV */
- hdrlen += 8;
- /* 8 byte MIC, 4 byte ICV */
- trimlen = 12;
- break;
- case SEC_ALG_CCMP:
- /* 8 byte CCMP header */
- hdrlen += 8;
- /* 8 byte MIC */
- trimlen = 8;
- break;
- }
-
- if (skb->len < trimlen)
- goto rx_dropped;
-
- __skb_trim(skb, skb->len - trimlen);
-
- if (skb->len < hdrlen)
- goto rx_dropped;
- }
-
- /* skb: hdr + (possible reassembled) full plaintext payload */
-
- payload = skb->data + hdrlen;
- ethertype = (payload[6] << 8) | payload[7];
-
-#ifdef NOT_YET
- /* If IEEE 802.1X is used, check whether the port is authorized to send
- * the received frame. */
- if (ieee->ieee802_1x && ieee->iw_mode == IW_MODE_MASTER) {
- if (ethertype == ETH_P_PAE) {
- printk(KERN_DEBUG "%s: RX: IEEE 802.1X frame\n",
- dev->name);
- if (ieee->hostapd && ieee->apdev) {
- /* Send IEEE 802.1X frames to the user
- * space daemon for processing */
- prism2_rx_80211(ieee->apdev, skb, rx_stats,
- PRISM2_RX_MGMT);
- ieee->apdevstats.rx_packets++;
- ieee->apdevstats.rx_bytes += skb->len;
- goto rx_exit;
- }
- } else if (!frame_authorized) {
- printk(KERN_DEBUG "%s: dropped frame from "
- "unauthorized port (IEEE 802.1X): "
- "ethertype=0x%04x\n", dev->name, ethertype);
- goto rx_dropped;
- }
- }
-#endif
-
- /* convert hdr + possible LLC headers into Ethernet header */
- if (skb->len - hdrlen >= 8 &&
- ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
- ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
- memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
- /* remove RFC1042 or Bridge-Tunnel encapsulation and
- * replace EtherType */
- skb_pull(skb, hdrlen + SNAP_SIZE);
- memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
- memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
- } else {
- __be16 len;
- /* Leave Ethernet header part of hdr and full payload */
- skb_pull(skb, hdrlen);
- len = htons(skb->len);
- memcpy(skb_push(skb, 2), &len, 2);
- memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
- memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
- }
-
-#ifdef NOT_YET
- if (wds && ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
- IEEE80211_FCTL_TODS) && skb->len >= ETH_HLEN + ETH_ALEN) {
- /* Non-standard frame: get addr4 from its bogus location after
- * the payload */
- skb_copy_to_linear_data_offset(skb, ETH_ALEN,
- skb->data + skb->len - ETH_ALEN,
- ETH_ALEN);
- skb_trim(skb, skb->len - ETH_ALEN);
- }
-#endif
-
- stats->rx_packets++;
- stats->rx_bytes += skb->len;
-
-#ifdef NOT_YET
- if (ieee->iw_mode == IW_MODE_MASTER && !wds && ieee->ap->bridge_packets) {
- if (dst[0] & 0x01) {
- /* copy multicast frame both to the higher layers and
- * to the wireless media */
- ieee->ap->bridged_multicast++;
- skb2 = skb_clone(skb, GFP_ATOMIC);
- if (skb2 == NULL)
- printk(KERN_DEBUG "%s: skb_clone failed for "
- "multicast frame\n", dev->name);
- } else if (hostap_is_sta_assoc(ieee->ap, dst)) {
- /* send frame directly to the associated STA using
- * wireless media and not passing to higher layers */
- ieee->ap->bridged_unicast++;
- skb2 = skb;
- skb = NULL;
- }
- }
-
- if (skb2 != NULL) {
- /* send to wireless media */
- skb2->dev = dev;
- skb2->protocol = htons(ETH_P_802_3);
- skb_reset_mac_header(skb2);
- skb_reset_network_header(skb2);
- /* skb2->network_header += ETH_HLEN; */
- dev_queue_xmit(skb2);
- }
-#endif
-
- if (skb) {
- skb->protocol = eth_type_trans(skb, dev);
- memset(skb->cb, 0, sizeof(skb->cb));
- skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
- if (netif_rx(skb) == NET_RX_DROP) {
- /* netif_rx always succeeds, but it might drop
- * the packet. If it drops the packet, we log that
- * in our stats. */
- IEEE80211_DEBUG_DROP
- ("RX: netif_rx dropped the packet\n");
- stats->rx_dropped++;
- }
- }
-
- rx_exit:
-#ifdef NOT_YET
- if (sta)
- hostap_handle_sta_release(sta);
-#endif
- return 1;
-
- rx_dropped:
- stats->rx_dropped++;
-
- /* Returning 0 indicates to caller that we have not handled the SKB--
- * so it is still allocated and can be used again by underlying
- * hardware as a DMA target */
- return 0;
-}
-
-/* Filter out unrelated packets, call ieee80211_rx[_mgt]
- * This function takes over the skb, it should not be used again after calling
- * this function. */
-void ieee80211_rx_any(struct ieee80211_device *ieee,
- struct sk_buff *skb, struct ieee80211_rx_stats *stats)
-{
- struct ieee80211_hdr_4addr *hdr;
- int is_packet_for_us;
- u16 fc;
-
- if (ieee->iw_mode == IW_MODE_MONITOR) {
- if (!ieee80211_rx(ieee, skb, stats))
- dev_kfree_skb_irq(skb);
- return;
- }
-
- if (skb->len < sizeof(struct ieee80211_hdr))
- goto drop_free;
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
-
- if ((fc & IEEE80211_FCTL_VERS) != 0)
- goto drop_free;
-
- switch (fc & IEEE80211_FCTL_FTYPE) {
- case IEEE80211_FTYPE_MGMT:
- if (skb->len < sizeof(struct ieee80211_hdr_3addr))
- goto drop_free;
- ieee80211_rx_mgt(ieee, hdr, stats);
- dev_kfree_skb_irq(skb);
- return;
- case IEEE80211_FTYPE_DATA:
- break;
- case IEEE80211_FTYPE_CTL:
- return;
- default:
- return;
- }
-
- is_packet_for_us = 0;
- switch (ieee->iw_mode) {
- case IW_MODE_ADHOC:
- /* our BSS and not from/to DS */
- if (memcmp(hdr->addr3, ieee->bssid, ETH_ALEN) == 0)
- if ((fc & (IEEE80211_FCTL_TODS+IEEE80211_FCTL_FROMDS)) == 0) {
- /* promisc: get all */
- if (ieee->dev->flags & IFF_PROMISC)
- is_packet_for_us = 1;
- /* to us */
- else if (memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN) == 0)
- is_packet_for_us = 1;
- /* mcast */
- else if (is_multicast_ether_addr(hdr->addr1))
- is_packet_for_us = 1;
- }
- break;
- case IW_MODE_INFRA:
- /* our BSS (== from our AP) and from DS */
- if (memcmp(hdr->addr2, ieee->bssid, ETH_ALEN) == 0)
- if ((fc & (IEEE80211_FCTL_TODS+IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS) {
- /* promisc: get all */
- if (ieee->dev->flags & IFF_PROMISC)
- is_packet_for_us = 1;
- /* to us */
- else if (memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN) == 0)
- is_packet_for_us = 1;
- /* mcast */
- else if (is_multicast_ether_addr(hdr->addr1)) {
- /* not our own packet bcasted from AP */
- if (memcmp(hdr->addr3, ieee->dev->dev_addr, ETH_ALEN))
- is_packet_for_us = 1;
- }
- }
- break;
- default:
- /* ? */
- break;
- }
-
- if (is_packet_for_us)
- if (!ieee80211_rx(ieee, skb, stats))
- dev_kfree_skb_irq(skb);
- return;
-
-drop_free:
- dev_kfree_skb_irq(skb);
- ieee->stats.rx_dropped++;
- return;
-}
-
-#define MGMT_FRAME_FIXED_PART_LENGTH 0x24
-
-static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
-
-/*
-* Make ther structure we read from the beacon packet has
-* the right values
-*/
-static int ieee80211_verify_qos_info(struct ieee80211_qos_information_element
- *info_element, int sub_type)
-{
-
- if (info_element->qui_subtype != sub_type)
- return -1;
- if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN))
- return -1;
- if (info_element->qui_type != QOS_OUI_TYPE)
- return -1;
- if (info_element->version != QOS_VERSION_1)
- return -1;
-
- return 0;
-}
-
-/*
- * Parse a QoS parameter element
- */
-static int ieee80211_read_qos_param_element(struct ieee80211_qos_parameter_info
- *element_param, struct ieee80211_info_element
- *info_element)
-{
- int ret = 0;
- u16 size = sizeof(struct ieee80211_qos_parameter_info) - 2;
-
- if ((info_element == NULL) || (element_param == NULL))
- return -1;
-
- if (info_element->id == QOS_ELEMENT_ID && info_element->len == size) {
- memcpy(element_param->info_element.qui, info_element->data,
- info_element->len);
- element_param->info_element.elementID = info_element->id;
- element_param->info_element.length = info_element->len;
- } else
- ret = -1;
- if (ret == 0)
- ret = ieee80211_verify_qos_info(&element_param->info_element,
- QOS_OUI_PARAM_SUB_TYPE);
- return ret;
-}
-
-/*
- * Parse a QoS information element
- */
-static int ieee80211_read_qos_info_element(struct
- ieee80211_qos_information_element
- *element_info, struct ieee80211_info_element
- *info_element)
-{
- int ret = 0;
- u16 size = sizeof(struct ieee80211_qos_information_element) - 2;
-
- if (element_info == NULL)
- return -1;
- if (info_element == NULL)
- return -1;
-
- if ((info_element->id == QOS_ELEMENT_ID) && (info_element->len == size)) {
- memcpy(element_info->qui, info_element->data,
- info_element->len);
- element_info->elementID = info_element->id;
- element_info->length = info_element->len;
- } else
- ret = -1;
-
- if (ret == 0)
- ret = ieee80211_verify_qos_info(element_info,
- QOS_OUI_INFO_SUB_TYPE);
- return ret;
-}
-
-/*
- * Write QoS parameters from the ac parameters.
- */
-static int ieee80211_qos_convert_ac_to_parameters(struct
- ieee80211_qos_parameter_info
- *param_elm, struct
- ieee80211_qos_parameters
- *qos_param)
-{
- int rc = 0;
- int i;
- struct ieee80211_qos_ac_parameter *ac_params;
- u32 txop;
- u8 cw_min;
- u8 cw_max;
-
- for (i = 0; i < QOS_QUEUE_NUM; i++) {
- ac_params = &(param_elm->ac_params_record[i]);
-
- qos_param->aifs[i] = (ac_params->aci_aifsn) & 0x0F;
- qos_param->aifs[i] -= (qos_param->aifs[i] < 2) ? 0 : 2;
-
- cw_min = ac_params->ecw_min_max & 0x0F;
- qos_param->cw_min[i] = cpu_to_le16((1 << cw_min) - 1);
-
- cw_max = (ac_params->ecw_min_max & 0xF0) >> 4;
- qos_param->cw_max[i] = cpu_to_le16((1 << cw_max) - 1);
-
- qos_param->flag[i] =
- (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00;
-
- txop = le16_to_cpu(ac_params->tx_op_limit) * 32;
- qos_param->tx_op_limit[i] = cpu_to_le16(txop);
- }
- return rc;
-}
-
-/*
- * we have a generic data element which it may contain QoS information or
- * parameters element. check the information element length to decide
- * which type to read
- */
-static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element
- *info_element,
- struct ieee80211_network *network)
-{
- int rc = 0;
- struct ieee80211_qos_parameters *qos_param = NULL;
- struct ieee80211_qos_information_element qos_info_element;
-
- rc = ieee80211_read_qos_info_element(&qos_info_element, info_element);
-
- if (rc == 0) {
- network->qos_data.param_count = qos_info_element.ac_info & 0x0F;
- network->flags |= NETWORK_HAS_QOS_INFORMATION;
- } else {
- struct ieee80211_qos_parameter_info param_element;
-
- rc = ieee80211_read_qos_param_element(&param_element,
- info_element);
- if (rc == 0) {
- qos_param = &(network->qos_data.parameters);
- ieee80211_qos_convert_ac_to_parameters(&param_element,
- qos_param);
- network->flags |= NETWORK_HAS_QOS_PARAMETERS;
- network->qos_data.param_count =
- param_element.info_element.ac_info & 0x0F;
- }
- }
-
- if (rc == 0) {
- IEEE80211_DEBUG_QOS("QoS is supported\n");
- network->qos_data.supported = 1;
- }
- return rc;
-}
-
-#ifdef CONFIG_IEEE80211_DEBUG
-#define MFIE_STRING(x) case MFIE_TYPE_ ##x: return #x
-
-static const char *get_info_element_string(u16 id)
-{
- switch (id) {
- MFIE_STRING(SSID);
- MFIE_STRING(RATES);
- MFIE_STRING(FH_SET);
- MFIE_STRING(DS_SET);
- MFIE_STRING(CF_SET);
- MFIE_STRING(TIM);
- MFIE_STRING(IBSS_SET);
- MFIE_STRING(COUNTRY);
- MFIE_STRING(HOP_PARAMS);
- MFIE_STRING(HOP_TABLE);
- MFIE_STRING(REQUEST);
- MFIE_STRING(CHALLENGE);
- MFIE_STRING(POWER_CONSTRAINT);
- MFIE_STRING(POWER_CAPABILITY);
- MFIE_STRING(TPC_REQUEST);
- MFIE_STRING(TPC_REPORT);
- MFIE_STRING(SUPP_CHANNELS);
- MFIE_STRING(CSA);
- MFIE_STRING(MEASURE_REQUEST);
- MFIE_STRING(MEASURE_REPORT);
- MFIE_STRING(QUIET);
- MFIE_STRING(IBSS_DFS);
- MFIE_STRING(ERP_INFO);
- MFIE_STRING(RSN);
- MFIE_STRING(RATES_EX);
- MFIE_STRING(GENERIC);
- MFIE_STRING(QOS_PARAMETER);
- default:
- return "UNKNOWN";
- }
-}
-#endif
-
-static int ieee80211_parse_info_param(struct ieee80211_info_element
- *info_element, u16 length,
- struct ieee80211_network *network)
-{
- u8 i;
-#ifdef CONFIG_IEEE80211_DEBUG
- char rates_str[64];
- char *p;
-#endif
-
- while (length >= sizeof(*info_element)) {
- if (sizeof(*info_element) + info_element->len > length) {
- IEEE80211_DEBUG_MGMT("Info elem: parse failed: "
- "info_element->len + 2 > left : "
- "info_element->len+2=%zd left=%d, id=%d.\n",
- info_element->len +
- sizeof(*info_element),
- length, info_element->id);
- /* We stop processing but don't return an error here
- * because some misbehaviour APs break this rule. ie.
- * Orinoco AP1000. */
- break;
- }
-
- switch (info_element->id) {
- case MFIE_TYPE_SSID:
- if (ieee80211_is_empty_essid(info_element->data,
- info_element->len)) {
- network->flags |= NETWORK_EMPTY_ESSID;
- break;
- }
-
- network->ssid_len = min(info_element->len,
- (u8) IW_ESSID_MAX_SIZE);
- memcpy(network->ssid, info_element->data,
- network->ssid_len);
- if (network->ssid_len < IW_ESSID_MAX_SIZE)
- memset(network->ssid + network->ssid_len, 0,
- IW_ESSID_MAX_SIZE - network->ssid_len);
-
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n",
- network->ssid, network->ssid_len);
- break;
-
- case MFIE_TYPE_RATES:
-#ifdef CONFIG_IEEE80211_DEBUG
- p = rates_str;
-#endif
- network->rates_len = min(info_element->len,
- MAX_RATES_LENGTH);
- for (i = 0; i < network->rates_len; i++) {
- network->rates[i] = info_element->data[i];
-#ifdef CONFIG_IEEE80211_DEBUG
- p += snprintf(p, sizeof(rates_str) -
- (p - rates_str), "%02X ",
- network->rates[i]);
-#endif
- if (ieee80211_is_ofdm_rate
- (info_element->data[i])) {
- network->flags |= NETWORK_HAS_OFDM;
- if (info_element->data[i] &
- IEEE80211_BASIC_RATE_MASK)
- network->flags &=
- ~NETWORK_HAS_CCK;
- }
- }
-
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n",
- rates_str, network->rates_len);
- break;
-
- case MFIE_TYPE_RATES_EX:
-#ifdef CONFIG_IEEE80211_DEBUG
- p = rates_str;
-#endif
- network->rates_ex_len = min(info_element->len,
- MAX_RATES_EX_LENGTH);
- for (i = 0; i < network->rates_ex_len; i++) {
- network->rates_ex[i] = info_element->data[i];
-#ifdef CONFIG_IEEE80211_DEBUG
- p += snprintf(p, sizeof(rates_str) -
- (p - rates_str), "%02X ",
- network->rates[i]);
-#endif
- if (ieee80211_is_ofdm_rate
- (info_element->data[i])) {
- network->flags |= NETWORK_HAS_OFDM;
- if (info_element->data[i] &
- IEEE80211_BASIC_RATE_MASK)
- network->flags &=
- ~NETWORK_HAS_CCK;
- }
- }
-
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
- rates_str, network->rates_ex_len);
- break;
-
- case MFIE_TYPE_DS_SET:
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n",
- info_element->data[0]);
- network->channel = info_element->data[0];
- break;
-
- case MFIE_TYPE_FH_SET:
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n");
- break;
-
- case MFIE_TYPE_CF_SET:
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n");
- break;
-
- case MFIE_TYPE_TIM:
- network->tim.tim_count = info_element->data[0];
- network->tim.tim_period = info_element->data[1];
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: partially ignored\n");
- break;
-
- case MFIE_TYPE_ERP_INFO:
- network->erp_value = info_element->data[0];
- network->flags |= NETWORK_HAS_ERP_VALUE;
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
- network->erp_value);
- break;
-
- case MFIE_TYPE_IBSS_SET:
- network->atim_window = info_element->data[0];
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n",
- network->atim_window);
- break;
-
- case MFIE_TYPE_CHALLENGE:
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n");
- break;
-
- case MFIE_TYPE_GENERIC:
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n",
- info_element->len);
- if (!ieee80211_parse_qos_info_param_IE(info_element,
- network))
- break;
-
- if (info_element->len >= 4 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x50 &&
- info_element->data[2] == 0xf2 &&
- info_element->data[3] == 0x01) {
- network->wpa_ie_len = min(info_element->len + 2,
- MAX_WPA_IE_LEN);
- memcpy(network->wpa_ie, info_element,
- network->wpa_ie_len);
- }
- break;
-
- case MFIE_TYPE_RSN:
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n",
- info_element->len);
- network->rsn_ie_len = min(info_element->len + 2,
- MAX_WPA_IE_LEN);
- memcpy(network->rsn_ie, info_element,
- network->rsn_ie_len);
- break;
-
- case MFIE_TYPE_QOS_PARAMETER:
- printk(KERN_ERR
- "QoS Error need to parse QOS_PARAMETER IE\n");
- break;
- /* 802.11h */
- case MFIE_TYPE_POWER_CONSTRAINT:
- network->power_constraint = info_element->data[0];
- network->flags |= NETWORK_HAS_POWER_CONSTRAINT;
- break;
-
- case MFIE_TYPE_CSA:
- network->power_constraint = info_element->data[0];
- network->flags |= NETWORK_HAS_CSA;
- break;
-
- case MFIE_TYPE_QUIET:
- network->quiet.count = info_element->data[0];
- network->quiet.period = info_element->data[1];
- network->quiet.duration = info_element->data[2];
- network->quiet.offset = info_element->data[3];
- network->flags |= NETWORK_HAS_QUIET;
- break;
-
- case MFIE_TYPE_IBSS_DFS:
- if (network->ibss_dfs)
- break;
- network->ibss_dfs = kmemdup(info_element->data,
- info_element->len,
- GFP_ATOMIC);
- if (!network->ibss_dfs)
- return 1;
- network->flags |= NETWORK_HAS_IBSS_DFS;
- break;
-
- case MFIE_TYPE_TPC_REPORT:
- network->tpc_report.transmit_power =
- info_element->data[0];
- network->tpc_report.link_margin = info_element->data[1];
- network->flags |= NETWORK_HAS_TPC_REPORT;
- break;
-
- default:
- IEEE80211_DEBUG_MGMT
- ("Unsupported info element: %s (%d)\n",
- get_info_element_string(info_element->id),
- info_element->id);
- break;
- }
-
- length -= sizeof(*info_element) + info_element->len;
- info_element =
- (struct ieee80211_info_element *)&info_element->
- data[info_element->len];
- }
-
- return 0;
-}
-
-static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct ieee80211_assoc_response
- *frame, struct ieee80211_rx_stats *stats)
-{
- struct ieee80211_network network_resp = {
- .ibss_dfs = NULL,
- };
- struct ieee80211_network *network = &network_resp;
- struct net_device *dev = ieee->dev;
-
- network->flags = 0;
- network->qos_data.active = 0;
- network->qos_data.supported = 0;
- network->qos_data.param_count = 0;
- network->qos_data.old_param_count = 0;
-
- //network->atim_window = le16_to_cpu(frame->aid) & (0x3FFF);
- network->atim_window = le16_to_cpu(frame->aid);
- network->listen_interval = le16_to_cpu(frame->status);
- memcpy(network->bssid, frame->header.addr3, ETH_ALEN);
- network->capability = le16_to_cpu(frame->capability);
- network->last_scanned = jiffies;
- network->rates_len = network->rates_ex_len = 0;
- network->last_associate = 0;
- network->ssid_len = 0;
- network->erp_value =
- (network->capability & WLAN_CAPABILITY_IBSS) ? 0x3 : 0x0;
-
- if (stats->freq == IEEE80211_52GHZ_BAND) {
- /* for A band (No DS info) */
- network->channel = stats->received_channel;
- } else
- network->flags |= NETWORK_HAS_CCK;
-
- network->wpa_ie_len = 0;
- network->rsn_ie_len = 0;
-
- if (ieee80211_parse_info_param
- (frame->info_element, stats->len - sizeof(*frame), network))
- return 1;
-
- network->mode = 0;
- if (stats->freq == IEEE80211_52GHZ_BAND)
- network->mode = IEEE_A;
- else {
- if (network->flags & NETWORK_HAS_OFDM)
- network->mode |= IEEE_G;
- if (network->flags & NETWORK_HAS_CCK)
- network->mode |= IEEE_B;
- }
-
- if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
- network->flags |= NETWORK_EMPTY_ESSID;
-
- memcpy(&network->stats, stats, sizeof(network->stats));
-
- if (ieee->handle_assoc_response != NULL)
- ieee->handle_assoc_response(dev, frame, network);
-
- return 0;
-}
-
-/***************************************************/
-
-static int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee80211_probe_response
- *beacon,
- struct ieee80211_network *network,
- struct ieee80211_rx_stats *stats)
-{
- DECLARE_MAC_BUF(mac);
-
- network->qos_data.active = 0;
- network->qos_data.supported = 0;
- network->qos_data.param_count = 0;
- network->qos_data.old_param_count = 0;
-
- /* Pull out fixed field data */
- memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
- network->capability = le16_to_cpu(beacon->capability);
- network->last_scanned = jiffies;
- network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]);
- network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]);
- network->beacon_interval = le16_to_cpu(beacon->beacon_interval);
- /* Where to pull this? beacon->listen_interval; */
- network->listen_interval = 0x0A;
- network->rates_len = network->rates_ex_len = 0;
- network->last_associate = 0;
- network->ssid_len = 0;
- network->flags = 0;
- network->atim_window = 0;
- network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?
- 0x3 : 0x0;
-
- if (stats->freq == IEEE80211_52GHZ_BAND) {
- /* for A band (No DS info) */
- network->channel = stats->received_channel;
- } else
- network->flags |= NETWORK_HAS_CCK;
-
- network->wpa_ie_len = 0;
- network->rsn_ie_len = 0;
-
- if (ieee80211_parse_info_param
- (beacon->info_element, stats->len - sizeof(*beacon), network))
- return 1;
-
- network->mode = 0;
- if (stats->freq == IEEE80211_52GHZ_BAND)
- network->mode = IEEE_A;
- else {
- if (network->flags & NETWORK_HAS_OFDM)
- network->mode |= IEEE_G;
- if (network->flags & NETWORK_HAS_CCK)
- network->mode |= IEEE_B;
- }
-
- if (network->mode == 0) {
- IEEE80211_DEBUG_SCAN("Filtered out '%s (%s)' "
- "network.\n",
- escape_essid(network->ssid,
- network->ssid_len),
- print_mac(mac, network->bssid));
- return 1;
- }
-
- if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
- network->flags |= NETWORK_EMPTY_ESSID;
-
- memcpy(&network->stats, stats, sizeof(network->stats));
-
- return 0;
-}
-
-static inline int is_same_network(struct ieee80211_network *src,
- struct ieee80211_network *dst)
-{
- /* A network is only a duplicate if the channel, BSSID, and ESSID
- * all match. We treat all <hidden> with the same BSSID and channel
- * as one network */
- return ((src->ssid_len == dst->ssid_len) &&
- (src->channel == dst->channel) &&
- !compare_ether_addr(src->bssid, dst->bssid) &&
- !memcmp(src->ssid, dst->ssid, src->ssid_len));
-}
-
-static void update_network(struct ieee80211_network *dst,
- struct ieee80211_network *src)
-{
- int qos_active;
- u8 old_param;
- DECLARE_MAC_BUF(mac);
-
- ieee80211_network_reset(dst);
- dst->ibss_dfs = src->ibss_dfs;
-
- /* We only update the statistics if they were created by receiving
- * the network information on the actual channel the network is on.
- *
- * This keeps beacons received on neighbor channels from bringing
- * down the signal level of an AP. */
- if (dst->channel == src->stats.received_channel)
- memcpy(&dst->stats, &src->stats,
- sizeof(struct ieee80211_rx_stats));
- else
- IEEE80211_DEBUG_SCAN("Network %s info received "
- "off channel (%d vs. %d)\n", print_mac(mac, src->bssid),
- dst->channel, src->stats.received_channel);
-
- dst->capability = src->capability;
- memcpy(dst->rates, src->rates, src->rates_len);
- dst->rates_len = src->rates_len;
- memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
- dst->rates_ex_len = src->rates_ex_len;
-
- dst->mode = src->mode;
- dst->flags = src->flags;
- dst->time_stamp[0] = src->time_stamp[0];
- dst->time_stamp[1] = src->time_stamp[1];
-
- dst->beacon_interval = src->beacon_interval;
- dst->listen_interval = src->listen_interval;
- dst->atim_window = src->atim_window;
- dst->erp_value = src->erp_value;
- dst->tim = src->tim;
-
- memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
- dst->wpa_ie_len = src->wpa_ie_len;
- memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
- dst->rsn_ie_len = src->rsn_ie_len;
-
- dst->last_scanned = jiffies;
- qos_active = src->qos_data.active;
- old_param = dst->qos_data.old_param_count;
- if (dst->flags & NETWORK_HAS_QOS_MASK)
- memcpy(&dst->qos_data, &src->qos_data,
- sizeof(struct ieee80211_qos_data));
- else {
- dst->qos_data.supported = src->qos_data.supported;
- dst->qos_data.param_count = src->qos_data.param_count;
- }
-
- if (dst->qos_data.supported == 1) {
- if (dst->ssid_len)
- IEEE80211_DEBUG_QOS
- ("QoS the network %s is QoS supported\n",
- dst->ssid);
- else
- IEEE80211_DEBUG_QOS
- ("QoS the network is QoS supported\n");
- }
- dst->qos_data.active = qos_active;
- dst->qos_data.old_param_count = old_param;
-
- /* dst->last_associate is not overwritten */
-}
-
-static inline int is_beacon(__le16 fc)
-{
- return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == IEEE80211_STYPE_BEACON);
-}
-
-static void ieee80211_process_probe_response(struct ieee80211_device
- *ieee, struct
- ieee80211_probe_response
- *beacon, struct ieee80211_rx_stats
- *stats)
-{
- struct net_device *dev = ieee->dev;
- struct ieee80211_network network = {
- .ibss_dfs = NULL,
- };
- struct ieee80211_network *target;
- struct ieee80211_network *oldest = NULL;
-#ifdef CONFIG_IEEE80211_DEBUG
- struct ieee80211_info_element *info_element = beacon->info_element;
-#endif
- unsigned long flags;
- DECLARE_MAC_BUF(mac);
-
- IEEE80211_DEBUG_SCAN("'%s' (%s"
- "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
- escape_essid(info_element->data, info_element->len),
- print_mac(mac, beacon->header.addr3),
- (beacon->capability & cpu_to_le16(1 << 0xf)) ? '1' : '0',
- (beacon->capability & cpu_to_le16(1 << 0xe)) ? '1' : '0',
- (beacon->capability & cpu_to_le16(1 << 0xd)) ? '1' : '0',
- (beacon->capability & cpu_to_le16(1 << 0xc)) ? '1' : '0',
- (beacon->capability & cpu_to_le16(1 << 0xb)) ? '1' : '0',
- (beacon->capability & cpu_to_le16(1 << 0xa)) ? '1' : '0',
- (beacon->capability & cpu_to_le16(1 << 0x9)) ? '1' : '0',
- (beacon->capability & cpu_to_le16(1 << 0x8)) ? '1' : '0',
- (beacon->capability & cpu_to_le16(1 << 0x7)) ? '1' : '0',
- (beacon->capability & cpu_to_le16(1 << 0x6)) ? '1' : '0',
- (beacon->capability & cpu_to_le16(1 << 0x5)) ? '1' : '0',
- (beacon->capability & cpu_to_le16(1 << 0x4)) ? '1' : '0',
- (beacon->capability & cpu_to_le16(1 << 0x3)) ? '1' : '0',
- (beacon->capability & cpu_to_le16(1 << 0x2)) ? '1' : '0',
- (beacon->capability & cpu_to_le16(1 << 0x1)) ? '1' : '0',
- (beacon->capability & cpu_to_le16(1 << 0x0)) ? '1' : '0');
-
- if (ieee80211_network_init(ieee, beacon, &network, stats)) {
- IEEE80211_DEBUG_SCAN("Dropped '%s' (%s) via %s.\n",
- escape_essid(info_element->data,
- info_element->len),
- print_mac(mac, beacon->header.addr3),
- is_beacon(beacon->header.frame_ctl) ?
- "BEACON" : "PROBE RESPONSE");
- return;
- }
-
- /* The network parsed correctly -- so now we scan our known networks
- * to see if we can find it in our list.
- *
- * NOTE: This search is definitely not optimized. Once its doing
- * the "right thing" we'll optimize it for efficiency if
- * necessary */
-
- /* Search for this entry in the list and update it if it is
- * already there. */
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- list_for_each_entry(target, &ieee->network_list, list) {
- if (is_same_network(target, &network))
- break;
-
- if ((oldest == NULL) ||
- (target->last_scanned < oldest->last_scanned))
- oldest = target;
- }
-
- /* If we didn't find a match, then get a new network slot to initialize
- * with this beacon's information */
- if (&target->list == &ieee->network_list) {
- if (list_empty(&ieee->network_free_list)) {
- /* If there are no more slots, expire the oldest */
- list_del(&oldest->list);
- target = oldest;
- IEEE80211_DEBUG_SCAN("Expired '%s' (%s) from "
- "network list.\n",
- escape_essid(target->ssid,
- target->ssid_len),
- print_mac(mac, target->bssid));
- ieee80211_network_reset(target);
- } else {
- /* Otherwise just pull from the free list */
- target = list_entry(ieee->network_free_list.next,
- struct ieee80211_network, list);
- list_del(ieee->network_free_list.next);
- }
-
-#ifdef CONFIG_IEEE80211_DEBUG
- IEEE80211_DEBUG_SCAN("Adding '%s' (%s) via %s.\n",
- escape_essid(network.ssid,
- network.ssid_len),
- print_mac(mac, network.bssid),
- is_beacon(beacon->header.frame_ctl) ?
- "BEACON" : "PROBE RESPONSE");
-#endif
- memcpy(target, &network, sizeof(*target));
- network.ibss_dfs = NULL;
- list_add_tail(&target->list, &ieee->network_list);
- } else {
- IEEE80211_DEBUG_SCAN("Updating '%s' (%s) via %s.\n",
- escape_essid(target->ssid,
- target->ssid_len),
- print_mac(mac, target->bssid),
- is_beacon(beacon->header.frame_ctl) ?
- "BEACON" : "PROBE RESPONSE");
- update_network(target, &network);
- network.ibss_dfs = NULL;
- }
-
- spin_unlock_irqrestore(&ieee->lock, flags);
-
- if (is_beacon(beacon->header.frame_ctl)) {
- if (ieee->handle_beacon != NULL)
- ieee->handle_beacon(dev, beacon, target);
- } else {
- if (ieee->handle_probe_response != NULL)
- ieee->handle_probe_response(dev, beacon, target);
- }
-}
-
-void ieee80211_rx_mgt(struct ieee80211_device *ieee,
- struct ieee80211_hdr_4addr *header,
- struct ieee80211_rx_stats *stats)
-{
- switch (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))) {
- case IEEE80211_STYPE_ASSOC_RESP:
- IEEE80211_DEBUG_MGMT("received ASSOCIATION RESPONSE (%d)\n",
- WLAN_FC_GET_STYPE(le16_to_cpu
- (header->frame_ctl)));
- ieee80211_handle_assoc_resp(ieee,
- (struct ieee80211_assoc_response *)
- header, stats);
- break;
-
- case IEEE80211_STYPE_REASSOC_RESP:
- IEEE80211_DEBUG_MGMT("received REASSOCIATION RESPONSE (%d)\n",
- WLAN_FC_GET_STYPE(le16_to_cpu
- (header->frame_ctl)));
- break;
-
- case IEEE80211_STYPE_PROBE_REQ:
- IEEE80211_DEBUG_MGMT("received auth (%d)\n",
- WLAN_FC_GET_STYPE(le16_to_cpu
- (header->frame_ctl)));
-
- if (ieee->handle_probe_request != NULL)
- ieee->handle_probe_request(ieee->dev,
- (struct
- ieee80211_probe_request *)
- header, stats);
- break;
-
- case IEEE80211_STYPE_PROBE_RESP:
- IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
- WLAN_FC_GET_STYPE(le16_to_cpu
- (header->frame_ctl)));
- IEEE80211_DEBUG_SCAN("Probe response\n");
- ieee80211_process_probe_response(ieee,
- (struct
- ieee80211_probe_response *)
- header, stats);
- break;
-
- case IEEE80211_STYPE_BEACON:
- IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
- WLAN_FC_GET_STYPE(le16_to_cpu
- (header->frame_ctl)));
- IEEE80211_DEBUG_SCAN("Beacon\n");
- ieee80211_process_probe_response(ieee,
- (struct
- ieee80211_probe_response *)
- header, stats);
- break;
- case IEEE80211_STYPE_AUTH:
-
- IEEE80211_DEBUG_MGMT("received auth (%d)\n",
- WLAN_FC_GET_STYPE(le16_to_cpu
- (header->frame_ctl)));
-
- if (ieee->handle_auth != NULL)
- ieee->handle_auth(ieee->dev,
- (struct ieee80211_auth *)header);
- break;
-
- case IEEE80211_STYPE_DISASSOC:
- if (ieee->handle_disassoc != NULL)
- ieee->handle_disassoc(ieee->dev,
- (struct ieee80211_disassoc *)
- header);
- break;
-
- case IEEE80211_STYPE_ACTION:
- IEEE80211_DEBUG_MGMT("ACTION\n");
- if (ieee->handle_action)
- ieee->handle_action(ieee->dev,
- (struct ieee80211_action *)
- header, stats);
- break;
-
- case IEEE80211_STYPE_REASSOC_REQ:
- IEEE80211_DEBUG_MGMT("received reassoc (%d)\n",
- WLAN_FC_GET_STYPE(le16_to_cpu
- (header->frame_ctl)));
-
- IEEE80211_DEBUG_MGMT("%s: IEEE80211_REASSOC_REQ received\n",
- ieee->dev->name);
- if (ieee->handle_reassoc_request != NULL)
- ieee->handle_reassoc_request(ieee->dev,
- (struct ieee80211_reassoc_request *)
- header);
- break;
-
- case IEEE80211_STYPE_ASSOC_REQ:
- IEEE80211_DEBUG_MGMT("received assoc (%d)\n",
- WLAN_FC_GET_STYPE(le16_to_cpu
- (header->frame_ctl)));
-
- IEEE80211_DEBUG_MGMT("%s: IEEE80211_ASSOC_REQ received\n",
- ieee->dev->name);
- if (ieee->handle_assoc_request != NULL)
- ieee->handle_assoc_request(ieee->dev);
- break;
-
- case IEEE80211_STYPE_DEAUTH:
- IEEE80211_DEBUG_MGMT("DEAUTH\n");
- if (ieee->handle_deauth != NULL)
- ieee->handle_deauth(ieee->dev,
- (struct ieee80211_deauth *)
- header);
- break;
- default:
- IEEE80211_DEBUG_MGMT("received UNKNOWN (%d)\n",
- WLAN_FC_GET_STYPE(le16_to_cpu
- (header->frame_ctl)));
- IEEE80211_DEBUG_MGMT("%s: Unknown management packet: %d\n",
- ieee->dev->name,
- WLAN_FC_GET_STYPE(le16_to_cpu
- (header->frame_ctl)));
- break;
- }
-}
-
-EXPORT_SYMBOL_GPL(ieee80211_rx_any);
-EXPORT_SYMBOL(ieee80211_rx_mgt);
-EXPORT_SYMBOL(ieee80211_rx);
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c
deleted file mode 100644
index d8b02603cbe..00000000000
--- a/net/ieee80211/ieee80211_tx.c
+++ /dev/null
@@ -1,631 +0,0 @@
-/******************************************************************************
-
- Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
-
- You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
- Contact Information:
- James P. Ketrenos <ipw2100-admin@linux.intel.com>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-******************************************************************************/
-#include <linux/compiler.h>
-#include <linux/errno.h>
-#include <linux/if_arp.h>
-#include <linux/in6.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/proc_fs.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/tcp.h>
-#include <linux/types.h>
-#include <linux/wireless.h>
-#include <linux/etherdevice.h>
-#include <asm/uaccess.h>
-
-#include <net/ieee80211.h>
-
-/*
-
-802.11 Data Frame
-
- ,-------------------------------------------------------------------.
-Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
- |------|------|---------|---------|---------|------|---------|------|
-Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs |
- | | tion | (BSSID) | | | ence | data | |
- `--------------------------------------------------| |------'
-Total: 28 non-data bytes `----.----'
- |
- .- 'Frame data' expands, if WEP enabled, to <----------'
- |
- V
- ,-----------------------.
-Bytes | 4 | 0-2296 | 4 |
- |-----|-----------|-----|
-Desc. | IV | Encrypted | ICV |
- | | Packet | |
- `-----| |-----'
- `-----.-----'
- |
- .- 'Encrypted Packet' expands to
- |
- V
- ,---------------------------------------------------.
-Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 |
- |------|------|---------|----------|------|---------|
-Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP |
- | DSAP | SSAP | | | | Packet |
- | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | |
- `----------------------------------------------------
-Total: 8 non-data bytes
-
-802.3 Ethernet Data Frame
-
- ,-----------------------------------------.
-Bytes | 6 | 6 | 2 | Variable | 4 |
- |-------|-------|------|-----------|------|
-Desc. | Dest. | Source| Type | IP Packet | fcs |
- | MAC | MAC | | | |
- `-----------------------------------------'
-Total: 18 non-data bytes
-
-In the event that fragmentation is required, the incoming payload is split into
-N parts of size ieee->fts. The first fragment contains the SNAP header and the
-remaining packets are just data.
-
-If encryption is enabled, each fragment payload size is reduced by enough space
-to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
-So if you have 1500 bytes of payload with ieee->fts set to 500 without
-encryption it will take 3 frames. With WEP it will take 4 frames as the
-payload of each frame is reduced to 492 bytes.
-
-* SKB visualization
-*
-* ,- skb->data
-* |
-* | ETHERNET HEADER ,-<-- PAYLOAD
-* | | 14 bytes from skb->data
-* | 2 bytes for Type --> ,T. | (sizeof ethhdr)
-* | | | |
-* |,-Dest.--. ,--Src.---. | | |
-* | 6 bytes| | 6 bytes | | | |
-* v | | | | | |
-* 0 | v 1 | v | v 2
-* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
-* ^ | ^ | ^ |
-* | | | | | |
-* | | | | `T' <---- 2 bytes for Type
-* | | | |
-* | | '---SNAP--' <-------- 6 bytes for SNAP
-* | |
-* `-IV--' <-------------------- 4 bytes for IV (WEP)
-*
-* SNAP HEADER
-*
-*/
-
-static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
-static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
-
-static int ieee80211_copy_snap(u8 * data, __be16 h_proto)
-{
- struct ieee80211_snap_hdr *snap;
- u8 *oui;
-
- snap = (struct ieee80211_snap_hdr *)data;
- snap->dsap = 0xaa;
- snap->ssap = 0xaa;
- snap->ctrl = 0x03;
-
- if (h_proto == htons(ETH_P_AARP) || h_proto == htons(ETH_P_IPX))
- oui = P802_1H_OUI;
- else
- oui = RFC1042_OUI;
- snap->oui[0] = oui[0];
- snap->oui[1] = oui[1];
- snap->oui[2] = oui[2];
-
- memcpy(data + SNAP_SIZE, &h_proto, sizeof(u16));
-
- return SNAP_SIZE + sizeof(u16);
-}
-
-static int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
- struct sk_buff *frag, int hdr_len)
-{
- struct ieee80211_crypt_data *crypt = ieee->crypt[ieee->tx_keyidx];
- int res;
-
- if (crypt == NULL)
- return -1;
-
- /* To encrypt, frame format is:
- * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
- atomic_inc(&crypt->refcnt);
- res = 0;
- if (crypt->ops && crypt->ops->encrypt_mpdu)
- res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
-
- atomic_dec(&crypt->refcnt);
- if (res < 0) {
- printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
- ieee->dev->name, frag->len);
- ieee->ieee_stats.tx_discards++;
- return -1;
- }
-
- return 0;
-}
-
-void ieee80211_txb_free(struct ieee80211_txb *txb)
-{
- int i;
- if (unlikely(!txb))
- return;
- for (i = 0; i < txb->nr_frags; i++)
- if (txb->fragments[i])
- dev_kfree_skb_any(txb->fragments[i]);
- kfree(txb);
-}
-
-static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
- int headroom, gfp_t gfp_mask)
-{
- struct ieee80211_txb *txb;
- int i;
- txb = kmalloc(sizeof(struct ieee80211_txb) + (sizeof(u8 *) * nr_frags),
- gfp_mask);
- if (!txb)
- return NULL;
-
- memset(txb, 0, sizeof(struct ieee80211_txb));
- txb->nr_frags = nr_frags;
- txb->frag_size = txb_size;
-
- for (i = 0; i < nr_frags; i++) {
- txb->fragments[i] = __dev_alloc_skb(txb_size + headroom,
- gfp_mask);
- if (unlikely(!txb->fragments[i])) {
- i--;
- break;
- }
- skb_reserve(txb->fragments[i], headroom);
- }
- if (unlikely(i != nr_frags)) {
- while (i >= 0)
- dev_kfree_skb_any(txb->fragments[i--]);
- kfree(txb);
- return NULL;
- }
- return txb;
-}
-
-static int ieee80211_classify(struct sk_buff *skb)
-{
- struct ethhdr *eth;
- struct iphdr *ip;
-
- eth = (struct ethhdr *)skb->data;
- if (eth->h_proto != htons(ETH_P_IP))
- return 0;
-
- ip = ip_hdr(skb);
- switch (ip->tos & 0xfc) {
- case 0x20:
- return 2;
- case 0x40:
- return 1;
- case 0x60:
- return 3;
- case 0x80:
- return 4;
- case 0xa0:
- return 5;
- case 0xc0:
- return 6;
- case 0xe0:
- return 7;
- default:
- return 0;
- }
-}
-
-/* Incoming skb is converted to a txb which consists of
- * a block of 802.11 fragment packets (stored as skbs) */
-int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct ieee80211_device *ieee = netdev_priv(dev);
- struct ieee80211_txb *txb = NULL;
- struct ieee80211_hdr_3addrqos *frag_hdr;
- int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size,
- rts_required;
- unsigned long flags;
- struct net_device_stats *stats = &ieee->stats;
- int encrypt, host_encrypt, host_encrypt_msdu, host_build_iv;
- __be16 ether_type;
- int bytes, fc, hdr_len;
- struct sk_buff *skb_frag;
- struct ieee80211_hdr_3addrqos header = {/* Ensure zero initialized */
- .duration_id = 0,
- .seq_ctl = 0,
- .qos_ctl = 0
- };
- u8 dest[ETH_ALEN], src[ETH_ALEN];
- struct ieee80211_crypt_data *crypt;
- int priority = skb->priority;
- int snapped = 0;
-
- if (ieee->is_queue_full && (*ieee->is_queue_full) (dev, priority))
- return NETDEV_TX_BUSY;
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- /* If there is no driver handler to take the TXB, dont' bother
- * creating it... */
- if (!ieee->hard_start_xmit) {
- printk(KERN_WARNING "%s: No xmit handler.\n", ieee->dev->name);
- goto success;
- }
-
- if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
- printk(KERN_WARNING "%s: skb too small (%d).\n",
- ieee->dev->name, skb->len);
- goto success;
- }
-
- ether_type = ((struct ethhdr *)skb->data)->h_proto;
-
- crypt = ieee->crypt[ieee->tx_keyidx];
-
- encrypt = !(ether_type == htons(ETH_P_PAE) && ieee->ieee802_1x) &&
- ieee->sec.encrypt;
-
- host_encrypt = ieee->host_encrypt && encrypt && crypt;
- host_encrypt_msdu = ieee->host_encrypt_msdu && encrypt && crypt;
- host_build_iv = ieee->host_build_iv && encrypt && crypt;
-
- if (!encrypt && ieee->ieee802_1x &&
- ieee->drop_unencrypted && ether_type != htons(ETH_P_PAE)) {
- stats->tx_dropped++;
- goto success;
- }
-
- /* Save source and destination addresses */
- skb_copy_from_linear_data(skb, dest, ETH_ALEN);
- skb_copy_from_linear_data_offset(skb, ETH_ALEN, src, ETH_ALEN);
-
- if (host_encrypt || host_build_iv)
- fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
- IEEE80211_FCTL_PROTECTED;
- else
- fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
-
- if (ieee->iw_mode == IW_MODE_INFRA) {
- fc |= IEEE80211_FCTL_TODS;
- /* To DS: Addr1 = BSSID, Addr2 = SA, Addr3 = DA */
- memcpy(header.addr1, ieee->bssid, ETH_ALEN);
- memcpy(header.addr2, src, ETH_ALEN);
- memcpy(header.addr3, dest, ETH_ALEN);
- } else if (ieee->iw_mode == IW_MODE_ADHOC) {
- /* not From/To DS: Addr1 = DA, Addr2 = SA, Addr3 = BSSID */
- memcpy(header.addr1, dest, ETH_ALEN);
- memcpy(header.addr2, src, ETH_ALEN);
- memcpy(header.addr3, ieee->bssid, ETH_ALEN);
- }
- hdr_len = IEEE80211_3ADDR_LEN;
-
- if (ieee->is_qos_active && ieee->is_qos_active(dev, skb)) {
- fc |= IEEE80211_STYPE_QOS_DATA;
- hdr_len += 2;
-
- skb->priority = ieee80211_classify(skb);
- header.qos_ctl |= cpu_to_le16(skb->priority & IEEE80211_QCTL_TID);
- }
- header.frame_ctl = cpu_to_le16(fc);
-
- /* Advance the SKB to the start of the payload */
- skb_pull(skb, sizeof(struct ethhdr));
-
- /* Determine total amount of storage required for TXB packets */
- bytes = skb->len + SNAP_SIZE + sizeof(u16);
-
- /* Encrypt msdu first on the whole data packet. */
- if ((host_encrypt || host_encrypt_msdu) &&
- crypt && crypt->ops && crypt->ops->encrypt_msdu) {
- int res = 0;
- int len = bytes + hdr_len + crypt->ops->extra_msdu_prefix_len +
- crypt->ops->extra_msdu_postfix_len;
- struct sk_buff *skb_new = dev_alloc_skb(len);
-
- if (unlikely(!skb_new))
- goto failed;
-
- skb_reserve(skb_new, crypt->ops->extra_msdu_prefix_len);
- memcpy(skb_put(skb_new, hdr_len), &header, hdr_len);
- snapped = 1;
- ieee80211_copy_snap(skb_put(skb_new, SNAP_SIZE + sizeof(u16)),
- ether_type);
- skb_copy_from_linear_data(skb, skb_put(skb_new, skb->len), skb->len);
- res = crypt->ops->encrypt_msdu(skb_new, hdr_len, crypt->priv);
- if (res < 0) {
- IEEE80211_ERROR("msdu encryption failed\n");
- dev_kfree_skb_any(skb_new);
- goto failed;
- }
- dev_kfree_skb_any(skb);
- skb = skb_new;
- bytes += crypt->ops->extra_msdu_prefix_len +
- crypt->ops->extra_msdu_postfix_len;
- skb_pull(skb, hdr_len);
- }
-
- if (host_encrypt || ieee->host_open_frag) {
- /* Determine fragmentation size based on destination (multicast
- * and broadcast are not fragmented) */
- if (is_multicast_ether_addr(dest) ||
- is_broadcast_ether_addr(dest))
- frag_size = MAX_FRAG_THRESHOLD;
- else
- frag_size = ieee->fts;
-
- /* Determine amount of payload per fragment. Regardless of if
- * this stack is providing the full 802.11 header, one will
- * eventually be affixed to this fragment -- so we must account
- * for it when determining the amount of payload space. */
- bytes_per_frag = frag_size - hdr_len;
- if (ieee->config &
- (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
- bytes_per_frag -= IEEE80211_FCS_LEN;
-
- /* Each fragment may need to have room for encryptiong
- * pre/postfix */
- if (host_encrypt)
- bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len +
- crypt->ops->extra_mpdu_postfix_len;
-
- /* Number of fragments is the total
- * bytes_per_frag / payload_per_fragment */
- nr_frags = bytes / bytes_per_frag;
- bytes_last_frag = bytes % bytes_per_frag;
- if (bytes_last_frag)
- nr_frags++;
- else
- bytes_last_frag = bytes_per_frag;
- } else {
- nr_frags = 1;
- bytes_per_frag = bytes_last_frag = bytes;
- frag_size = bytes + hdr_len;
- }
-
- rts_required = (frag_size > ieee->rts
- && ieee->config & CFG_IEEE80211_RTS);
- if (rts_required)
- nr_frags++;
-
- /* When we allocate the TXB we allocate enough space for the reserve
- * and full fragment bytes (bytes_per_frag doesn't include prefix,
- * postfix, header, FCS, etc.) */
- txb = ieee80211_alloc_txb(nr_frags, frag_size,
- ieee->tx_headroom, GFP_ATOMIC);
- if (unlikely(!txb)) {
- printk(KERN_WARNING "%s: Could not allocate TXB\n",
- ieee->dev->name);
- goto failed;
- }
- txb->encrypted = encrypt;
- if (host_encrypt)
- txb->payload_size = frag_size * (nr_frags - 1) +
- bytes_last_frag;
- else
- txb->payload_size = bytes;
-
- if (rts_required) {
- skb_frag = txb->fragments[0];
- frag_hdr =
- (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
-
- /*
- * Set header frame_ctl to the RTS.
- */
- header.frame_ctl =
- cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
- memcpy(frag_hdr, &header, hdr_len);
-
- /*
- * Restore header frame_ctl to the original data setting.
- */
- header.frame_ctl = cpu_to_le16(fc);
-
- if (ieee->config &
- (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
- skb_put(skb_frag, 4);
-
- txb->rts_included = 1;
- i = 1;
- } else
- i = 0;
-
- for (; i < nr_frags; i++) {
- skb_frag = txb->fragments[i];
-
- if (host_encrypt || host_build_iv)
- skb_reserve(skb_frag,
- crypt->ops->extra_mpdu_prefix_len);
-
- frag_hdr =
- (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
- memcpy(frag_hdr, &header, hdr_len);
-
- /* If this is not the last fragment, then add the MOREFRAGS
- * bit to the frame control */
- if (i != nr_frags - 1) {
- frag_hdr->frame_ctl =
- cpu_to_le16(fc | IEEE80211_FCTL_MOREFRAGS);
- bytes = bytes_per_frag;
- } else {
- /* The last fragment takes the remaining length */
- bytes = bytes_last_frag;
- }
-
- if (i == 0 && !snapped) {
- ieee80211_copy_snap(skb_put
- (skb_frag, SNAP_SIZE + sizeof(u16)),
- ether_type);
- bytes -= SNAP_SIZE + sizeof(u16);
- }
-
- skb_copy_from_linear_data(skb, skb_put(skb_frag, bytes), bytes);
-
- /* Advance the SKB... */
- skb_pull(skb, bytes);
-
- /* Encryption routine will move the header forward in order
- * to insert the IV between the header and the payload */
- if (host_encrypt)
- ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
- else if (host_build_iv) {
- atomic_inc(&crypt->refcnt);
- if (crypt->ops->build_iv)
- crypt->ops->build_iv(skb_frag, hdr_len,
- ieee->sec.keys[ieee->sec.active_key],
- ieee->sec.key_sizes[ieee->sec.active_key],
- crypt->priv);
- atomic_dec(&crypt->refcnt);
- }
-
- if (ieee->config &
- (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
- skb_put(skb_frag, 4);
- }
-
- success:
- spin_unlock_irqrestore(&ieee->lock, flags);
-
- dev_kfree_skb_any(skb);
-
- if (txb) {
- int ret = (*ieee->hard_start_xmit) (txb, dev, priority);
- if (ret == 0) {
- stats->tx_packets++;
- stats->tx_bytes += txb->payload_size;
- return 0;
- }
-
- ieee80211_txb_free(txb);
- }
-
- return 0;
-
- failed:
- spin_unlock_irqrestore(&ieee->lock, flags);
- netif_stop_queue(dev);
- stats->tx_errors++;
- return 1;
-}
-
-/* Incoming 802.11 strucure is converted to a TXB
- * a block of 802.11 fragment packets (stored as skbs) */
-int ieee80211_tx_frame(struct ieee80211_device *ieee,
- struct ieee80211_hdr *frame, int hdr_len, int total_len,
- int encrypt_mpdu)
-{
- struct ieee80211_txb *txb = NULL;
- unsigned long flags;
- struct net_device_stats *stats = &ieee->stats;
- struct sk_buff *skb_frag;
- int priority = -1;
- int fraglen = total_len;
- int headroom = ieee->tx_headroom;
- struct ieee80211_crypt_data *crypt = ieee->crypt[ieee->tx_keyidx];
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (encrypt_mpdu && (!ieee->sec.encrypt || !crypt))
- encrypt_mpdu = 0;
-
- /* If there is no driver handler to take the TXB, dont' bother
- * creating it... */
- if (!ieee->hard_start_xmit) {
- printk(KERN_WARNING "%s: No xmit handler.\n", ieee->dev->name);
- goto success;
- }
-
- if (unlikely(total_len < 24)) {
- printk(KERN_WARNING "%s: skb too small (%d).\n",
- ieee->dev->name, total_len);
- goto success;
- }
-
- if (encrypt_mpdu) {
- frame->frame_ctl |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
- fraglen += crypt->ops->extra_mpdu_prefix_len +
- crypt->ops->extra_mpdu_postfix_len;
- headroom += crypt->ops->extra_mpdu_prefix_len;
- }
-
- /* When we allocate the TXB we allocate enough space for the reserve
- * and full fragment bytes (bytes_per_frag doesn't include prefix,
- * postfix, header, FCS, etc.) */
- txb = ieee80211_alloc_txb(1, fraglen, headroom, GFP_ATOMIC);
- if (unlikely(!txb)) {
- printk(KERN_WARNING "%s: Could not allocate TXB\n",
- ieee->dev->name);
- goto failed;
- }
- txb->encrypted = 0;
- txb->payload_size = fraglen;
-
- skb_frag = txb->fragments[0];
-
- memcpy(skb_put(skb_frag, total_len), frame, total_len);
-
- if (ieee->config &
- (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
- skb_put(skb_frag, 4);
-
- /* To avoid overcomplicating things, we do the corner-case frame
- * encryption in software. The only real situation where encryption is
- * needed here is during software-based shared key authentication. */
- if (encrypt_mpdu)
- ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
-
- success:
- spin_unlock_irqrestore(&ieee->lock, flags);
-
- if (txb) {
- if ((*ieee->hard_start_xmit) (txb, ieee->dev, priority) == 0) {
- stats->tx_packets++;
- stats->tx_bytes += txb->payload_size;
- return 0;
- }
- ieee80211_txb_free(txb);
- }
- return 0;
-
- failed:
- spin_unlock_irqrestore(&ieee->lock, flags);
- stats->tx_errors++;
- return 1;
-}
-
-EXPORT_SYMBOL(ieee80211_tx_frame);
-EXPORT_SYMBOL(ieee80211_txb_free);
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
deleted file mode 100644
index 623489afa62..00000000000
--- a/net/ieee80211/ieee80211_wx.c
+++ /dev/null
@@ -1,841 +0,0 @@
-/******************************************************************************
-
- Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
-
- Portions of this file are based on the WEP enablement code provided by the
- Host AP project hostap-drivers v0.1.3
- Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- <j@w1.fi>
- Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
-
- You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
- Contact Information:
- James P. Ketrenos <ipw2100-admin@linux.intel.com>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-******************************************************************************/
-
-#include <linux/kmod.h>
-#include <linux/module.h>
-#include <linux/jiffies.h>
-
-#include <net/ieee80211.h>
-#include <linux/wireless.h>
-
-static const char *ieee80211_modes[] = {
- "?", "a", "b", "ab", "g", "ag", "bg", "abg"
-};
-
-#define MAX_CUSTOM_LEN 64
-static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
- char *start, char *stop,
- struct ieee80211_network *network)
-{
- char custom[MAX_CUSTOM_LEN];
- char *p;
- struct iw_event iwe;
- int i, j;
- char *current_val; /* For rates */
- u8 rate;
-
- /* First entry *MUST* be the AP MAC address */
- iwe.cmd = SIOCGIWAP;
- iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
- memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
-
- /* Remaining entries will be displayed in the order we provide them */
-
- /* Add the ESSID */
- iwe.cmd = SIOCGIWESSID;
- iwe.u.data.flags = 1;
- if (network->flags & NETWORK_EMPTY_ESSID) {
- iwe.u.data.length = sizeof("<hidden>");
- start = iwe_stream_add_point(start, stop, &iwe, "<hidden>");
- } else {
- iwe.u.data.length = min(network->ssid_len, (u8) 32);
- start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
- }
-
- /* Add the protocol name */
- iwe.cmd = SIOCGIWNAME;
- snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s",
- ieee80211_modes[network->mode]);
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_CHAR_LEN);
-
- /* Add mode */
- iwe.cmd = SIOCGIWMODE;
- if (network->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
- if (network->capability & WLAN_CAPABILITY_ESS)
- iwe.u.mode = IW_MODE_MASTER;
- else
- iwe.u.mode = IW_MODE_ADHOC;
-
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN);
- }
-
- /* Add channel and frequency */
- /* Note : userspace automatically computes channel using iwrange */
- iwe.cmd = SIOCGIWFREQ;
- iwe.u.freq.m = ieee80211_channel_to_freq(ieee, network->channel);
- iwe.u.freq.e = 6;
- iwe.u.freq.i = 0;
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
-
- /* Add encryption capability */
- iwe.cmd = SIOCGIWENCODE;
- if (network->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;
- start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
-
- /* Add basic and extended rates */
- /* Rate : stuffing multiple values in a single event require a bit
- * more of magic - Jean II */
- current_val = start + IW_EV_LCP_LEN;
- iwe.cmd = SIOCGIWRATE;
- /* Those two flags are ignored... */
- iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
-
- for (i = 0, j = 0; i < network->rates_len;) {
- if (j < network->rates_ex_len &&
- ((network->rates_ex[j] & 0x7F) <
- (network->rates[i] & 0x7F)))
- rate = network->rates_ex[j++] & 0x7F;
- else
- rate = network->rates[i++] & 0x7F;
- /* Bit rate given in 500 kb/s units (+ 0x80) */
- iwe.u.bitrate.value = ((rate & 0x7f) * 500000);
- /* Add new value to event */
- current_val = iwe_stream_add_value(start, current_val, stop, &iwe, IW_EV_PARAM_LEN);
- }
- for (; j < network->rates_ex_len; j++) {
- rate = network->rates_ex[j] & 0x7F;
- /* Bit rate given in 500 kb/s units (+ 0x80) */
- iwe.u.bitrate.value = ((rate & 0x7f) * 500000);
- /* Add new value to event */
- current_val = iwe_stream_add_value(start, current_val, stop, &iwe, IW_EV_PARAM_LEN);
- }
- /* Check if we added any rate */
- if((current_val - start) > IW_EV_LCP_LEN)
- start = current_val;
-
- /* Add quality statistics */
- iwe.cmd = IWEVQUAL;
- iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |
- IW_QUAL_NOISE_UPDATED;
-
- if (!(network->stats.mask & IEEE80211_STATMASK_RSSI)) {
- iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID |
- IW_QUAL_LEVEL_INVALID;
- iwe.u.qual.qual = 0;
- } else {
- if (ieee->perfect_rssi == ieee->worst_rssi)
- iwe.u.qual.qual = 100;
- else
- iwe.u.qual.qual =
- (100 *
- (ieee->perfect_rssi - ieee->worst_rssi) *
- (ieee->perfect_rssi - ieee->worst_rssi) -
- (ieee->perfect_rssi - network->stats.rssi) *
- (15 * (ieee->perfect_rssi - ieee->worst_rssi) +
- 62 * (ieee->perfect_rssi -
- network->stats.rssi))) /
- ((ieee->perfect_rssi -
- ieee->worst_rssi) * (ieee->perfect_rssi -
- ieee->worst_rssi));
- if (iwe.u.qual.qual > 100)
- iwe.u.qual.qual = 100;
- else if (iwe.u.qual.qual < 1)
- iwe.u.qual.qual = 0;
- }
-
- if (!(network->stats.mask & IEEE80211_STATMASK_NOISE)) {
- iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
- iwe.u.qual.noise = 0;
- } else {
- iwe.u.qual.noise = network->stats.noise;
- }
-
- if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL)) {
- iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
- iwe.u.qual.level = 0;
- } else {
- iwe.u.qual.level = network->stats.signal;
- }
-
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
-
- iwe.cmd = IWEVCUSTOM;
- p = custom;
-
- iwe.u.data.length = p - custom;
- if (iwe.u.data.length)
- start = iwe_stream_add_point(start, stop, &iwe, custom);
-
- memset(&iwe, 0, sizeof(iwe));
- if (network->wpa_ie_len) {
- char buf[MAX_WPA_IE_LEN];
- memcpy(buf, network->wpa_ie, network->wpa_ie_len);
- iwe.cmd = IWEVGENIE;
- iwe.u.data.length = network->wpa_ie_len;
- start = iwe_stream_add_point(start, stop, &iwe, buf);
- }
-
- memset(&iwe, 0, sizeof(iwe));
- if (network->rsn_ie_len) {
- char buf[MAX_WPA_IE_LEN];
- memcpy(buf, network->rsn_ie, network->rsn_ie_len);
- iwe.cmd = IWEVGENIE;
- iwe.u.data.length = network->rsn_ie_len;
- start = iwe_stream_add_point(start, stop, &iwe, buf);
- }
-
- /* Add EXTRA: Age to display seconds since last beacon/probe response
- * for given network. */
- iwe.cmd = IWEVCUSTOM;
- p = custom;
- p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
- " Last beacon: %dms ago",
- jiffies_to_msecs(jiffies - network->last_scanned));
- iwe.u.data.length = p - custom;
- if (iwe.u.data.length)
- start = iwe_stream_add_point(start, stop, &iwe, custom);
-
- /* Add spectrum management information */
- iwe.cmd = -1;
- p = custom;
- p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Channel flags: ");
-
- if (ieee80211_get_channel_flags(ieee, network->channel) &
- IEEE80211_CH_INVALID) {
- iwe.cmd = IWEVCUSTOM;
- p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), "INVALID ");
- }
-
- if (ieee80211_get_channel_flags(ieee, network->channel) &
- IEEE80211_CH_RADAR_DETECT) {
- iwe.cmd = IWEVCUSTOM;
- p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), "DFS ");
- }
-
- if (iwe.cmd == IWEVCUSTOM) {
- iwe.u.data.length = p - custom;
- start = iwe_stream_add_point(start, stop, &iwe, custom);
- }
-
- return start;
-}
-
-#define SCAN_ITEM_SIZE 128
-
-int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ieee80211_network *network;
- unsigned long flags;
- int err = 0;
-
- char *ev = extra;
- char *stop = ev + wrqu->data.length;
- int i = 0;
- DECLARE_MAC_BUF(mac);
-
- IEEE80211_DEBUG_WX("Getting scan\n");
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- list_for_each_entry(network, &ieee->network_list, list) {
- i++;
- if (stop - ev < SCAN_ITEM_SIZE) {
- err = -E2BIG;
- break;
- }
-
- if (ieee->scan_age == 0 ||
- time_after(network->last_scanned + ieee->scan_age, jiffies))
- ev = ieee80211_translate_scan(ieee, ev, stop, network);
- else
- IEEE80211_DEBUG_SCAN("Not showing network '%s ("
- "%s)' due to age (%dms).\n",
- escape_essid(network->ssid,
- network->ssid_len),
- print_mac(mac, network->bssid),
- jiffies_to_msecs(jiffies -
- network->
- last_scanned));
- }
-
- spin_unlock_irqrestore(&ieee->lock, flags);
-
- wrqu->data.length = ev - extra;
- wrqu->data.flags = 0;
-
- IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
-
- return err;
-}
-
-int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *keybuf)
-{
- struct iw_point *erq = &(wrqu->encoding);
- struct net_device *dev = ieee->dev;
- struct ieee80211_security sec = {
- .flags = 0
- };
- int i, key, key_provided, len;
- struct ieee80211_crypt_data **crypt;
- int host_crypto = ieee->host_encrypt || ieee->host_decrypt || ieee->host_build_iv;
-
- IEEE80211_DEBUG_WX("SET_ENCODE\n");
-
- key = erq->flags & IW_ENCODE_INDEX;
- if (key) {
- if (key > WEP_KEYS)
- return -EINVAL;
- key--;
- key_provided = 1;
- } else {
- key_provided = 0;
- key = ieee->tx_keyidx;
- }
-
- IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
- "provided" : "default");
-
- crypt = &ieee->crypt[key];
-
- if (erq->flags & IW_ENCODE_DISABLED) {
- if (key_provided && *crypt) {
- IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
- key);
- ieee80211_crypt_delayed_deinit(ieee, crypt);
- } else
- IEEE80211_DEBUG_WX("Disabling encryption.\n");
-
- /* Check all the keys to see if any are still configured,
- * and if no key index was provided, de-init them all */
- for (i = 0; i < WEP_KEYS; i++) {
- if (ieee->crypt[i] != NULL) {
- if (key_provided)
- break;
- ieee80211_crypt_delayed_deinit(ieee,
- &ieee->crypt[i]);
- }
- }
-
- if (i == WEP_KEYS) {
- sec.enabled = 0;
- sec.encrypt = 0;
- sec.level = SEC_LEVEL_0;
- sec.flags |= SEC_ENABLED | SEC_LEVEL | SEC_ENCRYPT;
- }
-
- goto done;
- }
-
- sec.enabled = 1;
- sec.encrypt = 1;
- sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
-
- if (*crypt != NULL && (*crypt)->ops != NULL &&
- strcmp((*crypt)->ops->name, "WEP") != 0) {
- /* changing to use WEP; deinit previously used algorithm
- * on this key */
- ieee80211_crypt_delayed_deinit(ieee, crypt);
- }
-
- if (*crypt == NULL && host_crypto) {
- struct ieee80211_crypt_data *new_crypt;
-
- /* take WEP into use */
- new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
- GFP_KERNEL);
- if (new_crypt == NULL)
- return -ENOMEM;
- new_crypt->ops = ieee80211_get_crypto_ops("WEP");
- if (!new_crypt->ops) {
- request_module("ieee80211_crypt_wep");
- new_crypt->ops = ieee80211_get_crypto_ops("WEP");
- }
-
- if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
- new_crypt->priv = new_crypt->ops->init(key);
-
- if (!new_crypt->ops || !new_crypt->priv) {
- kfree(new_crypt);
- new_crypt = NULL;
-
- printk(KERN_WARNING "%s: could not initialize WEP: "
- "load module ieee80211_crypt_wep\n", dev->name);
- return -EOPNOTSUPP;
- }
- *crypt = new_crypt;
- }
-
- /* If a new key was provided, set it up */
- if (erq->length > 0) {
- len = erq->length <= 5 ? 5 : 13;
- memcpy(sec.keys[key], keybuf, erq->length);
- if (len > erq->length)
- memset(sec.keys[key] + erq->length, 0,
- len - erq->length);
- IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
- key, escape_essid(sec.keys[key], len),
- erq->length, len);
- sec.key_sizes[key] = len;
- if (*crypt)
- (*crypt)->ops->set_key(sec.keys[key], len, NULL,
- (*crypt)->priv);
- sec.flags |= (1 << key);
- /* This ensures a key will be activated if no key is
- * explicitly set */
- if (key == sec.active_key)
- sec.flags |= SEC_ACTIVE_KEY;
-
- } else {
- if (host_crypto) {
- len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
- NULL, (*crypt)->priv);
- if (len == 0) {
- /* Set a default key of all 0 */
- IEEE80211_DEBUG_WX("Setting key %d to all "
- "zero.\n", key);
- memset(sec.keys[key], 0, 13);
- (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
- (*crypt)->priv);
- sec.key_sizes[key] = 13;
- sec.flags |= (1 << key);
- }
- }
- /* No key data - just set the default TX key index */
- if (key_provided) {
- IEEE80211_DEBUG_WX("Setting key %d to default Tx "
- "key.\n", key);
- ieee->tx_keyidx = key;
- sec.active_key = key;
- sec.flags |= SEC_ACTIVE_KEY;
- }
- }
- if (erq->flags & (IW_ENCODE_OPEN | IW_ENCODE_RESTRICTED)) {
- ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
- sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN :
- WLAN_AUTH_SHARED_KEY;
- sec.flags |= SEC_AUTH_MODE;
- IEEE80211_DEBUG_WX("Auth: %s\n",
- sec.auth_mode == WLAN_AUTH_OPEN ?
- "OPEN" : "SHARED KEY");
- }
-
- /* For now we just support WEP, so only set that security level...
- * TODO: When WPA is added this is one place that needs to change */
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
- sec.encode_alg[key] = SEC_ALG_WEP;
-
- done:
- if (ieee->set_security)
- ieee->set_security(dev, &sec);
-
- /* Do not reset port if card is in Managed mode since resetting will
- * generate new IEEE 802.11 authentication which may end up in looping
- * with IEEE 802.1X. If your hardware requires a reset after WEP
- * configuration (for example... Prism2), implement the reset_port in
- * the callbacks structures used to initialize the 802.11 stack. */
- if (ieee->reset_on_keychange &&
- ieee->iw_mode != IW_MODE_INFRA &&
- ieee->reset_port && ieee->reset_port(dev)) {
- printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
- return -EINVAL;
- }
- return 0;
-}
-
-int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *keybuf)
-{
- struct iw_point *erq = &(wrqu->encoding);
- int len, key;
- struct ieee80211_crypt_data *crypt;
- struct ieee80211_security *sec = &ieee->sec;
-
- IEEE80211_DEBUG_WX("GET_ENCODE\n");
-
- key = erq->flags & IW_ENCODE_INDEX;
- if (key) {
- if (key > WEP_KEYS)
- return -EINVAL;
- key--;
- } else
- key = ieee->tx_keyidx;
-
- crypt = ieee->crypt[key];
- erq->flags = key + 1;
-
- if (!sec->enabled) {
- erq->length = 0;
- erq->flags |= IW_ENCODE_DISABLED;
- return 0;
- }
-
- len = sec->key_sizes[key];
- memcpy(keybuf, sec->keys[key], len);
-
- erq->length = len;
- erq->flags |= IW_ENCODE_ENABLED;
-
- if (ieee->open_wep)
- erq->flags |= IW_ENCODE_OPEN;
- else
- erq->flags |= IW_ENCODE_RESTRICTED;
-
- return 0;
-}
-
-int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct net_device *dev = ieee->dev;
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- int i, idx, ret = 0;
- int group_key = 0;
- const char *alg, *module;
- struct ieee80211_crypto_ops *ops;
- struct ieee80211_crypt_data **crypt;
-
- struct ieee80211_security sec = {
- .flags = 0,
- };
-
- idx = encoding->flags & IW_ENCODE_INDEX;
- if (idx) {
- if (idx < 1 || idx > WEP_KEYS)
- return -EINVAL;
- idx--;
- } else
- idx = ieee->tx_keyidx;
-
- if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
- crypt = &ieee->crypt[idx];
- group_key = 1;
- } else {
- /* some Cisco APs use idx>0 for unicast in dynamic WEP */
- if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
- return -EINVAL;
- if (ieee->iw_mode == IW_MODE_INFRA)
- crypt = &ieee->crypt[idx];
- else
- return -EINVAL;
- }
-
- sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
- if ((encoding->flags & IW_ENCODE_DISABLED) ||
- ext->alg == IW_ENCODE_ALG_NONE) {
- if (*crypt)
- ieee80211_crypt_delayed_deinit(ieee, crypt);
-
- for (i = 0; i < WEP_KEYS; i++)
- if (ieee->crypt[i] != NULL)
- break;
-
- if (i == WEP_KEYS) {
- sec.enabled = 0;
- sec.encrypt = 0;
- sec.level = SEC_LEVEL_0;
- sec.flags |= SEC_LEVEL;
- }
- goto done;
- }
-
- sec.enabled = 1;
- sec.encrypt = 1;
-
- if (group_key ? !ieee->host_mc_decrypt :
- !(ieee->host_encrypt || ieee->host_decrypt ||
- ieee->host_encrypt_msdu))
- goto skip_host_crypt;
-
- switch (ext->alg) {
- case IW_ENCODE_ALG_WEP:
- alg = "WEP";
- module = "ieee80211_crypt_wep";
- break;
- case IW_ENCODE_ALG_TKIP:
- alg = "TKIP";
- module = "ieee80211_crypt_tkip";
- break;
- case IW_ENCODE_ALG_CCMP:
- alg = "CCMP";
- module = "ieee80211_crypt_ccmp";
- break;
- default:
- IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
- dev->name, ext->alg);
- ret = -EINVAL;
- goto done;
- }
-
- ops = ieee80211_get_crypto_ops(alg);
- if (ops == NULL) {
- request_module(module);
- ops = ieee80211_get_crypto_ops(alg);
- }
- if (ops == NULL) {
- IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
- dev->name, ext->alg);
- ret = -EINVAL;
- goto done;
- }
-
- if (*crypt == NULL || (*crypt)->ops != ops) {
- struct ieee80211_crypt_data *new_crypt;
-
- ieee80211_crypt_delayed_deinit(ieee, crypt);
-
- new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
- if (new_crypt == NULL) {
- ret = -ENOMEM;
- goto done;
- }
- new_crypt->ops = ops;
- if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
- new_crypt->priv = new_crypt->ops->init(idx);
- if (new_crypt->priv == NULL) {
- kfree(new_crypt);
- ret = -EINVAL;
- goto done;
- }
- *crypt = new_crypt;
- }
-
- if (ext->key_len > 0 && (*crypt)->ops->set_key &&
- (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
- (*crypt)->priv) < 0) {
- IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
- ret = -EINVAL;
- goto done;
- }
-
- skip_host_crypt:
- if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
- ieee->tx_keyidx = idx;
- sec.active_key = idx;
- sec.flags |= SEC_ACTIVE_KEY;
- }
-
- if (ext->alg != IW_ENCODE_ALG_NONE) {
- memcpy(sec.keys[idx], ext->key, ext->key_len);
- sec.key_sizes[idx] = ext->key_len;
- sec.flags |= (1 << idx);
- if (ext->alg == IW_ENCODE_ALG_WEP) {
- sec.encode_alg[idx] = SEC_ALG_WEP;
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_1;
- } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
- sec.encode_alg[idx] = SEC_ALG_TKIP;
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_2;
- } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
- sec.encode_alg[idx] = SEC_ALG_CCMP;
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_3;
- }
- /* Don't set sec level for group keys. */
- if (group_key)
- sec.flags &= ~SEC_LEVEL;
- }
- done:
- if (ieee->set_security)
- ieee->set_security(ieee->dev, &sec);
-
- /*
- * Do not reset port if card is in Managed mode since resetting will
- * generate new IEEE 802.11 authentication which may end up in looping
- * with IEEE 802.1X. If your hardware requires a reset after WEP
- * configuration (for example... Prism2), implement the reset_port in
- * the callbacks structures used to initialize the 802.11 stack.
- */
- if (ieee->reset_on_keychange &&
- ieee->iw_mode != IW_MODE_INFRA &&
- ieee->reset_port && ieee->reset_port(dev)) {
- IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
- return -EINVAL;
- }
-
- return ret;
-}
-
-int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- struct ieee80211_security *sec = &ieee->sec;
- int idx, max_key_len;
-
- max_key_len = encoding->length - sizeof(*ext);
- if (max_key_len < 0)
- return -EINVAL;
-
- idx = encoding->flags & IW_ENCODE_INDEX;
- if (idx) {
- if (idx < 1 || idx > WEP_KEYS)
- return -EINVAL;
- idx--;
- } else
- idx = ieee->tx_keyidx;
-
- if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
- ext->alg != IW_ENCODE_ALG_WEP)
- if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
- return -EINVAL;
-
- encoding->flags = idx + 1;
- memset(ext, 0, sizeof(*ext));
-
- if (!sec->enabled) {
- ext->alg = IW_ENCODE_ALG_NONE;
- ext->key_len = 0;
- encoding->flags |= IW_ENCODE_DISABLED;
- } else {
- if (sec->encode_alg[idx] == SEC_ALG_WEP)
- ext->alg = IW_ENCODE_ALG_WEP;
- else if (sec->encode_alg[idx] == SEC_ALG_TKIP)
- ext->alg = IW_ENCODE_ALG_TKIP;
- else if (sec->encode_alg[idx] == SEC_ALG_CCMP)
- ext->alg = IW_ENCODE_ALG_CCMP;
- else
- return -EINVAL;
-
- ext->key_len = sec->key_sizes[idx];
- memcpy(ext->key, sec->keys[idx], ext->key_len);
- encoding->flags |= IW_ENCODE_ENABLED;
- if (ext->key_len &&
- (ext->alg == IW_ENCODE_ALG_TKIP ||
- ext->alg == IW_ENCODE_ALG_CCMP))
- ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
-
- }
-
- return 0;
-}
-
-int ieee80211_wx_set_auth(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
-{
- struct ieee80211_device *ieee = netdev_priv(dev);
- unsigned long flags;
- int err = 0;
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- switch (wrqu->param.flags & IW_AUTH_INDEX) {
- case IW_AUTH_WPA_VERSION:
- case IW_AUTH_CIPHER_PAIRWISE:
- case IW_AUTH_CIPHER_GROUP:
- case IW_AUTH_KEY_MGMT:
- /*
- * Host AP driver does not use these parameters and allows
- * wpa_supplicant to control them internally.
- */
- break;
- case IW_AUTH_TKIP_COUNTERMEASURES:
- break; /* FIXME */
- case IW_AUTH_DROP_UNENCRYPTED:
- ieee->drop_unencrypted = !!wrqu->param.value;
- break;
- case IW_AUTH_80211_AUTH_ALG:
- break; /* FIXME */
- case IW_AUTH_WPA_ENABLED:
- ieee->privacy_invoked = ieee->wpa_enabled = !!wrqu->param.value;
- break;
- case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- ieee->ieee802_1x = !!wrqu->param.value;
- break;
- case IW_AUTH_PRIVACY_INVOKED:
- ieee->privacy_invoked = !!wrqu->param.value;
- break;
- default:
- err = -EOPNOTSUPP;
- break;
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
- return err;
-}
-
-int ieee80211_wx_get_auth(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
-{
- struct ieee80211_device *ieee = netdev_priv(dev);
- unsigned long flags;
- int err = 0;
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- switch (wrqu->param.flags & IW_AUTH_INDEX) {
- case IW_AUTH_WPA_VERSION:
- case IW_AUTH_CIPHER_PAIRWISE:
- case IW_AUTH_CIPHER_GROUP:
- case IW_AUTH_KEY_MGMT:
- case IW_AUTH_TKIP_COUNTERMEASURES: /* FIXME */
- case IW_AUTH_80211_AUTH_ALG: /* FIXME */
- /*
- * Host AP driver does not use these parameters and allows
- * wpa_supplicant to control them internally.
- */
- err = -EOPNOTSUPP;
- break;
- case IW_AUTH_DROP_UNENCRYPTED:
- wrqu->param.value = ieee->drop_unencrypted;
- break;
- case IW_AUTH_WPA_ENABLED:
- wrqu->param.value = ieee->wpa_enabled;
- break;
- case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- wrqu->param.value = ieee->ieee802_1x;
- break;
- default:
- err = -EOPNOTSUPP;
- break;
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
- return err;
-}
-
-EXPORT_SYMBOL(ieee80211_wx_set_encodeext);
-EXPORT_SYMBOL(ieee80211_wx_get_encodeext);
-
-EXPORT_SYMBOL(ieee80211_wx_get_scan);
-EXPORT_SYMBOL(ieee80211_wx_set_encode);
-EXPORT_SYMBOL(ieee80211_wx_get_encode);
-
-EXPORT_SYMBOL_GPL(ieee80211_wx_set_auth);
-EXPORT_SYMBOL_GPL(ieee80211_wx_get_auth);
diff --git a/net/ieee80211/softmac/Kconfig b/net/ieee80211/softmac/Kconfig
deleted file mode 100644
index 2811651cb13..00000000000
--- a/net/ieee80211/softmac/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-config IEEE80211_SOFTMAC
- tristate "Software MAC add-on to the IEEE 802.11 networking stack"
- depends on IEEE80211 && EXPERIMENTAL
- select WIRELESS_EXT
- select IEEE80211_CRYPT_WEP
- ---help---
- This option enables the hardware independent software MAC addon
- for the IEEE 802.11 networking stack.
-
-config IEEE80211_SOFTMAC_DEBUG
- bool "Enable full debugging output"
- depends on IEEE80211_SOFTMAC
diff --git a/net/ieee80211/softmac/Makefile b/net/ieee80211/softmac/Makefile
deleted file mode 100644
index bfcb391bb2c..00000000000
--- a/net/ieee80211/softmac/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-obj-$(CONFIG_IEEE80211_SOFTMAC) += ieee80211softmac.o
-ieee80211softmac-objs := \
- ieee80211softmac_io.o \
- ieee80211softmac_auth.o \
- ieee80211softmac_module.o \
- ieee80211softmac_scan.o \
- ieee80211softmac_wx.o \
- ieee80211softmac_assoc.o \
- ieee80211softmac_event.o
diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c
deleted file mode 100644
index c4d122ddd72..00000000000
--- a/net/ieee80211/softmac/ieee80211softmac_assoc.c
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
- * This file contains the softmac's association logic.
- *
- * Copyright (c) 2005, 2006 Johannes Berg <johannes@sipsolutions.net>
- * Joseph Jezak <josejx@gentoo.org>
- * Larry Finger <Larry.Finger@lwfinger.net>
- * Danny van Dyk <kugelfang@gentoo.org>
- * Michael Buesch <mbuesch@freenet.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called COPYING.
- */
-
-#include "ieee80211softmac_priv.h"
-
-/*
- * Overview
- *
- * Before you can associate, you have to authenticate.
- *
- */
-
-/* Sends out an association request to the desired AP */
-static void
-ieee80211softmac_assoc(struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net)
-{
- unsigned long flags;
-
- /* Switch to correct channel for this network */
- mac->set_channel(mac->dev, net->channel);
-
- /* Send association request */
- ieee80211softmac_send_mgt_frame(mac, net, IEEE80211_STYPE_ASSOC_REQ, 0);
-
- dprintk(KERN_INFO PFX "sent association request!\n");
-
- spin_lock_irqsave(&mac->lock, flags);
- mac->associnfo.associated = 0; /* just to make sure */
-
- /* Set a timer for timeout */
- /* FIXME: make timeout configurable */
- if (likely(mac->running))
- queue_delayed_work(mac->wq, &mac->associnfo.timeout, 5 * HZ);
- spin_unlock_irqrestore(&mac->lock, flags);
-}
-
-void
-ieee80211softmac_assoc_timeout(struct work_struct *work)
-{
- struct ieee80211softmac_device *mac =
- container_of(work, struct ieee80211softmac_device,
- associnfo.timeout.work);
- struct ieee80211softmac_network *n;
-
- mutex_lock(&mac->associnfo.mutex);
- /* we might race against ieee80211softmac_handle_assoc_response,
- * so make sure only one of us does something */
- if (!mac->associnfo.associating)
- goto out;
- mac->associnfo.associating = 0;
- mac->associnfo.bssvalid = 0;
- mac->associnfo.associated = 0;
-
- n = ieee80211softmac_get_network_by_bssid_locked(mac, mac->associnfo.bssid);
-
- dprintk(KERN_INFO PFX "assoc request timed out!\n");
- ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, n);
-out:
- mutex_unlock(&mac->associnfo.mutex);
-}
-
-void
-ieee80211softmac_disassoc(struct ieee80211softmac_device *mac)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&mac->lock, flags);
- if (mac->associnfo.associating)
- cancel_delayed_work(&mac->associnfo.timeout);
-
- netif_carrier_off(mac->dev);
-
- mac->associnfo.associated = 0;
- mac->associnfo.bssvalid = 0;
- mac->associnfo.associating = 0;
- ieee80211softmac_init_bss(mac);
- ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL);
- spin_unlock_irqrestore(&mac->lock, flags);
-}
-
-/* Sends out a disassociation request to the desired AP */
-void
-ieee80211softmac_send_disassoc_req(struct ieee80211softmac_device *mac, u16 reason)
-{
- struct ieee80211softmac_network *found;
-
- if (mac->associnfo.bssvalid && mac->associnfo.associated) {
- found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);
- if (found)
- ieee80211softmac_send_mgt_frame(mac, found, IEEE80211_STYPE_DISASSOC, reason);
- }
-
- ieee80211softmac_disassoc(mac);
-}
-
-static inline int
-we_support_all_basic_rates(struct ieee80211softmac_device *mac, u8 *from, u8 from_len)
-{
- int idx;
- u8 rate;
-
- for (idx = 0; idx < (from_len); idx++) {
- rate = (from)[idx];
- if (!(rate & IEEE80211_BASIC_RATE_MASK))
- continue;
- rate &= ~IEEE80211_BASIC_RATE_MASK;
- if (!ieee80211softmac_ratesinfo_rate_supported(&mac->ratesinfo, rate))
- return 0;
- }
- return 1;
-}
-
-static int
-network_matches_request(struct ieee80211softmac_device *mac, struct ieee80211_network *net)
-{
- /* we cannot associate to networks whose name we don't know */
- if (ieee80211_is_empty_essid(net->ssid, net->ssid_len))
- return 0;
- /* do not associate to a network whose BSSBasicRateSet we cannot support */
- if (!we_support_all_basic_rates(mac, net->rates, net->rates_len))
- return 0;
- /* do we really need to check the ex rates? */
- if (!we_support_all_basic_rates(mac, net->rates_ex, net->rates_ex_len))
- return 0;
-
- /* assume that users know what they're doing ...
- * (note we don't let them select a net we're incompatible with) */
- if (mac->associnfo.bssfixed) {
- return !memcmp(mac->associnfo.bssid, net->bssid, ETH_ALEN);
- }
-
- /* if 'ANY' network requested, take any that doesn't have privacy enabled */
- if (mac->associnfo.req_essid.len == 0
- && !(net->capability & WLAN_CAPABILITY_PRIVACY))
- return 1;
- if (net->ssid_len != mac->associnfo.req_essid.len)
- return 0;
- if (!memcmp(net->ssid, mac->associnfo.req_essid.data, mac->associnfo.req_essid.len))
- return 1;
- return 0;
-}
-
-static void
-ieee80211softmac_assoc_notify_scan(struct net_device *dev, int event_type, void *context)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
- ieee80211softmac_assoc_work(&mac->associnfo.work.work);
-}
-
-static void
-ieee80211softmac_assoc_notify_auth(struct net_device *dev, int event_type, void *context)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
-
- switch (event_type) {
- case IEEE80211SOFTMAC_EVENT_AUTHENTICATED:
- ieee80211softmac_assoc_work(&mac->associnfo.work.work);
- break;
- case IEEE80211SOFTMAC_EVENT_AUTH_FAILED:
- case IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT:
- ieee80211softmac_disassoc(mac);
- break;
- }
-}
-
-/* This function is called to handle userspace requests (asynchronously) */
-void
-ieee80211softmac_assoc_work(struct work_struct *work)
-{
- struct ieee80211softmac_device *mac =
- container_of(work, struct ieee80211softmac_device,
- associnfo.work.work);
- struct ieee80211softmac_network *found = NULL;
- struct ieee80211_network *net = NULL, *best = NULL;
- int bssvalid;
- unsigned long flags;
-
- mutex_lock(&mac->associnfo.mutex);
-
- if (!mac->associnfo.associating)
- goto out;
-
- /* ieee80211_disassoc might clear this */
- bssvalid = mac->associnfo.bssvalid;
-
- /* meh */
- if (mac->associnfo.associated)
- ieee80211softmac_send_disassoc_req(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT);
-
- /* try to find the requested network in our list, if we found one already */
- if (bssvalid || mac->associnfo.bssfixed)
- found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);
-
- /* Search the ieee80211 networks for this network if we didn't find it by bssid,
- * but only if we've scanned at least once (to get a better list of networks to
- * select from). If we have not scanned before, the !found logic below will be
- * invoked and will scan. */
- if (!found && (mac->associnfo.scan_retry < IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT))
- {
- s8 rssi = -128; /* if I don't initialise, gcc emits an invalid warning
- because it cannot follow the best pointer logic. */
- spin_lock_irqsave(&mac->ieee->lock, flags);
- list_for_each_entry(net, &mac->ieee->network_list, list) {
- /* we're supposed to find the network with
- * the best signal here, as we're asked to join
- * any network with a specific ESSID, and many
- * different ones could have that.
- *
- * I'll for now just go with the reported rssi.
- *
- * We also should take into account the rateset
- * here to find the best BSSID to try.
- */
- if (network_matches_request(mac, net)) {
- if (!best) {
- best = net;
- rssi = best->stats.rssi;
- continue;
- }
- /* we already had a matching network, so
- * compare their properties to get the
- * better of the two ... (see above)
- */
- if (rssi < net->stats.rssi) {
- best = net;
- rssi = best->stats.rssi;
- }
- }
- }
- /* if we unlock here, we might get interrupted and the `best'
- * pointer could go stale */
- if (best) {
- found = ieee80211softmac_create_network(mac, best);
- /* if found is still NULL, then we got -ENOMEM somewhere */
- if (found)
- ieee80211softmac_add_network(mac, found);
- }
- spin_unlock_irqrestore(&mac->ieee->lock, flags);
- }
-
- if (!found) {
- if (mac->associnfo.scan_retry > 0) {
- mac->associnfo.scan_retry--;
-
- /* We know of no such network. Let's scan.
- * NB: this also happens if we had no memory to copy the network info...
- * Maybe we can hope to have more memory after scanning finishes ;)
- */
- dprintk(KERN_INFO PFX "Associate: Scanning for networks first.\n");
- ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL);
- if (ieee80211softmac_start_scan(mac)) {
- dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n");
- }
- goto out;
- } else {
- mac->associnfo.associating = 0;
- mac->associnfo.associated = 0;
-
- dprintk(KERN_INFO PFX "Unable to find matching network after scan!\n");
- /* reset the retry counter for the next user request since we
- * break out and don't reschedule ourselves after this point. */
- mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT;
- ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND, NULL);
- goto out;
- }
- }
-
- /* reset the retry counter for the next user request since we
- * now found a net and will try to associate to it, but not
- * schedule this function again. */
- mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT;
- mac->associnfo.bssvalid = 1;
- memcpy(mac->associnfo.bssid, found->bssid, ETH_ALEN);
- /* copy the ESSID for displaying it */
- mac->associnfo.associate_essid.len = found->essid.len;
- memcpy(mac->associnfo.associate_essid.data, found->essid.data, IW_ESSID_MAX_SIZE + 1);
-
- /* we found a network! authenticate (if necessary) and associate to it. */
- if (found->authenticating) {
- dprintk(KERN_INFO PFX "Already requested authentication, waiting...\n");
- if(!mac->associnfo.assoc_wait) {
- mac->associnfo.assoc_wait = 1;
- ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL);
- }
- goto out;
- }
- if (!found->authenticated && !found->authenticating) {
- /* This relies on the fact that _auth_req only queues the work,
- * otherwise adding the notification would be racy. */
- if (!ieee80211softmac_auth_req(mac, found)) {
- if(!mac->associnfo.assoc_wait) {
- dprintk(KERN_INFO PFX "Cannot associate without being authenticated, requested authentication\n");
- mac->associnfo.assoc_wait = 1;
- ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL);
- }
- } else {
- printkl(KERN_WARNING PFX "Not authenticated, but requesting authentication failed. Giving up to associate\n");
- mac->associnfo.assoc_wait = 0;
- ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found);
- }
- goto out;
- }
- /* finally! now we can start associating */
- mac->associnfo.assoc_wait = 0;
- ieee80211softmac_assoc(mac, found);
-
-out:
- mutex_unlock(&mac->associnfo.mutex);
-}
-
-/* call this to do whatever is necessary when we're associated */
-static void
-ieee80211softmac_associated(struct ieee80211softmac_device *mac,
- struct ieee80211_assoc_response * resp,
- struct ieee80211softmac_network *net)
-{
- u16 cap = le16_to_cpu(resp->capability);
- u8 erp_value = net->erp_value;
-
- mac->associnfo.associating = 0;
- mac->bssinfo.supported_rates = net->supported_rates;
- ieee80211softmac_recalc_txrates(mac);
-
- mac->associnfo.associated = 1;
-
- mac->associnfo.short_preamble_available =
- (cap & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0;
- ieee80211softmac_process_erp(mac, erp_value);
-
- if (mac->set_bssid_filter)
- mac->set_bssid_filter(mac->dev, net->bssid);
- memcpy(mac->ieee->bssid, net->bssid, ETH_ALEN);
- netif_carrier_on(mac->dev);
-
- mac->association_id = le16_to_cpup(&resp->aid);
-}
-
-/* received frame handling functions */
-int
-ieee80211softmac_handle_assoc_response(struct net_device * dev,
- struct ieee80211_assoc_response * resp,
- struct ieee80211_network * _ieee80211_network)
-{
- /* NOTE: the network parameter has to be mostly ignored by
- * this code because it is the ieee80211's pointer
- * to the struct, not ours (we made a copy)
- */
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
- u16 status = le16_to_cpup(&resp->status);
- struct ieee80211softmac_network *network = NULL;
- unsigned long flags;
- DECLARE_MAC_BUF(mac2);
-
- if (unlikely(!mac->running))
- return -ENODEV;
-
- spin_lock_irqsave(&mac->lock, flags);
-
- if (!mac->associnfo.associating) {
- /* we race against the timeout function, so make sure
- * only one of us can do work */
- spin_unlock_irqrestore(&mac->lock, flags);
- return 0;
- }
- network = ieee80211softmac_get_network_by_bssid_locked(mac, resp->header.addr3);
-
- /* someone sending us things without us knowing him? Ignore. */
- if (!network) {
- dprintk(KERN_INFO PFX "Received unrequested assocation response from %s\n",
- print_mac(mac2, resp->header.addr3));
- spin_unlock_irqrestore(&mac->lock, flags);
- return 0;
- }
-
- /* now that we know it was for us, we can cancel the timeout */
- cancel_delayed_work(&mac->associnfo.timeout);
-
- /* if the association response included an ERP IE, update our saved
- * copy */
- if (_ieee80211_network->flags & NETWORK_HAS_ERP_VALUE)
- network->erp_value = _ieee80211_network->erp_value;
-
- switch (status) {
- case 0:
- dprintk(KERN_INFO PFX "associated!\n");
- ieee80211softmac_associated(mac, resp, network);
- ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATED, network);
- break;
- case WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH:
- if (!network->auth_desynced_once) {
- /* there seem to be a few rare cases where our view of
- * the world is obscured, or buggy APs that don't DEAUTH
- * us properly. So we handle that, but allow it only once.
- */
- printkl(KERN_INFO PFX "We were not authenticated during association, retrying...\n");
- network->authenticated = 0;
- /* we don't want to do this more than once ... */
- network->auth_desynced_once = 1;
- queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
- break;
- }
- default:
- dprintk(KERN_INFO PFX "associating failed (reason: 0x%x)!\n", status);
- mac->associnfo.associating = 0;
- mac->associnfo.bssvalid = 0;
- mac->associnfo.associated = 0;
- ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, network);
- }
-
- spin_unlock_irqrestore(&mac->lock, flags);
- return 0;
-}
-
-void
-ieee80211softmac_try_reassoc(struct ieee80211softmac_device *mac)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&mac->lock, flags);
- mac->associnfo.associating = 1;
- queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
- spin_unlock_irqrestore(&mac->lock, flags);
-}
-
-int
-ieee80211softmac_handle_disassoc(struct net_device * dev,
- struct ieee80211_disassoc *disassoc)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
-
- if (unlikely(!mac->running))
- return -ENODEV;
-
- if (memcmp(disassoc->header.addr2, mac->associnfo.bssid, ETH_ALEN))
- return 0;
-
- if (memcmp(disassoc->header.addr1, mac->dev->dev_addr, ETH_ALEN))
- return 0;
-
- dprintk(KERN_INFO PFX "got disassoc frame\n");
- ieee80211softmac_disassoc(mac);
-
- ieee80211softmac_try_reassoc(mac);
-
- return 0;
-}
-
-int
-ieee80211softmac_handle_reassoc_req(struct net_device * dev,
- struct ieee80211_reassoc_request * resp)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
- struct ieee80211softmac_network *network;
-
- if (unlikely(!mac->running))
- return -ENODEV;
-
- network = ieee80211softmac_get_network_by_bssid(mac, resp->header.addr3);
- if (!network) {
- dprintkl(KERN_INFO PFX "reassoc request from unknown network\n");
- return 0;
- }
- queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
-
- return 0;
-}
diff --git a/net/ieee80211/softmac/ieee80211softmac_auth.c b/net/ieee80211/softmac/ieee80211softmac_auth.c
deleted file mode 100644
index 1a96c257257..00000000000
--- a/net/ieee80211/softmac/ieee80211softmac_auth.c
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * This file contains the softmac's authentication logic.
- *
- * Copyright (c) 2005, 2006 Johannes Berg <johannes@sipsolutions.net>
- * Joseph Jezak <josejx@gentoo.org>
- * Larry Finger <Larry.Finger@lwfinger.net>
- * Danny van Dyk <kugelfang@gentoo.org>
- * Michael Buesch <mbuesch@freenet.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called COPYING.
- */
-
-#include "ieee80211softmac_priv.h"
-
-static void ieee80211softmac_auth_queue(struct work_struct *work);
-
-/* Queues an auth request to the desired AP */
-int
-ieee80211softmac_auth_req(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *net)
-{
- struct ieee80211softmac_auth_queue_item *auth;
- unsigned long flags;
- DECLARE_MAC_BUF(mac2);
-
- if (net->authenticating || net->authenticated)
- return 0;
- net->authenticating = 1;
-
- /* Add the network if it's not already added */
- ieee80211softmac_add_network(mac, net);
-
- dprintk(KERN_NOTICE PFX "Queueing Authentication Request to %s\n", print_mac(mac2, net->bssid));
- /* Queue the auth request */
- auth = (struct ieee80211softmac_auth_queue_item *)
- kmalloc(sizeof(struct ieee80211softmac_auth_queue_item), GFP_KERNEL);
- if(auth == NULL)
- return -ENOMEM;
-
- auth->net = net;
- auth->mac = mac;
- auth->retry = IEEE80211SOFTMAC_AUTH_RETRY_LIMIT;
- auth->state = IEEE80211SOFTMAC_AUTH_OPEN_REQUEST;
- INIT_DELAYED_WORK(&auth->work, ieee80211softmac_auth_queue);
-
- /* Lock (for list) */
- spin_lock_irqsave(&mac->lock, flags);
-
- /* add to list */
- list_add_tail(&auth->list, &mac->auth_queue);
- queue_delayed_work(mac->wq, &auth->work, 0);
- spin_unlock_irqrestore(&mac->lock, flags);
-
- return 0;
-}
-
-
-/* Sends an auth request to the desired AP and handles timeouts */
-static void
-ieee80211softmac_auth_queue(struct work_struct *work)
-{
- struct ieee80211softmac_device *mac;
- struct ieee80211softmac_auth_queue_item *auth;
- struct ieee80211softmac_network *net;
- unsigned long flags;
- DECLARE_MAC_BUF(mac2);
-
- auth = container_of(work, struct ieee80211softmac_auth_queue_item,
- work.work);
- net = auth->net;
- mac = auth->mac;
-
- if(auth->retry > 0) {
- /* Switch to correct channel for this network */
- mac->set_channel(mac->dev, net->channel);
-
- /* Lock and set flags */
- spin_lock_irqsave(&mac->lock, flags);
- if (unlikely(!mac->running)) {
- /* Prevent reschedule on workqueue flush */
- spin_unlock_irqrestore(&mac->lock, flags);
- return;
- }
- net->authenticated = 0;
- /* add a timeout call so we eventually give up waiting for an auth reply */
- queue_delayed_work(mac->wq, &auth->work, IEEE80211SOFTMAC_AUTH_TIMEOUT);
- auth->retry--;
- spin_unlock_irqrestore(&mac->lock, flags);
- if (ieee80211softmac_send_mgt_frame(mac, auth->net, IEEE80211_STYPE_AUTH, auth->state))
- dprintk(KERN_NOTICE PFX "Sending Authentication Request to %s failed (this shouldn't happen, wait for the timeout).\n",
- print_mac(mac2, net->bssid));
- else
- dprintk(KERN_NOTICE PFX "Sent Authentication Request to %s.\n", print_mac(mac2, net->bssid));
- return;
- }
-
- printkl(KERN_WARNING PFX "Authentication timed out with %s\n", print_mac(mac2, net->bssid));
- /* Remove this item from the queue */
- spin_lock_irqsave(&mac->lock, flags);
- net->authenticating = 0;
- ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT, net);
- cancel_delayed_work(&auth->work); /* just to make sure... */
- list_del(&auth->list);
- spin_unlock_irqrestore(&mac->lock, flags);
- /* Free it */
- kfree(auth);
-}
-
-/* Sends a response to an auth challenge (for shared key auth). */
-static void
-ieee80211softmac_auth_challenge_response(struct work_struct *work)
-{
- struct ieee80211softmac_auth_queue_item *aq =
- container_of(work, struct ieee80211softmac_auth_queue_item,
- work.work);
-
- /* Send our response */
- ieee80211softmac_send_mgt_frame(aq->mac, aq->net, IEEE80211_STYPE_AUTH, aq->state);
-}
-
-/* Handle the auth response from the AP
- * This should be registered with ieee80211 as handle_auth
- */
-int
-ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
-{
-
- struct list_head *list_ptr;
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
- struct ieee80211softmac_auth_queue_item *aq = NULL;
- struct ieee80211softmac_network *net = NULL;
- unsigned long flags;
- u8 * data;
- DECLARE_MAC_BUF(mac2);
-
- if (unlikely(!mac->running))
- return -ENODEV;
-
- /* Find correct auth queue item */
- spin_lock_irqsave(&mac->lock, flags);
- list_for_each(list_ptr, &mac->auth_queue) {
- aq = list_entry(list_ptr, struct ieee80211softmac_auth_queue_item, list);
- net = aq->net;
- if (!memcmp(net->bssid, auth->header.addr2, ETH_ALEN))
- break;
- else
- aq = NULL;
- }
- spin_unlock_irqrestore(&mac->lock, flags);
-
- /* Make sure that we've got an auth queue item for this request */
- if(aq == NULL)
- {
- dprintkl(KERN_DEBUG PFX "Authentication response received from %s but no queue item exists.\n", print_mac(mac2, auth->header.addr2));
- /* Error #? */
- return -1;
- }
-
- /* Check for out of order authentication */
- if(!net->authenticating)
- {
- dprintkl(KERN_DEBUG PFX "Authentication response received from %s but did not request authentication.\n",print_mac(mac2, auth->header.addr2));
- return -1;
- }
-
- /* Parse the auth packet */
- switch(le16_to_cpu(auth->algorithm)) {
- case WLAN_AUTH_OPEN:
- /* Check the status code of the response */
-
- switch(le16_to_cpu(auth->status)) {
- case WLAN_STATUS_SUCCESS:
- /* Update the status to Authenticated */
- spin_lock_irqsave(&mac->lock, flags);
- net->authenticating = 0;
- net->authenticated = 1;
- spin_unlock_irqrestore(&mac->lock, flags);
-
- /* Send event */
- printkl(KERN_NOTICE PFX "Open Authentication completed with %s\n", print_mac(mac2, net->bssid));
- ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_AUTHENTICATED, net);
- break;
- default:
- /* Lock and reset flags */
- spin_lock_irqsave(&mac->lock, flags);
- net->authenticated = 0;
- net->authenticating = 0;
- spin_unlock_irqrestore(&mac->lock, flags);
-
- printkl(KERN_NOTICE PFX "Open Authentication with %s failed, error code: %i\n",
- print_mac(mac2, net->bssid), le16_to_cpup(&auth->status));
- /* Count the error? */
- break;
- }
- goto free_aq;
- break;
- case WLAN_AUTH_SHARED_KEY:
- /* Figure out where we are in the process */
- switch(le16_to_cpu(auth->transaction)) {
- case IEEE80211SOFTMAC_AUTH_SHARED_CHALLENGE:
- /* Check to make sure we have a challenge IE */
- data = (u8 *)auth->info_element;
- if (*data++ != MFIE_TYPE_CHALLENGE) {
- printkl(KERN_NOTICE PFX "Shared Key Authentication failed due to a missing challenge.\n");
- break;
- }
- /* Save the challenge */
- spin_lock_irqsave(&mac->lock, flags);
- net->challenge_len = *data++;
- if (net->challenge_len > WLAN_AUTH_CHALLENGE_LEN)
- net->challenge_len = WLAN_AUTH_CHALLENGE_LEN;
- kfree(net->challenge);
- net->challenge = kmemdup(data, net->challenge_len,
- GFP_ATOMIC);
- if (net->challenge == NULL) {
- printkl(KERN_NOTICE PFX "Shared Key "
- "Authentication failed due to "
- "memory shortage.\n");
- spin_unlock_irqrestore(&mac->lock, flags);
- break;
- }
- aq->state = IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE;
-
- /* We reuse the work struct from the auth request here.
- * It is safe to do so as each one is per-request, and
- * at this point (dealing with authentication response)
- * we have obviously already sent the initial auth
- * request. */
- cancel_delayed_work(&aq->work);
- INIT_DELAYED_WORK(&aq->work, &ieee80211softmac_auth_challenge_response);
- queue_delayed_work(mac->wq, &aq->work, 0);
- spin_unlock_irqrestore(&mac->lock, flags);
- return 0;
- case IEEE80211SOFTMAC_AUTH_SHARED_PASS:
- kfree(net->challenge);
- net->challenge = NULL;
- net->challenge_len = 0;
- /* Check the status code of the response */
- switch(auth->status) {
- case WLAN_STATUS_SUCCESS:
- /* Update the status to Authenticated */
- spin_lock_irqsave(&mac->lock, flags);
- net->authenticating = 0;
- net->authenticated = 1;
- spin_unlock_irqrestore(&mac->lock, flags);
- printkl(KERN_NOTICE PFX "Shared Key Authentication completed with %s\n",
- print_mac(mac2, net->bssid));
- ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_AUTHENTICATED, net);
- break;
- default:
- printkl(KERN_NOTICE PFX "Shared Key Authentication with %s failed, error code: %i\n",
- print_mac(mac2, net->bssid), le16_to_cpup(&auth->status));
- /* Lock and reset flags */
- spin_lock_irqsave(&mac->lock, flags);
- net->authenticating = 0;
- net->authenticated = 0;
- spin_unlock_irqrestore(&mac->lock, flags);
- /* Count the error? */
- break;
- }
- goto free_aq;
- break;
- default:
- printkl(KERN_WARNING PFX "Unhandled Authentication Step: %i\n", auth->transaction);
- break;
- }
- goto free_aq;
- break;
- default:
- /* ERROR */
- goto free_aq;
- break;
- }
- return 0;
-free_aq:
- /* Cancel the timeout */
- spin_lock_irqsave(&mac->lock, flags);
- cancel_delayed_work(&aq->work);
- /* Remove this item from the queue */
- list_del(&aq->list);
- spin_unlock_irqrestore(&mac->lock, flags);
-
- /* Free it */
- kfree(aq);
- return 0;
-}
-
-/*
- * Handle deauthorization
- */
-static void
-ieee80211softmac_deauth_from_net(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *net)
-{
- struct ieee80211softmac_auth_queue_item *aq = NULL;
- struct list_head *list_ptr;
- unsigned long flags;
-
- /* deauthentication implies disassociation */
- ieee80211softmac_disassoc(mac);
-
- /* Lock and reset status flags */
- spin_lock_irqsave(&mac->lock, flags);
- net->authenticating = 0;
- net->authenticated = 0;
-
- /* Find correct auth queue item, if it exists */
- list_for_each(list_ptr, &mac->auth_queue) {
- aq = list_entry(list_ptr, struct ieee80211softmac_auth_queue_item, list);
- if (!memcmp(net->bssid, aq->net->bssid, ETH_ALEN))
- break;
- else
- aq = NULL;
- }
-
- /* Cancel pending work */
- if(aq != NULL)
- /* Not entirely safe? What about running work? */
- cancel_delayed_work(&aq->work);
-
- /* Free our network ref */
- ieee80211softmac_del_network_locked(mac, net);
- if(net->challenge != NULL)
- kfree(net->challenge);
- kfree(net);
-
- /* can't transmit data right now... */
- netif_carrier_off(mac->dev);
- spin_unlock_irqrestore(&mac->lock, flags);
-
- ieee80211softmac_try_reassoc(mac);
-}
-
-/*
- * Sends a deauth request to the desired AP
- */
-int
-ieee80211softmac_deauth_req(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *net, int reason)
-{
- int ret;
-
- /* Make sure the network is authenticated */
- if (!net->authenticated)
- {
- dprintkl(KERN_DEBUG PFX "Can't send deauthentication packet, network is not authenticated.\n");
- /* Error okay? */
- return -EPERM;
- }
-
- /* Send the de-auth packet */
- if((ret = ieee80211softmac_send_mgt_frame(mac, net, IEEE80211_STYPE_DEAUTH, reason)))
- return ret;
-
- ieee80211softmac_deauth_from_net(mac, net);
- return 0;
-}
-
-/*
- * This should be registered with ieee80211 as handle_deauth
- */
-int
-ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *deauth)
-{
-
- struct ieee80211softmac_network *net = NULL;
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
- DECLARE_MAC_BUF(mac2);
-
- if (unlikely(!mac->running))
- return -ENODEV;
-
- if (!deauth) {
- dprintk("deauth without deauth packet. eek!\n");
- return 0;
- }
-
- net = ieee80211softmac_get_network_by_bssid(mac, deauth->header.addr2);
-
- if (net == NULL) {
- dprintkl(KERN_DEBUG PFX "Received deauthentication packet from %s, but that network is unknown.\n",
- print_mac(mac2, deauth->header.addr2));
- return 0;
- }
-
- /* Make sure the network is authenticated */
- if(!net->authenticated)
- {
- dprintkl(KERN_DEBUG PFX "Can't perform deauthentication, network is not authenticated.\n");
- /* Error okay? */
- return -EPERM;
- }
-
- ieee80211softmac_deauth_from_net(mac, net);
-
- /* let's try to re-associate */
- queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
- return 0;
-}
diff --git a/net/ieee80211/softmac/ieee80211softmac_event.c b/net/ieee80211/softmac/ieee80211softmac_event.c
deleted file mode 100644
index 8cef05b60f1..00000000000
--- a/net/ieee80211/softmac/ieee80211softmac_event.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Event system
- * Also see comments in public header file and longer explanation below.
- *
- * Copyright (c) 2005, 2006 Johannes Berg <johannes@sipsolutions.net>
- * Joseph Jezak <josejx@gentoo.org>
- * Larry Finger <Larry.Finger@lwfinger.net>
- * Danny van Dyk <kugelfang@gentoo.org>
- * Michael Buesch <mbuesch@freenet.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called COPYING.
- */
-
-#include "ieee80211softmac_priv.h"
-
-/*
- * Each event has associated to it
- * - an event type (see constants in public header)
- * - an event context (see below)
- * - the function to be called
- * - a context (extra parameter to call the function with)
- * - and the softmac struct
- *
- * The event context is private and can only be used from
- * within this module. Its meaning varies with the event
- * type:
- * SCAN_FINISHED,
- * DISASSOCIATED: NULL
- * ASSOCIATED,
- * ASSOCIATE_FAILED,
- * ASSOCIATE_TIMEOUT,
- * AUTHENTICATED,
- * AUTH_FAILED,
- * AUTH_TIMEOUT: a pointer to the network struct
- * ...
- * Code within this module can use the event context to be only
- * called when the event is true for that specific context
- * as per above table.
- * If the event context is NULL, then the notification is always called,
- * regardless of the event context. The event context is not passed to
- * the callback, it is assumed that the context suffices.
- *
- * You can also use the event context only by setting the event type
- * to -1 (private use only), in which case you'll be notified
- * whenever the event context matches.
- */
-
-static char *event_descriptions[IEEE80211SOFTMAC_EVENT_LAST+1] = {
- NULL, /* scan finished */
- NULL, /* associated */
- "associating failed",
- "associating timed out",
- "authenticated",
- "authenticating failed",
- "authenticating timed out",
- "associating failed because no suitable network was found",
- NULL, /* disassociated */
-};
-
-
-static void
-ieee80211softmac_notify_callback(struct work_struct *work)
-{
- struct ieee80211softmac_event *pevent =
- container_of(work, struct ieee80211softmac_event, work.work);
- struct ieee80211softmac_event event = *pevent;
- kfree(pevent);
-
- event.fun(event.mac->dev, event.event_type, event.context);
-}
-
-int
-ieee80211softmac_notify_internal(struct ieee80211softmac_device *mac,
- int event, void *event_context, notify_function_ptr fun, void *context, gfp_t gfp_mask)
-{
- struct ieee80211softmac_event *eventptr;
- unsigned long flags;
-
- if (event < -1 || event > IEEE80211SOFTMAC_EVENT_LAST)
- return -ENOSYS;
-
- if (!fun)
- return -EINVAL;
-
- eventptr = kmalloc(sizeof(struct ieee80211softmac_event), gfp_mask);
- if (!eventptr)
- return -ENOMEM;
-
- eventptr->event_type = event;
- INIT_DELAYED_WORK(&eventptr->work, ieee80211softmac_notify_callback);
- eventptr->fun = fun;
- eventptr->context = context;
- eventptr->mac = mac;
- eventptr->event_context = event_context;
-
- spin_lock_irqsave(&mac->lock, flags);
- list_add(&eventptr->list, &mac->events);
- spin_unlock_irqrestore(&mac->lock, flags);
-
- return 0;
-}
-
-int
-ieee80211softmac_notify_gfp(struct net_device *dev,
- int event, notify_function_ptr fun, void *context, gfp_t gfp_mask)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
-
- if (event < 0 || event > IEEE80211SOFTMAC_EVENT_LAST)
- return -ENOSYS;
-
- return ieee80211softmac_notify_internal(mac, event, NULL, fun, context, gfp_mask);
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_notify_gfp);
-
-/* private -- calling all callbacks that were specified */
-void
-ieee80211softmac_call_events_locked(struct ieee80211softmac_device *mac, int event, void *event_ctx)
-{
- struct ieee80211softmac_event *eventptr, *tmp;
- struct ieee80211softmac_network *network;
-
- if (event >= 0) {
- union iwreq_data wrqu;
- int we_event;
- char *msg = NULL;
-
- memset(&wrqu, '\0', sizeof (union iwreq_data));
-
- switch(event) {
- case IEEE80211SOFTMAC_EVENT_ASSOCIATED:
- network = (struct ieee80211softmac_network *)event_ctx;
- memcpy(wrqu.ap_addr.sa_data, &network->bssid[0], ETH_ALEN);
- /* fall through */
- case IEEE80211SOFTMAC_EVENT_DISASSOCIATED:
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- we_event = SIOCGIWAP;
- break;
- case IEEE80211SOFTMAC_EVENT_SCAN_FINISHED:
- we_event = SIOCGIWSCAN;
- break;
- default:
- msg = event_descriptions[event];
- if (!msg)
- msg = "SOFTMAC EVENT BUG";
- wrqu.data.length = strlen(msg);
- we_event = IWEVCUSTOM;
- break;
- }
- wireless_send_event(mac->dev, we_event, &wrqu, msg);
- }
-
- if (!list_empty(&mac->events))
- list_for_each_entry_safe(eventptr, tmp, &mac->events, list) {
- if ((eventptr->event_type == event || eventptr->event_type == -1)
- && (eventptr->event_context == NULL || eventptr->event_context == event_ctx)) {
- list_del(&eventptr->list);
- /* User may have subscribed to ANY event, so
- * we tell them which event triggered it. */
- eventptr->event_type = event;
- queue_delayed_work(mac->wq, &eventptr->work, 0);
- }
- }
-}
-
-void
-ieee80211softmac_call_events(struct ieee80211softmac_device *mac, int event, void *event_ctx)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&mac->lock, flags);
- ieee80211softmac_call_events_locked(mac, event, event_ctx);
-
- spin_unlock_irqrestore(&mac->lock, flags);
-}
diff --git a/net/ieee80211/softmac/ieee80211softmac_io.c b/net/ieee80211/softmac/ieee80211softmac_io.c
deleted file mode 100644
index 73b4b13fbd8..00000000000
--- a/net/ieee80211/softmac/ieee80211softmac_io.c
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * Some parts based on code from net80211
- * Copyright (c) 2001 Atsushi Onoe
- * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "ieee80211softmac_priv.h"
-
-/* Helper functions for inserting data into the frames */
-
-/*
- * Adds an ESSID element to the frame
- *
- */
-static u8 *
-ieee80211softmac_add_essid(u8 *dst, struct ieee80211softmac_essid *essid)
-{
- if (essid) {
- *dst++ = MFIE_TYPE_SSID;
- *dst++ = essid->len;
- memcpy(dst, essid->data, essid->len);
- return dst+essid->len;
- } else {
- *dst++ = MFIE_TYPE_SSID;
- *dst++ = 0;
- return dst;
- }
-}
-
-/* Adds Supported Rates and if required Extended Rates Information Element
- * to the frame, ASSUMES WE HAVE A SORTED LIST OF RATES */
-static u8 *
-ieee80211softmac_frame_add_rates(u8 *dst, const struct ieee80211softmac_ratesinfo *r)
-{
- int cck_len, ofdm_len;
- *dst++ = MFIE_TYPE_RATES;
-
- for(cck_len=0; ieee80211_is_cck_rate(r->rates[cck_len]) && (cck_len < r->count);cck_len++);
-
- if(cck_len > IEEE80211SOFTMAC_MAX_RATES_LEN)
- cck_len = IEEE80211SOFTMAC_MAX_RATES_LEN;
- *dst++ = cck_len;
- memcpy(dst, r->rates, cck_len);
- dst += cck_len;
-
- if(cck_len < r->count){
- for (ofdm_len=0; ieee80211_is_ofdm_rate(r->rates[ofdm_len + cck_len]) && (ofdm_len + cck_len < r->count); ofdm_len++);
- if (ofdm_len > 0) {
- if (ofdm_len > IEEE80211SOFTMAC_MAX_EX_RATES_LEN)
- ofdm_len = IEEE80211SOFTMAC_MAX_EX_RATES_LEN;
- *dst++ = MFIE_TYPE_RATES_EX;
- *dst++ = ofdm_len;
- memcpy(dst, r->rates + cck_len, ofdm_len);
- dst += ofdm_len;
- }
- }
- return dst;
-}
-
-/* Allocate a management frame */
-static u8 *
-ieee80211softmac_alloc_mgt(u32 size)
-{
- u8 * data;
-
- /* Add the header and FCS to the size */
- size = size + IEEE80211_3ADDR_LEN;
- if(size > IEEE80211_DATA_LEN)
- return NULL;
- /* Allocate the frame */
- data = kzalloc(size, GFP_ATOMIC);
- return data;
-}
-
-/*
- * Add a 2 Address Header
- */
-static void
-ieee80211softmac_hdr_2addr(struct ieee80211softmac_device *mac,
- struct ieee80211_hdr_2addr *header, u32 type, u8 *dest)
-{
- /* Fill in the frame control flags */
- header->frame_ctl = cpu_to_le16(type);
- /* Control packets always have WEP turned off */
- if(type > IEEE80211_STYPE_CFENDACK && type < IEEE80211_STYPE_PSPOLL)
- header->frame_ctl |= mac->ieee->sec.level ? cpu_to_le16(IEEE80211_FCTL_PROTECTED) : 0;
-
- /* Fill in the duration */
- header->duration_id = 0;
- /* FIXME: How do I find this?
- * calculate. But most drivers just fill in 0 (except if it's a station id of course) */
-
- /* Fill in the Destination Address */
- if(dest == NULL)
- memset(header->addr1, 0xFF, ETH_ALEN);
- else
- memcpy(header->addr1, dest, ETH_ALEN);
- /* Fill in the Source Address */
- memcpy(header->addr2, mac->ieee->dev->dev_addr, ETH_ALEN);
-
-}
-
-
-/* Add a 3 Address Header */
-static void
-ieee80211softmac_hdr_3addr(struct ieee80211softmac_device *mac,
- struct ieee80211_hdr_3addr *header, u32 type, u8 *dest, u8 *bssid)
-{
- /* This is common with 2addr, so use that instead */
- ieee80211softmac_hdr_2addr(mac, (struct ieee80211_hdr_2addr *)header, type, dest);
-
- /* Fill in the BSS ID */
- if(bssid == NULL)
- memset(header->addr3, 0xFF, ETH_ALEN);
- else
- memcpy(header->addr3, bssid, ETH_ALEN);
-
- /* Fill in the sequence # */
- /* FIXME: I need to add this to the softmac struct
- * shouldn't the sequence number be in ieee80211? */
-}
-
-static __le16
-ieee80211softmac_capabilities(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *net)
-{
- __le16 capability = 0;
-
- /* ESS and IBSS bits are set according to the current mode */
- switch (mac->ieee->iw_mode) {
- case IW_MODE_INFRA:
- capability = cpu_to_le16(WLAN_CAPABILITY_ESS);
- break;
- case IW_MODE_ADHOC:
- capability = cpu_to_le16(WLAN_CAPABILITY_IBSS);
- break;
- case IW_MODE_AUTO:
- capability = cpu_to_le16(net->capabilities &
- (WLAN_CAPABILITY_ESS|WLAN_CAPABILITY_IBSS));
- break;
- default:
- /* bleh. we don't ever go to these modes */
- printk(KERN_ERR PFX "invalid iw_mode!\n");
- break;
- }
-
- /* CF Pollable / CF Poll Request */
- /* Needs to be implemented, for now, the 0's == not supported */
-
- /* Privacy Bit */
- capability |= mac->ieee->sec.level ?
- cpu_to_le16(WLAN_CAPABILITY_PRIVACY) : 0;
-
- /* Short Preamble */
- /* Always supported: we probably won't ever be powering devices which
- * dont support this... */
- capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
-
- /* PBCC */
- /* Not widely used */
-
- /* Channel Agility */
- /* Not widely used */
-
- /* Short Slot */
- /* Will be implemented later */
-
- /* DSSS-OFDM */
- /* Not widely used */
-
- return capability;
-}
-
-/*****************************************************************************
- * Create Management packets
- *****************************************************************************/
-
-/* Creates an association request packet */
-static u32
-ieee80211softmac_assoc_req(struct ieee80211_assoc_request **pkt,
- struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net)
-{
- u8 *data;
- (*pkt) = (struct ieee80211_assoc_request *)ieee80211softmac_alloc_mgt(
- 2 + /* Capability Info */
- 2 + /* Listen Interval */
- /* SSID IE */
- 1 + 1 + IW_ESSID_MAX_SIZE +
- /* Rates IE */
- 1 + 1 + IEEE80211SOFTMAC_MAX_RATES_LEN +
- /* Extended Rates IE */
- 1 + 1 + IEEE80211SOFTMAC_MAX_EX_RATES_LEN +
- /* WPA IE if present */
- mac->wpa.IElen
- /* Other IE's? Optional?
- * Yeah, probably need an extra IE parameter -- lots of vendors like to
- * fill in their own IEs */
- );
- if (unlikely((*pkt) == NULL))
- return 0;
- ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_ASSOC_REQ, net->bssid, net->bssid);
-
- /* Fill in the capabilities */
- (*pkt)->capability = ieee80211softmac_capabilities(mac, net);
-
- /* Fill in Listen Interval (?) */
- (*pkt)->listen_interval = cpu_to_le16(10);
-
- data = (u8 *)(*pkt)->info_element;
- /* Add SSID */
- data = ieee80211softmac_add_essid(data, &net->essid);
- /* Add Rates */
- data = ieee80211softmac_frame_add_rates(data, &mac->ratesinfo);
- /* Add WPA IE */
- if (mac->wpa.IElen && mac->wpa.IE) {
- memcpy(data, mac->wpa.IE, mac->wpa.IElen);
- data += mac->wpa.IElen;
- }
- /* Return the number of used bytes */
- return (data - (u8*)(*pkt));
-}
-
-/* Create a reassociation request packet */
-static u32
-ieee80211softmac_reassoc_req(struct ieee80211_reassoc_request **pkt,
- struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net)
-{
- u8 *data;
- (*pkt) = (struct ieee80211_reassoc_request *)ieee80211softmac_alloc_mgt(
- 2 + /* Capability Info */
- 2 + /* Listen Interval */
- ETH_ALEN + /* AP MAC */
- /* SSID IE */
- 1 + 1 + IW_ESSID_MAX_SIZE +
- /* Rates IE */
- 1 + 1 + IEEE80211SOFTMAC_MAX_RATES_LEN +
- /* Extended Rates IE */
- 1 + 1 + IEEE80211SOFTMAC_MAX_EX_RATES_LEN
- /* Other IE's? */
- );
- if (unlikely((*pkt) == NULL))
- return 0;
- ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_REASSOC_REQ, net->bssid, net->bssid);
-
- /* Fill in the capabilities */
- (*pkt)->capability = ieee80211softmac_capabilities(mac, net);
-
- /* Fill in Listen Interval (?) */
- (*pkt)->listen_interval = cpu_to_le16(10);
- /* Fill in the current AP MAC */
- memcpy((*pkt)->current_ap, mac->ieee->bssid, ETH_ALEN);
-
- data = (u8 *)(*pkt)->info_element;
- /* Add SSID */
- data = ieee80211softmac_add_essid(data, &net->essid);
- /* Add Rates */
- data = ieee80211softmac_frame_add_rates(data, &mac->ratesinfo);
- /* Return packet size */
- return (data - (u8 *)(*pkt));
-}
-
-/* Create an authentication packet */
-static u32
-ieee80211softmac_auth(struct ieee80211_auth **pkt,
- struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net,
- u16 transaction, u16 status, int *encrypt_mpdu)
-{
- u8 *data;
- int auth_mode = mac->ieee->sec.auth_mode;
- int is_shared_response = (auth_mode == WLAN_AUTH_SHARED_KEY
- && transaction == IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE);
-
- /* Allocate Packet */
- (*pkt) = (struct ieee80211_auth *)ieee80211softmac_alloc_mgt(
- 2 + /* Auth Algorithm */
- 2 + /* Auth Transaction Seq */
- 2 + /* Status Code */
- /* Challenge Text IE */
- (is_shared_response ? 1 + 1 + net->challenge_len : 0)
- );
- if (unlikely((*pkt) == NULL))
- return 0;
- ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_AUTH, net->bssid, net->bssid);
-
- /* Algorithm */
- (*pkt)->algorithm = cpu_to_le16(auth_mode);
- /* Transaction */
- (*pkt)->transaction = cpu_to_le16(transaction);
- /* Status */
- (*pkt)->status = cpu_to_le16(status);
-
- data = (u8 *)(*pkt)->info_element;
- /* Challenge Text */
- if (is_shared_response) {
- *data = MFIE_TYPE_CHALLENGE;
- data++;
-
- /* Copy the challenge in */
- *data = net->challenge_len;
- data++;
- memcpy(data, net->challenge, net->challenge_len);
- data += net->challenge_len;
-
- /* Make sure this frame gets encrypted with the shared key */
- *encrypt_mpdu = 1;
- } else
- *encrypt_mpdu = 0;
-
- /* Return the packet size */
- return (data - (u8 *)(*pkt));
-}
-
-/* Create a disassocation or deauthentication packet */
-static u32
-ieee80211softmac_disassoc_deauth(struct ieee80211_disassoc **pkt,
- struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net,
- u16 type, u16 reason)
-{
- /* Allocate Packet */
- (*pkt) = (struct ieee80211_disassoc *)ieee80211softmac_alloc_mgt(2);
- if (unlikely((*pkt) == NULL))
- return 0;
- ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), type, net->bssid, net->bssid);
- /* Reason */
- (*pkt)->reason = cpu_to_le16(reason);
- /* Return the packet size */
- return (2 + IEEE80211_3ADDR_LEN);
-}
-
-/* Create a probe request packet */
-static u32
-ieee80211softmac_probe_req(struct ieee80211_probe_request **pkt,
- struct ieee80211softmac_device *mac, struct ieee80211softmac_essid *essid)
-{
- u8 *data;
- /* Allocate Packet */
- (*pkt) = (struct ieee80211_probe_request *)ieee80211softmac_alloc_mgt(
- /* SSID of requested network */
- 1 + 1 + IW_ESSID_MAX_SIZE +
- /* Rates IE */
- 1 + 1 + IEEE80211SOFTMAC_MAX_RATES_LEN +
- /* Extended Rates IE */
- 1 + 1 + IEEE80211SOFTMAC_MAX_EX_RATES_LEN
- );
- if (unlikely((*pkt) == NULL))
- return 0;
- ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_PROBE_REQ, NULL, NULL);
-
- data = (u8 *)(*pkt)->info_element;
- /* Add ESSID (can be NULL) */
- data = ieee80211softmac_add_essid(data, essid);
- /* Add Rates */
- data = ieee80211softmac_frame_add_rates(data, &mac->ratesinfo);
- /* Return packet size */
- return (data - (u8 *)(*pkt));
-}
-
-/* Create a probe response packet */
-/* FIXME: Not complete */
-static u32
-ieee80211softmac_probe_resp(struct ieee80211_probe_response **pkt,
- struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net)
-{
- u8 *data;
- /* Allocate Packet */
- (*pkt) = (struct ieee80211_probe_response *)ieee80211softmac_alloc_mgt(
- 8 + /* Timestamp */
- 2 + /* Beacon Interval */
- 2 + /* Capability Info */
- /* SSID IE */
- 1 + 1 + IW_ESSID_MAX_SIZE +
- 7 + /* FH Parameter Set */
- 2 + /* DS Parameter Set */
- 8 + /* CF Parameter Set */
- 4 /* IBSS Parameter Set */
- );
- if (unlikely((*pkt) == NULL))
- return 0;
- ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_PROBE_RESP, net->bssid, net->bssid);
- data = (u8 *)(*pkt)->info_element;
-
- /* Return the packet size */
- return (data - (u8 *)(*pkt));
-}
-
-
-/* Sends a manangement packet
- * FIXME: document the use of the arg parameter
- * for _AUTH: (transaction #) | (status << 16)
- */
-int
-ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac,
- void *ptrarg, u32 type, u32 arg)
-{
- void *pkt = NULL;
- u32 pkt_size = 0;
- int encrypt_mpdu = 0;
-
- switch(type) {
- case IEEE80211_STYPE_ASSOC_REQ:
- pkt_size = ieee80211softmac_assoc_req((struct ieee80211_assoc_request **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg);
- break;
- case IEEE80211_STYPE_REASSOC_REQ:
- pkt_size = ieee80211softmac_reassoc_req((struct ieee80211_reassoc_request **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg);
- break;
- case IEEE80211_STYPE_AUTH:
- pkt_size = ieee80211softmac_auth((struct ieee80211_auth **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg, (u16)(arg & 0xFFFF), (u16) (arg >> 16), &encrypt_mpdu);
- break;
- case IEEE80211_STYPE_DISASSOC:
- case IEEE80211_STYPE_DEAUTH:
- pkt_size = ieee80211softmac_disassoc_deauth((struct ieee80211_disassoc **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg, type, (u16)(arg & 0xFFFF));
- break;
- case IEEE80211_STYPE_PROBE_REQ:
- pkt_size = ieee80211softmac_probe_req((struct ieee80211_probe_request **)(&pkt), mac, (struct ieee80211softmac_essid *)ptrarg);
- break;
- case IEEE80211_STYPE_PROBE_RESP:
- pkt_size = ieee80211softmac_probe_resp((struct ieee80211_probe_response **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg);
- break;
- default:
- printkl(KERN_DEBUG PFX "Unsupported Management Frame type: %i\n", type);
- return -EINVAL;
- };
-
- if(pkt_size == 0 || pkt == NULL) {
- printkl(KERN_DEBUG PFX "Error, packet is nonexistant or 0 length\n");
- return -ENOMEM;
- }
-
- /* Send the packet to the ieee80211 layer for tx */
- /* we defined softmac->mgmt_xmit for this. Should we keep it
- * as it is (that means we'd need to wrap this into a txb),
- * modify the prototype (so it matches this function),
- * or get rid of it alltogether?
- * Does this work for you now?
- */
- ieee80211_tx_frame(mac->ieee, (struct ieee80211_hdr *)pkt,
- IEEE80211_3ADDR_LEN, pkt_size, encrypt_mpdu);
-
- kfree(pkt);
- return 0;
-}
-
-/* Beacon handling */
-int ieee80211softmac_handle_beacon(struct net_device *dev,
- struct ieee80211_beacon *beacon,
- struct ieee80211_network *network)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
-
- /* This might race, but we don't really care and it's not worth
- * adding heavyweight locking in this fastpath.
- */
- if (mac->associnfo.associated) {
- if (memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0)
- ieee80211softmac_process_erp(mac, network->erp_value);
- }
-
- return 0;
-}
-
diff --git a/net/ieee80211/softmac/ieee80211softmac_module.c b/net/ieee80211/softmac/ieee80211softmac_module.c
deleted file mode 100644
index 07505ca859a..00000000000
--- a/net/ieee80211/softmac/ieee80211softmac_module.c
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * Contains some basic softmac functions along with module registration code etc.
- *
- * Copyright (c) 2005, 2006 Johannes Berg <johannes@sipsolutions.net>
- * Joseph Jezak <josejx@gentoo.org>
- * Larry Finger <Larry.Finger@lwfinger.net>
- * Danny van Dyk <kugelfang@gentoo.org>
- * Michael Buesch <mbuesch@freenet.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called COPYING.
- */
-
-#include "ieee80211softmac_priv.h"
-#include <linux/sort.h>
-#include <linux/etherdevice.h>
-
-struct net_device *alloc_ieee80211softmac(int sizeof_priv)
-{
- struct ieee80211softmac_device *softmac;
- struct net_device *dev;
-
- dev = alloc_ieee80211(sizeof(*softmac) + sizeof_priv);
- if (!dev)
- return NULL;
- softmac = ieee80211_priv(dev);
- softmac->wq = create_freezeable_workqueue("softmac");
- if (!softmac->wq) {
- free_ieee80211(dev);
- return NULL;
- }
-
- softmac->dev = dev;
- softmac->ieee = netdev_priv(dev);
- spin_lock_init(&softmac->lock);
-
- softmac->ieee->handle_auth = ieee80211softmac_auth_resp;
- softmac->ieee->handle_deauth = ieee80211softmac_deauth_resp;
- softmac->ieee->handle_assoc_response = ieee80211softmac_handle_assoc_response;
- softmac->ieee->handle_reassoc_request = ieee80211softmac_handle_reassoc_req;
- softmac->ieee->handle_disassoc = ieee80211softmac_handle_disassoc;
- softmac->ieee->handle_beacon = ieee80211softmac_handle_beacon;
- softmac->scaninfo = NULL;
-
- softmac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT;
-
- /* TODO: initialise all the other callbacks in the ieee struct
- * (once they're written)
- */
-
- INIT_LIST_HEAD(&softmac->auth_queue);
- INIT_LIST_HEAD(&softmac->network_list);
- INIT_LIST_HEAD(&softmac->events);
-
- mutex_init(&softmac->associnfo.mutex);
- INIT_DELAYED_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work);
- INIT_DELAYED_WORK(&softmac->associnfo.timeout, ieee80211softmac_assoc_timeout);
- softmac->start_scan = ieee80211softmac_start_scan_implementation;
- softmac->wait_for_scan = ieee80211softmac_wait_for_scan_implementation;
- softmac->stop_scan = ieee80211softmac_stop_scan_implementation;
-
- /* to start with, we can't send anything ... */
- netif_carrier_off(dev);
-
- return dev;
-}
-EXPORT_SYMBOL_GPL(alloc_ieee80211softmac);
-
-/* Clears the pending work queue items, stops all scans, etc. */
-void
-ieee80211softmac_clear_pending_work(struct ieee80211softmac_device *sm)
-{
- unsigned long flags;
- struct ieee80211softmac_event *eventptr, *eventtmp;
- struct ieee80211softmac_auth_queue_item *authptr, *authtmp;
- struct ieee80211softmac_network *netptr, *nettmp;
-
- ieee80211softmac_stop_scan(sm);
- ieee80211softmac_wait_for_scan(sm);
-
- spin_lock_irqsave(&sm->lock, flags);
- sm->running = 0;
-
- /* Free all pending assoc work items */
- cancel_delayed_work(&sm->associnfo.work);
-
- /* Free all pending scan work items */
- if(sm->scaninfo != NULL)
- cancel_delayed_work(&sm->scaninfo->softmac_scan);
-
- /* Free all pending auth work items */
- list_for_each_entry(authptr, &sm->auth_queue, list)
- cancel_delayed_work(&authptr->work);
-
- /* delete all pending event calls and work items */
- list_for_each_entry_safe(eventptr, eventtmp, &sm->events, list)
- cancel_delayed_work(&eventptr->work);
-
- spin_unlock_irqrestore(&sm->lock, flags);
- flush_workqueue(sm->wq);
-
- /* now we should be save and no longer need locking... */
- spin_lock_irqsave(&sm->lock, flags);
- /* Free all pending auth work items */
- list_for_each_entry_safe(authptr, authtmp, &sm->auth_queue, list) {
- list_del(&authptr->list);
- kfree(authptr);
- }
-
- /* delete all pending event calls and work items */
- list_for_each_entry_safe(eventptr, eventtmp, &sm->events, list) {
- list_del(&eventptr->list);
- kfree(eventptr);
- }
-
- /* Free all networks */
- list_for_each_entry_safe(netptr, nettmp, &sm->network_list, list) {
- ieee80211softmac_del_network_locked(sm, netptr);
- if(netptr->challenge != NULL)
- kfree(netptr->challenge);
- kfree(netptr);
- }
-
- spin_unlock_irqrestore(&sm->lock, flags);
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_clear_pending_work);
-
-void free_ieee80211softmac(struct net_device *dev)
-{
- struct ieee80211softmac_device *sm = ieee80211_priv(dev);
- ieee80211softmac_clear_pending_work(sm);
- kfree(sm->scaninfo);
- kfree(sm->wpa.IE);
- destroy_workqueue(sm->wq);
- free_ieee80211(dev);
-}
-EXPORT_SYMBOL_GPL(free_ieee80211softmac);
-
-static void ieee80211softmac_start_check_rates(struct ieee80211softmac_device *mac)
-{
- struct ieee80211softmac_ratesinfo *ri = &mac->ratesinfo;
- /* I took out the sorting check, we're seperating by modulation now. */
- if (ri->count)
- return;
- /* otherwise assume we hav'em all! */
- if (mac->ieee->modulation & IEEE80211_CCK_MODULATION) {
- ri->rates[ri->count++] = IEEE80211_CCK_RATE_1MB;
- ri->rates[ri->count++] = IEEE80211_CCK_RATE_2MB;
- ri->rates[ri->count++] = IEEE80211_CCK_RATE_5MB;
- ri->rates[ri->count++] = IEEE80211_CCK_RATE_11MB;
- }
- if (mac->ieee->modulation & IEEE80211_OFDM_MODULATION) {
- ri->rates[ri->count++] = IEEE80211_OFDM_RATE_6MB;
- ri->rates[ri->count++] = IEEE80211_OFDM_RATE_9MB;
- ri->rates[ri->count++] = IEEE80211_OFDM_RATE_12MB;
- ri->rates[ri->count++] = IEEE80211_OFDM_RATE_18MB;
- ri->rates[ri->count++] = IEEE80211_OFDM_RATE_24MB;
- ri->rates[ri->count++] = IEEE80211_OFDM_RATE_36MB;
- ri->rates[ri->count++] = IEEE80211_OFDM_RATE_48MB;
- ri->rates[ri->count++] = IEEE80211_OFDM_RATE_54MB;
- }
-}
-
-int ieee80211softmac_ratesinfo_rate_supported(struct ieee80211softmac_ratesinfo *ri, u8 rate)
-{
- int search;
- u8 search_rate;
-
- for (search = 0; search < ri->count; search++) {
- search_rate = ri->rates[search];
- search_rate &= ~IEEE80211_BASIC_RATE_MASK;
- if (rate == search_rate)
- return 1;
- }
-
- return 0;
-}
-
-u8 ieee80211softmac_highest_supported_rate(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_ratesinfo *ri, int basic_only)
-{
- u8 user_rate = mac->txrates.user_rate;
- int i;
-
- if (ri->count == 0)
- return IEEE80211_CCK_RATE_1MB;
-
- for (i = ri->count - 1; i >= 0; i--) {
- u8 rate = ri->rates[i];
- if (basic_only && !(rate & IEEE80211_BASIC_RATE_MASK))
- continue;
- rate &= ~IEEE80211_BASIC_RATE_MASK;
- if (rate > user_rate)
- continue;
- if (ieee80211softmac_ratesinfo_rate_supported(&mac->ratesinfo, rate))
- return rate;
- }
-
- /* If we haven't found a suitable rate by now, just trust the user */
- return user_rate;
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_highest_supported_rate);
-
-void ieee80211softmac_process_erp(struct ieee80211softmac_device *mac,
- u8 erp_value)
-{
- int use_protection;
- int short_preamble;
- u32 changes = 0;
-
- /* Barker preamble mode */
- short_preamble = ((erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0
- && mac->associnfo.short_preamble_available) ? 1 : 0;
-
- /* Protection needed? */
- use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0;
-
- if (mac->bssinfo.short_preamble != short_preamble) {
- changes |= IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE;
- mac->bssinfo.short_preamble = short_preamble;
- }
-
- if (mac->bssinfo.use_protection != use_protection) {
- changes |= IEEE80211SOFTMAC_BSSINFOCHG_PROTECTION;
- mac->bssinfo.use_protection = use_protection;
- }
-
- if (mac->bssinfo_change && changes)
- mac->bssinfo_change(mac->dev, changes);
-}
-
-void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac)
-{
- struct ieee80211softmac_txrates *txrates = &mac->txrates;
- u32 change = 0;
-
- change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
- txrates->default_rate = ieee80211softmac_highest_supported_rate(mac, &mac->bssinfo.supported_rates, 0);
-
- change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
- txrates->default_fallback = lower_rate(mac, txrates->default_rate);
-
- change |= IEEE80211SOFTMAC_TXRATECHG_MCAST;
- txrates->mcast_rate = ieee80211softmac_highest_supported_rate(mac, &mac->bssinfo.supported_rates, 1);
-
- if (mac->txrates_change)
- mac->txrates_change(mac->dev, change);
-
-}
-
-void ieee80211softmac_init_bss(struct ieee80211softmac_device *mac)
-{
- struct ieee80211_device *ieee = mac->ieee;
- u32 change = 0;
- struct ieee80211softmac_txrates *txrates = &mac->txrates;
- struct ieee80211softmac_bss_info *bssinfo = &mac->bssinfo;
-
- /* TODO: We need some kind of state machine to lower the default rates
- * if we loose too many packets.
- */
- /* Change the default txrate to the highest possible value.
- * The txrate machine will lower it, if it is too high.
- */
- if (ieee->modulation & IEEE80211_OFDM_MODULATION)
- txrates->user_rate = IEEE80211_OFDM_RATE_24MB;
- else
- txrates->user_rate = IEEE80211_CCK_RATE_11MB;
-
- txrates->default_rate = IEEE80211_CCK_RATE_1MB;
- change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
-
- txrates->default_fallback = IEEE80211_CCK_RATE_1MB;
- change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
-
- txrates->mcast_rate = IEEE80211_CCK_RATE_1MB;
- change |= IEEE80211SOFTMAC_TXRATECHG_MCAST;
-
- txrates->mgt_mcast_rate = IEEE80211_CCK_RATE_1MB;
- change |= IEEE80211SOFTMAC_TXRATECHG_MGT_MCAST;
-
- if (mac->txrates_change)
- mac->txrates_change(mac->dev, change);
-
- change = 0;
-
- bssinfo->supported_rates.count = 0;
- memset(bssinfo->supported_rates.rates, 0,
- sizeof(bssinfo->supported_rates.rates));
- change |= IEEE80211SOFTMAC_BSSINFOCHG_RATES;
-
- bssinfo->short_preamble = 0;
- change |= IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE;
-
- bssinfo->use_protection = 0;
- change |= IEEE80211SOFTMAC_BSSINFOCHG_PROTECTION;
-
- if (mac->bssinfo_change)
- mac->bssinfo_change(mac->dev, change);
-
- mac->running = 1;
-}
-
-void ieee80211softmac_start(struct net_device *dev)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
-
- ieee80211softmac_start_check_rates(mac);
- ieee80211softmac_init_bss(mac);
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_start);
-
-void ieee80211softmac_stop(struct net_device *dev)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
-
- ieee80211softmac_clear_pending_work(mac);
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_stop);
-
-void ieee80211softmac_set_rates(struct net_device *dev, u8 count, u8 *rates)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
- unsigned long flags;
-
- spin_lock_irqsave(&mac->lock, flags);
- memcpy(mac->ratesinfo.rates, rates, count);
- mac->ratesinfo.count = count;
- spin_unlock_irqrestore(&mac->lock, flags);
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_set_rates);
-
-static u8 raise_rate(struct ieee80211softmac_device *mac, u8 rate)
-{
- int i;
- struct ieee80211softmac_ratesinfo *ri = &mac->ratesinfo;
-
- for (i=0; i<ri->count-1; i++) {
- if (ri->rates[i] == rate)
- return ri->rates[i+1];
- }
- /* I guess we can't go any higher... */
- return ri->rates[ri->count];
-}
-
-u8 ieee80211softmac_lower_rate_delta(struct ieee80211softmac_device *mac, u8 rate, int delta)
-{
- int i;
- struct ieee80211softmac_ratesinfo *ri = &mac->ratesinfo;
-
- for (i=delta; i<ri->count; i++) {
- if (ri->rates[i] == rate)
- return ri->rates[i-delta];
- }
- /* I guess we can't go any lower... */
- return ri->rates[0];
-}
-
-static void ieee80211softmac_add_txrates_badness(struct ieee80211softmac_device *mac,
- int amount)
-{
- u8 default_rate = mac->txrates.default_rate;
- u8 default_fallback = mac->txrates.default_fallback;
- u32 changes = 0;
-
- //TODO: This is highly experimental code.
- // Maybe the dynamic rate selection does not work
- // and it has to be removed again.
-
-printk("badness %d\n", mac->txrate_badness);
- mac->txrate_badness += amount;
- if (mac->txrate_badness <= -1000) {
- /* Very small badness. Try a faster bitrate. */
- default_rate = raise_rate(mac, default_rate);
- changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
- default_fallback = get_fallback_rate(mac, default_rate);
- changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
- mac->txrate_badness = 0;
-printk("Bitrate raised to %u\n", default_rate);
- } else if (mac->txrate_badness >= 10000) {
- /* Very high badness. Try a slower bitrate. */
- default_rate = lower_rate(mac, default_rate);
- changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
- default_fallback = get_fallback_rate(mac, default_rate);
- changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
- mac->txrate_badness = 0;
-printk("Bitrate lowered to %u\n", default_rate);
- }
-
- mac->txrates.default_rate = default_rate;
- mac->txrates.default_fallback = default_fallback;
-
- if (changes && mac->txrates_change)
- mac->txrates_change(mac->dev, changes);
-}
-
-void ieee80211softmac_fragment_lost(struct net_device *dev,
- u16 wl_seq)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
- unsigned long flags;
-
- spin_lock_irqsave(&mac->lock, flags);
- ieee80211softmac_add_txrates_badness(mac, 1000);
- //TODO
-
- spin_unlock_irqrestore(&mac->lock, flags);
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_fragment_lost);
-
-static int rate_cmp(const void *a_, const void *b_) {
- u8 *a, *b;
- a = (u8*)a_;
- b = (u8*)b_;
- return ((*a & ~IEEE80211_BASIC_RATE_MASK) - (*b & ~IEEE80211_BASIC_RATE_MASK));
-}
-
-/* Allocate a softmac network struct and fill it from a network */
-struct ieee80211softmac_network *
-ieee80211softmac_create_network(struct ieee80211softmac_device *mac,
- struct ieee80211_network *net)
-{
- struct ieee80211softmac_network *softnet;
- softnet = kzalloc(sizeof(struct ieee80211softmac_network), GFP_ATOMIC);
- if(softnet == NULL)
- return NULL;
- memcpy(softnet->bssid, net->bssid, ETH_ALEN);
- softnet->channel = net->channel;
- softnet->essid.len = net->ssid_len;
- memcpy(softnet->essid.data, net->ssid, softnet->essid.len);
-
- /* copy rates over */
- softnet->supported_rates.count = net->rates_len;
- memcpy(&softnet->supported_rates.rates[0], net->rates, net->rates_len);
- memcpy(&softnet->supported_rates.rates[softnet->supported_rates.count], net->rates_ex, net->rates_ex_len);
- softnet->supported_rates.count += net->rates_ex_len;
- sort(softnet->supported_rates.rates, softnet->supported_rates.count, sizeof(softnet->supported_rates.rates[0]), rate_cmp, NULL);
-
- /* we save the ERP value because it is needed at association time, and
- * many AP's do not include an ERP IE in the association response. */
- softnet->erp_value = net->erp_value;
-
- softnet->capabilities = net->capability;
- return softnet;
-}
-
-
-/* Add a network to the list, while locked */
-void
-ieee80211softmac_add_network_locked(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *add_net)
-{
- struct ieee80211softmac_network *softmac_net;
-
- list_for_each_entry(softmac_net, &mac->network_list, list) {
- if(!memcmp(softmac_net->bssid, add_net->bssid, ETH_ALEN))
- return;
- }
- list_add(&(add_net->list), &mac->network_list);
-}
-
-/* Add a network to the list, with locking */
-void
-ieee80211softmac_add_network(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *add_net)
-{
- unsigned long flags;
- spin_lock_irqsave(&mac->lock, flags);
- ieee80211softmac_add_network_locked(mac, add_net);
- spin_unlock_irqrestore(&mac->lock, flags);
-}
-
-
-/* Delete a network from the list, while locked*/
-void
-ieee80211softmac_del_network_locked(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *del_net)
-{
- list_del(&(del_net->list));
-}
-
-/* Delete a network from the list with locking */
-void
-ieee80211softmac_del_network(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *del_net)
-{
- unsigned long flags;
- spin_lock_irqsave(&mac->lock, flags);
- ieee80211softmac_del_network_locked(mac, del_net);
- spin_unlock_irqrestore(&mac->lock, flags);
-}
-
-/* Get a network from the list by MAC while locked */
-struct ieee80211softmac_network *
-ieee80211softmac_get_network_by_bssid_locked(struct ieee80211softmac_device *mac,
- u8 *bssid)
-{
- struct ieee80211softmac_network *softmac_net;
-
- list_for_each_entry(softmac_net, &mac->network_list, list) {
- if(!memcmp(softmac_net->bssid, bssid, ETH_ALEN))
- return softmac_net;
- }
- return NULL;
-}
-
-/* Get a network from the list by BSSID with locking */
-struct ieee80211softmac_network *
-ieee80211softmac_get_network_by_bssid(struct ieee80211softmac_device *mac,
- u8 *bssid)
-{
- unsigned long flags;
- struct ieee80211softmac_network *softmac_net;
-
- spin_lock_irqsave(&mac->lock, flags);
- softmac_net = ieee80211softmac_get_network_by_bssid_locked(mac, bssid);
- spin_unlock_irqrestore(&mac->lock, flags);
- return softmac_net;
-}
-
-/* Get a network from the list by ESSID while locked */
-struct ieee80211softmac_network *
-ieee80211softmac_get_network_by_essid_locked(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_essid *essid)
-{
- struct ieee80211softmac_network *softmac_net;
-
- list_for_each_entry(softmac_net, &mac->network_list, list) {
- if (softmac_net->essid.len == essid->len &&
- !memcmp(softmac_net->essid.data, essid->data, essid->len))
- return softmac_net;
- }
- return NULL;
-}
-
-/* Get a network from the list by ESSID with locking */
-struct ieee80211softmac_network *
-ieee80211softmac_get_network_by_essid(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_essid *essid)
-{
- unsigned long flags;
- struct ieee80211softmac_network *softmac_net = NULL;
-
- spin_lock_irqsave(&mac->lock, flags);
- softmac_net = ieee80211softmac_get_network_by_essid_locked(mac, essid);
- spin_unlock_irqrestore(&mac->lock, flags);
- return softmac_net;
-}
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Johannes Berg");
-MODULE_AUTHOR("Joseph Jezak");
-MODULE_AUTHOR("Larry Finger");
-MODULE_AUTHOR("Danny van Dyk");
-MODULE_AUTHOR("Michael Buesch");
-MODULE_DESCRIPTION("802.11 software MAC");
diff --git a/net/ieee80211/softmac/ieee80211softmac_priv.h b/net/ieee80211/softmac/ieee80211softmac_priv.h
deleted file mode 100644
index c43b189634d..00000000000
--- a/net/ieee80211/softmac/ieee80211softmac_priv.h
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Internal softmac API definitions.
- *
- * Copyright (c) 2005, 2006 Johannes Berg <johannes@sipsolutions.net>
- * Joseph Jezak <josejx@gentoo.org>
- * Larry Finger <Larry.Finger@lwfinger.net>
- * Danny van Dyk <kugelfang@gentoo.org>
- * Michael Buesch <mbuesch@freenet.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called COPYING.
- */
-
-#ifndef IEEE80211SOFTMAC_PRIV_H_
-#define IEEE80211SOFTMAC_PRIV_H_
-
-#include <net/ieee80211softmac.h>
-#include <net/ieee80211softmac_wx.h>
-#include <linux/kernel.h>
-#include <linux/stringify.h>
-
-
-#define PFX "SoftMAC: "
-
-#ifdef assert
-# undef assert
-#endif
-#ifdef CONFIG_IEEE80211_SOFTMAC_DEBUG
-#define assert(expr) \
- do { \
- if (unlikely(!(expr))) { \
- printkl(KERN_ERR PFX "ASSERTION FAILED (%s) at: %s:%d:%s()\n", #expr, \
- __FILE__, __LINE__, __FUNCTION__); \
- } \
- } while (0)
-#else
-#define assert(expr) do {} while (0)
-#endif
-
-/* rate limited printk(). */
-#ifdef printkl
-# undef printkl
-#endif
-#define printkl(f, x...) do { if (printk_ratelimit()) printk(f ,##x); } while (0)
-/* rate limited printk() for debugging */
-#ifdef dprintkl
-# undef dprintkl
-#endif
-#ifdef CONFIG_IEEE80211_SOFTMAC_DEBUG
-# define dprintkl printkl
-#else
-# define dprintkl(f, x...) do { /* nothing */ } while (0)
-#endif
-
-/* debugging printk() */
-#ifdef dprintk
-# undef dprintk
-#endif
-#ifdef CONFIG_IEEE80211_SOFTMAC_DEBUG
-# define dprintk(f, x...) do { printk(f ,##x); } while (0)
-#else
-# define dprintk(f, x...) do { /* nothing */ } while (0)
-#endif
-
-/* private definitions and prototypes */
-
-/*** prototypes from _scan.c */
-void ieee80211softmac_scan(struct work_struct *work);
-/* for internal use if scanning is needed */
-int ieee80211softmac_start_scan(struct ieee80211softmac_device *mac);
-void ieee80211softmac_stop_scan(struct ieee80211softmac_device *mac);
-void ieee80211softmac_wait_for_scan(struct ieee80211softmac_device *mac);
-
-/* for use by _module.c to assign to the callbacks */
-int ieee80211softmac_start_scan_implementation(struct net_device *dev);
-void ieee80211softmac_stop_scan_implementation(struct net_device *dev);
-void ieee80211softmac_wait_for_scan_implementation(struct net_device *dev);
-
-/*** Network prototypes from _module.c */
-struct ieee80211softmac_network * ieee80211softmac_create_network(
- struct ieee80211softmac_device *mac, struct ieee80211_network *net);
-void ieee80211softmac_add_network_locked(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *net);
-void ieee80211softmac_add_network(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *net);
-void ieee80211softmac_del_network_locked(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *net);
-void ieee80211softmac_del_network(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *net);
-struct ieee80211softmac_network * ieee80211softmac_get_network_by_bssid_locked(
- struct ieee80211softmac_device *mac, u8 *ea);
-struct ieee80211softmac_network * ieee80211softmac_get_network_by_bssid(
- struct ieee80211softmac_device *mac, u8 *ea);
-struct ieee80211softmac_network * ieee80211softmac_get_network_by_ssid_locked(
- struct ieee80211softmac_device *mac, u8 *ssid, u8 ssid_len);
-struct ieee80211softmac_network * ieee80211softmac_get_network_by_ssid(
- struct ieee80211softmac_device *mac, u8 *ssid, u8 ssid_len);
-struct ieee80211softmac_network *
-ieee80211softmac_get_network_by_essid_locked(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_essid *essid);
-struct ieee80211softmac_network *
-ieee80211softmac_get_network_by_essid(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_essid *essid);
-
-/* Rates related */
-void ieee80211softmac_process_erp(struct ieee80211softmac_device *mac,
- u8 erp_value);
-int ieee80211softmac_ratesinfo_rate_supported(struct ieee80211softmac_ratesinfo *ri, u8 rate);
-u8 ieee80211softmac_lower_rate_delta(struct ieee80211softmac_device *mac, u8 rate, int delta);
-void ieee80211softmac_init_bss(struct ieee80211softmac_device *mac);
-void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac);
-static inline u8 lower_rate(struct ieee80211softmac_device *mac, u8 rate) {
- return ieee80211softmac_lower_rate_delta(mac, rate, 1);
-}
-
-static inline u8 get_fallback_rate(struct ieee80211softmac_device *mac, u8 rate)
-{
- return ieee80211softmac_lower_rate_delta(mac, rate, 2);
-}
-
-
-/*** prototypes from _io.c */
-int ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac,
- void* ptrarg, u32 type, u32 arg);
-int ieee80211softmac_handle_beacon(struct net_device *dev,
- struct ieee80211_beacon *beacon,
- struct ieee80211_network *network);
-
-/*** prototypes from _auth.c */
-/* do these have to go into the public header? */
-int ieee80211softmac_auth_req(struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net);
-int ieee80211softmac_deauth_req(struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net, int reason);
-
-/* for use by _module.c to assign to the callbacks */
-int ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth);
-int ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *deauth);
-
-/*** prototypes from _assoc.c */
-void ieee80211softmac_assoc_work(struct work_struct *work);
-int ieee80211softmac_handle_assoc_response(struct net_device * dev,
- struct ieee80211_assoc_response * resp,
- struct ieee80211_network * network);
-int ieee80211softmac_handle_disassoc(struct net_device * dev,
- struct ieee80211_disassoc * disassoc);
-int ieee80211softmac_handle_reassoc_req(struct net_device * dev,
- struct ieee80211_reassoc_request * reassoc);
-void ieee80211softmac_assoc_timeout(struct work_struct *work);
-void ieee80211softmac_send_disassoc_req(struct ieee80211softmac_device *mac, u16 reason);
-void ieee80211softmac_disassoc(struct ieee80211softmac_device *mac);
-
-/* some helper functions */
-static inline int ieee80211softmac_scan_handlers_check_self(struct ieee80211softmac_device *sm)
-{
- return (sm->start_scan == ieee80211softmac_start_scan_implementation) &&
- (sm->stop_scan == ieee80211softmac_stop_scan_implementation) &&
- (sm->wait_for_scan == ieee80211softmac_wait_for_scan_implementation);
-}
-
-static inline int ieee80211softmac_scan_sanity_check(struct ieee80211softmac_device *sm)
-{
- return ((sm->start_scan != ieee80211softmac_start_scan_implementation) &&
- (sm->stop_scan != ieee80211softmac_stop_scan_implementation) &&
- (sm->wait_for_scan != ieee80211softmac_wait_for_scan_implementation)
- ) || ieee80211softmac_scan_handlers_check_self(sm);
-}
-
-#define IEEE80211SOFTMAC_PROBE_DELAY HZ/50
-#define IEEE80211SOFTMAC_WORKQUEUE_NAME_LEN (17 + IFNAMSIZ)
-
-struct ieee80211softmac_network {
- struct list_head list; /* List */
- /* Network information copied from ieee80211_network */
- u8 bssid[ETH_ALEN];
- u8 channel;
- struct ieee80211softmac_essid essid;
-
- struct ieee80211softmac_ratesinfo supported_rates;
-
- /* SoftMAC specific */
- u16 authenticating:1, /* Status Flags */
- authenticated:1,
- auth_desynced_once:1;
-
- u8 erp_value; /* Saved ERP value */
- u16 capabilities; /* Capabilities bitfield */
- u8 challenge_len; /* Auth Challenge length */
- char *challenge; /* Challenge Text */
-};
-
-/* structure used to keep track of networks we're auth'ing to */
-struct ieee80211softmac_auth_queue_item {
- struct list_head list; /* List head */
- struct ieee80211softmac_network *net; /* Network to auth */
- struct ieee80211softmac_device *mac; /* SoftMAC device */
- u8 retry; /* Retry limit */
- u8 state; /* Auth State */
- struct delayed_work work; /* Work queue */
-};
-
-/* scanning information */
-struct ieee80211softmac_scaninfo {
- u8 current_channel_idx,
- number_channels;
- struct ieee80211_channel *channels;
- u8 started:1,
- stop:1;
- u8 skip_flags;
- struct completion finished;
- struct delayed_work softmac_scan;
- struct ieee80211softmac_device *mac;
-};
-
-/* private event struct */
-struct ieee80211softmac_event {
- struct list_head list;
- int event_type;
- void *event_context;
- struct delayed_work work;
- notify_function_ptr fun;
- void *context;
- struct ieee80211softmac_device *mac;
-};
-
-void ieee80211softmac_call_events(struct ieee80211softmac_device *mac, int event, void *event_context);
-void ieee80211softmac_call_events_locked(struct ieee80211softmac_device *mac, int event, void *event_context);
-int ieee80211softmac_notify_internal(struct ieee80211softmac_device *mac,
- int event, void *event_context, notify_function_ptr fun, void *context, gfp_t gfp_mask);
-
-void ieee80211softmac_try_reassoc(struct ieee80211softmac_device *mac);
-
-#endif /* IEEE80211SOFTMAC_PRIV_H_ */
diff --git a/net/ieee80211/softmac/ieee80211softmac_scan.c b/net/ieee80211/softmac/ieee80211softmac_scan.c
deleted file mode 100644
index bfab8d7db88..00000000000
--- a/net/ieee80211/softmac/ieee80211softmac_scan.c
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Scanning routines.
- *
- * These are not exported because they're assigned to the function pointers.
- *
- * Copyright (c) 2005, 2006 Johannes Berg <johannes@sipsolutions.net>
- * Joseph Jezak <josejx@gentoo.org>
- * Larry Finger <Larry.Finger@lwfinger.net>
- * Danny van Dyk <kugelfang@gentoo.org>
- * Michael Buesch <mbuesch@freenet.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called COPYING.
- */
-
-#include <linux/completion.h>
-#include "ieee80211softmac_priv.h"
-
-/* internal, use to trigger scanning if needed.
- * Returns -EBUSY if already scanning,
- * result of start_scan otherwise */
-int
-ieee80211softmac_start_scan(struct ieee80211softmac_device *sm)
-{
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&sm->lock, flags);
- if (sm->scanning)
- {
- spin_unlock_irqrestore(&sm->lock, flags);
- return -EINPROGRESS;
- }
- sm->scanning = 1;
- spin_unlock_irqrestore(&sm->lock, flags);
-
- ret = sm->start_scan(sm->dev);
- if (ret) {
- spin_lock_irqsave(&sm->lock, flags);
- sm->scanning = 0;
- spin_unlock_irqrestore(&sm->lock, flags);
- }
- return ret;
-}
-
-void
-ieee80211softmac_stop_scan(struct ieee80211softmac_device *sm)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&sm->lock, flags);
-
- if (!sm->scanning) {
- spin_unlock_irqrestore(&sm->lock, flags);
- return;
- }
-
- spin_unlock_irqrestore(&sm->lock, flags);
- sm->stop_scan(sm->dev);
-}
-
-void
-ieee80211softmac_wait_for_scan(struct ieee80211softmac_device *sm)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&sm->lock, flags);
-
- if (!sm->scanning) {
- spin_unlock_irqrestore(&sm->lock, flags);
- return;
- }
-
- spin_unlock_irqrestore(&sm->lock, flags);
- sm->wait_for_scan(sm->dev);
-}
-
-
-/* internal scanning implementation follows */
-void ieee80211softmac_scan(struct work_struct *work)
-{
- int invalid_channel;
- u8 current_channel_idx;
- struct ieee80211softmac_scaninfo *si =
- container_of(work, struct ieee80211softmac_scaninfo,
- softmac_scan.work);
- struct ieee80211softmac_device *sm = si->mac;
- unsigned long flags;
-
- while (!(si->stop) && (si->current_channel_idx < si->number_channels)) {
- current_channel_idx = si->current_channel_idx;
- si->current_channel_idx++; /* go to the next channel */
-
- invalid_channel = (si->skip_flags & si->channels[current_channel_idx].flags);
-
- if (!invalid_channel) {
- sm->set_channel(sm->dev, si->channels[current_channel_idx].channel);
- // FIXME make this user configurable (active/passive)
- if(ieee80211softmac_send_mgt_frame(sm, NULL, IEEE80211_STYPE_PROBE_REQ, 0))
- printkl(KERN_DEBUG PFX "Sending Probe Request Failed\n");
-
- /* also send directed management frame for the network we're looking for */
- // TODO: is this if correct, or should we do this only if scanning from assoc request?
- if (sm->associnfo.req_essid.len)
- ieee80211softmac_send_mgt_frame(sm, &sm->associnfo.req_essid, IEEE80211_STYPE_PROBE_REQ, 0);
-
- spin_lock_irqsave(&sm->lock, flags);
- if (unlikely(!sm->running)) {
- /* Prevent reschedule on workqueue flush */
- spin_unlock_irqrestore(&sm->lock, flags);
- break;
- }
- queue_delayed_work(sm->wq, &si->softmac_scan, IEEE80211SOFTMAC_PROBE_DELAY);
- spin_unlock_irqrestore(&sm->lock, flags);
- return;
- } else {
- dprintk(PFX "Not probing Channel %d (not allowed here)\n", si->channels[current_channel_idx].channel);
- }
- }
-
- spin_lock_irqsave(&sm->lock, flags);
- cancel_delayed_work(&si->softmac_scan);
- si->started = 0;
- spin_unlock_irqrestore(&sm->lock, flags);
-
- dprintk(PFX "Scanning finished: scanned %d channels starting with channel %d\n",
- sm->scaninfo->number_channels, sm->scaninfo->channels[0].channel);
- ieee80211softmac_scan_finished(sm);
- complete_all(&sm->scaninfo->finished);
-}
-
-static inline struct ieee80211softmac_scaninfo *allocate_scaninfo(struct ieee80211softmac_device *mac)
-{
- /* ugh. can we call this without having the spinlock held? */
- struct ieee80211softmac_scaninfo *info = kmalloc(sizeof(struct ieee80211softmac_scaninfo), GFP_ATOMIC);
- if (unlikely(!info))
- return NULL;
- INIT_DELAYED_WORK(&info->softmac_scan, ieee80211softmac_scan);
- info->mac = mac;
- init_completion(&info->finished);
- return info;
-}
-
-int ieee80211softmac_start_scan_implementation(struct net_device *dev)
-{
- struct ieee80211softmac_device *sm = ieee80211_priv(dev);
- unsigned long flags;
-
- if (!(dev->flags & IFF_UP))
- return -ENODEV;
-
- assert(ieee80211softmac_scan_handlers_check_self(sm));
- if (!ieee80211softmac_scan_handlers_check_self(sm))
- return -EINVAL;
-
- spin_lock_irqsave(&sm->lock, flags);
- /* it looks like we need to hold the lock here
- * to make sure we don't allocate two of these... */
- if (unlikely(!sm->scaninfo))
- sm->scaninfo = allocate_scaninfo(sm);
- if (unlikely(!sm->scaninfo)) {
- spin_unlock_irqrestore(&sm->lock, flags);
- return -ENOMEM;
- }
-
- sm->scaninfo->skip_flags = IEEE80211_CH_INVALID;
- if (0 /* not scanning in IEEE802.11b */)//TODO
- sm->scaninfo->skip_flags |= IEEE80211_CH_B_ONLY;
- if (0 /* IEEE802.11a */) {//TODO
- sm->scaninfo->channels = sm->ieee->geo.a;
- sm->scaninfo->number_channels = sm->ieee->geo.a_channels;
- } else {
- sm->scaninfo->channels = sm->ieee->geo.bg;
- sm->scaninfo->number_channels = sm->ieee->geo.bg_channels;
- }
- sm->scaninfo->current_channel_idx = 0;
- sm->scaninfo->started = 1;
- sm->scaninfo->stop = 0;
- INIT_COMPLETION(sm->scaninfo->finished);
- queue_delayed_work(sm->wq, &sm->scaninfo->softmac_scan, 0);
- spin_unlock_irqrestore(&sm->lock, flags);
- return 0;
-}
-
-void ieee80211softmac_stop_scan_implementation(struct net_device *dev)
-{
- struct ieee80211softmac_device *sm = ieee80211_priv(dev);
- unsigned long flags;
-
- assert(ieee80211softmac_scan_handlers_check_self(sm));
- if (!ieee80211softmac_scan_handlers_check_self(sm))
- return;
-
- spin_lock_irqsave(&sm->lock, flags);
- assert(sm->scaninfo != NULL);
- if (sm->scaninfo) {
- if (sm->scaninfo->started)
- sm->scaninfo->stop = 1;
- else
- complete_all(&sm->scaninfo->finished);
- }
- spin_unlock_irqrestore(&sm->lock, flags);
-}
-
-void ieee80211softmac_wait_for_scan_implementation(struct net_device *dev)
-{
- struct ieee80211softmac_device *sm = ieee80211_priv(dev);
- unsigned long flags;
-
- assert(ieee80211softmac_scan_handlers_check_self(sm));
- if (!ieee80211softmac_scan_handlers_check_self(sm))
- return;
-
- spin_lock_irqsave(&sm->lock, flags);
- if (!sm->scaninfo->started) {
- spin_unlock_irqrestore(&sm->lock, flags);
- return;
- }
- spin_unlock_irqrestore(&sm->lock, flags);
- wait_for_completion(&sm->scaninfo->finished);
-}
-
-/* this is what drivers (that do scanning) call when they're done */
-void ieee80211softmac_scan_finished(struct ieee80211softmac_device *sm)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&sm->lock, flags);
- sm->scanning = 0;
- spin_unlock_irqrestore(&sm->lock, flags);
-
- if (sm->associnfo.bssvalid) {
- struct ieee80211softmac_network *net;
-
- net = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid);
- if (net)
- sm->set_channel(sm->dev, net->channel);
- }
- ieee80211softmac_call_events(sm, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, NULL);
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_scan_finished);
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c
deleted file mode 100644
index e01b59aedc5..00000000000
--- a/net/ieee80211/softmac/ieee80211softmac_wx.c
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- * This file contains our _wx handlers. Make sure you EXPORT_SYMBOL_GPL them
- *
- * Copyright (c) 2005, 2006 Johannes Berg <johannes@sipsolutions.net>
- * Joseph Jezak <josejx@gentoo.org>
- * Larry Finger <Larry.Finger@lwfinger.net>
- * Danny van Dyk <kugelfang@gentoo.org>
- * Michael Buesch <mbuesch@freenet.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called COPYING.
- */
-
-#include "ieee80211softmac_priv.h"
-
-#include <net/iw_handler.h>
-/* for is_broadcast_ether_addr and is_zero_ether_addr */
-#include <linux/etherdevice.h>
-
-int
-ieee80211softmac_wx_trigger_scan(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct ieee80211softmac_device *sm = ieee80211_priv(net_dev);
- return ieee80211softmac_start_scan(sm);
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_wx_trigger_scan);
-
-
-/* if we're still scanning, return -EAGAIN so that userspace tools
- * can get the complete scan results, otherwise return 0. */
-int
-ieee80211softmac_wx_get_scan_results(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- unsigned long flags;
- struct ieee80211softmac_device *sm = ieee80211_priv(net_dev);
-
- spin_lock_irqsave(&sm->lock, flags);
- if (sm->scanning) {
- spin_unlock_irqrestore(&sm->lock, flags);
- return -EAGAIN;
- }
- spin_unlock_irqrestore(&sm->lock, flags);
- return ieee80211_wx_get_scan(sm->ieee, info, data, extra);
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_scan_results);
-
-int
-ieee80211softmac_wx_set_essid(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct ieee80211softmac_device *sm = ieee80211_priv(net_dev);
- struct ieee80211softmac_auth_queue_item *authptr;
- int length = 0;
- DECLARE_MAC_BUF(mac);
-
-check_assoc_again:
- mutex_lock(&sm->associnfo.mutex);
- if((sm->associnfo.associating || sm->associnfo.associated) &&
- (data->essid.flags && data->essid.length)) {
- dprintk(KERN_INFO PFX "Canceling existing associate request!\n");
- /* Cancel assoc work */
- cancel_delayed_work(&sm->associnfo.work);
- /* We don't have to do this, but it's a little cleaner */
- list_for_each_entry(authptr, &sm->auth_queue, list)
- cancel_delayed_work(&authptr->work);
- sm->associnfo.bssvalid = 0;
- sm->associnfo.bssfixed = 0;
- sm->associnfo.associating = 0;
- sm->associnfo.associated = 0;
- /* We must unlock to avoid deadlocks with the assoc workqueue
- * on the associnfo.mutex */
- mutex_unlock(&sm->associnfo.mutex);
- flush_workqueue(sm->wq);
- /* Avoid race! Check assoc status again. Maybe someone started an
- * association while we flushed. */
- goto check_assoc_again;
- }
-
- sm->associnfo.static_essid = 0;
- sm->associnfo.assoc_wait = 0;
-
- if (data->essid.flags && data->essid.length) {
- length = min((int)data->essid.length, IW_ESSID_MAX_SIZE);
- if (length) {
- memcpy(sm->associnfo.req_essid.data, extra, length);
- sm->associnfo.static_essid = 1;
- }
- }
-
- /* set our requested ESSID length.
- * If applicable, we have already copied the data in */
- sm->associnfo.req_essid.len = length;
-
- sm->associnfo.associating = 1;
- /* queue lower level code to do work (if necessary) */
- queue_delayed_work(sm->wq, &sm->associnfo.work, 0);
-
- mutex_unlock(&sm->associnfo.mutex);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid);
-
-int
-ieee80211softmac_wx_get_essid(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct ieee80211softmac_device *sm = ieee80211_priv(net_dev);
-
- mutex_lock(&sm->associnfo.mutex);
- /* If all fails, return ANY (empty) */
- data->essid.length = 0;
- data->essid.flags = 0; /* active */
-
- /* If we have a statically configured ESSID then return it */
- if (sm->associnfo.static_essid) {
- data->essid.length = sm->associnfo.req_essid.len;
- data->essid.flags = 1; /* active */
- memcpy(extra, sm->associnfo.req_essid.data, sm->associnfo.req_essid.len);
- dprintk(KERN_INFO PFX "Getting essid from req_essid\n");
- } else if (sm->associnfo.associated || sm->associnfo.associating) {
- /* If we're associating/associated, return that */
- data->essid.length = sm->associnfo.associate_essid.len;
- data->essid.flags = 1; /* active */
- memcpy(extra, sm->associnfo.associate_essid.data, sm->associnfo.associate_essid.len);
- dprintk(KERN_INFO PFX "Getting essid from associate_essid\n");
- }
- mutex_unlock(&sm->associnfo.mutex);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid);
-
-int
-ieee80211softmac_wx_set_rate(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
- struct ieee80211_device *ieee = mac->ieee;
- unsigned long flags;
- s32 in_rate = data->bitrate.value;
- u8 rate;
- int is_ofdm = 0;
- int err = -EINVAL;
-
- if (in_rate == -1) {
- if (ieee->modulation & IEEE80211_OFDM_MODULATION)
- in_rate = 24000000;
- else
- in_rate = 11000000;
- }
-
- switch (in_rate) {
- case 1000000:
- rate = IEEE80211_CCK_RATE_1MB;
- break;
- case 2000000:
- rate = IEEE80211_CCK_RATE_2MB;
- break;
- case 5500000:
- rate = IEEE80211_CCK_RATE_5MB;
- break;
- case 11000000:
- rate = IEEE80211_CCK_RATE_11MB;
- break;
- case 6000000:
- rate = IEEE80211_OFDM_RATE_6MB;
- is_ofdm = 1;
- break;
- case 9000000:
- rate = IEEE80211_OFDM_RATE_9MB;
- is_ofdm = 1;
- break;
- case 12000000:
- rate = IEEE80211_OFDM_RATE_12MB;
- is_ofdm = 1;
- break;
- case 18000000:
- rate = IEEE80211_OFDM_RATE_18MB;
- is_ofdm = 1;
- break;
- case 24000000:
- rate = IEEE80211_OFDM_RATE_24MB;
- is_ofdm = 1;
- break;
- case 36000000:
- rate = IEEE80211_OFDM_RATE_36MB;
- is_ofdm = 1;
- break;
- case 48000000:
- rate = IEEE80211_OFDM_RATE_48MB;
- is_ofdm = 1;
- break;
- case 54000000:
- rate = IEEE80211_OFDM_RATE_54MB;
- is_ofdm = 1;
- break;
- default:
- goto out;
- }
-
- spin_lock_irqsave(&mac->lock, flags);
-
- /* Check if correct modulation for this PHY. */
- if (is_ofdm && !(ieee->modulation & IEEE80211_OFDM_MODULATION))
- goto out_unlock;
-
- mac->txrates.user_rate = rate;
- ieee80211softmac_recalc_txrates(mac);
- err = 0;
-
-out_unlock:
- spin_unlock_irqrestore(&mac->lock, flags);
-out:
- return err;
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_rate);
-
-int
-ieee80211softmac_wx_get_rate(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
- unsigned long flags;
- int err = -EINVAL;
-
- spin_lock_irqsave(&mac->lock, flags);
-
- if (unlikely(!mac->running)) {
- err = -ENODEV;
- goto out_unlock;
- }
-
- switch (mac->txrates.default_rate) {
- case IEEE80211_CCK_RATE_1MB:
- data->bitrate.value = 1000000;
- break;
- case IEEE80211_CCK_RATE_2MB:
- data->bitrate.value = 2000000;
- break;
- case IEEE80211_CCK_RATE_5MB:
- data->bitrate.value = 5500000;
- break;
- case IEEE80211_CCK_RATE_11MB:
- data->bitrate.value = 11000000;
- break;
- case IEEE80211_OFDM_RATE_6MB:
- data->bitrate.value = 6000000;
- break;
- case IEEE80211_OFDM_RATE_9MB:
- data->bitrate.value = 9000000;
- break;
- case IEEE80211_OFDM_RATE_12MB:
- data->bitrate.value = 12000000;
- break;
- case IEEE80211_OFDM_RATE_18MB:
- data->bitrate.value = 18000000;
- break;
- case IEEE80211_OFDM_RATE_24MB:
- data->bitrate.value = 24000000;
- break;
- case IEEE80211_OFDM_RATE_36MB:
- data->bitrate.value = 36000000;
- break;
- case IEEE80211_OFDM_RATE_48MB:
- data->bitrate.value = 48000000;
- break;
- case IEEE80211_OFDM_RATE_54MB:
- data->bitrate.value = 54000000;
- break;
- default:
- assert(0);
- goto out_unlock;
- }
- err = 0;
-out_unlock:
- spin_unlock_irqrestore(&mac->lock, flags);
-
- return err;
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_rate);
-
-int
-ieee80211softmac_wx_get_wap(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
- int err = 0;
-
- mutex_lock(&mac->associnfo.mutex);
- if (mac->associnfo.bssvalid)
- memcpy(data->ap_addr.sa_data, mac->associnfo.bssid, ETH_ALEN);
- else
- memset(data->ap_addr.sa_data, 0xff, ETH_ALEN);
- data->ap_addr.sa_family = ARPHRD_ETHER;
- mutex_unlock(&mac->associnfo.mutex);
-
- return err;
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap);
-
-int
-ieee80211softmac_wx_set_wap(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
-
- /* sanity check */
- if (data->ap_addr.sa_family != ARPHRD_ETHER) {
- return -EINVAL;
- }
-
- mutex_lock(&mac->associnfo.mutex);
- if (is_broadcast_ether_addr(data->ap_addr.sa_data)) {
- /* the bssid we have is not to be fixed any longer,
- * and we should reassociate to the best AP. */
- mac->associnfo.bssfixed = 0;
- /* force reassociation */
- mac->associnfo.bssvalid = 0;
- if (mac->associnfo.associated)
- queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
- } else if (is_zero_ether_addr(data->ap_addr.sa_data)) {
- /* the bssid we have is no longer fixed */
- mac->associnfo.bssfixed = 0;
- } else {
- if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) {
- if (mac->associnfo.associating || mac->associnfo.associated) {
- /* bssid unchanged and associated or associating - just return */
- goto out;
- }
- } else {
- /* copy new value in data->ap_addr.sa_data to bssid */
- memcpy(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN);
- }
- /* tell the other code that this bssid should be used no matter what */
- mac->associnfo.bssfixed = 1;
- /* queue associate if new bssid or (old one again and not associated) */
- queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
- }
-
- out:
- mutex_unlock(&mac->associnfo.mutex);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap);
-
-int
-ieee80211softmac_wx_set_genie(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
- unsigned long flags;
- int err = 0;
- char *buf;
- int i;
-
- mutex_lock(&mac->associnfo.mutex);
- spin_lock_irqsave(&mac->lock, flags);
- /* bleh. shouldn't be locked for that kmalloc... */
-
- if (wrqu->data.length) {
- if ((wrqu->data.length < 2) || (extra[1]+2 != wrqu->data.length)) {
- /* this is an IE, so the length must be
- * correct. Is it possible though that
- * more than one IE is passed in?
- */
- err = -EINVAL;
- goto out;
- }
- if (mac->wpa.IEbuflen <= wrqu->data.length) {
- buf = kmalloc(wrqu->data.length, GFP_ATOMIC);
- if (!buf) {
- err = -ENOMEM;
- goto out;
- }
- kfree(mac->wpa.IE);
- mac->wpa.IE = buf;
- mac->wpa.IEbuflen = wrqu->data.length;
- }
- memcpy(mac->wpa.IE, extra, wrqu->data.length);
- dprintk(KERN_INFO PFX "generic IE set to ");
- for (i=0;i<wrqu->data.length;i++)
- dprintk("%.2x", (u8)mac->wpa.IE[i]);
- dprintk("\n");
- mac->wpa.IElen = wrqu->data.length;
- } else {
- kfree(mac->wpa.IE);
- mac->wpa.IE = NULL;
- mac->wpa.IElen = 0;
- mac->wpa.IEbuflen = 0;
- }
-
- out:
- spin_unlock_irqrestore(&mac->lock, flags);
- mutex_unlock(&mac->associnfo.mutex);
-
- return err;
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie);
-
-int
-ieee80211softmac_wx_get_genie(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
- unsigned long flags;
- int err = 0;
- int space = wrqu->data.length;
-
- mutex_lock(&mac->associnfo.mutex);
- spin_lock_irqsave(&mac->lock, flags);
-
- wrqu->data.length = 0;
-
- if (mac->wpa.IE && mac->wpa.IElen) {
- wrqu->data.length = mac->wpa.IElen;
- if (mac->wpa.IElen <= space)
- memcpy(extra, mac->wpa.IE, mac->wpa.IElen);
- else
- err = -E2BIG;
- }
- spin_unlock_irqrestore(&mac->lock, flags);
- mutex_unlock(&mac->associnfo.mutex);
-
- return err;
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie);
-
-int
-ieee80211softmac_wx_set_mlme(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
- struct iw_mlme *mlme = (struct iw_mlme *)extra;
- u16 reason = mlme->reason_code;
- struct ieee80211softmac_network *net;
- int err = -EINVAL;
-
- mutex_lock(&mac->associnfo.mutex);
-
- if (memcmp(mac->associnfo.bssid, mlme->addr.sa_data, ETH_ALEN)) {
- printk(KERN_DEBUG PFX "wx_set_mlme: requested operation on net we don't use\n");
- goto out;
- }
-
- switch (mlme->cmd) {
- case IW_MLME_DEAUTH:
- net = ieee80211softmac_get_network_by_bssid_locked(mac, mlme->addr.sa_data);
- if (!net) {
- printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n");
- goto out;
- }
- err = ieee80211softmac_deauth_req(mac, net, reason);
- goto out;
- case IW_MLME_DISASSOC:
- ieee80211softmac_send_disassoc_req(mac, reason);
- mac->associnfo.associated = 0;
- mac->associnfo.associating = 0;
- err = 0;
- goto out;
- default:
- err = -EOPNOTSUPP;
- }
-
-out:
- mutex_unlock(&mac->associnfo.mutex);
-
- return err;
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_mlme);