]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/wireless/hostap/hostap_ioctl.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
[linux-2.6-omap-h63xx.git] / drivers / net / wireless / hostap / hostap_ioctl.c
index 2318c5df7a08876d532d50faed32a65fd5769100..3f2bda881a4f1a40e68b00fc24045c583ae2c0a2 100644 (file)
@@ -2,7 +2,8 @@
 
 #include <linux/types.h>
 #include <linux/ethtool.h>
-#include <net/ieee80211_crypt.h>
+#include <linux/if_arp.h>
+#include <net/lib80211.h>
 
 #include "hostap_wlan.h"
 #include "hostap.h"
@@ -116,32 +117,6 @@ static int prism2_get_name(struct net_device *dev,
 }
 
 
-static void prism2_crypt_delayed_deinit(local_info_t *local,
-                                       struct ieee80211_crypt_data **crypt)
-{
-       struct ieee80211_crypt_data *tmp;
-       unsigned long flags;
-
-       tmp = *crypt;
-       *crypt = NULL;
-
-       if (tmp == NULL)
-               return;
-
-       /* 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(&local->lock, flags);
-       list_add(&tmp->list, &local->crypt_deinit_list);
-       if (!timer_pending(&local->crypt_deinit_timer)) {
-               local->crypt_deinit_timer.expires = jiffies + HZ;
-               add_timer(&local->crypt_deinit_timer);
-       }
-       spin_unlock_irqrestore(&local->lock, flags);
-}
-
-
 static int prism2_ioctl_siwencode(struct net_device *dev,
                                  struct iw_request_info *info,
                                  struct iw_point *erq, char *keybuf)
@@ -149,47 +124,47 @@ static int prism2_ioctl_siwencode(struct net_device *dev,
        struct hostap_interface *iface;
        local_info_t *local;
        int i;
-       struct ieee80211_crypt_data **crypt;
+       struct lib80211_crypt_data **crypt;
 
        iface = netdev_priv(dev);
        local = iface->local;
 
        i = erq->flags & IW_ENCODE_INDEX;
        if (i < 1 || i > 4)
-               i = local->tx_keyidx;
+               i = local->crypt_info.tx_keyidx;
        else
                i--;
        if (i < 0 || i >= WEP_KEYS)
                return -EINVAL;
 
-       crypt = &local->crypt[i];
+       crypt = &local->crypt_info.crypt[i];
 
        if (erq->flags & IW_ENCODE_DISABLED) {
                if (*crypt)
-                       prism2_crypt_delayed_deinit(local, crypt);
+                       lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
                goto done;
        }
 
        if (*crypt != NULL && (*crypt)->ops != NULL &&
            strcmp((*crypt)->ops->name, "WEP") != 0) {
                /* changing to use WEP; deinit previously used algorithm */
-               prism2_crypt_delayed_deinit(local, crypt);
+               lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
        }
 
        if (*crypt == NULL) {
-               struct ieee80211_crypt_data *new_crypt;
+               struct lib80211_crypt_data *new_crypt;
 
                /* take WEP into use */
-               new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
+               new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
                                GFP_KERNEL);
                if (new_crypt == NULL)
                        return -ENOMEM;
-               new_crypt->ops = ieee80211_get_crypto_ops("WEP");
+               new_crypt->ops = lib80211_get_crypto_ops("WEP");
                if (!new_crypt->ops) {
-                       request_module("ieee80211_crypt_wep");
-                       new_crypt->ops = ieee80211_get_crypto_ops("WEP");
+                       request_module("lib80211_crypt_wep");
+                       new_crypt->ops = lib80211_get_crypto_ops("WEP");
                }
-               if (new_crypt->ops)
+               if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
                        new_crypt->priv = new_crypt->ops->init(i);
                if (!new_crypt->ops || !new_crypt->priv) {
                        kfree(new_crypt);
@@ -210,16 +185,16 @@ static int prism2_ioctl_siwencode(struct net_device *dev,
                        memset(keybuf + erq->length, 0, len - erq->length);
                (*crypt)->ops->set_key(keybuf, len, NULL, (*crypt)->priv);
                for (j = 0; j < WEP_KEYS; j++) {
-                       if (j != i && local->crypt[j]) {
+                       if (j != i && local->crypt_info.crypt[j]) {
                                first = 0;
                                break;
                        }
                }
                if (first)
-                       local->tx_keyidx = i;
+                       local->crypt_info.tx_keyidx = i;
        } else {
                /* No key data - just set the default TX key index */
-               local->tx_keyidx = i;
+               local->crypt_info.tx_keyidx = i;
        }
 
  done:
@@ -252,20 +227,20 @@ static int prism2_ioctl_giwencode(struct net_device *dev,
        local_info_t *local;
        int i, len;
        u16 val;
-       struct ieee80211_crypt_data *crypt;
+       struct lib80211_crypt_data *crypt;
 
        iface = netdev_priv(dev);
        local = iface->local;
 
        i = erq->flags & IW_ENCODE_INDEX;
        if (i < 1 || i > 4)
-               i = local->tx_keyidx;
+               i = local->crypt_info.tx_keyidx;
        else
                i--;
        if (i < 0 || i >= WEP_KEYS)
                return -EINVAL;
 
-       crypt = local->crypt[i];
+       crypt = local->crypt_info.crypt[i];
        erq->flags = i + 1;
 
        if (crypt == NULL || crypt->ops == NULL) {
@@ -1664,7 +1639,7 @@ static int prism2_request_hostscan(struct net_device *dev,
        memset(&scan_req, 0, sizeof(scan_req));
        scan_req.channel_list = cpu_to_le16(local->channel_mask &
                                            local->scan_channel_mask);
-       scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS);
+       scan_req.txrate = cpu_to_le16(HFA384X_RATES_1MBPS);
        if (ssid) {
                if (ssid_len > 32)
                        return -EINVAL;
@@ -1694,7 +1669,7 @@ static int prism2_request_scan(struct net_device *dev)
        memset(&scan_req, 0, sizeof(scan_req));
        scan_req.channel_list = cpu_to_le16(local->channel_mask &
                                            local->scan_channel_mask);
-       scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS);
+       scan_req.txrate = cpu_to_le16(HFA384X_RATES_1MBPS);
 
        /* FIX:
         * It seems to be enough to set roaming mode for a short moment to
@@ -2540,7 +2515,7 @@ static int prism2_ioctl_priv_prism2_param(struct net_device *dev,
                u16 rate;
 
                memset(&scan_req, 0, sizeof(scan_req));
-               scan_req.channel_list = __constant_cpu_to_le16(0x3fff);
+               scan_req.channel_list = cpu_to_le16(0x3fff);
                switch (value) {
                case 1: rate = HFA384X_RATES_1MBPS; break;
                case 2: rate = HFA384X_RATES_2MBPS; break;
@@ -3227,8 +3202,8 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
        local_info_t *local = iface->local;
        struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
        int i, ret = 0;
-       struct ieee80211_crypto_ops *ops;
-       struct ieee80211_crypt_data **crypt;
+       struct lib80211_crypto_ops *ops;
+       struct lib80211_crypt_data **crypt;
        void *sta_ptr;
        u8 *addr;
        const char *alg, *module;
@@ -3237,7 +3212,7 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
        if (i > WEP_KEYS)
                return -EINVAL;
        if (i < 1 || i > WEP_KEYS)
-               i = local->tx_keyidx;
+               i = local->crypt_info.tx_keyidx;
        else
                i--;
        if (i < 0 || i >= WEP_KEYS)
@@ -3247,7 +3222,7 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
        if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff &&
            addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) {
                sta_ptr = NULL;
-               crypt = &local->crypt[i];
+               crypt = &local->crypt_info.crypt[i];
        } else {
                if (i != 0)
                        return -EINVAL;
@@ -3260,7 +3235,7 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
                                 * is emulated by using default key idx 0.
                                 */
                                i = 0;
-                               crypt = &local->crypt[i];
+                               crypt = &local->crypt_info.crypt[i];
                        } else
                                return -EINVAL;
                }
@@ -3269,22 +3244,22 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
        if ((erq->flags & IW_ENCODE_DISABLED) ||
            ext->alg == IW_ENCODE_ALG_NONE) {
                if (*crypt)
-                       prism2_crypt_delayed_deinit(local, crypt);
+                       lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
                goto done;
        }
 
        switch (ext->alg) {
        case IW_ENCODE_ALG_WEP:
                alg = "WEP";
-               module = "ieee80211_crypt_wep";
+               module = "lib80211_crypt_wep";
                break;
        case IW_ENCODE_ALG_TKIP:
                alg = "TKIP";
-               module = "ieee80211_crypt_tkip";
+               module = "lib80211_crypt_tkip";
                break;
        case IW_ENCODE_ALG_CCMP:
                alg = "CCMP";
-               module = "ieee80211_crypt_ccmp";
+               module = "lib80211_crypt_ccmp";
                break;
        default:
                printk(KERN_DEBUG "%s: unsupported algorithm %d\n",
@@ -3293,10 +3268,10 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
                goto done;
        }
 
-       ops = ieee80211_get_crypto_ops(alg);
+       ops = lib80211_get_crypto_ops(alg);
        if (ops == NULL) {
                request_module(module);
-               ops = ieee80211_get_crypto_ops(alg);
+               ops = lib80211_get_crypto_ops(alg);
        }
        if (ops == NULL) {
                printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n",
@@ -3315,18 +3290,19 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
        }
 
        if (*crypt == NULL || (*crypt)->ops != ops) {
-               struct ieee80211_crypt_data *new_crypt;
+               struct lib80211_crypt_data *new_crypt;
 
-               prism2_crypt_delayed_deinit(local, crypt);
+               lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
 
-               new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
+               new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
                                GFP_KERNEL);
                if (new_crypt == NULL) {
                        ret = -ENOMEM;
                        goto done;
                }
                new_crypt->ops = ops;
-               new_crypt->priv = new_crypt->ops->init(i);
+               if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+                       new_crypt->priv = new_crypt->ops->init(i);
                if (new_crypt->priv == NULL) {
                        kfree(new_crypt);
                        ret = -EINVAL;
@@ -3354,20 +3330,20 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
 
        if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
                if (!sta_ptr)
-                       local->tx_keyidx = i;
+                       local->crypt_info.tx_keyidx = i;
        }
 
 
        if (sta_ptr == NULL && ext->key_len > 0) {
                int first = 1, j;
                for (j = 0; j < WEP_KEYS; j++) {
-                       if (j != i && local->crypt[j]) {
+                       if (j != i && local->crypt_info.crypt[j]) {
                                first = 0;
                                break;
                        }
                }
                if (first)
-                       local->tx_keyidx = i;
+                       local->crypt_info.tx_keyidx = i;
        }
 
  done:
@@ -3399,7 +3375,7 @@ static int prism2_ioctl_giwencodeext(struct net_device *dev,
 {
        struct hostap_interface *iface = netdev_priv(dev);
        local_info_t *local = iface->local;
-       struct ieee80211_crypt_data **crypt;
+       struct lib80211_crypt_data **crypt;
        void *sta_ptr;
        int max_key_len, i;
        struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
@@ -3411,7 +3387,7 @@ static int prism2_ioctl_giwencodeext(struct net_device *dev,
 
        i = erq->flags & IW_ENCODE_INDEX;
        if (i < 1 || i > WEP_KEYS)
-               i = local->tx_keyidx;
+               i = local->crypt_info.tx_keyidx;
        else
                i--;
 
@@ -3419,7 +3395,7 @@ static int prism2_ioctl_giwencodeext(struct net_device *dev,
        if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff &&
            addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) {
                sta_ptr = NULL;
-               crypt = &local->crypt[i];
+               crypt = &local->crypt_info.crypt[i];
        } else {
                i = 0;
                sta_ptr = ap_crypt_get_ptrs(local->ap, addr, 0, &crypt);
@@ -3468,8 +3444,8 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
                                       int param_len)
 {
        int ret = 0;
-       struct ieee80211_crypto_ops *ops;
-       struct ieee80211_crypt_data **crypt;
+       struct lib80211_crypto_ops *ops;
+       struct lib80211_crypt_data **crypt;
        void *sta_ptr;
 
        param->u.crypt.err = 0;
@@ -3486,7 +3462,7 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
                if (param->u.crypt.idx >= WEP_KEYS)
                        return -EINVAL;
                sta_ptr = NULL;
-               crypt = &local->crypt[param->u.crypt.idx];
+               crypt = &local->crypt_info.crypt[param->u.crypt.idx];
        } else {
                if (param->u.crypt.idx)
                        return -EINVAL;
@@ -3503,20 +3479,20 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
 
        if (strcmp(param->u.crypt.alg, "none") == 0) {
                if (crypt)
-                       prism2_crypt_delayed_deinit(local, crypt);
+                       lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
                goto done;
        }
 
-       ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
+       ops = lib80211_get_crypto_ops(param->u.crypt.alg);
        if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
-               request_module("ieee80211_crypt_wep");
-               ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
+               request_module("lib80211_crypt_wep");
+               ops = lib80211_get_crypto_ops(param->u.crypt.alg);
        } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
-               request_module("ieee80211_crypt_tkip");
-               ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
+               request_module("lib80211_crypt_tkip");
+               ops = lib80211_get_crypto_ops(param->u.crypt.alg);
        } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
-               request_module("ieee80211_crypt_ccmp");
-               ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
+               request_module("lib80211_crypt_ccmp");
+               ops = lib80211_get_crypto_ops(param->u.crypt.alg);
        }
        if (ops == NULL) {
                printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n",
@@ -3531,11 +3507,11 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
        local->host_decrypt = local->host_encrypt = 1;
 
        if (*crypt == NULL || (*crypt)->ops != ops) {
-               struct ieee80211_crypt_data *new_crypt;
+               struct lib80211_crypt_data *new_crypt;
 
-               prism2_crypt_delayed_deinit(local, crypt);
+               lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
 
-               new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
+               new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
                                GFP_KERNEL);
                if (new_crypt == NULL) {
                        ret = -ENOMEM;
@@ -3568,7 +3544,7 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
 
        if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) {
                if (!sta_ptr)
-                       local->tx_keyidx = param->u.crypt.idx;
+                       local->crypt_info.tx_keyidx = param->u.crypt.idx;
                else if (param->u.crypt.idx) {
                        printk(KERN_DEBUG "%s: TX key idx setting failed\n",
                               local->dev->name);
@@ -3604,7 +3580,7 @@ static int prism2_ioctl_get_encryption(local_info_t *local,
                                       struct prism2_hostapd_param *param,
                                       int param_len)
 {
-       struct ieee80211_crypt_data **crypt;
+       struct lib80211_crypt_data **crypt;
        void *sta_ptr;
        int max_key_len;
 
@@ -3620,8 +3596,8 @@ static int prism2_ioctl_get_encryption(local_info_t *local,
            param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
                sta_ptr = NULL;
                if (param->u.crypt.idx >= WEP_KEYS)
-                       param->u.crypt.idx = local->tx_keyidx;
-               crypt = &local->crypt[param->u.crypt.idx];
+                       param->u.crypt.idx = local->crypt_info.tx_keyidx;
+               crypt = &local->crypt_info.crypt[param->u.crypt.idx];
        } else {
                param->u.crypt.idx = 0;
                sta_ptr = ap_crypt_get_ptrs(local->ap, param->sta_addr, 0,