[MAC80211]: Remove bitfields from struct ieee80211_sub_if_data
[linux-2.6] / net / mac80211 / ieee80211_ioctl.c
1 /*
2  * Copyright 2002-2005, Instant802 Networks, Inc.
3  * Copyright 2005-2006, Devicescape Software, Inc.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  */
9
10 #include <linux/module.h>
11 #include <linux/init.h>
12 #include <linux/netdevice.h>
13 #include <linux/types.h>
14 #include <linux/slab.h>
15 #include <linux/skbuff.h>
16 #include <linux/etherdevice.h>
17 #include <linux/if_arp.h>
18 #include <linux/wireless.h>
19 #include <net/iw_handler.h>
20 #include <asm/uaccess.h>
21
22 #include <net/mac80211.h>
23 #include "ieee80211_i.h"
24 #include "hostapd_ioctl.h"
25 #include "ieee80211_rate.h"
26 #include "wpa.h"
27 #include "aes_ccm.h"
28 #include "debugfs_key.h"
29
30 static void ieee80211_set_hw_encryption(struct net_device *dev,
31                                         struct sta_info *sta, u8 addr[ETH_ALEN],
32                                         struct ieee80211_key *key)
33 {
34         struct ieee80211_key_conf *keyconf = NULL;
35         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
36
37         /* default to sw encryption; this will be cleared by low-level
38          * driver if the hw supports requested encryption */
39         if (key)
40                 key->force_sw_encrypt = 1;
41
42         if (key && local->ops->set_key &&
43             (keyconf = ieee80211_key_data2conf(local, key))) {
44                 if (local->ops->set_key(local_to_hw(local), SET_KEY, addr,
45                                        keyconf, sta ? sta->aid : 0)) {
46                         key->force_sw_encrypt = 1;
47                         key->hw_key_idx = HW_KEY_IDX_INVALID;
48                 } else {
49                         key->force_sw_encrypt =
50                                 !!(keyconf->flags & IEEE80211_KEY_FORCE_SW_ENCRYPT);
51                         key->hw_key_idx =
52                                 keyconf->hw_key_idx;
53
54                 }
55         }
56         kfree(keyconf);
57 }
58
59
60 static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr,
61                                     int idx, int alg, int set_tx_key,
62                                     const u8 *_key, size_t key_len)
63 {
64         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
65         int ret = 0;
66         struct sta_info *sta;
67         struct ieee80211_key *key, *old_key;
68         int try_hwaccel = 1;
69         struct ieee80211_key_conf *keyconf;
70         struct ieee80211_sub_if_data *sdata;
71
72         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
73
74         if (is_broadcast_ether_addr(sta_addr)) {
75                 sta = NULL;
76                 if (idx >= NUM_DEFAULT_KEYS) {
77                         printk(KERN_DEBUG "%s: set_encrypt - invalid idx=%d\n",
78                                dev->name, idx);
79                         return -EINVAL;
80                 }
81                 key = sdata->keys[idx];
82
83                 /* TODO: consider adding hwaccel support for these; at least
84                  * Atheros key cache should be able to handle this since AP is
85                  * only transmitting frames with default keys. */
86                 /* FIX: hw key cache can be used when only one virtual
87                  * STA is associated with each AP. If more than one STA
88                  * is associated to the same AP, software encryption
89                  * must be used. This should be done automatically
90                  * based on configured station devices. For the time
91                  * being, this can be only set at compile time. */
92         } else {
93                 set_tx_key = 0;
94                 if (idx != 0) {
95                         printk(KERN_DEBUG "%s: set_encrypt - non-zero idx for "
96                                "individual key\n", dev->name);
97                         return -EINVAL;
98                 }
99
100                 sta = sta_info_get(local, sta_addr);
101                 if (!sta) {
102 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
103                         printk(KERN_DEBUG "%s: set_encrypt - unknown addr "
104                                MAC_FMT "\n",
105                                dev->name, MAC_ARG(sta_addr));
106 #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
107
108                         return -ENOENT;
109                 }
110
111                 key = sta->key;
112         }
113
114         /* FIX:
115          * Cannot configure default hwaccel keys with WEP algorithm, if
116          * any of the virtual interfaces is using static WEP
117          * configuration because hwaccel would otherwise try to decrypt
118          * these frames.
119          *
120          * For now, just disable WEP hwaccel for broadcast when there is
121          * possibility of conflict with default keys. This can maybe later be
122          * optimized by using non-default keys (at least with Atheros ar521x).
123          */
124         if (!sta && alg == ALG_WEP && !local->default_wep_only &&
125             sdata->type != IEEE80211_IF_TYPE_IBSS &&
126             sdata->type != IEEE80211_IF_TYPE_AP) {
127                 try_hwaccel = 0;
128         }
129
130         if (local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP) {
131                 /* Software encryption cannot be used with devices that hide
132                  * encryption from the host system, so always try to use
133                  * hardware acceleration with such devices. */
134                 try_hwaccel = 1;
135         }
136
137         if ((local->hw.flags & IEEE80211_HW_NO_TKIP_WMM_HWACCEL) &&
138             alg == ALG_TKIP) {
139                 if (sta && (sta->flags & WLAN_STA_WME)) {
140                 /* Hardware does not support hwaccel with TKIP when using WMM.
141                  */
142                         try_hwaccel = 0;
143                 }
144                 else if (sdata->type == IEEE80211_IF_TYPE_STA) {
145                         sta = sta_info_get(local, sdata->u.sta.bssid);
146                         if (sta) {
147                                 if (sta->flags & WLAN_STA_WME) {
148                                         try_hwaccel = 0;
149                                 }
150                                 sta_info_put(sta);
151                                 sta = NULL;
152                         }
153                 }
154         }
155
156         if (alg == ALG_NONE) {
157                 keyconf = NULL;
158                 if (try_hwaccel && key &&
159                     key->hw_key_idx != HW_KEY_IDX_INVALID &&
160                     local->ops->set_key &&
161                     (keyconf = ieee80211_key_data2conf(local, key)) != NULL &&
162                     local->ops->set_key(local_to_hw(local), DISABLE_KEY,
163                                        sta_addr, keyconf, sta ? sta->aid : 0)) {
164                         printk(KERN_DEBUG "%s: set_encrypt - low-level disable"
165                                " failed\n", dev->name);
166                         ret = -EINVAL;
167                 }
168                 kfree(keyconf);
169
170                 if (set_tx_key || sdata->default_key == key) {
171                         ieee80211_debugfs_key_remove_default(sdata);
172                         sdata->default_key = NULL;
173                 }
174                 ieee80211_debugfs_key_remove(key);
175                 if (sta)
176                         sta->key = NULL;
177                 else
178                         sdata->keys[idx] = NULL;
179                 ieee80211_key_free(key);
180                 key = NULL;
181         } else {
182                 old_key = key;
183                 key = ieee80211_key_alloc(sta ? NULL : sdata, idx, key_len,
184                                           GFP_KERNEL);
185                 if (!key) {
186                         ret = -ENOMEM;
187                         goto err_out;
188                 }
189
190                 /* default to sw encryption; low-level driver sets these if the
191                  * requested encryption is supported */
192                 key->hw_key_idx = HW_KEY_IDX_INVALID;
193                 key->force_sw_encrypt = 1;
194
195                 key->alg = alg;
196                 key->keyidx = idx;
197                 key->keylen = key_len;
198                 memcpy(key->key, _key, key_len);
199                 if (set_tx_key)
200                         key->default_tx_key = 1;
201
202                 if (alg == ALG_CCMP) {
203                         /* Initialize AES key state here as an optimization
204                          * so that it does not need to be initialized for every
205                          * packet. */
206                         key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(
207                                 key->key);
208                         if (!key->u.ccmp.tfm) {
209                                 ret = -ENOMEM;
210                                 goto err_free;
211                         }
212                 }
213
214                 if (set_tx_key || sdata->default_key == old_key) {
215                         ieee80211_debugfs_key_remove_default(sdata);
216                         sdata->default_key = NULL;
217                 }
218                 ieee80211_debugfs_key_remove(old_key);
219                 if (sta)
220                         sta->key = key;
221                 else
222                         sdata->keys[idx] = key;
223                 ieee80211_key_free(old_key);
224                 ieee80211_debugfs_key_add(local, key);
225                 if (sta)
226                         ieee80211_debugfs_key_sta_link(key, sta);
227
228                 if (try_hwaccel &&
229                     (alg == ALG_WEP || alg == ALG_TKIP || alg == ALG_CCMP))
230                         ieee80211_set_hw_encryption(dev, sta, sta_addr, key);
231         }
232
233         if (set_tx_key || (!sta && !sdata->default_key && key)) {
234                 sdata->default_key = key;
235                 if (key)
236                         ieee80211_debugfs_key_add_default(sdata);
237
238                 if (local->ops->set_key_idx &&
239                     local->ops->set_key_idx(local_to_hw(local), idx))
240                         printk(KERN_DEBUG "%s: failed to set TX key idx for "
241                                "low-level driver\n", dev->name);
242         }
243
244         if (sta)
245                 sta_info_put(sta);
246
247         return 0;
248
249 err_free:
250         ieee80211_key_free(key);
251 err_out:
252         if (sta)
253                 sta_info_put(sta);
254         return ret;
255 }
256
257 static int ieee80211_ioctl_siwgenie(struct net_device *dev,
258                                     struct iw_request_info *info,
259                                     struct iw_point *data, char *extra)
260 {
261         struct ieee80211_sub_if_data *sdata;
262         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
263
264         if (local->user_space_mlme)
265                 return -EOPNOTSUPP;
266
267         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
268         if (sdata->type == IEEE80211_IF_TYPE_STA ||
269             sdata->type == IEEE80211_IF_TYPE_IBSS) {
270                 int ret = ieee80211_sta_set_extra_ie(dev, extra, data->length);
271                 if (ret)
272                         return ret;
273                 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
274                 ieee80211_sta_req_auth(dev, &sdata->u.sta);
275                 return 0;
276         }
277
278         if (sdata->type == IEEE80211_IF_TYPE_AP) {
279                 kfree(sdata->u.ap.generic_elem);
280                 sdata->u.ap.generic_elem = kmalloc(data->length, GFP_KERNEL);
281                 if (!sdata->u.ap.generic_elem)
282                         return -ENOMEM;
283                 memcpy(sdata->u.ap.generic_elem, extra, data->length);
284                 sdata->u.ap.generic_elem_len = data->length;
285                 return ieee80211_if_config(dev);
286         }
287         return -EOPNOTSUPP;
288 }
289
290 static int ieee80211_ioctl_giwname(struct net_device *dev,
291                                    struct iw_request_info *info,
292                                    char *name, char *extra)
293 {
294         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
295
296         switch (local->hw.conf.phymode) {
297         case MODE_IEEE80211A:
298                 strcpy(name, "IEEE 802.11a");
299                 break;
300         case MODE_IEEE80211B:
301                 strcpy(name, "IEEE 802.11b");
302                 break;
303         case MODE_IEEE80211G:
304                 strcpy(name, "IEEE 802.11g");
305                 break;
306         case MODE_ATHEROS_TURBO:
307                 strcpy(name, "5GHz Turbo");
308                 break;
309         default:
310                 strcpy(name, "IEEE 802.11");
311                 break;
312         }
313
314         return 0;
315 }
316
317
318 static int ieee80211_ioctl_giwrange(struct net_device *dev,
319                                  struct iw_request_info *info,
320                                  struct iw_point *data, char *extra)
321 {
322         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
323         struct iw_range *range = (struct iw_range *) extra;
324         struct ieee80211_hw_mode *mode = NULL;
325         int c = 0;
326
327         data->length = sizeof(struct iw_range);
328         memset(range, 0, sizeof(struct iw_range));
329
330         range->we_version_compiled = WIRELESS_EXT;
331         range->we_version_source = 21;
332         range->retry_capa = IW_RETRY_LIMIT;
333         range->retry_flags = IW_RETRY_LIMIT;
334         range->min_retry = 0;
335         range->max_retry = 255;
336         range->min_rts = 0;
337         range->max_rts = 2347;
338         range->min_frag = 256;
339         range->max_frag = 2346;
340
341         range->encoding_size[0] = 5;
342         range->encoding_size[1] = 13;
343         range->num_encoding_sizes = 2;
344         range->max_encoding_tokens = NUM_DEFAULT_KEYS;
345
346         range->max_qual.qual = local->hw.max_signal;
347         range->max_qual.level = local->hw.max_rssi;
348         range->max_qual.noise = local->hw.max_noise;
349         range->max_qual.updated = local->wstats_flags;
350
351         range->avg_qual.qual = local->hw.max_signal/2;
352         range->avg_qual.level = 0;
353         range->avg_qual.noise = 0;
354         range->avg_qual.updated = local->wstats_flags;
355
356         range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
357                           IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
358
359         list_for_each_entry(mode, &local->modes_list, list) {
360                 int i = 0;
361
362                 if (!(local->enabled_modes & (1 << mode->mode)) ||
363                     (local->hw_modes & local->enabled_modes &
364                      (1 << MODE_IEEE80211G) && mode->mode == MODE_IEEE80211B))
365                         continue;
366
367                 while (i < mode->num_channels && c < IW_MAX_FREQUENCIES) {
368                         struct ieee80211_channel *chan = &mode->channels[i];
369
370                         if (chan->flag & IEEE80211_CHAN_W_SCAN) {
371                                 range->freq[c].i = chan->chan;
372                                 range->freq[c].m = chan->freq * 100000;
373                                 range->freq[c].e = 1;
374                                 c++;
375                         }
376                         i++;
377                 }
378         }
379         range->num_channels = c;
380         range->num_frequency = c;
381
382         IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
383         IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
384         IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
385         IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
386
387         return 0;
388 }
389
390
391 static int ieee80211_ioctl_siwmode(struct net_device *dev,
392                                    struct iw_request_info *info,
393                                    __u32 *mode, char *extra)
394 {
395         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
396         int type;
397
398         if (sdata->type == IEEE80211_IF_TYPE_VLAN)
399                 return -EOPNOTSUPP;
400
401         switch (*mode) {
402         case IW_MODE_INFRA:
403                 type = IEEE80211_IF_TYPE_STA;
404                 break;
405         case IW_MODE_ADHOC:
406                 type = IEEE80211_IF_TYPE_IBSS;
407                 break;
408         case IW_MODE_MONITOR:
409                 type = IEEE80211_IF_TYPE_MNTR;
410                 break;
411         default:
412                 return -EINVAL;
413         }
414
415         if (type == sdata->type)
416                 return 0;
417         if (netif_running(dev))
418                 return -EBUSY;
419
420         ieee80211_if_reinit(dev);
421         ieee80211_if_set_type(dev, type);
422
423         return 0;
424 }
425
426
427 static int ieee80211_ioctl_giwmode(struct net_device *dev,
428                                    struct iw_request_info *info,
429                                    __u32 *mode, char *extra)
430 {
431         struct ieee80211_sub_if_data *sdata;
432
433         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
434         switch (sdata->type) {
435         case IEEE80211_IF_TYPE_AP:
436                 *mode = IW_MODE_MASTER;
437                 break;
438         case IEEE80211_IF_TYPE_STA:
439                 *mode = IW_MODE_INFRA;
440                 break;
441         case IEEE80211_IF_TYPE_IBSS:
442                 *mode = IW_MODE_ADHOC;
443                 break;
444         case IEEE80211_IF_TYPE_MNTR:
445                 *mode = IW_MODE_MONITOR;
446                 break;
447         case IEEE80211_IF_TYPE_WDS:
448                 *mode = IW_MODE_REPEAT;
449                 break;
450         case IEEE80211_IF_TYPE_VLAN:
451                 *mode = IW_MODE_SECOND;         /* FIXME */
452                 break;
453         default:
454                 *mode = IW_MODE_AUTO;
455                 break;
456         }
457         return 0;
458 }
459
460 int ieee80211_set_channel(struct ieee80211_local *local, int channel, int freq)
461 {
462         struct ieee80211_hw_mode *mode;
463         int c, set = 0;
464         int ret = -EINVAL;
465
466         list_for_each_entry(mode, &local->modes_list, list) {
467                 if (!(local->enabled_modes & (1 << mode->mode)))
468                         continue;
469                 for (c = 0; c < mode->num_channels; c++) {
470                         struct ieee80211_channel *chan = &mode->channels[c];
471                         if (chan->flag & IEEE80211_CHAN_W_SCAN &&
472                             ((chan->chan == channel) || (chan->freq == freq))) {
473                                 /* Use next_mode as the mode preference to
474                                  * resolve non-unique channel numbers. */
475                                 if (set && mode->mode != local->next_mode)
476                                         continue;
477
478                                 local->oper_channel = chan;
479                                 local->oper_hw_mode = mode;
480                                 set++;
481                         }
482                 }
483         }
484
485         if (set) {
486                 if (local->sta_scanning)
487                         ret = 0;
488                 else
489                         ret = ieee80211_hw_config(local);
490
491                 rate_control_clear(local);
492         }
493
494         return ret;
495 }
496
497 static int ieee80211_ioctl_siwfreq(struct net_device *dev,
498                                    struct iw_request_info *info,
499                                    struct iw_freq *freq, char *extra)
500 {
501         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
502         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
503
504         if (sdata->type == IEEE80211_IF_TYPE_STA)
505                 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_CHANNEL_SEL;
506
507         /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */
508         if (freq->e == 0) {
509                 if (freq->m < 0) {
510                         if (sdata->type == IEEE80211_IF_TYPE_STA)
511                                 sdata->u.sta.flags |=
512                                         IEEE80211_STA_AUTO_CHANNEL_SEL;
513                         return 0;
514                 } else
515                         return ieee80211_set_channel(local, freq->m, -1);
516         } else {
517                 int i, div = 1000000;
518                 for (i = 0; i < freq->e; i++)
519                         div /= 10;
520                 if (div > 0)
521                         return ieee80211_set_channel(local, -1, freq->m / div);
522                 else
523                         return -EINVAL;
524         }
525 }
526
527
528 static int ieee80211_ioctl_giwfreq(struct net_device *dev,
529                                    struct iw_request_info *info,
530                                    struct iw_freq *freq, char *extra)
531 {
532         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
533
534         /* TODO: in station mode (Managed/Ad-hoc) might need to poll low-level
535          * driver for the current channel with firmware-based management */
536
537         freq->m = local->hw.conf.freq;
538         freq->e = 6;
539
540         return 0;
541 }
542
543
544 static int ieee80211_ioctl_siwessid(struct net_device *dev,
545                                     struct iw_request_info *info,
546                                     struct iw_point *data, char *ssid)
547 {
548         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
549         struct ieee80211_sub_if_data *sdata;
550         size_t len = data->length;
551
552         /* iwconfig uses nul termination in SSID.. */
553         if (len > 0 && ssid[len - 1] == '\0')
554                 len--;
555
556         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
557         if (sdata->type == IEEE80211_IF_TYPE_STA ||
558             sdata->type == IEEE80211_IF_TYPE_IBSS) {
559                 int ret;
560                 if (local->user_space_mlme) {
561                         if (len > IEEE80211_MAX_SSID_LEN)
562                                 return -EINVAL;
563                         memcpy(sdata->u.sta.ssid, ssid, len);
564                         sdata->u.sta.ssid_len = len;
565                         return 0;
566                 }
567                 if (data->flags)
568                         sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_SSID_SEL;
569                 else
570                         sdata->u.sta.flags |= IEEE80211_STA_AUTO_SSID_SEL;
571                 ret = ieee80211_sta_set_ssid(dev, ssid, len);
572                 if (ret)
573                         return ret;
574                 ieee80211_sta_req_auth(dev, &sdata->u.sta);
575                 return 0;
576         }
577
578         if (sdata->type == IEEE80211_IF_TYPE_AP) {
579                 memcpy(sdata->u.ap.ssid, ssid, len);
580                 memset(sdata->u.ap.ssid + len, 0,
581                        IEEE80211_MAX_SSID_LEN - len);
582                 sdata->u.ap.ssid_len = len;
583                 return ieee80211_if_config(dev);
584         }
585         return -EOPNOTSUPP;
586 }
587
588
589 static int ieee80211_ioctl_giwessid(struct net_device *dev,
590                                     struct iw_request_info *info,
591                                     struct iw_point *data, char *ssid)
592 {
593         size_t len;
594
595         struct ieee80211_sub_if_data *sdata;
596         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
597         if (sdata->type == IEEE80211_IF_TYPE_STA ||
598             sdata->type == IEEE80211_IF_TYPE_IBSS) {
599                 int res = ieee80211_sta_get_ssid(dev, ssid, &len);
600                 if (res == 0) {
601                         data->length = len;
602                         data->flags = 1;
603                 } else
604                         data->flags = 0;
605                 return res;
606         }
607
608         if (sdata->type == IEEE80211_IF_TYPE_AP) {
609                 len = sdata->u.ap.ssid_len;
610                 if (len > IW_ESSID_MAX_SIZE)
611                         len = IW_ESSID_MAX_SIZE;
612                 memcpy(ssid, sdata->u.ap.ssid, len);
613                 data->length = len;
614                 data->flags = 1;
615                 return 0;
616         }
617         return -EOPNOTSUPP;
618 }
619
620
621 static int ieee80211_ioctl_siwap(struct net_device *dev,
622                                  struct iw_request_info *info,
623                                  struct sockaddr *ap_addr, char *extra)
624 {
625         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
626         struct ieee80211_sub_if_data *sdata;
627
628         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
629         if (sdata->type == IEEE80211_IF_TYPE_STA ||
630             sdata->type == IEEE80211_IF_TYPE_IBSS) {
631                 int ret;
632                 if (local->user_space_mlme) {
633                         memcpy(sdata->u.sta.bssid, (u8 *) &ap_addr->sa_data,
634                                ETH_ALEN);
635                         return 0;
636                 }
637                 if (is_zero_ether_addr((u8 *) &ap_addr->sa_data))
638                         sdata->u.sta.flags |= IEEE80211_STA_AUTO_BSSID_SEL |
639                                 IEEE80211_STA_AUTO_CHANNEL_SEL;
640                 else if (is_broadcast_ether_addr((u8 *) &ap_addr->sa_data))
641                         sdata->u.sta.flags |= IEEE80211_STA_AUTO_BSSID_SEL;
642                 else
643                         sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
644                 ret = ieee80211_sta_set_bssid(dev, (u8 *) &ap_addr->sa_data);
645                 if (ret)
646                         return ret;
647                 ieee80211_sta_req_auth(dev, &sdata->u.sta);
648                 return 0;
649         } else if (sdata->type == IEEE80211_IF_TYPE_WDS) {
650                 if (memcmp(sdata->u.wds.remote_addr, (u8 *) &ap_addr->sa_data,
651                            ETH_ALEN) == 0)
652                         return 0;
653                 return ieee80211_if_update_wds(dev, (u8 *) &ap_addr->sa_data);
654         }
655
656         return -EOPNOTSUPP;
657 }
658
659
660 static int ieee80211_ioctl_giwap(struct net_device *dev,
661                                  struct iw_request_info *info,
662                                  struct sockaddr *ap_addr, char *extra)
663 {
664         struct ieee80211_sub_if_data *sdata;
665
666         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
667         if (sdata->type == IEEE80211_IF_TYPE_STA ||
668             sdata->type == IEEE80211_IF_TYPE_IBSS) {
669                 ap_addr->sa_family = ARPHRD_ETHER;
670                 memcpy(&ap_addr->sa_data, sdata->u.sta.bssid, ETH_ALEN);
671                 return 0;
672         } else if (sdata->type == IEEE80211_IF_TYPE_WDS) {
673                 ap_addr->sa_family = ARPHRD_ETHER;
674                 memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN);
675                 return 0;
676         }
677
678         return -EOPNOTSUPP;
679 }
680
681
682 static int ieee80211_ioctl_siwscan(struct net_device *dev,
683                                    struct iw_request_info *info,
684                                    struct iw_point *data, char *extra)
685 {
686         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
687         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
688         u8 *ssid = NULL;
689         size_t ssid_len = 0;
690
691         if (!netif_running(dev))
692                 return -ENETDOWN;
693
694         switch (sdata->type) {
695         case IEEE80211_IF_TYPE_STA:
696         case IEEE80211_IF_TYPE_IBSS:
697                 if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
698                         ssid = sdata->u.sta.ssid;
699                         ssid_len = sdata->u.sta.ssid_len;
700                 }
701                 break;
702         case IEEE80211_IF_TYPE_AP:
703                 if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
704                         ssid = sdata->u.ap.ssid;
705                         ssid_len = sdata->u.ap.ssid_len;
706                 }
707                 break;
708         default:
709                 return -EOPNOTSUPP;
710         }
711
712         return ieee80211_sta_req_scan(dev, ssid, ssid_len);
713 }
714
715
716 static int ieee80211_ioctl_giwscan(struct net_device *dev,
717                                    struct iw_request_info *info,
718                                    struct iw_point *data, char *extra)
719 {
720         int res;
721         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
722         if (local->sta_scanning)
723                 return -EAGAIN;
724         res = ieee80211_sta_scan_results(dev, extra, data->length);
725         if (res >= 0) {
726                 data->length = res;
727                 return 0;
728         }
729         data->length = 0;
730         return res;
731 }
732
733
734 static int ieee80211_ioctl_siwrate(struct net_device *dev,
735                                   struct iw_request_info *info,
736                                   struct iw_param *rate, char *extra)
737 {
738         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
739         struct ieee80211_hw_mode *mode;
740         int i;
741         u32 target_rate = rate->value / 100000;
742         struct ieee80211_sub_if_data *sdata;
743
744         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
745         if (!sdata->bss)
746                 return -ENODEV;
747         mode = local->oper_hw_mode;
748         /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates
749          * target_rate = X, rate->fixed = 1 means only rate X
750          * target_rate = X, rate->fixed = 0 means all rates <= X */
751         sdata->bss->max_ratectrl_rateidx = -1;
752         sdata->bss->force_unicast_rateidx = -1;
753         if (rate->value < 0)
754                 return 0;
755         for (i=0; i< mode->num_rates; i++) {
756                 struct ieee80211_rate *rates = &mode->rates[i];
757                 int this_rate = rates->rate;
758
759                 if (mode->mode == MODE_ATHEROS_TURBO ||
760                     mode->mode == MODE_ATHEROS_TURBOG)
761                         this_rate *= 2;
762                 if (target_rate == this_rate) {
763                         sdata->bss->max_ratectrl_rateidx = i;
764                         if (rate->fixed)
765                                 sdata->bss->force_unicast_rateidx = i;
766                         break;
767                 }
768         }
769         return 0;
770 }
771
772 static int ieee80211_ioctl_giwrate(struct net_device *dev,
773                                   struct iw_request_info *info,
774                                   struct iw_param *rate, char *extra)
775 {
776         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
777         struct sta_info *sta;
778         struct ieee80211_sub_if_data *sdata;
779
780         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
781         if (sdata->type == IEEE80211_IF_TYPE_STA)
782                 sta = sta_info_get(local, sdata->u.sta.bssid);
783         else
784                 return -EOPNOTSUPP;
785         if (!sta)
786                 return -ENODEV;
787         if (sta->txrate < local->oper_hw_mode->num_rates)
788                 rate->value = local->oper_hw_mode->rates[sta->txrate].rate * 100000;
789         else
790                 rate->value = 0;
791         sta_info_put(sta);
792         return 0;
793 }
794
795 static int ieee80211_ioctl_giwtxpower(struct net_device *dev,
796                                    struct iw_request_info *info,
797                                    union iwreq_data *data, char *extra)
798 {
799         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
800
801         data->txpower.fixed = 1;
802         data->txpower.disabled = !(local->hw.conf.radio_enabled);
803         data->txpower.value = local->hw.conf.power_level;
804         data->txpower.flags = IW_TXPOW_DBM;
805
806         return 0;
807 }
808
809 static int ieee80211_ioctl_siwrts(struct net_device *dev,
810                                   struct iw_request_info *info,
811                                   struct iw_param *rts, char *extra)
812 {
813         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
814
815         if (rts->disabled)
816                 local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
817         else if (rts->value < 0 || rts->value > IEEE80211_MAX_RTS_THRESHOLD)
818                 return -EINVAL;
819         else
820                 local->rts_threshold = rts->value;
821
822         /* If the wlan card performs RTS/CTS in hardware/firmware,
823          * configure it here */
824
825         if (local->ops->set_rts_threshold)
826                 local->ops->set_rts_threshold(local_to_hw(local),
827                                              local->rts_threshold);
828
829         return 0;
830 }
831
832 static int ieee80211_ioctl_giwrts(struct net_device *dev,
833                                   struct iw_request_info *info,
834                                   struct iw_param *rts, char *extra)
835 {
836         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
837
838         rts->value = local->rts_threshold;
839         rts->disabled = (rts->value >= IEEE80211_MAX_RTS_THRESHOLD);
840         rts->fixed = 1;
841
842         return 0;
843 }
844
845
846 static int ieee80211_ioctl_siwfrag(struct net_device *dev,
847                                    struct iw_request_info *info,
848                                    struct iw_param *frag, char *extra)
849 {
850         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
851
852         if (frag->disabled)
853                 local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
854         else if (frag->value < 256 ||
855                  frag->value > IEEE80211_MAX_FRAG_THRESHOLD)
856                 return -EINVAL;
857         else {
858                 /* Fragment length must be even, so strip LSB. */
859                 local->fragmentation_threshold = frag->value & ~0x1;
860         }
861
862         /* If the wlan card performs fragmentation in hardware/firmware,
863          * configure it here */
864
865         if (local->ops->set_frag_threshold)
866                 local->ops->set_frag_threshold(
867                         local_to_hw(local),
868                         local->fragmentation_threshold);
869
870         return 0;
871 }
872
873 static int ieee80211_ioctl_giwfrag(struct net_device *dev,
874                                    struct iw_request_info *info,
875                                    struct iw_param *frag, char *extra)
876 {
877         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
878
879         frag->value = local->fragmentation_threshold;
880         frag->disabled = (frag->value >= IEEE80211_MAX_RTS_THRESHOLD);
881         frag->fixed = 1;
882
883         return 0;
884 }
885
886
887 static int ieee80211_ioctl_siwretry(struct net_device *dev,
888                                     struct iw_request_info *info,
889                                     struct iw_param *retry, char *extra)
890 {
891         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
892
893         if (retry->disabled ||
894             (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
895                 return -EINVAL;
896
897         if (retry->flags & IW_RETRY_MAX)
898                 local->long_retry_limit = retry->value;
899         else if (retry->flags & IW_RETRY_MIN)
900                 local->short_retry_limit = retry->value;
901         else {
902                 local->long_retry_limit = retry->value;
903                 local->short_retry_limit = retry->value;
904         }
905
906         if (local->ops->set_retry_limit) {
907                 return local->ops->set_retry_limit(
908                         local_to_hw(local),
909                         local->short_retry_limit,
910                         local->long_retry_limit);
911         }
912
913         return 0;
914 }
915
916
917 static int ieee80211_ioctl_giwretry(struct net_device *dev,
918                                     struct iw_request_info *info,
919                                     struct iw_param *retry, char *extra)
920 {
921         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
922
923         retry->disabled = 0;
924         if (retry->flags == 0 || retry->flags & IW_RETRY_MIN) {
925                 /* first return min value, iwconfig will ask max value
926                  * later if needed */
927                 retry->flags |= IW_RETRY_LIMIT;
928                 retry->value = local->short_retry_limit;
929                 if (local->long_retry_limit != local->short_retry_limit)
930                         retry->flags |= IW_RETRY_MIN;
931                 return 0;
932         }
933         if (retry->flags & IW_RETRY_MAX) {
934                 retry->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
935                 retry->value = local->long_retry_limit;
936         }
937
938         return 0;
939 }
940
941 static void ieee80211_key_enable_hwaccel(struct ieee80211_local *local,
942                                          struct ieee80211_key *key)
943 {
944         struct ieee80211_key_conf *keyconf;
945         u8 addr[ETH_ALEN];
946
947         if (!key || key->alg != ALG_WEP || !key->force_sw_encrypt ||
948             (local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP))
949                 return;
950
951         memset(addr, 0xff, ETH_ALEN);
952         keyconf = ieee80211_key_data2conf(local, key);
953         if (keyconf && local->ops->set_key &&
954             local->ops->set_key(local_to_hw(local),
955                                SET_KEY, addr, keyconf, 0) == 0) {
956                 key->force_sw_encrypt =
957                         !!(keyconf->flags & IEEE80211_KEY_FORCE_SW_ENCRYPT);
958                 key->hw_key_idx = keyconf->hw_key_idx;
959         }
960         kfree(keyconf);
961 }
962
963
964 static void ieee80211_key_disable_hwaccel(struct ieee80211_local *local,
965                                           struct ieee80211_key *key)
966 {
967         struct ieee80211_key_conf *keyconf;
968         u8 addr[ETH_ALEN];
969
970         if (!key || key->alg != ALG_WEP || key->force_sw_encrypt ||
971             (local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP))
972                 return;
973
974         memset(addr, 0xff, ETH_ALEN);
975         keyconf = ieee80211_key_data2conf(local, key);
976         if (keyconf && local->ops->set_key)
977                 local->ops->set_key(local_to_hw(local), DISABLE_KEY,
978                                    addr, keyconf, 0);
979         kfree(keyconf);
980         key->force_sw_encrypt = 1;
981 }
982
983
984 static int ieee80211_ioctl_default_wep_only(struct ieee80211_local *local,
985                                             int value)
986 {
987         int i;
988         struct ieee80211_sub_if_data *sdata;
989
990         local->default_wep_only = value;
991         read_lock(&local->sub_if_lock);
992         list_for_each_entry(sdata, &local->sub_if_list, list)
993                 for (i = 0; i < NUM_DEFAULT_KEYS; i++)
994                         if (value)
995                                 ieee80211_key_enable_hwaccel(local,
996                                                              sdata->keys[i]);
997                         else
998                                 ieee80211_key_disable_hwaccel(local,
999                                                               sdata->keys[i]);
1000         read_unlock(&local->sub_if_lock);
1001
1002         return 0;
1003 }
1004
1005
1006 void ieee80211_update_default_wep_only(struct ieee80211_local *local)
1007 {
1008         int i = 0;
1009         struct ieee80211_sub_if_data *sdata;
1010
1011         read_lock(&local->sub_if_lock);
1012         list_for_each_entry(sdata, &local->sub_if_list, list) {
1013
1014                 if (sdata->dev == local->mdev)
1015                         continue;
1016
1017                 /* If there is an AP interface then depend on userspace to
1018                    set default_wep_only correctly. */
1019                 if (sdata->type == IEEE80211_IF_TYPE_AP) {
1020                         read_unlock(&local->sub_if_lock);
1021                         return;
1022                 }
1023
1024                 i++;
1025         }
1026
1027         read_unlock(&local->sub_if_lock);
1028
1029         if (i <= 1)
1030                 ieee80211_ioctl_default_wep_only(local, 1);
1031         else
1032                 ieee80211_ioctl_default_wep_only(local, 0);
1033 }
1034
1035
1036 static int ieee80211_ioctl_prism2_param(struct net_device *dev,
1037                                         struct iw_request_info *info,
1038                                         void *wrqu, char *extra)
1039 {
1040         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1041         struct ieee80211_sub_if_data *sdata;
1042         int *i = (int *) extra;
1043         int param = *i;
1044         int value = *(i + 1);
1045         int ret = 0;
1046
1047         if (!capable(CAP_NET_ADMIN))
1048                 return -EPERM;
1049
1050         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1051
1052         switch (param) {
1053         case PRISM2_PARAM_IEEE_802_1X:
1054                 if (local->ops->set_ieee8021x)
1055                         ret = local->ops->set_ieee8021x(local_to_hw(local),
1056                                                         value);
1057                 if (ret)
1058                         printk(KERN_DEBUG "%s: failed to set IEEE 802.1X (%d) "
1059                                "for low-level driver\n", dev->name, value);
1060                 else
1061                         sdata->ieee802_1x = value;
1062                 break;
1063
1064         case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES:
1065                 if (sdata->type == IEEE80211_IF_TYPE_AP) {
1066                         if (value)
1067                                 sdata->flags |= IEEE80211_SDATA_USE_PROTECTION;
1068                         else
1069                                 sdata->flags &= ~IEEE80211_SDATA_USE_PROTECTION;
1070                         ieee80211_erp_info_change_notify(dev,
1071                                         IEEE80211_ERP_CHANGE_PROTECTION);
1072                 } else {
1073                         ret = -ENOENT;
1074                 }
1075                 break;
1076
1077         case PRISM2_PARAM_PREAMBLE:
1078                 if (sdata->type != IEEE80211_IF_TYPE_AP) {
1079                         if (value)
1080                                 sdata->flags |= IEEE80211_SDATA_SHORT_PREAMBLE;
1081                         else
1082                                 sdata->flags &= ~IEEE80211_SDATA_SHORT_PREAMBLE;
1083                         ieee80211_erp_info_change_notify(dev,
1084                                         IEEE80211_ERP_CHANGE_PREAMBLE);
1085                 } else {
1086                         ret = -ENOENT;
1087                 }
1088                 break;
1089
1090         case PRISM2_PARAM_SHORT_SLOT_TIME:
1091                 if (value)
1092                         local->hw.conf.flags |= IEEE80211_CONF_SHORT_SLOT_TIME;
1093                 else
1094                         local->hw.conf.flags &= ~IEEE80211_CONF_SHORT_SLOT_TIME;
1095                 if (ieee80211_hw_config(local))
1096                         ret = -EINVAL;
1097                 break;
1098
1099         case PRISM2_PARAM_NEXT_MODE:
1100                 local->next_mode = value;
1101                 break;
1102
1103         case PRISM2_PARAM_KEY_TX_RX_THRESHOLD:
1104                 local->key_tx_rx_threshold = value;
1105                 break;
1106
1107         case PRISM2_PARAM_WIFI_WME_NOACK_TEST:
1108                 local->wifi_wme_noack_test = value;
1109                 break;
1110
1111         case PRISM2_PARAM_SCAN_FLAGS:
1112                 local->scan_flags = value;
1113                 break;
1114
1115         case PRISM2_PARAM_MIXED_CELL:
1116                 if (sdata->type != IEEE80211_IF_TYPE_STA &&
1117                     sdata->type != IEEE80211_IF_TYPE_IBSS)
1118                         ret = -EINVAL;
1119                 else {
1120                         if (value)
1121                                 sdata->u.sta.flags |= IEEE80211_STA_MIXED_CELL;
1122                         else
1123                                 sdata->u.sta.flags &= ~IEEE80211_STA_MIXED_CELL;
1124                 }
1125                 break;
1126
1127         case PRISM2_PARAM_HW_MODES:
1128                 local->enabled_modes = value;
1129                 break;
1130
1131         case PRISM2_PARAM_CREATE_IBSS:
1132                 if (sdata->type != IEEE80211_IF_TYPE_IBSS)
1133                         ret = -EINVAL;
1134                 else {
1135                         if (value)
1136                                 sdata->u.sta.flags |= IEEE80211_STA_CREATE_IBSS;
1137                         else
1138                                 sdata->u.sta.flags &= ~IEEE80211_STA_CREATE_IBSS;
1139                 }
1140                 break;
1141         case PRISM2_PARAM_WMM_ENABLED:
1142                 if (sdata->type != IEEE80211_IF_TYPE_STA &&
1143                     sdata->type != IEEE80211_IF_TYPE_IBSS)
1144                         ret = -EINVAL;
1145                 else {
1146                         if (value)
1147                                 sdata->u.sta.flags |= IEEE80211_STA_WMM_ENABLED;
1148                         else
1149                                 sdata->u.sta.flags &= ~IEEE80211_STA_WMM_ENABLED;
1150                 }
1151                 break;
1152         default:
1153                 ret = -EOPNOTSUPP;
1154                 break;
1155         }
1156
1157         return ret;
1158 }
1159
1160
1161 static int ieee80211_ioctl_get_prism2_param(struct net_device *dev,
1162                                             struct iw_request_info *info,
1163                                             void *wrqu, char *extra)
1164 {
1165         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1166         struct ieee80211_sub_if_data *sdata;
1167         int *param = (int *) extra;
1168         int ret = 0;
1169
1170         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1171
1172         switch (*param) {
1173         case PRISM2_PARAM_IEEE_802_1X:
1174                 *param = sdata->ieee802_1x;
1175                 break;
1176
1177         case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES:
1178                 *param = !!(sdata->flags & IEEE80211_SDATA_USE_PROTECTION);
1179                 break;
1180
1181         case PRISM2_PARAM_PREAMBLE:
1182                 *param = !!(sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE);
1183                 break;
1184
1185         case PRISM2_PARAM_SHORT_SLOT_TIME:
1186                 *param = !!(local->hw.conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME);
1187                 break;
1188
1189         case PRISM2_PARAM_NEXT_MODE:
1190                 *param = local->next_mode;
1191                 break;
1192
1193         case PRISM2_PARAM_KEY_TX_RX_THRESHOLD:
1194                 *param = local->key_tx_rx_threshold;
1195                 break;
1196
1197         case PRISM2_PARAM_WIFI_WME_NOACK_TEST:
1198                 *param = local->wifi_wme_noack_test;
1199                 break;
1200
1201         case PRISM2_PARAM_SCAN_FLAGS:
1202                 *param = local->scan_flags;
1203                 break;
1204
1205         case PRISM2_PARAM_HW_MODES:
1206                 *param = local->enabled_modes;
1207                 break;
1208
1209         case PRISM2_PARAM_CREATE_IBSS:
1210                 if (sdata->type != IEEE80211_IF_TYPE_IBSS)
1211                         ret = -EINVAL;
1212                 else
1213                         *param = !!(sdata->u.sta.flags &
1214                                         IEEE80211_STA_CREATE_IBSS);
1215                 break;
1216
1217         case PRISM2_PARAM_MIXED_CELL:
1218                 if (sdata->type != IEEE80211_IF_TYPE_STA &&
1219                     sdata->type != IEEE80211_IF_TYPE_IBSS)
1220                         ret = -EINVAL;
1221                 else
1222                         *param = !!(sdata->u.sta.flags &
1223                                         IEEE80211_STA_MIXED_CELL);
1224                 break;
1225         case PRISM2_PARAM_WMM_ENABLED:
1226                 if (sdata->type != IEEE80211_IF_TYPE_STA &&
1227                     sdata->type != IEEE80211_IF_TYPE_IBSS)
1228                         ret = -EINVAL;
1229                 else
1230                         *param = !!(sdata->u.sta.flags &
1231                                         IEEE80211_STA_WMM_ENABLED);
1232                 break;
1233         default:
1234                 ret = -EOPNOTSUPP;
1235                 break;
1236         }
1237
1238         return ret;
1239 }
1240
1241 static int ieee80211_ioctl_siwmlme(struct net_device *dev,
1242                                    struct iw_request_info *info,
1243                                    struct iw_point *data, char *extra)
1244 {
1245         struct ieee80211_sub_if_data *sdata;
1246         struct iw_mlme *mlme = (struct iw_mlme *) extra;
1247
1248         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1249         if (sdata->type != IEEE80211_IF_TYPE_STA &&
1250             sdata->type != IEEE80211_IF_TYPE_IBSS)
1251                 return -EINVAL;
1252
1253         switch (mlme->cmd) {
1254         case IW_MLME_DEAUTH:
1255                 /* TODO: mlme->addr.sa_data */
1256                 return ieee80211_sta_deauthenticate(dev, mlme->reason_code);
1257         case IW_MLME_DISASSOC:
1258                 /* TODO: mlme->addr.sa_data */
1259                 return ieee80211_sta_disassociate(dev, mlme->reason_code);
1260         default:
1261                 return -EOPNOTSUPP;
1262         }
1263 }
1264
1265
1266 static int ieee80211_ioctl_siwencode(struct net_device *dev,
1267                                      struct iw_request_info *info,
1268                                      struct iw_point *erq, char *keybuf)
1269 {
1270         struct ieee80211_sub_if_data *sdata;
1271         int idx, i, alg = ALG_WEP;
1272         u8 bcaddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1273
1274         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1275
1276         idx = erq->flags & IW_ENCODE_INDEX;
1277         if (idx == 0) {
1278                 if (sdata->default_key)
1279                         for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
1280                                 if (sdata->default_key == sdata->keys[i]) {
1281                                         idx = i;
1282                                         break;
1283                                 }
1284                         }
1285         } else if (idx < 1 || idx > 4)
1286                 return -EINVAL;
1287         else
1288                 idx--;
1289
1290         if (erq->flags & IW_ENCODE_DISABLED)
1291                 alg = ALG_NONE;
1292         else if (erq->length == 0) {
1293                 /* No key data - just set the default TX key index */
1294                 if (sdata->default_key != sdata->keys[idx]) {
1295                         ieee80211_debugfs_key_remove_default(sdata);
1296                         sdata->default_key = sdata->keys[idx];
1297                         if (sdata->default_key)
1298                                 ieee80211_debugfs_key_add_default(sdata);
1299                 }
1300                 return 0;
1301         }
1302
1303         return ieee80211_set_encryption(
1304                 dev, bcaddr,
1305                 idx, alg,
1306                 !sdata->default_key,
1307                 keybuf, erq->length);
1308 }
1309
1310
1311 static int ieee80211_ioctl_giwencode(struct net_device *dev,
1312                                      struct iw_request_info *info,
1313                                      struct iw_point *erq, char *key)
1314 {
1315         struct ieee80211_sub_if_data *sdata;
1316         int idx, i;
1317
1318         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1319
1320         idx = erq->flags & IW_ENCODE_INDEX;
1321         if (idx < 1 || idx > 4) {
1322                 idx = -1;
1323                 if (!sdata->default_key)
1324                         idx = 0;
1325                 else for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
1326                         if (sdata->default_key == sdata->keys[i]) {
1327                                 idx = i;
1328                                 break;
1329                         }
1330                 }
1331                 if (idx < 0)
1332                         return -EINVAL;
1333         } else
1334                 idx--;
1335
1336         erq->flags = idx + 1;
1337
1338         if (!sdata->keys[idx]) {
1339                 erq->length = 0;
1340                 erq->flags |= IW_ENCODE_DISABLED;
1341                 return 0;
1342         }
1343
1344         memcpy(key, sdata->keys[idx]->key,
1345                min((int)erq->length, sdata->keys[idx]->keylen));
1346         erq->length = sdata->keys[idx]->keylen;
1347         erq->flags |= IW_ENCODE_ENABLED;
1348
1349         return 0;
1350 }
1351
1352 static int ieee80211_ioctl_siwauth(struct net_device *dev,
1353                                    struct iw_request_info *info,
1354                                    struct iw_param *data, char *extra)
1355 {
1356         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1357         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1358         int ret = 0;
1359
1360         switch (data->flags & IW_AUTH_INDEX) {
1361         case IW_AUTH_WPA_VERSION:
1362         case IW_AUTH_CIPHER_PAIRWISE:
1363         case IW_AUTH_CIPHER_GROUP:
1364         case IW_AUTH_WPA_ENABLED:
1365         case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1366                 break;
1367         case IW_AUTH_KEY_MGMT:
1368                 if (sdata->type != IEEE80211_IF_TYPE_STA)
1369                         ret = -EINVAL;
1370                 else {
1371                         /*
1372                          * Key management was set by wpa_supplicant,
1373                          * we only need this to associate to a network
1374                          * that has privacy enabled regardless of not
1375                          * having a key.
1376                          */
1377                         sdata->u.sta.key_management_enabled = !!data->value;
1378                 }
1379                 break;
1380         case IW_AUTH_80211_AUTH_ALG:
1381                 if (sdata->type == IEEE80211_IF_TYPE_STA ||
1382                     sdata->type == IEEE80211_IF_TYPE_IBSS)
1383                         sdata->u.sta.auth_algs = data->value;
1384                 else
1385                         ret = -EOPNOTSUPP;
1386                 break;
1387         case IW_AUTH_PRIVACY_INVOKED:
1388                 if (local->ops->set_privacy_invoked)
1389                         ret = local->ops->set_privacy_invoked(
1390                                         local_to_hw(local), data->value);
1391                 break;
1392         default:
1393                 ret = -EOPNOTSUPP;
1394                 break;
1395         }
1396         return ret;
1397 }
1398
1399 /* Get wireless statistics.  Called by /proc/net/wireless and by SIOCGIWSTATS */
1400 static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev)
1401 {
1402         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1403         struct iw_statistics *wstats = &local->wstats;
1404         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1405         struct sta_info *sta = NULL;
1406
1407         if (sdata->type == IEEE80211_IF_TYPE_STA ||
1408             sdata->type == IEEE80211_IF_TYPE_IBSS)
1409                 sta = sta_info_get(local, sdata->u.sta.bssid);
1410         if (!sta) {
1411                 wstats->discard.fragment = 0;
1412                 wstats->discard.misc = 0;
1413                 wstats->qual.qual = 0;
1414                 wstats->qual.level = 0;
1415                 wstats->qual.noise = 0;
1416                 wstats->qual.updated = IW_QUAL_ALL_INVALID;
1417         } else {
1418                 wstats->qual.level = sta->last_rssi;
1419                 wstats->qual.qual = sta->last_signal;
1420                 wstats->qual.noise = sta->last_noise;
1421                 wstats->qual.updated = local->wstats_flags;
1422                 sta_info_put(sta);
1423         }
1424         return wstats;
1425 }
1426
1427 static int ieee80211_ioctl_giwauth(struct net_device *dev,
1428                                    struct iw_request_info *info,
1429                                    struct iw_param *data, char *extra)
1430 {
1431         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1432         int ret = 0;
1433
1434         switch (data->flags & IW_AUTH_INDEX) {
1435         case IW_AUTH_80211_AUTH_ALG:
1436                 if (sdata->type == IEEE80211_IF_TYPE_STA ||
1437                     sdata->type == IEEE80211_IF_TYPE_IBSS)
1438                         data->value = sdata->u.sta.auth_algs;
1439                 else
1440                         ret = -EOPNOTSUPP;
1441                 break;
1442         default:
1443                 ret = -EOPNOTSUPP;
1444                 break;
1445         }
1446         return ret;
1447 }
1448
1449
1450 static int ieee80211_ioctl_siwencodeext(struct net_device *dev,
1451                                         struct iw_request_info *info,
1452                                         struct iw_point *erq, char *extra)
1453 {
1454         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1455         struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
1456         int alg, idx, i;
1457
1458         switch (ext->alg) {
1459         case IW_ENCODE_ALG_NONE:
1460                 alg = ALG_NONE;
1461                 break;
1462         case IW_ENCODE_ALG_WEP:
1463                 alg = ALG_WEP;
1464                 break;
1465         case IW_ENCODE_ALG_TKIP:
1466                 alg = ALG_TKIP;
1467                 break;
1468         case IW_ENCODE_ALG_CCMP:
1469                 alg = ALG_CCMP;
1470                 break;
1471         default:
1472                 return -EOPNOTSUPP;
1473         }
1474
1475         if (erq->flags & IW_ENCODE_DISABLED)
1476                 alg = ALG_NONE;
1477
1478         idx = erq->flags & IW_ENCODE_INDEX;
1479         if (idx < 1 || idx > 4) {
1480                 idx = -1;
1481                 if (!sdata->default_key)
1482                         idx = 0;
1483                 else for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
1484                         if (sdata->default_key == sdata->keys[i]) {
1485                                 idx = i;
1486                                 break;
1487                         }
1488                 }
1489                 if (idx < 0)
1490                         return -EINVAL;
1491         } else
1492                 idx--;
1493
1494         return ieee80211_set_encryption(dev, ext->addr.sa_data, idx, alg,
1495                                         ext->ext_flags &
1496                                         IW_ENCODE_EXT_SET_TX_KEY,
1497                                         ext->key, ext->key_len);
1498 }
1499
1500
1501 static const struct iw_priv_args ieee80211_ioctl_priv[] = {
1502         { PRISM2_IOCTL_PRISM2_PARAM,
1503           IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "param" },
1504         { PRISM2_IOCTL_GET_PRISM2_PARAM,
1505           IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1506           IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_param" },
1507 };
1508
1509 /* Structures to export the Wireless Handlers */
1510
1511 static const iw_handler ieee80211_handler[] =
1512 {
1513         (iw_handler) NULL,                              /* SIOCSIWCOMMIT */
1514         (iw_handler) ieee80211_ioctl_giwname,           /* SIOCGIWNAME */
1515         (iw_handler) NULL,                              /* SIOCSIWNWID */
1516         (iw_handler) NULL,                              /* SIOCGIWNWID */
1517         (iw_handler) ieee80211_ioctl_siwfreq,           /* SIOCSIWFREQ */
1518         (iw_handler) ieee80211_ioctl_giwfreq,           /* SIOCGIWFREQ */
1519         (iw_handler) ieee80211_ioctl_siwmode,           /* SIOCSIWMODE */
1520         (iw_handler) ieee80211_ioctl_giwmode,           /* SIOCGIWMODE */
1521         (iw_handler) NULL,                              /* SIOCSIWSENS */
1522         (iw_handler) NULL,                              /* SIOCGIWSENS */
1523         (iw_handler) NULL /* not used */,               /* SIOCSIWRANGE */
1524         (iw_handler) ieee80211_ioctl_giwrange,          /* SIOCGIWRANGE */
1525         (iw_handler) NULL /* not used */,               /* SIOCSIWPRIV */
1526         (iw_handler) NULL /* kernel code */,            /* SIOCGIWPRIV */
1527         (iw_handler) NULL /* not used */,               /* SIOCSIWSTATS */
1528         (iw_handler) NULL /* kernel code */,            /* SIOCGIWSTATS */
1529         iw_handler_set_spy,                             /* SIOCSIWSPY */
1530         iw_handler_get_spy,                             /* SIOCGIWSPY */
1531         iw_handler_set_thrspy,                          /* SIOCSIWTHRSPY */
1532         iw_handler_get_thrspy,                          /* SIOCGIWTHRSPY */
1533         (iw_handler) ieee80211_ioctl_siwap,             /* SIOCSIWAP */
1534         (iw_handler) ieee80211_ioctl_giwap,             /* SIOCGIWAP */
1535         (iw_handler) ieee80211_ioctl_siwmlme,           /* SIOCSIWMLME */
1536         (iw_handler) NULL,                              /* SIOCGIWAPLIST */
1537         (iw_handler) ieee80211_ioctl_siwscan,           /* SIOCSIWSCAN */
1538         (iw_handler) ieee80211_ioctl_giwscan,           /* SIOCGIWSCAN */
1539         (iw_handler) ieee80211_ioctl_siwessid,          /* SIOCSIWESSID */
1540         (iw_handler) ieee80211_ioctl_giwessid,          /* SIOCGIWESSID */
1541         (iw_handler) NULL,                              /* SIOCSIWNICKN */
1542         (iw_handler) NULL,                              /* SIOCGIWNICKN */
1543         (iw_handler) NULL,                              /* -- hole -- */
1544         (iw_handler) NULL,                              /* -- hole -- */
1545         (iw_handler) ieee80211_ioctl_siwrate,           /* SIOCSIWRATE */
1546         (iw_handler) ieee80211_ioctl_giwrate,           /* SIOCGIWRATE */
1547         (iw_handler) ieee80211_ioctl_siwrts,            /* SIOCSIWRTS */
1548         (iw_handler) ieee80211_ioctl_giwrts,            /* SIOCGIWRTS */
1549         (iw_handler) ieee80211_ioctl_siwfrag,           /* SIOCSIWFRAG */
1550         (iw_handler) ieee80211_ioctl_giwfrag,           /* SIOCGIWFRAG */
1551         (iw_handler) NULL,                              /* SIOCSIWTXPOW */
1552         (iw_handler) ieee80211_ioctl_giwtxpower,        /* SIOCGIWTXPOW */
1553         (iw_handler) ieee80211_ioctl_siwretry,          /* SIOCSIWRETRY */
1554         (iw_handler) ieee80211_ioctl_giwretry,          /* SIOCGIWRETRY */
1555         (iw_handler) ieee80211_ioctl_siwencode,         /* SIOCSIWENCODE */
1556         (iw_handler) ieee80211_ioctl_giwencode,         /* SIOCGIWENCODE */
1557         (iw_handler) NULL,                              /* SIOCSIWPOWER */
1558         (iw_handler) NULL,                              /* SIOCGIWPOWER */
1559         (iw_handler) NULL,                              /* -- hole -- */
1560         (iw_handler) NULL,                              /* -- hole -- */
1561         (iw_handler) ieee80211_ioctl_siwgenie,          /* SIOCSIWGENIE */
1562         (iw_handler) NULL,                              /* SIOCGIWGENIE */
1563         (iw_handler) ieee80211_ioctl_siwauth,           /* SIOCSIWAUTH */
1564         (iw_handler) ieee80211_ioctl_giwauth,           /* SIOCGIWAUTH */
1565         (iw_handler) ieee80211_ioctl_siwencodeext,      /* SIOCSIWENCODEEXT */
1566         (iw_handler) NULL,                              /* SIOCGIWENCODEEXT */
1567         (iw_handler) NULL,                              /* SIOCSIWPMKSA */
1568         (iw_handler) NULL,                              /* -- hole -- */
1569 };
1570
1571 static const iw_handler ieee80211_private_handler[] =
1572 {                                                       /* SIOCIWFIRSTPRIV + */
1573         (iw_handler) ieee80211_ioctl_prism2_param,      /* 0 */
1574         (iw_handler) ieee80211_ioctl_get_prism2_param,  /* 1 */
1575 };
1576
1577 const struct iw_handler_def ieee80211_iw_handler_def =
1578 {
1579         .num_standard   = ARRAY_SIZE(ieee80211_handler),
1580         .num_private    = ARRAY_SIZE(ieee80211_private_handler),
1581         .num_private_args = ARRAY_SIZE(ieee80211_ioctl_priv),
1582         .standard       = (iw_handler *) ieee80211_handler,
1583         .private        = (iw_handler *) ieee80211_private_handler,
1584         .private_args   = (struct iw_priv_args *) ieee80211_ioctl_priv,
1585         .get_wireless_stats = ieee80211_get_wireless_stats,
1586 };