Merge branch 'intx' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/misc-2.6
[pandora-kernel.git] / drivers / net / wireless / hostap / hostap_ioctl.c
index e720369..3b7b806 100644 (file)
@@ -1,11 +1,13 @@
 /* ioctl() (mostly Linux Wireless Extensions) routines for Host AP driver */
 
-#ifdef in_atomic
-/* Get kernel_locked() for in_atomic() */
+#include <linux/types.h>
 #include <linux/smp_lock.h>
-#endif
 #include <linux/ethtool.h>
+#include <net/ieee80211_crypt.h>
 
+#include "hostap_wlan.h"
+#include "hostap.h"
+#include "hostap_ap.h"
 
 static struct iw_statistics *hostap_get_wireless_stats(struct net_device *dev)
 {
@@ -50,7 +52,8 @@ static struct iw_statistics *hostap_get_wireless_stats(struct net_device *dev)
 #endif /* in_atomic */
 
                if (update && prism2_update_comms_qual(dev) == 0)
-                       wstats->qual.updated = 7;
+                       wstats->qual.updated = IW_QUAL_ALL_UPDATED |
+                               IW_QUAL_DBM;
 
                wstats->qual.qual = local->comms_qual;
                wstats->qual.level = local->avg_signal;
@@ -59,7 +62,7 @@ static struct iw_statistics *hostap_get_wireless_stats(struct net_device *dev)
                wstats->qual.qual = 0;
                wstats->qual.level = 0;
                wstats->qual.noise = 0;
-               wstats->qual.updated = 0;
+               wstats->qual.updated = IW_QUAL_ALL_INVALID;
        }
 
        return wstats;
@@ -178,12 +181,10 @@ static int prism2_ioctl_siwencode(struct net_device *dev,
                struct ieee80211_crypt_data *new_crypt;
 
                /* take WEP into use */
-               new_crypt = (struct ieee80211_crypt_data *)
-                       kmalloc(sizeof(struct ieee80211_crypt_data),
+               new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
                                GFP_KERNEL);
                if (new_crypt == NULL)
                        return -ENOMEM;
-               memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
                new_crypt->ops = ieee80211_get_crypto_ops("WEP");
                if (!new_crypt->ops) {
                        request_module("ieee80211_crypt_wep");
@@ -551,7 +552,6 @@ static int prism2_ioctl_giwaplist(struct net_device *dev,
 
        kfree(addr);
        kfree(qual);
-
        return 0;
 }
 
@@ -1410,9 +1410,9 @@ static int prism2_ioctl_siwretry(struct net_device *dev,
        /* what could be done, if firmware would support this.. */
 
        if (rrq->flags & IW_RETRY_LIMIT) {
-               if (rrq->flags & IW_RETRY_MAX)
+               if (rrq->flags & IW_RETRY_LONG)
                        HFA384X_RID_LONGRETRYLIMIT = rrq->value;
-               else if (rrq->flags & IW_RETRY_MIN)
+               else if (rrq->flags & IW_RETRY_SHORT)
                        HFA384X_RID_SHORTRETRYLIMIT = rrq->value;
                else {
                        HFA384X_RID_LONGRETRYLIMIT = rrq->value;
@@ -1466,14 +1466,14 @@ static int prism2_ioctl_giwretry(struct net_device *dev,
                                rrq->value = le16_to_cpu(altretry);
                        else
                                rrq->value = local->manual_retry_count;
-               } else if ((rrq->flags & IW_RETRY_MAX)) {
-                       rrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
+               } else if ((rrq->flags & IW_RETRY_LONG)) {
+                       rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
                        rrq->value = longretry;
                } else {
                        rrq->flags = IW_RETRY_LIMIT;
                        rrq->value = shortretry;
                        if (shortretry != longretry)
-                               rrq->flags |= IW_RETRY_MIN;
+                               rrq->flags |= IW_RETRY_SHORT;
                }
        }
        return 0;
@@ -1827,13 +1827,6 @@ static char * __prism2_translate_scan(local_info_t *local,
        iwe.cmd = SIOCGIWAP;
        iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
        memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN);
-       /* FIX:
-        * I do not know how this is possible, but iwe_stream_add_event
-        * seems to re-order memcpy execution so that len is set only
-        * after copying.. Pre-setting len here "fixes" this, but real
-        * problems should be solved (after which these iwe.len
-        * settings could be removed from this function). */
-       iwe.len = IW_EV_ADDR_LEN;
        current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
                                          IW_EV_ADDR_LEN);
 
@@ -1843,7 +1836,6 @@ static char * __prism2_translate_scan(local_info_t *local,
        iwe.cmd = SIOCGIWESSID;
        iwe.u.data.length = ssid_len;
        iwe.u.data.flags = 1;
-       iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
        current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ssid);
 
        memset(&iwe, 0, sizeof(iwe));
@@ -1859,7 +1851,6 @@ static char * __prism2_translate_scan(local_info_t *local,
                        iwe.u.mode = IW_MODE_MASTER;
                else
                        iwe.u.mode = IW_MODE_ADHOC;
-               iwe.len = IW_EV_UINT_LEN;
                current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
                                                  IW_EV_UINT_LEN);
        }
@@ -1867,7 +1858,7 @@ static char * __prism2_translate_scan(local_info_t *local,
        memset(&iwe, 0, sizeof(iwe));
        iwe.cmd = SIOCGIWFREQ;
        if (scan) {
-               chan = scan->chid;
+               chan = le16_to_cpu(scan->chid);
        } else if (bss) {
                chan = bss->chan;
        } else {
@@ -1875,9 +1866,8 @@ static char * __prism2_translate_scan(local_info_t *local,
        }
 
        if (chan > 0) {
-               iwe.u.freq.m = freq_list[le16_to_cpu(chan - 1)] * 100000;
+               iwe.u.freq.m = freq_list[chan - 1] * 100000;
                iwe.u.freq.e = 1;
-               iwe.len = IW_EV_FREQ_LEN;
                current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
                                                  IW_EV_FREQ_LEN);
        }
@@ -1894,7 +1884,10 @@ static char * __prism2_translate_scan(local_info_t *local,
                        iwe.u.qual.noise =
                                HFA384X_LEVEL_TO_dBm(le16_to_cpu(scan->anl));
                }
-               iwe.len = IW_EV_QUAL_LEN;
+               iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED
+                       | IW_QUAL_NOISE_UPDATED
+                       | IW_QUAL_QUAL_INVALID
+                       | IW_QUAL_DBM;
                current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
                                                  IW_EV_QUAL_LEN);
        }
@@ -1906,7 +1899,6 @@ static char * __prism2_translate_scan(local_info_t *local,
        else
                iwe.u.data.flags = IW_ENCODE_DISABLED;
        iwe.u.data.length = 0;
-       iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
        current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");
 
        /* TODO: add SuppRates into BSS table */
@@ -1930,7 +1922,7 @@ static char * __prism2_translate_scan(local_info_t *local,
        }
 
        /* TODO: add BeaconInt,resp_rate,atim into BSS table */
-       buf = kmalloc(MAX_WPA_IE_LEN * 2 + 30, GFP_KERNEL);
+       buf = kmalloc(MAX_WPA_IE_LEN * 2 + 30, GFP_ATOMIC);
        if (buf && scan) {
                memset(&iwe, 0, sizeof(iwe));
                iwe.cmd = IWEVCUSTOM;
@@ -3088,9 +3080,7 @@ static int prism2_ioctl_priv_download(local_info_t *local, struct iw_point *p)
        ret = local->func->download(local, param);
 
  out:
-       if (param != NULL)
-               kfree(param);
-
+       kfree(param);
        return ret;
 }
 #endif /* PRISM2_DOWNLOAD_SUPPORT */
@@ -3328,14 +3318,12 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
 
                prism2_crypt_delayed_deinit(local, crypt);
 
-               new_crypt = (struct ieee80211_crypt_data *)
-                       kmalloc(sizeof(struct ieee80211_crypt_data),
+               new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
                                GFP_KERNEL);
                if (new_crypt == NULL) {
                        ret = -ENOMEM;
                        goto done;
                }
-               memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
                new_crypt->ops = ops;
                new_crypt->priv = new_crypt->ops->init(i);
                if (new_crypt->priv == NULL) {
@@ -3366,10 +3354,6 @@ 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;
-               else if (i) {
-                       ret = -EINVAL;
-                       goto done;
-               }
        }
 
 
@@ -3550,14 +3534,12 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
 
                prism2_crypt_delayed_deinit(local, crypt);
 
-               new_crypt = (struct ieee80211_crypt_data *)
-                       kmalloc(sizeof(struct ieee80211_crypt_data),
+               new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
                                GFP_KERNEL);
                if (new_crypt == NULL) {
                        ret = -ENOMEM;
                        goto done;
                }
-               memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
                new_crypt->ops = ops;
                new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx);
                if (new_crypt->priv == NULL) {
@@ -3897,9 +3879,7 @@ static int prism2_ioctl_priv_hostapd(local_info_t *local, struct iw_point *p)
        }
 
  out:
-       if (param != NULL)
-               kfree(param);
-
+       kfree(param);
        return ret;
 }
 
@@ -3922,7 +3902,7 @@ static void prism2_get_drvinfo(struct net_device *dev,
                 local->sta_fw_ver & 0xff);
 }
 
-static struct ethtool_ops prism2_ethtool_ops = {
+const struct ethtool_ops prism2_ethtool_ops = {
        .get_drvinfo = prism2_get_drvinfo
 };
 
@@ -3997,7 +3977,7 @@ static const iw_handler prism2_private_handler[] =
        (iw_handler) prism2_ioctl_priv_readmif,         /* 3 */
 };
 
-static const struct iw_handler_def hostap_iw_handler_def =
+const struct iw_handler_def hostap_iw_handler_def =
 {
        .num_standard   = sizeof(prism2_handler) / sizeof(iw_handler),
        .num_private    = sizeof(prism2_private_handler) / sizeof(iw_handler),