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